From 287fd2d2aa3bde2f84dfd293c2e3258ecb1616b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=84=EC=84=9D?= Date: Thu, 14 Nov 2024 15:44:23 +0900 Subject: [PATCH] =?UTF-8?q?[FEAT]=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8?= =?UTF-8?q?=20=EB=AC=B8=EC=9D=98=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 프로젝트 문의 페이지 초안 작성 * fix: inquiry 타입 추가 * feat: TitleRow 컴포넌트 추가 * feat: 프로젝트 문의 api 연결 --- .../admin/projects/inquiries/[id]/page.tsx | 11 ++ .../(admin)/admin/projects/inquiries/page.tsx | 10 +- .../common/TitleRow/TitleRow.module.css | 14 ++ src/components/common/TitleRow/TitleRow.tsx | 24 ++++ .../AdminInquiriesEditForm.tsx | 127 +++++++++++++++++ .../AdminInquiriesListSection.tsx | 134 ++++++++++++++++++ src/constants/DataTableHeaders.ts | 8 ++ src/hooks/swr/useInquiries.tsx | 30 ++++ src/types/inquiry.ts | 19 +++ 9 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 src/app/(admin)/admin/projects/inquiries/[id]/page.tsx create mode 100644 src/components/common/TitleRow/TitleRow.module.css create mode 100644 src/components/common/TitleRow/TitleRow.tsx create mode 100644 src/components/pages/AdminInquiriesEditForm/AdminInquiriesEditForm.tsx create mode 100644 src/components/pages/AdminInquiriesListSection/AdminInquiriesListSection.tsx create mode 100644 src/hooks/swr/useInquiries.tsx create mode 100644 src/types/inquiry.ts diff --git a/src/app/(admin)/admin/projects/inquiries/[id]/page.tsx b/src/app/(admin)/admin/projects/inquiries/[id]/page.tsx new file mode 100644 index 00000000..4f51cb5e --- /dev/null +++ b/src/app/(admin)/admin/projects/inquiries/[id]/page.tsx @@ -0,0 +1,11 @@ +import { PageHeader } from "@/components/common/PageHeader"; +import { AdminInquiriesEditForm } from "@/components/pages/AdminInquiriesEditForm/AdminInquiriesEditForm"; + +export default function AdminInquiriesPage({ params }: { params: { id: string } }) { + return ( +
+ + +
+ ); +} diff --git a/src/app/(admin)/admin/projects/inquiries/page.tsx b/src/app/(admin)/admin/projects/inquiries/page.tsx index 92e6a879..6984a42d 100644 --- a/src/app/(admin)/admin/projects/inquiries/page.tsx +++ b/src/app/(admin)/admin/projects/inquiries/page.tsx @@ -1,3 +1,11 @@ +import { PageHeader } from "@/components/common/PageHeader"; +import AdminInquiriesListSection from "@/components/pages/AdminInquiriesListSection/AdminInquiriesListSection"; + export default function AdminInquiriesPage() { - return
Hello, world!
; + return ( +
+ + +
+ ); } diff --git a/src/components/common/TitleRow/TitleRow.module.css b/src/components/common/TitleRow/TitleRow.module.css new file mode 100644 index 00000000..791d6a27 --- /dev/null +++ b/src/components/common/TitleRow/TitleRow.module.css @@ -0,0 +1,14 @@ +.title { + font-weight: var(--mantine-other-font-weights-bold); + font-size: 24px; +} + +.wrapper { + min-width: 500px; + padding-left: 18px; + padding-right: 20px; + margin-top: 12px; + margin-bottom: 12px; + height: 56px; + width: 100%; +} diff --git a/src/components/common/TitleRow/TitleRow.tsx b/src/components/common/TitleRow/TitleRow.tsx new file mode 100644 index 00000000..61383c53 --- /dev/null +++ b/src/components/common/TitleRow/TitleRow.tsx @@ -0,0 +1,24 @@ +import { Group, MantineStyleProp, Text } from "@mantine/core"; +import { ReactNode } from "react"; +import classes from "./TitleRow.module.css"; + +interface Props { + title: ReactNode; + badge?: ReactNode; + subString?: ReactNode; + style?: MantineStyleProp; +} + +function TitleRow({ title, badge, subString, style }: Props) { + return ( + + + {title} + {badge} + + {subString} + + ); +} + +export default TitleRow; diff --git a/src/components/pages/AdminInquiriesEditForm/AdminInquiriesEditForm.tsx b/src/components/pages/AdminInquiriesEditForm/AdminInquiriesEditForm.tsx new file mode 100644 index 00000000..0857e134 --- /dev/null +++ b/src/components/pages/AdminInquiriesEditForm/AdminInquiriesEditForm.tsx @@ -0,0 +1,127 @@ +"use client"; + +import { PrimaryButton } from "@/components/common/Buttons"; +import { Row } from "@/components/common/Row"; +import { Section } from "@/components/common/Section"; +import { Group, Stack, Textarea, TextInput } from "@mantine/core"; +import { isNotEmpty, useForm } from "@mantine/form"; +import { useEffect, useState } from "react"; +import { useRouter } from "next/navigation"; +import TitleRow from "@/components/common/TitleRow/TitleRow"; +import { Inquiry } from "@/types/inquiry"; +import { CommonAxios } from "@/utils/CommonAxios"; + +interface InquiryEditFormInputs { + title: string; + content: string; +} + +export function AdminInquiriesEditForm({ id }: { id: string }) { + /* next 라우터, 페이지 이동에 이용 */ + const { push } = useRouter(); + + const [inquiry, setInquiry] = useState(null); + const [prevReplyFlag, setPrevReplyFlag] = useState(false); + + // 문의 답변 등록 및 수정을 위한 mantine form hook + const { onSubmit, getInputProps, setValues } = useForm({ + initialValues: { + title: "", + content: "", + }, + validate: { + title: isNotEmpty("제목을 입력해주세요."), + content: isNotEmpty("내용을 입력해주세요."), + }, + }); + + /* id를 통해 데이터 패칭 */ + useEffect(() => { + const fetchInquiry = async () => { + const response = await CommonAxios.get(`/inquiries/${id}`); + setInquiry(response.data); + console.log(response.data); + }; + + const fetchPrevReply = async () => { + const response = await CommonAxios.get(`/inquiries/${id}/reply`); + if (response.data.title.length > 0) { + setPrevReplyFlag(true); + setValues(response.data); + } + }; + + if (id) { + fetchInquiry(); + try { + fetchPrevReply(); + } catch (error) { + console.error(error); + } + } + }, [id]); + + // 문의 답변 등록/수정 request 함수 + const handleSubmit = async (values: InquiryEditFormInputs) => { + try { + if (prevReplyFlag) { + await CommonAxios.put(`/inquiries/${id}/reply`, values); + } else { + await CommonAxios.post(`/inquiries/${id}/reply`, values); + } + push("../inquiries"); + } catch (error) { + console.error(error); + } + }; + + return ( +
+ + + + {inquiry?.projectName} + + + {inquiry?.authorName} + + + {inquiry?.title} + + + {inquiry?.content} + + + +
+ + + + + +