Add data to admin page for success/fail history

This commit is contained in:
jude 2023-07-30 19:09:48 +01:00
parent b8707bbc9a
commit d5fa8036e8
3 changed files with 105 additions and 0 deletions

View File

@ -133,6 +133,38 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> Jso
.await .await
.unwrap(); .unwrap();
let history = sqlx::query_as_unchecked!(
TimeFrame,
"SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 86400) * 86400) AS `time_key`,
COUNT(1) AS `count`
FROM stat
WHERE
`utc_time` > DATE_SUB(NOW(), INTERVAL 31 DAY) AND
`type` = 'reminder_sent'
GROUP BY `time_key`
ORDER BY `time_key`"
)
.fetch_all(pool.inner())
.await
.unwrap();
let history_failed = sqlx::query_as_unchecked!(
TimeFrame,
"SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 86400) * 86400) AS `time_key`,
COUNT(1) AS `count`
FROM stat
WHERE
`utc_time` > DATE_SUB(NOW(), INTERVAL 31 DAY) AND
`type` = 'reminder_failed'
GROUP BY `time_key`
ORDER BY `time_key`"
)
.fetch_all(pool.inner())
.await
.unwrap();
let interval_count = sqlx::query!( let interval_count = sqlx::query!(
"SELECT COUNT(1) AS count "SELECT COUNT(1) AS count
FROM reminders FROM reminders
@ -167,6 +199,10 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> Jso
"once": schedule_once_long, "once": schedule_once_long,
"interval": schedule_interval_long, "interval": schedule_interval_long,
}, },
"historyLong": {
"sent": history,
"failed": history_failed,
},
"count": { "count": {
"reminders": reminder_count.count, "reminders": reminder_count.count,
"intervals": interval_count.count, "intervals": interval_count.count,

View File

@ -6,6 +6,21 @@ document.addEventListener("DOMContentLoaded", () => {
document.querySelector("#reminders").textContent = data.count.reminders; document.querySelector("#reminders").textContent = data.count.reminders;
document.querySelector("#intervals").textContent = data.count.intervals; document.querySelector("#intervals").textContent = data.count.intervals;
let historySent = data.historyLong.sent.reduce(
(iv, frame) => iv + frame.count,
0
);
let historyFailed = data.historyLong.failed.reduce(
(iv, frame) => iv + frame.count,
0
);
document.querySelector("#historySent").textContent = historySent;
document.querySelector("#historyFailed").textContent = historyFailed;
document.querySelector("#failRate").textContent = `${
(historyFailed / (historySent + historyFailed)) * 100
}%`;
new Chart(document.getElementById("schedule"), { new Chart(document.getElementById("schedule"), {
type: "bar", type: "bar",
data: { data: {
@ -77,5 +92,40 @@ document.addEventListener("DOMContentLoaded", () => {
}, },
}, },
}); });
new Chart(document.getElementById("historyLong"), {
type: "bar",
data: {
labels: [...data.historyLong.sent, ...data.historyLong.failed].map(
(row) => luxon.DateTime.fromISO(row.time_key)
),
datasets: [
{
label: "Success",
data: data.historyLong.sent.map((row) => row.count),
},
{
label: "Fail",
data: data.historyLong.failed.map((row) => row.count),
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
stacked: true,
type: "time",
time: {
unit: "day",
},
},
y: {
stacked: true,
},
},
},
});
}); });
}); });

View File

@ -60,6 +60,25 @@
<canvas id="scheduleLong"></canvas> <canvas id="scheduleLong"></canvas>
</div> </div>
</div> </div>
<div class="stat-row">
<div class="stat-box figure">
<p>Last 31 days (success)</p>
<p class="figure-num" id="historySent">?</p>
</div>
<div class="stat-box figure">
<p>Last 31 days (failed)</p>
<p class="figure-num" id="historyFailed">?</p>
</div>
<div class="stat-box figure">
<p>Last 31 days (failure rate)</p>
<p class="figure-num" id="failRate">?</p>
</div>
</div>
<div class="stat-row">
<div class="stat-box" style="height: 400px;">
<canvas id="historyLong"></canvas>
</div>
</div>
</section> </section>
<script src="/static/js/chart.js" defer></script> <script src="/static/js/chart.js" defer></script>