| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- interface AlphabetSection {
- letter: string;
- brands: CarBrand[];
- }
- 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';
- const RegisterChooseVehiclesOne = () => {
- const [loading, setLoading] = useState(true);
- const [carData, setCarData] = useState();
- const [extractedCarNameAndImgUrl, setExtractedCarNameAndImgUrl] = useState('');
- const [processedCarData, setProcessedCarData] = useState([]);
- const {
- vehicleBrand,
- vehicleModel,
- BrandID,
- ModelID,
- licensePlate,
- setVehicleBrand,
- setVehicleModel,
- setBrandID,
- setModelID,
- setLicensePlate
- } = useVehicleStore();
- //this uses getCarBrand to create an array of object with 2 keys: name and img_url
- useEffect(() => {
- const fetchCarBrand = async () => {
- try {
- const response = await chargeStationService.fetchCarBrand();
- if (response) {
- const processedData = await Promise.all(
- response.data.map(async (car) => ({
- ...car,
- logo: await chargeStationService.getProcessedCarImageUrl(car.img_url)
- }))
- );
- setProcessedCarData(processedData);
- }
- } catch (error) {
- console.log(error);
- } finally {
- setLoading(false);
- }
- };
- fetchCarBrand();
- }, []);
- useEffect(() => {
- console.log('Zustand VehicleBrand', vehicleBrand);
- console.log('Zustand BrandID', BrandID);
- console.log('Zustand VehicleModel', vehicleModel);
- console.log('Zustand ModelID', ModelID);
- }, [processedCarData]);
- const renderBrandItem = ({ item: brand }: { item }) => (
- <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={{ uri: brand.logo }} 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>
- )}
- {/*
- <View className="flex-1 min-h-[80vh]">
- <FlashList
- estimatedItemSize={100}
- data={processedCarData.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;
|