diff --git a/src/app.ts b/src/app.ts index d773185..cf34ab9 100644 --- a/src/app.ts +++ b/src/app.ts @@ -6,9 +6,6 @@ import { useDictionaryStore } from './store/dictionaryStore' import { useGlobalStore } from './store/global' import { check_login_status } from './services/loginService'; - -// import { getNavbarHeight } from "@/utils/getNavbarHeight"; - interface AppProps { children: ReactNode } @@ -31,6 +28,7 @@ class App extends Component { // 初始化字典数据 this.initDictionaryData() this.getNavBarHeight() + this.getLocation() } componentDidShow() { } @@ -51,7 +49,12 @@ class App extends Component { getNavBarHeight = () => { const { getNavbarHeightInfo } = useGlobalStore.getState() getNavbarHeightInfo() + } + // 获取位置信息 + getLocation = () => { + const { getCurrentLocationInfo } = useGlobalStore.getState() + getCurrentLocationInfo() } render() { diff --git a/src/components/CalendarCard/index.module.scss b/src/components/CalendarCard/index.module.scss index e68e1ef..ddcfd00 100644 --- a/src/components/CalendarCard/index.module.scss +++ b/src/components/CalendarCard/index.module.scss @@ -30,6 +30,7 @@ } .arrow { width: 10px; + height: 20px; position: relative; } .arrow.left { diff --git a/src/components/DistanceQuickFilter/index.scss b/src/components/DistanceQuickFilter/index.scss index 8ce9f96..ebd5258 100644 --- a/src/components/DistanceQuickFilter/index.scss +++ b/src/components/DistanceQuickFilter/index.scss @@ -35,18 +35,18 @@ border-bottom-right-radius: 30px; } - .nut-menu-container-item { - color: rgba(60, 60, 67, 0.60); - font-size: 14px; - font-weight: 600; - line-height: 20px; - } + // .nut-menu-container-item { + // color: rgba(60, 60, 67, 0.6); + // font-size: 14px; + // font-weight: 600; + // line-height: 20px; + // } - .nut-menu-container-item.active { - flex-direction: row-reverse; - justify-content: space-between; - color: #000; - } + // .nut-menu-container-item.active { + // flex-direction: row-reverse; + // justify-content: space-between; + // color: #000; + // } .positionWrap { display: flex; @@ -88,4 +88,40 @@ width: 20px; height: 20px; } -} \ No newline at end of file + + .quickOptionsWrapper { + width: 100%; + display: flex; + flex-direction: column; + + .quickItem { + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px 0; + color: rgba(60, 60, 67, 0.6); + font-size: 14px; + font-weight: 600; + line-height: 20px; + &.active { + color: #000; + } + } + } +} + +.distanceQuickFilterWrap_0 .nut-menu-title-0 { + background-color: #000; + color: #fff; + &.active { + color: #ffffff; + } +} + +.distanceQuickFilterWrap_1 .nut-menu-title-1 { + background-color: #000; + color: #fff; + &.active { + color: #ffffff; + } +} diff --git a/src/components/DistanceQuickFilter/index.tsx b/src/components/DistanceQuickFilter/index.tsx index 0bfc283..6c48e54 100644 --- a/src/components/DistanceQuickFilter/index.tsx +++ b/src/components/DistanceQuickFilter/index.tsx @@ -1,6 +1,6 @@ -import React, { useRef, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { Menu, Button } from "@nutui/nutui-react-taro"; -import { Image } from "@tarojs/components"; +import { Image, View, Text } from "@tarojs/components"; import img from "@/config/images"; import Bubble from "../Bubble"; import "./index.scss"; @@ -15,23 +15,46 @@ const Demo3 = (props) => { cityValue, quickValue, } = props; + const cityRef = useRef(null); + const quickRef = useRef(null); + const [changePosition, setChangePosition] = useState([]); - const itemRef = useRef(null); + // 全城筛选显示的标题 + const cityTitle = cityOptions.find((item) => item.value === cityValue)?.label; - const handleChange = (name: string, value: string) => { + // 快捷筛选显示的标题 + const quickTitle = quickOptions.find( + (item) => item.value === quickValue + )?.label; + + // className + const filterWrapperClassName = changePosition.reduce((pre, cur) => { + return `${pre} distanceQuickFilterWrap_${cur}`; + }, ""); + + const handleChange = ( + name: string, + value: string | number, + index: number + ) => { + setChangePosition((preState) => { + const newData = new Set([...preState, index]); + return Array.from(newData); + }); onChange && onChange(name, value); - (itemRef.current as any)?.toggle(false); - }; - // const cityTitle = cityOptions.find((item) => item.value === cityValue)?.label; + // 控制隐藏 + index === 0 && (cityRef.current as any)?.toggle(false); + index === 1 && (quickRef.current as any)?.toggle(false); + }; return ( } >
@@ -42,7 +65,7 @@ const Demo3 = (props) => { handleChange(name, value, 0)} layout="grid" size="small" columns={4} @@ -52,30 +75,35 @@ const Demo3 = (props) => {
handleChange(quickName, value)} - icon={} - /> - {/* -
- 自定义内容 -
- -
*/} + // options={quickOptions} + // onChange={(value) => handleChange(quickName, value, 1)} + // icon={} + > + + {quickOptions.map((item) => { + const active = quickValue === item?.value; + return ( + handleChange(quickName, item.value, 1)} + > + {item?.label} + {active && ( + + + + )} + + ); + })} + +
); }; diff --git a/src/components/FilterPopup/index.tsx b/src/components/FilterPopup/index.tsx index ecc341d..a83a5bb 100644 --- a/src/components/FilterPopup/index.tsx +++ b/src/components/FilterPopup/index.tsx @@ -5,12 +5,23 @@ 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 CalendarCard from "@/components/CalendarCard/index"; +import dateRangeUtils from '@/utils/dateRange' + // 场地 import CourtType from "@/components/CourtType"; // 玩法 import GamePlayType from "@/components/GamePlayType"; import { useDictionaryActions } from "@/store/dictionaryStore"; import { useMemo } from "react"; +import { View } from "@tarojs/components"; + + +const dateTrabseformMap = { + '1': dateRangeUtils.getThisWeekend, + '2': dateRangeUtils.getNextWeekRange, + '3': dateRangeUtils.getNextMonthRange +} const FilterPopup = (props: FilterPopupProps) => { const { @@ -24,34 +35,75 @@ const FilterPopup = (props: FilterPopupProps) => { onClose, statusNavbarHeigh, } = props; - const store = useListStore() || {}; const { getDictionaryValue } = useDictionaryActions() || {}; - const { timeBubbleData } = store; + const { timeBubbleData, gamesNum, dateRangeOptions } = store; + /** + * @description 处理字典选项 + * @param dictionaryValue 字典选项 + * @returns 选项列表 + */ const handleOptions = (dictionaryValue: []) => { return dictionaryValue?.map((item) => ({ label: item, value: item })) || []; }; + /** + * @description 场地类型选项 + */ const courtType = getDictionaryValue("court_type") || []; const locationOptions: BubbleOption[] = useMemo(() => { return courtType ? handleOptions(courtType) : []; }, [courtType]); + /** + * @description 玩法选项 + */ const gamePlay = getDictionaryValue("game_play") || []; const gamePlayOptions = useMemo(() => { return gamePlay ? handleOptions(gamePlay) : []; }, [gamePlay]); + /** + * @description 筛选选项改变 + * @param name 选项名称 + * @param value 选项值 + */ const handleFilterChange = (name, value) => { onChange({ [name]: value }); }; + /** + * @description 清空筛选 + */ const handleClearFilter = () => { onClear(); onCancel(); }; + /** + * @description 日期选择 + * @param date 日期 + */ + const handleDateRangeChange = (date: Date) => { + onChange({ + 'dateRange': [date, date], + 'dateRangeQuick': '', + }) + } + + /** + * @description 点击 本周末 一周内 一月内 + */ + const handleDateRangeQuickClick = (name, value) => { + const date = dateTrabseformMap?.[value]() + onChange({ + 'dateRange': [date?.start, date?.end], + [name]: value, + }) + } + + return ( <> { onClose={onClose} style={{ marginTop: statusNavbarHeigh + "px" }} overlayStyle={{ marginTop: statusNavbarHeigh + "px" }} + zIndex={1001} >
+ {/* 日历 */} + + {/* 快捷选日期 */} + + + + + {/* 时间气泡选项 */} {/* 范围选择 */} @@ -131,7 +204,7 @@ const FilterPopup = (props: FilterPopupProps) => { loading={loading} onClick={onConfirm} > - 显示 332 场球局 + 显示 {gamesNum} 场球局
diff --git a/src/components/ListCard/index.scss b/src/components/ListCard/index.scss index bcb39aa..55b619c 100644 --- a/src/components/ListCard/index.scss +++ b/src/components/ListCard/index.scss @@ -51,7 +51,7 @@ } .location-position { - max-width: 66%; + max-width: 50%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; diff --git a/src/components/ListCard/index.tsx b/src/components/ListCard/index.tsx index b7e3c7b..e68ea26 100644 --- a/src/components/ListCard/index.tsx +++ b/src/components/ListCard/index.tsx @@ -7,18 +7,23 @@ import "./index.scss"; const ListCard: React.FC = ({ id, title, - dateTime, - venue_description, + start_time, + location, distance_km, - registeredCount, - maxCount, - skillLevel, + current_players, + max_players, + skill_level_min, + skill_level_max, play_type, - images = [], + image_list = [], court_type, + key }) => { const renderItemImage = (src: string) => { - return ; + return ; }; const handleViewDetail = () => { @@ -30,21 +35,21 @@ const ListCard: React.FC = ({ // 根据图片数量决定展示样式 const renderImages = () => { - if (images?.length === 0) return null; + if (image_list?.length === 0) return null; - if (images?.length === 1) { + if (image_list?.length === 1) { return ( - {renderItemImage(images[0])} + {renderItemImage(image_list?.[0])} ); } - if (images?.length === 2) { + if (image_list?.length === 2) { return ( - {renderItemImage(images[0])} - {renderItemImage(images[1])} + {renderItemImage(image_list?.[0])} + {renderItemImage(image_list?.[1])} ); } @@ -52,14 +57,14 @@ const ListCard: React.FC = ({ // 3张或更多图片 return ( - {renderItemImage(images?.[0])} - {renderItemImage(images?.[1])} - {renderItemImage(images?.[2])} + {renderItemImage(image_list?.[0])} + {renderItemImage(image_list?.[1])} + {renderItemImage(image_list?.[2])} ); }; return ( - + {/* 左侧内容区域 */} @@ -75,17 +80,17 @@ const ListCard: React.FC = ({ {/* 时间信息 */} - {dateTime} + {start_time} {/* 地点,室内外,距离 */} - {venue_description && - {venue_description}} + {location && + {location}} {court_type && `・${court_type}`} - {distance_km && `・${distance_km}`} + {distance_km && `・${distance_km}km`} @@ -93,7 +98,7 @@ const ListCard: React.FC = ({ - {Array.from({ length: Math.min(registeredCount, 3) }).map( + {Array.from({ length: 3 }).map( (_, index) => ( = ({ - 报名人数 {registeredCount}/ - {maxCount} + 报名人数 {current_players}/ + {max_players} - {skill_level_max} zh {skill_level_max} + {skill_level_min} 至 {skill_level_max} {play_type && {play_type} diff --git a/src/components/ListLoadError/index.tsx b/src/components/ListLoadError/index.tsx index 420393d..6583dc5 100644 --- a/src/components/ListLoadError/index.tsx +++ b/src/components/ListLoadError/index.tsx @@ -2,7 +2,13 @@ import { Image, View, Text, Button } from "@tarojs/components"; import styles from "./index.module.scss"; import img from "@/config/images"; -const ListLoadError = ({ reload }: { reload: () => void }) => { +interface IProps { + reload?: () => void; + text?: string; +} + +const ListLoadError = (props: IProps) => { + const { reload, text } = props; const handleReload = () => { reload && typeof reload === "function" && reload(); }; @@ -13,11 +19,13 @@ const ListLoadError = ({ reload }: { reload: () => void }) => { className={styles.listLoadErrorImg} src={img.ICON_LIST_LOAD_ERROR} /> - 加载失败 - + {text && {text}} + {reload && ( + + )} ); }; diff --git a/src/components/Range/index.tsx b/src/components/Range/index.tsx index 7a16109..01c7b8c 100644 --- a/src/components/Range/index.tsx +++ b/src/components/Range/index.tsx @@ -35,6 +35,11 @@ const NtrpRange: React.FC = ({ }, [JSON.stringify(value || [])]); const handleChange = (val: [number, number]) => { + setCurrentValue(val); + // onChange?.(name, val); + }; + + const handleEndChange = (val: [number, number]) => { setCurrentValue(val); onChange?.(name, val); }; @@ -76,7 +81,7 @@ const NtrpRange: React.FC = ({ max={max} step={step} value={currentValue} - onEnd={handleChange} + onEnd={handleEndChange} onChange={handleChange} disabled={disabled} defaultValue={[min, max]} diff --git a/src/container/inputCustomerNavbar/index.tsx b/src/container/inputCustomerNavbar/index.tsx index 3414715..1b3b242 100644 --- a/src/container/inputCustomerNavbar/index.tsx +++ b/src/container/inputCustomerNavbar/index.tsx @@ -20,20 +20,20 @@ const ListHeader = (props: IProps) => { const { statusBarHeight, navbarHeight } = statusNavbarHeightInfo; // 获取位置信息 - const getCurrentLocal = () => { - updateState({ - getLocationLoading: true, - }); - getCurrentLocation().then((res) => { - updateState({ - getLocationLoading: false, - location: res || {}, - }); - }); - }; - useEffect(() => { - getCurrentLocal(); - }, []); + // const getCurrentLocal = () => { + // updateState({ + // getLocationLoading: true, + // }); + // getCurrentLocation().then((res) => { + // updateState({ + // getLocationLoading: false, + // location: res || {}, + // }); + // }); + // }; + // useEffect(() => { + // getCurrentLocal(); + // }, []); const handleInputClick = () => { Taro.navigateTo({ diff --git a/src/container/listContainer/index.tsx b/src/container/listContainer/index.tsx index bd97347..055ad36 100644 --- a/src/container/listContainer/index.tsx +++ b/src/container/listContainer/index.tsx @@ -1,36 +1,72 @@ -import { View, Text } from "@tarojs/components"; +import { View } from "@tarojs/components"; import ListCard from "@/components/ListCard"; import ListLoadError from "@/components/ListLoadError"; import ListCardSkeleton from "@/components/ListCardSkeleton"; +// import { VirtualList } from '@nutui/nutui-react-taro' import "./index.scss"; import { useReachBottom } from "@tarojs/taro"; const ListContainer = (props) => { - const { loading, data = [], error, reload, recommendList } = props; + const { + loading, + data = [], + error, + reload, + recommendList, + loadMoreMatches, + } = props; + console.log("===data", data); useReachBottom(() => { console.log("触底了"); // 调用 store 的加载更多方法 - // loadMoreMatches(); + loadMoreMatches(); }); if (error) { return ; } - const renderList = (list) => { - if (loading && list.length === 0) { - return ( - <> - {new Array(10).fill(0).map(() => { - return ; - })} - - ); - } - + const renderSkeleton = () => { return ( <> + {new Array(10).fill(0).map(() => { + return ; + })} + + ); + }; + + // 渲染列表 + const renderList = (list) => { + // 请求未回来显示骨架屏 + // if (loading && list?.length === 0) { + // return ( + // <> + // {new Array(10).fill(0).map(() => { + // return ; + // })} + // + // ); + // } + + // 请求数据为空 + if (!loading && list?.length === 0) { + return ; + } + + // 渲染数据 + return ( + <> + {/* { + return + }} + /> */} {list?.map((match, index) => ( ))} @@ -41,12 +77,14 @@ const ListContainer = (props) => { return ( {renderList(data)} - + {/* 显示骨架屏 */} + {loading && renderSkeleton()} + {/* 搜索结果较少,已为你推荐其他内容 - {renderList(recommendList)} + {renderList(recommendList)} */} {/* 到底了 */} - 到底了 + {data?.length > 0 && 到底了} ); }; diff --git a/src/container/listCustomNavbar/index.module.scss b/src/container/listCustomNavbar/index.module.scss deleted file mode 100644 index b31514b..0000000 --- a/src/container/listCustomNavbar/index.module.scss +++ /dev/null @@ -1,43 +0,0 @@ - .container { - padding-left: 17px; - display: flex; - align-items: center; - gap: 8px; - - .line { - width: 1px; - height: 25px; - background-color: #0000000F; - } - - .logo { - width: 60px; - height: 34px; - } - - .change { - width: 12px; - height: 12px; - } - - .cityWrapper { - line-height: 20px; - } - - .city { - font-weight: 600; - font-size: 13px; - line-height: 20px; - } - - .infoWrapper { - line-height: 12px; - } - - .info { - font-weight: 400; - font-size: 10px; - line-height: 12px; - color: #3C3C4399; - } - } \ No newline at end of file diff --git a/src/container/listCustomNavbar/index.scss b/src/container/listCustomNavbar/index.scss new file mode 100644 index 0000000..6698e8f --- /dev/null +++ b/src/container/listCustomNavbar/index.scss @@ -0,0 +1,144 @@ +.listNavWrapper { + position: relative; +} + +.listNavContainer { + .listNavLine { + width: 1px; + height: 25px; + background-color: #0000000f; + } + + .listNavLogo { + width: 60px; + height: 34px; + } + + .listNavChange { + width: 12px; + height: 12px; + } + + .listNavContentWrapper { + padding-left: 17px; + display: flex; + align-items: center; + gap: 8px; + } + + .listNavCityWrapper { + line-height: 20px; + } + + .listNavCity { + font-weight: 600; + font-size: 13px; + line-height: 20px; + } + + .infoWrapper { + line-height: 12px; + } + + .listNavInfoWrapper { + font-weight: 400; + font-size: 10px; + line-height: 12px; + color: #3c3c4399; + } +} + +.inputCustomerNavbarContainer { + padding-left: 17px; + display: flex; + gap: 8px; + + .logo { + width: 28px; + height: 16px; + } + + .icon16 { + width: 16px; + height: 16px; + } + + .navContent { + display: flex; + align-items: center; + gap: 4px; + width: 65%; + height: max-content; + // padding-top: 5px; + } + + .searchContainer { + width: 100%; + display: flex; + align-items: center; + gap: 5.85px; + padding: 7.8px; + height: 30px; + box-sizing: border-box; + border-radius: 30px; + border: 0.488px solid rgba(0, 0, 0, 0.06); + box-shadow: 0 3.902px 46.829px 0 rgba(0, 0, 0, 0.08); + height: 30px; + box-sizing: border-box; + font-size: 13.659px; + font-style: normal; + font-weight: 400; + line-height: 17.561px; + flex: 1; + + .nut-input { + padding: 0; + } + } +} + +.inputCustomerNavbarShowInput { + padding-left: 10px; + .logo { + width: 32px; + height: 32px; + } +} + +.toggleElement { + /* 绝对定位使两个元素重叠 */ + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + + /* 过渡动画设置,实现平滑切换 */ + transition: opacity 0.5s ease, transform 0.5s ease; +} + +/* 第一个元素样式 */ +.firstElement { + // background-color: #4a90e2; +} + +/* 第二个元素样式 */ +.secondElement { + // background-color: #5cb85c; + /* 初始状态:透明且稍微偏移 */ + opacity: 0; + // transform: translateY(20px); +} + +/* 隐藏状态 */ +.hidden { + opacity: 0; + transform: translateY(20px); + // pointer-events: none; /* 隐藏时不响应鼠标事件 */ +} + +/* 可见状态 */ +.visible { + opacity: 1; + transform: translateY(0); +} \ No newline at end of file diff --git a/src/container/listCustomNavbar/index.tsx b/src/container/listCustomNavbar/index.tsx index b9484eb..7f07eb3 100644 --- a/src/container/listCustomNavbar/index.tsx +++ b/src/container/listCustomNavbar/index.tsx @@ -1,65 +1,134 @@ import { View, Text, Image } from "@tarojs/components"; import img from "@/config/images"; -import { getCurrentLocation } from "@/utils/locationUtils"; -import styles from "./index.module.scss"; -import { useEffect } from "react"; import { useGlobalState } from "@/store/global"; import { useListState } from "@/store/listStore"; -import CustomNavbar from '@/components/CustomNavbar' +import CustomNavbar from "@/components/CustomNavbar"; +import { Input } from "@nutui/nutui-react-taro"; +import Taro from "@tarojs/taro"; +import "./index.scss"; -const ListHeader = () => { +interface IProps { + config?: { + showInput: boolean; + inputLeftIcon: string; + iconPath?: string; + leftIconClick: () => void; + }; +} + +const ListHeader = (props: IProps) => { + const { config } = props; + const { + showInput = false, + inputLeftIcon, + leftIconClick, + } = config || {}; const { - updateState, location, getLocationText, getLocationLoading, statusNavbarHeightInfo, } = useGlobalState(); - const { gamesNum } = useListState(); + const { gamesNum, searchValue, isShowInputCustomerNavBar } = useListState(); const { statusBarHeight, navbarHeight } = statusNavbarHeightInfo; - // 获取位置信息 - const getCurrentLocal = () => { - updateState({ - getLocationLoading: true, - }); - getCurrentLocation().then((res) => { - updateState({ - getLocationLoading: false, - location: res || {}, - }); - }); - }; - useEffect(() => { - getCurrentLocal(); - }, []); - const currentAddress = getLocationLoading ? getLocationText : location?.address; + const handleInputClick = () => { + const pages = Taro.getCurrentPages(); + const currentPage = pages[pages.length - 1]; + const currentPagePath = currentPage.route; + if (currentPagePath === "pages/searchResult/index") { + Taro.navigateBack(); + } else { + Taro.navigateTo({ + url: "/pages/search/index", + }); + } + }; + + // 点击logo + const handleLogoClick = () => { + Taro.redirectTo({ + url: "pages/list/index", // 列表页 + }); + }; + + const handleInputLeftIconClick = () => { + if (leftIconClick) { + leftIconClick(); + } else { + handleLogoClick(); + } + }; + return ( - - {/* logo */} - - - - - {/* 位置 */} - {currentAddress} - {!getLocationLoading && ( - - )} + + {/* 首页logo 导航*/} +