-
Notifications
You must be signed in to change notification settings - Fork 1
✨Feat: main페이지 board판 #51
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
Changes from all commits
f9607ab
99f5ef5
69271c3
ed3a5bb
83f00fb
cea48ff
84b43c7
dca86bd
0ae1cda
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 |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { Header } from '@/shared/components'; | ||
|
|
||
| import Boardgame from '@/pages/main/components/board/Boardgame'; | ||
| import router from 'next/router'; | ||
|
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. 여기 next/router 보다는
Contributor
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.
Contributor
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. Pages Router (pages/ 디렉토리)는 전통적인 파일 기반 라우팅 방식으로, 각 파일이 하나의 페이지 컴포넌트 역할을 하고 클라이언트-사이드 라우팅을 기본으로 하며 next/router에서 useRouter() 등을 사용하고 두 라우터 방식이 내부적으로 다르게 구현되어 있기 때문에, 라우팅 관련 API 및 훅들도 그 구조에 맞춰야한다고 생각하는데 저희가 Next.js 13 이후 버전을 사용하고 있지만 Pages Router 기반이라 next/router에서 useRouter()를 사용하는게 맞다고 생각이듭니다.
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. 확인 했습니다! next 더 공부해봐야겠네요.. 겉핥기식으로 알고있다는 느낌을 받아서 답변 감사합니다! |
||
|
|
||
| const Board = () => { | ||
| return ( | ||
| <div className='relative w-full h-[100vh] bg-[#46d1cd] overflow-auto'> | ||
| <Header title='지도' onClick={() => router.back()} /> | ||
|
|
||
| <main className='relative pt-[11.8rem]'> | ||
| <Boardgame /> | ||
| </main> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default Board; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,43 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'use client'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import Image from 'next/image'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { boardData } from '@/shared/constants/main/boardData'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. 항상 확장성 용이하게 만드는 코드 진짜 배워갑니다.. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const Boardgame = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className='relative w-full h-full bg-[#46d1cd] overflow-hidden'> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Image | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| src='/assets/background_.svg' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alt='board background' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| width={402} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| height={755} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className='w-full h-full object-cover' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| priority | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className=' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| absolute top-0 left-0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| w-full h-full | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid grid-cols-4 grid-rows-8 gap-0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| px-[2rem] pb-[1.7rem] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {boardData.map((row, r) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| row.map((cell, c) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const key = `cell-${r}-${c}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!cell.active) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return <div key={key} className='bg-transparent' />; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. !cell.active일 때 null 반환으로 안하고
Contributor
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. null로 하게 될 경우 그 자리에 아무 요소도 렌더되지 않기 때문에 그리드의 셀 개수가 줄어들어 전체 배치가 틀어질 수 있어요 grid는 따로 빈 칸이라는 개념이 없어 요소가 없으면 셀 자체도 사라져버립니당
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. 셀 자체가 없어지는걸 생각을 못했네요 설명 감사합니다! |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div key={key} onClick={() => console.log(cell.label)}></div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. 프로덕션 코드에서 console.log를 제거하세요. 클릭 핸들러에 - <div key={key} onClick={() => console.log(cell.label)}></div>
+ <div
+ key={key}
+ onClick={() => {
+ // TODO: 셀 클릭 시 상세 페이지 또는 모달 표시
+ }}
+ ></div>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+29
to
+35
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. 활성 셀의 접근성을 개선하세요. 활성 셀이 클릭 가능하지만 시각적 피드백, 키보드 접근성, ARIA 레이블이 없습니다. 사용자에게 인터랙티브 요소임을 알리고 접근성을 향상시켜야 합니다. 다음과 같이 개선하세요: return (
<div
key={key}
- onClick={() => console.log(cell.label)}
- ></div>
+ role="button"
+ tabIndex={0}
+ aria-label={cell.label || '보드 셀'}
+ onClick={() => {
+ // TODO: 클릭 핸들러 구현
+ }}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ // TODO: 키보드 핸들러 구현
+ }
+ }}
+ className="cursor-pointer hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
+ />
);📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default Boardgame; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,18 +2,24 @@ import { cn } from '@/shared/lib'; | |
| import StampBoard from './components/stampBoard/StampBoard'; | ||
| import { ControlBar } from '@/shared/components'; | ||
| import Image from 'next/image'; | ||
| import router from 'next/router'; | ||
|
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 router from 'next/router';
+import { useRouter } from 'next/router';그리고 컴포넌트 내부에서: export default function MainPage() {
+ const router = useRouter();
+
return (
🤖 Prompt for AI Agents |
||
| import { BottomNav } from '@/shared/components/tab/BottomNav'; | ||
|
|
||
| export default function MainPage() { | ||
| return ( | ||
| <div className={cn('px-[2.4rem] bg-white flex flex-col gap-[1rem]')}> | ||
| <div | ||
| className={cn( | ||
| 'px-[2.4rem] bg-white flex flex-col gap-[1rem] h-full pt-[1.3rem] pb-[12rem]', | ||
| )} | ||
| > | ||
| <ControlBar | ||
| isLoggedIn={false} | ||
| onLogin={() => {}} | ||
| userName='글다' | ||
| className='fixed top-[0.6rem] left-0 right-0 z-50 px-[2rem]' | ||
| className='fixed top-[1rem] left-0 right-0 z-50 px-[2rem]' | ||
| /> | ||
|
|
||
| <main className='w-full pt-[6.2rem] flex flex-col gap-4 overflow-auto'> | ||
| <main className='w-full pt-[6.3rem] flex flex-col gap-4 overflow-auto'> | ||
| <section> | ||
| <Image | ||
| src='/assets/bannerMain.svg' | ||
|
|
@@ -26,7 +32,7 @@ export default function MainPage() { | |
|
|
||
| <section | ||
| onClick={() => { | ||
| /* TODO: 페이지 이동 */ | ||
| router.push('/main/Board'); | ||
| }} | ||
| > | ||
| <Image | ||
|
|
@@ -38,8 +44,9 @@ export default function MainPage() { | |
| /> | ||
| </section> | ||
|
|
||
| <StampBoard count={3} total={8} /> | ||
| <StampBoard count={3} total={10} /> | ||
| </main> | ||
| <BottomNav /> | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| const boardData = [ | ||
| [{ active: false }, { active: false }, { active: false }, { active: false }], | ||
| [ | ||
| { active: true, label: '김수환관' }, | ||
| { active: true, label: '부천 아트벙커' }, | ||
| { active: true, label: '한국 만화박물관' }, | ||
| { active: false }, | ||
| ], | ||
| [ | ||
| { active: false }, | ||
| { active: false }, | ||
| { active: false }, | ||
| { active: true, label: '상동 호수 공원' }, | ||
| ], | ||
| [ | ||
| { active: false }, | ||
| { active: true, label: '부천역' }, | ||
| { active: true, label: '다솔관' }, | ||
| { active: true, label: '부천 자유 시장' }, | ||
| ], | ||
| [ | ||
| { active: false }, | ||
| { active: true, label: '중앙도서관' }, | ||
| { active: false }, | ||
| { active: false }, | ||
| ], | ||
| [ | ||
| { active: false }, | ||
| { active: false }, | ||
| { active: true, label: '역곡공원' }, | ||
| { active: false }, | ||
| ], | ||
| [ | ||
| { active: false }, | ||
| { active: false }, | ||
| { active: false }, | ||
| { active: true, label: '부천 식물원' }, | ||
| ], | ||
| [{ active: false }, { active: false }, { active: false }, { active: false }], | ||
| ]; | ||
| export { boardData }; | ||
|
Comment on lines
+1
to
+41
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. 🛠️ Refactor suggestion | 🟠 Major TypeScript 타입 정의를 추가하세요.
다음과 같이 타입을 추가하세요: +interface BoardCell {
+ active: boolean;
+ label?: string;
+}
+
+type BoardRow = [BoardCell, BoardCell, BoardCell, BoardCell];
+type BoardData = BoardRow[];
+
-const boardData = [
+const boardData: BoardData = [
[{ active: false }, { active: false }, { active: false }, { active: false }],🤖 Prompt for AI Agents |
||

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.
라우터 import 방식이 잘못되었습니다.
Next.js에서 라우터를 사용하려면
useRouter훅을 import해야 합니다. 현재 코드는 default export로router를 import하려고 하는데,next/router는 default export를 제공하지 않습니다.다음과 같이 수정하세요:
그리고 컴포넌트 내부에서 훅을 사용하세요:
const Board = () => { + const router = useRouter(); + return (🤖 Prompt for AI Agents