feat: implement subtasks, track task completion/archival users, and enhance kanban UI with drag-and-drop states

This commit is contained in:
root
2026-03-29 19:46:21 +07:00
parent afb7ef2a37
commit 78d309ae4e
3 changed files with 169 additions and 12 deletions

View File

@@ -15,7 +15,10 @@ if ($action === 'api') {
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN status_updated_at DATETIME"); } catch(Exception $e) {}
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN due_date DATE"); } catch(Exception $e) {}
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN custom_assignee_name TEXT"); } catch(Exception $e) {}
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN completed_by INTEGER DEFAULT NULL"); } catch(Exception $e) {}
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN archived_by INTEGER DEFAULT NULL"); } catch(Exception $e) {}
try { $pdo->exec("CREATE TABLE IF NOT EXISTS task_attachments (id INTEGER PRIMARY KEY AUTOINCREMENT, task_id INTEGER, file_name TEXT, file_path TEXT, owner_id INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP)"); } catch(Exception $e) {}
try { $pdo->exec("CREATE TABLE IF NOT EXISTS task_subtasks (id INTEGER PRIMARY KEY AUTOINCREMENT, task_id INTEGER, title TEXT NOT NULL, is_completed INTEGER DEFAULT 0, created_by INTEGER, completed_by INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP)"); } catch(Exception $e) {}
$format_dt = function($value) {
$value = is_string($value) ? trim($value) : $value;
@@ -37,14 +40,54 @@ if ($action === 'api') {
if(!isset($_SESSION['user_id'])) die(json_encode(['status'=>'error','msg'=>'unauthorized']));
$task_id = $_POST['task_id'] ?? null;
$status = $_POST['status'] ?? null;
$stmt = $pdo->prepare("UPDATE tasks SET status = ?, status_updated_at = CURRENT_TIMESTAMP WHERE id = ?");
$stmt->execute([$status, $task_id]);
$user_id = $_SESSION['user_id'];
$set_clause = "status = ?, status_updated_at = CURRENT_TIMESTAMP";
$params = [$status];
if ($status === 'completed') {
$set_clause .= ", completed_by = ?";
$params[] = $user_id;
} elseif ($status === 'archived') {
$set_clause .= ", archived_by = ?";
$params[] = $user_id;
}
$params[] = $task_id;
$stmt = $pdo->prepare("UPDATE tasks SET $set_clause WHERE id = ?");
$stmt->execute($params);
$task_to_upd = query("SELECT title FROM tasks WHERE id=?", [$task_id])->fetch();
if($task_to_upd) notify_waha('Moved to '.$status, 'Task Status', $task_to_upd['title']);
echo json_encode(['status'=>'ok']);
exit;
}
if($api_action === 'add_subtask') {
if(!isset($_SESSION['user_id'])) die(json_encode(['status'=>'error','msg'=>'unauthorized']));
$task_id = $_POST['task_id'] ?? null;
$title = $_POST['title'] ?? null;
$user_id = $_SESSION['user_id'];
if($task_id && $title) {
$stmt = $pdo->prepare("INSERT INTO task_subtasks (task_id, title, created_by) VALUES (?, ?, ?)");
$stmt->execute([$task_id, $title, $user_id]);
}
echo json_encode(['status'=>'ok']);
exit;
}
if($api_action === 'toggle_subtask') {
if(!isset($_SESSION['user_id'])) die(json_encode(['status'=>'error','msg'=>'unauthorized']));
$subtask_id = $_POST['subtask_id'] ?? null;
$is_completed = (int)($_POST['is_completed'] ?? 0);
$user_id = $_SESSION['user_id'];
if($subtask_id) {
$stmt = $pdo->prepare("UPDATE task_subtasks SET is_completed = ?, completed_by = ? WHERE id = ?");
$stmt->execute([$is_completed, $is_completed ? $user_id : null, $subtask_id]);
}
echo json_encode(['status'=>'ok']);
exit;
}
if($api_action === 'get_tasks_status') {
$task_id = $_GET['task_id'] ?? null;