refactor wip
This commit is contained in:
		| @@ -2,8 +2,10 @@ pub mod step_payment_stripe; | ||||
| pub mod simple_resident_wizard; | ||||
| pub mod simple_step_info; | ||||
| pub mod residence_card; | ||||
| pub mod refactored_resident_wizard; | ||||
|  | ||||
| pub use step_payment_stripe::*; | ||||
| pub use simple_resident_wizard::*; | ||||
| pub use simple_step_info::*; | ||||
| pub use residence_card::*; | ||||
| pub use residence_card::*; | ||||
| pub use refactored_resident_wizard::*; | ||||
| @@ -0,0 +1,294 @@ | ||||
| use yew::prelude::*; | ||||
| use crate::models::company::{DigitalResidentFormData, DigitalResident}; | ||||
| use crate::services::ResidentService; | ||||
| use crate::components::common::ui::progress_indicator::{ProgressIndicator, ProgressVariant, ProgressColor, ProgressSize}; | ||||
| use crate::components::common::ui::loading_spinner::LoadingSpinner; | ||||
| use super::{SimpleStepInfo, StepPaymentStripe, ResidenceCard}; | ||||
| use web_sys::console; | ||||
|  | ||||
| #[derive(Properties, PartialEq)] | ||||
| pub struct RefactoredResidentWizardProps { | ||||
|     pub on_registration_complete: Callback<DigitalResident>, | ||||
|     pub on_back_to_parent: Callback<()>, | ||||
|     #[prop_or_default] | ||||
|     pub success_resident_id: Option<u32>, | ||||
|     #[prop_or_default] | ||||
|     pub show_failure: bool, | ||||
| } | ||||
|  | ||||
| pub enum RefactoredResidentWizardMsg { | ||||
|     NextStep, | ||||
|     PrevStep, | ||||
|     UpdateFormData(DigitalResidentFormData), | ||||
|     RegistrationComplete(DigitalResident), | ||||
|     RegistrationError(String), | ||||
| } | ||||
|  | ||||
| pub struct RefactoredResidentWizard { | ||||
|     current_step: usize, | ||||
|     form_data: DigitalResidentFormData, | ||||
|     validation_errors: Vec<String>, | ||||
| } | ||||
|  | ||||
| impl Component for RefactoredResidentWizard { | ||||
|     type Message = RefactoredResidentWizardMsg; | ||||
|     type Properties = RefactoredResidentWizardProps; | ||||
|  | ||||
|     fn create(ctx: &Context<Self>) -> Self { | ||||
|         let current_step = if ctx.props().success_resident_id.is_some() { | ||||
|             2 // Success step | ||||
|         } else if ctx.props().show_failure { | ||||
|             1 // Payment step | ||||
|         } else { | ||||
|             0 // Start from beginning | ||||
|         }; | ||||
|  | ||||
|         Self { | ||||
|             current_step, | ||||
|             form_data: DigitalResidentFormData::default(), | ||||
|             validation_errors: Vec::new(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool { | ||||
|         match msg { | ||||
|             RefactoredResidentWizardMsg::NextStep => { | ||||
|                 // Simple validation for demo | ||||
|                 if self.current_step == 0 { | ||||
|                     if self.form_data.full_name.trim().is_empty() || self.form_data.email.trim().is_empty() { | ||||
|                         self.validation_errors = vec!["Please fill in all required fields".to_string()]; | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|                  | ||||
|                 self.validation_errors.clear(); | ||||
|                 if self.current_step < 2 { | ||||
|                     self.current_step += 1; | ||||
|                 } | ||||
|                 true | ||||
|             } | ||||
|             RefactoredResidentWizardMsg::PrevStep => { | ||||
|                 if self.current_step > 0 { | ||||
|                     self.current_step -= 1; | ||||
|                 } | ||||
|                 true | ||||
|             } | ||||
|             RefactoredResidentWizardMsg::UpdateFormData(new_data) => { | ||||
|                 self.form_data = new_data; | ||||
|                 true | ||||
|             } | ||||
|             RefactoredResidentWizardMsg::RegistrationComplete(resident) => { | ||||
|                 self.current_step = 2; // Move to success step | ||||
|                 ctx.props().on_registration_complete.emit(resident); | ||||
|                 true | ||||
|             } | ||||
|             RefactoredResidentWizardMsg::RegistrationError(error) => { | ||||
|                 self.validation_errors = vec![error]; | ||||
|                 true | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn view(&self, ctx: &Context<Self>) -> Html { | ||||
|         let link = ctx.link(); | ||||
|  | ||||
|         html! { | ||||
|             <div class="h-100 d-flex flex-column"> | ||||
|                 {if self.current_step < 2 { | ||||
|                     html! { | ||||
|                         <> | ||||
|                             // Progress indicator using our generic component | ||||
|                             <ProgressIndicator | ||||
|                                 current_step={self.current_step} | ||||
|                                 total_steps={2} | ||||
|                                 variant={ProgressVariant::Dots} | ||||
|                                 color={ProgressColor::Primary} | ||||
|                                 size={ProgressSize::Medium} | ||||
|                                 show_step_numbers={true} | ||||
|                             /> | ||||
|                              | ||||
|                             // Step content | ||||
|                             <div class="flex-grow-1"> | ||||
|                                 {self.render_current_step(ctx)} | ||||
|                             </div> | ||||
|                              | ||||
|                             // Navigation footer | ||||
|                             {if self.current_step < 2 { | ||||
|                                 self.render_navigation_footer(ctx) | ||||
|                             } else { | ||||
|                                 html! {} | ||||
|                             }} | ||||
|                              | ||||
|                             // Validation errors | ||||
|                             {if !self.validation_errors.is_empty() { | ||||
|                                 html! { | ||||
|                                     <div class="alert alert-danger mt-3"> | ||||
|                                         <ul class="mb-0"> | ||||
|                                             {for self.validation_errors.iter().map(|error| { | ||||
|                                                 html! { <li>{error}</li> } | ||||
|                                             })} | ||||
|                                         </ul> | ||||
|                                     </div> | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 html! {} | ||||
|                             }} | ||||
|                         </> | ||||
|                     } | ||||
|                 } else { | ||||
|                     // Success step | ||||
|                     html! { | ||||
|                         <div class="flex-grow-1"> | ||||
|                             {self.render_success_step(ctx)} | ||||
|                         </div> | ||||
|                     } | ||||
|                 }} | ||||
|             </div> | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl RefactoredResidentWizard { | ||||
|     fn render_current_step(&self, ctx: &Context<Self>) -> Html { | ||||
|         let link = ctx.link(); | ||||
|         let on_form_update = link.callback(RefactoredResidentWizardMsg::UpdateFormData); | ||||
|  | ||||
|         match self.current_step { | ||||
|             0 => html! { | ||||
|                 <SimpleStepInfo | ||||
|                     form_data={self.form_data.clone()} | ||||
|                     on_change={on_form_update} | ||||
|                 /> | ||||
|             }, | ||||
|             1 => html! { | ||||
|                 <StepPaymentStripe | ||||
|                     form_data={self.form_data.clone()} | ||||
|                     client_secret={Option::<String>::None} | ||||
|                     processing_payment={false} | ||||
|                     on_process_payment={link.callback(|_| RefactoredResidentWizardMsg::NextStep)} | ||||
|                     on_payment_complete={link.callback(RefactoredResidentWizardMsg::RegistrationComplete)} | ||||
|                     on_payment_error={link.callback(RefactoredResidentWizardMsg::RegistrationError)} | ||||
|                     on_payment_plan_change={link.callback(|_| RefactoredResidentWizardMsg::NextStep)} | ||||
|                     on_confirmation_change={link.callback(|_| RefactoredResidentWizardMsg::NextStep)} | ||||
|                 /> | ||||
|             }, | ||||
|             _ => html! { <div>{"Invalid step"}</div> } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn render_navigation_footer(&self, ctx: &Context<Self>) -> Html { | ||||
|         let link = ctx.link(); | ||||
|  | ||||
|         html! { | ||||
|             <div class="card-footer"> | ||||
|                 <div class="d-flex justify-content-between align-items-center"> | ||||
|                     <div style="width: 120px;"> | ||||
|                         {if self.current_step > 0 { | ||||
|                             html! { | ||||
|                                 <button | ||||
|                                     type="button" | ||||
|                                     class="btn btn-outline-secondary" | ||||
|                                     onclick={link.callback(|_| RefactoredResidentWizardMsg::PrevStep)} | ||||
|                                 > | ||||
|                                     <i class="bi bi-arrow-left me-1"></i>{"Previous"} | ||||
|                                 </button> | ||||
|                             } | ||||
|                         } else { | ||||
|                             html! {} | ||||
|                         }} | ||||
|                     </div> | ||||
|  | ||||
|                     <div style="width: 150px;" class="text-end"> | ||||
|                         {if self.current_step == 0 { | ||||
|                             html! { | ||||
|                                 <button | ||||
|                                     type="button" | ||||
|                                     class="btn btn-success" | ||||
|                                     onclick={link.callback(|_| RefactoredResidentWizardMsg::NextStep)} | ||||
|                                 > | ||||
|                                     {"Next"}<i class="bi bi-arrow-right ms-1"></i> | ||||
|                                 </button> | ||||
|                             } | ||||
|                         } else { | ||||
|                             html! {} | ||||
|                         }} | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn render_success_step(&self, ctx: &Context<Self>) -> Html { | ||||
|         html! { | ||||
|             <div class="text-center py-5"> | ||||
|                 <div class="mb-4"> | ||||
|                     <i class="bi bi-check-circle-fill text-success" style="font-size: 4rem;"></i> | ||||
|                 </div> | ||||
|                  | ||||
|                 <h2 class="text-success mb-3">{"Registration Successful!"}</h2> | ||||
|                 <p class="lead mb-4"> | ||||
|                     {"Your digital resident registration has been successfully submitted and is now pending approval."} | ||||
|                 </p> | ||||
|                  | ||||
|                 <div class="row justify-content-center"> | ||||
|                     <div class="col-md-8"> | ||||
|                         <div class="card border-success"> | ||||
|                             <div class="card-body"> | ||||
|                                 <h5 class="card-title text-success"> | ||||
|                                     <i class="bi bi-info-circle me-2"></i>{"What happens next?"} | ||||
|                                 </h5> | ||||
|                                 <div class="text-start"> | ||||
|                                     <div class="d-flex align-items-start mb-3"> | ||||
|                                         <div class="me-3"> | ||||
|                                             <span class="badge bg-success rounded-pill">{"1"}</span> | ||||
|                                         </div> | ||||
|                                         <div> | ||||
|                                             <strong>{"Identity Verification"}</strong> | ||||
|                                             <p class="mb-0 text-muted">{"Our team will verify your identity and submitted documents."}</p> | ||||
|                                         </div> | ||||
|                                     </div> | ||||
|                                      | ||||
|                                     <div class="d-flex align-items-start mb-3"> | ||||
|                                         <div class="me-3"> | ||||
|                                             <span class="badge bg-primary rounded-pill">{"2"}</span> | ||||
|                                         </div> | ||||
|                                         <div> | ||||
|                                             <strong>{"Background Check"}</strong> | ||||
|                                             <p class="mb-0 text-muted">{"We'll conduct necessary background checks and compliance verification."}</p> | ||||
|                                         </div> | ||||
|                                     </div> | ||||
|                                      | ||||
|                                     <div class="d-flex align-items-start mb-3"> | ||||
|                                         <div class="me-3"> | ||||
|                                             <span class="badge bg-info rounded-pill">{"3"}</span> | ||||
|                                         </div> | ||||
|                                         <div> | ||||
|                                             <strong>{"Approval & Activation"}</strong> | ||||
|                                             <p class="mb-0 text-muted">{"Once approved, your digital resident status will be activated and you'll gain access to selected services."}</p> | ||||
|                                         </div> | ||||
|                                     </div> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                  | ||||
|                 <div class="mt-4"> | ||||
|                     <button | ||||
|                         class="btn btn-success btn-lg" | ||||
|                         onclick={ctx.props().on_back_to_parent.reform(|_| ())} | ||||
|                     > | ||||
|                         <i class="bi bi-list me-2"></i>{"View My Registrations"} | ||||
|                     </button> | ||||
|                 </div> | ||||
|                  | ||||
|                 <div class="mt-4"> | ||||
|                     <div class="alert alert-info"> | ||||
|                         <i class="bi bi-envelope me-2"></i> | ||||
|                         {"You will receive email updates about your registration status. The approval process typically takes 3-5 business days."} | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user