xtablo-source/apps/main/src/components/ProjectCardList.tsx
Arthur Belleville a3f5cf5e4e
Redesign overview dashboard with new project cards and task list
- Replace renderTabloListView with reusable ProjectCard / ProjectCardList components
  - Card layout with status badge, progress bar, date, and delete action
  - Default view shows 6 tablos with expand/collapse toggle
- Add DashboardTaskList component showing tasks assigned to the current user
  - Toggle done/todo inline; "Add Task" button opens TaskModal with tablo selection
- Wire TopBar search input to URL param ?q= to filter tablos on the overview page
- Add TopBar component to Layout (was missing)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 14:35:12 +01:00

78 lines
2.3 KiB
TypeScript

import type { UserTablo } from "@xtablo/shared/types/tablos.types";
import { ChevronDown, ChevronRight, ChevronUp } from "lucide-react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { ProjectCard } from "./ProjectCard";
const DEFAULT_VISIBLE = 6;
export interface ProjectCardListProps {
tablos: UserTablo[];
onTabloClick?: (tabloId: string) => void;
onTabloMenuClick?: (tabloId: string) => void;
onSeeAllClick?: () => void;
}
export function ProjectCardList({
tablos,
onTabloClick,
onTabloMenuClick,
onSeeAllClick,
}: ProjectCardListProps) {
const { t } = useTranslation("pages");
const [expanded, setExpanded] = useState(false);
const hasMore = tablos.length > DEFAULT_VISIBLE;
const visibleTablos = expanded ? tablos : tablos.slice(0, DEFAULT_VISIBLE);
return (
<div className="mb-8">
<div className="flex items-center justify-between mb-6">
<h2 className="text-2xl font-semibold text-gray-900">
{t("tablo.projectList.title")}
</h2>
{onSeeAllClick && (
<button
className="flex items-center gap-1 text-purple-600 hover:text-purple-700 font-medium"
onClick={onSeeAllClick}
>
{t("tablo.projectList.seeAll")}
<ChevronRight className="w-4 h-4" />
</button>
)}
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{visibleTablos.map((tablo) => (
<ProjectCard
key={tablo.id}
tablo={tablo}
onClick={onTabloClick}
onMenuClick={onTabloMenuClick}
/>
))}
</div>
{hasMore && (
<div className="flex justify-center mt-6">
<button
className="flex items-center gap-1.5 text-purple-600 hover:text-purple-700 font-medium text-sm"
onClick={() => setExpanded((prev) => !prev)}
>
{expanded ? (
<>
{t("tablo.projectList.showLess")}
<ChevronUp className="w-4 h-4" />
</>
) : (
<>
{t("tablo.projectList.showAll", {
count: tablos.length - DEFAULT_VISIBLE,
})}
<ChevronDown className="w-4 h-4" />
</>
)}
</button>
</div>
)}
</div>
);
}