From abc441fa2f41f11b217a56f7f96f779718e3e2c7 Mon Sep 17 00:00:00 2001 From: Sebastian Sebald Date: Mon, 30 Oct 2023 22:33:55 +0100 Subject: [PATCH] remove old composition page --- .../[id]/_component/pilot-details.tsx | 121 ------------- .../[id]/_component/squad-groups.tsx | 76 -------- .../[id]/_component/trend-curve.tsx | 74 -------- app/analyze/composition/[id]/layout.tsx | 13 -- app/analyze/composition/[id]/page.tsx | 145 ---------------- app/analyze/composition/page.tsx | 162 ------------------ 6 files changed, 591 deletions(-) delete mode 100644 app/analyze/composition/[id]/_component/pilot-details.tsx delete mode 100644 app/analyze/composition/[id]/_component/squad-groups.tsx delete mode 100644 app/analyze/composition/[id]/_component/trend-curve.tsx delete mode 100644 app/analyze/composition/[id]/layout.tsx delete mode 100644 app/analyze/composition/[id]/page.tsx delete mode 100644 app/analyze/composition/page.tsx diff --git a/app/analyze/composition/[id]/_component/pilot-details.tsx b/app/analyze/composition/[id]/_component/pilot-details.tsx deleted file mode 100644 index c0b4c441..00000000 --- a/app/analyze/composition/[id]/_component/pilot-details.tsx +++ /dev/null @@ -1,121 +0,0 @@ -'use client'; - -import { Fragment, useState } from 'react'; - -import { type Ships, getPilotName } from '@/lib/get-value'; -import type { SquadCompositionStats } from '@/lib/stats/details/composition'; -import { toPercentage } from '@/lib/utils'; -import { isStandardized, upgradesToList } from '@/lib/xws'; - -import { PilotImage, Detail, Card, Switch } from '@/ui'; -import { Info } from '@/ui/icons'; - -// Props -// --------------- -export interface PilotDetailProps { - className?: string; - ships: Ships[]; - value: SquadCompositionStats['pilot']; -} - -// Components -// --------------- -export const PilotDetails = ({ className, ships, value }: PilotDetailProps) => { - const [grouped, setGrouped] = useState(true); - - const data = Object.entries(value); - - if (grouped) { - data.sort(([, a], [, b]) => { - const result = ships.indexOf(a.ship) - ships.indexOf(b.ship); - return result !== 0 ? result : b.percentile - a.percentile; - }); - } - - return ( - - - Pilots - - - - - {data.map(([pid, current]) => ( -
- -
- {getPilotName(pid)} -
-
- - - - -
-
-
- Loadout Performance -
- {isStandardized(pid) ? ( -
- Standarized Pilot. No - variations. -
- ) : ( -
- {current.upgrades.map(({ id, list, count, percentile }) => ( - -
- {toPercentage(percentile)} ({count}) -
-
- {upgradesToList(list)} -
-
- ))} -
- )} -
-
- ))} -
-
-
- ); -}; diff --git a/app/analyze/composition/[id]/_component/squad-groups.tsx b/app/analyze/composition/[id]/_component/squad-groups.tsx deleted file mode 100644 index d8bb64a3..00000000 --- a/app/analyze/composition/[id]/_component/squad-groups.tsx +++ /dev/null @@ -1,76 +0,0 @@ -'use client'; - -import { Accordion, Badge, CopyButton, Detail, Squad, Timeline } from '@/ui'; - -import { getPilotName } from '@/lib/get-value'; -import { type SquadCompositionStats } from '@/lib/stats/details/composition'; -import { formatDate } from '@/lib/utils/date.utils'; -import { toPercentage } from '@/lib/utils/math.utils'; -import { Copy } from '@/ui/icons'; - -// Props -// --------------- -export interface SquadGroupsProps { - value: SquadCompositionStats['squads']; -} - -// Component -// --------------- -export const SquadGroups = ({ value }: SquadGroupsProps) => { - const data = Object.entries(value); - data.sort(([, a], [, b]) => b.percentile - a.percentile); - - return ( - - {data.map(([id, current]) => ( - - -
- {current.items.length} -
- {id.split('.').map(getPilotName).join(', ')} -
- -
-
- - - -
- - {current.items.map(({ date, player, xws }) => ( - - - {formatDate(new Date(date))} - by {player} - - - - - Copy XWS - - - - ))} - -
-
-
- ))} -
- ); -}; diff --git a/app/analyze/composition/[id]/_component/trend-curve.tsx b/app/analyze/composition/[id]/_component/trend-curve.tsx deleted file mode 100644 index 867a8f51..00000000 --- a/app/analyze/composition/[id]/_component/trend-curve.tsx +++ /dev/null @@ -1,74 +0,0 @@ -'use client'; - -import { toPercentage } from '@/lib/utils'; -import { formatMonth } from '@/lib/utils/date.utils'; -import { linearGradientDef } from '@nivo/core'; -import { ResponsiveLine } from '@nivo/line'; - -// Props -// --------------- -export interface TrendCurveProps { - value: { - /** - * Date format YYYY-MM - */ - date: string; - count: number; - percentile: number; - }[]; -} - -// Components -// --------------- -export const TrendCurve = ({ value }: TrendCurveProps) => { - const data = value.map(({ date, percentile, count }) => ({ - x: date, - y: percentile, - count, - })); - - return ( -
- Percentile, - legendPosition: 'middle', - legendOffset: -45, - }} - pointLabel={({ y }) => toPercentage(y as number)} - enablePointLabel - enableArea - enableGridX={false} - pointSize={8} - defs={[ - linearGradientDef('gradient', [ - { offset: 0, color: '#5155b1' }, - { offset: 100, color: '#96a6e3' }, - ]), - ]} - colors="#5155b1" - fill={[{ match: '*', id: 'gradient' }]} - margin={{ top: 20, right: 30, bottom: 30, left: 60 }} - isInteractive={false} - animate={false} - /> -
- ); -}; diff --git a/app/analyze/composition/[id]/layout.tsx b/app/analyze/composition/[id]/layout.tsx deleted file mode 100644 index d539c0e8..00000000 --- a/app/analyze/composition/[id]/layout.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import type { ReactNode } from 'react'; -import { Title } from '@/ui'; - -const Layout = ({ children }: { children: ReactNode }) => ( - <> -
- Composition Details -
-
{children}
- -); - -export default Layout; diff --git a/app/analyze/composition/[id]/page.tsx b/app/analyze/composition/[id]/page.tsx deleted file mode 100644 index 84de22d4..00000000 --- a/app/analyze/composition/[id]/page.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import { compositionDetails } from '@/lib/stats/details/composition'; -import { createMetadata } from '@/lib/metadata'; -import { fromDate } from '@/lib/utils/date.utils'; -import { getFactionCount, getSquads } from '@/lib/db/squads'; -import { getShipName } from '@/lib/get-value'; -import { pointsUpdateDate } from '@/lib/config'; -import { toPercentage } from '@/lib/utils'; - -import { Card, Detail, ShipIcon } from '@/ui'; - -import { PilotDetails } from './_component/pilot-details'; -import { SquadGroups } from './_component/squad-groups'; -import { TrendCurve } from './_component/trend-curve'; - -// Config -// --------------- -export const revalidate = 21600; // 6 hours - -/** - * Opt into background revalidation. (see: https://github.com/vercel/next.js/discussions/43085) - */ -export const generateStaticParams = async () => { - const squads = await getSquads({ from: fromDate(pointsUpdateDate) }); - const compositions = new Set(); - - squads.forEach(({ composition }) => { - if (composition) { - compositions.add(composition); - } - }); - - return [...compositions].map(id => ({ - id, - })); -}; - -// Props -// --------------- -interface PageParams { - params: { - id: string; - }; -} - -// Metadata -// --------------- -export const generateMetadata = ({ params }: PageParams) => { - const ships = params.id.split('.').map(ship => getShipName(ship)); - return createMetadata({ - title: `Squad Composition: ${ships.join(', ')}`, - description: 'Take a look at what is currently flown in X-Wing!', - ogShips: params.id, - }); -}; - -// Data -// --------------- -const getCompositionStats = async (composition: string, from: Date) => { - const squads = await getSquads({ from, composition }); - const count = await getFactionCount({ from }); - return compositionDetails({ composition, squads, count }); -}; - -// Page -// --------------- -const Page = async ({ params }: PageParams) => { - const stats = await getCompositionStats( - params.id, - fromDate(pointsUpdateDate) - ); - - return ( -
- - - Overview - - - - {stats.ships.map((ship, idx) => ( -
- - - {getShipName(ship)} - -
- ))} -
- } - /> -
- - - - - -
- - - - - Trend - - - - - - - - - Squads - - - - - - - ); -}; - -export default Page; diff --git a/app/analyze/composition/page.tsx b/app/analyze/composition/page.tsx deleted file mode 100644 index b26ffa8d..00000000 --- a/app/analyze/composition/page.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import { cache } from 'react'; -import { z } from 'zod'; - -import { pointsUpdateDate } from '@/lib/config'; -import { getFactionCount, getSquads } from '@/lib/db/squads'; -import { getTournamentsCount } from '@/lib/db/tournaments'; -import { formatDate, fromDate, toDate, today } from '@/lib/utils/date.utils'; - -import { Caption, Card, Inline, Message, Title } from '@/ui'; -import { Calendar, Rocket, Trophy } from '@/ui/icons'; - -import { - CompositionFilter, - CompositionFilterProvider, - CompositionTable, -} from '@/ui/stats/composition-stats'; -import { StatsFilter } from '@/ui/stats/stats-filter'; -import { createMetadata } from '@/lib/metadata'; -import { StatsHint } from '@/ui/stats/stats-hint'; -import { setup } from '@/lib/stats'; -import { CompositionData, composition } from '@/lib/stats/module'; - -// Config -// --------------- -/** - * Segment Config (see: https://beta.nextjs.org/docs/api-reference/segment-config) - */ -export const revalidate = 21600; // 6 hours - -// Metadata -// --------------- -export const metadata = createMetadata({ - title: 'Compositions', - description: 'Take a look at what is currently flown in X-Wing!', - ogTitle: 'Squad Compositions', - ogWidth: 65, -}); - -// 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', - })); - -const create = setup([composition]); - -// 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 { - searchParams: { - from: string; - to: string; - 'small-samples': 'show' | 'hide'; - }; -} - -// Page -// --------------- -const AnalyzeCompositionPage = async ({ searchParams }: AnalyzePageProps) => { - const params = schema.safeParse(searchParams); - - if (!params.success) { - return ( -
- - Whoopsie, something went wrong! - Looks like there is an error in the given query parameters. - -
- ); - } - - 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); - - return ( - <> -
- Compositions - - - - {formatDate(from)} -{' '} - {formatDate(to || today())} - - - {meta.tournaments} Tournaments - - - {meta.count.all} Squads - - - -
- - - - -
-
- - - - - -
-
- -
-
-
- - ); -}; - -export default AnalyzeCompositionPage;