|
|
@@ -0,0 +1,156 @@
|
|
|
+import { View, Text, ScrollView, Pressable, Alert } from 'react-native';
|
|
|
+import React, { useContext, useEffect, useState } from 'react';
|
|
|
+import { SafeAreaView } from 'react-native-safe-area-context';
|
|
|
+import { router } from 'expo-router';
|
|
|
+import { CrossLogoSvg } from '../global/SVG';
|
|
|
+import { AuthContext } from '../../context/AuthProvider';
|
|
|
+import NormalInput from '../global/normal_input';
|
|
|
+import NormalButton from '../global/normal_button';
|
|
|
+import { authenticationService } from '../../service/authService';
|
|
|
+import * as SecureStore from 'expo-secure-store';
|
|
|
+import { chargeStationService } from '../../service/chargeStationService';
|
|
|
+
|
|
|
+const ChangeCarPageComponent = () => {
|
|
|
+ const { user, setUser } = useContext(AuthContext);
|
|
|
+ const [token, setToken] = useState<string | null>(null);
|
|
|
+ const [car, setCar] = useState<string | null>(null);
|
|
|
+ const [isLoading, setIsLoading] = useState(false);
|
|
|
+ const [error, setError] = useState<string | null>(null);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const getToken = async () => {
|
|
|
+ const storedToken = await SecureStore.getItemAsync('accessToken');
|
|
|
+ setToken(storedToken);
|
|
|
+ };
|
|
|
+ getToken();
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ const validateLicensePlate = (licensePlate: string | null): string | null => {
|
|
|
+ if (!licensePlate || licensePlate.trim() === '') {
|
|
|
+ return '請輸入車牌號碼';
|
|
|
+ }
|
|
|
+
|
|
|
+ const trimmedPlate = licensePlate.trim();
|
|
|
+
|
|
|
+ if (trimmedPlate.length < 2) {
|
|
|
+ return '車牌號碼至少需要2個字符';
|
|
|
+ }
|
|
|
+
|
|
|
+ if (trimmedPlate.length > 10) {
|
|
|
+ return '車牌號碼不能超過10個字符';
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check for special characters (allow letters, numbers, hyphen, and spaces)
|
|
|
+ const validFormat = /^[A-Za-z0-9-\s]+$/;
|
|
|
+ if (!validFormat.test(trimmedPlate)) {
|
|
|
+ return '車牌號碼只能包含字母、數字和空格';
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ };
|
|
|
+
|
|
|
+ const saveLicensePlate = async (licensePlate: string | null) => {
|
|
|
+ const validationError = validateLicensePlate(licensePlate);
|
|
|
+ if (validationError) {
|
|
|
+ setError(validationError);
|
|
|
+ Alert.alert('錯誤', validationError);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await chargeStationService.addCar(
|
|
|
+ licensePlate!,
|
|
|
+ '1834d087-bfc1-4f90-8f09-805e3d9422b5',
|
|
|
+ 'f599470d-53a5-4026-99c0-2dab34c77f39',
|
|
|
+ true
|
|
|
+ );
|
|
|
+ if (response === true) {
|
|
|
+ setError(null);
|
|
|
+ Alert.alert('成功', '車牌號碼保存成功', [
|
|
|
+ {
|
|
|
+ text: 'OK',
|
|
|
+ onPress: () => router.replace('accountMainPage')
|
|
|
+ }
|
|
|
+ ]);
|
|
|
+ } else {
|
|
|
+ setError('無法保存車牌號碼');
|
|
|
+ Alert.alert('錯誤', '無法保存車牌號碼,請稍後再試');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ setError('暫時無法保存車牌號碼');
|
|
|
+ Alert.alert('錯誤', '暫時無法保存車牌號碼,請稍後再試');
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleChangeCar = async () => {
|
|
|
+ if (!name) {
|
|
|
+ setError('請輸入新的車牌號碼');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!token) {
|
|
|
+ setError('未找到有效的登錄令牌,請重新登錄');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ setError(null);
|
|
|
+ setIsLoading(true);
|
|
|
+ try {
|
|
|
+ const success = await authenticationService.changeName(name, token);
|
|
|
+ if (success) {
|
|
|
+ if (user) {
|
|
|
+ setUser({
|
|
|
+ ...user,
|
|
|
+ nickname: name
|
|
|
+ });
|
|
|
+ }
|
|
|
+ router.replace('accountMainPage');
|
|
|
+ } else {
|
|
|
+ setError('更新暱稱失敗,請稍後再試');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error changing name:', error);
|
|
|
+ setError('發生錯誤,請稍後再試');
|
|
|
+ } finally {
|
|
|
+ setIsLoading(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <SafeAreaView className="flex-1 bg-white" edges={['top', 'right', 'left']}>
|
|
|
+ <ScrollView className="flex-1 mx-[5%]">
|
|
|
+ <View style={{ marginTop: 25 }}>
|
|
|
+ <Pressable
|
|
|
+ onPress={() => {
|
|
|
+ if (router.canGoBack()) {
|
|
|
+ router.back();
|
|
|
+ } else {
|
|
|
+ router.replace('/accountMainPage');
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <CrossLogoSvg />
|
|
|
+ </Pressable>
|
|
|
+ <Text style={{ fontSize: 45, marginVertical: 25 }}>更改車牌號碼</Text>
|
|
|
+ <Text className="text-xl ">請輸入新車牌號碼</Text>
|
|
|
+ <View className="py-2">
|
|
|
+ <NormalInput
|
|
|
+ placeholder={'請輸入新車牌號碼'}
|
|
|
+ onChangeText={(t) => {
|
|
|
+ setCar(t);
|
|
|
+ setError(null); // Clear error when user types
|
|
|
+ }}
|
|
|
+ editable={!isLoading}
|
|
|
+ />
|
|
|
+ {error && <Text className="text-red-500 mt-1">{error}</Text>}
|
|
|
+ </View>
|
|
|
+ <NormalButton
|
|
|
+ title={<Text className="text-white">{isLoading ? '更改中...' : '確認'}</Text>}
|
|
|
+ disabled={isLoading}
|
|
|
+ onPress={() => saveLicensePlate(car)}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </ScrollView>
|
|
|
+ </SafeAreaView>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default ChangeCarPageComponent;
|