diff --git a/app/(stats)/analyze/content.tsx b/app/(stats)/analyze/content.tsx new file mode 100644 index 00000000..36a264c6 --- /dev/null +++ b/app/(stats)/analyze/content.tsx @@ -0,0 +1,108 @@ +import { getSquads, getFactionCount } from '@/lib/db/squads'; +import { getTournamentsCount } from '@/lib/db/tournaments'; +import { ChassisDistribution } from '@/ui/stats/chassis-distribution'; +import { CompositionStats } from '@/ui/stats/composition-stats'; +import { FactionDistribution } from '@/ui/stats/faction-distribution'; +import { FactionPerformance } from '@/ui/stats/faction-performance'; +import { FactionVictories } from '@/ui/stats/faction-victories'; +import { PilotCostDistribution } from '@/ui/stats/pilot-cost-distribution'; +import { PilotSkillDistribution } from '@/ui/stats/pilot-skill-distribution'; +import { PilotStats } from '@/ui/stats/pilot-stats'; +import { SquadSize } from '@/ui/stats/squad-size'; +import { StatsHint } from '@/ui/stats/stats-hint'; +import { UpgradeStats } from '@/ui/stats/upgrade-stats'; +import { setup } from '@/lib/stats'; +import { + CompositionData, + FactionData, + PilotData, + PilotCostDistributionData, + PilotSkillDistributionData, + ShipData, + SquadSizeData, + UpgradeData, + composition, + faction, + pilotCostDistribution, + pilotSkillDistribution, + pilot, + ship, + squadSize, + upgrade, +} from '@/lib/stats/module'; + +// Helpers +// --------------- +interface StatsData + extends CompositionData, + FactionData, + PilotData, + PilotCostDistributionData, + PilotSkillDistributionData, + ShipData, + SquadSizeData, + UpgradeData {} + +const create = setup([ + composition, + faction, + pilotCostDistribution, + pilotSkillDistribution, + pilot, + ship, + squadSize, + upgrade, +]); + +// Component +// --------------- +export const Content = async ({ from, to }: { from: Date; to?: Date }) => { + const [squads, tournaments, count] = await Promise.all([ + getSquads({ from, to }), + getTournamentsCount({ from, to }), + getFactionCount({ from, to }), + ]); + + const stats = create(squads, { + count, + tournaments, + }); + + return ( +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ ); +}; diff --git a/app/(stats)/analyze/page.tsx b/app/(stats)/analyze/page.tsx index cec44825..9da97b80 100644 --- a/app/(stats)/analyze/page.tsx +++ b/app/(stats)/analyze/page.tsx @@ -1,46 +1,12 @@ -import { cache } from 'react'; -import { z } from 'zod'; - -import { getSquads, getFactionCount } from '@/lib/db/squads'; -import { pointsUpdateDate } from '@/lib/config'; import { createMetadata } from '@/lib/metadata'; -import { setup } from '@/lib/stats'; -import { - composition, - faction, - pilot, - pilotCostDistribution, - pilotSkillDistribution, - ship, - squadSize, - upgrade, - type CompositionData, - type FactionData, - type PilotData, - type PilotCostDistributionData, - type PilotSkillDistributionData, - type ShipData, - type SquadSizeData, - type UpgradeData, -} from '@/lib/stats/module'; -import { formatDate, fromDate, toDate, today } from '@/lib/utils/date.utils'; +import { toDateRange } from '@/lib/utils/params.utils'; -import { Caption, Inline, Message, Title } from '@/ui'; -import { Calendar, Rocket, Trophy } from '@/ui/icons'; +import { Caption, Message, Title } from '@/ui'; +import { Filter } from '@/ui/params/filter'; +import { DateRangeFilter } from '@/ui/params/date-range-filter'; +import { StatsInfo } from '@/ui/stats/stats-info'; -import { ChassisDistribution } from '@/ui/stats/chassis-distribution'; -import { CompositionStats } from '@/ui/stats/composition-stats'; -import { FactionDistribution } from '@/ui/stats/faction-distribution'; -import { FactionPerformance } from '@/ui/stats/faction-performance'; -import { FactionVictories } from '@/ui/stats/faction-victories'; -import { StatsFilter } from '@/ui/stats/stats-filter'; -import { PilotCostDistribution } from '@/ui/stats/pilot-cost-distribution'; -import { PilotSkillDistribution } from '@/ui/stats/pilot-skill-distribution'; -import { PilotStats } from '@/ui/stats/pilot-stats'; -import { SquadSize } from '@/ui/stats/squad-size'; -import { StatsHint } from '@/ui/stats/stats-hint'; -import { UpgradeStats } from '@/ui/stats/upgrade-stats'; -import { getTournamentsCount } from '@/lib/db/tournaments'; +import { Content } from './content'; // Metadata // --------------- @@ -49,67 +15,6 @@ export const metadata = createMetadata({ description: 'Analyze the current X-Wing meta!', }); -// Helpers -// --------------- -// Note: only checks the format, can still produce invalid dates (like 2022-02-31) -const DATE_REGEX = /(\d{4})-(\d{2})-(\d{2})/; - -const schema = z - .object({ - from: z.string().regex(DATE_REGEX).optional(), - to: z.string().regex(DATE_REGEX).optional(), - 'small-samples': z.union([z.literal('show'), z.literal('hide')]).optional(), - }) - .transform(({ 'small-samples': smallSamples, ...props }) => ({ - ...props, - smallSamples: smallSamples === 'show', - })); - -interface StatsData - extends CompositionData, - FactionData, - PilotData, - PilotCostDistributionData, - PilotSkillDistributionData, - ShipData, - SquadSizeData, - UpgradeData {} - -const create = setup([ - composition, - faction, - pilotCostDistribution, - pilotSkillDistribution, - pilot, - ship, - squadSize, - upgrade, -]); - -// Data -// --------------- -const getStats = cache( - async (from: Date, to: Date | undefined, smallSamples: boolean) => { - const [squads, tournaments, count] = await Promise.all([ - getSquads({ from, to }), - getTournamentsCount({ from, to }), - getFactionCount({ from, to }), - ]); - - return { - stats: create(squads, { - smallSamples, - count, - tournaments, - }), - meta: { - tournaments, - count, - }, - }; - } -); - // Props // --------------- interface AnalyzePageProps { @@ -123,9 +28,9 @@ interface AnalyzePageProps { // Page // --------------- const AnalyzePage = async ({ searchParams }: AnalyzePageProps) => { - const params = schema.safeParse(searchParams); + const params = toDateRange(searchParams); - if (!params.success) { + if (params.error) { return (
@@ -136,76 +41,20 @@ const AnalyzePage = async ({ searchParams }: AnalyzePageProps) => { ); } - const from = - params.data && params.data.from - ? fromDate(params.data.from) - : fromDate(pointsUpdateDate); - const to = - params.data && params.data.to ? fromDate(params.data.to) : undefined; - - const { stats, meta } = await getStats(from, to, params.data.smallSamples); + const { from, to } = params; return ( <>
Analyze - - - {formatDate(from)} -{' '} - {formatDate(to || today())} - - - {meta.tournaments} Tournaments - - - {meta.count.all} Squads - - +
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
+ + + + ); }; diff --git a/app/(stats)/composition/page.tsx b/app/(stats)/composition/page.tsx index d935c6a6..d20d1c73 100644 --- a/app/(stats)/composition/page.tsx +++ b/app/(stats)/composition/page.tsx @@ -32,7 +32,7 @@ export const metadata = createMetadata({ // --------------- const create = setup([composition]); -// Async content block +// Content // --------------- const Content = async ({ from, to }: { from: Date; to?: Date }) => { const [squads, tournaments, count] = await Promise.all([ @@ -60,9 +60,9 @@ interface PageProps { // Page // --------------- const CompositionsPage = async ({ searchParams }: PageProps) => { - const result = toDateRange(searchParams); + const params = toDateRange(searchParams); - if (result.error) { + if (params.error) { return (
@@ -73,7 +73,7 @@ const CompositionsPage = async ({ searchParams }: PageProps) => { ); } - const { from, to } = result; + const { from, to } = params; return ( <>