202 lines
5.8 KiB
TypeScript
202 lines
5.8 KiB
TypeScript
import React, { useState, useCallback } from 'react'
|
||
import Taro from '@tarojs/taro'
|
||
import { View, Text, Image } from '@tarojs/components'
|
||
import images from '@/config/images'
|
||
import './StadiumDetail.scss'
|
||
import TextareaTag from '@/components/TextareaTag'
|
||
import CoverImageUpload, { type CoverImage } from '@/components/ImageUpload'
|
||
|
||
export interface Stadium {
|
||
id?: string
|
||
name: string
|
||
address?: string
|
||
longitude?: number
|
||
latitude?: number
|
||
istance?: string
|
||
}
|
||
|
||
interface StadiumDetailProps {
|
||
stadium: Stadium
|
||
onBack: () => void
|
||
onConfirm: (stadium: Stadium, venueType: string, groundMaterial: string, additionalInfo: string) => void
|
||
}
|
||
|
||
const stadiumInfo = [
|
||
{
|
||
label: '场地类型',
|
||
options: ['室内', '室外', '室外雨棚'],
|
||
prop: 'venueType',
|
||
type: 'tags'
|
||
},
|
||
{
|
||
label: '地面材质',
|
||
options: ['硬地', '红土', '草地'],
|
||
prop: 'groundMaterial',
|
||
type: 'tags'
|
||
},
|
||
{
|
||
label: '场地信息补充',
|
||
options: ['1号场', '2号场', '3号场', '4号场', '有空调', '6号场','6号场'],
|
||
prop: 'additionalInfo',
|
||
type: 'textareaTag'
|
||
},
|
||
{
|
||
label: '场地预定截图',
|
||
options: ['有其他场地信息可备注'],
|
||
prop: 'imagesList',
|
||
type: 'image'
|
||
}
|
||
]
|
||
|
||
// 公共的标题组件
|
||
const SectionTitle: React.FC<{ title: string,prop: string }> = ({ title, prop }) => {
|
||
console.log(prop,'propprop');
|
||
if (prop === 'imagesList') {
|
||
return (
|
||
<View className='section-title'>
|
||
<Text>{title}</Text>
|
||
<View className='heart-wrapper'>
|
||
<Image src={images.ICON_HEART_CIRCLE} className='heart-icon' />
|
||
<View className='icon-bg'></View>
|
||
<Text className='heart-text'>添加截图,平台会优先推荐</Text>
|
||
</View>
|
||
</View>
|
||
)
|
||
}
|
||
return (
|
||
<Text className='section-title'>{title}</Text>
|
||
)
|
||
}
|
||
|
||
// 公共的容器组件
|
||
const SectionContainer: React.FC<{ title: string; children: React.ReactNode, prop: string }> = ({ title, children, prop }) => (
|
||
<View className='venue-type-section'>
|
||
<SectionTitle title={title} prop={prop}/>
|
||
<View className='option-buttons'>
|
||
{children}
|
||
</View>
|
||
</View>
|
||
)
|
||
|
||
const StadiumDetail: React.FC<StadiumDetailProps> = ({
|
||
stadium,
|
||
}) => {
|
||
const [formData, setFormData] = useState({
|
||
stadiumName: stadium.name,
|
||
stadiumAddress: stadium.address,
|
||
stadiumLongitude: stadium.longitude,
|
||
stadiumLatitude: stadium.latitude,
|
||
istance: stadium.istance,
|
||
venueType: '室内',
|
||
groundMaterial: '硬地',
|
||
additionalInfo: '',
|
||
imagesList: [] as CoverImage[]
|
||
})
|
||
|
||
|
||
|
||
const handleMapLocation = () => {
|
||
Taro.chooseLocation({
|
||
success: (res) => {
|
||
console.log(res,'resres');
|
||
setFormData({
|
||
...formData,
|
||
stadiumName: res.name,
|
||
stadiumAddress: res.address,
|
||
stadiumLongitude: res.longitude,
|
||
stadiumLatitude: res.latitude
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.error('选择位置失败:', err)
|
||
Taro.showToast({
|
||
title: '位置选择失败',
|
||
icon: 'error'
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
const updateFormData = useCallback((prop: string, value: any) => {
|
||
setFormData(prev => ({ ...prev, [prop]: value }))
|
||
}, [])
|
||
|
||
const getSelectedByLabel = useCallback((label: string) => {
|
||
if (label === '场地类型') return formData.venueType
|
||
if (label === '地面材质') return formData.groundMaterial
|
||
return ''
|
||
}, [formData.venueType, formData.groundMaterial])
|
||
|
||
|
||
console.log(stadium,'stadiumstadium');
|
||
return (
|
||
<View className='stadium-detail'>
|
||
{/* 已选球场 */}
|
||
<View
|
||
className={`stadium-item`}
|
||
onClick={() => handleMapLocation()}
|
||
>
|
||
<View className='stadium-item-left'>
|
||
<Image src={images.ICON_STADIUM} className='stadium-icon' />
|
||
</View>
|
||
<View className='stadium-item-right'>
|
||
<View className='stadium-name'>{formData.stadiumName}</View>
|
||
<View className='stadium-address'>
|
||
<Text>{formData.istance} · </Text>
|
||
<Text>{formData.stadiumAddress}</Text>
|
||
<Image src={images.ICON_ARRORW_SMALL} className='stadium-map-icon' />
|
||
</View>
|
||
</View>
|
||
</View>
|
||
|
||
{stadiumInfo.map((item) => {
|
||
if (item.type === 'tags') {
|
||
const selected = getSelectedByLabel(item.label)
|
||
return (
|
||
<SectionContainer key={item.label} title={item.label} prop={item.prop}>
|
||
{item.options.map((opt) => (
|
||
<View
|
||
key={opt}
|
||
className={`option-btn ${selected === opt ? 'selected' : ''}`}
|
||
onClick={() => updateFormData(item.prop, opt)}
|
||
>
|
||
<Text className='option-text'>{opt}</Text>
|
||
</View>
|
||
))}
|
||
</SectionContainer>
|
||
)
|
||
}
|
||
|
||
if (item.type === 'textareaTag') {
|
||
return (
|
||
<SectionContainer key={item.label} title={item.label} prop={item.prop}>
|
||
<View className='textarea-tag-container'>
|
||
<TextareaTag
|
||
value={formData.additionalInfo}
|
||
onChange={(value) => updateFormData(item.prop, value)}
|
||
placeholder='有其他场地信息可备注'
|
||
options={(item.options || []).map((o) => ({ label: o, value: o }))}
|
||
/>
|
||
</View>
|
||
</SectionContainer>
|
||
)
|
||
}
|
||
|
||
if (item.type === 'image') {
|
||
return (
|
||
<SectionContainer key={item.label} title={item.label} prop={item.prop}>
|
||
<CoverImageUpload
|
||
images={formData.imagesList}
|
||
onChange={(images) => updateFormData(item.prop, images)}
|
||
/>
|
||
</SectionContainer>
|
||
)
|
||
}
|
||
|
||
return null
|
||
})}
|
||
</View>
|
||
)
|
||
}
|
||
|
||
export default StadiumDetail
|