use std::str::FromStr; use web_sys::{HtmlInputElement, HtmlSelectElement}; use yew::{classes, html, Component, Context, Html, Properties, NodeRef}; use yew_agent::{Dispatched, Dispatcher}; use crate::event_bus::{EventBus, Request}; use crate::events::Event; pub enum Msg { AmountChanged, Deposit, Withdraw, Transfer, } #[derive(Properties, PartialEq)] pub struct AccountProps { pub account_nrs: Vec, pub balance: f64, pub nr: String, pub owner: String, } pub struct Account { amount_ref: NodeRef, transfer_account_ref: NodeRef, amount_valid: bool, event_bus: Dispatcher, } impl Account { fn amount(&self) -> f64 { if let Some(amount_el) = self.amount_ref.cast::() { f64::from_str(&amount_el.value()).unwrap_or_default() } else { 0_f64 } } fn is_amount_valid(&self) -> bool { self.amount() > 0_f64 } fn selected_transfer_account(&self) -> Option { if let Some(transfer_account_el) = self.transfer_account_ref.cast::() { let value: String = transfer_account_el.value(); if value.is_empty() || value == "undefined" { None } else { Some(value) } } else { None } } } impl Component for Account { type Message = Msg; type Properties = AccountProps; fn create(_: &Context) -> Self { Self { amount_ref: NodeRef::default(), transfer_account_ref: NodeRef::default(), amount_valid: false, event_bus: EventBus::dispatcher(), } } fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool { match msg { Msg::AmountChanged => { let is_amount_valid = self.is_amount_valid(); let needs_redraw = is_amount_valid != self.amount_valid; self.amount_valid = is_amount_valid; needs_redraw } Msg::Deposit => { let amount = self.amount() + ctx.props().balance; self.event_bus.send(Request::EventBusMsg(Event::SetBalance(amount, ctx.props().nr.clone()))); false } Msg::Withdraw => { let amount = ctx.props().balance - self.amount(); if amount > 0_f64 { self.event_bus.send(Request::EventBusMsg(Event::SetBalance(amount, ctx.props().nr.clone()))); } else { self.event_bus.send(Request::EventBusMsg(Event::ShowError("Balance can not be overdrawn".into()))); } false } Msg::Transfer => { let amount = ctx.props().balance - self.amount(); if amount > 0_f64 { self.event_bus.send(Request::EventBusMsg(Event::SetBalance(amount, ctx.props().nr.clone()))); } else { let transfer_nr = self.selected_transfer_account(); if let Some(transfer_nr) = transfer_nr { self.event_bus.send(Request::EventBusMsg(Event::Transfer(amount, ctx.props().nr.clone(), transfer_nr))); } } false } } } fn view(&self, ctx: &Context) -> Html { let onchange = ctx .link() .callback(|_| Msg::AmountChanged); let on_deposit = ctx .link() .callback(|_| Msg::Deposit); let on_withdraw = ctx .link() .callback(|_| Msg::Withdraw); let on_transfer = ctx .link() .callback(|_| Msg::Transfer); html! { <>
{&ctx.props().owner} {" — "} {&ctx.props().balance}
} } }