214 lines
5.7 KiB
TypeScript
214 lines
5.7 KiB
TypeScript
import React, { useEffect } from "react";
|
|
import {
|
|
Text,
|
|
View,
|
|
TextInput,
|
|
StyleSheet,
|
|
TouchableOpacity,
|
|
TouchableWithoutFeedback,
|
|
Keyboard,
|
|
KeyboardAvoidingView,
|
|
StatusBar,
|
|
} from "react-native";
|
|
import { useRouter } from "expo-router";
|
|
import { Formik } from "formik";
|
|
import * as Yup from "yup";
|
|
import { sendOTP, clearSendOTPError } from "../../store/authSlice";
|
|
import { useDispatch } from "react-redux";
|
|
import { AppDispatch } from "../../store";
|
|
import { useSelector } from "react-redux";
|
|
import { RootState } from "../../store";
|
|
import { AUTH_STATUSES } from "@/constants/types";
|
|
|
|
// type VerifyOTPNavigationProp = StackNavigationProp<
|
|
// RootStackParamList,
|
|
// "VerifyOTP"
|
|
// >;
|
|
|
|
// import OTPInputView from "@twotalltotems/react-native-otp-input";
|
|
//handleblue => when input field looses focus (mark as touched)
|
|
// handleBlur marks the field as touched, when field looses focus
|
|
export default function WelcomeScreen() {
|
|
const {
|
|
status,
|
|
otpId,
|
|
phone: phoneNumber,
|
|
sendOTPError,
|
|
} = useSelector((state: RootState) => state.auth);
|
|
|
|
const dispatch = useDispatch<AppDispatch>();
|
|
const router = useRouter();
|
|
|
|
const phoneValidationSchema = Yup.object().shape({
|
|
phone: Yup.string()
|
|
.required("Phone number is required")
|
|
.matches(/^\d{10}$/, "Phone number must be exactly 10 digits"),
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (status === AUTH_STATUSES.SUCCESS && otpId) {
|
|
router.push({
|
|
pathname: "/auth/verifyOtp",
|
|
params: { otpId, phoneNumber },
|
|
});
|
|
}
|
|
}, [status, otpId, router]);
|
|
|
|
return (
|
|
<KeyboardAvoidingView style={styles.container} behavior="padding">
|
|
<StatusBar barStyle="dark-content" backgroundColor="#F3F5F8" />
|
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
|
<View style={styles.inner}>
|
|
<Text style={styles.title}>Welcome to Driver Saathi</Text>
|
|
|
|
<Formik
|
|
initialValues={{ phone: "" }}
|
|
onSubmit={(values) => dispatch(sendOTP({ phone: values.phone }))}
|
|
validationSchema={phoneValidationSchema}
|
|
>
|
|
{({
|
|
handleChange,
|
|
handleBlur,
|
|
handleSubmit,
|
|
values,
|
|
errors,
|
|
touched,
|
|
}) => (
|
|
<View style={styles.form}>
|
|
<Text style={styles.label}>Phone Number</Text>
|
|
<TextInput
|
|
style={{
|
|
...styles.input,
|
|
color: values.phone ? "black" : "#949CAC",
|
|
}}
|
|
onChangeText={(text) => {
|
|
handleChange("phone")(text);
|
|
if (sendOTPError) {
|
|
dispatch(clearSendOTPError());
|
|
}
|
|
}}
|
|
onBlur={handleBlur("phone")}
|
|
value={values.phone}
|
|
keyboardType="numeric"
|
|
placeholder="Enter your registered phone number"
|
|
/>
|
|
<View style={styles.errorContainer}>
|
|
{touched.phone && errors.phone && (
|
|
<Text style={styles.error}>{errors.phone}</Text>
|
|
)}
|
|
{sendOTPError && (
|
|
<Text style={styles.error}>{sendOTPError}</Text>
|
|
)}
|
|
</View>
|
|
<TouchableOpacity
|
|
onPress={handleSubmit as unknown as () => void}
|
|
style={{
|
|
...styles.button,
|
|
backgroundColor:
|
|
values.phone.length === 10 &&
|
|
!errors.phone &&
|
|
status !== AUTH_STATUSES.LOADING
|
|
? "#008761"
|
|
: "#B0B7C5",
|
|
}}
|
|
disabled={
|
|
values.phone.length !== 10 ||
|
|
!!errors.phone ||
|
|
status === AUTH_STATUSES.LOADING
|
|
}
|
|
>
|
|
<Text style={styles.buttonText}>Send OTP</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
)}
|
|
</Formik>
|
|
</View>
|
|
</TouchableWithoutFeedback>
|
|
</KeyboardAvoidingView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
errorContainer: {
|
|
flexDirection: "column",
|
|
gap: 8,
|
|
marginTop: 8,
|
|
},
|
|
error: {
|
|
color: "#D51D10",
|
|
fontFamily: "Inter",
|
|
fontSize: 12,
|
|
fontWeight: "bold",
|
|
lineHeight: 20,
|
|
},
|
|
inner: {
|
|
flex: 1,
|
|
justifyContent: "flex-start",
|
|
position: "relative",
|
|
},
|
|
form: {
|
|
height: "90%",
|
|
position: "relative",
|
|
},
|
|
button: {
|
|
height: 48,
|
|
borderRadius: 4,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
marginTop: 20,
|
|
width: "100%",
|
|
position: "absolute",
|
|
bottom: 50,
|
|
},
|
|
buttonText: {
|
|
color: "#FCFCFC",
|
|
fontFamily: "Inter",
|
|
fontSize: 14,
|
|
fontWeight: "bold",
|
|
lineHeight: 20,
|
|
},
|
|
container: {
|
|
flex: 1,
|
|
padding: 16,
|
|
backgroundColor: "#F3F5F8",
|
|
paddingTop: 0,
|
|
},
|
|
title: {
|
|
fontSize: 28,
|
|
fontWeight: "bold",
|
|
marginBottom: 16,
|
|
color: "#1A1C1E",
|
|
fontStyle: "normal",
|
|
lineHeight: 36,
|
|
letterSpacing: -0.56,
|
|
width: "70%",
|
|
},
|
|
label: {
|
|
fontSize: 14,
|
|
marginBottom: 8,
|
|
color: "#717B8C",
|
|
fontFamily: "Inter",
|
|
fontStyle: "normal",
|
|
fontWeight: "bold",
|
|
lineHeight: 20,
|
|
},
|
|
input: {
|
|
borderRadius: 4,
|
|
borderTopColor: "#D8DDE7",
|
|
borderBottomColor: "#D8DDE7",
|
|
borderLeftColor: "#D8DDE7",
|
|
borderRightColor: "#D8DDE7",
|
|
height: 40,
|
|
borderColor: "gray",
|
|
borderWidth: 1,
|
|
paddingHorizontal: 8,
|
|
fontSize: 14,
|
|
overflow: "hidden",
|
|
fontFamily: "Inter",
|
|
fontStyle: "normal",
|
|
lineHeight: 20,
|
|
fontWeight: "bold",
|
|
backgroundColor: "#ffffff",
|
|
},
|
|
});
|