Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
3795 lines
158 KiB
TypeScript
3795 lines
158 KiB
TypeScript
"use client"
|
||
|
||
import { useState } from "react"
|
||
import Link from "next/link"
|
||
import Image from "next/image"
|
||
import { Button } from "@/components/ui/button"
|
||
import { Badge } from "@/components/ui/badge"
|
||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
|
||
import { Input } from "@/components/ui/input"
|
||
import { Separator } from "@/components/ui/separator"
|
||
import {
|
||
Select,
|
||
SelectContent,
|
||
SelectItem,
|
||
SelectTrigger,
|
||
SelectValue,
|
||
} from "@/components/ui/select"
|
||
import { Checkbox } from "@/components/ui/checkbox"
|
||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
||
import { Label } from "@/components/ui/label"
|
||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"
|
||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
|
||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog"
|
||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
|
||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
||
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet"
|
||
import { Textarea } from "@/components/ui/textarea"
|
||
import { Skeleton } from "@/components/ui/skeleton"
|
||
import { Progress } from "@/components/ui/progress"
|
||
import { Slider } from "@/components/ui/slider"
|
||
import { Switch } from "@/components/ui/switch"
|
||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
|
||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
|
||
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb"
|
||
import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||
import { useToast } from "@/components/ui/use-toast"
|
||
import { Toaster } from "@/components/ui/toaster"
|
||
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel"
|
||
import { AspectRatio } from "@/components/ui/aspect-ratio"
|
||
import { ScrollArea } from "@/components/ui/scroll-area"
|
||
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card"
|
||
import { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from "@/components/ui/command"
|
||
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from "@/components/ui/context-menu"
|
||
import { Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarTrigger } from "@/components/ui/menubar"
|
||
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger } from "@/components/ui/navigation-menu"
|
||
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from "@/components/ui/pagination"
|
||
import { Toggle } from "@/components/ui/toggle"
|
||
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
|
||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
|
||
import { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger } from "@/components/ui/drawer"
|
||
import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from "@/components/ui/resizable"
|
||
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty"
|
||
import { Kbd, KbdGroup } from "@/components/ui/kbd"
|
||
import { Spinner } from "@/components/ui/spinner"
|
||
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp"
|
||
import { Calendar } from "@/components/ui/calendar"
|
||
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"
|
||
import { Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSet, FieldTitle } from "@/components/ui/field"
|
||
import { Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle } from "@/components/ui/item"
|
||
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea } from "@/components/ui/input-group"
|
||
import { ButtonGroup, ButtonGroupSeparator, ButtonGroupText } from "@/components/ui/button-group"
|
||
// Sidebar components - complex component, shown in code example only
|
||
// Note: Sidebar requires SidebarProvider context, so it's shown in code example only
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
import { Toaster as SonnerToaster } from "@/components/ui/sonner"
|
||
import {
|
||
LineChart,
|
||
Line,
|
||
BarChart,
|
||
Bar,
|
||
AreaChart,
|
||
Area,
|
||
PieChart,
|
||
Pie,
|
||
Cell,
|
||
RadarChart,
|
||
Radar,
|
||
PolarGrid,
|
||
PolarAngleAxis,
|
||
PolarRadiusAxis,
|
||
ComposedChart,
|
||
XAxis,
|
||
YAxis,
|
||
CartesianGrid,
|
||
} from "recharts"
|
||
import { Header } from "@/components/header"
|
||
import { Footer } from "@/components/footer"
|
||
import { GetFreeMachineModal } from "@/components/get-free-machine-modal"
|
||
import { Cart } from "@/components/cart"
|
||
import { CartButton } from "@/components/cart-button"
|
||
import { MobileCartButton } from "@/components/mobile-cart-button"
|
||
import { ProductGrid } from "@/components/product-grid"
|
||
import { VendingMachinesShowcase } from "@/components/vending-machines-showcase"
|
||
import { CreditCardReaderSection } from "@/components/credit-card-reader-section"
|
||
import { FeatureCard } from "@/components/feature-card"
|
||
import { ManualViewer } from "@/components/manual-viewer"
|
||
import { PartsPanel } from "@/components/parts-panel"
|
||
import { AboutPage } from "@/components/about-page"
|
||
import { ContactPage } from "@/components/contact-page"
|
||
import { WhoWeServePage } from "@/components/who-we-serve-page"
|
||
import { RepairsPage } from "@/components/repairs-page"
|
||
import { AuthorBio } from "@/components/author-bio"
|
||
import { PageWrapper, PageHeader } from "@/components/page-wrapper"
|
||
import { MovingServiceImage } from "@/components/moving-service-image"
|
||
import {
|
||
CheckCircle2,
|
||
Sparkles,
|
||
Wrench,
|
||
MonitorSmartphone,
|
||
CreditCard,
|
||
Package,
|
||
MapPin,
|
||
Phone,
|
||
Star,
|
||
Menu,
|
||
X,
|
||
Copy,
|
||
Check,
|
||
AlertCircle,
|
||
Info,
|
||
User,
|
||
Settings,
|
||
Search,
|
||
MoreHorizontal,
|
||
ChevronRight,
|
||
Loader2,
|
||
ShoppingCart
|
||
} from "lucide-react"
|
||
import { HeroSection } from "@/components/hero-section"
|
||
import { StatsSection } from "@/components/stats-section"
|
||
import { FeaturesSection } from "@/components/features-section"
|
||
import { ProductShowcaseSection } from "@/components/product-showcase-section"
|
||
import { HowItWorksSection } from "@/components/how-it-works-section"
|
||
import { ServicesSection } from "@/components/services-section"
|
||
import { ServiceAreasSection } from "@/components/service-areas-section"
|
||
import { ReviewsSection } from "@/components/reviews-section"
|
||
import { RequestMachineSection } from "@/components/request-machine-section"
|
||
import { ContactSection } from "@/components/contact-section"
|
||
|
||
// Color palette data
|
||
const colorPalette = {
|
||
primary: [
|
||
{ name: "Primary", variable: "--primary", value: "#29A047", description: "Primary brand color (green from logo)" },
|
||
{ name: "Secondary", variable: "--secondary", value: "#54595F", description: "Secondary color (gray)" },
|
||
{ name: "Text/Foreground", variable: "--foreground", value: "oklch(0.178 0.014 275.627)", description: "Main text color (dark black)" },
|
||
{ name: "Background", variable: "--background", value: "#fff8eb", description: "Warm cream background" },
|
||
],
|
||
links: [
|
||
{ name: "Link Default", variable: "--link-color", value: "var(--foreground)", description: "Default link color" },
|
||
{ name: "Link Hover (Accent)", variable: "--link-hover-color", value: "#C4142C", description: "Red accent/hover color" },
|
||
{ name: "Link Hover Dark", variable: "--link-hover-color-dark", value: "#a01020", description: "Darker red for gradients" },
|
||
{ name: "Link Hover BG", variable: "--link-hover-bg", value: "rgba(196, 20, 44, 0.1)", description: "Link hover background" },
|
||
],
|
||
custom: [
|
||
{ name: "Yellow", variable: "--yellow", value: "#FCBA09", description: "Custom yellow color" },
|
||
{ name: "Orange", variable: "--orange", value: "#F79611", description: "Custom orange color" },
|
||
{ name: "Mountain Bubbles", variable: "--mountain-bubbles", value: "#FCBA0924", description: "Yellow with transparency" },
|
||
],
|
||
semantic: [
|
||
{ name: "Muted", variable: "--muted", value: "oklch(0.961 0.004 106.423)", description: "Muted background" },
|
||
{ name: "Muted Foreground", variable: "--muted-foreground", value: "oklch(0.556 0.014 275.627)", description: "Muted text" },
|
||
{ name: "Destructive", variable: "--destructive", value: "oklch(0.577 0.245 27.325)", description: "Error/destructive actions" },
|
||
{ name: "Border", variable: "--border", value: "oklch(0.922 0.004 106.423)", description: "Border color" },
|
||
],
|
||
}
|
||
|
||
export default function StyleGuidePage() {
|
||
const [copiedCode, setCopiedCode] = useState<string | null>(null)
|
||
const [isNavOpen, setIsNavOpen] = useState(false)
|
||
|
||
const copyToClipboard = (text: string, id: string) => {
|
||
navigator.clipboard.writeText(text)
|
||
setCopiedCode(id)
|
||
setTimeout(() => setCopiedCode(null), 2000)
|
||
}
|
||
|
||
const CodeBlock = ({ code, id }: { code: string; id: string }) => (
|
||
<div className="relative group">
|
||
<pre className="bg-muted p-4 rounded-lg overflow-x-auto text-sm">
|
||
<code>{code}</code>
|
||
</pre>
|
||
<button
|
||
onClick={() => copyToClipboard(code, id)}
|
||
className="absolute top-2 right-2 p-2 bg-background border border-border rounded hover:bg-accent transition-colors"
|
||
aria-label="Copy code"
|
||
>
|
||
{copiedCode === id ? (
|
||
<Check className="h-4 w-4 text-secondary" />
|
||
) : (
|
||
<Copy className="h-4 w-4" />
|
||
)}
|
||
</button>
|
||
</div>
|
||
)
|
||
|
||
const Section = ({ id, title, children }: { id: string; title: string; children: React.ReactNode }) => (
|
||
<section id={id} className="scroll-mt-24 py-12 md:py-16">
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-8 text-balance border-b border-border pb-4">
|
||
{title}
|
||
</h2>
|
||
{children}
|
||
</section>
|
||
)
|
||
|
||
const navItems = [
|
||
{ id: "colors", label: "Color Palette" },
|
||
{ id: "typography", label: "Typography" },
|
||
{ id: "buttons", label: "Buttons" },
|
||
{ id: "cards", label: "Cards" },
|
||
{ id: "badges", label: "Badges" },
|
||
{ id: "links", label: "Links" },
|
||
{ id: "inputs", label: "Form Inputs" },
|
||
{ id: "feedback", label: "Feedback Components" },
|
||
{ id: "overlays", label: "Overlay Components" },
|
||
{ id: "navigation", label: "Navigation Components" },
|
||
{ id: "data-display", label: "Data Display" },
|
||
{ id: "charts", label: "Charts & Graphs" },
|
||
{ id: "interactive", label: "Interactive Components" },
|
||
{ id: "layout", label: "Layout Components" },
|
||
{ id: "advanced", label: "Advanced Components" },
|
||
{ id: "spacing", label: "Spacing & Layout" },
|
||
{ id: "images", label: "Image Patterns" },
|
||
{ id: "sections", label: "Home Page Sections" },
|
||
{ id: "custom", label: "Custom Components" },
|
||
]
|
||
|
||
// Chart data and configurations
|
||
const lineChartData = [
|
||
{ month: "January", desktop: 186, mobile: 80 },
|
||
{ month: "February", desktop: 305, mobile: 200 },
|
||
{ month: "March", desktop: 237, mobile: 120 },
|
||
{ month: "April", desktop: 273, mobile: 190 },
|
||
{ month: "May", desktop: 209, mobile: 130 },
|
||
{ month: "June", desktop: 214, mobile: 140 },
|
||
]
|
||
|
||
const lineChartConfig = {
|
||
desktop: {
|
||
label: "Desktop",
|
||
color: "#F79611", // Brand orange
|
||
},
|
||
mobile: {
|
||
label: "Mobile",
|
||
color: "#54595F", // Secondary gray
|
||
},
|
||
}
|
||
|
||
const barChartData = [
|
||
{ month: "January", desktop: 186, mobile: 80 },
|
||
{ month: "February", desktop: 305, mobile: 200 },
|
||
{ month: "March", desktop: 237, mobile: 120 },
|
||
{ month: "April", desktop: 273, mobile: 190 },
|
||
{ month: "May", desktop: 209, mobile: 130 },
|
||
{ month: "June", desktop: 214, mobile: 140 },
|
||
]
|
||
|
||
const barChartConfig = {
|
||
desktop: {
|
||
label: "Desktop",
|
||
color: "#F79611", // Brand orange
|
||
},
|
||
mobile: {
|
||
label: "Mobile",
|
||
color: "#54595F", // Secondary gray
|
||
},
|
||
}
|
||
|
||
const areaChartData = [
|
||
{ month: "January", desktop: 186, mobile: 80 },
|
||
{ month: "February", desktop: 305, mobile: 200 },
|
||
{ month: "March", desktop: 237, mobile: 120 },
|
||
{ month: "April", desktop: 273, mobile: 190 },
|
||
{ month: "May", desktop: 209, mobile: 130 },
|
||
{ month: "June", desktop: 214, mobile: 140 },
|
||
]
|
||
|
||
const areaChartConfig = {
|
||
desktop: {
|
||
label: "Desktop",
|
||
color: "#F79611", // Brand orange
|
||
},
|
||
mobile: {
|
||
label: "Mobile",
|
||
color: "#54595F", // Secondary gray
|
||
},
|
||
}
|
||
|
||
const pieChartData = [
|
||
{ name: "Desktop", value: 186, fill: "#F79611" }, // Brand orange
|
||
{ name: "Mobile", value: 80, fill: "#FCBA09" }, // Custom yellow
|
||
{ name: "Tablet", value: 50, fill: "#54595F" }, // Secondary gray
|
||
{ name: "Other", value: 30, fill: "#29A047" }, // Primary green
|
||
]
|
||
|
||
const pieChartConfig = {
|
||
value: {
|
||
label: "Value",
|
||
},
|
||
}
|
||
|
||
const radarChartData = [
|
||
{ subject: "Math", A: 120, B: 110, fullMark: 150 },
|
||
{ subject: "Chinese", A: 98, B: 130, fullMark: 150 },
|
||
{ subject: "English", A: 86, B: 130, fullMark: 150 },
|
||
{ subject: "Geography", A: 99, B: 100, fullMark: 150 },
|
||
{ subject: "Physics", A: 85, B: 90, fullMark: 150 },
|
||
{ subject: "History", A: 65, B: 85, fullMark: 150 },
|
||
]
|
||
|
||
const radarChartConfig = {
|
||
A: {
|
||
label: "Student A",
|
||
color: "#F79611", // Brand orange
|
||
},
|
||
B: {
|
||
label: "Student B",
|
||
color: "#54595F", // Secondary gray
|
||
},
|
||
}
|
||
|
||
const { toast } = useToast()
|
||
|
||
return (
|
||
<>
|
||
{/* Sticky Navigation */}
|
||
<nav className="sticky top-20 z-30 bg-background/95 backdrop-blur border-b border-border shadow-sm">
|
||
<div className="container mx-auto px-4">
|
||
<div className="flex items-center justify-between py-4">
|
||
<div className="text-xl font-bold">Rocky Mountain Vending Style Guide</div>
|
||
<div className="hidden md:flex gap-4 overflow-x-auto">
|
||
{navItems.map((item) => (
|
||
<a
|
||
key={item.id}
|
||
href={`#${item.id}`}
|
||
className="text-sm font-medium whitespace-nowrap hover:text-secondary transition-colors"
|
||
>
|
||
{item.label}
|
||
</a>
|
||
))}
|
||
</div>
|
||
<button
|
||
onClick={() => setIsNavOpen(!isNavOpen)}
|
||
className="md:hidden p-2"
|
||
aria-label="Toggle navigation"
|
||
>
|
||
{isNavOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
|
||
</button>
|
||
</div>
|
||
{isNavOpen && (
|
||
<div className="md:hidden pb-4 space-y-2">
|
||
{navItems.map((item) => (
|
||
<a
|
||
key={item.id}
|
||
href={`#${item.id}`}
|
||
onClick={() => setIsNavOpen(false)}
|
||
className="block text-sm font-medium py-2 hover:text-secondary transition-colors"
|
||
>
|
||
{item.label}
|
||
</a>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
</nav>
|
||
|
||
<div className="container mx-auto px-4 py-8 md:py-12 max-w-7xl">
|
||
{/* Introduction */}
|
||
<div className="mb-16">
|
||
<h1 className="text-4xl md:text-5xl font-bold mb-4">Rocky Mountain Vending Style Guide</h1>
|
||
<p className="text-lg text-muted-foreground text-pretty leading-relaxed max-w-3xl">
|
||
This style guide showcases all components, styles, and design patterns used throughout the Rocky Mountain Vending website.
|
||
Use this as a reference when building new pages or components.
|
||
</p>
|
||
</div>
|
||
|
||
{/* Color Palette */}
|
||
<Section id="colors" title="Color Palette">
|
||
<div className="space-y-12">
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-3 text-foreground">Primary Colors</h3>
|
||
<p className="text-sm text-muted-foreground mb-6 leading-relaxed">
|
||
Core brand colors used throughout the application for primary actions, backgrounds, and text.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||
{colorPalette.primary.map((color) => {
|
||
// Handle CSS variables - use the variable directly for display
|
||
const colorValue = color.value.startsWith('var(')
|
||
? `var(${color.variable})`
|
||
: color.value
|
||
|
||
return (
|
||
<Card key={color.variable} className="border-border/50 hover:border-border transition-colors shadow-sm">
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="w-full h-32 rounded-lg mb-4 border-2 border-border/50 shadow-inner"
|
||
style={{
|
||
backgroundColor: colorValue,
|
||
minHeight: '8rem'
|
||
}}
|
||
/>
|
||
<div className="space-y-2">
|
||
<div className="text-base font-semibold text-foreground">{color.name}</div>
|
||
<div className="text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded">
|
||
{color.variable}
|
||
</div>
|
||
<div className="text-xs font-mono text-foreground bg-muted px-2 py-1 rounded break-all">
|
||
{color.value}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground leading-relaxed pt-1">
|
||
{color.description}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-3 text-foreground">Link & Accent Colors</h3>
|
||
<p className="text-sm text-muted-foreground mb-6 leading-relaxed">
|
||
Colors used for links, hover states, and accent elements. Links use red hover color for brand consistency.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||
{colorPalette.links.map((color) => {
|
||
// Handle CSS variables and rgba values
|
||
const colorValue = color.value.startsWith('var(')
|
||
? `var(${color.variable})`
|
||
: color.value
|
||
|
||
return (
|
||
<Card key={color.variable} className="border-border/50 hover:border-border transition-colors shadow-sm">
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="w-full h-32 rounded-lg mb-4 border-2 border-border/50 shadow-inner"
|
||
style={{
|
||
backgroundColor: colorValue,
|
||
minHeight: '8rem'
|
||
}}
|
||
/>
|
||
<div className="space-y-2">
|
||
<div className="text-base font-semibold text-foreground">{color.name}</div>
|
||
<div className="text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded">
|
||
{color.variable}
|
||
</div>
|
||
<div className="text-xs font-mono text-foreground bg-muted px-2 py-1 rounded break-all">
|
||
{color.value}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground leading-relaxed pt-1">
|
||
{color.description}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-3 text-foreground">Custom Colors</h3>
|
||
<p className="text-sm text-muted-foreground mb-6 leading-relaxed">
|
||
Custom brand colors including yellow and orange accents used for special highlights and decorative elements.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||
{colorPalette.custom.map((color) => (
|
||
<Card key={color.variable} className="border-border/50 hover:border-border transition-colors shadow-sm">
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="w-full h-32 rounded-lg mb-4 border-2 border-border/50 shadow-inner"
|
||
style={{
|
||
backgroundColor: color.value,
|
||
minHeight: '8rem'
|
||
}}
|
||
/>
|
||
<div className="space-y-2">
|
||
<div className="text-base font-semibold text-foreground">{color.name}</div>
|
||
<div className="text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded">
|
||
{color.variable}
|
||
</div>
|
||
<div className="text-xs font-mono text-foreground bg-muted px-2 py-1 rounded break-all">
|
||
{color.value}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground leading-relaxed pt-1">
|
||
{color.description}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-3 text-foreground">Semantic Colors</h3>
|
||
<p className="text-sm text-muted-foreground mb-6 leading-relaxed">
|
||
Semantic color tokens for muted backgrounds, borders, and destructive actions. These provide consistent meaning across the UI.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||
{colorPalette.semantic.map((color) => {
|
||
const getColorValue = (val: string) => {
|
||
if (val.startsWith('oklch(')) return val
|
||
return val
|
||
}
|
||
|
||
return (
|
||
<Card key={color.variable} className="border-border/50 hover:border-border transition-colors shadow-sm">
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="w-full h-32 rounded-lg mb-4 border-2 border-border/50 shadow-inner"
|
||
style={{
|
||
backgroundColor: getColorValue(color.value),
|
||
minHeight: '8rem'
|
||
}}
|
||
/>
|
||
<div className="space-y-2">
|
||
<div className="text-base font-semibold text-foreground">{color.name}</div>
|
||
<div className="text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded">
|
||
{color.variable}
|
||
</div>
|
||
<div className="text-xs font-mono text-foreground bg-muted px-2 py-1 rounded break-all">
|
||
{color.value}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground leading-relaxed pt-1">
|
||
{color.description}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Typography */}
|
||
<Section id="typography" title="Typography">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Page Headers with Gradient Divider</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Header pattern with centered title and gradient divider line, commonly used on service pages.
|
||
</p>
|
||
<div className="mb-6">
|
||
<header className="text-center mb-8">
|
||
<h1 className="text-4xl md:text-5xl font-bold tracking-tight text-balance mb-4">
|
||
Page Title
|
||
</h1>
|
||
<div className="w-24 h-1 bg-gradient-to-r from-[var(--link-hover-color)] to-[var(--link-hover-color-dark)] mx-auto rounded-full" />
|
||
</header>
|
||
</div>
|
||
<CodeBlock
|
||
id="header-gradient-divider-code"
|
||
code={`<header className="text-center mb-12 md:mb-16">
|
||
<h1 className="text-4xl md:text-5xl font-bold tracking-tight text-balance mb-4">
|
||
Page Title
|
||
</h1>
|
||
<div className="w-24 h-1 bg-gradient-to-r from-[var(--link-hover-color)] to-[var(--link-hover-color-dark)] mx-auto rounded-full" />
|
||
</header>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Font Families</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Typography system using Inter for body text and UI elements, and Geist Mono for code and technical content.
|
||
</p>
|
||
<div className="grid gap-4 md:grid-cols-2">
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div className="text-2xl font-sans mb-2" style={{ fontFamily: 'var(--font-inter)' }}>
|
||
Inter (Sans-serif)
|
||
</div>
|
||
<div className="text-sm text-muted-foreground font-mono">--font-inter</div>
|
||
<p className="text-sm text-muted-foreground mt-2">Used for body text and UI elements</p>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div className="text-2xl font-mono mb-2" style={{ fontFamily: 'var(--font-geist-mono)' }}>
|
||
Geist Mono (Monospace)
|
||
</div>
|
||
<div className="text-sm text-muted-foreground font-mono">--font-geist-mono</div>
|
||
<p className="text-sm text-muted-foreground mt-2">Used for code and technical content</p>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Headings</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Heading hierarchy with responsive sizing. H1 is used for page titles, H2 for section headers, and H3-H4 for subsections.
|
||
</p>
|
||
<div className="space-y-6">
|
||
<div>
|
||
<h1 className="text-4xl md:text-5xl font-bold mb-2">Heading 1 (H1)</h1>
|
||
<CodeBlock
|
||
id="h1-code"
|
||
code={`<h1 className="text-4xl md:text-5xl font-bold mb-4">Heading 1</h1>`}
|
||
/>
|
||
<p className="text-sm text-muted-foreground mt-2">Used for page titles (only one per page)</p>
|
||
</div>
|
||
<div>
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-2 text-balance">Heading 2 (H2) - Section Header</h2>
|
||
<CodeBlock
|
||
id="h2-code"
|
||
code={`<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-4 text-balance">Section Header</h2>`}
|
||
/>
|
||
<p className="text-sm text-muted-foreground mt-2">Used for section headers (centered)</p>
|
||
</div>
|
||
<div>
|
||
<h2 className="text-2xl md:text-3xl font-semibold mb-2">Heading 2 (H2) - Page Header</h2>
|
||
<CodeBlock
|
||
id="h2-page-code"
|
||
code={`<h2 className="text-2xl md:text-3xl font-semibold mb-6">Page Header</h2>`}
|
||
/>
|
||
<p className="text-sm text-muted-foreground mt-2">Used for page headers (left-aligned)</p>
|
||
</div>
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-2">Heading 3 (H3)</h3>
|
||
<CodeBlock
|
||
id="h3-code"
|
||
code={`<h3 className="text-xl font-semibold mb-2">Heading 3</h3>`}
|
||
/>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-lg font-semibold mb-2">Heading 4 (H4)</h4>
|
||
<CodeBlock
|
||
id="h4-code"
|
||
code={`<h4 className="text-lg font-semibold mb-2">Heading 4</h4>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Paragraph Styles</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Standard paragraph text styles with consistent sizing, line height, and color for optimal readability.
|
||
</p>
|
||
<div className="space-y-4">
|
||
<div>
|
||
<p className="text-lg text-muted-foreground text-pretty leading-relaxed mb-2">
|
||
Standard paragraph text with text-lg, text-muted-foreground, text-pretty, and leading-relaxed classes.
|
||
</p>
|
||
<CodeBlock
|
||
id="p-standard-code"
|
||
code={`<p className="text-lg text-muted-foreground text-pretty leading-relaxed">Standard paragraph</p>`}
|
||
/>
|
||
</div>
|
||
<div>
|
||
<p className="text-sm text-muted-foreground mb-2">
|
||
Small text with text-sm and text-muted-foreground classes.
|
||
</p>
|
||
<CodeBlock
|
||
id="p-small-code"
|
||
code={`<p className="text-sm text-muted-foreground">Small text</p>`}
|
||
/>
|
||
</div>
|
||
<div>
|
||
<p className="text-lg text-muted-foreground max-w-2xl mx-auto text-pretty leading-relaxed mb-2">
|
||
Centered paragraph with max-w-2xl mx-auto for centered content.
|
||
</p>
|
||
<CodeBlock
|
||
id="p-centered-code"
|
||
code={`<p className="text-lg text-muted-foreground max-w-2xl mx-auto text-pretty leading-relaxed">Centered paragraph</p>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Buttons */}
|
||
<Section id="buttons" title="Buttons">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Button Variants</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Different button styles for various use cases. The brand variant uses the primary red color for important CTAs.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Button variant="default">Default</Button>
|
||
<Button variant="secondary">Secondary</Button>
|
||
<Button variant="destructive">Destructive</Button>
|
||
<Button variant="outline">Outline</Button>
|
||
<Button variant="ghost">Ghost</Button>
|
||
<Button variant="link">Link</Button>
|
||
<Button variant="brand">Brand</Button>
|
||
</div>
|
||
<CodeBlock
|
||
id="button-variants-code"
|
||
code={`<Button variant="default">Default</Button>
|
||
<Button variant="secondary">Secondary</Button>
|
||
<Button variant="destructive">Destructive</Button>
|
||
<Button variant="outline">Outline</Button>
|
||
<Button variant="ghost">Ghost</Button>
|
||
<Button variant="link">Link</Button>
|
||
<Button variant="brand">Brand</Button>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Button Sizes</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Button size options from small to large, plus icon-only buttons for compact interfaces.
|
||
</p>
|
||
<div className="flex flex-wrap items-center gap-4 mb-6">
|
||
<Button size="sm">Small</Button>
|
||
<Button size="default">Default</Button>
|
||
<Button size="lg">Large</Button>
|
||
<Button size="icon" aria-label="Icon button">
|
||
<Star className="h-4 w-4" />
|
||
</Button>
|
||
</div>
|
||
<CodeBlock
|
||
id="button-sizes-code"
|
||
code={`<Button size="sm">Small</Button>
|
||
<Button size="default">Default</Button>
|
||
<Button size="lg">Large</Button>
|
||
<Button size="icon" aria-label="Icon button">
|
||
<Star className="h-4 w-4" />
|
||
</Button>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Button States</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Button states including normal, disabled, and link variants. Buttons can also be used as links with the asChild prop.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Button>Normal</Button>
|
||
<Button disabled>Disabled</Button>
|
||
<Button asChild>
|
||
<Link href="#buttons">As Link</Link>
|
||
</Button>
|
||
</div>
|
||
<CodeBlock
|
||
id="button-states-code"
|
||
code={`<Button>Normal</Button>
|
||
<Button disabled>Disabled</Button>
|
||
<Button asChild>
|
||
<Link href="#buttons">As Link</Link>
|
||
</Button>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Cards */}
|
||
<Section id="cards" title="Cards">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Standard Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Basic card component with header, content, and footer sections. Includes hover effects for interactivity.
|
||
</p>
|
||
<Card className="border-border/50 hover:border-secondary/50 transition-colors mb-6">
|
||
<CardHeader>
|
||
<CardTitle>Card Title</CardTitle>
|
||
<CardDescription>Card description text goes here</CardDescription>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<p className="text-sm text-muted-foreground">Card content area with padding and proper spacing.</p>
|
||
</CardContent>
|
||
<CardFooter>
|
||
<Button size="sm">Action</Button>
|
||
</CardFooter>
|
||
</Card>
|
||
<CodeBlock
|
||
id="card-standard-code"
|
||
code={`<Card className="border-border/50 hover:border-secondary/50 transition-colors">
|
||
<CardHeader>
|
||
<CardTitle>Card Title</CardTitle>
|
||
<CardDescription>Card description</CardDescription>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<p>Card content</p>
|
||
</CardContent>
|
||
<CardFooter>
|
||
<Button size="sm">Action</Button>
|
||
</CardFooter>
|
||
</Card>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Card with Image</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Card layout with an image header using aspect-video ratio. Perfect for product cards and feature showcases.
|
||
</p>
|
||
<Card className="border-border/50 overflow-hidden hover:border-secondary/50 transition-colors mb-6">
|
||
<div className="aspect-video relative bg-muted">
|
||
<div className="absolute inset-0 flex items-center justify-center text-muted-foreground">
|
||
Image Placeholder
|
||
</div>
|
||
</div>
|
||
<CardContent className="p-6">
|
||
<h3 className="text-xl font-semibold mb-2">Card with Image</h3>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">Card content below image.</p>
|
||
</CardContent>
|
||
</Card>
|
||
<CodeBlock
|
||
id="card-image-code"
|
||
code={`<Card className="border-border/50 overflow-hidden hover:border-secondary/50 transition-colors">
|
||
<div className="aspect-video relative bg-muted">
|
||
<Image src="/image.jpg" alt="Description" fill className="object-cover" />
|
||
</div>
|
||
<CardContent className="p-6">
|
||
<h3 className="text-xl font-semibold mb-2">Title</h3>
|
||
<p className="text-sm text-muted-foreground">Content</p>
|
||
</CardContent>
|
||
</Card>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Gradient CTA Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
A call-to-action card with gradient background, typically used for important CTAs on service pages.
|
||
</p>
|
||
<Card className="border-2 shadow-lg [&>div]:!bg-transparent bg-gradient-to-r from-[var(--primary)] to-[#1d7a35] mb-6">
|
||
<CardContent className="p-10 md:p-12 text-center">
|
||
<h2 className="text-2xl md:text-3xl font-bold text-white mb-4 tracking-tight text-balance">
|
||
Ready to Get Started?
|
||
</h2>
|
||
<p className="text-white/90 mb-8 max-w-2xl mx-auto text-lg leading-relaxed">
|
||
Contact us today to learn more about our free vending machine services and how we can help your business.
|
||
</p>
|
||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||
<Button asChild size="lg" className="bg-white text-[var(--primary)] hover:bg-white/90 text-lg h-12 px-8 font-semibold">
|
||
<Link href="#cards">Contact Us</Link>
|
||
</Button>
|
||
<Button asChild size="lg" variant="outline" className="bg-transparent border-2 border-white text-white hover:bg-white/10 text-lg h-12 px-8 font-semibold">
|
||
<Link href="#cards">Get Free Machine</Link>
|
||
</Button>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<CodeBlock
|
||
id="card-gradient-cta-code"
|
||
code={`<Card className="border-2 shadow-lg [&>div]:!bg-transparent bg-gradient-to-r from-[var(--primary)] to-[#1d7a35]">
|
||
<CardContent className="p-10 md:p-12 text-center">
|
||
<h2 className="text-2xl md:text-3xl font-bold text-white mb-4 tracking-tight text-balance">
|
||
Ready to Get Started?
|
||
</h2>
|
||
<p className="text-white/90 mb-8 max-w-2xl mx-auto text-lg leading-relaxed">
|
||
Contact us today to learn more about our services.
|
||
</p>
|
||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||
<Button asChild size="lg" className="bg-white text-[var(--primary)] hover:bg-white/90">
|
||
<Link href="/contact-us">Contact Us</Link>
|
||
</Button>
|
||
<Button asChild size="lg" variant="outline" className="bg-transparent border-2 border-white text-white hover:bg-white/10">
|
||
<Link href="/#request-machine">Get Free Machine</Link>
|
||
</Button>
|
||
</div>
|
||
</CardContent>
|
||
</Card>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Card with Icon Grid</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Cards arranged in a grid with icons, commonly used for benefits or features sections.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 mb-6">
|
||
<Card className="border-border/50 hover:border-secondary/50 transition-colors">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">100% FREE Service</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
No upfront costs, installation fees, or monthly charges
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50 hover:border-secondary/50 transition-colors">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">Regular Maintenance</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
We stock, service, and maintain all machines at no cost to you
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
<CodeBlock
|
||
id="card-icon-grid-code"
|
||
code={`<div className="grid gap-6 md:grid-cols-2">
|
||
<Card className="border-border/50 hover:border-secondary/50 transition-colors">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2">Feature Title</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
Feature description text goes here.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Card with Secondary Background</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Card with subtle secondary color background for emphasis. Ideal for highlighting important information or callouts.
|
||
</p>
|
||
<Card className="border-secondary/20 bg-secondary/5 mb-6">
|
||
<CardContent className="p-6 md:p-8">
|
||
<p className="text-base md:text-lg leading-relaxed">
|
||
This card uses a subtle secondary color background for emphasis. Perfect for highlighting important information or anecdotes.
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
<CodeBlock
|
||
id="card-secondary-bg-code"
|
||
code={`<Card className="border-secondary/20 bg-secondary/5">
|
||
<CardContent className="p-6 md:p-8">
|
||
<p className="text-base md:text-lg leading-relaxed">
|
||
Content with subtle background emphasis.
|
||
</p>
|
||
</CardContent>
|
||
</Card>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Badges */}
|
||
<Section id="badges" title="Badges">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Badge Variants</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Badge components for labels, status indicators, and tags. Available in multiple variants for different contexts.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Badge variant="default">Default</Badge>
|
||
<Badge variant="secondary">Secondary</Badge>
|
||
<Badge variant="destructive">Destructive</Badge>
|
||
<Badge variant="outline">Outline</Badge>
|
||
</div>
|
||
<CodeBlock
|
||
id="badge-variants-code"
|
||
code={`<Badge variant="default">Default</Badge>
|
||
<Badge variant="secondary">Secondary</Badge>
|
||
<Badge variant="destructive">Destructive</Badge>
|
||
<Badge variant="outline">Outline</Badge>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Links */}
|
||
<Section id="links" title="Link Styling">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Link States</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Link styling with automatic red hover color. All links use the brand red (#c4142c) on hover for consistency.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<div>
|
||
<p className="mb-2">Default link: <a href="#links" className="transition-colors">Example Link</a></p>
|
||
</div>
|
||
<div>
|
||
<p className="mb-2">Hover state (red): <a href="#links" className="hover:text-[#c4142c] transition-colors">Hover me</a></p>
|
||
</div>
|
||
<div>
|
||
<p className="mb-2">Next.js Link: <Link href="#links" className="transition-colors">Next.js Link Component</Link></p>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="links-code"
|
||
code={`// Standard HTML link
|
||
<a href="/path" className="transition-colors">Link Text</a>
|
||
|
||
// Next.js Link component
|
||
<Link href="/path" className="transition-colors">Link Text</Link>
|
||
|
||
// All links automatically get red hover color via global CSS`}
|
||
/>
|
||
<p className="text-sm text-muted-foreground">
|
||
All links automatically use the red hover color (#c4142c) defined in globals.css. No need to add hover classes manually.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Form Inputs */}
|
||
<Section id="inputs" title="Form Inputs">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Input Fields</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Text input fields with labels. Supports various input types including text, email, and disabled states.
|
||
</p>
|
||
<div className="space-y-4 mb-6 max-w-md">
|
||
<div>
|
||
<Label htmlFor="text-input">Text Input</Label>
|
||
<Input id="text-input" type="text" placeholder="Enter text..." />
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="email-input">Email Input</Label>
|
||
<Input id="email-input" type="email" placeholder="email@example.com" />
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="disabled-input">Disabled Input</Label>
|
||
<Input id="disabled-input" type="text" placeholder="Disabled" disabled />
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="input-code"
|
||
code={`<div>
|
||
<Label htmlFor="text-input">Text Input</Label>
|
||
<Input id="text-input" type="text" placeholder="Enter text..." />
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Select Dropdown</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Dropdown select component for choosing from a list of options. Accessible and keyboard navigable.
|
||
</p>
|
||
<div className="mb-6 max-w-md">
|
||
<Label>Select Option</Label>
|
||
<Select>
|
||
<SelectTrigger>
|
||
<SelectValue placeholder="Select an option" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectItem value="option1">Option 1</SelectItem>
|
||
<SelectItem value="option2">Option 2</SelectItem>
|
||
<SelectItem value="option3">Option 3</SelectItem>
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
<CodeBlock
|
||
id="select-code"
|
||
code={`<Select>
|
||
<SelectTrigger>
|
||
<SelectValue placeholder="Select an option" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectItem value="option1">Option 1</SelectItem>
|
||
<SelectItem value="option2">Option 2</SelectItem>
|
||
</SelectContent>
|
||
</Select>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Checkboxes & Radio Buttons</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Form controls for multiple selection (checkboxes) and single selection (radio buttons) with labels.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<div className="flex items-center space-x-2">
|
||
<Checkbox id="checkbox1" />
|
||
<Label htmlFor="checkbox1">Checkbox option</Label>
|
||
</div>
|
||
<div className="flex items-center space-x-2">
|
||
<Checkbox id="checkbox2" checked />
|
||
<Label htmlFor="checkbox2">Checked checkbox</Label>
|
||
</div>
|
||
<RadioGroup defaultValue="option1">
|
||
<div className="flex items-center space-x-2">
|
||
<RadioGroupItem value="option1" id="radio1" />
|
||
<Label htmlFor="radio1">Radio option 1</Label>
|
||
</div>
|
||
<div className="flex items-center space-x-2">
|
||
<RadioGroupItem value="option2" id="radio2" />
|
||
<Label htmlFor="radio2">Radio option 2</Label>
|
||
</div>
|
||
</RadioGroup>
|
||
</div>
|
||
<CodeBlock
|
||
id="checkbox-radio-code"
|
||
code={`<div className="flex items-center space-x-2">
|
||
<Checkbox id="checkbox1" />
|
||
<Label htmlFor="checkbox1">Checkbox option</Label>
|
||
</div>
|
||
|
||
<RadioGroup defaultValue="option1">
|
||
<div className="flex items-center space-x-2">
|
||
<RadioGroupItem value="option1" id="radio1" />
|
||
<Label htmlFor="radio1">Radio option 1</Label>
|
||
</div>
|
||
</RadioGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Tabs</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Tabs component for organizing content into multiple panels. Supports default, card, and vertical variants.
|
||
</p>
|
||
<div className="space-y-8 mb-6">
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Default Tabs</h4>
|
||
<Tabs defaultValue="account" className="w-full">
|
||
<TabsList className="grid w-full grid-cols-3">
|
||
<TabsTrigger value="account">Account</TabsTrigger>
|
||
<TabsTrigger value="password">Password</TabsTrigger>
|
||
<TabsTrigger value="settings">Settings</TabsTrigger>
|
||
</TabsList>
|
||
<TabsContent value="account" className="mt-4">
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>Account</CardTitle>
|
||
<CardDescription>
|
||
Make changes to your account here. Click save when you're done.
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-2">
|
||
<div>
|
||
<Label htmlFor="name">Name</Label>
|
||
<Input id="name" defaultValue="Pedro Duarte" />
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="username">Username</Label>
|
||
<Input id="username" defaultValue="@peduarte" />
|
||
</div>
|
||
</CardContent>
|
||
<CardFooter>
|
||
<Button>Save changes</Button>
|
||
</CardFooter>
|
||
</Card>
|
||
</TabsContent>
|
||
<TabsContent value="password" className="mt-4">
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>Password</CardTitle>
|
||
<CardDescription>
|
||
Change your password here. After saving, you'll be logged out.
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-2">
|
||
<div>
|
||
<Label htmlFor="current">Current password</Label>
|
||
<Input id="current" type="password" />
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="new">New password</Label>
|
||
<Input id="new" type="password" />
|
||
</div>
|
||
</CardContent>
|
||
<CardFooter>
|
||
<Button>Save password</Button>
|
||
</CardFooter>
|
||
</Card>
|
||
</TabsContent>
|
||
<TabsContent value="settings" className="mt-4">
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>Settings</CardTitle>
|
||
<CardDescription>
|
||
Manage your account settings and preferences.
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-2">
|
||
<div className="flex items-center space-x-2">
|
||
<Switch id="notifications" />
|
||
<Label htmlFor="notifications">Enable notifications</Label>
|
||
</div>
|
||
<div className="flex items-center space-x-2">
|
||
<Switch id="marketing" />
|
||
<Label htmlFor="marketing">Marketing emails</Label>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</TabsContent>
|
||
</Tabs>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="tabs-code"
|
||
code={`<Tabs defaultValue="account" className="w-full">
|
||
<TabsList>
|
||
<TabsTrigger value="account">Account</TabsTrigger>
|
||
<TabsTrigger value="password">Password</TabsTrigger>
|
||
<TabsTrigger value="settings">Settings</TabsTrigger>
|
||
</TabsList>
|
||
<TabsContent value="account">
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>Account</CardTitle>
|
||
<CardDescription>Description</CardDescription>
|
||
</CardHeader>
|
||
<CardContent>
|
||
{/* Content */}
|
||
</CardContent>
|
||
</Card>
|
||
</TabsContent>
|
||
<TabsContent value="password">
|
||
{/* Content */}
|
||
</TabsContent>
|
||
</Tabs>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Accordion</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Collapsible content sections for organizing information. Supports single or multiple open items.
|
||
</p>
|
||
<Accordion type="single" collapsible className="mb-6">
|
||
<AccordionItem value="item-1">
|
||
<AccordionTrigger>Accordion Item 1</AccordionTrigger>
|
||
<AccordionContent>
|
||
Content for accordion item 1 goes here.
|
||
</AccordionContent>
|
||
</AccordionItem>
|
||
<AccordionItem value="item-2">
|
||
<AccordionTrigger>Accordion Item 2</AccordionTrigger>
|
||
<AccordionContent>
|
||
Content for accordion item 2 goes here.
|
||
</AccordionContent>
|
||
</AccordionItem>
|
||
</Accordion>
|
||
<CodeBlock
|
||
id="accordion-code"
|
||
code={`<Accordion type="single" collapsible>
|
||
<AccordionItem value="item-1">
|
||
<AccordionTrigger>Item 1</AccordionTrigger>
|
||
<AccordionContent>Content 1</AccordionContent>
|
||
</AccordionItem>
|
||
</Accordion>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Textarea</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Multi-line text input for longer content like messages, comments, or descriptions.
|
||
</p>
|
||
<div className="mb-6 max-w-md">
|
||
<Label htmlFor="textarea-example">Message</Label>
|
||
<Textarea id="textarea-example" placeholder="Enter your message here..." rows={4} />
|
||
</div>
|
||
<CodeBlock
|
||
id="textarea-code"
|
||
code={`<Textarea placeholder="Enter your message..." rows={4} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Field Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Field components provide a structured way to build forms with labels, descriptions, and error messages.
|
||
</p>
|
||
<div className="mb-6 max-w-md">
|
||
<FieldSet>
|
||
<FieldLegend>Personal Information</FieldLegend>
|
||
<FieldDescription>
|
||
Enter your personal details below. All fields are required.
|
||
</FieldDescription>
|
||
<FieldGroup>
|
||
<Field>
|
||
<FieldLabel>First Name</FieldLabel>
|
||
<Input placeholder="John" />
|
||
<FieldDescription>Enter your first name</FieldDescription>
|
||
</Field>
|
||
<Field>
|
||
<FieldLabel>Last Name</FieldLabel>
|
||
<Input placeholder="Doe" />
|
||
<FieldDescription>Enter your last name</FieldDescription>
|
||
</Field>
|
||
<Field>
|
||
<FieldLabel>Email</FieldLabel>
|
||
<Input type="email" placeholder="john@example.com" />
|
||
<FieldDescription>We'll never share your email</FieldDescription>
|
||
<FieldError>Email is required</FieldError>
|
||
</Field>
|
||
</FieldGroup>
|
||
</FieldSet>
|
||
</div>
|
||
<CodeBlock
|
||
id="field-code"
|
||
code={`<FieldSet>
|
||
<FieldLegend>Form Title</FieldLegend>
|
||
<FieldDescription>Form description text</FieldDescription>
|
||
<FieldGroup>
|
||
<Field>
|
||
<FieldLabel>Label</FieldLabel>
|
||
<Input placeholder="Enter value" />
|
||
<FieldDescription>Helper text</FieldDescription>
|
||
<FieldError>Error message</FieldError>
|
||
</Field>
|
||
</FieldGroup>
|
||
</FieldSet>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Feedback Components */}
|
||
<Section id="feedback" title="Feedback Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Alert</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Alert components for displaying important messages, warnings, and notifications to users.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<Alert>
|
||
<AlertCircle className="h-4 w-4" />
|
||
<AlertTitle>Default Alert</AlertTitle>
|
||
<AlertDescription>This is a default alert message.</AlertDescription>
|
||
</Alert>
|
||
<Alert variant="destructive">
|
||
<AlertCircle className="h-4 w-4" />
|
||
<AlertTitle>Destructive Alert</AlertTitle>
|
||
<AlertDescription>This is a destructive alert message.</AlertDescription>
|
||
</Alert>
|
||
</div>
|
||
<CodeBlock
|
||
id="alert-code"
|
||
code={`<Alert>
|
||
<AlertCircle className="h-4 w-4" />
|
||
<AlertTitle>Alert Title</AlertTitle>
|
||
<AlertDescription>Alert description text.</AlertDescription>
|
||
</Alert>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Alert Dialog</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Modal dialog for critical confirmations and destructive actions. Requires user interaction to dismiss.
|
||
</p>
|
||
<AlertDialog>
|
||
<AlertDialogTrigger asChild>
|
||
<Button variant="outline">Open Alert Dialog</Button>
|
||
</AlertDialogTrigger>
|
||
<AlertDialogContent>
|
||
<AlertDialogHeader>
|
||
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
|
||
<AlertDialogDescription>
|
||
This action cannot be undone. This will permanently delete your data.
|
||
</AlertDialogDescription>
|
||
</AlertDialogHeader>
|
||
<AlertDialogFooter>
|
||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||
<AlertDialogAction>Continue</AlertDialogAction>
|
||
</AlertDialogFooter>
|
||
</AlertDialogContent>
|
||
</AlertDialog>
|
||
<CodeBlock
|
||
id="alert-dialog-code"
|
||
code={`<AlertDialog>
|
||
<AlertDialogTrigger asChild>
|
||
<Button>Open</Button>
|
||
</AlertDialogTrigger>
|
||
<AlertDialogContent>
|
||
<AlertDialogHeader>
|
||
<AlertDialogTitle>Title</AlertDialogTitle>
|
||
<AlertDialogDescription>Description</AlertDialogDescription>
|
||
</AlertDialogHeader>
|
||
<AlertDialogFooter>
|
||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||
<AlertDialogAction>Continue</AlertDialogAction>
|
||
</AlertDialogFooter>
|
||
</AlertDialogContent>
|
||
</AlertDialog>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Skeleton</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Loading placeholders that mimic content structure while data is being fetched.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<div className="flex items-center space-x-4">
|
||
<Skeleton className="h-12 w-12 rounded-full" />
|
||
<div className="space-y-2">
|
||
<Skeleton className="h-4 w-[250px]" />
|
||
<Skeleton className="h-4 w-[200px]" />
|
||
</div>
|
||
</div>
|
||
<Skeleton className="h-32 w-full rounded-lg" />
|
||
</div>
|
||
<CodeBlock
|
||
id="skeleton-code"
|
||
code={`<Skeleton className="h-12 w-12 rounded-full" />
|
||
<Skeleton className="h-4 w-[250px]" />
|
||
<Skeleton className="h-32 w-full rounded-lg" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Progress</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Progress bar component for showing completion status, upload progress, or loading states.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<Progress value={33} />
|
||
<Progress value={66} />
|
||
<Progress value={100} />
|
||
</div>
|
||
<CodeBlock
|
||
id="progress-code"
|
||
code={`<Progress value={33} />
|
||
<Progress value={66} />
|
||
<Progress value={100} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Spinner</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Loading spinner component available in multiple sizes for indicating async operations.
|
||
</p>
|
||
<div className="flex items-center gap-4 mb-6">
|
||
<Spinner className="h-4 w-4" />
|
||
<Spinner className="h-6 w-6" />
|
||
<Spinner className="h-8 w-8" />
|
||
</div>
|
||
<CodeBlock
|
||
id="spinner-code"
|
||
code={`<Spinner className="h-4 w-4" />
|
||
<Spinner className="h-6 w-6" />
|
||
<Spinner className="h-8 w-8" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Toast</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Toast notifications for temporary messages, success confirmations, and error alerts.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Button onClick={() => toast({
|
||
title: "Toast Title",
|
||
description: "This is a toast notification.",
|
||
})}>
|
||
Show Toast
|
||
</Button>
|
||
<Button onClick={() => toast({
|
||
title: "Destructive Toast",
|
||
description: "This is a destructive toast.",
|
||
variant: "destructive",
|
||
})} variant="destructive">
|
||
Show Destructive Toast
|
||
</Button>
|
||
</div>
|
||
<CodeBlock
|
||
id="toast-code"
|
||
code={`const { toast } = useToast()
|
||
|
||
toast({
|
||
title: "Toast Title",
|
||
description: "This is a toast notification.",
|
||
})`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Overlay Components */}
|
||
<Section id="overlays" title="Overlay Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Dialog</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Modal dialog component for focused interactions, forms, and important content that requires user attention.
|
||
</p>
|
||
<Dialog>
|
||
<DialogTrigger asChild>
|
||
<Button variant="outline">Open Dialog</Button>
|
||
</DialogTrigger>
|
||
<DialogContent>
|
||
<DialogHeader>
|
||
<DialogTitle>Dialog Title</DialogTitle>
|
||
<DialogDescription>
|
||
This is a dialog description. It can contain any content.
|
||
</DialogDescription>
|
||
</DialogHeader>
|
||
<p className="text-sm text-muted-foreground">Dialog content goes here.</p>
|
||
</DialogContent>
|
||
</Dialog>
|
||
<CodeBlock
|
||
id="dialog-code"
|
||
code={`<Dialog>
|
||
<DialogTrigger asChild>
|
||
<Button>Open</Button>
|
||
</DialogTrigger>
|
||
<DialogContent>
|
||
<DialogHeader>
|
||
<DialogTitle>Title</DialogTitle>
|
||
<DialogDescription>Description</DialogDescription>
|
||
</DialogHeader>
|
||
<p>Content</p>
|
||
</DialogContent>
|
||
</Dialog>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Sheet</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Sheet component that slides in from different sides. Perfect for mobile menus, sidebars, and detail views.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Right Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="right">
|
||
<SheetHeader>
|
||
<SheetTitle>Right Side Sheet</SheetTitle>
|
||
<SheetDescription>
|
||
This sheet slides in from the right side. Perfect for detail views and forms.
|
||
</SheetDescription>
|
||
</SheetHeader>
|
||
<div className="mt-6 space-y-4">
|
||
<div>
|
||
<Label htmlFor="sheet-name">Name</Label>
|
||
<Input id="sheet-name" placeholder="Enter name" className="mt-2" />
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="sheet-email">Email</Label>
|
||
<Input id="sheet-email" type="email" placeholder="Enter email" className="mt-2" />
|
||
</div>
|
||
<Button className="w-full">Save Changes</Button>
|
||
</div>
|
||
</SheetContent>
|
||
</Sheet>
|
||
<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Left Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="left">
|
||
<SheetHeader>
|
||
<SheetTitle>Left Side Sheet</SheetTitle>
|
||
<SheetDescription>
|
||
This sheet slides in from the left side. Great for navigation menus.
|
||
</SheetDescription>
|
||
</SheetHeader>
|
||
<nav className="mt-6 space-y-2">
|
||
<a href="#" className="block py-2 hover:text-secondary transition-colors">Home</a>
|
||
<a href="#" className="block py-2 hover:text-secondary transition-colors">About</a>
|
||
<a href="#" className="block py-2 hover:text-secondary transition-colors">Services</a>
|
||
<a href="#" className="block py-2 hover:text-secondary transition-colors">Contact</a>
|
||
</nav>
|
||
</SheetContent>
|
||
</Sheet>
|
||
<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Top Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="top">
|
||
<SheetHeader>
|
||
<SheetTitle>Top Sheet</SheetTitle>
|
||
<SheetDescription>
|
||
This sheet slides in from the top. Useful for notifications and filters.
|
||
</SheetDescription>
|
||
</SheetHeader>
|
||
</SheetContent>
|
||
</Sheet>
|
||
<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Bottom Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="bottom">
|
||
<SheetHeader>
|
||
<SheetTitle>Bottom Sheet</SheetTitle>
|
||
<SheetDescription>
|
||
This sheet slides in from the bottom. Perfect for mobile actions.
|
||
</SheetDescription>
|
||
</SheetHeader>
|
||
</SheetContent>
|
||
</Sheet>
|
||
</div>
|
||
<CodeBlock
|
||
id="sheet-code"
|
||
code={`<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="right">
|
||
<SheetHeader>
|
||
<SheetTitle>Sheet Title</SheetTitle>
|
||
<SheetDescription>Description text</SheetDescription>
|
||
</SheetHeader>
|
||
<div className="mt-6">
|
||
{/* Your content here */}
|
||
</div>
|
||
</SheetContent>
|
||
</Sheet>
|
||
|
||
// Available sides: "top" | "right" | "bottom" | "left"`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Drawer</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Bottom drawer component for mobile-friendly interactions, filters, and additional content.
|
||
</p>
|
||
<Drawer>
|
||
<DrawerTrigger asChild>
|
||
<Button variant="outline">Open Drawer</Button>
|
||
</DrawerTrigger>
|
||
<DrawerContent>
|
||
<DrawerHeader>
|
||
<DrawerTitle>Drawer Title</DrawerTitle>
|
||
<DrawerDescription>This is a drawer component.</DrawerDescription>
|
||
</DrawerHeader>
|
||
<p className="text-sm text-muted-foreground px-4">Drawer content goes here.</p>
|
||
<DrawerFooter>
|
||
<Button>Submit</Button>
|
||
<DrawerClose asChild>
|
||
<Button variant="outline">Cancel</Button>
|
||
</DrawerClose>
|
||
</DrawerFooter>
|
||
</DrawerContent>
|
||
</Drawer>
|
||
<CodeBlock
|
||
id="drawer-code"
|
||
code={`<Drawer>
|
||
<DrawerTrigger asChild>
|
||
<Button>Open</Button>
|
||
</DrawerTrigger>
|
||
<DrawerContent>
|
||
<DrawerHeader>
|
||
<DrawerTitle>Title</DrawerTitle>
|
||
<DrawerDescription>Description</DrawerDescription>
|
||
</DrawerHeader>
|
||
<p>Content</p>
|
||
</DrawerContent>
|
||
</Drawer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Popover</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Popover component for displaying additional information or actions in a floating panel.
|
||
</p>
|
||
<Popover>
|
||
<PopoverTrigger asChild>
|
||
<Button variant="outline">Open Popover</Button>
|
||
</PopoverTrigger>
|
||
<PopoverContent>
|
||
<div className="space-y-2">
|
||
<h4 className="font-medium">Popover Title</h4>
|
||
<p className="text-sm text-muted-foreground">This is a popover component.</p>
|
||
</div>
|
||
</PopoverContent>
|
||
</Popover>
|
||
<CodeBlock
|
||
id="popover-code"
|
||
code={`<Popover>
|
||
<PopoverTrigger asChild>
|
||
<Button>Open</Button>
|
||
</PopoverTrigger>
|
||
<PopoverContent>
|
||
<h4>Title</h4>
|
||
<p>Content</p>
|
||
</PopoverContent>
|
||
</Popover>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Tooltip</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Tooltip component for showing helpful hints and additional context on hover or focus.
|
||
</p>
|
||
<TooltipProvider>
|
||
<Tooltip>
|
||
<TooltipTrigger asChild>
|
||
<Button variant="outline">Hover for tooltip</Button>
|
||
</TooltipTrigger>
|
||
<TooltipContent>
|
||
<p>This is a tooltip</p>
|
||
</TooltipContent>
|
||
</Tooltip>
|
||
</TooltipProvider>
|
||
<CodeBlock
|
||
id="tooltip-code"
|
||
code={`<TooltipProvider>
|
||
<Tooltip>
|
||
<TooltipTrigger asChild>
|
||
<Button>Hover me</Button>
|
||
</TooltipTrigger>
|
||
<TooltipContent>
|
||
<p>Tooltip text</p>
|
||
</TooltipContent>
|
||
</Tooltip>
|
||
</TooltipProvider>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Hover Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Rich hover card for displaying detailed information about users, items, or entities on hover.
|
||
</p>
|
||
<HoverCard>
|
||
<HoverCardTrigger asChild>
|
||
<Button variant="link">@username</Button>
|
||
</HoverCardTrigger>
|
||
<HoverCardContent>
|
||
<div className="space-y-2">
|
||
<h4 className="text-sm font-semibold">User Name</h4>
|
||
<p className="text-sm text-muted-foreground">User description goes here.</p>
|
||
</div>
|
||
</HoverCardContent>
|
||
</HoverCard>
|
||
<CodeBlock
|
||
id="hover-card-code"
|
||
code={`<HoverCard>
|
||
<HoverCardTrigger asChild>
|
||
<Button variant="link">@username</Button>
|
||
</HoverCardTrigger>
|
||
<HoverCardContent>
|
||
<h4>Title</h4>
|
||
<p>Content</p>
|
||
</HoverCardContent>
|
||
</HoverCard>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Navigation Components */}
|
||
<Section id="navigation" title="Navigation Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Breadcrumb</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Breadcrumb navigation for showing the current page location within the site hierarchy.
|
||
</p>
|
||
<Breadcrumb className="mb-6">
|
||
<BreadcrumbList>
|
||
<BreadcrumbItem>
|
||
<BreadcrumbLink href="#">Home</BreadcrumbLink>
|
||
</BreadcrumbItem>
|
||
<BreadcrumbSeparator />
|
||
<BreadcrumbItem>
|
||
<BreadcrumbLink href="#">Components</BreadcrumbLink>
|
||
</BreadcrumbItem>
|
||
<BreadcrumbSeparator />
|
||
<BreadcrumbItem>
|
||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||
</BreadcrumbItem>
|
||
</BreadcrumbList>
|
||
</Breadcrumb>
|
||
<CodeBlock
|
||
id="breadcrumb-code"
|
||
code={`<Breadcrumb>
|
||
<BreadcrumbList>
|
||
<BreadcrumbItem>
|
||
<BreadcrumbLink href="#">Home</BreadcrumbLink>
|
||
</BreadcrumbItem>
|
||
<BreadcrumbSeparator />
|
||
<BreadcrumbItem>
|
||
<BreadcrumbPage>Current</BreadcrumbPage>
|
||
</BreadcrumbItem>
|
||
</BreadcrumbList>
|
||
</Breadcrumb>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Pagination</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Pagination component for navigating through pages of content. Supports ellipsis for large page counts.
|
||
</p>
|
||
<div className="space-y-6 mb-6">
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Basic Pagination</h4>
|
||
<Pagination>
|
||
<PaginationContent>
|
||
<PaginationItem>
|
||
<PaginationPrevious href="#" />
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">1</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#" isActive>2</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">3</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationNext href="#" />
|
||
</PaginationItem>
|
||
</PaginationContent>
|
||
</Pagination>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Pagination with Ellipsis</h4>
|
||
<Pagination>
|
||
<PaginationContent>
|
||
<PaginationItem>
|
||
<PaginationPrevious href="#" />
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">1</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#" isActive>2</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">3</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<span className="px-2">...</span>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">10</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationNext href="#" />
|
||
</PaginationItem>
|
||
</PaginationContent>
|
||
</Pagination>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Compact Pagination</h4>
|
||
<Pagination>
|
||
<PaginationContent>
|
||
<PaginationItem>
|
||
<PaginationPrevious href="#" />
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#" isActive>1</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationNext href="#" />
|
||
</PaginationItem>
|
||
</PaginationContent>
|
||
</Pagination>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="pagination-code"
|
||
code={`<Pagination>
|
||
<PaginationContent>
|
||
<PaginationItem>
|
||
<PaginationPrevious href="#" />
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">1</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#" isActive>2</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">3</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<span className="px-2">...</span>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationNext href="#" />
|
||
</PaginationItem>
|
||
</PaginationContent>
|
||
</Pagination>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Dropdown Menu</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Dropdown menu component that appears on click. Perfect for user menus, action menus, and navigation dropdowns.
|
||
</p>
|
||
<DropdownMenu>
|
||
<DropdownMenuTrigger asChild>
|
||
<Button variant="outline">Open Menu</Button>
|
||
</DropdownMenuTrigger>
|
||
<DropdownMenuContent>
|
||
<DropdownMenuItem>Profile</DropdownMenuItem>
|
||
<DropdownMenuItem>Settings</DropdownMenuItem>
|
||
<DropdownMenuItem>Logout</DropdownMenuItem>
|
||
</DropdownMenuContent>
|
||
</DropdownMenu>
|
||
<CodeBlock
|
||
id="dropdown-menu-code"
|
||
code={`<DropdownMenu>
|
||
<DropdownMenuTrigger asChild>
|
||
<Button>Open</Button>
|
||
</DropdownMenuTrigger>
|
||
<DropdownMenuContent>
|
||
<DropdownMenuItem>Item 1</DropdownMenuItem>
|
||
<DropdownMenuItem>Item 2</DropdownMenuItem>
|
||
</DropdownMenuContent>
|
||
</DropdownMenu>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Context Menu</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Right-click context menu for displaying contextual actions. Appears on right-click or long-press on mobile devices.
|
||
</p>
|
||
<ContextMenu>
|
||
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
|
||
Right click here
|
||
</ContextMenuTrigger>
|
||
<ContextMenuContent>
|
||
<ContextMenuItem>Back</ContextMenuItem>
|
||
<ContextMenuItem>Forward</ContextMenuItem>
|
||
<ContextMenuItem>Reload</ContextMenuItem>
|
||
</ContextMenuContent>
|
||
</ContextMenu>
|
||
<CodeBlock
|
||
id="context-menu-code"
|
||
code={`<ContextMenu>
|
||
<ContextMenuTrigger>Right click here</ContextMenuTrigger>
|
||
<ContextMenuContent>
|
||
<ContextMenuItem>Item 1</ContextMenuItem>
|
||
<ContextMenuItem>Item 2</ContextMenuItem>
|
||
</ContextMenuContent>
|
||
</ContextMenu>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Data Display */}
|
||
<Section id="data-display" title="Data Display">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Avatar</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Avatar component for displaying user profile pictures with fallback initials when no image is available.
|
||
</p>
|
||
<div className="flex items-center gap-4 mb-6">
|
||
<Avatar>
|
||
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
||
<AvatarFallback>CN</AvatarFallback>
|
||
</Avatar>
|
||
<Avatar>
|
||
<AvatarFallback>JD</AvatarFallback>
|
||
</Avatar>
|
||
<Avatar>
|
||
<AvatarFallback>AB</AvatarFallback>
|
||
</Avatar>
|
||
</div>
|
||
<CodeBlock
|
||
id="avatar-code"
|
||
code={`<Avatar>
|
||
<AvatarImage src="/image.jpg" alt="User" />
|
||
<AvatarFallback>CN</AvatarFallback>
|
||
</Avatar>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Table</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Table component for displaying structured data. Supports headers, footers, and responsive layouts.
|
||
</p>
|
||
<div className="space-y-6 mb-6">
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Basic Table</h4>
|
||
<div className="border rounded-lg overflow-hidden">
|
||
<Table>
|
||
<TableCaption>A list of recent invoices.</TableCaption>
|
||
<TableHeader>
|
||
<TableRow>
|
||
<TableHead className="w-[100px]">Invoice</TableHead>
|
||
<TableHead>Status</TableHead>
|
||
<TableHead>Method</TableHead>
|
||
<TableHead className="text-right">Amount</TableHead>
|
||
</TableRow>
|
||
</TableHeader>
|
||
<TableBody>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV001</TableCell>
|
||
<TableCell>
|
||
<Badge variant="outline">Paid</Badge>
|
||
</TableCell>
|
||
<TableCell>Credit Card</TableCell>
|
||
<TableCell className="text-right">$250.00</TableCell>
|
||
</TableRow>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV002</TableCell>
|
||
<TableCell>
|
||
<Badge variant="secondary">Pending</Badge>
|
||
</TableCell>
|
||
<TableCell>PayPal</TableCell>
|
||
<TableCell className="text-right">$150.00</TableCell>
|
||
</TableRow>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV003</TableCell>
|
||
<TableCell>
|
||
<Badge variant="outline">Paid</Badge>
|
||
</TableCell>
|
||
<TableCell>Bank Transfer</TableCell>
|
||
<TableCell className="text-right">$350.00</TableCell>
|
||
</TableRow>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV004</TableCell>
|
||
<TableCell>
|
||
<Badge variant="destructive">Failed</Badge>
|
||
</TableCell>
|
||
<TableCell>Credit Card</TableCell>
|
||
<TableCell className="text-right">$450.00</TableCell>
|
||
</TableRow>
|
||
</TableBody>
|
||
<TableFooter>
|
||
<TableRow>
|
||
<TableCell colSpan={3}>Total</TableCell>
|
||
<TableCell className="text-right">$1,200.00</TableCell>
|
||
</TableRow>
|
||
</TableFooter>
|
||
</Table>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Compact Table</h4>
|
||
<div className="border rounded-lg overflow-hidden">
|
||
<Table>
|
||
<TableHeader>
|
||
<TableRow>
|
||
<TableHead>Product</TableHead>
|
||
<TableHead>Price</TableHead>
|
||
<TableHead>Stock</TableHead>
|
||
</TableRow>
|
||
</TableHeader>
|
||
<TableBody>
|
||
<TableRow>
|
||
<TableCell className="font-medium">Vending Machine A</TableCell>
|
||
<TableCell>$1,200.00</TableCell>
|
||
<TableCell>
|
||
<Badge variant="outline">In Stock</Badge>
|
||
</TableCell>
|
||
</TableRow>
|
||
<TableRow>
|
||
<TableCell className="font-medium">Vending Machine B</TableCell>
|
||
<TableCell>$950.00</TableCell>
|
||
<TableCell>
|
||
<Badge variant="secondary">Low Stock</Badge>
|
||
</TableCell>
|
||
</TableRow>
|
||
</TableBody>
|
||
</Table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="table-code"
|
||
code={`<Table>
|
||
<TableCaption>A list of recent invoices.</TableCaption>
|
||
<TableHeader>
|
||
<TableRow>
|
||
<TableHead className="w-[100px]">Invoice</TableHead>
|
||
<TableHead>Status</TableHead>
|
||
<TableHead className="text-right">Amount</TableHead>
|
||
</TableRow>
|
||
</TableHeader>
|
||
<TableBody>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV001</TableCell>
|
||
<TableCell>
|
||
<Badge variant="outline">Paid</Badge>
|
||
</TableCell>
|
||
<TableCell className="text-right">$250.00</TableCell>
|
||
</TableRow>
|
||
</TableBody>
|
||
<TableFooter>
|
||
<TableRow>
|
||
<TableCell colSpan={2}>Total</TableCell>
|
||
<TableCell className="text-right">$250.00</TableCell>
|
||
</TableRow>
|
||
</TableFooter>
|
||
</Table>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Empty State</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Empty state component for displaying helpful messages when there's no content to show.
|
||
</p>
|
||
<Empty className="mb-6">
|
||
<EmptyMedia variant="icon">
|
||
<Package className="h-8 w-8" />
|
||
</EmptyMedia>
|
||
<EmptyHeader>
|
||
<EmptyTitle>No items found</EmptyTitle>
|
||
<EmptyDescription>
|
||
There are no items to display at this time.
|
||
</EmptyDescription>
|
||
</EmptyHeader>
|
||
<EmptyContent>
|
||
<Button>Add Item</Button>
|
||
</EmptyContent>
|
||
</Empty>
|
||
<CodeBlock
|
||
id="empty-code"
|
||
code={`<Empty>
|
||
<EmptyMedia variant="icon">
|
||
<Package className="h-8 w-8" />
|
||
</EmptyMedia>
|
||
<EmptyHeader>
|
||
<EmptyTitle>No items</EmptyTitle>
|
||
<EmptyDescription>Description</EmptyDescription>
|
||
</EmptyHeader>
|
||
<EmptyContent>
|
||
<Button>Action</Button>
|
||
</EmptyContent>
|
||
</Empty>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Keyboard (Kbd)</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Keyboard key indicator component for displaying keyboard shortcuts and key combinations.
|
||
</p>
|
||
<div className="flex items-center gap-2 mb-6">
|
||
<Kbd>⌘</Kbd>
|
||
<span>+</span>
|
||
<Kbd>K</Kbd>
|
||
</div>
|
||
<CodeBlock
|
||
id="kbd-code"
|
||
code={`<Kbd>⌘</Kbd> + <Kbd>K</Kbd>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Charts & Graphs */}
|
||
<Section id="charts" title="Charts & Graphs">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Line Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Line charts are perfect for showing trends over time.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer config={lineChartConfig} className="h-[300px] w-full">
|
||
<LineChart data={lineChartData}>
|
||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||
<XAxis
|
||
dataKey="month"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => value.slice(0, 3)}
|
||
/>
|
||
<YAxis
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => `${value}`}
|
||
/>
|
||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||
<Line
|
||
dataKey="desktop"
|
||
type="monotone"
|
||
stroke="var(--color-desktop)"
|
||
strokeWidth={2}
|
||
dot={false}
|
||
/>
|
||
<Line
|
||
dataKey="mobile"
|
||
type="monotone"
|
||
stroke="var(--color-mobile)"
|
||
strokeWidth={2}
|
||
dot={false}
|
||
/>
|
||
</LineChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="line-chart-code"
|
||
code={`import { LineChart, Line, XAxis, YAxis, CartesianGrid } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
desktop: { label: "Desktop", color: "#F79611" }, // Brand orange
|
||
mobile: { label: "Mobile", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<LineChart data={data}>
|
||
<CartesianGrid strokeDasharray="3 3" />
|
||
<XAxis dataKey="month" />
|
||
<YAxis />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Line dataKey="desktop" stroke="var(--color-desktop)" />
|
||
<Line dataKey="mobile" stroke="var(--color-mobile)" />
|
||
</LineChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Bar Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Bar charts are great for comparing values across categories.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer config={barChartConfig} className="h-[300px] w-full">
|
||
<BarChart data={barChartData}>
|
||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||
<XAxis
|
||
dataKey="month"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => value.slice(0, 3)}
|
||
/>
|
||
<YAxis
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => `${value}`}
|
||
/>
|
||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
||
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
||
</BarChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="bar-chart-code"
|
||
code={`import { BarChart, Bar, XAxis, YAxis, CartesianGrid } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
desktop: { label: "Desktop", color: "#F79611" }, // Brand orange
|
||
mobile: { label: "Mobile", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<BarChart data={data}>
|
||
<CartesianGrid strokeDasharray="3 3" />
|
||
<XAxis dataKey="month" />
|
||
<YAxis />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
||
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
||
</BarChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Area Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Area charts show the magnitude of change over time, similar to line charts but with filled areas.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer config={areaChartConfig} className="h-[300px] w-full">
|
||
<AreaChart data={areaChartData}>
|
||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||
<XAxis
|
||
dataKey="month"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => value.slice(0, 3)}
|
||
/>
|
||
<YAxis
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => `${value}`}
|
||
/>
|
||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||
<Area
|
||
dataKey="desktop"
|
||
type="monotone"
|
||
fill="var(--color-desktop)"
|
||
fillOpacity={0.4}
|
||
stroke="var(--color-desktop)"
|
||
strokeWidth={2}
|
||
/>
|
||
<Area
|
||
dataKey="mobile"
|
||
type="monotone"
|
||
fill="var(--color-mobile)"
|
||
fillOpacity={0.4}
|
||
stroke="var(--color-mobile)"
|
||
strokeWidth={2}
|
||
/>
|
||
</AreaChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="area-chart-code"
|
||
code={`import { AreaChart, Area, XAxis, YAxis, CartesianGrid } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
desktop: { label: "Desktop", color: "#F79611" }, // Brand orange
|
||
mobile: { label: "Mobile", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<AreaChart data={data}>
|
||
<CartesianGrid strokeDasharray="3 3" />
|
||
<XAxis dataKey="month" />
|
||
<YAxis />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Area dataKey="desktop" fill="var(--color-desktop)" stroke="var(--color-desktop)" />
|
||
<Area dataKey="mobile" fill="var(--color-mobile)" stroke="var(--color-mobile)" />
|
||
</AreaChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Pie Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Pie charts are ideal for showing proportions and percentages of a whole.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer config={pieChartConfig} className="h-[300px] w-full">
|
||
<PieChart>
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Pie
|
||
data={pieChartData}
|
||
dataKey="value"
|
||
nameKey="name"
|
||
cx="50%"
|
||
cy="50%"
|
||
outerRadius={80}
|
||
label
|
||
>
|
||
{pieChartData.map((entry, index) => (
|
||
<Cell key={`cell-${index}`} fill={entry.fill} />
|
||
))}
|
||
</Pie>
|
||
</PieChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="pie-chart-code"
|
||
code={`import { PieChart, Pie, Cell } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const data = [
|
||
{ name: "Desktop", value: 186, fill: "#F79611" }, // Brand orange
|
||
{ name: "Mobile", value: 80, fill: "#FCBA09" }, // Custom yellow
|
||
]
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<PieChart>
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Pie data={data} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={80}>
|
||
{data.map((entry, index) => (
|
||
<Cell key={\`cell-\${index}\`} fill={entry.fill} />
|
||
))}
|
||
</Pie>
|
||
</PieChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Radar Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Radar charts are useful for displaying multivariate data in a way that makes it easy to compare multiple variables.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer config={radarChartConfig} className="h-[300px] w-full">
|
||
<RadarChart data={radarChartData}>
|
||
<PolarGrid />
|
||
<PolarAngleAxis dataKey="subject" />
|
||
<PolarRadiusAxis angle={90} domain={[0, 150]} />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Radar
|
||
name="Student A"
|
||
dataKey="A"
|
||
stroke="var(--color-A)"
|
||
fill="var(--color-A)"
|
||
fillOpacity={0.6}
|
||
/>
|
||
<Radar
|
||
name="Student B"
|
||
dataKey="B"
|
||
stroke="var(--color-B)"
|
||
fill="var(--color-B)"
|
||
fillOpacity={0.6}
|
||
/>
|
||
</RadarChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="radar-chart-code"
|
||
code={`import { RadarChart, Radar, PolarGrid, PolarAngleAxis, PolarRadiusAxis } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
A: { label: "Student A", color: "#F79611" }, // Brand orange
|
||
B: { label: "Student B", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<RadarChart data={data}>
|
||
<PolarGrid />
|
||
<PolarAngleAxis dataKey="subject" />
|
||
<PolarRadiusAxis />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Radar dataKey="A" stroke="var(--color-A)" fill="var(--color-A)" fillOpacity={0.6} />
|
||
<Radar dataKey="B" stroke="var(--color-B)" fill="var(--color-B)" fillOpacity={0.6} />
|
||
</RadarChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Composed Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Composed charts combine multiple chart types (like bars and lines) in a single visualization.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer config={lineChartConfig} className="h-[300px] w-full">
|
||
<ComposedChart data={lineChartData}>
|
||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||
<XAxis
|
||
dataKey="month"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => value.slice(0, 3)}
|
||
/>
|
||
<YAxis
|
||
yAxisId="left"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
/>
|
||
<YAxis
|
||
yAxisId="right"
|
||
orientation="right"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
/>
|
||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||
<Bar yAxisId="left" dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
||
<Line
|
||
yAxisId="right"
|
||
type="monotone"
|
||
dataKey="mobile"
|
||
stroke="var(--color-mobile)"
|
||
strokeWidth={2}
|
||
dot={false}
|
||
/>
|
||
</ComposedChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="composed-chart-code"
|
||
code={`import { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
desktop: { label: "Desktop", color: "#F79611" }, // Brand orange
|
||
mobile: { label: "Mobile", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<ComposedChart data={data}>
|
||
<CartesianGrid strokeDasharray="3 3" />
|
||
<XAxis dataKey="month" />
|
||
<YAxis yAxisId="left" />
|
||
<YAxis yAxisId="right" orientation="right" />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Bar yAxisId="left" dataKey="desktop" fill="var(--color-desktop)" />
|
||
<Line yAxisId="right" type="monotone" dataKey="mobile" stroke="var(--color-mobile)" />
|
||
</ComposedChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Interactive Components */}
|
||
<Section id="interactive" title="Interactive Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Switch</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Toggle switch component for binary on/off settings. More visually distinct than checkboxes for important settings.
|
||
</p>
|
||
<div className="flex items-center space-x-2 mb-6">
|
||
<Switch id="switch-example" />
|
||
<Label htmlFor="switch-example">Enable notifications</Label>
|
||
</div>
|
||
<CodeBlock
|
||
id="switch-code"
|
||
code={`<div className="flex items-center space-x-2">
|
||
<Switch id="switch" />
|
||
<Label htmlFor="switch">Label</Label>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Slider</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Slider component for selecting a value from a range. Supports single value or range selection with customizable steps.
|
||
</p>
|
||
<div className="space-y-4 mb-6 max-w-md">
|
||
<Slider defaultValue={[50]} max={100} step={1} />
|
||
<Slider defaultValue={[25, 75]} max={100} step={1} />
|
||
</div>
|
||
<CodeBlock
|
||
id="slider-code"
|
||
code={`<Slider defaultValue={[50]} max={100} step={1} />
|
||
<Slider defaultValue={[25, 75]} max={100} step={1} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Toggle</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Toggle button component that can be pressed to toggle a state. Useful for toolbar buttons and inline formatting controls.
|
||
</p>
|
||
<div className="flex items-center gap-4 mb-6">
|
||
<Toggle aria-label="Toggle italic">
|
||
<span>Bold</span>
|
||
</Toggle>
|
||
<Toggle variant="outline" aria-label="Toggle italic">
|
||
<span>Italic</span>
|
||
</Toggle>
|
||
</div>
|
||
<CodeBlock
|
||
id="toggle-code"
|
||
code={`<Toggle aria-label="Toggle">
|
||
<span>Bold</span>
|
||
</Toggle>
|
||
<Toggle variant="outline">
|
||
<span>Italic</span>
|
||
</Toggle>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Toggle Group</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Group of toggle buttons that work together. Supports single selection (radio-like) or multiple selection (checkbox-like).
|
||
</p>
|
||
<ToggleGroup type="single" defaultValue="center" className="mb-6">
|
||
<ToggleGroupItem value="left" aria-label="Left aligned">
|
||
<span>Left</span>
|
||
</ToggleGroupItem>
|
||
<ToggleGroupItem value="center" aria-label="Center aligned">
|
||
<span>Center</span>
|
||
</ToggleGroupItem>
|
||
<ToggleGroupItem value="right" aria-label="Right aligned">
|
||
<span>Right</span>
|
||
</ToggleGroupItem>
|
||
</ToggleGroup>
|
||
<CodeBlock
|
||
id="toggle-group-code"
|
||
code={`<ToggleGroup type="single" defaultValue="center">
|
||
<ToggleGroupItem value="left">Left</ToggleGroupItem>
|
||
<ToggleGroupItem value="center">Center</ToggleGroupItem>
|
||
<ToggleGroupItem value="right">Right</ToggleGroupItem>
|
||
</ToggleGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Collapsible</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Collapsible content component for showing and hiding content. Similar to accordion but without the accordion styling.
|
||
</p>
|
||
<Collapsible className="mb-6">
|
||
<CollapsibleTrigger asChild>
|
||
<Button variant="outline">Toggle</Button>
|
||
</CollapsibleTrigger>
|
||
<CollapsibleContent className="mt-2 p-4 border rounded-md">
|
||
<p className="text-sm text-muted-foreground">
|
||
This is collapsible content that can be shown or hidden.
|
||
</p>
|
||
</CollapsibleContent>
|
||
</Collapsible>
|
||
<CodeBlock
|
||
id="collapsible-code"
|
||
code={`<Collapsible>
|
||
<CollapsibleTrigger asChild>
|
||
<Button>Toggle</Button>
|
||
</CollapsibleTrigger>
|
||
<CollapsibleContent>
|
||
<p>Content</p>
|
||
</CollapsibleContent>
|
||
</Collapsible>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Layout Components */}
|
||
<Section id="layout" title="Layout Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Aspect Ratio</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Aspect ratio component for maintaining consistent image and video dimensions. Prevents layout shift during loading.
|
||
</p>
|
||
<div className="max-w-md mb-6">
|
||
<AspectRatio ratio={16 / 9} className="bg-muted rounded-lg overflow-hidden">
|
||
<div className="flex items-center justify-center h-full text-muted-foreground">
|
||
16:9 Aspect Ratio
|
||
</div>
|
||
</AspectRatio>
|
||
</div>
|
||
<CodeBlock
|
||
id="aspect-ratio-component-code"
|
||
code={`<AspectRatio ratio={16 / 9} className="bg-muted">
|
||
<Image src="/image.jpg" alt="Description" fill className="object-cover" />
|
||
</AspectRatio>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Scroll Area</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom scrollable area component with styled scrollbars. Provides consistent cross-browser scrolling behavior.
|
||
</p>
|
||
<ScrollArea className="h-32 w-full border rounded-md p-4 mb-6">
|
||
<div className="space-y-2">
|
||
{Array.from({ length: 10 }).map((_, i) => (
|
||
<p key={i} className="text-sm">Item {i + 1}</p>
|
||
))}
|
||
</div>
|
||
</ScrollArea>
|
||
<CodeBlock
|
||
id="scroll-area-code"
|
||
code={`<ScrollArea className="h-32 w-full">
|
||
<div>Content that scrolls</div>
|
||
</ScrollArea>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Resizable Panels</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Resizable panel group for creating adjustable layouts. Users can drag to resize panels horizontally or vertically.
|
||
</p>
|
||
<ResizablePanelGroup direction="horizontal" className="max-w-md border rounded-lg mb-6">
|
||
<ResizablePanel defaultSize={50}>
|
||
<div className="flex h-[200px] items-center justify-center p-6">
|
||
<span className="font-semibold">Panel 1</span>
|
||
</div>
|
||
</ResizablePanel>
|
||
<ResizableHandle />
|
||
<ResizablePanel defaultSize={50}>
|
||
<div className="flex h-[200px] items-center justify-center p-6">
|
||
<span className="font-semibold">Panel 2</span>
|
||
</div>
|
||
</ResizablePanel>
|
||
</ResizablePanelGroup>
|
||
<CodeBlock
|
||
id="resizable-code"
|
||
code={`<ResizablePanelGroup direction="horizontal">
|
||
<ResizablePanel defaultSize={50}>
|
||
<div>Panel 1</div>
|
||
</ResizablePanel>
|
||
<ResizableHandle />
|
||
<ResizablePanel defaultSize={50}>
|
||
<div>Panel 2</div>
|
||
</ResizablePanel>
|
||
</ResizablePanelGroup>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Advanced Components */}
|
||
<Section id="advanced" title="Advanced Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Carousel</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Carousel component for displaying a set of items in a scrollable container. Supports multiple items per view, navigation arrows, and autoplay.
|
||
</p>
|
||
<div className="space-y-8 mb-6">
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Single Item Carousel</h4>
|
||
<Carousel className="w-full max-w-xs mx-auto">
|
||
<CarouselContent>
|
||
{Array.from({ length: 5 }).map((_, index) => (
|
||
<CarouselItem key={index}>
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent className="flex aspect-square items-center justify-center p-6">
|
||
<span className="text-4xl font-semibold">{index + 1}</span>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
))}
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Multiple Items Carousel</h4>
|
||
<Carousel
|
||
opts={{
|
||
align: "start",
|
||
}}
|
||
className="w-full max-w-5xl mx-auto"
|
||
>
|
||
<CarouselContent>
|
||
{Array.from({ length: 10 }).map((_, index) => (
|
||
<CarouselItem key={index} className="md:basis-1/2 lg:basis-1/3">
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent className="flex aspect-square items-center justify-center p-6">
|
||
<span className="text-2xl font-semibold">Item {index + 1}</span>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
))}
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Image Carousel</h4>
|
||
<Carousel className="w-full max-w-2xl mx-auto">
|
||
<CarouselContent>
|
||
{Array.from({ length: 4 }).map((_, index) => (
|
||
<CarouselItem key={index}>
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent className="flex aspect-video items-center justify-center p-6 bg-muted">
|
||
<div className="text-center">
|
||
<div className="text-6xl mb-2">🖼️</div>
|
||
<p className="text-sm text-muted-foreground">Image {index + 1}</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
))}
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="carousel-code"
|
||
code={`<Carousel className="w-full max-w-xs">
|
||
<CarouselContent>
|
||
<CarouselItem>
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent>Item 1</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
<CarouselItem>
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent>Item 2</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>
|
||
|
||
// Multiple items per view
|
||
<Carousel opts={{ align: "start" }} className="w-full">
|
||
<CarouselContent>
|
||
<CarouselItem className="md:basis-1/2 lg:basis-1/3">
|
||
{/* Item */}
|
||
</CarouselItem>
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Calendar</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Calendar component for date selection. Supports single date, date range, and multiple date selection modes.
|
||
</p>
|
||
<div className="max-w-fit mb-6">
|
||
<Calendar mode="single" className="rounded-md border" />
|
||
</div>
|
||
<CodeBlock
|
||
id="calendar-code"
|
||
code={`<Calendar mode="single" className="rounded-md border" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Input OTP</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
One-time password input component with individual slots for each digit. Perfect for verification codes.
|
||
</p>
|
||
<div className="mb-6">
|
||
<InputOTP maxLength={6}>
|
||
<InputOTPGroup>
|
||
<InputOTPSlot index={0} />
|
||
<InputOTPSlot index={1} />
|
||
<InputOTPSlot index={2} />
|
||
<InputOTPSlot index={3} />
|
||
<InputOTPSlot index={4} />
|
||
<InputOTPSlot index={5} />
|
||
</InputOTPGroup>
|
||
</InputOTP>
|
||
</div>
|
||
<CodeBlock
|
||
id="input-otp-code"
|
||
code={`<InputOTP maxLength={6}>
|
||
<InputOTPGroup>
|
||
<InputOTPSlot index={0} />
|
||
<InputOTPSlot index={1} />
|
||
<InputOTPSlot index={2} />
|
||
</InputOTPGroup>
|
||
</InputOTP>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Command Palette</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Command palette component for quick actions and search. Similar to VS Code's command palette, accessible via keyboard shortcut.
|
||
</p>
|
||
<Command className="rounded-lg border shadow-md max-w-md mb-6">
|
||
<CommandInput placeholder="Type a command or search..." />
|
||
<CommandList>
|
||
<CommandEmpty>No results found.</CommandEmpty>
|
||
<CommandGroup heading="Suggestions">
|
||
<CommandItem>
|
||
<span>Calendar</span>
|
||
</CommandItem>
|
||
<CommandItem>
|
||
<span>Search Emoji</span>
|
||
</CommandItem>
|
||
<CommandItem>
|
||
<span>Calculator</span>
|
||
</CommandItem>
|
||
</CommandGroup>
|
||
</CommandList>
|
||
</Command>
|
||
<CodeBlock
|
||
id="command-code"
|
||
code={`<Command>
|
||
<CommandInput placeholder="Search..." />
|
||
<CommandList>
|
||
<CommandEmpty>No results</CommandEmpty>
|
||
<CommandGroup heading="Items">
|
||
<CommandItem>Item 1</CommandItem>
|
||
</CommandGroup>
|
||
</CommandList>
|
||
</Command>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Spacing & Layout */}
|
||
<Section id="spacing" title="Spacing & Layout">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Container Patterns</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Standard container patterns for page layouts with consistent max-widths and padding.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div className="bg-muted/50 p-4 rounded">
|
||
<p className="text-sm font-mono mb-2">Standard: container mx-auto px-4 py-8 md:py-12 max-w-4xl</p>
|
||
<p className="text-xs text-muted-foreground">Used for most content pages</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div className="bg-muted/50 p-4 rounded">
|
||
<p className="text-sm font-mono mb-2">Wide: container mx-auto px-4 py-8 md:py-12 max-w-6xl</p>
|
||
<p className="text-xs text-muted-foreground">Used for wider content layouts</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div className="bg-muted/50 p-4 rounded">
|
||
<p className="text-sm font-mono mb-2">Full-width: container mx-auto px-4 py-8 md:py-12</p>
|
||
<p className="text-xs text-muted-foreground">No max-width constraint</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Section Padding</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Standard vertical padding patterns for sections. Responsive padding increases on larger screens.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<div className="bg-muted/30 py-20 md:py-28 rounded-lg border border-border">
|
||
<p className="text-center text-sm font-mono">py-20 md:py-28 (Standard sections)</p>
|
||
</div>
|
||
<div className="bg-muted/30 py-16 md:py-24 rounded-lg border border-border">
|
||
<p className="text-center text-sm font-mono">py-16 md:py-24 (Compact sections)</p>
|
||
</div>
|
||
<div className="bg-muted/30 py-20 md:py-32 rounded-lg border border-border">
|
||
<p className="text-center text-sm font-mono">py-20 md:py-32 (Hero sections)</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Grid Layouts</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Responsive grid layouts that adapt from single column on mobile to multiple columns on larger screens.
|
||
</p>
|
||
<div className="space-y-6 mb-6">
|
||
<div className="grid gap-4 md:grid-cols-2">
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">2 columns</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">2 columns</div>
|
||
</div>
|
||
<div className="grid gap-4 md:grid-cols-3">
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">3 columns</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">3 columns</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">3 columns</div>
|
||
</div>
|
||
<div className="grid gap-4 md:grid-cols-4">
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">4 columns</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">4 columns</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">4 columns</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">4 columns</div>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="grid-code"
|
||
code={`<div className="grid gap-4 md:grid-cols-2">2 columns</div>
|
||
<div className="grid gap-4 md:grid-cols-3">3 columns</div>
|
||
<div className="grid gap-4 md:grid-cols-4">4 columns</div>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Image Patterns */}
|
||
<Section id="images" title="Image Patterns">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Aspect Ratios</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Common aspect ratio patterns for images and media. Ensures consistent sizing and prevents layout shift.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-3 mb-6">
|
||
<Card className="border-border/50 overflow-hidden">
|
||
<div className="aspect-square relative bg-muted">
|
||
<div className="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm">
|
||
Square (aspect-square)
|
||
</div>
|
||
</div>
|
||
<CardContent className="p-4">
|
||
<p className="text-xs text-muted-foreground">1:1 Ratio</p>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50 overflow-hidden">
|
||
<div className="aspect-video relative bg-muted">
|
||
<div className="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm">
|
||
Video (aspect-video)
|
||
</div>
|
||
</div>
|
||
<CardContent className="p-4">
|
||
<p className="text-xs text-muted-foreground">16:9 Ratio</p>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50 overflow-hidden">
|
||
<div className="aspect-[4/3] relative bg-muted">
|
||
<div className="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm">
|
||
Custom (aspect-[4/3])
|
||
</div>
|
||
</div>
|
||
<CardContent className="p-4">
|
||
<p className="text-xs text-muted-foreground">4:3 Ratio</p>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
<CodeBlock
|
||
id="aspect-ratio-code"
|
||
code={`<div className="aspect-square relative bg-muted">
|
||
<Image src="/image.jpg" alt="Description" fill className="object-cover" />
|
||
</div>
|
||
|
||
<div className="aspect-video relative bg-muted">
|
||
<Image src="/image.jpg" alt="Description" fill className="object-cover" />
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Image Sizing Standards</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Recommended maximum image dimensions for optimal performance. Grid/card images: 300px, full-width: 600px.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<p className="text-sm font-semibold mb-2">Grid/Card Images</p>
|
||
<p className="text-xs text-muted-foreground mb-4">Maximum 300px per dimension</p>
|
||
<div className="max-w-xs mx-auto">
|
||
<div className="relative w-full overflow-hidden rounded-lg bg-muted shadow-sm aspect-square">
|
||
<div className="absolute inset-0 flex items-center justify-center text-xs text-muted-foreground">
|
||
Max 300px
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<p className="text-sm font-semibold mb-2">Full-width Images</p>
|
||
<p className="text-xs text-muted-foreground mb-4">Maximum 600px per dimension</p>
|
||
<div className="max-w-md mx-auto">
|
||
<div className="relative w-full overflow-hidden rounded-lg bg-muted shadow-sm aspect-video">
|
||
<div className="absolute inset-0 flex items-center justify-center text-xs text-muted-foreground">
|
||
Max 600px
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
</div>
|
||
|
||
{/* Home Page Sections - Full Width */}
|
||
<section id="sections" className="scroll-mt-24">
|
||
<div className="container mx-auto px-4 max-w-7xl py-12 md:py-16">
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-8 text-balance border-b border-border pb-4">
|
||
Home Page Sections
|
||
</h2>
|
||
<p className="text-sm text-muted-foreground mb-8">
|
||
These sections are displayed at full width, matching the homepage layout. Each section has its own background and internal container.
|
||
</p>
|
||
</div>
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6">
|
||
<h3 className="text-xl font-semibold mb-2">Hero Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
The hero section includes a badge, main heading, description, feature list, and CTA buttons.
|
||
</p>
|
||
</div>
|
||
<HeroSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Stats Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Displays key statistics in a grid layout with large numbers.
|
||
</p>
|
||
</div>
|
||
<StatsSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Features Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Shows key features with icons in a card grid layout.
|
||
</p>
|
||
</div>
|
||
<FeaturesSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Product Showcase Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Displays products with images in a card grid.
|
||
</p>
|
||
</div>
|
||
<ProductShowcaseSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">How It Works Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Step-by-step process cards with numbered indicators.
|
||
</p>
|
||
</div>
|
||
<HowItWorksSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Services Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Service offerings with images and lists.
|
||
</p>
|
||
</div>
|
||
<ServicesSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Service Areas Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Displays service area map and city listings.
|
||
</p>
|
||
</div>
|
||
<ServiceAreasSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Reviews Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Customer reviews with rating badge.
|
||
</p>
|
||
</div>
|
||
<ReviewsSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Request Machine Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
CTA section with embedded form.
|
||
</p>
|
||
</div>
|
||
<RequestMachineSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Contact Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Contact information and detailed contact form.
|
||
</p>
|
||
</div>
|
||
<ContactSection />
|
||
</section>
|
||
|
||
<div className="container mx-auto px-4 py-8 md:py-12 max-w-7xl">
|
||
{/* Custom Components */}
|
||
<Section id="custom" title="Custom Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Benefits/Features Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Grid layout for displaying benefits or features with icons. Commonly used on service pages.
|
||
</p>
|
||
<div className="mb-6">
|
||
<div className="text-center mb-12 md:mb-16">
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-4 text-balance">
|
||
Why Choose Us?
|
||
</h2>
|
||
<p className="text-lg text-muted-foreground max-w-2xl mx-auto text-pretty leading-relaxed">
|
||
We provide comprehensive solutions tailored to your specific needs
|
||
</p>
|
||
</div>
|
||
<div className="grid gap-6 md:grid-cols-2">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">100% FREE Service</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
No upfront costs, installation fees, or monthly charges
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">Regular Maintenance</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
We stock, service, and maintain all machines at no cost to you
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">Modern Technology</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
Cashless payment options and state-of-the-art equipment
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">Local Support</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
Family-owned business with dedicated local customer service
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="benefits-section-code"
|
||
code={`<div className="text-center mb-12 md:mb-16">
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-4 text-balance">
|
||
Why Choose Us?
|
||
</h2>
|
||
<p className="text-lg text-muted-foreground max-w-2xl mx-auto text-pretty leading-relaxed">
|
||
Description text
|
||
</p>
|
||
</div>
|
||
|
||
<div className="grid gap-6 md:grid-cols-2">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">Feature Title</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
Feature description text
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Prose Content Styling</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Styling for rich text content from CMS or markdown, commonly used for page content.
|
||
</p>
|
||
<div className="mb-6">
|
||
<div className="prose prose-lg max-w-none prose-headings:text-foreground prose-p:text-muted-foreground prose-a:text-foreground prose-a:transition-colors">
|
||
<div className="text-foreground leading-relaxed space-y-6 text-base md:text-lg">
|
||
<p>
|
||
This is a paragraph with proper styling. It uses the prose classes to ensure consistent typography
|
||
throughout the content area. Links will automatically get the hover color treatment.
|
||
</p>
|
||
<h2>This is a Heading 2</h2>
|
||
<p>
|
||
Another paragraph with some <a href="#custom">linked text</a> that will have the proper hover styling.
|
||
</p>
|
||
<ul>
|
||
<li>List item one</li>
|
||
<li>List item two</li>
|
||
<li>List item three</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="prose-content-code"
|
||
code={`<div className="prose prose-lg max-w-none prose-headings:text-foreground prose-p:text-muted-foreground prose-a:text-foreground prose-a:transition-colors">
|
||
<div className="text-foreground leading-relaxed space-y-6 text-base md:text-lg">
|
||
{/* Your content here - can be from CMS, markdown, etc. */}
|
||
<p>Paragraph text</p>
|
||
<h2>Heading</h2>
|
||
<ul>
|
||
<li>List item</li>
|
||
</ul>
|
||
</div>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Product Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom component for displaying products with image, title, description, and price.
|
||
</p>
|
||
<CodeBlock
|
||
id="product-card-code"
|
||
code={`import { ProductCard } from "@/components/product-card"
|
||
|
||
<ProductCard
|
||
id="product-id"
|
||
name="Product Name"
|
||
description="Product description"
|
||
price={29.99}
|
||
image="/product-image.jpg"
|
||
/>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Vending Machine Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom component for displaying vending machine information.
|
||
</p>
|
||
<CodeBlock
|
||
id="vending-machine-card-code"
|
||
code={`import { VendingMachineCard } from "@/components/vending-machine-card"
|
||
|
||
<VendingMachineCard
|
||
name="Machine Name"
|
||
description="Machine description"
|
||
image="/machine-image.jpg"
|
||
/>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Animated Number</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Component that animates numbers when they come into view.
|
||
</p>
|
||
<CodeBlock
|
||
id="animated-number-code"
|
||
code={`import { AnimatedNumber } from "@/components/animated-number"
|
||
|
||
<AnimatedNumber value={100} duration={2000} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Breadcrumbs</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom breadcrumb navigation component.
|
||
</p>
|
||
<CodeBlock
|
||
id="breadcrumbs-custom-code"
|
||
code={`import { Breadcrumbs } from "@/components/breadcrumbs"
|
||
|
||
<Breadcrumbs items={[
|
||
{ label: "Home", href: "/" },
|
||
{ label: "Products", href: "/products" },
|
||
{ label: "Current Page" }
|
||
]} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">FAQ Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom FAQ section component with accordion functionality.
|
||
</p>
|
||
<CodeBlock
|
||
id="faq-section-code"
|
||
code={`import { FAQSection } from "@/components/faq-section"
|
||
|
||
<FAQSection
|
||
faqs={[
|
||
{ question: "Question 1?", answer: "Answer 1" },
|
||
{ question: "Question 2?", answer: "Answer 2" }
|
||
]}
|
||
/>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Header Component</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Main site header with navigation, cart, and mobile menu. Note: Header is already included in the root layout, so it appears at the top of every page.
|
||
</p>
|
||
<CodeBlock
|
||
id="header-code"
|
||
code={`import { Header } from "@/components/header"
|
||
|
||
// Header is typically included in the root layout
|
||
<Header />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Footer Component</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Site footer with links, contact info, and social media. Note: Footer is already included in the root layout, so it appears at the bottom of every page.
|
||
</p>
|
||
<CodeBlock
|
||
id="footer-code"
|
||
code={`import { Footer } from "@/components/footer"
|
||
|
||
// Footer is typically included in the root layout
|
||
<Footer />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Get Free Machine Modal</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Modal dialog for requesting a free vending machine with embedded form.
|
||
</p>
|
||
<CodeBlock
|
||
id="get-free-machine-modal-code"
|
||
code={`import { GetFreeMachineModal } from "@/components/get-free-machine-modal"
|
||
|
||
<GetFreeMachineModal open={isOpen} onOpenChange={setIsOpen} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Cart Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Shopping cart system with cart button, mobile cart button, and cart sheet.
|
||
</p>
|
||
<div className="flex gap-4 mb-6">
|
||
<CartButton onClick={() => {}} />
|
||
<MobileCartButton onClick={() => {}} />
|
||
</div>
|
||
<CodeBlock
|
||
id="cart-components-code"
|
||
code={`import { Cart, CartButton, MobileCartButton } from "@/components/cart"
|
||
|
||
<CartButton onClick={handleCartClick} />
|
||
<MobileCartButton onClick={handleCartClick} />
|
||
<Cart isOpen={isCartOpen} onClose={() => setIsCartOpen(false)} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Product Grid</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Grid layout component for displaying products.
|
||
</p>
|
||
<CodeBlock
|
||
id="product-grid-code"
|
||
code={`import { ProductGrid } from "@/components/product-grid"
|
||
|
||
<ProductGrid products={products} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Vending Machines Showcase</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Showcase component displaying vending machines in a grid.
|
||
</p>
|
||
<div className="mb-6">
|
||
<VendingMachinesShowcase />
|
||
</div>
|
||
<CodeBlock
|
||
id="vending-machines-showcase-code"
|
||
code={`import { VendingMachinesShowcase } from "@/components/vending-machines-showcase"
|
||
|
||
<VendingMachinesShowcase />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Feature Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Reusable card component for displaying features with image, title, and description. Used in a grid layout for multiple features.
|
||
</p>
|
||
<div className="mb-6 grid md:grid-cols-2 gap-6">
|
||
<FeatureCard
|
||
image="https://rockymountainvending.com/wp-content/uploads/2024/01/Parlevel-Pay-Plus-247x300.jpg"
|
||
alt="Parlevel PayPlus credit card reader screen showing options for inserting, swiping, or tapping a card for payment."
|
||
title="Credit Card Readers"
|
||
description="Enhanced Payment Flexibility: Our vending machines are equipped with advanced NAYAX and Parlevel credit card readers, seamlessly integrated with Parlevel's Vending Management System (VMS). These cutting-edge readers use EMV chip technology to enhance transaction security, offering users greater peace of mind."
|
||
imageWidth={247}
|
||
imageHeight={300}
|
||
/>
|
||
<FeatureCard
|
||
image="https://rockymountainvending.com/wp-content/uploads/2024/10/Drop-Sensors-300x225.webp"
|
||
alt="Illustration of a vending machine drop sensor ensuring successful item delivery."
|
||
title="Guaranteed Delivery"
|
||
description="Purchase with Confidence: Our vending machines are equipped with highly sensitive sensors that ensure you receive the item you select. In the rare case that a product isn't dispensed, the machine is designed either to prevent the charge or to issue a prompt refund."
|
||
imageWidth={300}
|
||
imageHeight={225}
|
||
/>
|
||
</div>
|
||
<CodeBlock
|
||
id="feature-card-code"
|
||
code={`import { FeatureCard } from "@/components/feature-card"
|
||
|
||
<div className="grid md:grid-cols-2 gap-6">
|
||
<FeatureCard
|
||
image="/path/to/image.jpg"
|
||
alt="Image description"
|
||
title="Feature Title"
|
||
description="Feature description text here."
|
||
imageWidth={247}
|
||
imageHeight={300}
|
||
/>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Credit Card Reader Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Section component displaying credit card reader information with image and description. Uses FeatureCard internally.
|
||
</p>
|
||
<div className="mb-6">
|
||
<CreditCardReaderSection />
|
||
</div>
|
||
<CodeBlock
|
||
id="credit-card-reader-section-code"
|
||
code={`import { CreditCardReaderSection } from "@/components/credit-card-reader-section"
|
||
|
||
<CreditCardReaderSection />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Manual Viewer</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
PDF manual viewer with parts panel integration.
|
||
</p>
|
||
<CodeBlock
|
||
id="manual-viewer-code"
|
||
code={`import { ManualViewer } from "@/components/manual-viewer"
|
||
|
||
<ManualViewer
|
||
manualUrl="/path/to/manual.pdf"
|
||
filename="manual.pdf"
|
||
isOpen={isOpen}
|
||
onClose={() => setIsOpen(false)}
|
||
/>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Parts Panel</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Panel component for displaying parts related to a manual.
|
||
</p>
|
||
<CodeBlock
|
||
id="parts-panel-code"
|
||
code={`import { PartsPanel } from "@/components/parts-panel"
|
||
|
||
<PartsPanel manualFilename="manual.pdf" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Page Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Reusable page layout components.
|
||
</p>
|
||
<CodeBlock
|
||
id="page-components-code"
|
||
code={`import { AboutPage } from "@/components/about-page"
|
||
import { ContactPage } from "@/components/contact-page"
|
||
import { WhoWeServePage } from "@/components/who-we-serve-page"
|
||
import { RepairsPage } from "@/components/repairs-page"
|
||
import { PageWrapper, PageHeader } from "@/components/page-wrapper"
|
||
|
||
<PageWrapper maxWidth="6xl">
|
||
<PageHeader title="Page Title" subtitle="Subtitle" />
|
||
{/* Content */}
|
||
</PageWrapper>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Author Bio</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Author biography component with schema markup.
|
||
</p>
|
||
<CodeBlock
|
||
id="author-bio-code"
|
||
code={`import { AuthorBio } from "@/components/author-bio"
|
||
|
||
<AuthorBio showSchema={true} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Moving Service Image</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Image component with error handling for moving service pages.
|
||
</p>
|
||
<CodeBlock
|
||
id="moving-service-image-code"
|
||
code={`import { MovingServiceImage } from "@/components/moving-service-image"
|
||
|
||
<MovingServiceImage src="/image.jpg" alt="Description" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Form Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
React Hook Form integration components.
|
||
</p>
|
||
<CodeBlock
|
||
id="form-components-code"
|
||
code={`import { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage } from "@/components/ui/form"
|
||
|
||
<Form {...form}>
|
||
<FormField
|
||
control={form.control}
|
||
name="fieldName"
|
||
render={({ field }) => (
|
||
<FormItem>
|
||
<FormLabel>Label</FormLabel>
|
||
<FormControl>
|
||
<Input {...field} />
|
||
</FormControl>
|
||
<FormDescription>Description</FormDescription>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
</Form>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Field Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Field components for form layouts.
|
||
</p>
|
||
<CodeBlock
|
||
id="field-components-code"
|
||
code={`import { FieldSet, FieldLegend, FieldGroup, Field, FieldLabel, FieldDescription } from "@/components/ui/field"
|
||
|
||
<FieldSet>
|
||
<FieldLegend>Field Group</FieldLegend>
|
||
<FieldGroup>
|
||
<Field>
|
||
<FieldLabel>Label</FieldLabel>
|
||
<FieldDescription>Description</FieldDescription>
|
||
</Field>
|
||
</FieldGroup>
|
||
</FieldSet>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Item Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Item components for lists and menus.
|
||
</p>
|
||
<CodeBlock
|
||
id="item-components-code"
|
||
code={`import { ItemGroup, Item, ItemMedia, ItemContent, ItemTitle, ItemDescription } from "@/components/ui/item"
|
||
|
||
<ItemGroup>
|
||
<Item>
|
||
<ItemMedia variant="icon">
|
||
<Icon />
|
||
</ItemMedia>
|
||
<ItemContent>
|
||
<ItemTitle>Title</ItemTitle>
|
||
<ItemDescription>Description</ItemDescription>
|
||
</ItemContent>
|
||
</Item>
|
||
</ItemGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Input Group</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Input group component for combining inputs with addons and buttons.
|
||
</p>
|
||
<CodeBlock
|
||
id="input-group-code"
|
||
code={`import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupButton } from "@/components/ui/input-group"
|
||
|
||
<InputGroup>
|
||
<InputGroupAddon align="inline-start">$</InputGroupAddon>
|
||
<InputGroupInput placeholder="Amount" />
|
||
<InputGroupButton>Submit</InputGroupButton>
|
||
</InputGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Button Group</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Button group component for grouping related buttons.
|
||
</p>
|
||
<CodeBlock
|
||
id="button-group-code"
|
||
code={`import { ButtonGroup, ButtonGroupText } from "@/components/ui/button-group"
|
||
|
||
<ButtonGroup orientation="horizontal">
|
||
<Button>Left</Button>
|
||
<Button>Center</Button>
|
||
<Button>Right</Button>
|
||
</ButtonGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Sidebar</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Sidebar component for navigation and content organization.
|
||
</p>
|
||
<CodeBlock
|
||
id="sidebar-code"
|
||
code={`import { SidebarProvider, Sidebar, SidebarContent, SidebarHeader, SidebarMenu, SidebarMenuItem, SidebarMenuButton } from "@/components/ui/sidebar"
|
||
|
||
<SidebarProvider>
|
||
<Sidebar>
|
||
<SidebarHeader>Header</SidebarHeader>
|
||
<SidebarContent>
|
||
<SidebarMenu>
|
||
<SidebarMenuItem>
|
||
<SidebarMenuButton>Item</SidebarMenuButton>
|
||
</SidebarMenuItem>
|
||
</SidebarMenu>
|
||
</SidebarContent>
|
||
</Sidebar>
|
||
</SidebarProvider>`}
|
||
/>
|
||
</div>
|
||
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Sonner Toaster</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Toast notifications using Sonner library.
|
||
</p>
|
||
<CodeBlock
|
||
id="sonner-code"
|
||
code={`import { Toaster } from "@/components/ui/sonner"
|
||
import { toast } from "sonner"
|
||
|
||
<Toaster />
|
||
// Usage: toast.success("Success message")`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
{/* Footer Note */}
|
||
<div className="mt-16 pt-8 border-t border-border">
|
||
<p className="text-center text-muted-foreground">
|
||
This style guide is a living document. Components and patterns may be updated over time.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<Toaster />
|
||
</>
|
||
)
|
||
}
|
||
|