286 lines
14 KiB
TypeScript
286 lines
14 KiB
TypeScript
import { features } from '@/data/features';
|
|
import { resources } from '@/data/resources';
|
|
import { notFound } from 'next/navigation';
|
|
import styles from './feature-page.module.css';
|
|
import SafeImage from '@/components/SafeImage';
|
|
import Link from 'next/link';
|
|
import TestimonialSlider from '@/components/TestimonialSlider';
|
|
import {
|
|
Calendar, Eye, BarChart, Trophy, Inbox, ShieldCheck,
|
|
Palette, Layout, Smartphone, Zap, PenTool, Repeat,
|
|
CheckCircle
|
|
} from 'lucide-react';
|
|
|
|
// Define Props interface
|
|
interface PageProps {
|
|
params: Promise<{ slug: string }>;
|
|
}
|
|
|
|
export async function generateStaticParams() {
|
|
return features.map((feature) => ({
|
|
slug: feature.slug,
|
|
}));
|
|
}
|
|
|
|
export async function generateMetadata(props: PageProps) {
|
|
const params = await props.params;
|
|
const feature = features.find((f) => f.slug === params.slug);
|
|
if (!feature) return { title: 'Feature Not Found' };
|
|
|
|
return {
|
|
title: `${feature.title} - SocialBuddy`,
|
|
description: feature.description,
|
|
};
|
|
}
|
|
|
|
// Icon mapping helper
|
|
const getIcon = (iconName: string) => {
|
|
switch (iconName) {
|
|
case 'Calendar': return <Calendar />;
|
|
case 'Eye': return <Eye />;
|
|
case 'BarChart': return <BarChart />;
|
|
case 'Trophy': return <Trophy />;
|
|
case 'Inbox': return <Inbox />;
|
|
case 'ShieldCheck': return <ShieldCheck />;
|
|
case 'Palette': return <Palette />;
|
|
case 'Layout': return <Layout />;
|
|
case 'Smartphone': return <Smartphone />;
|
|
case 'Zap': return <Zap />;
|
|
case 'PenTool': return <PenTool />;
|
|
case 'Repeat': return <Repeat />;
|
|
default: return <CheckCircle />;
|
|
}
|
|
};
|
|
|
|
export default async function FeaturePage(props: PageProps) {
|
|
const params = await props.params;
|
|
|
|
// Ensure params exists
|
|
if (!params?.slug) {
|
|
notFound();
|
|
}
|
|
|
|
const feature = features.find((f) => f.slug === params.slug);
|
|
|
|
if (!feature) {
|
|
notFound();
|
|
}
|
|
|
|
// Filter resources
|
|
const featureResources = resources.filter(b => b.featureSlug === feature.slug).slice(0, 3);
|
|
const displayResources = featureResources.length > 0 ? featureResources : resources.slice(0, 3);
|
|
|
|
return (
|
|
<main className={styles.page}>
|
|
{/* 1. Hero Section (Banner Style, Center Title + Breadcrumbs) */}
|
|
<section className={styles.hero}>
|
|
<div className={styles.container}>
|
|
<div className={styles.heroContent}>
|
|
<h1 className={styles.heroTitle}>{feature.title}</h1>
|
|
<div className={styles.breadcrumbs}>
|
|
<Link href="/">Home</Link> <span>/</span> <Link href="/features">Features</Link> <span>/</span> {feature.title}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* 2. About Section (Icons) */}
|
|
{feature.about && (
|
|
<section className={styles.aboutSection}>
|
|
<div className={styles.container}>
|
|
<div className={styles.aboutGrid}>
|
|
<div className={styles.aboutImages}>
|
|
<div className={styles.aboutMainImgWrapper}>
|
|
<SafeImage
|
|
src={feature.about.mainImage}
|
|
alt="Main Feature"
|
|
className={styles.img}
|
|
fallbackSrc="https://placehold.co/600x800/png?text=About+Main"
|
|
/>
|
|
</div>
|
|
<div className={styles.aboutSubImgWrapper}>
|
|
<SafeImage
|
|
src={feature.about.subImage}
|
|
alt="Sub Feature"
|
|
className={styles.img}
|
|
fallbackSrc="https://placehold.co/400x400/png?text=About+Sub"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className={styles.aboutContent}>
|
|
<span className={styles.sectionSubtitle}>{feature.about.subTitle}</span>
|
|
<h2 className={styles.sectionTitle}>{feature.about.title}</h2>
|
|
<p className={styles.aboutDescription}>{feature.about.description}</p>
|
|
<div className={styles.aboutPoints}>
|
|
{feature.about.bulletPoints.map((point, i) => (
|
|
<div key={i} className={styles.aboutPointItem}>
|
|
<span className={styles.aboutPointIcon}>
|
|
{getIcon(point.icon)}
|
|
</span>
|
|
<span className={styles.aboutPointText}>{point.text}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<a href="#" className="btn btn-primary">Read More</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)}
|
|
|
|
{/* 3. Benefits / Why Choose */}
|
|
<section className={styles.benefitsSection}>
|
|
<div className={styles.container}>
|
|
<div className={styles.benefitsContainer}>
|
|
<div className={styles.benefitsContent}>
|
|
<span className={styles.sectionSubtitle}>Why Choose Us</span>
|
|
<h2 className={styles.sectionTitle}>Custom Solutions for Your Social Growth</h2>
|
|
<p className={styles.aboutDescription}>
|
|
Everything you need to succeed on social media, all in one platform.
|
|
We provide the tools to help you scale effectively.
|
|
</p>
|
|
<a href="#" className="btn btn-primary">Video Showcase</a>
|
|
</div>
|
|
<div className={styles.benefitsGrid}>
|
|
{feature.benefits.slice(0, 4).map((benefit, index) => (
|
|
<div key={index} className={styles.benefitCard}>
|
|
<div className={styles.benefitIcon}>{benefit.icon}</div>
|
|
<h3 className={styles.benefitCardTitle}>{benefit.title}</h3>
|
|
<p className={styles.benefitCardDesc}>{benefit.description}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* 4. Testimonials (Left: 2 Images, Right: Slider) */}
|
|
{feature.testimonials && feature.testimonials.length > 0 && (
|
|
<section className={styles.testimonialSection}>
|
|
<div className={styles.container}>
|
|
<div className={styles.testimonialGrid}>
|
|
<div className={styles.testimonialImages}>
|
|
<div className={styles.testImgWrapper}>
|
|
<SafeImage
|
|
src={feature.heroImage}
|
|
alt="Happy Customer"
|
|
className={styles.img}
|
|
fallbackSrc="https://placehold.co/400x400/png?text=Customer+1"
|
|
/>
|
|
</div>
|
|
<div className={styles.testImgWrapper}>
|
|
<SafeImage
|
|
src={feature.about.mainImage}
|
|
alt="Community"
|
|
className={styles.img}
|
|
fallbackSrc="https://placehold.co/400x400/png?text=Customer+2"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className={styles.testimonialSliderWrapper}>
|
|
<span className={styles.sectionSubtitle}>Testimonials</span>
|
|
<h2 className={styles.sectionTitle}>Trusted by Thousands</h2>
|
|
<TestimonialSlider testimonials={feature.testimonials} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)}
|
|
|
|
{/* 5. Resources / Blogs */}
|
|
<section className={styles.resourcesSection}>
|
|
<div className={styles.container}>
|
|
<div style={{ textAlign: 'center', maxWidth: '800px', margin: '0 auto' }}>
|
|
<span className={styles.sectionSubtitle}>Resources</span>
|
|
<h2 className={styles.sectionTitle}>Latest Insights for {feature.title}</h2>
|
|
</div>
|
|
|
|
<div className={styles.blogGrid}>
|
|
{displayResources.map((resource) => (
|
|
<div key={resource.id} className={styles.blogCard}>
|
|
<div className={styles.blogImageWrapper}>
|
|
<SafeImage
|
|
src={resource.image}
|
|
alt={resource.title}
|
|
className={styles.blogImage}
|
|
fallbackSrc={`https://placehold.co/600x400/png?text=${encodeURIComponent(resource.category)}`}
|
|
/>
|
|
</div>
|
|
<div className={styles.blogContent}>
|
|
<span className={styles.blogCategory}>{resource.category}</span>
|
|
<h3 className={styles.blogTitle}>{resource.title}</h3>
|
|
<p className={styles.blogExcerpt}>{resource.excerpt}</p>
|
|
<Link href={`/resources/${resource.slug}`} className={styles.readMoreLink}>
|
|
Read Article →
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* 6. FAQ */}
|
|
{feature.faqs && feature.faqs.length > 0 && (
|
|
<section className={styles.faqSection}>
|
|
<div className={styles.container}>
|
|
<div className={styles.faqGrid}>
|
|
<div className={styles.faqContent}>
|
|
<span className={styles.sectionSubtitle}>FAQ</span>
|
|
<h2 className={styles.sectionTitle}>Frequently Asked Questions</h2>
|
|
<div className={styles.accordion}>
|
|
{feature.faqs.map((faq, index) => (
|
|
<details key={index} className={styles.accordionItem}>
|
|
<summary className={styles.accordionTrigger}>
|
|
{faq.question}
|
|
<span className={styles.accordionIcon}>+</span>
|
|
</summary>
|
|
<div className={styles.accordionContentOpen}>
|
|
<p style={{ paddingBottom: '1.5rem', color: 'var(--text-secondary)' }}>{faq.answer}</p>
|
|
</div>
|
|
</details>
|
|
))}
|
|
</div>
|
|
</div>
|
|
<div className={styles.faqImageWrapper}>
|
|
<SafeImage
|
|
src="/images/faq-illustration.png"
|
|
alt="FAQ Illustration"
|
|
className={styles.img}
|
|
fallbackSrc="https://placehold.co/600x600/png?text=FAQ+Support"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)}
|
|
|
|
{/* 7. CTA (Full Width Floating) */}
|
|
<section className={styles.ctaFullWidth}>
|
|
<SafeImage
|
|
src="/images/shape-left.png"
|
|
alt=""
|
|
className={`${styles.floatElem} ${styles.floatLeft}`}
|
|
fallbackSrc="https://placehold.co/150x150/png?text=Shape"
|
|
/>
|
|
<SafeImage
|
|
src="/images/shape-right.png"
|
|
alt=""
|
|
className={`${styles.floatElem} ${styles.floatRight}`}
|
|
fallbackSrc="https://placehold.co/150x150/png?text=Shape"
|
|
/>
|
|
|
|
<div className={styles.ctaContentCentered}>
|
|
<h2 className={styles.ctaFullTitle}>Ready to Grow Your Social Presence?</h2>
|
|
<p className={styles.ctaFullText}>
|
|
Join thousands of marketers who are already using SocialBuddy to streamline their workflow.
|
|
</p>
|
|
<a href="https://app.socialbuddy.co/signup" className={styles.ctaFullBtn}>
|
|
Start Free Trial
|
|
</a>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|