When post was deleted, website shows a 404 page insead of an 500 page. Also made the dashboard empty page message more explicit.
176 lines
4.1 KiB
Rust
176 lines
4.1 KiB
Rust
use crate::{
|
|
domain::{PostEntry, SubscriberEntry},
|
|
routes::{AppError, DashboardStats},
|
|
};
|
|
use askama::Template;
|
|
use axum::response::{Html, IntoResponse};
|
|
use uuid::Uuid;
|
|
|
|
pub struct HtmlTemplate<T>(pub T);
|
|
|
|
impl<T> IntoResponse for HtmlTemplate<T>
|
|
where
|
|
T: Template,
|
|
{
|
|
fn into_response(self) -> axum::response::Response {
|
|
match self.0.render() {
|
|
Ok(html) => Html(html).into_response(),
|
|
Err(err) => AppError::unexpected_page(anyhow::anyhow!(err)).into_response(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Template)]
|
|
pub enum MessageTemplate {
|
|
#[template(path = "../templates/success.html")]
|
|
Success { message: String },
|
|
#[template(path = "../templates/error.html")]
|
|
Error { message: String },
|
|
}
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "../templates/500.html")]
|
|
pub struct InternalErrorTemplate;
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "../templates/login.html")]
|
|
pub struct LoginTemplate;
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "../templates/dashboard.html")]
|
|
pub struct DashboardTemplate {
|
|
pub username: String,
|
|
pub idempotency_key_1: String,
|
|
pub idempotency_key_2: String,
|
|
pub stats: DashboardStats,
|
|
pub subscribers: Vec<SubscriberEntry>,
|
|
pub current_page: i64,
|
|
pub max_page: i64,
|
|
}
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "home.html")]
|
|
pub struct HomeTemplate;
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "posts.html")]
|
|
pub struct PostsTemplate {
|
|
pub posts: Vec<PostEntry>,
|
|
pub next_page: Option<i64>,
|
|
}
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "posts.html", block = "posts")]
|
|
pub struct PostListTemplate {
|
|
pub posts: Vec<PostEntry>,
|
|
pub next_page: Option<i64>,
|
|
}
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "post.html")]
|
|
pub struct PostTemplate {
|
|
pub post: PostEntry,
|
|
}
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "dashboard.html", block = "subs")]
|
|
pub struct SubListTemplate {
|
|
pub subscribers: Vec<SubscriberEntry>,
|
|
pub current_page: i64,
|
|
pub max_page: i64,
|
|
}
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "confirm.html")]
|
|
pub struct ConfirmTemplate;
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "404.html")]
|
|
pub struct NotFoundTemplate;
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "unsubscribe_confirm.html")]
|
|
pub struct UnsubscribeConfirmTemplate;
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "unsubscribe.html")]
|
|
pub struct UnsubscribeTemplate;
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "email/new_post.html")]
|
|
pub struct NewPostEmailTemplate<'a> {
|
|
pub base_url: &'a str,
|
|
pub post_title: &'a str,
|
|
pub post_id: &'a Uuid,
|
|
pub post_excerpt: &'a str,
|
|
}
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "email/standalone.html")]
|
|
pub struct StandaloneEmailTemplate<'a> {
|
|
pub base_url: &'a str,
|
|
pub html_content: &'a str,
|
|
pub text_content: &'a str,
|
|
}
|
|
|
|
pub trait EmailTemplate: Sync {
|
|
fn html(&self) -> String;
|
|
fn text(&self) -> String;
|
|
}
|
|
|
|
impl<'a> EmailTemplate for NewPostEmailTemplate<'a> {
|
|
fn html(&self) -> String {
|
|
self.render().unwrap()
|
|
}
|
|
|
|
fn text(&self) -> String {
|
|
format!(
|
|
r#"New post available!
|
|
|
|
Hello there!
|
|
I just published a new post that I think you'll find interesting:
|
|
|
|
"{}"
|
|
|
|
Read the full post: {}/posts/{}?origin=EMAIL_ID
|
|
|
|
This post covers practical insights and real-world examples that I hope will be valuable for your backend development journey.
|
|
|
|
Thanks for being a subscriber!
|
|
|
|
Best regards,
|
|
Alphonse
|
|
|
|
---
|
|
|
|
zero2prod - Building better backends with Rust
|
|
Visit the blog: {}
|
|
Unsubscribe: {}/unsubscribe/confirm?token=UNSUBSCRIBE_TOKEN
|
|
|
|
You're receiving this because you subscribed to the zero2prod newsletter."#,
|
|
self.post_title, self.base_url, self.post_id, self.base_url, self.base_url,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'a> EmailTemplate for StandaloneEmailTemplate<'a> {
|
|
fn html(&self) -> String {
|
|
self.render().unwrap()
|
|
}
|
|
|
|
fn text(&self) -> String {
|
|
format!(
|
|
r#"{}
|
|
|
|
---
|
|
|
|
zero2prod - Building better backends with Rust
|
|
Visit the blog: {}
|
|
Unsubscribe: {}/unsubscribe/confirm?token=UNSUBSCRIBE_TOKEN
|
|
|
|
You're receiving this because you subscribed to the zero2prod newsletter."#,
|
|
self.text_content, self.base_url, self.base_url
|
|
)
|
|
}
|
|
}
|