|
@@ -0,0 +1,146 @@
|
|
|
+import React, { useCallback, useEffect, useState } from 'react';
|
|
|
+import { View, Text, FlatList, Image, TouchableOpacity } from 'react-native';
|
|
|
+
|
|
|
+import { Header, PageWrapper, HorizontalTabView, Loading } from 'src/components';
|
|
|
+import { useGetSeriesGroups, useGetSeriesWithGroup } from '@api/series';
|
|
|
+import { useFocusEffect } from '@react-navigation/native';
|
|
|
+
|
|
|
+import { API_HOST } from 'src/constants';
|
|
|
+import { StoreType, storage } from 'src/storage';
|
|
|
+import { styles } from './styles';
|
|
|
+
|
|
|
+interface SeriesGroup {
|
|
|
+ key: string;
|
|
|
+ title: string;
|
|
|
+}
|
|
|
+
|
|
|
+interface SeriesList {
|
|
|
+ id: number;
|
|
|
+ name: string;
|
|
|
+ icon: string;
|
|
|
+ count: number;
|
|
|
+ new: number;
|
|
|
+ score: number;
|
|
|
+ icon_png: string;
|
|
|
+ count2: number;
|
|
|
+}
|
|
|
+
|
|
|
+const SeriesScreen = () => {
|
|
|
+ const [isLoading, setIsLoading] = useState(true);
|
|
|
+ const [index, setIndex] = useState(0);
|
|
|
+ const [routes, setRoutes] = useState<SeriesGroup[]>([]);
|
|
|
+ const { data } = useGetSeriesGroups(true);
|
|
|
+
|
|
|
+ useFocusEffect(
|
|
|
+ useCallback(() => {
|
|
|
+ const fetchRanking = async () => {
|
|
|
+ let staticGroups = [
|
|
|
+ {
|
|
|
+ key: '-1',
|
|
|
+ title: 'Top of the tops'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: '-2',
|
|
|
+ title: 'Milestones'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'all',
|
|
|
+ title: 'All series'
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ const routesData = data?.data?.map((item) => ({
|
|
|
+ key: item.id.toString(),
|
|
|
+ title: item.name
|
|
|
+ }));
|
|
|
+
|
|
|
+ routesData && staticGroups.push(...routesData);
|
|
|
+
|
|
|
+ setRoutes(staticGroups);
|
|
|
+ setIsLoading(false);
|
|
|
+ };
|
|
|
+
|
|
|
+ if (data && data.data) {
|
|
|
+ fetchRanking();
|
|
|
+ }
|
|
|
+ }, [data])
|
|
|
+ );
|
|
|
+
|
|
|
+ if (isLoading) return <Loading />;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <PageWrapper>
|
|
|
+ <Header label={'Series'} />
|
|
|
+ <HorizontalTabView
|
|
|
+ index={index}
|
|
|
+ setIndex={setIndex}
|
|
|
+ routes={routes}
|
|
|
+ renderScene={({ route }: { route: SeriesGroup }) => <SeriesList groupId={route.key} />}
|
|
|
+ />
|
|
|
+ </PageWrapper>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const SeriesList = React.memo(({ groupId }: { groupId: string }) => {
|
|
|
+ const [seriesData, setSeriesData] = useState<SeriesList[]>([]);
|
|
|
+ const [isLoading, setIsLoading] = useState(true);
|
|
|
+
|
|
|
+ const token = storage.get('token', StoreType.STRING) as string;
|
|
|
+ const { mutateAsync } = useGetSeriesWithGroup();
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const fetchSeriesData = async () => {
|
|
|
+ try {
|
|
|
+ await mutateAsync(
|
|
|
+ { group: groupId, token: token },
|
|
|
+ {
|
|
|
+ onSuccess: (data) => {
|
|
|
+ setSeriesData(data.data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Failed to fetch series data', error);
|
|
|
+ } finally {
|
|
|
+ setIsLoading(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ fetchSeriesData();
|
|
|
+ }, [groupId]);
|
|
|
+
|
|
|
+ if (isLoading) return <Loading />;
|
|
|
+
|
|
|
+ const renderItem = ({ item }: { item: SeriesList }) => {
|
|
|
+ return (
|
|
|
+ <TouchableOpacity style={styles.itemContainer}>
|
|
|
+ <Image style={styles.icon} source={{ uri: API_HOST + item.icon_png }} />
|
|
|
+
|
|
|
+ <View style={styles.infoContainer}>
|
|
|
+ <View style={styles.titleContainer}>
|
|
|
+ <Text style={styles.title}>{item.name}</Text>
|
|
|
+ {item.new === 1 && <Text style={styles.textNew}>NEW</Text>}
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <View style={styles.detailsContainer}>
|
|
|
+ <Text style={styles.details}>Total objects: {item.count}</Text>
|
|
|
+ <Text style={styles.count}>
|
|
|
+ {item.score} / {item.count}
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </TouchableOpacity>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <FlatList
|
|
|
+ horizontal={false}
|
|
|
+ data={seriesData}
|
|
|
+ renderItem={renderItem}
|
|
|
+ keyExtractor={(item) => item.id.toString()}
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
+ />
|
|
|
+ );
|
|
|
+});
|
|
|
+
|
|
|
+export default SeriesScreen;
|