From de05090b8596d7a93a8daeaa82ae451cf924e329 Mon Sep 17 00:00:00 2001 From: EdiFarcas Date: Tue, 6 May 2025 17:05:35 +0300 Subject: [PATCH] Winner selection --- src/app/admin/GiveawayManagementCards.tsx | 97 +++++++++++++++-------- src/app/admin/ModalGiveawayWinner.tsx | 80 +++++++++++++++++++ src/app/admin/SelectWinerServer.tsx | 46 +++++++++++ 3 files changed, 191 insertions(+), 32 deletions(-) create mode 100644 src/app/admin/ModalGiveawayWinner.tsx create mode 100644 src/app/admin/SelectWinerServer.tsx diff --git a/src/app/admin/GiveawayManagementCards.tsx b/src/app/admin/GiveawayManagementCards.tsx index 7084232..2cab412 100644 --- a/src/app/admin/GiveawayManagementCards.tsx +++ b/src/app/admin/GiveawayManagementCards.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react"; import { giveawaysFind } from "./GiveawayManagementCardServer"; +import Modal from "./ModalGiveawayWinner"; interface Giveaway { id: string; @@ -16,6 +17,13 @@ interface Giveaway { const GiveawayManagementCards: React.FC = () => { const [activeGiveaways, setActiveGiveaways] = useState([]); const [finishedGiveaways, setFinishedGiveaways] = useState([]); + const [isModalOpen, setIsModalOpen] = useState(false); + const [selectedGiveaway, setSelectedGiveaway] = useState<{ + id: string; + title: string; + prize: string; + value: number; + } | null>(null); const fetchGiveaways = async () => { try { @@ -40,19 +48,30 @@ const GiveawayManagementCards: React.FC = () => { } }; - const handleSelectWinner = async (giveawayId: string) => { - alert(`Selecting winner for giveaway ID: ${giveawayId}`); - }; - useEffect(() => { fetchGiveaways(); }, []); + const handleSelectWinner = (giveawayId: string, giveawayTitle: string, giveawayPrize: string, giveawayValue: number) => { + setSelectedGiveaway({ + id: giveawayId, + title: giveawayTitle, + prize: giveawayPrize, + value: giveawayValue, + }); // Set the selected giveaway + setIsModalOpen(true); // Open the modal + }; + + const handleCloseModal = () => { + setIsModalOpen(false); // Close the modal + setSelectedGiveaway(null); // Clear the selected giveaway + }; + return (
{/* Finished Giveaways Section */} -
+

🏁 Finished Giveaways

{finishedGiveaways.map((giveaway) => ( @@ -61,47 +80,61 @@ const GiveawayManagementCards: React.FC = () => { className="p-4 border border-gray-200 rounded-lg bg-gray-50 hover:bg-gray-100 transition relative" >
-

{giveaway.title}

-

{giveaway.description}

-

Prize: {giveaway.prize}

-

Value: {giveaway.value} coins

-

+

{giveaway.title}

+

{giveaway.description}

+

Prize: {giveaway.prize}

+

Value: {giveaway.value} coins

+

Ended At: {giveaway.endsAt ? new Date(giveaway.endsAt).toLocaleString() : "N/A"} -

+

))}
-
+
{/* Active Giveaways Section */}
-

🎉 Active Giveaways

-
- {activeGiveaways.map((giveaway) => ( -
-

{giveaway.title}

-

{giveaway.description}

-

Prize: {giveaway.prize}

-

Value: {giveaway.value} coins

-

- Ends At: {giveaway.endsAt ? new Date(giveaway.endsAt).toLocaleString() : "N/A"} -

-
- ))} +

🎉 Active Giveaways

+
+ {activeGiveaways.map((giveaway) => ( +
+

{giveaway.title}

+

{giveaway.description}

+

Prize: {giveaway.prize}

+

Value: {giveaway.value} coins

+

+ Ends At: {giveaway.endsAt ? new Date(giveaway.endsAt).toLocaleString() : "N/A"} +

+ ))} +
+ {/* Modal */} + {isModalOpen && ( + +

Here you can select the winner for the giveaway.

+
+ )}
); }; diff --git a/src/app/admin/ModalGiveawayWinner.tsx b/src/app/admin/ModalGiveawayWinner.tsx new file mode 100644 index 0000000..f4cda13 --- /dev/null +++ b/src/app/admin/ModalGiveawayWinner.tsx @@ -0,0 +1,80 @@ +import React from "react" +import { selectWinner } from "./SelectWinerServer" + + +interface ModalProps { + isOpen: boolean; + onClose: () => void; + title: string; + children: React.ReactNode; + giveawayId: string | null; + giveawayTitle: string | null; + giveawayPrize: string | null; + giveawayValue: number | null; +} + +const Modal: React.FC = ({ + isOpen, + onClose, + title, + children, + giveawayId, + giveawayTitle, + giveawayPrize, + giveawayValue, +}) => { + if (!isOpen) return null; + + const handleSelectWinner = () => { + if (giveawayId) { + selectWinner(giveawayId) + .then((winner) => { + alert(`Winner selected: ${winner.youtubeHandle}`); + }) + .catch((error) => { + console.error("Error selecting winner:", error); + alert("Failed to select a winner or no entries in the Giveaway. Please try again."); + }); + } else { + alert("No giveaway ID provided."); + } + }; + + return ( +
+
+

{title}

+ {giveawayTitle && ( +

+ Giveaway Title: {giveawayTitle} +

+ )} + {giveawayPrize && ( +

+ Prize: {giveawayPrize} +

+ )} + {giveawayValue !== null && ( +

+ Value: {giveawayValue} coins +

+ )} +
{children}
+ + +
+
+ ); +}; + +export default Modal; \ No newline at end of file diff --git a/src/app/admin/SelectWinerServer.tsx b/src/app/admin/SelectWinerServer.tsx new file mode 100644 index 0000000..05efee4 --- /dev/null +++ b/src/app/admin/SelectWinerServer.tsx @@ -0,0 +1,46 @@ +"use server"; + +import { db } from "@/lib/db"; + +async function selectWinner(giveawayId: string) { + try { + const giveaway = await db.giveaway.findUnique({ + where: { id: giveawayId }, + include: { entries: true }, + }); + + if (!giveaway) { + throw new Error("Giveaway not found"); + } + + if (giveaway.entries.length === 0) { + throw new Error("No entries in this giveaway"); + } + + const randomIndex = Math.floor(Math.random() * giveaway.entries.length); + const winnerEntry = giveaway.entries[randomIndex]; + + const user = await db.user.findUnique({ + where: { id: winnerEntry.userId }, + select: { youtubeHandle: true }, + }); + + if (!user || !user.youtubeHandle) { + throw new Error("Winner's YouTube handle not found"); + } + + const winner = { + entry: winnerEntry, + youtubeHandle: user.youtubeHandle, + }; + + // Here you can add logic to notify the winner, e.g., send an email or a message + + return winner; + } catch (error) { + console.error("Error selecting winner:", error); + throw new Error("Failed to select winner"); + } +} + +export { selectWinner }; \ No newline at end of file