verification.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { View, Text, StyleSheet, TextInput, Pressable } from "react-native";
  2. import { useEffect, useState } from "react";
  3. import { SignUpFormData, HandleSignUpFormDataChange } from "../../../../types/signup";
  4. import PhoneInput from "../../../global/phone_input";
  5. import NumberInput from "../../../global/number_input";
  6. import NormalButton from "../../../global/normal_button";
  7. import useSignUpStore from "../../../../providers/signup_form_store";
  8. type VerificationProps = {
  9. setScreen: React.Dispatch<React.SetStateAction<number>>;
  10. formData: SignUpFormData;
  11. handleFormDataChange: HandleSignUpFormDataChange;
  12. };
  13. const Verification: React.FC<VerificationProps> = ({ setScreen, formData, handleFormDataChange }) => {
  14. const [error, setError] = useState("");
  15. const [otp, setOtp] = useState("");
  16. const [canSendOtp, setCanSendOtp] = useState(true);
  17. const [lockPhoneInput, setLockPhoneInput] = useState(false);
  18. const handleVerification = () => {
  19. if (formData.phone === "" || otp === "") {
  20. setError("請確保所有資料都已填寫。");
  21. } else {
  22. setError("");
  23. setScreen((currentScreenNumber) => currentScreenNumber + 1);
  24. }
  25. };
  26. const handleSubmitOtp = () => {
  27. if (formData.phoneVerificationStatus) {
  28. if (canSendOtp) {
  29. setCanSendOtp(false);
  30. setLockPhoneInput(true);
  31. console.log(lockPhoneInput);
  32. //can only request otp every 60 seconds
  33. setTimeout(() => {
  34. setCanSendOtp(true);
  35. setLockPhoneInput(false);
  36. }, 60000);
  37. setError("");
  38. } else {
  39. setError("請等待一分鐘後再重新發送。");
  40. }
  41. } else {
  42. setError("請確保所有資料都已填寫。");
  43. }
  44. };
  45. const handleChangePhoneNumber = () => {
  46. setLockPhoneInput(false);
  47. };
  48. const otpButtonText = lockPhoneInput ? (
  49. <Text style={{ color: "#fff" }}>重新發送</Text>
  50. ) : (
  51. <Text style={{ color: "#fff" }}>發送</Text>
  52. );
  53. return (
  54. <>
  55. <View style={styles.container}>
  56. <Text style={styles.text}>請驗證您的電話號碼</Text>
  57. <PhoneInput
  58. placeholder="輸入電話號碼"
  59. handleFormDataChange={handleFormDataChange}
  60. editable={!lockPhoneInput}
  61. extendedStyle={{ opacity: !lockPhoneInput ? 1 : 0.5 }}
  62. />
  63. <View
  64. style={{
  65. display: "flex",
  66. flexDirection: "row",
  67. paddingVertical: 10,
  68. gap: 10,
  69. }}
  70. >
  71. <NumberInput placeholder="OTP驗證碼" onChangeText={setOtp} extendedStyle={{ flex: 1 }} />
  72. <NormalButton title={otpButtonText} onPress={handleSubmitOtp} extendedStyle={{ flex: 1 / 2 }} />
  73. </View>
  74. <NormalButton
  75. title={<Text style={{ color: "#fff" }}>驗證</Text>}
  76. onPress={() => {
  77. handleVerification();
  78. }}
  79. extendedStyle={{}}
  80. />
  81. {error && <Text style={styles.errorMessage}>{error}</Text>}
  82. <Pressable onPress={handleChangePhoneNumber}>
  83. <Text style={[styles.footer, { opacity: lockPhoneInput ? 1 : 0 }]}>修改電話號碼</Text>
  84. </Pressable>
  85. </View>
  86. </>
  87. );
  88. };
  89. const styles = StyleSheet.create({
  90. container: {
  91. flex: 1,
  92. marginHorizontal: 20,
  93. },
  94. text: {
  95. fontSize: 20,
  96. paddingBottom: 10,
  97. },
  98. errorMessage: {
  99. fontSize: 14,
  100. color: "#ff0033",
  101. fontWeight: "400",
  102. marginLeft: 10,
  103. marginTop: 10,
  104. },
  105. footer: { color: "#02677D", fontSize: 16, paddingVertical: 10 },
  106. });
  107. export default Verification;