feat: initial commit
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
import { MenuBurgerButton } from '@/ui/components/internal/header/mobile-header/utils/menu-burguer-button';
|
||||
import ThemeToggle from '@/ui/components/internal/theme-toggle';
|
||||
|
||||
export type BaseMobileHeaderProps = {
|
||||
active?: boolean;
|
||||
onStateChange?: (value: boolean) => void;
|
||||
};
|
||||
|
||||
export const BaseMobileHeader = ({
|
||||
active,
|
||||
onStateChange,
|
||||
}: BaseMobileHeaderProps) => {
|
||||
return (
|
||||
<div className='flex items-center space-x-4'>
|
||||
<ThemeToggle></ThemeToggle>
|
||||
<MenuBurgerButton
|
||||
state={active ?? false}
|
||||
onStateChange={onStateChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
'use client';
|
||||
|
||||
import { getSessionData } from '@/lib/session/session-storage';
|
||||
import { BaseMobileHeader } from '@/ui/components/internal/header/mobile-header/base-mobile-header';
|
||||
import { HeaderSlider } from '@/ui/components/internal/header/mobile-header/utils/header-slider';
|
||||
import { UserButton } from '@/ui/components/internal/user-profile/user-profile-button';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import Link from 'next/link';
|
||||
import { useState } from 'react';
|
||||
|
||||
export const DynamicMobileHeader = () => {
|
||||
const { data: sessionData } = useQuery({
|
||||
queryKey: ['sessionData'],
|
||||
queryFn: async () => {
|
||||
return await getSessionData();
|
||||
},
|
||||
});
|
||||
const user = sessionData?.user;
|
||||
|
||||
const [isNavigationState, setNavigationState] = useState(false);
|
||||
|
||||
const links = [
|
||||
{ href: '/home', label: 'Home', condition: true },
|
||||
{ href: '/about', label: 'About', condition: true },
|
||||
{ href: '/admin', label: 'Admin', condition: !!user },
|
||||
];
|
||||
|
||||
const userButton = !!user ? <UserButton user={user} /> : <div />;
|
||||
|
||||
return (
|
||||
<>
|
||||
<BaseMobileHeader
|
||||
active={isNavigationState}
|
||||
onStateChange={(value: boolean) => setNavigationState(value)}
|
||||
/>
|
||||
|
||||
<HeaderSlider
|
||||
isOpen={isNavigationState}
|
||||
onClose={() => setNavigationState(false)}
|
||||
>
|
||||
<div className='h-full flex flex-col items-center justify-center'>
|
||||
<div className='h-2/3 flex flex-col items-start justify-around'>
|
||||
{links
|
||||
.filter((link) => link.condition)
|
||||
.map((link) => (
|
||||
<Link
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
className='text-xl font-normal transition-colors hover:font-bold hover:text-primary'
|
||||
>
|
||||
{link.label}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<div className='h-1/3 flex items-center space-x-4 mt-4'>
|
||||
{userButton}
|
||||
</div>
|
||||
</div>
|
||||
</HeaderSlider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
import { BaseMobileHeader } from '@/ui/components/internal/header/mobile-header/base-mobile-header';
|
||||
|
||||
export const StaticMobileHeader = () => {
|
||||
return <BaseMobileHeader active={false} />;
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
export const HeaderSlider = ({
|
||||
children,
|
||||
isOpen,
|
||||
onClose,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
isOpen: boolean;
|
||||
onClose?: () => void;
|
||||
}>) => {
|
||||
const clickedOutside = () => {
|
||||
if (onClose) onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`absolute top-[8dvh] right-0 flex col w-full duration-300
|
||||
${isOpen ? '' : 'delay-300 translate-x-[102vw]'}`}
|
||||
>
|
||||
<div
|
||||
className={`page-height w-1/2 transition-all ease-in-out duration-300 ${
|
||||
isOpen ? 'delay-300 bg-black/60' : 'bg-black/0'
|
||||
}`}
|
||||
onClick={clickedOutside}
|
||||
/>
|
||||
{/* Only slide the content panel */}
|
||||
<div className={`bg-background page-height w-1/2`}>{children}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
'use client';
|
||||
|
||||
type MenuBurgerButtonProps = {
|
||||
state: boolean;
|
||||
onStateChange?: (value: boolean) => void;
|
||||
};
|
||||
|
||||
export const MenuBurgerButton = ({
|
||||
state,
|
||||
onStateChange,
|
||||
}: MenuBurgerButtonProps) => {
|
||||
state = state ?? false;
|
||||
|
||||
// This function is called when the button is clicked
|
||||
const handleClick = () => {
|
||||
if (onStateChange) onStateChange(!state);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className='flex flex-col md:hidden w-10 h-10 justify-center items-center cursor-pointer relative'
|
||||
onClick={handleClick}
|
||||
>
|
||||
<span
|
||||
className={`w-8 h-[4px] bg-primary rounded transition-all duration-200 ${
|
||||
state ? 'opacity-0' : 'opacity-100'
|
||||
}`}
|
||||
/>
|
||||
<span
|
||||
className={`absolute w-8 h-[4px] bg-primary rounded transition-all duration-200 ${
|
||||
state ? 'rotate-45' : '-translate-y-[10px]'
|
||||
}`}
|
||||
/>
|
||||
<span
|
||||
className={`absolute w-8 h-[4px] bg-primary rounded transition-all duration-200 ${
|
||||
state ? '-rotate-45' : 'translate-y-[10px]'
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user