feat: integrate login, registration steps and splash screen changes

This commit is contained in:
Abin Toppo
2026-05-19 11:23:16 +05:30
parent 66461370a2
commit 32049d90bd
9 changed files with 372 additions and 44 deletions
+89 -8
View File
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import { View, Text, StyleSheet, KeyboardAvoidingView, Platform, ScrollView, TouchableOpacity, Dimensions, StatusBar, TextInput, Image } from 'react-native';
import { Formik } from 'formik';
import * as Yup from 'yup';
@@ -15,9 +15,11 @@ import { setToken } from '../../Redux/Slices/Token';
import NavigationString from '../../Constant/NavigationString';
import ImagePath from '../../Constant/ImagePath';
import { TENDER_LOGIN, LOG_IN_URL } from '../../Services/ApiCall/ApiUrls';
import { showErrorAlert } from '../../Constant/ShowDailog';
import { showErrorAlert, showToast } from '../../Constant/ShowDailog';
import AppBackground from '../../components/AppBackground';
import FontsFamily from '../../Constant/FontsFamily';
import { useRagistrationState } from '../../Services/ApiCall/Hooks';
import AsyncStorage from '@react-native-async-storage/async-storage';
const { width, height } = Dimensions.get('window');
@@ -35,6 +37,7 @@ const Login = () => {
const [passwordVisible, setPasswordVisible] = useState(false);
const [activeType, setActiveType] = useState<'tender' | 'auction'>('tender');
const [showForm, setShowForm] = useState(false);
const { mutateAsync: registrationStateMutate } = useRagistrationState();
// Animation Shared Values for Reveal
const formOpacity = useSharedValue(0);
@@ -121,17 +124,95 @@ const Login = () => {
onSuccess: (res) => handleSuccess(res, 'auction'),
onError: (err) => showErrorAlert(err.message || 'Login failed')
});
const routeByOrgType = useCallback((params: { otherId: any; orgType: any }) => {
const orgType = String(params.orgType ?? '');
if (orgType === '4' || orgType === '5' || orgType === '6') {
navigation.replace(NavigationString.StageThreeScreen, params);
return;
}
const handleSuccess = (res: any, type: string) => {
if (res.statusCode === 200) {
console.log("Response login : ", res)
dispatch(setToken({ ...res.data, token: res.token, userType: type }));
navigation.dispatch(
CommonActions.reset({
if (orgType === '7') {
navigation.replace(NavigationString.Partnership, params);
return;
}
navigation.replace('Dashboard');
}, [navigation]);
const handleGetData = useCallback(async () => {
try {
const res = await registrationStateMutate();
console.log("splash", res);
if (res?.status === false) {
navigation.reset({
index: 0,
routes: [{ name: NavigationString.Login }],
});
return;
}
if (res?.data?.message === 'No Response From Server' && res?.data?.success === false) {
navigation.reset({
index: 0,
routes: [{ name: NavigationString.Login }],
});
return;
}
if (res?.statusCode === 404 || res?.statusCode === 401) {
navigation.replace('Registration');
return;
}
if (res?.statusCode === 200 && res?.data) {
const { registrationStatus, contOtherId, contOrganization } = res.data;
const params = { otherId: contOtherId, orgType: contOrganization };
switch (registrationStatus) {
case null:
case undefined:
navigation.replace(NavigationString.Registration);
break;
case 'Pending':
routeByOrgType(params);
break;
case 'Complete':
case 'Completed':
navigation.replace(NavigationString.Home);
break;
default:
navigation.replace(NavigationString.Login);
break;
}
return;
}
console.error('API error:', res);
showToast(res?.message || 'Something went wrong');
navigation.replace('Registration');
} catch (error: any) {
console.error('Registration status error:', error);
showToast(error?.message || 'Something went wrong');
if (error?.response?.status === 404) {
navigation.replace('Registration');
} else {
await AsyncStorage.removeItem('persist:root');
navigation.replace(NavigationString.Login);
}
}
}, [navigation, registrationStateMutate, routeByOrgType]);
const handleSuccess = (res: any, type: string) => {
dispatch(setToken({ ...res.data, token: res.token, userType: type }));
if (res.statusCode === 200) {
if (type === 'tender') {
handleGetData()
} else {
console.log("Response login : ", res, type)
navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [{ name: NavigationString.Home }],
}),
);
}
} else {
showErrorAlert(res.message);
}
+9 -4
View File
@@ -21,6 +21,7 @@ import { useSelector } from 'react-redux';
import Animated, { FadeInUp, FadeInDown } from 'react-native-reanimated';
import { useTheme } from '../../Hooks/useTheme';
import AppText from '../../components/AppText';
import NavigationString from '../../Constant/NavigationString';
type RouteParams = {
userData?: {
@@ -310,27 +311,31 @@ const Registration: React.FC = () => {
fileData.append('regfile', documents.registrationCertificate as any);
const res = await contractorStageTwoSubmit(fileData);
console.log('Stage Two Res : ', res)
if (res.statusCode === 200) {
if (res) {
showToast('Form submitted successfully!');
const orgType = selectedOrg;
const params = { otherId: res?.data?.contOtherId, orgType: orgType };
console.log("params : ", params)
if ([4, 5, 6].includes(orgType)) {
navigation.replace('StageThree' as never, params as never);
navigation.replace(NavigationString.StageThreeScreen as never, params as never);
} else if (orgType === 7) {
navigation.replace('PartnerShip' as never, { otherId: res?.data?.contOtherId } as never);
navigation.replace(NavigationString.Partnership as never, { otherId: res?.data?.contOtherId } as never);
} else {
navigation.replace('Dashboard' as never);
navigation.replace(NavigationString.Home as never);
}
} else {
showToast('Form submission failed');
}
} else {
showToast(res.message || 'Form submission failed. Please try again.');
}
} catch (error: any) {
console.log("Error in form submission")
if (axios.isAxiosError(error)) {
} else {
console.error('Unexpected error', error);
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { View } from 'react-native';
import { View, TouchableOpacity } from 'react-native';
import DatePicker from 'react-native-date-picker';
import MyInput from '../../../components/MyInput';
import MyDropdown from '../../../Component/Dropdown/MyDropdown';
@@ -50,7 +50,10 @@ const StageOne: React.FC<Props> = ({
const handleDateConfirm = (selectedDate: Date) => {
setOpen(false);
setDate(selectedDate);
handleChange('expiryDate', selectedDate.toISOString().split('T')[0]);
const day = String(selectedDate.getDate()).padStart(2, '0');
const month = String(selectedDate.getMonth() + 1).padStart(2, '0');
const year = selectedDate.getFullYear();
handleChange('expiryDate', `${day}/${month}/${year}`);
};
return (
@@ -140,17 +143,20 @@ const StageOne: React.FC<Props> = ({
{selectedAllMSME !== 3 && selectedOrg !== 8 && (
<>
<MyInput
label="Expiry Date"
placeholder="Select Expiry Date"
value={formData.expiryDate}
onChangeText={text => handleChange('expiryDate', text)}
onFocus={() => setFocusedField('expiryDate')}
onBlur={() => setFocusedField(null)}
focused={focusedField === 'expiryDate'}
editable={true}
rightIconPress={() => setOpen(true)}
/>
<TouchableOpacity onPress={() => setOpen(true)} activeOpacity={0.8}>
<View pointerEvents="none">
<MyInput
label="Expiry Date"
placeholder="Select Expiry Date"
value={formData.expiryDate}
onChangeText={text => handleChange('expiryDate', text)}
onFocus={() => setFocusedField('expiryDate')}
onBlur={() => setFocusedField(null)}
focused={open || focusedField === 'expiryDate'}
editable={false}
/>
</View>
</TouchableOpacity>
<DatePicker
modal
open={open}
@@ -1,4 +1,5 @@
import React from 'react';
import React, { useState } from 'react';
import DatePicker from 'react-native-date-picker';
import {
TouchableOpacity,
ActivityIndicator,
@@ -64,6 +65,18 @@ const StageTwo: React.FC<Props> = ({
selectedOrg,
}) => {
const { colors, spacing, shadows } = useTheme();
const [open, setOpen] = useState(false);
const [date, setDate] = useState(new Date());
const handleDateConfirm = (selectedDate: Date) => {
setOpen(false);
setDate(selectedDate);
const day = String(selectedDate.getDate()).padStart(2, '0');
const month = String(selectedDate.getMonth() + 1).padStart(2, '0');
const year = selectedDate.getFullYear();
setPanVerified(false);
handleChange('dateOfIncorp', `${day}/${month}/${year}`);
};
const verifyButtonStyle = {
backgroundColor: colors.primary,
@@ -101,22 +114,38 @@ const StageTwo: React.FC<Props> = ({
containerStyle={{ marginBottom: spacing.s }}
/>
<MyInput
label={selectedOrg == 8 ? "Date of Birth" : "Date of Incorporation"}
placeholder="DD/MM/YYYY"
value={formData.dateOfIncorp}
onChangeText={(text) => {
const formatted = formatDateInput(text);
setPanVerified(false);
handleChange('dateOfIncorp', formatted);
}}
isVerify={panVerified}
onFocus={() => setFocusedField('dob')}
onBlur={() => setFocusedField(null)}
focused={focusedField === 'dob'}
editable={!panVerified}
keyboardType="numeric"
containerStyle={{ marginBottom: spacing.s }}
<TouchableOpacity
onPress={() => !panVerified && setOpen(true)}
activeOpacity={0.8}
disabled={panVerified}
>
<View pointerEvents="none">
<MyInput
label={selectedOrg == 8 ? "Date of Birth" : "Date of Incorporation"}
placeholder="DD/MM/YYYY"
value={formData.dateOfIncorp}
onChangeText={(text) => {
const formatted = formatDateInput(text);
setPanVerified(false);
handleChange('dateOfIncorp', formatted);
}}
isVerify={panVerified}
onFocus={() => setFocusedField('dob')}
onBlur={() => setFocusedField(null)}
focused={open || focusedField === 'dob'}
editable={false}
keyboardType="numeric"
containerStyle={{ marginBottom: spacing.s }}
/>
</View>
</TouchableOpacity>
<DatePicker
modal
open={open}
date={date}
onConfirm={handleDateConfirm}
onCancel={() => setOpen(false)}
mode="date"
/>
<MyInput
+2
View File
@@ -111,6 +111,7 @@ const Signup = () => {
registerContractor(formData, {
onSuccess: (res: any) => {
console.log('Register Res : ', res)
if (res?.status === '201') {
ToastAndroid.show(`${res.message}`, ToastAndroid.SHORT);
navigation.pop();
@@ -119,6 +120,7 @@ const Signup = () => {
}
},
onError: (error: any) => {
console.log('Register Res : ', error)
ToastAndroid.show(error.message, ToastAndroid.SHORT);
},
});
+1 -1
View File
@@ -82,7 +82,7 @@ const Splash: React.FC = () => {
navigation.replace(NavigationString.Home);
break;
default:
navigation.replace(NavigationString.Registration);
navigation.replace(NavigationString.Login);
break;
}
return;