feat(landing): slicing navigation bar
This commit is contained in:
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 351 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 511 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
export function HeroSection() {
|
||||||
|
return (
|
||||||
|
<section className="relative w-full bg-primary-50 md:py-32 lg:py-40">
|
||||||
|
<div>Hero Section</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
import { FC, ReactElement } from 'react';
|
import { FC, ReactElement } from 'react';
|
||||||
|
import { HeroSection } from './_components/hero-section';
|
||||||
|
|
||||||
export const Components: FC = (): ReactElement => {
|
export const Components: FC = (): ReactElement => {
|
||||||
return <>Hallo</>;
|
return (
|
||||||
|
<HeroSection />
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Components;
|
export default Components;
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import { CloseOutlined, MenuOutlined } from "@ant-design/icons";
|
||||||
|
import { Button } from "@imphnen-frontend-service/ui/atoms";
|
||||||
|
import { cn } from "@imphnen-frontend-service/utils";
|
||||||
|
import { FC, useState } from "react";
|
||||||
|
import { Link, useLocation } from "react-router-dom";
|
||||||
|
import { For } from "../../_components/logic/for";
|
||||||
|
import { Show } from "../../_components/logic/show";
|
||||||
|
|
||||||
|
const MENUS: { label: string; href: string }[] = [
|
||||||
|
{ label: "Home", href: "/" },
|
||||||
|
{ label: 'Mentoring', href: '/mentoring' },
|
||||||
|
{ label: 'Resources', href: '/resources' },
|
||||||
|
{ label: 'Articles', href: '/articles' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export const Header: FC = () => {
|
||||||
|
const location = useLocation();
|
||||||
|
const [expandMenu, setExpandMenu] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-primary-50 w-full px-8 pt-8 top-0 z-50 md:px-[60px] md:pt-[60px] lg:px-20 sticky">
|
||||||
|
<header
|
||||||
|
className="bg-white shadow-lg rounded-lg h-12 flex justify-between w-full max-w-7xl xl:mx-auto md:h-[60px] lg:h-[71px]"
|
||||||
|
aria-roledescription="nav"
|
||||||
|
>
|
||||||
|
<div className="flex w-full items-center justify-between p-4 md:px-8 md:py-2.5">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<img
|
||||||
|
src="/logos/simple.svg"
|
||||||
|
alt="IMPHNEN Logo"
|
||||||
|
className="h-8 md:h-10 lg:h-[52px] w-auto"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col items-center py-2 fixed top-24 bg-white shadow-lg rounded-lg transition-all duration-300",
|
||||||
|
"md:top-32 lg:static lg:py-0 lg:flex-row lg:bg-transparent lg:shadow-none lg:gap-x-4",
|
||||||
|
!expandMenu ? "-right-96" : "right-8 md:right-[60px]"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<For data={MENUS}>
|
||||||
|
{(menu) => (
|
||||||
|
<Button
|
||||||
|
key={menu.label}
|
||||||
|
type="button"
|
||||||
|
variant="text"
|
||||||
|
className={cn(
|
||||||
|
"px-10 py-1.5 text-neutral-300 hover:text-neutral-400 lg:px-2.5 lg:py-2",
|
||||||
|
location.pathname === menu.href && "text-primary-500 hover:text-primary-500"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Link to={menu.href}>{menu.label}</Link>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
<Button type="button" className="px-12 py-1 md:hidden">Login</Button>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Button type="button" className="px-5 py-2 hidden lg:block">Login</Button>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="text"
|
||||||
|
className={cn("transition-transform duration-300 rotate-0 lg:hidden", expandMenu && "rotate-90")}
|
||||||
|
onClick={() => setExpandMenu(prev => !prev)}
|
||||||
|
>
|
||||||
|
<Show condition={!expandMenu} fallback={<CloseOutlined />}>
|
||||||
|
<MenuOutlined />
|
||||||
|
</Show>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { Outlet } from "react-router-dom";
|
||||||
|
import { Header } from "./_components/header";
|
||||||
|
|
||||||
|
export default function Layout() {
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-screen flex-col">
|
||||||
|
<Header />
|
||||||
|
<main className="flex-1">
|
||||||
|
<Outlet />
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
export interface ForProps<T, U> {
|
||||||
|
data: readonly T[]
|
||||||
|
children: (item: T, index: number) => U | null
|
||||||
|
fallback?: React.ReactNode | null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A functional component that renders a list of children components from a given
|
||||||
|
* array of data.
|
||||||
|
*
|
||||||
|
* @param data - The array of data to render
|
||||||
|
* @param children - A function that takes the current item and index and returns
|
||||||
|
* the child component to render
|
||||||
|
* @param fallback - An optional fallback component to render when the data is empty
|
||||||
|
*
|
||||||
|
* @returns An array of rendered child components if the data is not empty, otherwise
|
||||||
|
* the fallback component if it is provided, null otherwise
|
||||||
|
*/
|
||||||
|
export function For<T, U extends React.JSX.Element>({
|
||||||
|
data,
|
||||||
|
children,
|
||||||
|
fallback = null
|
||||||
|
}: ForProps<T, U>): (U | null)[] | React.ReactNode | null {
|
||||||
|
if (!Array.isArray(data) || !data?.length) return fallback
|
||||||
|
|
||||||
|
return data.map((item, idx) => children(item, idx))
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
export interface ShowProps {
|
||||||
|
condition: boolean
|
||||||
|
children: React.ReactNode
|
||||||
|
fallback?: React.ReactNode | null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conditionally renders the `children` component if `condition` is true. If
|
||||||
|
* `condition` is false, renders the `fallback` component instead.
|
||||||
|
*
|
||||||
|
* If `fallback` is `null`, renders nothing.
|
||||||
|
*
|
||||||
|
* @param condition - The condition to check
|
||||||
|
* @param children - The component to render if `condition` is true
|
||||||
|
* @param fallback - The component to render if `condition` is false
|
||||||
|
*/
|
||||||
|
export function Show({ condition, children, fallback = null }: ShowProps) {
|
||||||
|
return condition ? children : fallback
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user