Skip to main content

web/
pages.rs

1use std::sync::Arc;
2
3use crate::AppState;
4
5use crate::files::{S3File, list_s3};
6use askama::Template;
7use axum::{
8    extract::State,
9    http::StatusCode,
10    response::{Html, IntoResponse, Response},
11};
12use axum_extra::extract::CookieJar;
13pub mod account;
14pub mod commodity;
15pub mod report;
16pub mod script;
17pub mod tag;
18pub mod template;
19pub mod transaction;
20pub mod validation;
21
22pub async fn index(cookie_jar: CookieJar) -> impl IntoResponse {
23    let is_logged_in = match cookie_jar.get("access_token") {
24        Some(cookie) => crate::auth_keys::verify(cookie.value(), crate::token::TokenType::Access)
25            .await
26            .is_some(),
27        None => false,
28    };
29
30    let template = IndexTemplate {
31        is_logged_in,
32        scripting_enabled: true,
33    };
34
35    HtmlTemplate(template)
36}
37
38#[derive(Template)]
39#[template(path = "pages/index.html")]
40struct IndexTemplate {
41    is_logged_in: bool,
42    scripting_enabled: bool,
43}
44
45pub async fn file_table(
46    State(data): State<Arc<AppState>>,
47) -> Result<impl IntoResponse, StatusCode> {
48    let frac = State(&data).frac;
49    let template = FileTableTemplate {
50        files: list_s3(State(data)).await?,
51        frac,
52    };
53    Ok(HtmlTemplate(template))
54}
55
56#[derive(Template)]
57#[template(path = "components/file-table.html")]
58struct FileTableTemplate {
59    files: Vec<S3File>,
60    frac: i64,
61}
62
63pub async fn register() -> impl IntoResponse {
64    let template = RegisterTemplate {};
65    HtmlTemplate(template)
66}
67
68#[derive(Template)]
69#[template(path = "pages/register.html")]
70struct RegisterTemplate;
71
72pub async fn login() -> impl IntoResponse {
73    let template = LoginTemplate {};
74    HtmlTemplate(template)
75}
76
77#[derive(Template)]
78#[template(path = "pages/login.html")]
79struct LoginTemplate;
80
81/// A wrapper type that we'll use to encapsulate HTML parsed by askama into valid HTML for axum to serve.
82struct HtmlTemplate<T>(T);
83
84/// Allows us to convert Askama HTML templates into valid HTML for axum to serve in the response.
85impl<T> IntoResponse for HtmlTemplate<T>
86where
87    T: Template,
88{
89    fn into_response(self) -> Response {
90        // Attempt to render the template with askama
91        match self.0.render() {
92            // If we're able to successfully parse and aggregate the template, serve it
93            Ok(html) => Html(html).into_response(),
94            // If we're not, return an error or some bit of fallback HTML
95            Err(err) => (
96                StatusCode::INTERNAL_SERVER_ERROR,
97                format!("Failed to render template. Error: {err}"),
98            )
99                .into_response(),
100        }
101    }
102}