From ed8ccd0e2f1f79a198ddd64439843025472615e2 Mon Sep 17 00:00:00 2001 From: NerfedJabolo Date: Sat, 15 Jun 2024 22:49:29 +0300 Subject: [PATCH 001/148] put navabr into layout, make basic docs sidebar --- .gitignore | 3 +++ app/docs/page.tsx | 9 +++++++++ app/layout.tsx | 18 ++++++++++-------- app/page.tsx | 10 ++++------ components/shared/Navbar.tsx | 26 +++++++++++++------------- components/shared/Sidebar.tsx | 24 ++++++++++++++++++++++++ 6 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 app/docs/page.tsx create mode 100644 components/shared/Sidebar.tsx diff --git a/.gitignore b/.gitignore index fd3dbb5..cb4eac6 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +#bun +bun.lockb diff --git a/app/docs/page.tsx b/app/docs/page.tsx new file mode 100644 index 0000000..0a57e9f --- /dev/null +++ b/app/docs/page.tsx @@ -0,0 +1,9 @@ +import Sidebar from '@/components/shared/Sidebar'; + +export default function Page() { + return ( + <> + + + ); +} diff --git a/app/layout.tsx b/app/layout.tsx index 935158a..5cf6955 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,16 +1,17 @@ -import type { Metadata } from "next"; -import { Poppins } from "next/font/google"; -import "./globals.css"; -import { ThemeProvider } from "@/components/shared/providers/themeprovider"; +import type { Metadata } from 'next'; +import { Poppins } from 'next/font/google'; +import './globals.css'; +import { ThemeProvider } from '@/components/shared/providers/themeprovider'; +import Navbar from '@/components/shared/Navbar'; const poppins = Poppins({ - weight: ["400", "600", "700", "900"], - subsets: ["latin"], + weight: ['400', '600', '700', '900'], + subsets: ['latin'], }); export const metadata: Metadata = { - title: "SVRJS - A Web Server running on Nodejs", - description: "Open Source Software Library", + title: 'SVRJS - A Web Server running on Nodejs', + description: 'Open Source Software Library', }; export default function RootLayout({ @@ -27,6 +28,7 @@ export default function RootLayout({ enableSystem disableTransitionOnChange > + {children} diff --git a/app/page.tsx b/app/page.tsx index b01741f..623f50b 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,13 +1,11 @@ -import About from "@/components/shared/About"; -import Hero from "@/components/shared/Hero"; -import HowItWorks from "@/components/shared/HowItWorks"; -import Navbar from "@/components/shared/Navbar"; -import Newsletter from "@/components/shared/Newsletter"; +import About from '@/components/shared/About'; +import Hero from '@/components/shared/Hero'; +import HowItWorks from '@/components/shared/HowItWorks'; +import Newsletter from '@/components/shared/Newsletter'; const RootPage = () => { return ( <> - diff --git a/components/shared/Navbar.tsx b/components/shared/Navbar.tsx index 42753a5..f15a109 100644 --- a/components/shared/Navbar.tsx +++ b/components/shared/Navbar.tsx @@ -1,17 +1,17 @@ -"use client"; +'use client'; import { NavigationMenu, NavigationMenuItem, NavigationMenuList, -} from "@radix-ui/react-navigation-menu"; -import Image from "next/image"; -import Link from "next/link"; -import ThemeToggle from "../ui/theme-toggle"; -import { NAVBAR } from "@/constants"; -import { buttonVariants } from "../ui/button"; -import MobileNav from "./MobileNav"; -import { usePathname } from "next/navigation"; +} from '@radix-ui/react-navigation-menu'; +import Image from 'next/image'; +import Link from 'next/link'; +import ThemeToggle from '../ui/theme-toggle'; +import { NAVBAR } from '@/constants'; +import { buttonVariants } from '../ui/button'; +import MobileNav from './MobileNav'; +import { usePathname } from 'next/navigation'; const Navbar = () => { const pathname = usePathname(); @@ -50,9 +50,9 @@ const Navbar = () => { href={href} target={target} className={`text-[18px] tracking-tight ${ - pathname == href ? "bg-accent/40" : "" + pathname == href ? 'bg-accent/40' : '' } ${buttonVariants({ - variant: "ghost", + variant: 'ghost', })}`} > {label} @@ -61,12 +61,12 @@ const Navbar = () => {
- {NAVBAR.rightLinks?.map(({ href = "", label, target }) => ( + {NAVBAR.rightLinks?.map(({ href = '', label, target }) => ( { + return ( +
+ +

First use

+
    +
  • System requirements
  • +
  • Installation
  • +
  • Features
  • +
  • SVR.JS files
  • +
  • SVR.JS utilities
  • +
  • SVR.JS commands
  • +
  • Updating SVR.JS
  • +
  • Common problems
  • +
  • Bun support
  • +
+
+
+ ); +}; + +export default Sidebar; -- 2.39.5 From 9993e882af8b0ad36cc29e7729e9a89529094906 Mon Sep 17 00:00:00 2001 From: NerfedJabolo Date: Sat, 15 Jun 2024 20:02:00 +0300 Subject: [PATCH 002/148] remove useless whitespace --- app/page.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index e7f6dba..7e8f1f2 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -3,8 +3,6 @@ import Hero from '@/components/shared/Hero'; import HowItWorks from '@/components/shared/HowItWorks'; import Newsletter from '@/components/shared/Newsletter'; - - const RootPage = () => { return ( <> -- 2.39.5 From 7c2d8ceba326fd8c539ffac30f437b8babc8255e Mon Sep 17 00:00:00 2001 From: NerfedJabolo Date: Wed, 19 Jun 2024 17:07:40 +0300 Subject: [PATCH 003/148] remove conflicting docs pages, reverse order of downloads --- app/(root)/docs/page.tsx | 14 +++--- app/(root)/downloads/page.tsx | 83 ++++++++++++++++++----------------- app/docs/page.tsx | 9 ---- 3 files changed, 51 insertions(+), 55 deletions(-) delete mode 100644 app/docs/page.tsx diff --git a/app/(root)/docs/page.tsx b/app/(root)/docs/page.tsx index d6f0108..0a57e9f 100644 --- a/app/(root)/docs/page.tsx +++ b/app/(root)/docs/page.tsx @@ -1,7 +1,9 @@ -import React from "react"; +import Sidebar from '@/components/shared/Sidebar'; -const Docs = () => { - return
Docs
; -}; - -export default Docs; +export default function Page() { + return ( + <> + + + ); +} diff --git a/app/(root)/downloads/page.tsx b/app/(root)/downloads/page.tsx index 4f2662d..700d84e 100644 --- a/app/(root)/downloads/page.tsx +++ b/app/(root)/downloads/page.tsx @@ -1,4 +1,4 @@ -import { Button } from "@/components/ui/button"; +import { Button } from '@/components/ui/button'; import { Table, TableBody, @@ -8,38 +8,38 @@ import { TableHead, TableHeader, TableRow, -} from "@/components/ui/table"; -import { Download } from "lucide-react"; -import Link from "next/link"; +} from '@/components/ui/table'; +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-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-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-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", + date: '2024-06-20', + fileName: 'SVRJS_v1.3.0.zip', + version: '1.3.0', + fileSize: '22MB', + downloadLink: '/downloads/SVRJS_v1.3.0.zip', }, ]; @@ -67,22 +67,25 @@ const DownloadPage = () => { - {downloads.map((download) => ( - - {download.date} - {download.fileName} - {download.version} - {download.fileSize} - - - - - - - ))} + {downloads + .slice() + .reverse() + .map((download) => ( + + {download.date} + {download.fileName} + {download.version} + {download.fileSize} + + + + + + + ))} diff --git a/app/docs/page.tsx b/app/docs/page.tsx deleted file mode 100644 index 0a57e9f..0000000 --- a/app/docs/page.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import Sidebar from '@/components/shared/Sidebar'; - -export default function Page() { - return ( - <> - - - ); -} -- 2.39.5 From eee76eaa663d761ac1e86c2435558b2ee2d6fae6 Mon Sep 17 00:00:00 2001 From: NerfedJabolo Date: Wed, 19 Jun 2024 21:42:51 +0300 Subject: [PATCH 004/148] Co-authored-by: Abhijit Bhattacharjee --- .env | 2 ++ actions/login.actions.ts | 13 ++++++++ app/(root)/add-download/page.tsx | 7 +++++ app/(root)/login/page.tsx | 52 ++++++++++++++++++++++++++++++++ app/api/login/route.ts | 31 +++++++++++++++++++ app/api/protected/route.ts | 0 package.json | 2 ++ tsconfig.json | 2 +- 8 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 .env create mode 100644 actions/login.actions.ts create mode 100644 app/(root)/add-download/page.tsx create mode 100644 app/(root)/login/page.tsx create mode 100644 app/api/login/route.ts create mode 100644 app/api/protected/route.ts diff --git a/.env b/.env new file mode 100644 index 0000000..58ea260 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +USERNAME="Svr_admin" +PASSWORD="YP6t1kV6rmviuQG" \ No newline at end of file diff --git a/actions/login.actions.ts b/actions/login.actions.ts new file mode 100644 index 0000000..57d692f --- /dev/null +++ b/actions/login.actions.ts @@ -0,0 +1,13 @@ +'use server'; +import { NextApiRequest } from 'next'; +import { NextResponse } from 'next/server'; + +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 }); + } +} diff --git a/app/(root)/add-download/page.tsx b/app/(root)/add-download/page.tsx new file mode 100644 index 0000000..5bf4dc3 --- /dev/null +++ b/app/(root)/add-download/page.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +const AddDownload = () => { + return
Welcome to downloads
; +}; + +export default AddDownload; diff --git a/app/(root)/login/page.tsx b/app/(root)/login/page.tsx new file mode 100644 index 0000000..2d9d1aa --- /dev/null +++ b/app/(root)/login/page.tsx @@ -0,0 +1,52 @@ +'use client'; +import React, { useState } from 'react'; +import { useRouter } from 'next/navigation'; + +const Login = () => { + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const router = useRouter(); + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + const res = await fetch('/api/login', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ username, password }), + }); + + if (res.ok) { + router.push('/add-download'); + } else { + alert(res.status); + } + }; + return ( +
+
+ + ) => { + setUsername(e.target.value); + }} + /> +
+
+ + ) => { + setPassword(e.target.value); + }} + /> +
+ +
+ ); +}; + +export default Login; diff --git a/app/api/login/route.ts b/app/api/login/route.ts new file mode 100644 index 0000000..b731755 --- /dev/null +++ b/app/api/login/route.ts @@ -0,0 +1,31 @@ +// import { NextResponse } from 'next/server'; +// import { setCookie } from 'nookies'; +// require('dotenv').config(); + +// // nvm, clerk is overkill for one u + +// export async function POST(request: NextApiRequest) { +// const { username, password } = await request.json(); +// console.log(username, password); +// console.log(process.env.PASSWORD); + +// if (username === process.env.USERNAME && password === process.env.PASSWORD) { +// const response = NextResponse.json( +// { message: 'Login successful' }, +// { status: 200 } +// ); + +// setCookie({ res: response }, 'token', 'your-auth-token', { +// httpOnly: true, +// secure: process.env.NODE_ENV !== 'development', +// maxAge: 30 * 24 * 60 * 60, +// path: '/', +// }); + +// return response; +// } else { +// return NextResponse.json({ message: 'Login failed' }, { status: 401 }); +// } +// } + +// im gonna create server actions diff --git a/app/api/protected/route.ts b/app/api/protected/route.ts new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json index 40ae0d3..b383e5c 100644 --- a/package.json +++ b/package.json @@ -20,11 +20,13 @@ "@radix-ui/themes": "^3.0.5", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "dotenv": "^16.4.5", "framer-motion": "^11.2.10", "lucide-react": "^0.394.0", "mini-svg-data-uri": "^1.4.4", "next": "14.2.3", "next-themes": "^0.3.0", + "nookies": "^2.5.2", "react": "^18", "react-dom": "^18", "react-fontawesome": "^1.7.1", diff --git a/tsconfig.json b/tsconfig.json index e7ff90f..f834b79 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -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"] } -- 2.39.5 From 5a2c2d2e693a36bb5b433a17d0821379cbc04277 Mon Sep 17 00:00:00 2001 From: NerfedJabolo Date: Sat, 22 Jun 2024 05:50:53 +0300 Subject: [PATCH 005/148] Co-authored-by: Abhijit Bhattacharjee --- .env | 7 +- app/(auth)/admin/mods/page.tsx | 123 +++++++++++++++++++++++++++ app/(root)/add-download/page.tsx | 7 -- app/(root)/blog/page.tsx | 7 +- app/(root)/docs/page.tsx | 6 ++ app/(root)/downloads/layout.tsx | 11 +++ app/(root)/forum/page.tsx | 7 +- app/(root)/layout.tsx | 27 +++--- app/(root)/login/page.tsx | 52 ------------ app/(root)/mods/layout.tsx | 11 +++ app/(root)/mods/page.tsx | 128 +++++++++++++++------------- app/api/mods/route.ts | 17 ++++ app/api/uploadmods/route.ts | 20 +++++ constants/index.tsx | 140 +++++++++++++++---------------- lib/validations/validation.ts | 9 +- 15 files changed, 370 insertions(+), 202 deletions(-) create mode 100644 app/(auth)/admin/mods/page.tsx delete mode 100644 app/(root)/add-download/page.tsx create mode 100644 app/(root)/downloads/layout.tsx delete mode 100644 app/(root)/login/page.tsx create mode 100644 app/(root)/mods/layout.tsx create mode 100644 app/api/mods/route.ts create mode 100644 app/api/uploadmods/route.ts diff --git a/.env b/.env index 58ea260..962f00e 100644 --- a/.env +++ b/.env @@ -1,2 +1,5 @@ -USERNAME="Svr_admin" -PASSWORD="YP6t1kV6rmviuQG" \ No newline at end of file +ADMIN_USERNAME=Svr_admin +ADMIN_PASSWORD=temppass +MONGODB_URI=mongodb+srv://euler:0f61VcV5UWozRWxp@learning-mongo.jcsdeht.mongodb.net/node-tuts +UPLOADTHING_SECRET=sk_live_0c456ce4a8366c64660dbf057bf8dd8bbe9db3d4bf7a70766855c04c09ba0aa9 +UPLOADTHING_APP_ID=6no1s7ob1p diff --git a/app/(auth)/admin/mods/page.tsx b/app/(auth)/admin/mods/page.tsx new file mode 100644 index 0000000..66325aa --- /dev/null +++ b/app/(auth)/admin/mods/page.tsx @@ -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>({ + resolver: zodResolver(modsSchema), + }); + + const onSubmit: SubmitHandler> = 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 ( +
+

Admin Upload Section

+
+ + ( + + File Name + + + + + + )} + /> + ( + + Version + + + + + + )} + /> + ( + + Download Link + { + field.onChange(res[0].url); + }} + onUploadError={(error: Error) => { + alert(`ERROR! ${error.message}`); + }} + /> + + + + + + )} + /> + ( + + File Size + + + + + + )} + /> + + + +
+ ); +}; + +export default AdminPage; diff --git a/app/(root)/add-download/page.tsx b/app/(root)/add-download/page.tsx deleted file mode 100644 index 5bf4dc3..0000000 --- a/app/(root)/add-download/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -const AddDownload = () => { - return
Welcome to downloads
; -}; - -export default AddDownload; diff --git a/app/(root)/blog/page.tsx b/app/(root)/blog/page.tsx index 96f2896..17cd3a8 100644 --- a/app/(root)/blog/page.tsx +++ b/app/(root)/blog/page.tsx @@ -1,4 +1,9 @@ -import React from "react"; +import React from 'react'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Blog - SVRJS', +}; const BlogPage = () => { return
BlogPage
; diff --git a/app/(root)/docs/page.tsx b/app/(root)/docs/page.tsx index 0a57e9f..144071b 100644 --- a/app/(root)/docs/page.tsx +++ b/app/(root)/docs/page.tsx @@ -1,5 +1,11 @@ import Sidebar from '@/components/shared/Sidebar'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Docs - SVRJS', +}; + export default function Page() { return ( <> diff --git a/app/(root)/downloads/layout.tsx b/app/(root)/downloads/layout.tsx new file mode 100644 index 0000000..2840e60 --- /dev/null +++ b/app/(root)/downloads/layout.tsx @@ -0,0 +1,11 @@ +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Downloads - SVRJS', +}; + +const ModLayout = ({ children }: { children: React.ReactNode }) => { + return
{children}
; +}; + +export default ModLayout; diff --git a/app/(root)/forum/page.tsx b/app/(root)/forum/page.tsx index 755fa7f..2effb06 100644 --- a/app/(root)/forum/page.tsx +++ b/app/(root)/forum/page.tsx @@ -1,4 +1,9 @@ -import React from "react"; +import React from 'react'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Forum - SVRJS', +}; const Forum = () => { return
Forum
; diff --git a/app/(root)/layout.tsx b/app/(root)/layout.tsx index 1776783..78be397 100644 --- a/app/(root)/layout.tsx +++ b/app/(root)/layout.tsx @@ -1,16 +1,21 @@ -import Footer from "@/components/shared/Footer"; -import Navbar from "@/components/shared/Navbar"; +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 ( -
- -
{children}
-
-
- ); + return ( +
+ +
{children}
+
+
+ ); } diff --git a/app/(root)/login/page.tsx b/app/(root)/login/page.tsx deleted file mode 100644 index 2d9d1aa..0000000 --- a/app/(root)/login/page.tsx +++ /dev/null @@ -1,52 +0,0 @@ -'use client'; -import React, { useState } from 'react'; -import { useRouter } from 'next/navigation'; - -const Login = () => { - const [username, setUsername] = useState(''); - const [password, setPassword] = useState(''); - const router = useRouter(); - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - const res = await fetch('/api/login', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ username, password }), - }); - - if (res.ok) { - router.push('/add-download'); - } else { - alert(res.status); - } - }; - return ( -
-
- - ) => { - setUsername(e.target.value); - }} - /> -
-
- - ) => { - setPassword(e.target.value); - }} - /> -
- -
- ); -}; - -export default Login; diff --git a/app/(root)/mods/layout.tsx b/app/(root)/mods/layout.tsx new file mode 100644 index 0000000..47afa8d --- /dev/null +++ b/app/(root)/mods/layout.tsx @@ -0,0 +1,11 @@ +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'MOD - SVRJS', +}; + +const ModLayout = ({ children }: { children: React.ReactNode }) => { + return
{children}
; +}; + +export default ModLayout; diff --git a/app/(root)/mods/page.tsx b/app/(root)/mods/page.tsx index b83bb73..c05815e 100644 --- a/app/(root)/mods/page.tsx +++ b/app/(root)/mods/page.tsx @@ -1,4 +1,7 @@ -import { Button } from "@/components/ui/button"; +'use client'; + +import { useEffect, useState } from 'react'; +import { Button } from '@/components/ui/button'; import { Table, TableBody, @@ -7,53 +10,61 @@ import { TableHead, TableHeader, TableRow, -} from "@/components/ui/table"; -import { Download } from "lucide-react"; -import Link from "next/link"; +} from '@/components/ui/table'; +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 Download { + _id: string; + date: string; + fileName: string; + version: string; + fileSize: string; + downloadLink: string; +} + +const DownloadPage: React.FC = () => { + const [downloads, setDownloads] = useState([]); + const [error, setError] = useState(''); + + const fetchDownloads = async () => { + try { + const response = await fetch('/api/mods', { + method: 'GET', + }); + if (response.ok) { + const data: Download[] = 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 (

- SvrJS Mods + Downloads

- Get all the latest version of SVRJS Mods and compiled Files here! + Get all the latest version of SVRJS download and compiled Files here!

+ {error &&

{error}

} A list of all available downloads. @@ -61,31 +72,34 @@ const Mods = () => { Date File Name Version - Download Link - File Size + File Size + Download Link - {downloads.map((download) => ( - - {download.date} - {download.fileName} - {download.version} - {download.fileSize} - - - - - - - ))} + {downloads + .slice(0, 10) + .reverse() + .map((download) => ( + + {download.date} + {download.fileName} + {download.version} + {download.fileSize} + + + + + + + ))}
); }; -export default Mods; +export default DownloadPage; diff --git a/app/api/mods/route.ts b/app/api/mods/route.ts new file mode 100644 index 0000000..93000f0 --- /dev/null +++ b/app/api/mods/route.ts @@ -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 } + ); + } +} diff --git a/app/api/uploadmods/route.ts b/app/api/uploadmods/route.ts new file mode 100644 index 0000000..143dbad --- /dev/null +++ b/app/api/uploadmods/route.ts @@ -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 }); +} diff --git a/constants/index.tsx b/constants/index.tsx index c6e72d7..7d8e143 100644 --- a/constants/index.tsx +++ b/constants/index.tsx @@ -1,53 +1,53 @@ -import { BadgeAlert, BarChart4, Cog, ShieldCheck } from "lucide-react"; -import { Download, Home, Settings, User } from "lucide-react"; +import { BadgeAlert, BarChart4, Cog, ShieldCheck } from 'lucide-react'; +import { Download, Home, Settings, User } from 'lucide-react'; export const NAVBAR = { centerLinks: [ { - href: "/", - target: "_self", - label: "Home", + href: '/', + target: '_self', + label: 'Home', }, { - href: "/docs", - target: "_self", - label: "Docs", + href: '/docs', + target: '_self', + label: 'Docs', }, { - href: "/forum", - target: "_self", - label: "Forum", + href: '/forum', + target: '_self', + label: 'Forum', }, { - href: "/blog", - target: "_self", - label: "Blog", + href: '/blog', + target: '_self', + label: 'Blog', }, ], rightLinks: [ { - label: "Git", - target: "_blank", - href: "https://git.svrjs.org/", + label: 'Git', + target: '_blank', + href: 'https://git.svrjs.org/', }, ], }; export const stats = [ { - title: "Downloads", + title: 'Downloads', count: 69, }, { - title: "Users", + title: 'Users', count: 42, }, { - title: "Stars", + title: 'Stars', count: 6, }, { - title: "Products", + title: 'Products', count: 2, }, ]; @@ -55,121 +55,121 @@ export const stats = [ export const Features = [ { icon: , - title: "Complete Secured ", + title: 'Completely Secured ', description: - "lorem ipsum dolor sit amet, consectetur adip lorem ipsum dolor lorem ipsum dolor", + 'lorem ipsum dolor sit amet, consectetur adip lorem ipsum dolor lorem ipsum dolor', }, { icon: , - title: "Best Support", + title: 'Best Support', description: - "lorem ipsum dolor sit amet, consectetur adip lorem ipsum dolor lorem ipsum dolor", + 'lorem ipsum dolor sit amet, consectetur adip lorem ipsum dolor lorem ipsum dolor', }, { icon: , - title: "Most Scalable ", + title: 'Most Scalable ', description: - "lorem ipsum dolor sit amet, consectetur adip lorem ipsum dolor lorem ipsum dolor", + 'lorem ipsum dolor sit amet, consectetur adip lorem ipsum dolor lorem ipsum dolor', }, { icon: , - title: "Fully Configurable ", + title: 'Fully Configurable ', description: - "lorem ipsum dolor sit amet, consectetur adip lorem ipsum dolor lorem ipsum dolor", + 'lorem ipsum dolor sit amet, consectetur adip lorem ipsum dolor lorem ipsum dolor', }, ]; export const questions = [ { - key: "item-1", - question: "What is a web server?", + key: 'item-1', + question: 'What is a web server?', answer: - "A web server is computer software that accepts HTTP requests and serves websites. Web servers can also be underlying hardware running web server software.", + 'A web server is computer software that accepts HTTP requests and serves websites. Web servers can also be underlying hardware running web server software.', }, { - key: "item-2", - question: "What is SVR.JS?", + key: 'item-2', + question: 'What is SVR.JS?', answer: - "SVR.JS is web server software running on Node.JS that can host both static and dynamic content. With additional mods, SVR.JS can be used for different types of dynamic content and can even be used as a forward or reverse proxy. SVR.JS is licensed under a permissive MIT/X11 license", + 'SVR.JS is web server software running on Node.JS that can host both static and dynamic content. With additional mods, SVR.JS can be used for different types of dynamic content and can even be used as a forward or reverse proxy. SVR.JS is licensed under a permissive MIT/X11 license', }, { - key: "item-3", - question: "How was SVR.JS created?", + key: 'item-3', + question: 'How was SVR.JS created?', answer: - "Someone in 2018 wanted to create a website, but he didnt know about setting up popular web server software like Apache httpd, NGINX, or IIS... So he created his own web server in Node.JS to serve his website! And he saved it in a file called svr.js. Since then, this web server has been gradually turned from a web server intended for one website into a general-purpose web server, which is what SVR.JS is today!", + 'Someone in 2018 wanted to create a website, but he didnt know about setting up popular web server software like Apache httpd, NGINX, or IIS... So he created his own web server in Node.JS to serve his website! And he saved it in a file called svr.js. Since then, this web server has been gradually turned from a web server intended for one website into a general-purpose web server, which is what SVR.JS is today!', }, { - key: "item-4", - question: "How did SVR.JS get its name?", + key: 'item-4', + question: 'How did SVR.JS get its name?', answer: - "SVR.JS got its name from the original name of the server script: svr.js, one of many generic file names for a server written in JavaScript.", + 'SVR.JS got its name from the original name of the server script: svr.js, one of many generic file names for a server written in JavaScript.', }, { - key: "item-5", - question: "What is Node.JS?", + key: 'item-5', + question: 'What is Node.JS?', answer: - "Node.JS is an asynchronous event-driven JavaScript runtime built on Chromiums V8 engine. Node.JS is designed to build scalable network applications.", + 'Node.JS is an asynchronous event-driven JavaScript runtime built on Chromiums V8 engine. Node.JS is designed to build scalable network applications.', }, { - key: "item-6", - question: "How can I use SVR.JS?", + key: 'item-6', + question: 'How can I use SVR.JS?', answer: - "You can read the documents to learn how to use the SVR.JS web server.", + 'You can read the documents to learn how to use the SVR.JS web server.', }, ]; export const FOOTERLINKS = { otherPages: [ - { href: "/", label: "Home" }, - { href: "/contact", label: "Contact" }, - { href: "/blog", label: "Blog" }, - { href: "/forum", label: "Forum" }, + { href: '/', label: 'Home' }, + { href: '/contact', label: 'Contact' }, + { href: '/blog', label: 'Blog' }, + { href: '/forum', label: 'Forum' }, ], plans: [ - { href: "/docs", label: "Docs" }, - { href: "/downloads", label: "Downloads" }, - { href: "/tos", label: "Terms of Serivce" }, - { href: "/privacy-policy", label: "Privacy Policy" }, + { href: '/docs', label: 'Docs' }, + { href: '/downloads', label: 'Downloads' }, + { href: '/tos', label: 'Terms of Serivce' }, + { href: '/privacy-policy', label: 'Privacy Policy' }, ], social: { - supportText: "Support Us on Socials", + supportText: 'Support Us on Socials', }, footerBottom: { designedBy: { - href: "https://abhijee.com", - label: "Proxy", + href: 'https://abhijee.com', + label: 'Proxy', }, rightsReserved: { - href: "https://cyprostudio.com", - label: "SVRJS", + href: 'https://cyprostudio.com', + label: 'SVRJS', }, }, }; export const AdminLinks = [ { - name: "Dashboard", - url: "/admin", + name: 'Dashboard', + url: '/admin', icon: Home, }, { - name: "Downloads", - url: "/admin/downloads", + name: 'Downloads', + url: '/admin/downloads', icon: Download, }, { - name: "Mods", - url: "/admin/mods", + name: 'Mods', + url: '/admin/mods', icon: User, }, { - name: "Logs", - url: "/admin/changelogs", + name: 'Logs', + url: '/admin/changelogs', icon: Settings, }, { - name: "Back Home", - url: "/", + name: 'Back Home', + url: '/', icon: Home, }, ]; diff --git a/lib/validations/validation.ts b/lib/validations/validation.ts index 4cbcaab..d795ead 100644 --- a/lib/validations/validation.ts +++ b/lib/validations/validation.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from 'zod'; export const downloadSchema = z.object({ fileName: z.string().nonempty(), @@ -6,3 +6,10 @@ 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(), +}); -- 2.39.5 From 8c8256a995e1319d2fe30efb882b053f4f4a7f40 Mon Sep 17 00:00:00 2001 From: NerfedJabolo Date: Sat, 22 Jun 2024 06:31:03 +0300 Subject: [PATCH 006/148] implement logs upload and viewing --- app/(auth)/admin/changelogs/page.tsx | 123 +++++++++++++++++++++++++++ app/(root)/changelogs/page.tsx | 105 +++++++++++++++++++++++ app/api/logs/route.ts | 17 ++++ app/api/uploadlogs/route.ts | 20 +++++ lib/validations/validation.ts | 7 ++ 5 files changed, 272 insertions(+) create mode 100644 app/(auth)/admin/changelogs/page.tsx create mode 100644 app/(root)/changelogs/page.tsx create mode 100644 app/api/logs/route.ts create mode 100644 app/api/uploadlogs/route.ts diff --git a/app/(auth)/admin/changelogs/page.tsx b/app/(auth)/admin/changelogs/page.tsx new file mode 100644 index 0000000..41e3fa7 --- /dev/null +++ b/app/(auth)/admin/changelogs/page.tsx @@ -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>({ + resolver: zodResolver(logsSchema), + }); + + const onSubmit: SubmitHandler> = 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 ( +
+

Admin Upload Section

+
+ + ( + + File Name + + + + + + )} + /> + ( + + Version + + + + + + )} + /> + ( + + Download Link + { + field.onChange(res[0].url); + }} + onUploadError={(error: Error) => { + alert(`ERROR! ${error.message}`); + }} + /> + + + + + + )} + /> + ( + + File Size + + + + + + )} + /> + + + +
+ ); +}; + +export default AdminPage; diff --git a/app/(root)/changelogs/page.tsx b/app/(root)/changelogs/page.tsx new file mode 100644 index 0000000..9d8d6cc --- /dev/null +++ b/app/(root)/changelogs/page.tsx @@ -0,0 +1,105 @@ +'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 Download { + _id: string; + date: string; + fileName: string; + version: string; + fileSize: string; + downloadLink: string; +} + +const DownloadPage: React.FC = () => { + const [downloads, setDownloads] = useState([]); + const [error, setError] = useState(''); + + const fetchDownloads = async () => { + try { + const response = await fetch('/api/logs', { + method: 'GET', + }); + if (response.ok) { + const data: Download[] = 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 ( +
+

+ Downloads +

+

+ Get all the latest version of SVRJS download and compiled Files here! +

+ {error &&

{error}

} + + A list of all available downloads. + + + Date + File Name + Version + File Size + Download Link + + + + {downloads + .slice(0, 10) + .reverse() + .map((download) => ( + + {download.date} + {download.fileName} + {download.version} + {download.fileSize} + + + + + + + ))} + +
+
+ ); +}; + +export default DownloadPage; diff --git a/app/api/logs/route.ts b/app/api/logs/route.ts new file mode 100644 index 0000000..e4cb25a --- /dev/null +++ b/app/api/logs/route.ts @@ -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 } + ); + } +} diff --git a/app/api/uploadlogs/route.ts b/app/api/uploadlogs/route.ts new file mode 100644 index 0000000..3d5f213 --- /dev/null +++ b/app/api/uploadlogs/route.ts @@ -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 }); +} diff --git a/lib/validations/validation.ts b/lib/validations/validation.ts index d795ead..024cae7 100644 --- a/lib/validations/validation.ts +++ b/lib/validations/validation.ts @@ -13,3 +13,10 @@ export const modsSchema = z.object({ 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(), +}); -- 2.39.5 From 5e47f955e392cd699cbb05c9b189052339e9b64a Mon Sep 17 00:00:00 2001 From: NerfedJabolo Date: Sat, 22 Jun 2024 08:34:12 +0300 Subject: [PATCH 007/148] Update .env --- .env | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.env b/.env index 962f00e..44f1c10 100644 --- a/.env +++ b/.env @@ -1,5 +1,5 @@ -ADMIN_USERNAME=Svr_admin -ADMIN_PASSWORD=temppass -MONGODB_URI=mongodb+srv://euler:0f61VcV5UWozRWxp@learning-mongo.jcsdeht.mongodb.net/node-tuts -UPLOADTHING_SECRET=sk_live_0c456ce4a8366c64660dbf057bf8dd8bbe9db3d4bf7a70766855c04c09ba0aa9 -UPLOADTHING_APP_ID=6no1s7ob1p +ADMIN_USERNAME= +ADMIN_PASSWORD= +MONGODB_URI= +UPLOADTHING_SECRET= +UPLOADTHING_APP_ID= -- 2.39.5 From 04af299887a5bef7873a18fc6b14782d714a3816 Mon Sep 17 00:00:00 2001 From: Proxyy587 Date: Sat, 22 Jun 2024 14:00:51 +0530 Subject: [PATCH 008/148] maybe fixed --- .env.example | 2 +- actions/login.action.ts | 20 +++-- app/(auth)/admin/changelogs/page.tsx | 123 +++++++++++++++++++++++++++ app/(auth)/admin/mods/page.tsx | 123 +++++++++++++++++++++++++++ app/(root)/blog/page.tsx | 4 + app/(root)/changelogs/page.tsx | 92 ++++++++++++++++++++ app/(root)/docs/page.tsx | 16 +++- app/(root)/layout.tsx | 23 +++-- app/(root)/mods/layout.tsx | 11 +++ app/(root)/mods/page.tsx | 112 +++++++++++++----------- app/api/downloads/route.ts | 1 + app/api/logs/route.ts | 17 ++++ app/api/mods/route.ts | 17 ++++ app/api/uploadlogs/route.ts | 20 +++++ app/api/uploadmods/route.ts | 20 +++++ components/shared/Sidebar.tsx | 24 ++++++ lib/db.ts | 33 ++++--- lib/validations/validation.ts | 14 +++ package-lock.json | 67 +-------------- package.json | 4 - tsconfig.json | 2 +- 21 files changed, 594 insertions(+), 151 deletions(-) create mode 100644 app/(auth)/admin/changelogs/page.tsx create mode 100644 app/(auth)/admin/mods/page.tsx create mode 100644 app/(root)/changelogs/page.tsx create mode 100644 app/(root)/mods/layout.tsx create mode 100644 app/api/logs/route.ts create mode 100644 app/api/mods/route.ts create mode 100644 app/api/uploadlogs/route.ts create mode 100644 app/api/uploadmods/route.ts create mode 100644 components/shared/Sidebar.tsx diff --git a/.env.example b/.env.example index dc0218b..8d88136 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -MONGO_URI= +MONGODB_URI= UPLOADTHING_SECRET= UPLOADTHING_APP_ID= diff --git a/actions/login.action.ts b/actions/login.action.ts index ffa2912..a2cc4a4 100644 --- a/actions/login.action.ts +++ b/actions/login.action.ts @@ -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 }); +// } +// } diff --git a/app/(auth)/admin/changelogs/page.tsx b/app/(auth)/admin/changelogs/page.tsx new file mode 100644 index 0000000..ae89cb2 --- /dev/null +++ b/app/(auth)/admin/changelogs/page.tsx @@ -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>({ + resolver: zodResolver(logsSchema), + }); + + const onSubmit: SubmitHandler> = 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 ( +
+

Admin Upload Section

+
+ + ( + + File Name + + + + + + )} + /> + ( + + Version + + + + + + )} + /> + ( + + Download Link + { + field.onChange(res[0].url); + }} + onUploadError={(error: Error) => { + alert(`ERROR! ${error.message}`); + }} + /> + + + + + + )} + /> + ( + + File Size + + + + + + )} + /> + + + +
+ ); +}; + +export default AdminPage; diff --git a/app/(auth)/admin/mods/page.tsx b/app/(auth)/admin/mods/page.tsx new file mode 100644 index 0000000..131f3fb --- /dev/null +++ b/app/(auth)/admin/mods/page.tsx @@ -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>({ + resolver: zodResolver(modsSchema), + }); + + const onSubmit: SubmitHandler> = 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 ( +
+

Admin Upload Section

+
+ + ( + + File Name + + + + + + )} + /> + ( + + Version + + + + + + )} + /> + ( + + Download Link + { + field.onChange(res[0].url); + }} + onUploadError={(error: Error) => { + alert(`ERROR! ${error.message}`); + }} + /> + + + + + + )} + /> + ( + + File Size + + + + + + )} + /> + + + +
+ ); +}; + +export default AdminPage; diff --git a/app/(root)/blog/page.tsx b/app/(root)/blog/page.tsx index 96f2896..fc1f38e 100644 --- a/app/(root)/blog/page.tsx +++ b/app/(root)/blog/page.tsx @@ -1,5 +1,9 @@ import React from "react"; +import { Metadata } from "next"; +export const metadata: Metadata = { + title: "Blog - SVRJS", +}; const BlogPage = () => { return
BlogPage
; }; diff --git a/app/(root)/changelogs/page.tsx b/app/(root)/changelogs/page.tsx new file mode 100644 index 0000000..685d275 --- /dev/null +++ b/app/(root)/changelogs/page.tsx @@ -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([]); + 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 ( +
+

+ Server LOGS +

+

+ Get all the latest version of SVRJS download and compiled Files here! +

+ {error &&

{error}

} + + {downloads + .slice(0, 10) + .reverse() + .map((download) => ( +
+ {download.date} + {download.fileName} + {download.version} + {download.fileSize} + + + + + +
+ ))} +
+ ); +}; + +export default DownloadPage; diff --git a/app/(root)/docs/page.tsx b/app/(root)/docs/page.tsx index d6f0108..6947113 100644 --- a/app/(root)/docs/page.tsx +++ b/app/(root)/docs/page.tsx @@ -1,7 +1,15 @@ -import React from "react"; +import Sidebar from "@/components/shared/Sidebar"; -const Docs = () => { - return
Docs
; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Docs - SVRJS", }; -export default Docs; +export default function Page() { + return ( + <> + + + ); +} diff --git a/app/(root)/layout.tsx b/app/(root)/layout.tsx index 1776783..2a90436 100644 --- a/app/(root)/layout.tsx +++ b/app/(root)/layout.tsx @@ -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 ( -
- -
{children}
-
-
- ); + return ( +
+ +
{children}
+
+
+ ); } diff --git a/app/(root)/mods/layout.tsx b/app/(root)/mods/layout.tsx new file mode 100644 index 0000000..b638106 --- /dev/null +++ b/app/(root)/mods/layout.tsx @@ -0,0 +1,11 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "MOD - SVRJS", +}; + +const ModLayout = ({ children }: { children: React.ReactNode }) => { + return
{children}
; +}; + +export default ModLayout; diff --git a/app/(root)/mods/page.tsx b/app/(root)/mods/page.tsx index b83bb73..55f91cc 100644 --- a/app/(root)/mods/page.tsx +++ b/app/(root)/mods/page.tsx @@ -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([]); + 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 (
{ SvrJS Mods

- Get all the latest version of SVRJS Mods and compiled Files here! + Get all the latest version of SVRJS Mods and compiled Files here!{" "}

+ {error &&

{error}

} A list of all available downloads. @@ -66,26 +77,29 @@ const Mods = () => { - {downloads.map((download) => ( - - {download.date} - {download.fileName} - {download.version} - {download.fileSize} - - - - - - - ))} + {downloads + .slice(0, 10) + .reverse() + .map((download) => ( + + {download.date} + {download.fileName} + {download.version} + {download.fileSize} + + + + + + + ))}
); }; -export default Mods; +export default ModsPage; diff --git a/app/api/downloads/route.ts b/app/api/downloads/route.ts index 23a04df..7557a71 100644 --- a/app/api/downloads/route.ts +++ b/app/api/downloads/route.ts @@ -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 } diff --git a/app/api/logs/route.ts b/app/api/logs/route.ts new file mode 100644 index 0000000..76d777a --- /dev/null +++ b/app/api/logs/route.ts @@ -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 } + ); + } +} diff --git a/app/api/mods/route.ts b/app/api/mods/route.ts new file mode 100644 index 0000000..172e6e2 --- /dev/null +++ b/app/api/mods/route.ts @@ -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 } + ); + } +} diff --git a/app/api/uploadlogs/route.ts b/app/api/uploadlogs/route.ts new file mode 100644 index 0000000..2bc660d --- /dev/null +++ b/app/api/uploadlogs/route.ts @@ -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 }); +} diff --git a/app/api/uploadmods/route.ts b/app/api/uploadmods/route.ts new file mode 100644 index 0000000..230fcc0 --- /dev/null +++ b/app/api/uploadmods/route.ts @@ -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 }); +} diff --git a/components/shared/Sidebar.tsx b/components/shared/Sidebar.tsx new file mode 100644 index 0000000..f132711 --- /dev/null +++ b/components/shared/Sidebar.tsx @@ -0,0 +1,24 @@ +import React from "react"; + +const Sidebar = () => { + return ( +
+ +

First use

+
    +
  • System requirements
  • +
  • Installation
  • +
  • Features
  • +
  • SVR.JS files
  • +
  • SVR.JS utilities
  • +
  • SVR.JS commands
  • +
  • Updating SVR.JS
  • +
  • Common problems
  • +
  • Bun support
  • +
+
+
+ ); +}; + +export default Sidebar; diff --git a/lib/db.ts b/lib/db.ts index 6e6ea2e..b093401 100644 --- a/lib/db.ts +++ b/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; -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 | 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; diff --git a/lib/validations/validation.ts b/lib/validations/validation.ts index 4cbcaab..4b4dcb5 100644 --- a/lib/validations/validation.ts +++ b/lib/validations/validation.ts @@ -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(), +}); diff --git a/package-lock.json b/package-lock.json index 19cd20c..6178b13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index f44a3cf..a8b80fe 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/tsconfig.json b/tsconfig.json index e7ff90f..f834b79 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -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"] } -- 2.39.5 From 6aed03b2b734eac26fd7bb68922223d2a7aca30a Mon Sep 17 00:00:00 2001 From: Proxyy587 Date: Sat, 22 Jun 2024 14:53:31 +0530 Subject: [PATCH 009/148] prod db #1 --- app/api/downloads/route.ts | 1 + components/shared/Footer.tsx | 2 +- constants/index.tsx | 2 ++ lib/db.ts | 10 ---------- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/app/api/downloads/route.ts b/app/api/downloads/route.ts index 7557a71..f3f80b5 100644 --- a/app/api/downloads/route.ts +++ b/app/api/downloads/route.ts @@ -7,6 +7,7 @@ export async function GET(req: NextRequest) { const client = await clientPromise; const db = client.db("downloadsDatabase"); const downloads = await db.collection("downloads").find().toArray(); + // console.log("Downloads fetched:", downloads); return NextResponse.json(downloads, { status: 200 }); } catch (error) { console.log(`Error Messge ${error}`); diff --git a/components/shared/Footer.tsx b/components/shared/Footer.tsx index 0b4d868..9ed0c81 100644 --- a/components/shared/Footer.tsx +++ b/components/shared/Footer.tsx @@ -9,7 +9,7 @@ const Footer = () => { <>