diff --git a/client/public/Drone.svg b/client/public/Drone.svg deleted file mode 100644 index 66520ff..0000000 --- a/client/public/Drone.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/src/components/ui/SchedulePage/index.tsx b/client/src/components/ui/SchedulePage/index.tsx index df4bc12..3091e86 100644 --- a/client/src/components/ui/SchedulePage/index.tsx +++ b/client/src/components/ui/SchedulePage/index.tsx @@ -6,8 +6,6 @@ import EventCard from "./EventCard"; export default function SchedulePage() { return (
- -

Our next competition is:

Monday - July 9th, 2025

diff --git a/client/src/components/ui/progress.tsx b/client/src/components/ui/progress.tsx index 3b3ac7a..6031b48 100644 --- a/client/src/components/ui/progress.tsx +++ b/client/src/components/ui/progress.tsx @@ -1,68 +1,106 @@ import Image from "next/image"; -import { title } from "process"; -import * as React from "react"; +import { useEffect, useRef, useState } from "react"; + +import { getPageConfigByName } from "../../config/pages"; export default function ProgressBar({ pageName }: { pageName: string }) { - let progress = 0; - let titleName = ""; - switch (pageName) { - case "schedule": - progress = 0; - titleName = "Drone Competition Schedule"; - break; - case "format-rules": - progress = 25; - titleName = "Format Rules"; - break; - case "leaderboard": - titleName = "Leaderboard"; - progress = 50; - break; - case "sponsor-guest": - titleName = "Sponsor & Guest"; - progress = 75; - break; - } + const [progressWidth, setProgressWidth] = useState(0); + const [isAnimating, setIsAnimating] = useState(false); + const previousPageRef = useRef(""); + const previousProgressRef = useRef(0); + const isFirstRenderRef = useRef(true); + + const pageConfig = getPageConfigByName(pageName); + const progress = pageConfig?.progress || 0; + const titleName = pageConfig?.title || ""; + + useEffect(() => { + const updateProgress = () => { + let targetProgress = progress; + + if (pageName === "leaderboard") { + targetProgress = window.innerWidth >= 768 ? 90 : 80; + } + + if (isFirstRenderRef.current) { + setProgressWidth(0); + setIsAnimating(true); + setTimeout(() => { + setProgressWidth(targetProgress); + previousProgressRef.current = targetProgress; + previousPageRef.current = pageName; + isFirstRenderRef.current = false; + }, 10); + } else if (previousPageRef.current !== pageName) { + setIsAnimating(false); + setProgressWidth(previousProgressRef.current); + + setTimeout(() => { + setIsAnimating(true); + setProgressWidth(targetProgress); + previousProgressRef.current = targetProgress; + previousPageRef.current = pageName; + }, 10); + } else { + setProgressWidth(targetProgress); + previousProgressRef.current = targetProgress; + } + }; + + updateProgress(); + window.addEventListener("resize", updateProgress); + return () => window.removeEventListener("resize", updateProgress); + }, [pageName, progress]); + + useEffect(() => { + if (isAnimating) { + const timer = setTimeout(() => { + setIsAnimating(false); + }, 3000); + + return () => clearTimeout(timer); + } + }, [isAnimating]); return (
-
-
- +
+ -
+
-
+
Drone
-
+
Finish Flag
-
+
diff --git a/client/src/config/pages.ts b/client/src/config/pages.ts new file mode 100644 index 0000000..3bacb74 --- /dev/null +++ b/client/src/config/pages.ts @@ -0,0 +1,46 @@ +export interface PageConfig { + path: string; + name: string; + title: string; + progress: number; +} + +export const PAGES_CONFIG: PageConfig[] = [ + { + path: "/schedule", + name: "schedule", + title: "Drone Competition Schedule", + progress: 0, + }, + { + path: "/format-rules", + name: "format-rules", + title: "Format & Rules", + progress: 30, + }, + { + path: "/guests-sponsors", + name: "guests-sponsors", + title: "Guests & Sponsors", + progress: 60, + }, + { + path: "/leaderboard", + name: "leaderboard", + title: "Leaderboard", + progress: 80, + }, +]; + +export const getPageConfigByPath = (path: string): PageConfig | null => { + return PAGES_CONFIG.find((page) => page.path === path) || null; +}; + +export const getPageConfigByName = (name: string): PageConfig | null => { + return PAGES_CONFIG.find((page) => page.name === name) || null; +}; + +export const getPageName = (path: string): string | null => { + const config = getPageConfigByPath(path); + return config ? config.name : null; +}; diff --git a/client/src/pages/_app.tsx b/client/src/pages/_app.tsx index db622bb..9f8e9da 100644 --- a/client/src/pages/_app.tsx +++ b/client/src/pages/_app.tsx @@ -9,9 +9,12 @@ import { Plus_Jakarta_Sans, Work_Sans, } from "next/font/google"; +import { useRouter } from "next/router"; import Footer from "../components/ui/footer"; import Navbar from "../components/ui/navbar"; +import ProgressBar from "../components/ui/progress"; +import { getPageName } from "../config/pages"; const fontMontserrat = Montserrat({ subsets: ["latin"], @@ -37,6 +40,10 @@ const fontFugazOne = Fugaz_One({ const queryClient = new QueryClient(); export default function App({ Component, pageProps }: AppProps) { + const router = useRouter(); + + const currentPageName = getPageName(router.pathname); + return (
-
- -
+
+
+ {currentPageName && ( +
+ +
+ )} + +
+
diff --git a/client/src/pages/format-rules.tsx b/client/src/pages/format-rules.tsx index a764846..2d41285 100644 --- a/client/src/pages/format-rules.tsx +++ b/client/src/pages/format-rules.tsx @@ -2,7 +2,6 @@ import { NextPage } from "next"; import Head from "next/head"; import CheckList from "../components/ui/FormatRules/CheckList"; -import Navbar from "../components/ui/navbar"; import ProgressBar from "../components/ui/progress"; // Style constants definition @@ -106,9 +105,6 @@ const FormatRulesPage: NextPage = () => {
{/* Hero Section */}
- {/* ProgressBar Component replaces the title */} - - Complete guide to the 2025 WRC Drone Speed Challenge. Each match is a 3-minute 2v2 team competition with two diff --git a/client/src/pages/guests-sponsors.tsx b/client/src/pages/guests-sponsors.tsx index 671aee1..9910a2a 100644 --- a/client/src/pages/guests-sponsors.tsx +++ b/client/src/pages/guests-sponsors.tsx @@ -46,12 +46,6 @@ const SponsorsAndGuest = () => { return (
- {/* Page title */} -
-

- Guests & Sponsors -

-
{/* Special Guests & Sponsors Section */} {loading ? (

Loading...

diff --git a/client/src/pages/leaderboard.tsx b/client/src/pages/leaderboard.tsx index 6313816..19311c2 100644 --- a/client/src/pages/leaderboard.tsx +++ b/client/src/pages/leaderboard.tsx @@ -5,18 +5,6 @@ import List from "../components/ui/Leaderboard/List"; export default function LeaderboardPage() { return (
-
-

Leaderboard

-
- Progress Bar -
-
diff --git a/client/src/styles/globals.css b/client/src/styles/globals.css index dd062d3..a26a764 100644 --- a/client/src/styles/globals.css +++ b/client/src/styles/globals.css @@ -202,3 +202,12 @@ @apply mb-2 flex h-16 w-16 items-center justify-center rounded-full; } } + +@layer components { + .nav-link { + @apply text-dark transition-colors duration-200 hover:text-primary; + } + .nav-link-active { + @apply text-primary; + } +} diff --git a/client/tailwind.config.ts b/client/tailwind.config.ts index 2209d7b..688d415 100644 --- a/client/tailwind.config.ts +++ b/client/tailwind.config.ts @@ -19,6 +19,9 @@ const config = { }, }, extend: { + screens: { + lg: "1028px", + }, fontFamily: { sans: ["var(--font-sans)", ...fontFamily.sans], montserrat: ["var(--font-montserrat)", ...fontFamily.sans],