列表
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
.customerNavbar {
|
||||
// background-color: red;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
background-color: #ffffff;
|
||||
|
||||
.container {
|
||||
padding-left: 17px;
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import { View, Text, Image } from "@tarojs/components";
|
||||
import img from "@/config/images";
|
||||
import { getCurrentLocation } from "@/utils/locationUtils";
|
||||
import { getNavbarHeight } from "@/utils/getNavbarHeight";
|
||||
import styles from "./index.module.scss";
|
||||
import { useEffect } from "react";
|
||||
import { useGlobalState } from "@/store/global";
|
||||
import { useListState } from "@/store/listStore";
|
||||
|
||||
const ListHeader = () => {
|
||||
const { statusBarHeight, navbarHeight, totalHeight } = getNavbarHeight();
|
||||
const {
|
||||
updateState,
|
||||
location,
|
||||
getLocationText,
|
||||
getLocationLoading,
|
||||
getNavbarHeightInfo,
|
||||
statusNavbarHeightInfo,
|
||||
} = useGlobalState();
|
||||
const { gamesNum } = useListState();
|
||||
console.log("===statusNavbarHeightInfo", statusNavbarHeightInfo);
|
||||
const { statusBarHeight, navbarHeight, totalHeight } = statusNavbarHeightInfo;
|
||||
|
||||
// 获取位置信息
|
||||
const getCurrentLocal = () => {
|
||||
@@ -31,7 +31,7 @@ const ListHeader = () => {
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
getNavbarHeightInfo();
|
||||
// getNavbarHeightInfo();
|
||||
getCurrentLocal();
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px 12px env(safe-area-inset-bottom);
|
||||
z-index: 999;
|
||||
|
||||
&-pages {
|
||||
display: flex;
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
.list-item {
|
||||
.listCard {
|
||||
background: linear-gradient(90deg, rgba(183, 248, 113, 0.5) 0%, rgba(183, 248, 113, 0.1) 100%);
|
||||
border-radius: 20px;
|
||||
border-width: 0.5px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
display: flex;
|
||||
padding: 12px 15px;
|
||||
background: #ffffff;
|
||||
@@ -247,4 +253,43 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
// 底部
|
||||
.smoothPlayingGame {
|
||||
padding: 5px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 12px;
|
||||
|
||||
.smoothWrapper,
|
||||
.localAreaWrapper {
|
||||
line-height: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.smoothTitle {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 8px;
|
||||
width: 1px;
|
||||
background: #00000040;
|
||||
border-radius: 99px;
|
||||
}
|
||||
|
||||
.iconListPlayingGame,
|
||||
.localArea {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.localArea {
|
||||
border: 0.5px solid #FFFFFFA6;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { View, Text, Image } from "@tarojs/components";
|
||||
import Taro from '@tarojs/taro'
|
||||
import Taro from "@tarojs/taro";
|
||||
import img from "../../config/images";
|
||||
import { ListCardProps } from "../../../types/list/types";
|
||||
import "./index.scss";
|
||||
@@ -14,7 +14,7 @@ const ListCard: React.FC<ListCardProps> = ({
|
||||
maxCount,
|
||||
skillLevel,
|
||||
matchType,
|
||||
images=[],
|
||||
images = [],
|
||||
shinei,
|
||||
}) => {
|
||||
const renderItemImage = (src: string) => {
|
||||
@@ -23,9 +23,9 @@ const ListCard: React.FC<ListCardProps> = ({
|
||||
|
||||
const handleViewDetail = () => {
|
||||
Taro.navigateTo({
|
||||
url: `/pages/detail/index?id=${id || 1}&from=list&autoShare=0`
|
||||
})
|
||||
}
|
||||
url: `/pages/detail/index?id=${id || 1}&from=list&autoShare=0`,
|
||||
});
|
||||
};
|
||||
|
||||
// 根据图片数量决定展示样式
|
||||
const renderImages = () => {
|
||||
@@ -34,9 +34,7 @@ const ListCard: React.FC<ListCardProps> = ({
|
||||
if (images?.length === 1) {
|
||||
return (
|
||||
<View className="single-image">
|
||||
<View className="image-container">
|
||||
{renderItemImage(images[0])}
|
||||
</View>
|
||||
<View className="image-container">{renderItemImage(images[0])}</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -44,12 +42,8 @@ const ListCard: React.FC<ListCardProps> = ({
|
||||
if (images?.length === 2) {
|
||||
return (
|
||||
<View className="double-image">
|
||||
<View className="image-container">
|
||||
{renderItemImage(images[0])}
|
||||
</View>
|
||||
<View className="image-container">
|
||||
{renderItemImage(images[1])}
|
||||
</View>
|
||||
<View className="image-container">{renderItemImage(images[0])}</View>
|
||||
<View className="image-container">{renderItemImage(images[1])}</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -64,72 +58,87 @@ const ListCard: React.FC<ListCardProps> = ({
|
||||
);
|
||||
};
|
||||
return (
|
||||
<View className="list-item" onClick={handleViewDetail}>
|
||||
{/* 左侧内容区域 */}
|
||||
<View className="content">
|
||||
{/* 标题 */}
|
||||
<View className="titleWrapper">
|
||||
<Text className="title">{title}</Text>
|
||||
<Image
|
||||
src={img.ICON_LIST_RIGHT_ARROW}
|
||||
className="title-right-arrow"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* 时间信息 */}
|
||||
|
||||
<View className="date-time">
|
||||
<Text>{dateTime}</Text>
|
||||
</View>
|
||||
|
||||
{/* 地点,室内外,距离 */}
|
||||
|
||||
<View className="location">
|
||||
<Text className="location-text location-position">{location}</Text>
|
||||
<Text className="location-text location-time-distance">
|
||||
{shinei && `・${shinei}`}
|
||||
{distance && `・${distance}`}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* 底部信息行:头像组、报名人数、技能等级、比赛类型 */}
|
||||
<View className="bottom-info">
|
||||
<View className="left-section">
|
||||
<View className="avatar-group">
|
||||
{Array.from({ length: Math.min(registeredCount, 3) }).map(
|
||||
(_, index) => (
|
||||
<View key={index} className="avatar">
|
||||
<Image
|
||||
className="avatar-image"
|
||||
src="https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=200&h=200&fit=crop&crop=center"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
)}
|
||||
</View>
|
||||
<View className="listCard">
|
||||
<View className="listItem" onClick={handleViewDetail}>
|
||||
{/* 左侧内容区域 */}
|
||||
<View className="content">
|
||||
{/* 标题 */}
|
||||
<View className="titleWrapper">
|
||||
<Text className="title">{title}</Text>
|
||||
<Image
|
||||
src={img.ICON_LIST_RIGHT_ARROW}
|
||||
className="title-right-arrow"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View className="tags">
|
||||
<View className="tag">
|
||||
<Text className="tag-text">
|
||||
报名人数 {registeredCount}/
|
||||
<Text className="tag-text-max">{maxCount}</Text>
|
||||
</Text>
|
||||
{/* 时间信息 */}
|
||||
|
||||
<View className="date-time">
|
||||
<Text>{dateTime}</Text>
|
||||
</View>
|
||||
|
||||
{/* 地点,室内外,距离 */}
|
||||
|
||||
<View className="location">
|
||||
<Text className="location-text location-position">{location}</Text>
|
||||
<Text className="location-text location-time-distance">
|
||||
{shinei && `・${shinei}`}
|
||||
{distance && `・${distance}`}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* 底部信息行:头像组、报名人数、技能等级、比赛类型 */}
|
||||
<View className="bottom-info">
|
||||
<View className="left-section">
|
||||
<View className="avatar-group">
|
||||
{Array.from({ length: Math.min(registeredCount, 3) }).map(
|
||||
(_, index) => (
|
||||
<View key={index} className="avatar">
|
||||
<Image
|
||||
className="avatar-image"
|
||||
src="https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=200&h=200&fit=crop&crop=center"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
<View className="tag">
|
||||
<Text className="tag-text">{skillLevel}</Text>
|
||||
</View>
|
||||
<View className="tag">
|
||||
<Text className="tag-text">{matchType}</Text>
|
||||
|
||||
<View className="tags">
|
||||
<View className="tag">
|
||||
<Text className="tag-text">
|
||||
报名人数 {registeredCount}/
|
||||
<Text className="tag-text-max">{maxCount}</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<View className="tag">
|
||||
<Text className="tag-text">{skillLevel}</Text>
|
||||
</View>
|
||||
<View className="tag">
|
||||
<Text className="tag-text">{matchType}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 右侧图片区域 */}
|
||||
<View className="image-section">{renderImages()}</View>
|
||||
</View>
|
||||
{/* 畅打球局 */}
|
||||
<View className="smoothPlayingGame">
|
||||
<View className="smoothWrapper">
|
||||
<Image src={img.ICON_LIST_PLAYING_GAME} className="iconListPlayingGame" />
|
||||
<Text className="smoothTitle">畅打球局</Text>
|
||||
</View>
|
||||
<View className="line" />
|
||||
<View>场馆方:</View>
|
||||
<View className="localAreaWrapper">
|
||||
<Image className="localArea" src="https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=200&h=200&fit=crop&crop=center" />
|
||||
<Text className="localAreaText">仁恒河滨花园网球场</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 右侧图片区域 */}
|
||||
<View className="image-section">{renderImages()}</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,7 +13,6 @@ const ListCard = () => {
|
||||
</View>
|
||||
|
||||
{/* 时间信息 */}
|
||||
|
||||
<View className="date-time">
|
||||
<Skeleton visible={false} style={{ width: "88px", }} />
|
||||
</View>
|
||||
|
||||
44
src/components/ListLoadError/index.module.scss
Normal file
44
src/components/ListLoadError/index.module.scss
Normal file
@@ -0,0 +1,44 @@
|
||||
.listLoadError {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 400px;
|
||||
|
||||
.listLoadErrorImg {
|
||||
width: 154px;
|
||||
height: 154px;
|
||||
}
|
||||
|
||||
.listLoadErrorText {
|
||||
margin-top: 35px;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 500;
|
||||
font-style: Medium;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
letter-spacing: 0px;
|
||||
}
|
||||
|
||||
.listLoadErrorBtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 76px;
|
||||
background: #00000008;
|
||||
border: 0.5px solid #0000001F;
|
||||
border-radius: 12px;
|
||||
padding: 12px 0;
|
||||
font-weight: 500;
|
||||
font-style: Medium;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
letter-spacing: 0px;
|
||||
|
||||
}
|
||||
|
||||
.reloadIcon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
24
src/components/ListLoadError/index.tsx
Normal file
24
src/components/ListLoadError/index.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Image, View, Text, Button } from "@tarojs/components";
|
||||
import styles from "./index.module.scss";
|
||||
import img from "@/config/images";
|
||||
|
||||
const ListLoadError = ({ reload }: { reload: () => void }) => {
|
||||
const handleReload = () => {
|
||||
reload && typeof reload === "function" && reload();
|
||||
};
|
||||
|
||||
return (
|
||||
<View className={styles.listLoadError}>
|
||||
<Image
|
||||
className={styles.listLoadErrorImg}
|
||||
src={img.ICON_LIST_LOAD_ERROR}
|
||||
/>
|
||||
<Text className={styles.listLoadErrorText}>加载失败</Text>
|
||||
<Button className={styles.listLoadErrorBtn} onClick={handleReload}>
|
||||
<Image src={img?.ICON_LIST_RELOAD} className={styles.reloadIcon} />
|
||||
重试
|
||||
</Button>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
export default ListLoadError;
|
||||
@@ -5,9 +5,16 @@
|
||||
--nutui-searchbar-input-text-color: #000000;
|
||||
--nutui-searchbar-input-padding: 0 0 0 10px;
|
||||
--nutui-searchbar-padding: 10px 0 0 0;
|
||||
|
||||
:global(.nut-searchbar-content) {
|
||||
box-shadow: 0 4px 48px #00000014;
|
||||
}
|
||||
|
||||
.searchBarLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.searchBarRight {
|
||||
position: relative;
|
||||
width: 44px;
|
||||
@@ -18,14 +25,17 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.active {
|
||||
background-color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
.filterIcon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.filterCount {
|
||||
background-color: #000000;
|
||||
position: absolute;
|
||||
@@ -41,8 +51,9 @@
|
||||
justify-content: center;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.searchIcon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ interface IProps {
|
||||
|
||||
const SearchBarComponent = (props: IProps) => {
|
||||
const { handleFilterIcon, isSelect, filterCount, onChange } = props;
|
||||
|
||||
const handleChange = (value: string) => {
|
||||
onChange && onChange(value);
|
||||
};
|
||||
@@ -19,9 +20,9 @@ const SearchBarComponent = (props: IProps) => {
|
||||
<>
|
||||
<SearchBar
|
||||
leftIn={
|
||||
<div>
|
||||
<View className={styles.searchBarLeft}>
|
||||
<Image className={styles.searchIcon} src={img.ICON_SEARCH} />
|
||||
</div>
|
||||
</View>
|
||||
}
|
||||
right={
|
||||
<View
|
||||
|
||||
Reference in New Issue
Block a user