-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #248 from TripInfoWeb/dev_support
Dev support
- Loading branch information
Showing
21 changed files
with
933 additions
and
589 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { NextRequest } from "next/server"; | ||
|
||
/** | ||
* 공지사항 목록 조회 | ||
*/ | ||
export async function GET(request: NextRequest) { | ||
const url = new URL(request.url); | ||
const page = url.searchParams.get("page") || "1"; | ||
|
||
// 페이지 번호를 0 기반으로 조정합니다. | ||
const zeroBasedPage = Number(page) - 1; | ||
|
||
const apiUrl = `${process.env.BACKEND_URL}/api/notice${zeroBasedPage > 0 ? `?page=${zeroBasedPage}` : ""}`; | ||
|
||
// 백엔드 API 호출 | ||
const response = await fetch(apiUrl, { | ||
method: "GET", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
cache: "no-cache", | ||
}); | ||
|
||
return response; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { NextRequest, NextResponse } from "next/server"; | ||
|
||
/** | ||
* qna 등록 | ||
*/ | ||
export async function POST(request: NextRequest) { | ||
const access_cookie = request.cookies.get("access_token"); | ||
if (!access_cookie) { | ||
const refresh_cookie = request.cookies.get("refresh_token"); | ||
if (!refresh_cookie) { | ||
// 리프레시 토큰이 없으므로 요청 중단 | ||
return new NextResponse("Refresh token not found", { status: 403 }); | ||
} | ||
// 리프레시 토큰으로 재발급 받아 재요청 보내기 위한 응답 | ||
return new NextResponse("Refresh token not found", { status: 401 }); | ||
} | ||
const bodyData = await request.json(); | ||
|
||
const response = await fetch(`${process.env.BACKEND_URL}/api/qna`, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Cookie: `${access_cookie?.name}=${access_cookie?.value}`, | ||
}, | ||
body: JSON.stringify(bodyData), | ||
cache: "no-store", | ||
}); | ||
|
||
return response; | ||
} | ||
|
||
/** | ||
* qna 리스트 페이지네이션 | ||
*/ | ||
export async function GET(request: NextRequest) { | ||
// 요청에서 access_token을 가져옵니다. | ||
const access_cookie = request.cookies.get("access_token"); | ||
|
||
if (!access_cookie) { | ||
// access_token이 없으면 refresh_token이 있는지 확인합니다. | ||
const refresh_cookie = request.cookies.get("refresh_token"); | ||
if (!refresh_cookie) { | ||
// refresh_token이 없는 경우 요청을 중단하고 403 응답을 보냅니다. | ||
return new NextResponse("Refresh token not found", { status: 403 }); | ||
} | ||
// refresh_token만으로는 유효하지 않으므로 401 응답을 보냅니다. | ||
return new NextResponse("Access token not found", { status: 401 }); | ||
} | ||
|
||
// 요청 URL에서 쿼리 파라미터를 가져옵니다. | ||
const url = new URL(request.url); | ||
const page = url.searchParams.get("page") || "1"; // 페이지가 없으면 기본값으로 1을 사용합니다. | ||
|
||
// 페이지 번호를 0 기반으로 조정합니다. | ||
const zeroBasedPage = Number(page) - 1; | ||
|
||
// URL을 페이지 번호에 맞게 수정합니다. 페이지 번호가 0보다 큰 경우에만 쿼리 파라미터를 추가합니다. | ||
const apiUrl = `${process.env.BACKEND_URL}/api/qna${zeroBasedPage > 0 ? `?page=${zeroBasedPage}` : ""}`; | ||
|
||
// 백엔드 API 호출 | ||
const response = await fetch(apiUrl, { | ||
method: "GET", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Cookie: `${access_cookie?.name}=${access_cookie?.value}`, | ||
}, | ||
cache: "no-store", | ||
}); | ||
|
||
return response; | ||
} | ||
|
||
/** | ||
* qna 삭제 | ||
*/ | ||
export async function DELETE(request: NextRequest) { | ||
const access_cookie = request.cookies.get("access_token"); | ||
if (!access_cookie) { | ||
const refresh_cookie = request.cookies.get("refresh_token"); | ||
if (!refresh_cookie) { | ||
// 리프레시 토큰이 없으므로 요청 중단 | ||
return new NextResponse("Refresh token not found", { status: 403 }); | ||
} | ||
// 리프레시 토큰으로 재발급 받아 재요청 보내기 위한 응답 | ||
return new NextResponse("Refresh token not found", { status: 401 }); | ||
} | ||
const url = new URL(request.url); | ||
|
||
const response = await fetch( | ||
`${process.env.BACKEND_URL}/api/qna/${url.searchParams.get("id")}`, | ||
{ | ||
method: "DELETE", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Cookie: `${access_cookie?.name}=${access_cookie?.value}`, | ||
}, | ||
cache: "no-store", | ||
}, | ||
); | ||
|
||
return response; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { NextRequest, NextResponse } from "next/server"; | ||
|
||
/** | ||
* qna 질문 등록 | ||
*/ | ||
export async function POST(request: NextRequest) { | ||
const access_cookie = request.cookies.get("access_token"); | ||
if (!access_cookie) { | ||
const refresh_cookie = request.cookies.get("refresh_token"); | ||
if (!refresh_cookie) { | ||
// 리프레시 토큰이 없으므로 요청 중단 | ||
return new NextResponse("Refresh token not found", { status: 403 }); | ||
} | ||
// 리프레시 토큰으로 재발급 받아 재요청 보내기 위한 응답 | ||
return new NextResponse("Refresh token not found", { status: 401 }); | ||
} | ||
|
||
const bodyData = await request.json(); | ||
|
||
const response = await fetch(`${process.env.BACKEND_URL}/api/qna/question`, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Cookie: `${access_cookie?.name}=${access_cookie?.value}`, | ||
}, | ||
body: JSON.stringify(bodyData), | ||
cache: "no-store", | ||
}); | ||
|
||
return response; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// app/page.tsx | ||
import SupportNoticeDetail from "@/components/support/SupportNoticeDetail"; | ||
import { Metadata } from "next"; | ||
import { cookies } from "next/headers"; | ||
|
||
export const metadata: Metadata = { | ||
title: "공지사항 상세조회", | ||
description: "공지사항 상세조회", | ||
}; | ||
|
||
interface PageProps { | ||
params: { id: string }; | ||
} | ||
|
||
async function fetchData(id: number) { | ||
const cookie = cookies().get("access_token"); | ||
|
||
try { | ||
const res = await fetch( | ||
`${process.env.BACKEND_URL}/api/notice/${id}`, | ||
{ | ||
headers: { | ||
"Content-Type": "application/json", | ||
Cookie: `${cookie?.name}=${cookie?.value}`, | ||
}, | ||
next: { revalidate: 3600 }, | ||
}, | ||
); | ||
if (!res.ok) { | ||
throw new Error(`Failed to fetch data: ${res.statusText}`); | ||
} | ||
return res.json(); | ||
} catch (error) { | ||
return { error: "Failed to fetch data" }; | ||
} | ||
} | ||
|
||
export default async function Page({ params: { id } }: PageProps) { | ||
const noticeId = Number(id); | ||
if (noticeId <= 0 || !Number.isSafeInteger(noticeId)) { | ||
throw Error("Not Found"); | ||
} | ||
|
||
const data = await fetchData(noticeId); | ||
|
||
return ( | ||
<SupportNoticeDetail data={data} /> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,55 @@ | ||
import SupportQnADetailEditContainer from "@/containers/support/qna/SupportQnADetailEditContainer"; | ||
import { Metadata } from "next"; | ||
import { QnADetailType } from "@/types/QnADto"; | ||
import { fetchWithAuth } from "@/utils/fetchWithAuth"; | ||
import { cookies } from "next/headers"; | ||
|
||
export const metadata: Metadata = { | ||
title: "마이페이지", | ||
description: "Solitour 사용자 마이페이지", | ||
}; | ||
interface Props { | ||
params: { id: string }; | ||
} | ||
|
||
export async function generateMetadata({ params: { id } }: Props) { | ||
const qnaId = Number(id); | ||
if (qnaId <= 0 || !Number.isSafeInteger(qnaId)) { | ||
throw Error("Not Found"); | ||
} | ||
|
||
return { | ||
title: `공지사항 조회`, | ||
description: "공지사항 상세조회", | ||
}; | ||
} | ||
|
||
async function fetchData(id: number) { | ||
const cookie = cookies().get("access_token"); | ||
|
||
const res = await fetchWithAuth(`${process.env.BACKEND_URL}/api/qna/${id}`, { | ||
headers: { | ||
"Content-Type": "application/json", | ||
Cookie: `${cookie?.name}=${cookie?.value}`, | ||
}, | ||
}); | ||
|
||
console.log("page.tsx 파일 : ",res.status); | ||
console.log("page.tsx 파일 : ",cookie); | ||
|
||
if (!res.ok) { | ||
throw new Error(`Failed to fetch data: ${res.statusText}`); | ||
} | ||
|
||
return res.json(); | ||
} | ||
|
||
export default async function Page({ params: { id } }: Props) { | ||
const qnaId = Number(id); | ||
if (qnaId <= 0 || !Number.isSafeInteger(qnaId)) { | ||
throw Error("Not Found"); | ||
} | ||
|
||
const data: QnADetailType = await fetchData(qnaId); | ||
|
||
export default async function page() { | ||
return ( | ||
<main | ||
className={ | ||
"w-full mt-4 mb-8" | ||
} | ||
> | ||
<SupportQnADetailEditContainer /> | ||
<main className="mb-8 w-full"> | ||
<SupportQnADetailEditContainer data={data} /> | ||
</main> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"use client"; | ||
|
||
import { NoticeType } from "@/types/NoticeDto"; | ||
import { NOTICE_DETAIL_BREADCRUMB_PATH } from "@/utils/constant/BreadCrumbDirectory"; | ||
import { format } from "date-fns"; | ||
import Breadcrumbs from "../common/Breadcrumb"; | ||
|
||
interface ISupportNoticeDetail { | ||
data: NoticeType; | ||
} | ||
|
||
const SupportNoticeDetail = ({ data }: ISupportNoticeDetail) => { | ||
const categoryStyles: { [key: string]: string } = { | ||
이벤트: "bg-green-100 text-green-800", | ||
공지: "bg-blue-100 text-blue-800", | ||
점검: "bg-yellow-100 text-yellow-800", | ||
기타: "bg-gray-100 text-gray-800", | ||
}; | ||
|
||
return ( | ||
<div className={"flex w-full flex-col"}> | ||
<Breadcrumbs categories={NOTICE_DETAIL_BREADCRUMB_PATH(data.id)} /> | ||
<div className="mb-8 flex min-h-[calc(100vh-160px)] w-full flex-col rounded-lg border border-gray-300 bg-white p-6 shadow-lg"> | ||
{/* 카테고리 및 날짜 */} | ||
<div className="mb-6 flex items-center justify-between"> | ||
<div | ||
className={`inline-block rounded-full px-4 py-2 text-sm font-semibold ${categoryStyles[data.categoryName]}`} | ||
> | ||
{data.categoryName} | ||
</div> | ||
|
||
<div className="text-sm text-gray-600"> | ||
{format(new Date(data.createdAt), "yyyy-MM-dd")} | ||
</div> | ||
</div> | ||
|
||
{/* 제목 */} | ||
<div className="mb-4 text-3xl font-extrabold text-gray-900"> | ||
{data.title} | ||
</div> | ||
|
||
<hr className="my-4 border-t-2 border-gray-300" /> | ||
|
||
{/* 본문 내용 */} | ||
<div className="text-lg text-gray-800">{data.content}</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default SupportNoticeDetail; |
Oops, something went wrong.