feat: refactor workshop management by centralizing workshop data and improving session navigation across components
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m0s

This commit is contained in:
Julien Froidefond
2026-02-17 09:43:08 +01:00
parent a8f53bfe2a
commit cc7e73ce7b
11 changed files with 264 additions and 230 deletions

View File

@@ -17,26 +17,18 @@ import { deleteMotivatorSession, updateMotivatorSession } from '@/actions/moving
import { deleteYearReviewSession, updateYearReviewSession } from '@/actions/year-review';
import { deleteWeeklyCheckInSession, updateWeeklyCheckInSession } from '@/actions/weekly-checkin';
import { deleteWeatherSession, updateWeatherSession } from '@/actions/weather';
import {
type WorkshopTabType,
type WorkshopTypeId,
WORKSHOPS,
VALID_TAB_PARAMS,
getWorkshop,
getSessionPath,
} from '@/lib/workshops';
type WorkshopType = 'all' | 'swot' | 'motivators' | 'year-review' | 'weekly-checkin' | 'weather' | 'byPerson';
const VALID_TABS: WorkshopType[] = [
'all',
'swot',
'motivators',
'year-review',
'weekly-checkin',
'weather',
'byPerson',
];
const TYPE_TABS: { value: WorkshopType; icon: string; label: string }[] = [
{ value: 'all', icon: '📋', label: 'Tous' },
{ value: 'swot', icon: '📊', label: 'SWOT' },
{ value: 'motivators', icon: '🎯', label: 'Motivators' },
{ value: 'year-review', icon: '📅', label: 'Year Review' },
{ value: 'weekly-checkin', icon: '📝', label: 'Check-in' },
{ value: 'weather', icon: '🌤️', label: 'Météo' },
const TYPE_TABS = [
{ value: 'all' as const, icon: '📋', label: 'Tous' },
...WORKSHOPS.map((w) => ({ value: w.id, icon: w.icon, label: w.labelShort })),
];
interface ShareUser {
@@ -212,10 +204,12 @@ export function WorkshopTabs({
// Get tab from URL or default to 'all'
const tabParam = searchParams.get('tab');
const activeTab: WorkshopType =
tabParam && VALID_TABS.includes(tabParam as WorkshopType) ? (tabParam as WorkshopType) : 'all';
const activeTab: WorkshopTabType =
tabParam && VALID_TAB_PARAMS.includes(tabParam as WorkshopTabType)
? (tabParam as WorkshopTabType)
: 'all';
const setActiveTab = (tab: WorkshopType) => {
const setActiveTab = (tab: WorkshopTabType) => {
const params = new URLSearchParams(searchParams.toString());
if (tab === 'all') {
params.delete('tab');
@@ -362,8 +356,8 @@ function TypeFilterDropdown({
onOpenChange,
counts,
}: {
activeTab: WorkshopType;
setActiveTab: (t: WorkshopType) => void;
activeTab: WorkshopTabType;
setActiveTab: (t: WorkshopTabType) => void;
open: boolean;
onOpenChange: (v: boolean) => void;
counts: Record<string, number>;
@@ -493,20 +487,12 @@ function SessionCard({ session }: { session: AnySession }) {
: (session as MotivatorSession).participant
);
const workshop = getWorkshop(session.workshopType as WorkshopTypeId);
const isSwot = session.workshopType === 'swot';
const isYearReview = session.workshopType === 'year-review';
const isWeeklyCheckIn = session.workshopType === 'weekly-checkin';
const isWeather = session.workshopType === 'weather';
const href = isSwot
? `/sessions/${session.id}`
: isYearReview
? `/year-review/${session.id}`
: isWeeklyCheckIn
? `/weekly-checkin/${session.id}`
: isWeather
? `/weather/${session.id}`
: `/motivators/${session.id}`;
const icon = isSwot ? '📊' : isYearReview ? '📅' : isWeeklyCheckIn ? '📝' : isWeather ? '🌤️' : '🎯';
const href = getSessionPath(session.workshopType as WorkshopTypeId, session.id);
const participant = isSwot
? (session as SwotSession).collaborator
: isYearReview
@@ -516,15 +502,7 @@ function SessionCard({ session }: { session: AnySession }) {
: isWeather
? (session as WeatherSession).user.name || (session as WeatherSession).user.email
: (session as MotivatorSession).participant;
const accentColor = isSwot
? '#06b6d4'
: isYearReview
? '#f59e0b'
: isWeeklyCheckIn
? '#10b981'
: isWeather
? '#3b82f6'
: '#8b5cf6';
const accentColor = workshop.accentColor;
const handleDelete = () => {
startTransition(async () => {
@@ -582,7 +560,7 @@ function SessionCard({ session }: { session: AnySession }) {
setShowEditModal(true);
};
const editParticipantLabel = isSwot ? 'Collaborateur' : isWeather ? '' : 'Participant';
const editParticipantLabel = workshop.participantLabel;
return (
<>
@@ -597,7 +575,7 @@ function SessionCard({ session }: { session: AnySession }) {
{/* Header: Icon + Title + Role badge */}
<div className="flex items-center gap-2 mb-2">
<span className="text-xl">{icon}</span>
<span className="text-xl">{workshop.icon}</span>
<h3 className="font-semibold text-foreground line-clamp-1 flex-1">{session.title}</h3>
{!session.isOwner && (
<span