列表
This commit is contained in:
@@ -12,6 +12,8 @@ import { FilterPopupProps } from "../../../types/list/types";
|
||||
import CourtType from "@/components/CourtType";
|
||||
// 玩法
|
||||
import GamePlayType from "@/components/GamePlayType";
|
||||
import { useDictionaryActions } from "@/store/dictionaryStore";
|
||||
import { useMemo } from "react";
|
||||
|
||||
const FilterPopup = (props: FilterPopupProps) => {
|
||||
const {
|
||||
@@ -27,7 +29,22 @@ const FilterPopup = (props: FilterPopupProps) => {
|
||||
} = props;
|
||||
|
||||
const store = useListStore() || {};
|
||||
const { timeBubbleData, locationOptions, gamePlayOptions } = store;
|
||||
const { getDictionaryValue } = useDictionaryActions() || {};
|
||||
const { timeBubbleData } = store;
|
||||
|
||||
const handleOptions = (dictionaryValue: []) => {
|
||||
return dictionaryValue?.map((item) => ({ label: item, value: item })) || [];
|
||||
};
|
||||
|
||||
const courtType = getDictionaryValue("court_type") || [];
|
||||
const locationOptions = useMemo(() => {
|
||||
return courtType ? handleOptions(courtType) : [];
|
||||
}, [courtType]);
|
||||
|
||||
const gamePlay = getDictionaryValue("game_play") || [];
|
||||
const gamePlayOptions = useMemo(() => {
|
||||
return gamePlay ? handleOptions(gamePlay) : [];
|
||||
}, [gamePlay]);
|
||||
|
||||
const handleFilterChange = (name, value) => {
|
||||
onChange({ [name]: value });
|
||||
|
||||
@@ -3,20 +3,23 @@
|
||||
|
||||
.listTopSearchWrapper {
|
||||
padding: 0 15px;
|
||||
position: sticky;
|
||||
background: #fefefe;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.isScroll {
|
||||
border-bottom: 0.5px solid #0000000F;
|
||||
}
|
||||
|
||||
.listTopFilterWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.listContentWrapper {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.menuFilter {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,22 @@
|
||||
import ListCard from "../../components/ListCard";
|
||||
import ListCardSkeleton from "../../components/ListCardSkeleton";
|
||||
import List from "../../components/List";
|
||||
import Menu from "../../components/Menu";
|
||||
import CityFilter from "../../components/CityFilter";
|
||||
import SearchBar from "../../components/SearchBar";
|
||||
import FilterPopup from "./FilterPopup";
|
||||
import styles from "./index.module.scss";
|
||||
import { useEffect } from "react";
|
||||
import Taro, { useReachBottom } from "@tarojs/taro";
|
||||
import Taro, { usePageScroll, useReachBottom } from "@tarojs/taro";
|
||||
import { useListStore } from "@/store/listStore";
|
||||
import {useGlobalState} from '@/store/global'
|
||||
import { useGlobalState } from "@/store/global";
|
||||
import { View } from "@tarojs/components";
|
||||
import CustomerNavBar from "@/components/CustomNavbar";
|
||||
import GuideBar from "@/components/GuideBar";
|
||||
import { useDictionaryActions } from "@/store/dictionaryStore";
|
||||
import ListContainer from "@/container/listContainer";
|
||||
|
||||
const ListPage = () => {
|
||||
// 从 store 获取数据和方法
|
||||
const store = useListStore() || {};
|
||||
|
||||
const { statusNavbarHeightInfo } = useGlobalState() || {}
|
||||
const { getDictionaryValue } = useDictionaryActions() || {};
|
||||
console.log('===getDictionaryValue', getDictionaryValue('court_type'));
|
||||
// locationOptions 室内
|
||||
// game_play 玩法
|
||||
const { statusNavbarHeightInfo } = useGlobalState() || {};
|
||||
const {
|
||||
isShowFilterPopup,
|
||||
error,
|
||||
@@ -31,7 +24,6 @@ const ListPage = () => {
|
||||
loading,
|
||||
fetchMatches,
|
||||
refreshMatches,
|
||||
clearError,
|
||||
updateState,
|
||||
filterCount,
|
||||
updateFilterOptions, // 更新筛选条件
|
||||
@@ -40,8 +32,15 @@ const ListPage = () => {
|
||||
distanceData,
|
||||
quickFilterData,
|
||||
distanceQuickFilter,
|
||||
isScrollTop,
|
||||
} = store;
|
||||
|
||||
usePageScroll((res) => {
|
||||
if (res?.scrollTop > 0 && !isScrollTop) {
|
||||
updateState({ isScrollTop: true });
|
||||
}
|
||||
});
|
||||
|
||||
useReachBottom(() => {
|
||||
console.log("触底了");
|
||||
// 调用 store 的加载更多方法
|
||||
@@ -82,78 +81,6 @@ const ListPage = () => {
|
||||
});
|
||||
});
|
||||
|
||||
// 错误处理
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
Taro.showToast({
|
||||
title: error,
|
||||
icon: "error",
|
||||
duration: 2000,
|
||||
});
|
||||
// 3秒后自动清除错误
|
||||
setTimeout(() => {
|
||||
clearError();
|
||||
}, 3000);
|
||||
}
|
||||
}, [error, clearError]);
|
||||
|
||||
// 加载状态显示
|
||||
if (loading && matches.length === 0) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "200px",
|
||||
fontSize: "14px",
|
||||
color: "#999",
|
||||
}}
|
||||
>
|
||||
<div style={{ marginBottom: "10px" }}>加载中...</div>
|
||||
<div style={{ fontSize: "12px", color: "#ccc" }}>
|
||||
正在获取网球比赛数据
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 错误状态显示
|
||||
if (error && matches.length === 0) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "200px",
|
||||
fontSize: "14px",
|
||||
color: "#999",
|
||||
}}
|
||||
>
|
||||
<div style={{ marginBottom: "10px" }}>加载失败</div>
|
||||
<div style={{ marginBottom: "15px", fontSize: "12px", color: "#ccc" }}>
|
||||
{error}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => fetchMatches()}
|
||||
style={{
|
||||
padding: "8px 16px",
|
||||
fontSize: "12px",
|
||||
color: "#fff",
|
||||
backgroundColor: "#007aff",
|
||||
border: "none",
|
||||
borderRadius: "4px",
|
||||
}}
|
||||
>
|
||||
重试
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const toggleShowPopup = () => {
|
||||
updateState({ isShowFilterPopup: !isShowFilterPopup });
|
||||
};
|
||||
@@ -183,7 +110,14 @@ const ListPage = () => {
|
||||
<CustomerNavBar />
|
||||
|
||||
<View className={styles.listPage}>
|
||||
<View className={styles.listTopSearchWrapper}>
|
||||
<View
|
||||
className={`${styles.listTopSearchWrapper} ${
|
||||
isScrollTop ? styles.isScroll : ""
|
||||
}`}
|
||||
style={{
|
||||
top: statusNavbarHeightInfo?.totalHeight,
|
||||
}}
|
||||
>
|
||||
<SearchBar
|
||||
handleFilterIcon={toggleShowPopup}
|
||||
isSelect={filterCount > 0}
|
||||
@@ -227,26 +161,16 @@ const ListPage = () => {
|
||||
</div>
|
||||
</View>
|
||||
|
||||
<View className={styles.listContentWrapper}>
|
||||
{/* 列表内容 */}
|
||||
<List>
|
||||
{!loading &&
|
||||
matches.length > 0 &&
|
||||
matches.map((match, index) => (
|
||||
<ListCard key={match.id || index} {...match} />
|
||||
))}
|
||||
</List>
|
||||
|
||||
{/* 空状态 */}
|
||||
{loading &&
|
||||
matches.length === 0 &&
|
||||
new Array(10).fill(0).map(() => {
|
||||
return <ListCardSkeleton />;
|
||||
})}
|
||||
</View>
|
||||
<ListContainer
|
||||
data={matches}
|
||||
loading={loading}
|
||||
error={error}
|
||||
reload={refreshMatches}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<GuideBar currentPage='list' />
|
||||
<GuideBar currentPage="list" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user