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

105 lines
3.3 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';
import { useI18n } from '@/i18n/i18n';
export function DashboardPage() {
const { t } = useI18n();
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="page-section flex flex-wrap items-end justify-between gap-4">
<div>
<h1 className="page-section__title">{t('dashboard.title')}</h1>
<p className="page-section__text">
{t('dashboard.description')}
{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" />
{t('dashboard.addWish')}
</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="empty-state gap-4">
<img src="/empty-state.svg" alt="" className="empty-state__icon--image" />
<div>
<h2 className="empty-state__title">{t('dashboard.emptyTitle')}</h2>
<p className="empty-state__text mt-1">
{t('dashboard.emptyText')}
</p>
</div>
<Button onClick={() => setCreating(true)}>
<Sparkles className="h-4 w-4" />
{t('dashboard.addFirstWish')}
</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>
);
}