/* * File: SignUpScreen.tsx * Description: Multi-step signup screen with validation and Redux integration * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */ import React, { useEffect, useState } from 'react'; import { View, StyleSheet, StatusBar, Alert, Text, TouchableOpacity, ScrollView, KeyboardAvoidingView, Platform } from 'react-native'; import { theme } from '../../../theme/theme'; import { useAppDispatch, useAppSelector } from '../../../store/hooks'; import Icon from 'react-native-vector-icons/Feather'; // Import signup step components import EmailStep from '../components/signup/EmailStep'; import PasswordStep from '../components/signup/PasswordStep'; import NameStep from '../components/signup/NameStep'; import DocumentUploadStep from '../components/signup/DocumentUploadStep'; import HospitalSelectionStep from '../components/signup/HospitalSelectionStep'; import EmailAlreadyRegisteredModal from '../components/signup/EmailAlreadyRegisteredModal'; // Import API service // Import hospital Redux functionality import { fetchHospitals } from '../redux/hospitalSlice'; import { selectHospitalLoading, selectHospitals } from '../redux/hospitalSelectors'; // Import types import { SignUpData, SignUpStep } from '../types/signup'; import { authAPI } from '../services/authAPI'; import { showError, showSuccess } from '../../../shared/utils/toast'; // ============================================================================ // INTERFACES // ============================================================================ interface SignUpScreenProps { navigation: any; } // ============================================================================ // SIGNUP SCREEN COMPONENT // ============================================================================ /** * SignUpScreen Component * * Purpose: Multi-step signup flow with validation and Redux integration * * Features: * - Step-by-step signup process (email → password → name → document → hospital) * - Real-time validation with visual feedback * - Email and username availability checks * - Hospital selection with search * - Document upload with preview * - Progress tracking with visual progress bar * - Modern UI with icons and proper typography * - Keyboard-aware layout for better UX * - Redux state management * - Loading states and error handling */ const SignUpScreen: React.FC = ({ navigation }) => { // ============================================================================ // STATE MANAGEMENT // ============================================================================ const [currentStep, setCurrentStep] = useState('email'); const [showEmailRegisteredModal, setShowEmailRegisteredModal] = useState(false); const [isLoading, setIsLoading] = useState(false); const [signUpData, setSignUpData] = useState>({ email: '', password: '', first_name: '', last_name: '', username: '', id_photo_url: null, hospital_id: '', }); const dispatch = useAppDispatch(); // ============================================================================ // REDUX STATE // ============================================================================ const hospitals = useAppSelector(selectHospitals); const hospitalLoading = useAppSelector(selectHospitalLoading); // ============================================================================ // STEP CONFIGURATION // ============================================================================ const steps: SignUpStep[] = ['email', 'password', 'name', 'document', 'hospital']; const currentStepIndex = steps.indexOf(currentStep); // ============================================================================ // EFFECTS // ============================================================================ useEffect(() => { // Fetch hospitals on component mount dispatch(fetchHospitals()); }, [dispatch]); // ============================================================================ // STEP HANDLERS // ============================================================================ /** * Handle Email Step Continue * * Purpose: Validate email and proceed to next step */ const handleEmailContinue = async (email: string) => { setIsLoading(true); try { const response :any = await authAPI.validatemail({email}); console.log('response', response); if(response.status==409&&response.data.message){ // Show modal instead of toast for already registered email setShowEmailRegisteredModal(true) } if(response.status==200&&response.data.message){ setSignUpData(prev => ({ ...prev, email })); setCurrentStep('password'); } } catch (error) { Alert.alert('Error', 'Failed to validate email. Please try again.'); } finally { setIsLoading(false); } }; /** * Handle Password Step Continue * * Purpose: Validate password and proceed to next step */ const handlePasswordContinue = (password: string) => { setSignUpData(prev => ({ ...prev, password })); setCurrentStep('name'); }; /** * Handle Name Step Continue * * Purpose: Validate name and username, then proceed to next step */ const handleNameContinue = async (firstName: string, lastName: string, username: string) => { setIsLoading(true); try { const response:any = await authAPI.validateusername(username); console.log('response', response); if(response.status==409&&response.data.message){ showError(response.data.message); } if(response.status==200&&response.data.message){ setSignUpData(prev => ({ ...prev, first_name: firstName, last_name: lastName, username: username })); setCurrentStep('document'); } } catch (error) { Alert.alert('Error', 'Failed to validate username. Please try again.'); } finally { setIsLoading(false); } }; /** * Handle Document Upload Step Continue * * Purpose: Save document and proceed to next step */ const handleDocumentContinue = (documentUri: string) => { setSignUpData(prev => ({ ...prev, id_photo_url: documentUri })); setCurrentStep('hospital'); }; /** * Handle Hospital Selection Step Continue * * Purpose: Complete signup process */ const handleHospitalContinue = async (hospitalId: string) => { const finalData: SignUpData = { ...signUpData, hospital_id: hospitalId, } as SignUpData; setSignUpData(finalData); // Call completion handler await onSignUpComplete(finalData); }; /** * Complete Signup Process * * Purpose: Submit final signup data to API */ const onSignUpComplete = async (payload: SignUpData) => { console.log('final payload', payload); setIsLoading(true); try { const formData = new FormData(); let role = 'er_physician'; formData.append('email', payload.email); formData.append('password', payload.password); formData.append('first_name', payload.first_name); formData.append('last_name', payload.last_name); formData.append('username', payload.username); formData.append('dashboard_role', role); formData.append('hospital_id', payload.hospital_id); // Attach file if exists if (payload.id_photo_url) { const filePath = payload.id_photo_url; const file = { uri: filePath, name: 'id_photo', type: 'image/jpg', }; formData.append('id_photo_url', file as any); } console.log('payload prepared', formData); const response :any = await authAPI.signup(formData); console.log('signup response', response); if(response.ok && response.data && response.data.success ) { //@ts-ignore showSuccess('Sign Up Successfully') navigation.navigate('Login'); // dispatch(setHospitals(response.data.data)) } else { showError('error while signup'); if( response.data && response.data.message ) { //@ts-ignore showError(response.data.message) } } } catch (error: any) { console.log('error', error); Alert.alert('Error', 'Failed to create account. Please try again.'); } finally { setIsLoading(false); } }; // ============================================================================ // NAVIGATION HANDLERS // ============================================================================ /** * Handle Back Navigation * * Purpose: Navigate to previous step or go back to previous screen */ const handleBack = () => { if (currentStepIndex > 0) { const previousStep = steps[currentStepIndex - 1]; setCurrentStep(previousStep); } else { navigation.goBack(); } }; /** * Handle Modal Close * * Purpose: Close email already registered modal */ const handleCloseModal = () => { setShowEmailRegisteredModal(false); }; /** * Handle Go To Login * * Purpose: Navigate to login screen */ const handleGoToLogin = () => { setShowEmailRegisteredModal(false); navigation.navigate('Login'); }; // ============================================================================ // RENDER FUNCTIONS // ============================================================================ /** * Render Current Step * * Purpose: Render the appropriate step component based on current step */ const renderCurrentStep = () => { console.log('signupdate', signUpData); const commonProps = { onBack: handleBack, data: signUpData, isLoading, }; switch (currentStep) { case 'email': return ( ); case 'password': return ( ); case 'name': return ( ); case 'document': return ( ); case 'hospital': return ( ); default: return ( ); } }; // ============================================================================ // RENDER // ============================================================================ return ( {/* Conditional Content Rendering */} {currentStep === 'hospital' ? ( // For hospital step, render without ScrollView to avoid conflicts {renderCurrentStep()} ) : ( // For other steps, use ScrollView for proper scrolling {renderCurrentStep()} )} {/* Progress Bar - Bottom */} {Math.round(((currentStepIndex + 1) / steps.length) * 100)}% Complete ); }; // ============================================================================ // STYLES // ============================================================================ const styles = StyleSheet.create({ // Main container container: { flex: 1, backgroundColor: theme.colors.background, }, // Progress container progressContainer: { paddingHorizontal: theme.spacing.lg, paddingVertical: theme.spacing.md, backgroundColor: theme.colors.background, borderTopWidth: 1, borderTopColor: theme.colors.border, }, // Progress bar progressBar: { height: 4, backgroundColor: theme.colors.border, borderRadius: theme.borderRadius.round, marginBottom: theme.spacing.sm, overflow: 'hidden', }, // Progress fill progressFill: { height: '100%', backgroundColor: theme.colors.primary, borderRadius: theme.borderRadius.round, }, // Progress text progressText: { fontSize: theme.typography.fontSize.bodySmall, fontFamily: theme.typography.fontFamily.medium, color: theme.colors.textSecondary, textAlign: 'center', }, // Content area content: { flex: 1, }, // Content container contentContainer: { flexGrow: 1, padding: theme.spacing.lg, paddingBottom: theme.spacing.xl, }, }); export default SignUpScreen; /* * End of File: SignUpScreen.tsx * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */