diff --git a/src/app/projects/components/ProjectFormModal.tsx b/src/app/projects/components/ProjectFormModal.tsx index 6e1a38a..86ee72b 100644 --- a/src/app/projects/components/ProjectFormModal.tsx +++ b/src/app/projects/components/ProjectFormModal.tsx @@ -2,11 +2,14 @@ import { useMemo, useState } from "react"; import { FolderArchive, Loader2, LucideRocket, X } from "lucide-react"; -import type { ProjectCreateBody, ProjectRecord } from "@/lib/api"; +import type { ProjectCreateBody, ProjectRecord, Server } from "@/lib/api"; +import SearchableSelect from "@/components/SearchableSelect"; +import type { SearchableSelectOption } from "@/components/SearchableSelect"; interface ProjectFormModalProps { project?: ProjectRecord; submitting: boolean; + servers?: Server[]; onClose: () => void; onSubmit: (payload: ProjectCreateBody) => Promise; } @@ -14,21 +17,41 @@ interface ProjectFormModalProps { export default function ProjectFormModal({ project, submitting, + servers, onClose, onSubmit, }: ProjectFormModalProps) { const isEditing = Boolean(project); const [name, setName] = useState(project?.name ?? ""); const [description, setDescription] = useState(project?.description ?? ""); + const [serverId, setServerId] = useState(""); const [error, setError] = useState(""); - const canSubmit = useMemo(() => name.trim().length >= 2, [name]); + const canSubmit = useMemo( + () => name.trim().length >= 5 && (isEditing || serverId), + [name, isEditing, serverId], + ); + + const serverOptions: SearchableSelectOption[] = useMemo( + () => + (servers ?? []).map((s) => ({ + value: s.id, + label: s.name, + keywords: `${s.ip} ${s.os ?? ""}`, + description: `${s.ip} — ${s.status}`, + })), + [servers], + ); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); if (!canSubmit) { - setError("Lengkapi nama project minimal 2 karakter."); + setError( + isEditing + ? "Complete the project name (minimum 5 characters)." + : "Select a server and enter the project name.", + ); return; } @@ -36,7 +59,17 @@ export default function ProjectFormModal({ const payload = { name: name.trim(), description: description.trim(), - ...(isEditing ? {} : { environments: [] }), + ...(isEditing + ? {} + : { + environments: [ + { + name: "Development", + kind: "DEVELOPMENT" as const, + serverId, + }, + ], + }), }; await onSubmit(payload); @@ -67,134 +100,170 @@ export default function ProjectFormModal({ padding: 28, }} > -
-
-

- - {isEditing ? "Project Detail/Ops" : "Create New Project"} -

-

- {isEditing - ? "Update project information used across environments and deployments." - : "Create a new project to manage your environments and deployments."} -

-
-
- -
-
- - setName(event.target.value)} - placeholder="Project name, e.g. Doktainer App" - minLength={5} - maxLength={35} - style={{ width: "100%" }} - /> -
-
- -