121 lines
3.3 KiB
Rust
121 lines
3.3 KiB
Rust
use crate::{AppError, layouts, util::AppState};
|
|
use axum::{
|
|
Form, Router,
|
|
extract::{Path, State},
|
|
http::HeaderMap,
|
|
response::IntoResponse,
|
|
routing::get,
|
|
};
|
|
use maud::{Markup, html};
|
|
use serde::Deserialize;
|
|
use uuid::Uuid;
|
|
|
|
pub fn routes() -> Router<AppState> {
|
|
Router::new()
|
|
.route("/", get(page).delete(delete).put(submit_edit))
|
|
.route("/edit", get(edit))
|
|
}
|
|
|
|
async fn page(State(state): State<AppState>, Path(id): Path<Uuid>) -> Result<Markup, AppError> {
|
|
let exercise = sqlx::query_as!(
|
|
crate::models::Exercise,
|
|
"SELECT exercise_id, name, description FROM exercises WHERE exercise_id = $1",
|
|
id
|
|
)
|
|
.fetch_one(&state.pool)
|
|
.await?;
|
|
|
|
let content = html! {
|
|
div {
|
|
div class="flex w-full" {
|
|
h1 { (exercise.name) }
|
|
a href={"/exercises/" (exercise.exercise_id) "/edit" } class="ml-auto btn" { "Edit" }
|
|
}
|
|
p { (exercise.description) }
|
|
button hx-delete={ "/exercises/" (exercise.exercise_id) } hx-confirm="Are you sure that you want to delete this exercise?" class="btn btn-error" { "Delete Exercise" }
|
|
}
|
|
};
|
|
|
|
Ok(layouts::desktop(content, "Exercises"))
|
|
}
|
|
|
|
async fn delete(
|
|
State(state): State<AppState>,
|
|
Path(id): Path<Uuid>,
|
|
) -> Result<impl IntoResponse, AppError> {
|
|
sqlx::query_as!(
|
|
crate::models::Exercise,
|
|
"DELETE FROM exercises WHERE exercise_id = $1",
|
|
id
|
|
)
|
|
.execute(&state.pool)
|
|
.await?;
|
|
|
|
let mut headers = HeaderMap::new();
|
|
headers.insert("hx-location", "/exercises".parse().unwrap());
|
|
|
|
Ok((headers, html! {}))
|
|
}
|
|
|
|
async fn edit(
|
|
State(state): State<AppState>,
|
|
Path(id): Path<Uuid>,
|
|
) -> Result<impl IntoResponse, AppError> {
|
|
let exercise = sqlx::query_as!(
|
|
crate::models::Exercise,
|
|
"SELECT exercise_id, name, description FROM exercises WHERE exercise_id = $1",
|
|
id
|
|
)
|
|
.fetch_one(&state.pool)
|
|
.await?;
|
|
|
|
let content = html! {
|
|
h1 class="mb-5" { "Edit Exercise" }
|
|
|
|
form hx-put={"/exercises/" (exercise.exercise_id)} class="space-y-1" {
|
|
fieldset class="fieldset" {
|
|
legend class="fieldset-legend" { "Name" }
|
|
input required="true" name="name" class="input" value={(exercise.name)} {}
|
|
}
|
|
|
|
fieldset class="fieldset" {
|
|
legend class="fieldset-legend" { "Description" }
|
|
textarea required="true" name="description" class="textarea" { (exercise.description) }
|
|
}
|
|
|
|
input type="submit" class="btn" value="save" { }
|
|
}
|
|
};
|
|
|
|
Ok(layouts::desktop(content, "Edit Exercises"))
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
struct FormData {
|
|
name: String,
|
|
description: String,
|
|
}
|
|
|
|
async fn submit_edit(
|
|
State(state): State<AppState>,
|
|
Path(id): Path<Uuid>,
|
|
Form(form): Form<FormData>,
|
|
) -> Result<impl IntoResponse, AppError> {
|
|
sqlx::query_as!(
|
|
crate::models::Exercise,
|
|
"UPDATE exercises SET name = $1, description = $2 WHERE exercise_id = $3",
|
|
form.name,
|
|
form.description,
|
|
id
|
|
)
|
|
.execute(&state.pool)
|
|
.await?;
|
|
|
|
let mut headers = HeaderMap::new();
|
|
|
|
let location = format!("/exercises/{}", id);
|
|
headers.insert("hx-location", location.parse().unwrap());
|
|
|
|
Ok((headers, html! {}))
|
|
}
|