Forráskód Böngészése

implemented zustand, remade PhoneInput component to make it more scaleable and reusable

Ian Fung 1 éve
szülő
commit
6afa5cec8f

+ 243 - 82
component/global/phone_input.tsx

@@ -1,92 +1,253 @@
-import React, { useState } from "react";
-import { View, Text, TextInput, StyleSheet, ViewStyle, StyleProp } from "react-native";
-import { HandleForgetPasswordFormDataChange, HandleSignUpFormDataChange } from "../../types/signup";
+// import React, { useState } from "react";
+// import { View, Text, TextInput, StyleSheet, ViewStyle, StyleProp } from "react-native";
+// import { HandleSignUpFormDataChange } from "../../types/signup";
+// interface PhoneInputProps {
+// 	placeholder: string;
+// 	extendedStyle?: StyleProp<ViewStyle>;
+// 	handleFormDataChange?: HandleSignUpFormDataChange;
+// 	editable?: boolean;
+// }
+
+// const PhoneInput: React.FC<PhoneInputProps> = ({ placeholder, extendedStyle, handleFormDataChange, editable }) => {
+// 	const [error, setError] = useState("");
+// 	const handleTextChange = (text: string) => {
+// 		if (text.length >= 8) {
+// 			setError("");
+// 			handleFormDataChange?.("phone", text);
+// 			handleFormDataChange?.("phoneVerificationStatus", true);
+// 		} else {
+// 			setError("Please enter at least 8 digits");
+// 			handleFormDataChange?.("phone", text);
+// 			handleFormDataChange?.("phoneVerificationStatus", false);
+// 		}
+// 	};
+
+// 	return (
+// 		<View>
+// 			<View style={[styles.inputContainer, extendedStyle]}>
+// 				<Text style={styles.prefix}>+852</Text>
+// 				<View style={styles.horizontalLine} />
+// 				<TextInput
+// 					keyboardType="numeric"
+// 					onChangeText={handleTextChange}
+// 					placeholder={placeholder}
+// 					style={[styles.input]}
+// 					placeholderTextColor="#888888"
+// 					editable={editable}
+// 				/>
+// 			</View>
+// 			{error && <Text style={styles.errorMessage}>{error}</Text>}
+// 		</View>
+// 	);
+// };
+
+// const styles = StyleSheet.create({
+// 	inputContainer: {
+// 		maxWidth: "100%",
+// 		flexDirection: "row",
+// 		alignItems: "center",
+// 		justifyContent: "center",
+// 		borderWidth: 1,
+// 		borderColor: "#bbbbbb",
+// 		borderRadius: 12,
+// 		padding: 20,
+// 	},
+// 	prefix: {
+// 		marginRight: 5,
+// 		fontSize: 16,
+// 	},
+// 	horizontalLine: {
+// 		width: 24,
+// 		borderColor: "#bbbbbb",
+// 		borderWidth: 0.5,
+// 		transform: [{ rotate: "90deg" }],
+// 	},
+// 	input: {
+// 		flex: 1,
+// 		marginLeft: 5,
+// 		fontSize: 16,
+// 	},
+// 	errorMessage: {
+// 		fontSize: 14,
+// 		color: "#ff0033",
+// 		fontWeight: "400",
+// 		marginLeft: 10,
+// 		marginTop: 10,
+// 	},
+// });
+// export default PhoneInput;
+
+// import React, { useState } from "react";
+// import { View, Text, TextInput, StyleSheet, ViewStyle, StyleProp } from "react-native";
+// import { SignUpFormData } from "../../types/signUpFormData";
+
+// interface PhoneInputProps {
+// 	placeholder: string;
+// 	extendedStyle?: StyleProp<ViewStyle>;
+// 	editable?: boolean;
+// 	signUpFormData?: SignUpFormData;
+// 	setSignUpFormData?: (newFormData: Partial<SignUpFormData>) => void;
+// }
+
+// const PhoneInput: React.FC<PhoneInputProps> = ({
+// 	placeholder,
+// 	extendedStyle,
+// 	editable,
+// 	signUpFormData,
+// 	setSignUpFormData,
+// }) => {
+// 	const [error, setError] = useState("");
+
+// 	const handleTextChange = (text: string) => {
+// 		if (text.length >= 8) {
+// 			setError("");
+// 			setSignUpFormData({
+// 				...signUpFormData,
+// 				phone: text,
+// 				phoneVerificationStatus: true,
+// 			});
+// 		} else {
+// 			setError("Please enter at least 8 digits");
+// 			setSignUpFormData({
+// 				...signUpFormData,
+// 				phone: text,
+// 				phoneVerificationStatus: false,
+// 			});
+// 		}
+// 	};
+
+// 	return (
+// 		<View>
+// 			<View style={[styles.inputContainer, extendedStyle]}>
+// 				<Text style={styles.prefix}>+852</Text>
+// 				<View style={styles.horizontalLine} />
+// 				<TextInput
+// 					value={signUpFormData?.phone}
+// 					keyboardType="numeric"
+// 					onChangeText={handleTextChange}
+// 					placeholder={placeholder}
+// 					style={[styles.input]}
+// 					placeholderTextColor="#888888"
+// 					editable={editable}
+// 				/>
+// 			</View>
+// 			{error && <Text style={styles.errorMessage}>{error}</Text>}
+// 		</View>
+// 	);
+// };
+
+// const styles = StyleSheet.create({
+// 	inputContainer: {
+// 		maxWidth: "100%",
+// 		flexDirection: "row",
+// 		alignItems: "center",
+// 		justifyContent: "center",
+// 		borderWidth: 1,
+// 		borderColor: "#bbbbbb",
+// 		borderRadius: 12,
+// 		padding: 20,
+// 	},
+// 	prefix: {
+// 		marginRight: 5,
+// 		fontSize: 16,
+// 	},
+// 	horizontalLine: {
+// 		width: 24,
+// 		borderColor: "#bbbbbb",
+// 		borderWidth: 0.5,
+// 		transform: [{ rotate: "90deg" }],
+// 	},
+// 	input: {
+// 		flex: 1,
+// 		marginLeft: 5,
+// 		fontSize: 16,
+// 	},
+// 	errorMessage: {
+// 		fontSize: 14,
+// 		color: "#ff0033",
+// 		fontWeight: "400",
+// 		marginLeft: 10,
+// 		marginTop: 10,
+// 	},
+// });
+// export default PhoneInput;
+
+import React from 'react';
+import {
+    View,
+    Text,
+    TextInput,
+    StyleSheet,
+    ViewStyle,
+    StyleProp
+} from 'react-native';
+
 interface PhoneInputProps {
-	placeholder: string;
-	extendedStyle?: StyleProp<ViewStyle>;
-	handleFormDataChange?: HandleSignUpFormDataChange;
-	handleForgetPasswordFormDataChange?: HandleForgetPasswordFormDataChange;
-	editable?: boolean;
+    value: string;
+    onChangeText: (text: string) => void;
+    placeholder: string;
+    extendedStyle?: StyleProp<ViewStyle>;
+    editable?: boolean;
 }
 
 const PhoneInput: React.FC<PhoneInputProps> = ({
-	placeholder,
-	extendedStyle,
-	handleFormDataChange,
-	handleForgetPasswordFormDataChange,
-	editable,
+    value,
+    onChangeText,
+    placeholder,
+    extendedStyle,
+    editable
 }) => {
-	const [error, setError] = useState("");
-	//by calling <PhoneInput handleFormDataChange={}... />, we use Registration Form Type.
-	//by calling <PhoneInput handleForgetPasswordFormDataChange={}... />, we use Forget-Password Form Type.
-
-	const handleTextChange = (text: string) => {
-		if (text.length >= 8) {
-			setError("");
-			handleFormDataChange?.("phone", text);
-			handleFormDataChange?.("phoneVerificationStatus", true);
-			handleForgetPasswordFormDataChange?.("phone", text);
-			handleForgetPasswordFormDataChange?.("phoneVerificationStatus", true);
-		} else {
-			setError("Please enter at least 8 digits");
-			handleFormDataChange?.("phone", text);
-			handleFormDataChange?.("phoneVerificationStatus", false);
-			handleForgetPasswordFormDataChange?.("phone", text);
-			handleForgetPasswordFormDataChange?.("phoneVerificationStatus", false);
-		}
-	};
-
-	return (
-		<View>
-			<View style={[styles.inputContainer, extendedStyle]}>
-				<Text style={styles.prefix}>+852</Text>
-				<View style={styles.horizontalLine} />
-				<TextInput
-					keyboardType="numeric"
-					onChangeText={handleTextChange}
-					placeholder={placeholder}
-					style={[styles.input]}
-					placeholderTextColor="#888888"
-					editable={editable}
-				/>
-			</View>
-			{error && <Text style={styles.errorMessage}>{error}</Text>}
-		</View>
-	);
+    return (
+        <View>
+            <View style={[styles.inputContainer, extendedStyle]}>
+                <Text style={styles.prefix}>+852</Text>
+                <View style={styles.horizontalLine} />
+                <TextInput
+                    value={value}
+                    onChangeText={onChangeText}
+                    keyboardType="numeric"
+                    placeholder={placeholder}
+                    style={[styles.input]}
+                    placeholderTextColor="#888888"
+                    editable={editable}
+                />
+            </View>
+        </View>
+    );
 };
 
 const styles = StyleSheet.create({
-	inputContainer: {
-		maxWidth: "100%",
-		flexDirection: "row",
-		alignItems: "center",
-		justifyContent: "center",
-		borderWidth: 1,
-		borderColor: "#bbbbbb",
-		borderRadius: 12,
-		padding: 20,
-	},
-	prefix: {
-		marginRight: 5,
-		fontSize: 16,
-	},
-	horizontalLine: {
-		width: 24,
-		borderColor: "#bbbbbb",
-		borderWidth: 0.5,
-		transform: [{ rotate: "90deg" }],
-	},
-	input: {
-		flex: 1,
-		marginLeft: 5,
-		fontSize: 16,
-	},
-	errorMessage: {
-		fontSize: 14,
-		color: "#ff0033",
-		fontWeight: "400",
-		marginLeft: 10,
-		marginTop: 10,
-	},
+    inputContainer: {
+        maxWidth: '100%',
+        flexDirection: 'row',
+        alignItems: 'center',
+        justifyContent: 'center',
+        borderWidth: 1,
+        borderColor: '#bbbbbb',
+        borderRadius: 12,
+        padding: 20
+    },
+    prefix: {
+        marginRight: 5,
+        fontSize: 16
+    },
+    horizontalLine: {
+        width: 24,
+        borderColor: '#bbbbbb',
+        borderWidth: 0.5,
+        transform: [{ rotate: '90deg' }]
+    },
+    input: {
+        flex: 1,
+        marginLeft: 5,
+        fontSize: 16
+    },
+    errorMessage: {
+        fontSize: 14,
+        color: '#ff0033',
+        fontWeight: '400',
+        marginLeft: 10,
+        marginTop: 10
+    }
 });
 export default PhoneInput;

+ 6 - 18
component/multiStepForm/formComponent/formPages/basicInformation.tsx

@@ -3,16 +3,13 @@ import NormalInput from "../../../global/normal_input";
 import { useState } from "react";
 import DateModal from "../../../global/date_input";
 import NormalButton from "../../../global/normal_button";
-import { SignUpFormData, HandleSignUpFormDataChange } from "../../../../types/signup";
 import useSignUpStore from "../../../../providers/signup_form_store";
 
 type basicInformationProps = {
 	goToNextPage: () => void;
-	handleFormDataChange: HandleSignUpFormDataChange;
-	formData: SignUpFormData;
 };
 
-const BasicInformation: React.FC<basicInformationProps> = ({ handleFormDataChange, goToNextPage, formData }) => {
+const BasicInformation: React.FC<basicInformationProps> = ({ goToNextPage }) => {
 	const { signUpFormData, setSignUpFormData } = useSignUpStore();
 	const [error, setError] = useState("");
 	const handleNext = () => {
@@ -24,6 +21,8 @@ const BasicInformation: React.FC<basicInformationProps> = ({ handleFormDataChang
 		}
 	};
 
+	const nameFieldPlaceholder = signUpFormData.name ? signUpFormData.name : "姓名";
+
 	return (
 		<>
 			<View style={styles.container}>
@@ -35,20 +34,14 @@ const BasicInformation: React.FC<basicInformationProps> = ({ handleFormDataChang
 						gap: 10,
 					}}
 				>
-					{/* <NormalInput placeholder="姓名" onChangeText={(text) => handleFormDataChange("name", text)} /> */}
 					<NormalInput
-						placeholder="姓名"
+						value={signUpFormData.name}
+						placeholder={nameFieldPlaceholder}
 						onChangeText={(text) => {
 							setSignUpFormData({ ...signUpFormData, name: text });
 						}}
 					/>
 
-					{/* <NormalInput
-						placeholder="帳戶密碼"
-						onChangeText={(text) => handleFormDataChange("password", text)}
-						secureTextEntry={true}
-					/> */}
-
 					<NormalInput
 						placeholder="帳戶密碼"
 						onChangeText={(text) => {
@@ -64,12 +57,7 @@ const BasicInformation: React.FC<basicInformationProps> = ({ handleFormDataChang
 							onChangeText={(t) => console.log(t)}
 							extendedStyle={{ width: "50%" }}
 						/>
-						{/* <DateModal
-							placeholder={formData.birthDate ? formData.birthDate : "DD/MM/YY"}
-							onDateChange={(date) => {
-								handleFormDataChange("birthDate", date);
-							}}
-						/> */}
+
 						<DateModal
 							placeholder={signUpFormData.birthDate ? signUpFormData.birthDate : "DD/MM/YY"}
 							onDateChange={(date) => {

+ 4 - 21
component/multiStepForm/multi_step_form.tsx

@@ -1,36 +1,19 @@
-import { Text, View, StyleSheet } from 'react-native';
+import { View, StyleSheet } from 'react-native';
 import { StatusBar } from 'expo-status-bar';
-
-import { useEffect, useState } from 'react';
-import { SignUpFormData } from '../../types/signup';
+import { useEffect } from 'react';
 import useSignUpStore from '../../providers/signup_form_store';
 import Form from '../registrationMultiStepForm/formComponent/form';
 
 const MultiStepForm: React.FC = () => {
-    const [formData, setFormData] = useState<SignUpFormData>({
-        phone: '',
-        phoneVerificationStatus: false,
-        name: '',
-        gender: '',
-        password: '',
-        email: '',
-        birthDate: '',
-        isUberDriver: undefined,
-        vehicleType: '',
-        vehicleModel: '',
-        licensePlate: '',
-        address: '',
-        paymentMethod: ''
-    });
-    //logging to check if parent component can successfully receive user input in the multi-step form
     const { signUpFormData } = useSignUpStore();
+    //logging to check if parent component can successfully receive user input in the multi-step form
     useEffect(() => {
         console.log('Current Zustand Store:', signUpFormData);
     }, [signUpFormData]);
 
     return (
         <View style={styles.container}>
-            <Form formData={formData} setFormData={setFormData} />
+            <Form />
             <StatusBar style="auto" />
         </View>
     );

+ 15 - 51
component/registrationMultiStepForm/formComponent/form.tsx

@@ -5,18 +5,14 @@ import BasicInformation from "./formPages/basicInformation";
 import UberDriver from "./formPages/uberDriver";
 import CarInformation from "./formPages/carInformation";
 import PaginationIndicator from "../../global/PaginationIndicator";
-import { SignUpFormData, SignUpFormDataKey } from "../../../types/signup";
 import CreateWallet from "./formPages/createWallet";
 import FinishSignUp from "./formPages/finishSignUp";
 import LoginPage from "./formPages/loginPage";
 import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
 
-type FormProps = {
-	formData: SignUpFormData;
-	setFormData: React.Dispatch<React.SetStateAction<SignUpFormData>>;
-};
-const Form: React.FC<FormProps> = ({ formData, setFormData }) => {
-	const [screen, setScreen] = useState<number>(4);
+type FormProps = {};
+const Form: React.FC<FormProps> = ({}) => {
+	const [screen, setScreen] = useState<number>(0);
 	const FormTitle = [
 		"",
 		"註冊 - 電話驗證",
@@ -26,57 +22,20 @@ const Form: React.FC<FormProps> = ({ formData, setFormData }) => {
 		"註冊 - 設立銀包",
 	];
 
-	const handleFormDataChange = <K extends SignUpFormDataKey>(field: K, value: SignUpFormData[K]) => {
-		setFormData((prevFormData) => ({
-			...prevFormData,
-			[field]: value,
-		}));
-	};
-
 	const ScreenDisplay = () => {
 		switch (screen) {
 			case 0:
 				return <LoginPage goToNextPage={goToNextPage} />;
 			case 1:
-				return (
-					<Verification
-						setScreen={setScreen}
-						formData={formData}
-						handleFormDataChange={handleFormDataChange}
-					/>
-				);
+				return <Verification setScreen={setScreen} />;
 			case 2:
-				return (
-					<BasicInformation
-						formData={formData}
-						handleFormDataChange={handleFormDataChange}
-						goToNextPage={goToNextPage}
-					/>
-				);
+				return <BasicInformation goToNextPage={goToNextPage} />;
 			case 3:
-				return (
-					<UberDriver
-						formData={formData}
-						handleFormDataChange={handleFormDataChange}
-						goToNextPage={goToNextPage}
-					/>
-				);
+				return <UberDriver goToNextPage={goToNextPage} />;
 			case 4:
-				return (
-					<CarInformation
-						formData={formData}
-						handleFormDataChange={handleFormDataChange}
-						goToNextPage={goToNextPage}
-					/>
-				);
+				return <CarInformation goToNextPage={goToNextPage} />;
 			case 5:
-				return (
-					<CreateWallet
-						formData={formData}
-						handleFormDataChange={handleFormDataChange}
-						goToNextPage={goToNextPage}
-					/>
-				);
+				return <CreateWallet goToNextPage={goToNextPage} />;
 			case 6:
 				return <FinishSignUp />;
 			default:
@@ -135,7 +94,13 @@ const Form: React.FC<FormProps> = ({ formData, setFormData }) => {
 };
 
 const styles = StyleSheet.create({
-	topContainer: { flex: 1, alignItems: "center", justifyContent: "center", paddingBottom: "20%", paddingTop: "15%" },
+	topContainer: {
+		flex: 1,
+		alignItems: "center",
+		justifyContent: "center",
+		paddingBottom: "20%",
+		paddingTop: "15%",
+	},
 	previouspageAndPaginationWrapper: {
 		display: "flex",
 		width: "100%",
@@ -144,7 +109,6 @@ const styles = StyleSheet.create({
 		alignItems: "center",
 		paddingHorizontal: 25,
 	},
-
 	bottomContainer: { flex: 2.5 },
 	breakline: { width: 24, height: 1, backgroundColor: "#000000", marginVertical: 17 },
 	text: { fontSize: 24, fontWeight: "300" },

+ 11 - 7
component/registrationMultiStepForm/formComponent/formPages/carInformation.tsx

@@ -1,5 +1,4 @@
 import { View, Text, StyleSheet } from "react-native";
-import { SignUpFormData, HandleSignUpFormDataChange } from "../../../../types/signup";
 import NormalInput from "../../../global/normal_input";
 import NormalButton from "../../../global/normal_button";
 import { useState } from "react";
@@ -7,11 +6,9 @@ import useSignUpStore from "../../../../providers/signup_form_store";
 
 type CarInformationProps = {
 	goToNextPage: () => void;
-	handleFormDataChange: HandleSignUpFormDataChange;
-	formData: SignUpFormData;
 };
 
-const CarInformation: React.FC<CarInformationProps> = ({ goToNextPage, handleFormDataChange, formData }) => {
+const CarInformation: React.FC<CarInformationProps> = ({ goToNextPage }) => {
 	const { signUpFormData, setSignUpFormData } = useSignUpStore();
 	const [error, setError] = useState("");
 	const handleNext = () => {
@@ -27,6 +24,10 @@ const CarInformation: React.FC<CarInformationProps> = ({ goToNextPage, handleFor
 		}
 	};
 
+	const vehicleTypeFieldPlaceholder = signUpFormData.vehicleType ? signUpFormData.vehicleType : "車輛品牌";
+	const vehicleModelFieldPlaceholder = signUpFormData.vehicleModel ? signUpFormData.vehicleModel : "車輛型號";
+	const licensePlateFieldPlaceholder = signUpFormData.licensePlate ? signUpFormData.licensePlate : "車輛號碼";
+
 	return (
 		<>
 			<View style={styles.container}>
@@ -39,19 +40,22 @@ const CarInformation: React.FC<CarInformationProps> = ({ goToNextPage, handleFor
 					}}
 				>
 					<NormalInput
-						placeholder={"車輛品牌"}
+						value={signUpFormData.vehicleType}
+						placeholder={vehicleTypeFieldPlaceholder}
 						onChangeText={(vehicleType) => {
 							setSignUpFormData({ ...signUpFormData, vehicleType: vehicleType });
 						}}
 					/>
 					<NormalInput
-						placeholder={"車輛型號"}
+						value={signUpFormData.vehicleModel}
+						placeholder={vehicleModelFieldPlaceholder}
 						onChangeText={(vehicleModel) => {
 							setSignUpFormData({ ...signUpFormData, vehicleModel: vehicleModel });
 						}}
 					/>
 					<NormalInput
-						placeholder="車輛號碼"
+						value={signUpFormData.licensePlate}
+						placeholder={licensePlateFieldPlaceholder}
 						onChangeText={(licensePlate) => {
 							setSignUpFormData({ ...signUpFormData, licensePlate: licensePlate });
 						}}

+ 7 - 8
component/registrationMultiStepForm/formComponent/formPages/createWallet.tsx

@@ -1,5 +1,4 @@
 import { View, Text, StyleSheet } from "react-native";
-import { SignUpFormData, HandleSignUpFormDataChange } from "../../../../types/signup";
 import NormalInput from "../../../global/normal_input";
 import NormalButton from "../../../global/normal_button";
 import { useState } from "react";
@@ -8,18 +7,16 @@ import useSignUpStore from "../../../../providers/signup_form_store";
 
 type CreateWalletProps = {
 	goToNextPage: () => void;
-	handleFormDataChange: HandleSignUpFormDataChange;
-	formData: SignUpFormData;
 };
 const creditCard = "信用卡";
 const weChatAliPay = "微信支付/支付寶";
 
-const CreateWallet: React.FC<CreateWalletProps> = ({ goToNextPage, handleFormDataChange, formData }) => {
+const CreateWallet: React.FC<CreateWalletProps> = ({ goToNextPage }) => {
 	const options = [{ label: creditCard }, { label: weChatAliPay }];
 	const { signUpFormData, setSignUpFormData } = useSignUpStore();
 
 	const handleSelectedChange = (selectedLabel: string) => {
-		handleFormDataChange("paymentMethod", selectedLabel);
+		setSignUpFormData({ ...signUpFormData, paymentMethod: selectedLabel });
 		setError("");
 	};
 
@@ -56,15 +53,17 @@ const CreateWallet: React.FC<CreateWalletProps> = ({ goToNextPage, handleFormDat
 				>
 					<NormalInput
 						placeholder={"電子郵件"}
-						// onChangeText={(email) => handleFormDataChange("email", email)}
 						onChangeText={(email) => {
-							setSignUpFormData( ...signUpFormData, email: email )
+							setSignUpFormData({ ...signUpFormData, email: email });
 						}}
 					/>
 					<NormalInput
 						placeholder="地址"
-						onChangeText={(address) => handleFormDataChange("address", address)}
+						onChangeText={(address) => {
+							setSignUpFormData({ ...signUpFormData, address: address });
+						}}
 					/>
+
 					<SingleSelectButtonGroup
 						options={options}
 						onSelectionChange={handleSelectedChange}

+ 7 - 1
component/registrationMultiStepForm/formComponent/formPages/loginPage.tsx

@@ -3,12 +3,14 @@ import NormalButton from "../../../global/normal_button";
 import Logo from "../../../global/logo";
 import PhoneInput from "../../../global/phone_input";
 import NormalInput from "../../../global/normal_input";
+import { useState } from "react";
 
 type LoginPageProps = {
 	goToNextPage: () => void;
 };
 
 const LoginPage: React.FC<LoginPageProps> = ({ goToNextPage }) => {
+	const [loginPhone, setLoginPhone] = useState(""); //This loginPhone useState is only a placeholder, will be updated in the future
 	return (
 		<>
 			<View style={styles.container}>
@@ -17,8 +19,12 @@ const LoginPage: React.FC<LoginPageProps> = ({ goToNextPage }) => {
 				</View>
 				<View style={styles.bottomContainer}>
 					<PhoneInput
+						value={loginPhone}
+						onChangeText={(t) => {
+							setLoginPhone(t);
+							console.log(loginPhone);
+						}}
 						placeholder="電話號碼"
-						handleFormDataChange={(field, value) => console.log(`${field}: ${value}`)}
 						extendedStyle={{ borderRadius: 12, padding: 20 }}
 					/>
 					<NormalInput

+ 3 - 13
component/registrationMultiStepForm/formComponent/formPages/uberDriver.tsx

@@ -1,5 +1,4 @@
 import { View, Text, StyleSheet } from "react-native";
-import { SignUpFormData, HandleSignUpFormDataChange } from "../../../../types/signup";
 import NormalButton from "../../../global/normal_button";
 import { useState } from "react";
 import SingleSelectButtonGroup from "../../../global/select_button";
@@ -7,14 +6,13 @@ import useSignUpStore from "../../../../providers/signup_form_store";
 
 type UberDriverProps = {
 	goToNextPage: () => void;
-	handleFormDataChange: HandleSignUpFormDataChange;
-	formData: SignUpFormData;
 };
 
-const UberDriver: React.FC<UberDriverProps> = ({ formData, goToNextPage, handleFormDataChange }) => {
+const UberDriver: React.FC<UberDriverProps> = ({ goToNextPage }) => {
 	const { signUpFormData, setSignUpFormData } = useSignUpStore();
-
 	const [error, setError] = useState("");
+	const options = [{ label: "是(可享有獨家優惠)" }, { label: "否" }];
+
 	const handleNext = () => {
 		if (signUpFormData.isUberDriver == undefined) {
 			setError("請確保所有資料都已填寫。");
@@ -23,11 +21,6 @@ const UberDriver: React.FC<UberDriverProps> = ({ formData, goToNextPage, handleF
 			goToNextPage();
 		}
 	};
-	const handleSelectedChange = (selectedLabel: string) => {
-		handleFormDataChange("isUberDriver", selectedLabel === "是(可享有獨家優惠)" ? true : false);
-		setError("");
-	};
-
 	const selectLabelShown = () => {
 		if (signUpFormData.isUberDriver == undefined) {
 			return null;
@@ -37,15 +30,12 @@ const UberDriver: React.FC<UberDriverProps> = ({ formData, goToNextPage, handleF
 			return "否";
 		}
 	};
-
-	const options = [{ label: "是(可享有獨家優惠)" }, { label: "否" }];
 	return (
 		<>
 			<View style={styles.container}>
 				<Text style={styles.text}>請問您是Uber Driver嗎?</Text>
 				<SingleSelectButtonGroup
 					options={options}
-					// onSelectionChange={handleSelectedChange}
 					onSelectionChange={(label) => {
 						const convertLabelToBoolean =
 							label === "是(可享有獨家優惠)" ? true : label === "否" ? false : undefined;

+ 21 - 10
component/registrationMultiStepForm/formComponent/formPages/verification.tsx

@@ -1,6 +1,5 @@
 import { View, Text, StyleSheet, TextInput, Pressable } from "react-native";
-import { useEffect, useState } from "react";
-import { SignUpFormData, HandleSignUpFormDataChange } from "../../../../types/signup";
+import { useState } from "react";
 import PhoneInput from "../../../global/phone_input";
 import NumberInput from "../../../global/number_input";
 import NormalButton from "../../../global/normal_button";
@@ -8,27 +7,35 @@ import useSignUpStore from "../../../../providers/signup_form_store";
 
 type VerificationProps = {
 	setScreen: React.Dispatch<React.SetStateAction<number>>;
-	formData: SignUpFormData;
-	handleFormDataChange: HandleSignUpFormDataChange;
 };
 
-const Verification: React.FC<VerificationProps> = ({ setScreen, formData, handleFormDataChange }) => {
+const Verification: React.FC<VerificationProps> = ({ setScreen }) => {
+	const { signUpFormData, setSignUpFormData } = useSignUpStore();
 	const [error, setError] = useState("");
 	const [otp, setOtp] = useState("");
 	const [canSendOtp, setCanSendOtp] = useState(true);
 	const [lockPhoneInput, setLockPhoneInput] = useState(false);
 
+	const handleSignUpPhoneChange = (phone: string) => {
+		setSignUpFormData({ phone });
+		if (signUpFormData.phone.length + 1 === 8) {
+			setSignUpFormData({ phoneVerificationStatus: true });
+		} else {
+			setSignUpFormData({ phoneVerificationStatus: false });
+		}
+	};
 	const handleVerification = () => {
-		if (formData.phone === "" || otp === "") {
+		if (signUpFormData.phone === "" || otp === "") {
 			setError("請確保所有資料都已填寫。");
+		} else if (signUpFormData.phoneVerificationStatus === false) {
+			setError("請確保電話號碼長度正確");
 		} else {
 			setError("");
 			setScreen((currentScreenNumber) => currentScreenNumber + 1);
 		}
 	};
-
 	const handleSubmitOtp = () => {
-		if (formData.phoneVerificationStatus) {
+		if (signUpFormData.phoneVerificationStatus) {
 			if (canSendOtp) {
 				setCanSendOtp(false);
 				setLockPhoneInput(true);
@@ -56,13 +63,17 @@ const Verification: React.FC<VerificationProps> = ({ setScreen, formData, handle
 	) : (
 		<Text style={{ color: "#fff" }}>發送</Text>
 	);
+
+	const phoneFieldPlaceholder = signUpFormData.phone ? signUpFormData.phone : "輸入電話號碼";
+
 	return (
 		<>
 			<View style={styles.container}>
 				<Text style={styles.text}>請驗證您的電話號碼</Text>
 				<PhoneInput
-					placeholder="輸入電話號碼"
-					handleFormDataChange={handleFormDataChange}
+					value={signUpFormData.phone}
+					onChangeText={handleSignUpPhoneChange}
+					placeholder={phoneFieldPlaceholder}
 					editable={!lockPhoneInput}
 					extendedStyle={{ opacity: !lockPhoneInput ? 1 : 0.5 }}
 				/>

+ 19 - 0
types/signUpFormData.d.ts

@@ -0,0 +1,19 @@
+export interface SignUpFormData {
+	phone: string;
+	phoneVerificationStatus: boolean;
+	name: string;
+	password: string;
+	email: string;
+	birthDate: string;
+	isUberDriver?: boolean | undefined;
+	vehicleType: string;
+	vehicleModel: string;
+	licensePlate: string;
+	address: string;
+	paymentMethod: string;
+}
+
+export interface SignUpFormState {
+	signUpFormData: SignUpFormData;
+	setSignUpFormData: (newFormData: Partial<SignUpFormData>) => void;
+}