add: products ui

This commit is contained in:
trisua 2025-08-08 02:17:06 -04:00
parent 8f76578f1b
commit fd529d3847
31 changed files with 1041 additions and 49 deletions

View file

@ -1,5 +1,6 @@
use std::collections::HashMap;
use crate::model::auth::Notification;
use crate::model::{auth::User, mail::Letter, permissions::SecondaryPermission, Error, Result};
use crate::{auto_method, DataManager};
use oiseau::{cache::Cache, execute, get, params, query_rows, PostgresRow};
@ -160,6 +161,9 @@ impl DataManager {
return Err(Error::DataTooLong("receivers".to_string()));
}
// get sender
let sender = self.get_user_by_id(data.owner).await?;
// ...
let conn = match self.0.connect().await {
Ok(c) => c,
@ -185,6 +189,20 @@ impl DataManager {
return Err(Error::DatabaseError(e.to_string()));
}
// send notifications
for x in &data.receivers {
self.create_notification(Notification::new(
"You've got mail!".to_string(),
format!(
"[@{}](/api/v1/auth/user/find/{}) has sent you a [letter](/mail/letter/{}).",
sender.username, sender.id, data.id
),
*x,
))
.await?;
}
// ...
Ok(data)
}

View file

@ -150,7 +150,7 @@ impl DataManager {
match product.method {
ProductFulfillmentMethod::AutoMail(message) => {
// we're basically done, transfer coins and send mail
self.create_transfer(&mut transfer, false).await?;
self.create_transfer(&mut transfer, true).await?;
self.create_letter(Letter::new(
self.0.0.system_user,
@ -167,6 +167,16 @@ impl DataManager {
// mark transfer as pending and create it
self.create_transfer(&mut transfer, false).await?;
// tell the customer to wait
self.create_letter(Letter::new(
self.0.0.system_user,
vec![customer.id],
format!("Thank you for purchasing \"{}\"", product.title),
"This product uses manual mail, meaning you won't be charged until the product owner sends you a letter about the product. You'll see a pending transfer in your wallet.".to_string(),
0,
))
.await?;
// tell product owner they have a new pending purchase
self.create_letter(Letter::new(
self.0.0.system_user,
@ -178,7 +188,7 @@ impl DataManager {
If your product is a purchase of goods or services, please be sure to fulfill this purchase either in the letter or elsewhere. The customer may request support if you fail to do so.
***
<a class=\"button\" href=\"/mail/compose?receivers=id:{}&title=Product%20fulfillment&transfer_id={}\">Fulfill purchase</a>",
<a class=\"button\" href=\"/mail/compose?receivers=id:{}&subject=Product%20fulfillment&transfer_id={}\">Fulfill purchase</a>",
product.id, product.title, customer.id, transfer.id
),
0,

View file

@ -1,8 +1,9 @@
use std::collections::HashMap;
use crate::model::auth::User;
use crate::model::economy::{CoinTransferMethod, Product};
use crate::model::{Error, Result, economy::CoinTransfer};
use crate::model::{
Error, Result,
economy::{CoinTransferMethod, Product, CoinTransfer},
auth::{Notification, User},
};
use crate::{auto_method, DataManager};
use oiseau::{cache::Cache, execute, get, params, query_rows, PostgresRow};
@ -168,8 +169,35 @@ impl DataManager {
self.update_user_coins(sender.id, sender.coins).await?;
self.update_user_coins(receiver.id, receiver.coins).await?;
self.update_transfer_is_pending(id, 0).await?;
self.create_notification(Notification::new(
"Purchase fulfilled!".to_string(),
format!(
"You've just successfully fulfilled a purchase for a [product](/product/{}).",
match transfer.method {
CoinTransferMethod::Purchase(x) => x,
_ => 0,
}
),
receiver.id,
))
.await?;
self.create_notification(Notification::new(
"Purchase fulfilled!".to_string(),
format!(
"Your purchase for a [product](/product/{}) has been fulfilled.",
match transfer.method {
CoinTransferMethod::Purchase(x) => x,
_ => 0,
}
),
sender.id,
))
.await?;
Ok(())
}
auto_method!(update_transfer_is_pending(i32) -> "UPDATE products SET is_pending = $1 WHERE id = $2" --cache-key-tmpl="atto.transfer:{}");
auto_method!(update_transfer_is_pending(i32) -> "UPDATE transfers SET is_pending = $1 WHERE id = $2" --cache-key-tmpl="atto.transfer:{}");
}