'use client'; import { useState, useEffect, Suspense } from 'react'; import { useSearchParams, useRouter } from 'next/navigation'; import { ColorPicker } from '@/components/color/ColorPicker'; import { ColorInfo } from '@/components/color/ColorInfo'; import { ManipulationPanel } from '@/components/color/ManipulationPanel'; import { PaletteGrid } from '@/components/color/PaletteGrid'; import { ExportMenu } from '@/components/color/ExportMenu'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { AppPage } from '@/components/layout/AppPage'; import { useColorInfo, useGeneratePalette, useGenerateGradient } from '@/lib/color/api/queries'; import { Loader2, Share2, Palette, Plus, X, Layers } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { toast } from 'sonner'; type HarmonyType = | 'monochromatic' | 'analogous' | 'complementary' | 'triadic' | 'tetradic'; function PlaygroundContent() { const searchParams = useSearchParams(); const router = useRouter(); const [color, setColor] = useState(() => { // Initialize from URL if available const urlColor = searchParams.get('color'); return urlColor ? `#${urlColor.replace('#', '')}` : '#ff0099'; }); // Harmony state const [harmonyType, setHarmonyType] = useState('complementary'); const [palette, setPalette] = useState([]); const paletteMutation = useGeneratePalette(); // Gradient state const [stops, setStops] = useState(['#ff0099', '#0099ff']); const [gradientCount, setGradientCount] = useState(10); const [gradientResult, setGradientResult] = useState([]); const gradientMutation = useGenerateGradient(); const { data, isLoading, isError, error } = useColorInfo({ colors: [color], }); const colorInfo = data?.colors[0]; // Update URL when color changes useEffect(() => { const hex = color.replace('#', ''); if (hex.length === 6 || hex.length === 3) { router.push(`/color?color=${hex}`, { scroll: false }); } }, [color, router]); // Sync first gradient stop with active color useEffect(() => { const newStops = [...stops]; newStops[0] = color; setStops(newStops); }, [color]); // Share color via URL const handleShare = () => { const url = `${window.location.origin}/color?color=${color.replace('#', '')}`; navigator.clipboard.writeText(url); toast.success('Link copied to clipboard!'); }; const generateHarmony = async () => { try { const result = await paletteMutation.mutateAsync({ base: color, scheme: harmonyType, }); const colors = [result.palette.primary, ...result.palette.secondary]; setPalette(colors); toast.success(`Generated ${harmonyType} harmony palette`); } catch (error) { toast.error('Failed to generate harmony palette'); console.error(error); } }; const generateGradient = async () => { try { const result = await gradientMutation.mutateAsync({ stops, count: gradientCount, }); setGradientResult(result.gradient); toast.success(`Generated ${result.gradient.length} colors`); } catch (error) { toast.error('Failed to generate gradient'); } }; const addStop = () => { setStops([...stops, '#000000']); }; const removeStop = (index: number) => { if (index === 0) return; // Prevent deleting the first stop (synchronized with picker) if (stops.length > 2) { setStops(stops.filter((_, i) => i !== index)); } }; const updateStop = (index: number, colorValue: string) => { const newStops = [...stops]; newStops[index] = colorValue; setStops(newStops); if (index === 0) setColor(colorValue); }; const harmonyDescriptions: Record = { monochromatic: 'Single color with variations', analogous: 'Colors adjacent on the color wheel (±30°)', complementary: 'Colors opposite on the color wheel (180°)', triadic: 'Three colors evenly spaced on the color wheel (120°)', tetradic: 'Four colors evenly spaced on the color wheel (90°)', }; return (
{/* Row 1: Workspace */}
{/* Main Workspace: Color Picker and Information */}
Color Picker

Color Information

{isLoading && (
)} {isError && (

Error loading color information

{error?.message || 'Unknown error'}

)} {colorInfo && }
{/* Sidebar: Color Manipulation */}
Color Manipulation
{/* Row 2: Harmony Generator */}
{/* Harmony Controls */}
Harmony Type

{harmonyDescriptions[harmonyType]}

{/* Harmony Results */}
Generated Palette {palette.length > 0 && `(${palette.length} colors)`} {palette.length > 0 ? (
) : (

Select a harmony type and click Generate to create your palette based on the current color

)}
{/* Row 3: Gradient Generator */}
{/* Gradient Controls */}
Gradient Controls

Color Stops

{stops.map((stop, index) => (
updateStop(index, e.target.value)} className="h-10 w-full cursor-pointer p-1" />
{index !== 0 && stops.length > 2 && ( )}
))}

Steps

setGradientCount(parseInt(e.target.value))} />
{/* Gradient Results */}
Generated Gradient {gradientResult.length > 0 && `(${gradientResult.length} colors)`} {gradientResult.length > 0 ? (
) : (

Add color stops and click Generate to create your smooth gradient

)}
); } export default function PlaygroundPage() { return (
}> ); }