Files
muzak/frontend/src/app/mobile-voting/page.tsx
T
2025-08-15 18:30:57 +02:00

159 lines
4.5 KiB
TypeScript

"use client";
import { Nunito } from "next/font/google";
import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useAuth } from "react-oidc-context";
import { getUser } from "muzak/data/fetcher";
import Image from "next/image";
import getSessionId from "muzak/data/session";
import { useSession } from "muzak/contexts/SessionContext";
import Router from "next/router";
const nunito = Nunito({
weight: "900",
subsets: ["latin"],
});
export default function MobileVoting() {
const [vote, setVote] = useState(0.5);
const [noHighlight, setNoHighlight] = useState(false);
const [yesHighlight, setYesHighlight] = useState(false);
const auth = useAuth();
const router = useRouter();
const { sessionId, setSessionId } = useSession();
const [sessionSocket, setSessionSocket] = useState<WebSocket | null>(null);
async function waitForOpenSocket() {
await new Promise<void>((resolve) => {
const interval = setInterval(() => {
console.log("Checking socket state...");
if (sessionSocket?.readyState === WebSocket.OPEN) {
clearInterval(interval);
resolve();
}
}, 1000);
});
}
const user = getUser();
async function connect() {
console.log(`ik ben ${user.profile.nickname}`);
console.log(sessionSocket);
console.log(sessionSocket?.readyState);
await waitForOpenSocket();
console.log("socket is open");
sessionSocket.send(
JSON.stringify({
action: "login",
userr: user.profile.nickname,
token: user.access_token,
}),
);
}
// Initialize WebSocket connection when sessionId changes
useEffect(() => {
if (sessionId) {
console.log("Socket session ID:", sessionId);
const socket = new WebSocket(
`${process.env.NEXT_PUBLIC_WS_HOST}/voting/session/${sessionId}/`,
);
setSessionSocket(socket);
//setTimeout(() => connect(), 2000);
}
}, [sessionId]);
useEffect(() => {
if (sessionSocket) {
connect();
}
}, [sessionSocket]);
async function setSession() {
const id = await getSessionId();
setSessionId(id);
console.log("Session ID:", id);
}
useEffect(() => {
if (!auth.isLoading && !auth.error && auth.isAuthenticated) {
setSession();
} else if (!auth.isLoading && !auth.isAuthenticated) {
router.push("/");
}
}, [auth]);
useEffect(() => {
if (sessionSocket?.readyState == WebSocket.OPEN) {
sessionSocket.send(
JSON.stringify({
action: "vote",
token: user.access_token,
points: vote,
}),
);
}
}, [vote]);
return (
<main className="m-3 h-screen rounded bg-blue-950/80 p-8 sm:p-14 md:p-20">
<div className="flex flex-row items-center justify-between gap-8 rounded-md">
<button
className={`flex aspect-square w-1/2 max-w-[200px] items-center rounded bg-black/20 p-0 text-center font-bold text-white ${noHighlight ? "ring-5 ring-amber-400" : "ring-0 ring-black/20"}`}
onClick={() => {
setYesHighlight(false);
setNoHighlight(true);
setVote(0.0);
}}
>
{noHighlight ? (
<Image
src="/no-cat.webp"
alt="icon"
className="h-full w-full rounded object-contain"
width={200}
height={200}
/>
) : (
<Image
src="/no-cat-static.gif"
alt="icon"
className="h-full w-full rounded object-contain grayscale filter"
width={200}
height={200}
/>
)}
</button>
<button
className={`flex aspect-square w-1/2 max-w-[200px] items-center rounded bg-black/20 p-0 text-center font-bold text-white ${yesHighlight ? "ring-5 ring-amber-400" : "ring-0 ring-black/20"}`}
onClick={() => {
setYesHighlight(true);
setNoHighlight(false);
setVote(1.0);
}}
>
{yesHighlight ? (
<Image
src="/yes-cat.webp"
alt="icon"
className="h-full w-full rounded object-contain"
width={200}
height={200}
/>
) : (
<Image
src="/yes-cat-static2.gif"
alt="icon"
className="h-full w-full rounded object-contain grayscale filter"
width={200}
height={200}
/>
)}
</button>
</div>
</main>
);
}