From 009cabfc1ccab711da60b563fc2a5b1896a0f7cf Mon Sep 17 00:00:00 2001 From: ArraysID Date: Sat, 10 May 2025 05:35:24 +0700 Subject: [PATCH] feat: add CommunitiesSection configuration and integrate with Community component --- .../app/(frontend)/_components/community.tsx | 147 ++++++------------ apps/landing/src/app/(frontend)/page.tsx | 6 +- .../src/collections/CommunitiesSection.ts | 70 +++++++++ .../src/collections/FeaturesSection.ts | 3 - apps/landing/src/collections/HeroSection.ts | 4 - apps/landing/src/payload-types.ts | 50 ++++++ apps/landing/src/payload.config.ts | 3 +- .../get-globals-communitues-section.ts | 7 + 8 files changed, 178 insertions(+), 112 deletions(-) create mode 100644 apps/landing/src/collections/CommunitiesSection.ts create mode 100644 apps/landing/src/repositories/get-globals-communitues-section.ts diff --git a/apps/landing/src/app/(frontend)/_components/community.tsx b/apps/landing/src/app/(frontend)/_components/community.tsx index f1c415c..7370a13 100644 --- a/apps/landing/src/app/(frontend)/_components/community.tsx +++ b/apps/landing/src/app/(frontend)/_components/community.tsx @@ -6,48 +6,26 @@ import { InstagramIcon, MessageCircleIcon, } from '@imphnen-frontend-service/shadcn-ui/atoms'; +import { CommunitiesSection } from 'apps/landing/src/payload-types'; import { motion, useInView } from 'framer-motion'; import { useRef } from 'react'; -export function Community() { +export function Community(props: CommunitiesSection) { + const { items: communities, stats } = props; const ref = useRef(null); const isInView = useInView(ref, { once: true, amount: 0.2 }); - const communities = [ - { - icon: ( - - ), - iconBg: 'bg-blue-100 dark:bg-blue-900', - title: 'Facebook Group', - description: - 'Bergabunglah dengan grup Facebook kami untuk diskusi santai dan berbagi artikel menarik.', - buttonText: 'Gabung Sekarang', - buttonLink: '#', - }, - { - icon: ( - - ), - iconBg: 'bg-blue-100 dark:bg-blue-900', - title: 'Instagram', - description: - 'Ikuti kami di Instagram untuk tips programming, konten inspiratif, dan info event terbaru.', - buttonText: 'Follow Kami', - buttonLink: '#', - }, - { - icon: ( - - ), - iconBg: 'bg-blue-100 dark:bg-blue-900', - title: 'Discord Server', - description: - 'Diskusikan langsung dengan sesama programmer dan dapatkan bantuan langsung dari para ahli.', - buttonText: 'Join Server', - buttonLink: '#', - }, - ]; + const iconMap = { + FacebookIcon: ( + + ), + InstagramIcon: ( + + ), + MessageCircleIcon: ( + + ), + }; const containerVariants = { hidden: { opacity: 0 }, @@ -73,105 +51,70 @@ export function Community() { id="komunitas" className="w-full py-20 md:py-32 bg-muted relative overflow-hidden" > - {/* Background Elements */}
-
-
- -

- Komunitas{' '} - - Kami - -

-

- Bergabunglah dengan ribuan programmer Indonesia yang saling - membantu dan berbagi pengalaman. -

-
-
- +

+ Komunitas{' '} + + Kami + +

+

+ Bergabunglah dengan ribuan programmer Indonesia yang saling membantu + dan berbagi pengalaman. +

+
+ - {communities.map((community, index) => ( + {communities?.map((c, i) => (
-
-
- {community.icon} +
+ {iconMap[c.iconName]}
-

{community.title}

-

- {community.description} -

+

{c.title}

+

{c.description}

-
))} - - {/* Community Stats */} -
-
- 10K+ + {stats?.map((s, i) => ( +
+
+ {s.value} +
+
{s.label}
-
Member Aktif
-
-
-
- 50+ -
-
Event Bulanan
-
-
-
- 100+ -
-
- Mentor Profesional -
-
-
-
- 5K+ -
-
- Diskusi Mingguan -
-
+ ))}
diff --git a/apps/landing/src/app/(frontend)/page.tsx b/apps/landing/src/app/(frontend)/page.tsx index 079c88d..9a5a0ad 100644 --- a/apps/landing/src/app/(frontend)/page.tsx +++ b/apps/landing/src/app/(frontend)/page.tsx @@ -1,3 +1,4 @@ +import { getGlobalsCommunitiesSection } from '../../repositories/get-globals-communitues-section'; import { getGlobalsFeaturesSection } from '../../repositories/get-globals-features-section'; import { getGlobalsHeroSection } from '../../repositories/get-globals-hero-section'; import { CallToAction } from './_components/call-to-action'; @@ -12,9 +13,10 @@ import { Testimonials } from './_components/testimonials'; export const revalidate = 10; // Seconds export default async function Page() { - const [heroData, featuresData] = await Promise.all([ + const [heroData, featuresData, communitiesData] = await Promise.all([ getGlobalsHeroSection(), getGlobalsFeaturesSection(), + getGlobalsCommunitiesSection(), ]); return ( @@ -23,7 +25,7 @@ export default async function Page() {
- + diff --git a/apps/landing/src/collections/CommunitiesSection.ts b/apps/landing/src/collections/CommunitiesSection.ts new file mode 100644 index 0000000..a60a903 --- /dev/null +++ b/apps/landing/src/collections/CommunitiesSection.ts @@ -0,0 +1,70 @@ +import { GlobalConfig } from 'payload'; + +export const CommunitiesSection: GlobalConfig = { + slug: 'communities-section', + label: 'Communities Section', + fields: [ + { + name: 'items', + type: 'array', + required: true, + defaultValue: [ + { + iconName: 'FacebookIcon', + title: 'Facebook Group', + description: + 'Bergabunglah dengan grup Facebook kami untuk diskusi santai dan berbagi artikel menarik.', + buttonText: 'Gabung Sekarang', + buttonLink: 'https://facebook.com/groups/1032515944638255', + }, + { + iconName: 'InstagramIcon', + title: 'Instagram', + description: + 'Ikuti kami di Instagram untuk tips programming, konten inspiratif, dan info event terbaru.', + buttonText: 'Follow Kami', + buttonLink: 'https://www.instagram.com/imphnen.dev', + }, + { + iconName: 'MessageCircleIcon', + title: 'Discord Server', + description: + 'Diskusikan langsung dengan sesama programmer dan dapatkan bantuan langsung dari para ahli.', + buttonText: 'Join Server', + buttonLink: 'https://discord.com/invite/imphnen', + }, + ], + fields: [ + { + name: 'iconName', + type: 'select', + options: [ + { label: 'Facebook', value: 'FacebookIcon' }, + { label: 'Instagram', value: 'InstagramIcon' }, + { label: 'Discord', value: 'MessageCircleIcon' }, + ], + required: true, + }, + { name: 'title', type: 'text', required: true }, + { name: 'description', type: 'textarea', required: true }, + { name: 'buttonText', type: 'text', required: true }, + { name: 'buttonLink', type: 'text', required: true }, + ], + }, + { + name: 'stats', + type: 'array', + required: true, + defaultValue: [ + { value: '100K+', label: 'Member Aktif' }, + { value: '50+', label: 'Event Bulanan' }, + { value: '100+', label: 'Mentor Profesional' }, + { value: '5K+', label: 'Diskusi Mingguan' }, + ], + fields: [ + { name: 'value', type: 'text', required: true }, + { name: 'label', type: 'text', required: true }, + ], + }, + ], +}; diff --git a/apps/landing/src/collections/FeaturesSection.ts b/apps/landing/src/collections/FeaturesSection.ts index 8de4e31..37a058a 100644 --- a/apps/landing/src/collections/FeaturesSection.ts +++ b/apps/landing/src/collections/FeaturesSection.ts @@ -3,9 +3,6 @@ import { GlobalConfig } from 'payload'; export const FeaturesSection: GlobalConfig = { slug: 'features-section', label: 'Features Section', - access: { - read: (): boolean => true, - }, fields: [ { name: 'heading', diff --git a/apps/landing/src/collections/HeroSection.ts b/apps/landing/src/collections/HeroSection.ts index 38e5a1e..33c6490 100644 --- a/apps/landing/src/collections/HeroSection.ts +++ b/apps/landing/src/collections/HeroSection.ts @@ -3,10 +3,6 @@ import type { GlobalConfig } from 'payload'; export const HeroSection: GlobalConfig = { slug: 'hero-section', label: 'Hero Section', - access: { - read: () => true, - update: () => true, - }, fields: [ { name: 'badgeText', diff --git a/apps/landing/src/payload-types.ts b/apps/landing/src/payload-types.ts index b1c50ce..4ef1e98 100644 --- a/apps/landing/src/payload-types.ts +++ b/apps/landing/src/payload-types.ts @@ -87,10 +87,12 @@ export interface Config { globals: { 'hero-section': HeroSection; 'features-section': FeaturesSection; + 'communities-section': CommunitiesSection; }; globalsSelect: { 'hero-section': HeroSectionSelect | HeroSectionSelect; 'features-section': FeaturesSectionSelect | FeaturesSectionSelect; + 'communities-section': CommunitiesSectionSelect | CommunitiesSectionSelect; }; locale: null; user: User & { @@ -322,6 +324,28 @@ export interface FeaturesSection { updatedAt?: string | null; createdAt?: string | null; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "communities-section". + */ +export interface CommunitiesSection { + id: number; + items: { + iconName: 'FacebookIcon' | 'InstagramIcon' | 'MessageCircleIcon'; + title: string; + description: string; + buttonText: string; + buttonLink: string; + id?: string | null; + }[]; + stats: { + value: string; + label: string; + id?: string | null; + }[]; + updatedAt?: string | null; + createdAt?: string | null; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "hero-section_select". @@ -369,6 +393,32 @@ export interface FeaturesSectionSelect { createdAt?: T; globalType?: T; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "communities-section_select". + */ +export interface CommunitiesSectionSelect { + items?: + | T + | { + iconName?: T; + title?: T; + description?: T; + buttonText?: T; + buttonLink?: T; + id?: T; + }; + stats?: + | T + | { + value?: T; + label?: T; + id?: T; + }; + updatedAt?: T; + createdAt?: T; + globalType?: T; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "auth". diff --git a/apps/landing/src/payload.config.ts b/apps/landing/src/payload.config.ts index b63dcd5..dc962f5 100644 --- a/apps/landing/src/payload.config.ts +++ b/apps/landing/src/payload.config.ts @@ -5,6 +5,7 @@ import { buildConfig } from 'payload'; import sharp from 'sharp'; import { fileURLToPath } from 'url'; +import { CommunitiesSection } from './collections/CommunitiesSection'; import { FeaturesSection } from './collections/FeaturesSection'; import { HeroSection } from './collections/HeroSection'; import { Media } from './collections/Media'; @@ -27,7 +28,7 @@ export default buildConfig({ }, }, collections: [Users, Media], - globals: [HeroSection, FeaturesSection], + globals: [HeroSection, FeaturesSection, CommunitiesSection], editor: lexicalEditor(), secret: process.env.CMS_SECRET || '', typescript: { diff --git a/apps/landing/src/repositories/get-globals-communitues-section.ts b/apps/landing/src/repositories/get-globals-communitues-section.ts new file mode 100644 index 0000000..7b11ce7 --- /dev/null +++ b/apps/landing/src/repositories/get-globals-communitues-section.ts @@ -0,0 +1,7 @@ +import { payload } from '../lib/payload'; + +export async function getGlobalsCommunitiesSection() { + return await payload.findGlobal({ + slug: 'communities-section', + }); +}