284 lines
12 KiB
TypeScript
284 lines
12 KiB
TypeScript
|
|
import { CloseOutlined, ExperimentOutlined } from "@ant-design/icons";
|
|||
|
|
import { useState } from "react";
|
|||
|
|
|
|||
|
|
interface BetaApplicationModalProps {
|
|||
|
|
open: boolean;
|
|||
|
|
onClose: () => void;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ── Form state ── */
|
|||
|
|
interface BetaFormData {
|
|||
|
|
name: string;
|
|||
|
|
phone: string;
|
|||
|
|
wechat: string;
|
|||
|
|
industry: string;
|
|||
|
|
company: string;
|
|||
|
|
city: string;
|
|||
|
|
aiTools: string;
|
|||
|
|
aiDuration: string;
|
|||
|
|
aiTrack: string;
|
|||
|
|
aiDirection: string[];
|
|||
|
|
weeklyUsage: string;
|
|||
|
|
feedbackWilling: string;
|
|||
|
|
wantFeature: string[];
|
|||
|
|
selfStatement: string;
|
|||
|
|
signature: string;
|
|||
|
|
agreeRules: boolean;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const INITIAL_FORM: BetaFormData = {
|
|||
|
|
name: "",
|
|||
|
|
phone: "",
|
|||
|
|
wechat: "",
|
|||
|
|
industry: "",
|
|||
|
|
company: "",
|
|||
|
|
city: "",
|
|||
|
|
aiTools: "",
|
|||
|
|
aiDuration: "",
|
|||
|
|
aiTrack: "",
|
|||
|
|
aiDirection: [],
|
|||
|
|
weeklyUsage: "",
|
|||
|
|
feedbackWilling: "",
|
|||
|
|
wantFeature: [],
|
|||
|
|
selfStatement: "",
|
|||
|
|
signature: "",
|
|||
|
|
agreeRules: false,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* ── Option groups (from the docx) ── */
|
|||
|
|
const AI_DURATION_OPTIONS = ["1年以内", "1-3年", "3-5年", "5年以上"];
|
|||
|
|
const AI_TRACK_OPTIONS = ["是,长期承接相关业务", "业余创作", "新手学习"];
|
|||
|
|
const AI_DIRECTION_OPTIONS = [
|
|||
|
|
"AI短剧批量制作", "漫剧剧情生成", "自媒体短视频", "电商图文及视频素材",
|
|||
|
|
"MCN商业内容", "企业宣传视频", "个人兴趣创作", "其他",
|
|||
|
|
];
|
|||
|
|
const WEEKLY_USAGE_OPTIONS = ["7次及以上", "1-3次", "空闲时间使用"];
|
|||
|
|
const FEEDBACK_OPTIONS = ["全力配合深度反馈", "简单体验留言", "仅使用不反馈"];
|
|||
|
|
const WANT_FEATURE_OPTIONS = [
|
|||
|
|
"一站式短剧漫剧完整AIGC工作流", "电商素材自动化创作流程",
|
|||
|
|
"多模态智能中枢全能创作", "批量自动化创作流程", "全新未公开AI创作玩法",
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
/* ── Helper: single-select radio group ── */
|
|||
|
|
function RadioGroup({
|
|||
|
|
name, options, value, onChange,
|
|||
|
|
}: {
|
|||
|
|
name: string;
|
|||
|
|
options: string[];
|
|||
|
|
value: string;
|
|||
|
|
onChange: (v: string) => void;
|
|||
|
|
}) {
|
|||
|
|
return (
|
|||
|
|
<div className="beta-radio-group">
|
|||
|
|
{options.map((opt) => (
|
|||
|
|
<label key={opt} className="beta-radio">
|
|||
|
|
<input
|
|||
|
|
type="radio"
|
|||
|
|
name={name}
|
|||
|
|
checked={value === opt}
|
|||
|
|
onChange={() => onChange(opt)}
|
|||
|
|
/>
|
|||
|
|
<span>{opt}</span>
|
|||
|
|
</label>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ── Helper: multi-select checkbox group ── */
|
|||
|
|
function CheckboxGroup({
|
|||
|
|
options, value, onChange,
|
|||
|
|
}: {
|
|||
|
|
options: string[];
|
|||
|
|
value: string[];
|
|||
|
|
onChange: (v: string[]) => void;
|
|||
|
|
}) {
|
|||
|
|
return (
|
|||
|
|
<div className="beta-checkbox-group">
|
|||
|
|
{options.map((opt) => (
|
|||
|
|
<label key={opt} className="beta-checkbox">
|
|||
|
|
<input
|
|||
|
|
type="checkbox"
|
|||
|
|
checked={value.includes(opt)}
|
|||
|
|
onChange={() => {
|
|||
|
|
if (value.includes(opt)) {
|
|||
|
|
onChange(value.filter((item) => item !== opt));
|
|||
|
|
} else {
|
|||
|
|
onChange([...value, opt]);
|
|||
|
|
}
|
|||
|
|
}}
|
|||
|
|
/>
|
|||
|
|
<span>{opt}</span>
|
|||
|
|
</label>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ── Helper: text field ── */
|
|||
|
|
function TextField({
|
|||
|
|
label, value, onChange, placeholder,
|
|||
|
|
}: {
|
|||
|
|
label: string;
|
|||
|
|
value: string;
|
|||
|
|
onChange: (v: string) => void;
|
|||
|
|
placeholder?: string;
|
|||
|
|
}) {
|
|||
|
|
return (
|
|||
|
|
<div className="beta-text-field">
|
|||
|
|
<span className="beta-text-field__label">{label}</span>
|
|||
|
|
<input
|
|||
|
|
type="text"
|
|||
|
|
className="beta-text-field__input"
|
|||
|
|
value={value}
|
|||
|
|
onChange={(e) => onChange(e.target.value)}
|
|||
|
|
placeholder={placeholder ?? "请填写"}
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const BetaApplicationModal = ({ open, onClose }: BetaApplicationModalProps) => {
|
|||
|
|
const [form, setForm] = useState<BetaFormData>(INITIAL_FORM);
|
|||
|
|
|
|||
|
|
const update = <K extends keyof BetaFormData>(key: K, value: BetaFormData[K]) => {
|
|||
|
|
setForm((prev) => ({ ...prev, [key]: value }));
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (!open) return null;
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className="beta-application-modal" role="dialog" aria-modal="true" aria-labelledby="beta-modal-title">
|
|||
|
|
<button type="button" className="beta-application-modal__backdrop" onClick={onClose} aria-label="关闭内测申请弹窗" />
|
|||
|
|
|
|||
|
|
<section className="beta-application-modal__panel">
|
|||
|
|
{/* ── Header ── */}
|
|||
|
|
<header className="beta-modal-header">
|
|||
|
|
<div className="beta-modal-header__left">
|
|||
|
|
<ExperimentOutlined className="beta-modal-header__icon" />
|
|||
|
|
<div>
|
|||
|
|
<h2 id="beta-modal-title">OmniAI 内测体验官申请表</h2>
|
|||
|
|
<p className="beta-modal-header__subtitle">封闭限量内测 · 仅限 <strong>30 人</strong> · 赠送 <strong>500 元</strong> 通用调用积分</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<button type="button" className="beta-modal-header__close" onClick={onClose} aria-label="关闭">
|
|||
|
|
<CloseOutlined />
|
|||
|
|
</button>
|
|||
|
|
</header>
|
|||
|
|
|
|||
|
|
{/* ── Body (scrollable document) ── */}
|
|||
|
|
<div className="beta-modal-body">
|
|||
|
|
|
|||
|
|
{/* 一、个人基础信息 */}
|
|||
|
|
<section className="beta-doc-section">
|
|||
|
|
<h3 className="beta-doc-section__title">一、个人基础信息</h3>
|
|||
|
|
<div className="beta-doc-grid">
|
|||
|
|
<TextField label="姓名 / 常用昵称" value={form.name} onChange={(v) => update("name", v)} />
|
|||
|
|
<TextField label="联系手机号码" value={form.phone} onChange={(v) => update("phone", v)} />
|
|||
|
|
<TextField label="微信账号" value={form.wechat} onChange={(v) => update("wechat", v)} />
|
|||
|
|
<TextField label="所在行业 / 职业" value={form.industry} onChange={(v) => update("industry", v)} />
|
|||
|
|
<TextField label="所属公司 / 机构" value={form.company} onChange={(v) => update("company", v)} />
|
|||
|
|
<TextField label="所在城市" value={form.city} onChange={(v) => update("city", v)} />
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
{/* 二、AI从业与使用经历 */}
|
|||
|
|
<section className="beta-doc-section">
|
|||
|
|
<h3 className="beta-doc-section__title">二、AI 从业与使用经历</h3>
|
|||
|
|
<div className="beta-doc-grid">
|
|||
|
|
<TextField label="日常常用 AI 创作工具有哪些" value={form.aiTools} onChange={(v) => update("aiTools", v)} placeholder="例如:Midjourney / Stable Diffusion / ChatGPT 等" />
|
|||
|
|
<div className="beta-form-group">
|
|||
|
|
<span className="beta-form-group__label">AI 内容创作从业时长</span>
|
|||
|
|
<RadioGroup name="aiDuration" options={AI_DURATION_OPTIONS} value={form.aiDuration} onChange={(v) => update("aiDuration", v)} />
|
|||
|
|
</div>
|
|||
|
|
<div className="beta-form-group">
|
|||
|
|
<span className="beta-form-group__label">是否深耕 AI 短剧、漫剧、数字视频、电商赛道</span>
|
|||
|
|
<RadioGroup name="aiTrack" options={AI_TRACK_OPTIONS} value={form.aiTrack} onChange={(v) => update("aiTrack", v)} />
|
|||
|
|
</div>
|
|||
|
|
<div className="beta-form-group beta-form-group--full">
|
|||
|
|
<span className="beta-form-group__label">日常主要创作方向(可多选)</span>
|
|||
|
|
<CheckboxGroup options={AI_DIRECTION_OPTIONS} value={form.aiDirection} onChange={(v) => update("aiDirection", v)} />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
{/* 三、内测使用意向调研 */}
|
|||
|
|
<section className="beta-doc-section">
|
|||
|
|
<h3 className="beta-doc-section__title">三、内测使用意向调研</h3>
|
|||
|
|
<div className="beta-doc-grid">
|
|||
|
|
<div className="beta-form-group">
|
|||
|
|
<span className="beta-form-group__label">每周可稳定登录使用内测平台次数</span>
|
|||
|
|
<RadioGroup name="weeklyUsage" options={WEEKLY_USAGE_OPTIONS} value={form.weeklyUsage} onChange={(v) => update("weeklyUsage", v)} />
|
|||
|
|
</div>
|
|||
|
|
<div className="beta-form-group">
|
|||
|
|
<span className="beta-form-group__label">是否愿意积极反馈产品 BUG、优化建议、功能需求</span>
|
|||
|
|
<RadioGroup name="feedback" options={FEEDBACK_OPTIONS} value={form.feedbackWilling} onChange={(v) => update("feedbackWilling", v)} />
|
|||
|
|
</div>
|
|||
|
|
<div className="beta-form-group beta-form-group--full">
|
|||
|
|
<span className="beta-form-group__label">本次最想体验 OmniAI 核心功能(可多选)</span>
|
|||
|
|
<CheckboxGroup options={WANT_FEATURE_OPTIONS} value={form.wantFeature} onChange={(v) => update("wantFeature", v)} />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
{/* 四、申请自述 */}
|
|||
|
|
<section className="beta-doc-section">
|
|||
|
|
<h3 className="beta-doc-section__title">四、申请自述 <em className="beta-required">(必填)</em></h3>
|
|||
|
|
<p className="beta-doc-section__desc">请简述自身 AI 创作优势、业务需求,以及加入本次封闭内测的理由:</p>
|
|||
|
|
<textarea
|
|||
|
|
className="beta-textarea"
|
|||
|
|
value={form.selfStatement}
|
|||
|
|
onChange={(e) => update("selfStatement", e.target.value)}
|
|||
|
|
placeholder="请在此填写您的申请自述(必填)…"
|
|||
|
|
rows={6}
|
|||
|
|
/>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
{/* 五、内测规则知情同意书 */}
|
|||
|
|
<section className="beta-doc-section">
|
|||
|
|
<h3 className="beta-doc-section__title">五、内测规则知情同意书</h3>
|
|||
|
|
<ol className="beta-rules-list">
|
|||
|
|
<li>本次为封闭限量内测,仅限 <strong>30 人</strong>,按照资质匹配度 + 申请顺序筛选;</li>
|
|||
|
|
<li>内测赠送 <strong>500 元</strong> 通用调用积分,仅限内测期间使用,不可提现、不可转让、不可兑换现金;</li>
|
|||
|
|
<li>内测版本含未上线测试功能,存在功能不稳定、界面调整、参数优化等情况,申请人自愿理解包容;</li>
|
|||
|
|
<li>严禁私自泄露内测专属工作流、内部功能、测试接口、未发布技术方案等内部资料;</li>
|
|||
|
|
<li>审核通过后,官方将在 <strong>48 小时</strong> 内发放内测账号、登录权限及免费积分;</li>
|
|||
|
|
<li>正式版上线后,优质内测体验官可享受专属永久优惠权限与平台荣誉称号。</li>
|
|||
|
|
</ol>
|
|||
|
|
|
|||
|
|
<label className="beta-agree-row">
|
|||
|
|
<input
|
|||
|
|
type="checkbox"
|
|||
|
|
checked={form.agreeRules}
|
|||
|
|
onChange={(e) => update("agreeRules", e.target.checked)}
|
|||
|
|
/>
|
|||
|
|
<span>本人已完整阅读并同意以上全部内测规则,自愿遵守内测所有管理要求。</span>
|
|||
|
|
</label>
|
|||
|
|
|
|||
|
|
<div className="beta-doc-grid beta-doc-grid--two">
|
|||
|
|
<TextField label="申请人确认签字" value={form.signature} onChange={(v) => update("signature", v)} placeholder="请签署姓名" />
|
|||
|
|
<div className="beta-text-field">
|
|||
|
|
<span className="beta-text-field__label">申请填写日期</span>
|
|||
|
|
<input type="text" className="beta-text-field__input" value="2026年 月 日" readOnly />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* ── Footer ── */}
|
|||
|
|
<footer className="beta-modal-footer">
|
|||
|
|
<button type="button" className="beta-modal-footer__btn beta-modal-footer__btn--secondary" onClick={onClose}>
|
|||
|
|
关闭
|
|||
|
|
</button>
|
|||
|
|
<button type="button" className="beta-modal-footer__btn beta-modal-footer__btn--primary" onClick={onClose}>
|
|||
|
|
提交申请
|
|||
|
|
</button>
|
|||
|
|
</footer>
|
|||
|
|
</section>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export default BetaApplicationModal;
|