"use client"; import { useState, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Card, CardBody, Input, Button, addToast, Divider, Spinner, Chip, Tooltip, Modal, ModalContent, ModalBody, ModalFooter, } from "@heroui/react"; import { getFirestore, collection, addDoc, serverTimestamp, onSnapshot, query, orderBy, deleteDoc, doc, updateDoc, } from "firebase/firestore"; import { getAuth, onAuthStateChanged } from "firebase/auth"; import firebaseApp from "@/config/firebase"; import { fontCursive, fontSans, fontMono } from "@/config/fonts"; import { HeartFilledIcon } from "@/components/icons"; const db = getFirestore(firebaseApp()); const auth = getAuth(firebaseApp()); export default function SongRequestsPage() { const [formData, setFormData] = useState({ name: "", song: "", artist: "", captcha: "", }); const [loading, setLoading] = useState(false); const [user, setUser] = useState(null); const [requests, setRequests] = useState([]); const [listLoading, setListLoading] = useState(true); // Delete Confirmation States const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [requestToDelete, setRequestToDelete] = useState(null); useEffect(() => { const unsubscribeAuth = onAuthStateChanged(auth, (currentUser) => { setUser(currentUser); }); return () => unsubscribeAuth(); }, []); useEffect(() => { const q = query( collection(db, "song_requests"), orderBy("createdAt", "desc"), ); const unsubscribeData = onSnapshot(q, (snapshot) => { const data = snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data(), })); setRequests(data); setListLoading(false); }); return () => unsubscribeData(); }, []); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (formData.captcha.trim() !== "10") { addToast({ title: "Security Check", description: "Please answer the question correctly (Hint: 10 years!).", color: "warning", }); return; } if (!formData.name || !formData.song) return; setLoading(true); try { await addDoc(collection(db, "song_requests"), { ...formData, status: "pending", createdAt: serverTimestamp(), }); setFormData({ name: "", song: "", artist: "", captcha: "" }); addToast({ title: "Song Requested!", description: "We'll try our best to play your favorite track at the Reception.", color: "success", }); } catch (err) { console.error("Song request error", err); addToast({ title: "Error", description: "Could not save your request. Please try again.", color: "danger", }); } finally { setLoading(false); } }; const handleDeleteClick = (id: string) => { setRequestToDelete(id); setIsDeleteModalOpen(true); }; const handleConfirmDelete = async () => { if (!requestToDelete) return; try { await deleteDoc(doc(db, "song_requests", requestToDelete)); addToast({ title: "Deleted", description: "Request removed.", color: "success", }); } catch (err) { addToast({ title: "Error", color: "danger" }); } finally { setIsDeleteModalOpen(false); setRequestToDelete(null); } }; const toggleStatus = async (id: string, currentStatus: string) => { try { await updateDoc(doc(db, "song_requests", id), { status: currentStatus === "played" ? "pending" : "played", }); addToast({ title: "Status Updated", color: "success" }); } catch (err) { addToast({ title: "Error", color: "danger" }); } }; const isAdmin = user?.email === process.env.NEXT_PUBLIC_ADMIN_EMAIL; return (
{/* Header */}

Reception Playlist

"Music is the soul of our celebration. Tell us which song makes you want to hit the dance floor!"

{/* Left: Request Form */}

Request a Song

setFormData({ ...formData, name: e.target.value }) } />
setFormData({ ...formData, song: e.target.value }) } /> setFormData({ ...formData, artist: e.target.value }) } />

Bot Protection

setFormData({ ...formData, captcha: e.target.value }) } />
{/* Right: Requests Feed */}

The Queue

{requests.length} Total
{listLoading ? (
) : requests.length === 0 ? (

The playlist is waiting for your touch!

) : ( {requests.map((item, i) => (
{item.status === "played" ? ( ) : ( )}

{item.song}

{item.artist || "Unknown Artist"} • Requested by{" "} {item.name}

{isAdmin && (
)}
))}
)}

Let the music play

{/* Delete Confirmation Modal */} {(onClose) => ( <>

Delete Request?

Are you sure you want to remove this song from the queue?

)}
); }