// ======================================== // SessionDetailPage Component // ======================================== // Session detail page with tabs for tasks, context, summary, impl-plan, conflict, and review import * as React from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useIntl } from 'react-intl'; import { ArrowLeft, Calendar, ListChecks, Package, FileText, XCircle, Ruler, Scale, Search, } from 'lucide-react'; import { useSessionDetail } from '@/hooks/useSessionDetail'; import { TaskListTab } from './session-detail/TaskListTab'; import { ContextTab } from './session-detail/ContextTab'; import { SummaryTab } from './session-detail/SummaryTab'; import ImplPlanTab from './session-detail/ImplPlanTab'; import { ConflictTab } from './session-detail/ConflictTab'; import { ReviewTab } from './session-detail/ReviewTab'; import { TaskDrawer } from '@/components/shared/TaskDrawer'; import { Button } from '@/components/ui/Button'; import { Badge } from '@/components/ui/Badge'; import { TabsNavigation, type TabItem } from '@/components/ui/TabsNavigation'; import type { TaskData, SessionMetadata } from '@/types/store'; type TabValue = 'tasks' | 'context' | 'summary' | 'impl-plan' | 'conflict' | 'review'; // Status label keys for i18n (maps snake_case status to camelCase translation keys) const statusLabelKeys: Record = { planning: 'sessions.status.planning', in_progress: 'sessions.status.inProgress', completed: 'sessions.status.completed', archived: 'sessions.status.archived', paused: 'sessions.status.paused', }; /** * SessionDetailPage component - Main session detail page with tabs */ export function SessionDetailPage() { const { sessionId } = useParams<{ sessionId: string }>(); const navigate = useNavigate(); const { formatMessage } = useIntl(); const { sessionDetail, isLoading, error, refetch } = useSessionDetail(sessionId!); const [activeTab, setActiveTab] = React.useState('tasks'); const [selectedTask, setSelectedTask] = React.useState(null); const handleBack = () => { navigate('/sessions'); }; // Loading state if (isLoading) { return (
); } // Error state if (error) { return (

{formatMessage({ id: 'common.errors.loadFailed' })}

{error.message}

); } // Session not found if (!sessionDetail) { return (

{formatMessage({ id: 'sessionDetail.notFound.title' })}

{formatMessage({ id: 'sessionDetail.notFound.message' })}

); } const { session, context, summary, summaries, implPlan, conflicts, review } = sessionDetail; const tasks = session.tasks || []; const completedTasks = tasks.filter((t) => t.status === 'completed').length; const hasReview = session.has_review || session.review; const tabs: TabItem[] = [ { value: 'tasks', label: formatMessage({ id: 'sessionDetail.tabs.tasks' }), icon: , badge: {tasks.length}, }, { value: 'context', label: formatMessage({ id: 'sessionDetail.tabs.context' }), icon: , }, { value: 'summary', label: formatMessage({ id: 'sessionDetail.tabs.summary' }), icon: , }, { value: 'impl-plan', label: formatMessage({ id: 'sessionDetail.tabs.implPlan' }), icon: , }, { value: 'conflict', label: formatMessage({ id: 'sessionDetail.tabs.conflict' }), icon: , }, ]; if (hasReview) { tabs.push({ value: 'review', label: formatMessage({ id: 'sessionDetail.tabs.review' }), icon: , }); } return (
{/* Header */}

{session.title || session.session_id}

{session.title && session.title !== session.session_id && (

{session.session_id}

)}
{formatMessage({ id: statusLabelKeys[session.status] ?? 'sessions.status.inProgress' })}
{/* Info Bar */}
{formatMessage({ id: 'sessionDetail.info.created' })}:{' '} {new Date(session.created_at).toLocaleString()}
{session.updated_at && (
{formatMessage({ id: 'sessionDetail.info.updated' })}:{' '} {new Date(session.updated_at).toLocaleString()}
)}
{formatMessage({ id: 'sessionDetail.info.tasks' })}:{' '} {completedTasks}/{tasks.length}
{/* Tabs */} setActiveTab(v as TabValue)} tabs={tabs} /> {/* Tab Content */} {activeTab === 'tasks' && (
)} {activeTab === 'context' && (
)} {activeTab === 'summary' && (
)} {activeTab === 'impl-plan' && (
)} {activeTab === 'conflict' && (
)} {hasReview && activeTab === 'review' && (
)} {/* Description (if exists) */} {session.description && (

{formatMessage({ id: 'sessionDetail.info.description' })}

{session.description}

)} {/* TaskDrawer */} setSelectedTask(null)} />
); } export default SessionDetailPage;