'use client'; import { useState, useCallback } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { apiClient } from '@/infrastructure/api/api-client'; import { cn } from '@/lib/utils'; // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- interface Skill { id: string; name: string; description: string; category: 'inspection' | 'deployment' | 'maintenance' | 'security' | 'monitoring' | 'custom'; script: string; tags: string[]; enabled: boolean; createdAt: string; updatedAt: string; } interface SkillFormData { name: string; description: string; category: Skill['category']; script: string; tags: string; enabled: boolean; } interface SkillsResponse { data: Skill[]; total: number; } // --------------------------------------------------------------------------- // Constants // --------------------------------------------------------------------------- const SKILL_QUERY_KEY = ['skills'] as const; const CATEGORIES: { label: string; value: Skill['category'] }[] = [ { label: 'Inspection', value: 'inspection' }, { label: 'Deployment', value: 'deployment' }, { label: 'Maintenance', value: 'maintenance' }, { label: 'Security', value: 'security' }, { label: 'Monitoring', value: 'monitoring' }, { label: 'Custom', value: 'custom' }, ]; const CATEGORY_STYLES: Record = { inspection: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400', deployment: 'bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400', maintenance: 'bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-400', security: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400', monitoring: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400', custom: 'bg-gray-100 text-gray-800 dark:bg-gray-900/30 dark:text-gray-400', }; const EMPTY_FORM: SkillFormData = { name: '', description: '', category: 'custom', script: '', tags: '', enabled: true, }; // --------------------------------------------------------------------------- // Category badge // --------------------------------------------------------------------------- function CategoryBadge({ category }: { category: Skill['category'] }) { return ( {category} ); } // --------------------------------------------------------------------------- // Enabled / Disabled badge // --------------------------------------------------------------------------- function EnabledBadge({ enabled }: { enabled: boolean }) { return ( {enabled ? 'Enabled' : 'Disabled'} ); } // --------------------------------------------------------------------------- // Skill form dialog // --------------------------------------------------------------------------- function SkillDialog({ open, title, form, errors, saving, onClose, onChange, onSubmit, }: { open: boolean; title: string; form: SkillFormData; errors: Partial>; saving: boolean; onClose: () => void; onChange: (field: keyof SkillFormData, value: string | boolean) => void; onSubmit: () => void; }) { if (!open) return null; return (
{/* backdrop */}
{/* dialog */}

{title}

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

{errors.name}

)}
{/* description */}