import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { Switch } from '@/components/ui/switch'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; import { cn } from '@/lib/utils'; import { Webhook, Plus, Trash2, Pencil, Terminal, Globe, History } from 'lucide-react'; import { useAppStore } from '@/store/app-store'; import type { EventHook, EventHookTrigger } from '@automaker/types'; import { EVENT_HOOK_TRIGGER_LABELS } from '@automaker/types'; import { EventHookDialog } from './event-hook-dialog'; import { EventHistoryView } from './event-history-view'; export function EventHooksSection() { const { eventHooks, setEventHooks } = useAppStore(); const [dialogOpen, setDialogOpen] = useState(false); const [editingHook, setEditingHook] = useState(null); const [activeTab, setActiveTab] = useState<'hooks' | 'history'>('hooks'); const handleAddHook = () => { setEditingHook(null); setDialogOpen(true); }; const handleEditHook = (hook: EventHook) => { setEditingHook(hook); setDialogOpen(true); }; const handleDeleteHook = (hookId: string) => { setEventHooks(eventHooks.filter((h) => h.id !== hookId)); }; const handleToggleHook = (hookId: string, enabled: boolean) => { setEventHooks(eventHooks.map((h) => (h.id === hookId ? { ...h, enabled } : h))); }; const handleSaveHook = (hook: EventHook) => { if (editingHook) { // Update existing setEventHooks(eventHooks.map((h) => (h.id === hook.id ? hook : h))); } else { // Add new setEventHooks([...eventHooks, hook]); } setDialogOpen(false); setEditingHook(null); }; // Group hooks by trigger type for better organization const hooksByTrigger = eventHooks.reduce( (acc, hook) => { if (!acc[hook.trigger]) { acc[hook.trigger] = []; } acc[hook.trigger].push(hook); return acc; }, {} as Record ); return (
{/* Header */}

Event Hooks

Run custom commands or webhooks when events occur

{activeTab === 'hooks' && ( )}
{/* Tabs */} setActiveTab(v as 'hooks' | 'history')}>
Hooks History
{/* Hooks Tab */}
{eventHooks.length === 0 ? (

No event hooks configured

Add hooks to run commands or send webhooks when features complete

) : (
{/* Group by trigger type */} {Object.entries(hooksByTrigger).map(([trigger, hooks]) => (

{EVENT_HOOK_TRIGGER_LABELS[trigger as EventHookTrigger]}

{hooks.map((hook) => ( handleEditHook(hook)} onDelete={() => handleDeleteHook(hook.id)} onToggle={(enabled) => handleToggleHook(hook.id, enabled)} /> ))}
))}
)}
{/* Variable reference */}

Available variables:

{'{{featureId}}'} {'{{featureName}}'} {'{{projectPath}}'} {'{{projectName}}'}{' '} {'{{error}}'} {'{{timestamp}}'} {'{{eventType}}'}
{/* History Tab */}
{/* Dialog */}
); } interface HookCardProps { hook: EventHook; onEdit: () => void; onDelete: () => void; onToggle: (enabled: boolean) => void; } function HookCard({ hook, onEdit, onDelete, onToggle }: HookCardProps) { const isShell = hook.action.type === 'shell'; return (
{/* Type icon */}
{isShell ? : }
{/* Info */}

{hook.name || (isShell ? 'Shell Command' : 'HTTP Webhook')}

{isShell ? (hook.action as { type: 'shell'; command: string }).command : (hook.action as { type: 'http'; url: string }).url}

{/* Actions */}
); }