Skip to content

Commit 5f6171f

Browse files
authored
Merge pull request #415 from TripInfoWeb/dev
Release: v1.1.0
2 parents 95afda9 + 344678d commit 5f6171f

36 files changed

+1245
-276
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
name: Bug Report
3+
about: 어떤 버그인지 설명해 주세요.
4+
title: "Bug: 버그 설명"
5+
labels: Bug
6+
assignees: ""
7+
---
8+
9+
## ❓ 어떤 버그인가요?
10+
11+
- 어떤 버그인지 설명해 주세요.
12+
13+
## 🖥️ 발생 환경
14+
15+
- OS: (Ex. Windows, macOS, Ubuntu)
16+
- 브라우저: (Ex. Chrome, Firefox)
17+
- 버전: (Ex. v1.0.3)
18+
19+
## 🕘 발생 일시
20+
21+
- 버그가 발생한 날짜와 시간을 입력해 주세요. (Ex. 2024년 10월 1일, 오후 3시 30분)
22+
23+
## 📝 예상 결과
24+
25+
- 예상했던 정상적인 결과가 어떤 것이었는지 설명해주세요
26+
27+
## 📚 참고할만한 자료(선택)
28+
29+
- 추가적으로 참고할 만한 사항이 있으면 적어주세요.
30+
- 없는 경우 해당 단락을 삭제해 주세요.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
name: Feature Request
3+
about: 새로운 기능 추가 요청을 작성해 주세요.
4+
title: "Feat: 기능 설명"
5+
labels: Feat
6+
assignees: ""
7+
---
8+
9+
## ❓ 어떤 기능인가요?
10+
11+
- 추가 요청하려는 기능에 대해 설명해 주세요.
12+
13+
## 📝 기능 설명
14+
15+
- 추가하려는 기능의 세부 설명 및 목적을 작성해 주세요.
16+
17+
## ✅ TODO
18+
19+
구현해야 하는 기능에 대해 체크리스트를 작성해 주세요.
20+
21+
- [ ] TODO 1
22+
- [ ] TODO 2
23+
24+
## 📚 참고할만한 자료(선택)
25+
26+
- 추가적으로 참고할 만한 사항이 있으면 적어주세요.
27+
- 없는 경우 해당 단락을 삭제해 주세요.

.github/pull_request_template.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
- 제목: Feat: 기능명
2+
Ex. Feat: pull request template 작성
3+
4+
-- 절취선 위 부분의 내용은 모두 삭제하고 PR을 작성해 주세요. --
5+
6+
---- 절취선 ----
7+
8+
## ☑️ 개발 유형
9+
10+
- [x] Front-end
11+
12+
## ✔️ PR 유형
13+
14+
- [ ] 새로운 기능 추가
15+
- [ ] 버그 수정
16+
- [ ] CSS 등 사용자 UI 디자인 변경
17+
- [ ] 기존 기능에 영향을 주지 않는 변경사항 (Ex. 오타 수정, 탭 사이즈 변경, 변수명 변경, 코드 리팩토링 등)
18+
- [ ] 주석 관련 작업
19+
- [ ] 문서 관련 작업
20+
- [ ] 테스트 추가 혹은 테스트 리팩토링
21+
- [ ] 빌드 부분 혹은 패키지 매니저 수정
22+
- [ ] 파일 혹은 폴더명 수정
23+
- [ ] 파일 혹은 폴더 삭제
24+
25+
## 📝 작업 내용
26+
27+
이번 PR에서 작업한 내용을 간략히 설명해주세요.
28+
29+
- [x] 구현한 기능 1
30+
- [x] 구현한 기능 2
31+
32+
## #️⃣ Related Issue
33+
34+
해당 Pull Request과 관련된 Issue Link를 작성해 주세요
35+
36+
Ex. #123

README.md

Lines changed: 200 additions & 23 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "solitour-frontend",
3-
"version": "1.0.3",
3+
"version": "1.1.0",
44
"private": true,
55
"scripts": {
66
"dev": "next dev",
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import {
2+
CreateInformationCommentRequestDto,
3+
UpdateInformationCommentRequestDto,
4+
} from "@/types/InformationCommentDto";
5+
import { NextRequest } from "next/server";
6+
7+
/**
8+
* @method GET
9+
* @url /api/informations/comments/:informationId?page=0
10+
* @description 댓글 목록 조회
11+
*/
12+
export async function GET(
13+
request: NextRequest,
14+
{ params }: { params: { id: string } },
15+
) {
16+
const cookie = request.cookies.get("access_token");
17+
const searchParams = request.nextUrl.searchParams;
18+
const page = searchParams.get("page") ?? "0";
19+
20+
return await fetch(
21+
`${process.env.BACKEND_URL}/api/informations/comments/${params.id}?page=${page}`,
22+
{
23+
method: "GET",
24+
headers: {
25+
"Content-Type": "application/json",
26+
Cookie: `${cookie?.name}=${cookie?.value}`,
27+
},
28+
cache: "no-store",
29+
},
30+
);
31+
}
32+
33+
/**
34+
* @method POST
35+
* @url /api/informations/comments/:informationId
36+
* @description 댓글 작성
37+
*/
38+
export async function POST(
39+
request: NextRequest,
40+
{ params }: { params: { id: number } },
41+
) {
42+
const cookie = request.cookies.get("access_token");
43+
const body: CreateInformationCommentRequestDto = await request.json();
44+
return await fetch(
45+
`${process.env.BACKEND_URL}/api/informations/comments/${params.id}`,
46+
{
47+
method: "POST",
48+
headers: {
49+
"Content-Type": "application/json",
50+
Cookie: `${cookie?.name}=${cookie?.value}`,
51+
},
52+
body: JSON.stringify(body),
53+
cache: "no-store",
54+
},
55+
);
56+
}
57+
58+
/**
59+
* @method PUT
60+
* @url /api/informations/comments/:informationId
61+
* @description 댓글 수정
62+
*/
63+
export async function PUT(
64+
request: NextRequest,
65+
{ params }: { params: { id: number } },
66+
) {
67+
const cookie = request.cookies.get("access_token");
68+
const body: UpdateInformationCommentRequestDto = await request.json();
69+
return await fetch(
70+
`${process.env.BACKEND_URL}/api/informations/comments/${params.id}`,
71+
{
72+
method: "PUT",
73+
headers: {
74+
"Content-Type": "application/json",
75+
Cookie: `${cookie?.name}=${cookie?.value}`,
76+
},
77+
body: JSON.stringify(body),
78+
cache: "no-store",
79+
},
80+
);
81+
}
82+
83+
/**
84+
* @method DELETE
85+
* @url /api/informations/comments/:informationCommentId
86+
* @description 댓글 삭제
87+
*/
88+
export async function DELETE(
89+
request: NextRequest,
90+
{ params }: { params: { id: number } },
91+
) {
92+
const cookie = request.cookies.get("access_token");
93+
return await fetch(
94+
`${process.env.BACKEND_URL}/api/informations/comments/${params.id}`,
95+
{
96+
method: "DELETE",
97+
headers: {
98+
Cookie: `${cookie?.name}=${cookie?.value}`,
99+
},
100+
cache: "no-store",
101+
},
102+
);
103+
}

src/app/informations/(detail)/[id]/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Breadcrumbs from "@/components/common/Breadcrumb";
22
import InformationViewer from "@/components/informations/detail/InformationViewer";
33
import RecommendationList from "@/components/informations/detail/RecommendationList";
4+
import CommentListContainer from "@/containers/informations/detail/comment/CommentListContainer";
45
import { InformationDetailDto } from "@/types/InformationDto";
56
import { cookies } from "next/headers";
67

@@ -61,7 +62,7 @@ export default async function page({ params: { id } }: Props) {
6162
]}
6263
/>
6364
<InformationViewer informationId={informationId} data={data} />
64-
{/* <CommentListContainer informationId={informationId} /> */}
65+
<CommentListContainer informationId={informationId} />
6566
<RecommendationList data={data} />
6667
</div>
6768
);
Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import useModalState from "@/hooks/useModalState";
22
import useOutsideClick from "@/hooks/useOutsideClick";
33
import useAuthStore from "@/store/authStore";
4-
import { ModalState } from "@/types/ModalState";
54
import Image from "next/image";
65
import Link from "next/link";
76
import { useRouter } from "next/navigation";
@@ -10,10 +9,11 @@ import UserImage from "./UserImage";
109

1110
const UserDropDown = () => {
1211
const authStore = useAuthStore();
13-
const modalState = useModalState();
12+
const modalState = useModalState();
1413
const router = useRouter();
1514
const ref = useRef<any>();
1615
const ref1 = useRef<any>();
16+
1717
const logoutHandler = async () => {
1818
// api로 로그아웃 요청해서 쿠키제거
1919
const response = await fetch("/api/auth/logout", {
@@ -23,6 +23,7 @@ const UserDropDown = () => {
2323
if (!response.ok) {
2424
throw new Error(response.statusText);
2525
}
26+
2627
authStore.initialize();
2728
router.push("/");
2829
router.refresh();
@@ -34,7 +35,7 @@ const UserDropDown = () => {
3435

3536
return (
3637
<button
37-
className="flex items-center gap-x-2 w-full"
38+
className="flex w-full items-center gap-x-2"
3839
onClick={(e) => {
3940
if (!modalState.isOpen) {
4041
modalState.openModal();
@@ -44,7 +45,10 @@ const UserDropDown = () => {
4445
// 클릭된 요소가 ref 요소 내부에 포함되지 않으면
4546
if (!ref.current.contains(e.target as Node)) {
4647
modalState.closeModal();
47-
} else if (ref.current.contains(e.target as Node) && !ref1.current.contains(e.target as Node)) {
48+
} else if (
49+
ref.current.contains(e.target as Node) &&
50+
!ref1.current.contains(e.target as Node)
51+
) {
4852
modalState.closeModal();
4953
}
5054
}
@@ -60,45 +64,46 @@ const UserDropDown = () => {
6064
<span className="overflow-hidden text-ellipsis whitespace-nowrap font-bold">
6165
{authStore.nickname}
6266
</span>
63-
{
64-
modalState.isOpen &&
67+
{modalState.isOpen && (
6568
<section
6669
ref={ref1}
67-
onClick={(e)=>e.preventDefault()}
68-
className={"fixed right-0 top-[4rem] gap-y-4 p-4 rounded-2xl h-auto bg-white w-[20rem] flex flex-col outline outline-[0.0625rem] outline-offset-[-0.0625rem] outline-primary-20 outline-gray2 cursor-default"}>
69-
<div className="relative w-full flex justify-center h-[12rem] items-center p-4 rounded-[1rem] ">
70+
onClick={(e) => e.preventDefault()}
71+
className="outline-primary-20 fixed right-0 top-[4rem] flex h-auto w-[20rem] cursor-default flex-col gap-y-4 rounded-2xl bg-white p-4 outline outline-[0.0625rem] outline-offset-[-0.0625rem] outline-gray2"
72+
>
73+
<div className="relative flex h-[12rem] w-full items-center justify-center p-4">
7074
<Image
75+
className="rounded-full border-[0.03125rem] border-[#B8EDD9] bg-lightGreen"
7176
src={authStore.userImage.address}
72-
alt={"유저 이미지"}
77+
alt="유저 이미지"
7378
width={140}
7479
height={140}
7580
/>
7681
</div>
7782
<Link
78-
href={"/mypage?mainCategory=정보&category=owner"}
79-
className={"flex gap-x-2 items-center px-8 py-2 justify-center bg-white outline outline-[0.0625rem] outline-offset-[-0.0625rem] outline-gray3 outline-primary-20 rounded-[1rem]"}
83+
href="/mypage?mainCategory=정보&category=owner"
84+
className="outline-primary-20 flex items-center justify-center gap-x-2 rounded-[1rem] bg-white px-8 py-2 outline outline-[0.0625rem] outline-offset-[-0.0625rem] outline-gray3"
8085
onClick={() => modalState.closeModal()}
8186
prefetch={true}
8287
>
83-
<div className={"relative w-[1.25rem] h-[1.25rem]"}>
88+
<div className="relative h-[1.25rem] w-[1.25rem]">
8489
<Image
8590
className="aspect-square"
8691
src="/home/mypage-icon.svg"
8792
alt="signin-icon"
8893
fill
8994
/>
9095
</div>
91-
마이페이지
96+
마이페이지
9297
</Link>
9398
<button
9499
onClick={logoutHandler}
95-
className="px-8 py-2 bg-main rounded-2xl font-semibold text-white"
100+
className="rounded-2xl bg-main px-8 py-2 font-semibold text-white"
96101
>
97-
로그아웃
102+
로그아웃
98103
</button>
99-
</section>
100-
}
104+
</section>
105+
)}
101106
</button>
102107
);
103108
};
104-
export default UserDropDown;
109+
export default UserDropDown;

src/components/common/DeleteModal.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import HashSpinner from "./HashSpinner";
22

3-
interface Props {
3+
interface DeleteModalProps {
44
loading: boolean;
55
onDeleteClick: () => void;
66
onCancelClick: () => void;
77
}
88

9-
const DeleteModal = ({ loading, onDeleteClick, onCancelClick }: Props) => {
9+
const DeleteModal = ({
10+
loading,
11+
onDeleteClick,
12+
onCancelClick,
13+
}: DeleteModalProps) => {
1014
return (
1115
<div className="fixed left-0 top-0 z-50 flex h-full w-full items-center justify-center bg-black/25">
1216
<HashSpinner loading={loading} />

0 commit comments

Comments
 (0)