Fixed all the build errors and fixed participation

This commit is contained in:
boragenel 2025-01-23 12:00:07 +03:00
parent 74bc8014e9
commit 505fb56df8
9 changed files with 763 additions and 738 deletions

View file

@ -42,7 +42,7 @@ const [gameSlug, setGameSlug] = useState("");
const [thumbnailUrl, setThumbnailUrl] = useState(""); const [thumbnailUrl, setThumbnailUrl] = useState("");
const [authorSearch, setAuthorSearch] = useState(""); const [authorSearch, setAuthorSearch] = useState("");
const [selectedAuthors, setSelectedAuthors] = useState<Array<{id: number, name: string}>>([]); const [selectedAuthors, setSelectedAuthors] = useState<Array<{id: number, name: string}>>([]);
const [searchResults, setSearchResults] = useState([]); const [searchResults, setSearchResults] = useState<Array<{ id: number; name: string }>>([]);
// Add this function to handle author search // Add this function to handle author search
const handleAuthorSearch = async (query: string) => { const handleAuthorSearch = async (query: string) => {

View file

@ -19,6 +19,7 @@ import Select, { MultiValue, StylesConfig } from "react-select";
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";
import Timers from "@/components/timers"; import Timers from "@/components/timers";
import Streams from "@/components/streams"; import Streams from "@/components/streams";
import { UserType } from "@/types/UserType";
export default function CreatePostPage() { export default function CreatePostPage() {
const [title, setTitle] = useState(""); const [title, setTitle] = useState("");
@ -306,7 +307,7 @@ export default function CreatePostPage() {
</Button> </Button>
</div> </div>
</Form> </Form>
<div class="flex flex-col gap-4 px-8 items-end"> <div className="flex flex-col gap-4 px-8 items-end">
<Timers /> <Timers />
<Streams /> <Streams />
</div> </div>

View file

@ -40,7 +40,7 @@ import { useTheme } from "next-themes";
type EditorProps = { type EditorProps = {
content: string; content: string;
setContent: (content: string) => void; setContent: (content: string) => void;
gameEditor: boolean; gameEditor?: boolean;
}; };
const limit = 32767; const limit = 32767;

View file

@ -1,286 +1,295 @@
"use client"; "use client";
// import React, { useState, useEffect, useCallback } from "react"; import React, { useState, useEffect, useCallback } from "react";
// import { getCookie } from "@/helpers/cookie"; import { getCookie } from "@/helpers/cookie";
// import { import {
// getCurrentJam, getCurrentJam,
// hasJoinedCurrentJam, hasJoinedCurrentJam,
// ActiveJamResponse, ActiveJamResponse,
// } from "@/helpers/jam"; joinJam
} from "@/helpers/jam";
import {ThemeType} from "@/types/ThemeType";
export default function ThemeSlaughter() { export default function ThemeSlaughter() {
// const [randomTheme, setRandomTheme] = useState(null); const [randomTheme, setRandomTheme] = useState<ThemeType | null>(null);
// const [votedThemes, setVotedThemes] = useState([]); const [votedThemes, setVotedThemes] = useState<ThemeType[]>([]);
// const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
// const [token, setToken] = useState<string | null>(null); const [token, setToken] = useState<string | null>(null);
// const [hasJoined, setHasJoined] = useState<boolean>(false); const [hasJoined, setHasJoined] = useState<boolean>(false);
// const [activeJamResponse, setActiveJam] = useState<ActiveJamResponse | null>( const [activeJamResponse, setActiveJam] = useState<ActiveJamResponse | null>(
// null null
// ); );
// const [phaseLoading, setPhaseLoading] = useState(true); const [phaseLoading, setPhaseLoading] = useState(true);
// // Fetch token on the client side // Fetch token on the client side
// useEffect(() => { useEffect(() => {
// const fetchedToken = getCookie("token"); const fetchedToken = getCookie("token");
// setToken(fetchedToken); setToken(fetchedToken);
// }, []); }, []);
// // Fetch the current jam phase using helpers/jam // Fetch the current jam phase using helpers/jam
// useEffect(() => { useEffect(() => {
// const fetchCurrentJamPhase = async () => { const fetchCurrentJamPhase = async () => {
// try { try {
// const activeJam = await getCurrentJam(); const activeJam = await getCurrentJam();
// setActiveJam(activeJam); // Set active jam details setActiveJam(activeJam); // Set active jam details
// } catch (error) { } catch (error) {
// console.error("Error fetching current jam:", error); console.error("Error fetching current jam:", error);
// } finally { } finally {
// setPhaseLoading(false); // Stop loading when phase is fetched setPhaseLoading(false); // Stop loading when phase is fetched
// } }
// }; };
// fetchCurrentJamPhase(); fetchCurrentJamPhase();
// }, []); }, []);
// // Fetch a random theme // Fetch a random theme
// const fetchRandomTheme = useCallback(async () => { const fetchRandomTheme = useCallback(async () => {
// if (!token) return; // Wait until token is available if (!token) return; // Wait until token is available
// if (!activeJamResponse) return; if (!activeJamResponse) return;
// if ( if (
// activeJamResponse && activeJamResponse &&
// activeJamResponse.jam && activeJamResponse.jam &&
// activeJamResponse.phase != "Survival" activeJamResponse.phase != "Survival"
// ) { ) {
// return ( return (
// <div> <div>
// <h1>It&apos;s not Theme Survival phase.</h1> <h1>It&apos;s not Theme Survival phase.</h1>
// </div> </div>
// ); );
// } }
// try { try {
// const response = await fetch( const response = await fetch(
// process.env.NEXT_PUBLIC_MODE === "PROD" process.env.NEXT_PUBLIC_MODE === "PROD"
// ? "https://d2jam.com/api/v1/themes/random" ? "https://d2jam.com/api/v1/themes/random"
// : "http://localhost:3005/api/v1/themes/random", : "http://localhost:3005/api/v1/themes/random",
// { {
// headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
// credentials: "include", credentials: "include",
// } }
// ); );
// if (response.ok) { if (response.ok) {
// const data = await response.json(); const data = await response.json();
// setRandomTheme(data); setRandomTheme(data);
// } else { } else {
// console.error("Failed to fetch random theme."); console.error("Failed to fetch random theme.");
// } }
// } catch (error) { } catch (error) {
// console.error("Error fetching random theme:", error); console.error("Error fetching random theme:", error);
// } }
// }, [activeJamResponse, token]); }, [activeJamResponse, token]);
// // Fetch voted themes // Fetch voted themes
// const fetchVotedThemes = useCallback(async () => { const fetchVotedThemes = useCallback(async () => {
// if (!token) return; // Wait until token is available if (!token) return; // Wait until token is available
// try { try {
// const response = await fetch( const response = await fetch(
// process.env.NEXT_PUBLIC_MODE === "PROD" process.env.NEXT_PUBLIC_MODE === "PROD"
// ? "https://d2jam.com/api/v1/themes/voteSlaughter" ? "https://d2jam.com/api/v1/themes/voteSlaughter"
// : "http://localhost:3005/api/v1/themes/voteSlaughter", : "http://localhost:3005/api/v1/themes/voteSlaughter",
// { {
// headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
// credentials: "include", credentials: "include",
// } }
// ); );
// if (response.ok) { if (response.ok) {
// const data = await response.json(); const data = await response.json();
// setVotedThemes(data); setVotedThemes(data);
// } else { } else {
// console.error("Failed to fetch voted themes."); console.error("Failed to fetch voted themes.");
// } }
// } catch (error) { } catch (error) {
// console.error("Error fetching voted themes:", error); console.error("Error fetching voted themes:", error);
// } }
// }, [token]); }, [token]);
// // Handle voting // Handle voting
// const handleVote = async (voteType: string) => { const handleVote = async (voteType: string) => {
// if (!randomTheme) return; if (!randomTheme) return;
// setLoading(true); setLoading(true);
// try { try {
// const response = await fetch( const response = await fetch(
// process.env.NEXT_PUBLIC_MODE === "PROD" process.env.NEXT_PUBLIC_MODE === "PROD"
// ? "https://d2jam.com/api/v1/themes/voteSlaughter" ? "https://d2jam.com/api/v1/themes/voteSlaughter"
// : "http://localhost:3005/api/v1/themes/voteSlaughter", : "http://localhost:3005/api/v1/themes/voteSlaughter",
// { {
// method: "POST", method: "POST",
// headers: { headers: {
// "Content-Type": "application/json", "Content-Type": "application/json",
// Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
// }, },
// credentials: "include", credentials: "include",
// body: JSON.stringify({ body: JSON.stringify({
// suggestionId: randomTheme.id, suggestionId: randomTheme.id,
// voteType, voteType,
// }), }),
// } }
// ); );
// if (response.ok) { if (response.ok) {
// // Refresh data after voting // Refresh data after voting
// fetchRandomTheme(); fetchRandomTheme();
// fetchVotedThemes(); fetchVotedThemes();
// } else { } else {
// console.error("Failed to submit vote."); console.error("Failed to submit vote.");
// } }
// } catch (error) { } catch (error) {
// console.error("Error submitting vote:", error); console.error("Error submitting vote:", error);
// } finally { } finally {
// setLoading(false); setLoading(false);
// } }
// }; };
// // Handle resetting a vote from the grid // Handle resetting a vote from the grid
// const handleResetVote = async (themeId: number) => { const handleResetVote = async (themeId: number) => {
// try { try {
// setRandomTheme(votedThemes.find((theme) => theme.id === themeId)); const theme = votedThemes.find((theme) => theme.id === themeId);
// setVotedThemes((prev) => if (theme) {
// prev.map((theme) => setRandomTheme(theme);
// theme.id === themeId ? { ...theme, slaughterScore: 0 } : theme setVotedThemes((prev) =>
// ) prev.map((t) =>
// ); t.id === themeId ? { ...t, slaughterScore: 0 } : t
// } catch (error) { )
// console.error("Error resetting vote:", error); );
// } }
// }; } catch (error) {
console.error("Error resetting vote:", error);
}
};
// useEffect(() => { useEffect(() => {
// if (token && activeJamResponse?.phase === "Survival") { if (token && activeJamResponse?.phase === "Survival") {
// fetchRandomTheme(); fetchRandomTheme();
// fetchVotedThemes(); fetchVotedThemes();
// } }
// }, [token, activeJamResponse, fetchRandomTheme, fetchVotedThemes]); }, [token, activeJamResponse, fetchRandomTheme, fetchVotedThemes]);
// useEffect(() => { useEffect(() => {
// const init = async () => { const init = async () => {
// const joined = await hasJoinedCurrentJam(); const joined = await hasJoinedCurrentJam();
// setHasJoined(joined); setHasJoined(joined);
// setLoading(false); setLoading(false);
// }; };
// init(); init();
// }, []); }, []);
// if (phaseLoading || loading) { if (phaseLoading || loading) {
// return <div>Loading...</div>; return <div>Loading...</div>;
// } }
// if (!hasJoined) { if (!hasJoined) {
// return ( return (
// <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen"> <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen">
// <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6"> <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6">
// Join the Jam First Join the Jam First
// </h1> </h1>
// <p className="text-gray-600 dark:text-gray-400"> <p className="text-gray-600 dark:text-gray-400">
// You need to join the current jam before you can join Theme Survival. You need to join the current jam before you can join Theme Survival.
// </p> </p>
// <button <button
// onClick={() => joinJam(activeJamResponse?.jam?.id)} onClick={() => {
// className="mt-4 px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600" if (activeJamResponse?.jam?.id !== undefined) {
// > joinJam(activeJamResponse.jam.id);
// Join Jam }
// </button> }}
// </div> className="mt-4 px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600"
// ); >
// } Join Jam
</button>
</div>
);
}
// // Render message if not in Theme Slaughter phase // Render message if not in Theme Slaughter phase
// if (activeJamResponse?.phase !== "Survival") { if (activeJamResponse?.phase !== "Survival") {
// return ( return (
// <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen"> <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen">
// <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6"> <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6">
// Not in Theme Slaughter Phase Not in Theme Slaughter Phase
// </h1> </h1>
// <p className="text-gray-600 dark:text-gray-400"> <p className="text-gray-600 dark:text-gray-400">
// The current phase is{" "} The current phase is{" "}
// <strong>{activeJamResponse?.phase || "Unknown"}</strong>. Please come <strong>{activeJamResponse?.phase || "Unknown"}</strong>. Please come
// back during the Theme Slaughter phase. back during the Theme Slaughter phase.
// </p> </p>
// </div> </div>
// ); );
// } }
// const loggedIn = getCookie("token"); const loggedIn = getCookie("token");
// if (!loggedIn) { if (!loggedIn) {
// return <div>Sign in to be able to join the Theme Survival</div>; return <div>Sign in to be able to join the Theme Survival</div>;
// } }
// return ( return (
// <div className="flex h-screen"> <div className="flex h-screen">
// {/* Left Side */} {/* Left Side */}
// <div className="w-1/2 p-6 bg-gray-100 dark:bg-gray-800 flex flex-col justify-start items-center"> <div className="w-1/2 p-6 bg-gray-100 dark:bg-gray-800 flex flex-col justify-start items-center">
// {randomTheme ? ( {randomTheme ? (
// <> <>
// <h2 className="text-2xl font-bold text-gray-800 dark:text-white mb-4"> <h2 className="text-2xl font-bold text-gray-800 dark:text-white mb-4">
// {randomTheme.suggestion} {randomTheme.suggestion}
// </h2> </h2>
// <div className="flex gap-4"> <div className="flex gap-4">
// <button <button
// onClick={() => handleVote("YES")} onClick={() => handleVote("YES")}
// className="px-6 py-3 bg-green-500 text-white font-bold rounded-lg hover:bg-green-600" className="px-6 py-3 bg-green-500 text-white font-bold rounded-lg hover:bg-green-600"
// disabled={loading} disabled={loading}
// > >
// YES YES
// </button> </button>
// <button <button
// onClick={() => handleVote("NO")} onClick={() => handleVote("NO")}
// className="px-6 py-3 bg-red-500 text-white font-bold rounded-lg hover:bg-red-600" className="px-6 py-3 bg-red-500 text-white font-bold rounded-lg hover:bg-red-600"
// disabled={loading} disabled={loading}
// > >
// NO NO
// </button> </button>
// <button <button
// onClick={() => handleVote("SKIP")} onClick={() => handleVote("SKIP")}
// className="px-6 py-3 bg-gray-500 text-white font-bold rounded-lg hover:bg-gray-600" className="px-6 py-3 bg-gray-500 text-white font-bold rounded-lg hover:bg-gray-600"
// disabled={loading} disabled={loading}
// > >
// SKIP SKIP
// </button> </button>
// </div> </div>
// </> </>
// ) : ( ) : (
// <p className="text-gray-600 dark:text-gray-400"> <p className="text-gray-600 dark:text-gray-400">
// No themes available. No themes available.
// </p> </p>
// )} )}
// </div> </div>
// {/* Right Side */} {/* Right Side */}
// <div className="w-1/2 p-6 bg-white dark:bg-gray-900 overflow-y-auto"> <div className="w-1/2 p-6 bg-white dark:bg-gray-900 overflow-y-auto">
// <h3 className="text-xl font-bold text-gray-800 dark:text-white mb-4"> <h3 className="text-xl font-bold text-gray-800 dark:text-white mb-4">
// Your Votes Your Votes
// </h3> </h3>
// <div className="grid grid-cols-4 gap-4"> <div className="grid grid-cols-4 gap-4">
// {votedThemes.map((theme) => ( {votedThemes.map((theme) => (
// <div <div
// key={theme.id} key={theme.id}
// onClick={() => handleResetVote(theme.id)} onClick={() => handleResetVote(theme.id)}
// className={`p-4 rounded-lg cursor-pointer ${ className={`p-4 rounded-lg cursor-pointer ${
// theme.slaughterScore > 0 theme.slaughterScore > 0
// ? "bg-green-500 text-white" ? "bg-green-500 text-white"
// : theme.slaughterScore < 0 : theme.slaughterScore < 0
// ? "bg-red-500 text-white" ? "bg-red-500 text-white"
// : "bg-gray-300 text-black" : "bg-gray-300 text-black"
// }`} }`}
// > >
// {theme.suggestion} {theme.suggestion}
// </div> </div>
// ))} ))}
// </div> </div>
// </div> </div>
// </div> </div>
// ); );
return <></>; return <></>;
} }

View file

@ -1,282 +1,287 @@
"use client"; "use client";
// import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
// import { getCookie } from "@/helpers/cookie"; import { getCookie } from "@/helpers/cookie";
// import { import {
// getCurrentJam, getCurrentJam,
// hasJoinedCurrentJam, hasJoinedCurrentJam,
// ActiveJamResponse, ActiveJamResponse,
// } from "@/helpers/jam"; } from "@/helpers/jam";
import { ThemeType } from "@/types/ThemeType";
import { joinJam } from "@/helpers/jam";
export default function ThemeSuggestions() { export default function ThemeSuggestions() {
// const [suggestion, setSuggestion] = useState(""); const [suggestion, setSuggestion] = useState("");
// const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
// const [successMessage, setSuccessMessage] = useState(""); const [successMessage, setSuccessMessage] = useState("");
// const [errorMessage, setErrorMessage] = useState(""); const [errorMessage, setErrorMessage] = useState("");
// const [userSuggestions, setUserSuggestions] = useState([]); const [userSuggestions, setUserSuggestions] = useState<ThemeType[]>([]);
// const [themeLimit, setThemeLimit] = useState(0); const [themeLimit, setThemeLimit] = useState(0);
// const [hasJoined, setHasJoined] = useState<boolean>(false); const [hasJoined, setHasJoined] = useState<boolean>(false);
// const [activeJamResponse, setActiveJamResponse] = const [activeJamResponse, setActiveJamResponse] =
// useState<ActiveJamResponse | null>(null); useState<ActiveJamResponse | null>(null);
// const [phaseLoading, setPhaseLoading] = useState(true); // Loading state for fetching phase const [phaseLoading, setPhaseLoading] = useState(true); // Loading state for fetching phase
// // Fetch the current jam phase using helpers/jam // Fetch the current jam phase using helpers/jam
// useEffect(() => { useEffect(() => {
// const fetchCurrentJamPhase = async () => { const fetchCurrentJamPhase = async () => {
// try { try {
// const activeJam = await getCurrentJam(); const activeJam = await getCurrentJam();
// setActiveJamResponse(activeJam); // Set active jam details setActiveJamResponse(activeJam); // Set active jam details
// if (activeJam?.jam) { if (activeJam?.jam) {
// setThemeLimit(activeJam.jam.themePerUser || Infinity); // Set theme limit setThemeLimit(activeJam.jam.themePerUser || Infinity); // Set theme limit
// } }
// } catch (error) { } catch (error) {
// console.error("Error fetching current jam:", error); console.error("Error fetching current jam:", error);
// } finally { } finally {
// setPhaseLoading(false); // Stop loading when phase is fetched setPhaseLoading(false); // Stop loading when phase is fetched
// } }
// }; };
// fetchCurrentJamPhase(); fetchCurrentJamPhase();
// }, []); }, []);
// // Fetch all suggestions for the logged-in user // Fetch all suggestions for the logged-in user
// const fetchSuggestions = async () => { const fetchSuggestions = async () => {
// try { try {
// const response = await fetch( const response = await fetch(
// process.env.NEXT_PUBLIC_MODE === "PROD" process.env.NEXT_PUBLIC_MODE === "PROD"
// ? "https://d2jam.com/api/v1/themes/suggestion" ? "https://d2jam.com/api/v1/themes/suggestion"
// : "http://localhost:3005/api/v1/themes/suggestion", : "http://localhost:3005/api/v1/themes/suggestion",
// { {
// headers: { Authorization: `Bearer ${getCookie("token")}` }, headers: { Authorization: `Bearer ${getCookie("token")}` },
// credentials: "include", credentials: "include",
// } }
// ); );
// if (response.ok) { if (response.ok) {
// const data = await response.json(); const data = await response.json();
// setUserSuggestions(data); setUserSuggestions(data);
// } }
// } catch (error) { } catch (error) {
// console.error("Error fetching suggestions:", error); console.error("Error fetching suggestions:", error);
// } }
// }; };
// // Fetch suggestions only when phase is "Suggestion" // Fetch suggestions only when phase is "Suggestion"
// useEffect(() => { useEffect(() => {
// if (activeJamResponse?.phase === "Suggestion") { if (activeJamResponse?.phase === "Suggestion") {
// fetchSuggestions(); fetchSuggestions();
// } }
// }, [activeJamResponse]); }, [activeJamResponse]);
// // Handle form submission to add a new suggestion // Handle form submission to add a new suggestion
// const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
// e.preventDefault(); e.preventDefault();
// setLoading(true); setLoading(true);
// setSuccessMessage(""); setSuccessMessage("");
// setErrorMessage(""); setErrorMessage("");
// if (!suggestion.trim()) { if (!suggestion.trim()) {
// setErrorMessage("Suggestion cannot be empty."); setErrorMessage("Suggestion cannot be empty.");
// setLoading(false); setLoading(false);
// return; return;
// } }
// try { try {
// const token = getCookie("token"); const token = getCookie("token");
// if (!token) { if (!token) {
// throw new Error("User is not authenticated. Please log in."); throw new Error("User is not authenticated. Please log in.");
// } }
// const response = await fetch( const response = await fetch(
// process.env.NEXT_PUBLIC_MODE === "PROD" process.env.NEXT_PUBLIC_MODE === "PROD"
// ? "https://d2jam.com/api/v1/themes/suggestion" ? "https://d2jam.com/api/v1/themes/suggestion"
// : "http://localhost:3005/api/v1/themes/suggestion", : "http://localhost:3005/api/v1/themes/suggestion",
// { {
// method: "POST", method: "POST",
// headers: { headers: {
// "Content-Type": "application/json", "Content-Type": "application/json",
// Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
// }, },
// credentials: "include", credentials: "include",
// body: JSON.stringify({ suggestionText: suggestion }), body: JSON.stringify({ suggestionText: suggestion }),
// } }
// ); );
// if (!response.ok) { if (!response.ok) {
// const errorData = await response.json(); const errorData = await response.json();
// throw new Error(errorData.error || "Failed to submit suggestion."); throw new Error(errorData.error || "Failed to submit suggestion.");
// } }
// setSuccessMessage("Suggestion added successfully!"); setSuccessMessage("Suggestion added successfully!");
// setSuggestion(""); // Clear input field setSuggestion(""); // Clear input field
// fetchSuggestions(); // Refresh suggestions list fetchSuggestions(); // Refresh suggestions list
// } catch (error) { } catch (error) {
// if (error instanceof Error) { if (error instanceof Error) {
// console.error("Error submitting suggestion:", error.message); console.error("Error submitting suggestion:", error.message);
// setErrorMessage(error.message || "An unexpected error occurred."); setErrorMessage(error.message || "An unexpected error occurred.");
// } else { } else {
// console.error("Unknown error:", error); console.error("Unknown error:", error);
// setErrorMessage("An unexpected error occurred."); setErrorMessage("An unexpected error occurred.");
// } }
// } finally { } finally {
// setLoading(false); setLoading(false);
// } }
// }; };
// // Handle deleting a suggestion // Handle deleting a suggestion
// const handleDelete = async (id: number) => { const handleDelete = async (id: number) => {
// try { try {
// const token = getCookie("token"); const token = getCookie("token");
// const response = await fetch( const response = await fetch(
// process.env.NEXT_PUBLIC_MODE === "PROD" process.env.NEXT_PUBLIC_MODE === "PROD"
// ? `https://d2jam.com/api/v1/themes/suggestion/${id}` ? `https://d2jam.com/api/v1/themes/suggestion/${id}`
// : `http://localhost:3005/api/v1/themes/suggestion/${id}`, : `http://localhost:3005/api/v1/themes/suggestion/${id}`,
// { {
// method: "DELETE", method: "DELETE",
// headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
// credentials: "include", credentials: "include",
// } }
// ); );
// if (!response.ok) { if (!response.ok) {
// throw new Error("Failed to delete suggestion."); throw new Error("Failed to delete suggestion.");
// } }
// fetchSuggestions(); // Refresh suggestions list fetchSuggestions(); // Refresh suggestions list
// } catch (error) { } catch (error) {
// console.error("Error deleting suggestion:", error); console.error("Error deleting suggestion:", error);
// } }
// }; };
// useEffect(() => { useEffect(() => {
// const init = async () => { const init = async () => {
// const joined = await hasJoinedCurrentJam(); const joined = await hasJoinedCurrentJam();
// setHasJoined(joined); setHasJoined(joined);
// setLoading(false); setLoading(false);
// }; };
// init(); init();
// }, []); }, []);
// // Render loading state while fetching phase // Render loading state while fetching phase
// if (phaseLoading || loading) { if (phaseLoading || loading) {
// return <div>Loading...</div>; return <div>Loading...</div>;
// } }
// if (!hasJoined) { if (!hasJoined) {
// return ( return (
// <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen"> <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen">
// <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6"> <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6">
// Join the Jam First Join the Jam First
// </h1> </h1>
// <p className="text-gray-600 dark:text-gray-400"> <p className="text-gray-600 dark:text-gray-400">
// You need to join the current jam before you can suggest themes. You need to join the current jam before you can suggest themes.
// </p> </p>
// <button <button
// onClick={() => joinJam(activeJamResponse?.jam?.id)} onClick={() => {
// className="mt-4 px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600" if (activeJamResponse?.jam?.id !== undefined) {
// > joinJam(activeJamResponse.jam.id);
// Join Jam }
// </button> }}
// </div> className="mt-4 px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600"
// ); >
// } Join Jam
</button>
// const token = getCookie("token"); </div>
);
// if (!token) { }
// return <div>Sign in to be able to suggest themes</div>;
// } const token = getCookie("token");
// // Render message if not in Suggestion phase if (!token) {
// if (activeJamResponse?.phase !== "Suggestion") { return <div>Sign in to be able to suggest themes</div>;
// return ( }
// <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen">
// <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6"> // Render message if not in Suggestion phase
// Not in Suggestion Phase if (activeJamResponse?.phase !== "Suggestion") {
// </h1> return (
// <p className="text-gray-600 dark:text-gray-400"> <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen">
// The current phase is{" "} <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6">
// <strong>{activeJamResponse?.phase || "Unknown"}</strong>. Please come Not in Suggestion Phase
// back during the Suggestion phase. </h1>
// </p> <p className="text-gray-600 dark:text-gray-400">
// </div> The current phase is{" "}
// ); <strong>{activeJamResponse?.phase || "Unknown"}</strong>. Please come
// } back during the Suggestion phase.
</p>
// return ( </div>
// <div className="max-w-md mx-auto mt-8 p-6 bg-white dark:bg-gray-800 rounded-lg shadow-md"> );
// <h2 className="text-xl font-bold text-gray-800 dark:text-white mb-4"> }
// Submit Your Theme Suggestion
// </h2> return (
<div className="max-w-md mx-auto mt-8 p-6 bg-white dark:bg-gray-800 rounded-lg shadow-md">
// {/* Hide form if user has reached their limit */} <h2 className="text-xl font-bold text-gray-800 dark:text-white mb-4">
// {userSuggestions.length < themeLimit ? ( Submit Your Theme Suggestion
// <form onSubmit={handleSubmit} className="flex flex-col gap-4"> </h2>
// <textarea
// className="w-full p-3 border rounded-lg focus:outline-none text-gray-600 focus:ring focus:ring-blue-300 dark:bg-gray-700 dark:text-white" {/* Hide form if user has reached their limit */}
// placeholder="Enter your theme suggestion..." {userSuggestions.length < themeLimit ? (
// value={suggestion} <form onSubmit={handleSubmit} className="flex flex-col gap-4">
// onChange={(e) => { <textarea
// if (e.target.value.length <= 32) { className="w-full p-3 border rounded-lg focus:outline-none text-gray-600 focus:ring focus:ring-blue-300 dark:bg-gray-700 dark:text-white"
// setSuggestion(e.target.value); placeholder="Enter your theme suggestion..."
// } value={suggestion}
// }} onChange={(e) => {
// rows={1} if (e.target.value.length <= 32) {
// maxLength={32} setSuggestion(e.target.value);
// ></textarea> }
// {errorMessage && ( }}
// <p className="text-red-500 text-sm">{errorMessage}</p> rows={1}
// )} maxLength={32}
// {successMessage && ( ></textarea>
// <p className="text-green-500 text-sm">{successMessage}</p> {errorMessage && (
// )} <p className="text-red-500 text-sm">{errorMessage}</p>
// <button )}
// type="submit" {successMessage && (
// className={`w-full py-2 px-4 bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-600 focus:outline-none focus:ring focus:ring-blue-300 ${ <p className="text-green-500 text-sm">{successMessage}</p>
// loading ? "opacity-50 cursor-not-allowed" : "" )}
// }`} <button
// disabled={loading} type="submit"
// > className={`w-full py-2 px-4 bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-600 focus:outline-none focus:ring focus:ring-blue-300 ${
// {loading ? "Submitting..." : "Submit Suggestion"} loading ? "opacity-50 cursor-not-allowed" : ""
// </button> }`}
// </form> disabled={loading}
// ) : ( >
// <p className="text-yellow-500 text-sm"> {loading ? "Submitting..." : "Submit Suggestion"}
// You&apos;ve reached your theme suggestion limit for this jam! </button>
// </p> </form>
// )} ) : (
<p className="text-yellow-500 text-sm">
// {/* List of user's suggestions */} You&apos;ve reached your theme suggestion limit for this jam!
// <div className="mt-6"> </p>
// <h3 className="text-lg font-semibold text-gray-800 dark:text-white mb-4"> )}
// Your Suggestions
// </h3> {/* List of user's suggestions */}
// {userSuggestions.length > 0 ? ( <div className="mt-6">
// <ul className="space-y-4"> <h3 className="text-lg font-semibold text-gray-800 dark:text-white mb-4">
// {userSuggestions.map((suggestion) => ( Your Suggestions
// <li </h3>
// key={suggestion.id} {userSuggestions.length > 0 ? (
// className="flex justify-between items-center text-gray-400 bg-gray-100 dark:bg-gray-700 p-3 rounded-lg shadow-sm" <ul className="space-y-4">
// > {userSuggestions.map((suggestion) => (
// <span>{suggestion.suggestion}</span> <li
// <button key={suggestion.id}
// onClick={() => handleDelete(suggestion.id)} className="flex justify-between items-center text-gray-400 bg-gray-100 dark:bg-gray-700 p-3 rounded-lg shadow-sm"
// className="text-red-500 hover:text-red-700 font-semibold" >
// > <span>{suggestion.suggestion}</span>
// Delete <button
// </button> onClick={() => handleDelete(suggestion.id)}
// </li> className="text-red-500 hover:text-red-700 font-semibold"
// ))} >
// </ul> Delete
// ) : ( </button>
// <p className="text-gray-600 dark:text-gray-400"> </li>
// You haven&apos;t submitted any suggestions yet. ))}
// </p> </ul>
// )} ) : (
// </div> <p className="text-gray-600 dark:text-gray-400">
// </div> You haven&apos;t submitted any suggestions yet.
// ); </p>
return <></>; )}
</div>
</div>
);
} }

View file

@ -1,245 +1,248 @@
"use client"; "use client";
// import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
// import { getCookie } from "@/helpers/cookie"; import { getCookie } from "@/helpers/cookie";
// import { import {
// getCurrentJam, getCurrentJam,
// hasJoinedCurrentJam, hasJoinedCurrentJam,
// ActiveJamResponse, ActiveJamResponse,
// } from "@/helpers/jam"; } from "@/helpers/jam";
import { ThemeType } from "@/types/ThemeType";
import { joinJam } from "@/helpers/jam";
interface VoteType {
themeSuggestionId: number;
votingScore: number;
}
export default function VotingPage() { export default function VotingPage() {
return <></>; const [themes, setThemes] = useState<ThemeType[]>([]);
// const [themes, setThemes] = useState([]); const [loading, setLoading] = useState(false);
// const [loading, setLoading] = useState(false); const [activeJamResponse, setActiveJamResponse] = useState<ActiveJamResponse | null>(null);
// const [activeJamResponse, setActiveJamResponse] = const [hasJoined, setHasJoined] = useState<boolean>(false);
// useState<ActiveJamResponse | null>(null); const [phaseLoading, setPhaseLoading] = useState(true); // Loading state for fetching phase
// const [hasJoined, setHasJoined] = useState<boolean>(false); const token = getCookie("token");
// const [phaseLoading, setPhaseLoading] = useState(true); // Loading state for fetching phase
// const token = getCookie("token");
// // Fetch the current jam phase using helpers/jam // Fetch the current jam phase using helpers/jam
// useEffect(() => { useEffect(() => {
// const fetchCurrentJamPhase = async () => { const fetchCurrentJamPhase = async () => {
// try { try {
// const activeJam = await getCurrentJam(); const activeJam = await getCurrentJam();
// setActiveJamResponse(activeJam); // Set active jam details setActiveJamResponse(activeJam); // Set active jam details
// } catch (error) { } catch (error) {
// console.error("Error fetching current jam:", error); console.error("Error fetching current jam:", error);
// } finally { } finally {
// setPhaseLoading(false); // Stop loading when phase is fetched setPhaseLoading(false); // Stop loading when phase is fetched
// } }
// }; };
// fetchCurrentJamPhase(); fetchCurrentJamPhase();
// }, []); }, []);
// // Fetch themes only when phase is "Voting" // Fetch themes only when phase is "Voting"
// useEffect(() => { useEffect(() => {
// // Fetch top N themes with voting scores // Fetch top N themes with voting scores
// async function fetchThemes() { async function fetchThemes() {
// if (!token || !activeJamResponse) return; if (!token || !activeJamResponse) return;
// try { try {
// const response = await fetch( const response = await fetch(
// process.env.NEXT_PUBLIC_MODE === "PROD" process.env.NEXT_PUBLIC_MODE === "PROD"
// ? "https://d2jam.com/api/v1/themes/top-themes" ? "https://d2jam.com/api/v1/themes/top-themes"
// : "http://localhost:3005/api/v1/themes/top-themes", : "http://localhost:3005/api/v1/themes/top-themes",
// { {
// headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
// credentials: "include", credentials: "include",
// } }
// ); );
// if (response.ok) { if (response.ok) {
// const themes = await response.json(); const themes = await response.json();
// console.log("Fetched themes:", themes); // Debug log
// Fetch user's votes for these themes
// // Fetch user's votes for these themes const votesResponse = await fetch(
// const votesResponse = await fetch( process.env.NEXT_PUBLIC_MODE === "PROD"
// process.env.NEXT_PUBLIC_MODE === "PROD" ? "https://d2jam.com/api/v1/themes/votes"
// ? "https://d2jam.com/api/v1/themes/votes" : "http://localhost:3005/api/v1/themes/votes",
// : "http://localhost:3005/api/v1/themes/votes", {
// { headers: { Authorization: `Bearer ${token}` },
// headers: { Authorization: `Bearer ${token}` }, credentials: "include",
// credentials: "include", }
// } );
// );
if (votesResponse.ok) {
// if (votesResponse.ok) { const votes = await votesResponse.json();
// const votes = await votesResponse.json(); // Merge themes with user's votes
// console.log("Fetched votes:", votes); // Debug log const themesWithVotes = themes.map((theme: ThemeType) => {
const vote = votes.find((v: VoteType) => v.themeSuggestionId === theme.id);
// // Merge themes with user's votes return {
// const themesWithVotes = themes.map((theme) => { ...theme,
// const vote = votes.find((v) => v.themeSuggestionId === theme.id); votingScore: vote ? vote.votingScore : null,
// console.log(`Theme ${theme.id} vote:`, vote); // Debug log };
// return { });
// ...theme, setThemes(themesWithVotes);
// votingScore: vote ? vote.votingScore : null, }
// }; } else {
// }); console.error("Failed to fetch themes.");
}
// console.log("Themes with votes:", themesWithVotes); // Debug log } catch (error) {
// setThemes(themesWithVotes); console.error("Error fetching themes:", error);
// } }
// } else { }
// console.error("Failed to fetch themes.");
// } if (activeJamResponse?.phase === "Voting") {
// } catch (error) { fetchThemes();
// console.error("Error fetching themes:", error); }
// } }, [activeJamResponse, token]);
// }
// Handle voting
// if (activeJamResponse?.phase === "Voting") { const handleVote = async (themeId: number, votingScore: number) => {
// fetchThemes(); setLoading(true);
// } try {
// }, [activeJamResponse, token]); const response = await fetch(
process.env.NEXT_PUBLIC_MODE === "PROD"
// // Handle voting ? "https://d2jam.com/api/v1/themes/vote"
// const handleVote = async (themeId, votingScore) => { : "http://localhost:3005/api/v1/themes/vote",
// setLoading(true); {
// try { method: "POST",
// const response = await fetch( headers: {
// process.env.NEXT_PUBLIC_MODE === "PROD" "Content-Type": "application/json",
// ? "https://d2jam.com/api/v1/themes/vote" Authorization: `Bearer ${token}`,
// : "http://localhost:3005/api/v1/themes/vote", },
// { credentials: "include",
// method: "POST", body: JSON.stringify({ suggestionId: themeId, votingScore }),
// headers: { }
// "Content-Type": "application/json", );
// Authorization: `Bearer ${token}`,
// }, if (response.ok) {
// credentials: "include", // Just update the local state instead of re-fetching all themes
// body: JSON.stringify({ suggestionId: themeId, votingScore }), setThemes((prevThemes) =>
// } prevThemes.map((theme) =>
// ); theme.id === themeId ? { ...theme, votingScore } : theme
)
// if (response.ok) { );
// // Just update the local state instead of re-fetching all themes } else {
// setThemes((prevThemes) => console.error("Failed to submit vote.");
// prevThemes.map((theme) => }
// theme.id === themeId ? { ...theme, votingScore } : theme } catch (error) {
// ) console.error("Error submitting vote:", error);
// ); } finally {
// } else { setLoading(false);
// console.error("Failed to submit vote."); }
// } };
// } catch (error) {
// console.error("Error submitting vote:", error); useEffect(() => {
// } finally { const init = async () => {
// setLoading(false); const joined = await hasJoinedCurrentJam();
// } setHasJoined(joined);
// }; setLoading(false);
};
// useEffect(() => {
// const init = async () => { init();
// const joined = await hasJoinedCurrentJam(); }, []);
// setHasJoined(joined);
// setLoading(false); if (phaseLoading || loading) {
// }; return <div>Loading...</div>;
}
// init();
// }, []); if (!hasJoined) {
return (
// if (phaseLoading || loading) { <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen">
// return <div>Loading...</div>; <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6">
// } Join the Jam First
</h1>
// if (!hasJoined) { <p className="text-gray-600 dark:text-gray-400">
// return ( You need to join the current jam before you can vote themes.
// <div className="p-6 bg-gray-100 dark:bg-gray-800 min-h-screen"> </p>
// <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-6"> <button
// Join the Jam First onClick={() => {
// </h1> if (activeJamResponse?.jam?.id !== undefined) {
// <p className="text-gray-600 dark:text-gray-400"> joinJam(activeJamResponse.jam.id);
// You need to join the current jam before you can vote themes. }
// </p> }}
// <button className="mt-4 px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600"
// onClick={() => joinJam(activeJamResponse?.jam?.id)} >
// className="mt-4 px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600" Join Jam
// > </button>
// Join Jam </div>
// </button> );
// </div> }
// );
// } if (activeJamResponse?.phase !== "Voting") {
return (
// if (activeJamResponse?.phase !== "Voting") { <div className="p-4 bg-gray-100 dark:bg-gray-800 min-h-screen">
// return ( <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-4">
// <div className="p-4 bg-gray-100 dark:bg-gray-800 min-h-screen"> Not in Voting Phase
// <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-4"> </h1>
// Not in Voting Phase <p className="text-gray-600 dark:text-gray-400">
// </h1> The current phase is{" "}
// <p className="text-gray-600 dark:text-gray-400"> <strong>{activeJamResponse?.phase || "Unknown"}</strong>. Please come
// The current phase is{" "} back during the Voting phase.
// <strong>{activeJamResponse?.phase || "Unknown"}</strong>. Please come </p>
// back during the Voting phase. </div>
// </p> );
// </div> }
// );
// } const loggedIn = getCookie("token");
// const loggedIn = getCookie("token"); if (!loggedIn) {
return <div>Sign in to be able to vote</div>;
// if (!loggedIn) { }
// return <div>Sign in to be able to vote</div>;
// } return (
<div className="p-3 bg-gray-100 dark:bg-gray-800 min-h-screen">
// return ( <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-4">
// <div className="p-3 bg-gray-100 dark:bg-gray-800 min-h-screen"> Voting Phase
// <h1 className="text-2xl font-bold text-gray-800 dark:text-white mb-4"> </h1>
// Voting Phase <div className="space-y-2">
// </h1> {themes.map((theme) => (
// <div className="space-y-2"> <div
// {themes.map((theme) => ( key={theme.id}
// <div className="p-3 bg-white dark:bg-gray-900 rounded-lg shadow-md flex items-center"
// key={theme.id} >
// className="p-3 bg-white dark:bg-gray-900 rounded-lg shadow-md flex items-center" {/* Voting Buttons */}
// > <div className="flex gap-1 mr-4">
// {/* Voting Buttons */} <button
// <div className="flex gap-1 mr-4"> onClick={() => handleVote(theme.id, -1)}
// <button className={`px-3 py-2 rounded-lg ${
// onClick={() => handleVote(theme.id, -1)} theme.votingScore === -1
// className={`px-3 py-2 rounded-lg ${ ? "bg-red-500 text-white"
// theme.votingScore === -1 : "bg-gray-300 text-black hover:bg-red-500 hover:text-white"
// ? "bg-red-500 text-white" }`}
// : "bg-gray-300 text-black hover:bg-red-500 hover:text-white" disabled={loading}
// }`} >
// disabled={loading} -1
// > </button>
// -1 <button
// </button> onClick={() => handleVote(theme.id, 0)}
// <button className={`px-3 py-2 rounded-lg ${
// onClick={() => handleVote(theme.id, 0)} theme.votingScore === 0
// className={`px-3 py-2 rounded-lg ${ ? "bg-gray-500 text-white"
// theme.votingScore === 0 : "bg-gray-300 text-black hover:bg-gray-500 hover:text-white"
// ? "bg-gray-500 text-white" }`}
// : "bg-gray-300 text-black hover:bg-gray-500 hover:text-white" disabled={loading}
// }`} >
// disabled={loading} 0
// > </button>
// 0 <button
// </button> onClick={() => handleVote(theme.id, +1)}
// <button className={`px-3 py-2 rounded-lg ${
// onClick={() => handleVote(theme.id, +1)} theme.votingScore === +1
// className={`px-3 py-2 rounded-lg ${ ? "bg-green-500 text-white"
// theme.votingScore === +1 : "bg-gray-300 text-black hover:bg-green-500 hover:text-white"
// ? "bg-green-500 text-white" }`}
// : "bg-gray-300 text-black hover:bg-green-500 hover:text-white" disabled={loading}
// }`} >
// disabled={loading} +1
// > </button>
// +1 </div>
// </button>
// </div> {/* Theme Suggestion */}
<div className="text-gray-800 dark:text-white">
// {/* Theme Suggestion */} {theme.suggestion}
// <div className="text-gray-800 dark:text-white"> </div>
// {theme.suggestion} </div>
// </div> ))}
// </div> </div>
// ))} </div>
// </div> );
// </div>
// );
} }

View file

@ -74,8 +74,8 @@ export async function hasJoinedCurrentJam(): Promise<boolean> {
try { try {
const response = await fetch( const response = await fetch(
process.env.NEXT_PUBLIC_MODE === "PROD" process.env.NEXT_PUBLIC_MODE === "PROD"
? "https://d2jam.com/api/v1/participation" ? "https://d2jam.com/api/v1/jams/participation"
: "http://localhost:3005/api/v1/participation", : "http://localhost:3005/api/v1/jams/participation",
{ {
credentials: "include", credentials: "include",
headers: { headers: {

View file

@ -9,4 +9,5 @@ export interface JamType {
startTime: Date; startTime: Date;
createdAt: Date; createdAt: Date;
updatedAt: Date; updatedAt: Date;
themePerUser: number;
} }

6
src/types/ThemeType.ts Normal file
View file

@ -0,0 +1,6 @@
export interface ThemeType {
id: number;
suggestion: string;
slaughterScore: number;
votingScore: number;
}