列表搜索页面
This commit is contained in:
@@ -1,146 +0,0 @@
|
||||
import { Popup } from "@nutui/nutui-react-taro";
|
||||
import Range from "../../components/Range";
|
||||
import Bubble from "../../components/Bubble";
|
||||
import styles from "./filterPopup.module.scss";
|
||||
import TitleComponent from "@/components/Title";
|
||||
import { Button } from "@nutui/nutui-react-taro";
|
||||
import { Image } from "@tarojs/components";
|
||||
import img from "../../config/images";
|
||||
import { useListStore } from "src/store/listStore";
|
||||
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 {
|
||||
loading,
|
||||
onCancel,
|
||||
onConfirm,
|
||||
onChange,
|
||||
filterOptions,
|
||||
onClear,
|
||||
visible,
|
||||
onClose,
|
||||
statusNavbarHeigh,
|
||||
} = props;
|
||||
|
||||
const store = useListStore() || {};
|
||||
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 });
|
||||
};
|
||||
|
||||
const handleClearFilter = () => {
|
||||
onClear();
|
||||
onCancel();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Popup
|
||||
destroyOnClose
|
||||
position="top"
|
||||
round
|
||||
visible={visible}
|
||||
onClose={onClose}
|
||||
style={{ marginTop: statusNavbarHeigh + "px" }}
|
||||
overlayStyle={{ marginTop: statusNavbarHeigh + "px" }}
|
||||
>
|
||||
<div className={styles.filterPopupWrapper}>
|
||||
{/* 时间气泡选项 */}
|
||||
<Bubble
|
||||
options={timeBubbleData}
|
||||
value={filterOptions?.time}
|
||||
onChange={handleFilterChange}
|
||||
layout="grid"
|
||||
size="small"
|
||||
columns={3}
|
||||
name="time"
|
||||
/>
|
||||
|
||||
{/* 范围选择 */}
|
||||
<Range
|
||||
min={1.0}
|
||||
max={5.0}
|
||||
step={0.5}
|
||||
className={styles.filterPopupRange}
|
||||
onChange={handleFilterChange}
|
||||
value={filterOptions?.ntrp}
|
||||
name="ntrp"
|
||||
/>
|
||||
|
||||
{/* 场次气泡选项 */}
|
||||
{/* <div>
|
||||
<TitleComponent
|
||||
title="场地类型"
|
||||
icon={<Image src={img.ICON_SITE} />}
|
||||
/>
|
||||
<Bubble
|
||||
options={locationOptions}
|
||||
value={filterOptions?.site}
|
||||
onChange={handleFilterChange}
|
||||
layout="grid"
|
||||
size="small"
|
||||
columns={3}
|
||||
name="site"
|
||||
/>
|
||||
</div> */}
|
||||
{/* CourtType */}
|
||||
<CourtType
|
||||
onChange={handleFilterChange}
|
||||
name="court_type"
|
||||
options={locationOptions}
|
||||
value={filterOptions?.site}
|
||||
/>
|
||||
{/* 玩法 */}
|
||||
<GamePlayType
|
||||
onChange={handleFilterChange}
|
||||
name="game_play"
|
||||
options={gamePlayOptions}
|
||||
value={filterOptions?.game_play}
|
||||
/>
|
||||
{/* 按钮 */}
|
||||
<div className={styles.filterPopupBtnWrapper}>
|
||||
<Button
|
||||
className={styles.btn}
|
||||
type="default"
|
||||
onClick={handleClearFilter}
|
||||
>
|
||||
清空全部
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.btn} ${styles.confirm}`}
|
||||
type="default"
|
||||
loading={loading}
|
||||
onClick={onConfirm}
|
||||
>
|
||||
显示 332 场球局
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Popup>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default FilterPopup;
|
||||
@@ -1,35 +0,0 @@
|
||||
.filterPopupWrapper {
|
||||
position: relative;
|
||||
$m18: 18px;
|
||||
padding: $m18;
|
||||
|
||||
.filterPopupRange {
|
||||
margin-top: $m18;
|
||||
margin-bottom: $m18;
|
||||
}
|
||||
|
||||
.filterPopupBtnWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
background-color: #ffffff;
|
||||
padding: 8px 0;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
--nutui-button-border-width: 0.5px;
|
||||
--nutui-button-default-border-color: #0000000F;
|
||||
--nutui-button-border-radius: 16px;
|
||||
--nutui-button-default-height: 44px;
|
||||
--nutui-button-default-color: #000000;
|
||||
.confirm {
|
||||
--nutui-button-default-color: #ffffff;
|
||||
--nutui-button-default-background-color: #000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
import Menu from "../../components/Menu";
|
||||
import CityFilter from "../../components/CityFilter";
|
||||
import SearchBar from "../../components/SearchBar";
|
||||
import FilterPopup from "./FilterPopup";
|
||||
import FilterPopup from "@/components/FilterPopup";
|
||||
import styles from "./index.module.scss";
|
||||
import { useEffect } from "react";
|
||||
import Taro, { usePageScroll, useReachBottom } from "@tarojs/taro";
|
||||
import Taro, { usePageScroll } from "@tarojs/taro";
|
||||
import { useListStore } from "@/store/listStore";
|
||||
import { useGlobalState } from "@/store/global";
|
||||
import { View } from "@tarojs/components";
|
||||
@@ -19,7 +17,7 @@ const ListPage = () => {
|
||||
// 从 store 获取数据和方法
|
||||
const store = useListStore() || {};
|
||||
|
||||
const { statusNavbarHeightInfo } = useGlobalState() || {};
|
||||
const { statusNavbarHeightInfo, location } = useGlobalState() || {};
|
||||
const { totalHeight } = statusNavbarHeightInfo || {};
|
||||
const {
|
||||
isShowFilterPopup,
|
||||
@@ -43,25 +41,18 @@ const ListPage = () => {
|
||||
} = store;
|
||||
|
||||
usePageScroll((res) => {
|
||||
// if (res?.scrollTop > 0 && !isScrollTop) {
|
||||
// updateState({ isScrollTop: true });
|
||||
// }
|
||||
if (res?.scrollTop >= totalHeight && !isScrollTop) {
|
||||
updateState({ isShowInputCustomerNavBar: true });
|
||||
!isShowInputCustomerNavBar && updateState({ isShowInputCustomerNavBar: true });
|
||||
} else {
|
||||
updateState({ isShowInputCustomerNavBar: false });
|
||||
isShowInputCustomerNavBar && updateState({ isShowInputCustomerNavBar: false });
|
||||
}
|
||||
});
|
||||
|
||||
useReachBottom(() => {
|
||||
console.log("触底了");
|
||||
// 调用 store 的加载更多方法
|
||||
// loadMoreMatches();
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// 页面加载时获取数据
|
||||
fetchMatches();
|
||||
// 保存位置
|
||||
updateState({ location });
|
||||
}, []);
|
||||
|
||||
// 下拉刷新处理函数 - 使用Taro生命周期钩子
|
||||
|
||||
@@ -5,11 +5,60 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 5px 0px 10px 0px;
|
||||
padding: 5px 15px 10px 15px;
|
||||
position: sticky;
|
||||
top: -1px;
|
||||
background-color: #fefefe;
|
||||
z-index: 123;
|
||||
|
||||
.nut-menu-bar {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nut-menu-container-wrap {
|
||||
left: -15px;
|
||||
}
|
||||
|
||||
.filterIconWrapper {
|
||||
display: flex;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-shrink: 0;
|
||||
aspect-ratio: 1/1;
|
||||
border-radius: 999px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.06);
|
||||
background: #FFF;
|
||||
position: relative;
|
||||
|
||||
&.active {
|
||||
background-color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
.filterIcon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.filterCount {
|
||||
background-color: #000000;
|
||||
position: absolute;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 2px solid #ffffff;
|
||||
border-radius: 50%;
|
||||
right: -5px;
|
||||
bottom: -5px;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.menuFilter {
|
||||
|
||||
@@ -1,34 +1,53 @@
|
||||
import { View } from "@tarojs/components";
|
||||
import { useListState } from "@/store/listStore";
|
||||
import { View, Image, Text } from "@tarojs/components";
|
||||
import { useSearchResultState } from "@/store/searchResultStore";
|
||||
import { useGlobalState } from "@/store/global";
|
||||
import ListContainer from "@/container/listContainer";
|
||||
import img from "@/config/images";
|
||||
|
||||
import "./index.scss";
|
||||
import DistanceQuickFilter from "@/components/DistanceQuickFilter";
|
||||
import { useEffect } from "react";
|
||||
import FilterPopup from "@/components/FilterPopup";
|
||||
|
||||
const SearchResult = () => {
|
||||
const {
|
||||
distanceData,
|
||||
quickFilterData,
|
||||
isShowFilterPopup,
|
||||
error,
|
||||
distanceQuickFilter,
|
||||
updateState,
|
||||
matches,
|
||||
recommendList,
|
||||
loading,
|
||||
error,
|
||||
refreshMatches,
|
||||
fetchMatches,
|
||||
} = useListState() || {};
|
||||
|
||||
refreshMatches,
|
||||
updateState,
|
||||
filterCount,
|
||||
updateFilterOptions, // 更新筛选条件
|
||||
filterOptions,
|
||||
clearFilterOptions,
|
||||
distanceData,
|
||||
quickFilterData,
|
||||
} = useSearchResultState() || {};
|
||||
const { statusNavbarHeightInfo } = useGlobalState() || {};
|
||||
const { totalHeight } = statusNavbarHeightInfo || {}
|
||||
const { totalHeight } = statusNavbarHeightInfo || {};
|
||||
const isSelect = filterCount > 0;
|
||||
|
||||
useEffect(() => {
|
||||
// 页面加载时获取数据
|
||||
fetchMatches();
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* @description 更新筛选条件
|
||||
* @param {Record<string, any>} params 筛选项
|
||||
*/
|
||||
const handleUpdateFilterOptions = (params: Record<string, any>) => {
|
||||
updateFilterOptions(params);
|
||||
};
|
||||
|
||||
const toggleShowPopup = () => {
|
||||
updateState({ isShowFilterPopup: !isShowFilterPopup });
|
||||
};
|
||||
|
||||
// 距离筛选
|
||||
const handleDistanceOrQuickChange = (name, value) => {
|
||||
updateState({
|
||||
@@ -42,10 +61,15 @@ const SearchResult = () => {
|
||||
return (
|
||||
<View className="searchResultPage">
|
||||
{/* 筛选 */}
|
||||
<View className='searchResultFilterWrapper' style={{
|
||||
// top: `${totalHeight}px`
|
||||
}}>
|
||||
<DistanceQuickFilter
|
||||
<View
|
||||
className="searchResultFilterWrapper"
|
||||
style={
|
||||
{
|
||||
// top: `${totalHeight}px`
|
||||
}
|
||||
}
|
||||
>
|
||||
<DistanceQuickFilter
|
||||
cityOptions={distanceData}
|
||||
quickOptions={quickFilterData}
|
||||
onChange={handleDistanceOrQuickChange}
|
||||
@@ -54,6 +78,31 @@ const SearchResult = () => {
|
||||
cityValue={distanceQuickFilter?.distance}
|
||||
quickValue={distanceQuickFilter?.quick}
|
||||
/>
|
||||
{/* 筛选 icon */}
|
||||
<View className={`filterIconWrapper ${isSelect && 'active'}`} onClick={toggleShowPopup}>
|
||||
<Image
|
||||
src={isSelect ? img.ICON_FILTER_SELECTED : img.ICON_FILTER}
|
||||
className={`filterIcon ${isSelect && 'active'}`}
|
||||
/>
|
||||
{isSelect && <Text className="filterCount">{filterCount}</Text>}
|
||||
</View>
|
||||
{/* 筛选弹框 */}
|
||||
{/* 综合筛选 */}
|
||||
{isShowFilterPopup && (
|
||||
<View>
|
||||
<FilterPopup
|
||||
loading={loading}
|
||||
onCancel={toggleShowPopup}
|
||||
onConfirm={toggleShowPopup}
|
||||
onChange={handleUpdateFilterOptions}
|
||||
filterOptions={filterOptions}
|
||||
onClear={clearFilterOptions}
|
||||
visible={isShowFilterPopup}
|
||||
onClose={toggleShowPopup}
|
||||
statusNavbarHeigh={0}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* 列表内容 */}
|
||||
@@ -68,4 +117,4 @@ const SearchResult = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchResult;
|
||||
export default SearchResult;
|
||||
|
||||
Reference in New Issue
Block a user