chooseCarPageComponent.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import { router } from 'expo-router';
  2. import {
  3. View,
  4. Text,
  5. ScrollView,
  6. Pressable,
  7. Image,
  8. Dimensions,
  9. StyleSheet,
  10. TextInput,
  11. Alert,
  12. ActivityIndicator
  13. } from 'react-native';
  14. import { SafeAreaView } from 'react-native-safe-area-context';
  15. import { PreviousPageBlackSvg } from '../global/SVG';
  16. import NormalButton from '../global/normal_button';
  17. import { useEffect, useState } from 'react';
  18. import Checkbox from 'expo-checkbox';
  19. import DropdownSelect from '../global/dropdown_select';
  20. import { chargeStationService } from '../../service/chargeStationService';
  21. const chooseCarPageComponent = () => {
  22. const [isChecked, setChecked] = useState(false);
  23. const { height: deviceHeight, width: deviceWidth } = Dimensions.get('window');
  24. const [brandNameDropdownOptions, setBrandNameDropdownOptions] = useState([]);
  25. const [isLoading, setIsLoading] = useState(false);
  26. const [licensePlate, setLicensePlate] = useState('');
  27. const [selectedBrandID, setSelectedBrandID] = useState('');
  28. const [selectedTypeID, setSelectedTypeID] = useState('');
  29. const [caName, setCarName] = useState('');
  30. // const [carImg, setCarImg] = useState('');
  31. const [brandData, setBrandData] = useState([]);
  32. const [brandTypeDropdownOptions, setBrandTypeDropdownOptions] = useState([
  33. {
  34. label: '車輛型號',
  35. value: '車輛型號'
  36. }
  37. ]);
  38. const handleSubmit = async () => {
  39. setIsLoading(true);
  40. try {
  41. const result = await chargeStationService.addCar(licensePlate, selectedBrandID, selectedTypeID, isChecked);
  42. if (result) {
  43. router.push({
  44. pathname: 'addVehicleSuccessfulPage',
  45. params: { selectedTypeID: selectedTypeID }
  46. });
  47. } else {
  48. Alert.alert('新增車輛失敗', '請再試一次');
  49. }
  50. } catch (error) {
  51. console.log(error, 'unexpected');
  52. } finally {
  53. setIsLoading(false);
  54. }
  55. };
  56. useEffect(() => {
  57. const fetchData = async () => {
  58. try {
  59. const result = await chargeStationService.fetchCarBrand();
  60. setBrandData(result.data);
  61. const brandInfo = result.data.map((item) => ({
  62. name: item.name,
  63. id: item.id,
  64. img_url: item.img_url
  65. }));
  66. const brandName = brandInfo.map((item) => item.name);
  67. console.log(brandName);
  68. const brandNameDropdownOptions = brandInfo.map((item) => ({
  69. label: item.name,
  70. value: item.id
  71. }));
  72. setBrandNameDropdownOptions(brandNameDropdownOptions);
  73. } catch (error) {
  74. console.log(error);
  75. }
  76. };
  77. fetchData();
  78. }, []);
  79. useEffect(() => {
  80. if (selectedBrandID) {
  81. const selectedBrand = brandData.find((brand) => brand.id === selectedBrandID);
  82. if (selectedBrand && selectedBrand.car_types) {
  83. const typeOptions = selectedBrand.car_types.map((carType) => ({
  84. label: carType.name,
  85. value: carType.id
  86. }));
  87. setBrandTypeDropdownOptions(typeOptions);
  88. } else {
  89. setBrandTypeDropdownOptions([]);
  90. }
  91. } else {
  92. setBrandTypeDropdownOptions([]);
  93. }
  94. }, [selectedBrandID, brandData]);
  95. return (
  96. <SafeAreaView className="flex-1 bg-white" edges={['top', 'right', 'left']}>
  97. <ScrollView showsVerticalScrollIndicator={false} className="flex-1 mx-[5%]">
  98. <View style={{ marginTop: 25 }}>
  99. <Pressable
  100. className="self-start"
  101. onPress={() => {
  102. if (router.canGoBack()) {
  103. router.back();
  104. } else {
  105. router.replace('/accountMainPage');
  106. }
  107. }}
  108. >
  109. <PreviousPageBlackSvg />
  110. </Pressable>
  111. <Text
  112. style={{
  113. fontSize: 30,
  114. marginTop: 25,
  115. marginBottom: 20
  116. }}
  117. >
  118. 新增車輛
  119. </Text>
  120. </View>
  121. <View
  122. style={{
  123. display: 'flex',
  124. flexDirection: 'column',
  125. gap: 10
  126. }}
  127. >
  128. <DropdownSelect
  129. dropdownOptions={brandNameDropdownOptions}
  130. placeholder={'車輛品牌'}
  131. onSelect={(ID) => {
  132. setSelectedBrandID(ID);
  133. console.log(ID);
  134. }}
  135. extendedStyle={{
  136. borderWidth: 1,
  137. padding: 20,
  138. borderRadius: 12,
  139. borderColor: '#bbbbbb'
  140. }}
  141. />
  142. <DropdownSelect
  143. dropdownOptions={brandTypeDropdownOptions}
  144. placeholder={'車輛品牌'}
  145. onSelect={(carTypeID) => setSelectedTypeID(carTypeID)}
  146. extendedStyle={{
  147. borderWidth: 1,
  148. padding: 20,
  149. borderRadius: 12,
  150. borderColor: '#bbbbbb'
  151. }}
  152. />
  153. <TextInput
  154. style={styles.fakeTextInput}
  155. onChangeText={(text) => {
  156. setLicensePlate(text.toUpperCase());
  157. // console.log(licensePlate);
  158. }}
  159. value={licensePlate}
  160. placeholder="車輛牌照號碼"
  161. placeholderTextColor="#888"
  162. autoCapitalize="characters"
  163. />
  164. </View>
  165. <View className="flex-row items-center">
  166. <Text className="mt-4 mb-4 text-lg">設置為預設車輛</Text>
  167. <Checkbox
  168. style={styles.checkbox}
  169. value={isChecked}
  170. onValueChange={setChecked}
  171. color={isChecked ? '#025c72' : undefined}
  172. />
  173. </View>
  174. <NormalButton
  175. title={
  176. <Text
  177. style={{
  178. fontWeight: '700',
  179. fontSize: 20,
  180. color: '#fff'
  181. }}
  182. >
  183. {isLoading ? <ActivityIndicator /> : '新增'}
  184. </Text>
  185. }
  186. onPress={() => {
  187. handleSubmit();
  188. }}
  189. disabled={isLoading}
  190. />
  191. <Text> </Text>
  192. </ScrollView>
  193. </SafeAreaView>
  194. );
  195. };
  196. const styles = StyleSheet.create({
  197. button: { flex: 1, gap: 10, marginTop: 5 },
  198. fakeTextInput: {
  199. fontSize: 16,
  200. borderWidth: 1,
  201. padding: 24,
  202. borderRadius: 12,
  203. borderColor: '#bbbbbb',
  204. color: '#888'
  205. },
  206. checkbox: {
  207. margin: 8
  208. }
  209. });
  210. export default chooseCarPageComponent;