shitton of changes #2
15 changed files with 217 additions and 78 deletions
2
.env
Normal file
2
.env
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
USERNAME="Svr_admin"
|
||||||
|
PASSWORD="YP6t1kV6rmviuQG"
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -34,3 +34,6 @@ yarn-error.log*
|
||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
|
#bun
|
||||||
|
bun.lockb
|
||||||
|
|
13
actions/login.actions.ts
Normal file
13
actions/login.actions.ts
Normal file
|
@ -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 });
|
||||||
|
}
|
||||||
|
}
|
7
app/(root)/add-download/page.tsx
Normal file
7
app/(root)/add-download/page.tsx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const AddDownload = () => {
|
||||||
|
return <div>Welcome to downloads</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddDownload;
|
|
@ -1,7 +1,9 @@
|
||||||
import React from "react";
|
import Sidebar from '@/components/shared/Sidebar';
|
||||||
|
|
||||||
const Docs = () => {
|
export default function Page() {
|
||||||
return <div>Docs</div>;
|
return (
|
||||||
};
|
<>
|
||||||
|
<Sidebar />
|
||||||
export default Docs;
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
|
@ -8,38 +8,38 @@ import {
|
||||||
TableHead,
|
TableHead,
|
||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "@/components/ui/table";
|
} from '@/components/ui/table';
|
||||||
import { Download } from "lucide-react";
|
import { Download } from 'lucide-react';
|
||||||
import Link from "next/link";
|
import Link from 'next/link';
|
||||||
|
|
||||||
const downloads = [
|
const downloads = [
|
||||||
{
|
{
|
||||||
date: "2024-06-01",
|
date: '2024-06-01',
|
||||||
fileName: "SVRJS_v1.0.0.zip",
|
fileName: 'SVRJS_v1.0.0.zip',
|
||||||
version: "1.0.0",
|
version: '1.0.0',
|
||||||
fileSize: "15MB",
|
fileSize: '15MB',
|
||||||
downloadLink: "/downloads/SVRJS_v1.0.0.zip",
|
downloadLink: '/downloads/SVRJS_v1.0.0.zip',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
date: "2024-06-10",
|
date: '2024-06-10',
|
||||||
fileName: "SVRJS_v1.1.0.zip",
|
fileName: 'SVRJS_v1.1.0.zip',
|
||||||
version: "1.1.0",
|
version: '1.1.0',
|
||||||
fileSize: "18MB",
|
fileSize: '18MB',
|
||||||
downloadLink: "/downloads/SVRJS_v1.1.0.zip",
|
downloadLink: '/downloads/SVRJS_v1.1.0.zip',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
date: "2024-06-15",
|
date: '2024-06-15',
|
||||||
fileName: "SVRJS_v1.2.0.zip",
|
fileName: 'SVRJS_v1.2.0.zip',
|
||||||
version: "1.2.0",
|
version: '1.2.0',
|
||||||
fileSize: "20MB",
|
fileSize: '20MB',
|
||||||
downloadLink: "/downloads/SVRJS_v1.2.0.zip",
|
downloadLink: '/downloads/SVRJS_v1.2.0.zip',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
date: "2024-06-20",
|
date: '2024-06-20',
|
||||||
fileName: "SVRJS_v1.3.0.zip",
|
fileName: 'SVRJS_v1.3.0.zip',
|
||||||
version: "1.3.0",
|
version: '1.3.0',
|
||||||
fileSize: "22MB",
|
fileSize: '22MB',
|
||||||
downloadLink: "/downloads/SVRJS_v1.3.0.zip",
|
downloadLink: '/downloads/SVRJS_v1.3.0.zip',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -67,22 +67,25 @@ const DownloadPage = () => {
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{downloads.map((download) => (
|
{downloads
|
||||||
<TableRow key={download.fileName}>
|
.slice()
|
||||||
<TableCell className="font-medium">{download.date}</TableCell>
|
.reverse()
|
||||||
<TableCell>{download.fileName}</TableCell>
|
.map((download) => (
|
||||||
<TableCell>{download.version}</TableCell>
|
<TableRow key={download.fileName}>
|
||||||
<TableCell className="text-left">{download.fileSize}</TableCell>
|
<TableCell className="font-medium">{download.date}</TableCell>
|
||||||
<TableCell className="flex items-center justify-end">
|
<TableCell>{download.fileName}</TableCell>
|
||||||
<Link href={download.downloadLink}>
|
<TableCell>{download.version}</TableCell>
|
||||||
<Button variant={"ghost"} className="">
|
<TableCell className="text-left">{download.fileSize}</TableCell>
|
||||||
<Download className="w-4 h-4 mr-2" />
|
<TableCell className="flex items-center justify-end">
|
||||||
Download
|
<Link href={download.downloadLink}>
|
||||||
</Button>
|
<Button variant={'ghost'} className="">
|
||||||
</Link>
|
<Download className="w-4 h-4 mr-2" />
|
||||||
</TableCell>
|
Download
|
||||||
</TableRow>
|
</Button>
|
||||||
))}
|
</Link>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</section>
|
</section>
|
||||||
|
|
52
app/(root)/login/page.tsx
Normal file
52
app/(root)/login/page.tsx
Normal file
|
@ -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<HTMLFormElement>) => {
|
||||||
|
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 (
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div>
|
||||||
|
<label>Username:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={username}
|
||||||
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setUsername(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>Password:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={password}
|
||||||
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setPassword(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Login;
|
31
app/api/login/route.ts
Normal file
31
app/api/login/route.ts
Normal file
|
@ -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
|
0
app/api/protected/route.ts
Normal file
0
app/api/protected/route.ts
Normal file
|
@ -1,18 +1,18 @@
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from 'next';
|
||||||
import { Poppins } from "next/font/google";
|
import { Poppins } from 'next/font/google';
|
||||||
import "./globals.css";
|
import './globals.css';
|
||||||
import { ThemeProvider } from "@/components/shared/providers/themeprovider";
|
import { ThemeProvider } from '@/components/shared/providers/themeprovider';
|
||||||
import Navbar from "@/components/shared/Navbar";
|
import Navbar from '@/components/shared/Navbar';
|
||||||
import Footer from "@/components/shared/Footer";
|
import Footer from '@/components/shared/Footer';
|
||||||
|
|
||||||
const poppins = Poppins({
|
const poppins = Poppins({
|
||||||
weight: ["400", "600", "700", "900"],
|
weight: ['400', '600', '700', '900'],
|
||||||
subsets: ["latin"],
|
subsets: ['latin'],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "SVRJS - A Web Server running on Nodejs",
|
title: 'SVRJS - A Web Server running on Nodejs',
|
||||||
description: "Open Source Software Library",
|
description: 'Open Source Software Library',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
|
|
14
app/page.tsx
14
app/page.tsx
|
@ -1,10 +1,10 @@
|
||||||
import About from "@/components/shared/About";
|
import About from '@/components/shared/About';
|
||||||
import DataTable from "@/components/shared/DataTable";
|
import DataTable from '@/components/shared/DataTable';
|
||||||
import Faq from "@/components/shared/FAQ";
|
import Faq from '@/components/shared/FAQ';
|
||||||
import Hero from "@/components/shared/Hero";
|
import Hero from '@/components/shared/Hero';
|
||||||
import HowItWorks from "@/components/shared/HowItWorks";
|
import HowItWorks from '@/components/shared/HowItWorks';
|
||||||
import Newsletter from "@/components/shared/Newsletter";
|
import Newsletter from '@/components/shared/Newsletter';
|
||||||
import Partners from "@/components/shared/Partners";
|
import Partners from '@/components/shared/Partners';
|
||||||
|
|
||||||
const RootPage = () => {
|
const RootPage = () => {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
"use client";
|
'use client';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
NavigationMenu,
|
NavigationMenu,
|
||||||
NavigationMenuItem,
|
NavigationMenuItem,
|
||||||
NavigationMenuList,
|
NavigationMenuList,
|
||||||
} from "@radix-ui/react-navigation-menu";
|
} from '@radix-ui/react-navigation-menu';
|
||||||
import Image from "next/image";
|
import Image from 'next/image';
|
||||||
import Link from "next/link";
|
import Link from 'next/link';
|
||||||
import ThemeToggle from "../ui/theme-toggle";
|
import ThemeToggle from '../ui/theme-toggle';
|
||||||
import { NAVBAR } from "@/constants";
|
import { NAVBAR } from '@/constants';
|
||||||
import { buttonVariants } from "../ui/button";
|
import { buttonVariants } from '../ui/button';
|
||||||
import MobileNav from "./MobileNav";
|
import MobileNav from './MobileNav';
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from 'next/navigation';
|
||||||
|
|
||||||
const Navbar = () => {
|
const Navbar = () => {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
@ -50,9 +50,9 @@ const Navbar = () => {
|
||||||
href={href}
|
href={href}
|
||||||
target={target}
|
target={target}
|
||||||
className={`text-[17px] tracking-tight ${
|
className={`text-[17px] tracking-tight ${
|
||||||
pathname == href ? "bg-accent/40" : ""
|
pathname == href ? 'bg-accent/40' : ''
|
||||||
} ${buttonVariants({
|
} ${buttonVariants({
|
||||||
variant: "ghost",
|
variant: 'ghost',
|
||||||
})}`}
|
})}`}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
|
@ -61,14 +61,14 @@ const Navbar = () => {
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div className="hidden md:flex gap-2 items-center">
|
<div className="hidden md:flex gap-2 items-center">
|
||||||
{NAVBAR.rightLinks?.map(({ href = "", label, target }) => (
|
{NAVBAR.rightLinks?.map(({ href = '', label, target }) => (
|
||||||
<Link
|
<Link
|
||||||
key={label}
|
key={label}
|
||||||
href={href}
|
href={href}
|
||||||
target={target}
|
target={target}
|
||||||
className={`border ${buttonVariants({
|
className={`border ${buttonVariants({
|
||||||
variant: "ghost",
|
variant: 'ghost',
|
||||||
size: "icon",
|
size: 'icon',
|
||||||
})}`}
|
})}`}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
|
|
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;
|
|
@ -20,11 +20,13 @@
|
||||||
"@radix-ui/themes": "^3.0.5",
|
"@radix-ui/themes": "^3.0.5",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
"framer-motion": "^11.2.10",
|
"framer-motion": "^11.2.10",
|
||||||
"lucide-react": "^0.394.0",
|
"lucide-react": "^0.394.0",
|
||||||
"mini-svg-data-uri": "^1.4.4",
|
"mini-svg-data-uri": "^1.4.4",
|
||||||
"next": "14.2.3",
|
"next": "14.2.3",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
|
"nookies": "^2.5.2",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-fontawesome": "^1.7.1",
|
"react-fontawesome": "^1.7.1",
|
||||||
|
|
|
@ -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"]
|
"exclude": ["node_modules"]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue