"use client"; import { useCallback, useEffect, useMemo, useState } from "react"; import Link from "next/link"; import { useRouter, useSearchParams } from "next/navigation"; import { Badge, Button, Container } from "@/components/ui"; import { useAuth } from "@/hooks/useAuth"; import { loadAssessmentSchema, loadCommercialBundles, loadCommercialPricing, loadCommercialProducts, requestRecommendations, } from "../adapters"; import type { AdapterResult, AssessmentQuestion, AssessmentSchema, CommercialBundle, CommercialPricingItem, CommercialProduct, RecommendationResult, } from "../types"; import { BundleCard, CommercialEmptyState, ProductCard, } from "../components"; import { loadAssessmentSession, saveAssessmentSession, type AssessmentSession, } from "../session"; import { commercialEntityName, enumLabel, formatMoney, friendlyMessage, humanizeCommercialCode, recommendationReason, } from "../presentation"; type WizardStep = | "assessment" | "recommendations" | "bundles" | "pricing" | "trial_summary" | "create_workspace"; function businessQuestion(question: AssessmentQuestion): string { const key = question.question_id.toLowerCase(); if (/business.*type|industry/.test(key)) return "نوع کسب‌وکار شما چیست؟"; if (/employee|staff|personnel/.test(key)) return "چند پرسنل دارید؟"; if (/branch/.test(key)) return "چند شعبه دارید؟"; if (/in.?person|physical|pos/.test(key)) return "آیا فروش حضوری دارید؟"; if (/online|ecommerce/.test(key)) return "فروش آنلاین دارید؟"; if (/booking|reservation/.test(key)) return "به مدیریت رزرو نیاز دارید؟"; if (/delivery|shipping/.test(key)) return "ارسال کالا دارید؟"; if (/loyal|club/.test(key)) return "باشگاه مشتریان نیاز دارید؟"; if (/website|domain/.test(key)) return "وب‌سایت دارید؟"; return friendlyMessage(question.prompt, "این ویژگی برای کسب‌وکار شما لازم است؟"); } function QuestionField({ question, value, onChange, }: { question: AssessmentQuestion; value: unknown; onChange: (v: unknown) => void; }) { const inputClass = "mt-1 w-full rounded-xl border border-gray-200 bg-white px-4 py-2.5 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary dark:border-gray-700 dark:bg-gray-900"; if (question.input_type === "boolean") { return ( ); } if (question.input_type === "number") { return ( ); } if ((question.input_type === "multi" || question.input_type === "single") && question.options?.length) { const multi = question.input_type === "multi"; const selected = multi ? (Array.isArray(value) ? (value as string[]) : []) : null; return (
{businessQuestion(question)}
{question.options.map((opt) => { const on = multi ? selected!.includes(opt.value) : value === opt.value; return ( ); })}
); } return ( ); } const STEPS: { id: WizardStep; label: string }[] = [ { id: "assessment", label: "کشف" }, { id: "recommendations", label: "پیشنهاد" }, { id: "bundles", label: "بسته مناسب" }, { id: "pricing", label: "قیمت" }, { id: "trial_summary", label: "آزمایش رایگان" }, ]; export function CommercialDiscoverExperience() { const { isAuthenticated, login, loading: authLoading } = useAuth(); const router = useRouter(); const searchParams = useSearchParams(); const typeParam = searchParams.get("type"); const [step, setStep] = useState("assessment"); const [schemaRes, setSchemaRes] = useState | null>(null); const [productsRes, setProductsRes] = useState | null>(null); const [bundlesRes, setBundlesRes] = useState | null>(null); const [pricingRes, setPricingRes] = useState | null>(null); const [recoRes, setRecoRes] = useState | null>(null); const [answers, setAnswers] = useState>({}); const [selectedBundle, setSelectedBundle] = useState(null); const [qIndex, setQIndex] = useState(0); const [busy, setBusy] = useState(false); const [booted, setBooted] = useState(false); useEffect(() => { const session = loadAssessmentSession(); const nextAnswers = { ...session.answers }; if (typeParam && !nextAnswers.business_type_code) { nextAnswers.business_type_code = typeParam; } setAnswers(nextAnswers); if (session.selected_bundle_code) setSelectedBundle(session.selected_bundle_code); void (async () => { setBusy(true); const [schema, products, bundles, pricing] = await Promise.all([ loadAssessmentSchema(), loadCommercialProducts(), loadCommercialBundles(), loadCommercialPricing(), ]); setSchemaRes(schema); setProductsRes(products); setBundlesRes(bundles); setPricingRes(pricing); setBusy(false); setBooted(true); })(); }, [typeParam]); const persist = useCallback((next: AssessmentSession) => { saveAssessmentSession(next); }, []); const questions = schemaRes?.data.questions ?? []; const currentQ = questions[qIndex]; const runRecommendations = async () => { setBusy(true); persist({ answers, selected_bundle_code: selectedBundle }); const reco = await requestRecommendations(answers); setRecoRes(reco); const top = reco.data.recommended_bundles[0]?.code; if (top && !selectedBundle) { setSelectedBundle(top); persist({ answers, selected_bundle_code: top }); } setStep("recommendations"); setBusy(false); }; const productByCode = useMemo(() => { const map = new Map(); (productsRes?.data ?? []).forEach((p) => map.set(p.product_code, p)); return map; }, [productsRes]); const bundleByCode = useMemo(() => { const map = new Map(); (bundlesRes?.data ?? []).forEach((b) => map.set(b.bundle_code, b)); return map; }, [bundlesRes]); const recommendedProducts = (recoRes?.data.recommended_products ?? []) .map((r) => ({ ...r, product: productByCode.get(r.code) })) .filter((r) => r.product); const optionalProducts = recommendedProducts.length ? (productsRes?.data ?? []).filter( (p) => !recommendedProducts.some((r) => r.code === p.product_code) && p.visibility !== "hidden" ).slice(0, 3) : []; const recommendedBundles = (recoRes?.data.recommended_bundles ?? []) .map((r) => ({ ...r, bundle: bundleByCode.get(r.code) })) .filter((r) => r.bundle); const displayBundles = recommendedBundles.length > 0 ? recommendedBundles.map((r) => r.bundle!) : bundlesRes?.data ?? []; const selectedBundleObj = selectedBundle ? bundleByCode.get(selectedBundle) : null; const pricingForBundle = (pricingRes?.data ?? []).filter((p) => selectedBundleObj?.pricing_refs?.includes(p.pricing_item_code) ); const goWorkspace = () => { persist({ answers, selected_bundle_code: selectedBundle, selected_product_codes: recoRes?.data.recommended_products.map((p) => p.code), activate_trial: true, }); if (isAuthenticated) { const intent = typeof answers.business_type_code === "string" ? answers.business_type_code : ""; router.push(intent ? `/onboarding?intent=${encodeURIComponent(intent)}` : "/onboarding"); } else { setStep("create_workspace"); } }; const stepIndex = STEPS.findIndex((s) => s.id === step); if (!booted) { return (

آماده‌سازی مسیر کشف…

); } return (
← بازگشت به خانه

پیشنهاد مناسب کسب‌وکار

    {STEPS.map((s, i) => (
  1. {s.label}
  2. ))}
{step === "assessment" ? (

ارزیابی نیازها

با چند سؤال کوتاه، نیازهای واقعی کسب‌وکار شما را می‌شناسیم.

{schemaRes?.availability === "unavailable" || schemaRes?.availability === "empty" || !questions.length ? (
) : currentQ ? (

سؤال {qIndex + 1} از {questions.length}

{ const next = { ...answers, [currentQ.question_id]: v }; setAnswers(next); persist({ answers: next, selected_bundle_code: selectedBundle }); }} />
{qIndex < questions.length - 1 ? ( ) : ( )}
) : null}
) : null} {step === "recommendations" ? (

پیشنهاد شخصی‌سازی‌شده

فقط گزینه‌هایی را می‌بینید که با پاسخ‌های شما هم‌خوانی دارند.

ضروری برای شروع

{recommendedProducts.length ? (
{recommendedProducts.map((r) => (
{r.reason ? (

{recommendationReason(r.reason)}

) : null}
))}
) : ( )}
{optionalProducts.length ? (

بعداً اضافه کنید

{optionalProducts.slice(0, 6).map((p) => ( ))}
) : null} {selectedBundleObj ? (

باندل پیشنهادی فعلی

{commercialEntityName("bundles", selectedBundleObj.bundle_code, selectedBundleObj.display_name)}

{selectedBundleObj.upgrade_path_code ? (

امکان ارتقا در هر زمان

) : null}
) : null}
) : null} {step === "bundles" ? (

مقایسه بسته‌های پیشنهادی

محصولات، امکانات و روش پرداخت هر بسته را در یک نگاه مقایسه کنید.

{displayBundles.length ? (
{displayBundles.map((b) => ( r.code === b.bundle_code)?.score } selected={selectedBundle === b.bundle_code} onSelect={() => { setSelectedBundle(b.bundle_code); persist({ answers, selected_bundle_code: b.bundle_code }); }} pricingItems={pricingRes?.data || []} products={productsRes?.data || []} /> ))}
) : ( )}
) : null} {step === "pricing" ? (

مقایسه قیمت

هزینه ماهانه، سالانه و دوره آزمایشی را شفاف مقایسه کنید.

{(pricingForBundle.length ? pricingForBundle : pricingRes?.data ?? []).length ? (
    {(pricingForBundle.length ? pricingForBundle : pricingRes!.data).map((item) => (
  • {commercialEntityName("pricing", item.pricing_item_code, item.display_name)}

    {enumLabel(item.pricing_model)} · {formatMoney(item.amount_minor, item.currency)}

    {item.trial_days != null ? ( {item.trial_days} روز آزمایش رایگان ) : null}
  • ))}
) : ( )}
) : null} {step === "trial_summary" ? (

خلاصه دوره آزمایشی

پس از ثبت‌نام، فضای کاری و زیردامنه رایگان شما ساخته می‌شود و می‌توانید امکانات انتخابی را امتحان کنید.

{selectedBundle ? (

بسته: {selectedBundleObj ? commercialEntityName("bundles", selectedBundleObj.bundle_code, selectedBundleObj.display_name) : "بسته پیشنهادی"}

) : (

بسته‌ای انتخاب نشده است؛ می‌توانید بعداً از بخش اشتراک انتخاب کنید.

)}
  • ✓ ساخت فضای کاری و زیردامنه
  • ✓ داشبورد و دسترسی به محصولات
  • ✓ اتصال دامنه اختصاصی پس از فعال‌سازی اشتراک
) : null} {step === "create_workspace" ? (

ثبت‌نام / ورود

انتخاب‌های شما ذخیره می‌شود و پس از ورود، راه‌اندازی را از همین‌جا ادامه می‌دهید.

) : null}
); }