10 KiB
10 KiB
Resident Registration Refactoring Implementation Plan
Overview
This document outlines the detailed implementation plan for refactoring the resident registration components into reusable generic components.
Phase 1: Generic Components Implementation
Directory Structure
portal/src/components/
├── common/ # New generic components
│ ├── forms/
│ │ ├── multi_step_form.rs
│ │ ├── step_validator.rs
│ │ ├── validation_result.rs
│ │ └── mod.rs
│ ├── payments/
│ │ ├── stripe_provider.rs
│ │ ├── stripe_payment_form.rs
│ │ ├── payment_intent.rs
│ │ └── mod.rs
│ ├── ui/
│ │ ├── progress_indicator.rs
│ │ ├── validation_toast.rs
│ │ ├── loading_spinner.rs
│ │ └── mod.rs
│ └── mod.rs
├── resident_registration/ # Existing (to be refactored)
│ ├── simple_resident_wizard.rs
│ ├── step_payment_stripe.rs
│ ├── simple_step_info.rs
│ ├── residence_card.rs
│ └── mod.rs
└── mod.rs
Component Specifications
1. MultiStepForm (common/forms/multi_step_form.rs
)
Core Traits
pub trait FormStep<T: Clone + PartialEq> {
fn render(&self, ctx: &Context<MultiStepForm<T>>, data: &T) -> Html;
fn get_title(&self) -> &'static str;
fn get_description(&self) -> &'static str;
fn get_icon(&self) -> &'static str;
}
pub trait StepValidator<T> {
fn validate(&self, data: &T) -> ValidationResult;
}
MultiStepForm Component
#[derive(Properties, PartialEq)]
pub struct MultiStepFormProps<T: Clone + PartialEq + 'static> {
pub form_data: T,
pub on_form_change: Callback<T>,
pub on_complete: Callback<T>,
pub on_cancel: Option<Callback<()>>,
pub steps: Vec<Box<dyn FormStep<T>>>,
pub validators: HashMap<usize, Box<dyn StepValidator<T>>>,
pub show_progress: bool,
pub allow_skip_validation: bool,
}
pub enum MultiStepFormMsg<T> {
NextStep,
PrevStep,
GoToStep(usize),
UpdateFormData(T),
Complete,
Cancel,
HideValidationToast,
}
pub struct MultiStepForm<T: Clone + PartialEq> {
current_step: usize,
form_data: T,
validation_errors: Vec<String>,
show_validation_toast: bool,
processing: bool,
}
Key Features
- Generic over form data type
T
- Dynamic step registration via props
- Validation per step
- Progress indicator
- Navigation controls
- Error handling and display
2. StripeProvider (common/payments/stripe_provider.rs
)
Core Traits
pub trait PaymentIntentCreator {
type FormData;
fn create_payment_intent(&self, data: &Self::FormData) -> Result<PaymentIntentRequest, String>;
fn get_amount(&self, data: &Self::FormData) -> f64;
fn get_description(&self, data: &Self::FormData) -> String;
fn get_metadata(&self, data: &Self::FormData) -> HashMap<String, String>;
}
StripeProvider Component
#[derive(Properties, PartialEq)]
pub struct StripeProviderProps<T: Clone + PartialEq + 'static> {
pub form_data: T,
pub payment_creator: Box<dyn PaymentIntentCreator<FormData = T>>,
pub on_payment_complete: Callback<T>,
pub on_payment_error: Callback<String>,
pub endpoint_url: String,
pub auto_create_intent: bool,
}
pub enum StripeProviderMsg {
CreatePaymentIntent,
PaymentIntentCreated(String),
PaymentIntentError(String),
ProcessPayment,
PaymentComplete,
PaymentError(String),
}
pub struct StripeProvider<T: Clone + PartialEq> {
client_secret: Option<String>,
processing_payment: bool,
processing_intent: bool,
error: Option<String>,
}
3. StripePaymentForm (common/payments/stripe_payment_form.rs
)
Component Structure
#[derive(Properties, PartialEq)]
pub struct StripePaymentFormProps {
pub client_secret: Option<String>,
pub amount: f64,
pub currency: String,
pub description: String,
pub processing: bool,
pub on_payment_complete: Callback<()>,
pub on_payment_error: Callback<String>,
pub show_amount: bool,
pub custom_button_text: Option<String>,
}
pub struct StripePaymentForm {
elements_initialized: bool,
payment_error: Option<String>,
}
Key Features
- Stripe Elements integration
- Customizable payment button
- Amount display
- Error handling
- Loading states
4. UI Components
ProgressIndicator (common/ui/progress_indicator.rs
)
#[derive(Properties, PartialEq)]
pub struct ProgressIndicatorProps {
pub current_step: usize,
pub total_steps: usize,
pub step_titles: Vec<String>,
pub completed_steps: Vec<usize>,
pub show_step_numbers: bool,
pub show_step_titles: bool,
pub variant: ProgressVariant,
}
#[derive(Clone, PartialEq)]
pub enum ProgressVariant {
Dots,
Line,
Steps,
}
ValidationToast (common/ui/validation_toast.rs
)
#[derive(Properties, PartialEq)]
pub struct ValidationToastProps {
pub errors: Vec<String>,
pub show: bool,
pub on_close: Callback<()>,
pub auto_hide_duration: Option<u32>,
pub toast_type: ToastType,
}
#[derive(Clone, PartialEq)]
pub enum ToastType {
Error,
Warning,
Info,
Success,
}
Implementation Steps
Step 1: Create Base Structure
- Create
portal/src/components/common/
directory - Create module files (
mod.rs
) for each subdirectory - Update main components
mod.rs
to include common module
Step 2: Implement Core Traits and Types
- Create
validation_result.rs
withValidationResult
type - Create
payment_intent.rs
with payment-related types - Implement base traits in respective modules
Step 3: Implement MultiStepForm
- Create the generic
MultiStepForm
component - Implement step navigation logic
- Add validation integration
- Create progress indicator integration
Step 4: Implement Stripe Components
- Create
StripeProvider
for payment intent management - Create
StripePaymentForm
for payment processing - Integrate with existing JavaScript Stripe functions
- Add error handling and loading states
Step 5: Implement UI Components
- Create
ProgressIndicator
component - Create
ValidationToast
component - Create
LoadingSpinner
component - Style components to match existing design
Step 6: Integration Testing
- Create example usage in a test component
- Verify all components work independently
- Test component composition
- Ensure TypeScript/JavaScript integration works
Phase 2: Refactor Resident Registration
Step 1: Create Specific Implementations
- Create
ResidentFormStep
implementations - Create
ResidentStepValidator
implementations - Create
ResidentPaymentIntentCreator
implementation
Step 2: Replace Existing Components
- Replace
SimpleResidentWizard
withMultiStepForm
+ specific steps - Replace
StepPaymentStripe
withStripeProvider
+StripePaymentForm
- Update
SimpleStepInfo
to work with new architecture - Keep
ResidenceCard
as-is (already reusable)
Step 3: Update Integration
- Update parent components to use new architecture
- Ensure all callbacks and data flow work correctly
- Test complete registration flow
- Verify Stripe integration still works
Step 4: Cleanup
- Remove old components once new ones are proven
- Update imports throughout the codebase
- Update documentation
Testing Strategy
Unit Testing
- Test each generic component independently
- Test trait implementations
- Test validation logic
- Test payment intent creation
Integration Testing
- Test complete form flow
- Test payment processing
- Test error scenarios
- Test navigation and validation
Functionality Preservation
- Ensure all existing features work exactly the same
- Test edge cases and error conditions
- Verify UI/UX remains consistent
- Test browser compatibility
Success Criteria
Generic Components
- ✅ Components are truly reusable across different form types
- ✅ Type-safe implementation with proper Rust patterns
- ✅ Clean separation of concerns
- ✅ Easy to test and maintain
- ✅ Well-documented with examples
Resident Registration
- ✅ All existing functionality preserved
- ✅ Same user experience
- ✅ Same validation behavior
- ✅ Same payment flow
- ✅ Same error handling
Code Quality
- ✅ Reduced code duplication
- ✅ Better separation of concerns
- ✅ More maintainable architecture
- ✅ Easier to add new form types
- ✅ Easier to modify payment logic
Future Extensibility
Additional Form Types
The generic components should easily support:
- Company registration forms
- Service subscription forms
- Profile update forms
- Settings forms
Additional Payment Providers
The payment architecture should allow:
- PayPal integration
- Cryptocurrency payments
- Bank transfer payments
- Multiple payment methods per form
Additional UI Variants
The UI components should support:
- Different themes
- Mobile-optimized layouts
- Accessibility features
- Internationalization
Risk Mitigation
Breaking Changes
- Keep old components until new ones are fully tested
- Implement feature flags for gradual rollout
- Maintain backward compatibility during transition
Performance
- Ensure generic components don't add significant overhead
- Optimize re-renders with proper memoization
- Test with large forms and complex validation
Complexity
- Start with minimal viable implementation
- Add features incrementally
- Document usage patterns clearly
- Provide migration guides
Next Steps
- Review and Approve Plan - Get stakeholder approval for this approach
- Switch to Code Mode - Begin implementation of generic components
- Iterative Development - Implement and test each component separately
- Integration Testing - Test components together before refactoring existing code
- Gradual Migration - Replace existing components one at a time
- Documentation - Create usage examples and migration guides
This plan ensures a systematic approach to creating reusable components while preserving all existing functionality.