diff --git a/web/.env b/web/.env new file mode 100644 index 0000000..629a336 --- /dev/null +++ b/web/.env @@ -0,0 +1 @@ +NEXT_PUBLIC_BASE_URL=http://localhost:3000 \ No newline at end of file diff --git a/web/.eslintrc.json b/web/.eslintrc.json index 3722418..1a1ad7a 100644 --- a/web/.eslintrc.json +++ b/web/.eslintrc.json @@ -1,3 +1,6 @@ { - "extends": ["next/core-web-vitals", "next/typescript"] + "extends": ["next/core-web-vitals", "next/typescript"], + "rules": { + "@next/next/no-img-element": "off" + } } diff --git a/web/app/drivers/page.tsx b/web/app/drivers/page.tsx index cb47f5a..ec6e575 100644 --- a/web/app/drivers/page.tsx +++ b/web/app/drivers/page.tsx @@ -1,6 +1,12 @@ -import { Driver } from "@/src/components/drivers/Driver"; +import { Suspense } from "react"; + +import { Drivers as DriversComponent } from "@/src/components/drivers/Drivers"; +import { DriversSkeleton } from "@/src/components/drivers/DriversSkeleton"; export default function Drivers() { + + const year = (new Date()).getFullYear(); + return (
@@ -13,26 +19,11 @@ export default function Drivers() {
-

2024 Drivers

+

{year} Drivers

- - - + }> + +
diff --git a/web/app/results/page.tsx b/web/app/results/page.tsx index 8816ad0..6326e19 100644 --- a/web/app/results/page.tsx +++ b/web/app/results/page.tsx @@ -1,4 +1,3 @@ -import { Podium } from "@/src/components/results/Podium"; export default function Results() { return ( diff --git a/web/next.config.mjs b/web/next.config.mjs index 4678774..adb44b3 100644 --- a/web/next.config.mjs +++ b/web/next.config.mjs @@ -1,4 +1,13 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + rewrites: async () => { + return [ + { + source: '/api/:path*', + destination: 'http://api:8080/:path*', + }, + ]; + }, +}; export default nextConfig; diff --git a/web/src/components/drivers/Driver.tsx b/web/src/components/drivers/Driver.tsx index d5da93c..eb99024 100644 --- a/web/src/components/drivers/Driver.tsx +++ b/web/src/components/drivers/Driver.tsx @@ -2,21 +2,21 @@ interface DriverProps { name: string; img: string; team: string; - championships: number + number: number } -export function Driver (props: DriverProps): JSX.Element { +export function Driver(props: DriverProps): JSX.Element { - const { name, img, team, championships } = props; + const { name, img, team, number } = props; return (
- {name} + {name}

{name}

Team: {team}

-

Championships: {championships}

+

Number: {number}

diff --git a/web/src/components/drivers/Drivers.tsx b/web/src/components/drivers/Drivers.tsx new file mode 100644 index 0000000..d8fd215 --- /dev/null +++ b/web/src/components/drivers/Drivers.tsx @@ -0,0 +1,26 @@ +import { fetchDrivers } from "@/src/lib/api"; +import { Driver } from "./Driver"; + +export async function Drivers(): Promise { + + // sleep 1 sec just to show the skeleton + await new Promise((resolve) => setTimeout(resolve, 10000)); + + const drivers = await fetchDrivers(); + + return ( + <> + {drivers.map((driver) => { + return ( + + ); + })} + + ); +} \ No newline at end of file diff --git a/web/src/components/drivers/DriversSkeleton.tsx b/web/src/components/drivers/DriversSkeleton.tsx new file mode 100644 index 0000000..db81ed4 --- /dev/null +++ b/web/src/components/drivers/DriversSkeleton.tsx @@ -0,0 +1,28 @@ +export function DriversSkeleton(): JSX.Element { + + const fakeData = (new Array(20)).fill(0); + + return ( + <> + {fakeData.map((_, idx) => { + return ( +
+
+
+ +
+
+

+

+

+
+
+
+ ); + })} + + ); +} \ No newline at end of file diff --git a/web/src/components/results/Podium.tsx b/web/src/components/results/Podium.tsx index d047125..990a1af 100644 --- a/web/src/components/results/Podium.tsx +++ b/web/src/components/results/Podium.tsx @@ -1,3 +1,5 @@ +import Image from "next/image"; + interface PodiumProps { title: string; img: string; @@ -14,7 +16,7 @@ export function Podium (props: PodiumProps): JSX.Element {

{title}

- {driver} + {driver}

Driver: {driver}

diff --git a/web/src/components/teams/Team.tsx b/web/src/components/teams/Team.tsx index 467228a..92d6464 100644 --- a/web/src/components/teams/Team.tsx +++ b/web/src/components/teams/Team.tsx @@ -1,3 +1,5 @@ +import Image from "next/image"; + interface TeamProps { name: string; img: string; @@ -12,7 +14,7 @@ export function Team (props: TeamProps): JSX.Element { return (
- {name} + {name}

{name}

Team Principal: {teamPrincipal}

diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts new file mode 100644 index 0000000..f13f464 --- /dev/null +++ b/web/src/lib/api.ts @@ -0,0 +1,39 @@ +import { DriverInterface } from "../types/driver"; + +export async function fetchJson( + url: string, + reqDetails: RequestInit = {}, +) : Promise { + + const defaultHeaders = { + Accept: "application/json", + Authorization: "Basic Z286YXBp", + }; + + reqDetails.headers = { + ... defaultHeaders, + ...(reqDetails.headers ?? {}), + } + + const response = await fetch( + url, + reqDetails + ); + + return await response.json(); +} + +export async function fetchDrivers(): Promise { + + try { + + return await fetchJson( + `${process.env.NEXT_PUBLIC_BASE_URL}/api/drivers` + ); + + } catch (error) { + console.error('Unable to fetch drivers', error); + } + + return []; +} \ No newline at end of file diff --git a/web/src/types/driver.ts b/web/src/types/driver.ts new file mode 100644 index 0000000..2cacc51 --- /dev/null +++ b/web/src/types/driver.ts @@ -0,0 +1,7 @@ +export interface DriverInterface { + driver_number: number; + full_name: string; + country_code: string; + avatar: string; + team_name: string; +} \ No newline at end of file