Skip to content

Commit

Permalink
Design: #5 react-icons 아이콘 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
Yoonyesol committed Jun 22, 2024
2 parents 23cf695 + eefecd9 commit 99bd536
Show file tree
Hide file tree
Showing 25 changed files with 288 additions and 37 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</head>
<body>
<div id="root"></div>
<div id="modal"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.4",
"react-icons": "^5.2.1",
"react-router-dom": "^6.23.1",
"tailwind-scrollbar-hide": "^1.1.7",
"zustand": "^4.5.2"
Expand Down
4 changes: 4 additions & 0 deletions src/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file removed src/components/common/.gitkeep
Empty file.
30 changes: 30 additions & 0 deletions src/components/common/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Link, NavLink } from 'react-router-dom';
import logo from '@assets/logo.svg';
import { FaUserCircle } from 'react-icons/fa';
import { FiHome } from 'react-icons/fi';

export default function Header() {
// ToDo: 로그인 기능 구현 후, 로그아웃 로직 연결하기
// ToDo: 유저 정보를 토대로 응원 아이디 변경하기
return (
<header className="flex h-header items-center justify-between bg-main px-15">
<div>
<Link to="/" className="hover:brightness-90">
<img className="size-30 select-none" src={logo} alt="GrowUp Logo" />
</Link>
</div>
<nav className="flex items-center">
<div className="tracking-tight text-white">User 님의 Grow Up! 응원합니다.</div>
<NavLink to="/" className="ml-10 hover:brightness-90">
{({ isActive }) => <FiHome className={`size-20 ${isActive ? 'text-selected' : 'text-white'}`} />}
</NavLink>
<NavLink to="/setting/user" className="ml-10 hover:brightness-90">
{({ isActive }) => <FaUserCircle className={`size-20 ${isActive ? 'text-selected' : 'text-white'}`} />}
</NavLink>
<button type="button" className="ml-10 h-20 rounded-md bg-white px-4 tracking-tight hover:brightness-90">
Logout
</button>
</nav>
</header>
);
}
7 changes: 7 additions & 0 deletions src/components/common/ModalPortal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { PropsWithChildren } from 'react';
import { createPortal } from 'react-dom';

export default function ModalPortal({ children }: PropsWithChildren) {
const container = document.getElementById('modal')! as HTMLDivElement;
return createPortal(children, container);
}
30 changes: 30 additions & 0 deletions src/components/sidebar/ListProject.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Link, useParams } from 'react-router-dom';
import type { Project } from '@/types/ProjectType';

type ListProjectProps = {
data: Project[];
targetId?: string;
};

export default function ListProject({ data, targetId }: ListProjectProps) {
const { teamId } = useParams();

return (
<ul className="grow overflow-auto">
{data.map((item) => (
<li
key={item.id}
className={`relative cursor-pointer border-b bg-white hover:brightness-90 ${targetId === item.id && 'selected'}`}
>
<Link
to={`/teams/${teamId}/projects/${item.id}/calendar`}
className="flex h-30 flex-col justify-center px-10"
>
<small className="font-bold text-category">project</small>
<span>{item.title}</span>
</Link>
</li>
))}
</ul>
);
}
22 changes: 22 additions & 0 deletions src/components/sidebar/ListSidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { ReactNode } from 'react';

type ListSidebarProps = {
label?: string;
title: string;
children?: ReactNode | undefined;
};

// ToDo: 프로젝트 생성 등과 같은 버튼 기능 추가할 것
export default function ListSidebar({ label, title, children }: ListSidebarProps) {
return (
<aside className="mr-10 flex w-1/3 flex-col border border-list bg-contents-box">
<div className="flex min-h-30 items-center justify-between bg-sub px-10">
<div>
{label && <small className="mr-5 font-bold text-main">{label}</small>}
<span className="text-emphasis">{title}</span>
</div>
</div>
{children}
</aside>
);
}
25 changes: 23 additions & 2 deletions src/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* contents size */
--height-header: 4rem;
--height-contents: calc(100vh - var(--height-header));
--max-width-contents: 90rem;

/* font-family */
--font-family-roboto: 'Roboto', sans-serif;
Expand Down Expand Up @@ -54,7 +55,8 @@

/* text color */
--text-color-default: #2c2c2c;
--text-color-bold: #5e5e5e;
--text-color-emphasis: #5e5e5e;
--text-color-category: #b1b1b1;
--text-color-error: #be0000;
--text-color-blue: #0909e7;

Expand All @@ -68,16 +70,35 @@
font-family: var(--font-family-roboto);
font-size: var(--font-size-regular);
font-weight: var(--font-weight-regular);
color: var(--text-color-default);
font-style: normal;
}

/* ========= Scrollbar Custom ========= */
::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-track {
border: 1px solid var(--border-scroll);
}
::-webkit-scrollbar-thumb {
background: var(--color-scroll);
}
::-webkit-scrollbar-thumb:hover {
cursor: pointer;
background: #e5e5e5;
}
}

@layer components {
.selected::before {
@apply absolute left-0 top-0 block h-30 w-4 bg-main content-[''];
}
.auth-btn {
@apply h-30 rounded-lg bg-sub px-8 font-bold;
}

.auth-input {
@apply h-30 flex-grow rounded-lg px-8 text-sm outline-none placeholder:text-bold;
@apply h-30 flex-grow rounded-lg px-8 text-sm outline-none placeholder:text-emphasis;
}
}
Empty file removed src/layouts/.gitkeep
Empty file.
10 changes: 0 additions & 10 deletions src/layouts/DefaultLayout.tsx

This file was deleted.

23 changes: 23 additions & 0 deletions src/layouts/ModalLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useEffect } from 'react';

type ModalLayoutProps = {
onClose: () => void;
children?: React.ReactNode | undefined;
};

export default function ModalLayout({ onClose, children }: ModalLayoutProps) {
const handleKeyDownClose = (event: KeyboardEvent) => {
if (event.key.toLowerCase() === 'escape') onClose();
};

useEffect(() => {
globalThis.addEventListener('keydown', handleKeyDownClose);
return () => globalThis.removeEventListener('keydown', handleKeyDownClose);
}, []);

return (
<div className="absolute bottom-0 left-0 right-0 top-0 flex items-center justify-center bg-black/50" tabIndex={-1}>
<div className="h-4/5 max-h-375 min-w-375 overflow-auto bg-white p-20">{children}</div>
</div>
);
}
10 changes: 0 additions & 10 deletions src/layouts/ProjectLayout.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Outlet } from 'react-router-dom';
import AuthGULogo from '../assets/authGULogo.svg';
import AuthGULogo from '@/assets/authGULogo.svg';

export default function AuthLayout() {
return (
Expand Down
13 changes: 13 additions & 0 deletions src/layouts/page/DefaultLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Outlet } from 'react-router-dom';
import Header from '@components/common/Header';

export default function DefaultLayout() {
return (
<>
<Header />
<main className="m-auto h-contents max-w-contents">
<Outlet />
</main>
</>
);
}
79 changes: 79 additions & 0 deletions src/layouts/page/ProjectLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { useMemo, useState } from 'react';
import { RiSettings5Fill } from 'react-icons/ri';
import { NavLink, Outlet, useParams } from 'react-router-dom';

import ListSidebar from '@components/sidebar/ListSidebar';
import ListProject from '@components/sidebar/ListProject';

import ModalPortal from '@components/common/ModalPortal';
import ModalLayout from '@layouts/ModalLayout';

const dummy = {
teamName: '김찌와 소주',
data: [
{ id: '1', title: '캘린더 만들기1' },
{ id: '2', title: '캘린더 만들기2' },
{ id: '3', title: '캘린더 만들기3' },
{ id: '4', title: '캘린더 만들기4' },
{ id: '5', title: '캘린더 만들기5' },
{ id: '6', title: '캘린더 만들기6' },
{ id: '7', title: '캘린더 만들기7' },
{ id: '8', title: '캘린더 만들기8' },
{ id: '9', title: '캘린더 만들기9' },
{ id: '10', title: '캘린더 만들기10' },
],
};

export default function ProjectLayout() {
const { projectId } = useParams();
const [showStateModal, setShowStateModal] = useState(false);
const target = useMemo(() => dummy.data.find((d) => d.id === projectId), [projectId]);

return (
<>
<section className="flex h-full p-15">
<ListSidebar label="team" title={dummy.teamName}>
<ListProject data={dummy.data} targetId={projectId} />
</ListSidebar>
<section className="flex w-2/3 flex-col border border-list bg-contents-box">
<header className="flex h-30 items-center justify-between border-b p-10">
<div>
<small className="mr-5 font-bold text-category">project</small>
<span className="text-emphasis">{target?.title}</span>
</div>
<div className="flex cursor-pointer items-center text-sm text-main">
<RiSettings5Fill /> Project Setting
</div>
</header>
<div className="grow p-10">
<div className="flex justify-between">
<ul className="flex border-b *:mr-15">
<li>
<NavLink to="calendar" className={({ isActive }) => (isActive ? 'text-main' : 'text-emphasis')}>
Calendar
</NavLink>
</li>
<li>
<NavLink to="kanban" className={({ isActive }) => (isActive ? 'text-main' : 'text-emphasis')}>
Kanban
</NavLink>
</li>
</ul>
<div className="text-main">
<button type="button" onClick={() => setShowStateModal(true)}>
<small>+</small> New State
</button>
</div>
</div>
<Outlet />
</div>
</section>
</section>
{showStateModal && (
<ModalPortal>
<ModalLayout onClose={() => setShowStateModal(false)} />
</ModalPortal>
)}
</>
);
}
File renamed without changes.
File renamed without changes.
25 changes: 24 additions & 1 deletion src/pages/NotFoundPage.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
import { PiSmileySadFill } from 'react-icons/pi';
import { Link } from 'react-router-dom';
import Header from '@components/common/Header';

export default function NotFoundPage() {
return <div>NotFoundPage</div>;
return (
<>
<Header />
<section className="flex h-contents flex-col items-center justify-center">
<span className="text-center text-regular tracking-tight text-emphasis">
The page you are looking for doesn&#39;t exit or an other error occurred, go back to home page
</span>
<div className="m-12 flex items-center justify-center text-404 font-bold leading-none tracking-tighter">
<div className="mr-12">
<h3 className="text-main">Error 404</h3>
<h3 className="text-emphasis">Page Not Found</h3>
</div>
<PiSmileySadFill className="size-75 text-main" />
</div>
<Link to="/" className="flex h-30 w-130 items-center justify-center rounded-sl bg-button hover:brightness-90">
메인 페이지로 돌아가기
</Link>
</section>
</>
);
}
Loading

0 comments on commit 99bd536

Please sign in to comment.