This commit is contained in:
@@ -3,9 +3,9 @@ import React, { useState, useEffect } from 'react';
|
|||||||
import { useParams, useNavigate } from 'react-router-dom';
|
import { useParams, useNavigate } from 'react-router-dom';
|
||||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { motion, useScroll, useTransform } from 'framer-motion';
|
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 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 { getActivityDetail, signUpActivity } from '../../api';
|
||||||
import styles from '../../components/activity/activity.module.less';
|
import styles from '../../components/activity/activity.module.less';
|
||||||
import { pageTransition, buttonTap } from '../../animation';
|
import { pageTransition, buttonTap } from '../../animation';
|
||||||
@@ -119,9 +119,19 @@ const ActivityDetail = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleFormSubmit = (values) => {
|
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);
|
signUpMutation.mutate(values);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const normFile = (e) => {
|
||||||
|
if (Array.isArray(e)) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
return e?.fileList;
|
||||||
|
};
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh', background: '#1f1f1f' }}>
|
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh', background: '#1f1f1f' }}>
|
||||||
@@ -315,16 +325,78 @@ const ActivityDetail = () => {
|
|||||||
destroyOnHidden
|
destroyOnHidden
|
||||||
>
|
>
|
||||||
<Form form={form} onFinish={handleFormSubmit} layout="vertical">
|
<Form form={form} onFinish={handleFormSubmit} layout="vertical">
|
||||||
{activity.signup_form_config && activity.signup_form_config.map(field => (
|
{activity.signup_form_config && activity.signup_form_config.map(field => {
|
||||||
<Form.Item
|
let inputNode;
|
||||||
key={field.name}
|
const commonProps = {
|
||||||
name={field.name}
|
placeholder: field.placeholder || `请输入${field.label}`,
|
||||||
label={field.label}
|
};
|
||||||
rules={[{ required: field.required, message: `请填写${field.label}` }]}
|
|
||||||
>
|
switch (field.type) {
|
||||||
<Input placeholder={`请输入${field.label}`} />
|
case 'select':
|
||||||
</Form.Item>
|
inputNode = (
|
||||||
|
<Select placeholder={field.placeholder || `请选择${field.label}`}>
|
||||||
|
{field.options?.map(opt => (
|
||||||
|
<Select.Option key={opt.value} value={opt.value}>
|
||||||
|
{opt.label}
|
||||||
|
</Select.Option>
|
||||||
))}
|
))}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'radio':
|
||||||
|
inputNode = (
|
||||||
|
<Radio.Group>
|
||||||
|
{field.options?.map(opt => (
|
||||||
|
<Radio key={opt.value} value={opt.value}>
|
||||||
|
{opt.label}
|
||||||
|
</Radio>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'checkbox':
|
||||||
|
inputNode = (
|
||||||
|
<Checkbox.Group>
|
||||||
|
{field.options?.map(opt => (
|
||||||
|
<Checkbox key={opt.value} value={opt.value}>
|
||||||
|
{opt.label}
|
||||||
|
</Checkbox>
|
||||||
|
))}
|
||||||
|
</Checkbox.Group>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'textarea':
|
||||||
|
inputNode = <Input.TextArea {...commonProps} rows={4} />;
|
||||||
|
break;
|
||||||
|
case 'file':
|
||||||
|
inputNode = (
|
||||||
|
<Upload beforeUpload={() => false} maxCount={1}>
|
||||||
|
<Button icon={<UploadOutlined />}>点击上传</Button>
|
||||||
|
</Upload>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
inputNode = <Input {...commonProps} type={field.type === 'tel' ? 'tel' : 'text'} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<Form.Item {...itemProps}>
|
||||||
|
{inputNode}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|||||||
Reference in New Issue
Block a user