"use client"; import { useState, useCallback } from "react"; import { Button, Input, Label, Textarea, RadioGroup, RadioGroupItem, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "../../../shadcnui"; import { OAuthRedirectUriInput } from "./OAuthRedirectUriInput"; import { OAuthScopeSelector } from "./OAuthScopeSelector"; import { OAuthClientCreateRequest, OAuthClientInterface, DEFAULT_GRANT_TYPES } from "../interfaces/oauth.interface"; export interface OAuthClientFormProps { /** Existing client for edit mode (undefined = create mode) */ client?: OAuthClientInterface; /** Called on form submit */ onSubmit: (data: OAuthClientCreateRequest) => Promise; /** Called on cancel */ onCancel: () => void; /** Whether form is submitting */ isLoading?: boolean; } interface FormState { name: string; description: string; redirectUris: string[]; allowedScopes: string[]; isConfidential: boolean; } interface FormErrors { name?: string; redirectUris?: string; allowedScopes?: string; } /** * Form for creating or editing an OAuth client */ export function OAuthClientForm({ client, onSubmit, onCancel, isLoading = false }: OAuthClientFormProps) { const isEditMode = !!client; const [formState, setFormState] = useState({ name: client?.name || "", description: client?.description || "", redirectUris: client?.redirectUris?.length ? client.redirectUris : [""], allowedScopes: client?.allowedScopes || [], isConfidential: client?.isConfidential ?? true, }); const [errors, setErrors] = useState({}); const validate = useCallback((): boolean => { const newErrors: FormErrors = {}; if (!formState.name.trim()) { newErrors.name = "Application name is required"; } const validUris = formState.redirectUris.filter((uri) => uri.trim()); if (validUris.length === 0) { newErrors.redirectUris = "At least one redirect URI is required"; } if (formState.allowedScopes.length === 0) { newErrors.allowedScopes = "At least one scope must be selected"; } setErrors(newErrors); return Object.keys(newErrors).length === 0; }, [formState]); const handleSubmit = useCallback( async (e: React.FormEvent) => { e.preventDefault(); if (!validate()) return; const data: OAuthClientCreateRequest = { name: formState.name.trim(), description: formState.description.trim() || undefined, redirectUris: formState.redirectUris.filter((uri) => uri.trim()), allowedScopes: formState.allowedScopes, allowedGrantTypes: DEFAULT_GRANT_TYPES, isConfidential: formState.isConfidential, }; await onSubmit(data); }, [formState, validate, onSubmit], ); return (
{isEditMode ? "Edit Application" : "Create OAuth Application"} {isEditMode ? "Update your OAuth application settings." : "Register a new application to access the API."} {/* Name */}
setFormState((s) => ({ ...s, name: e.target.value }))} placeholder="My Lightroom Plugin" disabled={isLoading} className={errors.name ? "border-destructive" : ""} /> {errors.name &&

{errors.name}

}
{/* Description */}