111 lines
3.6 KiB
TypeScript
111 lines
3.6 KiB
TypeScript
"use client";
|
|
import { useState, useEffect } from "react";
|
|
import { Nunito } from "next/font/google";
|
|
import { api } from "muzak/data/fetcher";
|
|
import { useAnimation } from "muzak/contexts/AnimationContext";
|
|
import { useQuota } from "muzak/contexts/QuotaContext";
|
|
|
|
const nunito = Nunito({
|
|
weight: "900",
|
|
subsets: ["latin"],
|
|
});
|
|
|
|
export default function Nominations() {
|
|
const { isAnimate, setIsAnimate } = useAnimation();
|
|
const [songURL, setSongURL] = useState("");
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [message, setMessage] = useState("");
|
|
const [canNominate, setCanNominate] = useState(true);
|
|
const isSpotifyURL =
|
|
/^https:\/\/open\.spotify\.com\/track\/[a-zA-Z0-9]{22}(\?.*)?$/.test(
|
|
songURL,
|
|
);
|
|
const { quota, setQuota } = useQuota();
|
|
async function nominate(spotifyLink: string) {
|
|
try {
|
|
setIsAnimate(false);
|
|
const response = await api.tracks.nominate({
|
|
spotify_link: spotifyLink,
|
|
});
|
|
console.log("Nomination successful:", response);
|
|
setIsAnimate(true);
|
|
setQuota(quota - 1);
|
|
return { success: true, data: response.data };
|
|
} catch (error) {
|
|
console.error("Nomination failed:", error);
|
|
return { success: false, error };
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (quota > 0) {
|
|
setCanNominate(true);
|
|
} else {
|
|
setCanNominate(false);
|
|
}
|
|
}, [quota]);
|
|
|
|
return (
|
|
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
|
<h1
|
|
className={`${nunito.className} text-outline text-[42px] tracking-tighter text-yellow-500`}
|
|
>
|
|
NOMINATIES
|
|
</h1>
|
|
<div className="relative mt-4 mb-12 flex flex-col items-center justify-between gap-4 rounded-md bg-blue-950/80 p-8">
|
|
<form className="flex flex-col items-center justify-center gap-4">
|
|
<p className="text-2xl font-semibold text-white drop-shadow-sm drop-shadow-gray-900">
|
|
Dump hier je Spotify-link:
|
|
</p>
|
|
<label className="block w-lg text-sm font-bold text-gray-700">
|
|
<input
|
|
className="w-full rounded border border-white px-4 py-2 font-bold text-white/70 focus:border-yellow-500 focus:outline-2 focus:outline-yellow-500"
|
|
type="text"
|
|
placeholder="Spotify URL"
|
|
value={songURL}
|
|
onChange={(e) => setSongURL(e.target.value)}
|
|
/>
|
|
</label>
|
|
|
|
<button
|
|
className="w-full rounded bg-blue-500 px-4 py-2 text-center font-bold text-white hover:bg-blue-400 disabled:cursor-not-allowed disabled:bg-gray-500"
|
|
type="submit"
|
|
disabled={
|
|
isLoading || !songURL.trim() || !isSpotifyURL || !canNominate
|
|
}
|
|
onClick={async (e) => {
|
|
e.preventDefault();
|
|
if (!songURL.trim()) return;
|
|
|
|
setIsLoading(true);
|
|
setMessage("");
|
|
|
|
const result = await nominate(songURL);
|
|
|
|
if (result.success) {
|
|
setMessage("✅ Nominatie succesvol ingediend!");
|
|
setSongURL("");
|
|
} else {
|
|
setMessage("❌ Er ging iets mis. Probeer het opnieuw.");
|
|
}
|
|
|
|
setIsLoading(false);
|
|
}}
|
|
>
|
|
{isLoading ? "Nomineren..." : "Nomineer"}
|
|
</button>
|
|
</form>
|
|
{message && (
|
|
<div className="absolute top-50 mt-4 rounded bg-gray-800 p-3 text-center text-white">
|
|
{message}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<footer>
|
|
<p>© 2020-2025 Hoestende Draken PartyCo</p>
|
|
</footer>
|
|
</main>
|
|
);
|
|
}
|