Files
Keith SmithandClaude Sonnet 4.5 6a0b35c39c Initial commit: KeepItGoing task management server
Features:
- Django-based REST API with web interface
- Task management with tags, priorities, and due dates
- Time tracking with start/stop timers
- Subtasks support
- Task filtering (all, today, upcoming, overdue, completed)
- Tag-based organization with color coding
- Sorting by due date and priority
- Auto-assign tags when filtering
- Responsive 3-pane layout (sidebar, task list, detail panel)
- Task sharing between users
- Mobile-responsive design with dark mode support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 17:41:29 -07:00

100 lines
2.7 KiB
JavaScript

/**
* KeepItGoing - Main JavaScript
*/
document.addEventListener('DOMContentLoaded', function() {
// Initialize components
initTimerDisplay();
initTaskToggle();
initConfirmDialogs();
});
/**
* Update timer display
*/
function initTimerDisplay() {
const timerDisplay = document.querySelector('.timer-display');
if (!timerDisplay) return;
const startedAt = new Date(timerDisplay.dataset.started);
function updateTimer() {
const now = new Date();
const diff = Math.floor((now - startedAt) / 1000);
const hours = Math.floor(diff / 3600).toString().padStart(2, '0');
const minutes = Math.floor((diff % 3600) / 60).toString().padStart(2, '0');
const seconds = (diff % 60).toString().padStart(2, '0');
timerDisplay.textContent = `${hours}:${minutes}:${seconds}`;
}
updateTimer();
setInterval(updateTimer, 1000);
}
/**
* Handle task toggle without page reload (optional enhancement)
*/
function initTaskToggle() {
// For now, we let the form submit normally
// This could be enhanced with AJAX in the future
}
/**
* Initialize confirmation dialogs
*/
function initConfirmDialogs() {
const deleteButtons = document.querySelectorAll('[data-confirm]');
deleteButtons.forEach(button => {
button.addEventListener('click', function(e) {
const message = this.dataset.confirm || 'Are you sure?';
if (!confirm(message)) {
e.preventDefault();
}
});
});
}
/**
* Format duration in seconds to human-readable string
*/
function formatDuration(seconds) {
if (seconds < 60) {
return `${seconds}s`;
} else if (seconds < 3600) {
const mins = Math.floor(seconds / 60);
return `${mins}m`;
} else {
const hours = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60);
return `${hours}h ${mins}m`;
}
}
/**
* Format date to relative string (today, tomorrow, etc.)
*/
function formatRelativeDate(dateString) {
const date = new Date(dateString);
const today = new Date();
today.setHours(0, 0, 0, 0);
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
const dateOnly = new Date(date);
dateOnly.setHours(0, 0, 0, 0);
if (dateOnly.getTime() === today.getTime()) {
return 'Today';
} else if (dateOnly.getTime() === tomorrow.getTime()) {
return 'Tomorrow';
} else if (dateOnly.getTime() === yesterday.getTime()) {
return 'Yesterday';
} else {
return date.toLocaleDateString();
}
}