Files
workshop-manager/src/app/sessions/page.tsx
2026-02-03 18:08:06 +01:00

186 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Suspense } from 'react';
import Link from 'next/link';
import { auth } from '@/lib/auth';
import { getSessionsByUserId } from '@/services/sessions';
import { getMotivatorSessionsByUserId } from '@/services/moving-motivators';
import { getYearReviewSessionsByUserId } from '@/services/year-review';
import { getWeeklyCheckInSessionsByUserId } from '@/services/weekly-checkin';
import { getWeatherSessionsByUserId } from '@/services/weather';
import { Card, Button } from '@/components/ui';
import { WorkshopTabs } from './WorkshopTabs';
function WorkshopTabsSkeleton() {
return (
<div className="space-y-6">
{/* Tabs skeleton */}
<div className="flex gap-2 border-b border-border pb-4">
{[...Array(4)].map((_, i) => (
<div key={i} className="h-10 w-32 bg-card animate-pulse rounded-lg" />
))}
</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>
</div>
);
}
export default async function SessionsPage() {
const session = await auth();
if (!session?.user?.id) {
return null;
}
// Fetch SWOT, Moving Motivators, Year Review, Weekly Check-in, and Weather sessions
const [swotSessions, motivatorSessions, yearReviewSessions, weeklyCheckInSessions, weatherSessions] =
await Promise.all([
getSessionsByUserId(session.user.id),
getMotivatorSessionsByUserId(session.user.id),
getYearReviewSessionsByUserId(session.user.id),
getWeeklyCheckInSessionsByUserId(session.user.id),
getWeatherSessionsByUserId(session.user.id),
]);
// Add type to each session for unified display
const allSwotSessions = swotSessions.map((s) => ({
...s,
workshopType: 'swot' as const,
}));
const allMotivatorSessions = motivatorSessions.map((s) => ({
...s,
workshopType: 'motivators' as const,
}));
const allYearReviewSessions = yearReviewSessions.map((s) => ({
...s,
workshopType: 'year-review' as const,
}));
const allWeeklyCheckInSessions = weeklyCheckInSessions.map((s) => ({
...s,
workshopType: 'weekly-checkin' as const,
}));
const allWeatherSessions = weatherSessions.map((s) => ({
...s,
workshopType: 'weather' as const,
}));
// Combine and sort by updatedAt
const allSessions = [
...allSwotSessions,
...allMotivatorSessions,
...allYearReviewSessions,
...allWeeklyCheckInSessions,
...allWeatherSessions,
].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
const hasNoSessions = allSessions.length === 0;
return (
<main className="mx-auto max-w-7xl px-4 py-8">
{/* Header */}
<div className="mb-8 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
<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>
<div className="flex gap-2">
<Link href="/sessions/new">
<Button variant="outline">
<span>📊</span>
Nouveau SWOT
</Button>
</Link>
<Link href="/motivators/new">
<Button variant="outline">
<span>🎯</span>
Nouveau Motivators
</Button>
</Link>
<Link href="/year-review/new">
<Button variant="outline">
<span>📅</span>
Nouveau Year Review
</Button>
</Link>
<Link href="/weekly-checkin/new">
<Button variant="outline">
<span>📝</span>
Nouveau Check-in
</Button>
</Link>
<Link href="/weather/new">
<Button>
<span>🌤</span>
Nouvelle Météo
</Button>
</Link>
</div>
</div>
{/* Content */}
{hasNoSessions ? (
<Card className="p-12 text-center">
<div className="text-5xl mb-4">🚀</div>
<h2 className="text-xl font-semibold text-foreground mb-2">
Commencez votre premier atelier
</h2>
<p className="text-muted mb-6 max-w-md mx-auto">
Créez un atelier SWOT pour analyser les forces et faiblesses, un Moving Motivators pour
découvrir les motivations, un Year Review pour faire le bilan de l&apos;année, ou un
Weekly Check-in pour le suivi hebdomadaire.
</p>
<div className="flex gap-3 justify-center flex-wrap">
<Link href="/sessions/new">
<Button variant="outline">
<span>📊</span>
Créer un SWOT
</Button>
</Link>
<Link href="/motivators/new">
<Button variant="outline">
<span>🎯</span>
Créer un Moving Motivators
</Button>
</Link>
<Link href="/year-review/new">
<Button variant="outline">
<span>📅</span>
Créer un Year Review
</Button>
</Link>
<Link href="/weekly-checkin/new">
<Button variant="outline">
<span>📝</span>
Créer un Check-in
</Button>
</Link>
<Link href="/weather/new">
<Button>
<span>🌤</span>
Créer une Météo
</Button>
</Link>
</div>
</Card>
) : (
<Suspense fallback={<WorkshopTabsSkeleton />}>
<WorkshopTabs
swotSessions={allSwotSessions}
motivatorSessions={allMotivatorSessions}
yearReviewSessions={allYearReviewSessions}
weeklyCheckInSessions={allWeeklyCheckInSessions}
weatherSessions={allWeatherSessions}
/>
</Suspense>
)}
</main>
);
}