use yew::prelude::*; use std::collections::HashMap; use crate::routing::ViewContext; use crate::components::{ViewComponent, EmptyState}; use crate::services::mock_billing_api::{MockBillingApi, Plan}; use web_sys::MouseEvent; use wasm_bindgen::JsCast; use gloo::timers::callback::Timeout; #[derive(Properties, PartialEq)] pub struct AdministrationViewProps { pub context: ViewContext, } #[function_component(AdministrationView)] pub fn administration_view(props: &AdministrationViewProps) -> Html { // Initialize mock billing API let billing_api = use_state(|| MockBillingApi::new()); // State for managing UI interactions let show_plan_modal = use_state(|| false); let show_cancel_modal = use_state(|| false); let show_add_payment_modal = use_state(|| false); let downloading_invoice = use_state(|| None::); let selected_plan = use_state(|| None::); let loading_action = use_state(|| None::); // Event handlers let on_change_plan = { let show_plan_modal = show_plan_modal.clone(); Callback::from(move |_: MouseEvent| { show_plan_modal.set(true); }) }; let on_cancel_subscription = { let show_cancel_modal = show_cancel_modal.clone(); Callback::from(move |_: MouseEvent| { show_cancel_modal.set(true); }) }; let on_confirm_cancel_subscription = { let billing_api = billing_api.clone(); let show_cancel_modal = show_cancel_modal.clone(); let loading_action = loading_action.clone(); Callback::from(move |_: MouseEvent| { loading_action.set(Some("canceling".to_string())); let billing_api_clone = billing_api.clone(); let show_cancel_modal_clone = show_cancel_modal.clone(); let loading_action_clone = loading_action.clone(); // Simulate async operation with timeout Timeout::new(1000, move || { let mut api = (*billing_api_clone).clone(); api.current_subscription.status = "cancelled".to_string(); billing_api_clone.set(api); loading_action_clone.set(None); show_cancel_modal_clone.set(false); web_sys::console::log_1(&"Subscription canceled successfully".into()); }).forget(); }) }; let on_download_invoice = { let billing_api = billing_api.clone(); let downloading_invoice = downloading_invoice.clone(); Callback::from(move |e: MouseEvent| { if let Some(target) = e.target() { if let Ok(button) = target.dyn_into::() { if let Some(invoice_id) = button.get_attribute("data-invoice-id") { downloading_invoice.set(Some(invoice_id.clone())); let billing_api_clone = billing_api.clone(); let downloading_invoice_clone = downloading_invoice.clone(); let invoice_id_clone = invoice_id.clone(); // Simulate download with timeout Timeout::new(500, move || { let api = (*billing_api_clone).clone(); // Find the invoice and get its PDF URL if let Some(invoice) = api.invoices.iter().find(|i| i.id == invoice_id_clone) { // Create a link and trigger download if let Some(window) = web_sys::window() { if let Some(document) = window.document() { if let Ok(anchor) = document.create_element("a") { if let Ok(anchor) = anchor.dyn_into::() { anchor.set_attribute("href", &invoice.pdf_url).unwrap(); anchor.set_attribute("download", &format!("invoice_{}.pdf", invoice_id_clone)).unwrap(); anchor.click(); } } } } web_sys::console::log_1(&"Invoice downloaded successfully".into()); } else { web_sys::console::log_1(&"Invoice not found".into()); } downloading_invoice_clone.set(None); }).forget(); } } } }) }; let on_add_payment_method = { let show_add_payment_modal = show_add_payment_modal.clone(); Callback::from(move |_: MouseEvent| { show_add_payment_modal.set(true); }) }; let on_confirm_add_payment_method = { let billing_api = billing_api.clone(); let show_add_payment_modal = show_add_payment_modal.clone(); let loading_action = loading_action.clone(); Callback::from(move |_: MouseEvent| { loading_action.set(Some("adding_payment".to_string())); let billing_api_clone = billing_api.clone(); let show_add_payment_modal_clone = show_add_payment_modal.clone(); let loading_action_clone = loading_action.clone(); // Simulate async operation with timeout Timeout::new(1000, move || { let mut api = (*billing_api_clone).clone(); // Add a new payment method let new_method = crate::services::mock_billing_api::PaymentMethod { id: format!("card_{}", api.payment_methods.len() + 1), method_type: "Credit Card".to_string(), last_four: "•••• •••• •••• 4242".to_string(), expires: Some("12/28".to_string()), is_primary: false, }; api.payment_methods.push(new_method); billing_api_clone.set(api); loading_action_clone.set(None); show_add_payment_modal_clone.set(false); web_sys::console::log_1(&"Payment method added successfully".into()); }).forget(); }) }; let on_edit_payment_method = { let loading_action = loading_action.clone(); Callback::from(move |e: MouseEvent| { if let Some(target) = e.target() { if let Ok(button) = target.dyn_into::() { if let Some(method_id) = button.get_attribute("data-method") { let loading_action_clone = loading_action.clone(); let method_id_clone = method_id.clone(); loading_action.set(Some(format!("editing_{}", method_id))); // Simulate API call delay Timeout::new(1000, move || { loading_action_clone.set(None); web_sys::console::log_1(&format!("Edit payment method: {}", method_id_clone).into()); }).forget(); } } } }) }; let on_remove_payment_method = { let billing_api = billing_api.clone(); let loading_action = loading_action.clone(); Callback::from(move |e: MouseEvent| { if let Some(target) = e.target() { if let Ok(button) = target.dyn_into::() { if let Some(method_id) = button.get_attribute("data-method") { if web_sys::window() .unwrap() .confirm_with_message(&format!("Are you sure you want to remove this payment method?")) .unwrap_or(false) { let billing_api_clone = billing_api.clone(); let loading_action_clone = loading_action.clone(); let method_id_clone = method_id.clone(); loading_action.set(Some(format!("removing_{}", method_id))); // Simulate async operation with timeout Timeout::new(1000, move || { let mut api = (*billing_api_clone).clone(); // Remove the payment method if let Some(pos) = api.payment_methods.iter().position(|m| m.id == method_id_clone) { api.payment_methods.remove(pos); billing_api_clone.set(api); web_sys::console::log_1(&"Payment method removed successfully".into()); } else { web_sys::console::log_1(&"Payment method not found".into()); } loading_action_clone.set(None); }).forget(); } } } } }) }; let on_select_plan = { let selected_plan = selected_plan.clone(); Callback::from(move |e: MouseEvent| { if let Some(target) = e.target() { if let Ok(button) = target.dyn_into::() { if let Some(plan_id) = button.get_attribute("data-plan-id") { selected_plan.set(Some(plan_id)); } } } }) }; let on_confirm_plan_change = { let billing_api = billing_api.clone(); let selected_plan = selected_plan.clone(); let show_plan_modal = show_plan_modal.clone(); let loading_action = loading_action.clone(); Callback::from(move |_: MouseEvent| { if let Some(plan_id) = (*selected_plan).clone() { loading_action.set(Some("changing_plan".to_string())); let billing_api_clone = billing_api.clone(); let show_plan_modal_clone = show_plan_modal.clone(); let loading_action_clone = loading_action.clone(); let plan_id_clone = plan_id.clone(); // Simulate async operation with timeout Timeout::new(1000, move || { let mut api = (*billing_api_clone).clone(); // Change the plan if let Some(plan) = api.available_plans.iter().find(|p| p.id == plan_id_clone) { api.current_subscription.plan = plan.clone(); billing_api_clone.set(api); web_sys::console::log_1(&"Plan changed successfully".into()); } else { web_sys::console::log_1(&"Plan not found".into()); } loading_action_clone.set(None); show_plan_modal_clone.set(false); }).forget(); } }) }; let close_modals = { let show_plan_modal = show_plan_modal.clone(); let show_cancel_modal = show_cancel_modal.clone(); let show_add_payment_modal = show_add_payment_modal.clone(); let selected_plan = selected_plan.clone(); Callback::from(move |_: MouseEvent| { show_plan_modal.set(false); show_cancel_modal.set(false); show_add_payment_modal.set(false); selected_plan.set(None); }) }; // Create tabs content let mut tabs = HashMap::new(); // Organization Setup Tab tabs.insert("Organization Setup".to_string(), html! { }); // Shareholders Tab tabs.insert("Shareholders".to_string(), html! {
{"Shareholder Information"}
{"Name"} {"Ownership %"} {"Shares"} {"Type"} {"Status"}
{"John Doe"}
{"Founder & CEO"}
{"65%"} {"6,500"} {"Ordinary"} {"Active"}
{"Sarah Johnson"}
{"Co-Founder & CTO"}
{"25%"} {"2,500"} {"Ordinary"} {"Active"}
{"Innovation Ventures"}
{"Investment Fund"}
{"10%"} {"1,000"} {"Preferred"} {"Active"}
{"Total Authorized Shares: 10,000 | Issued Shares: 10,000 | Par Value: $1.00"}
}); // Members & Roles Tab tabs.insert("Members & Roles".to_string(), html! { }); // Integrations Tab tabs.insert("Integrations".to_string(), html! { }); // Billing and Payments Tab tabs.insert("Billing and Payments".to_string(), { let current_subscription = &billing_api.current_subscription; let current_plan = ¤t_subscription.plan; html! {
// Subscription Tier Pane
{"Current Plan"}
{¤t_plan.name}

{format!("${:.0}", current_plan.price)}{"/month"}

    {for current_plan.features.iter().map(|feature| html! {
  • {feature}
  • })}
{format!("Status: {}", current_subscription.status)}
// Payments Table Pane
{"Payment History"}
{for billing_api.invoices.iter().map(|invoice| html! { })}
{"Date"} {"Description"} {"Amount"} {"Status"} {"Invoice"}
{&invoice.date} {&invoice.description} {format!("${:.2}", invoice.amount)} {&invoice.status}
// Payment Methods Pane
{"Payment Methods"}
{for billing_api.payment_methods.iter().map(|method| html! {
{&method.last_four}
{&method.expires}
{if method.is_primary { "Primary" } else { "Backup" }}
})}
} }); html! { <> // Plan Selection Modal if *show_plan_modal { } // Cancel Subscription Modal if *show_cancel_modal { } // Add Payment Method Modal if *show_add_payment_modal { } } }