'use client'; import React, { useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { GroupSettingsSchema, type GroupSettings, type Model, } from '@/lib/api/schemas/models'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form'; import { Switch } from '@/components/ui/switch'; import { Users, Key, Loader2, Globe, AlertTriangle, Info } from 'lucide-react'; import { toast } from 'sonner'; import { Alert, AlertDescription } from '@/components/ui/alert'; interface EditGroupFormProps { provider: string; models: Model[]; groupSettings?: { group_api_key?: string; group_url?: string }; onGroupUpdate: (oldProvider: string, updatedData: GroupSettings) => void; onCancel?: () => void; isOpen: boolean; } export function EditGroupForm({ provider, models, groupSettings, onGroupUpdate, onCancel, isOpen, }: EditGroupFormProps) { const [isSubmitting, setIsSubmitting] = useState(false); const [showApiKey, setShowApiKey] = useState(false); const [useGroupUrl, setUseGroupUrl] = useState(!!groupSettings?.group_url); const form = useForm({ resolver: zodResolver(GroupSettingsSchema), defaultValues: { provider: provider, group_api_key: groupSettings?.group_api_key || '', group_url: groupSettings?.group_url || '', }, }); const onSubmit = async (data: GroupSettings) => { setIsSubmitting(true); try { // Clean up empty strings and handle URL removal const cleanData = { ...data, group_api_key: data.group_api_key?.trim() || undefined, group_url: useGroupUrl ? data.group_url?.trim() || undefined : undefined, }; await onGroupUpdate(provider, cleanData); toast.success(`Group "${provider}" updated successfully!`); onCancel?.(); } catch (error) { toast.error('Failed to update group. Please try again.'); console.error('Error updating group:', error); } finally { setIsSubmitting(false); } }; // Count models that have individual API keys const modelsWithoutKeys = models.filter((model) => !model.api_key).length; // Count models that would be affected by URL changes const modelsUsingGroupUrl = models.filter( (model) => !model.api_key && (!model.url || model.url.startsWith('/')) ).length; const handleClose = () => { if (!isSubmitting) { onCancel?.(); } }; return ( Edit Provider Group: {provider} Update settings for all {models.length} models in this group. Group settings provide defaults for models without individual configurations.
{/* API Key Status */}

API Key Configuration

Models using group API key: {modelsWithoutKeys}
{/* URL Configuration Status */}

URL Configuration

Models using group URL: {modelsUsingGroupUrl}
Models with individual URLs: {models.length - modelsUsingGroupUrl}
{groupSettings?.group_url && (
Current group URL:{' '} {groupSettings.group_url}
)}
{/* Models in this group */}

Models in this group:

{models.map((model) => ( {model.name} {model.api_key && ' 🔑'} {model.url && !model.url.startsWith('/') && model.api_key && ' 🌐'} ))}
( Provider Name * This will update the provider name for all models in this group )} /> {/* Group URL Toggle */}
Group Base URL Provide a custom base URL for this provider group
{useGroupUrl && ( ( Base URL This base URL will be used for models without individual URLs. Models will append their endpoint path (e.g., /chat/completions) to this base. )} /> )} {!useGroupUrl && groupSettings?.group_url && ( Removing the group URL will make models in this group fall back to the default system endpoint. Models with individual URLs will be unaffected. )} {useGroupUrl && !groupSettings?.group_url && ( Adding a group URL will allow models in this group to use a custom endpoint instead of the default system endpoint. )}
( Group API Key
This API key will be used for models that don't have individual API keys ({modelsWithoutKeys} models). Leave empty to remove the group API key.
)} />

How group settings work:

  • Models with individual API keys and URLs will keep their specific settings
  • Models without individual settings will use the group defaults
  • Removing the group URL makes models fall back to the system default endpoint
  • You can use "Apply Group Settings" to force models to use group configurations
); }