initial work of the arcline tickets

This commit is contained in:
Blake Ridgway
2026-07-13 20:44:57 -05:00
parent 28e38916f2
commit 7807a674b3
13 changed files with 1199 additions and 372 deletions

31
templates/base.html Normal file
View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Arcline Tickets{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<header class="site-header">
<div class="container">
<a href="{{ url_for('index') }}" class="logo">Arcline <span class="accent">Tickets</span></a>
<nav>
<a href="{{ url_for('index') }}">All Tickets</a>
<a href="{{ url_for('create_ticket') }}" class="btn btn-primary btn-sm">+ New Ticket</a>
</nav>
</div>
</header>
<main class="container">
{% block content %}{% endblock %}
</main>
<footer class="site-footer">
<div class="container">
<p>Arcline Tickets &mdash; Built with Python, Flask &amp; Jinja2</p>
</div>
</footer>
</body>
</html>

73
templates/create.html Normal file
View File

@@ -0,0 +1,73 @@
{% extends "base.html" %}
{% block title %}New Ticket{% endblock %}
{% block content %}
<div class="page-header">
<h1>Create New Ticket</h1>
</div>
<div class="form-container">
{% if error %}
<div class="alert alert-error">{{ error }}</div>
{% endif %}
<form method="post" class="ticket-form">
<div class="form-group">
<label for="title">Title <span class="required">*</span></label>
<input type="text" id="title" name="title" class="input"
value="{{ ticket.title if ticket else '' }}" required autofocus
placeholder="Brief summary of the issue">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea id="description" name="description" class="input" rows="6"
placeholder="Detailed description of the issue...">{{ ticket.description if ticket else '' }}</textarea>
</div>
<div class="form-row">
<div class="form-group">
<label for="priority">Priority</label>
<select id="priority" name="priority" class="input">
{% for val, label in priorities %}
<option value="{{ val }}" {% if ticket and ticket.priority.value == val %}selected{% endif %}>
{{ label }}
</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="status">Status</label>
<select id="status" name="status" class="input">
{% for val, label in statuses %}
<option value="{{ val }}" {% if ticket and ticket.status.value == val %}selected{% elif val == 'open' %}selected{% endif %}>
{{ label }}
</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="assignee">Assignee</label>
<input type="text" id="assignee" name="assignee" class="input"
value="{{ ticket.assignee if ticket else '' }}"
placeholder="Who is responsible?">
</div>
<div class="form-group">
<label for="project">Project / Tool</label>
<input type="text" id="project" name="project" class="input"
value="{{ ticket.project if ticket else '' }}"
placeholder="e.g. CLI, Web, API">
</div>
</div>
<div class="form-actions">
<a href="{{ url_for('index') }}" class="btn btn-ghost">Cancel</a>
<button type="submit" class="btn btn-primary">Create Ticket</button>
</div>
</form>
</div>
{% endblock %}

66
templates/detail.html Normal file
View File

@@ -0,0 +1,66 @@
{% extends "base.html" %}
{% block title %}Ticket #{{ ticket.id }}{% endblock %}
{% block content %}
<div class="page-header">
<div>
<a href="{{ url_for('index') }}" class="back-link">&larr; Back to tickets</a>
<h1>#{{ ticket.id }} &mdash; {{ ticket.title }}</h1>
</div>
<div class="action-buttons">
<a href="{{ url_for('edit_ticket', ticket_id=ticket.id) }}" class="btn btn-secondary">Edit</a>
<form method="post" action="{{ url_for('delete_ticket', ticket_id=ticket.id) }}"
onsubmit="return confirm('Delete this ticket?');" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</div>
</div>
<div class="ticket-detail-grid">
<div class="ticket-main">
<div class="ticket-section">
<h3>Description</h3>
<div class="ticket-description">
{% if ticket.description %}
<p>{{ ticket.description }}</p>
{% else %}
<p class="muted">No description provided.</p>
{% endif %}
</div>
</div>
</div>
<aside class="ticket-sidebar">
<div class="ticket-meta-card">
<div class="meta-row">
<span class="meta-label">Status</span>
<span class="badge badge-{{ ticket.status.value }}">{{ ticket.status.value.replace('_', ' ') | title }}</span>
</div>
<div class="meta-row">
<span class="meta-label">Priority</span>
<span class="badge badge-priority badge-p-{{ ticket.priority.value }}">{{ ticket.priority.value | upper }}</span>
</div>
<div class="meta-row">
<span class="meta-label">Assignee</span>
<span>{% if ticket.assignee %}{{ ticket.assignee }}{% else %}<span class="muted">Unassigned</span>{% endif %}</span>
</div>
{% if ticket.project %}
<div class="meta-row">
<span class="meta-label">Project</span>
<span class="badge badge-project">{{ ticket.project }}</span>
</div>
{% endif %}
<hr>
<div class="meta-row">
<span class="meta-label">Created</span>
<span class="date">{{ ticket.created_at[:19] }}</span>
</div>
<div class="meta-row">
<span class="meta-label">Updated</span>
<span class="date">{{ ticket.updated_at[:19] }}</span>
</div>
</div>
</aside>
</div>
{% endblock %}

73
templates/edit.html Normal file
View File

@@ -0,0 +1,73 @@
{% extends "base.html" %}
{% block title %}Edit Ticket #{{ ticket.id }}{% endblock %}
{% block content %}
<div class="page-header">
<h1>Edit Ticket #{{ ticket.id }}</h1>
</div>
<div class="form-container">
{% if error %}
<div class="alert alert-error">{{ error }}</div>
{% endif %}
<form method="post" class="ticket-form">
<div class="form-group">
<label for="title">Title <span class="required">*</span></label>
<input type="text" id="title" name="title" class="input"
value="{{ ticket.title }}" required autofocus
placeholder="Brief summary of the issue">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea id="description" name="description" class="input" rows="6"
placeholder="Detailed description of the issue...">{{ ticket.description }}</textarea>
</div>
<div class="form-row">
<div class="form-group">
<label for="priority">Priority</label>
<select id="priority" name="priority" class="input">
{% for val, label in priorities %}
<option value="{{ val }}" {% if ticket.priority.value == val %}selected{% endif %}>
{{ label }}
</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="status">Status</label>
<select id="status" name="status" class="input">
{% for val, label in statuses %}
<option value="{{ val }}" {% if ticket.status.value == val %}selected{% endif %}>
{{ label }}
</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="assignee">Assignee</label>
<input type="text" id="assignee" name="assignee" class="input"
value="{{ ticket.assignee }}"
placeholder="Who is responsible?">
</div>
<div class="form-group">
<label for="project">Project / Tool</label>
<input type="text" id="project" name="project" class="input"
value="{{ ticket.project }}"
placeholder="e.g. CLI, Web, API">
</div>
</div>
<div class="form-actions">
<a href="{{ url_for('view_ticket', ticket_id=ticket.id) }}" class="btn btn-ghost">Cancel</a>
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
{% endblock %}

80
templates/index.html Normal file
View File

@@ -0,0 +1,80 @@
{% extends "base.html" %}
{% block title %}Tickets{% endblock %}
{% block content %}
<div class="page-header">
<h1>Tickets</h1>
<a href="{{ url_for('create_ticket') }}" class="btn btn-primary">+ New Ticket</a>
</div>
{# ── stats bar ── #}
<div class="stats-bar">
<a href="{{ url_for('index') }}" class="stat {% if not status_filter %}active{% endif %}">
<span class="stat-num">{{ tickets|length }}</span>
<span class="stat-label">Total</span>
</a>
{% for val, label in statuses %}
<a href="{{ url_for('index', status=val, priority=priority_filter, search=search, project=project_filter) }}"
class="stat stat-{{ val }} {% if status_filter == val %}active{% endif %}">
<span class="stat-num">{{ counts.get(val, 0) }}</span>
<span class="stat-label">{{ label }}</span>
</a>
{% endfor %}
</div>
{# ── filters ── #}
<form method="get" class="filters">
<input type="text" name="search" placeholder="Search tickets..." value="{{ search }}"
class="input search-input">
<select name="priority" class="input">
<option value="">All Priorities</option>
{% for val, label in priorities %}
<option value="{{ val }}" {% if priority_filter == val %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
{% if projects %}
<select name="project" class="input">
<option value="">All Projects</option>
{% for p in projects %}
<option value="{{ p }}" {% if project_filter == p %}selected{% endif %}>{{ p }}</option>
{% endfor %}
</select>
{% endif %}
<button type="submit" class="btn btn-secondary">Filter</button>
{% if status_filter or priority_filter or search or project_filter %}
<a href="{{ url_for('index') }}" class="btn btn-ghost">Clear</a>
{% endif %}
</form>
{# ── ticket list ── #}
{% if tickets %}
<div class="ticket-list">
{% for ticket in tickets %}
<a href="{{ url_for('view_ticket', ticket_id=ticket.id) }}" class="ticket-card">
<div class="ticket-card-header">
<span class="ticket-id">#{{ ticket.id }}</span>
<span class="badge badge-{{ ticket.status.value }}">{{ ticket.status.value.replace('_', ' ') | title }}</span>
</div>
<h3 class="ticket-card-title">{{ ticket.title }}</h3>
<p class="ticket-card-desc">{{ ticket.description[:120] }}{% if ticket.description|length > 120 %}...{% endif %}</p>
<div class="ticket-card-meta">
<span class="badge badge-priority badge-p-{{ ticket.priority.value }}">{{ ticket.priority.value | upper }}</span>
{% if ticket.project %}
<span class="badge badge-project">{{ ticket.project }}</span>
{% endif %}
{% if ticket.assignee %}
<span class="assignee">👤 {{ ticket.assignee }}</span>
{% endif %}
<span class="date">{{ ticket.created_at[:10] }}</span>
</div>
</a>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<p>No tickets found.</p>
<a href="{{ url_for('create_ticket') }}" class="btn btn-primary">Create the first ticket</a>
</div>
{% endif %}
{% endblock %}