Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch drivers from API #12

Merged
merged 1 commit into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions web/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NEXT_PUBLIC_BASE_URL=http://localhost:3000
5 changes: 4 additions & 1 deletion web/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
31 changes: 11 additions & 20 deletions web/app/drivers/page.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<main>
<section className="py-16 bg-gray-50">
Expand All @@ -13,26 +19,11 @@ export default function Drivers() {
<div className="mx-auto container border-b-2 border-gray-200"></div>

<section className="container mx-auto py-12 px-4">
<h3 className="text-3xl font-semibold mb-6">2024 Drivers</h3>
<h3 className="text-3xl font-semibold mb-6">{year} Drivers</h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<Driver
name="Lewis Hamilton"
img="hamilton.jpeg"
team="Mercedes"
championships={7}
/>
<Driver
name="Max Verstappen"
img="verstappen.jpeg"
team="Red Bull Racing"
championships={2}
/>
<Driver
name="Fernando Alonso"
img="alonso.jpeg"
team="Aston Martin"
championships={2}
/>
<Suspense fallback={<DriversSkeleton />}>
<DriversComponent />
</Suspense>
</div>
</section>
</main>
Expand Down
1 change: 0 additions & 1 deletion web/app/results/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Podium } from "@/src/components/results/Podium";

export default function Results() {
return (
Expand Down
11 changes: 10 additions & 1 deletion web/next.config.mjs
Original file line number Diff line number Diff line change
@@ -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;
10 changes: 5 additions & 5 deletions web/src/components/drivers/Driver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div className="p-6 rounded-lg shadow-2xl">
<div className="bg-white flex items-center">
<img src={`/images/driver/${img}`} alt={name} className="w-16 h-16 rounded-full mr-4" />
<img src={img} width={64} height={64} alt={name} className="w-16 h-16 rounded-full mr-4" />
<div>
<h4 className="text-xl font-bold mb-2 text-gray-800">{name}</h4>
<p className="text-lg text-gray-600">Team: {team}</p>
<p className="text-lg text-gray-600">Championships: {championships}</p>
<p className="text-lg text-gray-600">Number: {number}</p>
</div>
</div>
</div>
Expand Down
26 changes: 26 additions & 0 deletions web/src/components/drivers/Drivers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { fetchDrivers } from "@/src/lib/api";
import { Driver } from "./Driver";

export async function Drivers(): Promise<JSX.Element> {

// sleep 1 sec just to show the skeleton
await new Promise((resolve) => setTimeout(resolve, 10000));

const drivers = await fetchDrivers();

return (
<>
{drivers.map((driver) => {
return (
<Driver
key={driver.driver_number}
name={driver.full_name}
img={driver.avatar}
team={driver.team_name}
number={driver.driver_number}
/>
);
})}
</>
);
}
28 changes: 28 additions & 0 deletions web/src/components/drivers/DriversSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export function DriversSkeleton(): JSX.Element {

const fakeData = (new Array(20)).fill(0);

return (
<>
{fakeData.map((_, idx) => {
return (
<div key={idx} className="p-6 rounded-lg shadow-2xl">
<div className="bg-white flex items-center">
<div className="flex items-center rounded-full justify-center w-16 h-16 mr-4 bg-gray-300 dark:bg-gray-700">
<svg className="w-6 h-6 text-gray-200 dark:text-gray-600" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 20">
<path d="M14.066 0H7v5a2 2 0 0 1-2 2H0v11a1.97 1.97 0 0 0 1.934 2h12.132A1.97 1.97 0 0 0 16 18V2a1.97 1.97 0 0 0-1.934-2ZM10.5 6a1.5 1.5 0 1 1 0 2.999A1.5 1.5 0 0 1 10.5 6Zm2.221 10.515a1 1 0 0 1-.858.485h-8a1 1 0 0 1-.9-1.43L5.6 10.039a.978.978 0 0 1 .936-.57 1 1 0 0 1 .9.632l1.181 2.981.541-1a.945.945 0 0 1 .883-.522 1 1 0 0 1 .879.529l1.832 3.438a1 1 0 0 1-.031.988Z"/>
<path d="M5 5V.13a2.96 2.96 0 0 0-1.293.749L.879 3.707A2.98 2.98 0 0 0 .13 5H5Z"/>
</svg>
</div>
<div className="w-10 flex-grow">
<p className="h-8 mb-2 bg-gray-200 rounded-md"></p>
<p className="h-2 mb-1 bg-gray-200 rounded-md"></p>
<p className="h-2 bg-gray-200 rounded-md"></p>
</div>
</div>
</div>
);
})}
</>
);
}
4 changes: 3 additions & 1 deletion web/src/components/results/Podium.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Image from "next/image";

interface PodiumProps {
title: string;
img: string;
Expand All @@ -14,7 +16,7 @@ export function Podium (props: PodiumProps): JSX.Element {
<div className="p-6 rounded-lg shadow-2xl">
<h4 className="text-xl font-bold mb-4 text-gray-700">{title}</h4>
<div className="bg-white flex items-center">
<img src={img} alt={driver} className="w-16 h-16 rounded-full mr-4" />
<Image src={img} width={64} height={64} alt={driver} className="w-16 h-16 rounded-full mr-4" />
<div>

<p className="text-lg">Driver: {driver}</p>
Expand Down
4 changes: 3 additions & 1 deletion web/src/components/teams/Team.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Image from "next/image";

interface TeamProps {
name: string;
img: string;
Expand All @@ -12,7 +14,7 @@ export function Team (props: TeamProps): JSX.Element {
return (
<div className="p-6 rounded-lg shadow-2xl">
<div className="bg-white flex items-center">
<img src={`/images/team/${img}`} alt={name} className="w-16 h-16 rounded-full mr-4" />
<Image src={`/images/team/${img}`} width={64} height={64} alt={name} className="w-16 h-16 rounded-full mr-4" />
<div>
<h4 className="text-xl font-bold mb-2 text-gray-800">{name}</h4>
<p className="text-lg text-gray-600">Team Principal: {teamPrincipal}</p>
Expand Down
39 changes: 39 additions & 0 deletions web/src/lib/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { DriverInterface } from "../types/driver";

export async function fetchJson<T>(
url: string,
reqDetails: RequestInit = {},
) : Promise<T> {

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<DriverInterface[]> {

try {

return await fetchJson<DriverInterface[]>(
`${process.env.NEXT_PUBLIC_BASE_URL}/api/drivers`
);

} catch (error) {
console.error('Unable to fetch drivers', error);
}

return [];
}
7 changes: 7 additions & 0 deletions web/src/types/driver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface DriverInterface {
driver_number: number;
full_name: string;
country_code: string;
avatar: string;
team_name: string;
}
Loading