列表搜索页面

This commit is contained in:
juguohong
2025-09-06 22:08:34 +08:00
parent c78be00ded
commit 2d0d728969
15 changed files with 518 additions and 128 deletions

View File

@@ -52,7 +52,6 @@ const Bubble: React.FC<BubbleProps> = ({
);
onChange(name, newSelectedValues, selectedOptions);
} else {
console.log('===111', name, option.value)
onChange(name, option.value, option);
}
}

View File

@@ -19,11 +19,12 @@ const Demo3 = (props) => {
const itemRef = useRef(null);
const handleChange = (name: string, value: string) => {
// setIsChange(true);
onChange && onChange(name, value);
(itemRef.current as any)?.toggle(false);
};
// const cityTitle = cityOptions.find((item) => item.value === cityValue)?.label;
return (
<Menu
className="distanceQuickFilterWrap"

View File

@@ -0,0 +1,35 @@
.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;
}
}
}

View File

@@ -0,0 +1,143 @@
import { Popup } from "@nutui/nutui-react-taro";
import Range from "../../components/Range";
import Bubble from "../../components/Bubble";
import styles from "./index.module.scss";
import { Button } from "@nutui/nutui-react-taro";
import { useListStore } from "src/store/listStore";
import { BubbleOption, 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: BubbleOption[] = 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="venueType"
options={locationOptions}
value={filterOptions?.venueType}
/>
{/* 玩法 */}
<GamePlayType
onChange={handleFilterChange}
name="playType"
options={gamePlayOptions}
value={filterOptions?.playType}
/>
{/* 按钮 */}
<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;

View File

@@ -8,14 +8,14 @@ const ListCard: React.FC<ListCardProps> = ({
id,
title,
dateTime,
location,
distance,
venue_description,
distance_km,
registeredCount,
maxCount,
skillLevel,
matchType,
play_type,
images = [],
shinei,
court_type,
}) => {
const renderItemImage = (src: string) => {
return <Image src={src} className="image" mode="aspectFill" />;
@@ -64,17 +64,16 @@ const ListCard: React.FC<ListCardProps> = ({
{/* 左侧内容区域 */}
<View className="content">
{/* 标题 */}
<View className="titleWrapper">
{title && <View className="titleWrapper">
<Text className="title">{title}</Text>
<Image
src={img.ICON_LIST_RIGHT_ARROW}
className="title-right-arrow"
mode="aspectFit"
/>
</View>
</View>}
{/* 时间信息 */}
<View className="date-time">
<Text>{dateTime}</Text>
</View>
@@ -82,10 +81,11 @@ const ListCard: React.FC<ListCardProps> = ({
{/* 地点,室内外,距离 */}
<View className="location">
<Text className="location-text location-position">{location}</Text>
{venue_description &&
<Text className="location-text location-position">{venue_description}</Text>}
<Text className="location-text location-time-distance">
{shinei && `${shinei}`}
{distance && `${distance}`}
{court_type && `${court_type}`}
{distance_km && `${distance_km}`}
</Text>
</View>
@@ -115,11 +115,11 @@ const ListCard: React.FC<ListCardProps> = ({
</Text>
</View>
<View className="tag">
<Text className="tag-text">{skillLevel}</Text>
</View>
<View className="tag">
<Text className="tag-text">{matchType}</Text>
<Text className="tag-text">{skill_level_max} zh {skill_level_max}</Text>
</View>
{play_type && <View className="tag">
<Text className="tag-text">{play_type}</Text>
</View>}
</View>
</View>
</View>

View File

@@ -21,6 +21,7 @@ const SearchBarComponent = (props: IProps) => {
return (
<>
<SearchBar
disabled
clearable={false}
leftIn={
<View className={styles.searchBarLeft}>