R1 foundation - Phase 1 live build

This commit is contained in:
2026-02-28 03:33:33 +00:00
commit f36ea194f3
45 changed files with 4009 additions and 0 deletions

22
templates/area_form.html Normal file
View File

@@ -0,0 +1,22 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb"><a href="/areas">Areas</a><span class="sep">/</span><span>{{ 'Edit' if item else 'New Area' }}</span></div>
<div class="page-header"><h1 class="page-title">{{ 'Edit Area' if item else 'New Area' }}</h1></div>
<div class="card">
<form method="post" action="{{ '/areas/' ~ item.id ~ '/edit' if item else '/areas/create' }}">
<div class="form-grid">
<div class="form-group"><label class="form-label">Name *</label><input type="text" name="name" class="form-input" required value="{{ item.name if item else '' }}"></div>
<div class="form-group"><label class="form-label">Domain *</label>
<select name="domain_id" class="form-select" required>
{% for d in domains %}<option value="{{ d.id }}" {{ 'selected' if (item and item.domain_id|string == d.id|string) or (not item and prefill_domain_id == d.id|string) }}>{{ d.name }}</option>{% endfor %}
</select></div>
<div class="form-group"><label class="form-label">Status</label>
<select name="status" class="form-select">
<option value="active" {{ 'selected' if not item or item.status == 'active' }}>Active</option>
<option value="inactive" {{ 'selected' if item and item.status == 'inactive' }}>Inactive</option>
</select></div>
<div class="form-group full-width"><label class="form-label">Description</label><textarea name="description" class="form-textarea" rows="3">{{ item.description if item and item.description else '' }}</textarea></div>
<div class="form-actions"><button type="submit" class="btn btn-primary">{{ 'Save' if item else 'Create' }}</button><a href="/areas" class="btn btn-secondary">Cancel</a></div>
</div>
</form></div>
{% endblock %}

25
templates/areas.html Normal file
View File

@@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">Areas<span class="page-count">{{ items|length }}</span></h1>
<a href="/areas/create" class="btn btn-primary">+ New Area</a>
</div>
{% if items %}
<div class="card">
{% for item in items %}
<div class="list-row">
<span class="row-domain-tag" style="background:{{ item.domain_color or '#4F6EF7' }}22;color:{{ item.domain_color or '#4F6EF7' }}">{{ item.domain_name }}</span>
<span class="row-title">{{ item.name }}</span>
{% if item.description %}<span class="row-meta">{{ item.description[:60] }}</span>{% endif %}
<span class="status-badge status-{{ item.status }}">{{ item.status }}</span>
<div class="row-actions">
<a href="/areas/{{ item.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
<form action="/areas/{{ item.id }}/delete" method="post" data-confirm="Delete this area?" style="display:inline"><button class="btn btn-ghost btn-xs" style="color:var(--red)">Del</button></form>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state"><div class="empty-state-text">No areas yet</div><a href="/areas/create" class="btn btn-primary">Create Area</a></div>
{% endif %}
{% endblock %}

111
templates/base.html Normal file
View File

@@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ page_title or "Life OS" }} - Life OS</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="app-layout">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<a href="/" class="sidebar-logo">Life<span>OS</span></a>
</div>
<nav class="sidebar-nav">
<div class="nav-section">
<a href="/" class="nav-item {{ 'active' if active_nav == 'dashboard' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
Dashboard
</a>
<a href="/focus" class="nav-item {{ 'active' if active_nav == 'focus' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>
Focus
{% if sidebar.focus_count %}<span class="badge">{{ sidebar.focus_count }}</span>{% endif %}
</a>
<a href="/tasks" class="nav-item {{ 'active' if active_nav == 'tasks' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>
All Tasks
</a>
<a href="/projects" class="nav-item {{ 'active' if active_nav == 'projects' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
Projects
</a>
<a href="/notes" class="nav-item {{ 'active' if active_nav == 'notes' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></svg>
Notes
</a>
<a href="/contacts" class="nav-item {{ 'active' if active_nav == 'contacts' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
Contacts
</a>
<a href="/links" class="nav-item {{ 'active' if active_nav == 'links' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
Links
</a>
<a href="/capture" class="nav-item {{ 'active' if active_nav == 'capture' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg>
Capture
{% if sidebar.capture_count %}<span class="badge">{{ sidebar.capture_count }}</span>{% endif %}
</a>
</div>
<!-- Domain hierarchy -->
<div class="nav-section">
<div class="nav-section-label">Domains</div>
{% for domain in sidebar.domain_tree %}
<div class="domain-group">
<div class="domain-header" data-domain-id="{{ domain.id }}">
<span class="domain-dot" style="background: {{ domain.color or '#4F6EF7' }}"></span>
{{ domain.name }}
</div>
<div class="domain-children" data-domain-id="{{ domain.id }}">
{% for area in domain.areas %}
<div class="area-label">{{ area.name }}</div>
{% for p in area.projects %}
<a href="/projects/{{ p.id }}" class="project-link">{{ p.name }}</a>
{% endfor %}
{% endfor %}
{% for p in domain.standalone_projects %}
<a href="/projects/{{ p.id }}" class="project-link">{{ p.name }}</a>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
<div class="nav-section" style="margin-top: auto; padding-bottom: 12px;">
<a href="/domains" class="nav-item {{ 'active' if active_nav == 'domains' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M12 1v6m0 6v6m-7-7h6m6 0h6"/></svg>
Manage Domains
</a>
<a href="/areas" class="nav-item {{ 'active' if active_nav == 'areas' }}">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="9" y1="21" x2="9" y2="9"/></svg>
Manage Areas
</a>
<div class="nav-item" onclick="toggleTheme()" style="cursor: pointer;">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
Toggle Theme
</div>
</div>
</nav>
</aside>
<!-- Main content -->
<main class="main-content">
<header class="topbar">
{% if request.state.environment == 'development' %}
<span class="topbar-env">DEV</span>
{% endif %}
<div class="topbar-spacer"></div>
</header>
<div class="page-content">
{% block content %}{% endblock %}
</div>
</main>
</div>
<script src="/static/app.js"></script>
</body>
</html>

42
templates/capture.html Normal file
View File

@@ -0,0 +1,42 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">Capture<span class="page-count">{{ items|length }}</span></h1>
</div>
<!-- Quick capture input -->
<div class="card mb-4">
<form action="/capture/add" method="post">
<label class="form-label mb-2">Quick Capture (one item per line)</label>
<textarea name="raw_text" class="form-textarea" rows="3" placeholder="Type or paste items here...&#10;Each line becomes a separate capture item"></textarea>
<div class="mt-2"><button type="submit" class="btn btn-primary">Capture</button></div>
</form>
</div>
<div class="flex items-center gap-2 mb-3">
<a href="/capture?show=unprocessed" class="btn {{ 'btn-primary' if show != 'all' else 'btn-secondary' }} btn-sm">Unprocessed</a>
<a href="/capture?show=all" class="btn {{ 'btn-primary' if show == 'all' else 'btn-secondary' }} btn-sm">All</a>
</div>
{% if items %}
{% for item in items %}
<div class="capture-item {{ 'completed' if item.processed }}">
<div class="capture-text {{ 'text-muted' if item.processed }}" style="{{ 'text-decoration:line-through' if item.processed }}">{{ item.raw_text }}</div>
{% if not item.processed %}
<div class="capture-actions">
<form action="/capture/{{ item.id }}/to-task" method="post" class="flex gap-2">
<select name="domain_id" class="filter-select" style="font-size:0.75rem;padding:3px 6px" required>
{% for d in sidebar.domain_tree %}<option value="{{ d.id }}">{{ d.name }}</option>{% endfor %}
</select>
<button type="submit" class="btn btn-ghost btn-xs" style="color:var(--green)">To Task</button>
</form>
<form action="/capture/{{ item.id }}/dismiss" method="post" style="display:inline"><button class="btn btn-ghost btn-xs">Dismiss</button></form>
<form action="/capture/{{ item.id }}/delete" method="post" style="display:inline"><button class="btn btn-ghost btn-xs" style="color:var(--red)">&times;</button></form>
</div>
{% endif %}
</div>
{% endfor %}
{% else %}
<div class="empty-state"><div class="empty-state-icon">&#128229;</div><div class="empty-state-text">Capture queue is empty</div></div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb"><a href="/contacts">Contacts</a><span class="sep">/</span><span>{{ item.first_name }} {{ item.last_name or '' }}</span></div>
<div class="detail-header">
<div class="flex items-center justify-between">
<h1 class="detail-title">{{ item.first_name }} {{ item.last_name or '' }}</h1>
<div class="flex gap-2">
<a href="/contacts/{{ item.id }}/edit" class="btn btn-secondary btn-sm">Edit</a>
<form action="/contacts/{{ item.id }}/delete" method="post" data-confirm="Delete?" style="display:inline"><button class="btn btn-danger btn-sm">Delete</button></form>
</div>
</div>
<div class="detail-meta mt-2">
{% if item.company %}<span class="row-tag">{{ item.company }}</span>{% endif %}
{% if item.role %}<span class="detail-meta-item">{{ item.role }}</span>{% endif %}
</div>
</div>
<div class="card">
<div class="form-grid" style="gap:12px">
{% if item.email %}<div class="form-group"><div class="form-label">Email</div><a href="mailto:{{ item.email }}">{{ item.email }}</a></div>{% endif %}
{% if item.phone %}<div class="form-group"><div class="form-label">Phone</div><a href="tel:{{ item.phone }}">{{ item.phone }}</a></div>{% endif %}
{% if item.notes %}<div class="form-group full-width"><div class="form-label">Notes</div><div class="detail-body" style="white-space:pre-wrap">{{ item.notes }}</div></div>{% endif %}
{% if item.tags %}<div class="form-group full-width"><div class="form-label">Tags</div><div class="flex gap-2">{% for tag in item.tags %}<span class="row-tag">{{ tag }}</span>{% endfor %}</div></div>{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,19 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb"><a href="/contacts">Contacts</a><span class="sep">/</span><span>{{ 'Edit' if item else 'New Contact' }}</span></div>
<div class="page-header"><h1 class="page-title">{{ 'Edit Contact' if item else 'New Contact' }}</h1></div>
<div class="card">
<form method="post" action="{{ '/contacts/' ~ item.id ~ '/edit' if item else '/contacts/create' }}">
<div class="form-grid">
<div class="form-group"><label class="form-label">First Name *</label><input type="text" name="first_name" class="form-input" required value="{{ item.first_name if item else '' }}"></div>
<div class="form-group"><label class="form-label">Last Name</label><input type="text" name="last_name" class="form-input" value="{{ item.last_name if item and item.last_name else '' }}"></div>
<div class="form-group"><label class="form-label">Company</label><input type="text" name="company" class="form-input" value="{{ item.company if item and item.company else '' }}"></div>
<div class="form-group"><label class="form-label">Role</label><input type="text" name="role" class="form-input" value="{{ item.role if item and item.role else '' }}"></div>
<div class="form-group"><label class="form-label">Email</label><input type="email" name="email" class="form-input" value="{{ item.email if item and item.email else '' }}"></div>
<div class="form-group"><label class="form-label">Phone</label><input type="tel" name="phone" class="form-input" value="{{ item.phone if item and item.phone else '' }}"></div>
<div class="form-group full-width"><label class="form-label">Notes</label><textarea name="notes" class="form-textarea" rows="4">{{ item.notes if item and item.notes else '' }}</textarea></div>
<div class="form-group full-width"><label class="form-label">Tags</label><input type="text" name="tags" class="form-input" value="{{ item.tags|join(', ') if item and item.tags else '' }}"></div>
<div class="form-actions"><button type="submit" class="btn btn-primary">{{ 'Save' if item else 'Create' }}</button><a href="/contacts" class="btn btn-secondary">Cancel</a></div>
</div>
</form></div>
{% endblock %}

25
templates/contacts.html Normal file
View File

@@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">Contacts<span class="page-count">{{ items|length }}</span></h1>
<a href="/contacts/create" class="btn btn-primary">+ New Contact</a>
</div>
{% if items %}
<div class="card">
{% for item in items %}
<div class="list-row">
<span class="row-title"><a href="/contacts/{{ item.id }}">{{ item.first_name }} {{ item.last_name or '' }}</a></span>
{% if item.company %}<span class="row-tag">{{ item.company }}</span>{% endif %}
{% if item.role %}<span class="row-meta">{{ item.role }}</span>{% endif %}
{% if item.email %}<span class="row-meta">{{ item.email }}</span>{% endif %}
<div class="row-actions">
<a href="/contacts/{{ item.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
<form action="/contacts/{{ item.id }}/delete" method="post" data-confirm="Delete?" style="display:inline"><button class="btn btn-ghost btn-xs" style="color:var(--red)">Del</button></form>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state"><div class="empty-state-icon">&#128100;</div><div class="empty-state-text">No contacts yet</div><a href="/contacts/create" class="btn btn-primary">Add Contact</a></div>
{% endif %}
{% endblock %}

86
templates/dashboard.html Normal file
View File

@@ -0,0 +1,86 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">Dashboard</h1>
</div>
<!-- Stats -->
<div class="dashboard-grid mb-4">
<div class="stat-card">
<div class="stat-value">{{ stats.open_tasks or 0 }}</div>
<div class="stat-label">Open Tasks</div>
</div>
<div class="stat-card">
<div class="stat-value">{{ stats.in_progress or 0 }}</div>
<div class="stat-label">In Progress</div>
</div>
<div class="stat-card">
<div class="stat-value">{{ stats.done_this_week or 0 }}</div>
<div class="stat-label">Done This Week</div>
</div>
<div class="stat-card">
<div class="stat-value">{{ focus_items|length }}</div>
<div class="stat-label">Today's Focus</div>
</div>
</div>
<div class="dashboard-grid">
<!-- Today's Focus -->
<div class="card">
<div class="card-header">
<h2 class="card-title">Today's Focus</h2>
<a href="/focus" class="btn btn-ghost btn-sm">View All</a>
</div>
{% if focus_items %}
{% for item in focus_items %}
<div class="focus-item {{ 'completed' if item.completed }}">
<span class="priority-dot priority-{{ item.priority }}"></span>
<a href="/tasks/{{ item.task_id }}" class="focus-title">{{ item.title }}</a>
{% if item.project_name %}
<span class="row-meta">{{ item.project_name }}</span>
{% endif %}
</div>
{% endfor %}
{% else %}
<div class="empty-state">
<div class="empty-state-text">No focus items for today</div>
<a href="/focus" class="btn btn-primary btn-sm">Set Focus</a>
</div>
{% endif %}
</div>
<!-- Overdue + Upcoming -->
<div class="card">
<div class="card-header">
<h2 class="card-title">Upcoming</h2>
</div>
{% if overdue_tasks %}
<div class="text-xs text-muted mb-2" style="font-weight:600; color: var(--red);">OVERDUE</div>
{% for t in overdue_tasks %}
<div class="list-row">
<span class="priority-dot priority-{{ t.priority }}"></span>
<span class="row-title"><a href="/tasks/{{ t.id }}">{{ t.title }}</a></span>
<span class="row-meta overdue">{{ t.due_date }}</span>
</div>
{% endfor %}
{% endif %}
{% if upcoming_tasks %}
<div class="text-xs text-muted mb-2 {{ 'mt-3' if overdue_tasks }}" style="font-weight:600;">NEXT 7 DAYS</div>
{% for t in upcoming_tasks %}
<div class="list-row">
<span class="priority-dot priority-{{ t.priority }}"></span>
<span class="row-title"><a href="/tasks/{{ t.id }}">{{ t.title }}</a></span>
<span class="row-meta">{{ t.due_date }}</span>
</div>
{% endfor %}
{% endif %}
{% if not overdue_tasks and not upcoming_tasks %}
<div class="empty-state">
<div class="empty-state-text">No upcoming deadlines</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,17 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb"><a href="/domains">Domains</a><span class="sep">/</span><span>{{ 'Edit' if item else 'New Domain' }}</span></div>
<div class="page-header"><h1 class="page-title">{{ 'Edit Domain' if item else 'New Domain' }}</h1></div>
<div class="card">
<form method="post" action="{{ '/domains/' ~ item.id ~ '/edit' if item else '/domains/create' }}">
<div class="form-grid">
<div class="form-group"><label class="form-label">Name *</label><input type="text" name="name" class="form-input" required value="{{ item.name if item else '' }}"></div>
<div class="form-group"><label class="form-label">Color</label><input type="color" name="color" class="form-input" value="{{ item.color if item and item.color else '#4F6EF7' }}" style="height:42px;padding:4px"></div>
<div class="form-group full-width"><label class="form-label">Description</label><textarea name="description" class="form-textarea" rows="3">{{ item.description if item and item.description else '' }}</textarea></div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">{{ 'Save' if item else 'Create' }}</button>
<a href="/domains" class="btn btn-secondary">Cancel</a>
</div>
</div>
</form></div>
{% endblock %}

26
templates/domains.html Normal file
View File

@@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">Domains<span class="page-count">{{ items|length }}</span></h1>
<a href="/domains/create" class="btn btn-primary">+ New Domain</a>
</div>
{% if items %}
<div class="card">
{% for item in items %}
<div class="list-row">
<span class="domain-dot" style="background: {{ item.color or '#4F6EF7' }}"></span>
<span class="row-title"><a href="/tasks?domain_id={{ item.id }}">{{ item.name }}</a></span>
{% if item.description %}<span class="row-meta">{{ item.description }}</span>{% endif %}
<div class="row-actions">
<a href="/domains/{{ item.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
<form action="/domains/{{ item.id }}/delete" method="post" data-confirm="Delete this domain and all its contents?" style="display:inline">
<button class="btn btn-ghost btn-xs" style="color:var(--red)">Del</button>
</form>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state"><div class="empty-state-text">No domains. Create your first life domain.</div><a href="/domains/create" class="btn btn-primary">Create Domain</a></div>
{% endif %}
{% endblock %}

58
templates/focus.html Normal file
View File

@@ -0,0 +1,58 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">Daily Focus</h1>
<div class="flex items-center gap-2">
{% if total_estimated %}<span class="text-sm text-muted">~{{ total_estimated }}min estimated</span>{% endif %}
</div>
</div>
<div class="flex items-center gap-2 mb-4">
<a href="/focus?focus_date={{ (focus_date|string)[:10] }}" class="btn btn-ghost btn-sm">Today</a>
<span class="text-sm" style="font-weight:600">{{ focus_date }}</span>
</div>
<!-- Focus items -->
{% if items %}
{% for item in items %}
<div class="focus-item {{ 'completed' if item.completed }}">
<form action="/focus/{{ item.id }}/toggle" method="post" style="display:inline">
<div class="row-check">
<input type="checkbox" id="f-{{ item.id }}" {{ 'checked' if item.completed }} onchange="this.form.submit()">
<label for="f-{{ item.id }}"></label>
</div>
</form>
<span class="priority-dot priority-{{ item.priority }}"></span>
<a href="/tasks/{{ item.task_id }}" class="focus-title">{{ item.title }}</a>
{% if item.project_name %}<span class="row-tag">{{ item.project_name }}</span>{% endif %}
{% if item.estimated_minutes %}<span class="focus-meta">~{{ item.estimated_minutes }}min</span>{% endif %}
{% if item.due_date %}<span class="focus-meta">{{ item.due_date }}</span>{% endif %}
<form action="/focus/{{ item.id }}/remove" method="post" style="display:inline">
<button class="btn btn-ghost btn-xs" style="color:var(--red)" title="Remove from focus">&times;</button>
</form>
</div>
{% endfor %}
{% else %}
<div class="empty-state mb-4"><div class="empty-state-text">No focus items for this day</div></div>
{% endif %}
<!-- Add task to focus -->
{% if available_tasks %}
<div class="card mt-4">
<div class="card-header"><h2 class="card-title">Add to Focus</h2></div>
{% for t in available_tasks[:15] %}
<div class="list-row">
<span class="priority-dot priority-{{ t.priority }}"></span>
<span class="row-title">{{ t.title }}</span>
{% if t.project_name %}<span class="row-tag">{{ t.project_name }}</span>{% endif %}
{% if t.due_date %}<span class="row-meta">{{ t.due_date }}</span>{% endif %}
<form action="/focus/add" method="post" style="display:inline">
<input type="hidden" name="task_id" value="{{ t.id }}">
<input type="hidden" name="focus_date" value="{{ focus_date }}">
<button class="btn btn-ghost btn-xs" style="color:var(--green)">+ Focus</button>
</form>
</div>
{% endfor %}
</div>
{% endif %}
{% endblock %}

18
templates/link_form.html Normal file
View File

@@ -0,0 +1,18 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb"><a href="/links">Links</a><span class="sep">/</span><span>{{ 'Edit' if item else 'New Link' }}</span></div>
<div class="page-header"><h1 class="page-title">{{ 'Edit Link' if item else 'New Link' }}</h1></div>
<div class="card">
<form method="post" action="{{ '/links/' ~ item.id ~ '/edit' if item else '/links/create' }}">
<div class="form-grid">
<div class="form-group"><label class="form-label">Label *</label><input type="text" name="label" class="form-input" required value="{{ item.label if item else '' }}"></div>
<div class="form-group"><label class="form-label">URL *</label><input type="url" name="url" class="form-input" required value="{{ item.url if item else '' }}"></div>
<div class="form-group"><label class="form-label">Domain *</label>
<select name="domain_id" class="form-select" required>{% for d in domains %}<option value="{{ d.id }}" {{ 'selected' if (item and item.domain_id|string == d.id|string) or (not item and prefill_domain_id == d.id|string) }}>{{ d.name }}</option>{% endfor %}</select></div>
<div class="form-group"><label class="form-label">Project</label>
<select name="project_id" class="form-select"><option value="">-- None --</option>{% for p in projects %}<option value="{{ p.id }}" {{ 'selected' if (item and item.project_id and item.project_id|string == p.id|string) or (not item and prefill_project_id == p.id|string) }}>{{ p.name }}</option>{% endfor %}</select></div>
<div class="form-group full-width"><label class="form-label">Description</label><textarea name="description" class="form-textarea" rows="3">{{ item.description if item and item.description else '' }}</textarea></div>
<div class="form-actions"><button type="submit" class="btn btn-primary">{{ 'Save' if item else 'Create' }}</button><a href="/links" class="btn btn-secondary">Cancel</a></div>
</div>
</form></div>
{% endblock %}

25
templates/links.html Normal file
View File

@@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">Links<span class="page-count">{{ items|length }}</span></h1>
<a href="/links/create" class="btn btn-primary">+ New Link</a>
</div>
{% if items %}
<div class="card">
{% for item in items %}
<div class="list-row">
{% if item.domain_color %}<span class="row-domain-tag" style="background:{{ item.domain_color }}22;color:{{ item.domain_color }}">{{ item.domain_name }}</span>{% endif %}
<span class="row-title"><a href="{{ item.url }}" target="_blank">{{ item.label }}</a></span>
{% if item.project_name %}<span class="row-tag">{{ item.project_name }}</span>{% endif %}
<span class="row-meta">{{ item.url[:50] }}{% if item.url|length > 50 %}...{% endif %}</span>
<div class="row-actions">
<a href="/links/{{ item.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
<form action="/links/{{ item.id }}/delete" method="post" data-confirm="Delete?" style="display:inline"><button class="btn btn-ghost btn-xs" style="color:var(--red)">Del</button></form>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state"><div class="empty-state-icon">&#128279;</div><div class="empty-state-text">No links yet</div><a href="/links/create" class="btn btn-primary">Add Link</a></div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb">
{% if domain %}<span style="color:{{ domain.color }}">{{ domain.name }}</span><span class="sep">/</span>{% endif %}
{% if project %}<a href="/projects/{{ project.id }}">{{ project.name }}</a><span class="sep">/</span>{% endif %}
<span>{{ item.title }}</span>
</div>
<div class="detail-header">
<div class="flex items-center justify-between">
<h1 class="detail-title">{{ item.title }}</h1>
<div class="flex gap-2">
<a href="/notes/{{ item.id }}/edit" class="btn btn-secondary btn-sm">Edit</a>
<form action="/notes/{{ item.id }}/delete" method="post" data-confirm="Delete?" style="display:inline"><button class="btn btn-danger btn-sm">Delete</button></form>
</div>
</div>
<div class="detail-meta mt-2">
<span class="detail-meta-item">Updated {{ item.updated_at.strftime('%Y-%m-%d %H:%M') if item.updated_at else '' }}</span>
{% if item.tags %}{% for tag in item.tags %}<span class="row-tag">{{ tag }}</span>{% endfor %}{% endif %}
</div>
</div>
{% if item.body %}
<div class="card"><div class="detail-body" style="white-space:pre-wrap;font-family:var(--font-body)">{{ item.body }}</div></div>
{% else %}
<div class="card"><div class="text-muted" style="padding:20px">No content yet. <a href="/notes/{{ item.id }}/edit">Start writing</a></div></div>
{% endif %}
{% endblock %}

19
templates/note_form.html Normal file
View File

@@ -0,0 +1,19 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb"><a href="/notes">Notes</a><span class="sep">/</span><span>{{ 'Edit' if item else 'New Note' }}</span></div>
<div class="page-header"><h1 class="page-title">{{ 'Edit Note' if item else 'New Note' }}</h1></div>
<div class="card">
<form method="post" action="{{ '/notes/' ~ item.id ~ '/edit' if item else '/notes/create' }}">
<div class="form-grid">
<div class="form-group full-width"><label class="form-label">Title *</label><input type="text" name="title" class="form-input" required value="{{ item.title if item else '' }}"></div>
<div class="form-group"><label class="form-label">Domain *</label>
<select name="domain_id" class="form-select" required>{% for d in domains %}<option value="{{ d.id }}" {{ 'selected' if (item and item.domain_id|string == d.id|string) or (not item and prefill_domain_id == d.id|string) }}>{{ d.name }}</option>{% endfor %}</select></div>
<div class="form-group"><label class="form-label">Project</label>
<select name="project_id" class="form-select"><option value="">-- None --</option>{% for p in projects %}<option value="{{ p.id }}" {{ 'selected' if (item and item.project_id and item.project_id|string == p.id|string) or (not item and prefill_project_id == p.id|string) }}>{{ p.name }}</option>{% endfor %}</select></div>
<div class="form-group full-width"><label class="form-label">Content</label><textarea name="body" class="form-textarea" rows="15" style="font-family:var(--font-mono);font-size:0.88rem">{{ item.body if item and item.body else '' }}</textarea></div>
<div class="form-group full-width"><label class="form-label">Tags</label><input type="text" name="tags" class="form-input" value="{{ item.tags|join(', ') if item and item.tags else '' }}"></div>
<input type="hidden" name="content_format" value="rich">
<div class="form-actions"><button type="submit" class="btn btn-primary">{{ 'Save' if item else 'Create' }}</button><a href="{{ '/notes/' ~ item.id if item else '/notes' }}" class="btn btn-secondary">Cancel</a></div>
</div>
</form></div>
{% endblock %}

25
templates/notes.html Normal file
View File

@@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">Notes<span class="page-count">{{ items|length }}</span></h1>
<a href="/notes/create" class="btn btn-primary">+ New Note</a>
</div>
{% if items %}
<div class="card">
{% for item in items %}
<div class="list-row">
{% if item.domain_color %}<span class="row-domain-tag" style="background:{{ item.domain_color }}22;color:{{ item.domain_color }}">{{ item.domain_name }}</span>{% endif %}
<span class="row-title"><a href="/notes/{{ item.id }}">{{ item.title }}</a></span>
{% if item.project_name %}<span class="row-tag">{{ item.project_name }}</span>{% endif %}
<span class="row-meta">{{ item.updated_at.strftime('%Y-%m-%d') if item.updated_at else '' }}</span>
<div class="row-actions">
<a href="/notes/{{ item.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
<form action="/notes/{{ item.id }}/delete" method="post" data-confirm="Delete?" style="display:inline"><button class="btn btn-ghost btn-xs" style="color:var(--red)">Del</button></form>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state"><div class="empty-state-icon">&#128196;</div><div class="empty-state-text">No notes yet</div><a href="/notes/create" class="btn btn-primary">Create Note</a></div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,95 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb">
{% if domain %}<span style="color: {{ domain.color or '#4F6EF7' }}">{{ domain.name }}</span><span class="sep">/</span>{% endif %}
{% if area %}<span>{{ area.name }}</span><span class="sep">/</span>{% endif %}
<span>{{ item.name }}</span>
</div>
<div class="detail-header">
<div class="flex items-center justify-between">
<h1 class="detail-title">{{ item.name }}</h1>
<div class="flex gap-2">
<a href="/projects/{{ item.id }}/edit" class="btn btn-secondary btn-sm">Edit</a>
<form action="/projects/{{ item.id }}/delete" method="post" data-confirm="Delete this project?" style="display:inline">
<button class="btn btn-danger btn-sm">Delete</button>
</form>
</div>
</div>
<div class="detail-meta mt-2">
<span class="status-badge status-{{ item.status }}">{{ item.status|replace('_', ' ') }}</span>
<span class="detail-meta-item"><span class="priority-dot priority-{{ item.priority }}"></span> P{{ item.priority }}</span>
{% if item.target_date %}<span class="detail-meta-item">Target: {{ item.target_date }}</span>{% endif %}
</div>
<div class="mt-2" style="max-width: 300px;">
<div class="progress-bar"><div class="progress-fill" style="width: {{ progress }}%"></div></div>
<div class="progress-text">{{ done_count }}/{{ task_count }} tasks complete ({{ progress }}%)</div>
</div>
</div>
{% if item.description %}
<div class="card mb-4"><div class="detail-body">{{ item.description }}</div></div>
{% endif %}
<!-- Tabs -->
<div class="tab-strip">
<a href="/projects/{{ item.id }}?tab=tasks" class="tab-item {{ 'active' if tab == 'tasks' }}">Tasks ({{ tasks|length }})</a>
<a href="/projects/{{ item.id }}?tab=notes" class="tab-item {{ 'active' if tab == 'notes' }}">Notes ({{ notes|length }})</a>
<a href="/projects/{{ item.id }}?tab=links" class="tab-item {{ 'active' if tab == 'links' }}">Links ({{ links|length }})</a>
</div>
{% if tab == 'tasks' %}
<form class="quick-add" action="/tasks/quick-add" method="post">
<input type="hidden" name="domain_id" value="{{ item.domain_id }}">
<input type="hidden" name="project_id" value="{{ item.id }}">
<input type="text" name="title" placeholder="Quick add task to this project..." required>
<button type="submit" class="btn btn-primary btn-sm">Add</button>
</form>
<a href="/tasks/create?domain_id={{ item.domain_id }}&project_id={{ item.id }}" class="btn btn-ghost btn-sm mb-3">+ Full Task Form</a>
{% for t in tasks %}
<div class="list-row {{ 'completed' if t.status == 'done' }}">
<div class="row-check">
<form action="/tasks/{{ t.id }}/toggle" method="post" style="display:inline">
<input type="checkbox" id="pt-{{ t.id }}" {{ 'checked' if t.status == 'done' }} onchange="this.form.submit()">
<label for="pt-{{ t.id }}"></label>
</form>
</div>
<span class="priority-dot priority-{{ t.priority }}"></span>
<span class="row-title"><a href="/tasks/{{ t.id }}">{{ t.title }}</a></span>
{% if t.due_date %}<span class="row-meta">{{ t.due_date }}</span>{% endif %}
<span class="status-badge status-{{ t.status }}">{{ t.status|replace('_', ' ') }}</span>
<div class="row-actions">
<a href="/tasks/{{ t.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
</div>
</div>
{% else %}
<div class="empty-state"><div class="empty-state-text">No tasks yet</div></div>
{% endfor %}
{% elif tab == 'notes' %}
<a href="/notes/create?domain_id={{ item.domain_id }}&project_id={{ item.id }}" class="btn btn-ghost btn-sm mb-3">+ New Note</a>
{% for n in notes %}
<div class="list-row">
<span class="row-title"><a href="/notes/{{ n.id }}">{{ n.title }}</a></span>
<span class="row-meta">{{ n.updated_at.strftime('%Y-%m-%d') if n.updated_at else '' }}</span>
</div>
{% else %}
<div class="empty-state"><div class="empty-state-text">No notes yet</div></div>
{% endfor %}
{% elif tab == 'links' %}
<a href="/links/create?domain_id={{ item.domain_id }}&project_id={{ item.id }}" class="btn btn-ghost btn-sm mb-3">+ New Link</a>
{% for l in links %}
<div class="list-row">
<span class="row-title"><a href="{{ l.url }}" target="_blank">{{ l.label }}</a></span>
<span class="row-meta">{{ l.url[:50] }}{% if l.url|length > 50 %}...{% endif %}</span>
<div class="row-actions">
<a href="/links/{{ l.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
</div>
</div>
{% else %}
<div class="empty-state"><div class="empty-state-text">No links yet</div></div>
{% endfor %}
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,69 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb"><a href="/projects">Projects</a><span class="sep">/</span><span>{{ 'Edit' if item else 'New Project' }}</span></div>
<div class="page-header"><h1 class="page-title">{{ 'Edit Project' if item else 'New Project' }}</h1></div>
<div class="card">
<form method="post" action="{{ '/projects/' ~ item.id ~ '/edit' if item else '/projects/create' }}">
<div class="form-grid">
<div class="form-group full-width">
<label class="form-label">Name *</label>
<input type="text" name="name" class="form-input" required value="{{ item.name if item else '' }}">
</div>
<div class="form-group">
<label class="form-label">Domain *</label>
<select name="domain_id" class="form-select" required>
{% for d in domains %}
<option value="{{ d.id }}" {{ 'selected' if (item and item.domain_id|string == d.id|string) or (not item and prefill_domain_id == d.id|string) }}>{{ d.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label class="form-label">Area</label>
<select name="area_id" class="form-select">
<option value="">-- None --</option>
{% for a in areas %}
<option value="{{ a.id }}" {{ 'selected' if (item and item.area_id and item.area_id|string == a.id|string) or (not item and prefill_area_id == a.id|string) }}>{{ a.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label class="form-label">Status</label>
<select name="status" class="form-select">
{% for s in ['active', 'on_hold', 'completed', 'archived'] %}
<option value="{{ s }}" {{ 'selected' if item and item.status == s }}>{{ s|replace('_', ' ')|title }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label class="form-label">Priority</label>
<select name="priority" class="form-select">
<option value="1" {{ 'selected' if item and item.priority == 1 }}>Critical</option>
<option value="2" {{ 'selected' if item and item.priority == 2 }}>High</option>
<option value="3" {{ 'selected' if (item and item.priority == 3) or not item }}>Normal</option>
<option value="4" {{ 'selected' if item and item.priority == 4 }}>Low</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Start Date</label>
<input type="date" name="start_date" class="form-input" value="{{ item.start_date if item and item.start_date else '' }}">
</div>
<div class="form-group">
<label class="form-label">Target Date</label>
<input type="date" name="target_date" class="form-input" value="{{ item.target_date if item and item.target_date else '' }}">
</div>
<div class="form-group full-width">
<label class="form-label">Description</label>
<textarea name="description" class="form-textarea">{{ item.description if item and item.description else '' }}</textarea>
</div>
<div class="form-group full-width">
<label class="form-label">Tags (comma-separated)</label>
<input type="text" name="tags" class="form-input" value="{{ item.tags|join(', ') if item and item.tags else '' }}">
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">{{ 'Save Changes' if item else 'Create Project' }}</button>
<a href="{{ '/projects/' ~ item.id if item else '/projects' }}" class="btn btn-secondary">Cancel</a>
</div>
</div>
</form>
</div>
{% endblock %}

48
templates/projects.html Normal file
View File

@@ -0,0 +1,48 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">Projects<span class="page-count">{{ items|length }}</span></h1>
<a href="/projects/create" class="btn btn-primary">+ New Project</a>
</div>
<form class="filters-bar" method="get" action="/projects">
<select name="domain_id" class="filter-select" onchange="this.form.submit()">
<option value="">All Domains</option>
{% for d in domains %}
<option value="{{ d.id }}" {{ 'selected' if current_domain_id == d.id|string }}>{{ d.name }}</option>
{% endfor %}
</select>
<select name="status" class="filter-select" onchange="this.form.submit()">
<option value="">All Statuses</option>
{% for s in ['active', 'on_hold', 'completed', 'archived'] %}
<option value="{{ s }}" {{ 'selected' if current_status == s }}>{{ s|replace('_', ' ')|title }}</option>
{% endfor %}
</select>
</form>
{% if items %}
<div class="card">
{% for item in items %}
<div class="list-row">
<span class="row-domain-tag" style="background: {{ item.domain_color or '#4F6EF7' }}22; color: {{ item.domain_color or '#4F6EF7' }}">{{ item.domain_name }}</span>
<span class="row-title"><a href="/projects/{{ item.id }}">{{ item.name }}</a></span>
{% if item.area_name %}<span class="row-meta">{{ item.area_name }}</span>{% endif %}
<span class="status-badge status-{{ item.status }}">{{ item.status|replace('_', ' ') }}</span>
<div style="width: 80px;">
<div class="progress-bar"><div class="progress-fill" style="width: {{ item.progress }}%"></div></div>
<div class="progress-text">{{ item.done_count }}/{{ item.task_count }}</div>
</div>
<div class="row-actions">
<a href="/projects/{{ item.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<div class="empty-state-icon">&#128194;</div>
<div class="empty-state-text">No projects found</div>
<a href="/projects/create" class="btn btn-primary">Create First Project</a>
</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,79 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb">
{% if domain %}<a href="/tasks?domain_id={{ item.domain_id }}">{{ domain.name }}</a><span class="sep">/</span>{% endif %}
{% if project %}<a href="/projects/{{ project.id }}">{{ project.name }}</a><span class="sep">/</span>{% endif %}
<span>{{ item.title }}</span>
</div>
<div class="detail-header">
<div class="flex items-center justify-between">
<h1 class="detail-title">{{ item.title }}</h1>
<div class="flex gap-2">
<a href="/tasks/{{ item.id }}/edit" class="btn btn-secondary btn-sm">Edit</a>
<form action="/tasks/{{ item.id }}/toggle" method="post" style="display:inline">
<button class="btn {{ 'btn-secondary' if item.status == 'done' else 'btn-primary' }} btn-sm">
{{ 'Reopen' if item.status == 'done' else 'Complete' }}
</button>
</form>
</div>
</div>
<div class="detail-meta mt-2">
<span class="status-badge status-{{ item.status }}">{{ item.status|replace('_', ' ') }}</span>
<span class="detail-meta-item"><span class="priority-dot priority-{{ item.priority }}"></span> P{{ item.priority }}</span>
{% if domain %}<span class="row-domain-tag" style="background: {{ domain.color or '#4F6EF7' }}22; color: {{ domain.color or '#4F6EF7' }}">{{ domain.name }}</span>{% endif %}
{% if project %}<span class="row-tag">{{ project.name }}</span>{% endif %}
{% if item.due_date %}<span class="detail-meta-item">Due: {{ item.due_date }}</span>{% endif %}
{% if item.context %}<span class="detail-meta-item">@{{ item.context }}</span>{% endif %}
{% if item.estimated_minutes %}<span class="detail-meta-item">~{{ item.estimated_minutes }}min</span>{% endif %}
{% if item.energy_required %}<span class="detail-meta-item">Energy: {{ item.energy_required }}</span>{% endif %}
</div>
</div>
{% if item.description %}
<div class="card mb-4">
<div class="detail-body">{{ item.description }}</div>
</div>
{% endif %}
{% if item.tags %}
<div class="flex gap-2 mb-4">
{% for tag in item.tags %}<span class="row-tag">{{ tag }}</span>{% endfor %}
</div>
{% endif %}
{% if parent %}
<div class="card mb-4">
<div class="card-title text-sm">Parent Task</div>
<a href="/tasks/{{ parent.id }}">{{ parent.title }}</a>
</div>
{% endif %}
<!-- Subtasks -->
<div class="card">
<div class="card-header">
<h2 class="card-title">Subtasks<span class="page-count">{{ subtasks|length }}</span></h2>
<a href="/tasks/create?parent_id={{ item.id }}&domain_id={{ item.domain_id }}&project_id={{ item.project_id or '' }}" class="btn btn-ghost btn-sm">+ Add Subtask</a>
</div>
{% for sub in subtasks %}
<div class="list-row {{ 'completed' if sub.status == 'done' }}">
<div class="row-check">
<form action="/tasks/{{ sub.id }}/toggle" method="post" style="display:inline">
<input type="checkbox" id="sub-{{ sub.id }}" {{ 'checked' if sub.status == 'done' }} onchange="this.form.submit()">
<label for="sub-{{ sub.id }}"></label>
</form>
</div>
<span class="priority-dot priority-{{ sub.priority }}"></span>
<span class="row-title"><a href="/tasks/{{ sub.id }}">{{ sub.title }}</a></span>
<span class="status-badge status-{{ sub.status }}">{{ sub.status|replace('_', ' ') }}</span>
</div>
{% else %}
<div class="text-sm text-muted" style="padding: 12px;">No subtasks</div>
{% endfor %}
</div>
<div class="text-xs text-muted mt-4">
Created {{ item.created_at.strftime('%Y-%m-%d %H:%M') if item.created_at else '' }}
{% if item.completed_at %} | Completed {{ item.completed_at.strftime('%Y-%m-%d %H:%M') }}{% endif %}
</div>
{% endblock %}

119
templates/task_form.html Normal file
View File

@@ -0,0 +1,119 @@
{% extends "base.html" %}
{% block content %}
<div class="breadcrumb">
<a href="/tasks">Tasks</a>
<span class="sep">/</span>
<span>{{ 'Edit' if item else 'New Task' }}</span>
</div>
<div class="page-header">
<h1 class="page-title">{{ 'Edit Task' if item else 'New Task' }}</h1>
</div>
<div class="card">
<form method="post" action="{{ '/tasks/' ~ item.id ~ '/edit' if item else '/tasks/create' }}">
<div class="form-grid">
<div class="form-group full-width">
<label class="form-label">Title *</label>
<input type="text" name="title" class="form-input" required
value="{{ item.title if item else '' }}">
</div>
<div class="form-group">
<label class="form-label">Domain *</label>
<select name="domain_id" class="form-select" required>
{% for d in domains %}
<option value="{{ d.id }}"
{{ 'selected' if (item and item.domain_id|string == d.id|string) or (not item and prefill_domain_id == d.id|string) }}>
{{ d.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label class="form-label">Project</label>
<select name="project_id" class="form-select">
<option value="">-- No Project --</option>
{% for p in projects %}
<option value="{{ p.id }}"
{{ 'selected' if (item and item.project_id and item.project_id|string == p.id|string) or (not item and prefill_project_id == p.id|string) }}>
{{ p.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label class="form-label">Priority</label>
<select name="priority" class="form-select">
<option value="1" {{ 'selected' if item and item.priority == 1 }}>1 - Critical</option>
<option value="2" {{ 'selected' if item and item.priority == 2 }}>2 - High</option>
<option value="3" {{ 'selected' if (item and item.priority == 3) or not item }}>3 - Normal</option>
<option value="4" {{ 'selected' if item and item.priority == 4 }}>4 - Low</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Status</label>
<select name="status" class="form-select">
{% for s in ['open', 'in_progress', 'blocked', 'done', 'cancelled'] %}
<option value="{{ s }}" {{ 'selected' if item and item.status == s }}>{{ s|replace('_', ' ')|title }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label class="form-label">Due Date</label>
<input type="date" name="due_date" class="form-input"
value="{{ item.due_date if item and item.due_date else '' }}">
</div>
<div class="form-group">
<label class="form-label">Context</label>
<select name="context" class="form-select">
<option value="">-- None --</option>
{% for ct in context_types %}
<option value="{{ ct.value }}"
{{ 'selected' if item and item.context == ct.value }}>{{ ct.label }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label class="form-label">Estimated Minutes</label>
<input type="number" name="estimated_minutes" class="form-input" min="0"
value="{{ item.estimated_minutes if item and item.estimated_minutes else '' }}">
</div>
<div class="form-group">
<label class="form-label">Energy Required</label>
<select name="energy_required" class="form-select">
<option value="">-- None --</option>
<option value="high" {{ 'selected' if item and item.energy_required == 'high' }}>High</option>
<option value="medium" {{ 'selected' if item and item.energy_required == 'medium' }}>Medium</option>
<option value="low" {{ 'selected' if item and item.energy_required == 'low' }}>Low</option>
</select>
</div>
<div class="form-group full-width">
<label class="form-label">Description</label>
<textarea name="description" class="form-textarea">{{ item.description if item and item.description else '' }}</textarea>
</div>
<div class="form-group full-width">
<label class="form-label">Tags (comma-separated)</label>
<input type="text" name="tags" class="form-input"
value="{{ item.tags|join(', ') if item and item.tags else '' }}">
</div>
{% if prefill_parent_id %}
<input type="hidden" name="parent_id" value="{{ prefill_parent_id }}">
{% endif %}
<div class="form-actions">
<button type="submit" class="btn btn-primary">{{ 'Save Changes' if item else 'Create Task' }}</button>
<a href="{{ '/tasks/' ~ item.id if item else '/tasks' }}" class="btn btn-secondary">Cancel</a>
</div>
</div>
</form>
</div>
{% endblock %}

91
templates/tasks.html Normal file
View File

@@ -0,0 +1,91 @@
{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h1 class="page-title">All Tasks<span class="page-count">{{ items|length }}</span></h1>
<a href="/tasks/create" class="btn btn-primary">+ New Task</a>
</div>
<!-- Quick Add -->
<form class="quick-add" action="/tasks/quick-add" method="post">
<input type="text" name="title" placeholder="Quick add task..." required>
<button type="submit" class="btn btn-primary btn-sm">Add</button>
</form>
<!-- Filters -->
<form class="filters-bar" method="get" action="/tasks">
<select name="status" class="filter-select" data-auto-submit onchange="this.form.submit()">
<option value="">All Statuses</option>
<option value="open" {{ 'selected' if current_status == 'open' }}>Open</option>
<option value="in_progress" {{ 'selected' if current_status == 'in_progress' }}>In Progress</option>
<option value="blocked" {{ 'selected' if current_status == 'blocked' }}>Blocked</option>
<option value="done" {{ 'selected' if current_status == 'done' }}>Done</option>
</select>
<select name="priority" class="filter-select" onchange="this.form.submit()">
<option value="">All Priorities</option>
<option value="1" {{ 'selected' if current_priority == '1' }}>Critical</option>
<option value="2" {{ 'selected' if current_priority == '2' }}>High</option>
<option value="3" {{ 'selected' if current_priority == '3' }}>Normal</option>
<option value="4" {{ 'selected' if current_priority == '4' }}>Low</option>
</select>
<select name="domain_id" class="filter-select" onchange="this.form.submit()">
<option value="">All Domains</option>
{% for d in domains %}
<option value="{{ d.id }}" {{ 'selected' if current_domain_id == d.id|string }}>{{ d.name }}</option>
{% endfor %}
</select>
<select name="project_id" class="filter-select" onchange="this.form.submit()">
<option value="">All Projects</option>
{% for p in projects %}
<option value="{{ p.id }}" {{ 'selected' if current_project_id == p.id|string }}>{{ p.name }}</option>
{% endfor %}
</select>
<select name="sort" class="filter-select" onchange="this.form.submit()">
<option value="sort_order" {{ 'selected' if current_sort == 'sort_order' }}>Manual Order</option>
<option value="priority" {{ 'selected' if current_sort == 'priority' }}>Priority</option>
<option value="due_date" {{ 'selected' if current_sort == 'due_date' }}>Due Date</option>
<option value="created_at" {{ 'selected' if current_sort == 'created_at' }}>Newest</option>
<option value="title" {{ 'selected' if current_sort == 'title' }}>Title</option>
</select>
</form>
<!-- Task List -->
{% if items %}
<div class="card">
{% for item in items %}
<div class="list-row {{ 'completed' if item.status in ['done', 'cancelled'] }}">
<div class="row-check">
<form action="/tasks/{{ item.id }}/toggle" method="post" style="display:inline">
<input type="checkbox" id="check-{{ item.id }}" {{ 'checked' if item.status == 'done' }}
onchange="this.form.submit()">
<label for="check-{{ item.id }}"></label>
</form>
</div>
<span class="priority-dot priority-{{ item.priority }}"></span>
<span class="row-title"><a href="/tasks/{{ item.id }}">{{ item.title }}</a></span>
{% if item.project_name %}
<span class="row-tag">{{ item.project_name }}</span>
{% endif %}
{% if item.domain_name %}
<span class="row-domain-tag" style="background: {{ item.domain_color or '#4F6EF7' }}22; color: {{ item.domain_color or '#4F6EF7' }}">{{ item.domain_name }}</span>
{% endif %}
{% if item.due_date %}
<span class="row-meta {{ 'overdue' if item.due_date|string < now_date|default('9999') }}">{{ item.due_date }}</span>
{% endif %}
<span class="status-badge status-{{ item.status }}">{{ item.status|replace('_', ' ') }}</span>
<div class="row-actions">
<a href="/tasks/{{ item.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
<form action="/tasks/{{ item.id }}/delete" method="post" data-confirm="Delete this task?" style="display:inline">
<button type="submit" class="btn btn-ghost btn-xs" style="color: var(--red)">Del</button>
</form>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<div class="empty-state-icon">&#9745;</div>
<div class="empty-state-text">No tasks found</div>
<a href="/tasks/create" class="btn btn-primary">Create First Task</a>
</div>
{% endif %}
{% endblock %}