use axum::{extract::Path, response::Redirect, Form}; use axum_login::AuthSession; use crate::{handler::internal_server_error, models::{Document, ModelPermission, ModelType, Permission}, prelude::*}; pub async fn documents_page( State(ctx): State, auth_session: AuthSession, ) -> Response { if let Some(user) = auth_session.user { render_documents_page(ctx, user).await } else { Redirect::to("/login").into_response() } } async fn render_documents_page(ctx: Context, user: crate::entity::user::Model) -> Response { let documents = ModelPermission::user_documents(&ctx.kv_handles, user.id).unwrap_or_default(); let values = context! { user => user, documents => documents, }; ctx.render_resp("documents/list_documents.html", values) } pub async fn create_document_page( State(ctx): State, auth_session: AuthSession, ) -> Response { let user = match auth_session.user { Some(user) => user, None => return Redirect::to("/login").into_response(), }; let projects = ModelPermission::user_projects(&ctx.kv_handles, user.id).unwrap_or_default(); let values = context! { user => user, projects => projects, }; ctx.render_resp("documents/create_document.html", values) } #[derive(Debug, Deserialize)] pub struct CreateDocumentSubmission { pub project_id: Uuid, pub title: String, } pub async fn create_document_submit( State(ctx): State, auth_session: AuthSession, form: Form, ) -> Response { let user = match auth_session.user { Some(user) => user, None => return Redirect::to("/login").into_response(), }; let project = match ModelPermission::user_project(&ctx.kv_handles, user.id, form.project_id) { Ok(Some(project)) => project, Ok(None) => return Redirect::to("/documents/create").into_response(), Err(err) => { error!(?err, "failed to access kv store"); return Redirect::to("/documents/create").into_response(); } }; let document = Document { id: Uuid::now_v7(), project_id: project.id, title: form.title.to_owned(), content: "".to_owned(), }; if let Err(err) = document.save(&ctx.kv_handles) { error!(?err, "failed to save document"); return internal_server_error(); } info!(?document, "document created"); let permission = ModelPermission { user_id: user.id, model_type: ModelType::Document, role: Permission::Admin, model_id: document.id, }; if let Err(err) = permission.add(&ctx.kv_handles) { error!(?err, "failed to save new project permission"); return internal_server_error(); } Redirect::to("/documents").into_response() } pub async fn edit_document_page( State(ctx): State, auth_session: AuthSession, Path((id,)): Path<(Uuid,)>, ) -> Response { let user = match auth_session.user { Some(user) => user, None => return Redirect::to("/login").into_response(), }; let document = match ModelPermission::user_document(&ctx.kv_handles, user.id, id) { Ok(Some(document)) => document, Ok(None) => return Redirect::to("/documents").into_response(), Err(err) => { error!(?err, "failed to load document"); return internal_server_error(); } }; dbg!(&document); let values = context! { user => user, document => document, }; ctx.render_resp("documents/edit_document.html", values) } #[derive(Debug, Deserialize)] pub struct EditDocumentSubmission { pub title: String, pub content: String, } pub async fn edit_document_submit( State(ctx): State, auth_session: AuthSession, Path((document_id,)): Path<(Uuid,)>, form: Form, ) -> Response { let user = match auth_session.user { Some(user) => user, None => return Redirect::to("/login").into_response(), }; let mut document = match ModelPermission::user_document(&ctx.kv_handles, user.id, document_id) { Ok(Some(document)) => document, Ok(None) => return Redirect::to("/documents").into_response(), Err(err) => { error!(?err, "failed to load document"); return internal_server_error(); } }; let new_document = Document { id: document.id, project_id: document.id, title: form.title.to_owned(), content: form.content.to_owned(), }; if let Err(err) = new_document.save(&ctx.kv_handles) { error!(?err, "failed to save document"); return internal_server_error(); } info!(?new_document, "document updated"); Redirect::to("/documents").into_response() }