Skip to content

Commit

Permalink
chore: building out constructor standings for season results
Browse files Browse the repository at this point in the history
  • Loading branch information
Lombardoc4 authored and borolepratik committed Jan 10, 2024
1 parent 0e08921 commit 7064c7c
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 84 deletions.
6 changes: 5 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ export default async function RootLayout({

return (
<html lang='en'>
<body className={clsx(inter.className, { server: server })}>
<body
className={clsx('min-h-screen px-4', inter.className, {
server: server,
})}
>
<Nav />
{children}
</body>
Expand Down
73 changes: 24 additions & 49 deletions src/app/lib/placerholder-results.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,43 @@
import { faker } from '@faker-js/faker';

import { positionEnding } from './utils';

export const DriverHeadings = [
'Pos.',
'position',
'Driver',
'Constructor',
'Points',
'Wins',
// Race Starts
// Race Finishes
// Podiums
];
export const ConstuctorHeadings = [
'Pos.',
'Constructor',
'Points',
'Drivers',
// Best Result
// DNFs
];

const formatDriver = (key: string, i: number) => {
switch (key) {
case 'Pos.':
return i + 1;
case 'Driver':
return (
<>
{faker.lorem.word()}
<br />
<span className='text-xs' suppressHydrationWarning={true}>
{faker.lorem.word()}
</span>
</>
);
case 'Points':
return faker.number.int(26);
}
};
const formatConstructor = (key: string, i: number) => {
switch (key) {
case 'Pos.':
return i + 1;
case 'Constructor':
case 'position':
return positionEnding(i + 1);
case 'Constructor.name':
return faker.lorem.word();
case 'Points':
return faker.number.int(51);
case 'Drivers':
return (
<>
{faker.lorem.word()} - {faker.number.int(26)}, {faker.lorem.word()} -{' '}
{faker.number.int(26)}
</>
);
// case 'Driver':
// return (
// <>
// {positionEnding(i + 1)}
// {" "}
// {faker.lorem.word()}
// <span className='text-xs md:hidden' suppressHydrationWarning={true}>
// <br />
// {faker.lorem.word()}
// </span>
// </>
// );
case 'points':
return faker.number.int(26);
case 'wins':
return faker.number.int(10);
}
};

export const constructorsData = Array.from({ length: 20 }, (_v, index) =>
ConstuctorHeadings.reduce(
(obj, value) => ({
...obj,
[value]: formatConstructor(value, index),
}),
{},
),
);

export const driverData = Array.from({ length: 20 }, (_v, index) =>
DriverHeadings.reduce(
(obj, value) => ({ ...obj, [value]: formatDriver(value, index) }),
Expand Down
45 changes: 45 additions & 0 deletions src/app/lib/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { faker } from '@faker-js/faker';

export const positionEnding = (position: number | string) => {
// Convert to int
position = typeof position === 'string' ? parseInt(position) : position;
// Format
if ([1, 21].includes(position)) return position + 'st';
else if ([2, 22].includes(position)) return position + 'nd';
else if ([3, 23].includes(position)) return position + 'rd';
else return position + 'th';
};

/**
* @description
* Get all possible seasons/years with results
Expand Down Expand Up @@ -55,11 +65,33 @@ export interface ISchedule {
F1ApiSupport: boolean;
}

export type IConstructorStandingsFetch = {
[key in 'position' | 'points' | 'wins']: string;
} & {
Constructor: {
name: string;
};
};
export type IConstructorStandings = {
[key in 'pos' | 'points' | 'wins' | 'name']: string;
};

interface IDataConfigs {
seasons: string[];
schedule: ISchedule[];
drivers: string[];
sessions: string[];
standings: {
// drivers: {
// position: string,
// points: string,
// wins: string,
// Constructor?: {
// name: string,
// }
// }[],
constructors: IConstructorStandingsFetch[];
};
}

const dataConfig: IDataConfigs = {
Expand Down Expand Up @@ -98,6 +130,19 @@ const dataConfig: IDataConfigs = {
'Drive 5',
],
sessions: ['Practice 1', 'Practice 2', 'Practice 3', 'Qualifying', 'Race'],
standings: {
// drivers: {

// },
constructors: Array.from(Array(10).keys()).map(() => ({
position: faker.number.int(20).toString(),
points: faker.number.int(25).toString(),
wins: faker.number.int(10).toString(),
Constructor: {
name: faker.person.middleName(),
},
})),
},
};

export const fetchAPI = async (endpoint: string) => {
Expand Down
1 change: 0 additions & 1 deletion src/app/results/RaceResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ const WinterTesting = ({ data }: { data: ISchedule }) => {

export const RaceSchedule = () => {
const [races] = useAtom(seasonRacesAtom);
// console.log('races', races)

const winterTesting = useMemo(
() => races.find((race) => race.EventFormat === 'testing'),
Expand Down
77 changes: 62 additions & 15 deletions src/app/results/SeasonResults.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,78 @@
'use client';

import { useAtom } from 'jotai';

import { constructorStandingsAtom, fetchStandings } from '@/atoms/results';

import { RaceSchedule } from './RaceResults';
import {
constructorsData,
ConstuctorHeadings,
driverData,
DriverHeadings,
} from '../lib/placerholder-results';
import { driverData, DriverHeadings } from '../lib/placerholder-results';
import { IConstructorStandings, positionEnding } from '../lib/utils';
import { Table } from '../ui/Table';
import { Tabs } from '../ui/Tabs';

const ConstuctorHeadings = ['position', 'points', 'wins', 'name'];

const ConstructorCard = ({ data }: { data: IConstructorStandings }) => (
<div className='card overflow-hidden bg-base-100 shadow-xl'>
<div className='card-body px-0 pb-4 pt-2'>
<h3 className='card-title max-w-64'>
{positionEnding(data.pos)} {data.name}
</h3>
<div className='flex'>
<p className='flex-1'>
Points:
<br />
{data.points}
</p>
<p className='flex-1'>
Wins:
<br />
{data.wins}
</p>
</div>
</div>
</div>
);

const ConstructorResults = () => {
const [constructorStandings] = useAtom(constructorStandingsAtom);
useAtom(fetchStandings);

return (
<>
<div className='mt-8 grid gap-8 lg:hidden'>
{constructorStandings.map((constructor) => (
<ConstructorCard key={constructor.name} data={constructor} />
))}
</div>
<div className='hidden lg:block'>
<Table
key='Constructors Championship'
headings={ConstuctorHeadings}
data={constructorStandings}
/>
</div>
</>
);
};

const tabHeaders = ['Races', 'Drivers', 'Constructors'];
const tabs = [
<RaceSchedule key='Race Results' />,

<div key='Drivers Championship' className='rounded bg-base-100 p-4'>
<Table headings={DriverHeadings} data={driverData} />
</div>,
<div key='Constructors Championship' className='rounded bg-base-100 p-4'>
<Table headings={ConstuctorHeadings} data={constructorsData} />,
</div>,
<Table
key='Drivers Championship'
headings={DriverHeadings}
data={driverData}
/>,
];

export default function ResultsPage() {
return (
<main className='min-h-screen'>
<Tabs headers={tabHeaders} containers={tabs} />
<main>
<Tabs
headers={tabHeaders}
containers={[...tabs, <ConstructorResults key='ConstructorResults' />]}
/>
</main>
);
}
2 changes: 1 addition & 1 deletion src/app/results/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function ResultsLayout({
}) {
return (
<>
<div className='container mx-auto mb-4 rounded-box bg-base-300 p-4 lg:my-4'>
<div className='container mx-auto mb-4 rounded-box bg-base-300 p-4 md:my-4'>
<MainFilters />
</div>
{children}
Expand Down
22 changes: 15 additions & 7 deletions src/app/ui/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@

import { Fragment } from 'react';

interface ITable {
title?: string;
export interface IStanding {
headings: string[];
data: { [key: string]: React.ReactNode }[];
}

interface ITable extends IStanding {
title?: string;
// headings: string[];
}

export const Table = ({ title, headings, data }: ITable) => {
if (data.length <= 0 && headings.length <= 0) return;

const Title = title && <h2 className='text-xl'>{title}</h2>;

return (
<>
<div className='flex-1 rounded-box bg-base-100 p-4'>
{Title}
<div className='overflow-x-auto'>
<table className='table'>
Expand Down Expand Up @@ -45,20 +49,24 @@ export const Table = ({ title, headings, data }: ITable) => {
{headings.map(
(key) =>
row && (
<td key={key} suppressHydrationWarning={true}>
<td
key={key}
suppressHydrationWarning={true}
className='w-fit'
>
{row[key]}
</td>
),
)}
<th>
{/* <th>
<button className='btn btn-ghost btn-xs'>details</button>
</th>
</th> */}
</tr>
</Fragment>
))}
</tbody>
</table>
</div>
</>
</div>
);
};
Loading

0 comments on commit 7064c7c

Please sign in to comment.