feat: migrate header component
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 159 KiB |
@@ -0,0 +1,143 @@
|
|||||||
|
'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';
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<header
|
||||||
|
className={cn(
|
||||||
|
'sticky top-0 z-50 w-full transition-all duration-300',
|
||||||
|
isScrolled
|
||||||
|
? 'bg-background/80 backdrop-blur-md border-b shadow-sm'
|
||||||
|
: 'bg-transparent'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="container flex h-16 items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<div className="relative overflow-hidden rounded">
|
||||||
|
<Image
|
||||||
|
src="/logo.png"
|
||||||
|
alt="IMPHNEN Logo"
|
||||||
|
width={64}
|
||||||
|
height={64}
|
||||||
|
className="object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Desktop Navigation */}
|
||||||
|
<nav className="hidden md:flex items-center gap-8">
|
||||||
|
<Link href="#fitur" className="text-sm font-medium relative group">
|
||||||
|
<span className="transition-colors hover:text-primary">Fitur</span>
|
||||||
|
<span className="absolute -bottom-1 left-0 w-0 h-0.5 bg-primary transition-all duration-300 group-hover:w-full"></span>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#komunitas"
|
||||||
|
className="text-sm font-medium relative group"
|
||||||
|
>
|
||||||
|
<span className="transition-colors hover:text-primary">
|
||||||
|
Komunitas
|
||||||
|
</span>
|
||||||
|
<span className="absolute -bottom-1 left-0 w-0 h-0.5 bg-primary transition-all duration-300 group-hover:w-full"></span>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#sumber-belajar"
|
||||||
|
className="text-sm font-medium relative group"
|
||||||
|
>
|
||||||
|
<span className="transition-colors hover:text-primary">
|
||||||
|
Sumber Belajar
|
||||||
|
</span>
|
||||||
|
<span className="absolute -bottom-1 left-0 w-0 h-0.5 bg-primary transition-all duration-300 group-hover:w-full"></span>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#testimoni"
|
||||||
|
className="text-sm font-medium relative group"
|
||||||
|
>
|
||||||
|
<span className="transition-colors hover:text-primary">
|
||||||
|
Testimoni
|
||||||
|
</span>
|
||||||
|
<span className="absolute -bottom-1 left-0 w-0 h-0.5 bg-primary transition-all duration-300 group-hover:w-full"></span>
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<Button className="hidden md:flex bg-gradient-to-r from-primary to-blue-400 hover:from-primary/90 hover:to-blue-400/90 transition-all duration-300">
|
||||||
|
Gabung Discord
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
{/* Mobile Menu Button */}
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
className="md:hidden"
|
||||||
|
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||||
|
>
|
||||||
|
{mobileMenuOpen ? (
|
||||||
|
<XIcon className="h-6 w-6" />
|
||||||
|
) : (
|
||||||
|
<MenuIcon className="h-6 w-6" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Menu */}
|
||||||
|
{mobileMenuOpen && (
|
||||||
|
<div className="md:hidden border-t bg-background/95 backdrop-blur-md">
|
||||||
|
<nav className="container flex flex-col py-4 text-center">
|
||||||
|
<Link
|
||||||
|
href="#fitur"
|
||||||
|
className="py-3 text-sm font-medium border-b border-border/50"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
Fitur
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#komunitas"
|
||||||
|
className="py-3 text-sm font-medium border-b border-border/50"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
Komunitas
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#sumber-belajar"
|
||||||
|
className="py-3 text-sm font-medium border-b border-border/50"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
Sumber Belajar
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#testimoni"
|
||||||
|
className="py-3 text-sm font-medium"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
Testimoni
|
||||||
|
</Link>
|
||||||
|
<Button className="mt-4 bg-gradient-to-r from-primary to-blue-400 hover:from-primary/90 hover:to-blue-400/90">
|
||||||
|
Gabung Discord
|
||||||
|
</Button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
import { type Metadata } from 'next';
|
import { type Metadata } from 'next';
|
||||||
|
import { Inter } from 'next/font/google';
|
||||||
import '../styles/globals.css';
|
import '../styles/globals.css';
|
||||||
|
|
||||||
|
const inter = Inter({ subsets: ['latin'] });
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'IMPHNEN',
|
title: 'IMPHNEN - Ingin Menjadi Programmer Handal?',
|
||||||
|
description: 'Komunitas belajar programming untuk semua level',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
@@ -12,7 +16,7 @@ export default function RootLayout({
|
|||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="id" suppressHydrationWarning>
|
<html lang="id" suppressHydrationWarning>
|
||||||
<body>{children}</body>
|
<body className={inter.className}>{children}</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Button } from '@imphnen-frontend-service/shadcn-ui/atoms';
|
import { Header } from './_components/header';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="flex min-h-screen flex-col">
|
||||||
<h1 className="text-2xl underline">Hello World</h1>
|
<Header />
|
||||||
<Button>Click Me</Button>
|
<main className="flex-1"></main>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+10
@@ -13,6 +13,7 @@
|
|||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"lucide-react": "^0.503.0",
|
"lucide-react": "^0.503.0",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"tailwind-merge": "^3.2.0",
|
"tailwind-merge": "^3.2.0",
|
||||||
"tailwindcss": "^4.1.4"
|
"tailwindcss": "^4.1.4"
|
||||||
},
|
},
|
||||||
@@ -1463,6 +1464,15 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-icons": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.40.0",
|
"version": "4.40.0",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"lucide-react": "^0.503.0",
|
"lucide-react": "^0.503.0",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"tailwind-merge": "^3.2.0",
|
"tailwind-merge": "^3.2.0",
|
||||||
"tailwindcss": "^4.1.4"
|
"tailwindcss": "^4.1.4"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { LuMenu as MenuIcon, LuX as XIcon } from 'react-icons/lu';
|
||||||
|
|
||||||
|
export { MenuIcon, XIcon };
|
||||||
@@ -1 +1,2 @@
|
|||||||
export * from './button';
|
export * from './button';
|
||||||
|
export * from './icons';
|
||||||
|
|||||||
@@ -42,15 +42,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--radius: 0.625rem;
|
--radius: 1rem;
|
||||||
--background: oklch(1 0 0);
|
--background: oklch(1 0 0);
|
||||||
--foreground: oklch(0.141 0.005 285.823);
|
--foreground: oklch(0.141 0.005 285.823);
|
||||||
--card: oklch(1 0 0);
|
--card: oklch(1 0 0);
|
||||||
--card-foreground: oklch(0.141 0.005 285.823);
|
--card-foreground: oklch(0.141 0.005 285.823);
|
||||||
--popover: oklch(1 0 0);
|
--popover: oklch(1 0 0);
|
||||||
--popover-foreground: oklch(0.141 0.005 285.823);
|
--popover-foreground: oklch(0.141 0.005 285.823);
|
||||||
--primary: oklch(0.21 0.006 285.885);
|
--primary: oklch(0.623 0.214 259.815);
|
||||||
--primary-foreground: oklch(0.985 0 0);
|
--primary-foreground: oklch(0.97 0.014 254.604);
|
||||||
--secondary: oklch(0.967 0.001 286.375);
|
--secondary: oklch(0.967 0.001 286.375);
|
||||||
--secondary-foreground: oklch(0.21 0.006 285.885);
|
--secondary-foreground: oklch(0.21 0.006 285.885);
|
||||||
--muted: oklch(0.967 0.001 286.375);
|
--muted: oklch(0.967 0.001 286.375);
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
--destructive: oklch(0.577 0.245 27.325);
|
--destructive: oklch(0.577 0.245 27.325);
|
||||||
--border: oklch(0.92 0.004 286.32);
|
--border: oklch(0.92 0.004 286.32);
|
||||||
--input: oklch(0.92 0.004 286.32);
|
--input: oklch(0.92 0.004 286.32);
|
||||||
--ring: oklch(0.705 0.015 286.067);
|
--ring: oklch(0.623 0.214 259.815);
|
||||||
--chart-1: oklch(0.646 0.222 41.116);
|
--chart-1: oklch(0.646 0.222 41.116);
|
||||||
--chart-2: oklch(0.6 0.118 184.704);
|
--chart-2: oklch(0.6 0.118 184.704);
|
||||||
--chart-3: oklch(0.398 0.07 227.392);
|
--chart-3: oklch(0.398 0.07 227.392);
|
||||||
@@ -68,12 +68,12 @@
|
|||||||
--chart-5: oklch(0.769 0.188 70.08);
|
--chart-5: oklch(0.769 0.188 70.08);
|
||||||
--sidebar: oklch(0.985 0 0);
|
--sidebar: oklch(0.985 0 0);
|
||||||
--sidebar-foreground: oklch(0.141 0.005 285.823);
|
--sidebar-foreground: oklch(0.141 0.005 285.823);
|
||||||
--sidebar-primary: oklch(0.21 0.006 285.885);
|
--sidebar-primary: oklch(0.623 0.214 259.815);
|
||||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
--sidebar-primary-foreground: oklch(0.97 0.014 254.604);
|
||||||
--sidebar-accent: oklch(0.967 0.001 286.375);
|
--sidebar-accent: oklch(0.967 0.001 286.375);
|
||||||
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
|
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
|
||||||
--sidebar-border: oklch(0.92 0.004 286.32);
|
--sidebar-border: oklch(0.92 0.004 286.32);
|
||||||
--sidebar-ring: oklch(0.705 0.015 286.067);
|
--sidebar-ring: oklch(0.623 0.214 259.815);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
@@ -83,8 +83,8 @@
|
|||||||
--card-foreground: oklch(0.985 0 0);
|
--card-foreground: oklch(0.985 0 0);
|
||||||
--popover: oklch(0.21 0.006 285.885);
|
--popover: oklch(0.21 0.006 285.885);
|
||||||
--popover-foreground: oklch(0.985 0 0);
|
--popover-foreground: oklch(0.985 0 0);
|
||||||
--primary: oklch(0.92 0.004 286.32);
|
--primary: oklch(0.546 0.245 262.881);
|
||||||
--primary-foreground: oklch(0.21 0.006 285.885);
|
--primary-foreground: oklch(0.379 0.146 265.522);
|
||||||
--secondary: oklch(0.274 0.006 286.033);
|
--secondary: oklch(0.274 0.006 286.033);
|
||||||
--secondary-foreground: oklch(0.985 0 0);
|
--secondary-foreground: oklch(0.985 0 0);
|
||||||
--muted: oklch(0.274 0.006 286.033);
|
--muted: oklch(0.274 0.006 286.033);
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
--destructive: oklch(0.704 0.191 22.216);
|
--destructive: oklch(0.704 0.191 22.216);
|
||||||
--border: oklch(1 0 0 / 10%);
|
--border: oklch(1 0 0 / 10%);
|
||||||
--input: oklch(1 0 0 / 15%);
|
--input: oklch(1 0 0 / 15%);
|
||||||
--ring: oklch(0.552 0.016 285.938);
|
--ring: oklch(0.488 0.243 264.376);
|
||||||
--chart-1: oklch(0.488 0.243 264.376);
|
--chart-1: oklch(0.488 0.243 264.376);
|
||||||
--chart-2: oklch(0.696 0.17 162.48);
|
--chart-2: oklch(0.696 0.17 162.48);
|
||||||
--chart-3: oklch(0.769 0.188 70.08);
|
--chart-3: oklch(0.769 0.188 70.08);
|
||||||
@@ -102,12 +102,12 @@
|
|||||||
--chart-5: oklch(0.645 0.246 16.439);
|
--chart-5: oklch(0.645 0.246 16.439);
|
||||||
--sidebar: oklch(0.21 0.006 285.885);
|
--sidebar: oklch(0.21 0.006 285.885);
|
||||||
--sidebar-foreground: oklch(0.985 0 0);
|
--sidebar-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
--sidebar-primary: oklch(0.546 0.245 262.881);
|
||||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
--sidebar-primary-foreground: oklch(0.379 0.146 265.522);
|
||||||
--sidebar-accent: oklch(0.274 0.006 286.033);
|
--sidebar-accent: oklch(0.274 0.006 286.033);
|
||||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-border: oklch(1 0 0 / 10%);
|
--sidebar-border: oklch(1 0 0 / 10%);
|
||||||
--sidebar-ring: oklch(0.552 0.016 285.938);
|
--sidebar-ring: oklch(0.488 0.243 264.376);
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
@@ -118,3 +118,17 @@
|
|||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* https://github.com/tailwindlabs/tailwindcss/issues/13129 */
|
||||||
|
.container {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding-left: 2rem;
|
||||||
|
padding-right: 2rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
@media (min-width: 1536px) {
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user