635 lines
24 KiB
TypeScript
635 lines
24 KiB
TypeScript
import React, { useState, useRef, useImperativeHandle, forwardRef } from 'react'
|
||
import { View, Text, Image, Map, ScrollView } from '@tarojs/components'
|
||
import { Avatar, Popover } from '@nutui/nutui-react-taro'
|
||
import Taro, { useRouter, useShareAppMessage, useShareTimeline, useDidShow } from '@tarojs/taro'
|
||
import dayjs from 'dayjs'
|
||
import 'dayjs/locale/zh-cn'
|
||
// 导入API服务
|
||
import { CommonPopup, withAuth } from '@/components'
|
||
import DetailService, { MATCH_STATUS} from '@/services/detailService'
|
||
import { getCurrentLocation, calculateDistance } from '@/utils/locationUtils'
|
||
import {
|
||
useUserInfo,
|
||
useUserActions,
|
||
} from '@/store/userStore'
|
||
import img from '@/config/images'
|
||
// import { getTextColorOnImage } from '../../utils'
|
||
import './index.scss'
|
||
|
||
dayjs.locale('zh-cn')
|
||
|
||
// 将·作为连接符插入到标签文本之间
|
||
function insertDotInTags(tags: string[]) {
|
||
return tags.join('-·-').split('-')
|
||
}
|
||
|
||
// 分享弹窗
|
||
const SharePopup = forwardRef(({ id, from }: { id: string, from: string }, ref) => {
|
||
const [visible, setVisible] = useState(false)
|
||
|
||
useImperativeHandle(ref, () => ({
|
||
show: () => {
|
||
setVisible(true)
|
||
}
|
||
}))
|
||
|
||
// function handleShareToWechat() {
|
||
// useShareAppMessage(() => {
|
||
// return {
|
||
// title: '分享',
|
||
// path: `/pages/detail/index?id=${id}&from=share`,
|
||
// }
|
||
// })
|
||
// }
|
||
|
||
// function handleShareToWechatMoments() {
|
||
// useShareTimeline(() => {
|
||
// return {
|
||
// title: '分享',
|
||
// path: `/pages/detail/index?id=${id}&from=share`,
|
||
// }
|
||
// })
|
||
// }
|
||
|
||
// function handleSaveToLocal() {
|
||
// Taro.saveImageToPhotosAlbum({
|
||
// filePath: images[0],
|
||
// success: () => {
|
||
// Taro.showToast({ title: '保存成功', icon: 'success' })
|
||
// },
|
||
// fail: () => {
|
||
// Taro.showToast({ title: '保存失败', icon: 'none' })
|
||
// },
|
||
// })
|
||
// }
|
||
|
||
return (
|
||
<CommonPopup
|
||
title="分享"
|
||
visible={visible}
|
||
onClose={() => { setVisible(false) }}
|
||
hideFooter
|
||
style={{ minHeight: '100px' }}
|
||
>
|
||
<View catchMove className='share-popup-content'>
|
||
分享卡片
|
||
</View>
|
||
</CommonPopup>
|
||
)
|
||
})
|
||
|
||
// 底部操作栏
|
||
function StickyButton(props) {
|
||
const { handleShare, handleJoinGame, detail } = props
|
||
const userInfo = useUserInfo()
|
||
const { id } = userInfo
|
||
const { publisher_id, match_status, price } = detail || {}
|
||
|
||
const role = Number(publisher_id) === id ? 'ownner' : 'visitor'
|
||
console.log(match_status, role)
|
||
return (
|
||
<View className="sticky-bottom-bar">
|
||
<View className="sticky-bottom-bar-share-and-comment">
|
||
<View className='sticky-bottom-bar-share' onClick={handleShare}>
|
||
<Image className='sticky-bottom-bar-share-icon' src={img.ICON_DETAIL_SHARE} />
|
||
<Text className='sticky-bottom-bar-share-text'>分享</Text>
|
||
</View>
|
||
<View className='sticky-bottom-bar-share-and-comment-separator' />
|
||
<View className='sticky-bottom-bar-comment' onClick={() => { Taro.showToast({ title: 'To be continued', icon: 'none' }) }}>
|
||
<Image className='sticky-bottom-bar-comment-icon' src={img.ICON_DETAIL_COMMENT_DARK} />
|
||
<Text className='sticky-bottom-bar-comment-text'>32</Text>
|
||
</View>
|
||
</View>
|
||
<View className="sticky-bottom-bar-join-game" onClick={handleJoinGame}>
|
||
<Text>🎾</Text>
|
||
<Text>立即加入</Text>
|
||
<View className='game-price'>
|
||
<Text>¥ {price}</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
)
|
||
}
|
||
|
||
// 球局信息
|
||
function GameInfo(props) {
|
||
const { detail, currentLocation } = props
|
||
const { latitude, longitude, location, location_name, start_time, end_time } = detail || {}
|
||
|
||
const openMap = () => {
|
||
Taro.openLocation({
|
||
latitude, // 纬度(必填)
|
||
longitude, // 经度(必填)
|
||
name: location_name, // 位置名(可选)
|
||
address: location, // 地址详情(可选)
|
||
scale: 15, // 地图缩放级别(1-28)
|
||
})
|
||
}
|
||
|
||
const [c_latitude, c_longitude] = currentLocation
|
||
const distance = calculateDistance(c_latitude, c_longitude, latitude, longitude) / 1000
|
||
|
||
const startTime = dayjs(start_time)
|
||
const endTime = dayjs(end_time)
|
||
const game_length = endTime.diff(startTime, 'minutes') / 60
|
||
|
||
const startMonth = startTime.format('M')
|
||
const startDay = startTime.format('D')
|
||
const theDayOfWeek = startTime.format('dddd')
|
||
const startDate = `${startMonth}月${startDay}日 ${theDayOfWeek}`
|
||
const gameRange = `${startTime.format('HH:mm')} - ${endTime.format('HH:mm')}`
|
||
|
||
|
||
return (
|
||
<View className='detail-page-content-game-info'>
|
||
{/* Date and Weather */}
|
||
<View className='detail-page-content-game-info-date-weather'>
|
||
{/* Calendar and Date time */}
|
||
<View className='detail-page-content-game-info-date-weather-calendar-date'>
|
||
{/* Calendar */}
|
||
<View className='detail-page-content-game-info-date-weather-calendar-date-calendar'>
|
||
<View className="month">{startMonth}月</View>
|
||
<View className="day">{startDay}</View>
|
||
</View>
|
||
{/* Date time */}
|
||
<View className='detail-page-content-game-info-date-weather-calendar-date-date'>
|
||
<View className="date">{startDate}</View>
|
||
<View className="venue-time">{gameRange} ({game_length}小时)</View>
|
||
</View>
|
||
</View>
|
||
{/* Weather */}
|
||
<View className='detail-page-content-game-info-date-weather-weather'>
|
||
{/* Weather icon */}
|
||
<View className='detail-page-content-game-info-date-weather-weather-icon'>
|
||
<Image className="weather-icon" src={img.ICON_WEATHER_SUN} />
|
||
</View>
|
||
{/* Weather text and temperature */}
|
||
<View className='detail-page-content-game-info-date-weather-weather-text-temperature'>
|
||
<Text>28℃ - 32℃</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
{/* Place */}
|
||
<View className='detail-page-content-game-info-place'>
|
||
{/* venue location message */}
|
||
<View className='location-message'>
|
||
{/* location icon */}
|
||
<View className='location-message-icon'>
|
||
<Image className='location-message-icon-image' src={img.ICON_DETAIL_MAP} />
|
||
</View>
|
||
{/* location message */}
|
||
<View className='location-message-text'>
|
||
{/* venue name and distance */}
|
||
<View className='location-message-text-name-distance' onClick={openMap}>
|
||
<Text>{location_name || '-'}</Text>
|
||
<Text>·</Text>
|
||
<Text>{distance.toFixed(1)}km</Text>
|
||
<Image className='location-message-text-name-distance-arrow' src={img.ICON_DETAIL_ARROW_RIGHT} />
|
||
</View>
|
||
{/* venue address */}
|
||
<View className='location-message-text-address'>
|
||
<Text>{location || '-'}</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
{/* venue map */}
|
||
<View className='location-map'>
|
||
{longitude && latitude && (
|
||
<Map
|
||
className='location-map-map'
|
||
longitude={latitude}
|
||
latitude={longitude}
|
||
markers={[{ id: 1, latitude: longitude, longitude: latitude, iconPath: require('@/static/detail/icon-stark.svg'), width: 16, height: 16 }]}
|
||
includePoints={[{ latitude: longitude, longitude: latitude }, { latitude: currentLocation[0], longitude: currentLocation[1] }]}
|
||
includePadding={{ left: 50, right: 50, top: 50, bottom: 50 }}
|
||
onError={() => {}}
|
||
// hide business msg
|
||
showLocation
|
||
theme='dark'
|
||
/>
|
||
)}
|
||
</View>
|
||
</View>
|
||
</View>
|
||
)
|
||
}
|
||
|
||
function Index() {
|
||
// 使用Zustand store
|
||
// const userStats = useUserStats()
|
||
// const { incrementRequestCount, resetUserStats } = useUserActions()
|
||
|
||
const [current, setCurrent] = useState(0)
|
||
// const [textColor, setTextColor] = useState<string []>([])
|
||
const [detail, setDetail] = useState<any>(null)
|
||
const { params } = useRouter()
|
||
const [currentLocation, setCurrentLocation] = useState<[number, number]>([0, 0])
|
||
const { id, autoShare, from } = params
|
||
const { fetchUserInfo, updateUserInfo } = useUserActions()
|
||
|
||
console.group('params')
|
||
console.log(params)
|
||
console.groupEnd()
|
||
|
||
// 本地状态管理
|
||
const [loading, setLoading] = useState(false)
|
||
const sharePopupRef = useRef<any>(null)
|
||
|
||
// 页面加载时获取数据
|
||
// useEffect(() => {
|
||
// fetchDetail()
|
||
// calcBgMainColors()
|
||
// }, [])
|
||
|
||
useDidShow(async () => {
|
||
await updateLocation()
|
||
await fetchUserInfo()
|
||
await fetchDetail()
|
||
// calcBgMainColors()
|
||
})
|
||
|
||
const updateLocation = async () => {
|
||
try {
|
||
const location = await getCurrentLocation()
|
||
setCurrentLocation([location.latitude, location.longitude])
|
||
await updateUserInfo({ latitude: location.latitude, longitude: location.longitude })
|
||
console.log('用户位置更新成功')
|
||
} catch (error) {
|
||
console.error('用户位置更新失败', error)
|
||
}
|
||
}
|
||
|
||
const fetchDetail = async () => {
|
||
const res = await DetailService.getDetail(243/* Number(id) */)
|
||
if (res.code === 0) {
|
||
console.log(res.data)
|
||
setDetail(res.data)
|
||
}
|
||
}
|
||
|
||
// const calcBgMainColors = async () => {
|
||
// const textcolors: string[] = []
|
||
// // for (const index in images) {
|
||
// // const { textColor } = await getTextColorOnImage(images[index])
|
||
// // textcolors[index] = textColor
|
||
// // }
|
||
// if (detail?.image_list?.length > 0) {
|
||
// const { textColor } = await getTextColorOnImage(detail.image_list[0])
|
||
// textcolors[0] = textColor
|
||
// }
|
||
// setColors(textcolors)
|
||
// }
|
||
|
||
function handleShare() {
|
||
sharePopupRef.current.show()
|
||
}
|
||
|
||
const handleJoinGame = () => {
|
||
Taro.navigateTo({
|
||
url: `/pages/orderCheck/index?gameId=${243/* id */}`,
|
||
})
|
||
}
|
||
|
||
const tags = [{
|
||
name: '🕙 急招',
|
||
icon: '',
|
||
}, {
|
||
name: '🔥 本周热门',
|
||
icon: '',
|
||
}, {
|
||
name: '🎉 新活动',
|
||
icon: '',
|
||
}, {
|
||
name: '官方组织',
|
||
icon: '',
|
||
}]
|
||
|
||
const detailTags = ['室内', '硬地', '2号场', '有停车场', '有淋浴间', '有更衣室']
|
||
|
||
const { title, longitude, latitude } = detail || {}
|
||
|
||
console.log(longitude, latitude, 2222)
|
||
|
||
const requirements = [{
|
||
title: 'NTRP水平要求',
|
||
desc: '2.0 - 4.5 之间',
|
||
}, {
|
||
title: '活动玩法',
|
||
desc: '双打',
|
||
}, {
|
||
title: '人员构成',
|
||
desc: '个人球局 · 组织者参与活动',
|
||
}]
|
||
|
||
const participants = detail?.participants || []
|
||
|
||
const supplementalNotesTags = ['仅限男生', '装备自备', '其他']
|
||
|
||
const recommendGames = [
|
||
{
|
||
title: '黄浦日场对拉',
|
||
time: '2025-08-25 9:00',
|
||
timeLength: '2小时',
|
||
venue: '上海体育场',
|
||
veuneType: '室外',
|
||
distance: '1.2km',
|
||
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||
applications: 10,
|
||
checkedApplications: 3,
|
||
levelRequirements: 'NTRP 3.5',
|
||
playType: '双打',
|
||
},
|
||
{
|
||
title: '黄浦夜场对拉',
|
||
time: '2025-08-25 19:00',
|
||
timeLength: '2小时',
|
||
venue: '上海体育场',
|
||
veuneType: '室外',
|
||
distance: '1.2km',
|
||
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||
applications: 10,
|
||
checkedApplications: 3,
|
||
levelRequirements: 'NTRP 3.5',
|
||
playType: '双打',
|
||
},
|
||
{
|
||
title: '黄浦全天对拉',
|
||
time: '2025-08-25 9:00',
|
||
timeLength: '12小时',
|
||
venue: '上海体育场',
|
||
veuneType: '室外',
|
||
distance: '1.2km',
|
||
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||
applications: 10,
|
||
checkedApplications: 3,
|
||
levelRequirements: 'NTRP 3.5',
|
||
playType: '双打',
|
||
},
|
||
]
|
||
|
||
console.log('detail', detail)
|
||
return (
|
||
<View className='detail-page'>
|
||
{/* custom navbar */}
|
||
<view className="custom-navbar">
|
||
<View className='detail-navigator'>
|
||
<View className='detail-navigator-back' onClick={() => { Taro.navigateBack() }}>
|
||
<Image className='detail-navigator-back-icon' src={img.ICON_ARROW_LEFT} />
|
||
</View>
|
||
<View className='detail-navigator-icon'>
|
||
<Image className='detail-navigator-logo-icon' src={img.ICON_LOGO_GO} />
|
||
</View>
|
||
</View>
|
||
</view>
|
||
<View className='detail-page-bg' style={detail?.image_list?.[0] ? { backgroundImage: `url(${detail?.image_list?.[0]})` } : {}} />
|
||
<View className='detail-page-bg-text' />
|
||
{/* swiper */}
|
||
<View className="detail-swiper-container">
|
||
<View className="detail-swiper-scroll-container">
|
||
{
|
||
detail?.image_list?.length > 0 && detail?.image_list.map((item, index) => {
|
||
return (
|
||
<View className='detail-swiper-item' key={index}>
|
||
<Image
|
||
src={item}
|
||
mode="aspectFill"
|
||
className='detail-swiper-item-image'
|
||
/>
|
||
</View>
|
||
)
|
||
})
|
||
}
|
||
</View>
|
||
</View>
|
||
{/* <Swiper
|
||
className='detail-swiper'
|
||
indicatorDots={false}
|
||
circular
|
||
nextMargin="20px"
|
||
onChange={(e) => { setCurrent(e.detail.current) }}
|
||
>
|
||
{images.map((imageUrl, index) => (
|
||
<SwiperItem
|
||
key={index}
|
||
className='detail-swiper-item'
|
||
>
|
||
<Image
|
||
src={imageUrl}
|
||
mode="aspectFill"
|
||
className='detail-swiper-item-image'
|
||
style={{
|
||
transform: index !== current ? 'scale(0.8) translateX(-12%)' : 'scale(0.95)', // 前后图缩小
|
||
}}
|
||
/>
|
||
</SwiperItem>
|
||
))}
|
||
</Swiper> */}
|
||
{/* content */}
|
||
<View className='detail-page-content'>
|
||
{/* avatar and tags */}
|
||
<View className='detail-page-content-avatar-tags'>
|
||
<View className='detail-page-content-avatar-tags-avatar'>
|
||
{/* network image mock */}
|
||
<Image className='detail-page-content-avatar-tags-avatar-image' src="https://img.yzcdn.cn/vant/cat.jpeg" />
|
||
</View>
|
||
<View className='detail-page-content-avatar-tags-tags'>
|
||
{tags.map((tag, index) => (
|
||
<View key={index} className='detail-page-content-avatar-tags-tags-tag'>
|
||
{tag.icon && <Image src={tag.icon} />}
|
||
<Text>{tag.name}</Text>
|
||
</View>
|
||
))}
|
||
</View>
|
||
</View>
|
||
{/* title */}
|
||
<View className='detail-page-content-title'>
|
||
<Text className='detail-page-content-title-text'>{title}</Text>
|
||
</View>
|
||
{/* Date and Place and weather */}
|
||
<GameInfo detail={detail} currentLocation={currentLocation} />
|
||
{/* detail */}
|
||
<View className='detail-page-content-detail'>
|
||
{/* venue detail title and venue ordered status */}
|
||
<View className='venue-detail-title'>
|
||
<Text>场馆详情</Text>
|
||
<Text>·</Text>
|
||
<Text>已订场</Text>
|
||
<Popover
|
||
title="场地预定截图"
|
||
description={<View>
|
||
<Image src="https://img.yzcdn.cn/vant/cat.jpeg" />
|
||
</View>}
|
||
location='top'
|
||
visible={false}
|
||
>
|
||
<Image className='venue-detail-title-notice-icon' src={img.ICON_DETAIL_NOTICE} />
|
||
</Popover>
|
||
</View>
|
||
{/* venue detail content */}
|
||
<View className='venue-detail-content'>
|
||
{/* venue detail tags */}
|
||
<View className='venue-detail-content-tags'>
|
||
{insertDotInTags(detailTags).map((tag, index) => (
|
||
<View key={index} className='venue-detail-content-tags-tag'>
|
||
<Text>{tag}</Text>
|
||
</View>
|
||
))}
|
||
</View>
|
||
{/* venue remarks */}
|
||
<View className='venue-detail-content-remarks'>
|
||
<Text>其他这是用户在场地补充描述里自己写的东西啦啦啦啦啦啦啦啦啦啦啦啦</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
{/* gameplay requirements */}
|
||
<View className='detail-page-content-gameplay-requirements'>
|
||
{/* title */}
|
||
<View className="gameplay-requirements-title">
|
||
<Text>玩法要求</Text>
|
||
</View>
|
||
{/* requirements */}
|
||
<View className='gameplay-requirements'>
|
||
{requirements.map((item, index) => (
|
||
<View key={index} className='gameplay-requirements-item'>
|
||
<Text className='gameplay-requirements-item-title'>{item.title}</Text>
|
||
<Text className='gameplay-requirements-item-desc'>{item.desc}</Text>
|
||
</View>
|
||
))}
|
||
</View>
|
||
</View>
|
||
{/* participants */}
|
||
<View className='detail-page-content-participants'>
|
||
<View className='participants-title'>
|
||
<Text>参与者</Text>
|
||
<Text>·</Text>
|
||
<Text>剩余空位 3</Text>
|
||
</View>
|
||
<View className='participants-list'>
|
||
{/* application */}
|
||
<View className='participants-list-application' onClick={() => { Taro.showToast({ title: 'To be continued', icon: 'none' }) }}>
|
||
<Image className='participants-list-application-icon' src={img.ICON_DETAIL_APPLICATION_ADD} />
|
||
<Text className='participants-list-application-text'>申请加入</Text>
|
||
</View>
|
||
{/* participants list */}
|
||
<ScrollView className='participants-list-scroll' scrollX>
|
||
<View className='participants-list-scroll-content' style={{ width: `${participants.length * 103 + (participants.length - 1) * 8}px` }}>
|
||
{participants.map((participant) => (
|
||
<View key={participant.id} className='participants-list-item'>
|
||
{/* <Avatar className='participants-list-item-avatar' src={participant.user.avatar_url} /> */}
|
||
{/* network image mock random */}
|
||
<Avatar className='participants-list-item-avatar' src={`https://picsum.photos/800/600?random=${participant.id}`} />
|
||
<Text className='participants-list-item-name'>{participant.user.nickname || '未知'}</Text>
|
||
<Text className='participants-list-item-level'>{participant.level || '未知'}</Text>
|
||
<Text className='participants-list-item-role'>{participant.role || '参与者'}</Text>
|
||
</View>
|
||
))}
|
||
</View>
|
||
</ScrollView>
|
||
</View>
|
||
</View>
|
||
{/* supplemental notes */}
|
||
<View className='detail-page-content-supplemental-notes'>
|
||
<View className='supplemental-notes-title'>
|
||
<Text>补充说明</Text>
|
||
</View>
|
||
<View className='supplemental-notes-content'>
|
||
{/* supplemental notes tags */}
|
||
<View className='supplemental-notes-content-tags'>
|
||
{insertDotInTags(supplementalNotesTags).map((tag, index) => (
|
||
<View key={index} className='supplemental-notes-content-tags-tag'>
|
||
<Text>{tag}</Text>
|
||
</View>
|
||
))}
|
||
</View>
|
||
{/* supplemental notes content */}
|
||
<View className='supplemental-notes-content-text'>
|
||
<Text>其他这是用户在补充说明里自己写的东西啦啦啦啦啦啦啦啦啦啦啦啦其他这是用户在补充说明里自己写的东西啦啦啦啦啦啦啦啦啦啦啦啦</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
{/* organizer and recommend games by organizer */}
|
||
<View className='detail-page-content-organizer-recommend-games'>
|
||
{/* orgnizer title */}
|
||
<View className='organizer-title'>
|
||
<Text>组织者</Text>
|
||
</View>
|
||
{/* organizer avatar and name */}
|
||
<View className='organizer-avatar-name'>
|
||
<Avatar className='organizer-avatar-name-avatar' src="https://img.yzcdn.cn/vant/cat.jpeg" />
|
||
<View className='organizer-avatar-name-message'>
|
||
<Text className='organizer-avatar-name-message-name'>Light</Text>
|
||
<View className='organizer-avatar-name-message-stats'>
|
||
<Text>已组织 8 次</Text>
|
||
<View className='organizer-avatar-name-message-stats-separator' />
|
||
<Text>NTRP 3.5</Text>
|
||
</View>
|
||
</View>
|
||
<View className="organizer-actions">
|
||
<View className="organizer-actions-follow">
|
||
<Image className='organizer-actions-follow-icon' src={img.ICON_DETAIL_APPLICATION_ADD} />
|
||
<Text className='organizer-actions-follow-text'>关注</Text>
|
||
</View>
|
||
<View className="organizer-actions-comment">
|
||
<Image className='organizer-actions-comment-icon' src={img.ICON_DETAIL_COMMENT} />
|
||
</View>
|
||
</View>
|
||
</View>
|
||
{/* recommend games by organizer */}
|
||
<View className='organizer-recommend-games'>
|
||
<View className='organizer-recommend-games-title'>
|
||
<Text>TA的更多活动</Text>
|
||
<Image className='organizer-recommend-games-title-arrow' src={img.ICON_DETAIL_ARROW_RIGHT} />
|
||
</View>
|
||
<ScrollView className='recommend-games-list' scrollX>
|
||
<View className='recommend-games-list-content'>
|
||
{recommendGames.map((game, index) => (
|
||
<View key={index} className='recommend-games-list-item'>
|
||
{/* game title */}
|
||
<View className='recommend-games-list-item-title'>
|
||
<Text>{game.title}</Text>
|
||
<Image className='recommend-games-list-item-title-arrow' src={img.ICON_DETAIL_ARROW_RIGHT} />
|
||
</View>
|
||
{/* game time and range */}
|
||
<View className='recommend-games-list-item-time-range'>
|
||
<Text>{game.time}</Text>
|
||
<Text>{game.timeLength}</Text>
|
||
</View>
|
||
{/* game location、vunue、distance */}
|
||
<View className='recommend-games-list-item-location-venue-distance'>
|
||
<Text>{game.venue}</Text>
|
||
<Text>·</Text>
|
||
<Text>{game.veuneType}</Text>
|
||
<Text>·</Text>
|
||
<Text>{game.distance}</Text>
|
||
</View>
|
||
{/* organizer avatar、applications、level requirements、play type */}
|
||
<View className='recommend-games-list-item-addon'>
|
||
<Avatar className='recommend-games-list-item-addon-avatar' src={game.avatar} />
|
||
<View className='recommend-games-list-item-addon-message'>
|
||
<View className='recommend-games-list-item-addon-message-applications'>
|
||
<Text>报名人数 {game.checkedApplications}/{game.applications}</Text>
|
||
</View>
|
||
<View className='recommend-games-list-item-addon-message-level-requirements'>
|
||
<Text>{game.levelRequirements}</Text>
|
||
</View>
|
||
<View className='recommend-games-list-item-addon-message-play-type'>
|
||
<Text>{game.playType}</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
))}
|
||
</View>
|
||
</ScrollView>
|
||
</View>
|
||
</View>
|
||
{/* sticky bottom action bar */}
|
||
<StickyButton handleShare={handleShare} handleJoinGame={handleJoinGame} detail={detail} />
|
||
{/* share popup */}
|
||
<SharePopup ref={sharePopupRef} id={id as string} from={from as string} />
|
||
</View>
|
||
</View>
|
||
)
|
||
}
|
||
|
||
export default withAuth(Index) |