import { useCallback, useMemo } from 'react'; import { useAppTranslation } from '@features/localization/renderer'; import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip'; import { useStore } from '@renderer/store'; import { resolveProjectIdByPath } from '@renderer/utils/projectLookup'; import { formatSessionLabel } from '@renderer/utils/sessionTitleParser'; import { formatDistanceToNowStrict } from 'date-fns'; import { AlertCircle, Crown, ExternalLink, Filter, FilterX, Loader2, MessageSquare, Monitor, } from 'lucide-react'; import { useShallow } from 'zustand/react/shallow'; import type { Session } from '@renderer/types/data'; interface TeamSessionsSectionProps { sessions: Session[]; sessionsLoading: boolean; sessionsError: string | null; leadSessionId?: string; selectedSessionId: string | null; onSelectSession: (sessionId: string | null) => void; projectPath?: string; } export const TeamSessionsSection = ({ sessions, sessionsLoading, sessionsError, leadSessionId, selectedSessionId, onSelectSession, projectPath, }: TeamSessionsSectionProps): React.JSX.Element => { const { t } = useAppTranslation('team'); const { openTab, selectSession, projects, repositoryGroups } = useStore( useShallow((s) => ({ openTab: s.openTab, selectSession: s.selectSession, projects: s.projects, repositoryGroups: s.repositoryGroups, })) ); const projectId = useMemo( () => resolveProjectIdByPath(projectPath, projects, repositoryGroups), [projects, repositoryGroups, projectPath] ); // Sort: lead session first, then by most recent const sortedSessions = useMemo(() => { if (!leadSessionId) return sessions; return [...sessions].sort((a, b) => { if (a.id === leadSessionId) return -1; if (b.id === leadSessionId) return 1; return b.createdAt - a.createdAt; }); }, [sessions, leadSessionId]); const handleSessionClick = useCallback( (session: Session) => { if (!projectId) return; openTab( { type: 'session', sessionId: session.id, projectId, label: formatSessionLabel(session.firstMessage), }, { forceNewTab: true } ); selectSession(session.id); }, [projectId, openTab, selectSession] ); if (!projectPath) { return (
{t('sessions.noProjectPath')}

{t('sessions.provisioningHint')}

); } if (!projectId) { return (
{t('sessions.projectNotFound')}

{projectPath}

); } if (sessionsLoading) { return (
{t('sessions.loading')}
); } if (sessionsError) { return (
{sessionsError}
); } if (sortedSessions.length === 0) { return (
{t('sessions.empty')}
); } return (
{selectedSessionId !== null && ( )} {sortedSessions.map((session) => ( handleSessionClick(session)} onToggleFilter={() => onSelectSession(session.id === selectedSessionId ? null : session.id) } leadLabel={t('sessions.lead')} removeFilterLabel={t('sessions.removeFilter')} filterBySessionLabel={t('sessions.filterBySession')} openSessionLabel={t('sessions.openSession')} /> ))}
); }; // --------------------------------------------------------------------------- // Session row // --------------------------------------------------------------------------- interface SessionRowProps { session: Session; isLead: boolean; isSelected: boolean; onClick: () => void; onToggleFilter: () => void; leadLabel: string; removeFilterLabel: string; filterBySessionLabel: string; openSessionLabel: string; } const SessionRow = ({ session, isLead, isSelected, onClick, onToggleFilter, leadLabel, removeFilterLabel, filterBySessionLabel, openSessionLabel, }: SessionRowProps): React.JSX.Element => { const timeAgo = formatShortTime(new Date(session.createdAt)); const label = formatSessionLabel(session.firstMessage); return (
{isLead && }
{isSelected ? removeFilterLabel : filterBySessionLabel} {openSessionLabel}
); }; // --------------------------------------------------------------------------- // Helpers // --------------------------------------------------------------------------- function formatShortTime(date: Date): string { const distance = formatDistanceToNowStrict(date, { addSuffix: false }); return distance .replace(' seconds', 's') .replace(' second', 's') .replace(' minutes', 'm') .replace(' minute', 'm') .replace(' hours', 'h') .replace(' hour', 'h') .replace(' days', 'd') .replace(' day', 'd') .replace(' weeks', 'w') .replace(' week', 'w') .replace(' months', 'mo') .replace(' month', 'mo') .replace(' years', 'y') .replace(' year', 'y'); }