recipes/backend/src/services/recipe.rs

136 lines
4.3 KiB
Rust

use axum::{
debug_handler,
extract::{Extension, Path, State},
response::{Html, IntoResponse, Redirect, Response},
};
use rinja::Template;
// use tracing::{event, Level};
use crate::{
data::{db, model},
html_templates::*,
translation::{self, Sentence},
Result,
};
#[debug_handler]
pub async fn create(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
Extension(tr): Extension<translation::Tr>,
) -> Result<Response> {
if let Some(user) = user {
let recipe_id = connection.create_recipe(user.id).await?;
Ok(Redirect::to(&format!("/recipe/edit/{}", recipe_id)).into_response())
} else {
Ok(Html(MessageTemplate::new(tr.t(Sentence::NotLoggedIn), tr).render()?).into_response())
}
}
#[debug_handler]
pub async fn edit(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
Extension(tr): Extension<translation::Tr>,
Path(recipe_id): Path<i64>,
) -> Result<Response> {
if let Some(user) = user {
if let Some(recipe) = connection.get_recipe(recipe_id, false).await? {
if model::can_user_edit_recipe(&user, &recipe) {
let recipes = Recipes {
published: connection
.get_all_published_recipe_titles(tr.current_lang_code(), Some(user.id))
.await?,
unpublished: connection
.get_all_unpublished_recipe_titles(user.id)
.await?,
current_id: Some(recipe_id),
};
Ok(Html(
RecipeEditTemplate {
user: Some(user),
tr,
recipes,
recipe,
}
.render()?,
)
.into_response())
} else {
Ok(
Html(
MessageTemplate::new(tr.t(Sentence::RecipeNotAllowedToEdit), tr)
.render()?,
)
.into_response(),
)
}
} else {
Ok(
Html(MessageTemplate::new(tr.t(Sentence::RecipeNotFound), tr).render()?)
.into_response(),
)
}
} else {
Ok(Html(MessageTemplate::new(tr.t(Sentence::NotLoggedIn), tr).render()?).into_response())
}
}
#[debug_handler]
pub async fn view(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
Extension(tr): Extension<translation::Tr>,
Path(recipe_id): Path<i64>,
) -> Result<Response> {
match connection.get_recipe(recipe_id, true).await? {
Some(recipe) => {
if !recipe.is_published
&& (user.is_none() || recipe.user_id != user.as_ref().unwrap().id)
{
return Ok(Html(
MessageTemplate::new_with_user(
&tr.tp(Sentence::RecipeNotAllowedToView, &[Box::new(recipe_id)]),
tr,
user,
)
.render()?,
)
.into_response());
}
let recipes = Recipes {
published: connection
.get_all_published_recipe_titles(
tr.current_lang_code(),
user.as_ref().map(|u| u.id),
)
.await?,
unpublished: if let Some(user) = user.as_ref() {
connection
.get_all_unpublished_recipe_titles(user.id)
.await?
} else {
vec![]
},
current_id: Some(recipe_id),
};
Ok(Html(
RecipeViewTemplate {
user,
tr,
recipes,
recipe,
}
.render()?,
)
.into_response())
}
None => Ok(Html(
MessageTemplate::new_with_user(tr.t(Sentence::RecipeNotFound), tr, user).render()?,
)
.into_response()),
}
}