done edit/mods
This commit is contained in:
parent
7fb098bc73
commit
b6459b529e
7 changed files with 240 additions and 52 deletions
|
@ -25,6 +25,12 @@ import {
|
|||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
|
||||
interface ModEntry {
|
||||
_id: string;
|
||||
|
@ -37,10 +43,12 @@ interface ModEntry {
|
|||
const SvrjsModsAdminPage = () => {
|
||||
const { toast } = useToast();
|
||||
const [mods, setMods] = useState<ModEntry[]>([]);
|
||||
const [editMod, setEditMod] = useState<ModEntry | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
|
||||
const form = useForm<z.infer<typeof modsSchema>>({
|
||||
const mainForm = useForm<z.infer<typeof modsSchema>>({
|
||||
resolver: zodResolver(modsSchema),
|
||||
defaultValues: {
|
||||
fileName: "",
|
||||
|
@ -50,6 +58,37 @@ const SvrjsModsAdminPage = () => {
|
|||
},
|
||||
});
|
||||
|
||||
const dialogForm = useForm<z.infer<typeof modsSchema>>({
|
||||
resolver: zodResolver(modsSchema),
|
||||
defaultValues: {
|
||||
fileName: "",
|
||||
version: "",
|
||||
downloadLink: "",
|
||||
fileSize: "",
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
fetchMods();
|
||||
const interval = setInterval(() => {
|
||||
fetchMods();
|
||||
}, 10000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (editMod) {
|
||||
dialogForm.reset({
|
||||
fileName: editMod.fileName,
|
||||
version: editMod.version,
|
||||
downloadLink: editMod.downloadLink,
|
||||
fileSize: editMod.fileSize,
|
||||
});
|
||||
setDialogOpen(true); // Open dialog when a mod is being edited
|
||||
}
|
||||
}, [editMod]);
|
||||
|
||||
const fetchMods = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/mods", {
|
||||
|
@ -66,18 +105,18 @@ const SvrjsModsAdminPage = () => {
|
|||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchMods();
|
||||
const interval = setInterval(() => {
|
||||
fetchMods();
|
||||
}, 10000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
const onSubmit: SubmitHandler<z.infer<typeof modsSchema>> = async (data) => {
|
||||
setLoading(true);
|
||||
const response = await fetch("/api/uploadmods", {
|
||||
try {
|
||||
const response = editMod
|
||||
? await fetch(`/api/update/mods/${editMod._id}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
: await fetch("/api/uploadmods", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
@ -86,17 +125,28 @@ const SvrjsModsAdminPage = () => {
|
|||
});
|
||||
|
||||
if (response.ok) {
|
||||
form.reset();
|
||||
mainForm.reset();
|
||||
dialogForm.reset();
|
||||
fetchMods();
|
||||
setLoading(false);
|
||||
setEditMod(null);
|
||||
setDialogOpen(false); // Close dialog on successful submission
|
||||
toast({
|
||||
description: "Successfully Uploaded Mods",
|
||||
description: "Successfully Saved Changes",
|
||||
});
|
||||
} else {
|
||||
console.error("Upload failed");
|
||||
console.error("Save failed");
|
||||
setLoading(false);
|
||||
toast({
|
||||
description: "Upload failed",
|
||||
description: "Save failed",
|
||||
variant: "destructive",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Save failed", error);
|
||||
setLoading(false);
|
||||
toast({
|
||||
description: "Save failed",
|
||||
variant: "destructive",
|
||||
});
|
||||
}
|
||||
|
@ -120,10 +170,10 @@ const SvrjsModsAdminPage = () => {
|
|||
return (
|
||||
<section id="mods-page" className="wrapper container">
|
||||
<h1 className="text-3xl font-bold py-6">Mods Form</h1>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||||
<Form {...mainForm}>
|
||||
<form onSubmit={mainForm.handleSubmit(onSubmit)} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={mainForm.control}
|
||||
name="fileName"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
|
@ -136,7 +186,7 @@ const SvrjsModsAdminPage = () => {
|
|||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={mainForm.control}
|
||||
name="version"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
|
@ -149,7 +199,7 @@ const SvrjsModsAdminPage = () => {
|
|||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={mainForm.control}
|
||||
name="downloadLink"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
|
@ -171,7 +221,7 @@ const SvrjsModsAdminPage = () => {
|
|||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={mainForm.control}
|
||||
name="fileSize"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
|
@ -189,7 +239,7 @@ const SvrjsModsAdminPage = () => {
|
|||
size={"lg"}
|
||||
disabled={loading}
|
||||
>
|
||||
Submit
|
||||
{editMod ? "Save Changes" : "Submit"}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
|
@ -234,7 +284,109 @@ const SvrjsModsAdminPage = () => {
|
|||
<TableCell className="border-b px-4 py-2">
|
||||
{mod.fileSize}
|
||||
</TableCell>
|
||||
<TableCell className="border-b px-4 py-2">
|
||||
<TableCell className="border-b px-4 py-2 gap-2 flex-center">
|
||||
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
||||
<DialogTrigger>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setEditMod(mod)}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogTitle>Edit Content</DialogTitle>
|
||||
|
||||
<Form {...dialogForm}>
|
||||
<form
|
||||
onSubmit={dialogForm.handleSubmit(onSubmit)}
|
||||
className="space-y-4"
|
||||
>
|
||||
<FormField
|
||||
control={dialogForm.control}
|
||||
name="fileName"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>File Name</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
defaultValue={editMod?.fileName}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={dialogForm.control}
|
||||
name="version"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Version</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
defaultValue={editMod?.version}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={dialogForm.control}
|
||||
name="downloadLink"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Download Link</FormLabel>
|
||||
<UploadButton
|
||||
endpoint="imageUploader"
|
||||
onClientUploadComplete={(res) => {
|
||||
field.onChange(res[0].url);
|
||||
}}
|
||||
onUploadError={(error: Error) => {
|
||||
alert(`ERROR! ${error.message}`);
|
||||
}}
|
||||
/>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
defaultValue={editMod?.downloadLink}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={dialogForm.control}
|
||||
name="fileSize"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>File Size</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
defaultValue={editMod?.fileSize}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full text-lg rounded-full"
|
||||
size={"lg"}
|
||||
disabled={loading}
|
||||
>
|
||||
Save Changes
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<Button
|
||||
variant={"destructive"}
|
||||
onClick={() => deleteMod(mod._id)}
|
||||
|
|
46
app/api/update/mods/[id]/route.ts
Normal file
46
app/api/update/mods/[id]/route.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { NextResponse } from "next/server";
|
||||
import clientPromise from "@/lib/db";
|
||||
import { ObjectId } from "mongodb";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function PUT(
|
||||
request: Request,
|
||||
{ params }: { params: { id: string } }
|
||||
) {
|
||||
const { id } = params;
|
||||
const body = await request.json();
|
||||
const { fileName, version, downloadLink, fileSize } = body;
|
||||
|
||||
try {
|
||||
const client = await clientPromise;
|
||||
const db = client.db("downloadsDatabase");
|
||||
|
||||
const result = await db.collection("mods").updateOne(
|
||||
{ _id: new ObjectId(id) },
|
||||
{
|
||||
$set: {
|
||||
fileName,
|
||||
version,
|
||||
downloadLink,
|
||||
fileSize,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (result.modifiedCount > 0) {
|
||||
return NextResponse.json({ success: true });
|
||||
} else {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "No document updated",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Update failed", error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "Failed to update mod",
|
||||
});
|
||||
}
|
||||
}
|
|
@ -6,16 +6,10 @@ const f = createUploadthing();
|
|||
// const auth = (req: Request) => ({ id: "fakeId" });
|
||||
|
||||
export const ourFileRouter = {
|
||||
imageUploader: f({ "application/zip": { maxFileSize: "8MB" } })
|
||||
// .middleware(async ({ req }) => {
|
||||
// const user = await auth(req);
|
||||
// if (!user) throw new UploadThingError("Unauthorized");
|
||||
// return { userId: user.id };
|
||||
// })
|
||||
.onUploadComplete(async ({ metadata, file }) => {
|
||||
// console.log("Upload complete for userId:", metadata.userId);
|
||||
imageUploader: f({
|
||||
"application/zip": { maxFileSize: "8MB" },
|
||||
}).onUploadComplete(async ({ metadata, file }) => {
|
||||
console.log("file url", file.url);
|
||||
// return { uploadedBy: metadata.userId };
|
||||
}),
|
||||
} satisfies FileRouter;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { createRouteHandler } from "uploadthing/next";
|
||||
import { ourFileRouter } from "./core";
|
||||
|
||||
// Force the API to use SSR instead of static generation
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export const { GET, POST } = createRouteHandler({
|
||||
|
|
|
@ -5,11 +5,9 @@ import "prismjs/themes/prism-okaidia.css";
|
|||
import "prismjs/components/prism-javascript";
|
||||
import "prismjs/components/prism-python";
|
||||
import "prismjs/components/prism-php";
|
||||
// Import the languages and their dependencies
|
||||
import "prismjs/components/prism-javascript";
|
||||
import "prismjs/components/prism-python";
|
||||
import "prismjs/components/prism-php";
|
||||
// Import additional dependencies for Handlebars if needed
|
||||
import "prismjs/components/prism-markup";
|
||||
import "prismjs/components/prism-markup-templating";
|
||||
import "prismjs/components/prism-handlebars";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"use client"; // This directive indicates that the component is client-side
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Button } from "../ui/button";
|
||||
|
|
|
@ -35,7 +35,6 @@ export const config = {
|
|||
"/api/upload",
|
||||
"/api/uploadlogs",
|
||||
"/api/uploadmods",
|
||||
"/api/uploadthing",
|
||||
"/api/uploadvulnerabilities",
|
||||
"/email-editor",
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue