Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions src/components/Drawer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable tailwindcss/enforces-shorthand */
import { useEffect, useState } from 'react';
import clsx from 'clsx';
import Image from 'next/image';
Expand All @@ -11,6 +10,8 @@ import { useQueryClient } from '@tanstack/react-query';

interface DrawerProps {
isLoggedIn: boolean;
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
userData: {
email: string | null;
id: string | null;
Expand All @@ -19,9 +20,8 @@ interface DrawerProps {
};
}

export default function Drawer({ isLoggedIn, userData }: DrawerProps) {
export default function Drawer({ isLoggedIn, userData, setIsOpen, isOpen }: DrawerProps) {
const queryClient = useQueryClient();
const [isOpen, setIsOpen] = useState(false);
const [, setIsMobile] = useState(false);

const router = useRouter();
Expand All @@ -36,6 +36,7 @@ export default function Drawer({ isLoggedIn, userData }: DrawerProps) {
if (isLoggedIn) {
await logout(queryClient);
setIsOpen(false);
void router.push('/main');
}
};
const closeDrawer = () => {
Expand All @@ -60,12 +61,12 @@ export default function Drawer({ isLoggedIn, userData }: DrawerProps) {
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
}, [setIsOpen]);

return (
<div className="flex items-center">
<Notification />
<button type="button" onClick={toggleDrawer} className="relative flex h-10 w-10 items-center justify-center">
{isLoggedIn && <Notification />}
<button type="button" onClick={toggleDrawer} className="relative flex size-10 items-center justify-center">
<div className={clsx('absolute transition-all duration-300 ease-in-out', isOpen ? 'rotate-90 opacity-0' : 'rotate-0 opacity-100')}>
<Image src="/icons/menu.svg" alt="메뉴" width={38} height={38} />
</div>
Expand All @@ -85,7 +86,7 @@ export default function Drawer({ isLoggedIn, userData }: DrawerProps) {

<div
className={clsx(
'fixed right-0 top-[60px] z-20 flex h-full min-h-[calc(100vh-60px)] w-full transform flex-col bg-blue-800 shadow-lg transition-transform duration-300 mobile:w-[375px]',
'fixed right-0 top-[60px] z-20 flex size-full min-h-[calc(100vh-60px)] transform flex-col bg-blue-800 shadow-lg transition-transform duration-300 mobile:w-[375px]',
{
'translate-x-full': !isOpen,
'translate-x-0': isOpen,
Expand All @@ -96,12 +97,12 @@ export default function Drawer({ isLoggedIn, userData }: DrawerProps) {
{isLoggedIn ? (
<div className="flex items-center justify-between gap-3 border-b border-blue-400 p-4">
<div className="flex gap-2">
<div>
<Image src={userData.image || '/images/profile.svg'} alt="profile" width={40} height={40} className="size-10 rounded-full object-cover" />
<div className="shadow-custom-md relative size-10 rounded-full bg-slate-50 focus:outline-none">
<Image className="size-10 rounded-full object-cover" src={userData.image || '/icons/person-rounded.png'} alt="프로필" fill />
</div>
<div>
<p className="text-sm font-semibold text-white">{userData.name}</p>
<p className="text-[10px] font-medium text-gray-200">{userData.email}</p>
<div className="max-w-[160px]">
<p className="truncate text-sm font-semibold text-white">{userData.name}</p>
<p className="truncate text-[10px] font-medium text-gray-200">{userData.email}</p>
</div>
</div>
<Link
Expand All @@ -122,7 +123,7 @@ export default function Drawer({ isLoggedIn, userData }: DrawerProps) {
)}
</header>

<section className="px-4 py-4 text-white">
<section className="p-4 text-white">
<p className="px-2 text-xl font-semibold text-white">모임</p>
<div className="flex-grow overflow-y-auto pt-4 text-base font-medium">
<div
Expand Down
2 changes: 1 addition & 1 deletion src/components/shared/GNB/Notification/MobileUI/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface MobileUIProps {
}

export const MobileUI = forwardRef<HTMLDivElement, MobileUIProps>(({ notifications, isLoading, onDropClick, isError }, ref) => (
<div className="fixed inset-0 z-10 bg-white p-10">
<div className="fixed inset-0 z-50 bg-white p-10">
<div className="mb-5 flex items-center">
<button type="button" onClick={onDropClick}>
<ArrowBtn direction="left" color="#fb1c49" className="size-8" />
Expand Down
39 changes: 4 additions & 35 deletions src/components/shared/GNB/Toggle.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useEffect, useRef, useState } from 'react';
import clsx from 'clsx';
import Image from 'next/image';
import Link from 'next/link';
import { logout } from '@/apis/user/postUser';
Expand All @@ -14,7 +13,6 @@ interface ToggleProps {
export default function Toggle({ userData }: ToggleProps) {
const queryClient = useQueryClient();
const [isModalOpen, setIsModalOpen] = useState(false);
const [isProfileHover, setIsProfileHover] = useState(false);
const [animation, setAnimation] = useState<'animate-slide-down' | 'animate-slide-up'>('animate-slide-down');
const dropdownRef = useRef<HTMLDivElement>(null);

Expand All @@ -29,8 +27,6 @@ export default function Toggle({ userData }: ToggleProps) {
setIsModalOpen(false);
}, 300);
};
const handleMouseEnter = () => setIsProfileHover(true);
const handleMouseLeave = () => setIsProfileHover(false);

const handleLogout = async () => {
await logout(queryClient);
Expand All @@ -44,7 +40,6 @@ export default function Toggle({ userData }: ToggleProps) {
useEffect(() => {
const handleResize = () => closeModal();
window.addEventListener('resize', handleResize);

return () => {
window.removeEventListener('resize', handleResize);
};
Expand All @@ -65,42 +60,16 @@ export default function Toggle({ userData }: ToggleProps) {

return (
<div className="relative flex items-center justify-center" ref={dropdownRef}>
{/* 배경 */}
{(isModalOpen || isProfileHover) && (
<div
className={clsx(
'absolute flex size-12 rounded-full transition-all duration-100 ease-in-out',
isModalOpen ? (isProfileHover ? 'bg-gray-50 shadow-md' : 'shadow-md') : 'bg-gray-50 shadow-md',
)}
onClick={isModalOpen ? closeModal : openModal}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
/>
)}

{/* 프로필 */}
<button
type="button"
onClick={isModalOpen ? closeModal : openModal}
className="relative z-10"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<div className="rounded-full focus:outline-none">
<Image
className="size-10 rounded-full"
src={userData.image || '/images/profile.svg'}
alt="프로필"
width={40}
height={40}
style={{ objectFit: 'cover' }}
/>
<button type="button" onClick={isModalOpen ? closeModal : openModal} className="relative z-10">
<div className="shadow-custom-md size-10 rounded-full bg-slate-50 focus:outline-none">
<Image className="relative size-10 rounded-full object-cover" src={userData.image || '/icons/person-rounded.png'} alt="프로필" fill />
</div>
</button>

{/* 모달 */}
{isModalOpen && (
<div className={`absolute -right-9 top-14 z-50 flex w-32 flex-col gap-1 rounded-lg bg-white p-2 drop-shadow-2xl transition-transform ${animation}`}>
<div className={`absolute -right-5 top-14 z-50 flex w-32 flex-col gap-1 rounded-lg bg-white p-2 drop-shadow-2xl transition-transform ${animation}`}>
<Link href="/mypage" onClick={() => setIsModalOpen(false)} className="rounded-lg p-1 transition-colors duration-100 hover:bg-gray-50">
<div className="flex flex-row content-between items-center">
<Image src="/icons/person.svg" className="size-6" alt="프로필" width={24} height={24} />
Expand Down
20 changes: 11 additions & 9 deletions src/components/shared/GNB/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import clsx from 'clsx';
import Image from 'next/image';
import Link from 'next/link';
Expand All @@ -19,17 +19,22 @@ export default function GNB() {
const isLoggedIn = userStore((state) => state.isLoggedIn);
const logoutStore = userStore((state) => state.logout);
const login = userStore((state) => state.login);
const [isOpen, setIsOpen] = useState(false);

const userinfo = userStore((state) => state.user);
const updateUser = userStore((state) => state.updateUser);

const { data, isPending, isError, error } = useQuery({
const { data } = useQuery({
queryKey: ['queryUserInfo'],
queryFn: getUserInfo,
staleTime: 1000 * 60 * 5,
gcTime: 1000 * 60 * 6,
});

function toggleDrawer() {
if (isOpen) {
setIsOpen(false);
}
}
useEffect(() => {
const accessToken: string | null = localStorage.getItem('accessToken');
if (data && accessToken) {
Expand All @@ -46,14 +51,11 @@ export default function GNB() {
}
}, [login, data, logoutStore, queryClient, updateUser]);

if (isPending) return <div>Loading...</div>;
if (isError) return <div>Error: {error.message}</div>;

return (
<nav className="fixed top-0 z-[9999] w-full bg-white">
<div className="mx-auto flex h-[60px] max-w-[1500px] items-center justify-between px-4 tablet:px-6 pc:px-10">
<div className="mx-auto flex h-[60px] max-w-[1500px] items-center justify-between px-4 tablet:px-6 pc:px-10" onClick={toggleDrawer}>
<div className="absolute left-1/2 -translate-x-1/2 transform">
<Link href="/">
<Link href="/main">
<Image src="/logo/logo.png" alt="로고" width={73} height={35} />
</Link>
</div>
Expand Down Expand Up @@ -93,7 +95,7 @@ export default function GNB() {
</div>

<div className="-mr-2 flex flex-grow justify-end tablet:-mr-4 tablet:hidden">
<Drawer isLoggedIn={isLoggedIn ?? false} userData={userinfo} />
<Drawer isLoggedIn={isLoggedIn ?? false} userData={userinfo} setIsOpen={setIsOpen} isOpen={isOpen} />
</div>
<div className="hidden w-[154px] flex-grow tablet:flex tablet:justify-end">
{isLoggedIn ? (
Expand Down