"use client"; import { useRef, useState } from "react"; import { Upload, User, X } from "lucide-react"; import { addDocumentToProject, createProject, uploadProjectDocument, } from "@/app/lib/mikeApi"; import { FileDirectory } from "../shared/FileDirectory"; import { AddUserInput } from "../shared/AddUserInput"; import type { Document, Project } from "../shared/types"; import type { UserLookupResult } from "@/app/lib/mikeApi"; import { useAuth } from "@/app/contexts/AuthContext"; import { Modal } from "../modals/Modal"; import { ModalFieldLabel } from "../modals/ModalFieldLabel"; import { ModalTextInput } from "../modals/ModalTextInput"; import { ProjectPracticeField } from "./ProjectPracticeField"; interface Props { open: boolean; onClose: () => void; onCreated: (project: Project) => void; } export function NewProjectModal({ open, onClose, onCreated }: Props) { const [step, setStep] = useState<"details" | "documents">("details"); const [name, setName] = useState(""); const [cmNumber, setCmNumber] = useState(""); const [practice, setPractice] = useState(""); const [sharedUsers, setSharedUsers] = useState([]); const [selectedDocuments, setSelectedDocuments] = useState([]); const [pendingFiles, setPendingFiles] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const fileInputRef = useRef(null); const { user } = useAuth(); const ownEmail = user?.email?.trim().toLowerCase() ?? null; const formId = "new-project-modal-form"; if (!open) return null; function submitterValue(e: React.FormEvent) { return ( (e.nativeEvent as SubmitEvent).submitter as | HTMLButtonElement | null )?.value; } function handleFileChange(e: React.ChangeEvent) { const files = Array.from(e.target.files ?? []); e.target.value = ""; if (!files.length) return; setPendingFiles((prev) => [...prev, ...files.filter((f) => !prev.some((p) => p.name === f.name))]); } async function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (!name.trim()) return; if (step === "details" || submitterValue(e) !== "create-project") { setStep("documents"); return; } setLoading(true); setError(""); try { const project = await createProject( name.trim(), cmNumber.trim() || undefined, practice.trim() && practice.trim() !== "Other" ? practice.trim() : undefined, ownEmail ? sharedUsers .map((user) => user.email) .filter((email) => email !== ownEmail) : sharedUsers.map((user) => user.email), ); await Promise.all([ ...selectedDocuments.map((document) => addDocumentToProject(project.id, document.id).catch(() => {}), ), ...pendingFiles.map((f) => uploadProjectDocument(project.id, f).catch(() => {})), ]); onCreated({ ...project, document_count: selectedDocuments.length + pendingFiles.length, }); resetForm(); onClose(); } catch (err: unknown) { setError((err as Error).message || "Failed to create project"); } finally { setLoading(false); } } function resetForm() { setStep("details"); setName(""); setCmNumber(""); setPractice(""); setSharedUsers([]); setSelectedDocuments([]); setPendingFiles([]); setError(""); } function handleClose() { resetForm(); onClose(); } function validateShareUser(email: string) { if (ownEmail && email === ownEmail) { return "You cannot share a project with yourself."; } if ( sharedUsers.some( (user) => user.email.trim().toLowerCase() === email, ) ) { return `${email} already has access.`; } return null; } function handleAddShareUser(user: UserLookupResult) { setSharedUsers((prev) => [ ...prev, { ...user, email: user.email.trim().toLowerCase(), }, ]); } function handleRemoveShareUser(email: string) { setSharedUsers((prev) => prev.filter( (user) => user.email.trim().toLowerCase() !== email.trim().toLowerCase(), ), ); } return ( 0 ? ` (${pendingFiles.length})` : ""}`, icon: , onClick: () => fileInputRef.current?.click(), disabled: loading, } : undefined } cancelAction={ step === "documents" ? { label: "Back", onClick: () => setStep("details"), disabled: loading, } : undefined } primaryAction={ step === "details" ? { label: "Next", type: "button", onClick: (event) => { event.preventDefault(); setStep("documents"); }, disabled: !name.trim() || loading, } : { label: loading ? "Creating…" : "Create project", type: "submit", form: formId, name: "modalAction", value: "create-project", disabled: !name.trim() || loading, } } >
{step === "details" ? (
Project name setName(e.target.value)} placeholder="Add project name" variant="minimal" autoFocus />
CM number setCmNumber(e.target.value)} placeholder="Add a CM number..." variant="minimal" className="text-xl text-gray-600" />
Practice
Share with {sharedUsers.length > 0 && (
    {sharedUsers.map((entry) => { const displayName = entry.display_name?.trim(); const primary = displayName || "User"; const initial = displayName ?.charAt(0) .toUpperCase(); return (
  • {initial ? ( {initial} ) : ( )}

    {primary} {" "} · {entry.email}

  • ); })}
)}
) : (
)} {error && (

{error}

)}
); }