init projectmycelium
This commit is contained in:
229
src/services/navbar.rs
Normal file
229
src/services/navbar.rs
Normal file
@@ -0,0 +1,229 @@
|
||||
use actix_session::Session;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use rust_decimal::Decimal;
|
||||
use crate::services::{currency::CurrencyService, user_persistence::UserPersistence};
|
||||
|
||||
/// Service for handling navbar dropdown data
|
||||
#[derive(Clone)]
|
||||
pub struct NavbarService {
|
||||
currency_service: CurrencyService,
|
||||
}
|
||||
|
||||
/// Data structure for navbar dropdown menu
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct NavbarDropdownData {
|
||||
pub user_name: Option<String>,
|
||||
pub user_email: String,
|
||||
pub wallet_balance: Decimal,
|
||||
pub wallet_balance_formatted: String,
|
||||
pub display_currency: String,
|
||||
pub currency_symbol: String,
|
||||
pub quick_actions: Vec<QuickAction>,
|
||||
pub show_topup_button: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct QuickAction {
|
||||
pub id: String,
|
||||
pub label: String,
|
||||
pub url: String,
|
||||
pub icon: String,
|
||||
pub badge: Option<String>,
|
||||
}
|
||||
|
||||
/// Builder for NavbarService
|
||||
#[derive(Default)]
|
||||
pub struct NavbarServiceBuilder {
|
||||
currency_service: Option<CurrencyService>,
|
||||
}
|
||||
|
||||
impl NavbarServiceBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn with_currency_service(mut self, service: CurrencyService) -> Self {
|
||||
self.currency_service = Some(service);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<NavbarService, String> {
|
||||
let currency_service = self.currency_service
|
||||
.unwrap_or_else(|| CurrencyService::builder().build().unwrap());
|
||||
|
||||
Ok(NavbarService {
|
||||
currency_service,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl NavbarService {
|
||||
pub fn builder() -> NavbarServiceBuilder {
|
||||
NavbarServiceBuilder::new()
|
||||
}
|
||||
|
||||
/// Get navbar dropdown data for authenticated user
|
||||
pub fn get_dropdown_data(&self, session: &Session) -> Result<NavbarDropdownData, String> {
|
||||
// Get user email from session
|
||||
let user_email = session.get::<String>("user_email")
|
||||
.map_err(|e| format!("Failed to get user email from session: {}", e))?
|
||||
.ok_or("User not authenticated")?;
|
||||
|
||||
// Load user persistent data
|
||||
let persistent_data = UserPersistence::load_user_data(&user_email)
|
||||
.unwrap_or_else(|| crate::services::user_persistence::UserPersistentData {
|
||||
user_email: user_email.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
// Get user's preferred display currency
|
||||
let mut display_currency = self.currency_service.get_user_preferred_currency(session);
|
||||
|
||||
// Get currency info for formatting; fall back to USD if invalid
|
||||
let (currency, effective_currency) = match self.currency_service.get_currency(&display_currency) {
|
||||
Some(c) => (c, display_currency.clone()),
|
||||
None => {
|
||||
let usd = self
|
||||
.currency_service
|
||||
.get_currency("USD")
|
||||
.expect("USD currency must be available");
|
||||
display_currency = "USD".to_string();
|
||||
(usd, "USD".to_string())
|
||||
}
|
||||
};
|
||||
|
||||
// Convert wallet balance to display currency
|
||||
let wallet_balance_display = if effective_currency == "USD" {
|
||||
persistent_data.wallet_balance_usd
|
||||
} else {
|
||||
self.currency_service.convert_amount(
|
||||
persistent_data.wallet_balance_usd,
|
||||
"USD",
|
||||
&effective_currency,
|
||||
).unwrap_or(Decimal::ZERO)
|
||||
};
|
||||
|
||||
// Format the balance
|
||||
let wallet_balance_formatted = currency.format_amount(wallet_balance_display);
|
||||
|
||||
// Create quick actions
|
||||
let quick_actions = vec![
|
||||
QuickAction {
|
||||
id: "topup".to_string(),
|
||||
label: "Top Up Wallet".to_string(),
|
||||
url: "/wallet?action=topup".to_string(),
|
||||
icon: "bi-plus-circle".to_string(),
|
||||
badge: None,
|
||||
},
|
||||
QuickAction {
|
||||
id: "wallet".to_string(),
|
||||
label: "Wallet".to_string(),
|
||||
url: "/wallet".to_string(),
|
||||
icon: "bi-wallet2".to_string(),
|
||||
badge: None,
|
||||
},
|
||||
QuickAction {
|
||||
id: "settings".to_string(),
|
||||
label: "Settings".to_string(),
|
||||
url: "/dashboard/settings".to_string(),
|
||||
icon: "bi-gear".to_string(),
|
||||
badge: None,
|
||||
},
|
||||
];
|
||||
|
||||
Ok(NavbarDropdownData {
|
||||
user_name: persistent_data.name,
|
||||
user_email,
|
||||
wallet_balance: wallet_balance_display,
|
||||
wallet_balance_formatted,
|
||||
display_currency: effective_currency.clone(),
|
||||
currency_symbol: currency.symbol.clone(),
|
||||
quick_actions,
|
||||
show_topup_button: true,
|
||||
})
|
||||
}
|
||||
|
||||
/// Get simplified navbar data for guest users
|
||||
pub fn get_guest_data() -> NavbarDropdownData {
|
||||
NavbarDropdownData {
|
||||
user_name: None,
|
||||
user_email: String::new(),
|
||||
wallet_balance: Decimal::ZERO,
|
||||
wallet_balance_formatted: "Not logged in".to_string(),
|
||||
display_currency: "USD".to_string(),
|
||||
currency_symbol: "$".to_string(),
|
||||
quick_actions: vec![
|
||||
QuickAction {
|
||||
id: "login".to_string(),
|
||||
label: "Login".to_string(),
|
||||
url: "/login".to_string(),
|
||||
icon: "bi-box-arrow-in-right".to_string(),
|
||||
badge: None,
|
||||
},
|
||||
QuickAction {
|
||||
id: "register".to_string(),
|
||||
label: "Register".to_string(),
|
||||
url: "/register".to_string(),
|
||||
icon: "bi-person-plus".to_string(),
|
||||
badge: None,
|
||||
},
|
||||
],
|
||||
show_topup_button: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if user has sufficient balance for a purchase
|
||||
pub fn check_sufficient_balance(&self, session: &Session, required_amount_usd: Decimal) -> Result<bool, String> {
|
||||
let user_email = session.get::<String>("user_email")
|
||||
.map_err(|e| format!("Failed to get user email: {}", e))?
|
||||
.ok_or("User not authenticated")?;
|
||||
|
||||
let persistent_data = UserPersistence::load_user_data(&user_email)
|
||||
.unwrap_or_default();
|
||||
|
||||
Ok(persistent_data.wallet_balance_usd >= required_amount_usd)
|
||||
}
|
||||
|
||||
/// Get quick top-up amounts for user's preferred currency
|
||||
pub fn get_quick_topup_amounts(&self, session: &Session) -> Result<Vec<Decimal>, String> {
|
||||
let user_email = session.get::<String>("user_email")
|
||||
.map_err(|e| format!("Failed to get user email: {}", e))?
|
||||
.ok_or("User not authenticated")?;
|
||||
|
||||
let persistent_data = UserPersistence::load_user_data(&user_email)
|
||||
.unwrap_or_default();
|
||||
|
||||
// Use custom amounts if set, otherwise use defaults
|
||||
if let Some(custom_amounts) = persistent_data.quick_topup_amounts {
|
||||
Ok(custom_amounts)
|
||||
} else {
|
||||
// Default amounts in user's preferred currency
|
||||
let display_currency = self.currency_service.get_user_preferred_currency(session);
|
||||
|
||||
let default_amounts = if display_currency == "USD" {
|
||||
vec![
|
||||
Decimal::from(10), // $10
|
||||
Decimal::from(25), // $25
|
||||
Decimal::from(50), // $50
|
||||
Decimal::from(100), // $100
|
||||
]
|
||||
} else {
|
||||
// Default fiat amounts (will be converted to USD internally)
|
||||
vec![
|
||||
Decimal::from(10), // $10, €10, etc.
|
||||
Decimal::from(20), // $20, €20, etc.
|
||||
Decimal::from(50), // $50, €50, etc.
|
||||
Decimal::from(100), // $100, €100, etc.
|
||||
]
|
||||
};
|
||||
|
||||
Ok(default_amounts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for NavbarService {
|
||||
fn default() -> Self {
|
||||
Self::builder().build().unwrap()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user