Skip to content

Commit

Permalink
refa
Browse files Browse the repository at this point in the history
  • Loading branch information
sebald committed Nov 8, 2023
1 parent a67965a commit e4f1ff1
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 169 deletions.
108 changes: 108 additions & 0 deletions app/(stats)/analyze/content.tsx
Original file line number Diff line number Diff line change
@@ -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<StatsData>([
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 (
<div className="grid grid-cols-1 gap-4 md:grid-cols-12">
<div className="md:col-span-6">
<FactionDistribution value={stats.faction} total={count.all} />
</div>
<div className="md:col-span-6">
<FactionPerformance value={stats.faction} />
</div>
<div className="md:col-span-6">
<FactionVictories value={stats.faction} total={tournaments} />
</div>
<div className="md:col-span-6">
<SquadSize value={stats.squadSize} total={count.all - count.unknown} />
</div>
<div className="col-span-full">
<ChassisDistribution value={stats.ship} />
</div>
<div className="md:col-span-6">
<PilotCostDistribution value={stats.pilotCostDistribution} />
</div>
<div className="md:col-span-6">
<PilotSkillDistribution value={stats.pilotSkillDistribution} />
</div>
<div className="col-span-full">
<PilotStats value={stats.pilot} />
</div>
<div className="col-span-full">
<UpgradeStats value={stats.upgrade} />
</div>
<div className="col-span-full">
<CompositionStats value={stats.composition} />
</div>
<div className="col-span-full pt-8 lg:col-start-2 lg:col-end-12">
<StatsHint />
</div>
</div>
);
};
179 changes: 14 additions & 165 deletions app/(stats)/analyze/page.tsx
Original file line number Diff line number Diff line change
@@ -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
// ---------------
Expand All @@ -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<StatsData>([
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 {
Expand All @@ -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 (
<div className="grid flex-1 place-items-center">
<Message variant="error">
Expand All @@ -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 (
<>
<div className="pb-6">
<Title>Analyze</Title>
<Caption>
<Inline className="gap-4">
<Inline className="whitespace-nowrap">
<Calendar className="h-3 w-3" /> {formatDate(from)} -{' '}
{formatDate(to || today())}
</Inline>
<Inline className="whitespace-nowrap">
<Trophy className="h-3 w-3" /> {meta.tournaments} Tournaments
</Inline>
<Inline className="whitespace-nowrap">
<Rocket className="h-3 w-3" /> {meta.count.all} Squads
</Inline>
</Inline>
<StatsInfo from={from} to={to} />
</Caption>
</div>
<StatsFilter
smallSamples={!params.data.smallSamples}
dateRange={toDate(from, to)}
/>
<div className="grid grid-cols-1 gap-4 md:grid-cols-12">
<div className="md:col-span-6">
<FactionDistribution value={stats.faction} total={meta.count.all} />
</div>
<div className="md:col-span-6">
<FactionPerformance value={stats.faction} />
</div>
<div className="md:col-span-6">
<FactionVictories value={stats.faction} total={meta.tournaments} />
</div>
<div className="md:col-span-6">
<SquadSize
value={stats.squadSize}
total={meta.count.all - meta.count.unknown}
/>
</div>
<div className="col-span-full">
<ChassisDistribution value={stats.ship} />
</div>
<div className="md:col-span-6">
<PilotCostDistribution value={stats.pilotCostDistribution} />
</div>
<div className="md:col-span-6">
<PilotSkillDistribution value={stats.pilotSkillDistribution} />
</div>
<div className="col-span-full">
<PilotStats value={stats.pilot} />
</div>
<div className="col-span-full">
<UpgradeStats value={stats.upgrade} />
</div>
<div className="col-span-full">
<CompositionStats value={stats.composition} />
</div>
<div className="col-span-full pt-8 lg:col-start-2 lg:col-end-12">
<StatsHint />
</div>
</div>
<Filter>
<DateRangeFilter />
</Filter>
<Content from={from} to={to} />
</>
);
};
Expand Down
8 changes: 4 additions & 4 deletions app/(stats)/composition/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const metadata = createMetadata({
// ---------------
const create = setup<CompositionData>([composition]);

// Async content block
// Content
// ---------------
const Content = async ({ from, to }: { from: Date; to?: Date }) => {
const [squads, tournaments, count] = await Promise.all([
Expand Down Expand Up @@ -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 (
<div className="grid flex-1 place-items-center">
<Message variant="error">
Expand All @@ -73,7 +73,7 @@ const CompositionsPage = async ({ searchParams }: PageProps) => {
);
}

const { from, to } = result;
const { from, to } = params;

return (
<>
Expand Down

0 comments on commit e4f1ff1

Please sign in to comment.