Merge pull request #4 from johndoe6345789/copilot/split-large-components

Refactor large components (>150 LOC) into focused, composable modules
This commit is contained in:
2026-01-17 22:25:53 +00:00
committed by GitHub
15 changed files with 1181 additions and 977 deletions

View File

@@ -0,0 +1,64 @@
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog'
import { Plus } from '@phosphor-icons/react'
interface CreateNamespaceDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
namespaceName: string
onNamespaceNameChange: (name: string) => void
onCreateNamespace: () => void
loading: boolean
}
export function CreateNamespaceDialog({
open,
onOpenChange,
namespaceName,
onNamespaceNameChange,
onCreateNamespace,
loading,
}: CreateNamespaceDialogProps) {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogTrigger asChild>
<Button variant="outline" size="icon">
<Plus weight="bold" />
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Create Namespace</DialogTitle>
<DialogDescription>
Create a new namespace to organize your snippets
</DialogDescription>
</DialogHeader>
<div className="space-y-4 py-4">
<Input
placeholder="Namespace name"
value={namespaceName}
onChange={(e) => onNamespaceNameChange(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && onCreateNamespace()}
/>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>
Cancel
</Button>
<Button onClick={onCreateNamespace} disabled={loading}>
Create
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}

View File

@@ -0,0 +1,64 @@
import { Button } from '@/components/ui/button'
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import { Trash } from '@phosphor-icons/react'
import { Namespace } from '@/lib/types'
interface DeleteNamespaceDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
namespace: Namespace | null
onDeleteNamespace: () => void
loading: boolean
showTrigger?: boolean
onOpenDialog?: () => void
}
export function DeleteNamespaceDialog({
open,
onOpenChange,
namespace,
onDeleteNamespace,
loading,
showTrigger = false,
onOpenDialog,
}: DeleteNamespaceDialogProps) {
return (
<>
{showTrigger && (
<Button
variant="outline"
size="icon"
onClick={onOpenDialog}
>
<Trash weight="bold" />
</Button>
)}
<AlertDialog open={open} onOpenChange={onOpenChange}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Delete Namespace</AlertDialogTitle>
<AlertDialogDescription>
Are you sure you want to delete "{namespace?.name}"? All snippets in this namespace will be moved to the default namespace.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={onDeleteNamespace} disabled={loading}>
Delete
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</>
)
}

View File

@@ -1,6 +1,4 @@
import { useState, useEffect } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import {
Select,
SelectContent,
@@ -8,26 +6,7 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog'
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import { Plus, Trash, Folder } from '@phosphor-icons/react'
import { Folder } from '@phosphor-icons/react'
import { toast } from 'sonner'
import { Namespace } from '@/lib/types'
import {
@@ -35,6 +14,8 @@ import {
createNamespace,
deleteNamespace,
} from '@/lib/db'
import { CreateNamespaceDialog } from './CreateNamespaceDialog'
import { DeleteNamespaceDialog } from './DeleteNamespaceDialog'
interface NamespaceSelectorProps {
selectedNamespaceId: string | null
@@ -149,67 +130,29 @@ export function NamespaceSelector({ selectedNamespaceId, onNamespaceChange }: Na
</SelectContent>
</Select>
<Dialog open={createDialogOpen} onOpenChange={setCreateDialogOpen}>
<DialogTrigger asChild>
<Button variant="outline" size="icon">
<Plus weight="bold" />
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Create Namespace</DialogTitle>
<DialogDescription>
Create a new namespace to organize your snippets
</DialogDescription>
</DialogHeader>
<div className="space-y-4 py-4">
<Input
placeholder="Namespace name"
value={newNamespaceName}
onChange={(e) => setNewNamespaceName(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && handleCreateNamespace()}
/>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setCreateDialogOpen(false)}>
Cancel
</Button>
<Button onClick={handleCreateNamespace} disabled={loading}>
Create
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<CreateNamespaceDialog
open={createDialogOpen}
onOpenChange={setCreateDialogOpen}
namespaceName={newNamespaceName}
onNamespaceNameChange={setNewNamespaceName}
onCreateNamespace={handleCreateNamespace}
loading={loading}
/>
{selectedNamespace && !selectedNamespace.isDefault && (
<Button
variant="outline"
size="icon"
onClick={() => {
<DeleteNamespaceDialog
open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen}
namespace={namespaceToDelete}
onDeleteNamespace={handleDeleteNamespace}
loading={loading}
showTrigger
onOpenDialog={() => {
setNamespaceToDelete(selectedNamespace)
setDeleteDialogOpen(true)
}}
>
<Trash weight="bold" />
</Button>
/>
)}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Delete Namespace</AlertDialogTitle>
<AlertDialogDescription>
Are you sure you want to delete "{namespaceToDelete?.name}"? All snippets in this namespace will be moved to the default namespace.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleDeleteNamespace} disabled={loading}>
Delete
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
)
}

View File

@@ -1,481 +1,26 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Badge } from '@/components/ui/badge'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Separator } from '@/components/ui/separator'
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table'
import {
List,
GridFour,
Bell,
Gear,
SignOut,
User,
House,
ChartBar,
Folder,
CheckCircle,
Clock,
XCircle,
ArrowRight,
Envelope,
Lock,
Plus,
} from '@phosphor-icons/react'
import { useState } from 'react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { organismsCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
import { NavigationBarsShowcase } from './showcases/NavigationBarsShowcase'
import { DataTablesShowcase } from './showcases/DataTablesShowcase'
import { FormsShowcase } from './showcases/FormsShowcase'
import { TaskListsShowcase } from './showcases/TaskListsShowcase'
import { ContentGridsShowcase } from './showcases/ContentGridsShowcase'
import { SidebarNavigationShowcase } from './showcases/SidebarNavigationShowcase'
interface OrganismsSectionProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
}
export function OrganismsSection({ onSaveSnippet }: OrganismsSectionProps) {
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid')
return (
<div className="space-y-16">
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Navigation Bars</h2>
<p className="text-muted-foreground">
Complete navigation components with branding and actions
</p>
</div>
<ComponentShowcase
code={organismsCodeSnippets.navigationBar}
title="Navigation Bar"
description="Primary navigation with user menu and notifications"
category="organisms"
onSaveSnippet={onSaveSnippet}
>
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-6">
<h3 className="text-xl font-bold">BrandName</h3>
<nav className="hidden md:flex items-center gap-1">
<Button variant="ghost" size="sm">
<House className="mr-2" />
Home
</Button>
<Button variant="ghost" size="sm">
<ChartBar className="mr-2" />
Analytics
</Button>
<Button variant="ghost" size="sm">
<Folder className="mr-2" />
Projects
</Button>
</nav>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon">
<Bell />
</Button>
<Button variant="ghost" size="icon">
<Gear />
</Button>
<Avatar className="h-8 w-8">
<AvatarImage src="https://i.pravatar.cc/150?img=3" />
<AvatarFallback>U</AvatarFallback>
</Avatar>
</div>
</div>
</div>
<div className="p-6">
<p className="text-sm text-muted-foreground">
Primary navigation with user menu and notifications
</p>
</div>
</Card>
</ComponentShowcase>
<Card className="overflow-hidden">
<div className="border-b border-border bg-card">
<div className="p-4 flex items-center justify-between">
<div className="flex items-center gap-6">
<div className="flex items-center gap-2">
<div className="h-8 w-8 rounded-lg bg-accent" />
<h3 className="text-xl font-bold">Product</h3>
</div>
</div>
<div className="flex items-center gap-2">
<Button variant="outline" size="sm">
Sign In
</Button>
<Button size="sm">Get Started</Button>
</div>
</div>
<nav className="px-4 pb-2 flex items-center gap-1 overflow-x-auto">
<Button variant="ghost" size="sm" className="text-accent">
Features
</Button>
<Button variant="ghost" size="sm">
Pricing
</Button>
<Button variant="ghost" size="sm">
Documentation
</Button>
<Button variant="ghost" size="sm">
Blog
</Button>
</nav>
</div>
<div className="p-6">
<p className="text-sm text-muted-foreground">
Marketing site navigation with CTAs
</p>
</div>
</Card>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Data Tables</h2>
<p className="text-muted-foreground">
Structured data display with actions
</p>
</div>
<Card>
<div className="p-4 border-b border-border">
<div className="flex items-center justify-between">
<h3 className="font-semibold text-lg">Recent Transactions</h3>
<Button variant="outline" size="sm">
Export
</Button>
</div>
</div>
<Table>
<TableHeader>
<TableRow>
<TableHead>Status</TableHead>
<TableHead>Transaction</TableHead>
<TableHead>Date</TableHead>
<TableHead className="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>
<Badge>Completed</Badge>
</TableCell>
<TableCell className="font-medium">Payment received</TableCell>
<TableCell>Mar 15, 2024</TableCell>
<TableCell className="text-right">$250.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Badge variant="secondary">Pending</Badge>
</TableCell>
<TableCell className="font-medium">Processing payment</TableCell>
<TableCell>Mar 14, 2024</TableCell>
<TableCell className="text-right">$150.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Badge>Completed</Badge>
</TableCell>
<TableCell className="font-medium">Refund issued</TableCell>
<TableCell>Mar 13, 2024</TableCell>
<TableCell className="text-right text-destructive">-$75.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Badge variant="destructive">Failed</Badge>
</TableCell>
<TableCell className="font-medium">Payment declined</TableCell>
<TableCell>Mar 12, 2024</TableCell>
<TableCell className="text-right">$0.00</TableCell>
</TableRow>
</TableBody>
</Table>
</Card>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Forms</h2>
<p className="text-muted-foreground">
Complete form layouts with validation and actions
</p>
</div>
<Card className="p-6">
<form className="space-y-6">
<div>
<h3 className="text-xl font-semibold mb-4">Create Account</h3>
<p className="text-sm text-muted-foreground">
Fill in your details to get started
</p>
</div>
<Separator />
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="firstName">First Name</Label>
<Input id="firstName" placeholder="John" />
</div>
<div className="space-y-2">
<Label htmlFor="lastName">Last Name</Label>
<Input id="lastName" placeholder="Doe" />
</div>
</div>
<div className="space-y-2">
<Label htmlFor="formEmail">Email</Label>
<div className="relative">
<Envelope className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input id="formEmail" type="email" placeholder="john@example.com" className="pl-10" />
</div>
</div>
<div className="space-y-2">
<Label htmlFor="formPassword">Password</Label>
<div className="relative">
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input id="formPassword" type="password" placeholder="••••••••" className="pl-10" />
</div>
<p className="text-sm text-muted-foreground">
Must be at least 8 characters
</p>
</div>
<Separator />
<div className="flex items-center justify-between gap-4">
<Button variant="outline" type="button">
Cancel
</Button>
<Button type="submit">
Create Account
<ArrowRight className="ml-2" />
</Button>
</div>
</form>
</Card>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Task Lists</h2>
<p className="text-muted-foreground">
Interactive lists with status and actions
</p>
</div>
<Card>
<div className="p-4 border-b border-border">
<div className="flex items-center justify-between">
<h3 className="font-semibold text-lg">Project Tasks</h3>
<Button size="sm">
<Plus className="mr-2" />
Add Task
</Button>
</div>
</div>
<div className="divide-y divide-border">
<div className="p-4 hover:bg-muted/50 transition-colors">
<div className="flex items-start gap-4">
<CheckCircle weight="fill" className="h-6 w-6 text-accent mt-0.5" />
<div className="flex-1 min-w-0">
<h4 className="font-medium">Design system documentation</h4>
<p className="text-sm text-muted-foreground mt-1">
Complete the component library documentation
</p>
<div className="flex items-center gap-4 mt-3">
<Badge variant="secondary">Design</Badge>
<span className="text-xs text-muted-foreground">Completed</span>
</div>
</div>
</div>
</div>
<div className="p-4 hover:bg-muted/50 transition-colors">
<div className="flex items-start gap-4">
<Clock weight="fill" className="h-6 w-6 text-accent mt-0.5" />
<div className="flex-1 min-w-0">
<h4 className="font-medium">API integration</h4>
<p className="text-sm text-muted-foreground mt-1">
Connect frontend to backend services
</p>
<div className="flex items-center gap-4 mt-3">
<Badge>Development</Badge>
<span className="text-xs text-muted-foreground">In Progress</span>
</div>
</div>
</div>
</div>
<div className="p-4 hover:bg-muted/50 transition-colors">
<div className="flex items-start gap-4">
<XCircle weight="fill" className="h-6 w-6 text-destructive mt-0.5" />
<div className="flex-1 min-w-0">
<h4 className="font-medium">Performance optimization</h4>
<p className="text-sm text-muted-foreground mt-1">
Improve page load times and reduce bundle size
</p>
<div className="flex items-center gap-4 mt-3">
<Badge variant="destructive">Blocked</Badge>
<span className="text-xs text-muted-foreground">Needs review</span>
</div>
</div>
</div>
</div>
</div>
</Card>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Content Grids</h2>
<p className="text-muted-foreground">
Switchable grid and list views with filtering
</p>
</div>
<Card>
<div className="p-4 border-b border-border">
<div className="flex items-center justify-between flex-wrap gap-4">
<h3 className="font-semibold text-lg">Projects</h3>
<div className="flex items-center gap-2">
<Button
variant={viewMode === 'grid' ? 'default' : 'outline'}
size="icon"
onClick={() => setViewMode('grid')}
>
<GridFour />
</Button>
<Button
variant={viewMode === 'list' ? 'default' : 'outline'}
size="icon"
onClick={() => setViewMode('list')}
>
<List />
</Button>
</div>
</div>
</div>
{viewMode === 'grid' ? (
<div className="p-6 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{[1, 2, 3, 4, 5, 6].map((i) => (
<Card key={i} className="p-4 hover:shadow-lg transition-shadow">
<div className="space-y-3">
<div className="h-32 rounded-lg bg-gradient-to-br from-primary to-accent" />
<h4 className="font-semibold">Project {i}</h4>
<p className="text-sm text-muted-foreground line-clamp-2">
A brief description of this project and its goals.
</p>
<div className="flex items-center justify-between pt-2">
<Badge variant="outline">Active</Badge>
<Button variant="ghost" size="sm">
View
</Button>
</div>
</div>
</Card>
))}
</div>
) : (
<div className="divide-y divide-border">
{[1, 2, 3, 4, 5, 6].map((i) => (
<div key={i} className="p-4 hover:bg-muted/50 transition-colors">
<div className="flex items-center gap-4">
<div className="h-16 w-16 rounded-lg bg-gradient-to-br from-primary to-accent flex-shrink-0" />
<div className="flex-1 min-w-0">
<h4 className="font-semibold">Project {i}</h4>
<p className="text-sm text-muted-foreground">
A brief description of this project
</p>
</div>
<Badge variant="outline">Active</Badge>
<Button variant="ghost" size="sm">
View
</Button>
</div>
</div>
))}
</div>
)}
</Card>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Sidebar Navigation</h2>
<p className="text-muted-foreground">
Complete sidebar with nested navigation
</p>
</div>
<Card className="overflow-hidden">
<div className="flex">
<aside className="w-64 border-r border-border bg-card/50 p-4">
<div className="space-y-6">
<div className="flex items-center gap-2 px-2">
<div className="h-8 w-8 rounded-lg bg-accent" />
<span className="font-bold">Dashboard</span>
</div>
<nav className="space-y-1">
<Button variant="ghost" className="w-full justify-start">
<House className="mr-2" />
Home
</Button>
<Button variant="default" className="w-full justify-start">
<ChartBar className="mr-2" />
Analytics
</Button>
<Button variant="ghost" className="w-full justify-start">
<Folder className="mr-2" />
Projects
</Button>
<Button variant="ghost" className="w-full justify-start">
<User className="mr-2" />
Team
</Button>
</nav>
<Separator />
<nav className="space-y-1">
<Button variant="ghost" className="w-full justify-start">
<Gear className="mr-2" />
Settings
</Button>
<Button variant="ghost" className="w-full justify-start text-destructive">
<SignOut className="mr-2" />
Sign Out
</Button>
</nav>
</div>
</aside>
<div className="flex-1 p-6">
<p className="text-sm text-muted-foreground">
Sidebar with navigation items and user actions
</p>
</div>
</div>
</Card>
</section>
<NavigationBarsShowcase onSaveSnippet={onSaveSnippet} />
<DataTablesShowcase />
<FormsShowcase />
<TaskListsShowcase />
<ContentGridsShowcase />
<SidebarNavigationShowcase />
</div>
)
}

View File

@@ -0,0 +1,89 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import {
List,
GridFour,
} from '@phosphor-icons/react'
import { useState } from 'react'
export function ContentGridsShowcase() {
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid')
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Content Grids</h2>
<p className="text-muted-foreground">
Switchable grid and list views with filtering
</p>
</div>
<Card>
<div className="p-4 border-b border-border">
<div className="flex items-center justify-between flex-wrap gap-4">
<h3 className="font-semibold text-lg">Projects</h3>
<div className="flex items-center gap-2">
<Button
variant={viewMode === 'grid' ? 'default' : 'outline'}
size="icon"
onClick={() => setViewMode('grid')}
>
<GridFour />
</Button>
<Button
variant={viewMode === 'list' ? 'default' : 'outline'}
size="icon"
onClick={() => setViewMode('list')}
>
<List />
</Button>
</div>
</div>
</div>
{viewMode === 'grid' ? (
<div className="p-6 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{[1, 2, 3, 4, 5, 6].map((i) => (
<Card key={i} className="p-4 hover:shadow-lg transition-shadow">
<div className="space-y-3">
<div className="h-32 rounded-lg bg-gradient-to-br from-primary to-accent" />
<h4 className="font-semibold">Project {i}</h4>
<p className="text-sm text-muted-foreground line-clamp-2">
A brief description of this project and its goals.
</p>
<div className="flex items-center justify-between pt-2">
<Badge variant="outline">Active</Badge>
<Button variant="ghost" size="sm">
View
</Button>
</div>
</div>
</Card>
))}
</div>
) : (
<div className="divide-y divide-border">
{[1, 2, 3, 4, 5, 6].map((i) => (
<div key={i} className="p-4 hover:bg-muted/50 transition-colors">
<div className="flex items-center gap-4">
<div className="h-16 w-16 rounded-lg bg-gradient-to-br from-primary to-accent flex-shrink-0" />
<div className="flex-1 min-w-0">
<h4 className="font-semibold">Project {i}</h4>
<p className="text-sm text-muted-foreground">
A brief description of this project
</p>
</div>
<Badge variant="outline">Active</Badge>
<Button variant="ghost" size="sm">
View
</Button>
</div>
</div>
))}
</div>
)}
</Card>
</section>
)
}

View File

@@ -0,0 +1,79 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table'
export function DataTablesShowcase() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Data Tables</h2>
<p className="text-muted-foreground">
Structured data display with actions
</p>
</div>
<Card>
<div className="p-4 border-b border-border">
<div className="flex items-center justify-between">
<h3 className="font-semibold text-lg">Recent Transactions</h3>
<Button variant="outline" size="sm">
Export
</Button>
</div>
</div>
<Table>
<TableHeader>
<TableRow>
<TableHead>Status</TableHead>
<TableHead>Transaction</TableHead>
<TableHead>Date</TableHead>
<TableHead className="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>
<Badge>Completed</Badge>
</TableCell>
<TableCell className="font-medium">Payment received</TableCell>
<TableCell>Mar 15, 2024</TableCell>
<TableCell className="text-right">$250.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Badge variant="secondary">Pending</Badge>
</TableCell>
<TableCell className="font-medium">Processing payment</TableCell>
<TableCell>Mar 14, 2024</TableCell>
<TableCell className="text-right">$150.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Badge>Completed</Badge>
</TableCell>
<TableCell className="font-medium">Refund issued</TableCell>
<TableCell>Mar 13, 2024</TableCell>
<TableCell className="text-right text-destructive">-$75.00</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Badge variant="destructive">Failed</Badge>
</TableCell>
<TableCell className="font-medium">Payment declined</TableCell>
<TableCell>Mar 12, 2024</TableCell>
<TableCell className="text-right">$0.00</TableCell>
</TableRow>
</TableBody>
</Table>
</Card>
</section>
)
}

View File

@@ -0,0 +1,78 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Separator } from '@/components/ui/separator'
import {
Envelope,
Lock,
ArrowRight,
} from '@phosphor-icons/react'
export function FormsShowcase() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Forms</h2>
<p className="text-muted-foreground">
Complete form layouts with validation and actions
</p>
</div>
<Card className="p-6">
<form className="space-y-6">
<div>
<h3 className="text-xl font-semibold mb-4">Create Account</h3>
<p className="text-sm text-muted-foreground">
Fill in your details to get started
</p>
</div>
<Separator />
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="firstName">First Name</Label>
<Input id="firstName" placeholder="John" />
</div>
<div className="space-y-2">
<Label htmlFor="lastName">Last Name</Label>
<Input id="lastName" placeholder="Doe" />
</div>
</div>
<div className="space-y-2">
<Label htmlFor="formEmail">Email</Label>
<div className="relative">
<Envelope className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input id="formEmail" type="email" placeholder="john@example.com" className="pl-10" />
</div>
</div>
<div className="space-y-2">
<Label htmlFor="formPassword">Password</Label>
<div className="relative">
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input id="formPassword" type="password" placeholder="••••••••" className="pl-10" />
</div>
<p className="text-sm text-muted-foreground">
Must be at least 8 characters
</p>
</div>
<Separator />
<div className="flex items-center justify-between gap-4">
<Button variant="outline" type="button">
Cancel
</Button>
<Button type="submit">
Create Account
<ArrowRight className="ml-2" />
</Button>
</div>
</form>
</Card>
</section>
)
}

View File

@@ -0,0 +1,119 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import {
Bell,
Gear,
House,
ChartBar,
Folder,
} from '@phosphor-icons/react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { organismsCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
interface NavigationBarsShowcaseProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
}
export function NavigationBarsShowcase({ onSaveSnippet }: NavigationBarsShowcaseProps) {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Navigation Bars</h2>
<p className="text-muted-foreground">
Complete navigation components with branding and actions
</p>
</div>
<ComponentShowcase
code={organismsCodeSnippets.navigationBar}
title="Navigation Bar"
description="Primary navigation with user menu and notifications"
category="organisms"
onSaveSnippet={onSaveSnippet}
>
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-6">
<h3 className="text-xl font-bold">BrandName</h3>
<nav className="hidden md:flex items-center gap-1">
<Button variant="ghost" size="sm">
<House className="mr-2" />
Home
</Button>
<Button variant="ghost" size="sm">
<ChartBar className="mr-2" />
Analytics
</Button>
<Button variant="ghost" size="sm">
<Folder className="mr-2" />
Projects
</Button>
</nav>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon">
<Bell />
</Button>
<Button variant="ghost" size="icon">
<Gear />
</Button>
<Avatar className="h-8 w-8">
<AvatarImage src="https://i.pravatar.cc/150?img=3" />
<AvatarFallback>U</AvatarFallback>
</Avatar>
</div>
</div>
</div>
<div className="p-6">
<p className="text-sm text-muted-foreground">
Primary navigation with user menu and notifications
</p>
</div>
</Card>
</ComponentShowcase>
<Card className="overflow-hidden">
<div className="border-b border-border bg-card">
<div className="p-4 flex items-center justify-between">
<div className="flex items-center gap-6">
<div className="flex items-center gap-2">
<div className="h-8 w-8 rounded-lg bg-accent" />
<h3 className="text-xl font-bold">Product</h3>
</div>
</div>
<div className="flex items-center gap-2">
<Button variant="outline" size="sm">
Sign In
</Button>
<Button size="sm">Get Started</Button>
</div>
</div>
<nav className="px-4 pb-2 flex items-center gap-1 overflow-x-auto">
<Button variant="ghost" size="sm" className="text-accent">
Features
</Button>
<Button variant="ghost" size="sm">
Pricing
</Button>
<Button variant="ghost" size="sm">
Documentation
</Button>
<Button variant="ghost" size="sm">
Blog
</Button>
</nav>
</div>
<div className="p-6">
<p className="text-sm text-muted-foreground">
Marketing site navigation with CTAs
</p>
</div>
</Card>
</section>
)
}

View File

@@ -0,0 +1,75 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Separator } from '@/components/ui/separator'
import {
Gear,
SignOut,
User,
House,
ChartBar,
Folder,
} from '@phosphor-icons/react'
export function SidebarNavigationShowcase() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Sidebar Navigation</h2>
<p className="text-muted-foreground">
Complete sidebar with nested navigation
</p>
</div>
<Card className="overflow-hidden">
<div className="flex">
<aside className="w-64 border-r border-border bg-card/50 p-4">
<div className="space-y-6">
<div className="flex items-center gap-2 px-2">
<div className="h-8 w-8 rounded-lg bg-accent" />
<span className="font-bold">Dashboard</span>
</div>
<nav className="space-y-1">
<Button variant="ghost" className="w-full justify-start">
<House className="mr-2" />
Home
</Button>
<Button variant="default" className="w-full justify-start">
<ChartBar className="mr-2" />
Analytics
</Button>
<Button variant="ghost" className="w-full justify-start">
<Folder className="mr-2" />
Projects
</Button>
<Button variant="ghost" className="w-full justify-start">
<User className="mr-2" />
Team
</Button>
</nav>
<Separator />
<nav className="space-y-1">
<Button variant="ghost" className="w-full justify-start">
<Gear className="mr-2" />
Settings
</Button>
<Button variant="ghost" className="w-full justify-start text-destructive">
<SignOut className="mr-2" />
Sign Out
</Button>
</nav>
</div>
</aside>
<div className="flex-1 p-6">
<p className="text-sm text-muted-foreground">
Sidebar with navigation items and user actions
</p>
</div>
</div>
</Card>
</section>
)
}

View File

@@ -0,0 +1,84 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import {
CheckCircle,
Clock,
XCircle,
Plus,
} from '@phosphor-icons/react'
export function TaskListsShowcase() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Task Lists</h2>
<p className="text-muted-foreground">
Interactive lists with status and actions
</p>
</div>
<Card>
<div className="p-4 border-b border-border">
<div className="flex items-center justify-between">
<h3 className="font-semibold text-lg">Project Tasks</h3>
<Button size="sm">
<Plus className="mr-2" />
Add Task
</Button>
</div>
</div>
<div className="divide-y divide-border">
<div className="p-4 hover:bg-muted/50 transition-colors">
<div className="flex items-start gap-4">
<CheckCircle weight="fill" className="h-6 w-6 text-accent mt-0.5" />
<div className="flex-1 min-w-0">
<h4 className="font-medium">Design system documentation</h4>
<p className="text-sm text-muted-foreground mt-1">
Complete the component library documentation
</p>
<div className="flex items-center gap-4 mt-3">
<Badge variant="secondary">Design</Badge>
<span className="text-xs text-muted-foreground">Completed</span>
</div>
</div>
</div>
</div>
<div className="p-4 hover:bg-muted/50 transition-colors">
<div className="flex items-start gap-4">
<Clock weight="fill" className="h-6 w-6 text-accent mt-0.5" />
<div className="flex-1 min-w-0">
<h4 className="font-medium">API integration</h4>
<p className="text-sm text-muted-foreground mt-1">
Connect frontend to backend services
</p>
<div className="flex items-center gap-4 mt-3">
<Badge>Development</Badge>
<span className="text-xs text-muted-foreground">In Progress</span>
</div>
</div>
</div>
</div>
<div className="p-4 hover:bg-muted/50 transition-colors">
<div className="flex items-start gap-4">
<XCircle weight="fill" className="h-6 w-6 text-destructive mt-0.5" />
<div className="flex-1 min-w-0">
<h4 className="font-medium">Performance optimization</h4>
<p className="text-sm text-muted-foreground mt-1">
Improve page load times and reduce bundle size
</p>
<div className="flex items-center gap-4 mt-3">
<Badge variant="destructive">Blocked</Badge>
<span className="text-xs text-muted-foreground">Needs review</span>
</div>
</div>
</div>
</div>
</div>
</Card>
</section>
)
}

View File

@@ -0,0 +1,102 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Separator } from '@/components/ui/separator'
import { ArrowRight } from '@phosphor-icons/react'
export function BlogTemplate() {
return (
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<h3 className="text-xl font-bold">Blog</h3>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm">
Articles
</Button>
<Button variant="ghost" size="sm">
Tutorials
</Button>
<Button variant="ghost" size="sm">
About
</Button>
</div>
</div>
</div>
<div className="p-8">
<div className="max-w-4xl mx-auto">
<div className="space-y-6 mb-8">
<div className="flex gap-2">
<Badge>Design</Badge>
<Badge variant="secondary">Tutorial</Badge>
</div>
<h1 className="text-5xl font-bold">
Building a Comprehensive Component Library
</h1>
<div className="flex items-center gap-4">
<Avatar className="h-12 w-12">
<AvatarImage src="https://i.pravatar.cc/150?img=5" />
<AvatarFallback>AW</AvatarFallback>
</Avatar>
<div>
<p className="font-medium">Alex Writer</p>
<p className="text-sm text-muted-foreground">
March 15, 2024 · 10 min read
</p>
</div>
</div>
</div>
<Separator className="my-8" />
<div className="prose prose-invert max-w-none space-y-6">
<div className="aspect-video rounded-lg bg-gradient-to-br from-primary to-accent" />
<p className="text-lg text-muted-foreground leading-relaxed">
Design systems have become an essential part of modern product development.
They provide consistency, improve efficiency, and create a shared language
between designers and developers.
</p>
<h2 className="text-3xl font-bold mt-12 mb-4">
Understanding Atomic Design
</h2>
<p className="text-muted-foreground leading-relaxed">
The atomic design methodology consists of five distinct stages: atoms,
molecules, organisms, templates, and pages. Each stage builds upon the
previous, creating a comprehensive system that scales with your needs.
</p>
<Card className="p-6 my-8 bg-muted/50">
<p className="text-sm text-muted-foreground italic">
"A design system is never complete. It's a living, breathing ecosystem
that evolves with your product and team."
</p>
</Card>
<h2 className="text-3xl font-bold mt-12 mb-4">Getting Started</h2>
<p className="text-muted-foreground leading-relaxed">
Begin by identifying the core components your product needs. Start small
with basic atoms like buttons and inputs, then gradually build up to more
complex organisms and templates.
</p>
</div>
<Separator className="my-12" />
<div className="flex items-center justify-between">
<Button variant="outline">
Previous Article
</Button>
<Button>
Next Article
<ArrowRight className="ml-2" />
</Button>
</div>
</div>
</div>
</Card>
)
}

View File

@@ -0,0 +1,165 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import {
Bell,
Gear,
House,
ChartBar,
Folder,
Plus,
TrendUp,
Users,
} from '@phosphor-icons/react'
export function DashboardTemplate() {
return (
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-6">
<h3 className="text-xl font-bold">Dashboard</h3>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon">
<Bell />
</Button>
<Button variant="ghost" size="icon">
<Gear />
</Button>
<Avatar className="h-8 w-8">
<AvatarImage src="https://i.pravatar.cc/150?img=4" />
<AvatarFallback>U</AvatarFallback>
</Avatar>
</div>
</div>
</div>
<div className="flex">
<aside className="w-64 border-r border-border bg-card/30 p-4 hidden lg:block">
<nav className="space-y-1">
<Button variant="default" className="w-full justify-start">
<House className="mr-2" />
Overview
</Button>
<Button variant="ghost" className="w-full justify-start">
<ChartBar className="mr-2" />
Analytics
</Button>
<Button variant="ghost" className="w-full justify-start">
<Folder className="mr-2" />
Projects
</Button>
<Button variant="ghost" className="w-full justify-start">
<Users className="mr-2" />
Team
</Button>
</nav>
</aside>
<main className="flex-1 p-6">
<div className="space-y-6">
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold">Overview</h1>
<p className="text-muted-foreground">
Welcome back, here's what's happening
</p>
</div>
<Button>
<Plus className="mr-2" />
New Project
</Button>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card className="p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-muted-foreground">Total Revenue</p>
<p className="text-3xl font-bold mt-2">$45,231</p>
<p className="text-sm text-accent mt-2 flex items-center gap-1">
<TrendUp className="h-4 w-4" />
+20.1% from last month
</p>
</div>
</div>
</Card>
<Card className="p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-muted-foreground">Active Users</p>
<p className="text-3xl font-bold mt-2">2,350</p>
<p className="text-sm text-accent mt-2 flex items-center gap-1">
<TrendUp className="h-4 w-4" />
+12.5% from last month
</p>
</div>
</div>
</Card>
<Card className="p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-muted-foreground">Total Orders</p>
<p className="text-3xl font-bold mt-2">1,234</p>
<p className="text-sm text-accent mt-2 flex items-center gap-1">
<TrendUp className="h-4 w-4" />
+8.2% from last month
</p>
</div>
</div>
</Card>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<Card>
<div className="p-4 border-b border-border">
<h3 className="font-semibold">Recent Activity</h3>
</div>
<div className="p-4 space-y-4">
{[1, 2, 3].map((i) => (
<div key={i} className="flex items-start gap-3">
<Avatar className="h-8 w-8">
<AvatarImage src={`https://i.pravatar.cc/150?img=${i + 10}`} />
<AvatarFallback>U</AvatarFallback>
</Avatar>
<div className="flex-1">
<p className="text-sm">
<span className="font-medium">User {i}</span> completed a task
</p>
<p className="text-xs text-muted-foreground">2 hours ago</p>
</div>
</div>
))}
</div>
</Card>
<Card>
<div className="p-4 border-b border-border">
<h3 className="font-semibold">Quick Actions</h3>
</div>
<div className="p-4 space-y-3">
<Button className="w-full justify-start" variant="outline">
<Plus className="mr-2" />
Create New Project
</Button>
<Button className="w-full justify-start" variant="outline">
<Users className="mr-2" />
Invite Team Members
</Button>
<Button className="w-full justify-start" variant="outline">
<Folder className="mr-2" />
Browse Templates
</Button>
</div>
</Card>
</div>
</div>
</main>
</div>
</Card>
)
}

View File

@@ -0,0 +1,97 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Badge } from '@/components/ui/badge'
import { Avatar, AvatarFallback } from '@/components/ui/avatar'
import { Separator } from '@/components/ui/separator'
import {
MagnifyingGlass,
ShoppingCart,
} from '@phosphor-icons/react'
export function EcommerceTemplate() {
return (
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-6">
<h3 className="text-xl font-bold">Store</h3>
<div className="relative hidden md:block">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search products..." className="pl-10 w-80" />
</div>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon">
<ShoppingCart />
</Button>
<Avatar className="h-8 w-8">
<AvatarFallback>U</AvatarFallback>
</Avatar>
</div>
</div>
</div>
<div className="p-8">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
<div className="space-y-4">
<div className="aspect-square rounded-lg bg-gradient-to-br from-primary to-accent" />
<div className="grid grid-cols-4 gap-2">
{[1, 2, 3, 4].map((i) => (
<div
key={i}
className="aspect-square rounded-lg bg-gradient-to-br from-primary/50 to-accent/50"
/>
))}
</div>
</div>
<div className="space-y-6">
<div>
<Badge className="mb-3">New Arrival</Badge>
<h1 className="text-4xl font-bold mb-2">Premium Product Name</h1>
<div className="flex items-baseline gap-3">
<span className="text-3xl font-bold">$299.00</span>
<span className="text-lg text-muted-foreground line-through">
$399.00
</span>
</div>
</div>
<Separator />
<div>
<h3 className="font-semibold mb-2">Description</h3>
<p className="text-muted-foreground">
Experience premium quality with this exceptional product. Crafted with
attention to detail and designed for those who demand excellence.
</p>
</div>
<div>
<h3 className="font-semibold mb-2">Features</h3>
<ul className="space-y-2 text-muted-foreground">
<li> Premium materials and construction</li>
<li> Industry-leading performance</li>
<li> 2-year warranty included</li>
<li> Free shipping on orders over $50</li>
</ul>
</div>
<Separator />
<div className="space-y-4">
<Button size="lg" className="w-full">
<ShoppingCart className="mr-2" />
Add to Cart
</Button>
<Button size="lg" variant="outline" className="w-full">
Add to Wishlist
</Button>
</div>
</div>
</div>
</div>
</Card>
)
}

View File

@@ -0,0 +1,108 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import {
ChartBar,
Users,
Gear,
ArrowRight,
} from '@phosphor-icons/react'
export function LandingPageTemplate() {
return (
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="h-8 w-8 rounded-lg bg-accent" />
<h3 className="text-xl font-bold">ProductName</h3>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm">
Features
</Button>
<Button variant="ghost" size="sm">
Pricing
</Button>
<Button variant="ghost" size="sm">
About
</Button>
<Button size="sm">Sign Up</Button>
</div>
</div>
</div>
<div className="p-12 text-center bg-gradient-to-br from-primary/20 to-accent/20">
<Badge className="mb-4">New Release</Badge>
<h1 className="text-5xl font-bold mb-6">
Build Amazing Products Faster
</h1>
<p className="text-xl text-muted-foreground mb-8 max-w-2xl mx-auto">
The complete toolkit for modern product development. Ship faster with our
component library and design system.
</p>
<div className="flex items-center justify-center gap-4">
<Button size="lg">
Get Started
<ArrowRight className="ml-2" />
</Button>
<Button size="lg" variant="outline">
View Demo
</Button>
</div>
</div>
<div className="p-12">
<div className="text-center mb-12">
<h2 className="text-3xl font-bold mb-4">Features</h2>
<p className="text-muted-foreground max-w-2xl mx-auto">
Everything you need to build production-ready applications
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
<Card className="p-6">
<div className="h-12 w-12 rounded-lg bg-accent/20 flex items-center justify-center mb-4">
<ChartBar className="h-6 w-6 text-accent" />
</div>
<h3 className="font-semibold text-lg mb-2">Analytics</h3>
<p className="text-sm text-muted-foreground">
Track and analyze your product metrics in real-time
</p>
</Card>
<Card className="p-6">
<div className="h-12 w-12 rounded-lg bg-accent/20 flex items-center justify-center mb-4">
<Users className="h-6 w-6 text-accent" />
</div>
<h3 className="font-semibold text-lg mb-2">Collaboration</h3>
<p className="text-sm text-muted-foreground">
Work together with your team seamlessly
</p>
</Card>
<Card className="p-6">
<div className="h-12 w-12 rounded-lg bg-accent/20 flex items-center justify-center mb-4">
<Gear className="h-6 w-6 text-accent" />
</div>
<h3 className="font-semibold text-lg mb-2">Customizable</h3>
<p className="text-sm text-muted-foreground">
Adapt the platform to your specific needs
</p>
</Card>
</div>
</div>
<div className="p-12 text-center bg-gradient-to-br from-primary to-accent text-primary-foreground">
<h2 className="text-4xl font-bold mb-4">Ready to get started?</h2>
<p className="text-xl mb-8 opacity-90">
Join thousands of teams already building with our platform
</p>
<Button size="lg" variant="secondary">
Start Free Trial
<ArrowRight className="ml-2" />
</Button>
</div>
</Card>
)
}

View File

@@ -1,25 +1,10 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Badge } from '@/components/ui/badge'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Separator } from '@/components/ui/separator'
import {
Bell,
Gear,
House,
ChartBar,
Folder,
MagnifyingGlass,
Plus,
ArrowRight,
TrendUp,
Users,
ShoppingCart,
} from '@phosphor-icons/react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { templatesCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
import { DashboardTemplate } from './DashboardTemplate'
import { LandingPageTemplate } from './LandingPageTemplate'
import { EcommerceTemplate } from './EcommerceTemplate'
import { BlogTemplate } from './BlogTemplate'
interface TemplatesSectionProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
@@ -43,153 +28,8 @@ export function TemplatesSection({ onSaveSnippet }: TemplatesSectionProps) {
category="templates"
onSaveSnippet={onSaveSnippet}
>
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-6">
<h3 className="text-xl font-bold">Dashboard</h3>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon">
<Bell />
</Button>
<Button variant="ghost" size="icon">
<Gear />
</Button>
<Avatar className="h-8 w-8">
<AvatarImage src="https://i.pravatar.cc/150?img=4" />
<AvatarFallback>U</AvatarFallback>
</Avatar>
</div>
</div>
</div>
<div className="flex">
<aside className="w-64 border-r border-border bg-card/30 p-4 hidden lg:block">
<nav className="space-y-1">
<Button variant="default" className="w-full justify-start">
<House className="mr-2" />
Overview
</Button>
<Button variant="ghost" className="w-full justify-start">
<ChartBar className="mr-2" />
Analytics
</Button>
<Button variant="ghost" className="w-full justify-start">
<Folder className="mr-2" />
Projects
</Button>
<Button variant="ghost" className="w-full justify-start">
<Users className="mr-2" />
Team
</Button>
</nav>
</aside>
<main className="flex-1 p-6">
<div className="space-y-6">
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold">Overview</h1>
<p className="text-muted-foreground">
Welcome back, here's what's happening
</p>
</div>
<Button>
<Plus className="mr-2" />
New Project
</Button>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card className="p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-muted-foreground">Total Revenue</p>
<p className="text-3xl font-bold mt-2">$45,231</p>
<p className="text-sm text-accent mt-2 flex items-center gap-1">
<TrendUp className="h-4 w-4" />
+20.1% from last month
</p>
</div>
</div>
</Card>
<Card className="p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-muted-foreground">Active Users</p>
<p className="text-3xl font-bold mt-2">2,350</p>
<p className="text-sm text-accent mt-2 flex items-center gap-1">
<TrendUp className="h-4 w-4" />
+12.5% from last month
</p>
</div>
</div>
</Card>
<Card className="p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-muted-foreground">Total Orders</p>
<p className="text-3xl font-bold mt-2">1,234</p>
<p className="text-sm text-accent mt-2 flex items-center gap-1">
<TrendUp className="h-4 w-4" />
+8.2% from last month
</p>
</div>
</div>
</Card>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<Card>
<div className="p-4 border-b border-border">
<h3 className="font-semibold">Recent Activity</h3>
</div>
<div className="p-4 space-y-4">
{[1, 2, 3].map((i) => (
<div key={i} className="flex items-start gap-3">
<Avatar className="h-8 w-8">
<AvatarImage src={`https://i.pravatar.cc/150?img=${i + 10}`} />
<AvatarFallback>U</AvatarFallback>
</Avatar>
<div className="flex-1">
<p className="text-sm">
<span className="font-medium">User {i}</span> completed a task
</p>
<p className="text-xs text-muted-foreground">2 hours ago</p>
</div>
</div>
))}
</div>
</Card>
<Card>
<div className="p-4 border-b border-border">
<h3 className="font-semibold">Quick Actions</h3>
</div>
<div className="p-4 space-y-3">
<Button className="w-full justify-start" variant="outline">
<Plus className="mr-2" />
Create New Project
</Button>
<Button className="w-full justify-start" variant="outline">
<Users className="mr-2" />
Invite Team Members
</Button>
<Button className="w-full justify-start" variant="outline">
<Folder className="mr-2" />
Browse Templates
</Button>
</div>
</Card>
</div>
</div>
</main>
</div>
</Card>
</ComponentShowcase>
<DashboardTemplate />
</ComponentShowcase>
</section>
<section className="space-y-6">
@@ -207,100 +47,7 @@ export function TemplatesSection({ onSaveSnippet }: TemplatesSectionProps) {
category="templates"
onSaveSnippet={onSaveSnippet}
>
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="h-8 w-8 rounded-lg bg-accent" />
<h3 className="text-xl font-bold">ProductName</h3>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm">
Features
</Button>
<Button variant="ghost" size="sm">
Pricing
</Button>
<Button variant="ghost" size="sm">
About
</Button>
<Button size="sm">Sign Up</Button>
</div>
</div>
</div>
<div className="p-12 text-center bg-gradient-to-br from-primary/20 to-accent/20">
<Badge className="mb-4">New Release</Badge>
<h1 className="text-5xl font-bold mb-6">
Build Amazing Products Faster
</h1>
<p className="text-xl text-muted-foreground mb-8 max-w-2xl mx-auto">
The complete toolkit for modern product development. Ship faster with our
component library and design system.
</p>
<div className="flex items-center justify-center gap-4">
<Button size="lg">
Get Started
<ArrowRight className="ml-2" />
</Button>
<Button size="lg" variant="outline">
View Demo
</Button>
</div>
</div>
<div className="p-12">
<div className="text-center mb-12">
<h2 className="text-3xl font-bold mb-4">Features</h2>
<p className="text-muted-foreground max-w-2xl mx-auto">
Everything you need to build production-ready applications
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
<Card className="p-6">
<div className="h-12 w-12 rounded-lg bg-accent/20 flex items-center justify-center mb-4">
<ChartBar className="h-6 w-6 text-accent" />
</div>
<h3 className="font-semibold text-lg mb-2">Analytics</h3>
<p className="text-sm text-muted-foreground">
Track and analyze your product metrics in real-time
</p>
</Card>
<Card className="p-6">
<div className="h-12 w-12 rounded-lg bg-accent/20 flex items-center justify-center mb-4">
<Users className="h-6 w-6 text-accent" />
</div>
<h3 className="font-semibold text-lg mb-2">Collaboration</h3>
<p className="text-sm text-muted-foreground">
Work together with your team seamlessly
</p>
</Card>
<Card className="p-6">
<div className="h-12 w-12 rounded-lg bg-accent/20 flex items-center justify-center mb-4">
<Gear className="h-6 w-6 text-accent" />
</div>
<h3 className="font-semibold text-lg mb-2">Customizable</h3>
<p className="text-sm text-muted-foreground">
Adapt the platform to your specific needs
</p>
</Card>
</div>
</div>
<div className="p-12 text-center bg-gradient-to-br from-primary to-accent text-primary-foreground">
<h2 className="text-4xl font-bold mb-4">Ready to get started?</h2>
<p className="text-xl mb-8 opacity-90">
Join thousands of teams already building with our platform
</p>
<Button size="lg" variant="secondary">
Start Free Trial
<ArrowRight className="ml-2" />
</Button>
</div>
</Card>
<LandingPageTemplate />
</ComponentShowcase>
</section>
@@ -312,88 +59,15 @@ export function TemplatesSection({ onSaveSnippet }: TemplatesSectionProps) {
</p>
</div>
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-6">
<h3 className="text-xl font-bold">Store</h3>
<div className="relative hidden md:block">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search products..." className="pl-10 w-80" />
</div>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon">
<ShoppingCart />
</Button>
<Avatar className="h-8 w-8">
<AvatarFallback>U</AvatarFallback>
</Avatar>
</div>
</div>
</div>
<div className="p-8">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
<div className="space-y-4">
<div className="aspect-square rounded-lg bg-gradient-to-br from-primary to-accent" />
<div className="grid grid-cols-4 gap-2">
{[1, 2, 3, 4].map((i) => (
<div
key={i}
className="aspect-square rounded-lg bg-gradient-to-br from-primary/50 to-accent/50"
/>
))}
</div>
</div>
<div className="space-y-6">
<div>
<Badge className="mb-3">New Arrival</Badge>
<h1 className="text-4xl font-bold mb-2">Premium Product Name</h1>
<div className="flex items-baseline gap-3">
<span className="text-3xl font-bold">$299.00</span>
<span className="text-lg text-muted-foreground line-through">
$399.00
</span>
</div>
</div>
<Separator />
<div>
<h3 className="font-semibold mb-2">Description</h3>
<p className="text-muted-foreground">
Experience premium quality with this exceptional product. Crafted with
attention to detail and designed for those who demand excellence.
</p>
</div>
<div>
<h3 className="font-semibold mb-2">Features</h3>
<ul className="space-y-2 text-muted-foreground">
<li> Premium materials and construction</li>
<li> Industry-leading performance</li>
<li> 2-year warranty included</li>
<li> Free shipping on orders over $50</li>
</ul>
</div>
<Separator />
<div className="space-y-4">
<Button size="lg" className="w-full">
<ShoppingCart className="mr-2" />
Add to Cart
</Button>
<Button size="lg" variant="outline" className="w-full">
Add to Wishlist
</Button>
</div>
</div>
</div>
</div>
</Card>
<ComponentShowcase
code={templatesCodeSnippets.ecommercePage}
title="E-commerce Product Page"
description="Product page with images, details, and purchase options"
category="templates"
onSaveSnippet={onSaveSnippet}
>
<EcommerceTemplate />
</ComponentShowcase>
</section>
<section className="space-y-6">
@@ -404,97 +78,15 @@ export function TemplatesSection({ onSaveSnippet }: TemplatesSectionProps) {
</p>
</div>
<Card className="overflow-hidden">
<div className="border-b border-border bg-card p-4">
<div className="flex items-center justify-between">
<h3 className="text-xl font-bold">Blog</h3>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm">
Articles
</Button>
<Button variant="ghost" size="sm">
Tutorials
</Button>
<Button variant="ghost" size="sm">
About
</Button>
</div>
</div>
</div>
<div className="p-8">
<div className="max-w-4xl mx-auto">
<div className="space-y-6 mb-8">
<div className="flex gap-2">
<Badge>Design</Badge>
<Badge variant="secondary">Tutorial</Badge>
</div>
<h1 className="text-5xl font-bold">
Building a Comprehensive Component Library
</h1>
<div className="flex items-center gap-4">
<Avatar className="h-12 w-12">
<AvatarImage src="https://i.pravatar.cc/150?img=5" />
<AvatarFallback>AW</AvatarFallback>
</Avatar>
<div>
<p className="font-medium">Alex Writer</p>
<p className="text-sm text-muted-foreground">
March 15, 2024 · 10 min read
</p>
</div>
</div>
</div>
<Separator className="my-8" />
<div className="prose prose-invert max-w-none space-y-6">
<div className="aspect-video rounded-lg bg-gradient-to-br from-primary to-accent" />
<p className="text-lg text-muted-foreground leading-relaxed">
Design systems have become an essential part of modern product development.
They provide consistency, improve efficiency, and create a shared language
between designers and developers.
</p>
<h2 className="text-3xl font-bold mt-12 mb-4">
Understanding Atomic Design
</h2>
<p className="text-muted-foreground leading-relaxed">
The atomic design methodology consists of five distinct stages: atoms,
molecules, organisms, templates, and pages. Each stage builds upon the
previous, creating a comprehensive system that scales with your needs.
</p>
<Card className="p-6 my-8 bg-muted/50">
<p className="text-sm text-muted-foreground italic">
"A design system is never complete. It's a living, breathing ecosystem
that evolves with your product and team."
</p>
</Card>
<h2 className="text-3xl font-bold mt-12 mb-4">Getting Started</h2>
<p className="text-muted-foreground leading-relaxed">
Begin by identifying the core components your product needs. Start small
with basic atoms like buttons and inputs, then gradually build up to more
complex organisms and templates.
</p>
</div>
<Separator className="my-12" />
<div className="flex items-center justify-between">
<Button variant="outline">
Previous Article
</Button>
<Button>
Next Article
<ArrowRight className="ml-2" />
</Button>
</div>
</div>
</div>
</Card>
<ComponentShowcase
code={templatesCodeSnippets.blogArticle}
title="Blog Article"
description="Article layout with header, content, and navigation"
category="templates"
onSaveSnippet={onSaveSnippet}
>
<BlogTemplate />
</ComponentShowcase>
</section>
</div>
)