maybe fixed

This commit is contained in:
Proxyy587 2024-06-22 14:00:51 +05:30
parent 8db4d65295
commit 04af299887
21 changed files with 594 additions and 151 deletions

View file

@ -1,4 +1,4 @@
MONGO_URI=
MONGODB_URI=
UPLOADTHING_SECRET=
UPLOADTHING_APP_ID=

View file

@ -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 });
// }
// }

View 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;

View 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;

View file

@ -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>;
};

View 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;

View file

@ -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 />
</>
);
}

View file

@ -1,5 +1,10 @@
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,

View 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;

View file

@ -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,8 +77,11 @@ const Mods = () => {
</TableRow>
</TableHeader>
<TableBody>
{downloads.map((download) => (
<TableRow key={download.fileName}>
{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>
@ -88,4 +102,4 @@ const Mods = () => {
);
};
export default Mods;
export default ModsPage;

View file

@ -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
View 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
View 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 }
);
}
}

View 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 });
}

View 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 });
}

View 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;

View file

@ -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;

View file

@ -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
View file

@ -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",

View file

@ -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",

View file

@ -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"]
}