Initial commit

This commit is contained in:
rocord01 2024-12-17 20:40:15 -05:00
commit eb23967bb4
40 changed files with 6837 additions and 0 deletions

41
.gitignore vendored Normal file
View file

@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

8
.idea/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/untitled1.iml" filepath="$PROJECT_DIR$/.idea/untitled1.iml" />
</modules>
</component>
</project>

12
.idea/untitled1.iml Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

36
README.md Normal file
View file

@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.

21
components.json Normal file
View file

@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": false,
"tailwind": {
"config": "tailwind.config.mjs",
"css": "oldapp/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}

14
eslint.config.mjs Normal file
View file

@ -0,0 +1,14 @@
import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [...compat.extends("next/core-web-vitals")];
export default eslintConfig;

7
jsconfig.json Normal file
View file

@ -0,0 +1,7 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}

5
next.config.mjs Normal file
View file

@ -0,0 +1,5 @@
const nextConfig = {
output: 'export',
};
export default nextConfig;

BIN
oldapp/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

29
oldapp/layout.js Normal file
View file

@ -0,0 +1,29 @@
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}

101
oldapp/page.js Normal file
View file

@ -0,0 +1,101 @@
import Image from "next/image";
export default function Home() {
return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="list-inside list-decimal text-sm text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
<li className="mb-2">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-semibold">
src/app/page.js
</code>
.
</li>
<li>Save and see your changes instantly.</li>
</ol>
<div className="flex gap-4 items-center flex-col sm:flex-row">
<a
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={20}
height={20}
/>
Deploy now
</a>
<a
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:min-w-44"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Read our docs
</a>
</div>
</main>
<footer className="row-start-3 flex gap-6 flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
/>
Examples
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org
</a>
</footer>
</div>
);
}

5620
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

33
package.json Normal file
View file

@ -0,0 +1,33 @@
{
"name": "litenetwebsite",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@radix-ui/react-alert-dialog": "^1.1.4",
"@radix-ui/react-avatar": "^1.1.2",
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-scroll-area": "^1.2.2",
"@radix-ui/react-slot": "^1.1.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.468.0",
"next": "15.1.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"tailwind-merge": "^2.5.5",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"eslint": "^9",
"eslint-config-next": "15.1.1",
"postcss": "^8",
"tailwindcss": "^3.4.1"
}
}

8
postcss.config.mjs Normal file
View file

@ -0,0 +1,8 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};
export default config;

BIN
public/ashton.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
public/cayden.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
public/chris.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
public/faux_lemons.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
public/litenet-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
public/maddix.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

BIN
public/nick.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/rocord.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

71
src/app/globals.css Normal file
View file

@ -0,0 +1,71 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}
@layer base {
:root {
--background: 0 0% 0%;
--foreground: 0 0% 100%;
--card: 0 0% 4%;
--card-foreground: 0 0% 100%;
--popover: 0 0% 4%;
--popover-foreground: 0 0% 100%;
--primary: 212 100% 47%;
--primary-foreground: 0 0% 100%;
--secondary: 0 0% 13%;
--secondary-foreground: 0 0% 100%;
--muted: 0 0% 13%;
--muted-foreground: 0 0% 63%;
--accent: 0 0% 13%;
--accent-foreground: 0 0% 100%;
--destructive: 0 62% 30%;
--destructive-foreground: 0 0% 100%;
--border: 0 0% 13%;
--input: 0 0% 13%;
--ring: 212 100% 47%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
/* Reset border-radius */
@layer utilities {
.rounded-lg {
border-radius: 0.5rem;
}
.rounded-md {
border-radius: 0.375rem;
}
.rounded-sm {
border-radius: 0.125rem;
}
}
/* Ensure proper centering */
.container {
@apply mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl;
}

22
src/app/layout.js Normal file
View file

@ -0,0 +1,22 @@
import { Inter } from 'next/font/google'
import './globals.css'
const inter = Inter({ subsets: ['latin'] })
export const metadata = {
title: 'LiteNet - Free Community PBX',
description: 'A free community PBX based on FreePBX. Get your own 4-digit number and start calling other members today!',
}
export default function RootLayout({ children }) {
return (
(<html lang="en" className="scroll-smooth">
<body className={`${inter.className} min-h-screen bg-black text-gray-100`}>
<div className="flex flex-col min-h-screen">
{children}
</div>
</body>
</html>)
);
}

20
src/app/page.jsx Normal file
View file

@ -0,0 +1,20 @@
import Header from '@/components/header'
import Hero from '@/components/hero'
import Features from '@/components/features'
import Team from '@/components/team'
import Footer from '@/components/footer'
export default function Home() {
return (
<>
<Header />
<main>
<Hero />
<Features />
<Team />
</main>
<Footer />
</>
)
}

View file

@ -0,0 +1,65 @@
import { Phone, Users, VoicemailIcon, Radio, MoreHorizontal, Network, Bot, UserCog } from 'lucide-react'
import Link from 'next/link'
const features = [
{
name: 'Free Dial-in and Out',
description: 'Call using +1 (610) LITENET / +1 (610) 548 3638',
icon: Phone,
},
{
name: 'Conference Rooms',
description: 'Host or join conference calls with multiple participants',
icon: Users,
},
{
name: 'Voicemail',
description: 'Set up your own private voicemail and receive messages from anyone',
icon: VoicemailIcon,
},
{
name: 'Intercom and Paging',
description: 'Easily communicate with other extensions and page groups',
icon: Radio,
},
{
name: 'IAX2 Trunking with AstroCom',
description: <>Seamlessly integrate your FreePBX/Asterisk instance with <Link href="https://astrocom.tel/" className="text-sm underline underline-offset-4">AstroCom</Link>, officially supported by LiteNet</>,
icon: Network,
},
{
name: 'Discord Bot',
description: 'Quickly create your own extension, manage page groups, and view Call Detail Records',
icon: Bot,
},
{
name: 'UCP Account',
description: 'Log in to the User Control Panel to manage your account and settings',
icon: UserCog,
},
{
name: 'And More!',
description: 'We\'re always adding new features to LiteNet!',
icon: MoreHorizontal,
},
]
export default function Features() {
return (
(<section id="features" className="container py-24">
<h2 className="mb-12 text-center text-3xl font-bold">Features</h2>
<div className="grid gap-8 sm:grid-cols-2 lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col items-center text-center">
<div className="mb-4 rounded-full bg-blue-500 p-3">
<feature.icon className="h-6 w-6 text-gray-100" />
</div>
<h3 className="mb-2 text-xl font-semibold">{feature.name}</h3>
<p className="text-gray-400">{feature.description}</p>
</div>
))}
</div>
</section>)
);
}

22
src/components/footer.jsx Normal file
View file

@ -0,0 +1,22 @@
import { TermsOfServiceModal } from './terms-of-service-modal'
import { PrivacyPolicyModal } from './privacy-policy-modal'
export default function Footer() {
return (
<footer className="border-t border-gray-800 bg-black text-gray-300">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 flex flex-col items-center justify-between gap-4 py-10 md:h-24 md:flex-row md:py-0">
<div className="flex flex-col items-center gap-4 px-8 md:flex-row md:gap-2 md:px-0">
<img src="/litenet-logo.png" alt="LiteNet Logo" className="h-6 w-6" />
<p className="text-center text-sm leading-loose md:text-left">
&copy; 2024 The LiteNet Group. All rights reserved.
</p>
</div>
<div className="flex gap-4 items-center">
<TermsOfServiceModal />
<PrivacyPolicyModal />
</div>
</div>
</footer>
)
}

74
src/components/header.jsx Normal file
View file

@ -0,0 +1,74 @@
import Link from 'next/link'
import { Button } from '@/components/ui/button'
import { Phone } from 'lucide-react'
export default function Header() {
return (
(<header
className="sticky top-0 z-50 w-full border-b border-gray-800 bg-black/95 backdrop-blur supports-[backdrop-filter]:bg-black/60">
<div className="container flex h-14 items-center">
<div className="mr-4 hidden md:flex">
<Link href="/" className="mr-6 flex items-center space-x-2">
<img
src="/litenet-logo.png"
alt="LiteNet Logo"
className="h-6 w-6" />
<span className="hidden font-bold text-white sm:inline-block">LiteNet</span>
</Link>
<nav className="flex items-center space-x-6 text-sm font-medium">
<Link href="#features" className="text-gray-300 hover:text-white">
Features
</Link>
<Link href="#team" className="text-gray-300 hover:text-white">
Team
</Link>
</nav>
</div>
<div
className="flex flex-1 items-center justify-between space-x-2 md:justify-end">
<Button
variant="outline"
className="border-gray-700 bg-gray-900 text-white hover:bg-gray-800"
asChild>
<a
href="https://discord.litenet.tel"
target="_blank"
rel="noopener noreferrer">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="mr-2 h-4 w-4">
<circle cx="9" cy="12" r="1" />
<circle cx="15" cy="12" r="1" />
<path d="M7.5 7.5c3.5-1 5.5-1 9 0" />
<path d="M7 16.5c3.5 1 6.5 1 10 0" />
<path
d="M15.5 17c0 1 1.5 3 2 3 1.5 0 2.833-1.667 3.5-3 .667-1.667.5-5.833-1.5-11.5-1.457-1.015-3-1.34-4.5-1.5l-1 2.5" />
<path
d="M8.5 17c0 1-1.356 3-1.832 3-1.429 0-2.698-1.667-3.333-3-.635-1.667-.476-5.833 1.428-11.5C6.151 4.485 7.545 4.16 9 4l1 2.5" />
</svg>
Join Discord
</a>
</Button>
<Button className="bg-blue-600 text-white hover:bg-blue-700" asChild>
<a
href="https://pbx.phreaki.ng/ucp/"
target="_blank"
rel="noopener noreferrer">
<Phone className="mr-2 h-4 w-4" />
UCP Login
</a>
</Button>
</div>
</div>
</header>)
);
}

63
src/components/hero.jsx Normal file
View file

@ -0,0 +1,63 @@
import { Button } from '@/components/ui/button'
import { Phone } from 'lucide-react'
export default function Hero() {
return (
(<section
className="container flex flex-col items-center justify-center space-y-4 py-24 text-center">
<img
src="/litenet-logo.png"
alt="LiteNet Logo"
className="h-24 w-24" />
<h1
className="text-4xl font-extrabold tracking-tight sm:text-5xl md:text-6xl">Welcome to LiteNet</h1>
<p
className="max-w-[42rem] leading-normal text-gray-400 sm:text-xl sm:leading-8">
A free community PBX based on FreePBX. Get your own 4-digit extension and start calling other members today!
</p>
<div className="flex justify-center space-x-4">
<Button
variant="outline"
className="border-gray-700 bg-gray-900 text-white hover:bg-gray-800"
asChild>
<a
href="https://discord.litenet.tel"
target="_blank"
rel="noopener noreferrer">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="mr-2 h-4 w-4">
<circle cx="9" cy="12" r="1" />
<circle cx="15" cy="12" r="1" />
<path d="M7.5 7.5c3.5-1 5.5-1 9 0" />
<path d="M7 16.5c3.5 1 6.5 1 10 0" />
<path
d="M15.5 17c0 1 1.5 3 2 3 1.5 0 2.833-1.667 3.5-3 .667-1.667.5-5.833-1.5-11.5-1.457-1.015-3-1.34-4.5-1.5l-1 2.5" />
<path
d="M8.5 17c0 1-1.356 3-1.832 3-1.429 0-2.698-1.667-3.333-3-.635-1.667-.476-5.833 1.428-11.5C6.151 4.485 7.545 4.16 9 4l1 2.5" />
</svg>
Join Discord
</a>
</Button>
<Button className="bg-blue-600 text-white hover:bg-blue-700" asChild>
<a
href="https://pbx.phreaki.ng/ucp/"
target="_blank"
rel="noopener noreferrer">
<Phone className="mr-2 h-4 w-4" />
UCP Login
</a>
</Button>
</div>
</section>)
);
}

View file

@ -0,0 +1,74 @@
import React from 'react'
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { ScrollArea } from "@/components/ui/scroll-area"
export function PrivacyPolicyModal() {
return (
<Dialog>
<DialogTrigger asChild>
<button className="text-sm underline underline-offset-4">Privacy Policy</button>
</DialogTrigger>
<DialogContent className="sm:max-w-[625px] bg-black text-white border border-gray-800">
<DialogHeader>
<DialogTitle className="text-2xl font-bold">Privacy Policy</DialogTitle>
<DialogDescription className="text-gray-400">
LiteNet is committed to protecting your privacy. This Privacy Policy explains our practices regarding the collection, use, and disclosure of your information.
</DialogDescription>
</DialogHeader>
<ScrollArea className="h-[400px] w-full rounded-md border border-gray-800 p-4">
<h2 className="text-lg font-semibold mb-2">1. Information Collection and Use</h2>
<p className="mb-4">
Privacy is a primary goal of LiteNet. We collect and maintain only necessary information to ensure the safety and functionality of our system.
</p>
<h2 className="text-lg font-semibold mb-2">2. Call Detail Records (CDR) Logs</h2>
<p className="mb-4">
CDR Logs are accessible only by authorized personnel. These logs are used solely for system debugging purposes and to identify and block malicious callers. Access to these logs is strictly controlled and monitored.
</p>
<h2 className="text-lg font-semibold mb-2">3. Call Recording</h2>
<p className="mb-4">
By default, call recording is disabled for all users. However, at the request of a user, call recording can be enabled for their individual extension. Recorded calls are accessible only by the owner of the extension.
</p>
<h2 className="text-lg font-semibold mb-2">4. Voicemail Privacy</h2>
<p className="mb-4">
LiteNet does not track or monitor voicemails. Users can expect an inherent level of privacy when using the voicemail system. Voicemail messages are accessible only by the owner of the extension.
</p>
<h2 className="text-lg font-semibold mb-2">5. Data Deletion</h2>
<p className="mb-4">
Users have the right to request the deletion of their data at any time. This can be done by using the "Delete your extension" function within the user interface. Upon deletion, all relevant user information, including but not limited to login credentials, voicemail messages, and voicemail PIN numbers, will be immediately and permanently removed from our system.
</p>
<h2 className="text-lg font-semibold mb-2">6. Data Security</h2>
<p className="mb-4">
We implement a variety of security measures to maintain the safety of your personal information. However, no method of transmission over the Internet or method of electronic storage is 100% secure.
</p>
<h2 className="text-lg font-semibold mb-2">7. Changes to This Privacy Policy</h2>
<p className="mb-4">
We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page and updating the "last updated" date.
</p>
<h2 className="text-lg font-semibold mb-2">8. Contact Us</h2>
<p className="mb-4">
If you have any questions or concerns regarding this Privacy Policy, please contact our staff members. They are available to assist you with any privacy-related inquiries.
</p>
<p className="mt-4 font-semibold">
By using LiteNet's services, you acknowledge that you have read and understood this Privacy Policy and agree to its terms.
</p>
</ScrollArea>
</DialogContent>
</Dialog>
)
}

62
src/components/team.jsx Normal file
View file

@ -0,0 +1,62 @@
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
const adminTeam = [
{ name: 'Chris Chrome', ext: '1000', image: '/chris.webp', discord: '@chrischrome' },
{ name: 'Cayden', ext: '1001', image: '/cayden.webp', discord: '@freepbx' },
{ name: 'Nick', ext: '1036', image: '/nick.webp', discord: '@gamewell' },
{ name: 'Faux_Lemons', ext: '1011', image: '/faux_lemons.webp', discord: '@faux_lemons' },
]
const modTeam = [
{ name: 'ashton', ext: '1007', image: '/ashton.webp', discord: '@ashtoncarlson' },
{ name: 'Maddix', ext: '1019', image: '/maddix.webp', discord: '@maddix6859' },
{ name: 'rocord', ext: '2222', image: '/rocord.webp', discord: '@rocord01' },
]
function TeamMember({ name, ext, image, discord }) {
return (
(<Card className="bg-gray-950 text-white">
<CardHeader className="flex flex-row items-center gap-4 space-y-0">
<Avatar className="h-14 w-14">
<AvatarImage src={image} alt={name} />
<AvatarFallback>{name[0]}</AvatarFallback>
</Avatar>
<div>
<CardTitle>{name}</CardTitle>
<div className="text-sm text-gray-400">{discord}</div>
</div>
</CardHeader>
<CardContent>
<div className="text-sm text-gray-300">x{ext}</div>
</CardContent>
</Card>)
);
}
export default function Team() {
return (
(<section id="team" className="container py-24">
<h2 className="mb-12 text-center text-3xl font-bold text-white">Our Team</h2>
<div className="space-y-12">
<div>
<h3 className="mb-4 text-2xl font-semibold text-gray-200">Administration Team</h3>
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
{adminTeam.map((member) => (
<TeamMember key={member.ext} {...member} />
))}
</div>
</div>
<div>
<h3 className="mb-4 text-2xl font-semibold text-gray-200">Moderation Team</h3>
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{modTeam.map((member) => (
<TeamMember key={member.ext} {...member} />
))}
</div>
</div>
</div>
</section>)
);
}

View file

@ -0,0 +1,92 @@
"use client";
import React from 'react'
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { ScrollArea } from "@/components/ui/scroll-area"
export function TermsOfServiceModal() {
React.useEffect(() => {
if (window.location.hash === '#tos') {
document.getElementById('tos-trigger').click();
}
}, []);
return (
<Dialog>
<DialogTrigger asChild>
<button id="tos-trigger" className="text-sm underline underline-offset-4">Terms of Service</button>
</DialogTrigger>
<DialogContent className="sm:max-w-[625px] bg-black text-white border border-gray-800">
<DialogHeader>
<DialogTitle className="text-2xl font-bold">Terms of Service</DialogTitle>
<DialogDescription className="text-gray-400">
Please read our Terms of Service carefully.
</DialogDescription>
</DialogHeader>
<ScrollArea className="h-[400px] w-full rounded-md border border-gray-800 p-4">
<h2 className="text-lg font-semibold mb-2">1. Acceptance of Terms</h2>
<p className="mb-4">
By accessing or using LiteNet's services, you agree to comply with and be bound by these Terms of Service. If you do not agree to these terms, please do not use our services.
</p>
<h2 className="text-lg font-semibold mb-2">2. Discord Community Rules</h2>
<ul className="list-disc pl-5 mb-4">
<li>External drama is strictly prohibited.</li>
<li>Discrimination of any kind, including but not limited to sexism, racism, homophobia, and transphobia, is not tolerated.</li>
<li>Users must use common sense in all channels. Spamming and posting NSFW content are prohibited.</li>
<li>Paging should only occur during normal hours, not in the middle of the night.</li>
<li>Staff reserve the right to delete messages, warn, mute, kick, and ban users for any reason, within reason.</li>
</ul>
<h2 className="text-lg font-semibold mb-2">3. Fax Usage Rules</h2>
<ul className="list-disc pl-5 mb-4">
<li>NSFW content is prohibited in faxes.</li>
<li>Faxes that would take an excessive amount of time to send are not allowed.</li>
<li>Extremely long faxes are prohibited.</li>
<li>Sending faxes that waste ink excessively is not permitted.</li>
<li>Users should not send faxes they wouldn't want to receive themselves.</li>
</ul>
<p className="mb-4">
Note: These fax rules can be waived with prior consent from the recipient.
</p>
<h2 className="text-lg font-semibold mb-2">4. Conduct</h2>
<p className="mb-4">
Users are expected to behave in a respectful and lawful manner. The absence of a specific written rule does not imply that an action is permitted. LiteNet reserves the right to determine what constitutes appropriate behavior.
</p>
<h2 className="text-lg font-semibold mb-2">5. Modifications to Terms</h2>
<p className="mb-4">
These Terms of Service are subject to change. LiteNet will make an announcement whenever changes occur. It is the user's responsibility to review these terms periodically.
</p>
<h2 className="text-lg font-semibold mb-2">6. Termination of Service</h2>
<p className="mb-4">
LiteNet reserves the right to terminate or suspend access to our services, without prior notice or liability, for any reason whatsoever, including without limitation if you breach the Terms of Service.
</p>
<h2 className="text-lg font-semibold mb-2">7. Limitation of Liability</h2>
<p className="mb-4">
LiteNet shall not be liable for any indirect, incidental, special, consequential or punitive damages, or any loss of profits or revenues, whether incurred directly or indirectly, or any loss of data, use, goodwill, or other intangible losses, resulting from your access to or use of or inability to access or use the services.
</p>
<h2 className="text-lg font-semibold mb-2">8. Governing Law</h2>
<p className="mb-4">
These Terms shall be governed and construed in accordance with the laws of the jurisdiction in which LiteNet operates, without regard to its conflict of law provisions.
</p>
<p className="mt-4 font-semibold">
By using LiteNet's services, you acknowledge that you have read, understood, and agree to be bound by these Terms of Service.
</p>
</ScrollArea>
</DialogContent>
</Dialog>
)
}

View file

@ -0,0 +1,33 @@
import * as React from "react"
import * as AvatarPrimitive from "@radix-ui/react-avatar"
import { cn } from "@/lib/utils"
const Avatar = React.forwardRef(({ className, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", className)}
{...props} />
))
Avatar.displayName = AvatarPrimitive.Root.displayName
const AvatarImage = React.forwardRef(({ className, ...props }, ref) => (
<AvatarPrimitive.Image
ref={ref}
className={cn("aspect-square h-full w-full", className)}
{...props} />
))
AvatarImage.displayName = AvatarPrimitive.Image.displayName
const AvatarFallback = React.forwardRef(({ className, ...props }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
className
)}
{...props} />
))
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
export { Avatar, AvatarImage, AvatarFallback }

View file

@ -0,0 +1,47 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva } from "class-variance-authority";
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
(<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props} />)
);
})
Button.displayName = "Button"
export { Button, buttonVariants }

View file

@ -0,0 +1,50 @@
import * as React from "react"
import { cn } from "@/lib/utils"
const Card = React.forwardRef(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("rounded-lg border bg-black text-card-foreground shadow-sm", className)}
{...props} />
))
Card.displayName = "Card"
const CardHeader = React.forwardRef(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props} />
))
CardHeader.displayName = "CardHeader"
const CardTitle = React.forwardRef(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("text-2xl font-semibold leading-none tracking-tight", className)}
{...props} />
))
CardTitle.displayName = "CardTitle"
const CardDescription = React.forwardRef(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props} />
))
CardDescription.displayName = "CardDescription"
const CardContent = React.forwardRef(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"
const CardFooter = React.forwardRef(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props} />
))
CardFooter.displayName = "CardFooter"
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }

View file

@ -0,0 +1,94 @@
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { X } from "lucide-react"
import { cn } from "@/lib/utils"
const Dialog = DialogPrimitive.Root
const DialogTrigger = DialogPrimitive.Trigger
const DialogPortal = DialogPrimitive.Portal
const DialogClose = DialogPrimitive.Close
const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props} />
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className
)}
{...props}>
{children}
<DialogPrimitive.Close
className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
))
DialogContent.displayName = DialogPrimitive.Content.displayName
const DialogHeader = ({
className,
...props
}) => (
<div
className={cn("flex flex-col space-y-1.5 text-center sm:text-left", className)}
{...props} />
)
DialogHeader.displayName = "DialogHeader"
const DialogFooter = ({
className,
...props
}) => (
<div
className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
{...props} />
)
DialogFooter.displayName = "DialogFooter"
const DialogTitle = React.forwardRef(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold leading-none tracking-tight", className)}
{...props} />
))
DialogTitle.displayName = DialogPrimitive.Title.displayName
const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props} />
))
DialogDescription.displayName = DialogPrimitive.Description.displayName
export {
Dialog,
DialogPortal,
DialogOverlay,
DialogClose,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
}

View file

@ -0,0 +1,38 @@
import * as React from "react"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
import { cn } from "@/lib/utils"
const ScrollArea = React.forwardRef(({ className, children, ...props }, ref) => (
<ScrollAreaPrimitive.Root
ref={ref}
className={cn("relative overflow-hidden", className)}
{...props}>
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
))
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
const ScrollBar = React.forwardRef(({ className, orientation = "vertical", ...props }, ref) => (
<ScrollAreaPrimitive.ScrollAreaScrollbar
ref={ref}
orientation={orientation}
className={cn(
"flex touch-none select-none transition-colors",
orientation === "vertical" &&
"h-full w-2.5 border-l border-l-transparent p-[1px]",
orientation === "horizontal" &&
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
className
)}
{...props}>
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
</ScrollAreaPrimitive.ScrollAreaScrollbar>
))
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
export { ScrollArea, ScrollBar }

6
src/lib/utils.js Normal file
View file

@ -0,0 +1,6 @@
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge"
export function cn(...inputs) {
return twMerge(clsx(inputs));
}

61
tailwind.config.mjs Normal file
View file

@ -0,0 +1,61 @@
/** @type {import('tailwindcss').Config} */
export default {
darkMode: ["class"],
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))'
},
popover: {
DEFAULT: 'hsl(var(--popover))',
foreground: 'hsl(var(--popover-foreground))'
},
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))'
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))'
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))'
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))'
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))'
},
border: 'hsl(var(--border))',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
chart: {
'1': 'hsl(var(--chart-1))',
'2': 'hsl(var(--chart-2))',
'3': 'hsl(var(--chart-3))',
'4': 'hsl(var(--chart-4))',
'5': 'hsl(var(--chart-5))'
}
},
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)'
}
}
},
plugins: [require("tailwindcss-animate")],
};