feat: enhance homepage with new features sections

- Added FeaturesSection and Features2Section components to showcase product features on the homepage, improving user engagement and information accessibility.
- Updated English and Chinese JSON files to include new feature descriptions and titles for both features sections.
- Refactored the homepage layout to integrate the new features sections, enhancing overall user experience.
- Made adjustments to the LogoCloud section for improved styling and consistency.
This commit is contained in:
javayhu 2025-04-12 22:26:03 +08:00
parent 43777b5989
commit ea0c0cf027
6 changed files with 357 additions and 15 deletions

View File

@ -35,7 +35,7 @@
"description": "Make AI SaaS in days, simply and effortlessly",
"hero": {
"title": "Make AI SaaS in days, simply and effortlessly",
"description": "The best AI SaaS boilerplate, packed with AI, Authentication, Payment, Blog, Documentation, Newsletter, SEO, Themes, Blocks, Dashboard and more.",
"description": "The is a demo website built with MkSaaS, a Next.js SaaS boilerplate to help you build your AI SaaS faster and better.",
"introduction": "Introducing MkSaaS Boilerplate",
"primary": "Get Started",
"secondary": "See Demo"
@ -43,6 +43,58 @@
"LogoCloud": {
"title": "Your favorite companies are our partners"
},
"features": {
"title": "The features of your product",
"description": "Write the description of your product here",
"items": {
"item-1": {
"title": "Product Feature One",
"description": "Please write the detailed description of feature one here, make it as detailed as possible, make it more attractive to users"
},
"item-2": {
"title": "Product Feature Two",
"description": "Please write the detailed description of feature two here, make it as detailed as possible, make it more attractive to users"
},
"item-3": {
"title": "Product Feature Three",
"description": "Please write the detailed description of feature three here, make it as detailed as possible, make it more attractive to users"
},
"item-4": {
"title": "Product Feature Four",
"description": "Please write the detailed description of feature four here, make it as detailed as possible, make it more attractive to users"
}
}
},
"features2": {
"title": "The features of your product",
"description": "Write the description of your product here",
"items": {
"item-1": {
"title": "Product Feature One",
"description": "Please write the detailed description of feature one here"
},
"item-2": {
"title": "Product Feature Two",
"description": "Please write the detailed description of feature two here"
},
"item-3": {
"title": "Product Feature Three",
"description": "Please write the detailed description of feature three here"
},
"item-4": {
"title": "Product Feature Four",
"description": "Please write the detailed description of feature four here"
},
"item-5": {
"title": "Product Feature Five",
"description": "Please write the detailed description of feature five here"
},
"item-6": {
"title": "Product Feature Six",
"description": "Please write the detailed description of feature six here"
}
}
},
"faqs": {
"title": "Frequently Asked Questions",
"description": "Please feel free to contact us if you have any questions",

View File

@ -43,6 +43,58 @@
"LogoCloud": {
"title": "您最爱公司都是我们的合作伙伴"
},
"features": {
"title": "您的 SaaS 产品功能",
"description": "请在详细介绍您的 SaaS 产品的特色功能的信息",
"items": {
"item-1": {
"title": "产品特色功能一",
"description": "请在这里详细描述您的产品特色功能一,尽可能详细,使其更吸引用户,提高落地页的转化率"
},
"item-2": {
"title": "产品特色功能二",
"description": "请在这里详细描述您的产品特色功能二,尽可能详细,使其更吸引用户,提高落地页的转化率"
},
"item-3": {
"title": "产品特色功能三",
"description": "请在这里详细描述您的产品特色功能三,尽可能详细,使其更吸引用户,提高落地页的转化率"
},
"item-4": {
"title": "产品特色功能四",
"description": "请在这里详细描述您的产品特色功能四,尽可能详细,使其更吸引用户,提高落地页的转化率"
}
}
},
"features2": {
"title": "您的 SaaS 产品功能",
"description": "请在详细介绍您的 SaaS 产品的特色功能的信息",
"items": {
"item-1": {
"title": "产品特色功能一",
"description": "请在这里详细描述您的产品特色功能一,尽可能详细,使其更吸引用户"
},
"item-2": {
"title": "产品特色功能二",
"description": "请在这里详细描述您的产品特色功能二,尽可能详细,使其更吸引用户"
},
"item-3": {
"title": "产品特色功能三",
"description": "请在这里详细描述您的产品特色功能三,尽可能详细,使其更吸引用户"
},
"item-4": {
"title": "产品特色功能四",
"description": "请在这里详细描述您的产品特色功能四,尽可能详细,使其更吸引用户"
},
"item-5": {
"title": "产品特色功能五",
"description": "请在这里详细描述您的产品特色功能五,尽可能详细,使其更吸引用户"
},
"item-6": {
"title": "产品特色功能六",
"description": "请在这里详细描述您的产品特色功能六,尽可能详细,使其更吸引用户"
}
}
},
"faqs": {
"title": "常见问题",
"description": "如果您有任何问题,请随时联系我们",

View File

@ -1,5 +1,8 @@
import FaqSection from '@/components/blocks/faqs/faqs';
import FeaturesSection from '@/components/blocks/features/features';
import Features2Section from '@/components/blocks/features/features2';
import HeroSection from '@/components/blocks/hero/hero';
import LogoCloud from '@/components/blocks/logo-cloud/logo-cloud';
import { constructMetadata } from '@/lib/metadata';
import { getUrlWithLocale } from '@/lib/urls/urls';
import { Metadata } from 'next';
@ -7,11 +10,9 @@ import { Locale } from 'next-intl';
import { getTranslations } from 'next-intl/server';
import CallToAction from '../../preview/call-to-action/one/page';
import ContentSection from '../../preview/content/one/page';
import Features from '../../preview/features/one/page';
import Pricing from '../../preview/pricing/three/page';
import StatsSection from '../../preview/stats/one/page';
import Testimonials from '../../preview/testimonials/one/page';
import LogoCloud from '@/components/blocks/logo-cloud/logo-cloud';
/**
* https://next-intl.dev/docs/environments/actions-metadata-route-handlers#metadata-api
@ -52,7 +53,11 @@ export default async function HomePage(props: HomePageProps) {
</div>
<div id="features" className="">
<Features />
<FeaturesSection />
</div>
<div id="features2" className="">
<Features2Section />
</div>
<div id="content" className="">

View File

@ -0,0 +1,147 @@
'use client';
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from '@/components/ui/accordion';
import {
ChartBarIncreasingIcon,
Database,
Fingerprint,
IdCard,
} from 'lucide-react';
import Image from 'next/image';
import { useState } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { BorderBeam } from '@/components/magicui/border-beam';
import { useTranslations } from 'next-intl';
/**
* https://nsui.irung.me/features
* pnpm dlx shadcn@canary add https://nsui.irung.me/r/features-12.json
*/
export default function FeaturesSection() {
const t = useTranslations('HomePage.features');
type ImageKey = 'item-1' | 'item-2' | 'item-3' | 'item-4';
const [activeItem, setActiveItem] = useState<ImageKey>('item-1');
const images = {
'item-1': {
image: '/blocks/charts.png',
alt: 'Product Feature One',
},
'item-2': {
image: '/blocks/music.png',
alt: 'Product Feature Two',
},
'item-3': {
image: '/blocks/mail2.png',
alt: 'Product Feature Three',
},
'item-4': {
image: '/blocks/payments.png',
alt: 'Product Feature Four',
},
};
return (
<section className="py-16">
<div className="bg-linear-to-b absolute inset-0 -z-10 sm:inset-6 sm:rounded-b-3xl dark:block dark:to-[color-mix(in_oklab,var(--color-zinc-900)_75%,var(--color-background))]"></div>
<div className="mx-auto max-w-5xl space-y-8 px-6 md:space-y-16 lg:space-y-20 dark:[--color-border:color-mix(in_oklab,var(--color-white)_10%,transparent)]">
<div className="relative z-10 mx-auto max-w-2xl space-y-6 text-center">
<h2 className="text-balance text-4xl lg:text-5xl font-semibold">
{t('title')}
</h2>
<p>
{t('description')}
</p>
</div>
<div className="grid gap-12 sm:px-12 md:grid-cols-2 lg:gap-20 lg:px-0">
<Accordion
type="single"
value={activeItem}
onValueChange={(value) => setActiveItem(value as ImageKey)}
className="w-full"
>
<AccordionItem value="item-1">
<AccordionTrigger>
<div className="flex items-center gap-2 text-base">
<Database className="size-4" />
{t('items.item-1.title')}
</div>
</AccordionTrigger>
<AccordionContent>
{t('items.item-1.description')}
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>
<div className="flex items-center gap-2 text-base">
<Fingerprint className="size-4" />
{t('items.item-2.title')}
</div>
</AccordionTrigger>
<AccordionContent>
{t('items.item-2.description')}
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger>
<div className="flex items-center gap-2 text-base">
<IdCard className="size-4" />
{t('items.item-3.title')}
</div>
</AccordionTrigger>
<AccordionContent>
{t('items.item-3.description')}
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-4">
<AccordionTrigger>
<div className="flex items-center gap-2 text-base">
<ChartBarIncreasingIcon className="size-4" />
{t('items.item-4.title')}
</div>
</AccordionTrigger>
<AccordionContent>
{t('items.item-4.description')}
</AccordionContent>
</AccordionItem>
</Accordion>
<div className="bg-background relative flex overflow-hidden rounded-2xl border p-2">
{/* <div className="w-15 absolute inset-0 right-0 ml-auto border-l bg-[repeating-linear-gradient(-45deg,var(--color-border),var(--color-border)_1px,transparent_1px,transparent_8px)]"></div> */}
<div className="aspect-76/59 bg-background relative rounded-2xl">
<AnimatePresence mode="wait">
<motion.div
key={`${activeItem}-id`}
initial={{ opacity: 0, y: 6, scale: 0.98 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: 6, scale: 0.98 }}
transition={{ duration: 0.2 }}
className="size-full overflow-hidden rounded-2xl border bg-zinc-900 shadow-md"
>
<Image
src={images[activeItem].image}
className="size-full object-cover object-left-top dark:mix-blend-lighten"
alt={images[activeItem].alt}
width={1207}
height={929}
/>
</motion.div>
</AnimatePresence>
</div>
<BorderBeam
duration={6}
size={200}
className="from-transparent via-yellow-700 to-transparent dark:via-white/50"
/>
</div>
</div>
</div>
</section>
);
}

View File

@ -0,0 +1,86 @@
import { CpuIcon, FingerprintIcon, PencilIcon, Settings2Icon, SparklesIcon, ZapIcon } from 'lucide-react';
import { useTranslations } from 'next-intl';
/**
* https://nsui.irung.me/features
* pnpm dlx shadcn@canary add https://nsui.irung.me/r/features-4.json
*/
export default function Features2Section() {
const t = useTranslations('HomePage.features2');
return (
<section className="py-16">
<div className="mx-auto max-w-5xl px-6 space-y-16">
<div className="text-center">
<h2 className="text-balance text-4xl lg:text-5xl font-semibold">
{t('title')}
</h2>
<p className="mt-4">
{t('description')}
</p>
</div>
<div className="relative mx-auto grid max-w-5xl divide-x divide-y border *:p-12 sm:grid-cols-2 lg:grid-cols-3">
<div className="space-y-2">
<div className="flex items-center gap-2">
<ZapIcon className="size-4" />
<h3 className="text-base font-medium">{t('items.item-1.title')}</h3>
</div>
<p className="text-sm text-muted-foreground mt-4">
{t('items.item-1.description')}
</p>
</div>
<div className="space-y-2">
<div className="flex items-center gap-2">
<CpuIcon className="size-4" />
<h3 className="text-base font-medium">{t('items.item-2.title')}</h3>
</div>
<p className="text-sm text-muted-foreground mt-4">
{t('items.item-2.description')}
</p>
</div>
<div className="space-y-2">
<div className="flex items-center gap-2">
<FingerprintIcon className="size-4" />
<h3 className="text-base font-medium">{t('items.item-3.title')}</h3>
</div>
<p className="text-sm text-muted-foreground mt-4">
{t('items.item-3.description')}
</p>
</div>
<div className="space-y-2">
<div className="flex items-center gap-2">
<PencilIcon className="size-4" />
<h3 className="text-base font-medium">{t('items.item-4.title')}</h3>
</div>
<p className="text-sm text-muted-foreground mt-4">
{t('items.item-4.description')}
</p>
</div>
<div className="space-y-2">
<div className="flex items-center gap-2">
<Settings2Icon className="size-4" />
<h3 className="text-base font-medium">{t('items.item-5.title')}</h3>
</div>
<p className="text-sm text-muted-foreground mt-4">
{t('items.item-5.description')}
</p>
</div>
<div className="space-y-2">
<div className="flex items-center gap-2">
<SparklesIcon className="size-4" />
<h3 className="text-base font-medium">{t('items.item-6.title')}</h3>
</div>
<p className="text-sm text-muted-foreground mt-4">
{t('items.item-6.description')}
</p>
</div>
</div>
</div>
</section>
);
}

View File

@ -6,12 +6,12 @@ export default function LogoCloudSection() {
return (
<section className="py-16">
<div className="mx-auto max-w-5xl px-6">
<h2 className="text-center text-lg font-medium">
<h2 className="text-center text-xl font-semibold">
{t('title')}
</h2>
<div className="mx-auto mt-20 flex max-w-4xl flex-wrap items-center justify-center gap-x-12 gap-y-8 sm:gap-x-16 sm:gap-y-12">
<img
className="h-5 w-fit dark:invert"
className="h-4 w-fit dark:invert"
src="/svg/nextjs_logo_light.svg"
alt="Nextjs Logo"
height="20"
@ -25,7 +25,7 @@ export default function LogoCloudSection() {
width="auto"
/>
<img
className="h-7 w-fit dark:invert"
className="h-6 w-fit dark:invert"
src="/svg/resend-wordmark-black.svg"
alt="Resend Logo"
height="28"
@ -46,7 +46,14 @@ export default function LogoCloudSection() {
width="auto"
/>
<img
className="h-4 w-fit dark:invert"
className="h-5 w-fit dark:invert"
src="/svg/cursor_wordmark_light.svg"
alt="Cursor Logo"
height="20"
width="auto"
/>
<img
className="h-5 w-fit dark:invert"
src="/svg/lemonsqueezy.svg"
alt="Lemon Squeezy Logo"
height="16"
@ -73,13 +80,6 @@ export default function LogoCloudSection() {
height="20"
width="auto"
/>
<img
className="h-5 w-fit dark:invert"
src="/svg/cursor_wordmark_light.svg"
alt="Cursor Logo"
height="20"
width="auto"
/>
</div>
</div>
</section>