-
Notifications
You must be signed in to change notification settings - Fork 0
feat/라우팅 설정 #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat/라우팅 설정 #10
Changes from all commits
df3f863
a786fb6
a3338bb
15389c1
841d6a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,22 @@ | ||
| import { Outlet, useLocation } from 'react-router-dom'; | ||
|
|
||
| import './App.css'; | ||
| import { Gnb, Layout } from './components/layout'; | ||
| import { DEFAULT_TAB, PATH_TO_TAB } from './constants/navigation'; | ||
|
|
||
| function App() { | ||
| return <></>; | ||
| const location = useLocation(); | ||
| const activeTab = PATH_TO_TAB[location.pathname] ?? DEFAULT_TAB; | ||
|
|
||
| return ( | ||
| <Layout | ||
| headerLeft={<div>로고</div>} | ||
| headerCenter={<Gnb activeTab={activeTab} />} | ||
| headerRight={<div>로그인</div>} | ||
| > | ||
| <Outlet /> | ||
| </Layout> | ||
| ); | ||
| } | ||
|
|
||
| export default App; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,17 @@ | ||
| import type { ReactNode } from 'react'; | ||
|
|
||
| interface HeaderProps { | ||
| children?: ReactNode; | ||
| left?: ReactNode; | ||
| center?: ReactNode; | ||
| right?: ReactNode; | ||
| } | ||
|
|
||
| export function Header({ children }: HeaderProps) { | ||
| export function Header({ left, center, right }: HeaderProps) { | ||
| return ( | ||
| <header className="fixed top-0 left-0 right-0 z-50 flex h-15 items-center justify-center border-b border-gray-200 bg-white px-18"> | ||
| {children} | ||
| <header className="fixed top-0 left-0 right-0 z-50 flex h-15 items-center justify-between border-b border-gray-200 bg-white px-18"> | ||
| <div className="flex items-center">{left}</div> | ||
| <div className="absolute left-1/2 -translate-x-1/2">{center}</div> | ||
| <div className="flex items-center">{right}</div> | ||
| </header> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| export { GNB } from './GNB'; | ||
| export { Gnb } from './Gnb'; | ||
| export { Header } from './Header'; | ||
| export { Layout } from './Layout'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,14 @@ | ||
| export const TABS = [ | ||
| { key: 'slide', label: '슬라이드' }, | ||
| { key: 'video', label: '영상' }, | ||
| { key: 'insight', label: '인사이트' }, | ||
| { key: 'slide', label: '슬라이드', path: '/slide' }, | ||
| { key: 'video', label: '영상', path: '/video' }, | ||
| { key: 'insight', label: '인사이트', path: '/insight' }, | ||
| ] as const; | ||
|
|
||
| export type Tab = (typeof TABS)[number]['key']; | ||
|
|
||
| export const DEFAULT_TAB: Tab = 'slide'; | ||
|
|
||
| export const PATH_TO_TAB: Record<string, Tab> = { | ||
| '/': DEFAULT_TAB, | ||
| ...Object.fromEntries(TABS.map((tab) => [tab.path, tab.key])), | ||
| }; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,11 +1,28 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { StrictMode } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { createRoot } from 'react-dom/client'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { RouterProvider, createBrowserRouter } from 'react-router-dom'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import App from './App.tsx'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import App from './App'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import InsightPage from './pages/InsightPage'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import SlidePage from './pages/SlidePage'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import VideoPage from './pages/VideoPage'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import './styles/index.css'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const router = createBrowserRouter([ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: '/', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| element: <App />, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| children: [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { index: true, element: <SlidePage /> }, // DEFAULT_TAB 변경 시 동기화 필요 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { path: 'slide', element: <SlidePage /> }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { path: 'video', element: <VideoPage /> }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { path: 'insight', element: <InsightPage /> }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+11
to
+22
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 라우팅 설정이
아래 제안을 적용하기 전에 파일 상단에 다음 import 구문을 추가하거나 수정해주세요. import { StrictMode, type ReactElement } from 'react';
import { TABS, DEFAULT_TAB, type Tab } from './constants/navigation';
Suggested change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 동적으로 만들어봤자 이에 현행으로 유지합니다. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createRoot(document.querySelector('#root')!).render( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <StrictMode> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <App /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <RouterProvider router={router} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </StrictMode>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| export default function InsightPage() { | ||
| return ( | ||
| <div role="tabpanel" id="tabpanel-insight" aria-labelledby="tab-insight" className="p-8"> | ||
| <h1 className="text-body-m-bold">인사이트</h1> | ||
| </div> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| export default function SlidePage() { | ||
| return ( | ||
| <div role="tabpanel" id="tabpanel-slide" aria-labelledby="tab-slide" className="p-8"> | ||
| <h1 className="text-body-m-bold">슬라이드</h1> | ||
| </div> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| export default function VideoPage() { | ||
| return ( | ||
| <div role="tabpanel" id="tabpanel-video" aria-labelledby="tab-video" className="p-8"> | ||
| <h1 className="text-body-m-bold">영상</h1> | ||
| </div> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로고와 로그인 UI가
div태그로 직접 작성되어 있습니다. 이를 각각의 컴포넌트(예:<Logo />,<UserAuth />)로 분리하는 것을 고려해보세요. 이렇게 하면App컴포넌트가 더 선언적으로 되고, 각 UI 요소의 재사용성과 관리 용이성이 향상됩니다.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로고와 공유, 로그인 버튼은 추후 추가될 예정이므로 현행을 유지합니다.