safety-eval-service-frontend/src/pages/Container/EnterpriseInfo/MaterialReport/index.js

194 lines
5.4 KiB
JavaScript
Raw Normal View History

import React, { useEffect, useMemo, useRef, useState } from 'react';
import { Button, Form, Input, message, Space } from 'antd';
import {
CheckCircleFilled,
FileSearchOutlined,
LoadingOutlined,
SafetyCertificateFilled
} from '@ant-design/icons';
import './index.css';
import { materialFields, materialInitialValues, mockSubmitMaterial } from './mockData';
const steps = [
{ key: 1, title: '填写信息' },
{ key: 2, title: '认证审核中' },
{ key: 3, title: '认证通过' }
];
function PageHeader() {
return (
<div className="material-report-header">
<div className="material-report-brand">
<span className="material-report-logo"><SafetyCertificateFilled /></span>
<span>巫溪县安全评价在线监管一件事</span>
</div>
<div className="material-report-hero">
<h1>认证信息</h1>
<div className="material-report-hero-art">
<div className="verify-platform"><CheckCircleFilled /></div>
<div className="verify-card" />
</div>
</div>
</div>
);
}
function StepHeader({ current }) {
return (
<div className="material-report-steps">
{steps.map((step, index) => {
const active = current >= step.key;
const currentStep = current === step.key;
return (
<div key={step.key} className={`material-step ${active ? 'is-active' : ''} ${currentStep ? 'is-current' : ''}`}>
<span className="material-step__dot">{step.key}</span>
<span className="material-step__title">{step.title}</span>
{index < steps.length - 1 && <i className="material-step__line" />}
</div>
);
})}
</div>
);
}
function FieldItem({ field }) {
const labelLines = field.label.split('\n');
return (
<div className={`material-form-field material-form-field--${field.span}`}>
<Form.Item
name={field.name}
label={(
<span>
{labelLines.map((line) => <React.Fragment key={line}>{line}<br /></React.Fragment>)}
</span>
)}
rules={field.span === 24 ? [{ required: true, message: `请输入${labelLines[0]}` }] : undefined}
>
<Input />
</Form.Item>
</div>
);
}
function FillStep({ onSubmitted }) {
const [form] = Form.useForm();
const [submitting, setSubmitting] = useState(false);
const groupedRows = useMemo(() => {
const rows = [];
let current = [];
let used = 0;
materialFields.forEach((field) => {
if (field.span === 24) {
if (current.length) rows.push(current);
rows.push([field]);
current = [];
used = 0;
return;
}
if (used + field.span > 24) {
rows.push(current);
current = [];
used = 0;
}
current.push(field);
used += field.span;
});
if (current.length) rows.push(current);
return rows;
}, []);
const handleSubmit = async () => {
try {
const values = await form.validateFields();
setSubmitting(true);
const res = await mockSubmitMaterial(values);
if (res?.success) {
message.success('提交成功,正在进入认证审核');
onSubmitted(res.data);
}
}
catch (err) {
if (!err?.errorFields) {
message.error('提交失败,请稍后重试');
}
}
finally {
setSubmitting(false);
}
};
return (
<div className="material-fill-step">
<Form form={form} initialValues={materialInitialValues} colon={false} labelAlign="right">
<div className="material-form-grid">
{groupedRows.map((row, index) => (
<div key={index} className="material-form-row">
{row.map((field) => <FieldItem key={field.name} field={field} />)}
</div>
))}
</div>
</Form>
<div className="material-form-actions">
<Space size={10}>
<Button>取消</Button>
<Button className="material-save-btn">保存</Button>
<Button type="primary" loading={submitting} onClick={handleSubmit}>提交</Button>
</Space>
</div>
</div>
);
}
function ReviewLoadingStep() {
return (
<div className="material-result-wrap">
<div className="review-loading-icon">
<div className="review-loading-ring" />
<FileSearchOutlined />
<span />
</div>
<p>认证审核中请耐心等待...</p>
</div>
);
}
function ReviewSuccessStep() {
return (
<div className="material-result-wrap material-success-wrap">
<div className="review-success-illustration">
<div className="success-paper">
<i /><i /><i /><i />
</div>
<CheckCircleFilled />
</div>
<p>审核通过</p>
</div>
);
}
export default function MaterialReportPage() {
const [current, setCurrent] = useState(1);
const timerRef = useRef(null);
useEffect(() => () => clearTimeout(timerRef.current), []);
const handleSubmitted = () => {
setCurrent(2);
clearTimeout(timerRef.current);
timerRef.current = setTimeout(() => {
setCurrent(3);
}, 2300);
};
return (
<div className={`material-report-page material-report-page--step-${current}`}>
<PageHeader />
<StepHeader current={current} />
{current === 1 && <FillStep onSubmitted={handleSubmitted} />}
{current === 2 && <ReviewLoadingStep />}
{current === 3 && <ReviewSuccessStep />}
</div>
);
}