Initial CMPP frontend prototype

This commit is contained in:
hectorzhao
2026-06-30 16:09:46 +08:00
commit 2f3c274a30
98 changed files with 25255 additions and 0 deletions
@@ -0,0 +1,279 @@
import { useState } from 'react';
import {
AlertCircle,
Building2,
Check,
ChevronRight,
CreditCard,
Landmark,
ShieldCheck,
Upload,
UserCheck,
} from 'lucide-react';
import { Button, Input, Select, Textarea } from '@/components/ui';
type AuthStep = 'overview' | 'profile' | 'method' | 'recharge' | 'face' | 'faceScan' | 'success' | 'failed';
type AuthMethod = 'face' | 'recharge';
const companyInfo = {
name: '上海闪联九玖信息通信技术有限公司',
code: 'XXXXXXXXXX',
legalPerson: '张三',
certifiedAt: '2022年07月09日 13:12:01',
address: '上海XXX区XX路XX号',
};
function UploadPanel() {
return (
<div className="enterprise-upload">
<Upload size={38} />
<strong></strong>
</div>
);
}
function EnterpriseStepper({ current }: { current: number }) {
const steps = ['填写资料', '选择认证方式', '校验认证信息', '认证完成'];
return (
<div className="enterprise-stepper">
{steps.map((label, index) => {
const step = index + 1;
const complete = step < current;
const active = step === current;
return (
<div className="enterprise-stepper__item" key={label}>
<span className={['enterprise-stepper__dot', complete ? 'is-complete' : '', active ? 'is-active' : ''].filter(Boolean).join(' ')}>
{complete ? <Check size={20} /> : step}
</span>
<strong className={active || complete ? 'is-active' : ''}>{label}</strong>
{index < steps.length - 1 ? <ChevronRight className="enterprise-stepper__arrow" size={22} /> : null}
</div>
);
})}
</div>
);
}
function AuthHeader({ onCertified }: { onCertified: () => void }) {
return (
<div className="system-page-toolbar">
<div className="sms-send-title">
<span className="sms-send-title__icon"><ShieldCheck size={22} /></span>
<h1></h1>
</div>
<Button onClick={onCertified} variant="secondary"></Button>
</div>
);
}
export function ClientEnterpriseAuthPage() {
const [step, setStep] = useState<AuthStep>('overview');
const [method, setMethod] = useState<AuthMethod>('face');
const currentStep = step === 'profile' ? 1 : step === 'method' ? 2 : step === 'recharge' || step === 'face' || step === 'faceScan' ? 3 : step === 'success' || step === 'failed' ? 4 : 1;
if (step === 'overview') {
return (
<section className="page-stack enterprise-page">
<AuthHeader onCertified={() => setStep('success')} />
<div className="surface enterprise-status-card">
<strong></strong>
<button type="button" onClick={() => setStep('profile')}> &gt;</button>
</div>
<div className="surface enterprise-info-card">
<dl>
<div><dt></dt><dd></dd></div>
<div><dt></dt><dd></dd></div>
<div><dt></dt><dd></dd></div>
<div><dt></dt><dd></dd></div>
<div><dt></dt><dd></dd></div>
</dl>
</div>
</section>
);
}
return (
<section className="page-stack enterprise-page">
<h1 className="enterprise-page-title"></h1>
<div className="surface enterprise-flow-card">
<EnterpriseStepper current={currentStep} />
{step === 'profile' ? (
<div className="enterprise-form-panel">
<label className="enterprise-required"></label>
<UploadPanel />
<p className="enterprise-help">JPG或PNG格式5M</p>
<Input label="* 企业名称" placeholder="请填写企业全称" hint="请严格按照营业执照上的企业名称进行填写" />
<Input label="* 统一社会信用代码/其他组织机构代码" placeholder="请填写统一社会信用代码(若无请填写其他组织机构代码)" />
<div className="enterprise-address-selects">
<span>* </span>
<div>
<Select
options={[
{ label: '请选择省/直辖市', value: '' },
{ label: '上海市', value: 'shanghai' },
{ label: '北京市', value: 'beijing' },
]}
defaultValue=""
/>
<Select
options={[
{ label: '请选择', value: '' },
{ label: '浦东新区', value: 'pudong' },
{ label: '徐汇区', value: 'xuhui' },
]}
defaultValue=""
/>
</div>
</div>
<Textarea placeholder="请填写详细的通讯地址,可与证件上的地址不一致" rows={5} />
<p className="enterprise-form-note">便</p>
<Input label="* 企业联系人姓名" placeholder="请填写企业联系人姓名" />
<Input label="* 企业联系人身份证号" placeholder="请填写企业联系人身份证号" />
<Input label="* 企业联系人手机号" placeholder="请填写企业联系人手机号" />
<Input label="企业联系人邮箱" placeholder="请填写企业联系人邮箱" />
<div className="enterprise-actions">
<Button onClick={() => setStep('overview')} variant="secondary"></Button>
<Button onClick={() => setStep('method')}></Button>
</div>
</div>
) : null}
{step === 'method' ? (
<div className="enterprise-method-panel">
<button
className={['enterprise-method-card', method === 'face' ? 'is-selected' : ''].filter(Boolean).join(' ')}
onClick={() => setMethod('face')}
type="button"
>
<UserCheck size={56} />
<div>
<strong> <span></span></strong>
<p></p>
<p></p>
</div>
</button>
<button
className={['enterprise-method-card', method === 'recharge' ? 'is-selected' : ''].filter(Boolean).join(' ')}
onClick={() => setMethod('recharge')}
type="button"
>
<Landmark size={56} />
<div>
<strong> <span>1</span></strong>
<p>使1</p>
<p>使</p>
<p>退</p>
</div>
</button>
<div className="enterprise-actions">
<Button onClick={() => setStep('profile')} variant="secondary"></Button>
<Button onClick={() => setStep(method === 'face' ? 'face' : 'recharge')}></Button>
</div>
</div>
) : null}
{step === 'recharge' ? (
<div className="enterprise-verify-panel">
<p><span></span><strong></strong></p>
<p className="enterprise-verify-copy">
使 <em></em> <em>1</em>
</p>
<h2></h2>
<p><span></span><strong>XXXXXXX公司</strong></p>
<small>使便</small>
<div className="enterprise-info-alert">
<AlertCircle size={20} />
<span> <strong></strong> <em>7</em>2</span>
</div>
<div className="enterprise-actions enterprise-actions--center">
<Button onClick={() => setStep('success')}></Button>
<Button onClick={() => setStep('method')} variant="secondary"></Button>
</div>
</div>
) : null}
{step === 'face' ? (
<div className="enterprise-face-panel">
<p><span></span><strong></strong></p>
<h2></h2>
<Input label="* 企业法人姓名" placeholder="请填写企业法人姓名" />
<Input label="* 企业法人身份证号" placeholder="请填写企业法人身份证号" />
<div className="enterprise-actions">
<Button onClick={() => setStep('method')} variant="secondary"></Button>
<Button onClick={() => setStep('faceScan')}></Button>
</div>
</div>
) : null}
{step === 'faceScan' ? (
<div className="enterprise-face-panel">
<p><span></span><strong></strong></p>
<h2></h2>
<dl className="enterprise-legal-summary">
<div><dt></dt><dd></dd></div>
<div><dt></dt><dd>162xxxxxxxxxxxxx</dd></div>
</dl>
<div className="enterprise-qr-section">
<h2></h2>
<p>使<em>5957</em></p>
<div className="enterprise-qr"></div>
<span></span>
<div className="enterprise-actions enterprise-actions--center">
<Button onClick={() => setStep('face')} variant="secondary"></Button>
<Button onClick={() => setStep('success')} className="enterprise-success-test"></Button>
<Button onClick={() => setStep('failed')} variant="danger"></Button>
</div>
</div>
</div>
) : null}
{step === 'success' ? (
<div className="enterprise-result enterprise-result--success">
<span><Check size={70} /></span>
<h2></h2>
<dl>
<div><dt></dt><dd>{companyInfo.name}</dd></div>
<div><dt></dt><dd>{companyInfo.code}</dd></div>
<div><dt></dt><dd>{companyInfo.legalPerson}</dd></div>
<div><dt></dt><dd>{companyInfo.certifiedAt}</dd></div>
<div><dt></dt><dd>{companyInfo.address}</dd></div>
</dl>
<Button onClick={() => setStep('overview')} variant="secondary"></Button>
</div>
) : null}
{step === 'failed' ? (
<div className="enterprise-result enterprise-result--failed">
<span>!</span>
<h2></h2>
<p></p>
<strong>22359</strong>
<button type="button" onClick={() => setStep('method')}> <ChevronRight size={18} /></button>
<div className="enterprise-actions enterprise-actions--center">
<Button onClick={() => setStep('method')} variant="secondary"></Button>
<Button onClick={() => setStep('overview')} variant="secondary"></Button>
</div>
</div>
) : null}
</div>
</section>
);
}