'use client'; import { useMemo, useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { apiFetch } from '../../../lib/api'; import { useSession } from '../../../components/session-provider'; interface Task { id: string; title: string; description: string | null; status: string; priority: string | null; tags: string[]; targetDate: string | null; createdAt: string; } const CONTENT_TAGS = ['content','post','articol','newsletter','video','podcast','reel','thread','blog']; const PLATFORM_TAGS = ['linkedin','twitter','facebook','instagram','youtube','substack','blog','medium']; const STATUS_FLOW = ['idea','draft','review','scheduled','published']; const STATUS_LABELS: Record = { idea:'💡 Idee', draft:'✏️ Draft', review:'🔍 Review', scheduled:'📅 Programat', published:'✅ Publicat', todo:'📋 Todo', 'in-progress':'⚡ În progres', completed:'✅ Done', }; const STATUS_COLORS: Record = { idea:'bg-muted text-ink-faint', draft:'bg-primary/10 text-primary', review:'bg-warn/10 text-warn', scheduled:'bg-blue-500/10 text-blue-600', published:'bg-signal-ok/10 text-signal-ok', completed:'bg-signal-ok/10 text-signal-ok', }; export default function ContentCalendarPage() { const { activeTenant } = useSession(); const tenantId = activeTenant?.tenantId ?? ''; const qc = useQueryClient(); const [platformFilter, setPlatformFilter] = useState('all'); const [statusFilter, setStatusFilter] = useState('all'); const [showAdd, setShowAdd] = useState(false); const [form, setForm] = useState({ title: '', platform: 'linkedin', type: 'post', targetDate: '', priority: 'normal' }); const { data: tasks = [], isLoading } = useQuery({ queryKey: ['content', tenantId], queryFn: () => apiFetch('/v1/tasks?limit=500', { tenantId }), enabled: Boolean(tenantId), staleTime: 60_000, }); const content = useMemo(() => tasks.filter((t) => t.tags.some((tag) => CONTENT_TAGS.includes(tag.toLowerCase()))), [tasks]); function detectPlatform(t: Task): string { return t.tags.find((tag) => PLATFORM_TAGS.includes(tag.toLowerCase())) ?? 'general'; } function detectStatus(t: Task): string { const knownStatuses = [...STATUS_FLOW, 'todo', 'in-progress', 'completed', 'cancelled']; const fromTags = t.tags.find((tag) => STATUS_FLOW.includes(tag.toLowerCase())); if (fromTags) return fromTags; if (t.status === 'completed') return 'published'; if (t.status === 'in-progress') return 'draft'; return 'idea'; } const platformCounts = useMemo(() => { const map: Record = {}; for (const t of content) { const p = detectPlatform(t); map[p] = (map[p] ?? 0) + 1; } return map; }, [content]); const filtered = useMemo(() => { let list = content; if (platformFilter !== 'all') list = list.filter((t) => detectPlatform(t) === platformFilter); if (statusFilter !== 'all') list = list.filter((t) => detectStatus(t) === statusFilter); return list.sort((a, b) => { const aDate = a.targetDate ?? a.createdAt; const bDate = b.targetDate ?? b.createdAt; return aDate.localeCompare(bDate); }); }, [content, platformFilter, statusFilter]); const addMut = useMutation({ mutationFn: () => apiFetch('/v1/tasks', { tenantId, method: 'POST', body: { title: form.title, tags: ['content', form.type, form.platform, 'idea'], priority: form.priority, status: 'todo', targetDate: form.targetDate || undefined, }}), onSuccess: () => { qc.invalidateQueries({ queryKey: ['content', tenantId] }); setShowAdd(false); setForm({ title: '', platform: 'linkedin', type: 'post', targetDate: '', priority: 'normal' }); }, }); const patchStatusMut = useMutation({ mutationFn: ({ id, nextStatus }: { id: string; nextStatus: string }) => { const tag = STATUS_FLOW.includes(nextStatus) ? nextStatus : 'published'; return apiFetch(`/v1/tasks/${id}`, { tenantId, method: 'PATCH', body: { status: nextStatus === 'published' ? 'completed' : 'in-progress', tags: undefined, }}); }, onSuccess: () => qc.invalidateQueries({ queryKey: ['content', tenantId] }), }); const PLATFORM_ICONS: Record = { linkedin:'💼', twitter:'🐦', facebook:'📘', instagram:'📸', youtube:'▶️', substack:'📮', blog:'✍️', medium:'📰', general:'📢', }; return (

Content Calendar

{content.length} piese de conținut

{showAdd && (

Conținut nou

setForm((p) => ({ ...p, title: e.target.value }))} className="w-full rounded-lg border bg-background px-3 py-2 text-sm text-ink focus:outline-none focus:ring-2 focus:ring-ring" />
setForm((p) => ({ ...p, targetDate: e.target.value }))} className="rounded-lg border bg-background px-3 py-2 text-sm text-ink focus:outline-none focus:ring-2 focus:ring-ring" />
)} {/* Filters */}
{Object.entries(platformCounts).map(([p, c]) => ( ))}
{['all', ...STATUS_FLOW].map((s) => ( ))}
{isLoading ? (
Se încarcă…
) : filtered.length === 0 ? (

📅

Niciun conținut. Adaugă idei cu tag „content".

) : (
{filtered.map((t) => { const platform = detectPlatform(t); const status = detectStatus(t); const nextIdx = STATUS_FLOW.indexOf(status); const next = STATUS_FLOW[nextIdx + 1]; return (
{PLATFORM_ICONS[platform] ?? '📢'}

{t.title}

{STATUS_LABELS[status] ?? status} {t.targetDate && 📅 {new Date(t.targetDate).toLocaleDateString('ro-RO')}}
{next && ( )}
); })}
)}
); }