refactor wip
This commit is contained in:
parent
c1ea9483d7
commit
6f8fb27221
@ -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 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>
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user