Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
2 changes: 2 additions & 0 deletions src/route/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export const PATH = {
MANDAL: '/mandal',
EDIT: '/edit',
HISTORY: '/history',
TERMS: '/terms',
PRIVACY: '/privacy',
} as const;

export type PathType = (typeof PATH)[keyof typeof PATH];
34 changes: 0 additions & 34 deletions src/shared/component/Layout/Header/Header.tsx

This file was deleted.

12 changes: 9 additions & 3 deletions src/shared/component/Layout/Layout.css.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { style } from '@vanilla-extract/css';

export const layoutContainer = style({
height: '100vh',
display: 'flex',
flexDirection: 'column',
height: '100vh',
overflow: 'hidden',
overflow: 'auto',
scrollbarWidth: 'none',
msOverflowStyle: 'none',
selectors: {
'&::-webkit-scrollbar': {
display: 'none',
},
},
});

export const layoutMain = style({
flex: 1,
overflow: 'hidden',
});
9 changes: 3 additions & 6 deletions src/shared/component/Layout/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Outlet } from 'react-router-dom';

import Header from './Header/Header';
import * as styles from './Layout.css';
import Header from './header/Header';
import Footer from './footer/Footer';

const Layout = () => {
return (
Expand All @@ -11,11 +12,7 @@ const Layout = () => {
<Outlet />
</main>

{/* TODO: Footer 컴포넌트 추가 */}
<footer>
{/* 임시 푸터 */}
<p>© 2024 NINEDOT</p>
</footer>
<Footer />
</div>
);
};
Expand Down
37 changes: 37 additions & 0 deletions src/shared/component/Layout/footer/Footer.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { style } from '@vanilla-extract/css';

import { colors } from '@/style/token';
import { fonts } from '@/style/token/typography.css';

export const footerContainer = style({
display: 'flex',
flexDirection: 'column',
height: '15.1rem',
padding: '4rem 0',
justifyContent: 'center',
alignItems: 'center',
borderTop: `2px solid ${colors.grey1}`,
background: colors.black01,
});

export const linkWrapper = style({
display: 'flex',
gap: '2.7rem',
marginBottom: '2rem',
});

export const linkText = style({
color: colors.grey11,
...fonts.caption01,
cursor: 'pointer',
textDecoration: 'none',
});

export const infoWrapper = style({
textAlign: 'center',
});

export const infoText = style({
color: colors.grey11,
...fonts.caption02,
});
26 changes: 26 additions & 0 deletions src/shared/component/Layout/footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Link } from 'react-router-dom';

import * as styles from './Footer.css';

import { PATH } from '@/route';

const Footer = () => {
return (
<footer className={styles.footerContainer}>
<nav className={styles.linkWrapper}>
<Link to={PATH.TERMS} className={styles.linkText}>
이용약관
</Link>
<Link to={PATH.PRIVACY} className={styles.linkText}>
개인정보처리방침
</Link>
</nav>
<div className={styles.infoWrapper}>
<p className={styles.infoText}>대표: 이현준</p>
<p className={styles.infoText}>이메일: 999inedot@gmail.com</p>
Comment on lines +19 to +20
Copy link
Copy Markdown
Contributor

@shinjigu shinjigu Jul 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3) 사이트 제작자의 이름이나 제작자의 웹 페이지 또는 피드백을 위한 연락처 정보는 <address> 태그 활용해 보는 것도 좋을 것 같아요 !!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정해버릴게요

</div>
</footer>
);
};

export default Footer;
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { colors } from '@/style/token/color.css';
import { fonts } from '@/style/token/typography.css';

export const header = style({
position: 'sticky',
top: 0,
zIndex: 100,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p2) zIndex 는 따로 토큰 처리해놓아서 가져다 쓰시면 될 것 같습니다 !!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감쟘다

width: '100%',
backgroundColor: colors.bg_black01,
display: 'flex',
Expand All @@ -12,8 +15,8 @@ export const header = style({

export const headerInner = style({
width: '100%',
maxWidth: '90rem',
padding: '0.94rem 5rem',
maxWidth: '128rem',
padding: '1.5rem 8rem',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
Expand All @@ -26,33 +29,62 @@ export const logo = style({

export const navWrapper = style({
display: 'flex',
gap: '1.25rem',
gap: '2rem',
});

export const navItem = style({
display: 'flex',
padding: '0.75rem 1.25rem',
padding: '1.2rem 2rem',
justifyContent: 'center',
alignItems: 'center',
flexShrink: 0,
color: '#5A5E66', // 추후 토큰 색상으로 변경
color: colors.grey6,
textAlign: 'center',
...fonts.subtitle05,
background: 'transparent',
border: 'none',
cursor: 'pointer',
whiteSpace: 'nowrap',
transition: 'color 0.2s',
selectors: {
'&:hover': {
color: colors.grey7,
},
},
});

export const navItemActive = style({
color: `${colors.grey11} !important`,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3) !important 사용보다는 다른 스타일 우선순위로 조정해보는 게 더 좋지 않을까 … 라는 생각을 해봤습니다 ㅎㅎ 나중에 유지보수할 때도 좀 더 안정적일 것 같아요 !

selectors: {
'&:hover': {
color: `${colors.grey11} !important`,
},
},
});

export const active = style({
color: '#FDFDFD',
color: colors.grey11,
});

export const profilePlaceholder = style({
width: '3.125rem',
height: '3.125rem',
width: '5rem',
height: '5rem',
borderRadius: '50%',
backgroundColor: '#5A5E66', // 추후 토큰 색상으로 변경
backgroundColor: colors.grey6,
flexShrink: 0,
});

export const loginButton = style({
color: colors.grey11,
textAlign: 'center',
...fonts.subtitle05,
background: 'transparent',
border: 'none',
cursor: 'pointer',
transition: 'color 0.2s',
selectors: {
'&:hover': {
color: colors.grey7,
},
},
});
59 changes: 59 additions & 0 deletions src/shared/component/Layout/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';

import * as styles from './Header.css';

import { PATH } from '@/route/path';

const MENUS = [
{ label: '나의 할 일', path: PATH.TODO },
{ label: '나의 만다르트', path: PATH.MANDAL },
{ label: '나의 히스토리', path: PATH.HISTORY },
];

const Header = () => {
const [activeMenu, setActiveMenu] = useState<string>(MENUS[0].label);
const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
const navigate = useNavigate();

const handleLogin = () => {
// 로그인 로직 추가하기
setIsLoggedIn(true);
};

const handleMenuClick = (menuLabel: string, path: string) => {
setActiveMenu(menuLabel);
navigate(path);
};

return (
<header className={styles.header}>
<div className={styles.headerInner}>
<h1 className={styles.logo}>NINEDOT</h1>

<nav className={styles.navWrapper}>
{MENUS.map((menu) => (
<button
key={menu.label}
className={`${styles.navItem} ${activeMenu === menu.label ? styles.navItemActive : ''}`}
onClick={() => handleMenuClick(menu.label, menu.path)}
aria-current={activeMenu === menu.label ? 'page' : undefined}
>
Comment on lines +40 to +41
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p5) aria-current 속성 사용 좋아요 🙊

{menu.label}
</button>
))}
</nav>

{isLoggedIn ? (
<div className={styles.profilePlaceholder} />
) : (
<button className={styles.loginButton} onClick={handleLogin}>
로그인
</button>
)}
</div>
</header>
);
};

export default Header;
Loading