minor cleanup with traits
This commit is contained in:
parent
73f9c95e37
commit
8a37a7b2da
17 changed files with 81 additions and 71 deletions
|
|
@ -6,7 +6,7 @@ use chattyness_db::{
|
|||
models::{CreateServerAvatarRequest, ServerAvatar, ServerAvatarSummary, UpdateServerAvatarRequest},
|
||||
queries::server_avatars,
|
||||
};
|
||||
use chattyness_error::AppError;
|
||||
use chattyness_error::{AppError, OptionExt};
|
||||
use serde::Serialize;
|
||||
use sqlx::PgPool;
|
||||
use uuid::Uuid;
|
||||
|
|
@ -87,7 +87,7 @@ pub async fn get_avatar(
|
|||
) -> Result<Json<ServerAvatar>, AppError> {
|
||||
let avatar = server_avatars::get_server_avatar_by_id(&pool, avatar_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Avatar not found".to_string()))?;
|
||||
.or_not_found("Avatar")?;
|
||||
Ok(Json(avatar))
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ pub async fn update_avatar(
|
|||
// Check avatar exists
|
||||
let existing = server_avatars::get_server_avatar_by_id(&mut *guard, avatar_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Avatar not found".to_string()))?;
|
||||
.or_not_found("Avatar")?;
|
||||
|
||||
// Update the avatar
|
||||
let avatar = server_avatars::update_server_avatar(&mut *guard, avatar_id, &req).await?;
|
||||
|
|
@ -127,7 +127,7 @@ pub async fn delete_avatar(
|
|||
// Get the avatar first to log its name
|
||||
let avatar = server_avatars::get_server_avatar_by_id(&mut *guard, avatar_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Avatar not found".to_string()))?;
|
||||
.or_not_found("Avatar")?;
|
||||
|
||||
// Delete from database
|
||||
server_avatars::delete_server_avatar(&mut *guard, avatar_id).await?;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use axum::Json;
|
||||
use axum::extract::Path;
|
||||
use chattyness_db::{models::LooseProp, queries::loose_props};
|
||||
use chattyness_error::AppError;
|
||||
use chattyness_error::{AppError, OptionExt};
|
||||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ pub async fn get_loose_prop(
|
|||
|
||||
let prop = loose_props::get_loose_prop_by_id(&mut *guard, loose_prop_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Loose prop not found or has expired".to_string()))?;
|
||||
.or_not_found("Loose prop (may have expired)")?;
|
||||
|
||||
Ok(Json(prop))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use chattyness_db::{
|
|||
models::{CreateServerPropRequest, ServerProp, ServerPropSummary},
|
||||
queries::props,
|
||||
};
|
||||
use chattyness_error::AppError;
|
||||
use chattyness_error::{AppError, OptionExt};
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
|
@ -218,7 +218,7 @@ pub async fn get_prop(
|
|||
) -> Result<Json<ServerProp>, AppError> {
|
||||
let prop = props::get_server_prop_by_id(&pool, prop_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Prop not found".to_string()))?;
|
||||
.or_not_found("Prop")?;
|
||||
Ok(Json(prop))
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ pub async fn delete_prop(
|
|||
// Get the prop first to get the asset path
|
||||
let prop = props::get_server_prop_by_id(&mut *guard, prop_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Prop not found".to_string()))?;
|
||||
.or_not_found("Prop")?;
|
||||
|
||||
// Delete from database
|
||||
props::delete_server_prop(&mut *guard, prop_id).await?;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use chattyness_db::{
|
|||
},
|
||||
queries::{owner as queries, realm_avatars},
|
||||
};
|
||||
use chattyness_error::AppError;
|
||||
use chattyness_error::{AppError, OptionExt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::PgPool;
|
||||
use uuid::Uuid;
|
||||
|
|
@ -231,7 +231,7 @@ pub async fn get_realm_avatar(
|
|||
|
||||
let avatar = realm_avatars::get_realm_avatar_by_id(&pool, avatar_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Avatar not found".to_string()))?;
|
||||
.or_not_found("Avatar")?;
|
||||
Ok(Json(avatar))
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ pub async fn update_realm_avatar(
|
|||
// Check avatar exists
|
||||
let existing = realm_avatars::get_realm_avatar_by_id(&mut *guard, avatar_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Avatar not found".to_string()))?;
|
||||
.or_not_found("Avatar")?;
|
||||
|
||||
// Update the avatar
|
||||
let avatar = realm_avatars::update_realm_avatar(&mut *guard, avatar_id, &req).await?;
|
||||
|
|
@ -284,7 +284,7 @@ pub async fn delete_realm_avatar(
|
|||
// Get the avatar first to log its name
|
||||
let avatar = realm_avatars::get_realm_avatar_by_id(&mut *guard, avatar_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Avatar not found".to_string()))?;
|
||||
.or_not_found("Avatar")?;
|
||||
|
||||
// Delete from database
|
||||
realm_avatars::delete_realm_avatar(&mut *guard, avatar_id).await?;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use chattyness_db::{
|
|||
models::{CreateSceneRequest, Scene, SceneSummary, UpdateSceneRequest},
|
||||
queries::{realms, scenes},
|
||||
};
|
||||
use chattyness_error::AppError;
|
||||
use chattyness_error::{AppError, OptionExt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::PgPool;
|
||||
use std::path::PathBuf;
|
||||
|
|
@ -199,7 +199,7 @@ pub async fn get_scene(
|
|||
) -> Result<Json<Scene>, AppError> {
|
||||
let scene = scenes::get_scene_by_id(&pool, scene_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Scene not found".to_string()))?;
|
||||
.or_not_found("Scene")?;
|
||||
Ok(Json(scene))
|
||||
}
|
||||
|
||||
|
|
@ -273,7 +273,7 @@ pub async fn update_scene(
|
|||
// Get the existing scene to get realm_id
|
||||
let existing_scene = scenes::get_scene_by_id(&mut *guard, scene_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Scene not found".to_string()))?;
|
||||
.or_not_found("Scene")?;
|
||||
|
||||
// Handle clear background image
|
||||
if req.clear_background_image {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use chattyness_db::{
|
|||
models::{CreateSpotRequest, Spot, SpotSummary, UpdateSpotRequest},
|
||||
queries::spots,
|
||||
};
|
||||
use chattyness_error::AppError;
|
||||
use chattyness_error::{AppError, OptionExt};
|
||||
use serde::Serialize;
|
||||
use sqlx::PgPool;
|
||||
use uuid::Uuid;
|
||||
|
|
@ -31,7 +31,7 @@ pub async fn get_spot(
|
|||
) -> Result<Json<Spot>, AppError> {
|
||||
let spot = spots::get_spot_by_id(&pool, spot_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Spot not found".to_string()))?;
|
||||
.or_not_found("Spot")?;
|
||||
Ok(Json(spot))
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ pub async fn update_spot(
|
|||
if let Some(ref new_slug) = req.slug {
|
||||
let existing = spots::get_spot_by_id(&mut *guard, spot_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Spot not found".to_string()))?;
|
||||
.or_not_found("Spot")?;
|
||||
|
||||
if Some(new_slug.clone()) != existing.slug {
|
||||
let available =
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use leptos::prelude::*;
|
|||
use leptos::task::spawn_local;
|
||||
|
||||
use crate::components::{Card, PageHeader};
|
||||
use crate::utils::name_to_slug;
|
||||
|
||||
/// Server avatar new page component.
|
||||
#[component]
|
||||
|
|
@ -28,14 +29,7 @@ pub fn AvatarsNewPage() -> impl IntoView {
|
|||
let new_name = event_target_value(&ev);
|
||||
set_name.set(new_name.clone());
|
||||
if slug_auto.get() {
|
||||
let new_slug = new_name
|
||||
.to_lowercase()
|
||||
.chars()
|
||||
.map(|c| if c.is_alphanumeric() { c } else { '-' })
|
||||
.collect::<String>()
|
||||
.trim_matches('-')
|
||||
.to_string();
|
||||
set_slug.set(new_slug);
|
||||
set_slug.set(name_to_slug(&new_name));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use leptos::prelude::*;
|
|||
use leptos::task::spawn_local;
|
||||
|
||||
use crate::components::{Card, PageHeader};
|
||||
use crate::utils::name_to_slug;
|
||||
|
||||
/// Prop new page component with file upload.
|
||||
#[component]
|
||||
|
|
@ -32,14 +33,7 @@ pub fn PropsNewPage() -> impl IntoView {
|
|||
let new_name = event_target_value(&ev);
|
||||
set_name.set(new_name.clone());
|
||||
if slug_auto.get() {
|
||||
let new_slug = new_name
|
||||
.to_lowercase()
|
||||
.chars()
|
||||
.map(|c| if c.is_alphanumeric() { c } else { '-' })
|
||||
.collect::<String>()
|
||||
.trim_matches('-')
|
||||
.to_string();
|
||||
set_slug.set(new_slug);
|
||||
set_slug.set(name_to_slug(&new_name));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use leptos::task::spawn_local;
|
|||
use leptos_router::hooks::use_params_map;
|
||||
|
||||
use crate::components::{Card, PageHeader};
|
||||
use crate::utils::name_to_slug;
|
||||
#[cfg(feature = "hydrate")]
|
||||
use crate::utils::get_api_base;
|
||||
|
||||
|
|
@ -36,14 +37,7 @@ pub fn RealmAvatarsNewPage() -> impl IntoView {
|
|||
let new_name = event_target_value(&ev);
|
||||
set_name.set(new_name.clone());
|
||||
if slug_auto.get() {
|
||||
let new_slug = new_name
|
||||
.to_lowercase()
|
||||
.chars()
|
||||
.map(|c| if c.is_alphanumeric() { c } else { '-' })
|
||||
.collect::<String>()
|
||||
.trim_matches('-')
|
||||
.to_string();
|
||||
set_avatar_slug.set(new_slug);
|
||||
set_avatar_slug.set(name_to_slug(&new_name));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use leptos::prelude::*;
|
|||
use leptos::task::spawn_local;
|
||||
|
||||
use crate::components::{Card, PageHeader};
|
||||
use crate::utils::name_to_slug;
|
||||
|
||||
/// Realm new page component.
|
||||
#[component]
|
||||
|
|
@ -40,14 +41,7 @@ pub fn RealmNewPage() -> impl IntoView {
|
|||
let new_name = event_target_value(&ev);
|
||||
set_name.set(new_name.clone());
|
||||
if slug_auto.get() {
|
||||
let new_slug = new_name
|
||||
.to_lowercase()
|
||||
.chars()
|
||||
.map(|c| if c.is_alphanumeric() { c } else { '-' })
|
||||
.collect::<String>()
|
||||
.trim_matches('-')
|
||||
.to_string();
|
||||
set_slug.set(new_slug);
|
||||
set_slug.set(name_to_slug(&new_name));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use leptos::task::spawn_local;
|
|||
use leptos_router::hooks::use_params_map;
|
||||
|
||||
use crate::components::{Card, PageHeader};
|
||||
use crate::utils::name_to_slug;
|
||||
#[cfg(feature = "hydrate")]
|
||||
use crate::utils::fetch_image_dimensions_client;
|
||||
|
||||
|
|
@ -40,14 +41,7 @@ pub fn SceneNewPage() -> impl IntoView {
|
|||
let new_name = event_target_value(&ev);
|
||||
set_name.set(new_name.clone());
|
||||
if slug_auto.get() {
|
||||
let new_slug = new_name
|
||||
.to_lowercase()
|
||||
.chars()
|
||||
.map(|c| if c.is_alphanumeric() { c } else { '-' })
|
||||
.collect::<String>()
|
||||
.trim_matches('-')
|
||||
.to_string();
|
||||
set_slug.set(new_slug);
|
||||
set_slug.set(name_to_slug(&new_name));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,24 @@
|
|||
//! Utility functions for the admin UI.
|
||||
|
||||
/// Generate a URL-friendly slug from a name.
|
||||
///
|
||||
/// Converts to lowercase, replaces non-alphanumeric chars with hyphens,
|
||||
/// and trims leading/trailing hyphens.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// assert_eq!(name_to_slug("My Cool Realm!"), "my-cool-realm-");
|
||||
/// assert_eq!(name_to_slug("Test 123"), "test-123");
|
||||
/// ```
|
||||
pub fn name_to_slug(name: &str) -> String {
|
||||
name.to_lowercase()
|
||||
.chars()
|
||||
.map(|c| if c.is_alphanumeric() { c } else { '-' })
|
||||
.collect::<String>()
|
||||
.trim_matches('-')
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Gets the API base path based on the current URL.
|
||||
///
|
||||
/// Returns `/api/admin` if the current path starts with `/admin`,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue