mirror of
https://github.com/EdiFarcas/Giveaway-app.git
synced 2026-06-22 05:00:55 +03:00
Color manegement to generic
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 150 KiB |
+129
-116
@@ -5,131 +5,144 @@ import handleUpdateCoins from "./AdminServer";
|
|||||||
import GiveawayManagement from "./GiveawayManagementCards";
|
import GiveawayManagement from "./GiveawayManagementCards";
|
||||||
|
|
||||||
interface AdminClientProps {
|
interface AdminClientProps {
|
||||||
email: string;
|
email: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AdminClient({ email }: AdminClientProps) {
|
export default function AdminClient({ email }: AdminClientProps) {
|
||||||
const [giveaway, setGiveaway] = useState({
|
const [giveaway, setGiveaway] = useState({
|
||||||
title: "",
|
title: "",
|
||||||
description: "",
|
description: "",
|
||||||
value: 0,
|
value: 0,
|
||||||
prize: "",
|
prize: "",
|
||||||
entryCost: 70000000,
|
entryCost: 70000000,
|
||||||
duration: 0,
|
duration: 0,
|
||||||
endsAt: new Date(Date.now() + 24 * 60 * 60 * 1000).getTime() // Set to tomorrow
|
endsAt: new Date(Date.now() + 24 * 60 * 60 * 1000).getTime(),
|
||||||
|
});
|
||||||
|
const [youtube_url, setYoutubeUrl] = useState("");
|
||||||
|
const [coin_value, setCoinValue] = useState(0);
|
||||||
|
const [showGiveawayManagement, setShowGiveawayManagement] = useState(false);
|
||||||
|
|
||||||
|
const handleCreateGiveaway = async () => {
|
||||||
|
const response = await fetch("/api/admin/create-giveaway", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(giveaway),
|
||||||
});
|
});
|
||||||
const [youtube_url, setYoutubeUrl] = useState("");
|
if (response.ok) {
|
||||||
const [coin_value, setCoinValue] = useState(0);
|
alert("Giveaway created successfully!");
|
||||||
const [showGiveawayManagement, setShowGiveawayManagement] = useState(false);
|
setGiveaway({
|
||||||
|
title: "",
|
||||||
|
description: "",
|
||||||
|
value: 0,
|
||||||
|
prize: "",
|
||||||
|
entryCost: 70000000,
|
||||||
|
duration: 0,
|
||||||
|
endsAt: new Date(Date.now() + 24 * 60 * 60 * 1000).getTime(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const error = await response.json();
|
||||||
|
alert(`Failed to create giveaway: ${error.error}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleCreateGiveaway = async () => {
|
return (
|
||||||
const response = await fetch("/api/admin/create-giveaway", {
|
<div className="min-h-screen bg-gradient-to-br from-gray-900 to-gray-800 text-white py-12 px-4 sm:px-6 lg:px-8">
|
||||||
method: "POST",
|
<div className="max-w-3xl mx-auto space-y-10">
|
||||||
headers: { "Content-Type": "application/json" },
|
<h1 className="text-4xl font-bold text-white">Admin Dashboard</h1>
|
||||||
body: JSON.stringify(giveaway),
|
<p className="text-lg text-gray-300">
|
||||||
});
|
Welcome, <span className="font-medium">{email}</span>!
|
||||||
if (response.ok) {
|
</p>
|
||||||
alert("Giveaway created successfully!");
|
|
||||||
|
|
||||||
setGiveaway({ title: "", description: "", value: 0, prize: "", entryCost: 70000000, duration: 0, endsAt: new Date(Date.now() + 24 * 60 * 60 * 1000).getTime() }); // Reset form
|
|
||||||
} else {
|
|
||||||
const error = await response.json();
|
|
||||||
alert(`Failed to create giveaway: ${error.error}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
{/* Create Giveaway Form */}
|
||||||
<div className="min-h-screen bg-gradient-to-br from-yellow-50 to-pink-100 text-black py-12 px-4 sm:px-6 lg:px-8">
|
<div className="bg-gray-800 border border-gray-700 p-6 rounded-2xl shadow-lg">
|
||||||
<div className="max-w-3xl mx-auto space-y-10">
|
<h2 className="text-2xl font-semibold text-white mb-4">🎁 Create Giveaway</h2>
|
||||||
<h1 className="text-4xl font-bold text-pink-700">Admin Dashboard</h1>
|
<div className="space-y-3">
|
||||||
<p className="text-lg text-gray-700">Welcome, <span className="font-medium">{email}</span>!</p>
|
<input
|
||||||
|
type="text"
|
||||||
{/* Create Giveaway Form */}
|
placeholder="Giveaway Title"
|
||||||
<div className="bg-white border border-pink-200 p-6 rounded-2xl shadow-lg">
|
value={giveaway.title}
|
||||||
<h2 className="text-2xl font-semibold text-pink-700 mb-4">🎁 Create Giveaway</h2>
|
onChange={(e) => setGiveaway({ ...giveaway, title: e.target.value })}
|
||||||
<div className="space-y-3">
|
className="w-full p-3 border border-gray-600 rounded-lg bg-gray-900 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-white"
|
||||||
<input
|
/>
|
||||||
type="text"
|
<textarea
|
||||||
placeholder="Giveaway Title"
|
placeholder="Description"
|
||||||
value={giveaway.title}
|
value={giveaway.description}
|
||||||
onChange={(e) => setGiveaway({ ...giveaway, title: e.target.value })}
|
onChange={(e) => setGiveaway({ ...giveaway, description: e.target.value })}
|
||||||
className="w-full p-3 border border-pink-200 rounded-lg bg-white text-gray-700 focus:outline-none focus:ring-2 focus:ring-pink-400"
|
className="w-full p-3 border border-gray-600 rounded-lg bg-gray-900 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-white"
|
||||||
/>
|
/>
|
||||||
<textarea
|
<input
|
||||||
placeholder="Description"
|
type="text"
|
||||||
value={giveaway.description}
|
placeholder="Prize"
|
||||||
onChange={(e) => setGiveaway({ ...giveaway, description: e.target.value })}
|
value={giveaway.prize}
|
||||||
className="w-full p-3 border border-pink-200 rounded-lg bg-white text-gray-700 focus:outline-none focus:ring-2 focus:ring-pink-400"
|
onChange={(e) => setGiveaway({ ...giveaway, prize: e.target.value })}
|
||||||
/>
|
className="w-full p-3 border border-gray-600 rounded-lg bg-gray-900 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-white"
|
||||||
<input
|
/>
|
||||||
type="text"
|
<input
|
||||||
placeholder="Prize"
|
type="number"
|
||||||
value={giveaway.prize}
|
placeholder="Value in Coins"
|
||||||
onChange={(e) => setGiveaway({ ...giveaway, prize: e.target.value })}
|
value={giveaway.value || ""}
|
||||||
className="w-full p-3 border border-pink-200 rounded-lg bg-white text-gray-700 focus:outline-none focus:ring-2 focus:ring-pink-400"
|
onChange={(e) => setGiveaway({ ...giveaway, value: Number(e.target.value) })}
|
||||||
/>
|
className="w-full p-3 border border-gray-600 rounded-lg bg-gray-900 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-white"
|
||||||
<input
|
/>
|
||||||
type="number"
|
<input
|
||||||
placeholder="Value in Coins"
|
type="datetime-local"
|
||||||
value={giveaway.value || ""}
|
placeholder="Ends At"
|
||||||
onChange={(e) => setGiveaway({ ...giveaway, value: Number(e.target.value) })}
|
value={giveaway.endsAt ? new Date(giveaway.endsAt).toISOString().slice(0, 16) : ""}
|
||||||
className="w-full p-3 border border-pink-200 rounded-lg bg-white text-gray-700 focus:outline-none focus:ring-2 focus:ring-pink-400"
|
onChange={(e) => setGiveaway({ ...giveaway, endsAt: Date.parse(e.target.value) })}
|
||||||
/>
|
className="w-full p-3 border border-gray-600 rounded-lg bg-gray-900 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-white"
|
||||||
<input
|
/>
|
||||||
type="datetime-local"
|
|
||||||
placeholder="Ends At"
|
|
||||||
value={giveaway.endsAt ? new Date(giveaway.endsAt).toISOString().slice(0, 16) : ""}
|
|
||||||
onChange={(e) => setGiveaway({ ...giveaway, endsAt: Date.parse(e.target.value) })}
|
|
||||||
className="w-full p-3 border border-pink-200 rounded-lg bg-white text-gray-700 focus:outline-none focus:ring-2 focus:ring-pink-400"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
onClick={handleCreateGiveaway}
|
|
||||||
className="w-full bg-gradient-to-r from-pink-500 to-yellow-400 text-white font-semibold py-3 rounded-lg hover:brightness-110 transition-all shadow"
|
|
||||||
>
|
|
||||||
🚀 Create Giveaway
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Update User Coins Form */}
|
|
||||||
<div className="bg-white border border-green-200 p-6 rounded-2xl shadow-lg">
|
|
||||||
<h2 className="text-2xl font-semibold text-green-700 mb-4">💸 Update User Coins</h2>
|
|
||||||
<div className="space-y-3">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder="YouTube Video URL"
|
|
||||||
value={youtube_url}
|
|
||||||
onChange={(e) => setYoutubeUrl(e.target.value)}
|
|
||||||
className="w-full p-3 border border-green-200 rounded-lg bg-white text-gray-700 focus:outline-none focus:ring-2 focus:ring-green-400"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
placeholder="Coins to Add"
|
|
||||||
value={coin_value || ""}
|
|
||||||
onChange={(e) => setCoinValue(Number(e.target.value))}
|
|
||||||
className="w-full p-3 border border-green-200 rounded-lg bg-white text-gray-700 focus:outline-none focus:ring-2 focus:ring-green-400"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
onClick={() => handleUpdateCoins(youtube_url, coin_value)}
|
|
||||||
className="w-full bg-gradient-to-r from-green-500 to-lime-400 text-white font-semibold py-3 rounded-lg hover:brightness-110 transition-all shadow"
|
|
||||||
>
|
|
||||||
✅ Update Coins
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Toggle Giveaway Management */}
|
|
||||||
<div className="bg-white border border-blue-200 p-6 rounded-2xl shadow-lg">
|
|
||||||
<h2 className="text-2xl font-semibold text-blue-700 mb-4">🎮 Giveaway Management</h2>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowGiveawayManagement((prev) => !prev)}
|
onClick={handleCreateGiveaway}
|
||||||
className="w-full bg-gradient-to-r from-blue-500 to-indigo-400 text-white font-semibold py-3 rounded-lg hover:brightness-110 transition-all shadow"
|
className="w-full bg-gradient-to-r from-white to-gray-400 text-black font-semibold py-3 rounded-lg hover:brightness-110 transition-all shadow"
|
||||||
>
|
>
|
||||||
{showGiveawayManagement ? "Hide Giveaway Management" : "Show Giveaway Management"}
|
🚀 Create Giveaway
|
||||||
</button>
|
</button>
|
||||||
{showGiveawayManagement && <GiveawayManagement />}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Update User Coins Form */}
|
||||||
|
<div className="bg-gray-800 border border-gray-700 p-6 rounded-2xl shadow-lg">
|
||||||
|
<h2 className="text-2xl font-semibold text-white mb-4">💸 Update User Coins</h2>
|
||||||
|
<div className="space-y-3">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="YouTube Video URL"
|
||||||
|
value={youtube_url}
|
||||||
|
onChange={(e) => setYoutubeUrl(e.target.value)}
|
||||||
|
className="w-full p-3 border border-gray-600 rounded-lg bg-gray-900 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-white"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
placeholder="Coins to Add"
|
||||||
|
value={coin_value || ""}
|
||||||
|
onChange={(e) => setCoinValue(Number(e.target.value))}
|
||||||
|
className="w-full p-3 border border-gray-600 rounded-lg bg-gray-900 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-white"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={() => handleUpdateCoins(youtube_url, coin_value)}
|
||||||
|
className="w-full bg-gradient-to-r from-white to-gray-400 text-black font-semibold py-3 rounded-lg hover:brightness-110 transition-all shadow"
|
||||||
|
>
|
||||||
|
✅ Update Coins
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Toggle Giveaway Management */}
|
||||||
|
<div className="bg-gray-800 border border-gray-700 p-6 rounded-2xl shadow-lg">
|
||||||
|
<h2 className="text-2xl font-semibold text-white mb-4">🎮 Giveaway Management</h2>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowGiveawayManagement((prev) => !prev)}
|
||||||
|
className="w-full bg-gradient-to-r from-white to-gray-400 text-black font-semibold py-3 rounded-lg hover:brightness-110 transition-all shadow"
|
||||||
|
>
|
||||||
|
{showGiveawayManagement ? "Hide Giveaway Management" : "Show Giveaway Management"}
|
||||||
|
</button>
|
||||||
|
{showGiveawayManagement && (
|
||||||
|
<div className="mt-6">
|
||||||
|
<GiveawayManagement />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|||||||
+30
-31
@@ -8,7 +8,7 @@ export default async function GiveawaysPage() {
|
|||||||
const session = await getServerSession(authOptions);
|
const session = await getServerSession(authOptions);
|
||||||
|
|
||||||
if (!session?.user?.email) {
|
if (!session?.user?.email) {
|
||||||
redirect("/api/auth/signin");
|
redirect("/api/auth/signin");
|
||||||
}
|
}
|
||||||
|
|
||||||
const giveaways = await db.giveaway.findMany({
|
const giveaways = await db.giveaway.findMany({
|
||||||
@@ -35,64 +35,63 @@ export default async function GiveawaysPage() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-yellow-50 to-pink-100 py-12 px-4 sm:px-6 lg:px-8 font-sans">
|
<div className="min-h-screen bg-gradient-to-br from-gray-900 to-gray-800 py-12 px-4 sm:px-6 lg:px-8 font-sans text-white">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="max-w-7xl mx-auto">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<h1 className="text-4xl sm:text-5xl font-bold mb-10 text-center drop-shadow-md">
|
<h1 className="text-4xl sm:text-5xl font-bold mb-10 text-center drop-shadow-md">
|
||||||
🎁
|
🎁{" "}
|
||||||
{" "}
|
<span className="bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
|
||||||
<span className="bg-gradient-to-r from-pink-600 to-yellow-500 bg-clip-text text-transparent">
|
|
||||||
Active Giveaways
|
Active Giveaways
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{/* Grid of Cards */}
|
{/* Grid of Cards */}
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 text-black">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 text-black">
|
||||||
{giveaways
|
{giveaways
|
||||||
.filter((giveaway) => {
|
.filter((giveaway) => {
|
||||||
const remainingTime =
|
const remainingTime =
|
||||||
new Date(giveaway.endsAt ?? 0).getTime() - Date.now();
|
new Date(giveaway.endsAt ?? 0).getTime() - Date.now();
|
||||||
return remainingTime > 0;
|
return remainingTime > 0;
|
||||||
})
|
})
|
||||||
.map((giveaway) => {
|
.map((giveaway) => {
|
||||||
const remainingTime = Math.max(
|
const remainingTime = Math.max(
|
||||||
0,
|
0,
|
||||||
new Date(giveaway.endsAt ?? 0).getTime() - Date.now()
|
new Date(giveaway.endsAt ?? 0).getTime() - Date.now()
|
||||||
);
|
);
|
||||||
|
|
||||||
const days = Math.floor(remainingTime / (1000 * 60 * 60 * 24));
|
const days = Math.floor(remainingTime / (1000 * 60 * 60 * 24));
|
||||||
const hours = Math.floor(
|
const hours = Math.floor(
|
||||||
(remainingTime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
|
(remainingTime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
|
||||||
);
|
);
|
||||||
const minutes = Math.floor(
|
const minutes = Math.floor(
|
||||||
(remainingTime % (1000 * 60 * 60)) / (1000 * 60)
|
(remainingTime % (1000 * 60 * 60)) / (1000 * 60)
|
||||||
);
|
);
|
||||||
|
|
||||||
const countdownText =
|
const countdownText =
|
||||||
days > 0
|
days > 0
|
||||||
? `${days}d ${hours}h ${minutes}m left`
|
? `${days}d ${hours}h ${minutes}m left`
|
||||||
: hours > 0
|
: hours > 0
|
||||||
? `${hours}h ${minutes}m left`
|
? `${hours}h ${minutes}m left`
|
||||||
: `${minutes}m left`;
|
: `${minutes}m left`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={giveaway.id}
|
key={giveaway.id}
|
||||||
className="bg-white rounded-2xl shadow-lg border-2 border-pink-200 hover:shadow-xl transition-shadow duration-300"
|
className="bg-gray-800 rounded-2xl shadow-lg border border-gray-600 hover:shadow-xl transition-shadow duration-300"
|
||||||
>
|
>
|
||||||
<GiveawayCard
|
<GiveawayCard
|
||||||
giveawayId={giveaway.id}
|
giveawayId={giveaway.id}
|
||||||
title={giveaway.title}
|
title={giveaway.title}
|
||||||
description={`${giveaway.description} — 🕒 ${countdownText}`}
|
description={`${giveaway.description} — 🕒 ${countdownText}`}
|
||||||
imageUrl={giveaway.prize}
|
imageUrl={giveaway.prize}
|
||||||
value={giveaway.value}
|
value={giveaway.value}
|
||||||
userId={user?.id ?? ""}
|
userId={user?.id ?? ""}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+51
-58
@@ -7,78 +7,73 @@ export default function GiveawaySystem() {
|
|||||||
const [activeTab, setActiveTab] = useState("how");
|
const [activeTab, setActiveTab] = useState("how");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-yellow-100 to-pink-200 py-12 px-4 sm:px-6 lg:px-8 font-sans">
|
<div className="min-h-screen bg-gradient-to-br from-gray-900 to-gray-700 py-12 px-4 sm:px-6 lg:px-8 font-sans text-white">
|
||||||
<div className="max-w-4xl mx-auto">
|
<div className="max-w-4xl mx-auto">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="text-center mb-12">
|
<div className="text-center mb-12">
|
||||||
<Image
|
<Image
|
||||||
src="/images/logo-tcg-love.png"
|
src="/images/generic_logo.jpg"
|
||||||
alt="TCG Love Openings Logo"
|
alt="Giveaway Logo"
|
||||||
width={120}
|
width={100}
|
||||||
height={120}
|
height={100}
|
||||||
className="mx-auto mb-4 rounded-full border-4 border-pink-400 shadow-lg"
|
className="mx-auto mb-4 rounded-full border-4 border-gray-500 shadow-lg"
|
||||||
/>
|
/>
|
||||||
<h1 className="text-4xl sm:text-5xl font-bold mb-2 drop-shadow">
|
<h1 className="text-4xl sm:text-5xl font-bold mb-2">🎁 Giveaway System</h1>
|
||||||
🎁{" "}
|
<p className="text-lg text-gray-300">Earn points. Join raffles. Win rewards.</p>
|
||||||
<span className="bg-gradient-to-r from-pink-600 to-yellow-500 bg-clip-text text-transparent">
|
|
||||||
TCG Love Giveaway System
|
|
||||||
</span>
|
|
||||||
</h1>
|
|
||||||
<p className="text-lg text-gray-700">Comment. Collect Coins. Win MTG Cards!</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tabs */}
|
{/* Tabs */}
|
||||||
<div className="flex justify-center mb-8 space-x-4">
|
<div className="flex justify-center mb-8 space-x-4">
|
||||||
{["how", "lottery", "entries", "patreon"].map((tab) => (
|
{["how", "lottery", "entries", "perks"].map((tab) => (
|
||||||
<button
|
<button
|
||||||
key={tab}
|
key={tab}
|
||||||
onClick={() => setActiveTab(tab)}
|
onClick={() => setActiveTab(tab)}
|
||||||
className={`px-4 py-2 rounded-full font-semibold shadow transition ${
|
className={`px-4 py-2 rounded-full font-semibold shadow transition ${
|
||||||
activeTab === tab
|
activeTab === tab
|
||||||
? "bg-pink-600 text-white"
|
? "bg-white text-black"
|
||||||
: "bg-white text-pink-600 border border-pink-300"
|
: "bg-gray-800 text-white border border-gray-500"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{tab === "how" && "🪙 How It Works"}
|
{tab === "how" && "ℹ️ How It Works"}
|
||||||
{tab === "lottery" && "🎲 Lottery"}
|
{tab === "lottery" && "🎲 Lottery"}
|
||||||
{tab === "entries" && "🎟️ Entry Scaling"}
|
{tab === "entries" && "📊 Entry Scaling"}
|
||||||
{tab === "patreon" && "💖 Patreon Perks"}
|
{tab === "perks" && "⭐ Perks"}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tab Content */}
|
{/* Tab Content */}
|
||||||
<div className="bg-white rounded-2xl shadow-xl p-6 border-2 border-yellow-300 transition-all duration-300">
|
<div className="bg-gray-800 rounded-2xl shadow-xl p-6 border-2 border-gray-600 transition-all duration-300">
|
||||||
{activeTab === "how" && (
|
{activeTab === "how" && (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-2xl font-bold text-yellow-700 mb-4">How It Works</h2>
|
<h2 className="text-2xl font-bold text-white mb-4">How It Works</h2>
|
||||||
<ol className="list-decimal pl-6 space-y-3 text-gray-800">
|
<ol className="list-decimal pl-6 space-y-3 text-gray-200">
|
||||||
<li>💬 Comment on any TCG Love video to earn its coin value.</li>
|
<li>💬 Interact to earn points.</li>
|
||||||
<li>🎁 Use coins to join giveaways (10% of prize value = 1 entry).</li>
|
<li>🎁 Spend points to enter giveaways.</li>
|
||||||
<li>📈 Entry costs increase after 50, 100, 150 entries.</li>
|
<li>📈 Entry cost increases with volume.</li>
|
||||||
<li>🔥 Some high-value giveaways require you to burn coins.</li>
|
<li>🔥 Premium rewards may require point burning.</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === "lottery" && (
|
{activeTab === "lottery" && (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-2xl font-bold text-purple-700 mb-4">Weighted Lottery</h2>
|
<h2 className="text-2xl font-bold text-white mb-4">Weighted Lottery</h2>
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{[
|
{[
|
||||||
{ label: "First 100 coins", value: "1x", percent: 100, color: "bg-yellow-400" },
|
{ label: "First 100 points", value: "1x", percent: 100 },
|
||||||
{ label: "Next 100 coins", value: "0.5x", percent: 50, color: "bg-green-400" },
|
{ label: "Next 100 points", value: "0.5x", percent: 50 },
|
||||||
{ label: "Next 100 coins", value: "0.25x", percent: 25, color: "bg-blue-400" },
|
{ label: "Next 100 points", value: "0.25x", percent: 25 },
|
||||||
{ label: "Coins beyond 300", value: "0.1x", percent: 10, color: "bg-red-400" },
|
{ label: "Beyond 300 points", value: "0.1x", percent: 10 },
|
||||||
].map((tier, i) => (
|
].map((tier, i) => (
|
||||||
<div key={i} className="space-y-1">
|
<div key={i} className="space-y-1">
|
||||||
<div className="flex justify-between font-medium text-sm text-gray-700">
|
<div className="flex justify-between font-medium text-sm text-gray-300">
|
||||||
<span>{tier.label}</span>
|
<span>{tier.label}</span>
|
||||||
<span>{tier.value}</span>
|
<span>{tier.value}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full h-3 rounded-full bg-gray-200 overflow-hidden">
|
<div className="w-full h-3 rounded-full bg-gray-600 overflow-hidden">
|
||||||
<div
|
<div
|
||||||
className={`${tier.color} h-full`}
|
className="bg-white h-full"
|
||||||
style={{ width: `${tier.percent}%` }}
|
style={{ width: `${tier.percent}%` }}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -90,47 +85,45 @@ export default function GiveawaySystem() {
|
|||||||
|
|
||||||
{activeTab === "entries" && (
|
{activeTab === "entries" && (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-2xl font-bold text-blue-700 mb-4">Entry Scaling & Burning</h2>
|
<h2 className="text-2xl font-bold text-white mb-4">Entry Scaling</h2>
|
||||||
<p className="text-sm mb-4 text-gray-700">
|
<p className="text-sm mb-4 text-gray-300">
|
||||||
Each giveaway has a base coin cost for one entry. As more entries are added, the cost increases:
|
Entry costs rise as more participants join:
|
||||||
</p>
|
</p>
|
||||||
<ul className="list-disc pl-5 text-sm text-gray-800 space-y-2">
|
<ul className="list-disc pl-5 text-sm text-gray-200 space-y-2">
|
||||||
<li>🔹 First 50 entries: 10% of prize value</li>
|
<li>🔹 First 50 entries: standard rate</li>
|
||||||
<li>🔸 51–100 entries: 15%</li>
|
<li>🔸 51–100 entries: higher rate</li>
|
||||||
<li>🔥 100+ entries: 20% + potential coin burn for top-tier cards</li>
|
<li>🔥 100+ entries: premium rate + possible point burn</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div className="mt-4 bg-blue-100 p-4 rounded-lg text-blue-800 text-sm">
|
<div className="mt-4 bg-gray-700 p-4 rounded-lg text-gray-200 text-sm">
|
||||||
💡 Some $50+ giveaways will ask you to burn coins (e.g., +50 coins per extra entry).
|
💡 High-value giveaways may require additional point expenditure.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === "patreon" && (
|
{activeTab === "perks" && (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-2xl font-bold text-red-600 mb-4">Support Us on Patreon</h2>
|
<h2 className="text-2xl font-bold text-white mb-4">Supporter Perks</h2>
|
||||||
<p className="text-gray-800 mb-2">
|
<p className="text-gray-300 mb-2">
|
||||||
Become a patron and receive coins automatically every month — no commenting required!
|
Get automatic point rewards and exclusive access by supporting us.
|
||||||
</p>
|
</p>
|
||||||
<ul className="list-disc pl-5 text-sm text-gray-800 space-y-2">
|
<ul className="list-disc pl-5 text-sm text-gray-200 space-y-2">
|
||||||
<li>💎 Monthly coin drops based on your tier</li>
|
<li>💎 Monthly point drops</li>
|
||||||
<li>🎟️ Access to patron-only giveaways</li>
|
<li>🎟️ Private giveaways</li>
|
||||||
<li>🚀 Helps keep the pack openings flowing!</li>
|
<li>🚀 Support the system’s growth</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a
|
<a
|
||||||
href="https://patreon.com/TCG_Love?utm_medium=clipboard_copy&utm_source=copyLink&utm_campaign=creatorshare_fan&utm_content=join_link"
|
href="#"
|
||||||
target="_blank"
|
className="inline-block mt-4 px-4 py-2 rounded-full bg-white text-black font-semibold shadow hover:bg-gray-300 transition"
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="inline-block mt-4 px-4 py-2 rounded-full bg-pink-500 text-white font-semibold shadow hover:bg-pink-600 transition"
|
|
||||||
>
|
>
|
||||||
Join Patreon
|
Learn More
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<div className="mt-10 text-center text-sm text-gray-500">
|
<div className="mt-10 text-center text-sm text-gray-400">
|
||||||
<p>⚠️ This system is evolving — always check our Discord or YouTube for updates.</p>
|
<p>⚠️ This system is evolving. Stay tuned for updates.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,62 +8,66 @@ interface User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ProfileClient({ user }: { user: User }) {
|
export default function ProfileClient({ user }: { user: User }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-pink-50 to-yellow-100 py-12 px-4 sm:px-6 lg:px-8">
|
<div className="min-h-screen bg-gradient-to-br from-gray-900 to-gray-700 py-12 px-4 sm:px-6 lg:px-8 text-white">
|
||||||
<div className="max-w-3xl mx-auto">
|
<div className="max-w-3xl mx-auto">
|
||||||
<div className="rounded-3xl shadow-xl overflow-hidden bg-white border-4 border-pink-200">
|
<div className="rounded-3xl shadow-xl overflow-hidden bg-gray-800 border-4 border-gray-700">
|
||||||
{/* Profile Header */}
|
{/* Profile Header */}
|
||||||
<div className="bg-gradient-to-r from-pink-600 to-yellow-500 p-6 flex items-center space-x-4">
|
<div className="bg-gradient-to-r from-gray-700 to-gray-900 p-6 flex items-center space-x-4">
|
||||||
<div className="h-16 w-16 bg-white rounded-full shadow-lg flex items-center justify-center">
|
<div className="h-16 w-16 bg-gray-100 rounded-full shadow-lg flex items-center justify-center">
|
||||||
<span className="text-3xl font-bold bg-gradient-to-r from-pink-600 to-yellow-400 bg-clip-text text-transparent">
|
<span className="text-3xl font-bold text-gray-900">
|
||||||
{user.name?.[0]?.toUpperCase() || 'U'}
|
{user.name?.[0]?.toUpperCase() || "U"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-bold text-white drop-shadow">{user.name}</h1>
|
<h1 className="text-2xl font-bold text-white drop-shadow">{user.name}</h1>
|
||||||
<p className="text-yellow-100 italic">🌟 Premium Member</p>
|
<p className="text-gray-400 italic">🌟 Premium Member</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Profile Info & Wallet */}
|
{/* Profile Info & Wallet */}
|
||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
{/* Info Block */}
|
{/* Info Block */}
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{[["👤", "Full Name", user.name], ["📧", "Email Address", user.email], ["📺", "YouTube Handle", user.youtubeHandle]].map(
|
{[
|
||||||
([icon, label, value], index) => (
|
["👤", "Full Name", user.name],
|
||||||
<div key={index} className="flex items-center space-x-3 p-3 bg-white border border-pink-100 rounded-xl shadow-sm">
|
["📧", "Email Address", user.email],
|
||||||
<span className="text-xl">{icon}</span>
|
["📺", "YouTube Handle", user.youtubeHandle],
|
||||||
<div>
|
].map(([icon, label, value], index) => (
|
||||||
<p className="text-sm text-gray-700">{label}</p>
|
<div
|
||||||
<p className="font-medium text-gray-500">{value}</p>
|
key={index}
|
||||||
</div>
|
className="flex items-center space-x-3 p-3 bg-gray-700 border border-gray-600 rounded-xl shadow-sm"
|
||||||
</div>
|
>
|
||||||
)
|
<span className="text-xl">{icon}</span>
|
||||||
)}
|
<div>
|
||||||
</div>
|
<p className="text-sm text-gray-300">{label}</p>
|
||||||
|
<p className="font-medium text-gray-100">{value || "—"}</p>
|
||||||
{/* Wallet */}
|
|
||||||
<div className="bg-yellow-50 border border-yellow-200 rounded-2xl p-5 shadow-inner">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<div>
|
|
||||||
<p className="text-sm text-yellow-600 mb-1">Available Balance</p>
|
|
||||||
<div className="flex items-baseline space-x-2">
|
|
||||||
<span className="text-lg">💰</span>
|
|
||||||
<span className="text-2xl font-bold text-black">{user.coins}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button className="bg-gradient-to-r from-yellow-400 to-pink-500 text-white px-4 py-2 rounded-xl hover:brightness-110 transition-all shadow-md">
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Wallet */}
|
||||||
|
<div className="bg-gray-700 border border-gray-600 rounded-2xl p-5 shadow-inner">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p className="text-sm text-gray-300 mb-1">Available Balance</p>
|
||||||
|
<div className="flex items-baseline space-x-2">
|
||||||
|
<span className="text-lg">💰</span>
|
||||||
|
<span className="text-2xl font-bold text-white">{user.coins}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button className="bg-white text-black px-4 py-2 rounded-xl hover:bg-gray-200 transition-all shadow-md font-semibold">
|
||||||
Add Coins
|
Add Coins
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Achievements */}
|
{/* Achievements */}
|
||||||
<div className="mt-10 pt-6 border-t border-pink-100">
|
<div className="mt-10 pt-6 border-t border-gray-600">
|
||||||
<h3 className="text-xl font-bold mb-4 flex items-center text-pink-700">
|
<h3 className="text-xl font-bold mb-4 flex items-center text-white">
|
||||||
<span className="text-2xl mr-2">⭐</span>
|
<span className="text-2xl mr-2">⭐</span>
|
||||||
Achievements
|
Achievements
|
||||||
</h3>
|
</h3>
|
||||||
@@ -73,9 +77,12 @@ export default function ProfileClient({ user }: { user: User }) {
|
|||||||
["12", "Active Days"],
|
["12", "Active Days"],
|
||||||
["3", "Badges Earned"],
|
["3", "Badges Earned"],
|
||||||
].map(([value, label], idx) => (
|
].map(([value, label], idx) => (
|
||||||
<div key={idx} className="text-center p-4 bg-white rounded-xl shadow-sm border border-pink-100">
|
<div
|
||||||
<div className="text-2xl font-bold text-pink-600">{value}</div>
|
key={idx}
|
||||||
<div className="text-sm text-gray-500">{label}</div>
|
className="text-center p-4 bg-gray-700 rounded-xl shadow-sm border border-gray-600"
|
||||||
|
>
|
||||||
|
<div className="text-2xl font-bold text-white">{value}</div>
|
||||||
|
<div className="text-sm text-gray-300">{label}</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -84,5 +91,5 @@ export default function ProfileClient({ user }: { user: User }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user