diff --git a/modules/todo/api.php b/modules/todo/api.php index 86c5e7f..9bfd1d7 100644 --- a/modules/todo/api.php +++ b/modules/todo/api.php @@ -19,6 +19,17 @@ function tOk($d) { echo json_encode(['ok' => true, 'data' => $d], JSON_UNESCAPE function tErr($m, $c = 400) { http_response_code($c); echo json_encode(['ok' => false, 'error' => $m]); exit; } function tBody() { return json_decode(file_get_contents('php://input'), true) ?? []; } +function discordNotify(PDO $pdo, string $msg): void { + $s = $pdo->prepare("SELECT content FROM pf_notes WHERE note_type='todo_settings' AND reference_id='webhook_discord'"); + $s->execute(); $url = $s->fetchColumn(); + if (!$url) return; + $ch = curl_init($url); + curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>4, + CURLOPT_HTTPHEADER=>['Content-Type: application/json'], + CURLOPT_POSTFIELDS=>json_encode(['username'=>'HouseHub Todo','content'=>$msg])]); + curl_exec($ch); curl_close($ch); +} + // ── LISTS ────────────────────────────────────────────────────────────────────── if ($action === 'lists') { if ($method === 'GET') { @@ -71,14 +82,17 @@ if ($action === 'todos') { } elseif ($list_id === 'upcoming') { $where[] = 't.due_date >= CURDATE()'; $where[] = 't.done = 0'; + } elseif ($list_id === 'overdue') { + $where[] = 't.due_date < CURDATE()'; + $where[] = 't.done = 0'; + } elseif ($list_id === 'done') { + $where[] = 't.done = 1'; } else { $where[] = 't.list_id = ?'; $params[] = $list_id; } - if (!$show_done && $list_id !== 'done') { + if (!$show_done && !in_array($list_id, ['done', 'overdue'])) { $where[] = 't.done = 0'; - } elseif ($list_id === 'done') { - $where[] = 't.done = 1'; } if ($priority) { $where[] = 't.priority = ?'; $params[] = $priority; } @@ -105,7 +119,10 @@ if ($action === 'todos') { ]); $id = (int)$pdo->lastInsertId(); $new = $pdo->prepare("SELECT t.*, l.name as list_name, l.color as list_color, l.icon as list_icon FROM pf_todos t LEFT JOIN pf_todo_lists l ON l.id = t.list_id WHERE t.id=?"); - $new->execute([$id]); tOk($new->fetch()); + $new->execute([$id]); + $row = $new->fetch(); + discordNotify($pdo, "📋 **Nouvelle tâche** : " . $title . ($row['list_name'] ? " _(". $row['list_name'] .")_" : "")); + tOk($row); } if ($method === 'PUT') { @@ -117,6 +134,11 @@ if ($action === 'todos') { $done = $d['done'] ? 1 : 0; $pdo->prepare("UPDATE pf_todos SET done=?, done_at=?, updated_at=NOW() WHERE id=?") ->execute([$done, $done ? date('Y-m-d H:i:s') : null, $id]); + if ($done) { + $t = $pdo->prepare("SELECT title FROM pf_todos WHERE id=?"); $t->execute([$id]); + $row = $t->fetch(); + if ($row) discordNotify($pdo, "✅ **Tâche terminée** : " . $row['title']); + } tOk(['done' => $done]); } @@ -145,4 +167,22 @@ if ($action === 'stats') { ]); } +// ── SETTINGS ─────────────────────────────────────────────────────────────────── +if ($action === 'settings') { + if ($method === 'GET') { + $rows = $pdo->query("SELECT reference_id, content FROM pf_notes WHERE note_type='todo_settings'")->fetchAll(); + $s = []; + foreach ($rows as $r) $s[$r['reference_id']] = $r['content']; + tOk($s); + } + if ($method === 'PUT') { + $d = tBody(); + foreach ($d as $key => $val) { + $pdo->prepare("INSERT INTO pf_notes (note_type, reference_id, content) VALUES ('todo_settings',?,?) ON DUPLICATE KEY UPDATE content=?") + ->execute([$key, $val ?? '', $val ?? '']); + } + tOk(['updated' => true]); + } +} + tErr('Action inconnue', 404); diff --git a/modules/todo/assets/todo.js b/modules/todo/assets/todo.js index 9a652ff..a8a1b6f 100644 --- a/modules/todo/assets/todo.js +++ b/modules/todo/assets/todo.js @@ -28,6 +28,7 @@ let editTodoId=null; let editListId=null; let selectedPriority='none'; let selectedColor='#3b82f6'; +let selectedIcon='📋'; const COLORS=['#3b82f6','#10b981','#f59e0b','#ef4444','#8b5cf6','#ec4899','#06b6d4','#84cc16','#f97316','#64748b']; const ICONS=['📋','🏠','🛒','💼','💪','🎯','📚','✈️','🎮','❤️','⭐','🔧']; @@ -39,35 +40,45 @@ async function loadSidebar(){ lists=data; const el=document.getElementById('todo-sidebar-lists'); - // Smart views - let smartHtml=` -
${currentFilter==='done'?'Aucune tâche terminée.':'Aucune tâche. Ajoutez-en une !'}
${currentFilter==='done'?'Aucune tâche terminée.':'Aucune tâche pour le moment.'}