处理列表
This commit is contained in:
@@ -9,12 +9,12 @@ interface IProps {
|
|||||||
const CustomNavbar = (props: IProps) => {
|
const CustomNavbar = (props: IProps) => {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
const { statusNavbarHeightInfo } = useGlobalState();
|
const { statusNavbarHeightInfo } = useGlobalState();
|
||||||
const { totalHeight } = statusNavbarHeightInfo;
|
const { statusBarHeight, navbarHeight } = statusNavbarHeightInfo;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
className={styles.customerNavbar}
|
className={styles.customerNavbar}
|
||||||
style={{ height: `${totalHeight}px` }}
|
style={{ height: `${navbarHeight}px`, paddingTop: `${statusBarHeight}px`, }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
.distanceQuickFilterWrap {
|
.distanceQuickFilterWrap {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
--nutui-menu-bar-line-height: 30px;
|
||||||
|
|
||||||
.nut-menu-bar {
|
.nut-menu-bar {
|
||||||
background-color: unset;
|
background-color: unset;
|
||||||
@@ -35,19 +36,6 @@
|
|||||||
border-bottom-right-radius: 30px;
|
border-bottom-right-radius: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// .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;
|
|
||||||
// }
|
|
||||||
|
|
||||||
.positionWrap {
|
.positionWrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import React, { useEffect, useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
import { Menu, Button } from "@nutui/nutui-react-taro";
|
import { Menu } from "@nutui/nutui-react-taro";
|
||||||
import { Image, View, Text } from "@tarojs/components";
|
import { Image, View } from "@tarojs/components";
|
||||||
import img from "@/config/images";
|
import img from "@/config/images";
|
||||||
import Bubble from "../Bubble";
|
import Bubble from "../Bubble";
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
|
|
||||||
const Demo3 = (props) => {
|
const DistanceQuickFilter = (props) => {
|
||||||
const {
|
const {
|
||||||
cityOptions,
|
cityOptions,
|
||||||
quickOptions,
|
quickOptions,
|
||||||
@@ -49,6 +49,7 @@ const Demo3 = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<View>
|
||||||
<Menu
|
<Menu
|
||||||
className={`distanceQuickFilterWrap ${filterWrapperClassName}`}
|
className={`distanceQuickFilterWrap ${filterWrapperClassName}`}
|
||||||
>
|
>
|
||||||
@@ -105,6 +106,7 @@ const Demo3 = (props) => {
|
|||||||
</View>
|
</View>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default Demo3;
|
export default DistanceQuickFilter;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useMemo, useState } from "react";
|
import { useMemo } from "react";
|
||||||
import { Popup } from "@nutui/nutui-react-taro";
|
import { Popup } from "@nutui/nutui-react-taro";
|
||||||
import Range from "../../components/Range";
|
import Range from "../../components/Range";
|
||||||
import Bubble from "../../components/Bubble";
|
import Bubble from "../../components/Bubble";
|
||||||
@@ -29,7 +29,7 @@ const FilterPopup = (props: FilterPopupProps) => {
|
|||||||
} = props;
|
} = props;
|
||||||
const store = useListStore() || {};
|
const store = useListStore() || {};
|
||||||
const { getDictionaryValue } = useDictionaryActions() || {};
|
const { getDictionaryValue } = useDictionaryActions() || {};
|
||||||
const { timeBubbleData, gamesNum, dateRangeOptions } = store;
|
const { timeBubbleData, gamesNum } = store;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 处理字典选项
|
* @description 处理字典选项
|
||||||
@@ -91,7 +91,7 @@ const FilterPopup = (props: FilterPopupProps) => {
|
|||||||
round
|
round
|
||||||
visible={visible}
|
visible={visible}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
style={{ marginTop: statusNavbarHeigh + "px" }}
|
style={{ marginTop: statusNavbarHeigh + "px", maxHeight: '75vh' }}
|
||||||
overlayStyle={{ marginTop: statusNavbarHeigh + "px" }}
|
overlayStyle={{ marginTop: statusNavbarHeigh + "px" }}
|
||||||
zIndex={1001}
|
zIndex={1001}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -269,6 +269,15 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.localAreaWrapper {
|
||||||
|
max-width: 69%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.localAreaTitle {
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.smoothTitle {
|
.smoothTitle {
|
||||||
@@ -291,5 +300,11 @@
|
|||||||
.localArea {
|
.localArea {
|
||||||
border: 0.5px solid #FFFFFFA6;
|
border: 0.5px solid #FFFFFFA6;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.localAreaText {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,21 @@ const ListCard: React.FC<ListCardProps> = ({
|
|||||||
image_list = [],
|
image_list = [],
|
||||||
court_type,
|
court_type,
|
||||||
key,
|
key,
|
||||||
|
participants, // 参与者图片
|
||||||
|
venue_image_list, // 场馆图片
|
||||||
|
venue_description,
|
||||||
|
game_type, // 球局类型
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
|
// 参与者要前三个数据
|
||||||
|
const participantsImageList = participants?.slice(0, 3) || [];
|
||||||
|
// 场地 要第一个数据
|
||||||
|
// const venueImageList = venue_image_list?.slice(0, 1) || [];
|
||||||
|
const venueImage = venue_image_list?.[0]?.url || '';
|
||||||
|
|
||||||
|
// 是否显示畅打球局
|
||||||
|
const isShowSmoothPlayingGame = game_type === '畅打球局';
|
||||||
|
|
||||||
const renderItemImage = (src: string) => {
|
const renderItemImage = (src: string) => {
|
||||||
return (
|
return (
|
||||||
<Image
|
<Image
|
||||||
@@ -32,7 +46,6 @@ const ListCard: React.FC<ListCardProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleViewDetail = () => {
|
const handleViewDetail = () => {
|
||||||
console.log("id", id);
|
|
||||||
Taro.navigateTo({
|
Taro.navigateTo({
|
||||||
url: `/game_pages/detail/index?id=${id || 1}&from=list`,
|
url: `/game_pages/detail/index?id=${id || 1}&from=list`,
|
||||||
});
|
});
|
||||||
@@ -120,11 +133,11 @@ const ListCard: React.FC<ListCardProps> = ({
|
|||||||
<View className="bottom-info">
|
<View className="bottom-info">
|
||||||
<View className="left-section">
|
<View className="left-section">
|
||||||
<View className="avatar-group">
|
<View className="avatar-group">
|
||||||
{Array.from({ length: 3 }).map((_, index) => (
|
{(participantsImageList || []).map((item, index) => (
|
||||||
<View key={index} className="avatar">
|
<View key={index} className="avatar">
|
||||||
<Image
|
<Image
|
||||||
className="avatar-image"
|
className="avatar-image"
|
||||||
src="https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=200&h=200&fit=crop&crop=center"
|
src={item?.user?.avatar_url}
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
@@ -157,24 +170,24 @@ const ListCard: React.FC<ListCardProps> = ({
|
|||||||
<View className="image-section">{renderImages()}</View>
|
<View className="image-section">{renderImages()}</View>
|
||||||
</View>
|
</View>
|
||||||
{/* 畅打球局 */}
|
{/* 畅打球局 */}
|
||||||
<View className="smoothPlayingGame">
|
{isShowSmoothPlayingGame && <View className="smoothPlayingGame">
|
||||||
<View className="smoothWrapper">
|
<View className="smoothWrapper">
|
||||||
<Image
|
<Image
|
||||||
src={img.ICON_LIST_PLAYING_GAME}
|
src={img.ICON_LIST_PLAYING_GAME}
|
||||||
className="iconListPlayingGame"
|
className="iconListPlayingGame"
|
||||||
/>
|
/>
|
||||||
<Text className="smoothTitle">畅打球局</Text>
|
<Text className="smoothTitle">{game_type}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View className="line" />
|
<View className="line" />
|
||||||
<View>场馆方:</View>
|
<View className="localAreaTitle">场馆方:</View>
|
||||||
<View className="localAreaWrapper">
|
<View className="localAreaWrapper">
|
||||||
<Image
|
<Image
|
||||||
className="localArea"
|
className="localArea"
|
||||||
src="https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=200&h=200&fit=crop&crop=center"
|
src={venueImage}
|
||||||
/>
|
/>
|
||||||
<Text className="localAreaText">仁恒河滨花园网球场</Text>
|
<Text className="localAreaText">{venue_description}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ import { View } from "@tarojs/components";
|
|||||||
import ListCard from "@/components/ListCard";
|
import ListCard from "@/components/ListCard";
|
||||||
import ListLoadError from "@/components/ListLoadError";
|
import ListLoadError from "@/components/ListLoadError";
|
||||||
import ListCardSkeleton from "@/components/ListCardSkeleton";
|
import ListCardSkeleton from "@/components/ListCardSkeleton";
|
||||||
// import { VirtualList } from '@nutui/nutui-react-taro'
|
|
||||||
import "./index.scss";
|
|
||||||
import { useReachBottom } from "@tarojs/taro";
|
import { useReachBottom } from "@tarojs/taro";
|
||||||
|
import "./index.scss";
|
||||||
|
|
||||||
const ListContainer = (props) => {
|
const ListContainer = (props) => {
|
||||||
const {
|
const {
|
||||||
@@ -12,14 +11,12 @@ const ListContainer = (props) => {
|
|||||||
data = [],
|
data = [],
|
||||||
error,
|
error,
|
||||||
reload,
|
reload,
|
||||||
recommendList,
|
// recommendList,
|
||||||
loadMoreMatches,
|
loadMoreMatches,
|
||||||
} = props;
|
} = props;
|
||||||
console.log("===data", data);
|
|
||||||
|
|
||||||
useReachBottom(() => {
|
useReachBottom(() => {
|
||||||
console.log("触底了");
|
// 加载更多方法
|
||||||
// 调用 store 的加载更多方法
|
|
||||||
loadMoreMatches();
|
loadMoreMatches();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -39,17 +36,6 @@ const ListContainer = (props) => {
|
|||||||
|
|
||||||
// 渲染列表
|
// 渲染列表
|
||||||
const renderList = (list) => {
|
const renderList = (list) => {
|
||||||
// 请求未回来显示骨架屏
|
|
||||||
// if (loading && list?.length === 0) {
|
|
||||||
// return (
|
|
||||||
// <>
|
|
||||||
// {new Array(10).fill(0).map(() => {
|
|
||||||
// return <ListCardSkeleton />;
|
|
||||||
// })}
|
|
||||||
// </>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 请求数据为空
|
// 请求数据为空
|
||||||
if (!loading && list?.length === 0) {
|
if (!loading && list?.length === 0) {
|
||||||
return <ListLoadError reload={reload} text="暂无数据" />;
|
return <ListLoadError reload={reload} text="暂无数据" />;
|
||||||
@@ -58,15 +44,6 @@ const ListContainer = (props) => {
|
|||||||
// 渲染数据
|
// 渲染数据
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* <VirtualList
|
|
||||||
containerHeight={1000}
|
|
||||||
itemHeight={144}
|
|
||||||
// itemEqual={false}
|
|
||||||
list={list}
|
|
||||||
itemRender={(data) => {
|
|
||||||
return <ListCard {...data}/>
|
|
||||||
}}
|
|
||||||
/> */}
|
|
||||||
{list?.map((match, index) => (
|
{list?.map((match, index) => (
|
||||||
<ListCard key={match.id || index} {...match} />
|
<ListCard key={match.id || index} {...match} />
|
||||||
))}
|
))}
|
||||||
@@ -76,15 +53,25 @@ const ListContainer = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View className="listContentWrapper">
|
<View className="listContentWrapper">
|
||||||
{renderList(data)}
|
{/* <ScrollView
|
||||||
{/* 显示骨架屏 */}
|
scrollY
|
||||||
{loading && renderSkeleton()}
|
scrollWithAnimation
|
||||||
{/* <View className="recommendTextWrapper">
|
enableBackToTop
|
||||||
|
enablePassive
|
||||||
|
style={{ height: '100vh' }}
|
||||||
|
onScrollToLower={handleScrollToLower}
|
||||||
|
upperThreshold={60}
|
||||||
|
> */}
|
||||||
|
{renderList(data)}
|
||||||
|
{/* 显示骨架屏 */}
|
||||||
|
{loading && renderSkeleton()}
|
||||||
|
{/* <View className="recommendTextWrapper">
|
||||||
<Text className="recommendText">搜索结果较少,已为你推荐其他内容</Text>
|
<Text className="recommendText">搜索结果较少,已为你推荐其他内容</Text>
|
||||||
</View>
|
</View>
|
||||||
{renderList(recommendList)} */}
|
{renderList(recommendList)} */}
|
||||||
{/* 到底了 */}
|
{/* 到底了 */}
|
||||||
{data?.length > 0 && <View className="bottomTextWrapper">到底了</View>}
|
{data?.length > 0 && <View className="bottomTextWrapper">到底了</View>}
|
||||||
|
{/* </ScrollView> */}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -113,28 +113,31 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
/* 过渡动画设置,实现平滑切换 */
|
/* 启用硬件加速 */
|
||||||
transition: opacity 0.5s ease, transform 0.5s ease;
|
will-change: opacity, transform;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
|
||||||
|
/* 优化过渡动画,使用更快的缓动函数 */
|
||||||
|
transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
||||||
|
transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 第一个元素样式 */
|
/* 第一个元素样式 */
|
||||||
.firstElement {
|
.firstElement {
|
||||||
// background-color: #4a90e2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 第二个元素样式 */
|
/* 第二个元素样式 */
|
||||||
.secondElement {
|
.secondElement {
|
||||||
// background-color: #5cb85c;
|
|
||||||
/* 初始状态:透明且稍微偏移 */
|
/* 初始状态:透明且稍微偏移 */
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
// transform: translateY(20px);
|
transform: translateY(10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 隐藏状态 */
|
/* 隐藏状态 */
|
||||||
.hidden {
|
.hidden {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(20px);
|
transform: translateY(10px);
|
||||||
// pointer-events: none; /* 隐藏时不响应鼠标事件 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 可见状态 */
|
/* 可见状态 */
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { View, Text, Image } from "@tarojs/components";
|
|||||||
import img from "@/config/images";
|
import img from "@/config/images";
|
||||||
import { useGlobalState } from "@/store/global";
|
import { useGlobalState } from "@/store/global";
|
||||||
import { useUserInfo, } from '@/store/userStore'
|
import { useUserInfo, } from '@/store/userStore'
|
||||||
|
|
||||||
import { useListState } from "@/store/listStore";
|
import { useListState } from "@/store/listStore";
|
||||||
import CustomNavbar from "@/components/CustomNavbar";
|
import CustomNavbar from "@/components/CustomNavbar";
|
||||||
import { Input } from "@nutui/nutui-react-taro";
|
import { Input } from "@nutui/nutui-react-taro";
|
||||||
@@ -26,13 +25,11 @@ const ListHeader = (props: IProps) => {
|
|||||||
leftIconClick,
|
leftIconClick,
|
||||||
} = config || {};
|
} = config || {};
|
||||||
const {
|
const {
|
||||||
location,
|
|
||||||
getLocationText,
|
|
||||||
getLocationLoading,
|
getLocationLoading,
|
||||||
statusNavbarHeightInfo,
|
statusNavbarHeightInfo,
|
||||||
} = useGlobalState();
|
} = useGlobalState();
|
||||||
const { gamesNum, searchValue, isShowInputCustomerNavBar } = useListState();
|
const { gamesNum, searchValue, isShowInputCustomerNavBar } = useListState();
|
||||||
const { statusBarHeight, navbarHeight } = statusNavbarHeightInfo;
|
const { navbarHeight } = statusNavbarHeightInfo;
|
||||||
|
|
||||||
const { city,district } = useUserInfo()
|
const { city,district } = useUserInfo()
|
||||||
|
|
||||||
@@ -68,6 +65,11 @@ const ListHeader = (props: IProps) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const navbarStyle = {
|
||||||
|
height: `${navbarHeight}px`,
|
||||||
|
paddingTop: `4px`,
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CustomNavbar>
|
<CustomNavbar>
|
||||||
<View className="listNavWrapper">
|
<View className="listNavWrapper">
|
||||||
@@ -75,10 +77,7 @@ const ListHeader = (props: IProps) => {
|
|||||||
<View
|
<View
|
||||||
className={`listNavContainer toggleElement firstElement hidden ${(!isShowInputCustomerNavBar && !showInput) && "visible"
|
className={`listNavContainer toggleElement firstElement hidden ${(!isShowInputCustomerNavBar && !showInput) && "visible"
|
||||||
}`}
|
}`}
|
||||||
style={{
|
style={navbarStyle}
|
||||||
height: `${navbarHeight}px`,
|
|
||||||
paddingTop: `${statusBarHeight}px`,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<View className="listNavContentWrapper">
|
<View className="listNavContentWrapper">
|
||||||
{/* logo */}
|
{/* logo */}
|
||||||
@@ -106,10 +105,7 @@ const ListHeader = (props: IProps) => {
|
|||||||
<View
|
<View
|
||||||
className={`inputCustomerNavbarContainer toggleElement secondElement hidden ${(isShowInputCustomerNavBar || showInput) && "visible"
|
className={`inputCustomerNavbarContainer toggleElement secondElement hidden ${(isShowInputCustomerNavBar || showInput) && "visible"
|
||||||
} ${showInput && "inputCustomerNavbarShowInput"}`}
|
} ${showInput && "inputCustomerNavbarShowInput"}`}
|
||||||
style={{
|
style={navbarStyle}
|
||||||
height: `${navbarHeight}px`,
|
|
||||||
paddingTop: `${statusBarHeight}px`,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<View className="navContent">
|
<View className="navContent">
|
||||||
{/* logo */}
|
{/* logo */}
|
||||||
@@ -137,4 +133,5 @@ const ListHeader = (props: IProps) => {
|
|||||||
</CustomNavbar>
|
</CustomNavbar>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ListHeader;
|
export default ListHeader;
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
position: sticky;
|
||||||
|
background-color: #fff;
|
||||||
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menuFilter {
|
.menuFilter {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import SearchBar from "@/components/SearchBar";
|
import SearchBar from "@/components/SearchBar";
|
||||||
import FilterPopup from "@/components/FilterPopup";
|
import FilterPopup from "@/components/FilterPopup";
|
||||||
import styles from "./index.module.scss";
|
import styles from "./index.module.scss";
|
||||||
import { useEffect } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import Taro, { usePageScroll } from "@tarojs/taro";
|
import Taro, { usePageScroll } from "@tarojs/taro";
|
||||||
import { useListStore } from "@/store/listStore";
|
import { useListStore } from "@/store/listStore";
|
||||||
import { useGlobalState } from "@/store/global";
|
import { useGlobalState } from "@/store/global";
|
||||||
@@ -12,11 +12,6 @@ import ListContainer from "@/container/listContainer";
|
|||||||
import DistanceQuickFilter from "@/components/DistanceQuickFilter";
|
import DistanceQuickFilter from "@/components/DistanceQuickFilter";
|
||||||
import { withAuth } from "@/components";
|
import { withAuth } from "@/components";
|
||||||
import { updateUserLocation } from "@/services/userService";
|
import { updateUserLocation } from "@/services/userService";
|
||||||
// import img from "@/config/images";
|
|
||||||
// import ShareCardCanvas from "@/components/ShareCardCanvas/example";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ListPage = () => {
|
const ListPage = () => {
|
||||||
|
|
||||||
@@ -46,23 +41,28 @@ const ListPage = () => {
|
|||||||
isShowInputCustomerNavBar,
|
isShowInputCustomerNavBar,
|
||||||
initialFilterSearch,
|
initialFilterSearch,
|
||||||
loadMoreMatches,
|
loadMoreMatches,
|
||||||
dateRangeOptions
|
fetchGetGamesCount
|
||||||
} = store;
|
} = store;
|
||||||
|
|
||||||
|
// 简化的滚动处理函数
|
||||||
usePageScroll((res) => {
|
usePageScroll((res) => {
|
||||||
if (res?.scrollTop >= totalHeight) {
|
const shouldShowInputNav = res?.scrollTop >= totalHeight;
|
||||||
!isShowInputCustomerNavBar &&
|
|
||||||
|
// 只有当状态需要改变时才更新
|
||||||
|
if (shouldShowInputNav && !isShowInputCustomerNavBar) {
|
||||||
updateState({ isShowInputCustomerNavBar: true });
|
updateState({ isShowInputCustomerNavBar: true });
|
||||||
} else {
|
} else if (!shouldShowInputNav && isShowInputCustomerNavBar) {
|
||||||
isShowInputCustomerNavBar &&
|
|
||||||
updateState({ isShowInputCustomerNavBar: false });
|
updateState({ isShowInputCustomerNavBar: false });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const scrollContextRef = useRef(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getLocation()
|
getLocation()
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
// 监听距离和排序方式变化,自动调用接口
|
// 监听距离和排序方式变化,自动调用接口
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 只有当 distanceQuickFilter 有值时才调用接口
|
// 只有当 distanceQuickFilter 有值时才调用接口
|
||||||
@@ -89,6 +89,7 @@ const ListPage = () => {
|
|||||||
console.error('更新用户位置失败:', error);
|
console.error('更新用户位置失败:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fetchGetGamesCount();
|
||||||
|
|
||||||
// 页面加载时获取数据
|
// 页面加载时获取数据
|
||||||
getMatchesData();
|
getMatchesData();
|
||||||
@@ -104,35 +105,45 @@ const ListPage = () => {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// 下拉刷新处理函数 - 使用Taro生命周期钩子
|
// 下拉刷新处理函数 - 使用Taro生命周期钩子
|
||||||
Taro.usePullDownRefresh(() => {
|
Taro.usePullDownRefresh(async () => {
|
||||||
console.log("===触发下拉刷新");
|
try {
|
||||||
clearFilterOptions()
|
// 调用刷新方法
|
||||||
|
await refreshMatches();
|
||||||
|
|
||||||
// 调用 store 的刷新方法
|
// 刷新完成后停止下拉刷新动画
|
||||||
// refreshMatches()
|
Taro.stopPullDownRefresh();
|
||||||
// .then(() => {
|
|
||||||
// // 刷新完成后停止下拉刷新动画
|
|
||||||
// Taro.stopPullDownRefresh();
|
|
||||||
|
|
||||||
// // 显示刷新成功提示
|
// 显示刷新成功提示
|
||||||
// Taro.showToast({
|
Taro.showToast({
|
||||||
// title: "刷新成功",
|
title: "刷新成功",
|
||||||
// icon: "success",
|
icon: "success",
|
||||||
// duration: 1500,
|
duration: 1500,
|
||||||
// });
|
});
|
||||||
// })
|
} catch (error) {
|
||||||
// .catch(() => {
|
// 刷新失败时也停止动画
|
||||||
// // 刷新失败时也停止动画
|
Taro.stopPullDownRefresh();
|
||||||
// Taro.stopPullDownRefresh();
|
|
||||||
|
|
||||||
// Taro.showToast({
|
Taro.showToast({
|
||||||
// title: "刷新失败",
|
title: "刷新失败,请重试",
|
||||||
// icon: "error",
|
icon: "error",
|
||||||
// duration: 1500,
|
duration: 1500,
|
||||||
// });
|
});
|
||||||
// });
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 综合筛选确认
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const handleFilterConfirm = () => {
|
||||||
|
toggleShowPopup();
|
||||||
|
getMatchesData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 综合筛选弹框
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
const toggleShowPopup = () => {
|
const toggleShowPopup = () => {
|
||||||
updateState({ isShowFilterPopup: !isShowFilterPopup });
|
updateState({ isShowFilterPopup: !isShowFilterPopup });
|
||||||
};
|
};
|
||||||
@@ -164,9 +175,10 @@ const ListPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View ref={scrollContextRef}>
|
||||||
{/* 自定义导航 */}
|
{/* 自定义导航 */}
|
||||||
<CustomerNavBar />
|
<CustomerNavBar />
|
||||||
|
|
||||||
{/* <ShareCardCanvas /> */}
|
{/* <ShareCardCanvas /> */}
|
||||||
<View className={styles.listPage}>
|
<View className={styles.listPage}>
|
||||||
<View
|
<View
|
||||||
@@ -187,7 +199,7 @@ const ListPage = () => {
|
|||||||
<FilterPopup
|
<FilterPopup
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onCancel={toggleShowPopup}
|
onCancel={toggleShowPopup}
|
||||||
onConfirm={toggleShowPopup}
|
onConfirm={handleFilterConfirm}
|
||||||
onChange={handleUpdateFilterOptions}
|
onChange={handleUpdateFilterOptions}
|
||||||
filterOptions={filterOptions}
|
filterOptions={filterOptions}
|
||||||
onClear={clearFilterOptions}
|
onClear={clearFilterOptions}
|
||||||
@@ -199,7 +211,10 @@ const ListPage = () => {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
{/* 筛选 */}
|
{/* 筛选 */}
|
||||||
<View className={styles.listTopFilterWrapper}>
|
<View className={styles.listTopFilterWrapper}
|
||||||
|
style={{
|
||||||
|
top: totalHeight -1,
|
||||||
|
}}>
|
||||||
<DistanceQuickFilter
|
<DistanceQuickFilter
|
||||||
cityOptions={distanceData}
|
cityOptions={distanceData}
|
||||||
quickOptions={quickFilterData}
|
quickOptions={quickFilterData}
|
||||||
@@ -221,7 +236,6 @@ const ListPage = () => {
|
|||||||
loadMoreMatches={loadMoreMatches}
|
loadMoreMatches={loadMoreMatches}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<GuideBar currentPage="list" />
|
<GuideBar currentPage="list" />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -38,16 +38,9 @@ const SearchResult = () => {
|
|||||||
const pages = Taro.getCurrentPages()
|
const pages = Taro.getCurrentPages()
|
||||||
const currentPage = pages?.[pages.length - 1];
|
const currentPage = pages?.[pages.length - 1];
|
||||||
updateState({currentPage, isSearchResult: true})
|
updateState({currentPage, isSearchResult: true})
|
||||||
// if (location?.address) {
|
|
||||||
// 保存位置
|
|
||||||
// updateState({ location });
|
|
||||||
// 页面加载时获取数据
|
|
||||||
console.log('===搜索结果页===')
|
|
||||||
getMatchesData();
|
getMatchesData();
|
||||||
// }
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
console.log('===搜索结果组件卸载')
|
|
||||||
updateState({currentPage: '', isSearchResult: false})
|
updateState({currentPage: '', isSearchResult: false})
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
@@ -46,6 +46,20 @@ export const getGamesIntegrateList = async (params?: Record<string, any>) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取列表数量
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getGamesCount = async (params?: Record<string, any>) => {
|
||||||
|
try {
|
||||||
|
return httpService.post('/games/count', params, { showLoading: true })
|
||||||
|
} catch (error) {
|
||||||
|
console.error("列表数量获取失败:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取搜索历史记录的异步函数
|
* 获取搜索历史记录的异步函数
|
||||||
* @param {Object} params - 查询参数对象
|
* @param {Object} params - 查询参数对象
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
getSearchHistory,
|
getSearchHistory,
|
||||||
clearHistory,
|
clearHistory,
|
||||||
searchSuggestion,
|
searchSuggestion,
|
||||||
|
getGamesCount,
|
||||||
} from "../services/listApi";
|
} from "../services/listApi";
|
||||||
import {
|
import {
|
||||||
ListActions,
|
ListActions,
|
||||||
@@ -14,12 +15,10 @@ import {
|
|||||||
IPayload,
|
IPayload,
|
||||||
} from "../../types/list/types";
|
} from "../../types/list/types";
|
||||||
|
|
||||||
import dateRangeUtils from '@/utils/dateRange'
|
|
||||||
|
|
||||||
// 完整的 Store 类型
|
// 完整的 Store 类型
|
||||||
type TennisStore = ListState & ListActions;
|
type TennisStore = ListState & ListActions;
|
||||||
|
|
||||||
const toDate = dateRangeUtils?.formatDate(new Date())
|
|
||||||
const defaultDateRange: [string, string] = [dayjs().format('YYYY-MM-DD'), dayjs().add(1, 'M').format('YYYY-MM-DD')]
|
const defaultDateRange: [string, string] = [dayjs().format('YYYY-MM-DD'), dayjs().add(1, 'M').format('YYYY-MM-DD')]
|
||||||
|
|
||||||
const defaultFilterOptions: IFilterOptions = {
|
const defaultFilterOptions: IFilterOptions = {
|
||||||
@@ -100,6 +99,8 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
],
|
],
|
||||||
// 球局数量
|
// 球局数量
|
||||||
gamesNum: 0,
|
gamesNum: 0,
|
||||||
|
// 是否还有更多数据
|
||||||
|
isHasMoreData: true,
|
||||||
// 页面滚动距离顶部距离 是否大于0
|
// 页面滚动距离顶部距离 是否大于0
|
||||||
isScrollTop: false,
|
isScrollTop: false,
|
||||||
// 搜索历史数据
|
// 搜索历史数据
|
||||||
@@ -143,22 +144,31 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
lat: state?.location?.latitude,
|
lat: state?.location?.latitude,
|
||||||
lng: state?.location?.longitude,
|
lng: state?.location?.longitude,
|
||||||
};
|
};
|
||||||
console.log('===列表参数params', params)
|
|
||||||
return params;
|
return params;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 设置搜索的列表结果
|
// 设置搜索的列表结果
|
||||||
setListData: (payload: IPayload) => {
|
setListData: (payload: IPayload & { isAppend?: boolean }) => {
|
||||||
const { isSearchResult } = get();
|
const { isSearchResult } = get();
|
||||||
const { error, data, loading, gamesNum } = payload;
|
const { error, data, loading, count, isAppend = false } = payload;
|
||||||
const saveKey = isSearchResult ? "searchResultData" : "matches";
|
const saveKey = isSearchResult ? "searchResultData" : "matches";
|
||||||
const saveData = { error, loading, gamesNum, [saveKey]: data };
|
const isHasMoreData = count > 0;
|
||||||
console.log('===saveData', saveData)
|
|
||||||
set({...saveData});
|
if (isAppend) {
|
||||||
|
// 追加数据到现有数组
|
||||||
|
const currentData = get()[saveKey] || [];
|
||||||
|
const newData = [...currentData, ...(data || [])];
|
||||||
|
const saveData = { error, loading, count, isHasMoreData, [saveKey]: newData };
|
||||||
|
set({...saveData});
|
||||||
|
} else {
|
||||||
|
// 替换整个数组
|
||||||
|
const saveData = { error, loading, count, isHasMoreData, [saveKey]: data };
|
||||||
|
set({...saveData});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取列表数据(常规搜索)
|
// 获取列表数据(常规搜索)
|
||||||
fetchMatches: async (params, isFirstLoad = false) => {
|
fetchMatches: async (params, isFirstLoad = false, isAppend = false) => {
|
||||||
set({ loading: true, error: null });
|
set({ loading: true, error: null });
|
||||||
const { getSearchParams, setListData, distanceQuickFilter } = get();
|
const { getSearchParams, setListData, distanceQuickFilter } = get();
|
||||||
|
|
||||||
@@ -191,70 +201,45 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
error: "-1",
|
error: "-1",
|
||||||
data: [],
|
data: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
gamesNum: 0,
|
count: 0,
|
||||||
|
isAppend,
|
||||||
});
|
});
|
||||||
|
return Promise.reject(new Error('获取数据失败'));
|
||||||
}
|
}
|
||||||
const { count, rows } = data;
|
const { count, rows } = data;
|
||||||
setListData({
|
setListData({
|
||||||
error: '',
|
error: '',
|
||||||
data: rows || [],
|
data: rows || [],
|
||||||
loading: false,
|
loading: false,
|
||||||
gamesNum: count,
|
count,
|
||||||
|
isAppend,
|
||||||
});
|
});
|
||||||
|
return Promise.resolve();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setListData({
|
setListData({
|
||||||
error: "-1",
|
error: "-1",
|
||||||
data: [],
|
data: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
gamesNum: 0,
|
count: 0,
|
||||||
|
isAppend,
|
||||||
});
|
});
|
||||||
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取列表数据(智能筛选)
|
|
||||||
// getIntegrateListData: async (params) => {
|
|
||||||
// set({ loading: true, error: null });
|
|
||||||
// const { getSearchParams, setListData } = get();
|
|
||||||
// try {
|
|
||||||
// const searchParams = getSearchParams() || {};
|
|
||||||
// const reqParams = {
|
|
||||||
// ...(searchParams || {}),
|
|
||||||
// ...params,
|
|
||||||
// };
|
|
||||||
// reqParams.order = "";
|
|
||||||
// console.log("===getGamesIntegrateList 获取列表数据参数:", reqParams);
|
|
||||||
// const resData = (await getGamesIntegrateList(reqParams)) || {};
|
|
||||||
// const { data = {}, code } = resData;
|
|
||||||
// if (code !== 0) {
|
|
||||||
// setListData({
|
|
||||||
// error: '-1',
|
|
||||||
// data: [],
|
|
||||||
// loading: false,
|
|
||||||
// gamesNum: 0,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// const { count, rows } = data;
|
|
||||||
// setListData({
|
|
||||||
// // recommendList: rows || [],
|
|
||||||
// error: null,
|
|
||||||
// data: rows || [],
|
|
||||||
// loading: false,
|
|
||||||
// gamesNum: count,
|
|
||||||
// });
|
|
||||||
// } catch (error) {
|
|
||||||
// setListData({
|
|
||||||
// error: null,
|
|
||||||
// matches: [],
|
|
||||||
// loading: false,
|
|
||||||
// gamesNum: 0,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
|
|
||||||
// 获取列表数据
|
// 获取列表数据
|
||||||
getMatchesData: () => {
|
getMatchesData: async () => {
|
||||||
const { fetchMatches } = get();
|
const { fetchMatches } = get();
|
||||||
fetchMatches({}, true); // 第一次进入页面,传入 isFirstLoad = true
|
return await fetchMatches({}, true); // 第一次进入页面,传入 isFirstLoad = true
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取球局数量
|
||||||
|
fetchGetGamesCount: async () => {
|
||||||
|
const { getSearchParams } = get();
|
||||||
|
const params = getSearchParams() || {};
|
||||||
|
const resData = (await getGamesCount(params)) || {};
|
||||||
|
const gamesNum = resData?.data?.count || 0;
|
||||||
|
set({ gamesNum });
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取历史搜索数据
|
// 获取历史搜索数据
|
||||||
@@ -307,7 +292,7 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
|
|
||||||
// 更新综合筛选项
|
// 更新综合筛选项
|
||||||
updateFilterOptions: (payload: Record<string, any>) => {
|
updateFilterOptions: (payload: Record<string, any>) => {
|
||||||
const { filterOptions: preFilterOptions, getMatchesData } = get() || {};
|
const { filterOptions: preFilterOptions, fetchGetGamesCount } = get() || {};
|
||||||
const filterOptions = { ...preFilterOptions, ...payload };
|
const filterOptions = { ...preFilterOptions, ...payload };
|
||||||
const filterCount = Object.values(filterOptions).filter(Boolean).length;
|
const filterCount = Object.values(filterOptions).filter(Boolean).length;
|
||||||
console.log("===更新综合筛选项", filterOptions, filterCount);
|
console.log("===更新综合筛选项", filterOptions, filterCount);
|
||||||
@@ -316,42 +301,48 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
filterCount,
|
filterCount,
|
||||||
pageOption: defaultPageOption,
|
pageOption: defaultPageOption,
|
||||||
});
|
});
|
||||||
// 重新搜索数据
|
// 获取球局数量
|
||||||
getMatchesData();
|
fetchGetGamesCount();
|
||||||
},
|
},
|
||||||
|
|
||||||
// 清空综合筛选选项
|
// 清空综合筛选选项
|
||||||
clearFilterOptions: () => {
|
clearFilterOptions: () => {
|
||||||
const { getMatchesData } = get() || {};
|
const { getMatchesData, fetchGetGamesCount } = get() || {};
|
||||||
set({
|
set({
|
||||||
filterOptions: defaultFilterOptions,
|
filterOptions: defaultFilterOptions,
|
||||||
filterCount: 0,
|
filterCount: 0,
|
||||||
pageOption: defaultPageOption,
|
pageOption: defaultPageOption,
|
||||||
});
|
});
|
||||||
getMatchesData();
|
getMatchesData();
|
||||||
|
fetchGetGamesCount();
|
||||||
},
|
},
|
||||||
|
|
||||||
// 加载更多数据
|
// 加载更多数据
|
||||||
loadMoreMatches: () => {
|
loadMoreMatches: () => {
|
||||||
const { pageOption, getMatchesData } = get() || {};
|
const { pageOption, fetchMatches, isHasMoreData } = get() || {};
|
||||||
|
if (!isHasMoreData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
set({
|
set({
|
||||||
pageOption: {
|
pageOption: {
|
||||||
page: pageOption?.page + 1,
|
page: pageOption?.page + 1,
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
getMatchesData();
|
// 加载更多时追加数据到现有数组
|
||||||
|
fetchMatches({}, false, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 初始化搜索条件 重新搜索
|
// 初始化搜索条件 重新搜索
|
||||||
initialFilterSearch: () => {
|
initialFilterSearch: async () => {
|
||||||
const { getMatchesData } = get();
|
const { getMatchesData, fetchGetGamesCount } = get();
|
||||||
set({
|
set({
|
||||||
distanceQuickFilter: defaultDistanceQuickFilter,
|
distanceQuickFilter: defaultDistanceQuickFilter,
|
||||||
filterOptions: defaultFilterOptions,
|
filterOptions: defaultFilterOptions,
|
||||||
pageOption: defaultPageOption,
|
pageOption: defaultPageOption,
|
||||||
});
|
});
|
||||||
getMatchesData();
|
fetchGetGamesCount();
|
||||||
|
return await getMatchesData();
|
||||||
},
|
},
|
||||||
|
|
||||||
// 更新store数据
|
// 更新store数据
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export interface ListState {
|
|||||||
timeBubbleData: BubbleOption[]
|
timeBubbleData: BubbleOption[]
|
||||||
dateRangeOptions: BubbleOption[]
|
dateRangeOptions: BubbleOption[]
|
||||||
gamesNum: number
|
gamesNum: number
|
||||||
|
isHasMoreData: boolean
|
||||||
isScrollTop: boolean
|
isScrollTop: boolean
|
||||||
searchHistoryParams: Record<string, any>
|
searchHistoryParams: Record<string, any>
|
||||||
searchHistory: {id: number, title: string}[]
|
searchHistory: {id: number, title: string}[]
|
||||||
@@ -61,7 +62,7 @@ export interface ListState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ListActions {
|
export interface ListActions {
|
||||||
fetchMatches: (params?: Record<string, any>,isFirstLoad?: Boolean) => Promise<void>
|
fetchMatches: (params?: Record<string, any>, isFirstLoad?: Boolean, isAppend?: boolean) => Promise<void>
|
||||||
// getIntegrateListData: (params?: Record<string, any>) => Promise<void>
|
// getIntegrateListData: (params?: Record<string, any>) => Promise<void>
|
||||||
getMatchesData: () => void
|
getMatchesData: () => void
|
||||||
clearError: () => void
|
clearError: () => void
|
||||||
@@ -75,13 +76,15 @@ export interface ListActions {
|
|||||||
loadMoreMatches: () => void
|
loadMoreMatches: () => void
|
||||||
initialFilterSearch: () => void
|
initialFilterSearch: () => void
|
||||||
setListData: (payload: IPayload) => void
|
setListData: (payload: IPayload) => void
|
||||||
|
fetchGetGamesCount: () => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPayload {
|
export interface IPayload {
|
||||||
error: string;
|
error: string;
|
||||||
data: TennisMatch[];
|
data: TennisMatch[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
gamesNum: number;
|
count: number;
|
||||||
|
isAppend?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快捷筛选
|
// 快捷筛选
|
||||||
@@ -178,4 +181,13 @@ export interface ListCardProps {
|
|||||||
shinei: string;
|
shinei: string;
|
||||||
showSkeleton?: boolean;
|
showSkeleton?: boolean;
|
||||||
key?: string
|
key?: string
|
||||||
|
participants: {
|
||||||
|
avatar_url: string;
|
||||||
|
}[];
|
||||||
|
venue_image_list: {
|
||||||
|
url: string;
|
||||||
|
}[];
|
||||||
|
venue_description: string;
|
||||||
|
game_type: string;
|
||||||
|
type: string;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user