"use client"; import { useCallback, useEffect, useRef, useState } from "react"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "@/components/ui/accordion"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; type Category = "Support" | "Account" | "Features" | "Security" | "Other"; interface FAQItem { question: string; answer: string; category: Category; } const categoryLabels: Record = { Support: "پشتیبانی", Account: "حساب کاربری", Features: "امکانات", Security: "امنیت", Other: "سایر", }; const faqItems: FAQItem[] = [ { category: "Support", question: "آیا می‌توانم قبل از خرید نسخه آزمایشی داشته باشم؟", answer: "بله. فضای کاری آزمایشی با داده نمونه در دسترس است و هر زمان می‌توانید به پلن تیمی یا سازمانی ارتقا دهید.", }, { category: "Support", question: "چطور به تیم پشتیبانی دسترسی پیدا کنم؟", answer: "از تیکت داخل محصول، ایمیل و مرکز راهنما کمک بگیرید؛ زمان پاسخ بر اساس پلن شما اولویت‌بندی می‌شود.", }, { category: "Support", question: "اگر مشکل فوری در فروش دارم چه کنم؟", answer: "تیکت با اولویت بحرانی ثبت کنید تا صف پشتیبانی سازمانی در کوتاه‌ترین زمان بررسی کند.", }, { category: "Account", question: "چگونه پروفایل و اطلاعات شرکت را ویرایش کنم؟", answer: "در تنظیمات حساب، نام، نقش، لوگو و مشخصات صورتحساب را بدون قطع دسترسی تیم به‌روز کنید.", }, { category: "Account", question: "افزودن عضو جدید چقدر ساده است؟", answer: "با دعوت ایمیل و انتخاب نقش، عضو جدید در چند دقیقه به فضای کاری و داشبورد فروش دسترسی پیدا می‌کند.", }, { category: "Account", question: "اگر رمز عبورم را فراموش کنم چه می‌شود؟", answer: "از «فراموشی رمز عبور» لینک بازیابی بگیرید؛ در صورت فعال بودن تأیید دو مرحله‌ای، همان مسیر حفظ می‌شود.", }, { category: "Features", question: "هوش مصنوعی جای کارشناس فروش را می‌گیرد؟", answer: "خیر. خلاصه مکالمه و پیشنهاد گام بعدی کمک‌کننده است؛ تصمیم و تماس نهایی با تیم شماست.", }, { category: "Features", question: "چه چیزی قیف فروش را شفاف‌تر می‌کند؟", answer: "مراحل استاندارد، اتوماسیون پیگیری و گزارش تبدیل لحظه‌ای باعث می‌شود گلوگاه قیف پنهان نماند.", }, { category: "Features", question: "با ابزارهای فعلی‌مان یکپارچه می‌شود؟", answer: "اتصال آماده برای ایمیل، تقویم، پیام‌رسان و پشتیبانی دارید؛ API برای سفارشی‌سازی در دسترس است.", }, { category: "Security", question: "داده‌های مشتریان چقدر امن هستند؟", answer: "رمزنگاری، نقش‌های دسترسی و ممیزی ورود از داده حساس در برابر دسترسی ناخواسته محافظت می‌کند.", }, { category: "Security", question: "در صورت رخداد امنیتی چه می‌کنید؟", answer: "طبق سیاست اطلاع‌رسانی، تیم امنیتی شما را مطلع می‌کنیم و مسیر مهار و بازیابی را مستند می‌کنیم.", }, { category: "Security", question: "نسخه پشتیبان دارید؟", answer: "بله. پشتیبان‌گیری منظم در زیرساخت امن انجام می‌شود تا بازیابی سریع پس از خطا ممکن باشد.", }, { category: "Other", question: "قیمت‌گذاری بر چه اساسی است؟", answer: "بر اساس تعداد کاربر، حجم تماس و سطح اتوماسیون؛ قبل از خرید پیشنهاد شفاف دریافت می‌کنید.", }, { category: "Other", question: "آیا بازپرداخت دارید؟", answer: "در صورت احراز شرایط بازگشت وجه، تا ۳۰ روز می‌توانید درخواست استرداد ثبت کنید.", }, { category: "Other", question: "نقشه راه محصول کجا دیده می‌شود؟", answer: "نقشه راه عمومی بر اساس بازخورد مشتریان به‌روز می‌شود و ویژگی‌های در حال توسعه را نشان می‌دهد.", }, ]; const categories: Category[] = [ "Support", "Account", "Features", "Security", "Other", ]; const TOP_PADDING = 300; interface Faq12Props { className?: string; } const Faq12 = ({ className }: Faq12Props) => { const [activeCategory, setActiveCategory] = useState("Support"); const observerRef = useRef(null); const isScrollingRef = useRef(false); const categoryRefs = useRef>({ Support: null, Account: null, Features: null, Security: null, Other: null, }); const setupObserver = useCallback(() => { observerRef.current?.disconnect(); let debounceTimeout: NodeJS.Timeout; observerRef.current = new IntersectionObserver( (entries) => { if (isScrollingRef.current) return; if (debounceTimeout) { clearTimeout(debounceTimeout); } debounceTimeout = setTimeout(() => { const intersectingEntries = entries.filter( (entry) => entry.isIntersecting, ); const entry = intersectingEntries.reduce( (closest, current) => { const rect = current.boundingClientRect; const distanceFromThreshold = Math.abs(rect.top - TOP_PADDING); const closestDistance = closest ? Math.abs(closest.boundingClientRect.top - TOP_PADDING) : Infinity; return distanceFromThreshold < closestDistance ? current : closest; }, null as IntersectionObserverEntry | null, ); if (entry) { const category = entry.target.getAttribute( "data-category", ) as Category; if (category) { setActiveCategory(category); } } }, 150); }, { root: null, rootMargin: `-${TOP_PADDING}px 0px -100% 0px`, threshold: [0, 0.25, 0.5, 0.75, 1], }, ); Object.entries(categoryRefs.current).forEach(([category, element]) => { if (element) { element.setAttribute("data-category", category); observerRef.current?.observe(element); } }); return () => { if (debounceTimeout) { clearTimeout(debounceTimeout); } }; }, []); useEffect(() => { const cleanup = setupObserver(); return () => { cleanup(); observerRef.current?.disconnect(); }; }, [setupObserver]); const handleCategoryClick = (category: Category) => { setActiveCategory(category); isScrollingRef.current = true; const element = document.getElementById(`faq-${category.toLowerCase()}`); if (element) { element.style.scrollMargin = `${TOP_PADDING}px`; element.scrollIntoView({ behavior: "smooth", block: "start" }); setTimeout(() => { isScrollingRef.current = false; }, 1000); } }; return (

همه چیز درباره فضای کاری فروش

اگر پاسخ را پیدا نکردید، از مرکز راهنما یا تیکت پشتیبانی کمک بگیرید.

{categories.map((category) => ( ))}
{categories.map((category) => { const categoryItems = faqItems.filter( (item) => item.category === category, ); return (
{ categoryRefs.current[category] = el; }} className={cn( "rounded-xl px-6", activeCategory === category ? "bg-background" : "bg-background md:bg-background/40", )} style={{ scrollMargin: `${TOP_PADDING}px`, }} > {categoryItems.map((item, i) => ( {item.question} {item.answer} ))}
); })}
); }; export { Faq12 };