Update, profile and part of admin

This commit is contained in:
EdiFarcas
2025-04-29 19:33:35 +03:00
parent 6cff4acc36
commit 9a33acbf53
9 changed files with 120 additions and 94 deletions
+73 -36
View File
@@ -9,13 +9,12 @@
"version": "0.1.0",
"dependencies": {
"@next-auth/prisma-adapter": "^1.0.7",
"@prisma/client": "^6.6.0",
"@prisma/client": "^6.7.0",
"autoprefixer": "^10.4.21",
"axios": "^1.9.0",
"next": "15.3.1",
"next-auth": "^4.24.11",
"postcss": "^8.5.3",
"prisma": "^6.6.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
@@ -27,6 +26,7 @@
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "15.3.1",
"prisma": "^6.7.0",
"tailwindcss": "^4.1.4",
"typescript": "^5"
}
@@ -96,6 +96,7 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -112,6 +113,7 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -128,6 +130,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -144,6 +147,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -160,6 +164,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -176,6 +181,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -192,6 +198,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -208,6 +215,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -224,6 +232,7 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -240,6 +249,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -256,6 +266,7 @@
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -272,6 +283,7 @@
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -288,6 +300,7 @@
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -304,6 +317,7 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -320,6 +334,7 @@
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -336,6 +351,7 @@
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -352,6 +368,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -368,6 +385,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -384,6 +402,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -400,6 +419,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -416,6 +436,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -432,6 +453,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -448,6 +470,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -464,6 +487,7 @@
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -480,6 +504,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1295,9 +1320,9 @@
}
},
"node_modules/@prisma/client": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.6.0.tgz",
"integrity": "sha512-vfp73YT/BHsWWOAuthKQ/1lBgESSqYqAWZEYyTdGXyFAHpmewwWL2Iz6ErIzkj4aHbuc6/cGSsE6ZY+pBO04Cg==",
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.7.0.tgz",
"integrity": "sha512-+k61zZn1XHjbZul8q6TdQLpuI/cvyfil87zqK2zpreNIXyXtpUv3+H/oM69hcsFcZXaokHJIzPAt5Z8C8eK2QA==",
"hasInstallScript": true,
"license": "Apache-2.0",
"engines": {
@@ -1317,9 +1342,10 @@
}
},
"node_modules/@prisma/config": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.6.0.tgz",
"integrity": "sha512-d8FlXRHsx72RbN8nA2QCRORNv5AcUnPXgtPvwhXmYkQSMF/j9cKaJg+9VcUzBRXGy9QBckNzEQDEJZdEOZ+ubA==",
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.7.0.tgz",
"integrity": "sha512-di8QDdvSz7DLUi3OOcCHSwxRNeW7jtGRUD2+Z3SdNE3A+pPiNT8WgUJoUyOwJmUr5t+JA2W15P78C/N+8RXrOA==",
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"esbuild": ">=0.12 <1",
@@ -1327,48 +1353,53 @@
}
},
"node_modules/@prisma/debug": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.6.0.tgz",
"integrity": "sha512-DL6n4IKlW5k2LEXzpN60SQ1kP/F6fqaCgU/McgaYsxSf43GZ8lwtmXLke9efS+L1uGmrhtBUP4npV/QKF8s2ZQ==",
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.7.0.tgz",
"integrity": "sha512-RabHn9emKoYFsv99RLxvfG2GHzWk2ZI1BuVzqYtmMSIcuGboHY5uFt3Q3boOREM9de6z5s3bQoyKeWnq8Fz22w==",
"devOptional": true,
"license": "Apache-2.0"
},
"node_modules/@prisma/engines": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.6.0.tgz",
"integrity": "sha512-nC0IV4NHh7500cozD1fBoTwTD1ydJERndreIjpZr/S3mno3P6tm8qnXmIND5SwUkibNeSJMpgl4gAnlqJ/gVlg==",
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.7.0.tgz",
"integrity": "sha512-3wDMesnOxPrOsq++e5oKV9LmIiEazFTRFZrlULDQ8fxdub5w4NgRBoxtWbvXmj2nJVCnzuz6eFix3OhIqsZ1jw==",
"devOptional": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "6.6.0",
"@prisma/engines-version": "6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a",
"@prisma/fetch-engine": "6.6.0",
"@prisma/get-platform": "6.6.0"
"@prisma/debug": "6.7.0",
"@prisma/engines-version": "6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed",
"@prisma/fetch-engine": "6.7.0",
"@prisma/get-platform": "6.7.0"
}
},
"node_modules/@prisma/engines-version": {
"version": "6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a.tgz",
"integrity": "sha512-JzRaQ5Em1fuEcbR3nUsMNYaIYrOT1iMheenjCvzZblJcjv/3JIuxXN7RCNT5i6lRkLodW5ojCGhR7n5yvnNKrw==",
"version": "6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed.tgz",
"integrity": "sha512-EvpOFEWf1KkJpDsBCrih0kg3HdHuaCnXmMn7XFPObpFTzagK1N0Q0FMnYPsEhvARfANP5Ok11QyoTIRA2hgJTA==",
"devOptional": true,
"license": "Apache-2.0"
},
"node_modules/@prisma/fetch-engine": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.6.0.tgz",
"integrity": "sha512-Ohfo8gKp05LFLZaBlPUApM0M7k43a0jmo86YY35u1/4t+vuQH9mRGU7jGwVzGFY3v+9edeb/cowb1oG4buM1yw==",
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.7.0.tgz",
"integrity": "sha512-zLlAGnrkmioPKJR4Yf7NfW3hftcvqeNNEHleMZK9yX7RZSkhmxacAYyfGsCcqRt47jiZ7RKdgE0Wh2fWnm7WsQ==",
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "6.6.0",
"@prisma/engines-version": "6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a",
"@prisma/get-platform": "6.6.0"
"@prisma/debug": "6.7.0",
"@prisma/engines-version": "6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed",
"@prisma/get-platform": "6.7.0"
}
},
"node_modules/@prisma/get-platform": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.6.0.tgz",
"integrity": "sha512-3qCwmnT4Jh5WCGUrkWcc6VZaw0JY7eWN175/pcb5Z6FiLZZ3ygY93UX0WuV41bG51a6JN/oBH0uywJ90Y+V5eA==",
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.7.0.tgz",
"integrity": "sha512-i9IH5lO4fQwnMLvQLYNdgVh9TK3PuWBfQd7QLk/YurnAIg+VeADcZDbmhAi4XBBDD+hDif9hrKyASu0hbjwabw==",
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "6.6.0"
"@prisma/debug": "6.7.0"
}
},
"node_modules/@rtsao/scc": {
@@ -2881,6 +2912,7 @@
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -3184,6 +3216,7 @@
"version": "0.25.3",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz",
"integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==",
"devOptional": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
@@ -3224,6 +3257,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz",
"integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"debug": "^4.3.4"
@@ -3873,6 +3907,7 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -5131,6 +5166,7 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"devOptional": true,
"license": "MIT"
},
"node_modules/nanoid": {
@@ -5675,14 +5711,15 @@
"license": "MIT"
},
"node_modules/prisma": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.6.0.tgz",
"integrity": "sha512-SYCUykz+1cnl6Ugd8VUvtTQq5+j1Q7C0CtzKPjQ8JyA2ALh0EEJkMCS+KgdnvKW1lrxjtjCyJSHOOT236mENYg==",
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.7.0.tgz",
"integrity": "sha512-vArg+4UqnQ13CVhc2WUosemwh6hr6cr6FY2uzDvCIFwH8pu8BXVv38PktoMLVjtX7sbYThxbnZF5YiR8sN2clw==",
"devOptional": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/config": "6.6.0",
"@prisma/engines": "6.6.0"
"@prisma/config": "6.7.0",
"@prisma/engines": "6.7.0"
},
"bin": {
"prisma": "build/index.js"
+2 -2
View File
@@ -10,13 +10,12 @@
},
"dependencies": {
"@next-auth/prisma-adapter": "^1.0.7",
"@prisma/client": "^6.6.0",
"@prisma/client": "^6.7.0",
"autoprefixer": "^10.4.21",
"axios": "^1.9.0",
"next": "15.3.1",
"next-auth": "^4.24.11",
"postcss": "^8.5.3",
"prisma": "^6.6.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
@@ -28,6 +27,7 @@
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "15.3.1",
"prisma": "^6.7.0",
"tailwindcss": "^4.1.4",
"typescript": "^5"
}
@@ -0,0 +1,7 @@
-- CreateTable
CREATE TABLE "Video" (
"id" TEXT NOT NULL,
"URL" TEXT,
CONSTRAINT "Video_pkey" PRIMARY KEY ("id")
);
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Video" ADD COLUMN "coins" INTEGER NOT NULL DEFAULT 0;
@@ -0,0 +1,8 @@
/*
Warnings:
- You are about to drop the `Video` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropTable
DROP TABLE "Video";
+14 -14
View File
@@ -71,7 +71,7 @@ export default function AdminClient({ email }: AdminClientProps) {
/>
<input
type="number"
placeholder="Value"
placeholder="Value in Dollars"
value={giveaway.value || ""}
onChange={(e) => setGiveaway({ ...giveaway, value: Number(e.target.value) })}
className="block w-full mt-2 p-2 border rounded bg-gray-700 text-gray-200"
@@ -95,24 +95,24 @@ export default function AdminClient({ email }: AdminClientProps) {
<div className="p-4 text-white bg-gray-800 shadow rounded">
<h2 className="text-xl font-semibold">Update User Coins</h2>
<input
type="text"
placeholder="User ID"
value={userCoins.userId}
onChange={(e) => setUserCoins({ ...userCoins, userId: e.target.value })}
className="block w-full mt-2 p-2 border rounded bg-gray-700 text-gray-200"
type="text"
placeholder="YouTube Video URL"
value={userCoins.userId}
onChange={(e) => setUserCoins({ ...userCoins, userId: e.target.value })}
className="block w-full mt-2 p-2 border rounded bg-gray-700 text-gray-200"
/>
<input
type="number"
placeholder="Coins"
value={userCoins.coins}
onChange={(e) => setUserCoins({ ...userCoins, coins: Number(e.target.value) })}
className="block w-full mt-2 p-2 border rounded bg-gray-700 text-gray-200"
type="number"
placeholder="Coins"
value={userCoins.coins}
onChange={(e) => setUserCoins({ ...userCoins, coins: Number(e.target.value) })}
className="block w-full mt-2 p-2 border rounded bg-gray-700 text-gray-200"
/>
<button
onClick={handleUpdateCoins}
className="mt-4 bg-green-600 text-white px-4 py-2 rounded"
onClick={handleUpdateCoins}
className="mt-4 bg-green-600 text-white px-4 py-2 rounded"
>
Update Coins
Update Coins
</button>
</div>
</div>
+7 -1
View File
@@ -1,10 +1,16 @@
import { getServerSession } from "next-auth";
import { authOptions } from "../api/auth/[...nextauth]/route";
import { db } from "@/lib/db";
import { redirect } from "next/navigation";
import GiveawayCard from "@/components/GiveawayCard";
export default async function GiveawaysPage() {
// Fetch giveaways from the database
const session = await getServerSession(authOptions);
if (!session?.user?.email) {
redirect("/api/auth/signin");
}
const giveaways = await db.giveaway.findMany({
where: { active: true },
select: {
+6 -40
View File
@@ -1,7 +1,5 @@
"use client";
import { useState } from "react";
interface User {
name: string;
email: string;
@@ -10,26 +8,6 @@ interface User {
}
export default function ProfileClient({ user }: { user: User }) {
const [youtubeHandle, setYoutubeHandle] = useState(user.youtubeHandle || "");
const [saving, setSaving] = useState(false);
const handleSave = async () => {
setSaving(true);
try {
const res = await fetch("/api/youtube-handle", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ youtubeHandle }),
});
if (!res.ok) throw new Error("Failed to update");
alert("YouTube handle updated successfully!");
} catch (error) {
console.error(error);
alert("Error updating handle.");
} finally {
setSaving(false);
}
};
return (
<div className="min-h-screen bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
@@ -68,24 +46,12 @@ export default function ProfileClient({ user }: { user: User }) {
</div>
</div>
<div className="flex flex-col space-y-2 p-3 bg-gray-50 rounded-lg">
<label className="text-sm text-black flex items-center">
<span className="text-lg mr-2">📺</span> YouTube Handle
</label>
<input
type="text"
className="p-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-purple-600 text-black"
placeholder="@yourhandle"
value={youtubeHandle}
onChange={(e) => setYoutubeHandle(e.target.value)}
/>
<button
onClick={handleSave}
disabled={saving}
className="bg-purple-600 text-white px-4 py-2 rounded-lg mt-2 hover:bg-purple-700 transition-colors disabled:opacity-50"
>
{saving ? "Saving..." : "Save Handle"}
</button>
<div className="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg">
<span className="text-lg">📺</span>
<div>
<p className="text-sm text-black">YouTube Handle</p>
<p className="font-medium text-gray-500">{user.youtubeHandle}</p>
</div>
</div>
</div>
+1 -1
View File
@@ -10,7 +10,7 @@ export default function AuthButtons() {
<div className="flex items-center gap-4">
{/* <p>Hi, {session.user?.name}!</p> */}
<button
onClick={() => signOut()}
onClick={() => {signOut()}}
className="bg-red-500 text-white px-4 py-2 rounded"
>
Sign Out