todo_list

This commit is contained in:
jeremygan2021
2025-11-16 17:36:42 +08:00
parent a2682dc040
commit bb04bd8fa5
25 changed files with 1198 additions and 34 deletions

View File

@@ -35,6 +35,11 @@
<i class="fas fa-file-image me-1"></i>内容管理
</a>
</li>
<li class="nav-item">
<a class="nav-link {% if '/admin/todos' in request.url.path %}active{% endif %}" href="/admin/todos">
<i class="fas fa-tasks me-1"></i>待办事项
</a>
</li>
<li class="nav-item">
<a class="nav-link {% if '/admin/upload' in request.url.path %}active{% endif %}" href="/admin/upload">
<i class="fas fa-upload me-1"></i>图片上传

View File

@@ -100,20 +100,45 @@
<div class="row">
<div class="col-5">
<div class="icon-big text-center">
<i class="fas fa-play-circle"></i>
<i class="fas fa-tasks"></i>
</div>
</div>
<div class="col-7">
<div class="numbers">
<p class="card-category">活跃内容</p>
<h3 class="card-title">{{ active_content_count }}</h3>
<p class="card-category">待办事项</p>
<h3 class="card-title">{{ todo_count }}</h3>
</div>
</div>
</div>
</div>
<div class="card-footer">
<div class="stats">
<i class="fas fa-chart-line"></i> 活跃率: {{ ((active_content_count / content_count * 100) | round(1) if content_count > 0 else 0) }}%
<i class="fas fa-check-circle"></i> 完成率: {{ ((completed_todo_count / todo_count * 100) | round(1) if todo_count > 0 else 0) }}%
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card card-stats bg-danger text-white shadow-sm">
<div class="card-body">
<div class="row">
<div class="col-5">
<div class="icon-big text-center">
<i class="fas fa-exclamation-triangle"></i>
</div>
</div>
<div class="col-7">
<div class="numbers">
<p class="card-category">待完成</p>
<h3 class="card-title">{{ pending_todo_count }}</h3>
</div>
</div>
</div>
</div>
<div class="card-footer">
<div class="stats">
<i class="fas fa-clock"></i> 待处理任务
</div>
</div>
</div>
@@ -172,36 +197,44 @@
</div>
</div>
<!-- 最近创建的内容 -->
<!-- 最近待办事项 -->
<div class="col-lg-6 mb-4">
<div class="card shadow-sm">
<div class="card-header bg-white py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-clock me-2"></i>最近创建的内容
<i class="fas fa-tasks me-2"></i>最近待办事项
</h6>
<a href="/admin/contents" class="btn btn-sm btn-primary">
<a href="/admin/todos" class="btn btn-sm btn-primary">
<i class="fas fa-list me-1"></i>查看全部
</a>
</div>
<div class="card-body">
{% if recent_contents %}
{% if recent_todos %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th><i class="fas fa-barcode me-1"></i>设备ID</th>
<th><i class="fas fa-heading me-1"></i>标题</th>
<th><i class="fas fa-code-branch me-1"></i>版本</th>
<th><i class="fas fa-mobile-alt me-1"></i>设备</th>
<th><i class="fas fa-check me-1"></i>状态</th>
<th><i class="fas fa-calendar me-1"></i>创建时间</th>
</tr>
</thead>
<tbody>
{% for content in recent_contents %}
{% for item in recent_todos %}
{% set todo = item.todo %}
{% set device = item.device %}
<tr>
<td><a href="/admin/devices/{{ content.device_id }}" class="text-decoration-none"><code>{{ content.device_id }}</code></a></td>
<td><a href="/admin/devices/{{ content.device_id }}/contents/{{ content.version }}" class="text-decoration-none">{{ content.title }}</a></td>
<td><span class="badge bg-info">v{{ content.version }}</span></td>
<td>{{ content.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
<td><a href="/admin/todos/{{ todo.id }}" class="text-decoration-none">{{ todo.title }}</a></td>
<td><a href="/admin/devices/{{ device.device_id }}" class="text-decoration-none">{{ device.name or device.device_id }}</a></td>
<td>
{% if todo.is_completed %}
<span class="badge bg-success"><i class="fas fa-check me-1"></i>已完成</span>
{% else %}
<span class="badge bg-warning"><i class="fas fa-clock me-1"></i>待完成</span>
{% endif %}
</td>
<td>{{ todo.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
</tr>
{% endfor %}
</tbody>
@@ -209,8 +242,8 @@
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-inbox fa-3x text-muted mb-3"></i>
<p class="text-muted">暂无内容</p>
<i class="fas fa-clipboard-list fa-3x text-muted mb-3"></i>
<p class="text-muted">暂无待办事项</p>
</div>
{% endif %}
</div>
@@ -240,13 +273,13 @@
</a>
</div>
<div class="col-md-3 mb-3">
<a href="/admin/upload" class="btn btn-success btn-lg btn-block">
<i class="fas fa-upload me-2"></i> 上传图片
<a href="/admin/todos/add" class="btn btn-warning btn-lg btn-block">
<i class="fas fa-plus me-2"></i> 添加待办
</a>
</div>
<div class="col-md-3 mb-3">
<a href="/admin/devices" class="btn btn-warning btn-lg btn-block">
<i class="fas fa-tv me-2"></i> 设备管理
<a href="/admin/todos" class="btn btn-success btn-lg btn-block">
<i class="fas fa-tasks me-2"></i> 待办管理
</a>
</div>
</div>

View File

@@ -0,0 +1,108 @@
{% extends "admin/base.html" %}
{% block title %}添加待办事项{% endblock %}
{% block content %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">
<i class="fas fa-plus me-2"></i>添加待办事项
</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group me-2">
<a href="/admin/todos{% if device_id %}?device_id={{ device_id }}{% endif %}" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>返回列表
</a>
</div>
</div>
</div>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/admin">首页</a></li>
<li class="breadcrumb-item"><a href="/admin/todos{% if device_id %}?device_id={{ device_id }}{% endif %}">待办事项管理</a></li>
<li class="breadcrumb-item active">添加待办事项</li>
</ol>
</nav>
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-clipboard-list me-2"></i>待办事项信息
</h5>
</div>
<div class="card-body">
<form method="post" action="/admin/todos/add">
<div class="mb-3">
<label for="title" class="form-label">标题 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="title" name="title" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">描述</label>
<textarea class="form-control" id="description" name="description" rows="3"></textarea>
</div>
<div class="mb-3">
<label for="device_id" class="form-label">关联设备 <span class="text-danger">*</span></label>
<select class="form-select" id="device_id" name="device_id" required>
<option value="">请选择设备</option>
{% for device in devices %}
<option value="{{ device.device_id }}" {% if device_id and device.device_id == device_id %}selected{% endif %}>
{{ device.name or device.device_id }}
</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="due_date" class="form-label">截止时间</label>
<input type="datetime-local" class="form-control" id="due_date" name="due_date">
<div class="form-text">留空表示无截止时间</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="is_completed" name="is_completed">
<label class="form-check-label" for="is_completed">
标记为已完成
</label>
</div>
</div>
<div class="d-flex justify-content-between">
<a href="/admin/todos{% if device_id %}?device_id={{ device_id }}{% endif %}" class="btn btn-secondary">
<i class="fas fa-times me-1"></i>取消
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-1"></i>保存
</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-info-circle me-2"></i>帮助信息
</h5>
</div>
<div class="card-body">
<p>创建一个新的待办事项:</p>
<ul>
<li><strong>标题:</strong>待办事项的简短描述</li>
<li><strong>描述:</strong>待办事项的详细说明(可选)</li>
<li><strong>关联设备:</strong>选择要显示此待办事项的设备</li>
<li><strong>截止时间:</strong>设置待办事项的截止时间(可选)</li>
<li><strong>状态:</strong>可以选择直接标记为已完成</li>
</ul>
<p class="text-muted">创建后,待办事项将发送到关联的设备,并可以在设备上标记完成状态。</p>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,161 @@
{% extends "admin/base.html" %}
{% block title %}待办事项详情{% endblock %}
{% block content %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">
<i class="fas fa-tasks me-2"></i>待办事项详情
</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group me-2">
<a href="/admin/todos{% if todo.device_id %}?device_id={{ todo.device_id }}{% endif %}" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>返回列表
</a>
</div>
</div>
</div>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/admin">首页</a></li>
<li class="breadcrumb-item"><a href="/admin/todos{% if todo.device_id %}?device_id={{ todo.device_id }}{% endif %}">待办事项管理</a></li>
<li class="breadcrumb-item active">{{ todo.title }}</li>
</ol>
</nav>
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">
<i class="fas fa-clipboard-list me-2"></i>待办事项信息
</h5>
<span class="badge {% if todo.is_completed %}bg-success{% else %}bg-warning{% %} fs-6">
{% if todo.is_completed %}已完成{% else %}未完成{% endif %}
</span>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-sm-3 fw-bold">标题:</div>
<div class="col-sm-9">{{ todo.title }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-3 fw-bold">描述:</div>
<div class="col-sm-9">{{ todo.description or '无' }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-3 fw-bold">关联设备:</div>
<div class="col-sm-9">
<a href="/admin/devices/{{ device.device_id }}" class="text-decoration-none">
{{ device.name or device.device_id }}
</a>
</div>
</div>
<div class="row mb-3">
<div class="col-sm-3 fw-bold">截止时间:</div>
<div class="col-sm-9">
{% if todo.due_date %}
{{ todo.due_date.strftime('%Y-%m-%d %H:%M') }}
{% else %}
{% endif %}
</div>
</div>
<div class="row mb-3">
<div class="col-sm-3 fw-bold">创建时间:</div>
<div class="col-sm-9">{{ todo.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-3 fw-bold">更新时间:</div>
<div class="col-sm-9">{{ todo.updated_at.strftime('%Y-%m-%d %H:%M:%S') }}</div>
</div>
{% if todo.is_completed and todo.completed_at %}
<div class="row mb-3">
<div class="col-sm-3 fw-bold">完成时间:</div>
<div class="col-sm-9">{{ todo.completed_at.strftime('%Y-%m-%d %H:%M:%S') }}</div>
</div>
{% endif %}
</div>
<div class="card-footer">
<div class="btn-group">
<a href="/admin/todos/{{ todo.id }}/edit" class="btn btn-primary">
<i class="fas fa-edit me-1"></i>编辑
</a>
<form method="post" action="/admin/todos/{{ todo.id }}/toggle" style="display: inline;">
<button type="submit" class="btn {% if todo.is_completed %}btn-warning{% else %}btn-success{% %}">
<i class="fas {% if todo.is_completed %}fa-undo{% else %}fa-check{% %} me-1"></i>
{% if todo.is_completed %}标记为未完成{% else %}标记为已完成{% endif %}
</button>
</form>
<form method="post" action="/admin/todos/{{ todo.id }}/delete" style="display: inline;" onsubmit="return confirm('确定要删除这个待办事项吗?');">
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash me-1"></i>删除
</button>
</form>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-info-circle me-2"></i>设备信息
</h5>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-sm-4 fw-bold">设备ID:</div>
<div class="col-sm-8">{{ device.device_id }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4 fw-bold">设备名称:</div>
<div class="col-sm-8">{{ device.name or '未设置' }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4 fw-bold">设备类型:</div>
<div class="col-sm-8">{{ device.device_type or '未知' }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4 fw-bold">状态:</div>
<div class="col-sm-8">
{% if device.status == 'online' %}
<span class="badge bg-success">在线</span>
{% else %}
<span class="badge bg-danger">离线</span>
{% endif %}
</div>
</div>
<div class="row mb-3">
<div class="col-sm-4 fw-bold">最后活跃:</div>
<div class="col-sm-8">
{% if device.last_seen %}
{{ device.last_seen.strftime('%Y-%m-%d %H:%M:%S') }}
{% else %}
未知
{% endif %}
</div>
</div>
<div class="text-center mt-3">
<a href="/admin/devices/{{ device.device_id }}" class="btn btn-outline-primary btn-sm">
<i class="fas fa-tv me-1"></i>查看设备详情
</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,121 @@
{% extends "admin/base.html" %}
{% block title %}编辑待办事项{% endblock %}
{% block content %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">
<i class="fas fa-edit me-2"></i>编辑待办事项
</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group me-2">
<a href="/admin/todos/{{ todo.id }}" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>返回详情
</a>
</div>
</div>
</div>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/admin">首页</a></li>
<li class="breadcrumb-item"><a href="/admin/todos{% if todo.device_id %}?device_id={{ todo.device_id }}{% endif %}">待办事项管理</a></li>
<li class="breadcrumb-item"><a href="/admin/todos/{{ todo.id }}">{{ todo.title }}</a></li>
<li class="breadcrumb-item active">编辑</li>
</ol>
</nav>
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-clipboard-list me-2"></i>待办事项信息
</h5>
</div>
<div class="card-body">
<form method="post" action="/admin/todos/{{ todo.id }}/edit">
<div class="mb-3">
<label for="title" class="form-label">标题 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="title" name="title" value="{{ todo.title }}" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">描述</label>
<textarea class="form-control" id="description" name="description" rows="3">{{ todo.description or '' }}</textarea>
</div>
<div class="mb-3">
<label for="device_id" class="form-label">关联设备 <span class="text-danger">*</span></label>
<select class="form-select" id="device_id" name="device_id" required>
{% for device in devices %}
<option value="{{ device.device_id }}" {% if device.device_id == todo.device_id %}selected{% endif %}>
{{ device.name or device.device_id }}
</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="due_date" class="form-label">截止时间</label>
<input type="datetime-local" class="form-control" id="due_date" name="due_date"
{% if todo.due_date %}value="{{ todo.due_date.strftime('%Y-%m-%dT%H:%M') }}"{% endif %}>
<div class="form-text">留空表示无截止时间</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="is_completed" name="is_completed"
{% if todo.is_completed %}checked{% endif %}>
<label class="form-check-label" for="is_completed">
标记为已完成
</label>
</div>
</div>
<div class="d-flex justify-content-between">
<a href="/admin/todos/{{ todo.id }}" class="btn btn-secondary">
<i class="fas fa-times me-1"></i>取消
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-1"></i>保存更改
</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-info-circle me-2"></i>当前信息
</h5>
</div>
<div class="card-body">
<div class="row mb-2">
<div class="col-sm-4 fw-bold">创建时间:</div>
<div class="col-sm-8">{{ todo.created_at.strftime('%Y-%m-%d %H:%M') }}</div>
</div>
<div class="row mb-2">
<div class="col-sm-4 fw-bold">更新时间:</div>
<div class="col-sm-8">{{ todo.updated_at.strftime('%Y-%m-%d %H:%M') }}</div>
</div>
{% if todo.is_completed and todo.completed_at %}
<div class="row mb-2">
<div class="col-sm-4 fw-bold">完成时间:</div>
<div class="col-sm-8">{{ todo.completed_at.strftime('%Y-%m-%d %H:%M') }}</div>
</div>
{% endif %}
<hr>
<p class="text-muted">修改待办事项后,更新将发送到关联的设备。</p>
</div>
</div>
</div>
</div>
{% endblock %}

218
templates/admin/todos.html Normal file
View File

@@ -0,0 +1,218 @@
{% extends "admin/base.html" %}
{% block title %}待办事项管理{% endblock %}
{% block content %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">
<i class="fas fa-tasks me-2"></i>待办事项管理
{% if filtered %}
<small class="text-muted">- {{ device.name or device.device_id }}</small>
{% endif %}
</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group me-2">
<a href="/admin/todos/add{% if filtered %}?device_id={{ device.device_id }}{% endif %}" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-plus me-1"></i>添加待办事项
</a>
</div>
{% if not filtered %}
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fas fa-filter me-1"></i>筛选设备
</button>
<ul class="dropdown-menu">
{% for device in devices %}
<li><a class="dropdown-item" href="/admin/todos?device_id={{ device.device_id }}">{{ device.name or device.device_id }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
</div>
{% if filtered %}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/admin/todos">所有待办事项</a></li>
<li class="breadcrumb-item active">{{ device.name or device.device_id }}</li>
</ol>
</nav>
{% endif %}
<div class="row">
<div class="col-12">
{% if filtered %}
{% if todos %}
<div class="card">
<div class="card-header">
<i class="fas fa-list me-2"></i>待办事项列表
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>标题</th>
<th>描述</th>
<th>截止时间</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for todo in todos %}
<tr>
<td>
<a href="/admin/todos/{{ todo.id }}" class="text-decoration-none">
{{ todo.title }}
</a>
</td>
<td>{{ todo.description or '-' }}</td>
<td>
{% if todo.due_date %}
{{ todo.due_date.strftime('%Y-%m-%d %H:%M') }}
{% else %}
-
{% endif %}
</td>
<td>
{% if todo.is_completed %}
<span class="badge bg-success">已完成</span>
{% if todo.completed_at %}
<small class="text-muted d-block">{{ todo.completed_at.strftime('%Y-%m-%d %H:%M') }}</small>
{% endif %}
{% else %}
<span class="badge bg-warning">未完成</span>
{% endif %}
</td>
<td>{{ todo.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<a href="/admin/todos/{{ todo.id }}" class="btn btn-outline-primary" title="查看详情">
<i class="fas fa-eye"></i>
</a>
<form method="post" action="/admin/todos/{{ todo.id }}/toggle" style="display: inline;">
<button type="submit" class="btn {% if todo.is_completed %}btn-outline-warning{% else %}btn-outline-success{% endif %}" title="{% if todo.is_completed %}标记为未完成{% else %}标记为已完成{% endif %}">
<i class="fas {% if todo.is_completed %}fa-undo{% else %}fa-check{% endif %}"></i>
</button>
</form>
<form method="post" action="/admin/todos/{{ todo.id }}/delete" style="display: inline;" onsubmit="return confirm('确定要删除这个待办事项吗?');">
<button type="submit" class="btn btn-outline-danger" title="删除">
<i class="fas fa-trash"></i>
</button>
</form>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% else %}
<div class="card">
<div class="card-body text-center py-5">
<i class="fas fa-clipboard-list fa-3x text-muted mb-3"></i>
<h5 class="text-muted">该设备暂无待办事项</h5>
<p class="text-muted">点击上方按钮添加第一个待办事项</p>
<a href="/admin/todos/add?device_id={{ device.device_id }}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>添加待办事项
</a>
</div>
</div>
{% endif %}
{% else %}
{% if todo_list %}
<div class="card">
<div class="card-header">
<i class="fas fa-list me-2"></i>所有待办事项
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>标题</th>
<th>设备</th>
<th>描述</th>
<th>截止时间</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in todo_list %}
<tr>
<td>
<a href="/admin/todos/{{ item.todo.id }}" class="text-decoration-none">
{{ item.todo.title }}
</a>
</td>
<td>
<a href="/admin/devices/{{ item.device.device_id }}" class="text-decoration-none">
{{ item.device.name or item.device.device_id }}
</a>
</td>
<td>{{ item.todo.description or '-' }}</td>
<td>
{% if item.todo.due_date %}
{{ item.todo.due_date.strftime('%Y-%m-%d %H:%M') }}
{% else %}
-
{% endif %}
</td>
<td>
{% if item.todo.is_completed %}
<span class="badge bg-success">已完成</span>
{% if item.todo.completed_at %}
<small class="text-muted d-block">{{ item.todo.completed_at.strftime('%Y-%m-%d %H:%M') }}</small>
{% endif %}
{% else %}
<span class="badge bg-warning">未完成</span>
{% endif %}
</td>
<td>{{ item.todo.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<a href="/admin/todos/{{ item.todo.id }}" class="btn btn-outline-primary" title="查看详情">
<i class="fas fa-eye"></i>
</a>
<form method="post" action="/admin/todos/{{ item.todo.id }}/toggle" style="display: inline;">
<button type="submit" class="btn {% if item.todo.is_completed %}btn-outline-warning{% else %}btn-outline-success{% endif %}" title="{% if item.todo.is_completed %}标记为未完成{% else %}标记为已完成{% endif %}">
<i class="fas {% if item.todo.is_completed %}fa-undo{% else %}fa-check{% endif %}"></i>
</button>
</form>
<form method="post" action="/admin/todos/{{ item.todo.id }}/delete" style="display: inline;" onsubmit="return confirm('确定要删除这个待办事项吗?');">
<button type="submit" class="btn btn-outline-danger" title="删除">
<i class="fas fa-trash"></i>
</button>
</form>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% else %}
<div class="card">
<div class="card-body text-center py-5">
<i class="fas fa-clipboard-list fa-3x text-muted mb-3"></i>
<h5 class="text-muted">暂无待办事项</h5>
<p class="text-muted">点击上方按钮添加第一个待办事项</p>
<a href="/admin/todos/add" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>添加待办事项
</a>
</div>
</div>
{% endif %}
{% endif %}
</div>
</div>
{% endblock %}