style: style the code according to Prettier rules

This commit is contained in:
Dorian Niemiec 2024-09-07 09:12:48 +02:00
parent fe3ab6cdf1
commit 7bb89ce202
125 changed files with 5263 additions and 5263 deletions

View file

@ -1,7 +1,7 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Admin // Changelogs", title: "Admin // Changelogs"
}; };
export default function logPages({ children }: { children: React.ReactNode }) { export default function logPages({ children }: { children: React.ReactNode }) {

View file

@ -10,7 +10,7 @@ import {
FormField, FormField,
FormItem, FormItem,
FormLabel, FormLabel,
FormMessage, FormMessage
} from "@/components/ui/form"; } from "@/components/ui/form";
import { import {
Table, Table,
@ -19,7 +19,7 @@ import {
TableCell, TableCell,
TableHead, TableHead,
TableHeader, TableHeader,
TableRow, TableRow
} from "@/components/ui/table"; } from "@/components/ui/table";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { logsSchema } from "@/lib/validations/validation"; import { logsSchema } from "@/lib/validations/validation";
@ -46,13 +46,13 @@ const AdminLogPage = () => {
defaultValues: { defaultValues: {
version: "", version: "",
date: "", date: "",
bullets: [{ point: "" }], bullets: [{ point: "" }]
}, }
}); });
const { fields, append, remove } = useFieldArray({ const { fields, append, remove } = useFieldArray({
control: form.control, control: form.control,
name: "bullets", name: "bullets"
}); });
const fetchLogs = async () => { const fetchLogs = async () => {
@ -74,7 +74,7 @@ const AdminLogPage = () => {
const response = await fetch("/api/uploadlogs", { const response = await fetch("/api/uploadlogs", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(data), body: JSON.stringify(data)
}); });
if (response.ok) { if (response.ok) {
@ -91,7 +91,7 @@ const AdminLogPage = () => {
const deleteLog = async (id: string) => { const deleteLog = async (id: string) => {
try { try {
const response = await fetch(`/api/delete/logs/${id}`, { const response = await fetch(`/api/delete/logs/${id}`, {
method: "DELETE", method: "DELETE"
}); });
if (response.ok) { if (response.ok) {
fetchLogs(); fetchLogs();

View file

@ -1,7 +1,7 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Admin // Downloads", title: "Admin // Downloads"
}; };
export default function logPages({ children }: { children: React.ReactNode }) { export default function logPages({ children }: { children: React.ReactNode }) {

View file

@ -11,7 +11,7 @@ import {
FormField, FormField,
FormItem, FormItem,
FormLabel, FormLabel,
FormMessage, FormMessage
} from "@/components/ui/form"; } from "@/components/ui/form";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { UploadButton } from "@/lib/uploadthing"; import { UploadButton } from "@/lib/uploadthing";
@ -23,7 +23,7 @@ import {
TableCell, TableCell,
TableHead, TableHead,
TableHeader, TableHeader,
TableRow, TableRow
} from "@/components/ui/table"; } from "@/components/ui/table";
interface DownloadEntry { interface DownloadEntry {
@ -46,14 +46,14 @@ const DownloadsPage = () => {
fileName: "", fileName: "",
version: "", version: "",
downloadLink: "", downloadLink: "",
fileSize: "", fileSize: ""
}, }
}); });
const fetchDownloads = async () => { const fetchDownloads = async () => {
try { try {
const response = await fetch("/api/downloads", { const response = await fetch("/api/downloads", {
method: "GET", method: "GET"
}); });
if (response.ok) { if (response.ok) {
const data: DownloadEntry[] = await response.json(); const data: DownloadEntry[] = await response.json();
@ -82,9 +82,9 @@ const DownloadsPage = () => {
const response = await fetch("/api/upload", { const response = await fetch("/api/upload", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json"
}, },
body: JSON.stringify(data), body: JSON.stringify(data)
}); });
if (response.ok) { if (response.ok) {
@ -102,7 +102,7 @@ const DownloadsPage = () => {
const deleteDownload = async (id: string) => { const deleteDownload = async (id: string) => {
try { try {
const response = await fetch(`/api/delete/downloads/${id}`, { const response = await fetch(`/api/delete/downloads/${id}`, {
method: "DELETE", method: "DELETE"
}); });
if (response.ok) { if (response.ok) {
fetchDownloads(); fetchDownloads();

View file

@ -9,7 +9,7 @@ import {
TableCell, TableCell,
TableHead, TableHead,
TableHeader, TableHeader,
TableRow, TableRow
} from "@/components/ui/table"; } from "@/components/ui/table";
import { import {
Pagination, Pagination,
@ -17,7 +17,7 @@ import {
PaginationItem, PaginationItem,
PaginationLink, PaginationLink,
PaginationNext, PaginationNext,
PaginationPrevious, PaginationPrevious
} from "@/components/ui/pagination"; } from "@/components/ui/pagination";
import Link from "next/link"; import Link from "next/link";
@ -45,7 +45,7 @@ const EmailPage = () => {
} catch (error) { } catch (error) {
toast({ toast({
title: "Error fetching subscribers", title: "Error fetching subscribers",
description: `${error}`, description: `${error}`
}); });
} }
}; };

View file

@ -2,7 +2,7 @@ import MobileNav from "../_components/Mobilenav";
import Sidebar from "../_components/Sidebar"; import Sidebar from "../_components/Sidebar";
export default function PageLayout({ export default function PageLayout({
children, children
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {

View file

@ -1,7 +1,7 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Admin // Mods", title: "Admin // Mods"
}; };
export default function logPages({ children }: { children: React.ReactNode }) { export default function logPages({ children }: { children: React.ReactNode }) {

View file

@ -11,7 +11,7 @@ import {
FormField, FormField,
FormItem, FormItem,
FormLabel, FormLabel,
FormMessage, FormMessage
} from "@/components/ui/form"; } from "@/components/ui/form";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { UploadButton } from "@/lib/uploadthing"; import { UploadButton } from "@/lib/uploadthing";
@ -23,13 +23,13 @@ import {
TableCell, TableCell,
TableHead, TableHead,
TableHeader, TableHeader,
TableRow, TableRow
} from "@/components/ui/table"; } from "@/components/ui/table";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
interface ModEntry { interface ModEntry {
@ -54,8 +54,8 @@ const SvrjsModsAdminPage = () => {
fileName: "", fileName: "",
version: "", version: "",
downloadLink: "", downloadLink: "",
fileSize: "", fileSize: ""
}, }
}); });
const dialogForm = useForm<z.infer<typeof modsSchema>>({ const dialogForm = useForm<z.infer<typeof modsSchema>>({
@ -64,8 +64,8 @@ const SvrjsModsAdminPage = () => {
fileName: "", fileName: "",
version: "", version: "",
downloadLink: "", downloadLink: "",
fileSize: "", fileSize: ""
}, }
}); });
useEffect(() => { useEffect(() => {
@ -83,7 +83,7 @@ const SvrjsModsAdminPage = () => {
fileName: editMod.fileName, fileName: editMod.fileName,
version: editMod.version, version: editMod.version,
downloadLink: editMod.downloadLink, downloadLink: editMod.downloadLink,
fileSize: editMod.fileSize, fileSize: editMod.fileSize
}); });
setDialogOpen(true); // Open dialog when a mod is being edited setDialogOpen(true); // Open dialog when a mod is being edited
} }
@ -92,7 +92,7 @@ const SvrjsModsAdminPage = () => {
const fetchMods = async () => { const fetchMods = async () => {
try { try {
const response = await fetch("/api/mods", { const response = await fetch("/api/mods", {
method: "GET", method: "GET"
}); });
if (response.ok) { if (response.ok) {
const data: ModEntry[] = await response.json(); const data: ModEntry[] = await response.json();
@ -112,16 +112,16 @@ const SvrjsModsAdminPage = () => {
? await fetch(`/api/update/mods/${editMod._id}`, { ? await fetch(`/api/update/mods/${editMod._id}`, {
method: "PUT", method: "PUT",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json"
}, },
body: JSON.stringify(data), body: JSON.stringify(data)
}) })
: await fetch("/api/uploadmods", { : await fetch("/api/uploadmods", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json"
}, },
body: JSON.stringify(data), body: JSON.stringify(data)
}); });
if (response.ok) { if (response.ok) {
@ -132,14 +132,14 @@ const SvrjsModsAdminPage = () => {
setEditMod(null); setEditMod(null);
setDialogOpen(false); // Close dialog on successful submission setDialogOpen(false); // Close dialog on successful submission
toast({ toast({
description: "Successfully Saved Changes", description: "Successfully Saved Changes"
}); });
} else { } else {
console.error("Save failed"); console.error("Save failed");
setLoading(false); setLoading(false);
toast({ toast({
description: "Save failed", description: "Save failed",
variant: "destructive", variant: "destructive"
}); });
} }
} catch (error) { } catch (error) {
@ -147,7 +147,7 @@ const SvrjsModsAdminPage = () => {
setLoading(false); setLoading(false);
toast({ toast({
description: "Save failed", description: "Save failed",
variant: "destructive", variant: "destructive"
}); });
} }
}; };
@ -155,7 +155,7 @@ const SvrjsModsAdminPage = () => {
const deleteMod = async (id: string) => { const deleteMod = async (id: string) => {
try { try {
const response = await fetch(`/api/delete/mods/${id}`, { const response = await fetch(`/api/delete/mods/${id}`, {
method: "DELETE", method: "DELETE"
}); });
if (response.ok) { if (response.ok) {
fetchMods(); fetchMods();

View file

@ -7,7 +7,7 @@ import { Button } from "@/components/ui/button";
import { useToast } from "@/components/ui/use-toast"; import { useToast } from "@/components/ui/use-toast";
const MarkdownEditor = dynamic(() => import("@uiw/react-md-editor"), { const MarkdownEditor = dynamic(() => import("@uiw/react-md-editor"), {
ssr: false, ssr: false
}); });
const EditPage = ({ params }: { params: { slug: string } }) => { const EditPage = ({ params }: { params: { slug: string } }) => {
@ -37,7 +37,7 @@ const EditPage = ({ params }: { params: { slug: string } }) => {
const response = await fetch(`/api/mdx/pages/${slug}`, { const response = await fetch(`/api/mdx/pages/${slug}`, {
method: "PUT", method: "PUT",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title, content, vulnerabilities }), body: JSON.stringify({ title, content, vulnerabilities })
}); });
if (response.ok) { if (response.ok) {

View file

@ -1,7 +1,7 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Admin // MultiLogs", title: "Admin // MultiLogs"
}; };
export default function logPages({ children }: { children: React.ReactNode }) { export default function logPages({ children }: { children: React.ReactNode }) {

View file

@ -7,7 +7,7 @@ import {
TableCell, TableCell,
TableHead, TableHead,
TableHeader, TableHeader,
TableRow, TableRow
} from "@/components/ui/table"; } from "@/components/ui/table";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
@ -17,7 +17,7 @@ import {
DialogContent, DialogContent,
DialogHeader, DialogHeader,
DialogFooter, DialogFooter,
DialogTitle, DialogTitle
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
interface PageEntry { interface PageEntry {
@ -47,7 +47,7 @@ const MultiLogs = () => {
const response = await fetch("/api/mdx/pages", { const response = await fetch("/api/mdx/pages", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: pageTitle, slug, content: "" }), body: JSON.stringify({ title: pageTitle, slug, content: "" })
}); });
if (response.ok) { if (response.ok) {
@ -68,7 +68,7 @@ const MultiLogs = () => {
const deletePage = async (slug: string) => { const deletePage = async (slug: string) => {
setLoading(true); setLoading(true);
const response = await fetch(`/api/mdx/pages/${slug}`, { const response = await fetch(`/api/mdx/pages/${slug}`, {
method: "DELETE", method: "DELETE"
}); });
if (response.ok) { if (response.ok) {

View file

@ -1,7 +1,7 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Admin // Vulnerabilities", title: "Admin // Vulnerabilities"
}; };
export default function logPages({ children }: { children: React.ReactNode }) { export default function logPages({ children }: { children: React.ReactNode }) {

View file

@ -10,7 +10,7 @@ import {
FormField, FormField,
FormItem, FormItem,
FormLabel, FormLabel,
FormMessage, FormMessage
} from "@/components/ui/form"; } from "@/components/ui/form";
import { import {
Table, Table,
@ -19,7 +19,7 @@ import {
TableCell, TableCell,
TableHead, TableHead,
TableHeader, TableHeader,
TableRow, TableRow
} from "@/components/ui/table"; } from "@/components/ui/table";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { z } from "zod"; import { z } from "zod";
@ -29,7 +29,7 @@ import {
Select, Select,
SelectContent, SelectContent,
SelectItem, SelectItem,
SelectTrigger, SelectTrigger
} from "@/components/ui/select"; } from "@/components/ui/select";
interface VulnerabiltyEntry { interface VulnerabiltyEntry {
@ -50,13 +50,13 @@ const AdminLogPage = () => {
resolver: zodResolver(vulnerabilitiesSchema), resolver: zodResolver(vulnerabilitiesSchema),
defaultValues: { defaultValues: {
version: "", version: "",
bullets: [{ point: "" }], bullets: [{ point: "" }]
}, }
}); });
const { fields, append, remove } = useFieldArray({ const { fields, append, remove } = useFieldArray({
control: form.control, control: form.control,
name: "bullets", name: "bullets"
}); });
const fetchLogs = async () => { const fetchLogs = async () => {
@ -78,7 +78,7 @@ const AdminLogPage = () => {
const response = await fetch("/api/uploadvulnerabilities", { const response = await fetch("/api/uploadvulnerabilities", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(data), body: JSON.stringify(data)
}); });
if (response.ok) { if (response.ok) {
@ -95,7 +95,7 @@ const AdminLogPage = () => {
const deleteLog = async (id: string) => { const deleteLog = async (id: string) => {
try { try {
const response = await fetch(`/api/delete/vulnerability/${id}`, { const response = await fetch(`/api/delete/vulnerability/${id}`, {
method: "DELETE", method: "DELETE"
}); });
if (response.ok) { if (response.ok) {
fetchLogs(); fetchLogs();

View file

@ -18,7 +18,7 @@ const EmailEditor = () => {
toast({ toast({
title: "Validation Error", title: "Validation Error",
description: "Subject and content cannot be empty.", description: "Subject and content cannot be empty.",
variant: "destructive", variant: "destructive"
}); });
return false; return false;
} }
@ -33,12 +33,12 @@ const EmailEditor = () => {
const response = await fetch("/api/newsletter/send", { const response = await fetch("/api/newsletter/send", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json"
}, },
body: JSON.stringify({ body: JSON.stringify({
subject: subject, subject: subject,
html: previewContent, html: previewContent
}), })
}); });
if (!response.ok) { if (!response.ok) {
@ -48,14 +48,14 @@ const EmailEditor = () => {
const result = await response.json(); const result = await response.json();
toast({ toast({
title: "Success!", title: "Success!",
description: result.message || "Emails sent successfully", description: result.message || "Emails sent successfully"
}); });
} catch (error) { } catch (error) {
console.error("Error:", error); console.error("Error:", error);
toast({ toast({
title: "Uh oh!", title: "Uh oh!",
description: `Failed to send emails: ${error}`, description: `Failed to send emails: ${error}`,
variant: "destructive", variant: "destructive"
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@ -70,12 +70,12 @@ const EmailEditor = () => {
const response = await fetch("/api/newsletter/test", { const response = await fetch("/api/newsletter/test", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json"
}, },
body: JSON.stringify({ body: JSON.stringify({
subject: subject, subject: subject,
html: previewContent, html: previewContent
}), })
}); });
if (!response.ok) { if (!response.ok) {
@ -85,14 +85,14 @@ const EmailEditor = () => {
const result = await response.json(); const result = await response.json();
toast({ toast({
title: "Success!", title: "Success!",
description: result.message || "Test email sent successfully", description: result.message || "Test email sent successfully"
}); });
} catch (error) { } catch (error) {
console.error("Error:", error); console.error("Error:", error);
toast({ toast({
title: "Uh oh!", title: "Uh oh!",
description: `Failed to send test email: ${error}`, description: `Failed to send test email: ${error}`,
variant: "destructive", variant: "destructive"
}); });
} finally { } finally {
setLoading(false); setLoading(false);

View file

@ -2,13 +2,9 @@ import React from "react";
import AuthProvider from "../../components/shared/providers/AuthProvider"; import AuthProvider from "../../components/shared/providers/AuthProvider";
export default function AdminLayout({ export default function AdminLayout({
children, children
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {
return ( return <AuthProvider>{children}</AuthProvider>;
<AuthProvider>
{children}
</AuthProvider>
);
} }

View file

@ -41,7 +41,7 @@ interface BlogSlugArticle {
} }
export async function generateMetadata({ export async function generateMetadata({
params, params
}: { }: {
params: { slug: string }; params: { slug: string };
}): Promise<Metadata> { }): Promise<Metadata> {
@ -50,7 +50,7 @@ export async function generateMetadata({
if (!data) { if (!data) {
return { return {
title: "Not Found", title: "Not Found",
description: "Blog post not found", description: "Blog post not found"
}; };
} }
@ -67,9 +67,9 @@ export async function generateMetadata({
url: urlFor(data.titleImage).url(), url: urlFor(data.titleImage).url(),
width: 800, width: 800,
height: 600, height: 600,
alt: `${data.title} - SVRJS`, alt: `${data.title} - SVRJS`
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -77,8 +77,8 @@ export async function generateMetadata({
title: `${data.title} - SVRJS`, title: `${data.title} - SVRJS`,
description: data.smallDescription, description: data.smallDescription,
images: [urlFor(data.titleImage).url()], images: [urlFor(data.titleImage).url()],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
} }
@ -126,12 +126,12 @@ const customPortableTextComponents: PortableTextComponents = {
<CopyButton code={value.code} /> <CopyButton code={value.code} />
</div> </div>
); );
}, }
}, }
}; };
export default async function BlogSlugArticle({ export default async function BlogSlugArticle({
params, params
}: { }: {
params: { slug: string }; params: { slug: string };
}) { }) {

View file

@ -20,9 +20,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "Blog - SVRJS", alt: "Blog - SVRJS"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -31,12 +31,12 @@ export const metadata: Metadata = {
description: description:
"Welcome to the SVR.JS Blog! Explore our latest blog posts featuring web development, web application security, and web server administration tips. Stay tuned for the latest SVR.JS updates.", "Welcome to the SVR.JS Blog! Explore our latest blog posts featuring web development, web application security, and web server administration tips. Stay tuned for the latest SVR.JS updates.",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
const BlogPage = async ({ const BlogPage = async ({
searchParams, searchParams
}: { }: {
searchParams: { page?: string }; searchParams: { page?: string };
}) => { }) => {

View file

@ -16,9 +16,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "ChangeLogs - SVRJS", alt: "ChangeLogs - SVRJS"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -27,8 +27,8 @@ export const metadata: Metadata = {
description: description:
"Stay up-to-date with the latest improvements and updates to SVR.JS web server. Our change log page provides a comprehensive list of new features, bug fixes, and enhancements for each release.", "Stay up-to-date with the latest improvements and updates to SVR.JS web server. Our change log page provides a comprehensive list of new features, bug fixes, and enhancements for each release.",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
const ContactLayout = ({ children }: { children: React.ReactNode }) => { const ContactLayout = ({ children }: { children: React.ReactNode }) => {
return <main>{children}</main>; return <main>{children}</main>;

View file

@ -27,7 +27,7 @@ const LogsPage: React.FC = () => {
const fetchDownloads = async () => { const fetchDownloads = async () => {
try { try {
const response = await fetch("/api/logs", { const response = await fetch("/api/logs", {
method: "GET", method: "GET"
}); });
if (response.ok) { if (response.ok) {
const data: LOGS[] = await response.json(); const data: LOGS[] = await response.json();

View file

@ -16,9 +16,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "Contact Us - SVRJS", alt: "Contact Us - SVRJS"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -27,8 +27,8 @@ export const metadata: Metadata = {
description: description:
"Have questions about SVR.JS? Need technical support? Visit our Contact Us page to find various ways to get in touch with our team, including email, forums, and our official support channel.", "Have questions about SVR.JS? Need technical support? Visit our Contact Us page to find various ways to get in touch with our team, including email, forums, and our official support channel.",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
const ContactLayout = ({ children }: { children: React.ReactNode }) => { const ContactLayout = ({ children }: { children: React.ReactNode }) => {
return <main>{children}</main>; return <main>{children}</main>;

View file

@ -12,7 +12,7 @@ import {
FormField, FormField,
FormItem, FormItem,
FormLabel, FormLabel,
FormMessage, FormMessage
} from "@/components/ui/form"; } from "@/components/ui/form";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
@ -33,8 +33,8 @@ const ContactUs = () => {
defaultValues: { defaultValues: {
name: "", name: "",
email: "", email: "",
message: "", message: ""
}, }
}); });
async function onSubmit(values: z.infer<typeof contactFormSchema>) { async function onSubmit(values: z.infer<typeof contactFormSchema>) {
@ -50,27 +50,27 @@ const ContactUs = () => {
body: JSON.stringify({ ...values, captchaToken }), body: JSON.stringify({ ...values, captchaToken }),
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
Accept: "application/json", Accept: "application/json"
}, }
}); });
if (res.ok) { if (res.ok) {
form.reset(); form.reset();
setCaptchaToken(null); // Reset captcha token after successful submission setCaptchaToken(null); // Reset captcha token after successful submission
toast({ toast({
description: "Your message has been sent.", description: "Your message has been sent."
}); });
} else { } else {
toast({ toast({
title: "Uh oh! Something went wrong.", title: "Uh oh! Something went wrong.",
variant: "destructive", variant: "destructive"
}); });
} }
} catch (error) { } catch (error) {
console.error(error); console.error(error);
toast({ toast({
title: "Uh oh! Something went wrong.", title: "Uh oh! Something went wrong.",
variant: "destructive", variant: "destructive"
}); });
} finally { } finally {
setLoading(false); setLoading(false);

View file

@ -18,9 +18,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "Contribute - SVRJS", alt: "Contribute - SVRJS"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -29,8 +29,8 @@ export const metadata: Metadata = {
description: description:
"Contribute to SVR.JS and be part of an exciting open-source project. Follow the step-by-step guidelines to make your code contributions.", "Contribute to SVR.JS and be part of an exciting open-source project. Follow the step-by-step guidelines to make your code contributions.",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
const Contribute = () => { const Contribute = () => {
return ( return (

View file

@ -16,9 +16,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "Downloads - SVRJS", alt: "Downloads - SVRJS"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -27,12 +27,12 @@ export const metadata: Metadata = {
description: description:
"Ready to get started with SVR.JS? Visit our downloads page to access the latest stable releases, nightly builds, and archived versions. Find the right fit for your needs today!", "Ready to get started with SVR.JS? Visit our downloads page to access the latest stable releases, nightly builds, and archived versions. Find the right fit for your needs today!",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
export default function DownloadLayout({ export default function DownloadLayout({
children, children
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {

View file

@ -9,7 +9,7 @@ import {
TableCell, TableCell,
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";
@ -31,7 +31,7 @@ const DownloadPage: React.FC = () => {
const fetchDownloads = async () => { const fetchDownloads = async () => {
try { try {
const response = await fetch("/api/downloads", { const response = await fetch("/api/downloads", {
method: "GET", method: "GET"
}); });
if (response.ok) { if (response.ok) {
const data: Download[] = await response.json(); const data: Download[] = await response.json();

View file

@ -3,7 +3,7 @@ import React from "react";
import { Metadata } from "next"; import { Metadata } from "next";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Forum - SVRJS", title: "Forum - SVRJS"
}; };
const Forum = () => { const Forum = () => {

View file

@ -20,9 +20,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "SVRJS - A Web Server running on Node.js", alt: "SVRJS - A Web Server running on Node.js"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -31,12 +31,12 @@ export const metadata: Metadata = {
description: description:
"Experience unparalleled flexibility with SVR.JS - the ultimate web server for Node.js. Host web pages, run server-side JavaScript, utilize mods for extended functionality, and more. Integrated log viewer and user management tools included. Also supports Bun (experimental).", "Experience unparalleled flexibility with SVR.JS - the ultimate web server for Node.js. Host web pages, run server-side JavaScript, utilize mods for extended functionality, and more. Integrated log viewer and user management tools included. Also supports Bun (experimental).",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
export default function PageLayout({ export default function PageLayout({
children, children
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {

View file

@ -16,9 +16,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "Mods - SVRJS", alt: "Mods - SVRJS"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -27,8 +27,8 @@ export const metadata: Metadata = {
description: description:
"Expand the functionality of SVR.JS with our collection of mods! Visit the mod downloads page to explore, download, and install a wide range of mods tailored to enhance your web server experience.", "Expand the functionality of SVR.JS with our collection of mods! Visit the mod downloads page to explore, download, and install a wide range of mods tailored to enhance your web server experience.",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
const ModLayout = ({ children }: { children: React.ReactNode }) => { const ModLayout = ({ children }: { children: React.ReactNode }) => {
return <main>{children}</main>; return <main>{children}</main>;

View file

@ -9,7 +9,7 @@ import {
TableCell, TableCell,
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";
@ -30,7 +30,7 @@ const ModsPage: React.FC = () => {
const fetchDownloads = async () => { const fetchDownloads = async () => {
try { try {
const response = await fetch("/api/mods", { const response = await fetch("/api/mods", {
method: "GET", method: "GET"
}); });
if (response.ok) { if (response.ok) {
const data: Mods[] = await response.json(); const data: Mods[] = await response.json();

View file

@ -20,9 +20,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "Privacy Policy - SVRJS", alt: "Privacy Policy - SVRJS"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -31,8 +31,8 @@ export const metadata: Metadata = {
description: description:
"Learn how we collect, use, and protect your data. Our Privacy Policy outlines our commitment to your privacy and the measures we take to safeguard your information when visiting our website.", "Learn how we collect, use, and protect your data. Our Privacy Policy outlines our commitment to your privacy and the measures we take to safeguard your information when visiting our website.",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
const PrivacyPolicy = () => { const PrivacyPolicy = () => {

View file

@ -18,9 +18,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "Terms of Service - SVRJS", alt: "Terms of Service - SVRJS"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -29,8 +29,8 @@ export const metadata: Metadata = {
description: description:
"Understand your rights and responsibilities when using SVR.JS. Our Terms of Service page outlines the conditions for visiting our website, ensuring a transparent and fair experience for all users.", "Understand your rights and responsibilities when using SVR.JS. Our Terms of Service page outlines the conditions for visiting our website, ensuring a transparent and fair experience for all users.",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
const TermsOfService = () => { const TermsOfService = () => {

View file

@ -16,9 +16,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "Vulnerabilities - SVRJS", alt: "Vulnerabilities - SVRJS"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -27,8 +27,8 @@ export const metadata: Metadata = {
description: description:
"Learn about potential security risks associated with outdated SVR.JS web server versions. Stay informed and safeguard your web applications from potential threats with timely updates.", "Learn about potential security risks associated with outdated SVR.JS web server versions. Stay informed and safeguard your web applications from potential threats with timely updates.",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
const ModLayout = ({ children }: { children: React.ReactNode }) => { const ModLayout = ({ children }: { children: React.ReactNode }) => {
return <main>{children}</main>; return <main>{children}</main>;

View file

@ -32,7 +32,7 @@ const Vulnerabilities = () => {
const fetchData = async () => { const fetchData = async () => {
try { try {
const response = await fetch("/api/vulnerabilities", { const response = await fetch("/api/vulnerabilities", {
method: "GET", method: "GET"
}); });
if (response.ok) { if (response.ok) {
const data: Vulnerabilities[] = await response.json(); const data: Vulnerabilities[] = await response.json();
@ -51,7 +51,7 @@ const Vulnerabilities = () => {
const fetchMods = async () => { const fetchMods = async () => {
try { try {
const response = await fetch(`/api/mdx/pages`, { const response = await fetch(`/api/mdx/pages`, {
method: "GET", method: "GET"
}); });
if (response.ok) { if (response.ok) {
const data: ModsVulnerability[] = await response.json(); const data: ModsVulnerability[] = await response.json();

View file

@ -9,7 +9,7 @@ export const authOptions: NextAuthOptions = {
name: "Credentials", name: "Credentials",
credentials: { credentials: {
username: { label: "Username", type: "text" }, username: { label: "Username", type: "text" },
password: { label: "Password", type: "password" }, password: { label: "Password", type: "password" }
}, },
async authorize(credentials: any): Promise<any> { async authorize(credentials: any): Promise<any> {
const adminUsername = process.env.ADMIN_USERNAME; const adminUsername = process.env.ADMIN_USERNAME;
@ -34,8 +34,8 @@ export const authOptions: NextAuthOptions = {
} }
// If you return null then an error will be displayed that the user to check their details. // If you return null then an error will be displayed that the user to check their details.
return null; return null;
}, }
}), })
], ],
callbacks: { callbacks: {
async jwt({ token, user }) { async jwt({ token, user }) {
@ -51,13 +51,13 @@ export const authOptions: NextAuthOptions = {
// session.user.id = token.id; // session.user.id = token.id;
// session.user.name = token.name; // session.user.name = token.name;
return session; return session;
}, }
}, },
pages: { pages: {
signIn: "/login", signIn: "/login"
}, },
session: { session: {
strategy: "jwt", strategy: "jwt"
}, },
secret: process.env.NEXTAUTH_SECRET, secret: process.env.NEXTAUTH_SECRET
}; };

View file

@ -4,7 +4,7 @@ import { NextRequest, NextResponse } from "next/server";
const CONTACT_MESSAGE_FIELDS: Record<string, string> = { const CONTACT_MESSAGE_FIELDS: Record<string, string> = {
name: "Name", name: "Name",
email: "Email", email: "Email",
message: "Message", message: "Message"
}; };
const escapeHtml = (text: string) => { const escapeHtml = (text: string) => {
@ -90,7 +90,7 @@ const generateEmailContent = (data: Record<string, string>) => {
</tr> </tr>
</table> </table>
</body> </body>
</html>`, </html>`
}; };
}; };
@ -109,7 +109,7 @@ export async function POST(req: NextRequest) {
await transporter.sendMail({ await transporter.sendMail({
...mailOptions, ...mailOptions,
...generateEmailContent(data), ...generateEmailContent(data),
subject: "Contact Email", subject: "Contact Email"
}); });
return NextResponse.json( return NextResponse.json(

View file

@ -14,21 +14,21 @@ export async function POST(request: NextRequest) {
const cookie = serialize("auth", "authenticated", { const cookie = serialize("auth", "authenticated", {
httpOnly: true, httpOnly: true,
path: "/", path: "/",
maxAge: 60 * 60 * 24, // 1 day maxAge: 60 * 60 * 24 // 1 day
}); });
return new NextResponse(JSON.stringify({ message: "Login successful" }), { return new NextResponse(JSON.stringify({ message: "Login successful" }), {
headers: { headers: {
"Set-Cookie": cookie, "Set-Cookie": cookie,
"Content-Type": "application/json", "Content-Type": "application/json"
}, }
}); });
} }
return new NextResponse(JSON.stringify({ message: "Invalid credentials" }), { return new NextResponse(JSON.stringify({ message: "Invalid credentials" }), {
status: 401, status: 401,
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json"
}, }
}); });
} }

View file

@ -57,7 +57,7 @@ export const PUT = async (
if (result?.value) { if (result?.value) {
const serializedResult = { const serializedResult = {
...result.value, ...result.value,
_id: result.value._id.toString(), // Convert ObjectId to string _id: result.value._id.toString() // Convert ObjectId to string
}; };
return NextResponse.json(serializedResult, { status: 200 }); return NextResponse.json(serializedResult, { status: 200 });
} else { } else {

View file

@ -8,8 +8,8 @@ const transporter = nodemailer.createTransport({
port: 587, port: 587,
auth: { auth: {
user: process.env.EMAIL, user: process.env.EMAIL,
pass: process.env.EMAIL_PASS, pass: process.env.EMAIL_PASS
}, }
}); });
const sendEmail = async (to: string[], subject: string, html: string) => { const sendEmail = async (to: string[], subject: string, html: string) => {
@ -18,7 +18,7 @@ const sendEmail = async (to: string[], subject: string, html: string) => {
from: process.env.EMAIL_USER, from: process.env.EMAIL_USER,
to: to.join(", "), to: to.join(", "),
subject: subject, subject: subject,
html: html, html: html
}); });
} catch (error) { } catch (error) {
console.error("Error sending email:", error); console.error("Error sending email:", error);

View file

@ -27,7 +27,7 @@ export async function GET(req: Request) {
subscribedAt: subscribedAt:
doc.subscribedAt instanceof Date doc.subscribedAt instanceof Date
? doc.subscribedAt ? doc.subscribedAt
: new Date(doc.subscribedAt), : new Date(doc.subscribedAt)
})); }));
const totalSubscribers = await collection.countDocuments(); const totalSubscribers = await collection.countDocuments();
@ -35,7 +35,7 @@ export async function GET(req: Request) {
return NextResponse.json({ return NextResponse.json({
subscribers, subscribers,
totalSubscribers, totalSubscribers,
totalPages: Math.ceil(totalSubscribers / limit), totalPages: Math.ceil(totalSubscribers / limit)
}); });
} catch (error) { } catch (error) {
console.error("Error fetching subscribers:", error); console.error("Error fetching subscribers:", error);

View file

@ -7,8 +7,8 @@ const transporter = nodemailer.createTransport({
port: 587, port: 587,
auth: { auth: {
user: process.env.EMAIL, user: process.env.EMAIL,
pass: process.env.EMAIL_PASS, pass: process.env.EMAIL_PASS
}, }
}); });
const sendEmail = async (to: string[], subject: string, html: string) => { const sendEmail = async (to: string[], subject: string, html: string) => {
@ -17,7 +17,7 @@ const sendEmail = async (to: string[], subject: string, html: string) => {
from: process.env.EMAIL_USER, from: process.env.EMAIL_USER,
to: to.join(", "), to: to.join(", "),
subject: subject, subject: subject,
html: html, html: html
}); });
} catch (error) { } catch (error) {
console.error("Error sending email:", error); console.error("Error sending email:", error);
@ -32,7 +32,7 @@ export async function POST(req: NextRequest) {
// add ur email here // add ur email here
const testEmails = [ const testEmails = [
"abhijitbhattacharjee333@gmail.com", "abhijitbhattacharjee333@gmail.com",
"test2@example.com", "test2@example.com"
]; ];
if (testEmails.length === 0) { if (testEmails.length === 0) {

View file

@ -18,9 +18,9 @@ export async function POST(req: NextRequest) {
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/x-www-form-urlencoded", "Content-Type": "application/x-www-form-urlencoded"
}, },
body: `secret=${process.env.HCAPTCHA_SECRET}&response=${captchaToken}`, body: `secret=${process.env.HCAPTCHA_SECRET}&response=${captchaToken}`
} }
); );

View file

@ -23,8 +23,8 @@ export async function PUT(
fileName, fileName,
version, version,
downloadLink, downloadLink,
fileSize, fileSize
}, }
} }
); );
@ -33,14 +33,14 @@ export async function PUT(
} else { } else {
return NextResponse.json({ return NextResponse.json({
success: false, success: false,
message: "No document updated", message: "No document updated"
}); });
} }
} catch (error) { } catch (error) {
console.error("Update failed", error); console.error("Update failed", error);
return NextResponse.json({ return NextResponse.json({
success: false, success: false,
message: "Failed to update mod", message: "Failed to update mod"
}); });
} }
} }

View file

@ -16,7 +16,7 @@ export async function POST(request: Request) {
fileName, fileName,
version, version,
downloadLink, downloadLink,
fileSize, fileSize
}); });
return NextResponse.json({ success: true, id: result.insertedId }); return NextResponse.json({ success: true, id: result.insertedId });

View file

@ -14,7 +14,7 @@ export async function POST(request: Request) {
const result = await db.collection("logs").insertOne({ const result = await db.collection("logs").insertOne({
version, version,
date, date,
bullets, bullets
}); });
return NextResponse.json({ success: true, id: result.insertedId }); return NextResponse.json({ success: true, id: result.insertedId });

View file

@ -16,7 +16,7 @@ export async function POST(request: Request) {
fileName, fileName,
version, version,
downloadLink, downloadLink,
fileSize, fileSize
}); });
return NextResponse.json({ success: true, id: result.insertedId }); return NextResponse.json({ success: true, id: result.insertedId });

View file

@ -7,10 +7,10 @@ const f = createUploadthing();
export const ourFileRouter = { export const ourFileRouter = {
imageUploader: f({ imageUploader: f({
"application/zip": { maxFileSize: "8MB" }, "application/zip": { maxFileSize: "8MB" }
}).onUploadComplete(async ({ metadata, file }) => { }).onUploadComplete(async ({ metadata, file }) => {
console.log("file url", file.url); console.log("file url", file.url);
}), })
} satisfies FileRouter; } satisfies FileRouter;
export type OurFileRouter = typeof ourFileRouter; export type OurFileRouter = typeof ourFileRouter;

View file

@ -4,5 +4,5 @@ import { ourFileRouter } from "./core";
export const dynamic = "force-dynamic"; export const dynamic = "force-dynamic";
export const { GET, POST } = createRouteHandler({ export const { GET, POST } = createRouteHandler({
router: ourFileRouter, router: ourFileRouter
}); });

View file

@ -13,7 +13,7 @@ export async function POST(request: Request) {
const result = await db.collection("vulnerabilities").insertOne({ const result = await db.collection("vulnerabilities").insertOne({
version, version,
bullets, bullets
}); });
return NextResponse.json({ success: true, id: result.insertedId }); return NextResponse.json({ success: true, id: result.insertedId });

View file

@ -7,7 +7,7 @@ import { Analytics } from "@vercel/analytics/react";
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 = {
@ -25,9 +25,9 @@ export const metadata: Metadata = {
url: "https://svrjs.vercel.app/metadata/svrjs-cover.png", url: "https://svrjs.vercel.app/metadata/svrjs-cover.png",
width: 800, width: 800,
height: 600, height: 600,
alt: "SVRJS - A Web Server running on Node.js", alt: "SVRJS - A Web Server running on Node.js"
}, }
], ]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -36,12 +36,12 @@ export const metadata: Metadata = {
description: description:
"Experience unparalleled flexibility with SVR.JS - the ultimate web server for Node.js. Host web pages, run server-side JavaScript, utilize mods for extended functionality, and more. Integrated log viewer and user management tools included. Also supports Bun (experimental).", "Experience unparalleled flexibility with SVR.JS - the ultimate web server for Node.js. Host web pages, run server-side JavaScript, utilize mods for extended functionality, and more. Integrated log viewer and user management tools included. Also supports Bun (experimental).",
images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"], images: ["https://svrjs.vercel.app/metadata/svrjs-cover.png"],
creator: "@SVR_JS", creator: "@SVR_JS"
}, }
}; };
export default function RootLayout({ export default function RootLayout({
children, children
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
@ -54,7 +54,6 @@ export default function RootLayout({
enableSystem enableSystem
disableTransitionOnChange disableTransitionOnChange
> >
{children} {children}
<Toaster /> <Toaster />
<Analytics /> <Analytics />

View file

@ -30,7 +30,7 @@ const LoginPage = () => {
const res = await signIn("credentials", { const res = await signIn("credentials", {
redirect: false, redirect: false,
username, username,
password, password
}); });
if (res?.ok) { if (res?.ok) {

View file

@ -27,7 +27,7 @@ export async function GET() {
site_url: `${SITE_URL}`, site_url: `${SITE_URL}`,
image_url: `${SITE_URL}/metadata/svrjs-cover.png`, image_url: `${SITE_URL}/metadata/svrjs-cover.png`,
language: "en-US", language: "en-US",
pubDate: new Date().toUTCString(), pubDate: new Date().toUTCString()
}); });
posts.forEach((post: any) => { posts.forEach((post: any) => {
@ -35,7 +35,7 @@ export async function GET() {
title: post.title, title: post.title,
description: toHTML(post.content), description: toHTML(post.content),
url: `${SITE_URL}/blog/${post.slug}`, url: `${SITE_URL}/blog/${post.slug}`,
date: new Date(post._createdAt).toUTCString(), date: new Date(post._createdAt).toUTCString()
// uncomment this if u want to // uncomment this if u want to
// enclosure: { url: urlFor(post.titleImage).url() }, // enclosure: { url: urlFor(post.titleImage).url() },
// author: "SVRJS", // author: "SVRJS",
@ -44,7 +44,7 @@ export async function GET() {
return new NextResponse(feed.xml({ indent: true }), { return new NextResponse(feed.xml({ indent: true }), {
headers: { headers: {
"Content-Type": "application/xml", "Content-Type": "application/xml"
}, }
}); });
} }

View file

@ -15,15 +15,15 @@ export default async function sitemap() {
"/privacy-policy", "/privacy-policy",
"/tos", "/tos",
"/vulnerabilities", "/vulnerabilities",
"/newsletter", "/newsletter"
].map((route) => ({ ].map((route) => ({
url: `https://svrjs.vercel.app${route}`, url: `https://svrjs.vercel.app${route}`,
lastModified: new Date().toISOString().split("T")[0], lastModified: new Date().toISOString().split("T")[0]
})); }));
const blogRoutes = blogPostSlugs.map((slug) => ({ const blogRoutes = blogPostSlugs.map((slug) => ({
url: `https://svrjs.vercel.app/blog/${slug.slug}`, url: `https://svrjs.vercel.app/blog/${slug.slug}`,
lastModified: new Date().toISOString().split("T")[0], lastModified: new Date().toISOString().split("T")[0]
})); }));
return [...baseRoutes, ...blogRoutes]; return [...baseRoutes, ...blogRoutes];

View file

@ -10,7 +10,7 @@ import {
PaginationItem, PaginationItem,
PaginationLink, PaginationLink,
PaginationNext, PaginationNext,
PaginationPrevious, PaginationPrevious
} from "@/components/ui/pagination"; } from "@/components/ui/pagination";
import { format } from "date-fns"; import { format } from "date-fns";

View file

@ -13,8 +13,8 @@ const CodeEditor = ({ onChange }: CodeEditorProps) => {
<Editor <Editor
options={{ options={{
minimap: { minimap: {
enabled: false, enabled: false
}, }
}} }}
height="75vh" height="75vh"
theme="vs-dark" theme="vs-dark"

View file

@ -14,7 +14,7 @@ const TestimonialCard = ({
name, name,
role, role,
testimonial, testimonial,
rating, rating
}: TestimonialCard) => { }: TestimonialCard) => {
return ( return (
<li className="inline-block w-full"> <li className="inline-block w-full">

View file

@ -4,7 +4,7 @@ import {
Accordion, Accordion,
AccordionContent, AccordionContent,
AccordionItem, AccordionItem,
AccordionTrigger, AccordionTrigger
} from "../ui/accordion"; } from "../ui/accordion";
const Faq = () => { const Faq = () => {

View file

@ -13,7 +13,7 @@ import Image from "next/image";
const happyMonkey = Happy_Monkey({ const happyMonkey = Happy_Monkey({
preload: true, preload: true,
weight: ["400"], weight: ["400"],
subsets: ["latin"], subsets: ["latin"]
}); });
const Hero = () => { const Hero = () => {
@ -29,7 +29,7 @@ const Hero = () => {
linux: linux:
"curl -fsSL https://downloads.svrjs.org/installer/svr.js.installer.linux.20240509.sh > /tmp/installer.sh && sudo bash /tmp/installer.sh", "curl -fsSL https://downloads.svrjs.org/installer/svr.js.installer.linux.20240509.sh > /tmp/installer.sh && sudo bash /tmp/installer.sh",
docker: docker:
"docker pull svrjs/svrjs && docker run --name mysvrjs -d -p 80:80 --restart=always svrjs/svrjs", "docker pull svrjs/svrjs && docker run --name mysvrjs -d -p 80:80 --restart=always svrjs/svrjs"
}; };
const copyToClipboard = () => { const copyToClipboard = () => {

View file

@ -10,7 +10,7 @@ import {
CardDescription, CardDescription,
CardFooter, CardFooter,
CardHeader, CardHeader,
CardTitle, CardTitle
} from "@/components/ui/card"; } from "@/components/ui/card";
import Image from "next/image"; import Image from "next/image";
import { Happy_Monkey } from "next/font/google"; import { Happy_Monkey } from "next/font/google";
@ -21,7 +21,7 @@ import { useRouter } from "next/navigation";
const happyMonkey = Happy_Monkey({ const happyMonkey = Happy_Monkey({
preload: true, preload: true,
weight: ["400"], weight: ["400"],
subsets: ["latin"], subsets: ["latin"]
}); });
const HeroCards = () => { const HeroCards = () => {
@ -34,8 +34,8 @@ const HeroCards = () => {
x: "https://x.com/SVR_JS", x: "https://x.com/SVR_JS",
Mastodon: "https://mastodon.social/@svrjs", Mastodon: "https://mastodon.social/@svrjs",
Bluesky: "https://bsky.app/profile/svrjs.org", Bluesky: "https://bsky.app/profile/svrjs.org",
Odysee: "https://odysee.com/@SVRJS", Odysee: "https://odysee.com/@SVRJS"
}, }
}, },
pricingCard: { pricingCard: {
planName: "Pro Plan", planName: "Pro Plan",
@ -48,26 +48,26 @@ const HeroCards = () => {
features: [ features: [
{ {
title: "Unlimited Projects", title: "Unlimited Projects",
icons: <Infinity className="rounded-full" width={25} height={25} />, icons: <Infinity className="rounded-full" width={25} height={25} />
}, },
{ {
title: "Priority Support", title: "Priority Support",
icons: ( icons: (
<ArchiveRestore className="rounded-full" width={25} height={25} /> <ArchiveRestore className="rounded-full" width={25} height={25} />
), )
}, },
{ {
title: "Free Updates", title: "Free Updates",
icons: <Headset className="rounded-full" width={25} height={25} />, icons: <Headset className="rounded-full" width={25} height={25} />
}, }
], ],
curlyText: "Best Value!", curlyText: "Best Value!"
}, },
serviceCard: { serviceCard: {
title: "Our Services", title: "Our Services",
description: description:
"We offer a variety of services to cater to your needs, including web development, SEO, and more.", "We offer a variety of services to cater to your needs, including web development, SEO, and more."
}, }
}; };
return ( return (

View file

@ -3,7 +3,7 @@ import {
SheetContent, SheetContent,
SheetHeader, SheetHeader,
SheetTitle, SheetTitle,
SheetTrigger, SheetTrigger
} from "../ui/sheet"; } from "../ui/sheet";
import { Menu } from "lucide-react"; import { Menu } from "lucide-react";
import Image from "next/image"; import Image from "next/image";
@ -48,7 +48,7 @@ const MobileNav = () => {
href={href} href={href}
target={target} target={target}
className={`w-[110px] gap-2 ${buttonVariants({ className={`w-[110px] gap-2 ${buttonVariants({
variant: "secondary", variant: "secondary"
})}`} })}`}
> >
<svg <svg

View file

@ -3,7 +3,7 @@
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";
@ -44,7 +44,7 @@ const Navbar = () => {
className={`text-[17px] tracking-tight ${ className={`text-[17px] tracking-tight ${
pathname == href ? "bg-muted-foreground/20" : "" pathname == href ? "bg-muted-foreground/20" : ""
} ${buttonVariants({ } ${buttonVariants({
variant: "ghost", variant: "ghost"
})}`} })}`}
> >
{label} {label}
@ -61,7 +61,7 @@ const Navbar = () => {
target={target} target={target}
className={`border ${buttonVariants({ className={`border ${buttonVariants({
variant: "ghost", variant: "ghost",
size: "icon", size: "icon"
})}`} })}`}
> >
<span className="sr-only">Git</span> <span className="sr-only">Git</span>

View file

@ -11,7 +11,7 @@ import HCaptcha from "@hcaptcha/react-hcaptcha";
const happyMonkey = Happy_Monkey({ const happyMonkey = Happy_Monkey({
preload: true, preload: true,
weight: "400", weight: "400",
subsets: ["latin"], subsets: ["latin"]
}); });
const Newsletter = () => { const Newsletter = () => {
@ -41,9 +41,9 @@ const Newsletter = () => {
const response = await fetch("/api/subscribe", { const response = await fetch("/api/subscribe", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json"
}, },
body: JSON.stringify({ email: input, captchaToken: token }), body: JSON.stringify({ email: input, captchaToken: token })
}); });
if (response.ok) { if (response.ok) {

View file

@ -8,7 +8,7 @@ const testimonials = [
avatar: "avatar1", avatar: "avatar1",
testimonial: testimonial:
"Working with this team was a fantastic experience. They developed our website exactly to our specifications, and everything was seamless and well-integrated.", "Working with this team was a fantastic experience. They developed our website exactly to our specifications, and everything was seamless and well-integrated.",
rating: 5, rating: 5
}, },
{ {
name: "Jane Smith", name: "Jane Smith",
@ -16,7 +16,7 @@ const testimonials = [
avatar: "avatar2", avatar: "avatar2",
testimonial: testimonial:
"We're thrilled with the website. It's simple, clean, and has significantly boosted our sales. The developers did an excellent job.", "We're thrilled with the website. It's simple, clean, and has significantly boosted our sales. The developers did an excellent job.",
rating: 4, rating: 4
}, },
{ {
name: "Sam Green", name: "Sam Green",
@ -24,7 +24,7 @@ const testimonials = [
avatar: "avatar3", avatar: "avatar3",
testimonial: testimonial:
"Collaborating with this team to build a SaaS-integrated website was a perfect experience. I look forward to working with them again.", "Collaborating with this team to build a SaaS-integrated website was a perfect experience. I look forward to working with them again.",
rating: 5, rating: 5
}, },
{ {
name: "Chris Brown", name: "Chris Brown",
@ -32,14 +32,14 @@ const testimonials = [
avatar: "avatar4", avatar: "avatar4",
testimonial: testimonial:
"The team's understanding of our needs and their ability to provide fitting solutions was impressive. Their support and guidance were invaluable.", "The team's understanding of our needs and their ability to provide fitting solutions was impressive. Their support and guidance were invaluable.",
rating: 4, rating: 4
}, },
{ {
name: "Alex Johnson", name: "Alex Johnson",
avatar: "avatar5", avatar: "avatar5",
testimonial: testimonial:
"Exceptional service and outstanding results. They consistently deliver on time and within budget, making them our go-to partner for all our projects.", "Exceptional service and outstanding results. They consistently deliver on time and within budget, making them our go-to partner for all our projects.",
rating: 5, rating: 5
}, },
{ {
name: "Patricia Taylor", name: "Patricia Taylor",
@ -47,7 +47,7 @@ const testimonials = [
avatar: "avatar6", avatar: "avatar6",
testimonial: testimonial:
"It was great to work with them. I needed a design for a SaaS project, and it was delivered within 2 days.", "It was great to work with them. I needed a design for a SaaS project, and it was delivered within 2 days.",
rating: 4, rating: 4
}, },
{ {
name: "Emily Davis", name: "Emily Davis",
@ -55,22 +55,22 @@ const testimonials = [
avatar: "avatar7", avatar: "avatar7",
testimonial: testimonial:
"Collaborating with them has been a pleasure. Their creativity and user-centric approach have significantly enhanced our product's usability.", "Collaborating with them has been a pleasure. Their creativity and user-centric approach have significantly enhanced our product's usability.",
rating: 5, rating: 5
}, },
{ {
name: "Michael Lee", name: "Michael Lee",
avatar: "avatar8", avatar: "avatar8",
testimonial: testimonial:
"They have a keen understanding of our business needs and consistently deliver top-notch solutions. Their reliability and efficiency are commendable.", "They have a keen understanding of our business needs and consistently deliver top-notch solutions. Their reliability and efficiency are commendable.",
rating: 5, rating: 5
}, },
{ {
name: "Sarah Wilson", name: "Sarah Wilson",
avatar: "avatar9", avatar: "avatar9",
testimonial: testimonial:
"Their dedication to client satisfaction is evident in everything they do. We've seen remarkable improvements in our processes thanks to their expertise.", "Their dedication to client satisfaction is evident in everything they do. We've seen remarkable improvements in our processes thanks to their expertise.",
rating: 4, rating: 4
}, }
]; ];
const Testimonials = () => { const Testimonials = () => {

View file

@ -2,7 +2,7 @@
import { SessionProvider } from "next-auth/react"; import { SessionProvider } from "next-auth/react";
export default function AuthProvider({ export default function AuthProvider({
children, children
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {

View file

@ -5,7 +5,7 @@ interface ChangelogLayoutProps {
} }
export const ChangelogLayout: React.FC<ChangelogLayoutProps> = ({ export const ChangelogLayout: React.FC<ChangelogLayoutProps> = ({
children, children
}) => { }) => {
return ( return (
<div className="wrapper container py-24 md:py-28 gap-4 flex flex-col"> <div className="wrapper container py-24 md:py-28 gap-4 flex flex-col">

View file

@ -1,9 +1,9 @@
"use client" "use client";
import * as React from "react" import * as React from "react";
import { ThemeProvider as NextThemesProvider } from "next-themes" import { ThemeProvider as NextThemesProvider } from "next-themes";
import { type ThemeProviderProps } from "next-themes/dist/types" import { type ThemeProviderProps } from "next-themes/dist/types";
export function ThemeProvider({ children, ...props }: ThemeProviderProps) { export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider> return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
} }

View file

@ -3,7 +3,7 @@ import { ReactNode } from "react";
export default function AnimatedGradientText({ export default function AnimatedGradientText({
children, children,
className, className
}: { }: {
children: ReactNode; children: ReactNode;
className?: string; className?: string;
@ -12,7 +12,7 @@ export default function AnimatedGradientText({
<div <div
className={cn( className={cn(
"group relative mx-auto flex max-w-fit flex-row items-center justify-center rounded-2xl bg-white/40 px-4 py-1.5 text-sm font-medium shadow-[inset_0_-8px_10px_#8fdfff1f] backdrop-blur-sm transition-shadow duration-500 ease-out [--bg-size:300%] hover:shadow-[inset_0_-5px_10px_#8fdfff3f] dark:bg-black/40", "group relative mx-auto flex max-w-fit flex-row items-center justify-center rounded-2xl bg-white/40 px-4 py-1.5 text-sm font-medium shadow-[inset_0_-8px_10px_#8fdfff1f] backdrop-blur-sm transition-shadow duration-500 ease-out [--bg-size:300%] hover:shadow-[inset_0_-5px_10px_#8fdfff3f] dark:bg-black/40",
className, className
)} )}
> >
<div <div

View file

@ -10,13 +10,13 @@ interface AnimatedShinyTextProps {
const AnimatedShinyText: FC<AnimatedShinyTextProps> = ({ const AnimatedShinyText: FC<AnimatedShinyTextProps> = ({
children, children,
className, className,
shimmerWidth = 100, shimmerWidth = 100
}) => { }) => {
return ( return (
<p <p
style={ style={
{ {
"--shimmer-width": `${shimmerWidth}px`, "--shimmer-width": `${shimmerWidth}px`
} as CSSProperties } as CSSProperties
} }
className={cn( className={cn(
@ -28,7 +28,7 @@ const AnimatedShinyText: FC<AnimatedShinyTextProps> = ({
// Shimmer gradient // Shimmer gradient
"bg-gradient-to-r from-transparent via-black/80 via-50% to-transparent dark:via-white/80", "bg-gradient-to-r from-transparent via-black/80 via-50% to-transparent dark:via-white/80",
className, className
)} )}
> >
{children} {children}

View file

@ -13,7 +13,7 @@ const Avatar = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
className, className
)} )}
{...props} {...props}
/> />
@ -40,7 +40,7 @@ const AvatarFallback = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted", "flex h-full w-full items-center justify-center rounded-full bg-muted",
className, className
)} )}
{...props} {...props}
/> />

View file

@ -14,13 +14,13 @@ const badgeVariants = cva(
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive: destructive:
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
outline: "text-foreground", outline: "text-foreground"
}, }
}, },
defaultVariants: { defaultVariants: {
variant: "default", variant: "default"
}, }
}, }
); );
export interface BadgeProps export interface BadgeProps

View file

@ -19,7 +19,7 @@ export const BorderBeam = ({
borderWidth = 1.5, borderWidth = 1.5,
colorFrom = "#8803AF", colorFrom = "#8803AF",
colorTo = "#61DAFB", colorTo = "#61DAFB",
delay = 0, delay = 0
}: BorderBeamProps) => { }: BorderBeamProps) => {
return ( return (
<div <div
@ -31,7 +31,7 @@ export const BorderBeam = ({
"--border-width": borderWidth, "--border-width": borderWidth,
"--color-from": colorFrom, "--color-from": colorFrom,
"--color-to": colorTo, "--color-to": colorTo,
"--delay": `-${delay}s`, "--delay": `-${delay}s`
} as React.CSSProperties } as React.CSSProperties
} }
className={cn( className={cn(

View file

@ -1,8 +1,8 @@
import * as React from "react" import * as React from "react";
import { Slot } from "@radix-ui/react-slot" import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority" import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const buttonVariants = cva( const buttonVariants = cva(
"inline-flex items-center justify-center 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", "inline-flex items-center justify-center 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",
@ -17,40 +17,40 @@ const buttonVariants = cva(
secondary: secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80", "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground", ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline", link: "text-primary underline-offset-4 hover:underline"
}, },
size: { size: {
default: "h-10 px-4 py-2", default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3", sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8", lg: "h-11 rounded-md px-8",
icon: "h-10 w-10", icon: "h-10 w-10"
}, }
}, },
defaultVariants: { defaultVariants: {
variant: "default", variant: "default",
size: "default", size: "default"
},
} }
) }
);
export interface ButtonProps export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>, extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> { VariantProps<typeof buttonVariants> {
asChild?: boolean asChild?: boolean;
} }
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>( const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => { ({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button" const Comp = asChild ? Slot : "button";
return ( return (
<Comp <Comp
className={cn(buttonVariants({ variant, size, className }))} className={cn(buttonVariants({ variant, size, className }))}
ref={ref} ref={ref}
{...props} {...props}
/> />
) );
} }
) );
Button.displayName = "Button" Button.displayName = "Button";
export { Button, buttonVariants } export { Button, buttonVariants };

View file

@ -1,6 +1,6 @@
import * as React from "react" import * as React from "react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const Card = React.forwardRef< const Card = React.forwardRef<
HTMLDivElement, HTMLDivElement,
@ -14,8 +14,8 @@ const Card = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
Card.displayName = "Card" Card.displayName = "Card";
const CardHeader = React.forwardRef< const CardHeader = React.forwardRef<
HTMLDivElement, HTMLDivElement,
@ -26,8 +26,8 @@ const CardHeader = React.forwardRef<
className={cn("flex flex-col space-y-1.5 p-6", className)} className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props} {...props}
/> />
)) ));
CardHeader.displayName = "CardHeader" CardHeader.displayName = "CardHeader";
const CardTitle = React.forwardRef< const CardTitle = React.forwardRef<
HTMLParagraphElement, HTMLParagraphElement,
@ -41,8 +41,8 @@ const CardTitle = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
CardTitle.displayName = "CardTitle" CardTitle.displayName = "CardTitle";
const CardDescription = React.forwardRef< const CardDescription = React.forwardRef<
HTMLParagraphElement, HTMLParagraphElement,
@ -53,16 +53,16 @@ const CardDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)} className={cn("text-sm text-muted-foreground", className)}
{...props} {...props}
/> />
)) ));
CardDescription.displayName = "CardDescription" CardDescription.displayName = "CardDescription";
const CardContent = React.forwardRef< const CardContent = React.forwardRef<
HTMLDivElement, HTMLDivElement,
React.HTMLAttributes<HTMLDivElement> React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} /> <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
)) ));
CardContent.displayName = "CardContent" CardContent.displayName = "CardContent";
const CardFooter = React.forwardRef< const CardFooter = React.forwardRef<
HTMLDivElement, HTMLDivElement,
@ -73,7 +73,14 @@ const CardFooter = React.forwardRef<
className={cn("flex items-center p-6 pt-0", className)} className={cn("flex items-center p-6 pt-0", className)}
{...props} {...props}
/> />
)) ));
CardFooter.displayName = "CardFooter" CardFooter.displayName = "CardFooter";
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardDescription,
CardContent
};

View file

@ -1,18 +1,18 @@
"use client" "use client";
import * as React from "react" import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog" import * as DialogPrimitive from "@radix-ui/react-dialog";
import { X } from "lucide-react" import { X } from "lucide-react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const Dialog = DialogPrimitive.Root const Dialog = DialogPrimitive.Root;
const DialogTrigger = DialogPrimitive.Trigger const DialogTrigger = DialogPrimitive.Trigger;
const DialogPortal = DialogPrimitive.Portal const DialogPortal = DialogPrimitive.Portal;
const DialogClose = DialogPrimitive.Close const DialogClose = DialogPrimitive.Close;
const DialogOverlay = React.forwardRef< const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>, React.ElementRef<typeof DialogPrimitive.Overlay>,
@ -26,8 +26,8 @@ const DialogOverlay = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
const DialogContent = React.forwardRef< const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>, React.ElementRef<typeof DialogPrimitive.Content>,
@ -50,8 +50,8 @@ const DialogContent = React.forwardRef<
</DialogPrimitive.Close> </DialogPrimitive.Close>
</DialogPrimitive.Content> </DialogPrimitive.Content>
</DialogPortal> </DialogPortal>
)) ));
DialogContent.displayName = DialogPrimitive.Content.displayName DialogContent.displayName = DialogPrimitive.Content.displayName;
const DialogHeader = ({ const DialogHeader = ({
className, className,
@ -64,8 +64,8 @@ const DialogHeader = ({
)} )}
{...props} {...props}
/> />
) );
DialogHeader.displayName = "DialogHeader" DialogHeader.displayName = "DialogHeader";
const DialogFooter = ({ const DialogFooter = ({
className, className,
@ -78,8 +78,8 @@ const DialogFooter = ({
)} )}
{...props} {...props}
/> />
) );
DialogFooter.displayName = "DialogFooter" DialogFooter.displayName = "DialogFooter";
const DialogTitle = React.forwardRef< const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>, React.ElementRef<typeof DialogPrimitive.Title>,
@ -93,8 +93,8 @@ const DialogTitle = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
DialogTitle.displayName = DialogPrimitive.Title.displayName DialogTitle.displayName = DialogPrimitive.Title.displayName;
const DialogDescription = React.forwardRef< const DialogDescription = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Description>, React.ElementRef<typeof DialogPrimitive.Description>,
@ -105,8 +105,8 @@ const DialogDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)} className={cn("text-sm text-muted-foreground", className)}
{...props} {...props}
/> />
)) ));
DialogDescription.displayName = DialogPrimitive.Description.displayName DialogDescription.displayName = DialogPrimitive.Description.displayName;
export { export {
Dialog, Dialog,
@ -118,5 +118,5 @@ export {
DialogHeader, DialogHeader,
DialogFooter, DialogFooter,
DialogTitle, DialogTitle,
DialogDescription, DialogDescription
} };

View file

@ -1,27 +1,27 @@
"use client" "use client";
import * as React from "react" import * as React from "react";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { Check, ChevronRight, Circle } from "lucide-react" import { Check, ChevronRight, Circle } from "lucide-react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const DropdownMenu = DropdownMenuPrimitive.Root const DropdownMenu = DropdownMenuPrimitive.Root;
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
const DropdownMenuGroup = DropdownMenuPrimitive.Group const DropdownMenuGroup = DropdownMenuPrimitive.Group;
const DropdownMenuPortal = DropdownMenuPrimitive.Portal const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
const DropdownMenuSub = DropdownMenuPrimitive.Sub const DropdownMenuSub = DropdownMenuPrimitive.Sub;
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
const DropdownMenuSubTrigger = React.forwardRef< const DropdownMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>, React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & { React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean inset?: boolean;
} }
>(({ className, inset, children, ...props }, ref) => ( >(({ className, inset, children, ...props }, ref) => (
<DropdownMenuPrimitive.SubTrigger <DropdownMenuPrimitive.SubTrigger
@ -36,9 +36,9 @@ const DropdownMenuSubTrigger = React.forwardRef<
{children} {children}
<ChevronRight className="ml-auto h-4 w-4" /> <ChevronRight className="ml-auto h-4 w-4" />
</DropdownMenuPrimitive.SubTrigger> </DropdownMenuPrimitive.SubTrigger>
)) ));
DropdownMenuSubTrigger.displayName = DropdownMenuSubTrigger.displayName =
DropdownMenuPrimitive.SubTrigger.displayName DropdownMenuPrimitive.SubTrigger.displayName;
const DropdownMenuSubContent = React.forwardRef< const DropdownMenuSubContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>, React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
@ -52,9 +52,9 @@ const DropdownMenuSubContent = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
DropdownMenuSubContent.displayName = DropdownMenuSubContent.displayName =
DropdownMenuPrimitive.SubContent.displayName DropdownMenuPrimitive.SubContent.displayName;
const DropdownMenuContent = React.forwardRef< const DropdownMenuContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Content>, React.ElementRef<typeof DropdownMenuPrimitive.Content>,
@ -71,13 +71,13 @@ const DropdownMenuContent = React.forwardRef<
{...props} {...props}
/> />
</DropdownMenuPrimitive.Portal> </DropdownMenuPrimitive.Portal>
)) ));
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
const DropdownMenuItem = React.forwardRef< const DropdownMenuItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Item>, React.ElementRef<typeof DropdownMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & { React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean inset?: boolean;
} }
>(({ className, inset, ...props }, ref) => ( >(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Item <DropdownMenuPrimitive.Item
@ -89,8 +89,8 @@ const DropdownMenuItem = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
const DropdownMenuCheckboxItem = React.forwardRef< const DropdownMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>, React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
@ -112,9 +112,9 @@ const DropdownMenuCheckboxItem = React.forwardRef<
</span> </span>
{children} {children}
</DropdownMenuPrimitive.CheckboxItem> </DropdownMenuPrimitive.CheckboxItem>
)) ));
DropdownMenuCheckboxItem.displayName = DropdownMenuCheckboxItem.displayName =
DropdownMenuPrimitive.CheckboxItem.displayName DropdownMenuPrimitive.CheckboxItem.displayName;
const DropdownMenuRadioItem = React.forwardRef< const DropdownMenuRadioItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>, React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
@ -135,13 +135,13 @@ const DropdownMenuRadioItem = React.forwardRef<
</span> </span>
{children} {children}
</DropdownMenuPrimitive.RadioItem> </DropdownMenuPrimitive.RadioItem>
)) ));
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
const DropdownMenuLabel = React.forwardRef< const DropdownMenuLabel = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Label>, React.ElementRef<typeof DropdownMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & { React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean inset?: boolean;
} }
>(({ className, inset, ...props }, ref) => ( >(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Label <DropdownMenuPrimitive.Label
@ -153,8 +153,8 @@ const DropdownMenuLabel = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
const DropdownMenuSeparator = React.forwardRef< const DropdownMenuSeparator = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Separator>, React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
@ -165,8 +165,8 @@ const DropdownMenuSeparator = React.forwardRef<
className={cn("-mx-1 my-1 h-px bg-muted", className)} className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props} {...props}
/> />
)) ));
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
const DropdownMenuShortcut = ({ const DropdownMenuShortcut = ({
className, className,
@ -177,9 +177,9 @@ const DropdownMenuShortcut = ({
className={cn("ml-auto text-xs tracking-widest opacity-60", className)} className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
{...props} {...props}
/> />
) );
} };
DropdownMenuShortcut.displayName = "DropdownMenuShortcut" DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
export { export {
DropdownMenu, DropdownMenu,
@ -196,5 +196,5 @@ export {
DropdownMenuSub, DropdownMenuSub,
DropdownMenuSubContent, DropdownMenuSubContent,
DropdownMenuSubTrigger, DropdownMenuSubTrigger,
DropdownMenuRadioGroup, DropdownMenuRadioGroup
} };

View file

@ -1,30 +1,30 @@
import * as React from "react" import * as React from "react";
import * as LabelPrimitive from "@radix-ui/react-label" import * as LabelPrimitive from "@radix-ui/react-label";
import { Slot } from "@radix-ui/react-slot" import { Slot } from "@radix-ui/react-slot";
import { import {
Controller, Controller,
ControllerProps, ControllerProps,
FieldPath, FieldPath,
FieldValues, FieldValues,
FormProvider, FormProvider,
useFormContext, useFormContext
} from "react-hook-form" } from "react-hook-form";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
import { Label } from "@/components/ui/label" import { Label } from "@/components/ui/label";
const Form = FormProvider const Form = FormProvider;
type FormFieldContextValue< type FormFieldContextValue<
TFieldValues extends FieldValues = FieldValues, TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues> TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> = { > = {
name: TName name: TName;
} };
const FormFieldContext = React.createContext<FormFieldContextValue>( const FormFieldContext = React.createContext<FormFieldContextValue>(
{} as FormFieldContextValue {} as FormFieldContextValue
) );
const FormField = < const FormField = <
TFieldValues extends FieldValues = FieldValues, TFieldValues extends FieldValues = FieldValues,
@ -36,21 +36,21 @@ const FormField = <
<FormFieldContext.Provider value={{ name: props.name }}> <FormFieldContext.Provider value={{ name: props.name }}>
<Controller {...props} /> <Controller {...props} />
</FormFieldContext.Provider> </FormFieldContext.Provider>
) );
} };
const useFormField = () => { const useFormField = () => {
const fieldContext = React.useContext(FormFieldContext) const fieldContext = React.useContext(FormFieldContext);
const itemContext = React.useContext(FormItemContext) const itemContext = React.useContext(FormItemContext);
const { getFieldState, formState } = useFormContext() const { getFieldState, formState } = useFormContext();
const fieldState = getFieldState(fieldContext.name, formState) const fieldState = getFieldState(fieldContext.name, formState);
if (!fieldContext) { if (!fieldContext) {
throw new Error("useFormField should be used within <FormField>") throw new Error("useFormField should be used within <FormField>");
} }
const { id } = itemContext const { id } = itemContext;
return { return {
id, id,
@ -58,37 +58,37 @@ const useFormField = () => {
formItemId: `${id}-form-item`, formItemId: `${id}-form-item`,
formDescriptionId: `${id}-form-item-description`, formDescriptionId: `${id}-form-item-description`,
formMessageId: `${id}-form-item-message`, formMessageId: `${id}-form-item-message`,
...fieldState, ...fieldState
} };
} };
type FormItemContextValue = { type FormItemContextValue = {
id: string id: string;
} };
const FormItemContext = React.createContext<FormItemContextValue>( const FormItemContext = React.createContext<FormItemContextValue>(
{} as FormItemContextValue {} as FormItemContextValue
) );
const FormItem = React.forwardRef< const FormItem = React.forwardRef<
HTMLDivElement, HTMLDivElement,
React.HTMLAttributes<HTMLDivElement> React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => { >(({ className, ...props }, ref) => {
const id = React.useId() const id = React.useId();
return ( return (
<FormItemContext.Provider value={{ id }}> <FormItemContext.Provider value={{ id }}>
<div ref={ref} className={cn("space-y-2", className)} {...props} /> <div ref={ref} className={cn("space-y-2", className)} {...props} />
</FormItemContext.Provider> </FormItemContext.Provider>
) );
}) });
FormItem.displayName = "FormItem" FormItem.displayName = "FormItem";
const FormLabel = React.forwardRef< const FormLabel = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>, React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => { >(({ className, ...props }, ref) => {
const { error, formItemId } = useFormField() const { error, formItemId } = useFormField();
return ( return (
<Label <Label
@ -97,15 +97,16 @@ const FormLabel = React.forwardRef<
htmlFor={formItemId} htmlFor={formItemId}
{...props} {...props}
/> />
) );
}) });
FormLabel.displayName = "FormLabel" FormLabel.displayName = "FormLabel";
const FormControl = React.forwardRef< const FormControl = React.forwardRef<
React.ElementRef<typeof Slot>, React.ElementRef<typeof Slot>,
React.ComponentPropsWithoutRef<typeof Slot> React.ComponentPropsWithoutRef<typeof Slot>
>(({ ...props }, ref) => { >(({ ...props }, ref) => {
const { error, formItemId, formDescriptionId, formMessageId } = useFormField() const { error, formItemId, formDescriptionId, formMessageId } =
useFormField();
return ( return (
<Slot <Slot
@ -119,15 +120,15 @@ const FormControl = React.forwardRef<
aria-invalid={!!error} aria-invalid={!!error}
{...props} {...props}
/> />
) );
}) });
FormControl.displayName = "FormControl" FormControl.displayName = "FormControl";
const FormDescription = React.forwardRef< const FormDescription = React.forwardRef<
HTMLParagraphElement, HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement> React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => { >(({ className, ...props }, ref) => {
const { formDescriptionId } = useFormField() const { formDescriptionId } = useFormField();
return ( return (
<p <p
@ -136,19 +137,19 @@ const FormDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)} className={cn("text-sm text-muted-foreground", className)}
{...props} {...props}
/> />
) );
}) });
FormDescription.displayName = "FormDescription" FormDescription.displayName = "FormDescription";
const FormMessage = React.forwardRef< const FormMessage = React.forwardRef<
HTMLParagraphElement, HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement> React.HTMLAttributes<HTMLParagraphElement>
>(({ className, children, ...props }, ref) => { >(({ className, children, ...props }, ref) => {
const { error, formMessageId } = useFormField() const { error, formMessageId } = useFormField();
const body = error ? String(error?.message) : children const body = error ? String(error?.message) : children;
if (!body) { if (!body) {
return null return null;
} }
return ( return (
@ -160,9 +161,9 @@ const FormMessage = React.forwardRef<
> >
{body} {body}
</p> </p>
) );
}) });
FormMessage.displayName = "FormMessage" FormMessage.displayName = "FormMessage";
export { export {
useFormField, useFormField,
@ -172,5 +173,5 @@ export {
FormControl, FormControl,
FormDescription, FormDescription,
FormMessage, FormMessage,
FormField, FormField
} };

View file

@ -29,7 +29,7 @@ export function GridPattern({
aria-hidden="true" aria-hidden="true"
className={cn( className={cn(
"pointer-events-none absolute inset-0 h-full w-full fill-gray-400/35 stroke-gray-400/35", "pointer-events-none absolute inset-0 h-full w-full fill-gray-400/35 stroke-gray-400/35",
className, className
)} )}
{...props} {...props}
> >

View file

@ -26,50 +26,50 @@ const animationVariants = {
"from-bottom": { "from-bottom": {
initial: { y: "100%", opacity: 0 }, initial: { y: "100%", opacity: 0 },
animate: { y: 0, opacity: 1 }, animate: { y: 0, opacity: 1 },
exit: { y: "100%", opacity: 0 }, exit: { y: "100%", opacity: 0 }
}, },
"from-center": { "from-center": {
initial: { scale: 0.5, opacity: 0 }, initial: { scale: 0.5, opacity: 0 },
animate: { scale: 1, opacity: 1 }, animate: { scale: 1, opacity: 1 },
exit: { scale: 0.5, opacity: 0 }, exit: { scale: 0.5, opacity: 0 }
}, },
"from-top": { "from-top": {
initial: { y: "-100%", opacity: 0 }, initial: { y: "-100%", opacity: 0 },
animate: { y: 0, opacity: 1 }, animate: { y: 0, opacity: 1 },
exit: { y: "-100%", opacity: 0 }, exit: { y: "-100%", opacity: 0 }
}, },
"from-left": { "from-left": {
initial: { x: "-100%", opacity: 0 }, initial: { x: "-100%", opacity: 0 },
animate: { x: 0, opacity: 1 }, animate: { x: 0, opacity: 1 },
exit: { x: "-100%", opacity: 0 }, exit: { x: "-100%", opacity: 0 }
}, },
"from-right": { "from-right": {
initial: { x: "100%", opacity: 0 }, initial: { x: "100%", opacity: 0 },
animate: { x: 0, opacity: 1 }, animate: { x: 0, opacity: 1 },
exit: { x: "100%", opacity: 0 }, exit: { x: "100%", opacity: 0 }
}, },
fade: { fade: {
initial: { opacity: 0 }, initial: { opacity: 0 },
animate: { opacity: 1 }, animate: { opacity: 1 },
exit: { opacity: 0 }, exit: { opacity: 0 }
}, },
"top-in-bottom-out": { "top-in-bottom-out": {
initial: { y: "-100%", opacity: 0 }, initial: { y: "-100%", opacity: 0 },
animate: { y: 0, opacity: 1 }, animate: { y: 0, opacity: 1 },
exit: { y: "100%", opacity: 0 }, exit: { y: "100%", opacity: 0 }
}, },
"left-in-right-out": { "left-in-right-out": {
initial: { x: "-100%", opacity: 0 }, initial: { x: "-100%", opacity: 0 },
animate: { x: 0, opacity: 1 }, animate: { x: 0, opacity: 1 },
exit: { x: "100%", opacity: 0 }, exit: { x: "100%", opacity: 0 }
}, }
}; };
export default function HeroVideoDialog({ export default function HeroVideoDialog({
animationStyle = "from-center", animationStyle = "from-center",
videoSrc, videoSrc,
thumbnailSrc, thumbnailSrc,
thumbnailAlt = "Video thumbnail", thumbnailAlt = "Video thumbnail"
}: HeroVideoProps) { }: HeroVideoProps) {
const [isVideoOpen, setIsVideoOpen] = useState(false); const [isVideoOpen, setIsVideoOpen] = useState(false);
const [isCloseHovered, setIsCloseHovered] = useState(false); const [isCloseHovered, setIsCloseHovered] = useState(false);
@ -105,7 +105,7 @@ export default function HeroVideoDialog({
className="size-8 text-white" className="size-8 text-white"
style={{ style={{
transform: isPlayHovered ? "scale(1.1)" : "scale(1)", transform: isPlayHovered ? "scale(1.1)" : "scale(1)",
transition: "transform 0.3s ease", transition: "transform 0.3s ease"
}} }}
/> />
</div> </div>

View file

@ -10,9 +10,9 @@ const Iconss = () => {
x: "https://x.com/SVR_JS", x: "https://x.com/SVR_JS",
Mastodon: "https://mastodon.social/@svrjs", Mastodon: "https://mastodon.social/@svrjs",
Bluesky: "https://bsky.app/profile/svrjs.org", Bluesky: "https://bsky.app/profile/svrjs.org",
Odysee: "https://odysee.com/@SVRJS", Odysee: "https://odysee.com/@SVRJS"
}, }
}, }
}; };
return ( return (
@ -22,7 +22,7 @@ const Iconss = () => {
target="_blank" target="_blank"
className={buttonVariants({ className={buttonVariants({
variant: "ghost", variant: "ghost",
size: "sm", size: "sm"
})} })}
> >
<span className="sr-only">X icon</span> <span className="sr-only">X icon</span>
@ -44,7 +44,7 @@ const Iconss = () => {
target="_blank" target="_blank"
className={buttonVariants({ className={buttonVariants({
variant: "ghost", variant: "ghost",
size: "sm", size: "sm"
})} })}
> >
<span className="sr-only">Mastodon icon</span> <span className="sr-only">Mastodon icon</span>
@ -68,7 +68,7 @@ const Iconss = () => {
target="_blank" target="_blank"
className={buttonVariants({ className={buttonVariants({
variant: "ghost", variant: "ghost",
size: "sm", size: "sm"
})} })}
> >
<span className="sr-only">Bluesky icon</span> <span className="sr-only">Bluesky icon</span>
@ -92,7 +92,7 @@ const Iconss = () => {
target="_blank" target="_blank"
className={buttonVariants({ className={buttonVariants({
variant: "ghost", variant: "ghost",
size: "sm", size: "sm"
})} })}
> >
<span className="sr-only">Odysee icon</span> <span className="sr-only">Odysee icon</span>

View file

@ -1,6 +1,6 @@
import * as React from "react" import * as React from "react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
export interface InputProps export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {} extends React.InputHTMLAttributes<HTMLInputElement> {}
@ -17,9 +17,9 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
ref={ref} ref={ref}
{...props} {...props}
/> />
) );
} }
) );
Input.displayName = "Input" Input.displayName = "Input";
export { Input } export { Input };

View file

@ -1,14 +1,14 @@
"use client" "use client";
import * as React from "react" import * as React from "react";
import * as LabelPrimitive from "@radix-ui/react-label" import * as LabelPrimitive from "@radix-ui/react-label";
import { cva, type VariantProps } from "class-variance-authority" import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const labelVariants = cva( const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
) );
const Label = React.forwardRef< const Label = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>, React.ElementRef<typeof LabelPrimitive.Root>,
@ -20,7 +20,7 @@ const Label = React.forwardRef<
className={cn(labelVariants(), className)} className={cn(labelVariants(), className)}
{...props} {...props}
/> />
)) ));
Label.displayName = LabelPrimitive.Root.displayName Label.displayName = LabelPrimitive.Root.displayName;
export { Label } export { Label };

View file

@ -1,9 +1,9 @@
import * as React from "react" import * as React from "react";
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu" import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
import { cva } from "class-variance-authority" import { cva } from "class-variance-authority";
import { ChevronDown } from "lucide-react" import { ChevronDown } from "lucide-react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const NavigationMenu = React.forwardRef< const NavigationMenu = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Root>, React.ElementRef<typeof NavigationMenuPrimitive.Root>,
@ -20,8 +20,8 @@ const NavigationMenu = React.forwardRef<
{children} {children}
<NavigationMenuViewport /> <NavigationMenuViewport />
</NavigationMenuPrimitive.Root> </NavigationMenuPrimitive.Root>
)) ));
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
const NavigationMenuList = React.forwardRef< const NavigationMenuList = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.List>, React.ElementRef<typeof NavigationMenuPrimitive.List>,
@ -35,14 +35,14 @@ const NavigationMenuList = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
const NavigationMenuItem = NavigationMenuPrimitive.Item const NavigationMenuItem = NavigationMenuPrimitive.Item;
const navigationMenuTriggerStyle = cva( const navigationMenuTriggerStyle = cva(
"group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50" "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
) );
const NavigationMenuTrigger = React.forwardRef< const NavigationMenuTrigger = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Trigger>, React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,
@ -59,8 +59,8 @@ const NavigationMenuTrigger = React.forwardRef<
aria-hidden="true" aria-hidden="true"
/> />
</NavigationMenuPrimitive.Trigger> </NavigationMenuPrimitive.Trigger>
)) ));
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
const NavigationMenuContent = React.forwardRef< const NavigationMenuContent = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Content>, React.ElementRef<typeof NavigationMenuPrimitive.Content>,
@ -74,10 +74,10 @@ const NavigationMenuContent = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
const NavigationMenuLink = NavigationMenuPrimitive.Link const NavigationMenuLink = NavigationMenuPrimitive.Link;
const NavigationMenuViewport = React.forwardRef< const NavigationMenuViewport = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Viewport>, React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
@ -93,9 +93,9 @@ const NavigationMenuViewport = React.forwardRef<
{...props} {...props}
/> />
</div> </div>
)) ));
NavigationMenuViewport.displayName = NavigationMenuViewport.displayName =
NavigationMenuPrimitive.Viewport.displayName NavigationMenuPrimitive.Viewport.displayName;
const NavigationMenuIndicator = React.forwardRef< const NavigationMenuIndicator = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Indicator>, React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,
@ -111,9 +111,9 @@ const NavigationMenuIndicator = React.forwardRef<
> >
<div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" /> <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
</NavigationMenuPrimitive.Indicator> </NavigationMenuPrimitive.Indicator>
)) ));
NavigationMenuIndicator.displayName = NavigationMenuIndicator.displayName =
NavigationMenuPrimitive.Indicator.displayName NavigationMenuPrimitive.Indicator.displayName;
export { export {
navigationMenuTriggerStyle, navigationMenuTriggerStyle,
@ -124,5 +124,5 @@ export {
NavigationMenuTrigger, NavigationMenuTrigger,
NavigationMenuLink, NavigationMenuLink,
NavigationMenuIndicator, NavigationMenuIndicator,
NavigationMenuViewport, NavigationMenuViewport
} };

View file

@ -1,8 +1,8 @@
import * as React from "react" import * as React from "react";
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react" import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
import { ButtonProps, buttonVariants } from "@/components/ui/button" import { ButtonProps, buttonVariants } from "@/components/ui/button";
const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => ( const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
<nav <nav
@ -11,8 +11,8 @@ const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
className={cn("mx-auto flex w-full justify-center", className)} className={cn("mx-auto flex w-full justify-center", className)}
{...props} {...props}
/> />
) );
Pagination.displayName = "Pagination" Pagination.displayName = "Pagination";
const PaginationContent = React.forwardRef< const PaginationContent = React.forwardRef<
HTMLUListElement, HTMLUListElement,
@ -23,21 +23,21 @@ const PaginationContent = React.forwardRef<
className={cn("flex flex-row items-center gap-1", className)} className={cn("flex flex-row items-center gap-1", className)}
{...props} {...props}
/> />
)) ));
PaginationContent.displayName = "PaginationContent" PaginationContent.displayName = "PaginationContent";
const PaginationItem = React.forwardRef< const PaginationItem = React.forwardRef<
HTMLLIElement, HTMLLIElement,
React.ComponentProps<"li"> React.ComponentProps<"li">
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<li ref={ref} className={cn("", className)} {...props} /> <li ref={ref} className={cn("", className)} {...props} />
)) ));
PaginationItem.displayName = "PaginationItem" PaginationItem.displayName = "PaginationItem";
type PaginationLinkProps = { type PaginationLinkProps = {
isActive?: boolean isActive?: boolean;
} & Pick<ButtonProps, "size"> & } & Pick<ButtonProps, "size"> &
React.ComponentProps<"a"> React.ComponentProps<"a">;
const PaginationLink = ({ const PaginationLink = ({
className, className,
@ -50,14 +50,14 @@ const PaginationLink = ({
className={cn( className={cn(
buttonVariants({ buttonVariants({
variant: isActive ? "outline" : "ghost", variant: isActive ? "outline" : "ghost",
size, size
}), }),
className className
)} )}
{...props} {...props}
/> />
) );
PaginationLink.displayName = "PaginationLink" PaginationLink.displayName = "PaginationLink";
const PaginationPrevious = ({ const PaginationPrevious = ({
className, className,
@ -72,8 +72,8 @@ const PaginationPrevious = ({
<ChevronLeft className="h-4 w-4" /> <ChevronLeft className="h-4 w-4" />
<span>Previous</span> <span>Previous</span>
</PaginationLink> </PaginationLink>
) );
PaginationPrevious.displayName = "PaginationPrevious" PaginationPrevious.displayName = "PaginationPrevious";
const PaginationNext = ({ const PaginationNext = ({
className, className,
@ -88,8 +88,8 @@ const PaginationNext = ({
<span>Next</span> <span>Next</span>
<ChevronRight className="h-4 w-4" /> <ChevronRight className="h-4 w-4" />
</PaginationLink> </PaginationLink>
) );
PaginationNext.displayName = "PaginationNext" PaginationNext.displayName = "PaginationNext";
const PaginationEllipsis = ({ const PaginationEllipsis = ({
className, className,
@ -103,8 +103,8 @@ const PaginationEllipsis = ({
<MoreHorizontal className="h-4 w-4" /> <MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More pages</span> <span className="sr-only">More pages</span>
</span> </span>
) );
PaginationEllipsis.displayName = "PaginationEllipsis" PaginationEllipsis.displayName = "PaginationEllipsis";
export { export {
Pagination, Pagination,
@ -113,5 +113,5 @@ export {
PaginationItem, PaginationItem,
PaginationLink, PaginationLink,
PaginationNext, PaginationNext,
PaginationPrevious, PaginationPrevious
} };

View file

@ -1,16 +1,16 @@
"use client" "use client";
import * as React from "react" import * as React from "react";
import * as SelectPrimitive from "@radix-ui/react-select" import * as SelectPrimitive from "@radix-ui/react-select";
import { Check, ChevronDown, ChevronUp } from "lucide-react" import { Check, ChevronDown, ChevronUp } from "lucide-react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const Select = SelectPrimitive.Root const Select = SelectPrimitive.Root;
const SelectGroup = SelectPrimitive.Group const SelectGroup = SelectPrimitive.Group;
const SelectValue = SelectPrimitive.Value const SelectValue = SelectPrimitive.Value;
const SelectTrigger = React.forwardRef< const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>, React.ElementRef<typeof SelectPrimitive.Trigger>,
@ -29,8 +29,8 @@ const SelectTrigger = React.forwardRef<
<ChevronDown className="h-4 w-4 opacity-50" /> <ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon> </SelectPrimitive.Icon>
</SelectPrimitive.Trigger> </SelectPrimitive.Trigger>
)) ));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
const SelectScrollUpButton = React.forwardRef< const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>, React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
@ -46,8 +46,8 @@ const SelectScrollUpButton = React.forwardRef<
> >
<ChevronUp className="h-4 w-4" /> <ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton> </SelectPrimitive.ScrollUpButton>
)) ));
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
const SelectScrollDownButton = React.forwardRef< const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>, React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
@ -63,9 +63,9 @@ const SelectScrollDownButton = React.forwardRef<
> >
<ChevronDown className="h-4 w-4" /> <ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton> </SelectPrimitive.ScrollDownButton>
)) ));
SelectScrollDownButton.displayName = SelectScrollDownButton.displayName =
SelectPrimitive.ScrollDownButton.displayName SelectPrimitive.ScrollDownButton.displayName;
const SelectContent = React.forwardRef< const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>, React.ElementRef<typeof SelectPrimitive.Content>,
@ -96,8 +96,8 @@ const SelectContent = React.forwardRef<
<SelectScrollDownButton /> <SelectScrollDownButton />
</SelectPrimitive.Content> </SelectPrimitive.Content>
</SelectPrimitive.Portal> </SelectPrimitive.Portal>
)) ));
SelectContent.displayName = SelectPrimitive.Content.displayName SelectContent.displayName = SelectPrimitive.Content.displayName;
const SelectLabel = React.forwardRef< const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>, React.ElementRef<typeof SelectPrimitive.Label>,
@ -108,8 +108,8 @@ const SelectLabel = React.forwardRef<
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)} className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
{...props} {...props}
/> />
)) ));
SelectLabel.displayName = SelectPrimitive.Label.displayName SelectLabel.displayName = SelectPrimitive.Label.displayName;
const SelectItem = React.forwardRef< const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>, React.ElementRef<typeof SelectPrimitive.Item>,
@ -131,8 +131,8 @@ const SelectItem = React.forwardRef<
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText> <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item> </SelectPrimitive.Item>
)) ));
SelectItem.displayName = SelectPrimitive.Item.displayName SelectItem.displayName = SelectPrimitive.Item.displayName;
const SelectSeparator = React.forwardRef< const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>, React.ElementRef<typeof SelectPrimitive.Separator>,
@ -143,8 +143,8 @@ const SelectSeparator = React.forwardRef<
className={cn("-mx-1 my-1 h-px bg-muted", className)} className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props} {...props}
/> />
)) ));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
export { export {
Select, Select,
@ -156,5 +156,5 @@ export {
SelectItem, SelectItem,
SelectSeparator, SelectSeparator,
SelectScrollUpButton, SelectScrollUpButton,
SelectScrollDownButton, SelectScrollDownButton
} };

View file

@ -1,9 +1,9 @@
"use client" "use client";
import * as React from "react" import * as React from "react";
import * as SeparatorPrimitive from "@radix-ui/react-separator" import * as SeparatorPrimitive from "@radix-ui/react-separator";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const Separator = React.forwardRef< const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>, React.ElementRef<typeof SeparatorPrimitive.Root>,
@ -25,7 +25,7 @@ const Separator = React.forwardRef<
{...props} {...props}
/> />
) )
) );
Separator.displayName = SeparatorPrimitive.Root.displayName Separator.displayName = SeparatorPrimitive.Root.displayName;
export { Separator } export { Separator };

View file

@ -40,12 +40,12 @@ const sheetVariants = cva(
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right: right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"
}, }
}, },
defaultVariants: { defaultVariants: {
side: "right", side: "right"
}, }
} }
); );
@ -136,5 +136,5 @@ export {
SheetHeader, SheetHeader,
SheetFooter, SheetFooter,
SheetTitle, SheetTitle,
SheetDescription, SheetDescription
}; };

View file

@ -1,4 +1,4 @@
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
function Skeleton({ function Skeleton({
className, className,
@ -9,7 +9,7 @@ function Skeleton({
className={cn("animate-pulse rounded-md bg-muted", className)} className={cn("animate-pulse rounded-md bg-muted", className)}
{...props} {...props}
/> />
) );
} }
export { Skeleton } export { Skeleton };

View file

@ -1,6 +1,6 @@
import * as React from "react" import * as React from "react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const Table = React.forwardRef< const Table = React.forwardRef<
HTMLTableElement, HTMLTableElement,
@ -13,16 +13,16 @@ const Table = React.forwardRef<
{...props} {...props}
/> />
</div> </div>
)) ));
Table.displayName = "Table" Table.displayName = "Table";
const TableHeader = React.forwardRef< const TableHeader = React.forwardRef<
HTMLTableSectionElement, HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement> React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} /> <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
)) ));
TableHeader.displayName = "TableHeader" TableHeader.displayName = "TableHeader";
const TableBody = React.forwardRef< const TableBody = React.forwardRef<
HTMLTableSectionElement, HTMLTableSectionElement,
@ -33,8 +33,8 @@ const TableBody = React.forwardRef<
className={cn("[&_tr:last-child]:border-0", className)} className={cn("[&_tr:last-child]:border-0", className)}
{...props} {...props}
/> />
)) ));
TableBody.displayName = "TableBody" TableBody.displayName = "TableBody";
const TableFooter = React.forwardRef< const TableFooter = React.forwardRef<
HTMLTableSectionElement, HTMLTableSectionElement,
@ -48,8 +48,8 @@ const TableFooter = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
TableFooter.displayName = "TableFooter" TableFooter.displayName = "TableFooter";
const TableRow = React.forwardRef< const TableRow = React.forwardRef<
HTMLTableRowElement, HTMLTableRowElement,
@ -63,8 +63,8 @@ const TableRow = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
TableRow.displayName = "TableRow" TableRow.displayName = "TableRow";
const TableHead = React.forwardRef< const TableHead = React.forwardRef<
HTMLTableCellElement, HTMLTableCellElement,
@ -78,8 +78,8 @@ const TableHead = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
TableHead.displayName = "TableHead" TableHead.displayName = "TableHead";
const TableCell = React.forwardRef< const TableCell = React.forwardRef<
HTMLTableCellElement, HTMLTableCellElement,
@ -90,8 +90,8 @@ const TableCell = React.forwardRef<
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)} className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
{...props} {...props}
/> />
)) ));
TableCell.displayName = "TableCell" TableCell.displayName = "TableCell";
const TableCaption = React.forwardRef< const TableCaption = React.forwardRef<
HTMLTableCaptionElement, HTMLTableCaptionElement,
@ -102,8 +102,8 @@ const TableCaption = React.forwardRef<
className={cn("mt-4 text-sm text-muted-foreground", className)} className={cn("mt-4 text-sm text-muted-foreground", className)}
{...props} {...props}
/> />
)) ));
TableCaption.displayName = "TableCaption" TableCaption.displayName = "TableCaption";
export { export {
Table, Table,
@ -113,5 +113,5 @@ export {
TableHead, TableHead,
TableRow, TableRow,
TableCell, TableCell,
TableCaption, TableCaption
} };

View file

@ -1,6 +1,6 @@
import * as React from "react" import * as React from "react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
export interface TextareaProps export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {} extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
@ -16,9 +16,9 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
ref={ref} ref={ref}
{...props} {...props}
/> />
) );
} }
) );
Textarea.displayName = "Textarea" Textarea.displayName = "Textarea";
export { Textarea } export { Textarea };

View file

@ -5,7 +5,7 @@ import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
DropdownMenuItem, DropdownMenuItem,
DropdownMenuTrigger, DropdownMenuTrigger
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { Moon, Sun } from "lucide-react"; import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";

View file

@ -1,13 +1,13 @@
"use client" "use client";
import * as React from "react" import * as React from "react";
import * as ToastPrimitives from "@radix-ui/react-toast" import * as ToastPrimitives from "@radix-ui/react-toast";
import { cva, type VariantProps } from "class-variance-authority" import { cva, type VariantProps } from "class-variance-authority";
import { X } from "lucide-react" import { X } from "lucide-react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const ToastProvider = ToastPrimitives.Provider const ToastProvider = ToastPrimitives.Provider;
const ToastViewport = React.forwardRef< const ToastViewport = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Viewport>, React.ElementRef<typeof ToastPrimitives.Viewport>,
@ -21,8 +21,8 @@ const ToastViewport = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
ToastViewport.displayName = ToastPrimitives.Viewport.displayName ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
const toastVariants = cva( const toastVariants = cva(
"group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
@ -31,14 +31,14 @@ const toastVariants = cva(
variant: { variant: {
default: "border bg-background text-foreground", default: "border bg-background text-foreground",
destructive: destructive:
"destructive group border-destructive bg-destructive text-destructive-foreground", "destructive group border-destructive bg-destructive text-destructive-foreground"
}, }
}, },
defaultVariants: { defaultVariants: {
variant: "default", variant: "default"
},
} }
) }
);
const Toast = React.forwardRef< const Toast = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Root>, React.ElementRef<typeof ToastPrimitives.Root>,
@ -51,9 +51,9 @@ const Toast = React.forwardRef<
className={cn(toastVariants({ variant }), className)} className={cn(toastVariants({ variant }), className)}
{...props} {...props}
/> />
) );
}) });
Toast.displayName = ToastPrimitives.Root.displayName Toast.displayName = ToastPrimitives.Root.displayName;
const ToastAction = React.forwardRef< const ToastAction = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Action>, React.ElementRef<typeof ToastPrimitives.Action>,
@ -67,8 +67,8 @@ const ToastAction = React.forwardRef<
)} )}
{...props} {...props}
/> />
)) ));
ToastAction.displayName = ToastPrimitives.Action.displayName ToastAction.displayName = ToastPrimitives.Action.displayName;
const ToastClose = React.forwardRef< const ToastClose = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Close>, React.ElementRef<typeof ToastPrimitives.Close>,
@ -85,8 +85,8 @@ const ToastClose = React.forwardRef<
> >
<X className="h-4 w-4" /> <X className="h-4 w-4" />
</ToastPrimitives.Close> </ToastPrimitives.Close>
)) ));
ToastClose.displayName = ToastPrimitives.Close.displayName ToastClose.displayName = ToastPrimitives.Close.displayName;
const ToastTitle = React.forwardRef< const ToastTitle = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Title>, React.ElementRef<typeof ToastPrimitives.Title>,
@ -97,8 +97,8 @@ const ToastTitle = React.forwardRef<
className={cn("text-sm font-semibold", className)} className={cn("text-sm font-semibold", className)}
{...props} {...props}
/> />
)) ));
ToastTitle.displayName = ToastPrimitives.Title.displayName ToastTitle.displayName = ToastPrimitives.Title.displayName;
const ToastDescription = React.forwardRef< const ToastDescription = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Description>, React.ElementRef<typeof ToastPrimitives.Description>,
@ -109,12 +109,12 @@ const ToastDescription = React.forwardRef<
className={cn("text-sm opacity-90", className)} className={cn("text-sm opacity-90", className)}
{...props} {...props}
/> />
)) ));
ToastDescription.displayName = ToastPrimitives.Description.displayName ToastDescription.displayName = ToastPrimitives.Description.displayName;
type ToastProps = React.ComponentPropsWithoutRef<typeof Toast> type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;
type ToastActionElement = React.ReactElement<typeof ToastAction> type ToastActionElement = React.ReactElement<typeof ToastAction>;
export { export {
type ToastProps, type ToastProps,
@ -125,5 +125,5 @@ export {
ToastTitle, ToastTitle,
ToastDescription, ToastDescription,
ToastClose, ToastClose,
ToastAction, ToastAction
} };

View file

@ -1,4 +1,4 @@
"use client" "use client";
import { import {
Toast, Toast,
@ -6,12 +6,12 @@ import {
ToastDescription, ToastDescription,
ToastProvider, ToastProvider,
ToastTitle, ToastTitle,
ToastViewport, ToastViewport
} from "@/components/ui/toast" } from "@/components/ui/toast";
import { useToast } from "@/components/ui/use-toast" import { useToast } from "@/components/ui/use-toast";
export function Toaster() { export function Toaster() {
const { toasts } = useToast() const { toasts } = useToast();
return ( return (
<ToastProvider> <ToastProvider>
@ -27,9 +27,9 @@ export function Toaster() {
{action} {action}
<ToastClose /> <ToastClose />
</Toast> </Toast>
) );
})} })}
<ToastViewport /> <ToastViewport />
</ToastProvider> </ToastProvider>
) );
} }

View file

@ -1,106 +1,103 @@
"use client" "use client";
// Inspired by react-hot-toast library // Inspired by react-hot-toast library
import * as React from "react" import * as React from "react";
import type { import type { ToastActionElement, ToastProps } from "@/components/ui/toast";
ToastActionElement,
ToastProps,
} from "@/components/ui/toast"
const TOAST_LIMIT = 1 const TOAST_LIMIT = 1;
const TOAST_REMOVE_DELAY = 1000000 const TOAST_REMOVE_DELAY = 1000000;
type ToasterToast = ToastProps & { type ToasterToast = ToastProps & {
id: string id: string;
title?: React.ReactNode title?: React.ReactNode;
description?: React.ReactNode description?: React.ReactNode;
action?: ToastActionElement action?: ToastActionElement;
} };
const actionTypes = { const actionTypes = {
ADD_TOAST: "ADD_TOAST", ADD_TOAST: "ADD_TOAST",
UPDATE_TOAST: "UPDATE_TOAST", UPDATE_TOAST: "UPDATE_TOAST",
DISMISS_TOAST: "DISMISS_TOAST", DISMISS_TOAST: "DISMISS_TOAST",
REMOVE_TOAST: "REMOVE_TOAST", REMOVE_TOAST: "REMOVE_TOAST"
} as const } as const;
let count = 0 let count = 0;
function genId() { function genId() {
count = (count + 1) % Number.MAX_SAFE_INTEGER count = (count + 1) % Number.MAX_SAFE_INTEGER;
return count.toString() return count.toString();
} }
type ActionType = typeof actionTypes type ActionType = typeof actionTypes;
type Action = type Action =
| { | {
type: ActionType["ADD_TOAST"] type: ActionType["ADD_TOAST"];
toast: ToasterToast toast: ToasterToast;
} }
| { | {
type: ActionType["UPDATE_TOAST"] type: ActionType["UPDATE_TOAST"];
toast: Partial<ToasterToast> toast: Partial<ToasterToast>;
} }
| { | {
type: ActionType["DISMISS_TOAST"] type: ActionType["DISMISS_TOAST"];
toastId?: ToasterToast["id"] toastId?: ToasterToast["id"];
} }
| { | {
type: ActionType["REMOVE_TOAST"] type: ActionType["REMOVE_TOAST"];
toastId?: ToasterToast["id"] toastId?: ToasterToast["id"];
} };
interface State { interface State {
toasts: ToasterToast[] toasts: ToasterToast[];
} }
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>() const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
const addToRemoveQueue = (toastId: string) => { const addToRemoveQueue = (toastId: string) => {
if (toastTimeouts.has(toastId)) { if (toastTimeouts.has(toastId)) {
return return;
} }
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
toastTimeouts.delete(toastId) toastTimeouts.delete(toastId);
dispatch({ dispatch({
type: "REMOVE_TOAST", type: "REMOVE_TOAST",
toastId: toastId, toastId: toastId
}) });
}, TOAST_REMOVE_DELAY) }, TOAST_REMOVE_DELAY);
toastTimeouts.set(toastId, timeout) toastTimeouts.set(toastId, timeout);
} };
export const reducer = (state: State, action: Action): State => { export const reducer = (state: State, action: Action): State => {
switch (action.type) { switch (action.type) {
case "ADD_TOAST": case "ADD_TOAST":
return { return {
...state, ...state,
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT), toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT)
} };
case "UPDATE_TOAST": case "UPDATE_TOAST":
return { return {
...state, ...state,
toasts: state.toasts.map((t) => toasts: state.toasts.map((t) =>
t.id === action.toast.id ? { ...t, ...action.toast } : t t.id === action.toast.id ? { ...t, ...action.toast } : t
), )
} };
case "DISMISS_TOAST": { case "DISMISS_TOAST": {
const { toastId } = action const { toastId } = action;
// ! Side effects ! - This could be extracted into a dismissToast() action, // ! Side effects ! - This could be extracted into a dismissToast() action,
// but I'll keep it here for simplicity // but I'll keep it here for simplicity
if (toastId) { if (toastId) {
addToRemoveQueue(toastId) addToRemoveQueue(toastId);
} else { } else {
state.toasts.forEach((toast) => { state.toasts.forEach((toast) => {
addToRemoveQueue(toast.id) addToRemoveQueue(toast.id);
}) });
} }
return { return {
@ -109,48 +106,48 @@ export const reducer = (state: State, action: Action): State => {
t.id === toastId || toastId === undefined t.id === toastId || toastId === undefined
? { ? {
...t, ...t,
open: false, open: false
} }
: t : t
), )
} };
} }
case "REMOVE_TOAST": case "REMOVE_TOAST":
if (action.toastId === undefined) { if (action.toastId === undefined) {
return { return {
...state, ...state,
toasts: [], toasts: []
} };
} }
return { return {
...state, ...state,
toasts: state.toasts.filter((t) => t.id !== action.toastId), toasts: state.toasts.filter((t) => t.id !== action.toastId)
};
} }
} };
}
const listeners: Array<(state: State) => void> = [] const listeners: Array<(state: State) => void> = [];
let memoryState: State = { toasts: [] } let memoryState: State = { toasts: [] };
function dispatch(action: Action) { function dispatch(action: Action) {
memoryState = reducer(memoryState, action) memoryState = reducer(memoryState, action);
listeners.forEach((listener) => { listeners.forEach((listener) => {
listener(memoryState) listener(memoryState);
}) });
} }
type Toast = Omit<ToasterToast, "id"> type Toast = Omit<ToasterToast, "id">;
function toast({ ...props }: Toast) { function toast({ ...props }: Toast) {
const id = genId() const id = genId();
const update = (props: ToasterToast) => const update = (props: ToasterToast) =>
dispatch({ dispatch({
type: "UPDATE_TOAST", type: "UPDATE_TOAST",
toast: { ...props, id }, toast: { ...props, id }
}) });
const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id }) const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id });
dispatch({ dispatch({
type: "ADD_TOAST", type: "ADD_TOAST",
@ -159,36 +156,36 @@ function toast({ ...props }: Toast) {
id, id,
open: true, open: true,
onOpenChange: (open) => { onOpenChange: (open) => {
if (!open) dismiss() if (!open) dismiss();
}, }
}, }
}) });
return { return {
id: id, id: id,
dismiss, dismiss,
update, update
} };
} }
function useToast() { function useToast() {
const [state, setState] = React.useState<State>(memoryState) const [state, setState] = React.useState<State>(memoryState);
React.useEffect(() => { React.useEffect(() => {
listeners.push(setState) listeners.push(setState);
return () => { return () => {
const index = listeners.indexOf(setState) const index = listeners.indexOf(setState);
if (index > -1) { if (index > -1) {
listeners.splice(index, 1) listeners.splice(index, 1);
} }
} };
}, [state]) }, [state]);
return { return {
...state, ...state,
toast, toast,
dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }), dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId })
} };
} }
export { useToast, toast } export { useToast, toast };

View file

@ -20,7 +20,7 @@ export default function Banner({
link, link,
buttonText = "Learn More", buttonText = "Learn More",
closeButton = true, closeButton = true,
icon, icon
}: BannerProps) { }: BannerProps) {
const [isBannerVisible, setIsBannerVisible] = useState(true); const [isBannerVisible, setIsBannerVisible] = useState(true);
@ -43,7 +43,7 @@ export default function Banner({
<div <div
style={{ style={{
clipPath: clipPath:
"polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)", "polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)"
}} }}
className="aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-primary to-yellow-200 opacity-30" className="aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-primary to-yellow-200 opacity-30"
/> />
@ -55,7 +55,7 @@ export default function Banner({
<div <div
style={{ style={{
clipPath: clipPath:
"polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)", "polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)"
}} }}
className="aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-primary to-[#9089fc] opacity-30" className="aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-primary to-[#9089fc] opacity-30"
/> />

View file

@ -9,7 +9,7 @@ export default function NumberTicker({
value, value,
direction = "up", direction = "up",
delay = 0, delay = 0,
className, className
}: { }: {
value: number; value: number;
direction?: "up" | "down"; direction?: "up" | "down";
@ -20,7 +20,7 @@ export default function NumberTicker({
const motionValue = useMotionValue(direction === "down" ? value : 0); const motionValue = useMotionValue(direction === "down" ? value : 0);
const springValue = useSpring(motionValue, { const springValue = useSpring(motionValue, {
damping: 60, damping: 60,
stiffness: 100, stiffness: 100
}); });
const isInView = useInView(ref, { once: true, margin: "0px" }); const isInView = useInView(ref, { once: true, margin: "0px" });

View file

@ -5,8 +5,8 @@ export const transporter = nodemailer.createTransport({
port: 587, port: 587,
auth: { auth: {
user: process.env.EMAIL, user: process.env.EMAIL,
pass: process.env.EMAIL_PASS, pass: process.env.EMAIL_PASS
}, }
}); });
export const mailOptions = { export const mailOptions = {
@ -33,5 +33,5 @@ export const mailOptions = {
<td></td> <td></td>
</tr> </tr>
</table> </table>
`, `
}; };

View file

@ -5,7 +5,7 @@ const config = {
apiVersion: "2023-08-08", apiVersion: "2023-08-08",
dataset: "production", dataset: "production",
projectId: `${process.env.SANITY_PROJECT_ID}`, projectId: `${process.env.SANITY_PROJECT_ID}`,
useCdn: false, // ensure fresh data useCdn: false // ensure fresh data
}; };
export const client = createClient(config); export const client = createClient(config);

View file

@ -1,6 +1,6 @@
import { import {
generateUploadButton, generateUploadButton,
generateUploadDropzone, generateUploadDropzone
} from "@uploadthing/react"; } from "@uploadthing/react";
import type { OurFileRouter } from "@/app/api/uploadthing/core"; import type { OurFileRouter } from "@/app/api/uploadthing/core";

View file

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

View file

@ -4,14 +4,14 @@ export const downloadSchema = z.object({
fileName: z.string().nonempty(), fileName: z.string().nonempty(),
version: z.string().nonempty(), version: z.string().nonempty(),
downloadLink: z.string().url().nonempty(), downloadLink: z.string().url().nonempty(),
fileSize: z.string().nonempty(), fileSize: z.string().nonempty()
}); });
export const modsSchema = z.object({ export const modsSchema = z.object({
fileName: z.string().nonempty(), fileName: z.string().nonempty(),
version: z.string().nonempty(), version: z.string().nonempty(),
downloadLink: z.string().url().nonempty(), downloadLink: z.string().url().nonempty(),
fileSize: z.string().nonempty(), fileSize: z.string().nonempty()
}); });
export const logsSchema = z.object({ export const logsSchema = z.object({
@ -19,18 +19,18 @@ export const logsSchema = z.object({
date: z.string(), date: z.string(),
bullets: z.array( bullets: z.array(
z.object({ z.object({
point: z.string(), point: z.string()
}) })
), )
}); });
export const vulnerabilitiesSchema = z.object({ export const vulnerabilitiesSchema = z.object({
version: z.string(), version: z.string(),
bullets: z.array( bullets: z.array(
z.object({ z.object({
point: z.string(), point: z.string()
}) })
), )
}); });
export const ModsVulnerabilities = z.object({ export const ModsVulnerabilities = z.object({
@ -38,9 +38,9 @@ export const ModsVulnerabilities = z.object({
category: z.string(), category: z.string(),
bullets: z.array( bullets: z.array(
z.object({ z.object({
point: z.string(), point: z.string()
}) })
), )
}); });
export type LogsFormValues = z.infer<typeof logsSchema>; export type LogsFormValues = z.infer<typeof logsSchema>;
@ -51,12 +51,12 @@ export type ModsVulnerability = z.infer<typeof ModsVulnerabilities>;
export const contactFormSchema = z.object({ export const contactFormSchema = z.object({
name: z.string().min(2, { name: z.string().min(2, {
message: "Name must be at least 2 characters.", message: "Name must be at least 2 characters."
}), }),
email: z.string().email({ email: z.string().email({
message: "Invalid email address.", message: "Invalid email address."
}), }),
message: z.string().min(10, { message: z.string().min(10, {
message: "Message must be at least 10 characters.", message: "Message must be at least 10 characters."
}), })
}); });

View file

@ -4,7 +4,7 @@ import { AppProps } from "next/app";
const poppins = Poppins({ const poppins = Poppins({
weight: ["400", "600", "700", "900"], weight: ["400", "600", "700", "900"],
subsets: ["latin"], subsets: ["latin"]
}); });
function MyApp({ Component, pageProps }: AppProps) { function MyApp({ Component, pageProps }: AppProps) {