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
3 changes: 2 additions & 1 deletion src/app/mydashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import Sidebar from '@/components/Sidebar/Sidebar';
import { ReactNode } from 'react';
import Header from '@/components/dashboard-header/Header';

export default function Layout({ children }: { children: ReactNode }) {
return (
<div className='flex'>
<Sidebar />

<Header showCrown showSetting showMembers showProfile />
<main className='flex-1'>{children}</main>
</div>
);
Expand Down
72 changes: 72 additions & 0 deletions src/components/dashboard-header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use client';

import React from 'react';
import { usePathname } from 'next/navigation';
import Image from 'next/image';
import Crown from '@/assets/icons/crown.svg';
import Title from './Title';
import SettingBtn from './SettingBtn';
import Members from './Members';
import Profile from './Profile';

interface HeaderProps {
title?: string;
showCrown?: boolean;
showSetting?: boolean;
showMembers?: boolean;
showProfile?: boolean;
}

const titleMap: { [key: string]: string } = {
'/mydashboard': '내 대시보드',
'/mypage': '계정관리',
};

// TODO : API 연동 이후 추가 작업 예정, 우선 mock 데이터로 집어넣어놨습니다.
interface UserType {
nickname: string;
profileImageUrl: string;
}

const mockUsers: UserType[] = [
{ nickname: '배유철', profileImageUrl: 'B' },
{ nickname: '김철수', profileImageUrl: 'K' },
{ nickname: '이영희', profileImageUrl: 'L' },
];

export default function Header({ showCrown = false, showSetting = false, showMembers = false, showProfile = false }: HeaderProps) {
const pathname = usePathname();
const title = titleMap[pathname] || '내 대시보드';
const handleSettingClick = () => {
console.log('관리 버튼 클릭');
// TODO : 디버깅 용도 console.log API 기능 구현 후 수정 예정
};

const handleInviteClick = () => {
console.log('초대 버튼 클릭');
// TODO : 디버깅 용도 console.log API 기능 구현 후 수정 예정
};

const handleProfileClick = () => {
console.log('프로필 버튼 클릭');
// TODO : 디버깅 용도 console.log API 기능 구현 후 수정 예정
};

return (
<header className='flex h-[60px] w-full items-center justify-between border-b-2 border-gray-20 py-[15.5px] sm:h-[70px] sm:px-[40px]'>
{/* 왼쪽 제목 그룹 */}
<div className='flex items-center gap-[8px]'>
<Title title={title} />
{showCrown && <Image src={Crown} alt='방장 표시' width={20} height={16} className='hidden lg:block' />}
</div>
{/* 오른쪽 버튼 그룹 */}
<div className='flex items-center'>
<div className='flex items-center gap-[16px] border-r border-gray-30 pr-[12px] sm:gap-[32px] sm:pr-[24px] md:gap-[40px] md:pr-[32px]'>
{showSetting && <SettingBtn onSettingClick={handleSettingClick} onInviteClick={handleInviteClick} />}
{showMembers && <Members users={mockUsers} />}
</div>
{showProfile && <Profile nickname={mockUsers[0].nickname} profileImageUrl={mockUsers[0].profileImageUrl} onClick={handleProfileClick} />}
</div>
</header>
);
}
17 changes: 17 additions & 0 deletions src/components/dashboard-header/Members.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';

interface MembersProps {
users: { profileImageUrl: string }[];
}

export default function Members({ users }: MembersProps) {
return (
<div className='flex'>
{users.map((user, index) => (
<span key={index} className='-ml-[8px] flex h-[34px] w-[34px] items-center justify-center rounded-full border-2 border-white bg-green-30 text-white sm:h-[38px] sm:w-[38px]'>
{user.profileImageUrl}
</span>
))}
</div>
);
}
16 changes: 16 additions & 0 deletions src/components/dashboard-header/Profile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';

interface ProfileProps {
nickname: string;
profileImageUrl: string;
onClick: () => void;
}

export default function Profile({ nickname, profileImageUrl, onClick }: ProfileProps) {
return (
<button onClick={onClick} className='mr-[40px] flex items-center justify-center gap-[12px] pl-[12px] sm:pl-[24px] md:pl-[32px]'>
<span className='flex h-[34px] w-[34px] items-center justify-center rounded-full border-2 border-white bg-green-30 text-white sm:h-[38px] sm:w-[38px]'>{profileImageUrl}</span>
<span className='hidden text-[16px] md:block'>{nickname}</span>
</button>
);
}
30 changes: 30 additions & 0 deletions src/components/dashboard-header/SettingBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import Image from 'next/image';
import Setting from '@/assets/icons/setting.svg';
import AddBox from '@/assets/icons/add_box.svg';

interface SettingBtnProps {
onSettingClick: () => void;
onInviteClick: () => void;
}

export default function SettingBtn({ onSettingClick, onInviteClick }: SettingBtnProps) {
return (
<div className='flex items-center gap-[6px] sm:gap-[12px] md:gap-[16px]'>
<button
className='flex h-[30px] w-[49px] items-center justify-center gap-[8px] rounded-[8px] border border-gray-30 text-[14px] text-gray-50 transition-transform hover:scale-105 hover:border-violet-20 hover:bg-violet-20 hover:text-white sm:h-[40px] sm:w-[88px] md:text-[16px]'
onClick={onSettingClick}
>
<Image src={Setting} alt='관리 버튼' width={15} height={15} className='hidden sm:block' />
관리
</button>
<button
className='flex h-[30px] w-[73px] items-center justify-center gap-[8px] rounded-[8px] border border-gray-30 text-[14px] text-gray-50 transition-transform hover:scale-105 hover:border-violet-20 hover:bg-violet-20 hover:text-white sm:h-[40px] sm:w-[116px] md:text-[14px]'
onClick={onInviteClick}
>
<Image src={AddBox} alt='초대 버튼' width={15} height={15} className='hidden sm:block' />
초대하기
</button>
</div>
);
}
13 changes: 13 additions & 0 deletions src/components/dashboard-header/Title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

interface TitleProps {
title?: string;
}

export default function Title({ title }: TitleProps) {
return (
<div className='flex items-center'>
<span className='hidden text-[20px] font-bold lg:block'>{title}</span>
</div>
);
}