54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
"use client";
|
||
|
||
import { useMemo, useState } from "react";
|
||
import { useTrack } from "@/hooks/use-track";
|
||
import { TRACKING_EVENTS } from "@/lib/tracking-events";
|
||
import { useAuth } from "@/components/auth-provider";
|
||
|
||
export function UnlockWorkflow() {
|
||
const [code, setCode] = useState("");
|
||
const [step, setStep] = useState<"idle" | "checking" | "valid" | "invalid">("idle");
|
||
const { track } = useTrack();
|
||
const { setAccessLevel } = useAuth();
|
||
|
||
const hint = useMemo(() => {
|
||
if (step === "checking") return "正在校验解锁码...";
|
||
if (step === "valid") return "验证成功,已解锁高级下载入口(模拟)。";
|
||
if (step === "invalid") return "解锁码无效,请关注公众号回复“下载”获取。";
|
||
return "输入公众号返回的解锁码,体验后端接入前的完整交互流程。";
|
||
}, [step]);
|
||
|
||
const verify = () => {
|
||
setStep("checking");
|
||
track(TRACKING_EVENTS.unlockSubmit, { codeLength: code.length });
|
||
setTimeout(() => {
|
||
const pass = code.trim().toUpperCase() === "DOWNLOAD2026";
|
||
setStep(pass ? "valid" : "invalid");
|
||
track(TRACKING_EVENTS.unlockResult, { success: pass });
|
||
if (pass) setAccessLevel("unlocked");
|
||
}, 600);
|
||
};
|
||
|
||
return (
|
||
<div className="card-glass space-y-4">
|
||
<h3 className="text-lg font-semibold">解锁码验证(前端状态机)</h3>
|
||
<div className="flex flex-col gap-3 md:flex-row">
|
||
<input
|
||
className="input-fancy"
|
||
placeholder="请输入解锁码,例如 DOWNLOAD2026"
|
||
value={code}
|
||
onChange={(e) => setCode(e.target.value)}
|
||
/>
|
||
<button onClick={verify} className="cta-main whitespace-nowrap">
|
||
立即验证
|
||
</button>
|
||
</div>
|
||
<p className="text-sm text-slate-300">{hint}</p>
|
||
<div className="flex flex-wrap gap-2">
|
||
<button className="cta-sub" onClick={() => track(TRACKING_EVENTS.ctaClick, { location: "unlock", target: "group" })}>加入交流群</button>
|
||
<button className="cta-sub" onClick={() => track(TRACKING_EVENTS.ctaClick, { location: "unlock", target: "vip" })}>开通 VIP(预留)</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|