This commit is contained in:
MacRimi 2025-02-14 12:05:00 +01:00
parent c56f306c91
commit 0fdd3e32a3
41 changed files with 0 additions and 4847 deletions

View File

@ -1,18 +0,0 @@
import { Button } from "@/components/ui/button"
export default function CTA() {
return (
<section className="py-20 bg-primary text-white">
<div className="container mx-auto text-center">
<h2 className="text-3xl font-bold mb-6">Ready to Streamline Your Workflow?</h2>
<p className="text-xl mb-8 max-w-2xl mx-auto">
Join thousands of teams already using StreamLine to boost their productivity.
</p>
<Button size="lg" variant="secondary">
Start Your Free Trial
</Button>
</div>
</section>
)
}

View File

@ -1,14 +0,0 @@
"use client";
import Navbar from "@/components/navbar"
import MouseMoveEffect from "@/components/mouse-move-effect"
export default function ClientLayout({ children }: { children: React.ReactNode }) {
return (
<>
<Navbar />
<MouseMoveEffect />
<div className="pt-16 md:pt-16">{children}</div>
</>
)
}

View File

@ -1,50 +0,0 @@
"use client"
import Link from "next/link"
import { usePathname } from "next/navigation"
import { useState } from "react"
import { Menu } from "lucide-react"
const sidebarItems = [
{ title: "Introduction", href: "/docs/introduction" },
{ title: "Installation", href: "/docs/installation" },
{ title: "Getting Started", href: "/docs/getting-started" },
{ title: "Features", href: "/docs/features" },
{ title: "API", href: "/docs/api" },
{ title: "Guides", href: "/guides" },
{ title: "FAQ", href: "/docs/faq" },
]
export default function DocSidebar() {
const pathname = usePathname()
const [isOpen, setIsOpen] = useState(false)
return (
<nav className="w-full md:w-64 bg-gray-100 p-4 md:p-6">
<div className="flex justify-between items-center md:block">
<h2 className="text-lg font-semibold mb-4 text-gray-900">Documentation</h2>
<button className="md:hidden" onClick={() => setIsOpen(!isOpen)}>
<Menu className="h-6 w-6" />
</button>
</div>
<ul className={`space-y-2 ${isOpen ? "block" : "hidden"} md:block`}>
{sidebarItems.map((item) => (
<li key={item.href}>
<Link
href={item.href}
className={`block p-2 rounded ${
pathname === item.href
? "bg-blue-500 text-white"
: "text-gray-700 hover:bg-gray-200 hover:text-gray-900"
}`}
onClick={() => setIsOpen(false)}
>
{item.title}
</Link>
</li>
))}
</ul>
</nav>
)
}

View File

@ -1,28 +0,0 @@
"use client"
import { useEffect, useState } from "react"
export default function MouseMoveEffect() {
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
useEffect(() => {
const handleMouseMove = (event: MouseEvent) => {
setMousePosition({ x: event.clientX, y: event.clientY })
}
window.addEventListener("mousemove", handleMouseMove)
return () => {
window.removeEventListener("mousemove", handleMouseMove)
}
}, [])
return (
<div
className="pointer-events-none fixed inset-0 z-30 transition-opacity duration-300"
style={{
background: `radial-gradient(600px at ${mousePosition.x}px ${mousePosition.y}px, rgba(29, 78, 216, 0.15), transparent 80%)`,
}}
/>
)
}

View File

@ -1,44 +0,0 @@
import { CheckCircle, Zap, Users, TrendingUp } from "lucide-react"
const features = [
{
icon: <CheckCircle className="h-8 w-8 text-primary" />,
title: "Task Management",
description: "Organize and prioritize tasks with ease.",
},
{
icon: <Zap className="h-8 w-8 text-primary" />,
title: "Real-time Collaboration",
description: "Work together seamlessly in real-time.",
},
{
icon: <Users className="h-8 w-8 text-primary" />,
title: "Team Communication",
description: "Stay connected with built-in messaging.",
},
{
icon: <TrendingUp className="h-8 w-8 text-primary" />,
title: "Analytics Dashboard",
description: "Track progress and gain insights with powerful analytics.",
},
]
export default function Features() {
return (
<section id="features" className="py-20 bg-gray-50">
<div className="container mx-auto">
<h2 className="text-3xl font-bold text-center mb-12">Key Features</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
{features.map((feature, index) => (
<div key={index} className="bg-white p-6 rounded-lg shadow-md">
<div className="mb-4">{feature.icon}</div>
<h3 className="text-xl font-semibold mb-2">{feature.title}</h3>
<p className="text-gray-600">{feature.description}</p>
</div>
))}
</div>
</div>
</section>
)
}

View File

@ -1,58 +0,0 @@
import Link from "next/link"
import { MessageCircle } from "lucide-react"
import Image from "next/image"
export default function Footer() {
return (
<footer className="bg-gray-900 text-white py-12">
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex flex-col md:flex-row justify-between">
{/* Support Section - Left Side */}
<div className="flex flex-col items-start mb-8 md:mb-0">
<h4 className="text-lg font-semibold mb-4">Sponsor</h4>
<p className="text-gray-400 mb-4 max-w-md">
If you would like to support the project, you can buy me a coffee on Ko-fi! Thank you! 😊
</p>
<a
href="https://ko-fi.com/G2G313ECAN"
target="_blank"
rel="noopener noreferrer"
className="hover:opacity-90 transition-opacity flex items-center"
>
<Image
src="https://raw.githubusercontent.com/MacRimi/HWEncoderX/main/images/kofi.png"
alt="Support me on Ko-fi"
width={175}
height={50}
className="w-[175px] mr-[65px]"
/>
</a>
</div>
{/* Connect Section - Right Side */}
<div className="flex flex-col items-start md:items-end">
<h4 className="text-lg font-semibold mb-4">Connect</h4>
<p className="text-gray-400 mb-4 max-w-md md:text-right">
Join our community discussions on GitHub to get help, share ideas, and contribute to the project.
</p>
<Link
href="https://github.com/MacRimi/ProxMenux/discussions"
className="flex items-center text-blue-400 hover:text-blue-300 transition-colors duration-200"
target="_blank"
rel="noopener noreferrer"
>
<MessageCircle className="mr-2 h-5 w-5" />
Join the Discussion
</Link>
</div>
</div>
{/* Copyright - Center */}
<div className="mt-8 pt-8 border-t border-gray-800 text-center text-gray-400">
<p>&copy; {new Date().getFullYear()} ProxMenux. All rights reserved.</p>
</div>
</div>
</footer>
)
}

View File

@ -1,27 +0,0 @@
import Link from "next/link"
import { Button } from "@/components/ui/button"
export default function Header() {
return (
<header className="py-4 px-6 bg-white shadow-sm">
<div className="container mx-auto flex justify-between items-center">
<Link href="/" className="text-2xl font-bold text-primary">
StreamLine
</Link>
<nav className="hidden md:flex space-x-6">
<Link href="#features" className="text-gray-600 hover:text-primary">
Features
</Link>
<Link href="#testimonials" className="text-gray-600 hover:text-primary">
Testimonials
</Link>
<Link href="#pricing" className="text-gray-600 hover:text-primary">
Pricing
</Link>
</nav>
<Button>Get Started</Button>
</div>
</header>
)
}

View File

@ -1,30 +0,0 @@
import { Button } from "@/components/ui/button"
import { ArrowRight } from "lucide-react"
import Link from "next/link"
export default function Hero() {
return (
<section className="py-20 px-4 sm:px-6 lg:px-8 text-center">
<h1 className="text-4xl sm:text-5xl md:text-6xl font-extrabold mb-6">
ProxMenux{" "}
<span className="bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-500">
A menu-driven script for Proxmox VE management
</span>
</h1>
<p className="text-base sm:text-lg md:text-xl mb-8 max-w-4xl mx-auto text-gray-300">
ProxMenu is a tool designed to execute shell scripts in an organized manner, using a menu system with categories
to facilitate access and execution of various scripts hosted on GitHub. ProxMenu simplifies script usage, aiming
to improve productivity and streamline automated tasks.
</p>
<div className="flex justify-center">
<Button size="lg" className="bg-blue-500 hover:bg-blue-600" asChild>
<Link href="/docs/installation">
Install Now
<ArrowRight className="ml-2 h-4 w-4" />
</Link>
</Button>
</div>
</section>
)
}

View File

@ -1,29 +0,0 @@
"use client"
import { useEffect, useState } from "react"
export default function MouseMoveEffect() {
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
useEffect(() => {
const handleMouseMove = (event: MouseEvent) => {
setMousePosition({ x: event.clientX, y: event.clientY })
}
window.addEventListener("mousemove", handleMouseMove)
return () => {
window.removeEventListener("mousemove", handleMouseMove)
}
}, [])
return (
<div
className="pointer-events-none fixed inset-0 z-30 transition-opacity duration-300"
style={{
background: `radial-gradient(600px at ${mousePosition.x}px ${mousePosition.y}px, rgba(29, 78, 216, 0.15), transparent 80%)`,
}}
/>
)
}

View File

@ -1,73 +0,0 @@
"use client"
import Link from "next/link"
import Image from "next/image"
import { Book, GitBranch, FileText, Github, Menu } from "lucide-react"
import { useState } from "react"
export default function Navbar() {
const [isMenuOpen, setIsMenuOpen] = useState(false)
const navItems = [
{ href: "/docs/introduction", icon: <Book className="h-4 w-4" />, label: "Documentation" },
{ href: "/changelog", icon: <FileText className="h-4 w-4" />, label: "Changelog" },
{ href: "/guides", icon: <GitBranch className="h-4 w-4" />, label: "Guides" },
{ href: "https://github.com/MacRimi/ProxMenux", icon: <Github className="h-4 w-4" />, label: "GitHub" },
]
return (
<header className="fixed top-0 left-0 right-0 z-50 bg-background/95 backdrop-blur border-b border-border/40">
<div className="container mx-auto px-4">
<div className="flex items-center justify-between h-16">
<Link href="/" className="flex items-center space-x-2">
<Image
src="https://raw.githubusercontent.com/MacRimi/ProxMenux/main/images/logo2.png"
alt="ProxMenux Logo"
width={32}
height={32}
className="w-8 h-8"
/>
<span className="text-xl font-bold">ProxMenux</span>
</Link>
{/* Desktop menu */}
<nav className="hidden md:flex items-center space-x-6 text-sm font-medium">
{navItems.map((item) => (
<Link
key={item.href}
href={item.href}
className="flex items-center space-x-2 transition-colors hover:text-primary"
>
{item.icon}
<span>{item.label}</span>
</Link>
))}
</nav>
{/* Mobile menu button */}
<button className="md:hidden p-2" onClick={() => setIsMenuOpen(!isMenuOpen)}>
<Menu className="h-6 w-6" />
</button>
</div>
{/* Mobile menu */}
{isMenuOpen && (
<nav className="md:hidden py-4">
{navItems.map((item) => (
<Link
key={item.href}
href={item.href}
className="flex items-center space-x-2 py-2 transition-colors hover:text-primary"
onClick={() => setIsMenuOpen(false)}
>
{item.icon}
<span>{item.label}</span>
</Link>
))}
</nav>
)}
</div>
</header>
)
}

View File

@ -1,53 +0,0 @@
import { Check } from "lucide-react"
import { Button } from "@/components/ui/button"
const plans = [
{
name: "Basic",
price: "$9",
features: ["5 team members", "10 projects", "Basic analytics", "Email support"],
},
{
name: "Pro",
price: "$29",
features: ["Unlimited team members", "Unlimited projects", "Advanced analytics", "Priority support"],
},
{
name: "Enterprise",
price: "Custom",
features: ["Custom features", "Dedicated account manager", "On-premise deployment", "24/7 phone support"],
},
]
export default function Pricing() {
return (
<section id="pricing" className="py-20 bg-gray-50">
<div className="container mx-auto">
<h2 className="text-3xl font-bold text-center mb-12">Choose Your Plan</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{plans.map((plan, index) => (
<div key={index} className="bg-white p-8 rounded-lg shadow-md">
<h3 className="text-2xl font-bold mb-4">{plan.name}</h3>
<p className="text-4xl font-bold mb-6">
{plan.price}
<span className="text-lg font-normal text-gray-600">/month</span>
</p>
<ul className="mb-8">
{plan.features.map((feature, featureIndex) => (
<li key={featureIndex} className="flex items-center mb-2">
<Check className="h-5 w-5 text-primary mr-2" />
<span>{feature}</span>
</li>
))}
</ul>
<Button className="w-full" variant={index === 1 ? "default" : "outline"}>
{index === 2 ? "Contact Sales" : "Get Started"}
</Button>
</div>
))}
</div>
</div>
</section>
)
}

View File

@ -1,21 +0,0 @@
import Image from "next/image"
export default function ProductPreview() {
return (
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-20">
<div className="relative rounded-lg overflow-hidden border border-white/10 shadow-2xl">
<div className="absolute inset-0 bg-gradient-to-tr from-primary/10 via-accent/10 to-transparent" />
<Image
src="https://sjc.microlink.io/dACoBD81V0jhbU_TaUYiRrOVrhAXOh8TCYVdXmvVaYFIpbvF9B17bU0pnQF3gHfzVAOFzC-nwZVACScUpFYQsg.jpeg"
alt="Huly App Interface"
width={1200}
height={800}
className="w-full h-auto"
/>
</div>
{/* Glow effect */}
<div className="absolute -inset-x-20 top-0 h-[500px] bg-gradient-conic opacity-30 blur-3xl" />
</div>
)
}

View File

@ -1,52 +0,0 @@
import { Book, GitBranch, FileText, Github } from "lucide-react"
import Link from "next/link"
const resources = [
{
icon: <Book className="h-6 w-6" />,
title: "Documentation",
description: "Comprehensive guides to get you started",
link: "/docs/introduction",
},
{
icon: <FileText className="h-6 w-6" />,
title: "Changelog",
description: "Stay up to date with the latest changes",
link: "/changelog",
},
{
icon: <GitBranch className="h-6 w-6" />,
title: "Guides",
description: "Step-by-step tutorials for common tasks",
link: "/guides",
},
{
icon: <Github className="h-6 w-6" />,
title: "GitHub Repository",
description: "Explore the source code and contribute",
link: "https://github.com/MacRimi/ProxMenux",
},
]
export default function Resources() {
return (
<section className="py-20 bg-gray-900">
<div className="container mx-auto px-4">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
{resources.map((resource, index) => (
<Link key={index} href={resource.link} className="block">
<div className="bg-gray-800 p-6 rounded-lg shadow-lg hover:bg-gray-700 transition-colors duration-200">
<div className="flex items-center mb-4">
{resource.icon}
<h3 className="text-xl font-semibold ml-2">{resource.title}</h3>
</div>
<p className="text-gray-400">{resource.description}</p>
</div>
</Link>
))}
</div>
</div>
</section>
)
}

View File

@ -1,26 +0,0 @@
import { Button } from "@/components/ui/button"
import { Star } from "lucide-react"
export default function SupportProject() {
return (
<section className="py-16 bg-gray-900">
<div className="container mx-auto px-4 text-center">
<h2 className="text-3xl font-bold mb-6">Support the Project!</h2>
<p className="text-xl mb-8">
If you find <span className="font-bold">ProxMenux</span> useful, consider giving it a on GitHub to help
others discover it!
</p>
<div className="flex justify-center items-center">
<Button
className="bg-yellow-400 text-gray-900 hover:bg-yellow-500"
onClick={() => window.open("https://github.com/MacRimi/ProxMenux", "_blank")}
>
<Star className="mr-2" />
Star on GitHub
</Button>
</div>
</div>
</section>
)
}

View File

@ -1,35 +0,0 @@
const testimonials = [
{
quote: "StreamLine has revolutionized our team's workflow. It's a game-changer!",
author: "Jane Doe",
company: "Tech Innovators Inc.",
},
{
quote: "The best project management tool we've ever used. Highly recommended!",
author: "John Smith",
company: "Creative Solutions LLC",
},
{
quote: "StreamLine helped us increase productivity by 40%. It's incredible!",
author: "Emily Johnson",
company: "Startup Ventures",
},
]
export default function Testimonials() {
return (
<section className="py-20 px-4 sm:px-6 lg:px-8 bg-gray-900">
<h2 className="text-3xl font-bold text-center mb-12">What Our Customers Say</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{testimonials.map((testimonial, index) => (
<div key={index} className="bg-gray-800 p-6 rounded-lg shadow-lg">
<p className="text-lg mb-4">"{testimonial.quote}"</p>
<p className="font-semibold">{testimonial.author}</p>
<p className="text-sm text-gray-400">{testimonial.company}</p>
</div>
))}
</div>
</section>
)
}

View File

@ -1,7 +0,0 @@
'use client'
import { ThemeProvider as NextThemesProvider } from "next-themes";
export function ThemeProvider({ children }: { children: React.ReactNode }) {
return <NextThemesProvider>{children}</NextThemesProvider>;
}

View File

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

View File

@ -1,35 +0,0 @@
import React from "react"
interface StepProps {
title: string
children: React.ReactNode
}
const Step: React.FC<StepProps> = ({ title, children }) => (
<div className="mb-8">
<h3 className="text-xl font-semibold mb-2 text-gray-900">{title}</h3>
{children}
</div>
)
interface StepsProps {
children: React.ReactNode
}
const Steps: React.FC<StepsProps> & { Step: typeof Step } = ({ children }) => (
<div className="space-y-4">
{React.Children.map(children, (child, index) => (
<div className="flex items-start">
<div className="flex-shrink-0 w-8 h-8 bg-blue-500 text-white rounded-full flex items-center justify-center mr-4 mt-1">
{index + 1}
</div>
<div className="flex-grow">{child}</div>
</div>
))}
</div>
)
Steps.Step = Step
export { Steps }

View File

@ -1,129 +0,0 @@
"use client"
import * as React from "react"
import * as ToastPrimitives from "@radix-ui/react-toast"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"
import { cn } from "@/lib/utils"
const ToastProvider = ToastPrimitives.Provider
const ToastViewport = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Viewport>,
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
>(({ className, ...props }, ref) => (
<ToastPrimitives.Viewport
ref={ref}
className={cn(
"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
className
)}
{...props}
/>
))
ToastViewport.displayName = ToastPrimitives.Viewport.displayName
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",
{
variants: {
variant: {
default: "border bg-background text-foreground",
destructive:
"destructive group border-destructive bg-destructive text-destructive-foreground",
},
},
defaultVariants: {
variant: "default",
},
}
)
const Toast = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Root>,
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &
VariantProps<typeof toastVariants>
>(({ className, variant, ...props }, ref) => {
return (
<ToastPrimitives.Root
ref={ref}
className={cn(toastVariants({ variant }), className)}
{...props}
/>
)
})
Toast.displayName = ToastPrimitives.Root.displayName
const ToastAction = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Action>,
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>
>(({ className, ...props }, ref) => (
<ToastPrimitives.Action
ref={ref}
className={cn(
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
className
)}
{...props}
/>
))
ToastAction.displayName = ToastPrimitives.Action.displayName
const ToastClose = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Close>,
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
>(({ className, ...props }, ref) => (
<ToastPrimitives.Close
ref={ref}
className={cn(
"absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
className
)}
toast-close=""
{...props}
>
<X className="h-4 w-4" />
</ToastPrimitives.Close>
))
ToastClose.displayName = ToastPrimitives.Close.displayName
const ToastTitle = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Title>,
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>
>(({ className, ...props }, ref) => (
<ToastPrimitives.Title
ref={ref}
className={cn("text-sm font-semibold", className)}
{...props}
/>
))
ToastTitle.displayName = ToastPrimitives.Title.displayName
const ToastDescription = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Description>,
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>
>(({ className, ...props }, ref) => (
<ToastPrimitives.Description
ref={ref}
className={cn("text-sm opacity-90", className)}
{...props}
/>
))
ToastDescription.displayName = ToastPrimitives.Description.displayName
type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>
type ToastActionElement = React.ReactElement<typeof ToastAction>
export {
type ToastProps,
type ToastActionElement,
ToastProvider,
ToastViewport,
Toast,
ToastTitle,
ToastDescription,
ToastClose,
ToastAction,
}

View File

@ -1,33 +0,0 @@
export default function InstallationPage() {
return (
<div className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 py-8 text-gray-900">
<h1 className="text-3xl sm:text-4xl font-bold mb-6">Installing ProxMenux</h1>
<h2 className="text-2xl font-semibold mt-8 mb-4">Installation</h2>
<p className="mb-4">To install ProxMenux, simply run the following command in your Proxmox server terminal:</p>
<pre className="bg-gray-100 p-4 rounded-md overflow-x-auto text-sm">
<code>
bash -c "$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)"
</code>
</pre>
<h2 className="text-2xl font-semibold mt-8 mb-4">How to Use</h2>
<p className="mb-4">
Once installed, launch <strong>ProxMenux</strong> by running:
</p>
<pre className="bg-gray-100 p-4 rounded-md overflow-x-auto text-sm">
<code>menu</code>
</pre>
<h2 className="text-2xl font-semibold mt-8 mb-4">Troubleshooting</h2>
<p className="mb-4">
If you encounter any issues during installation or usage, please check the{" "}
<a href="https://github.com/MacRimi/ProxMenux/issues" className="text-blue-600 hover:underline">
GitHub Issues
</a>{" "}
page or open a new issue if your problem isn't already addressed.
</p>
</div>
)
}

View File

@ -1,25 +0,0 @@
export default function IntroductionPage() {
return (
<div className="max-w-3xl mx-auto">
<h1 className="text-3xl font-bold mb-6">Introduction to ProxMenux</h1>
<p className="mb-4">
ProxMenux is a tool designed to simplify and streamline the management of Proxmox VE through a menu-based interface. It allows users to execute shell scripts in an organized way, eliminating the need to manually enter complex commands.
It is designed for both experienced Proxmox VE administrators and less experienced users, providing a more accessible and efficient way to manage their infrastructure.
</p>
<h2 className="text-2xl font-semibold mt-8 mb-4">Key Features</h2>
<ul className="list-disc pl-6 space-y-2">
<li>Menu-based interface for easy script execution.</li>
<li>Organized categories for quick access to available functions.</li>
<li>Scripts hosted on GitHub, always accessible and up to date.</li>
<li>Automatic text translation using Google Translate.</li>
<li>Simplified Proxmox VE management, reducing the complexity of common tasks.</li>
</ul>
<p className="mt-6">
The following sections of this documentation provide instructions on how to install ProxMenux and detailed explanations of each available script.
</p>
</div>
)
}

View File

@ -1,16 +0,0 @@
import type React from "react"
import DocSidebar from "@/components/DocSidebar"
import Footer from "@/components/footer"
export default function DocsLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex flex-col min-h-screen bg-white text-gray-900">
<div className="flex flex-col md:flex-row flex-1">
<DocSidebar />
<main className="flex-1 p-4 md:p-6">{children}</main>
</div>
<Footer />
</div>
)
}

View File

@ -1,60 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 5.9% 10%;
--radius: 0.5rem;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}

View File

@ -1,38 +0,0 @@
import fs from "fs"
import path from "path"
import { remark } from "remark"
import html from "remark-html"
// Function to retrieve the guide content based on the slug
async function getGuideContent(slug: string) {
// Adjusted to look inside the correct 'guides' folder at the root level of the project
const guidePath = path.join(process.cwd(), "..", "guides", slug, "index.md") // Corrected to look in the root directory
const fileContents = fs.readFileSync(guidePath, "utf8")
const result = await remark().use(html).process(fileContents)
return result.toString()
}
// Function to generate static paths for all available guides
export async function generateStaticParams() {
// Adjusted to look in the correct 'guides' folder at the root level of the project
const guidesPath = path.join(process.cwd(), "..", "guides")
const guideFolders = fs.readdirSync(guidesPath, { withFileTypes: true }) // Read only directories
return guideFolders
.filter((folder) => folder.isDirectory()) // Ensure it's a directory
.map((folder) => ({
slug: folder.name, // Use the folder name as slug
}))
}
// Page component to render a guide based on its slug
export default async function GuidePage({ params }: { params: { slug: string } }) {
const guideContent = await getGuideContent(params.slug)
return (
<div className="container mx-auto px-4 py-16 max-w-3xl">
<div className="prose prose-lg dark:prose-invert" dangerouslySetInnerHTML={{ __html: guideContent }} />
</div>
)
}

View File

@ -1,46 +0,0 @@
import Link from "next/link"
// Interface defining the structure of a guide
interface Guide {
title: string
description: string
slug: string
}
// Guide list (manually added, can be automated later)
const guides: Guide[] = [
{
title: "Setting up NVIDIA Drivers on Proxmox VE with GPU Passthrough",
description:
"Learn how to install and configure NVIDIA drivers on your Proxmox VE host and enable GPU passthrough to your virtual machines.",
slug: "nvidia_proxmox",
},
{
title: "Example Additional Guide",
description: "This is a sample guide to show how multiple guides are handled.",
slug: "example_guide",
},
// Add more guides as needed
]
// Main component that renders the list of available guides
export default function GuidesPage() {
return (
<div className="container mx-auto px-4 py-16">
<h1 className="text-4xl font-bold mb-8">ProxMenux Guides</h1>
<p className="text-xl mb-8">Complementary guides to make the most of your Proxmox VE.</p>
<div className="grid md:grid-cols-2 gap-6">
{guides.map((guide) => (
<Link
key={guide.slug}
href={`/guides/${guide.slug}`}
className="block p-6 bg-white rounded-lg shadow-md hover:shadow-lg transition-shadow"
>
<h2 className="text-2xl font-semibold mb-2 text-gray-900">{guide.title}</h2>
<p className="text-gray-600">{guide.description}</p>
</Link>
))}
</div>
</div>
)
}

View File

@ -1,23 +0,0 @@
import "./globals.css"
import { Inter } from "next/font/google"
import type { Metadata } from "next"
import ClientLayout from "@/components/ClientLayout"
const inter = Inter({ subsets: ["latin"] })
export const metadata: Metadata = {
title: "ProxMenux - A menu-driven script for Proxmox VE management",
description:
"ProxMenux is a tool designed to execute shell scripts in an organized manner for Proxmox VE management.",
generator: "v0.dev",
}
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className="dark">
<body className={`${inter.className} bg-background text-foreground antialiased`}>
<ClientLayout>{children}</ClientLayout>
</body>
</html>
)
}

View File

@ -1,20 +0,0 @@
"use client";
import Hero from "@/components/hero"
import Resources from "@/components/resources"
import SupportProject from "@/components/support-project"
import Footer from "@/components/footer"
export default function Home() {
return (
<div className="min-h-screen bg-gradient-to-b from-gray-900 to-gray-800 text-white pt-16">
{" "}
{/* Added pt-16 for navbar space */}
<Hero />
<Resources />
<SupportProject />
<Footer />
</div>
)
}

View File

@ -1,19 +0,0 @@
import * as React from "react"
const MOBILE_BREAKPOINT = 768
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
}
mql.addEventListener("change", onChange)
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
return () => mql.removeEventListener("change", onChange)
}, [])
return !!isMobile
}

View File

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

View File

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

View File

@ -1,11 +0,0 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "export", // Forces static export for GitHub Pages
trailingSlash: true, // Fixes route issues
images: {
unoptimized: true, // Fixes image loading issues on GitHub Pages
},
assetPrefix: process.env.NODE_ENV === "production" ? "/ProxMenux" : "",
}
module.exports = nextConfig

3331
web2/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +0,0 @@
{
"name": "proxmenux-docs",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "13.4.7",
"react": "18.2.0",
"react-dom": "18.2.0",
"remark": "^14.0.3",
"remark-html": "^15.0.2",
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"lucide-react": "^0.284.0",
"tailwind-merge": "^1.14.0",
"next-themes": "^0.2.0",
"tailwindcss-animate": "^1.0.7",
"@radix-ui/react-accordion": "^1.0.2",
"@radix-ui/react-alert-dialog": "^1.0.2",
"@radix-ui/react-aspect-ratio": "^1.0.2",
"@radix-ui/react-avatar": "^1.0.2",
"@radix-ui/react-dialog": "^1.0.2",
"@radix-ui/react-tooltip": "^1.0.2",
"@radix-ui/react-switch": "^1.0.2",
"@radix-ui/react-popover": "^1.0.2",
"@radix-ui/react-toast": "^1.0.2"
},
"devDependencies": {
"@types/node": "^20.8.4",
"@types/react": "^18.2.27",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.3",
"typescript": "^5.2.2"
}
}

Binary file not shown.

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="215" height="48" fill="none"><path fill="#000" d="M57.588 9.6h6L73.828 38h-5.2l-2.36-6.88h-11.36L52.548 38h-5.2l10.24-28.4Zm7.16 17.16-4.16-12.16-4.16 12.16h8.32Zm23.694-2.24c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.486-7.72.12 3.4c.534-1.227 1.307-2.173 2.32-2.84 1.04-.693 2.267-1.04 3.68-1.04 1.494 0 2.76.387 3.8 1.16 1.067.747 1.827 1.813 2.28 3.2.507-1.44 1.294-2.52 2.36-3.24 1.094-.747 2.414-1.12 3.96-1.12 1.414 0 2.64.307 3.68.92s1.84 1.52 2.4 2.72c.56 1.2.84 2.667.84 4.4V38h-4.96V25.92c0-1.813-.293-3.187-.88-4.12-.56-.96-1.413-1.44-2.56-1.44-.906 0-1.68.213-2.32.64-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.84-.48 3.04V38h-4.56V25.92c0-1.2-.133-2.213-.4-3.04-.24-.827-.626-1.453-1.16-1.88-.506-.427-1.133-.64-1.88-.64-.906 0-1.68.227-2.32.68-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.827-.48 3V38h-4.96V16.8h4.48Zm26.723 10.6c0-2.24.427-4.187 1.28-5.84.854-1.68 2.067-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.84 0 3.494.413 4.96 1.24 1.467.827 2.64 2.08 3.52 3.76.88 1.653 1.347 3.693 1.4 6.12v1.32h-15.08c.107 1.813.614 3.227 1.52 4.24.907.987 2.134 1.48 3.68 1.48.987 0 1.88-.253 2.68-.76a4.803 4.803 0 0 0 1.84-2.2l5.08.36c-.64 2.027-1.84 3.64-3.6 4.84-1.733 1.173-3.733 1.76-6 1.76-2.08 0-3.906-.453-5.48-1.36-1.573-.907-2.786-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84Zm15.16-2.04c-.213-1.733-.76-3.013-1.64-3.84-.853-.827-1.893-1.24-3.12-1.24-1.44 0-2.6.453-3.48 1.36-.88.88-1.44 2.12-1.68 3.72h9.92ZM163.139 9.6V38h-5.04V9.6h5.04Zm8.322 7.2.24 5.88-.64-.36c.32-2.053 1.094-3.56 2.32-4.52 1.254-.987 2.787-1.48 4.6-1.48 2.32 0 4.107.733 5.36 2.2 1.254 1.44 1.88 3.387 1.88 5.84V38h-4.96V25.92c0-1.253-.12-2.28-.36-3.08-.24-.8-.64-1.413-1.2-1.84-.533-.427-1.253-.64-2.16-.64-1.44 0-2.573.48-3.4 1.44-.8.933-1.2 2.307-1.2 4.12V38h-4.96V16.8h4.48Zm30.003 7.72c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.443 8.16V38h-5.6v-5.32h5.6Z"/><path fill="#171717" fill-rule="evenodd" d="m7.839 40.783 16.03-28.054L20 6 0 40.783h7.839Zm8.214 0H40L27.99 19.894l-4.02 7.032 3.976 6.914H20.02l-3.967 6.943Z" clip-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -1,94 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
font-family: Arial, Helvetica, sans-serif;
}
@layer utilities {
.text-balance {
text-wrap: balance;
}
}
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
--radius: 0.5rem;
--sidebar-background: 0 0% 98%;
--sidebar-foreground: 240 5.3% 26.1%;
--sidebar-primary: 240 5.9% 10%;
--sidebar-primary-foreground: 0 0% 98%;
--sidebar-accent: 240 4.8% 95.9%;
--sidebar-accent-foreground: 240 5.9% 10%;
--sidebar-border: 220 13% 91%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 0 0% 14.9%;
--ring: 0 0% 83.1%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 224.3 76.3% 48%;
--sidebar-primary-foreground: 0 0% 100%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}

View File

@ -1,72 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
content: ["./app/**/*.{ts,tsx}"],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
keyframes: {
"accordion-down": {
from: { height: 0 },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: 0 },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [require("tailwindcss-animate")],
};

View File

@ -1,30 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"],
"@/components/*": ["./app/components/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}