diff --git a/js/src/app/duel/_components/current/DuelTimer.tsx b/js/src/app/duel/_components/current/DuelTimer.tsx
new file mode 100644
index 000000000..da8929f1c
--- /dev/null
+++ b/js/src/app/duel/_components/current/DuelTimer.tsx
@@ -0,0 +1,43 @@
+import { Text } from "@mantine/core";
+import { useState, useEffect } from "react";
+
+interface DuelTimerProps {
+ endTime: number; // milliseconds
+}
+
+const DuelTimer = ({ endTime }: DuelTimerProps) => {
+ const getTimeRemaining = () => {
+ const total = endTime - Date.now();
+ const seconds = Math.floor((total / 1000) % 60);
+ const minutes = Math.floor((total / 1000 / 60) % 60);
+ if (total <= 0) {
+ return {
+ minutes: 0,
+ seconds: 0,
+ };
+ }
+ return {
+ minutes,
+ seconds,
+ };
+ };
+
+ const [timeLeft, setTimeLeft] = useState(() => getTimeRemaining());
+ useEffect(() => {
+ const timer = setInterval(() => {
+ setTimeLeft(getTimeRemaining());
+ }, 1);
+
+ return () => clearInterval(timer);
+ });
+
+ return (
+
+
+ {timeLeft.minutes}:{timeLeft.seconds.toString().padStart(2, "0")}
+
+
+ );
+};
+
+export default DuelTimer;
diff --git a/js/src/lib/router.tsx b/js/src/lib/router.tsx
index cbb99e497..d05d5835b 100644
--- a/js/src/lib/router.tsx
+++ b/js/src/lib/router.tsx
@@ -1,6 +1,7 @@
import AdminPage from "@/app/admin/admin.page";
import ClubSignUp from "@/app/club/[clubSlug]/ClubSignUp.page";
import DashboardPage from "@/app/dashboard/Dashboard.page";
+import DuelTimer from "@/app/duel/_components/current/DuelTimer";
import DuelPage from "@/app/duel/[lobbyCode]/Duel.page";
import CurrentDuelPage from "@/app/duel/current/CurrentDuel.page";
import PartyEntryPage from "@/app/duel/PartyEntry.page";
@@ -239,4 +240,13 @@ export const router = createBrowserRouter([
),
errorElement: ,
},
+ {
+ path: "/timer",
+ element: (
+
+
+
+ ),
+ errorElement: ,
+ },
]);
diff --git a/pom.xml b/pom.xml
index 11b7fe7c3..968e110d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -306,4 +306,4 @@
-
+
\ No newline at end of file