feat: redesign sessions dashboard with multi-view layout and sortable table
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m17s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m17s
- Redesign session cards with colored left border (Figma-style), improved visual hierarchy, hover states, and stats in footer - Add 4 switchable view modes: grid, list, sortable table, and timeline - Table view: unified flat table with clickable column headers for sorting (Type, Titre, Créateur, Participant, Stats, Date) - Add Créateur column showing the workshop owner with Gravatar avatar - Widen Type column to 160px for better readability - Improve tabs navigation with pill-shaped active state and shadow - Fix TypeFilterDropdown to exclude 'Équipe' from type list - Make filter tabs visually distinct with bg-card + border + shadow-sm - Split WorkshopTabs.tsx into 4 focused modules: workshop-session-types.ts, workshop-session-helpers.ts, SessionCard.tsx, WorkshopTabs.tsx Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -33,15 +33,15 @@ function WorkshopTabsSkeleton() {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Tabs skeleton */}
|
||||
<div className="flex gap-2 border-b border-border pb-4">
|
||||
<div className="flex gap-2 pb-2">
|
||||
{[...Array(4)].map((_, i) => (
|
||||
<div key={i} className="h-10 w-32 bg-card animate-pulse rounded-lg" />
|
||||
<div key={i} className="h-9 w-28 bg-card animate-pulse rounded-full" />
|
||||
))}
|
||||
</div>
|
||||
{/* Cards skeleton */}
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{[...Array(6)].map((_, i) => (
|
||||
<div key={i} className="h-40 bg-card animate-pulse rounded-xl" />
|
||||
<div key={i} className="h-44 bg-card animate-pulse rounded-xl" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -110,14 +110,22 @@ export default async function SessionsPage() {
|
||||
].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
|
||||
|
||||
const hasNoSessions = allSessions.length === 0;
|
||||
const totalCount = allSessions.length;
|
||||
|
||||
return (
|
||||
<main className="mx-auto max-w-7xl px-4 py-8">
|
||||
<main className="mx-auto max-w-7xl px-4 py-8 sm:py-12">
|
||||
{/* Header */}
|
||||
<div className="mb-8 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||
<div className="mb-10 flex flex-col sm:flex-row sm:items-end justify-between gap-6">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-foreground">Mes Ateliers</h1>
|
||||
<p className="mt-1 text-muted">Tous vos ateliers en un seul endroit</p>
|
||||
<div className="flex items-center gap-3 mb-1.5">
|
||||
<h1 className="text-3xl font-bold tracking-tight text-foreground">Mes Ateliers</h1>
|
||||
{totalCount > 0 && (
|
||||
<span className="inline-flex items-center justify-center px-2.5 h-6 rounded-full bg-primary/10 text-primary text-sm font-semibold">
|
||||
{totalCount}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm text-muted">Tous vos ateliers en un seul endroit</p>
|
||||
</div>
|
||||
<NewWorkshopDropdown />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user