import { useId, useRef, useState } from "react"; import { open } from "@tauri-apps/plugin-dialog"; import { useProjects } from "../../hooks/useProjects"; import type { ProjectPath } from "../../lib/types"; import Modal from "../ui/Modal"; import Button from "../ui/Button"; import { inputClass, monoInputClass } from "../ui/Field"; interface Props { onClose: () => void; } interface PathEntry { host_path: string; mount_name: string; } function basenameFromPath(p: string): string { return p.replace(/[/\\]$/, "").split(/[/\\]/).pop() || ""; } export default function AddProjectDialog({ onClose }: Props) { const { add } = useProjects(); const [name, setName] = useState(""); const [pathEntries, setPathEntries] = useState([ { host_path: "", mount_name: "" }, ]); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); const nameInputRef = useRef(null); const formId = useId(); const handleBrowse = async (index: number) => { const selected = await open({ directory: true, multiple: false }); if (typeof selected === "string") { const basename = basenameFromPath(selected); const entries = [...pathEntries]; entries[index] = { host_path: selected, mount_name: entries[index].mount_name || basename, }; setPathEntries(entries); // Auto-fill project name from first folder if (!name && index === 0) { setName(basename); } } }; const updateEntry = (index: number, field: keyof PathEntry, value: string) => { const entries = [...pathEntries]; entries[index] = { ...entries[index], [field]: value }; setPathEntries(entries); }; const handleSubmit = async (e?: React.FormEvent) => { if (e) e.preventDefault(); if (!name.trim()) { setError("Project name is required"); return; } const validPaths: ProjectPath[] = pathEntries .filter((p) => p.host_path.trim()) .map((p) => ({ host_path: p.host_path.trim(), mount_name: p.mount_name.trim() || basenameFromPath(p.host_path), })); if (validPaths.length === 0) { setError("At least one folder path is required"); return; } const mountNames = validPaths.map((p) => p.mount_name); if (new Set(mountNames).size !== mountNames.length) { setError("Mount names must be unique"); return; } setLoading(true); setError(null); try { await add(name.trim(), validPaths); onClose(); } catch (err) { setError(String(err)); } finally { setLoading(false); } }; return ( } >
setName(e.target.value)} placeholder="my-project" className={inputClass} />
Folders
{pathEntries.map((entry, i) => (
updateEntry(i, "host_path", e.target.value)} placeholder="/path/to/folder" aria-label={`Folder ${i + 1} host path`} className={inputClass} /> {pathEntries.length > 1 && ( )}
/workspace/ updateEntry(i, "mount_name", e.target.value)} placeholder="mount-name" aria-label={`Folder ${i + 1} mount name`} className={monoInputClass} />
))}
{error && (
{error}
)}
); }