/
pages.rs
145 lines (126 loc) · 2.91 KB
/
pages.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use std::time::Duration;
use axum::{
extract::{Path, State},
response::{IntoResponse, Redirect},
Form,
};
use cja::{app_state::AppState as _, server::session::DBSession};
use maud::html;
use uuid::Uuid;
use crate::{app_state::AppState, templates::IntoTemplate};
use super::sites::Site;
pub async fn new(
site: Site,
session: DBSession,
State(app_state): State<AppState>,
) -> impl IntoResponse {
html! {
h1 { "New Page" }
form method="post" action=(format!("/my/sites/{}/pages", site.site_id)) {
label {
"Path"
input type="text" name="path" required;
}
label {
"Name"
input type="text" name="name" required;
}
button type="submit" { "Create" }
}
}
.into_template(app_state, Some(session))
.await
.unwrap()
}
#[derive(serde::Deserialize)]
pub struct PageFormData {
path: String,
name: String,
}
pub async fn create(
site: Site,
State(state): State<AppState>,
Form(form_data): Form<PageFormData>,
) -> impl IntoResponse {
let site_id = site.site_id;
sqlx::query!(
r#"
INSERT INTO Pages (site_id, path, name)
VALUES ($1, $2, $3)
"#,
site_id,
form_data.path,
form_data.name
)
.execute(state.db())
.await
.unwrap();
Redirect::to(&format!("/my/sites/{}", site_id,))
}
pub struct Page {
pub page_id: Uuid,
pub site_id: Uuid,
pub path: String,
pub name: String,
}
#[derive(serde::Deserialize)]
pub struct PagePath {
page_id: Uuid,
}
pub async fn show(
site: Site,
State(state): State<AppState>,
Path(PagePath { page_id }): Path<PagePath>,
session: DBSession,
) -> impl IntoResponse {
let page = sqlx::query_as!(
Page,
r#"
SELECT Pages.*
FROM Pages
JOIN Sites ON Sites.site_id = Pages.site_id
WHERE Pages.page_id = $1 AND Pages.site_id = $2 AND Sites.user_id = $3
"#,
page_id,
site.site_id,
session.user_id
)
.fetch_one(state.db())
.await
.unwrap();
let checkins = sqlx::query!(
r#"
SELECT *
FROM Checkins
WHERE page_id = $1
ORDER BY created_at DESC
LIMIT 10
"#,
page_id
)
.fetch_all(state.db())
.await
.unwrap();
html! {
h1 { (page.name) }
p { (page.path) }
h2 { "Checkins" }
ul {
@for checkin in checkins {
li {
(checkin.created_at.format("%d/%m/%Y %H:%M:%S")) " - " (checkin.outcome)
@if let Some(status) = checkin.status_code {
" - " (status)
}
@if let Some(duration) = checkin.duration_nanos {
@let duration = Duration::from_nanos(duration as u64);
" - " (humantime::format_duration(duration))
}
}
}
}
}
.into_template(state, Some(session))
.await
.unwrap()
}