diff --git a/src/app/dashboard/automation/page.tsx b/src/app/dashboard/automation/page.tsx new file mode 100644 index 0000000..0ac3acc --- /dev/null +++ b/src/app/dashboard/automation/page.tsx @@ -0,0 +1,177 @@ +'use client'; + +import { useState } from 'react'; +import { useQuery } from '@tanstack/react-query'; +import { apiFetch } from '../../../lib/api'; +import { useSession } from '../../../components/session-provider'; + +const WORKFLOWS = [ + { + id: 'weekly-review', + name: 'Weekly Review Generator', + icon: '🔄', + schedule: 'Luni, 8:00', + description: 'Generează retrospectiva săptămânii: task-uri finalizate, obiective, lecții. Salvat ca observație.', + file: 'weekly-review.json', + color: 'text-indigo-600', + bg: 'bg-indigo-50', + }, + { + id: 'daily-planner', + name: 'Daily Planner', + icon: '📅', + schedule: 'Lun–Vin, 7:00', + description: 'Compilează brief-ul zilnic AI + task-urile prioritare active. Plan salvat în observații.', + file: 'daily-planner.json', + color: 'text-emerald-600', + bg: 'bg-emerald-50', + }, + { + id: 'gmail-bridge', + name: 'Gmail → CEO OS', + icon: '📧', + schedule: 'La fiecare 15 min', + description: 'Citește emailuri importante din Gmail, clasifică cu AI (skip/info/action), creează task-uri automat.', + file: 'gmail-bridge.json', + color: 'text-red-600', + bg: 'bg-red-50', + }, + { + id: 'financial-brief', + name: 'Financial Weekly Brief', + icon: '💰', + schedule: 'Vineri, 17:00', + description: 'Calculează sold, contracte active și cheltuieli. Generează brief financiar cu AI și îl salvează.', + file: 'financial-brief.json', + color: 'text-amber-600', + bg: 'bg-amber-50', + }, +]; + +const ENV_VARS = [ + { key: 'CEO_OS_API_URL', value: 'https://boardmind.dev/api', desc: 'URL de bază CEO OS API' }, + { key: 'CEO_OS_TENANT_ID', value: '', desc: 'Se găsește în Settings → Workspace' }, + { key: 'CEO_OS_SERVICE_KEY', value: '', desc: 'Trebuie să fie egal cu N8N_SERVICE_KEY din ceo-api' }, +]; + +const N8N_STEPS = [ + 'Deschide n8n → Settings → Variables → adaugă cele 3 variabile de mai jos', + 'Importă fiecare workflow JSON din Forgejo → ceo-api/n8n-workflows/', + 'Pentru Gmail Bridge: adaugă credential Gmail OAuth2 în n8n → Credentials', + 'Activează workflow-urile pe rând. Testează cu "Execute Workflow" manual prima dată.', + 'Monitorizează execuțiile din n8n → Executions.', +]; + +export default function AutomationHubPage() { + const { activeTenant } = useSession(); + const tenantId = activeTenant?.tenantId ?? ''; + const [copied, setCopied] = useState(''); + + // Show automation results from observations + const { data: observations = [] } = useQuery({ + queryKey: ['automation-obs', tenantId], + queryFn: () => apiFetch('/v1/observations', { tenantId }), + enabled: Boolean(tenantId), staleTime: 60_000, + }); + + const autoObs = observations.filter((o) => + ['weekly-review', 'daily-plan', 'financial-brief', 'email-received'].includes(o.metric), + ).sort((a, b) => (b.observedAt ?? b.createdAt).localeCompare(a.observedAt ?? a.createdAt)); + + function copy(text: string, id: string) { + navigator.clipboard.writeText(text); + setCopied(id); + setTimeout(() => setCopied(''), 2000); + } + + return ( +
+
+

Automation Hub

+

4 agenți n8n care lucrează automat cu CEO OS

+
+ + {/* Workflow cards */} +
+ {WORKFLOWS.map((wf) => ( +
+
+ + {wf.icon} + +
+

{wf.name}

+

⏰ {wf.schedule}

+
+
+

{wf.description}

+
+ + n8n-workflows/{wf.file} + +
+
+ ))} +
+ + {/* Setup guide */} +
+

Pași de configurare n8n

+
    + {N8N_STEPS.map((step, i) => ( +
  1. + + {i + 1} + + {step} +
  2. + ))} +
+
+ + {/* Environment variables */} +
+

Variabile de setat în n8n (Settings → Variables)

+
+ {ENV_VARS.map((v) => ( +
+ {v.key} + {v.value} + +
+ ))} +
+

+ N8N_SERVICE_KEY → setat în Coolify → ceo-api env + n8n Variables simultan cu aceeași valoare. + TenantId-ul → Settings → Workspace în CEO OS. +

+
+ + {/* Recent automation results */} + {autoObs.length > 0 && ( +
+

Execuții recente

+
+ {autoObs.slice(0, 10).map((o) => ( +
+ + {o.metric === 'weekly-review' ? '🔄' : o.metric === 'daily-plan' ? '📅' : o.metric === 'financial-brief' ? '💰' : '📧'} + +
+

{o.metric}

+

{String(o.value).slice(0, 120)}…

+
+

+ {new Date(o.observedAt ?? o.createdAt).toLocaleDateString('ro-RO', {day:'numeric', month:'short'})} +

+
+ ))} +
+
+ )} +
+ ); +}