use crate::{ controllers::admin, models::_entities::site_pages, }; use loco_rs::prelude::*; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set}; use serde::{Deserialize, Serialize}; use uuid::Uuid; const ABOUT_SLUG: &str = "about"; #[derive(Debug, Deserialize)] struct AboutParams { title: String, content: String, } #[derive(Debug, Serialize)] struct PageResponse { id: Uuid, slug: String, title: String, content: String, updated_at: chrono::DateTime, } impl From for PageResponse { fn from(page: site_pages::Model) -> Self { Self { id: page.id, slug: page.slug, title: page.title, content: page.content, updated_at: page.updated_at, } } } async fn find_about(ctx: &AppContext) -> Result { site_pages::Entity::find() .filter(site_pages::Column::Slug.eq(ABOUT_SLUG)) .one(&ctx.db) .await? .ok_or_else(|| Error::NotFound) } #[debug_handler] async fn about(State(ctx): State) -> Result { format::json(PageResponse::from(find_about(&ctx).await?)) } #[debug_handler] async fn update_about( auth: auth::JWT, State(ctx): State, Json(params): Json, ) -> Result { admin::current_admin(auth, &ctx).await?; let page = match find_about(&ctx).await { Ok(page) => { let mut page = page.into_active_model(); page.title = Set(params.title); page.content = Set(params.content); page.update(&ctx.db).await? } Err(Error::NotFound) => { site_pages::ActiveModel { id: Set(Uuid::new_v4()), slug: Set(ABOUT_SLUG.to_string()), title: Set(params.title), content: Set(params.content), ..Default::default() } .insert(&ctx.db) .await? } Err(err) => return Err(err), }; format::json(PageResponse::from(page)) } pub fn routes() -> Routes { Routes::new() .prefix("/api") .add("/about", get(about)) .add("/admin/about", put(update_about)) }