changeCarPageComponent.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { View, Text, ScrollView, Pressable, Alert } from 'react-native';
  2. import React, { useContext, useEffect, useState } from 'react';
  3. import { SafeAreaView } from 'react-native-safe-area-context';
  4. import { router } from 'expo-router';
  5. import { CrossLogoSvg } from '../global/SVG';
  6. import { AuthContext } from '../../context/AuthProvider';
  7. import NormalInput from '../global/normal_input';
  8. import NormalButton from '../global/normal_button';
  9. import { authenticationService } from '../../service/authService';
  10. import * as SecureStore from 'expo-secure-store';
  11. import { chargeStationService } from '../../service/chargeStationService';
  12. import { User } from '../../types/user';
  13. const ChangeCarPageComponent = () => {
  14. const { user, setUser } = useContext(AuthContext);
  15. const [token, setToken] = useState<string | null>(null);
  16. const [car, setCar] = useState<string | null>(null);
  17. const [isLoading, setIsLoading] = useState(false);
  18. const [error, setError] = useState<string | null>(null);
  19. useEffect(() => {
  20. const getToken = async () => {
  21. const storedToken = await SecureStore.getItemAsync('accessToken');
  22. setToken(storedToken);
  23. };
  24. getToken();
  25. }, []);
  26. const validateLicensePlate = (licensePlate: string | null): string | null => {
  27. if (!licensePlate || licensePlate.trim() === '') {
  28. return '請輸入車牌號碼';
  29. }
  30. const trimmedPlate = licensePlate.trim();
  31. if (trimmedPlate.length < 2) {
  32. return '車牌號碼至少需要2個字符';
  33. }
  34. if (trimmedPlate.length > 10) {
  35. return '車牌號碼不能超過10個字符';
  36. }
  37. // Check for special characters (allow letters, numbers, hyphen, and spaces)
  38. const validFormat = /^[A-Za-z0-9-\s]+$/;
  39. if (!validFormat.test(trimmedPlate)) {
  40. return '車牌號碼只能包含字母、數字和空格';
  41. }
  42. return null;
  43. };
  44. const saveLicensePlate = async (licensePlate: string | null) => {
  45. const validationError = validateLicensePlate(licensePlate);
  46. if (validationError) {
  47. setError(validationError);
  48. Alert.alert('錯誤', validationError);
  49. return;
  50. }
  51. try {
  52. const response = await chargeStationService.addCar(
  53. licensePlate!,
  54. '1834d087-bfc1-4f90-8f09-805e3d9422b5',
  55. 'f599470d-53a5-4026-99c0-2dab34c77f39',
  56. true
  57. );
  58. if (response === true) {
  59. setError(null);
  60. Alert.alert('成功', '車牌號碼保存成功', [
  61. {
  62. text: 'OK',
  63. onPress: () => router.replace('accountMainPage')
  64. }
  65. ]);
  66. const newUser = {...user}
  67. newUser.car = car
  68. setUser({
  69. ...newUser,
  70. } as User);
  71. } else {
  72. setError('無法保存車牌號碼');
  73. Alert.alert('錯誤', '無法保存車牌號碼,請稍後再試');
  74. }
  75. } catch (error) {
  76. setError('暫時無法保存車牌號碼');
  77. Alert.alert('錯誤', '暫時無法保存車牌號碼,請稍後再試');
  78. }
  79. };
  80. return (
  81. <SafeAreaView className="flex-1 bg-white" edges={['top', 'right', 'left']}>
  82. <ScrollView className="flex-1 mx-[5%]">
  83. <View style={{ marginTop: 25 }}>
  84. <Pressable
  85. onPress={() => {
  86. if (router.canGoBack()) {
  87. router.back();
  88. } else {
  89. router.replace('/accountMainPage');
  90. }
  91. }}
  92. >
  93. <CrossLogoSvg />
  94. </Pressable>
  95. <Text style={{ fontSize: 45, marginVertical: 25 }}>更改車牌號碼</Text>
  96. <Text className="text-xl ">請輸入新車牌號碼</Text>
  97. <View className="py-2">
  98. <NormalInput
  99. placeholder={'請輸入新車牌號碼'}
  100. onChangeText={(t) => {
  101. setCar(t);
  102. setError(null); // Clear error when user types
  103. }}
  104. editable={!isLoading}
  105. />
  106. {error && <Text className="text-red-500 mt-1">{error}</Text>}
  107. </View>
  108. <NormalButton
  109. title={<Text className="text-white">{isLoading ? '更改中...' : '確認'}</Text>}
  110. disabled={isLoading}
  111. onPress={() => saveLicensePlate(car)}
  112. />
  113. </View>
  114. </ScrollView>
  115. </SafeAreaView>
  116. );
  117. };
  118. export default ChangeCarPageComponent;