about page
This commit is contained in:
@@ -54,6 +54,7 @@ impl Hooks for App {
|
||||
.add_route(controllers::auth::routes())
|
||||
.add_route(controllers::admin::routes())
|
||||
.add_route(controllers::blog::routes())
|
||||
.add_route(controllers::pages::routes())
|
||||
}
|
||||
async fn connect_workers(ctx: &AppContext, queue: &Queue) -> Result<()> {
|
||||
queue.register(DownloadWorker::build(ctx)).await?;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod admin;
|
||||
pub mod auth;
|
||||
pub mod blog;
|
||||
pub mod pages;
|
||||
|
||||
89
src/controllers/pages.rs
Normal file
89
src/controllers/pages.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
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<chrono::FixedOffset>,
|
||||
}
|
||||
|
||||
impl From<site_pages::Model> 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::Model> {
|
||||
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<AppContext>) -> Result<Response> {
|
||||
format::json(PageResponse::from(find_about(&ctx).await?))
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn update_about(
|
||||
auth: auth::JWT,
|
||||
State(ctx): State<AppContext>,
|
||||
Json(params): Json<AboutParams>,
|
||||
) -> Result<Response> {
|
||||
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))
|
||||
}
|
||||
@@ -8,4 +8,5 @@ pub mod audio_track_tags;
|
||||
pub mod audio_tracks;
|
||||
pub mod audit_logs;
|
||||
pub mod blog_articles;
|
||||
pub mod site_pages;
|
||||
pub mod users;
|
||||
|
||||
@@ -6,4 +6,5 @@ pub use super::audio_track_tags::Entity as AudioTrackTags;
|
||||
pub use super::audio_tracks::Entity as AudioTracks;
|
||||
pub use super::audit_logs::Entity as AuditLogs;
|
||||
pub use super::blog_articles::Entity as BlogArticles;
|
||||
pub use super::site_pages::Entity as SitePages;
|
||||
pub use super::users::Entity as Users;
|
||||
|
||||
21
src/models/_entities/site_pages.rs
Normal file
21
src/models/_entities/site_pages.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.20
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "site_pages")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
#[sea_orm(unique)]
|
||||
pub slug: String,
|
||||
pub title: String,
|
||||
#[sea_orm(column_type = "Text")]
|
||||
pub content: String,
|
||||
pub created_at: DateTimeWithTimeZone,
|
||||
pub updated_at: DateTimeWithTimeZone,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
@@ -6,3 +6,4 @@ pub mod audio_track_tags;
|
||||
pub mod audit_logs;
|
||||
pub mod blog_articles;
|
||||
pub mod audio_albums;
|
||||
pub mod site_pages;
|
||||
|
||||
23
src/models/site_pages.rs
Normal file
23
src/models/site_pages.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use sea_orm::entity::prelude::*;
|
||||
pub use super::_entities::site_pages::{ActiveModel, Entity, Model};
|
||||
pub type SitePages = Entity;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ActiveModelBehavior for ActiveModel {
|
||||
async fn before_save<C>(self, _db: &C, insert: bool) -> std::result::Result<Self, DbErr>
|
||||
where
|
||||
C: ConnectionTrait,
|
||||
{
|
||||
if !insert && self.updated_at.is_unchanged() {
|
||||
let mut this = self;
|
||||
this.updated_at = sea_orm::ActiveValue::Set(chrono::Utc::now().into());
|
||||
Ok(this)
|
||||
} else {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Model {}
|
||||
impl ActiveModel {}
|
||||
impl Entity {}
|
||||
Reference in New Issue
Block a user