From 959a1259928ab3818a5ccea300978c687a18dd15 Mon Sep 17 00:00:00 2001 From: trisua Date: Mon, 14 Jul 2025 22:05:59 -0400 Subject: [PATCH] add: change default avatar --- .../app/src/public/images/default-avatar.svg | 7 ++++ crates/app/src/routes/api/v1/products.rs | 23 ++++++++--- crates/app/src/routes/pages/marketplace.rs | 10 ++++- crates/core/src/database/common.rs | 20 ++++++++++ crates/core/src/database/products.rs | 39 +++++++++++++++++-- crates/core/src/database/stacks.rs | 6 ++- 6 files changed, 92 insertions(+), 13 deletions(-) diff --git a/crates/app/src/public/images/default-avatar.svg b/crates/app/src/public/images/default-avatar.svg index 00fa7ab..2f92a92 100644 --- a/crates/app/src/public/images/default-avatar.svg +++ b/crates/app/src/public/images/default-avatar.svg @@ -6,4 +6,11 @@ xmlns="http://www.w3.org/2000/svg" > + + + diff --git a/crates/app/src/routes/api/v1/products.rs b/crates/app/src/routes/api/v1/products.rs index 6a48dd3..05d8e9c 100644 --- a/crates/app/src/routes/api/v1/products.rs +++ b/crates/app/src/routes/api/v1/products.rs @@ -1,13 +1,20 @@ use crate::{ get_user_from_token, image::{save_webp_buffer, JsonMultipart}, - routes::api::v1::{ - communities::posts::MAXIMUM_FILE_SIZE, CreateProduct, UpdateProductDescription, - UpdateProductName, UpdateProductPrice, + routes::{ + api::v1::{ + communities::posts::MAXIMUM_FILE_SIZE, CreateProduct, UpdateProductDescription, + UpdateProductName, UpdateProductPrice, + }, + pages::PaginatedQuery, }, State, }; -use axum::{extract::Path, response::IntoResponse, Extension, Json}; +use axum::{ + extract::{Path, Query}, + response::IntoResponse, + Extension, Json, +}; use axum_extra::extract::CookieJar; use tetratto_core::model::{ oauth, @@ -31,14 +38,18 @@ pub async fn get_request( } } -pub async fn list_request(jar: CookieJar, Extension(data): Extension) -> impl IntoResponse { +pub async fn list_request( + jar: CookieJar, + Extension(data): Extension, + Query(props): Query, +) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadProducts) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; - match data.get_products_by_user(user.id).await { + match data.get_products_by_user(user.id, 12, props.page).await { Ok(x) => Json(ApiReturn { ok: true, message: "Success".to_string(), diff --git a/crates/app/src/routes/pages/marketplace.rs b/crates/app/src/routes/pages/marketplace.rs index f2b6b11..0de9be7 100644 --- a/crates/app/src/routes/pages/marketplace.rs +++ b/crates/app/src/routes/pages/marketplace.rs @@ -1,6 +1,9 @@ use super::render_error; -use crate::{assets::initial_context, get_lang, get_user_from_token, State}; +use crate::{ + assets::initial_context, get_lang, get_user_from_token, State, routes::pages::PaginatedQuery, +}; use axum::{ + extract::Query, response::{Html, IntoResponse}, Extension, }; @@ -11,6 +14,7 @@ use tetratto_core::model::Error; pub async fn seller_settings_request( jar: CookieJar, Extension(data): Extension, + Query(props): Query, ) -> impl IntoResponse { let data = data.read().await; let user = match get_user_from_token!(jar, data.0) { @@ -22,14 +26,16 @@ pub async fn seller_settings_request( } }; - let products = match data.0.get_products_by_user(user.id).await { + let products = match data.0.get_products_by_user(user.id, 12, props.page).await { Ok(x) => x, Err(e) => return Err(Html(render_error(e, &jar, &data, &None).await)), }; let lang = get_lang!(jar, data.0); let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await; + context.insert("list", &products); + context.insert("page", &props.page); // return Ok(Html( diff --git a/crates/core/src/database/common.rs b/crates/core/src/database/common.rs index e7cd0ef..e61b565 100644 --- a/crates/core/src/database/common.rs +++ b/crates/core/src/database/common.rs @@ -75,6 +75,26 @@ impl DataManager { Ok(res.unwrap()) } + + pub async fn get_table_row_count_where(&self, table: &str, r#where: &str) -> Result { + let conn = match self.0.connect().await { + Ok(c) => c, + Err(e) => return Err(Error::DatabaseConnection(e.to_string())), + }; + + let res = query_row!( + &conn, + &format!("SELECT COUNT(*)::int FROM {} {}", table, r#where), + params![], + |x| Ok(x.get::(0)) + ); + + if let Err(e) = res { + return Err(Error::DatabaseError(e.to_string())); + } + + Ok(res.unwrap()) + } } #[macro_export] diff --git a/crates/core/src/database/products.rs b/crates/core/src/database/products.rs index 5127f78..0eab9aa 100644 --- a/crates/core/src/database/products.rs +++ b/crates/core/src/database/products.rs @@ -30,7 +30,38 @@ impl DataManager { /// /// # Arguments /// * `id` - the ID of the user to fetch products for - pub async fn get_products_by_user(&self, id: usize) -> Result> { + /// * `batch` + /// * `page` + pub async fn get_products_by_user( + &self, + id: usize, + batch: usize, + page: usize, + ) -> Result> { + let conn = match self.0.connect().await { + Ok(c) => c, + Err(e) => return Err(Error::DatabaseConnection(e.to_string())), + }; + + let res = query_rows!( + &conn, + "SELECT * FROM products WHERE owner = $1 ORDER BY created DESC LIMIT {} OFFSET {}", + &[&(id as i64), &(batch as i64), &((page * batch) as i64)], + |x| { Self::get_product_from_row(x) } + ); + + if res.is_err() { + return Err(Error::GeneralNotFound("product".to_string())); + } + + Ok(res.unwrap()) + } + + /// Get all products by user. + /// + /// # Arguments + /// * `id` - the ID of the user to fetch products for + pub async fn get_products_by_user_all(&self, id: usize) -> Result> { let conn = match self.0.connect().await { Ok(c) => c, Err(e) => return Err(Error::DatabaseConnection(e.to_string())), @@ -68,9 +99,11 @@ impl DataManager { let owner = self.get_user_by_id(data.owner).await?; if !owner.permissions.check(FinePermission::SUPPORTER) { - let products = self.get_products_by_user(data.owner).await?; + let products = self + .get_table_row_count_where("products", &format!("owner = {}", owner.id)) + .await? as usize; - if products.len() >= Self::MAXIMUM_FREE_PRODUCTS { + if products >= Self::MAXIMUM_FREE_PRODUCTS { return Err(Error::MiscError( "You already have the maximum number of products you can have".to_string(), )); diff --git a/crates/core/src/database/stacks.rs b/crates/core/src/database/stacks.rs index 6a64b53..cea2be9 100644 --- a/crates/core/src/database/stacks.rs +++ b/crates/core/src/database/stacks.rs @@ -165,9 +165,11 @@ impl DataManager { let owner = self.get_user_by_id(data.owner).await?; if !owner.permissions.check(FinePermission::SUPPORTER) { - let stacks = self.get_stacks_by_user(data.owner).await?; + let stacks = self + .get_table_row_count_where("stacks", &format!("owner = {}", owner.id)) + .await? as usize; - if stacks.len() >= Self::MAXIMUM_FREE_STACKS { + if stacks >= Self::MAXIMUM_FREE_STACKS { return Err(Error::MiscError( "You already have the maximum number of stacks you can have".to_string(), ));