Files
myeasycms-v2/apps/web/app/(marketing)/faq/page.tsx
giancarlo 8d04624b1d Add queryUsage method to billing services
A new method, queryUsage, has been added to the billing strategy classes and the gateway service to offer usage querying capabilities for Stripe and Lemon Squeezy. QueryBillingUsageSchema has also been introduced in the schema-related changes. Changes also include updates to the functions' comment descriptions. A minor tweak was made to the Button and Link components in the `faq/page.tsx' file.
2024-04-25 11:34:47 +07:00

144 lines
3.7 KiB
TypeScript

import Link from 'next/link';
import { ArrowRight, ChevronDown } from 'lucide-react';
import { Button } from '@kit/ui/button';
import { Trans } from '@kit/ui/trans';
import { SitePageHeader } from '~/(marketing)/_components/site-page-header';
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
import { withI18n } from '~/lib/i18n/with-i18n';
export const generateMetadata = async () => {
const { t } = await createI18nServerInstance();
return {
title: t('marketing:faq'),
};
};
async function FAQPage() {
const { t } = await createI18nServerInstance();
// replace this content
// with translations
const faqItems = [
{
question: `Do you offer a free trial?`,
answer: `Yes, we offer a 14-day free trial. You can cancel at any time during the trial period and you won't be charged.`,
},
{
question: `Can I cancel my subscription?`,
answer: `You can cancel your subscription at any time. You can do this from your account settings.`,
},
{
question: `Where can I find my invoices?`,
answer: `You can find your invoices in your account settings.`,
},
{
question: `What payment methods do you accept?`,
answer: `We accept all major credit cards and PayPal.`,
},
{
question: `Can I upgrade or downgrade my plan?`,
answer: `Yes, you can upgrade or downgrade your plan at any time. You can do this from your account settings.`,
},
{
question: `Do you offer discounts for non-profits?`,
answer: `Yes, we offer a 50% discount for non-profits. Please contact us to learn more.`,
},
];
const structuredData = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: faqItems.map((item) => {
return {
'@type': 'Question',
name: item.question,
acceptedAnswer: {
'@type': 'Answer',
text: item.answer,
},
};
}),
};
return (
<>
<script
key={'ld:json'}
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
/>
<div className={'flex flex-col space-y-4 xl:space-y-8'}>
<SitePageHeader
title={t('marketing:faq')}
subtitle={t('marketing:faqSubtitle')}
/>
<div className={'container flex flex-col space-y-8 pb-16'}>
<div className="flex w-full max-w-xl flex-col">
{faqItems.map((item, index) => {
return <FaqItem key={index} item={item} />;
})}
</div>
<div>
<Button asChild variant={'outline'}>
<Link href={'/contact'}>
<span>
<Trans i18nKey={'marketing:contactFaq'} />
</span>
<ArrowRight className={'ml-2 w-4'} />
</Link>
</Button>
</div>
</div>
</div>
</>
);
}
export default withI18n(FAQPage);
function FaqItem({
item,
}: React.PropsWithChildren<{
item: {
question: string;
answer: string;
};
}>) {
return (
<details className={'group border-b px-2 py-4 last:border-b-transparent'}>
<summary
className={
'flex items-center justify-between hover:cursor-pointer hover:underline'
}
>
<h2
className={
'hover:underline-none cursor-pointer font-sans font-medium'
}
>
{item.question}
</h2>
<div>
<ChevronDown
className={'h-5 transition duration-300 group-open:-rotate-180'}
/>
</div>
</summary>
<div
className={'flex flex-col space-y-2 py-1 text-muted-foreground'}
dangerouslySetInnerHTML={{ __html: item.answer }}
/>
</details>
);
}