| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- import React, { useEffect, useState } from 'react';
- import { View, Text, Image, Pressable, StyleSheet, ScrollView, ActivityIndicator } from 'react-native';
- import { FlashList } from '@shopify/flash-list';
- import { router } from 'expo-router';
- import { SafeAreaView } from 'react-native-safe-area-context';
- import useVehicleStore from '../../providers/vehicle_store';
- import { chargeStationService } from '../../service/chargeStationService';
- import { PreviousPageBlackSvg } from '../../component/global/SVG';
- interface AlphabetSection {
- letter: string;
- brands: CarBrand[];
- }
- interface CarBrand {
- id: number;
- name: string;
- img_url: string;
- car_types: any[];
- }
- const brandLogos = {
- audi: require('../../assets/audi.png'),
- benz: require('../../assets/benz.png'),
- bmw: require('../../assets/bmw.png'),
- byd: require('../../assets/byd.png'),
- lexus: require('../../assets/lexus.png'),
- mg: require('../../assets/mg.png'),
- porsche: require('../../assets/porsche.png'),
- tesla: require('../../assets/tesla.png'),
- toyota: require('../../assets/toyota.png'),
- xiaomi: require('../../assets/xiaomi.png')
- // Add all other brands here
- };
- const RegisterChooseVehiclesOne = () => {
- const [loading, setLoading] = useState(true);
- const [processedCarData, setProcessedCarData] = useState<CarBrand[]>([]);
- const { vehicleBrand, vehicleModel, BrandID, ModelID, setVehicleBrand, setBrandID } = useVehicleStore();
- useEffect(() => {
- const fetchCarBrand = async () => {
- try {
- const response = await chargeStationService.fetchCarBrand();
- if (response) {
- setProcessedCarData(response.data);
- }
- } catch (error) {
- console.log(error);
- } finally {
- setLoading(false);
- }
- };
- fetchCarBrand();
- }, []);
- useEffect(() => {}, [processedCarData]);
- const renderBrandItem = ({ item: brand }: { item: CarBrand }) => (
- <Pressable
- key={brand.id}
- style={styles.brandItem}
- onPress={() => {
- setVehicleBrand(brand.name);
- setBrandID(brand.id);
- router.push({
- pathname: 'registerChooseVehiclesTwo',
- params: {
- brandId: brand.id.toString(),
- brandName: brand.name,
- carTypes: JSON.stringify(brand.car_types)
- }
- });
- }}
- >
- <Image source={brandLogos[brand.name.toLowerCase()]} style={styles.logo} resizeMode="contain" />
- <Text style={styles.brandName}>{brand.name}</Text>
- </Pressable>
- );
- const renderAlphabetSection = ({ item: section }: { item: AlphabetSection }) => (
- <View>
- <View style={styles.letterHeader} className="h-9">
- <Text style={styles.letterText}>{section.letter}</Text>
- </View>
- <View style={styles.brandRow}>{section.brands.map((brand) => renderBrandItem({ item: brand }))}</View>
- </View>
- );
- return (
- <SafeAreaView className="flex-1 bg-white" edges={['top', 'right', 'left']}>
- <ScrollView showsVerticalScrollIndicator={false} className="flex-1 mx-[5%]">
- <View style={{ marginTop: 25 }}>
- <Pressable
- className="self-start"
- onPress={() => {
- if (router.canGoBack()) {
- router.back();
- } else {
- router.replace('/accountMainPage');
- }
- }}
- >
- <PreviousPageBlackSvg />
- </Pressable>
- <Text
- style={{
- fontSize: 30,
- marginTop: 25,
- marginBottom: 10
- }}
- >
- 選擇品牌
- </Text>
- </View>
- {loading ? (
- <View className="flex h-full items-center justify-center">
- <ActivityIndicator />
- </View>
- ) : (
- <View className="flex-1 min-h-[80vh]">
- <FlashList
- estimatedItemSize={100}
- data={processedCarData
- .sort((a, b) => a.name.localeCompare(b.name))
- .reduce((acc, brand) => {
- const letter = brand.name[0].toUpperCase();
- const existingSection = acc.find((section) => section.letter === letter);
- if (existingSection) {
- existingSection.brands.push(brand);
- } else {
- acc.push({ letter, brands: [brand] });
- }
- return acc;
- }, [] as AlphabetSection[])}
- renderItem={renderAlphabetSection}
- keyExtractor={(item) => item.letter}
- />
- </View>
- )}
- </ScrollView>
- </SafeAreaView>
- );
- };
- const styles = StyleSheet.create({
- letterHeader: {
- backgroundColor: '#E3F2F8',
- padding: 10,
- marginVertical: 10
- },
- letterText: {
- color: '#02677D',
- fontSize: 14,
- fontWeight: 'bold'
- },
- brandRow: {
- flexDirection: 'row',
- flexWrap: 'wrap'
- },
- brandItem: {
- width: '33.33%',
- alignItems: 'center',
- padding: 10
- },
- logo: {
- width: 80,
- height: 80
- },
- brandName: {
- marginTop: 5,
- textAlign: 'center'
- }
- });
- export default RegisterChooseVehiclesOne;
|