'use client'; import { useState, useCallback } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { apiClient } from '@/infrastructure/api/api-client'; import { queryKeys } from '@/infrastructure/api/query-keys'; import { cn } from '@/lib/utils'; // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- interface Server { id: string; hostname: string; host: string; sshPort: number; environment: 'dev' | 'staging' | 'prod'; role: string; status: 'online' | 'offline' | 'maintenance'; tags: string[]; description: string; } interface ServerFormData { hostname: string; host: string; sshPort: number; environment: 'dev' | 'staging' | 'prod'; role: string; tags: string; description: string; } interface ServersResponse { data: Server[]; total: number; } type EnvironmentFilter = 'all' | 'dev' | 'staging' | 'prod'; // --------------------------------------------------------------------------- // Constants // --------------------------------------------------------------------------- const ENVIRONMENTS: { label: string; value: EnvironmentFilter }[] = [ { label: 'All', value: 'all' }, { label: 'Dev', value: 'dev' }, { label: 'Staging', value: 'staging' }, { label: 'Prod', value: 'prod' }, ]; const EMPTY_FORM: ServerFormData = { hostname: '', host: '', sshPort: 22, environment: 'dev', role: '', tags: '', description: '', }; // --------------------------------------------------------------------------- // Status badge // --------------------------------------------------------------------------- function StatusBadge({ status }: { status: Server['status'] }) { const styles: Record = { online: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400', offline: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400', maintenance: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400', }; return ( {status} ); } // --------------------------------------------------------------------------- // Server form dialog // --------------------------------------------------------------------------- function ServerDialog({ open, title, form, errors, saving, onClose, onChange, onSubmit, }: { open: boolean; title: string; form: ServerFormData; errors: Partial>; saving: boolean; onClose: () => void; onChange: (field: keyof ServerFormData, value: string | number) => void; onSubmit: () => void; }) { if (!open) return null; return (
{/* backdrop */}
{/* dialog */}

{title}

{/* hostname */}
onChange('hostname', e.target.value)} className={cn( 'w-full px-3 py-2 rounded-md border bg-background text-sm', errors.hostname ? 'border-destructive' : 'border-input', )} placeholder="web-server-01" /> {errors.hostname && (

{errors.hostname}

)}
{/* host */}
onChange('host', e.target.value)} className={cn( 'w-full px-3 py-2 rounded-md border bg-background text-sm', errors.host ? 'border-destructive' : 'border-input', )} placeholder="192.168.1.100" /> {errors.host && (

{errors.host}

)}
{/* sshPort */}
onChange('sshPort', parseInt(e.target.value, 10) || 22)} className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm" min={1} max={65535} />
{/* environment */}
{/* role */}
onChange('role', e.target.value)} className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm" placeholder="web, db, cache..." />
{/* tags */}
onChange('tags', e.target.value)} className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm" placeholder="linux, ubuntu, docker (comma-separated)" />
{/* description */}