diff --git a/apps/landing/src/app/(frontend)/_components/header.tsx b/apps/landing/src/app/(frontend)/_components/header.tsx
deleted file mode 100644
index b27daa0..0000000
--- a/apps/landing/src/app/(frontend)/_components/header.tsx
+++ /dev/null
@@ -1,159 +0,0 @@
-'use client';
-
-import {
- Button,
- MenuIcon,
- XIcon,
-} from '@imphnen-frontend-service/shadcn-ui/atoms';
-import { cn } from '@imphnen-frontend-service/utils';
-import Image from 'next/image';
-import Link from 'next/link';
-import { useEffect, useState } from 'react';
-import { SimpleThemeToggle } from './simple-theme-toggle';
-
-export function Header() {
- const [isScrolled, setIsScrolled] = useState(false);
- const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
-
- useEffect(() => {
- const handleScroll = () => {
- setIsScrolled(window.scrollY > 10);
- };
- window.addEventListener('scroll', handleScroll);
- return () => window.removeEventListener('scroll', handleScroll);
- }, []);
-
- return (
-
- );
-}
diff --git a/apps/landing/src/app/(frontend)/_components/header/desktop-navigation.tsx b/apps/landing/src/app/(frontend)/_components/header/desktop-navigation.tsx
new file mode 100644
index 0000000..ed79e27
--- /dev/null
+++ b/apps/landing/src/app/(frontend)/_components/header/desktop-navigation.tsx
@@ -0,0 +1,22 @@
+import Link from 'next/link';
+
+export function DesktopNavigation() {
+ return (
+
+ );
+}
diff --git a/apps/landing/src/app/(frontend)/_components/header/header-wrapper.tsx b/apps/landing/src/app/(frontend)/_components/header/header-wrapper.tsx
new file mode 100644
index 0000000..b6b0016
--- /dev/null
+++ b/apps/landing/src/app/(frontend)/_components/header/header-wrapper.tsx
@@ -0,0 +1,29 @@
+'use client';
+
+import { cn } from '@imphnen-frontend-service/utils';
+import { ReactNode, useEffect, useState } from 'react';
+
+export function HeaderWrapper({ children }: { children: ReactNode }) {
+ const [isScrolled, setIsScrolled] = useState(false);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ setIsScrolled(window.scrollY > 10);
+ };
+ window.addEventListener('scroll', handleScroll);
+ return () => window.removeEventListener('scroll', handleScroll);
+ }, []);
+
+ return (
+
+ );
+}
diff --git a/apps/landing/src/app/(frontend)/_components/header/index.tsx b/apps/landing/src/app/(frontend)/_components/header/index.tsx
new file mode 100644
index 0000000..701026e
--- /dev/null
+++ b/apps/landing/src/app/(frontend)/_components/header/index.tsx
@@ -0,0 +1,30 @@
+'use client';
+
+import { useMobileMenuStore } from '../../../../stores/mobile-menu-store';
+import { DesktopNavigation } from './desktop-navigation';
+import { HeaderWrapper } from './header-wrapper';
+import { Logo } from './logo';
+import { MobileMenuHamburger } from './mobile-menu-hamburger';
+import { MobileNavigation } from './mobile-navigation';
+import { SimpleThemeToggle } from './simple-theme-toggle';
+
+export function Header() {
+ const mobileMenuOpen = useMobileMenuStore((s) => s.mobileMenuOpen);
+
+ return (
+
+
+
+ {mobileMenuOpen && }
+
+ );
+}
diff --git a/apps/landing/src/app/(frontend)/_components/header/logo.tsx b/apps/landing/src/app/(frontend)/_components/header/logo.tsx
new file mode 100644
index 0000000..3aeee27
--- /dev/null
+++ b/apps/landing/src/app/(frontend)/_components/header/logo.tsx
@@ -0,0 +1,16 @@
+import Image from 'next/image';
+import Link from 'next/link';
+
+export function Logo() {
+ return (
+
+
+
+ );
+}
diff --git a/apps/landing/src/app/(frontend)/_components/header/mobile-menu-hamburger.tsx b/apps/landing/src/app/(frontend)/_components/header/mobile-menu-hamburger.tsx
new file mode 100644
index 0000000..acee8a0
--- /dev/null
+++ b/apps/landing/src/app/(frontend)/_components/header/mobile-menu-hamburger.tsx
@@ -0,0 +1,28 @@
+'use client';
+
+import {
+ Button,
+ MenuIcon,
+ XIcon,
+} from '@imphnen-frontend-service/shadcn-ui/atoms';
+import { useMobileMenuStore } from '../../../../stores/mobile-menu-store';
+
+export function MobileMenuHamburger() {
+ const mobileMenuOpen = useMobileMenuStore((s) => s.mobileMenuOpen);
+ const toggleMobileMenu = useMobileMenuStore((s) => s.toggleMobileMenu);
+
+ return (
+
+ );
+}
diff --git a/apps/landing/src/app/(frontend)/_components/header/mobile-navigation.tsx b/apps/landing/src/app/(frontend)/_components/header/mobile-navigation.tsx
new file mode 100644
index 0000000..e9e0a1d
--- /dev/null
+++ b/apps/landing/src/app/(frontend)/_components/header/mobile-navigation.tsx
@@ -0,0 +1,28 @@
+import Link from 'next/link';
+
+export function MobileNavigation() {
+ return (
+
+
+
+ );
+}
diff --git a/apps/landing/src/app/(frontend)/_components/simple-theme-toggle.tsx b/apps/landing/src/app/(frontend)/_components/header/simple-theme-toggle.tsx
similarity index 100%
rename from apps/landing/src/app/(frontend)/_components/simple-theme-toggle.tsx
rename to apps/landing/src/app/(frontend)/_components/header/simple-theme-toggle.tsx
diff --git a/apps/landing/src/app/(frontend)/layout.tsx b/apps/landing/src/app/(frontend)/layout.tsx
index 8cbe8a6..5356b87 100644
--- a/apps/landing/src/app/(frontend)/layout.tsx
+++ b/apps/landing/src/app/(frontend)/layout.tsx
@@ -8,8 +8,9 @@ import { ThemeProvider } from './_components/theme-provider';
const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
- title: 'IMPHNEN - Ingin Menjadi Programmer Handal?',
- description: 'Komunitas belajar programming untuk semua level',
+ title: 'IMPHNEN - Ingin Menjadi Programmer Handal Namung Enggan Ngonding',
+ description:
+ 'Komunitas Ingin Menjadi Programmer Handal Namung Enggan Ngonding',
};
export default function RootLayout({
diff --git a/apps/landing/src/app/(frontend)/page.tsx b/apps/landing/src/app/(frontend)/page.tsx
index e50e601..470e7ad 100644
--- a/apps/landing/src/app/(frontend)/page.tsx
+++ b/apps/landing/src/app/(frontend)/page.tsx
@@ -1,41 +1,27 @@
import { getGlobalsCallToActionSection } from '../../services/get-globals-call-to-action-section';
import { getGlobalsCommunitiesSection } from '../../services/get-globals-communitues-section';
-import { getGlobalsFeaturesSection } from '../../services/get-globals-features-section';
import { getGlobalsHeroSection } from '../../services/get-globals-hero-section';
-import { getGlobalsLearningResourcesSection } from '../../services/get-globals-learning-resources-section';
import { getGlobalsTestimonialsSection } from '../../services/get-globals-testimonials-section';
import { CallToAction } from './_components/call-to-action';
import { Community } from './_components/community';
-import { Features } from './_components/features';
import { Hero } from './_components/hero';
-import { LearningResources } from './_components/learning-resources';
import { Testimonials } from './_components/testimonials';
export const revalidate = 10; // Seconds
export default async function Page() {
- const [
- heroData,
- featuresData,
- communitiesData,
- learningResourcesData,
- testimonialsData,
- callToActionData,
- ] = await Promise.all([
- getGlobalsHeroSection(),
- getGlobalsFeaturesSection(),
- getGlobalsCommunitiesSection(),
- getGlobalsLearningResourcesSection(),
- getGlobalsTestimonialsSection(),
- getGlobalsCallToActionSection(),
- ]);
+ const [heroData, communitiesData, testimonialsData, callToActionData] =
+ await Promise.all([
+ getGlobalsHeroSection(),
+ getGlobalsCommunitiesSection(),
+ getGlobalsTestimonialsSection(),
+ getGlobalsCallToActionSection(),
+ ]);
return (
<>
-
-
>
diff --git a/apps/landing/src/stores/mobile-menu-store.ts b/apps/landing/src/stores/mobile-menu-store.ts
new file mode 100644
index 0000000..7c39b1f
--- /dev/null
+++ b/apps/landing/src/stores/mobile-menu-store.ts
@@ -0,0 +1,12 @@
+import { create } from 'zustand';
+
+interface MobileMenuState {
+ mobileMenuOpen: boolean;
+ toggleMobileMenu: () => void;
+}
+
+export const useMobileMenuStore = create((set) => ({
+ mobileMenuOpen: false,
+ toggleMobileMenu: () =>
+ set((state) => ({ mobileMenuOpen: !state.mobileMenuOpen })),
+}));
diff --git a/package-lock.json b/package-lock.json
index c5d83b2..8699fd4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -38,7 +38,8 @@
"sharp": "^0.34.1",
"sonner": "^2.0.3",
"tailwind-merge": "^3.0.2",
- "zod": "^3.24.2"
+ "zod": "^3.24.2",
+ "zustand": "^5.0.4"
},
"devDependencies": {
"@babel/core": "^7.14.5",
@@ -40387,6 +40388,35 @@
"url": "https://github.com/sponsors/colinhacks"
}
},
+ "node_modules/zustand": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.4.tgz",
+ "integrity": "sha512-39VFTN5InDtMd28ZhjLyuTnlytDr9HfwO512Ai4I8ZABCoyAj4F1+sr7sD1jP/+p7k77Iko0Pb5NhgBFDCX0kQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "immer": ">=9.0.6",
+ "react": ">=18.0.0",
+ "use-sync-external-store": ">=1.2.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "use-sync-external-store": {
+ "optional": true
+ }
+ }
+ },
"node_modules/zwitch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
diff --git a/package.json b/package.json
index 6069068..010156d 100644
--- a/package.json
+++ b/package.json
@@ -55,7 +55,8 @@
"sharp": "^0.34.1",
"sonner": "^2.0.3",
"tailwind-merge": "^3.0.2",
- "zod": "^3.24.2"
+ "zod": "^3.24.2",
+ "zustand": "^5.0.4"
},
"devDependencies": {
"@babel/core": "^7.14.5",