Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
21 changes: 4 additions & 17 deletions components/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import useOutsideClick from 'hooks/useOutsideClick';
import { useRef, useState } from 'react';

import Menu from './Menu';

Expand Down Expand Up @@ -32,24 +33,10 @@ export default function Dropdown({
};

//외부 클릭시 드롭다운 닫기
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
dropdownRef.current &&
!dropdownRef.current.contains(event.target as Node)
) {
setIsOpen(false);
}
};

document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
useOutsideClick(dropdownRef, () => setIsOpen(false));

return (
<div ref={dropdownRef}>
<div className="relative" ref={dropdownRef}>
<button
onClick={() => setIsOpen(!isOpen)}
className={`${dropdownSize} flex items-center justify-between rounded-xl border border-gray-300 bg-background px-5 py-3.5 text-14 leading-none text-gray-400 hover:border-green-200 focus:ring-1 focus:ring-green-200`}
Expand Down
135 changes: 135 additions & 0 deletions components/GNB.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { useRouter } from 'next/router';
import { useEffect, useRef, useState } from 'react';

import useOutsideClick from '../hooks/useOutsideClick';
import Menu from './Menu';

export default function GNB() {
const [isLoggedIn, setIsLoggedIn] = useState(false); // 임시 로그인 상태(추후 업데이트예정)
const [isOpen, setIsOpen] = useState(false);
const [isMobile, setIsMobile] = useState(false);
const profileImage = null; // 추후 업데이트 예정
const [profileMenu, setProfileMenu] = useState<string[]>([]);
const router = useRouter();
const profileMenuRef = useRef<HTMLDivElement>(null);

const handleLogin = () => {
setIsLoggedIn(true);
};

const handleLogout = () => {
setIsLoggedIn(false);
};

const handleProfileMenu = (option: string) => {
if (option === '위키목록') {
router.push('/wikilist');
} else if (option === '자유게시판') {
router.push('/boards');
} else if (option === '마이페이지') {
router.push('/mypage');
} else if (option === '로그인') {
handleLogin(); // 추후 업데이트 예정
} else if (option === '로그아웃') {
handleLogout();
}
};

useEffect(() => {
const checkMobile = () => setIsMobile(window.innerWidth <= 767);
checkMobile();
window.addEventListener('resize', checkMobile);

return () => {
window.removeEventListener('resize', checkMobile);
};
}, []);

const updateProfileMenu = () => {
if (!isLoggedIn && isMobile) {
return ['로그인', '위키목록', '자유게시판'];
} else if (isLoggedIn && !isMobile) {
return ['마이페이지', '로그아웃'];
} else if (isLoggedIn && isMobile) {
return ['위키목록', '자유게시판', '알림', '마이페이지', '로그아웃'];
} else return [];
};

useEffect(() => {
setProfileMenu(updateProfileMenu());
}, [isLoggedIn, isMobile]);

useOutsideClick(profileMenuRef, () => setIsOpen(false));

return (
<div
ref={profileMenuRef}
className="z-100 fixed left-0 top-0 flex h-20 w-full items-center justify-between bg-background px-20 py-5 shadow-custom"
>
<div className="flex items-center gap-10">
<button onClick={() => router.push('/')}>
<img src="/logo.svg" alt="위키드 로고" />
</button>
<button className="mo:hidden" onClick={() => router.push('/wikilist')}>
위키목록
</button>
<button className="mo:hidden" onClick={() => router.push('/boards')}>
자유게시판
</button>
</div>

{isLoggedIn ? (
<div className="flex items-center gap-5">
{!isMobile && (
<button>
<img src="/icon/icon-alarm.svg" alt="알림 아이콘" />
</button>
)}
<button className="relative" onClick={() => setIsOpen(!isOpen)}>
<img
src={profileImage || '/icon/icon-profile.svg'}
className="mo:hidden"
alt="프로필 아이콘"
/>
<img
src="/icon/icon-menu.svg"
className="hidden mo:block"
alt="메뉴 아이콘"
/>

{isOpen && (
<Menu
options={profileMenu}
onSelect={handleProfileMenu}
menuSize="w-28"
/>
)}
</button>
</div>
) : (
<>
{isMobile ? (
<button
onClick={() => setIsOpen(!isOpen)}
className="relative hidden mo:block"
>
<img src="/icon/icon-menu.svg" alt="메뉴 아이콘" />

{isOpen && (
<Menu
options={profileMenu}
onSelect={handleProfileMenu}
menuSize="w-28"
/>
)}
</button>
) : (
<button onClick={handleLogin} className="mo:hidden">
로그인
</button> // 추후 업데이트 예정
)}
</>
)}
</div>
);
}
2 changes: 1 addition & 1 deletion components/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface MenuProps {
export default function Menu({ options, onSelect, menuSize }: MenuProps) {
return (
<ul
className={`${menuSize} absolute z-10 mt-2 rounded-xl border border-gray-300 bg-background p-1 text-14 shadow-custom`}
className={`${menuSize} absolute right-1/2 z-10 mt-2 translate-x-1/2 rounded-xl border border-gray-300 bg-background p-1 text-14 shadow-custom`}
>
{options.map((option, index) => (
<li
Expand Down
20 changes: 20 additions & 0 deletions hooks/useOutsideClick.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useEffect } from 'react';

const useOutsideClick = (
ref: React.RefObject<HTMLElement | null>,
callback: () => void
) => {
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (ref.current && !ref.current.contains(event.target as Node)) {
callback();
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [ref, callback]);
};

export default useOutsideClick;
9 changes: 9 additions & 0 deletions pages/test/GNB/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import GNB from '@/components/GNB';

export default function GNBtest() {
return (
<div>
<GNB />
</div>
);
}
10 changes: 4 additions & 6 deletions pages/test/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useState } from 'react';

import Button from '@/components/Button';
import Dropdown from '@/components/Dropdown';
import LinkBar from '@/components/LinkBar';
Expand Down Expand Up @@ -61,9 +63,7 @@ export default function Test() {
<tbody>
<tr>
<td className={commonCellClass}>inputfield</td>
<td className={commonRowClass}>
<Signup />
</td>
<td className={commonRowClass}>{/* <Signup /> */}</td>
</tr>
<tr className="border-b border-gray-300">
<td className={commonCellClass}>Button</td>
Expand Down Expand Up @@ -98,9 +98,7 @@ export default function Test() {
<LinkBar link="https://www.google.com" />

<td className={commonCellClass}>inputfield</td>
<td className={commonRowClass}>
<Signup />
</td>
<td className={commonRowClass}>{/* <Signup /> */}</td>
</td>
</tr>
<tr className="border-b border-gray-300">
Expand Down
4 changes: 4 additions & 0 deletions public/icon/icon-alarm.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/icon/icon-menu.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/icon/icon-profile.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions public/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading