This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import Taro, { useRouter, useShareAppMessage, useShareTimeline, useDidShow } from '@tarojs/taro'
|
||||
import { View, Text, Image, Button, RichText, Picker } from '@tarojs/components'
|
||||
import { AtIcon, AtProgress, AtModal, AtModalHeader, AtModalContent, AtModalAction, AtInput, AtTextarea, AtRadio, AtCheckbox } from 'taro-ui'
|
||||
import { View, Text, Image, Button, Picker } from '@tarojs/components'
|
||||
import { AtIcon, AtModal, AtModalHeader, AtModalContent, AtModalAction, AtInput, AtTextarea, AtRadio, AtCheckbox } from 'taro-ui'
|
||||
import { getActivityDetail, signupActivity } from '../../../api'
|
||||
import { marked } from 'marked'
|
||||
import MarkdownReader from '../../../components/MarkdownReader'
|
||||
import './detail.scss'
|
||||
|
||||
const ActivityDetail = () => {
|
||||
@@ -13,7 +13,6 @@ const ActivityDetail = () => {
|
||||
const [activity, setActivity] = useState<any>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [htmlContent, setHtmlContent] = useState('')
|
||||
const [signupPercentage, setSignupPercentage] = useState(0)
|
||||
|
||||
// Signup Form State
|
||||
@@ -51,11 +50,6 @@ const ActivityDetail = () => {
|
||||
const percent = Math.min(100, Math.round((data.current_signups || 0) / data.max_participants * 100))
|
||||
setSignupPercentage(percent)
|
||||
}
|
||||
|
||||
if (data.description) {
|
||||
const html = marked.parse(data.description)
|
||||
setHtmlContent((html as string).replace(/<img/g, '<img style="max-width:100%;border-radius:8px;"'))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
Taro.showToast({ title: '加载失败', icon: 'none' })
|
||||
@@ -130,8 +124,11 @@ const ActivityDetail = () => {
|
||||
|
||||
const handleModalConfirm = () => {
|
||||
// Validate
|
||||
if (activity.signup_form_config) {
|
||||
if (activity.signup_form_config && Array.isArray(activity.signup_form_config)) {
|
||||
for (const field of activity.signup_form_config) {
|
||||
// Defensive programming: skip invalid fields
|
||||
if (!field || typeof field !== 'object') continue
|
||||
|
||||
if (field.required && !formData[field.name]) {
|
||||
Taro.showToast({ title: `请填写${field.label}`, icon: 'none' })
|
||||
return
|
||||
@@ -233,7 +230,7 @@ const ActivityDetail = () => {
|
||||
<View className='line' />
|
||||
</View>
|
||||
<View className='rich-text-wrapper'>
|
||||
<RichText nodes={htmlContent} />
|
||||
<MarkdownReader content={activity.description} themeColor='#00f0ff' />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
@@ -270,7 +267,10 @@ const ActivityDetail = () => {
|
||||
<AtModalHeader>填写报名信息</AtModalHeader>
|
||||
<AtModalContent>
|
||||
<View className='signup-form'>
|
||||
{activity.signup_form_config && activity.signup_form_config.map((field, idx) => {
|
||||
{activity.signup_form_config && Array.isArray(activity.signup_form_config) && activity.signup_form_config.map((field, idx) => {
|
||||
// Defensive programming: skip invalid fields or known bad data
|
||||
if (!field || typeof field !== 'object' || field.label === '自定义报名配置') return null
|
||||
|
||||
if (field.type === 'select') {
|
||||
const currentOption = field.options?.find(opt => opt.value === formData[field.name])
|
||||
return (
|
||||
@@ -375,4 +375,4 @@ const ActivityDetail = () => {
|
||||
)
|
||||
}
|
||||
|
||||
export default ActivityDetail
|
||||
export default ActivityDetail
|
||||
|
||||
Reference in New Issue
Block a user