mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
160 lines
8.1 KiB
PHP
160 lines
8.1 KiB
PHP
<?php
|
|
// JARVIS Planner — tasks, appointments, daily briefing
|
|
|
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
function parseNaturalDate(string $text): ?string {
|
|
$text = trim($text);
|
|
if (!$text || strtolower($text) === 'none') return null;
|
|
$ts = strtotime($text);
|
|
return ($ts !== false && $ts > 0) ? date('Y-m-d', $ts) : null;
|
|
}
|
|
function parseNaturalDatetime(string $text): ?string {
|
|
$text = trim($text);
|
|
if (!$text) return null;
|
|
$ts = strtotime($text);
|
|
return ($ts !== false && $ts > 0) ? date('Y-m-d H:i:s', $ts) : null;
|
|
}
|
|
|
|
// ── Route ─────────────────────────────────────────────────────────────────────
|
|
// $action from api.php: tasks | appointments | today | done | summary
|
|
|
|
switch ($action) {
|
|
|
|
// ── Tasks ─────────────────────────────────────────────────────────────────
|
|
case 'tasks':
|
|
if ($method === 'GET') {
|
|
$status = $_GET['status'] ?? '';
|
|
$category = $_GET['category'] ?? '';
|
|
$where = '1=1';
|
|
$params = [];
|
|
if ($status) { $where .= ' AND status=?'; $params[] = $status; }
|
|
if ($category) { $where .= ' AND category=?'; $params[] = $category; }
|
|
else { $where .= " AND status NOT IN ('done','cancelled')"; }
|
|
$rows = JarvisDB::query(
|
|
"SELECT * FROM tasks WHERE {$where} ORDER BY
|
|
FIELD(priority,'urgent','high','normal','low'), due_date ASC, created_at DESC",
|
|
$params
|
|
) ?? [];
|
|
echo json_encode(['tasks' => $rows]);
|
|
} elseif ($method === 'POST') {
|
|
$id = (int)($data['id'] ?? 0);
|
|
$title = trim($data['title'] ?? '');
|
|
$notes = trim($data['notes'] ?? '');
|
|
$category = $data['category'] ?? 'personal';
|
|
$priority = $data['priority'] ?? 'normal';
|
|
$status = $data['status'] ?? 'pending';
|
|
$due_date = parseNaturalDate($data['due_date'] ?? '');
|
|
$due_time = !empty($data['due_time']) ? $data['due_time'] : null;
|
|
if (!$title) { echo json_encode(['error' => 'Title required']); exit; }
|
|
if ($id) {
|
|
JarvisDB::execute(
|
|
'UPDATE tasks SET title=?,notes=?,category=?,priority=?,status=?,due_date=?,due_time=?,updated_at=NOW() WHERE id=?',
|
|
[$title,$notes,$category,$priority,$status,$due_date,$due_time,$id]
|
|
);
|
|
echo json_encode(['success' => true, 'id' => $id]);
|
|
} else {
|
|
$newId = JarvisDB::insert(
|
|
'INSERT INTO tasks (title,notes,category,priority,due_date,due_time) VALUES (?,?,?,?,?,?)',
|
|
[$title,$notes,$category,$priority,$due_date,$due_time]
|
|
);
|
|
echo json_encode(['success' => true, 'id' => $newId]);
|
|
}
|
|
} elseif ($method === 'DELETE') {
|
|
$id = (int)($_GET['id'] ?? 0);
|
|
if ($id) { JarvisDB::execute('DELETE FROM tasks WHERE id=?', [$id]); }
|
|
echo json_encode(['success' => true]);
|
|
}
|
|
break;
|
|
|
|
// ── Mark task done ────────────────────────────────────────────────────────
|
|
case 'done':
|
|
$id = (int)($data['id'] ?? $_GET['id'] ?? 0);
|
|
if ($id) {
|
|
JarvisDB::execute(
|
|
"UPDATE tasks SET status='done', completed_at=NOW() WHERE id=?", [$id]
|
|
);
|
|
}
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
// ── Appointments ──────────────────────────────────────────────────────────
|
|
case 'appointments':
|
|
if ($method === 'GET') {
|
|
$from = $_GET['from'] ?? date('Y-m-d');
|
|
$to = $_GET['to'] ?? date('Y-m-d', strtotime('+90 days'));
|
|
$rows = JarvisDB::query(
|
|
"SELECT * FROM appointments WHERE DATE(start_at) BETWEEN ? AND ? ORDER BY start_at ASC",
|
|
[$from, $to]
|
|
) ?? [];
|
|
echo json_encode(['appointments' => $rows]);
|
|
} elseif ($method === 'POST') {
|
|
$id = (int)($data['id'] ?? 0);
|
|
$title = trim($data['title'] ?? '');
|
|
$description = trim($data['description'] ?? '');
|
|
$category = $data['category'] ?? 'personal';
|
|
$location = trim($data['location'] ?? '');
|
|
$all_day = (int)($data['all_day'] ?? 0);
|
|
$reminder = (int)($data['reminder_min'] ?? 30);
|
|
$start_raw = trim($data['start_at'] ?? '');
|
|
$end_raw = trim($data['end_at'] ?? '');
|
|
if (!$title || !$start_raw) { echo json_encode(['error' => 'Title and start time required']); exit; }
|
|
$start_at = parseNaturalDatetime($start_raw) ?? date('Y-m-d H:i:s', strtotime($start_raw));
|
|
$end_at = $end_raw ? (parseNaturalDatetime($end_raw) ?? null) : null;
|
|
if ($id) {
|
|
JarvisDB::execute(
|
|
'UPDATE appointments SET title=?,description=?,category=?,start_at=?,end_at=?,location=?,all_day=?,reminder_min=?,alerted=0,updated_at=NOW() WHERE id=?',
|
|
[$title,$description,$category,$start_at,$end_at,$location,$all_day,$reminder,$id]
|
|
);
|
|
echo json_encode(['success' => true, 'id' => $id]);
|
|
} else {
|
|
$newId = JarvisDB::insert(
|
|
'INSERT INTO appointments (title,description,category,start_at,end_at,location,all_day,reminder_min) VALUES (?,?,?,?,?,?,?,?)',
|
|
[$title,$description,$category,$start_at,$end_at,$location,$all_day,$reminder]
|
|
);
|
|
echo json_encode(['success' => true, 'id' => $newId]);
|
|
}
|
|
} elseif ($method === 'DELETE') {
|
|
$id = (int)($_GET['id'] ?? 0);
|
|
if ($id) { JarvisDB::execute('DELETE FROM appointments WHERE id=?', [$id]); }
|
|
echo json_encode(['success' => true]);
|
|
}
|
|
break;
|
|
|
|
// ── Today / briefing summary ──────────────────────────────────────────────
|
|
case 'today':
|
|
default:
|
|
$today = date('Y-m-d');
|
|
$tomorrow = date('Y-m-d', strtotime('+1 day'));
|
|
|
|
$tasks_today = JarvisDB::query(
|
|
"SELECT * FROM tasks WHERE due_date=? AND status NOT IN ('done','cancelled') ORDER BY FIELD(priority,'urgent','high','normal','low')",
|
|
[$today]
|
|
) ?? [];
|
|
$tasks_overdue = JarvisDB::query(
|
|
"SELECT * FROM tasks WHERE due_date < ? AND status NOT IN ('done','cancelled') ORDER BY due_date ASC",
|
|
[$today]
|
|
) ?? [];
|
|
$tasks_pending = JarvisDB::query(
|
|
"SELECT COUNT(*) cnt FROM tasks WHERE status='pending' AND (due_date IS NULL OR due_date >= ?)",
|
|
[$today]
|
|
);
|
|
$appts_today = JarvisDB::query(
|
|
"SELECT * FROM appointments WHERE DATE(start_at)=? ORDER BY start_at ASC",
|
|
[$today]
|
|
) ?? [];
|
|
$appts_upcoming = JarvisDB::query(
|
|
"SELECT * FROM appointments WHERE start_at > NOW() ORDER BY start_at ASC LIMIT 5",
|
|
[]
|
|
) ?? [];
|
|
|
|
echo json_encode([
|
|
'date' => $today,
|
|
'tasks_today' => $tasks_today,
|
|
'tasks_overdue' => $tasks_overdue,
|
|
'pending_count' => (int)($tasks_pending[0]['cnt'] ?? 0),
|
|
'appts_today' => $appts_today,
|
|
'appts_upcoming' => $appts_upcoming,
|
|
]);
|
|
break;
|
|
}
|