refactor: use shadcn Card component in pastel app
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user