@@ -1,16 +1,24 @@
'use client' ;
import { useState , useRef } from 'react' ;
import { useEffect , useRef , useState } from 'react' ;
import { useSearchParams , useRouter } from 'next/navigation' ;
import { CollaboratorDisplay } from '@/components/ui' ;
import { type WorkshopTabType , WORKSHOPS , VALID_TAB_PARAMS } from '@/lib/workshops' ;
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 ,
type CardView ,
type SortCol ,
type WorkshopTabsProps ,
type AnySession ,
TABLE_COLS ,
SORT_COLUMNS ,
TYPE_TABS ,
} from './workshop-session-types' ;
import {
getResolvedCollaborator , groupByPerson , getMonthGroup , sortSessions ,
getResolvedCollaborator ,
groupByPerson ,
getMonthGroup ,
sortSessions ,
} from './workshop-session-helpers' ;
import { SessionCard } from './SessionCard' ;
@@ -33,7 +41,13 @@ function SectionHeader({ label, count }: { label: string; count: number }) {
function SortIcon ( { active , dir } : { active : boolean ; dir : 'asc' | 'desc' } ) {
if ( ! active ) {
return (
< svg width = "10" height = "10" viewBox = "0 0 10 10" fill = "currentColor" className = "opacity-30 flex-shrink-0" >
< svg
width = "10"
height = "10"
viewBox = "0 0 10 10"
fill = "currentColor"
className = "opacity-30 flex-shrink-0"
>
< path d = "M5 1.5L8 5H2L5 1.5Z" / >
< path d = "M5 8.5L2 5H8L5 8.5Z" / >
< / svg >
@@ -72,27 +86,61 @@ function ViewToggle({ view, setView }: { view: CardView; setView: (v: CardView)
return (
< div className = "flex items-center gap-0.5 p-0.5 bg-card border border-border rounded-lg ml-auto flex-shrink-0 shadow-sm" >
{ btn ( 'grid' , 'Grille' ,
{ btn (
'grid' ,
'Grille' ,
< svg width = "14" height = "14" viewBox = "0 0 14 14" fill = "currentColor" >
< rect x = "0" y = "0" width = "4" height = "4" rx = "0.5" / > < rect x = "5" y = "0" width = "4" height = "4" rx = "0.5" / > < rect x = "10" y = "0" width = "4" height = "4" rx = "0.5" / >
< rect x = "0" y = "5" width = "4" height = "4" rx = "0.5" / > < rect x = "5" y = "5" width = "4" height = "4" rx = "0.5" / > < rect x = "10" y = "5 " width = "4" height = "4" rx = "0.5" / >
< rect x = "0" y = "10" width = "4" height = "4" rx = "0.5" / > < rect x = "5" y = "10" width = "4" height = "4" rx = "0.5" / > < rect x = " 10" y = "1 0" width = "4" height = "4" rx = "0.5" / >
< rect x = "0" y = "0" width = "4" height = "4" rx = "0.5" / >
< rect x = "5" y = "0 " width = "4" height = "4" rx = "0.5" / >
< rect x = "10" y = "0" width = "4" height = "4" rx = "0.5" / >
< rect x = "0" y = "5" width = "4" height = "4" rx = "0.5" / >
< rect x = "5" y = "5" width = "4" height = "4" rx = "0.5" / >
< rect x = "10" y = "5" width = "4" height = "4" rx = "0.5" / >
< rect x = "0" y = "10" width = "4" height = "4" rx = "0.5" / >
< rect x = "5" y = "10" width = "4" height = "4" rx = "0.5" / >
< rect x = "10" y = "10" width = "4" height = "4" rx = "0.5" / >
< / svg >
) }
{ btn ( 'list' , 'Liste' ,
< svg width = "14" height = "14" viewBox = "0 0 14 14" fill = "none" stroke = "currentColor" strokeWidth = "1.5" strokeLinecap = "round" >
< line x1 = "0" y1 = "2.5" x2 = "14" y2 = "2.5" / > < line x1 = "0" y1 = "7" x2 = "14" y2 = "7" / > < line x1 = "0" y1 = "11.5" x2 = "14" y2 = "11.5" / >
{ btn (
'list' ,
'Liste' ,
< svg
width = "14"
height = "14"
viewBox = "0 0 14 14"
fill = "none"
stroke = "currentColor"
strokeWidth = "1.5"
strokeLinecap = "round"
>
< line x1 = "0" y1 = "2.5" x2 = "14" y2 = "2.5" / >
< line x1 = "0" y1 = "7" x2 = "14" y2 = "7" / >
< line x1 = "0" y1 = "11.5" x2 = "14" y2 = "11.5" / >
< / svg >
) }
{ btn ( 'table' , 'Tableau' ,
{ btn (
'table' ,
'Tableau' ,
< svg width = "14" height = "14" viewBox = "0 0 14 14" fill = "currentColor" >
< rect x = "0" y = "0" width = "14" height = "3.5" rx = "0.5" / >
< rect x = "0" y = "5" width = "6" height = "2.5" rx = "0.5" / > < rect x = "8" y = "5" width = "6" height = "2.5" rx = "0.5" / >
< rect x = "0" y = "9.5" width = "6" height = "2.5" rx = "0.5" / > < rect x = " 8" y = "9. 5" width = "6" height = "2.5" rx = "0.5" / >
< rect x = "0" y = "5" width = "6" height = "2.5" rx = "0.5" / >
< rect x = "8" y = "5" width = "6" height = "2.5" rx = "0.5" / >
< rect x = "0" y = "9.5" width = "6" height = "2.5" rx = "0.5" / >
< rect x = "8" y = "9.5" width = "6" height = "2.5" rx = "0.5" / >
< / svg >
) }
{ btn ( 'timeline' , 'Chronologique' ,
< svg width = "14" height = "14" viewBox = "0 0 14 14" fill = "none" stroke = "currentColor" strokeWidth = "1.5" strokeLinecap = "round" >
{ btn (
'timeline' ,
'Chronologique' ,
< svg
width = "14"
height = "14"
viewBox = "0 0 14 14"
fill = "none"
stroke = "currentColor"
strokeWidth = "1.5"
strokeLinecap = "round"
>
< line x1 = "3" y1 = "0" x2 = "3" y2 = "14" / >
< circle cx = "3" cy = "2.5" r = "1.5" fill = "currentColor" stroke = "none" / >
< line x1 = "5" y1 = "2.5" x2 = "14" y2 = "2.5" / >
@@ -108,11 +156,23 @@ function ViewToggle({ view, setView }: { view: CardView; setView: (v: CardView)
// ─── TabButton ────────────────────────────────────────────────────────────────
function TabButton ( { active , onClick , icon , label , count } : {
active : boolean ; onClick : ( ) = > void ; icon : string ; label : string ; count : number ;
function TabButton ( {
active ,
onClick ,
icon ,
label ,
count ,
} : {
active : boolean ;
onClick : ( ) = > void ;
icon : string ;
label : string ;
count : number ;
} ) {
return (
< button type = "button" onClick = { onClick }
< button
type = "button"
onClick = { onClick }
className = { ` flex items-center gap-1.5 px-3.5 py-1.5 rounded-full font-medium text-sm transition-all duration-150 shadow-sm ${
active
? 'bg-primary text-primary-foreground shadow-md'
@@ -121,7 +181,9 @@ function TabButton({ active, onClick, icon, label, count }: {
>
< span > { icon } < / span >
< span > { label } < / span >
< span className = { ` text-[11px] font-semibold px-1.5 py-0.5 rounded-full ${ active ? 'bg-white/20 text-white' : 'bg-primary/10 text-primary' } ` } >
< span
className = { ` text-[11px] font-semibold px-1.5 py-0.5 rounded-full ${ active ? 'bg-white/20 text-white' : 'bg-primary/10 text-primary' } ` }
>
{ count }
< / span >
< / button >
@@ -131,10 +193,17 @@ function TabButton({ active, onClick, icon, label, count }: {
// ─── TypeFilterDropdown ───────────────────────────────────────────────────────
function TypeFilterDropdown ( {
activeTab , setActiveTab , open , onOpenChange , counts ,
activeTab ,
setActiveTab ,
open ,
onOpenChange ,
counts ,
} : {
activeTab : WorkshopTabType ; setActiveTab : ( t : WorkshopTabType ) = > void ;
open : boolean ; onOpenChange : ( v : boolean ) = > void ; counts : Record < string , number > ;
activeTab : WorkshopTabType ;
setActiveTab : ( t : WorkshopTabType ) = > void ;
open : boolean ;
onOpenChange : ( v : boolean ) = > void ;
counts : Record < string , number > ;
} ) {
const typeTabs = TYPE_TABS . filter ( ( t ) = > t . value !== 'all' && t . value !== 'team' ) ;
const current = TYPE_TABS . find ( ( t ) = > t . value === activeTab ) ? ? TYPE_TABS [ 0 ] ;
@@ -156,25 +225,55 @@ function TypeFilterDropdown({
>
< span > { isTypeSelected ? current . icon : '🔖' } < / span >
< span > { isTypeSelected ? current . label : 'Type' } < / span >
< span className = { ` text-[11px] font-semibold px-1.5 py-0.5 rounded-full ${ isTypeSelected ? 'bg-white/20 text-white' : 'bg-primary/10 text-primary' } ` } >
< span
className = { ` text-[11px] font-semibold px-1.5 py-0.5 rounded-full ${ isTypeSelected ? 'bg-white/20 text-white' : 'bg-primary/10 text-primary' } ` }
>
{ isTypeSelected ? ( counts [ activeTab ] ? ? 0 ) : totalCount }
< / span >
< svg className = { ` h-3.5 w-3.5 transition-transform ${ open ? 'rotate-180' : '' } ` } fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
< svg
className = { ` h-3.5 w-3.5 transition-transform ${ open ? 'rotate-180' : '' } ` }
fill = "none"
viewBox = "0 0 24 24"
stroke = "currentColor"
>
< path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M19 9l-7 7-7-7" / >
< / svg >
< / button >
{ open && (
< div className = "absolute left-0 z-20 mt-2 w-48 rounded-xl border border-border bg-card py-1.5 shadow-lg" >
< button type = "button" onClick = { ( ) = > { setActiveTab ( 'all' ) ; onOpenChange ( false ) ; } }
className = "flex w-full items-center justify-between gap-2 px-4 py-2 text-left text-sm text-foreground hover:bg-card-hover border-b border-border transition-colors" >
< span className = "flex items-center gap-2" > < span > 📋 < / span > < span > Tous les types < / span > < / span >
< span className = "text-[11px] font-semibold px-1.5 py-0.5 rounded-full bg-primary/10 text-primary" > { totalCount } < / span >
< button
type = "button"
onClick = { ( ) = > {
setActiveTab ( 'all' ) ;
onOpenChange ( false ) ;
} }
className = "flex w-full items-center justify-between gap-2 px-4 py-2 text-left text-sm text-foreground hover:bg-card-hover border-b border-border transition-colors"
>
< span className = "flex items-center gap-2" >
< span > 📋 < / span >
< span > Tous les types < / span >
< / span >
< span className = "text-[11px] font-semibold px-1.5 py-0.5 rounded-full bg-primary/10 text-primary" >
{ totalCount }
< / span >
< / button >
{ typeTabs . map ( ( t ) = > (
< button key = { t . value } type = "button" onClick = { ( ) = > { setActiveTab ( t . value ) ; onOpenChange ( false ) ; } }
className = "flex w-full items-center justify-between gap-2 px-4 py-2 text-left text-sm text-foreground hover:bg-card-hover transition-colors" >
< span className = "flex items-center gap-2" > < span > { t . icon } < / span > < span > { t . label } < / span > < / span >
< span className = "text-[11px] font-semibold px-1.5 py-0.5 rounded-full bg-primary/10 text-primary" > { counts [ t . value ] ? ? 0 } < / span >
< button
key = { t . value }
type = "button"
onClick = { ( ) = > {
setActiveTab ( t . value ) ;
onOpenChange ( false ) ;
} }
className = "flex w-full items-center justify-between gap-2 px-4 py-2 text-left text-sm text-foreground hover:bg-card-hover transition-colors"
>
< span className = "flex items-center gap-2" >
< span > { t . icon } < / span >
< span > { t . label } < / span >
< / span >
< span className = "text-[11px] font-semibold px-1.5 py-0.5 rounded-full bg-primary/10 text-primary" >
{ counts [ t . value ] ? ? 0 }
< / span >
< / button >
) ) }
< / div >
@@ -186,16 +285,25 @@ function TypeFilterDropdown({
// ─── SessionsGrid ─────────────────────────────────────────────────────────────
function SessionsGrid ( {
sessions , view , isTeamCollab = false ,
sessions ,
view ,
isTeamCollab = false ,
} : {
sessions : AnySession [ ] ; view : CardView ; isTeamCollab? : boolean ;
sessions : AnySession [ ] ;
view : CardView ;
isTeamCollab? : boolean ;
} ) {
if ( view === 'table' ) {
return (
< div className = "rounded-xl border border-border overflow-hidden overflow-x-auto bg-card" >
< div className = "grid text-[11px] font-semibold text-muted uppercase tracking-wider bg-card-hover/60 border-b border-border" style = { { gridTemplateColumns : TABLE_COLS } } >
< div
className = "grid text-[11px] font-semibold text-muted uppercase tracking-wider bg-card-hover/60 border-b border-border"
style = { { gridTemplateColumns : TABLE_COLS } }
>
{ SORT_COLUMNS . map ( ( col ) = > (
< div key = { col . key } className = "px-4 py-2.5" > { col . label } < / div >
< div key = { col . key } className = "px-4 py-2.5" >
{ col . label }
< / div >
) ) }
< / div >
{ sessions . map ( ( s ) = > (
@@ -205,7 +313,11 @@ function SessionsGrid({
) ;
}
return (
< div className = { view === 'list' ? 'flex flex-col gap-2' : 'grid gap-4 md:grid-cols-2 lg:grid-cols-3' } >
< div
className = {
view === 'list' ? 'flex flex-col gap-2' : 'grid gap-4 md:grid-cols-2 lg:grid-cols-3'
}
>
{ sessions . map ( ( s ) = > (
< SessionCard key = { s . id } session = { s } isTeamCollab = { isTeamCollab } view = { view } / >
) ) }
@@ -216,7 +328,10 @@ function SessionsGrid({
// ─── SortableTableView ────────────────────────────────────────────────────────
function SortableTableView ( {
sessions , sortCol , sortDir , onSort ,
sessions ,
sortCol ,
sortDir ,
onSort ,
} : {
sessions : AnySession [ ] ;
sortCol : SortCol ;
@@ -228,7 +343,10 @@ function SortableTableView({
}
return (
< div className = "rounded-xl border border-border overflow-hidden overflow-x-auto bg-card" >
< div className = "grid bg-card-hover/60 border-b border-border" style = { { gridTemplateColumns : TABLE_COLS } } >
< div
className = "grid bg-card-hover/60 border-b border-border"
style = { { gridTemplateColumns : TABLE_COLS } }
>
{ SORT_COLUMNS . map ( ( col ) = > (
< button
key = { col . key }
@@ -258,20 +376,39 @@ function SortableTableView({
// ─── WorkshopTabs ─────────────────────────────────────────────────────────────
export function WorkshopTabs ( {
swotSessions , motivatorSessions , yearReviewSessions ,
weeklyCheckInSessions , weatherSessions , gifMood Sessions,
swotSessions ,
motivator Sessions,
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 < CardView > ( 'grid' ) ;
const [ cardView , setCardView ] = useState < CardView > ( ( ) = > {
if ( typeof window === 'undefined' ) return 'grid' ;
const storedView = localStorage . getItem ( CARD_VIEW_STORAGE_KEY ) ;
return storedView && isCardView ( storedView ) ? storedView : 'grid' ;
} ) ;
const [ sortCol , setSortCol ] = useState < SortCol > ( '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' ) ; }
else {
setSortCol ( col ) ;
setSortDir ( 'asc' ) ;
}
} ;
const tabParam = searchParams . get ( 'tab' ) ;
@@ -288,18 +425,29 @@ export function WorkshopTabs({
} ;
const allSessions : AnySession [ ] = [
. . . swotSessions , . . . motivatorSessions , . . . yearReviewSessions ,
. . . weeklyCheckInSessions , . . . weatherSessions , . . . gifMood Sessions,
. . . swotSessions ,
. . . motivator Sessions,
. . . 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' ? teamCollab Sessions
: activeTab === 'swot' ? swotSessions
: activeTab === 'motivators' ? motivator Sessions
: activeTab === 'year-review' ? yearReviewSessions
: activeTab === 'weekly-checkin' ? weeklyCheckIn Sessions
: activeTab === 'gif-mood' ? gifMoodSessions
activeTab === 'all' || activeTab === 'byPerson'
? all Sessions
: activeTab === 'team'
? teamCollab Sessions
: activeTab === 'swot'
? swot Sessions
: activeTab === 'motivators'
? motivatorSessions
: activeTab === 'year-review'
? yearReviewSessions
: activeTab === 'weekly-checkin'
? weeklyCheckInSessions
: activeTab === 'gif-mood'
? gifMoodSessions
: weatherSessions ;
const ownedSessions = filteredSessions . filter ( ( s ) = > s . isOwner ) ;
@@ -309,11 +457,14 @@ export function WorkshopTabs({
const teamCollabFiltered = activeTab === 'all' ? teamCollabSessions : [ ] ;
const sessionsByPerson = groupByPerson ( allSessions ) ;
const sortedPersons = Array . from ( sessionsByPerson . entries ( ) ) . sort ( ( a , b ) = > a [ 0 ] . localeCompare ( b [ 0 ] , 'fr' ) ) ;
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 timelineSessions = [
. . . ( activeTab === 'all' ? [ . . . filteredSessions , . . . teamCollabSessions ] : filteredSessions ) ,
] . sort ( ( a , b ) = > new Date ( b . updatedAt ) . getTime ( ) - new Date ( a . updatedAt ) . getTime ( ) ) ;
const byMonth = new Map < string , AnySession [ ] > ( ) ;
timelineSessions . forEach ( ( s ) = > {
const key = getMonthGroup ( s . updatedAt ) ;
@@ -326,7 +477,8 @@ export function WorkshopTabs({
cardView === 'table' && activeTab !== 'byPerson'
? sortSessions (
activeTab === 'all' ? [ . . . filteredSessions , . . . teamCollabSessions ] : filteredSessions ,
sortCol , sortDir ,
sortCol ,
sortDir
)
: [ ] ;
@@ -334,19 +486,42 @@ export function WorkshopTabs({
< div className = "space-y-8" >
{ /* Tabs + vue toggle */ }
< div className = "flex gap-1.5 items-center flex-wrap" >
< TabButton active = { activeTab === 'all' } onClick = { ( ) = > setActiveTab ( 'all' ) } icon = "📋" label = "Tous" count = { allSessions . length } / >
< TabButton active = { activeTab === 'byPerson' } onClick = { ( ) = > setActiveTab ( 'byPerson' ) } icon = "👥" label = "Par personne" count = { sessionsByPerson . size } / >
< TabButton
active = { activeTab === 'all' }
onClick = { ( ) = > setActiveTab ( 'all' ) }
icon = "📋"
label = "Tous"
count = { allSessions . length }
/ >
< TabButton
active = { activeTab === 'byPerson' }
onClick = { ( ) = > setActiveTab ( 'byPerson' ) }
icon = "👥"
label = "Par personne"
count = { sessionsByPerson . size }
/ >
{ teamCollabSessions . length > 0 && (
< TabButton active = { activeTab === 'team' } onClick = { ( ) = > setActiveTab ( 'team' ) } icon = "🏢" label = "Équipe" count = { teamCollabSessions . length } / >
< TabButton
active = { activeTab === 'team' }
onClick = { ( ) = > setActiveTab ( 'team' ) }
icon = "🏢"
label = "Équipe"
count = { teamCollabSessions . length }
/ >
) }
< div className = "h-5 w-px bg-border mx-0.5 self-center" / >
< TypeFilterDropdown
activeTab = { activeTab } setActiveTab = { setActiveTab }
open = { typeDropdownOpen } onOpenChange = { setTypeDropdownOpen }
activeTab = { activeTab }
setActiveTab = { setActiveTab }
open = { typeDropdownOpen }
onOpenChange = { setTypeDropdownOpen }
counts = { {
swot : swotSessions.length , motivators : motivatorSessions.length ,
'year-review' : yearReviewSessions . length , 'weekly-checkin' : weeklyCheckIn Sessions. length,
weather : weatherSessions.length , 'gif-mood' : gifMood Sessions. length ,
swot : swotSessions.length ,
motivators : motivator Sessions. length,
'year-review' : yearReview Sessions. length ,
'weekly-checkin' : weeklyCheckInSessions . length ,
weather : weatherSessions.length ,
'gif-mood' : gifMoodSessions . length ,
team : teamCollabSessions.length ,
} }
/ >
@@ -355,8 +530,12 @@ export function WorkshopTabs({
{ /* ── Vue Tableau flat (colonnes triables) ──────────────────── */ }
{ cardView === 'table' && activeTab !== 'byPerson' ? (
< SortableTableView sessions = { flatTableSessions } sortCol = { sortCol } sortDir = { sortDir } onSort = { handleSort } / >
< SortableTableView
sessions = { flatTableSessions }
sortCol = { sortCol }
sortDir = { sortDir }
onSort = { handleSort }
/ >
) : cardView === 'timeline' && activeTab !== 'byPerson' ? (
/* ── Vue Timeline ────────────────────────────────────────── */
byMonth . size === 0 ? (
@@ -367,19 +546,25 @@ export function WorkshopTabs({
< section key = { period } >
< div className = "flex items-center gap-3 mb-4" >
< div className = "h-px flex-1 bg-border" / >
< span className = "text-xs font-semibold text-muted uppercase tracking-widest px-2 capitalize" > { period } < / span >
< span className = "text-xs font-semibold text-muted uppercase tracking-widest px-2 capitalize" >
{ period }
< / span >
< div className = "h-px flex-1 bg-border" / >
< / div >
< div className = "flex flex-col gap-2" >
{ sessions . map ( ( s ) = > (
< SessionCard key = { s . id } session = { s } isTeamCollab = { ( s as AnySession & { isTeamCollab? : boolean } ) . isTeamCollab } view = "list" / >
< SessionCard
key = { s . id }
session = { s }
isTeamCollab = { ( s as AnySession & { isTeamCollab? : boolean } ) . isTeamCollab }
view = "list"
/ >
) ) }
< / div >
< / section >
) ) }
< / div >
)
) : activeTab === 'byPerson' ? (
/* ── Vue Par personne ───────────────────────────────────── */
sortedPersons . length === 0 ? (
@@ -396,21 +581,28 @@ export function WorkshopTabs({
{ sessions . length } atelier { sessions . length > 1 ? 's' : '' }
< / span >
< / div >
< SessionsGrid sessions = { sessions } view = { cardView === 'timeline' ? 'list' : cardView } / >
< SessionsGrid
sessions = { sessions }
view = { cardView === 'timeline' ? 'list' : cardView }
/ >
< / section >
) ;
} ) }
< / div >
)
) : activeTab === 'team' ? (
/* ── Vue Équipe ─────────────────────────────────────────── */
teamCollabSessions . length === 0 ? (
< div className = "text-center py-12 text-muted" > Aucun atelier de vos collaborateurs ( non partagés ) < / div >
< div className = "text-center py-12 text-muted" >
Aucun atelier de vos collaborateurs ( non partagés )
< / div >
) : (
< div className = "space-y-8" >
< section >
< SectionHeader label = "Ateliers de l'équipe – non partagés" count = { teamCollabSessions . length } / >
< SectionHeader
label = "Ateliers de l'équipe – non partagés"
count = { teamCollabSessions . length }
/ >
< p className = "text-sm text-muted mb-5 -mt-2" >
En tant qu & apos ; admin d & apos ; é quipe , vous voyez les ateliers de vos collaborateurs
qui ne vous sont pas encore partagés .
@@ -419,10 +611,8 @@ export function WorkshopTabs({
< / section >
< / div >
)
) : filteredSessions . length === 0 ? (
< div className = "text-center py-12 text-muted" > Aucun atelier de ce type pour le moment < / div >
) : (
/* ── Vue normale (tous / par type) ─────────────────────── */
< div className = "space-y-10" >