Files
family_wishlist/apps/frontend/src/pages/DashboardPage.tsx

103 lines
3.4 KiB
TypeScript

import { useState } from 'react';
import { Plus, Sparkles } from 'lucide-react';
import type { Wish } from '@family-wishlist/shared';
import { Button } from '@/components/ui/Button';
import { WishCard } from '@/components/WishCard/WishCard';
import { WishForm } from '@/components/WishForm/WishForm';
import {
useArchiveWish,
useCompleteWish,
useDeleteWish,
useWishes,
} from '@/features/wishes/wishes.hooks';
import { useAuthStore } from '@/features/auth/authStore';
import { Link } from 'react-router-dom';
export function DashboardPage() {
const { data, isLoading } = useWishes('active');
const [creating, setCreating] = useState(false);
const [editing, setEditing] = useState<Wish | null>(null);
const archive = useArchiveWish();
const complete = useCompleteWish();
const remove = useDeleteWish();
const user = useAuthStore((s) => s.user);
return (
<div className="grid gap-6">
<section className="flex flex-wrap items-end justify-between gap-4">
<div>
<h1 className="font-display text-3xl">Your wishlist</h1>
<p className="text-sm text-muted">
Add things you dream of. Share your public page at{' '}
{user && (
<Link
to={`/u/${user.slug}`}
className="font-medium text-primary hover:text-primary-600"
>
/u/{user.slug}
</Link>
)}
.
</p>
</div>
<Button size="lg" onClick={() => setCreating(true)}>
<Plus className="h-4 w-4" />
Add wish
</Button>
</section>
{isLoading && (
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{[0, 1, 2].map((i) => (
<div
key={i}
className="wish-card animate-pulse"
style={{ minHeight: 320, background: 'rgb(var(--color-surface-muted))' }}
/>
))}
</div>
)}
{!isLoading && data && data.length === 0 && (
<div className="flex flex-col items-center gap-4 rounded-xl border border-border bg-surface/80 p-10 text-center shadow-card">
<img src="/empty-state.svg" alt="" className="h-40 w-40 opacity-90" />
<div>
<h2 className="text-xl font-semibold">No wishes yet</h2>
<p className="mt-1 text-sm text-muted">
Start by adding something you'd love to receive.
</p>
</div>
<Button onClick={() => setCreating(true)}>
<Sparkles className="h-4 w-4" />
Add your first wish
</Button>
</div>
)}
{!isLoading && data && data.length > 0 && (
<div className="grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
{data.map((wish) => (
<WishCard
key={wish.id}
wish={wish}
view="owner"
onEdit={() => setEditing(wish)}
onArchive={() => archive.mutate(wish.id)}
onComplete={() => complete.mutate(wish.id)}
onDelete={() => remove.mutate(wish.id)}
/>
))}
</div>
)}
<WishForm open={creating} mode="create" onClose={() => setCreating(false)} />
<WishForm
open={editing !== null}
mode="edit"
initial={editing ?? undefined}
onClose={() => setEditing(null)}
/>
</div>
);
}