import * as React from "react"; import type { Project } from "@/features/projects/hooks"; import type { AddProjectRepositoryInput } from "@/features/projects/useAddProjectRepository"; import type { Channel } from "@/shared/api/types"; import { cn } from "@/shared/lib/cn"; import { Button } from "@/shared/ui/button"; import { ChooserDialogContent } from "@/shared/ui/chooser-dialog-content"; import { Dialog } from "@/shared/ui/dialog"; import { Input } from "@/shared/ui/input"; const FIELD_SHELL_CLASS = "flex min-h-11 items-center rounded-xl border border-input bg-muted/40 px-3 transition-colors hover:border-muted-foreground/40 focus-within:border-muted-foreground/50"; const FIELD_CONTROL_CLASS = "h-8 border-0 bg-transparent px-0 py-0 text-muted-foreground/55 shadow-none outline-none ring-0 placeholder:text-muted-foreground/55 focus:bg-transparent focus:text-foreground focus-visible:ring-0"; export function AddProjectRepositoryDialog({ accessChannelId, channels, isCreating, onAdd, onOpenChange, open, project, }: { accessChannelId?: string; channels: Channel[]; isCreating: boolean; onAdd: (input: AddProjectRepositoryInput) => Promise; onOpenChange: (open: boolean) => void; open: boolean; project: Project; }) { const [name, setName] = React.useState(""); const [cloneUrl, setCloneUrl] = React.useState(""); const [selectedChannelId, setSelectedChannelId] = React.useState(""); const [errorMessage, setErrorMessage] = React.useState(null); const nameInputRef = React.useRef(null); React.useEffect(() => { if (!open) return; setName(""); setCloneUrl(""); setSelectedChannelId(accessChannelId ?? ""); setErrorMessage(null); const timerId = globalThis.setTimeout( () => nameInputRef.current?.focus(), 50, ); return () => globalThis.clearTimeout(timerId); }, [accessChannelId, open]); async function handleSubmit(event: React.FormEvent) { event.preventDefault(); if (!name.trim() || !selectedChannelId) return; setErrorMessage(null); try { await onAdd({ accessChannelId: selectedChannelId, cloneUrl: cloneUrl.trim() || undefined, name: name.trim(), project, }); onOpenChange(false); } catch (error) { setErrorMessage( error instanceof Error ? error.message : "Failed to add repository.", ); } } return ( { if (!nextOpen && isCreating) return; onOpenChange(nextOpen); }} open={open} > {isCreating ? "Adding..." : "Add repository"} } footerClassName="border-t-0 pt-0" headerClassName="pb-2" title="Add repository" >
void handleSubmit(event)} >
{ setName(event.target.value); setErrorMessage(null); }} placeholder="mobile-app" ref={nameInputRef} spellCheck={false} value={name} />

Members of this channel can access the repository.

{ setCloneUrl(event.target.value); setErrorMessage(null); }} placeholder="https://relay.example.com/git/mobile-app.git" spellCheck={false} value={cloneUrl} />
{errorMessage ? (

{errorMessage}

) : null}
); }