"use client"; import { useEffect, useState } from "react"; import { IconExternalLink } from "@tabler/icons-react"; import { Button } from "@kandev/ui/button"; import { Input } from "@kandev/ui/input"; import { Label } from "@kandev/ui/label"; import { RadioGroup, RadioGroupItem } from "@kandev/ui/radio-group"; import { Spinner } from "@kandev/ui/spinner"; import { useToast } from "@/components/toast-provider"; import type { StartGitHubAppManifestResponse } from "@/lib/types/github"; import { appRegistrationError, defaultVisibility, submitManifestToGitHub, validateRegistrationBasics, type AppSetupErrors, } from "./github-app-onboarding-model"; import { GitHubAppPolicyDialog } from "./github-app-policy-dialog"; import { GitHubAppVisibilityField } from "./github-app-visibility-field"; import type { useGitHubAppRegistrations } from "@/hooks/domains/github/use-github-app-registrations"; import { useTranslation } from "react-i18next"; type RegistrationHook = ReturnType; export function GitHubAppCreateForm({ workspaceId, registrations, }: { workspaceId: string; registrations: RegistrationHook; }) { const { t } = useTranslation(); const [displayName, setDisplayName] = useState(""); const [ownerType, setOwnerType] = useState<"user" | "organization">("organization"); const [ownerLogin, setOwnerLogin] = useState(""); const [publicBaseUrl, setPublicBaseUrl] = useState(""); const [visibility, setVisibility] = useState(defaultVisibility); const [errors, setErrors] = useState({}); const [handoff, setHandoff] = useState(null); const { toast } = useToast(); useEffect(() => { setDisplayName(""); setOwnerType("organization"); setOwnerLogin(""); setPublicBaseUrl(""); setVisibility(defaultVisibility); setErrors({}); setHandoff(null); }, [workspaceId]); async function prepare(event: React.FormEvent) { event.preventDefault(); const basics = validateRegistrationBasics({ displayName, ownerType, ownerLogin, publicBaseUrl, }); setErrors(basics.errors); if (!basics.publicBaseUrl || Object.keys(basics.errors).length) return; try { setHandoff( await registrations.startManifest({ display_name: basics.displayName, owner_type: ownerType, owner_login: basics.ownerLogin, visibility, public_base_url: basics.publicBaseUrl, }), ); } catch (error) { const detail = appRegistrationError(error); toast({ description: detail?.error ?? t("github:githubAppSetupCouldNotStart"), variant: "error", }); } } if (handoff) { return setHandoff(null)} />; } return ( ); } function ManifestHandoff({ handoff, onEdit, }: { handoff: StartGitHubAppManifestResponse; onEdit: () => void; }) { const { t } = useTranslation(); return (

{t("github:githubIsReadyToCreateThe")}

{t("github:githubWillShowTheGeneratedPermissions")}

); } type CreateFieldsProps = { displayName: string; ownerType: "user" | "organization"; ownerLogin: string; publicBaseUrl: string; visibility: "private" | "public"; errors: AppSetupErrors; mutating: boolean; onDisplayName: (value: string) => void; onOwnerType: (value: "user" | "organization") => void; onOwnerLogin: (value: string) => void; onPublicBaseUrl: (value: string) => void; onVisibility: (value: "private" | "public") => void; onSubmit: (event: React.FormEvent) => void; }; function CreateAppFields(props: CreateFieldsProps) { const { t } = useTranslation(); return (

{t("github:createAGithubApp")}

{t("github:kandevGeneratesTheExactAppPolicy")}

props.onDisplayName(event.target.value)} /> props.onOwnerLogin(event.target.value)} />
props.onOwnerType(value as CreateFieldsProps["ownerType"])} className="flex min-h-11 flex-wrap items-center gap-5" > props.onPublicBaseUrl(event.target.value)} />

{t("github:githubMustReachThisHttpsOrigin")}

); } function Field({ label, error, children, }: { label: string; error?: string; children: React.ReactNode; }) { return ( ); }