import { useState, useEffect, useMemo } from 'react' import { useAuthStore } from '../../store/authStore' import { useTranslation } from '../../i18n' import { MessageCircle, StickyNote, BarChart3, Sparkles } from 'lucide-react' import CollabChat from './CollabChat' import CollabNotes from './CollabNotes' import CollabPolls from './CollabPolls' import WhatsNextWidget from './WhatsNextWidget' function useIsDesktop(breakpoint = 1024) { const [isDesktop, setIsDesktop] = useState(window.innerWidth >= breakpoint) useEffect(() => { const check = () => setIsDesktop(window.innerWidth >= breakpoint) window.addEventListener('resize', check) return () => window.removeEventListener('resize', check) }, [breakpoint]) return isDesktop } const card = { display: 'flex', flexDirection: 'column', background: 'var(--bg-card)', borderRadius: 16, border: '1px solid var(--border-faint)', overflow: 'hidden', minHeight: 0, } interface TripMember { id: number username: string avatar_url?: string | null } interface CollabFeatures { chat: boolean notes: boolean polls: boolean whatsnext: boolean } interface CollabPanelProps { tripId: number tripMembers?: TripMember[] collabFeatures?: CollabFeatures } const ALL_TABS = [ { id: 'chat', featureKey: 'chat' as const, labelKey: 'collab.tabs.chat', fallback: 'Chat', icon: MessageCircle }, { id: 'notes', featureKey: 'notes' as const, labelKey: 'collab.tabs.notes', fallback: 'Notes', icon: StickyNote }, { id: 'polls', featureKey: 'polls' as const, labelKey: 'collab.tabs.polls', fallback: 'Polls', icon: BarChart3 }, { id: 'next', featureKey: 'whatsnext' as const, labelKey: 'collab.whatsNext.title', fallback: "What's Next", icon: Sparkles }, ] export default function CollabPanel({ tripId, tripMembers = [], collabFeatures }: CollabPanelProps) { const { user } = useAuthStore() const { t } = useTranslation() const isDesktop = useIsDesktop() const features = collabFeatures || { chat: true, notes: true, polls: true, whatsnext: true } const tabs = useMemo(() => ALL_TABS.filter(tab => features[tab.featureKey]).map(tab => ({ ...tab, label: t(tab.labelKey) || tab.fallback, })), [features, t]) const [mobileTab, setMobileTab] = useState(() => tabs[0]?.id || 'chat') // If active tab gets disabled, switch to first available useEffect(() => { if (tabs.length > 0 && !tabs.some(t => t.id === mobileTab)) { setMobileTab(tabs[0].id) } }, [tabs, mobileTab]) const chatOn = features.chat const rightPanels = [ features.notes && 'notes', features.polls && 'polls', features.whatsnext && 'whatsnext', ].filter(Boolean) as string[] if (tabs.length === 0) return null if (isDesktop) { // Chat always 380px fixed when on. Right panels share remaining space. // If chat off, all panels share full width equally. if (chatOn && rightPanels.length === 0) { // Only chat return (
) } if (chatOn) { // Chat left (380px) + right panels return (
{rightPanels.length === 1 && (
{rightPanels[0] === 'notes' && } {rightPanels[0] === 'polls' && } {rightPanels[0] === 'whatsnext' && }
)} {rightPanels.length === 2 && rightPanels.map(p => (
{p === 'notes' && } {p === 'polls' && } {p === 'whatsnext' && }
))} {rightPanels.length === 3 && ( <>
)}
) } // Chat off — remaining panels share full width const panels = rightPanels if (panels.length === 1) { return (
{panels[0] === 'notes' && } {panels[0] === 'polls' && } {panels[0] === 'whatsnext' && }
) } return (
{panels.map(p => (
{p === 'notes' && } {p === 'polls' && } {p === 'whatsnext' && }
))}
) } // Mobile: tab bar + single panel (only enabled tabs) return (
{tabs.map(tab => { const active = mobileTab === tab.id return ( ) })}
{mobileTab === 'chat' && features.chat && } {mobileTab === 'notes' && features.notes && } {mobileTab === 'polls' && features.polls && } {mobileTab === 'next' && features.whatsnext && }
) }