refactor: use shadcn Card component in pastel app

This commit is contained in:
2026-02-25 13:35:29 +01:00
parent 57ba63aa32
commit 4ccf316184
9 changed files with 608 additions and 494 deletions

View File

@@ -6,6 +6,7 @@ import { ColorPicker } from '@/components/pastel/ColorPicker';
import { ColorDisplay } from '@/components/pastel/ColorDisplay';
import { ColorInfo } from '@/components/pastel/ColorInfo';
import { ManipulationPanel } from '@/components/pastel/ManipulationPanel';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { useColorInfo } from '@/lib/pastel/api/queries';
import { useColorHistory } from '@/lib/pastel/stores/historyStore';
import { Loader2, Share2, History, X } from 'lucide-react';
@@ -84,30 +85,36 @@ function PlaygroundContent() {
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Left Column: Color Picker and Display */}
<div className="space-y-6">
<div className="p-6 border rounded-lg bg-card">
<h2 className="text-sm font-medium mb-4">Color Picker</h2>
<ColorPicker color={color} onChange={setColor} />
</div>
<Card>
<CardHeader>
<CardTitle className="text-sm font-medium">Color Picker</CardTitle>
</CardHeader>
<CardContent>
<ColorPicker color={color} onChange={setColor} />
</CardContent>
</Card>
<div className="p-6 border rounded-lg bg-card">
<div className="flex items-center justify-between mb-4">
<h2 className="text-sm font-medium">Preview</h2>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0">
<CardTitle className="text-sm font-medium">Preview</CardTitle>
<Button onClick={handleShare} variant="outline" size="sm">
<Share2 className="h-4 w-4 mr-2" />
Share
</Button>
</div>
<div className="flex justify-center">
<ColorDisplay color={color} size="xl" />
</div>
</div>
</CardHeader>
<CardContent>
<div className="flex justify-center">
<ColorDisplay color={color} size="xl" />
</div>
</CardContent>
</Card>
{recentColors.length > 0 && (
<div className="p-6 border rounded-lg bg-card">
<div className="flex items-center justify-between mb-4">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0">
<div className="flex items-center gap-2">
<History className="h-5 w-5" />
<h2 className="text-sm font-medium">Recent Colors</h2>
<CardTitle className="text-sm font-medium">Recent Colors</CardTitle>
</div>
<Button
onClick={clearHistory}
@@ -117,68 +124,77 @@ function PlaygroundContent() {
>
Clear
</Button>
</div>
<div className="grid grid-cols-5 gap-2">
{recentColors.map((entry) => (
<div
key={entry.timestamp}
className="group relative aspect-square rounded-lg border-2 border-border hover:border-primary transition-all hover:scale-110 cursor-pointer"
style={{ backgroundColor: entry.color }}
onClick={() => setColor(entry.color)}
title={entry.color}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
setColor(entry.color);
}
}}
>
<div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity bg-black/30 rounded-lg">
<button
onClick={(e) => {
e.stopPropagation();
removeColor(entry.color);
toast.success('Color removed from history');
}}
className="p-1 bg-destructive rounded-full hover:bg-destructive/80"
aria-label="Remove color"
>
<X className="h-3 w-3 text-destructive-foreground" />
</button>
</CardHeader>
<CardContent>
<div className="grid grid-cols-5 gap-2">
{recentColors.map((entry) => (
<div
key={entry.timestamp}
className="group relative aspect-square rounded-lg border-2 border-border hover:border-primary transition-all hover:scale-110 cursor-pointer"
style={{ backgroundColor: entry.color }}
onClick={() => setColor(entry.color)}
title={entry.color}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
setColor(entry.color);
}
}}
>
<div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity bg-black/30 rounded-lg">
<button
onClick={(e) => {
e.stopPropagation();
removeColor(entry.color);
toast.success('Color removed from history');
}}
className="p-1 bg-destructive rounded-full hover:bg-destructive/80"
aria-label="Remove color"
>
<X className="h-3 w-3 text-destructive-foreground" />
</button>
</div>
</div>
</div>
))}
</div>
</div>
))}
</div>
</CardContent>
</Card>
)}
</div>
{/* Right Column: Color Information */}
<div className="space-y-6">
<div className="p-6 border rounded-lg bg-card">
<h2 className="text-sm font-medium mb-4">Color Information</h2>
<Card>
<CardHeader>
<CardTitle className="text-sm font-medium">Color Information</CardTitle>
</CardHeader>
<CardContent>
{isLoading && (
<div className="flex items-center justify-center py-12">
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
</div>
)}
{isLoading && (
<div className="flex items-center justify-center py-12">
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
</div>
)}
{isError && (
<div className="p-4 bg-destructive/10 text-destructive rounded-lg">
<p className="font-medium">Error loading color information</p>
<p className="text-sm mt-1">{error?.message || 'Unknown error'}</p>
</div>
)}
{isError && (
<div className="p-4 bg-destructive/10 text-destructive rounded-lg">
<p className="font-medium">Error loading color information</p>
<p className="text-sm mt-1">{error?.message || 'Unknown error'}</p>
</div>
)}
{colorInfo && <ColorInfo info={colorInfo} />}
</CardContent>
</Card>
{colorInfo && <ColorInfo info={colorInfo} />}
</div>
<div className="p-6 border rounded-lg bg-card">
<h2 className="text-sm font-medium mb-4">Color Manipulation</h2>
<ManipulationPanel color={color} onColorChange={setColor} />
</div>
<Card>
<CardHeader>
<CardTitle className="text-sm font-medium">Color Manipulation</CardTitle>
</CardHeader>
<CardContent>
<ManipulationPanel color={color} onColorChange={setColor} />
</CardContent>
</Card>
</div>
</div>
</div>