"use client"; import { useMemo, useState } from "react"; import type { Visa } from "@/lib/types"; interface Props { visas: Visa[]; } const INCOME_OPTIONS = [ { key: "low", label: "💰 低于 ¥8,000/月", max: 8000 }, { key: "mid", label: "💼 ¥8,000 – ¥20,000/月", max: 20000 }, { key: "high", label: "🚀 ¥20,000 – ¥50,000/月", max: 50000 }, { key: "premium", label: "👑 高于 ¥50,000/月", max: Infinity }, ]; const DURATION_OPTIONS = [ { key: "short", label: "⏱️ 1-3 个月", months: 3 }, { key: "medium", label: "📅 3-12 个月", months: 12 }, { key: "long", label: "🏠 1 年以上", months: 24 }, ]; const REGION_OPTIONS = [ { key: "any", label: "🌏 不限" }, { key: "europe", label: "🏰 欧洲" }, { key: "sea", label: "🌴 东南亚" }, { key: "latam", label: "🌮 拉美" }, ]; const VISA_INCOME: Record = { "1": 6000, "2": 17000, "3": 2000, "4": 47000, "5": 18000, "6": 28000, }; const VISA_REGION: Record = { "1": "europe", "2": "europe", "3": "sea", "4": "sea", "5": "latam", "6": "europe", }; export default function VisaWizard({ visas }: Props) { const [step, setStep] = useState(0); const [income, setIncome] = useState(""); const [duration, setDuration] = useState(""); const [region, setRegion] = useState("any"); const [showResults, setShowResults] = useState(false); const results = useMemo(() => { if (!income || !duration) return []; const incomeOpt = INCOME_OPTIONS.find((o) => o.key === income)!; const durOpt = DURATION_OPTIONS.find((o) => o.key === duration)!; return visas .map((v) => { let score = 0; const reqIncome = VISA_INCOME[v.id] ?? 15000; const vRegion = VISA_REGION[v.id] ?? "any"; if (reqIncome <= incomeOpt.max) score += 40; else if (reqIncome <= incomeOpt.max * 1.5) score += 20; if (v.difficulty <= 35) score += 25; else if (v.difficulty <= 55) score += 15; else score += 5; if (durOpt.months >= 12 && v.duration.includes("年")) score += 20; else if (durOpt.months <= 3) score += v.duration.includes("天") ? 20 : 10; else score += 15; if (region === "any" || vRegion === region) score += 15; return { visa: v, score: Math.min(score, 100) }; }) .filter((r) => r.score >= 30) .sort((a, b) => b.score - a.score) .slice(0, 3); }, [visas, income, duration, region]); const canNext = step === 0 ? !!income : step === 1 ? !!duration : true; const handleFinish = () => { setShowResults(true); setStep(3); }; const reset = () => { setStep(0); setIncome(""); setDuration(""); setRegion("any"); setShowResults(false); }; return (
🧙 VISA WIZARD

签证智能匹配

回答 3 个问题,找到最适合你的远程工作签证

{!showResults ? (
{["月收入", "停留时长", "目的地"].map((label, i) => (
{i < step ? "✓" : i + 1} {label}
))}
{step === 0 && (
{INCOME_OPTIONS.map((o) => ( ))}
)} {step === 1 && (
{DURATION_OPTIONS.map((o) => ( ))}
)} {step === 2 && (
{REGION_OPTIONS.map((o) => ( ))}
)}
{step > 0 && } {step < 2 ? ( ) : ( )}
) : (
{results.length === 0 ? (

暂无完全匹配的签证,建议咨询专业移民顾问或放宽条件重试

) : (
{results.map(({ visa, score }, i) => (
{i === 0 && 🏆 最佳匹配}
{visa.flag}

{visa.name}

{score}% 匹配
  • 💰 {visa.income_req}
  • 📅 {visa.duration}
  • ⏱️ {visa.approval_time}
))}
)}
)}
); }