Skip to content

Commit

Permalink
Merge pull request #212 from AmbireTech/admin-panel-on-steroids
Browse files Browse the repository at this point in the history
Admin panel on steroids
  • Loading branch information
ivopaunov authored Jul 10, 2024
2 parents b016056 + 34b87e2 commit 2cbaebd
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 72 deletions.
114 changes: 114 additions & 0 deletions src/components/AdminPanel/Accounts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { useEffect, useState, useMemo } from 'react'
import {
Container,
Loader,
Flex,
Box,
Badge

// Flex, Loader, Tabs
} from '@mantine/core'

import CustomTable from 'components/common/CustomTable'
import { useAdExApi } from 'hooks/useAdexServices'
import { Account } from 'types'
import { parseBigNumTokenAmountToDecimal } from 'helpers/balances'

const headingsDefault = ['Id', 'email', 'balance', 'campaigns launched', 'total spend', 'created']

const AdminAnalytics = () => {
const { adexServicesRequest } = useAdExApi()
const [loading, setLoading] = useState(true)
const [accounts, setAccounts] = useState<Array<Account>>([])
const headings = useMemo(() => [...headingsDefault], [])

useEffect(() => {
const getData = async () => {
try {
const res = await adexServicesRequest<Array<Account>>('backend', {
route: '/dsp/admin/accounts/all',
method: 'GET',
headers: {
'content-type': 'application/json'
}
})

console.log({ res })
setAccounts(res)
} catch (err) {
console.log({ err })
}
setLoading(false)
}

getData()
}, [adexServicesRequest])

const data = useMemo(() => {
// TODO: fix this when multy token
const decimals = accounts[0].balanceToken.decimals
const totalDeposits = parseBigNumTokenAmountToDecimal(
accounts?.reduce((sum, a) => sum + BigInt(a.fundsDeposited.total), 0n),
decimals
).toLocaleString()
const totalCampaignsLocked = parseBigNumTokenAmountToDecimal(
accounts?.reduce(
(sum, a) => sum + BigInt(a.fundsOnCampaigns.total - a.refundsFromCampaigns.total),
0n
),
decimals
).toLocaleString()

const elements = accounts
.sort((a, b) => Number(b.availableBalance) - Number(a.availableBalance))
.map((a) => {
return {
id: a.id,
accountId: a.id,
email: a.info?.email,
balance: parseBigNumTokenAmountToDecimal(
a.availableBalance,
a.balanceToken.decimals
).toFixed(2),
campaigns: a.fundsOnCampaigns.perCampaign.length,
fudsOnCampaigns: parseBigNumTokenAmountToDecimal(
a.fundsOnCampaigns.total - a.refundsFromCampaigns.total,
a.balanceToken.decimals
).toFixed(2),
created: new Date(a.created).toLocaleDateString()
}
})

return {
elements,
totalDeposits,
totalCampaignsLocked
}
}, [accounts])

return (
<Container fluid>
{loading ? (
<Loader size="xl" variant="dots" color="violet" />
) : (
<Flex direction="column">
<Flex direction="row" align="center" justify="left" gap="xl" mb="md">
<Box>Totals: </Box>
<Badge leftSection="Accounts" size="xl">
({data.elements.length})
</Badge>
<Badge leftSection="Deposits" size="xl">
({data.totalDeposits} USDC)
</Badge>
<Badge leftSection="Campaigns" size="xl">
({data.totalCampaignsLocked} USDC)
</Badge>
</Flex>
<CustomTable background headings={headings} elements={data.elements} pageSize={10} />
</Flex>
)}
</Container>
)
}

export default AdminAnalytics
132 changes: 82 additions & 50 deletions src/components/AdminPanel/AdminAnalytics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {

// Flex, Loader, Tabs
} from '@mantine/core'
import { BaseAnalyticsData, AnalyticsPeriod, Timeframe, AnalyticsType } from 'types'
import { BaseAnalyticsData, AnalyticsPeriod, Timeframe, AnalyticsType, SSPs } from 'types'
import useCampaignAnalytics from 'hooks/useCampaignAnalytics'
import CustomTable from 'components/common/CustomTable'
import { CountryData } from 'helpers/countries'
Expand All @@ -22,6 +22,7 @@ import BillingIcon from 'resources/icons/Billing'
import VisibilityIcon from 'resources/icons/Visibility'
import { getHumneSrcName } from 'helpers'
import CheckMarkFilledIcon from 'resources/icons/CheckMarkFilled'
import DownloadCSV from 'components/common/DownloadCSV'

const headingsDefault = [
// 'Country',
Expand All @@ -30,10 +31,22 @@ const headingsDefault = [
'Impressions',
'Clicks',
'CTR',
'Average CPM',
'Avg CPM',
'Avg CPC',
'Spent'
]

const csvHeaders = {
// segment: 'segment',
share: 'share',
impressions: 'impressions',
clicks: 'clicks',
ctr: 'ctr',
avgCpm: 'avgCpm',
avgCpc: 'avgCpc',
paid: 'paid'
}

const timeframeData: Array<{ value: Timeframe; label: Timeframe }> = [
{ value: 'year', label: 'year' },
{ value: 'month', label: 'month' },
Expand All @@ -48,7 +61,15 @@ const analyticsTypeData: Array<{ value: AnalyticsType; label: string }> = [
{ value: 'hostname', label: 'By hostname' },
{ value: 'placement', label: 'By placement' },
{ value: 'campaignId', label: 'By campaign id' },
{ value: 'advertiser', label: 'By advertiser' }
{ value: 'advertiser', label: 'By advertiser' },
{ value: 'timeframe', label: 'By Timeframe' }
]

const sspsData: Array<{ value: SSPs; label: string }> = [
{ value: '', label: 'All SSPs' },
{ value: 'Eskimi', label: 'Eskimi' },
{ value: 'Epom', label: 'Epom' },
{ value: 'Qortex', label: 'Qortex' }
]

const mapSegmentLabel = (analType: AnalyticsType, segment: string): { segementLabel: string } => {
Expand All @@ -59,7 +80,7 @@ const mapSegmentLabel = (analType: AnalyticsType, segment: string): { segementLa
segementLabel = CountryData.get(segment)?.name || segment
break
case 'timeframe':
segementLabel = new Date(Number(segment)).toLocaleString()
segementLabel = new Date(Number(segment)).toUTCString()
break
case 'hostname':
// TODO: separate calls for app/site - will require more work
Expand Down Expand Up @@ -88,6 +109,7 @@ const AdminAnalytics = () => {

const [timeframe, setTimeframe] = useState<Timeframe>('month')
const [analType, setAnalType] = useState<AnalyticsType>('ssp')
const [ssp, setSsp] = useState<SSPs>('')
const [startDate, setStartDate] = useState<Date | null>(
dayjs().subtract(1, 'month').startOf('month').toDate()
)
Expand Down Expand Up @@ -134,24 +156,25 @@ const AdminAnalytics = () => {
true,
timeframe,
startDate || undefined,
end || undefined
end || undefined,
ssp || undefined
)
setAnalyticsKey(key)
console.log('key', key)
}

checkAnalytics()
}, [analType, getAnalyticsKeyAndUpdate, startDate, timeframe])
}, [analType, getAnalyticsKeyAndUpdate, ssp, startDate, timeframe])

const loading = useMemo(
() => !analyticsKey || !adminMappedAnalytics,
[analyticsKey, adminMappedAnalytics]
)

const data = useMemo(() => {
const paid = adminMappedAnalytics?.reduce((sum, i) => sum + i.paid, 0) || 1
const imps = adminMappedAnalytics?.reduce((sum, i) => sum + i.impressions, 0) || 1
const clicks = adminMappedAnalytics?.reduce((sum, i) => sum + i.clicks, 0) || 1
const paid = adminMappedAnalytics?.reduce((sum, i) => sum + i.paid, 0) || 0
const imps = adminMappedAnalytics?.reduce((sum, i) => sum + i.impressions, 0) || 0
const clicks = adminMappedAnalytics?.reduce((sum, i) => sum + i.clicks, 0) || 0
return {
paid,
imps,
Expand All @@ -160,12 +183,13 @@ const AdminAnalytics = () => {
adminMappedAnalytics?.map((item) => ({
id: item.segment.toString(),
segment: mapSegmentLabel(analType, item.segment).segementLabel,
share: `${((item.paid / paid) * 100).toFixed(2)} %`,
shareImps: `${((item.impressions / imps) * 100).toFixed(2)} %`,
share: `${((item.paid / (paid || 1)) * 100).toFixed(2)} %`,
shareImps: `${((item.impressions / (imps || 1)) * 100).toFixed(2)} %`,
impressions: item.impressions,
clicks: item.clicks,
ctr: `${item.ctr} %`,
avgCpm: `${item.avgCpm}`,
avgCPC: `${item.avgCpc}`,
paid: `${item.paid.toFixed(4)}`
})) || []
}
Expand All @@ -185,14 +209,21 @@ const AdminAnalytics = () => {
etc. (NOT the stats form received requests form the SSPs)
</Text>

<Flex direction="row" align="center" justify="left" gap="xl" mb="md">
<Flex direction="row" align="start" justify="left" gap="xl" mb="md">
<Select
label="Type"
value={analType}
onChange={(val) => setAnalType(val as AnalyticsType)}
data={analyticsTypeData}
size="md"
/>
<Select
label="SSP"
value={ssp}
onChange={(val) => setSsp(val as SSPs)}
data={sspsData}
size="md"
/>
<Select
label="Period"
value={timeframe}
Expand Down Expand Up @@ -224,44 +255,45 @@ const AdminAnalytics = () => {
<Flex direction="column">
<Flex direction="row" align="center" justify="left" gap="xl" mb="md">
<Box>Totals: </Box>
<Box>
<Badge
leftSection={
<ActionIcon size="sm" color="brand">
<BillingIcon />
</ActionIcon>
}
size="xl"
>
{Number(data.paid.toFixed(2)).toLocaleString()}
</Badge>
</Box>
<Box>
<Badge
size="xl"
leftSection={
<ActionIcon size="sm" color="brand">
<VisibilityIcon />
</ActionIcon>
}
>
{' '}
{data.imps.toLocaleString()}
</Badge>
</Box>
<Box>
<Badge
size="xl"
leftSection={
<ActionIcon size="sm" color="brand">
<CheckMarkFilledIcon />
</ActionIcon>
}
>
{' '}
{data.clicks.toLocaleString()}
</Badge>
</Box>
<Badge
leftSection={
<ActionIcon size="sm" color="brand">
<BillingIcon />
</ActionIcon>
}
size="xl"
>
{Number(data.paid.toFixed(2)).toLocaleString()}
</Badge>

<Badge
size="xl"
leftSection={
<ActionIcon size="sm" color="brand">
<VisibilityIcon />
</ActionIcon>
}
>
{data.imps.toLocaleString()}
</Badge>

<Badge
size="xl"
leftSection={
<ActionIcon size="sm" color="brand">
<CheckMarkFilledIcon />
</ActionIcon>
}
>
{data.clicks.toLocaleString()}
</Badge>

<DownloadCSV
data={adminMappedAnalytics}
mapHeadersToDataProperties={{ [analType]: 'segment', ...csvHeaders }}
filename={`${analyticsKey?.key || 'admin-data-export'}.csv`}
disabled={loading}
/>
</Flex>
<CustomTable
background
Expand Down
4 changes: 2 additions & 2 deletions src/components/AdminPanel/AdminDeposits.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function AdminDeposit() {
address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
decimals: 6
},
txHash: '0x0000000000000000000000000000000000000000000000000000000000000000'
txHash: ''
},

validate: {
Expand Down Expand Up @@ -135,7 +135,7 @@ function AdminDeposit() {
/>
<TextInput
label="Tx hash"
placeholder="tx hash"
placeholder="0x0000000000000000000000000000000000000000000000000000000000000000"
withAsterisk
mt="md"
{...form.getInputProps('txHash')}
Expand Down
10 changes: 8 additions & 2 deletions src/components/AdminPanel/AdminPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Tabs } from '@mantine/core'
import { AdminBadge } from 'components/common/AdminBadge'
import Dashboard from 'components/Dashboard'
import AdminAnalytics from './AdminAnalytics'
import Accounts from './Accounts'
import { AdminDeposit } from './AdminDeposits'

const AdminPanel = () => {
Expand All @@ -13,7 +14,8 @@ const AdminPanel = () => {
<Tabs.List>
<Tabs.Tab value="campaigns">Campaigns</Tabs.Tab>
<Tabs.Tab value="generalAnalytics">Validator Analytics</Tabs.Tab>
<Tabs.Tab value="Deposits">Deposits</Tabs.Tab>
<Tabs.Tab value="deposits">Deposits</Tabs.Tab>
<Tabs.Tab value="accounts">Accounts</Tabs.Tab>
</Tabs.List>

<Tabs.Panel value="campaigns" pt="xs">
Expand All @@ -24,9 +26,13 @@ const AdminPanel = () => {
<AdminAnalytics />
</Tabs.Panel>

<Tabs.Panel value="Deposits" pt="xs">
<Tabs.Panel value="deposits" pt="xs">
<AdminDeposit />
</Tabs.Panel>

<Tabs.Panel value="accounts" pt="xs">
<Accounts />
</Tabs.Panel>
</Tabs>
</>
)
Expand Down
Loading

0 comments on commit 2cbaebd

Please sign in to comment.