Skip to content

Commit 811b839

Browse files
committedOct 23, 2023
feat: intercepting routes 구현 #65
1 parent f29aa58 commit 811b839

File tree

18 files changed

+164
-196
lines changed

18 files changed

+164
-196
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Default() {
2+
return null;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import BoardModal from '@/components/pages/main/Board/BoardModal';
2+
import React from 'react';
3+
4+
export default function BoardModalPage({
5+
params: { boardId },
6+
}: {
7+
params: { boardId: number };
8+
}) {
9+
return <BoardModal boardId={boardId} />;
10+
}

‎app/(main)/@modal/default.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Default() {
2+
return null;
3+
}

‎app/(main)/board/[boardId]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Board from '@/components/pages/board';
1+
import Board from '@/components/pages/main/Board';
22

33
export default async function BoardPage({
44
params: { boardId },

‎app/(main)/layout.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@ export const metadata: Metadata = {
1010

1111
export default function MainLayout({
1212
children,
13+
modal,
1314
}: {
1415
children: React.ReactNode;
16+
modal: React.ReactNode;
1517
}) {
1618
return (
1719
<div className="flex flex-col flex-wrap h-full tablet:flex-row">
1820
<Header />
1921
<Sidebar />
2022
<div id="modal-root" />
2123
{children}
24+
{modal}
2225
<Footer />
2326
</div>
2427
);
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* eslint-disable jsx-a11y/click-events-have-key-events */
2+
/* eslint-disable jsx-a11y/no-static-element-interactions */
3+
4+
'use client';
5+
6+
import Image from 'next/image';
7+
import ModalBoardCard from '@/components/ui/BoardCard/ModalBoardCard';
8+
import { useRouter } from 'next/navigation';
9+
import { MouseEventHandler, useCallback, useEffect, useRef } from 'react';
10+
import FlexBox from '../../../ui/FlexBox';
11+
12+
export default function BoardModal({ boardId }: { boardId: number }) {
13+
const overlay = useRef(null);
14+
const wrapper = useRef(null);
15+
const router = useRouter();
16+
17+
const onDismiss = useCallback(() => {
18+
router.back();
19+
}, [router]);
20+
21+
const onClick: MouseEventHandler = useCallback(
22+
(e) => {
23+
if (e.target === overlay.current || e.target === wrapper.current) {
24+
if (onDismiss) onDismiss();
25+
}
26+
},
27+
[onDismiss, overlay, wrapper],
28+
);
29+
30+
const onKeyDown = useCallback(
31+
(e: KeyboardEvent) => {
32+
if (e.key === 'Escape') onDismiss();
33+
},
34+
[onDismiss],
35+
);
36+
37+
useEffect(() => {
38+
document.addEventListener('keydown', onKeyDown);
39+
return () => document.removeEventListener('keydown', onKeyDown);
40+
}, [onKeyDown]);
41+
42+
return (
43+
<div
44+
ref={overlay}
45+
className="fixed inset-0 flex items-center justify-center flex-1 w-screen bg-black bg-opacity-70"
46+
onClick={onClick}
47+
>
48+
<FlexBox direction="column" className="gap-4">
49+
<FlexBox justify="end" className="w-full">
50+
<button type="button" onClick={() => router.back()}>
51+
<Image
52+
src="/Feed/desktop/ModalOut.svg"
53+
alt="나가기"
54+
width={32}
55+
height={32}
56+
/>
57+
</button>
58+
</FlexBox>
59+
<div ref={wrapper}>
60+
<ModalBoardCard boardId={boardId} />
61+
</div>
62+
</FlexBox>
63+
</div>
64+
);
65+
}
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
'use client';
22

33
import BoardIdCard from '@/components/ui/BoardCard/BoardIdCard';
4-
// import useGetBoard from '@/hooks/queries/useGetBoard';
54

65
export default function Board({ boardId }: { boardId: number }) {
7-
// const { data } = useGetBoard(boardId);
8-
// if (data) {
96
return (
107
<div className="w-full">
118
<BoardIdCard boardId={boardId} />
129
</div>
1310
);
14-
// }
1511
}

‎components/pages/main/Feed/BoardsList/index.tsx

+6-18
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
/* eslint-disable jsx-a11y/no-static-element-interactions */
22
/* eslint-disable jsx-a11y/click-events-have-key-events */
3-
4-
import { Dispatch, SetStateAction } from 'react';
53
import useGetBoardList from '@/hooks/queries/useGetBoardList';
6-
import { Board } from '@/types/types';
74
import FeedBoardLoading from '@/components/ui/Loading/FeedBoardLoading';
5+
import Link from 'next/link';
86
import FlexBox from '../../../../ui/FlexBox';
97
import FeedBoardCard from '../../../../ui/BoardCard/FeedBoardCard';
108

11-
export default function BoardsList({
12-
setSelectedBoard,
13-
setShowModal,
14-
}: {
15-
setSelectedBoard: Dispatch<SetStateAction<Board | null>>;
16-
setShowModal: Dispatch<SetStateAction<boolean>>;
17-
}) {
9+
export default function BoardsList() {
1810
const {
1911
Observer,
2012
data: boardList,
@@ -31,14 +23,10 @@ export default function BoardsList({
3123
boardList?.pages?.map((page) =>
3224
page.content.length > 0 ? (
3325
page.content.map((board) => (
34-
<div
35-
key={board.id}
36-
onClick={() => {
37-
setSelectedBoard(board);
38-
}}
39-
className="w-full"
40-
>
41-
<FeedBoardCard board={board} setShowModal={setShowModal} />
26+
<div key={board.id} className="w-full">
27+
<Link key={board.id} href={`/board/${board.id}`}>
28+
<FeedBoardCard board={board} />
29+
</Link>
4230
</div>
4331
))
4432
) : (

‎components/pages/main/Feed/index.tsx

+2-19
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,14 @@
11
'use client';
22

3-
import { useState } from 'react';
43
import BoardsList from '@/components/pages/main/Feed/BoardsList';
54
import FlexBox from '@/components/ui/FlexBox';
65
import FeedHeader from '@/components/pages/main/Feed/FeedHeader';
7-
import { Board } from '@/types/types';
8-
import BoardModal from '../../../ui/BoardModal';
96

107
export default function Feed() {
11-
const [showModal, setShowModal] = useState(false);
12-
const [selectedBoard, setSelectedBoard] = useState<Board | null>(null);
13-
148
return (
15-
<FlexBox
16-
direction="column"
17-
className={`gap-10 w-full ${showModal ? 'overflow-hidden' : null}`}
18-
>
9+
<FlexBox direction="column" className="w-full gap-10">
1910
<FeedHeader />
20-
<BoardsList
21-
setShowModal={setShowModal}
22-
setSelectedBoard={setSelectedBoard}
23-
/>
24-
<BoardModal
25-
showModal={showModal}
26-
setShowModal={setShowModal}
27-
board={selectedBoard}
28-
/>
11+
<BoardsList />
2912
</FlexBox>
3013
);
3114
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
/* eslint-disable jsx-a11y/no-static-element-interactions */
22
/* eslint-disable jsx-a11y/click-events-have-key-events */
33

4-
import { useState } from 'react';
5-
import { Board } from '@/types/types';
64
import MyBoardCard from '@/components/ui/BoardCard/MyPageBoardCard';
7-
import BoardModal from '@/components/ui/BoardModal';
85
import MyBoardListLoading from '@/components/ui/Loading/MyBoardListLoading';
96
import useGetBookmarkedBoardList from '@/hooks/queries/useGetMyBookmarkedBoardList';
7+
import Link from 'next/link';
108

119
export default function BookmarkedBoardsList() {
1210
const { Observer, data, isLoading } = useGetBookmarkedBoardList();
1311

1412
// 모달을 위한 상태
15-
const [showModal, setShowModal] = useState(false);
16-
const [selectedBoard, setSelectedBoard] = useState<Board | null>(null);
1713

1814
if (isLoading) {
1915
return <MyBoardListLoading />;
@@ -27,26 +23,17 @@ export default function BookmarkedBoardsList() {
2723
{data &&
2824
data?.pages?.map((page) =>
2925
page.content.map((board) => (
30-
<div
31-
key={board.id}
32-
onClick={() => {
33-
setSelectedBoard(board);
34-
}}
35-
className="w-full"
36-
>
37-
<MyBoardCard board={board} setShowModal={setShowModal} />
26+
<div key={board.id} className="w-full">
27+
<Link key={board.id} href={`/board/${board.id}`}>
28+
<MyBoardCard board={board} />
29+
</Link>
3830
</div>
3931
)),
4032
)}
4133
<Observer>
4234
<div>로딩스피너...</div>
4335
</Observer>
4436
</div>
45-
<BoardModal
46-
showModal={showModal}
47-
setShowModal={setShowModal}
48-
board={selectedBoard}
49-
/>
5037
</>
5138
);
5239
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
/* eslint-disable jsx-a11y/no-static-element-interactions */
22
/* eslint-disable jsx-a11y/click-events-have-key-events */
33

4-
import { useState } from 'react';
5-
import { Board } from '@/types/types';
64
import MyBoardCard from '@/components/ui/BoardCard/MyPageBoardCard';
7-
import BoardModal from '@/components/ui/BoardModal';
85
import useGetMyBoardList from '@/hooks/queries/useGetMyBoardList';
96
import MyBoardListLoading from '@/components/ui/Loading/MyBoardListLoading';
7+
import Link from 'next/link';
108

119
export default function MyBoardsList() {
1210
const { Observer, data: myBoards, isLoading } = useGetMyBoardList();
1311

1412
// 모달을 위한 상태
15-
const [showModal, setShowModal] = useState(false);
16-
const [selectedBoard, setSelectedBoard] = useState<Board | null>(null);
1713

1814
if (isLoading) {
1915
return <MyBoardListLoading />;
@@ -28,26 +24,17 @@ export default function MyBoardsList() {
2824
{myBoards &&
2925
myBoards?.pages?.map((page) =>
3026
page.content.map((board) => (
31-
<div
32-
key={board.id}
33-
onClick={() => {
34-
setSelectedBoard(board);
35-
}}
36-
className="w-full"
37-
>
38-
<MyBoardCard board={board} setShowModal={setShowModal} />
27+
<div key={board.id} className="w-full">
28+
<Link key={board.id} href={`/board/${board.id}`}>
29+
<MyBoardCard board={board} />
30+
</Link>
3931
</div>
4032
)),
4133
)}
4234
<Observer>
4335
<div>로딩스피너...</div>
4436
</Observer>
4537
</div>
46-
<BoardModal
47-
showModal={showModal}
48-
setShowModal={setShowModal}
49-
board={selectedBoard}
50-
/>
5138
</>
5239
);
5340
}

‎components/ui/BoardCard/BoardCardPackage/CommentWrapper.tsx

+18-21
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use client';
2+
13
import Image from 'next/image';
24
import { useState } from 'react';
35
import usePostComment from '@/hooks/mutations/usePostComment';
@@ -117,36 +119,31 @@ export function BoardCardCommentWrapper({
117119
}
118120

119121
export function MyPageBoardCardCommentWrapper({
120-
onClickModal,
121122
commentsCount,
122123
likedCount,
123124
}: {
124-
onClickModal: () => void;
125125
commentsCount: number;
126126
likedCount: number;
127127
}) {
128128
return (
129-
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
130-
<div onClick={onClickModal}>
131-
<FlexBox
132-
direction="column"
133-
align="stretch"
134-
justify="between"
135-
className="w-full h-full"
136-
>
137-
<FlexBox direction="column" align="start" className="w-full gap-3">
138-
<FlexBox className="gap-5">
139-
<FlexBox className="gap-2 body3 text-grey-500">
140-
<div>댓글</div>
141-
<div>{commentsCount}</div>
142-
</FlexBox>
143-
<FlexBox className="gap-2 body3 text-grey-500">
144-
<div>좋아요</div>
145-
<div>{likedCount}</div>
146-
</FlexBox>
129+
<FlexBox
130+
direction="column"
131+
align="stretch"
132+
justify="between"
133+
className="w-full h-full"
134+
>
135+
<FlexBox direction="column" align="start" className="w-full gap-3">
136+
<FlexBox className="gap-5">
137+
<FlexBox className="gap-2 body3 text-grey-500">
138+
<div>댓글</div>
139+
<div>{commentsCount}</div>
140+
</FlexBox>
141+
<FlexBox className="gap-2 body3 text-grey-500">
142+
<div>좋아요</div>
143+
<div>{likedCount}</div>
147144
</FlexBox>
148145
</FlexBox>
149146
</FlexBox>
150-
</div>
147+
</FlexBox>
151148
);
152149
}

‎components/ui/BoardCard/BoardCardPackage/Comments.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
export default function BoardCardComments({
22
userName,
33
content,
4-
onClickModal,
54
}: {
65
userName: string;
76
content: string;
8-
onClickModal: () => void;
97
}) {
108
return (
11-
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
12-
<div onClick={onClickModal} className="flex flex-row">
9+
<div className="flex flex-row">
1310
<div className="inline-block mr-1 body2 text-grey-500">{userName}</div>
1411
<div className="inline body4 text-grey-500">{content}</div>
1512
</div>

‎components/ui/BoardCard/FeedBoardCard.tsx

+1-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
import { Dispatch, SetStateAction } from 'react';
21
import { Board } from '@/types/types';
32
import { BoardCard } from '@/components/ui/BoardCard/BoardCardPackage';
43
import FlexBox from '../FlexBox';
54

6-
export default function FeedBoardCard({
7-
board,
8-
setShowModal,
9-
}: {
10-
board: Board;
11-
setShowModal: Dispatch<SetStateAction<boolean>>;
12-
}) {
5+
export default function FeedBoardCard({ board }: { board: Board }) {
136
return (
147
<FlexBox
158
direction="column"
@@ -21,7 +14,6 @@ export default function FeedBoardCard({
2114
type="mainPC"
2215
content={board.content}
2316
imgs={board.fileNames}
24-
onClickModal={() => setShowModal(true)}
2517
>
2618
<BoardCard.BoardCardCommentWrapper
2719
boardId={board.id}
@@ -40,7 +32,6 @@ export default function FeedBoardCard({
4032
key={comment.id}
4133
userName={comment.nickname}
4234
content={comment.content}
43-
onClickModal={() => setShowModal(true)}
4435
/>
4536
))}
4637
</FlexBox>
+37-33
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,43 @@
11
import { BoardCardModal } from '@/components/ui/BoardCard/BoardCardPackage/BoardCardModalPackage';
2+
import useGetBoard from '@/hooks/queries/useGetBoard';
23
import useGetCommentList from '@/hooks/queries/useGetCommentList';
3-
import { Board } from '@/types/types';
44

5-
export default function ModalBoardCard({ board }: { board: Board }) {
6-
const { data: commentList, Observer } = useGetCommentList(board.id);
5+
export default function ModalBoardCard({ boardId }: { boardId: number }) {
6+
const { data: board } = useGetBoard(boardId);
7+
const { data: commentList, Observer } = useGetCommentList(boardId);
78

8-
return (
9-
<BoardCardModal imgs={board.fileNames}>
10-
<BoardCardModal.Header board={board} />
11-
<BoardCardModal.Content
12-
type="modal"
13-
content={board.content}
14-
imgs={board.fileNames}
15-
>
16-
<BoardCardModal.BoardCardCommentWrapper
17-
isModal
18-
boardId={board.id}
19-
commentsCount={board.replyCount}
20-
likedCount={board.likedCount}
21-
isLiked={board.boardLiked}
9+
if (board) {
10+
return (
11+
<BoardCardModal imgs={board.fileNames}>
12+
<BoardCardModal.Header board={board} />
13+
<BoardCardModal.Content
14+
type="modal"
15+
content={board.content}
16+
imgs={board.fileNames}
2217
>
23-
{commentList?.pages.map((page) =>
24-
page.content.map((comment) => (
25-
<BoardCardModal.ModalComments
26-
id={comment.id}
27-
userName={comment.nickname}
28-
content={comment.content}
29-
// TODO: 유저 프로필 사진 연결!
30-
userImage="/Feed/desktop/tempProfilePic.svg"
31-
/>
32-
)),
33-
)}
34-
<Observer>로딩중...</Observer>
35-
</BoardCardModal.BoardCardCommentWrapper>
36-
</BoardCardModal.Content>
37-
</BoardCardModal>
38-
);
18+
<BoardCardModal.BoardCardCommentWrapper
19+
isModal
20+
boardId={board.id}
21+
commentsCount={board.replyCount}
22+
likedCount={board.likedCount}
23+
isLiked={board.boardLiked}
24+
>
25+
{commentList?.pages.map((page) =>
26+
page.content.map((comment) => (
27+
<BoardCardModal.ModalComments
28+
id={comment.id}
29+
userName={comment.nickname}
30+
content={comment.content}
31+
// TODO: 유저 프로필 사진 연결!
32+
userImage="/Feed/desktop/tempProfilePic.svg"
33+
/>
34+
)),
35+
)}
36+
<Observer>로딩중...</Observer>
37+
</BoardCardModal.BoardCardCommentWrapper>
38+
</BoardCardModal.Content>
39+
</BoardCardModal>
40+
);
41+
}
42+
return <div>내용이 없습니다.</div>;
3943
}

‎components/ui/BoardCard/MyPageBoardCard.tsx

+1-12
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,16 @@
11
import { BoardCard } from '@/components/ui/BoardCard/BoardCardPackage';
22
import { Board } from '@/types/types';
3-
import { Dispatch, SetStateAction } from 'react';
43

5-
interface MyBoardCardProps {
6-
board: Board;
7-
setShowModal: Dispatch<SetStateAction<boolean>>;
8-
}
9-
10-
export default function MyPageBoardCard({
11-
board,
12-
setShowModal,
13-
}: MyBoardCardProps) {
4+
export default function MyPageBoardCard({ board }: { board: Board }) {
145
return (
156
<BoardCard>
167
<BoardCard.Header board={board} />
178
<BoardCard.Content
189
type="myPage"
1910
content={board.content}
2011
imgs={board.fileNames}
21-
onClickModal={() => setShowModal(true)}
2212
>
2313
<BoardCard.MyPageBoardCardCommentWrapper
24-
onClickModal={() => setShowModal(true)}
2514
commentsCount={board.replyCount}
2615
likedCount={board.likedCount}
2716
/>

‎components/ui/BoardModal/index.tsx

-35
This file was deleted.

‎components/ui/Input/SelectInput/index.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export default function SelectInput({
8080
<button
8181
type="button"
8282
onClick={() => handleSelect(item)}
83-
className="w-full text-start cursor-pointer px-5 py-4 hover:bg-grey-100 body1 text-grey-400 border-b border-grey-200"
83+
className="w-full px-5 py-4 border-b cursor-pointer text-start hover:bg-grey-100 body1 text-grey-400 border-grey-200"
8484
>
8585
{item}
8686
</button>
@@ -93,7 +93,7 @@ export default function SelectInput({
9393
setIsCustomInputOpen(true);
9494
inputRef.current?.focus();
9595
}}
96-
className="w-full text-start cursor-pointer px-5 py-4 hover:bg-grey-100 body1 text-grey-400"
96+
className="w-full px-5 py-4 cursor-pointer text-start hover:bg-grey-100 body1 text-grey-400"
9797
>
9898
+직접입력
9999
</button>
@@ -103,7 +103,7 @@ export default function SelectInput({
103103
{isCustomInputOpen && (
104104
<div className="absolute z-[10] px-5 py-4 bg-white border border-grey-200 rounded-b-[10px] shadow-sm flex gap-1.5 w-full">
105105
<input
106-
className="w-full flex-1 border-0 focus-none p-0"
106+
className="flex-1 w-full p-0 border-0 focus-none"
107107
type="text"
108108
value={customValue}
109109
onChange={handleInputChange}

0 commit comments

Comments
 (0)
Please sign in to comment.