import { Grid } from '@mui/material' import { AxiosError } from 'axios' import { Field, Form, Formik } from 'formik' import _get from 'lodash/get' import _map from 'lodash/map' import React, { FC, useEffect, useState } from 'react' import { getCountries, getProfileData, getStates, register } from '../../api' import { CONFIGS, isBrowser, setLoggedUserData } from '../../utils' import { confirmPasswordValidator, emailValidator, passwordValidator, requiredValidator, } from '../../validators' import { CustomField } from '../common/CustomField' import { PhoneNumberField } from '../common/PhoneNumberField' interface SignUpFormProps { onSignUpSuccess: (res: IProfileData) => void; onGetProfileDataSuccess?: (res: any) => void; onGetProfileDataError?: (e: AxiosError) => void; logo?: string; } export const SignUpForm: FC = ({ onSignUpSuccess, onGetProfileDataSuccess = () => {}, onGetProfileDataError = () => {}, logo, }) => { const [error, setError] = useState('') const [isSubmitting, setIsSubmitting] = useState(false) const [countries, setCountries] = useState([]) const [states, setStates] = useState([]) const [phoneValidationIsLoading, setPhoneValidationIsLoading] = useState(false) // Fetch countries on mount useEffect(() => { const fetchCountries = async () => { try { const res = await getCountries() const mappedCountries = _map(res.data, (item: any) => ({ id: item.id, name: item.name, code: item.code, })) setCountries(mappedCountries) } catch (e) { console.error('Error fetching countries:', e) } } fetchCountries() }, []) return ( { setIsSubmitting(true) setError('') try { const formData = new FormData() formData.append('first_name', values.firstName) formData.append('last_name', values.lastName) formData.append('email', values.email) formData.append('password', values.password) formData.append('password_confirmation', values.passwordConfirmation) formData.append('phone', values.phone) formData.append('country', values.country) formData.append('city', values.city) formData.append('state', values.state) formData.append('street_address', values.streetAddress) formData.append('zip', values.zip) formData.append('client_id', CONFIGS.CLIENT_ID || '') formData.append('client_secret', CONFIGS.CLIENT_SECRET || '') await register(formData) // Fetch profile data after successful signup try { const profileResponse = await getProfileData() onGetProfileDataSuccess(profileResponse.data) const profileSpecifiedData = profileResponse.data const profileDataObj = setLoggedUserData(profileSpecifiedData) if (isBrowser) { window.localStorage.setItem('user_data', JSON.stringify(profileDataObj)) const event = new window.CustomEvent('tf-login') window.document.dispatchEvent(event) } onSignUpSuccess(_get(profileResponse, 'data.data', {}) as IProfileData) } catch (e) { if ((e as any).isAxiosError) { onGetProfileDataError(e as AxiosError) } setError('Registration successful but failed to fetch profile data') } } catch (e) { const errorData = _get(e, 'response.data.message', '') // Check if error is an object with field-specific errors if (typeof errorData === 'object' && errorData !== null) { const errorMessages = Object.entries(errorData) .map(([field, messages]) => { const fieldName = field.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()) const messageArray = Array.isArray(messages) ? messages : [messages] return `${fieldName}: ${messageArray.join(', ')}` }) .join('\n') setError(errorMessages || 'Registration failed. Please try again.') } else { setError(String(errorData) || 'Registration failed. Please try again.') } } finally { setIsSubmitting(false) } }} > {props => (
logo
{error && (
{error}
)} {/* Name Fields */} {/* Email */} { const required = requiredValidator(value) if (required) return required return emailValidator(value) }} /> {/* Street Address */} {/* Zip Code */} {/* Country */} ({ value: item.id, label: item.name, }))} onChange={(e: React.ChangeEvent) => { props.setFieldValue('country', e.target.value) props.setFieldValue('state', '') // Fetch states for selected country const fetchStatesForCountry = async () => { try { const res = await getStates(e.target.value) const mappedStates = _map(res.data, (item, key) => ({ label: item, value: key, })) setStates(mappedStates) } catch (error) { console.error('Error fetching states:', error) setStates([]) } } fetchStatesForCountry() }} /> {/* State */} {/* City */} {/* Phone */} {/* Password */} {/* Confirm Password */} confirmPasswordValidator(value, props.values.password)} />
)}
) }