Files
blitzkit/packages/website/src/components/HomePageHotTanks.tsx
T

111 lines
3.2 KiB
TypeScript
Raw Normal View History

2024-12-12 15:03:51 -06:00
import { assertSecret } from '@blitzkit/core';
2025-01-15 20:14:05 -06:00
import { literals } from '@blitzkit/i18n/src/literals';
2024-12-12 15:03:51 -06:00
import { EyeOpenIcon } from '@radix-ui/react-icons';
import { Box, Flex, Heading, Text } from '@radix-ui/themes';
import { google } from 'googleapis';
2024-11-29 13:20:27 -06:00
import { awaitableTankDefinitions } from '../core/awaitables/tankDefinitions';
2025-01-06 20:31:21 -06:00
import {
LocaleProvider,
useLocale,
type LocaleAcceptorProps,
} from '../hooks/useLocale';
2024-11-11 12:46:06 -06:00
import { TankopediaPersistent } from '../stores/tankopediaPersistent';
2024-11-16 22:47:12 -06:00
import { TankCard } from './TankCard';
2024-11-11 12:46:06 -06:00
2024-12-12 15:03:51 -06:00
const [tankDefinitions] = await Promise.all([awaitableTankDefinitions, ,]);
2024-11-11 12:46:06 -06:00
2024-12-12 15:03:51 -06:00
const auth = await google.auth.getClient({
keyFile: import.meta.env.GOOGLE_APPLICATION_CREDENTIALS,
scopes: ['https://www.googleapis.com/auth/analytics.readonly'],
});
const analytics = google.analyticsdata({ version: 'v1beta', auth });
const report = await analytics.properties.runReport({
property: `properties/${assertSecret(import.meta.env.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID)}`,
requestBody: {
dateRanges: [{ startDate: '7daysAgo', endDate: 'today' }],
dimensions: [{ name: 'pagePath' }],
metrics: [{ name: 'screenPageViews' }],
orderBys: [{ metric: { metricName: 'screenPageViews' }, desc: true }],
dimensionFilter: {
filter: {
fieldName: 'pagePath',
stringFilter: { matchType: 'BEGINS_WITH', value: '/tools/tankopedia/' },
},
},
},
});
if (!report.data.rows) {
throw new Error('No rows in report');
}
const hotTanks = report.data.rows
.filter(
(row) =>
row.dimensionValues &&
row.dimensionValues[0].value &&
row.dimensionValues[0].value !== '/tools/tankopedia/' &&
row.metricValues &&
row.metricValues[0].value,
)
.map((row) => ({
id: Number(
row.dimensionValues![0].value!.match(
/\/tools\/tankopedia\/(\d+)\/?/,
)?.[1],
),
views: Number(row.metricValues![0].value!),
}))
.filter((row) => {
if (!(row.id in tankDefinitions.tanks)) {
// console.log('Unknown tank', row.id);
}
return row.id in tankDefinitions.tanks;
})
2024-12-14 13:28:48 -06:00
.slice(0, 8)
2024-12-12 15:03:51 -06:00
.map(({ id, views }) => ({
tank: tankDefinitions.tanks[id],
views,
}));
2024-11-11 12:46:06 -06:00
2025-01-06 20:31:21 -06:00
export function HomePageHotTanks({ locale }: LocaleAcceptorProps) {
2024-11-11 12:46:06 -06:00
return (
2024-12-27 14:01:59 -06:00
<LocaleProvider locale={locale}>
<TankopediaPersistent.Provider>
<Content />
</TankopediaPersistent.Provider>
</LocaleProvider>
2024-11-11 12:46:06 -06:00
);
}
function Content() {
2025-01-06 20:09:11 -06:00
const { locale, strings } = useLocale();
2024-11-11 12:46:06 -06:00
return (
2025-04-03 12:15:08 -05:00
<Flex direction="column" pt="4" pb="6">
2024-11-11 12:46:06 -06:00
<Heading align="center" size="5">
2025-01-06 20:09:11 -06:00
{strings.website.home.hot_tanks.title}
2024-11-11 12:46:06 -06:00
</Heading>
2024-12-12 15:03:51 -06:00
<Text color="gray" align="center" mb="5" size="2">
2025-01-06 20:09:11 -06:00
{literals(strings.website.home.hot_tanks.subtitle, ['7'])}
2024-12-12 15:03:51 -06:00
</Text>
2024-11-11 12:46:06 -06:00
<Flex justify="center" gap="4" wrap="wrap">
2024-12-12 15:03:51 -06:00
{hotTanks.map((row) => (
<Box width="7rem" key={row.tank.id}>
<TankCard
tank={row.tank}
discriminator={
<Flex align="center" gap="1" justify="center">
<EyeOpenIcon />
2025-01-06 20:09:11 -06:00
{Math.round(row.views * (30 / 7)).toLocaleString(locale)}
2024-12-12 15:03:51 -06:00
</Flex>
}
/>
2024-11-11 12:46:06 -06:00
</Box>
))}
</Flex>
</Flex>
);
}