'use client'; import { useEffect, useRef, useState } from 'react'; import { useSearchParams, useRouter } from 'next/navigation'; import { CollaboratorDisplay } from '@/components/ui'; import { type WorkshopTabType, VALID_TAB_PARAMS } from '@/lib/workshops'; import { useClickOutside } from '@/hooks/useClickOutside'; import { type CardView, type SortCol, type WorkshopTabsProps, type AnySession, TABLE_COLS, SORT_COLUMNS, TYPE_TABS, } from './workshop-session-types'; import { getResolvedCollaborator, groupByPerson, getMonthGroup, sortSessions, } from './workshop-session-helpers'; import { SessionCard } from './SessionCard'; // ─── SectionHeader ──────────────────────────────────────────────────────────── function SectionHeader({ label, count }: { label: string; count: number }) { return (

{label}

{count}
); } // ─── SortIcon ───────────────────────────────────────────────────────────────── function SortIcon({ active, dir }: { active: boolean; dir: 'asc' | 'desc' }) { if (!active) { return ( ); } if (dir === 'asc') { return ( ); } return ( ); } // ─── ViewToggle ─────────────────────────────────────────────────────────────── function ViewToggle({ view, setView }: { view: CardView; setView: (v: CardView) => void }) { const btn = (v: CardView, label: string, icon: React.ReactNode) => ( ); return (
{btn( 'grid', 'Grille', )} {btn( 'list', 'Liste', )} {btn( 'table', 'Tableau', )} {btn( 'timeline', 'Chronologique', )}
); } // ─── TabButton ──────────────────────────────────────────────────────────────── function TabButton({ active, onClick, icon, label, count, }: { active: boolean; onClick: () => void; icon: string; label: string; count: number; }) { return ( ); } // ─── TypeFilterDropdown ─────────────────────────────────────────────────────── function TypeFilterDropdown({ activeTab, setActiveTab, open, onOpenChange, counts, }: { activeTab: WorkshopTabType; setActiveTab: (t: WorkshopTabType) => void; open: boolean; onOpenChange: (v: boolean) => void; counts: Record; }) { const typeTabs = TYPE_TABS.filter((t) => t.value !== 'all' && t.value !== 'team'); const current = TYPE_TABS.find((t) => t.value === activeTab) ?? TYPE_TABS[0]; const isTypeSelected = activeTab !== 'all' && activeTab !== 'byPerson' && activeTab !== 'team'; const totalCount = typeTabs.reduce((s, t) => s + (counts[t.value] ?? 0), 0); const containerRef = useRef(null); useClickOutside(containerRef, () => onOpenChange(false), open); return (
{open && (
{typeTabs.map((t) => ( ))}
)}
); } // ─── SessionsGrid ───────────────────────────────────────────────────────────── function SessionsGrid({ sessions, view, isTeamCollab = false, }: { sessions: AnySession[]; view: CardView; isTeamCollab?: boolean; }) { if (view === 'table') { return (
{SORT_COLUMNS.map((col) => (
{col.label}
))}
{sessions.map((s) => ( ))}
); } return (
{sessions.map((s) => ( ))}
); } // ─── SortableTableView ──────────────────────────────────────────────────────── function SortableTableView({ sessions, sortCol, sortDir, onSort, }: { sessions: AnySession[]; sortCol: SortCol; sortDir: 'asc' | 'desc'; onSort: (col: SortCol) => void; }) { if (sessions.length === 0) { return
Aucun atelier pour le moment
; } return (
{SORT_COLUMNS.map((col) => ( ))}
{sessions.map((s) => ( ))}
); } // ─── WorkshopTabs ───────────────────────────────────────────────────────────── export function WorkshopTabs({ swotSessions, motivatorSessions, yearReviewSessions, weeklyCheckInSessions, weatherSessions, gifMoodSessions, teamCollabSessions = [], }: WorkshopTabsProps) { const CARD_VIEW_STORAGE_KEY = 'sessions:cardView'; const isCardView = (value: string): value is CardView => value === 'grid' || value === 'list' || value === 'table' || value === 'timeline'; const searchParams = useSearchParams(); const router = useRouter(); const [typeDropdownOpen, setTypeDropdownOpen] = useState(false); const [cardView, setCardView] = useState(() => { if (typeof window === 'undefined') return 'grid'; const storedView = localStorage.getItem(CARD_VIEW_STORAGE_KEY); return storedView && isCardView(storedView) ? storedView : 'grid'; }); const [sortCol, setSortCol] = useState('date'); const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc'); useEffect(() => { localStorage.setItem(CARD_VIEW_STORAGE_KEY, cardView); }, [cardView]); const handleSort = (col: SortCol) => { if (sortCol === col) setSortDir((d) => (d === 'asc' ? 'desc' : 'asc')); else { setSortCol(col); setSortDir('asc'); } }; const tabParam = searchParams.get('tab'); const activeTab: WorkshopTabType = tabParam && VALID_TAB_PARAMS.includes(tabParam as WorkshopTabType) ? (tabParam as WorkshopTabType) : 'all'; const setActiveTab = (tab: WorkshopTabType) => { const params = new URLSearchParams(searchParams.toString()); if (tab === 'all') params.delete('tab'); else params.set('tab', tab); router.push(`/sessions${params.toString() ? `?${params.toString()}` : ''}`); }; const allSessions: AnySession[] = [ ...swotSessions, ...motivatorSessions, ...yearReviewSessions, ...weeklyCheckInSessions, ...weatherSessions, ...gifMoodSessions, ].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()); const filteredSessions: AnySession[] = activeTab === 'all' || activeTab === 'byPerson' ? allSessions : activeTab === 'team' ? teamCollabSessions : activeTab === 'swot' ? swotSessions : activeTab === 'motivators' ? motivatorSessions : activeTab === 'year-review' ? yearReviewSessions : activeTab === 'weekly-checkin' ? weeklyCheckInSessions : activeTab === 'gif-mood' ? gifMoodSessions : weatherSessions; const ownedSessions = filteredSessions.filter((s) => s.isOwner); const sharedSessions = filteredSessions.filter( (s) => !s.isOwner && !(s as AnySession & { isTeamCollab?: boolean }).isTeamCollab ); const teamCollabFiltered = activeTab === 'all' ? teamCollabSessions : []; const sessionsByPerson = groupByPerson(allSessions); const sortedPersons = Array.from(sessionsByPerson.entries()).sort((a, b) => a[0].localeCompare(b[0], 'fr') ); // Timeline grouping const timelineSessions = [ ...(activeTab === 'all' ? [...filteredSessions, ...teamCollabSessions] : filteredSessions), ].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()); const byMonth = new Map(); timelineSessions.forEach((s) => { const key = getMonthGroup(s.updatedAt); if (!byMonth.has(key)) byMonth.set(key, []); byMonth.get(key)!.push(s); }); // Flat sorted sessions for the sortable table view const flatTableSessions = cardView === 'table' && activeTab !== 'byPerson' ? sortSessions( activeTab === 'all' ? [...filteredSessions, ...teamCollabSessions] : filteredSessions, sortCol, sortDir ) : []; return (
{/* Tabs + vue toggle */}
setActiveTab('all')} icon="📋" label="Tous" count={allSessions.length} /> setActiveTab('byPerson')} icon="👥" label="Par personne" count={sessionsByPerson.size} /> {teamCollabSessions.length > 0 && ( setActiveTab('team')} icon="🏢" label="Équipe" count={teamCollabSessions.length} /> )}
{/* ── Vue Tableau flat (colonnes triables) ──────────────────── */} {cardView === 'table' && activeTab !== 'byPerson' ? ( ) : cardView === 'timeline' && activeTab !== 'byPerson' ? ( /* ── Vue Timeline ────────────────────────────────────────── */ byMonth.size === 0 ? (
Aucun atelier pour le moment
) : (
{Array.from(byMonth.entries()).map(([period, sessions]) => (
{period}
{sessions.map((s) => ( ))}
))}
) ) : activeTab === 'byPerson' ? ( /* ── Vue Par personne ───────────────────────────────────── */ sortedPersons.length === 0 ? (
Aucun atelier pour le moment
) : (
{sortedPersons.map(([personKey, sessions]) => { const resolved = getResolvedCollaborator(sessions[0]); return (
{sessions.length} atelier{sessions.length > 1 ? 's' : ''}
); })}
) ) : activeTab === 'team' ? ( /* ── Vue Équipe ─────────────────────────────────────────── */ teamCollabSessions.length === 0 ? (
Aucun atelier de vos collaborateurs (non partagés)
) : (

En tant qu'admin d'équipe, vous voyez les ateliers de vos collaborateurs qui ne vous sont pas encore partagés.

) ) : filteredSessions.length === 0 ? (
Aucun atelier de ce type pour le moment
) : ( /* ── Vue normale (tous / par type) ─────────────────────── */
{ownedSessions.length > 0 && (
)} {sharedSessions.length > 0 && (
)} {activeTab === 'all' && teamCollabFiltered.length > 0 && (
)}
)}
); }