Report PDF emailing
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Report Settings - SwitchBot Temps{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Report settings</p>
|
||||
<h1>Scheduled reports</h1>
|
||||
<p class="muted">Manage recipients and recurring PDF report schedules.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-grid">
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
<div>
|
||||
<h2>Recipients</h2>
|
||||
<p class="muted">Email addresses that can receive scheduled reports.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="settings-form" method="post" action="/report-settings/recipients">
|
||||
<label>
|
||||
Email
|
||||
<input type="email" name="email" placeholder="recipient@example.com" required>
|
||||
</label>
|
||||
<label>
|
||||
Name
|
||||
<input type="text" name="name" placeholder="Optional">
|
||||
</label>
|
||||
<button class="button" type="submit">Add recipient</button>
|
||||
</form>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for recipient in recipients %}
|
||||
<tr>
|
||||
<td>{{ recipient.email }}</td>
|
||||
<td>{{ recipient.name or "n/a" }}</td>
|
||||
<td>{{ "Active" if recipient.active else "Paused" }}</td>
|
||||
<td>
|
||||
<form method="post" action="/report-settings/recipients/{{ recipient.id }}/toggle">
|
||||
<button class="button secondary small" type="submit">{{ "Pause" if recipient.active else "Resume" }}</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="4" class="empty">No recipients configured.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
<div>
|
||||
<h2>Add schedule</h2>
|
||||
<p class="muted">Schedules send the previous complete day, week, or month.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="settings-form schedule-form" method="post" action="/report-settings/schedules">
|
||||
<label>
|
||||
Recipient
|
||||
<select name="recipient_id" required>
|
||||
<option value="">Choose recipient</option>
|
||||
{% for recipient in recipients %}
|
||||
<option value="{{ recipient.id }}">{{ recipient.email }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Cadence
|
||||
<select name="cadence" required>
|
||||
<option value="daily">Daily</option>
|
||||
<option value="weekly">Weekly</option>
|
||||
<option value="monthly">Monthly</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Time
|
||||
<input type="time" name="send_time" value="08:00" required>
|
||||
</label>
|
||||
<label>
|
||||
Weekday
|
||||
<select name="weekday">
|
||||
{% for value, label in weekdays %}
|
||||
<option value="{{ value }}" {% if value == 0 %}selected{% endif %}>{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Month day
|
||||
<input type="number" name="monthday" min="1" max="31" value="1">
|
||||
</label>
|
||||
<label>
|
||||
Device
|
||||
<select name="device_id">
|
||||
<option value="">All devices</option>
|
||||
{% for device in devices %}
|
||||
<option value="{{ device.id }}">{{ device.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<button class="button" type="submit">Add schedule</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<div class="panel-heading">
|
||||
<div>
|
||||
<h2>Active schedules</h2>
|
||||
<p class="muted">Each schedule is guarded by a database run record, so a period is sent once.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Recipient</th>
|
||||
<th>Cadence</th>
|
||||
<th>Device</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for schedule in schedules %}
|
||||
<tr>
|
||||
<td>{{ schedule.recipient.email }}</td>
|
||||
<td>{{ schedule_labels[schedule.id] }}</td>
|
||||
<td>{{ schedule.device.name if schedule.device else "All devices" }}</td>
|
||||
<td>{{ "Active" if schedule.active else "Paused" }}</td>
|
||||
<td>
|
||||
<form method="post" action="/report-settings/schedules/{{ schedule.id }}/toggle">
|
||||
<button class="button secondary small" type="submit">{{ "Pause" if schedule.active else "Resume" }}</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="5" class="empty">No scheduled reports configured.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<div class="panel-heading">
|
||||
<div>
|
||||
<h2>Recent runs</h2>
|
||||
<p class="muted">The scheduler writes one run record per schedule and report period.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<th>Recipient</th>
|
||||
<th>Cadence</th>
|
||||
<th>Period</th>
|
||||
<th>Status</th>
|
||||
<th>Error</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for run in runs %}
|
||||
<tr>
|
||||
<td>{{ run.created_at }}</td>
|
||||
<td>{{ run.scheduled_report.recipient.email }}</td>
|
||||
<td>{{ run.scheduled_report.cadence|title }}</td>
|
||||
<td>{{ run.period_start }} to {{ run.period_end }}</td>
|
||||
<td>{{ run.status|title }}</td>
|
||||
<td>{{ run.error or "" }}</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="empty">No scheduled report runs yet.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user