maybe fixed
This commit is contained in:
parent
8db4d65295
commit
04af299887
21 changed files with 594 additions and 151 deletions
|
@ -1,4 +1,4 @@
|
|||
MONGO_URI=
|
||||
MONGODB_URI=
|
||||
|
||||
UPLOADTHING_SECRET=
|
||||
UPLOADTHING_APP_ID=
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
"use server";
|
||||
// 'use server';
|
||||
// import { NextApiRequest } from 'next';
|
||||
// import { NextResponse } from 'next/server';
|
||||
|
||||
export function CheckLoggedIn(username: string, password: string) {
|
||||
if (
|
||||
username === process.env.ADMIN_USERNAME &&
|
||||
password === process.env.ADMIN_PASSWORD
|
||||
) {
|
||||
}
|
||||
}
|
||||
// export async function POST(req: NextApiRequest) {
|
||||
// const { username, password } = await req.body;
|
||||
|
||||
// if (username === process.env.USERNAME && password === process.env.PASSWORD) {
|
||||
// return NextResponse.json({ success: true });
|
||||
// } else {
|
||||
// return NextResponse.json({ success: false });
|
||||
// }
|
||||
// }
|
||||
|
|
123
app/(auth)/admin/changelogs/page.tsx
Normal file
123
app/(auth)/admin/changelogs/page.tsx
Normal file
|
@ -0,0 +1,123 @@
|
|||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { useForm, SubmitHandler } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { UploadButton, UploadDropzone } from "@/lib/uploadthing";
|
||||
import { logsSchema } from "@/lib/validations/validation";
|
||||
|
||||
const AdminPage = () => {
|
||||
const form = useForm<z.infer<typeof logsSchema>>({
|
||||
resolver: zodResolver(logsSchema),
|
||||
});
|
||||
|
||||
const onSubmit: SubmitHandler<z.infer<typeof logsSchema>> = async (data) => {
|
||||
const response = await fetch("/api/uploadlogs", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
form.reset();
|
||||
console.log("Upload successful");
|
||||
alert("Uploaded");
|
||||
} else {
|
||||
console.error("Upload failed");
|
||||
alert("Upload Failed");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="admin-page" className="wrapper container">
|
||||
<h1 className="text-3xl font-bold py-6">Admin Upload Section</h1>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fileName"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>File Name</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="version"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Version</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.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} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fileSize"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>File Size</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full text-lg rounded-full"
|
||||
size={"lg"}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default AdminPage;
|
123
app/(auth)/admin/mods/page.tsx
Normal file
123
app/(auth)/admin/mods/page.tsx
Normal file
|
@ -0,0 +1,123 @@
|
|||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { useForm, SubmitHandler } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { UploadButton, UploadDropzone } from "@/lib/uploadthing";
|
||||
import { modsSchema } from "@/lib/validations/validation";
|
||||
|
||||
const AdminPage = () => {
|
||||
const form = useForm<z.infer<typeof modsSchema>>({
|
||||
resolver: zodResolver(modsSchema),
|
||||
});
|
||||
|
||||
const onSubmit: SubmitHandler<z.infer<typeof modsSchema>> = async (data) => {
|
||||
const response = await fetch("/api/uploadmods", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
form.reset();
|
||||
console.log("Upload successful");
|
||||
alert("Uploaded");
|
||||
} else {
|
||||
console.error("Upload failed");
|
||||
alert("Upload Failed");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="admin-page" className="wrapper container">
|
||||
<h1 className="text-3xl font-bold py-6">Admin Upload Section</h1>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fileName"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>File Name</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="version"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Version</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.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} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fileSize"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>File Size</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full text-lg rounded-full"
|
||||
size={"lg"}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default AdminPage;
|
|
@ -1,5 +1,9 @@
|
|||
import React from "react";
|
||||
import { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Blog - SVRJS",
|
||||
};
|
||||
const BlogPage = () => {
|
||||
return <div>BlogPage</div>;
|
||||
};
|
||||
|
|
92
app/(root)/changelogs/page.tsx
Normal file
92
app/(root)/changelogs/page.tsx
Normal file
|
@ -0,0 +1,92 @@
|
|||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCaption,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { Download } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
interface LOGS {
|
||||
_id: string;
|
||||
date: string;
|
||||
fileName: string;
|
||||
version: string;
|
||||
fileSize: string;
|
||||
downloadLink: string;
|
||||
}
|
||||
|
||||
const DownloadPage: React.FC = () => {
|
||||
const [downloads, setDownloads] = useState<LOGS[]>([]);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
const fetchDownloads = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/logs", {
|
||||
method: "GET",
|
||||
});
|
||||
if (response.ok) {
|
||||
const data: LOGS[] = await response.json();
|
||||
setDownloads(data);
|
||||
} else {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
setError(error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchDownloads();
|
||||
|
||||
const interval = setInterval(() => {
|
||||
fetchDownloads();
|
||||
}, 10000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section
|
||||
id="logs"
|
||||
className="wrapper container py-24 md:py-28 gap-4 flex flex-col"
|
||||
>
|
||||
<h1 className="text-3xl md:text-5xl font-bold text-black dark:bg-clip-text dark:text-transparent dark:bg-gradient-to-b dark:from-white dark:to-neutral-400">
|
||||
Server LOGS
|
||||
</h1>
|
||||
<p className="text-lg text-muted-foreground text-start mb-4">
|
||||
Get all the latest version of SVRJS download and compiled Files here!
|
||||
</p>
|
||||
{error && <p className="text-red-500">{error}</p>}
|
||||
|
||||
{downloads
|
||||
.slice(0, 10)
|
||||
.reverse()
|
||||
.map((download) => (
|
||||
<div key={download._id}>
|
||||
<span className="font-medium">{download.date}</span>
|
||||
<span>{download.fileName}</span>
|
||||
<span>{download.version}</span>
|
||||
<span className="text-left">{download.fileSize}</span>
|
||||
<span className="flex items-center justify-end">
|
||||
<Link href={download.downloadLink}>
|
||||
<Button variant={"ghost"} className="">
|
||||
<Download className="w-4 h-4 mr-2" />
|
||||
Download
|
||||
</Button>
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default DownloadPage;
|
|
@ -1,7 +1,15 @@
|
|||
import React from "react";
|
||||
import Sidebar from "@/components/shared/Sidebar";
|
||||
|
||||
const Docs = () => {
|
||||
return <div>Docs</div>;
|
||||
import { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Docs - SVRJS",
|
||||
};
|
||||
|
||||
export default Docs;
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<Sidebar />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
import Footer from "@/components/shared/Footer";
|
||||
import Navbar from "@/components/shared/Navbar";
|
||||
import { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Home - SVRJS",
|
||||
};
|
||||
|
||||
export default function PageLayout({
|
||||
children,
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<main className="flex flex-col min-h-screen">
|
||||
<Navbar />
|
||||
<div className="flex-grow flex-1">{children}</div>
|
||||
<Footer />
|
||||
</main>
|
||||
);
|
||||
return (
|
||||
<main className="flex flex-col min-h-screen">
|
||||
<Navbar />
|
||||
<div className="flex-grow flex-1">{children}</div>
|
||||
<Footer />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
|
11
app/(root)/mods/layout.tsx
Normal file
11
app/(root)/mods/layout.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "MOD - SVRJS",
|
||||
};
|
||||
|
||||
const ModLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
return <main>{children}</main>;
|
||||
};
|
||||
|
||||
export default ModLayout;
|
|
@ -1,3 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Table,
|
||||
|
@ -11,38 +14,45 @@ import {
|
|||
import { Download } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
const downloads = [
|
||||
{
|
||||
date: "2024-06-01",
|
||||
fileName: "SVRJS_v1.0.0.zip",
|
||||
version: "1.0.0",
|
||||
fileSize: "15MB",
|
||||
downloadLink: "/downloads/SVRJS_v1.0.0.zip",
|
||||
},
|
||||
{
|
||||
date: "2024-06-10",
|
||||
fileName: "SVRJS_v1.1.0.zip",
|
||||
version: "1.1.0",
|
||||
fileSize: "18MB",
|
||||
downloadLink: "/downloads/SVRJS_v1.1.0.zip",
|
||||
},
|
||||
{
|
||||
date: "2024-06-15",
|
||||
fileName: "SVRJS_v1.2.0.zip",
|
||||
version: "1.2.0",
|
||||
fileSize: "20MB",
|
||||
downloadLink: "/downloads/SVRJS_v1.2.0.zip",
|
||||
},
|
||||
{
|
||||
date: "2024-06-20",
|
||||
fileName: "SVRJS_v1.3.0.zip",
|
||||
version: "1.3.0",
|
||||
fileSize: "22MB",
|
||||
downloadLink: "/downloads/SVRJS_v1.3.0.zip",
|
||||
},
|
||||
];
|
||||
interface Mods {
|
||||
_id: string;
|
||||
date: string;
|
||||
fileName: string;
|
||||
version: string;
|
||||
fileSize: string;
|
||||
downloadLink: string;
|
||||
}
|
||||
|
||||
const ModsPage: React.FC = () => {
|
||||
const [downloads, setDownloads] = useState<Mods[]>([]);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
const fetchDownloads = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/mods", {
|
||||
method: "GET",
|
||||
});
|
||||
if (response.ok) {
|
||||
const data: Mods[] = await response.json();
|
||||
setDownloads(data);
|
||||
} else {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
setError(error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchDownloads();
|
||||
|
||||
const interval = setInterval(() => {
|
||||
fetchDownloads();
|
||||
}, 10000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
const Mods = () => {
|
||||
return (
|
||||
<section
|
||||
id="mods"
|
||||
|
@ -52,8 +62,9 @@ const Mods = () => {
|
|||
SvrJS Mods
|
||||
</h1>
|
||||
<p className="text-lg text-muted-foreground text-start mb-4">
|
||||
Get all the latest version of SVRJS Mods and compiled Files here!
|
||||
Get all the latest version of SVRJS Mods and compiled Files here!{" "}
|
||||
</p>
|
||||
{error && <p className="text-red-500">{error}</p>}
|
||||
<Table>
|
||||
<TableCaption>A list of all available downloads.</TableCaption>
|
||||
<TableHeader>
|
||||
|
@ -66,26 +77,29 @@ const Mods = () => {
|
|||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{downloads.map((download) => (
|
||||
<TableRow key={download.fileName}>
|
||||
<TableCell className="font-medium">{download.date}</TableCell>
|
||||
<TableCell>{download.fileName}</TableCell>
|
||||
<TableCell>{download.version}</TableCell>
|
||||
<TableCell className="text-left">{download.fileSize}</TableCell>
|
||||
<TableCell className="flex items-center justify-end">
|
||||
<Link href={download.downloadLink}>
|
||||
<Button variant={"ghost"} className="">
|
||||
<Download className="w-4 h-4 mr-2" />
|
||||
Download
|
||||
</Button>
|
||||
</Link>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
{downloads
|
||||
.slice(0, 10)
|
||||
.reverse()
|
||||
.map((download) => (
|
||||
<TableRow key={download._id}>
|
||||
<TableCell className="font-medium">{download.date}</TableCell>
|
||||
<TableCell>{download.fileName}</TableCell>
|
||||
<TableCell>{download.version}</TableCell>
|
||||
<TableCell className="text-left">{download.fileSize}</TableCell>
|
||||
<TableCell className="flex items-center justify-end">
|
||||
<Link href={download.downloadLink}>
|
||||
<Button variant={"ghost"} className="">
|
||||
<Download className="w-4 h-4 mr-2" />
|
||||
Download
|
||||
</Button>
|
||||
</Link>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Mods;
|
||||
export default ModsPage;
|
||||
|
|
|
@ -9,6 +9,7 @@ export async function GET(req: NextRequest) {
|
|||
const downloads = await db.collection("downloads").find().toArray();
|
||||
return NextResponse.json(downloads, { status: 200 });
|
||||
} catch (error) {
|
||||
console.log(`Error Messge ${error}`);
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to fetch downloads" },
|
||||
{ status: 500 }
|
||||
|
|
17
app/api/logs/route.ts
Normal file
17
app/api/logs/route.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import clientPromise from "@/lib/db";
|
||||
|
||||
// Handler for GET requests
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const client = await clientPromise;
|
||||
const db = client.db("downloadsDatabase");
|
||||
const downloads = await db.collection("logs").find().toArray();
|
||||
return NextResponse.json(downloads, { status: 200 });
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to fetch logs" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
17
app/api/mods/route.ts
Normal file
17
app/api/mods/route.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import clientPromise from "@/lib/db";
|
||||
|
||||
// Handler for GET requests
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const client = await clientPromise;
|
||||
const db = client.db("downloadsDatabase");
|
||||
const downloads = await db.collection("mods").find().toArray();
|
||||
return NextResponse.json(downloads, { status: 200 });
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to fetch mods" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
20
app/api/uploadlogs/route.ts
Normal file
20
app/api/uploadlogs/route.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { NextResponse } from "next/server";
|
||||
import clientPromise from "@/lib/db";
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const body = await request.json();
|
||||
const { fileName, version, downloadLink, fileSize } = body;
|
||||
|
||||
const client = await clientPromise;
|
||||
const db = client.db("downloadsDatabase");
|
||||
|
||||
const result = await db.collection("logs").insertOne({
|
||||
date: new Date().toISOString().split("T")[0],
|
||||
fileName,
|
||||
version,
|
||||
downloadLink,
|
||||
fileSize,
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true, id: result.insertedId });
|
||||
}
|
20
app/api/uploadmods/route.ts
Normal file
20
app/api/uploadmods/route.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { NextResponse } from "next/server";
|
||||
import clientPromise from "@/lib/db";
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const body = await request.json();
|
||||
const { fileName, version, downloadLink, fileSize } = body;
|
||||
|
||||
const client = await clientPromise;
|
||||
const db = client.db("downloadsDatabase");
|
||||
|
||||
const result = await db.collection("mods").insertOne({
|
||||
date: new Date().toISOString().split("T")[0],
|
||||
fileName,
|
||||
version,
|
||||
downloadLink,
|
||||
fileSize,
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true, id: result.insertedId });
|
||||
}
|
24
components/shared/Sidebar.tsx
Normal file
24
components/shared/Sidebar.tsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
import React from "react";
|
||||
|
||||
const Sidebar = () => {
|
||||
return (
|
||||
<div className="w-[250px] h-[100vh] border-r dark:border-r-slate-800 pl-4 pt-2">
|
||||
<span className="flex flex-col gap-2">
|
||||
<h2 className="text-2xl font-bold">First use</h2>
|
||||
<ul className="pl-4 flex flex-col gap-2">
|
||||
<li>System requirements</li>
|
||||
<li>Installation</li>
|
||||
<li>Features</li>
|
||||
<li>SVR.JS files</li>
|
||||
<li>SVR.JS utilities</li>
|
||||
<li>SVR.JS commands</li>
|
||||
<li>Updating SVR.JS</li>
|
||||
<li>Common problems</li>
|
||||
<li>Bun support</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
33
lib/db.ts
33
lib/db.ts
|
@ -1,24 +1,35 @@
|
|||
import { MongoClient } from "mongodb";
|
||||
|
||||
// Ensure the environment variable is set
|
||||
if (!process.env.MONGODB_URI) {
|
||||
throw new Error('Invalid/Missing environment variable: "MONGODB_URI"');
|
||||
}
|
||||
|
||||
const uri = process.env.MONGODB_URI;
|
||||
const options = {};
|
||||
const options = {
|
||||
// Add any SSL/TLS options if needed, for example:
|
||||
// ssl: true,
|
||||
// tlsAllowInvalidCertificates: true,
|
||||
};
|
||||
|
||||
let client;
|
||||
let client: MongoClient;
|
||||
let clientPromise: Promise<MongoClient>;
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
if (!(global as any)._mongoClientPromise) {
|
||||
client = new MongoClient(uri!, options);
|
||||
(global as any)._mongoClientPromise = client.connect();
|
||||
}
|
||||
clientPromise = (global as any)._mongoClientPromise;
|
||||
} else {
|
||||
client = new MongoClient(uri!, options);
|
||||
clientPromise = client.connect();
|
||||
declare global {
|
||||
var _mongoClientPromise: Promise<MongoClient> | undefined;
|
||||
}
|
||||
|
||||
// if (process.env.NODE_ENV === "development") {
|
||||
// // In development mode, use a global variable to ensure the client is not recreated
|
||||
// if (!global._mongoClientPromise) {
|
||||
// client = new MongoClient(uri, options);
|
||||
// global._mongoClientPromise = client.connect();
|
||||
// }
|
||||
// clientPromise = global._mongoClientPromise;
|
||||
// } else {
|
||||
// In production mode, create a new client for each request
|
||||
client = new MongoClient(uri, options);
|
||||
clientPromise = client.connect();
|
||||
// }
|
||||
|
||||
export default clientPromise;
|
||||
|
|
|
@ -6,3 +6,17 @@ export const downloadSchema = z.object({
|
|||
downloadLink: z.string().url().nonempty(),
|
||||
fileSize: z.string().nonempty(),
|
||||
});
|
||||
|
||||
export const modsSchema = z.object({
|
||||
fileName: z.string().nonempty(),
|
||||
version: z.string().nonempty(),
|
||||
downloadLink: z.string().url().nonempty(),
|
||||
fileSize: z.string().nonempty(),
|
||||
});
|
||||
|
||||
export const logsSchema = z.object({
|
||||
fileName: z.string().nonempty(),
|
||||
version: z.string().nonempty(),
|
||||
downloadLink: z.string().url().nonempty(),
|
||||
fileSize: z.string().nonempty(),
|
||||
});
|
||||
|
|
67
package-lock.json
generated
67
package-lock.json
generated
|
@ -8,9 +8,6 @@
|
|||
"name": "svrjs",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.2",
|
||||
"@fortawesome/react-fontawesome": "^0.2.2",
|
||||
"@hookform/resolvers": "^3.6.0",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
|
@ -32,7 +29,6 @@
|
|||
"next-themes": "^0.3.0",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-fontawesome": "^1.7.1",
|
||||
"react-hook-form": "^7.52.0",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
|
@ -172,51 +168,6 @@
|
|||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz",
|
||||
"integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw=="
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz",
|
||||
"integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==",
|
||||
"hasInstallScript": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-svg-core": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz",
|
||||
"integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/free-regular-svg-icons": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz",
|
||||
"integrity": "sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/react-fontawesome": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz",
|
||||
"integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "~1 || ~6",
|
||||
"react": ">=16.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@hookform/resolvers": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.6.0.tgz",
|
||||
|
@ -5704,6 +5655,7 @@
|
|||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
|
@ -5776,20 +5728,6 @@
|
|||
"react": "^18.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-fontawesome": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/react-fontawesome/-/react-fontawesome-1.7.1.tgz",
|
||||
"integrity": "sha512-kottReWW1I9Uupub6A5YX4VK7qfpFnEjAcm5zB4Aepst7iofONT27GJYdTcRsj7q5uQu9PXBL7GsxAFKANNUVg==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.5.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-hook-form": {
|
||||
"version": "7.52.0",
|
||||
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.0.tgz",
|
||||
|
@ -5809,7 +5747,8 @@
|
|||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/react-remove-scroll": {
|
||||
"version": "2.5.5",
|
||||
|
|
|
@ -9,9 +9,6 @@
|
|||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.2",
|
||||
"@fortawesome/react-fontawesome": "^0.2.2",
|
||||
"@hookform/resolvers": "^3.6.0",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
|
@ -33,7 +30,6 @@
|
|||
"next-themes": "^0.3.0",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-fontawesome": "^1.7.1",
|
||||
"react-hook-form": "^7.52.0",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
|
|
|
@ -21,6 +21,6 @@
|
|||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "lib/Hoc/withAuth.jsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue