Finalize three-state toggle feature
This commit is contained in:
2
db.php
2
db.php
@@ -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
|
||||||
|
|||||||
95
index.php
95
index.php
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
Reference in New Issue
Block a user