// Tasks / Kanban Module function Tasks() { const emptycols = { todo: { title: 'A fazer', color: '#64748B', items: [] }, doing: { title: 'Em andamento', color: '#3B82F6', items: [] }, done: { title: 'Concluído', color: '#10B981', items: [] }, }; const [cols, setCols] = React.useState(emptycols); const [loading, setLoading] = React.useState(true); const [dragItem, setDragItem] = React.useState(null); const [dragFrom, setDragFrom] = React.useState(null); const [modal, setModal] = React.useState(false); const [editModal, setEditModal] = React.useState(false); const [editingTask, setEditingTask] = React.useState(null); const [editColKey, setEditColKey] = React.useState(null); const [newTask, setNewTask] = React.useState({ title: '', event: '', assignee: '', priority: 'Média', due: '' }); const [toast, setToast] = React.useState(null); const showToast = (msg) => { setToast({ msg }); setTimeout(() => setToast(null), 3000); }; const buildCols = (rows) => { const c = { todo: { title: 'A fazer', color: '#64748B', items: [] }, doing: { title: 'Em andamento', color: '#3B82F6', items: [] }, done: { title: 'Concluído', color: '#10B981', items: [] }, }; (rows || []).forEach(row => { const task = { id: row.id, title: row.title, event: row.event_name, assignee: row.assignee, priority: row.priority, due: row.due_date, tags: row.tags || [] }; if (c[row.column_key]) c[row.column_key].items.push(task); }); return c; }; React.useEffect(() => { sb.from('tasks').select('*').order('created_at').then(({ data }) => { if (data) setCols(buildCols(data)); setLoading(false); }); }, []); const priorityColor = { 'Alta': 'danger', 'Média': 'warning', 'Baixa': 'success' }; const tagColor = { 'Operacional': 'default', 'Cliente': 'primary', 'Jurídico': 'purple', 'Criativo': 'warning', 'Fornecedor': 'default', 'Comercial': 'success' }; const onDragStart = (item, fromCol) => { setDragItem(item); setDragFrom(fromCol); }; const onDrop = async (toCol) => { if (!dragItem || dragFrom === toCol) return; const toTitle = cols[toCol].title; setCols(prev => { const next = { ...prev }; next[dragFrom] = { ...next[dragFrom], items: next[dragFrom].items.filter(i => i.id !== dragItem.id) }; next[toCol] = { ...next[toCol], items: [...next[toCol].items, dragItem] }; return next; }); await sb.from('tasks').update({ column_key: toCol }).eq('id', dragItem.id); showToast(`Tarefa movida para "${toTitle}"`); setDragItem(null); setDragFrom(null); }; const addTask = async () => { if (!newTask.title.trim()) return; const { data } = await sb.from('tasks').insert({ title: newTask.title, event_name: newTask.event, assignee: newTask.assignee, priority: newTask.priority, due_date: newTask.due, tags: ['Operacional'], column_key: 'todo', }).select().single(); if (data) { const task = { id: data.id, title: data.title, event: data.event_name, assignee: data.assignee, priority: data.priority, due: data.due_date, tags: data.tags || [] }; setCols(prev => ({ ...prev, todo: { ...prev.todo, items: [task, ...prev.todo.items] } })); showToast('Tarefa criada com sucesso!'); } setModal(false); setNewTask({ title: '', event: '', assignee: '', priority: 'Média', due: '' }); }; const openEditTask = (task, colKey) => { setEditingTask({ ...task }); setEditColKey(colKey); setEditModal(true); }; const saveEditTask = async () => { if (!editingTask.title.trim()) return; const { error } = await sb.from('tasks').update({ title: editingTask.title, event_name: editingTask.event, assignee: editingTask.assignee, priority: editingTask.priority, due_date: editingTask.due, }).eq('id', editingTask.id); if (!error) { setCols(prev => ({ ...prev, [editColKey]: { ...prev[editColKey], items: prev[editColKey].items.map(t => t.id === editingTask.id ? editingTask : t) } })); showToast('Tarefa atualizada!'); } setEditModal(false); setEditingTask(null); }; const removeTask = async (colKey, taskId) => { setCols(prev => ({ ...prev, [colKey]: { ...prev[colKey], items: prev[colKey].items.filter(i => i.id !== taskId) } })); await sb.from('tasks').delete().eq('id', taskId); showToast('Tarefa removida'); }; const totalTasks = Object.values(cols).reduce((s, c) => s + c.items.length, 0); return (
{totalTasks} tarefas · {cols.doing.items.length} em andamento