"use client"; import { useState, useCallback, useEffect } from "react"; import { useRouter } from "next/navigation"; import { Button } from "@/components/ui/button"; import { HugeiconsIcon } from "@hugeicons/react"; import { Loading02Icon } from "@hugeicons/core-free-icons"; import { useTranslation } from "@/hooks/useTranslation"; interface FileStatus { exists: boolean; chars: number; preview: string; } interface WorkspaceState { onboardingComplete: boolean; lastCheckInDate: string | null; schemaVersion: number; } interface WorkspaceInfo { path: string | null; exists?: boolean; files: Record; state: WorkspaceState | null; } const FILE_LABELS: Record = { claude: "claude.md", soul: "soul.md", user: "user.md", memory: "memory.md", }; export function AssistantWorkspaceSection() { const { t } = useTranslation(); const router = useRouter(); const [workspace, setWorkspace] = useState(null); const [loading, setLoading] = useState(true); const [initializing, setInitializing] = useState(false); const [refreshingDocs, setRefreshingDocs] = useState(false); const [pathInput, setPathInput] = useState(""); const [creatingSession, setCreatingSession] = useState(false); const fetchWorkspace = useCallback(async () => { try { const res = await fetch("/api/settings/workspace"); if (res.ok) { const data = await res.json(); setWorkspace(data); if (data.path) setPathInput(data.path); } } catch (e) { console.error("Failed to fetch workspace:", e); } finally { setLoading(false); } }, []); useEffect(() => { fetchWorkspace(); }, [fetchWorkspace]); const handleSavePath = useCallback(async (initialize: boolean) => { if (!pathInput.trim()) return; if (initialize) setInitializing(true); try { const res = await fetch("/api/settings/workspace", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ path: pathInput.trim(), initialize }), }); if (res.ok) { await fetchWorkspace(); } } catch (e) { console.error("Failed to save workspace path:", e); } finally { setInitializing(false); } }, [pathInput, fetchWorkspace]); const handleSelectFolder = useCallback(async () => { try { const w = window as unknown as { electronAPI?: { selectFolder?: () => Promise } }; if (w.electronAPI?.selectFolder) { const selected = await w.electronAPI.selectFolder(); if (selected) { setPathInput(selected); } } else { const input = prompt("Enter workspace directory path:"); if (input) setPathInput(input); } } catch (e) { console.error("Failed to select folder:", e); } }, []); const handleRefreshDocs = useCallback(async () => { setRefreshingDocs(true); try { await fetch("/api/workspace/docs", { method: "POST" }); } catch (e) { console.error("Failed to refresh docs:", e); } finally { setRefreshingDocs(false); } }, []); /** Create a new onboarding session in the assistant project folder and navigate to it */ const handleStartOnboarding = useCallback(async () => { if (!workspace?.path) return; setCreatingSession(true); try { const model = typeof window !== 'undefined' ? localStorage.getItem('codepilot:last-model') || '' : ''; const provider_id = typeof window !== 'undefined' ? localStorage.getItem('codepilot:last-provider-id') || '' : ''; const res = await fetch("/api/workspace/session", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ mode: 'onboarding', model, provider_id }), }); if (res.ok) { const data = await res.json(); window.dispatchEvent(new CustomEvent("session-created")); router.push(`/chat/${data.session.id}`); } } catch (e) { console.error("Failed to create onboarding session:", e); } finally { setCreatingSession(false); } }, [workspace?.path, router]); /** Create or reuse a check-in session in the assistant project folder and navigate to it */ const handleStartCheckIn = useCallback(async () => { if (!workspace?.path) return; setCreatingSession(true); try { const model = typeof window !== 'undefined' ? localStorage.getItem('codepilot:last-model') || '' : ''; const provider_id = typeof window !== 'undefined' ? localStorage.getItem('codepilot:last-provider-id') || '' : ''; const res = await fetch("/api/workspace/session", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ mode: 'checkin', model, provider_id }), }); if (res.ok) { const data = await res.json(); window.dispatchEvent(new CustomEvent("session-created")); router.push(`/chat/${data.session.id}`); } } catch (e) { console.error("Failed to create check-in session:", e); } finally { setCreatingSession(false); } }, [workspace?.path, router]); if (loading) { return (
); } const today = new Date().toISOString().slice(0, 10); const checkInDoneToday = workspace?.state?.lastCheckInDate === today; return (
{/* Workspace Path Card */}

{t('assistant.workspacePath')}

{t('assistant.workspacePathHint')}

setPathInput(e.target.value)} placeholder="/path/to/workspace" className="flex-1 rounded-md border border-border/50 bg-background px-3 py-1.5 text-sm" />
{/* File Status Card */} {workspace?.path && (

{t('assistant.fileStatus')}

{Object.entries(FILE_LABELS).map(([key, label]) => { const file = workspace.files[key]; return (
{label}
{file?.exists ? ( <> {t('assistant.fileChars', { count: String(file.chars) })} {t('assistant.fileExists')} ) : ( <> {t('assistant.fileMissing')} )}
); })}
)} {/* Onboarding Status Card */} {workspace?.path && (

{t('assistant.onboardingTitle')}

{t('assistant.onboardingDesc')}

{workspace.state?.onboardingComplete ? {t('assistant.onboardingComplete')} : {t('assistant.onboardingNotStarted')} }

)} {/* Daily Check-in Card */} {workspace?.path && (

{t('assistant.checkInTitle')}

{t('assistant.checkInDesc')}

{workspace.state?.lastCheckInDate && ( {t('assistant.lastCheckIn')}: {workspace.state.lastCheckInDate} )} {" "} {checkInDoneToday ? {t('assistant.checkInToday')} : {t('assistant.checkInNeeded')} }

)} {/* Directory Docs Card */} {workspace?.path && (

{t('assistant.refreshDocs')}

)}
); }