feat: add FAQ block to pricing page

- Updated HomePage title and description to reflect new branding.
- Added a comprehensive FAQ section with questions and answers to improve user support.
- Modified the PricingPage layout to include the new FAQs component for better information accessibility.
This commit is contained in:
javayhu 2025-04-12 15:10:28 +08:00
parent 5026fb3b4d
commit 74404eb0c6
4 changed files with 159 additions and 5 deletions

View File

@ -32,8 +32,31 @@
"logoutFailed": "Failed to log out"
},
"HomePage": {
"title": "next-intl example",
"description": "This is a simple example of how to use next-intl to build a website"
"title": "MkSaaS",
"description": "Make AI SaaS in days, simply and effortlessly",
"FAQ": {
"title": "Frequently Asked Questions",
"description": "Can't find what you're looking for? Contact our ",
"contact": "customer support team",
"items": {
"item-1": {
"question": "Do you offer a free trial?",
"answer": "Yes, we offer a 7-day free trial."
},
"item-2": {
"question": "How do I cancel my subscription?",
"answer": "You can cancel your subscription by visiting the billing page."
},
"item-3": {
"question": "Can I change my plan?",
"answer": "Yes, you can change your plan at any time by visiting the billing page."
},
"item-4": {
"question": "What is the refund policy?",
"answer": "We offer a 30-day money-back guarantee if you are not happy with our product."
}
}
}
},
"PricingPage": {
"title": "Pricing",

View File

@ -32,8 +32,31 @@
"logoutFailed": "退出失败"
},
"HomePage": {
"title": "MkSaaS 示例",
"description": "这是一个使用 MkSaaS 构建网站的简单示例"
"title": "MkSaaS",
"description": "使用 MkSaaS 在几天内轻松构建您的 AI SaaS",
"FAQ": {
"title": "常见问题",
"description": "找不到您想问的问题?请联系我们的",
"contact": "客户支持团队",
"items": {
"item-1": {
"question": "你们提供免费试用吗?",
"answer": "是的我们提供7天的免费试用。"
},
"item-2": {
"question": "如何取消我的订阅?",
"answer": "您可以通过访问账单页面取消您的订阅。"
},
"item-3": {
"question": "我可以更改我的计划吗?",
"answer": "是的,您可以随时通过访问账单页面更改您的计划。"
},
"item-4": {
"question": "你们的退款政策是什么?",
"answer": "是的我们提供30天的退款保证。"
}
}
}
},
"PricingPage": {
"title": "价格",

View File

@ -1,3 +1,5 @@
import FAQs from '@/components/landing/faq/FAQs';
import Container from '@/components/layout/container';
import { constructMetadata } from '@/lib/metadata';
import { getBaseUrlWithLocale } from '@/lib/urls/urls';
import { Metadata } from 'next';
@ -39,7 +41,11 @@ export default async function PricingPageLayout({
</div>
</div>
{children}
<Container className="mt-8 px-4 flex flex-col gap-16">
{children}
<FAQs />
</Container>
</div>
);
}

View File

@ -0,0 +1,102 @@
'use client';
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from '@/components/ui/accordion';
import { getBaseUrlWithLocale } from '@/lib/urls/urls';
import { DynamicIcon, type IconName } from 'lucide-react/dynamic';
import { useTranslations } from 'next-intl';
import Link from 'next/link';
type FAQItem = {
id: string;
icon: IconName;
question: string;
answer: string;
};
export default function FAQs() {
const t = useTranslations('HomePage.FAQ');
const faqItems: FAQItem[] = [
{
id: 'item-1',
icon: 'calendar-clock',
question: t('items.item-1.question'),
answer: t('items.item-1.answer'),
},
{
id: 'item-2',
icon: 'receipt',
question: t('items.item-2.question'),
answer: t('items.item-2.answer'),
},
{
id: 'item-3',
icon: 'refresh-cw',
question: t('items.item-3.question'),
answer: t('items.item-3.answer'),
},
{
id: 'item-4',
icon: 'hand-coins',
question: t('items.item-4.question'),
answer: t('items.item-4.answer'),
},
];
return (
<section className="py-20">
<div className="mx-auto max-w-5xl px-4 md:px-6">
<div className="flex flex-col gap-10 md:flex-row md:gap-16">
<div className="md:w-1/3">
<div className="sticky top-20">
<h2 className="mt-4 text-3xl font-bold">
{t('title')}
</h2>
<p className="text-muted-foreground mt-4">
{t('description')}
<Link
href={getBaseUrlWithLocale('/contact')}
className="text-primary font-medium hover:underline"
>
{t('contact')}
</Link>
</p>
</div>
</div>
<div className="md:w-2/3">
<Accordion type="single" collapsible className="w-full space-y-2">
{faqItems.map((item) => (
<AccordionItem
key={item.id}
value={item.id}
className="bg-background shadow-xs rounded-lg border px-4 last:border-b"
>
<AccordionTrigger className="cursor-pointer items-center py-5 hover:no-underline">
<div className="flex items-center gap-3">
<div className="flex size-6">
<DynamicIcon
name={item.icon}
className="m-auto size-4"
/>
</div>
<span className="text-base">{item.question}</span>
</div>
</AccordionTrigger>
<AccordionContent className="pb-5">
<div className="px-9">
<p className="text-base">{item.answer}</p>
</div>
</AccordionContent>
</AccordionItem>
))}
</Accordion>
</div>
</div>
</div>
</section>
);
}