ifixkart-storefront/components/faq/FaqPageView.tsx

173 lines
5.4 KiB
TypeScript

'use client';
import React, { useState } from 'react';
import Link from 'next/link';
import { ChevronDown } from 'lucide-react';
import type { FaqCategory, FaqItem, FaqPageData } from '@/lib/faqDefaults';
export function FaqAccordionList({ faqs }: { faqs: FaqItem[] }) {
const [openIdx, setOpenIdx] = useState<number | null>(null);
if (faqs.length === 0) {
return (
<p className="text-[13px] text-gray-500 py-8 text-center">
No questions in this category yet.
</p>
);
}
return (
<div className="space-y-3">
{faqs.map((faq, idx) => {
const isOpen = openIdx === idx;
const collapsed =
faq.answer.length > 180 ? `${faq.answer.slice(0, 180).trim()}` : faq.answer;
return (
<article
key={`${faq.question}-${idx}`}
className="bg-white border border-gray-200 rounded-xl px-5 py-4 shadow-xs"
>
<button
type="button"
onClick={() => setOpenIdx(isOpen ? null : idx)}
className="w-full text-left flex items-start justify-between gap-3 cursor-pointer"
>
<h3 className="text-[15px] font-bold text-[#1E293B] leading-snug">
{idx + 1}) {faq.question}
</h3>
<ChevronDown
className={`w-4 h-4 mt-1 shrink-0 text-gray-400 transition-transform ${
isOpen ? 'rotate-180 text-primary' : ''
}`}
/>
</button>
<div className="mt-2 text-[13px] text-gray-600 leading-relaxed">
<p className="font-semibold text-gray-800 mb-1">Answer:</p>
<p>{isOpen ? faq.answer : collapsed}</p>
{faq.answer.length > 180 ? (
<button
type="button"
onClick={() => setOpenIdx(isOpen ? null : idx)}
className="mt-2 text-[12px] font-semibold text-primary hover:underline cursor-pointer"
>
{isOpen ? 'read less' : 'read more'}
</button>
) : null}
</div>
</article>
);
})}
</div>
);
}
export function FaqCategoryNav({
categories,
activeSlug,
}: {
categories: FaqCategory[];
activeSlug?: string;
}) {
return (
<nav className="bg-white border border-gray-200 rounded-xl p-4">
<h2 className="text-[11px] font-bold uppercase tracking-[0.08em] text-gray-400 mb-3">
FAQ Categories
</h2>
<ul className="space-y-1">
<li>
<Link
href="/faqs"
className={`block rounded-lg px-3 py-2 text-[13px] font-semibold transition-colors ${
!activeSlug
? 'bg-primary/10 text-primary'
: 'text-gray-600 hover:bg-gray-50 hover:text-primary'
}`}
>
All FAQs
</Link>
</li>
{categories.map((cat) => {
const active = cat.slug === activeSlug;
return (
<li key={cat.slug}>
<Link
href={`/faqs/${cat.slug}`}
className={`block rounded-lg px-3 py-2 text-[13px] font-semibold transition-colors ${
active
? 'bg-primary/10 text-primary'
: 'text-gray-600 hover:bg-gray-50 hover:text-primary'
}`}
>
{cat.title}
</Link>
</li>
);
})}
</ul>
</nav>
);
}
export function FaqHub({ data }: { data: FaqPageData }) {
return (
<div className="space-y-8">
<div>
<h1 className="text-[28px] md:text-[32px] font-bold text-[#1E293B]">
{data.title}
</h1>
{data.subtitle ? (
<p className="text-[14px] text-gray-500 mt-2 max-w-2xl">{data.subtitle}</p>
) : null}
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{data.categories.map((cat) => (
<Link
key={cat.slug}
href={`/faqs/${cat.slug}`}
className="bg-white border border-gray-200 rounded-xl p-5 hover:border-primary/40 hover:shadow-sm transition-all"
>
<h2 className="text-[16px] font-bold text-[#1E293B]">{cat.title}</h2>
{cat.description ? (
<p className="text-[13px] text-gray-500 mt-2 leading-relaxed">
{cat.description}
</p>
) : null}
<p className="text-[12px] font-semibold text-primary mt-4">
{cat.faqs.length} question{cat.faqs.length === 1 ? '' : 's'}
</p>
</Link>
))}
</div>
</div>
);
}
export function FaqCategoryPage({
data,
category,
}: {
data: FaqPageData;
category: FaqCategory;
}) {
return (
<div className="grid grid-cols-1 lg:grid-cols-[260px_minmax(0,1fr)] gap-6 lg:gap-8">
<aside className="lg:sticky lg:top-28 h-fit">
<FaqCategoryNav categories={data.categories} activeSlug={category.slug} />
</aside>
<div className="min-w-0">
<h1 className="text-[26px] md:text-[30px] font-bold text-[#1E293B]">
{category.title}
</h1>
{category.description ? (
<p className="text-[14px] text-gray-500 mt-1.5 mb-6">{category.description}</p>
) : (
<div className="mb-6" />
)}
<FaqAccordionList faqs={category.faqs} />
</div>
</div>
);
}