diff --git a/frontend/src/pages/activity/Detail.jsx b/frontend/src/pages/activity/Detail.jsx index b825744..aa08c0b 100644 --- a/frontend/src/pages/activity/Detail.jsx +++ b/frontend/src/pages/activity/Detail.jsx @@ -3,9 +3,9 @@ import React, { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { motion, useScroll, useTransform } from 'framer-motion'; -import { ArrowLeftOutlined, ShareAltOutlined, CalendarOutlined, ClockCircleOutlined, EnvironmentOutlined, UserOutlined } from '@ant-design/icons'; +import { ArrowLeftOutlined, ShareAltOutlined, CalendarOutlined, ClockCircleOutlined, EnvironmentOutlined, UserOutlined, UploadOutlined } from '@ant-design/icons'; import confetti from 'canvas-confetti'; -import { message, Spin, Button, Result, Modal, Form, Input } from 'antd'; +import { message, Spin, Button, Result, Modal, Form, Input, Select, Radio, Checkbox, Upload } from 'antd'; import { getActivityDetail, signUpActivity } from '../../api'; import styles from '../../components/activity/activity.module.less'; import { pageTransition, buttonTap } from '../../animation'; @@ -119,9 +119,19 @@ const ActivityDetail = () => { }; const handleFormSubmit = (values) => { + // Handle file uploads if any (convert to base64 or just warn if not supported) + // For now, we just pass values. + // Note: File objects won't serialize to JSON well. signUpMutation.mutate(values); }; + const normFile = (e) => { + if (Array.isArray(e)) { + return e; + } + return e?.fileList; + }; + if (isLoading) { return (
@@ -315,16 +325,78 @@ const ActivityDetail = () => { destroyOnHidden >
- {activity.signup_form_config && activity.signup_form_config.map(field => ( - - - - ))} + {activity.signup_form_config && activity.signup_form_config.map(field => { + let inputNode; + const commonProps = { + placeholder: field.placeholder || `请输入${field.label}`, + }; + + switch (field.type) { + case 'select': + inputNode = ( + + ); + break; + case 'radio': + inputNode = ( + + {field.options?.map(opt => ( + + {opt.label} + + ))} + + ); + break; + case 'checkbox': + inputNode = ( + + {field.options?.map(opt => ( + + {opt.label} + + ))} + + ); + break; + case 'textarea': + inputNode = ; + break; + case 'file': + inputNode = ( + false} maxCount={1}> + + + ); + break; + default: + inputNode = ; + } + + const itemProps = { + key: field.name, + name: field.name, + label: field.label, + rules: [{ required: field.required, message: `请填写${field.label}` }], + }; + + if (field.type === 'file') { + itemProps.valuePropName = 'fileList'; + itemProps.getValueFromEvent = normFile; + } + + return ( + + {inputNode} + + ); + })}