From 1d217133ab9897907fc6db3c60a010549292f4d6 Mon Sep 17 00:00:00 2001 From: Cypro Freelance <110410268+Proxyy587@users.noreply.github.com> Date: Thu, 18 Jul 2024 00:03:43 +0530 Subject: [PATCH] some minor changes --- app/(auth)/_components/Sidebar.tsx | 100 +++++++++---------- app/(auth)/admin/changelogs/page.tsx | 2 +- app/(auth)/admin/downloads/page.tsx | 125 +++++++++++++++++++++++- app/(auth)/admin/mods/page.tsx | 124 ++++++++++++++++++++++- app/api/delete/downloads/[id]/route.ts | 30 ++++++ app/api/delete/{ => logs}/[id]/route.ts | 0 app/api/delete/mods/[id]/route.ts | 30 ++++++ 7 files changed, 353 insertions(+), 58 deletions(-) create mode 100644 app/api/delete/downloads/[id]/route.ts rename app/api/delete/{ => logs}/[id]/route.ts (100%) create mode 100644 app/api/delete/mods/[id]/route.ts diff --git a/app/(auth)/_components/Sidebar.tsx b/app/(auth)/_components/Sidebar.tsx index 74bab14..39266f6 100644 --- a/app/(auth)/_components/Sidebar.tsx +++ b/app/(auth)/_components/Sidebar.tsx @@ -6,60 +6,60 @@ import { usePathname } from "next/navigation"; import { AdminLinks } from "@/constants"; const Sidebar = () => { - const pathname = usePathname(); - return ( - <> - + + ); }; export default Sidebar; diff --git a/app/(auth)/admin/changelogs/page.tsx b/app/(auth)/admin/changelogs/page.tsx index 5573a04..216fff1 100644 --- a/app/(auth)/admin/changelogs/page.tsx +++ b/app/(auth)/admin/changelogs/page.tsx @@ -105,7 +105,7 @@ const AdminLogPage = () => { const deleteLog = async (id: string) => { try { - const response = await fetch(`/api/delete/${id}`, { + const response = await fetch(`/api/delete/logs/${id}`, { method: "DELETE", }); if (response.ok) { diff --git a/app/(auth)/admin/downloads/page.tsx b/app/(auth)/admin/downloads/page.tsx index 52e8cc7..f91975f 100644 --- a/app/(auth)/admin/downloads/page.tsx +++ b/app/(auth)/admin/downloads/page.tsx @@ -1,6 +1,6 @@ "use client"; -import React from "react"; +import React, { useEffect, useState } from "react"; import { useForm, SubmitHandler } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; @@ -14,12 +14,31 @@ import { FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; -import { UploadButton, UploadDropzone } from "@/lib/uploadthing"; +import { UploadButton } from "@/lib/uploadthing"; import { downloadSchema } from "@/lib/validations/validation"; import { useToast } from "@/components/ui/use-toast"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; + +interface DownloadEntry { + _id: string; + fileName: string; + version: string; + downloadLink: string; + fileSize: string; +} const DownloadsPage = () => { const { toast } = useToast(); + const [downloads, setDownloads] = useState([]); + const [error, setError] = useState(null); + const [loading, setLoading] = useState(false); const form = useForm>({ resolver: zodResolver(downloadSchema), @@ -31,9 +50,35 @@ const DownloadsPage = () => { }, }); + const fetchDownloads = async () => { + try { + const response = await fetch("/api/downloads", { + method: "GET", + }); + if (response.ok) { + const data: DownloadEntry[] = await response.json(); + setDownloads(data); + } else { + throw new Error(`HTTP error! status: ${response.status}`); + } + } catch (error: any) { + setError(error.message || "Failed to fetch downloads"); + } + }; + + useEffect(() => { + fetchDownloads(); + const interval = setInterval(() => { + fetchDownloads(); + }, 10000); + + return () => clearInterval(interval); + }, []); + const onSubmit: SubmitHandler> = async ( data ) => { + setLoading(true); const response = await fetch("/api/upload", { method: "POST", headers: { @@ -44,14 +89,31 @@ const DownloadsPage = () => { if (response.ok) { form.reset(); - toast({ description: "Download Sucessfully Updated" }); - console.log("Upload successful"); + fetchDownloads(); + setLoading(false); + toast({ description: "Download Successfully Updated" }); } else { console.error("Upload failed"); + setLoading(false); toast({ description: "Uploading Failed", variant: "destructive" }); } }; + const deleteDownload = async (id: string) => { + try { + const response = await fetch(`/api/delete/downloads/${id}`, { + method: "DELETE", + }); + if (response.ok) { + fetchDownloads(); + } else { + throw new Error(`HTTP error! status: ${response.status}`); + } + } catch (error: any) { + setError(error.message || "Failed to delete download"); + } + }; + return (

Downloads Form

@@ -122,11 +184,66 @@ const DownloadsPage = () => { type="submit" className="w-full text-lg rounded-full" size={"lg"} + disabled={loading} > Submit + + {/* Section to list and delete downloads */} +
+

Existing Downloads

+ {error &&

{error}

} + + + + File Name + Version + + Download Link + + File Size + Actions + + + + {downloads + .slice() + .reverse() + .map((download) => ( + + + {download.fileName} + + + {download.version} + + + + {download.downloadLink} + + + + {download.fileSize} + + + + + + ))} + +
+
); }; diff --git a/app/(auth)/admin/mods/page.tsx b/app/(auth)/admin/mods/page.tsx index f540ecc..cae5f1b 100644 --- a/app/(auth)/admin/mods/page.tsx +++ b/app/(auth)/admin/mods/page.tsx @@ -1,6 +1,6 @@ "use client"; -import React from "react"; +import React, { useEffect, useState } from "react"; import { useForm, SubmitHandler } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; @@ -14,12 +14,32 @@ import { FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; -import { UploadButton, UploadDropzone } from "@/lib/uploadthing"; +import { UploadButton } from "@/lib/uploadthing"; import { modsSchema } from "@/lib/validations/validation"; import { useToast } from "@/components/ui/use-toast"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; + +interface ModEntry { + _id: string; + fileName: string; + version: string; + downloadLink: string; + fileSize: string; +} const SvrjsModsAdminPage = () => { const { toast } = useToast(); + const [mods, setMods] = useState([]); + const [error, setError] = useState(null); + const [loading, setLoading] = useState(false); + const form = useForm>({ resolver: zodResolver(modsSchema), defaultValues: { @@ -30,7 +50,33 @@ const SvrjsModsAdminPage = () => { }, }); + const fetchMods = async () => { + try { + const response = await fetch("/api/mods", { + method: "GET", + }); + if (response.ok) { + const data: ModEntry[] = await response.json(); + setMods(data); + } else { + throw new Error(`HTTP error! status: ${response.status}`); + } + } catch (error: any) { + setError(error.message || "Failed to fetch mods"); + } + }; + + useEffect(() => { + fetchMods(); + const interval = setInterval(() => { + fetchMods(); + }, 10000); + + return () => clearInterval(interval); + }, []); + const onSubmit: SubmitHandler> = async (data) => { + setLoading(true); const response = await fetch("/api/uploadmods", { method: "POST", headers: { @@ -41,12 +87,14 @@ const SvrjsModsAdminPage = () => { if (response.ok) { form.reset(); + fetchMods(); + setLoading(false); toast({ description: "Successfully Uploaded Mods", }); - console.log("Upload successful"); } else { console.error("Upload failed"); + setLoading(false); toast({ description: "Upload failed", variant: "destructive", @@ -54,6 +102,21 @@ const SvrjsModsAdminPage = () => { } }; + const deleteMod = async (id: string) => { + try { + const response = await fetch(`/api/delete/mods/${id}`, { + method: "DELETE", + }); + if (response.ok) { + fetchMods(); + } else { + throw new Error(`HTTP error! status: ${response.status}`); + } + } catch (error: any) { + setError(error.message || "Failed to delete mod"); + } + }; + return (

Mods Form

@@ -124,11 +187,66 @@ const SvrjsModsAdminPage = () => { type="submit" className="w-full text-lg rounded-full" size={"lg"} + disabled={loading} > Submit + + {/* Section to list and delete mods */} +
+

Existing Mods

+ {error &&

{error}

} + + + + File Name + Version + + Download Link + + File Size + Actions + + + + {mods + .slice() + .reverse() + .map((mod) => ( + + + {mod.fileName} + + + {mod.version} + + + + {mod.downloadLink} + + + + {mod.fileSize} + + + + + + ))} + +
+
); }; diff --git a/app/api/delete/downloads/[id]/route.ts b/app/api/delete/downloads/[id]/route.ts new file mode 100644 index 0000000..5a972ac --- /dev/null +++ b/app/api/delete/downloads/[id]/route.ts @@ -0,0 +1,30 @@ +// app/api/delete/[id]/route.ts +import clientPromise from "@/lib/db"; +import { ObjectId } from "mongodb"; +import { NextResponse } from "next/server"; + +export async function DELETE( + request: Request, + { params }: { params: { id: string } } +) { + const { id } = params; + + try { + const client = await clientPromise; + const db = client.db("downloadsDatabase"); + const collection = db.collection("downloads"); + + const result = await collection.deleteOne({ _id: new ObjectId(id) }); + + if (result.deletedCount === 1) { + return NextResponse.json({ message: "Log deleted successfully" }); + } else { + return NextResponse.json({ message: "Log not found" }, { status: 404 }); + } + } catch (error) { + return NextResponse.json( + { message: "Failed to delete log", error: error }, + { status: 500 } + ); + } +} diff --git a/app/api/delete/[id]/route.ts b/app/api/delete/logs/[id]/route.ts similarity index 100% rename from app/api/delete/[id]/route.ts rename to app/api/delete/logs/[id]/route.ts diff --git a/app/api/delete/mods/[id]/route.ts b/app/api/delete/mods/[id]/route.ts new file mode 100644 index 0000000..065d062 --- /dev/null +++ b/app/api/delete/mods/[id]/route.ts @@ -0,0 +1,30 @@ +// app/api/delete/[id]/route.ts +import clientPromise from "@/lib/db"; +import { ObjectId } from "mongodb"; +import { NextResponse } from "next/server"; + +export async function DELETE( + request: Request, + { params }: { params: { id: string } } +) { + const { id } = params; + + try { + const client = await clientPromise; + const db = client.db("downloadsDatabase"); + const collection = db.collection("mods"); + + const result = await collection.deleteOne({ _id: new ObjectId(id) }); + + if (result.deletedCount === 1) { + return NextResponse.json({ message: "Log deleted successfully" }); + } else { + return NextResponse.json({ message: "Log not found" }, { status: 404 }); + } + } catch (error) { + return NextResponse.json( + { message: "Failed to delete log", error: error }, + { status: 500 } + ); + } +}