Internal
Public Access
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>
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
<!-- Task Detail Panel -->
|
||||
<div class="detail-header">
|
||||
<h2 style="font-size: var(--font-lg); font-weight: 600;">Task Details</h2>
|
||||
<button class="detail-close" onclick="closeDetail()" aria-label="Close detail panel">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M18 6L6 18M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<form method="post" action="{% url 'task-detail' task.id %}" id="task-detail-form">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{% url 'dashboard' %}?selected={{ task.id }}{% if request.GET.filter %}&filter={{ request.GET.filter }}{% endif %}{% if request.GET.tag %}&tag={{ request.GET.tag }}{% endif %}">
|
||||
|
||||
<!-- Title -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="detail-title">Title</label>
|
||||
<input type="text" class="form-input" id="detail-title" name="title" value="{{ task.title }}" required>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="detail-description">Description</label>
|
||||
<textarea class="form-textarea" id="detail-description" name="description" rows="3">{{ task.description }}</textarea>
|
||||
</div>
|
||||
|
||||
<!-- Status & Priority -->
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="detail-status">Status</label>
|
||||
<select class="form-select" id="detail-status" name="status">
|
||||
<option value="pending" {% if task.status == 'pending' %}selected{% endif %}>Pending</option>
|
||||
<option value="in_progress" {% if task.status == 'in_progress' %}selected{% endif %}>In Progress</option>
|
||||
<option value="completed" {% if task.status == 'completed' %}selected{% endif %}>Completed</option>
|
||||
<option value="cancelled" {% if task.status == 'cancelled' %}selected{% endif %}>Cancelled</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="detail-priority">Priority</label>
|
||||
<select class="form-select" id="detail-priority" name="priority">
|
||||
<option value="low" {% if task.priority == 'low' %}selected{% endif %}>Low</option>
|
||||
<option value="medium" {% if task.priority == 'medium' %}selected{% endif %}>Medium</option>
|
||||
<option value="high" {% if task.priority == 'high' %}selected{% endif %}>High</option>
|
||||
<option value="urgent" {% if task.priority == 'urgent' %}selected{% endif %}>Urgent</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Due Date & Time -->
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="detail-due-date">Due Date</label>
|
||||
<input type="date" class="form-input" id="detail-due-date" name="due_date" value="{{ task.due_date|date:'Y-m-d' }}">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="detail-due-time">Due Time</label>
|
||||
<input type="time" class="form-input" id="detail-due-time" name="due_time" value="{{ task.due_time|time:'H:i' }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tags -->
|
||||
{% if tags %}
|
||||
<div class="form-group">
|
||||
<label class="form-label">Tags</label>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: var(--space-sm);">
|
||||
{% for tag in tags %}
|
||||
<label style="display: flex; align-items: center; gap: var(--space-xs); cursor: pointer;">
|
||||
<input type="checkbox" name="tags" value="{{ tag.id }}" {% if tag in task.tags.all %}checked{% endif %}>
|
||||
<span style="color: {{ tag.color }}">{{ tag.name }}</span>
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Recurrence -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="detail-recurrence">Recurrence</label>
|
||||
<select class="form-select" id="detail-recurrence" name="recurrence">
|
||||
<option value="none" {% if task.recurrence == 'none' %}selected{% endif %}>None</option>
|
||||
<option value="daily" {% if task.recurrence == 'daily' %}selected{% endif %}>Daily</option>
|
||||
<option value="weekly" {% if task.recurrence == 'weekly' %}selected{% endif %}>Weekly</option>
|
||||
<option value="biweekly" {% if task.recurrence == 'biweekly' %}selected{% endif %}>Bi-weekly</option>
|
||||
<option value="monthly" {% if task.recurrence == 'monthly' %}selected{% endif %}>Monthly</option>
|
||||
<option value="yearly" {% if task.recurrence == 'yearly' %}selected{% endif %}>Yearly</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Save Button (moved inside form, before subtasks) -->
|
||||
<div class="detail-actions" style="margin-bottom: var(--space-lg);">
|
||||
<button type="submit" class="btn btn-primary" style="flex: 1;">Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Subtasks Section (OUTSIDE the main form) -->
|
||||
<div style="background: var(--bg); border-radius: var(--radius-sm); padding: var(--space-md); margin-bottom: var(--space-lg);">
|
||||
<div style="font-size: var(--font-sm); font-weight: 500; color: var(--text-secondary); margin-bottom: var(--space-sm);">Subtasks</div>
|
||||
|
||||
<!-- Add subtask form (now separate) -->
|
||||
<form method="post" action="{% url 'subtask-create' task.id %}" style="display: flex; gap: var(--space-sm); margin-bottom: var(--space-sm);">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{% url 'dashboard' %}?selected={{ task.id }}{% if request.GET.filter %}&filter={{ request.GET.filter }}{% endif %}{% if request.GET.tag %}&tag={{ request.GET.tag }}{% endif %}">
|
||||
<input type="text" name="title" class="form-input" placeholder="Add a subtask..." style="flex: 1; padding: var(--space-xs) var(--space-sm); font-size: var(--font-sm);" required>
|
||||
<button type="submit" class="btn btn-primary btn-sm">Add</button>
|
||||
</form>
|
||||
|
||||
<!-- Subtask list -->
|
||||
{% if task.subtasks.all %}
|
||||
<div style="display: flex; flex-direction: column; gap: var(--space-xs);">
|
||||
{% for subtask in task.subtasks.all %}
|
||||
<div style="display: flex; align-items: center; gap: var(--space-sm); padding: var(--space-xs); border-radius: var(--radius-xs); background: var(--surface);">
|
||||
<form method="post" action="{% url 'task-toggle' subtask.id %}" style="display: flex;">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{% url 'dashboard' %}?selected={{ task.id }}{% if request.GET.filter %}&filter={{ request.GET.filter }}{% endif %}{% if request.GET.tag %}&tag={{ request.GET.tag }}{% endif %}">
|
||||
<button type="submit" class="task-checkbox {% if subtask.status == 'completed' %}checked{% endif %}" style="width: 16px; height: 16px; font-size: 10px;">
|
||||
{% if subtask.status == 'completed' %}✓{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
<span style="font-size: var(--font-sm); {% if subtask.status == 'completed' %}text-decoration: line-through; color: var(--text-muted);{% endif %}">
|
||||
{{ subtask.title }}
|
||||
</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div style="font-size: var(--font-sm); color: var(--text-muted);">No subtasks</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Time Tracker (OUTSIDE the main form) -->
|
||||
<div class="time-tracker">
|
||||
<div class="time-tracker-header">
|
||||
<span class="time-tracker-label">Time Spent</span>
|
||||
<span class="time-tracker-total">{{ task.total_time_formatted|default:"0:00:00" }}</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: var(--space-sm); margin-top: var(--space-sm);">
|
||||
{% if running_timer and running_timer.task_id == task.id %}
|
||||
<form method="post" action="{% url 'timer-stop' task.id %}" style="flex: 1;">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{% url 'dashboard' %}?selected={{ task.id }}{% if request.GET.filter %}&filter={{ request.GET.filter }}{% endif %}{% if request.GET.tag %}&tag={{ request.GET.tag }}{% endif %}">
|
||||
<button type="submit" class="btn btn-danger btn-full btn-sm">Stop Timer</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<form method="post" action="{% url 'timer-start' task.id %}" style="flex: 1;">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{% url 'dashboard' %}?selected={{ task.id }}{% if request.GET.filter %}&filter={{ request.GET.filter }}{% endif %}{% if request.GET.tag %}&tag={{ request.GET.tag }}{% endif %}">
|
||||
<button type="submit" class="btn btn-secondary btn-full btn-sm">Start Timer</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delete Button (separate form) -->
|
||||
<div class="detail-actions" style="margin-top: var(--space-lg);">
|
||||
<form method="post" action="{% url 'task-delete' task.id %}" onsubmit="return confirm('Delete this task?')">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{% url 'dashboard' %}">
|
||||
<button type="submit" class="btn btn-danger btn-sm">Delete Task</button>
|
||||
</form>
|
||||
</div>
|
||||
Reference in New Issue
Block a user