Finalize three-state toggle feature

This commit is contained in:
2026-02-11 12:27:52 -08:00
parent d48b934f5d
commit 6be1cfb6ab
3 changed files with 79 additions and 51 deletions

2
db.php
View File

@@ -1,5 +1,5 @@
<?php <?php
$host = '192.168.0.201'; $host = 'localhost';
$db = 'tinytask'; $db = 'tinytask';
$user = 'tinytask'; // change this if needed $user = 'tinytask'; // change this if needed
$pass = 'GD3AVEZRNnE@A3P]'; // change this if needed $pass = 'GD3AVEZRNnE@A3P]'; // change this if needed

View File

@@ -46,19 +46,19 @@
font-size: 1.4rem; font-size: 1.4rem;
} }
.modal { .modal {
padding: 2rem; /* or try 3rem or a % like 5% */ padding: 2rem; /* or try 3rem or a % like 5% */
} }
.modal.show { .modal.show {
display: flex !important; display: flex !important;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.modal-dialog { .modal-dialog {
margin: 0; margin: 0;
} }
.modal-content { .modal-content {
font-size: 2.0rem; /* slightly larger than Bootstrap's default (~0.875rem) */ font-size: 2.0rem; /* slightly larger than Bootstrap's default (~0.875rem) */
@@ -104,6 +104,11 @@
background-color: #transparent; background-color: #transparent;
} }
.completed {
text-decoration: line-through;
opacity: 0.5;
}
.btn-icon { .btn-icon {
width: 20px; width: 20px;
height: 20px; height: 20px;
@@ -154,9 +159,9 @@
.project-color-9 .project-header { background-color: #d0e4ff; } .project-color-9 .project-header { background-color: #d0e4ff; }
.project-column { .project-column {
width: 100%; /* 1 per row */ width: 100%; /* 1 per row */
} }
/* Small devices (landscape phones, ≥576px) */ /* Small devices (landscape phones, ≥576px) */
@@ -458,7 +463,8 @@
<div class="project-body"> <div class="project-body">
${project.tasks.map(task => ` ${project.tasks.map(task => `
<div class="d-flex justify-content-between align-items-center small-text mb-1 task-text"> <div class="d-flex justify-content-between align-items-center small-text mb-1 task-text">
<span class="${task.highlighted ? 'highlighted' : ''}" data-task-id="${task.id}">${task.name}</span> <span class="${task.highlighted == 1 ? 'highlighted' : ''} ${task.highlighted == 2 ? 'completed' : ''}".trim()
data-task-id="${task.id}">${task.name}</span>
<div class="d-flex"> <div class="d-flex">
<button class="btn-icon add-subtask-btn" data-task-id="${task.id}" title="Add Subtask"> <button class="btn-icon add-subtask-btn" data-task-id="${task.id}" title="Add Subtask">
<i class="bi bi-plus"></i> <i class="bi bi-plus"></i>
@@ -471,7 +477,8 @@
<div class="ms-3"> <div class="ms-3">
${task.subtasks.map(sub => ` ${task.subtasks.map(sub => `
<div class="d-flex justify-content-between align-items-center small-text mb-1"> <div class="d-flex justify-content-between align-items-center small-text mb-1">
<span class="${sub.highlighted ? 'highlighted' : ''}" data-subtask-id="${sub.id}">${sub.name}</span> <span class="${sub.highlighted == 1 ? 'highlighted' : ''} ${sub.highlighted == 2 ? 'completed' : ''}".trim()
data-subtask-id="${sub.id}">${sub.name}</span>
<button class="btn-icon text-danger delete-subtask-btn" data-subtask-id="${sub.id}" title="Delete Subtask"> <button class="btn-icon text-danger delete-subtask-btn" data-subtask-id="${sub.id}" title="Delete Subtask">
<i class="bi bi-dash"></i> <i class="bi bi-dash"></i>
</button> </button>
@@ -615,31 +622,43 @@ document.querySelectorAll('.project-column').forEach(col => {
}); });
}); });
document.querySelectorAll('[data-task-id]').forEach(span => { document.querySelectorAll('[data-task-id]').forEach(span => {
span.addEventListener('click', () => { span.addEventListener('click', () => {
const taskId = span.dataset.taskId; const taskId = span.dataset.taskId;
const isHighlighted = span.classList.toggle('highlighted');
fetch('toggle_highlight.php', { fetch('toggle_highlight.php', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'task', id: taskId, highlighted: isHighlighted }) body: JSON.stringify({ type: 'task', id: taskId })
}); })
}); .then(res => res.json())
}); .then(data => {
if (!data.success) return;
document.querySelectorAll('[data-subtask-id]').forEach(span => { span.classList.toggle('highlighted', data.highlighted === 1);
span.addEventListener('click', () => { span.classList.toggle('completed', data.highlighted === 2);
const subtaskId = span.dataset.subtaskId; });
const isHighlighted = span.classList.toggle('highlighted'); });
});
fetch('toggle_highlight.php', { document.querySelectorAll('[data-subtask-id]').forEach(span => {
method: 'POST', span.addEventListener('click', () => {
headers: { 'Content-Type': 'application/json' }, const subtaskId = span.dataset.subtaskId;
body: JSON.stringify({ type: 'subtask', id: subtaskId, highlighted: isHighlighted })
}); fetch('toggle_highlight.php', {
}); method: 'POST',
}); headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'subtask', id: subtaskId })
})
.then(res => res.json())
.then(data => {
if (!data.success) return;
span.classList.toggle('highlighted', data.highlighted === 1);
span.classList.toggle('completed', data.highlighted === 2);
});
});
});
let itemToDelete = null; let itemToDelete = null;

View File

@@ -3,19 +3,28 @@ require 'db.php';
$data = json_decode(file_get_contents('php://input'), true); $data = json_decode(file_get_contents('php://input'), true);
$type = $data['type']; $type = $data['type'] ?? '';
$id = intval($data['id']); $id = intval($data['id'] ?? 0);
$highlighted = isset($data['highlighted']) && $data['highlighted'] ? 1 : 0;
if ($id <= 0 || ($type !== 'task' && $type !== 'subtask')) {
echo json_encode(['success' => false, 'error' => 'Invalid request']);
exit;
}
if ($type === 'task') { if ($type === 'task') {
$stmt = $pdo->prepare("UPDATE tasks SET highlighted = ? WHERE id = ?"); $stmt = $pdo->prepare("UPDATE tasks SET highlighted = (highlighted + 1) % 3 WHERE id = ?");
$stmt->execute([$highlighted, $id]); $stmt->execute([$id]);
echo json_encode(['success' => true]);
} elseif ($type === 'subtask') { $stmt = $pdo->prepare("SELECT highlighted FROM tasks WHERE id = ?");
$stmt = $pdo->prepare("UPDATE subtasks SET highlighted = ? WHERE id = ?"); $stmt->execute([$id]);
$stmt->execute([$highlighted, $id]); $newState = intval($stmt->fetchColumn());
echo json_encode(['success' => true]);
} else { } else {
echo json_encode(['success' => false, 'error' => 'Invalid type']); $stmt = $pdo->prepare("UPDATE subtasks SET highlighted = (highlighted + 1) % 3 WHERE id = ?");
$stmt->execute([$id]);
$stmt = $pdo->prepare("SELECT highlighted FROM subtasks WHERE id = ?");
$stmt->execute([$id]);
$newState = intval($stmt->fetchColumn());
} }
?>
echo json_encode(['success' => true, 'highlighted' => $newState]);