diff --git a/public/favicon.svg b/public/favicon.svg index 6893eb1..6e5eed7 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1 +1,8 @@ - \ No newline at end of file + + Racing flag + + + + + + diff --git a/src/App.css b/src/App.css index f456afc..ab4b2a3 100644 --- a/src/App.css +++ b/src/App.css @@ -1,7 +1,30 @@ +* { + font-family: "Formula1", sans-serif; + font-weight: bold; + text-transform: uppercase; + font-style: italic; +} + body { - background-color: #272745; + /**background-color: #272745;*/ + background-color: #a6a09b; color: white; font-family: "Titillium Web", sans-serif; + margin: 0; +} + +button:hover { + background-color: #3b3b3b; +} + +.driver-filters { + display: flex; + flex-wrap: wrap; + flex-direction: row; + justify-content: center; + gap: 1rem; + margin-bottom: 1rem; + margin: 5px; } .driver-card { @@ -42,29 +65,57 @@ body { font-weight: 400; } +.driver-card { + box-shadow: #15151e 5px 5px 10px 5px; + height: 110px; +} + .content-row { display: flex; align-items: flex-start; gap: 2rem; flex-wrap: wrap; + justify-content: center; } .standing-drivers { display: flex; flex-direction: column; align-items: flex-start; + text-align: center; width: 542px; max-width: 100%; min-width: 0; } + +#header-container { + display: flex; + justify-content: center; + align-items: center; + background-color: #b5332e; + z-index: -1; + width: 100%; + height: 6vw; +} + .header { - align-self: center; + text-align: center; + color: white; + font-size: 40px; +} + +#header-container img { + height: 8vw; + width: auto; + margin-right: 10px; + transform: scaleX(-1); } .driver-detail { background-color: #15151e; border-radius: 30px; + box-shadow: #15151e 5px 5px 10px 10px; color: white; font-family: "Titillium Web", sans-serif; @@ -98,7 +149,7 @@ body { font-size: 1.1rem; font-weight: 600; cursor: pointer; - width: 130px; + width: 145px; height: 40px; } diff --git a/src/App.tsx b/src/App.tsx index 761fa82..142f2d6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ import "./App.css"; +import race_car_icon from "./assets/race_car_icon_125926.svg"; import api from "./api/api"; import { useQuery } from "@tanstack/react-query"; import { useEffect, useState } from "react"; @@ -51,10 +52,7 @@ function App() { sessionStorage.setItem("sortOrder", sortOrder); }, [sortOrder]); - const { - getDriversWithStandings, - getAllTeamStandings, - } = api(); + const { getDriversWithStandings, getAllTeamStandings } = api(); const { data: driversWithStandings = [], @@ -114,8 +112,10 @@ function App() { return ( <> -

F1 The Website

- +
+

F1 The Website

+ Race Car Icon +
toggleFavorite(driver.driver_number)} - isSelected={selectedDriver?.driver_number === driver.driver_number} - onSelect={() => selectDriverByNumber(driver.driver_number)} + onToggleFavorite={() => + toggleFavorite(driver.driver_number) + } + isSelected={ + selectedDriver?.driver_number === driver.driver_number + } + onSelect={() => + selectDriverByNumber(driver.driver_number) + } teamStanding={teamStandings.find( (team) => team.team_name === driver.team_name, )} @@ -183,7 +189,9 @@ function App() { } teamStanding={ selectedDriver - ? teamStandings.find((team) => team.team_name === selectedDriver.team_name) + ? teamStandings.find( + (team) => team.team_name === selectedDriver.team_name, + ) : undefined } teamStandingsPending={teamStandingsPending} @@ -192,7 +200,9 @@ function App() { hasNext={clampedIndex < filteredDrivers.length - 1} onPrev={() => setSelectedIndex((index) => Math.max(0, index - 1))} onNext={() => - setSelectedIndex((index) => Math.min(filteredDrivers.length - 1, index + 1)) + setSelectedIndex((index) => + Math.min(filteredDrivers.length - 1, index + 1), + ) } /> diff --git a/src/assets/race_car_icon_125926.svg b/src/assets/race_car_icon_125926.svg new file mode 100644 index 0000000..717aa3d --- /dev/null +++ b/src/assets/race_car_icon_125926.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/DriverDetail.tsx b/src/components/DriverDetail.tsx index b562bb1..780aa12 100644 --- a/src/components/DriverDetail.tsx +++ b/src/components/DriverDetail.tsx @@ -1,124 +1,141 @@ -import type { TeamStandings } from '../api/api' -import type { DriverProps } from './DriverCard' +import type { TeamStandings } from "../api/api"; +import type { DriverProps } from "./DriverCard"; // Default "avatar" used when api does not return a driver photo -const DEFAULT_AVATAR_URL = 'https://canvas.ntnu.no/images/messages/avatar-50.png' +const DEFAULT_AVATAR_URL = + "https://canvas.ntnu.no/images/messages/avatar-50.png"; interface DriverDetailProps { - isOpen: boolean; - onClose: () => void; - driver?: DriverProps; - teamStanding?: TeamStandings; - teamStandingsPending: boolean; - teamStandingsError: boolean; - isLoading: boolean; - isError: boolean; - hasPrev: boolean; - hasNext: boolean; - onPrev: () => void; - onNext: () => void; + isOpen: boolean; + onClose: () => void; + driver?: DriverProps; + teamStanding?: TeamStandings; + teamStandingsPending: boolean; + teamStandingsError: boolean; + isLoading: boolean; + isError: boolean; + hasPrev: boolean; + hasNext: boolean; + onPrev: () => void; + onNext: () => void; } export default function DriverDetail({ - isOpen, - onClose, - driver, - teamStanding, - teamStandingsPending, - teamStandingsError, - isLoading, - isError, - hasPrev, - hasNext, - onPrev, - onNext, + isOpen, + onClose, + driver, + teamStanding, + teamStandingsPending, + teamStandingsError, + isLoading, + isError, + hasPrev, + hasNext, + onPrev, + onNext, }: DriverDetailProps) { + if (!isLoading && !isError && !driver) { + return null; + } + return ( +
+ - return ( -
- - - {isLoading ? ( -

Loading driver...

- ) : isError ? ( -

Could not load driver details.

- ) : !driver ? ( -

No driver selected.

- ) : ( - <> - {driver.name} { event.currentTarget.src = DEFAULT_AVATAR_URL }} - /> + {isLoading ? ( +

Loading driver...

+ ) : isError ? ( +

Could not load driver details.

+ ) : !driver ? ( +

No driver selected.

+ ) : ( + <> + {driver.name} { + event.currentTarget.src = DEFAULT_AVATAR_URL; + }} + /> -
-

{driver.name}

- {driver.number} -
+
+

{driver.name}

+ + {driver.number} + +
-
-
- Team - {driver.team_name} -
-
+
+
+ Team + + {driver.team_name} + +
+
-
- Position - {driver.position_current || '—'} -
-
+
+ Position + + {driver.position_current || "—"} + +
+
-
- Driver points - {driver.points_current} -
-
+
+ Driver points + + {driver.points_current} + +
+
-
- Team points - - {teamStandingsPending - ? 'Loading...' - : teamStandingsError - ? 'Unavailable' - : teamStanding?.points_current ?? 'Unavailable'} - -
-
- - )} -
- - +
+ Team points + + {teamStandingsPending + ? "Loading..." + : teamStandingsError + ? "Unavailable" + : (teamStanding?.points_current ?? "Unavailable")} +
-
- ) +
+ + )} +
+ + +
+
+ ); }