From 1078936f36987745f1e47877f893269aaf7bd21f Mon Sep 17 00:00:00 2001 From: YouD0313 <102004480+YouD0313@users.noreply.github.com> Date: Mon, 9 Jun 2025 01:53:11 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=EB=AC=B8=EC=9D=98=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=EB=A6=AC=EC=8A=A4=ED=8A=B8,=20=EB=AC=B8=EC=9D=98?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=EC=83=81=EC=84=B8=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/activityLog.api.ts | 10 --- src/api/admin/customerService/Inquiry.api.ts | 57 +++++++++++++++++ .../admin/adminInquiry/AdminInquiry.styled.ts | 36 +++++++++++ .../admin/adminInquiry/AdminInquiry.tsx | 24 +++++++ .../adminInquiry/AdminInquiryAnswer.styled.ts | 36 +++++++++++ .../admin/adminInquiry/AdminInquiryAnswer.tsx | 37 +++++++++++ .../adminInquiry/AdminInquiryDetail.styled.ts | 12 ++++ .../admin/adminInquiry/AdminInquiryDetail.tsx | 31 +++++++++ .../AdminInquiryDetailContent.styled.ts | 30 +++++++++ .../AdminInquiryDetailContent.tsx | 24 +++++++ .../adminInquiry/AdminInquiryList.styled.ts | 15 +++++ .../admin/adminInquiry/AdminInquiryList.tsx | 26 ++++++++ src/hooks/admin/useAdminFAQ.ts | 2 +- src/hooks/admin/useAdminInquiry.ts | 63 +++++++++++++++++++ src/hooks/admin/useAdminNotice.ts | 2 +- src/hooks/admin/useGetAllInquiries.ts | 4 +- src/hooks/admin/useGetAllReports.ts | 2 +- src/hooks/admin/useGetAllUsers.ts | 2 +- src/hooks/admin/useGetAllUsersPreview.ts | 2 +- src/hooks/queries/{user => }/keys.ts | 1 + src/hooks/useAuth.ts | 2 +- .../user/CommentHooks/useDeleteComment.ts | 2 +- src/hooks/user/CommentHooks/useDeleteReply.ts | 2 +- src/hooks/user/CommentHooks/useGetComment.ts | 2 +- src/hooks/user/CommentHooks/useGetReply.ts | 2 +- src/hooks/user/CommentHooks/usePatchReply.ts | 2 +- src/hooks/user/CommentHooks/usePostComment.ts | 2 +- src/hooks/user/CommentHooks/usePostReply.ts | 2 +- src/hooks/user/CommentHooks/usePutComment.ts | 2 +- .../user/ProjectHooks/useApplyProject.ts | 2 +- .../user/ProjectHooks/useCreateProject.ts | 2 +- .../user/ProjectHooks/useUpdateProject.ts | 2 +- .../user/evaluationHooks/useGetEvaluation.ts | 2 +- .../user/evaluationHooks/usePostEvaluation.ts | 2 +- src/hooks/user/useAlarmDelete.ts | 2 +- src/hooks/user/useAlarmList.ts | 2 +- src/hooks/user/useAlarmPatch.ts | 2 +- src/hooks/user/useApllicantList.ts | 2 +- src/hooks/user/useApplicantInfo.ts | 2 +- src/hooks/user/useChartData.ts | 2 +- src/hooks/user/useGetFAQ.ts | 2 +- src/hooks/user/useGetMyComments.ts | 2 +- src/hooks/user/useGetMyInquiries.ts | 2 +- src/hooks/user/useGetNotice.ts | 2 +- src/hooks/user/useGetNoticeDetail.ts | 2 +- src/hooks/user/useGetProjectData.ts | 2 +- src/hooks/user/useGetUserProjectList.ts | 2 +- src/hooks/user/useManagedProjects.ts | 2 +- src/hooks/user/useMyInfo.ts | 2 +- src/hooks/user/useNotification.ts | 4 +- src/hooks/user/usePassNonPassList.ts | 2 +- src/hooks/user/usePassNonPassMutation.ts | 2 +- src/hooks/user/usePostInquiry.ts | 2 +- src/hooks/user/useSendResultMutation.ts | 2 +- src/hooks/user/useUserInfo.ts | 2 +- src/models/activityLog.ts | 5 +- src/models/inquiry.ts | 24 +++++++ .../adminInquiries/AdminInquiries.styled.ts | 3 - .../admin/adminInquiries/AdminInquiries.tsx | 4 +- .../AdminInquiryDetailPage.tsx | 5 ++ .../adminInquiryList/AdminInquiryListPage.tsx | 5 ++ .../AdminInquiryWritePage.tsx | 3 + src/routes/AdminRoutes.tsx | 50 +++++++++++++-- 63 files changed, 523 insertions(+), 64 deletions(-) create mode 100644 src/api/admin/customerService/Inquiry.api.ts create mode 100644 src/components/admin/adminInquiry/AdminInquiry.styled.ts create mode 100644 src/components/admin/adminInquiry/AdminInquiry.tsx create mode 100644 src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts create mode 100644 src/components/admin/adminInquiry/AdminInquiryAnswer.tsx create mode 100644 src/components/admin/adminInquiry/AdminInquiryDetail.styled.ts create mode 100644 src/components/admin/adminInquiry/AdminInquiryDetail.tsx create mode 100644 src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts create mode 100644 src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx create mode 100644 src/components/admin/adminInquiry/AdminInquiryList.styled.ts create mode 100644 src/components/admin/adminInquiry/AdminInquiryList.tsx create mode 100644 src/hooks/admin/useAdminInquiry.ts rename src/hooks/queries/{user => }/keys.ts (97%) delete mode 100644 src/pages/admin/adminInquiries/AdminInquiries.styled.ts create mode 100644 src/pages/admin/adminInquiries/adminInquiryDetail/AdminInquiryDetailPage.tsx create mode 100644 src/pages/admin/adminInquiries/adminInquiryList/AdminInquiryListPage.tsx create mode 100644 src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx diff --git a/src/api/activityLog.api.ts b/src/api/activityLog.api.ts index e5a2c5fa..3a2498b0 100644 --- a/src/api/activityLog.api.ts +++ b/src/api/activityLog.api.ts @@ -23,13 +23,3 @@ export const getMyInquiries = async () => { throw e; } }; - -export const getAllInquiries = async () => { - try { - const response = await httpClient.get(`/inquiry`); - return response.data.data; - } catch (e) { - console.error('전체 문의 조회 에러', e); - throw e; - } -}; diff --git a/src/api/admin/customerService/Inquiry.api.ts b/src/api/admin/customerService/Inquiry.api.ts new file mode 100644 index 00000000..7eb5ffa8 --- /dev/null +++ b/src/api/admin/customerService/Inquiry.api.ts @@ -0,0 +1,57 @@ +import type { ApiCommonBasicType } from '../../../models/apiCommon'; +import type { + ApiAdminInquiry, + ApiAdminInquiryDetail, + InquiryAnswerBody, +} from '../../../models/inquiry'; +import { httpClient } from '../../http.api'; + +export const getAllInquiries = async () => { + try { + const response = await httpClient.get(`/inquiry`); + return response.data.data; + } catch (e) { + console.error('전체 문의 조회 에러', e); + throw e; + } +}; + +export const getInquiryDetail = async (id: string) => { + try { + const response = await httpClient.get( + `/inquiry/${id}` + ); + + return response.data.data; + } catch (e) { + console.error(e); + throw e; + } +}; + +export const postInquiryAnswer = async ({ id, answer }: InquiryAnswerBody) => { + try { + await httpClient.post(`/inquiry/${id}/answer`, answer); + } catch (e) { + console.error(e); + throw e; + } +}; + +export const patchInquiryAnswer = async ({ id, answer }: InquiryAnswerBody) => { + try { + await httpClient.patch(`/inquiry/${id}/answer`, answer); + } catch (e) { + console.error(e); + throw e; + } +}; + +export const deleteInquiry = async (id: string) => { + try { + await httpClient.delete(`/inquiry/${id}`); + } catch (e) { + console.error(e); + throw e; + } +}; diff --git a/src/components/admin/adminInquiry/AdminInquiry.styled.ts b/src/components/admin/adminInquiry/AdminInquiry.styled.ts new file mode 100644 index 00000000..d2495df0 --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiry.styled.ts @@ -0,0 +1,36 @@ +import { Link } from 'react-router-dom'; +import styled, { css } from 'styled-components'; + +export const AdminInquiryContainer = styled(Link)``; + +export const AdminInquiryWrapper = styled.div` + padding: 0.8rem; + display: grid; + grid-template-columns: 64% 15% 11% 10%; + justify-content: center; + align-items: center; + font-size: 1.1rem; +`; + +export const AdminInquiryTitle = styled.div``; + +export const AdminInquiryUser = styled.div``; + +export const ADminInquiryDate = styled.span` + font-size: 0.9rem; + color: ${({ theme }) => theme.color.deepGrey}; +`; + +export const AdminInquiryState = styled.div<{ $hasAnswer: boolean }>` + text-align: center; + color: ${({ $hasAnswer, theme }) => + $hasAnswer ? theme.color.white : theme.color.green}; + padding: 0.3rem; + + ${({ $hasAnswer }) => + $hasAnswer && + css` + border-radius: ${({ theme }) => theme.borderRadius.large}; + background: ${({ theme }) => theme.color.navy}; + `} +`; diff --git a/src/components/admin/adminInquiry/AdminInquiry.tsx b/src/components/admin/adminInquiry/AdminInquiry.tsx new file mode 100644 index 00000000..76ffec2a --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiry.tsx @@ -0,0 +1,24 @@ +import { ADMIN_ROUTE } from '../../../constants/routes'; +import type { AdminInquiry } from '../../../models/inquiry'; +import ContentBorder from '../../common/contentBorder/ContentBorder'; +import * as S from './AdminInquiry.styled'; + +interface AdminInquiryProps { + list: AdminInquiry; +} + +export default function AdminInquiry({ list }: AdminInquiryProps) { + return ( + + + {list.title} + {list.user.nickname} + {list.createdAt} + + {list.state ? '답변완료' : '확인중'} + + + + + ); +} diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts b/src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts new file mode 100644 index 00000000..b5d6bb12 --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts @@ -0,0 +1,36 @@ +import styled from 'styled-components'; +import { + AdminInquiryContentContainer, + AdminInquiryContentWrapper, + InquiryContent, + InquiryHeaderWrapper, + InquiryInfo, +} from './AdminInquiryDetailContent.styled'; +import { SendButton } from '../../user/customerService/inquiry/Inquiry.styled'; + +export const InquiryAnswerContentContainer = styled( + AdminInquiryContentContainer +)``; + +export const InquiryAnswerContentWrapper = styled(AdminInquiryContentWrapper)``; + +export const AnswerHeaderWrapper = styled(InquiryHeaderWrapper)` + display: flex; + gap: 3rem; +`; + +export const InquiryAnswerInfo = styled(InquiryInfo)` + display: flex; + align-items: center; +`; + +export const InquiryAnswerButton = styled(SendButton)` + align-items: start; + height: fit-content; + font-size: 0.9rem; + padding: 0.3rem 0.5rem; +`; + +export const AnswerButtonSpan = styled.span``; + +export const InquiryAnswerContent = styled(InquiryContent)``; diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx b/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx new file mode 100644 index 00000000..c51241b0 --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx @@ -0,0 +1,37 @@ +import { useEffect, useState } from 'react'; +import * as S from './AdminInquiryAnswer.styled'; +import { useOutletContext } from 'react-router-dom'; + +interface AdminInquiryDetailContentOutletContext { + createdAt: string; + answerData: string; +} + +export default function AdminInquiryAnswer() { + const { createdAt, answerData }: AdminInquiryDetailContentOutletContext = + useOutletContext(); + + const [answer, setAnswer] = useState(''); + + useEffect(() => { + setAnswer(answerData); + }, [answerData]); + + return ( + + + + + {createdAt ? createdAt : ''} + + + + {answer === null ? '작성하기' : '수정하기'} + + + + {answer} + + + ); +} diff --git a/src/components/admin/adminInquiry/AdminInquiryDetail.styled.ts b/src/components/admin/adminInquiry/AdminInquiryDetail.styled.ts new file mode 100644 index 00000000..103e2042 --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryDetail.styled.ts @@ -0,0 +1,12 @@ +import styled from 'styled-components'; +import { SpinnerWrapperStyled } from '../../user/mypage/Spinner.styled'; + +export const SpinnerWrapper = styled(SpinnerWrapperStyled)``; + +export const AdminInquiryDetailContainer = styled.main` + width: 100%; + display: flex; + flex-direction: column; + justify-content: center; + gap: 1.5rem; +`; diff --git a/src/components/admin/adminInquiry/AdminInquiryDetail.tsx b/src/components/admin/adminInquiry/AdminInquiryDetail.tsx new file mode 100644 index 00000000..8b8db608 --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryDetail.tsx @@ -0,0 +1,31 @@ +import { Outlet, useParams } from 'react-router-dom'; +import * as S from './AdminInquiryDetail.styled'; +import AdminInquiryDetailContent from './AdminInquiryDetailContent'; +import { useAdminInquiry } from '../../../hooks/admin/useAdminInquiry'; +import Spinner from '../../user/mypage/Spinner'; + +export default function AdminInquiryDetail() { + const { inquiryId } = useParams(); + const id = inquiryId || ''; + const { getInquiryDetailData } = useAdminInquiry(id); + const { data, isLoading } = getInquiryDetailData; + + if (isLoading) { + return ( + + + + ); + } + + if (!data) return; + + return ( + + + + + ); +} diff --git a/src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts b/src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts new file mode 100644 index 00000000..888aed44 --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts @@ -0,0 +1,30 @@ +import styled from 'styled-components'; + +export const AdminInquiryContentContainer = styled.section` + width: 95%; + padding: 1rem; + border: 1px solid ${({ theme }) => theme.color.border}; + border-radius: ${({ theme }) => theme.borderRadius.primary}; +`; + +export const AdminInquiryContentWrapper = styled.div``; + +export const InquiryHeaderWrapper = styled.header` + margin-bottom: 0.5rem; +`; + +export const InquiryTitle = styled.div` + font-size: 1.5rem; + font-weight: 600; + margin-bottom: 0.5rem; +`; + +export const InquiryInfo = styled.div` + font-size: 0.9rem; + color: ${({ theme }) => theme.color.placeholder}; +`; + +export const InquiryContent = styled.div` + font-size: 1.1rem; + width: 100%; +`; diff --git a/src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx b/src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx new file mode 100644 index 00000000..62583e9a --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx @@ -0,0 +1,24 @@ +import type { MyInquiries } from '../../../models/activityLog'; +import * as S from './AdminInquiryDetailContent.styled'; + +interface AdminInquiryDetailContentProps { + inquiry: MyInquiries; +} + +export default function AdminInquiryDetailContent({ + inquiry, +}: AdminInquiryDetailContentProps) { + console.log(inquiry); + + return ( + + + + {`[${inquiry.category}] ${inquiry.title}`} + {`${inquiry.user.nickname} | ${inquiry.createdAt}`} + + {inquiry.content} + + + ); +} diff --git a/src/components/admin/adminInquiry/AdminInquiryList.styled.ts b/src/components/admin/adminInquiry/AdminInquiryList.styled.ts new file mode 100644 index 00000000..152ad450 --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryList.styled.ts @@ -0,0 +1,15 @@ +import styled from 'styled-components'; +import { SpinnerWrapperStyled } from '../../user/mypage/Spinner.styled'; + +export const SpinnerWrapper = styled(SpinnerWrapperStyled)``; + +export const AdminInquiryListContainer = styled.section` + width: 100%; + display: flex; + justify-content: center; +`; + +export const AdminInquiryListWrapper = styled.div` + width: 90%; + margin-bottom: 5rem; +`; diff --git a/src/components/admin/adminInquiry/AdminInquiryList.tsx b/src/components/admin/adminInquiry/AdminInquiryList.tsx new file mode 100644 index 00000000..184c4ceb --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryList.tsx @@ -0,0 +1,26 @@ +import { useGetAllInquiries } from '../../../hooks/admin/useGetAllInquiries'; +import Spinner from '../../user/mypage/Spinner'; +import AdminInquiry from './AdminInquiry'; +import * as S from './AdminInquiryList.styled'; + +export default function AdminInquiryList() { + const { allInquiriesData, isLoading } = useGetAllInquiries(); + + if (isLoading) { + + + ; + } + + if (!allInquiriesData) return; + + return ( + + + {allInquiriesData.map((list) => ( + + ))} + + + ); +} diff --git a/src/hooks/admin/useAdminFAQ.ts b/src/hooks/admin/useAdminFAQ.ts index 6b93e022..a9eabc3d 100644 --- a/src/hooks/admin/useAdminFAQ.ts +++ b/src/hooks/admin/useAdminFAQ.ts @@ -9,7 +9,7 @@ import type { WriteBody } from '../../models/customerService'; import { AxiosError } from 'axios'; import { useNavigate } from 'react-router-dom'; import { ADMIN_MODAL_MESSAGE } from '../../constants/admin/adminModal'; -import { CustomerService } from '../queries/user/keys'; +import { CustomerService } from '../queries/keys'; type State = 'success' | 'fail'; diff --git a/src/hooks/admin/useAdminInquiry.ts b/src/hooks/admin/useAdminInquiry.ts new file mode 100644 index 00000000..f63e4e9a --- /dev/null +++ b/src/hooks/admin/useAdminInquiry.ts @@ -0,0 +1,63 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { + deleteInquiry, + getInquiryDetail, + postInquiryAnswer, +} from '../../api/admin/customerService/Inquiry.api'; +import { InquiryAnswerBody } from '../../models/inquiry'; +import { AxiosError } from 'axios'; +import { CustomerService } from '../queries/keys'; + +export const useAdminInquiry = (id: string) => { + const queryClient = useQueryClient(); + + const getInquiryDetailData = useQuery({ + queryKey: [CustomerService.inquiryDetail, id], + queryFn: () => getInquiryDetail(id), + enabled: !!id, + }); + + const postInquiryAnswerMutate = useMutation< + void, + AxiosError, + InquiryAnswerBody + >({ + mutationFn: ({ id, answer }: InquiryAnswerBody) => + postInquiryAnswer({ id, answer }), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: [CustomerService.inquiryDetail, id], + }); + }, + }); + + const patchInquiryAnswerMutate = useMutation< + void, + AxiosError, + InquiryAnswerBody + >({ + mutationFn: ({ id, answer }: InquiryAnswerBody) => + postInquiryAnswer({ id, answer }), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: [CustomerService.inquiryDetail, id], + }); + }, + }); + + const deleteInquiryMutate = useMutation({ + mutationFn: (id: string) => deleteInquiry(id), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: [CustomerService.inquiryDetail, id], + }); + }, + }); + + return { + getInquiryDetailData, + postInquiryAnswerMutate, + patchInquiryAnswerMutate, + deleteInquiryMutate, + }; +}; diff --git a/src/hooks/admin/useAdminNotice.ts b/src/hooks/admin/useAdminNotice.ts index fb352eb2..e06a5cac 100644 --- a/src/hooks/admin/useAdminNotice.ts +++ b/src/hooks/admin/useAdminNotice.ts @@ -5,7 +5,7 @@ import { putNotice, } from '../../api/admin/customerService/Notice.api'; import { AxiosError } from 'axios'; -import { CustomerService } from '../queries/user/keys'; +import { CustomerService } from '../queries/keys'; import { useNavigate } from 'react-router-dom'; import { ADMIN_MODAL_MESSAGE } from '../../constants/admin/adminModal'; import { WriteBody } from '../../models/customerService'; diff --git a/src/hooks/admin/useGetAllInquiries.ts b/src/hooks/admin/useGetAllInquiries.ts index b4b7b797..4abb9aa3 100644 --- a/src/hooks/admin/useGetAllInquiries.ts +++ b/src/hooks/admin/useGetAllInquiries.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { getAllInquiries } from '../../api/activityLog.api'; -import { Inquiries } from '../queries/user/keys'; +import { Inquiries } from '../queries/keys'; +import { getAllInquiries } from '../../api/admin/customerService/Inquiry.api'; export const useGetAllInquiries = () => { const { diff --git a/src/hooks/admin/useGetAllReports.ts b/src/hooks/admin/useGetAllReports.ts index ab7c1f31..de128ee5 100644 --- a/src/hooks/admin/useGetAllReports.ts +++ b/src/hooks/admin/useGetAllReports.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { ReportData } from '../queries/user/keys'; +import { ReportData } from '../queries/keys'; import { getAllReports } from '../../api/report.api'; export const useGetAllReports = () => { diff --git a/src/hooks/admin/useGetAllUsers.ts b/src/hooks/admin/useGetAllUsers.ts index 243fffea..36294486 100644 --- a/src/hooks/admin/useGetAllUsers.ts +++ b/src/hooks/admin/useGetAllUsers.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { UserData } from '../queries/user/keys'; +import { UserData } from '../queries/keys'; import { getAllUsers } from '../../api/auth.api'; import type { SearchType } from '../../models/search'; diff --git a/src/hooks/admin/useGetAllUsersPreview.ts b/src/hooks/admin/useGetAllUsersPreview.ts index 9a90d386..b1b5d6bc 100644 --- a/src/hooks/admin/useGetAllUsersPreview.ts +++ b/src/hooks/admin/useGetAllUsersPreview.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { UserData } from '../queries/user/keys'; +import { UserData } from '../queries/keys'; import { getAllUsersPreview } from '../../api/auth.api'; export const useGetAllUsersPreview = () => { diff --git a/src/hooks/queries/user/keys.ts b/src/hooks/queries/keys.ts similarity index 97% rename from src/hooks/queries/user/keys.ts rename to src/hooks/queries/keys.ts index 1c50aa6b..36e571a6 100644 --- a/src/hooks/queries/user/keys.ts +++ b/src/hooks/queries/keys.ts @@ -57,6 +57,7 @@ export const CustomerService = { faq: 'faq', notice: 'notice', noticeDetail: 'noticeDetail', + inquiryDetail: 'inquiryDetail', }; export const ReportData = { diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts index b8741ce0..590862a5 100644 --- a/src/hooks/useAuth.ts +++ b/src/hooks/useAuth.ts @@ -6,7 +6,7 @@ import useAuthStore from '../store/authStore'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import type { LoginResponse } from '../models/auth'; import { AxiosError } from 'axios'; -import { myInfoKey } from './queries/user/keys'; +import { myInfoKey } from './queries/keys'; import { MODAL_MESSAGE } from '../constants/user/modalMessage'; import { ROUTES } from '../constants/routes'; import { registerFormValues } from '../pages/user/register/Register'; diff --git a/src/hooks/user/CommentHooks/useDeleteComment.ts b/src/hooks/user/CommentHooks/useDeleteComment.ts index 5c9a4c22..b3457edf 100644 --- a/src/hooks/user/CommentHooks/useDeleteComment.ts +++ b/src/hooks/user/CommentHooks/useDeleteComment.ts @@ -1,5 +1,5 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { ProjectCommentList } from '../../queries/user/keys'; +import { ProjectCommentList } from '../../queries/keys'; import { deleteComment } from '../../../api/comment.api'; const useDeleteComment = (id: number) => { diff --git a/src/hooks/user/CommentHooks/useDeleteReply.ts b/src/hooks/user/CommentHooks/useDeleteReply.ts index 923911c2..fc5eae7b 100644 --- a/src/hooks/user/CommentHooks/useDeleteReply.ts +++ b/src/hooks/user/CommentHooks/useDeleteReply.ts @@ -1,5 +1,5 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { ProjectReplyList } from '../../queries/user/keys'; +import { ProjectReplyList } from '../../queries/keys'; import { deleteReply } from '../../../api/reply.api'; const useDeleteReply = (commentId: number, projectId: number) => { diff --git a/src/hooks/user/CommentHooks/useGetComment.ts b/src/hooks/user/CommentHooks/useGetComment.ts index b36c6b5a..644850f8 100644 --- a/src/hooks/user/CommentHooks/useGetComment.ts +++ b/src/hooks/user/CommentHooks/useGetComment.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; import { getComment } from '../../../api/comment.api'; -import { ProjectCommentList } from '../../queries/user/keys'; +import { ProjectCommentList } from '../../queries/keys'; const useGetComment = (id: number) => { const { data, isLoading, isFetching, isError } = useQuery({ diff --git a/src/hooks/user/CommentHooks/useGetReply.ts b/src/hooks/user/CommentHooks/useGetReply.ts index 340a2ece..840dc016 100644 --- a/src/hooks/user/CommentHooks/useGetReply.ts +++ b/src/hooks/user/CommentHooks/useGetReply.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { ProjectReplyList } from '../../queries/user/keys'; +import { ProjectReplyList } from '../../queries/keys'; import { getReply } from '../../../api/reply.api'; const useGetReply = (projectId: number, commentId: number) => { diff --git a/src/hooks/user/CommentHooks/usePatchReply.ts b/src/hooks/user/CommentHooks/usePatchReply.ts index bdd2a558..0f7f1307 100644 --- a/src/hooks/user/CommentHooks/usePatchReply.ts +++ b/src/hooks/user/CommentHooks/usePatchReply.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { putReply } from '../../../api/reply.api'; -import { ProjectReplyList } from '../../queries/user/keys'; +import { ProjectReplyList } from '../../queries/keys'; const usePatchReply = ( recommentId: number | undefined, diff --git a/src/hooks/user/CommentHooks/usePostComment.ts b/src/hooks/user/CommentHooks/usePostComment.ts index ab4af545..5113c039 100644 --- a/src/hooks/user/CommentHooks/usePostComment.ts +++ b/src/hooks/user/CommentHooks/usePostComment.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { postComment } from '../../../api/comment.api'; -import { ProjectCommentList } from '../../queries/user/keys'; +import { ProjectCommentList } from '../../queries/keys'; const usePostComment = (id: number) => { const queryClient = useQueryClient(); diff --git a/src/hooks/user/CommentHooks/usePostReply.ts b/src/hooks/user/CommentHooks/usePostReply.ts index 4115fe55..aa3df68a 100644 --- a/src/hooks/user/CommentHooks/usePostReply.ts +++ b/src/hooks/user/CommentHooks/usePostReply.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { postReply } from '../../../api/reply.api'; -import { ProjectReplyList } from '../../queries/user/keys'; +import { ProjectReplyList } from '../../queries/keys'; const usePostReply = (projectId: number, commentId: number) => { const queryClient = useQueryClient(); diff --git a/src/hooks/user/CommentHooks/usePutComment.ts b/src/hooks/user/CommentHooks/usePutComment.ts index c1ac279c..0147c5b0 100644 --- a/src/hooks/user/CommentHooks/usePutComment.ts +++ b/src/hooks/user/CommentHooks/usePutComment.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { patchComment } from '../../../api/comment.api'; -import { ProjectCommentList } from '../../queries/user/keys'; +import { ProjectCommentList } from '../../queries/keys'; const usePutComment = (id: number, commentId: number) => { const queryClient = useQueryClient(); diff --git a/src/hooks/user/ProjectHooks/useApplyProject.ts b/src/hooks/user/ProjectHooks/useApplyProject.ts index c925ac94..60dfe985 100644 --- a/src/hooks/user/ProjectHooks/useApplyProject.ts +++ b/src/hooks/user/ProjectHooks/useApplyProject.ts @@ -1,5 +1,5 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { ProjectListKey, userInfoKey } from '../../queries/user/keys'; +import { ProjectListKey, userInfoKey } from '../../queries/keys'; import { useNavigate } from 'react-router-dom'; import { postApplicantProject } from '../../../api/joinProject.api'; import { joinProject } from '../../../models/joinProject'; diff --git a/src/hooks/user/ProjectHooks/useCreateProject.ts b/src/hooks/user/ProjectHooks/useCreateProject.ts index 403f6a7a..eca51778 100644 --- a/src/hooks/user/ProjectHooks/useCreateProject.ts +++ b/src/hooks/user/ProjectHooks/useCreateProject.ts @@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import { postProject } from '../../../api/joinProject.api'; import { MODAL_MESSAGE } from '../../../constants/user/modalMessage'; -import { managedProjectKey } from '../../queries/user/keys'; +import { managedProjectKey } from '../../queries/keys'; import { ROUTES } from '../../../constants/routes'; import type { FormData } from '../../../models/createProject'; diff --git a/src/hooks/user/ProjectHooks/useUpdateProject.ts b/src/hooks/user/ProjectHooks/useUpdateProject.ts index a1ea85a6..bcce15f8 100644 --- a/src/hooks/user/ProjectHooks/useUpdateProject.ts +++ b/src/hooks/user/ProjectHooks/useUpdateProject.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import { putProject } from '../../../api/joinProject.api'; -import { managedProjectKey } from '../../queries/user/keys'; +import { managedProjectKey } from '../../queries/keys'; import type { FormData } from '../../../models/createProject'; import { MODAL_MESSAGE } from '../../../constants/user/modalMessage'; import { ROUTES } from '../../../constants/routes'; diff --git a/src/hooks/user/evaluationHooks/useGetEvaluation.ts b/src/hooks/user/evaluationHooks/useGetEvaluation.ts index 25b33338..5f22dd74 100644 --- a/src/hooks/user/evaluationHooks/useGetEvaluation.ts +++ b/src/hooks/user/evaluationHooks/useGetEvaluation.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; import { getEvaluation } from '../../../api/evaluation.api'; -import { ProjectMemberListEval } from '../../queries/user/keys'; +import { ProjectMemberListEval } from '../../queries/keys'; import { useEffect } from 'react'; import { MODAL_MESSAGE } from '../../../constants/user/modalMessage'; import { useNavigate } from 'react-router-dom'; diff --git a/src/hooks/user/evaluationHooks/usePostEvaluation.ts b/src/hooks/user/evaluationHooks/usePostEvaluation.ts index 303071c0..5722508d 100644 --- a/src/hooks/user/evaluationHooks/usePostEvaluation.ts +++ b/src/hooks/user/evaluationHooks/usePostEvaluation.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { postEvaluation } from '../../../api/evaluation.api'; -import { ProjectMemberListEval } from '../../queries/user/keys'; +import { ProjectMemberListEval } from '../../queries/keys'; import type { apiEvaluatedUser } from '../../../models/evaluation'; export const usePostEvaluation = (projectId: number) => { diff --git a/src/hooks/user/useAlarmDelete.ts b/src/hooks/user/useAlarmDelete.ts index cefa4a5c..a67175ed 100644 --- a/src/hooks/user/useAlarmDelete.ts +++ b/src/hooks/user/useAlarmDelete.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { deleteAlarm } from '../../api/alarm.api'; -import { AlarmList } from '../queries/user/keys'; +import { AlarmList } from '../queries/keys'; import useAuthStore from '../../store/authStore'; export const useAlarmDelete = () => { diff --git a/src/hooks/user/useAlarmList.ts b/src/hooks/user/useAlarmList.ts index 19f4241a..eb6f1ec0 100644 --- a/src/hooks/user/useAlarmList.ts +++ b/src/hooks/user/useAlarmList.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { AlarmList } from '../queries/user/keys'; +import { AlarmList } from '../queries/keys'; import { getAlarmList } from '../../api/alarm.api'; import useAuthStore from '../../store/authStore'; diff --git a/src/hooks/user/useAlarmPatch.ts b/src/hooks/user/useAlarmPatch.ts index d063a40b..0069ca18 100644 --- a/src/hooks/user/useAlarmPatch.ts +++ b/src/hooks/user/useAlarmPatch.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { patchAlarm } from '../../api/alarm.api'; -import { AlarmList } from '../queries/user/keys'; +import { AlarmList } from '../queries/keys'; import useAuthStore from '../../store/authStore'; export const useAlarmPatch = () => { diff --git a/src/hooks/user/useApllicantList.ts b/src/hooks/user/useApllicantList.ts index 34956e90..21698a79 100644 --- a/src/hooks/user/useApllicantList.ts +++ b/src/hooks/user/useApllicantList.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { applicantKey } from '../queries/user/keys'; +import { applicantKey } from '../queries/keys'; import { getApplicantList } from '../../api/applicant.api'; import type { ApiApplicants } from '../../models/applicant'; diff --git a/src/hooks/user/useApplicantInfo.ts b/src/hooks/user/useApplicantInfo.ts index 9ed2e48e..50c191e8 100644 --- a/src/hooks/user/useApplicantInfo.ts +++ b/src/hooks/user/useApplicantInfo.ts @@ -1,7 +1,7 @@ import { getApplicantInfo } from '../../api/applicant.api'; import { useEffect, useState } from 'react'; import { useQuery } from '@tanstack/react-query'; -import { applicantKey } from '../queries/user/keys'; +import { applicantKey } from '../queries/keys'; import { useLocation } from 'react-router-dom'; import type { ApiApplicantInfo } from '../../models/applicant'; diff --git a/src/hooks/user/useChartData.ts b/src/hooks/user/useChartData.ts index 392476bf..364396ce 100644 --- a/src/hooks/user/useChartData.ts +++ b/src/hooks/user/useChartData.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; import { getChartData } from '../../api/chart.api'; -import { ChartDataList } from '../queries/user/keys'; +import { ChartDataList } from '../queries/keys'; const useChartData = () => { const { data, isLoading, isFetching } = useQuery({ diff --git a/src/hooks/user/useGetFAQ.ts b/src/hooks/user/useGetFAQ.ts index 4ec4e0dd..33a9e606 100644 --- a/src/hooks/user/useGetFAQ.ts +++ b/src/hooks/user/useGetFAQ.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; import { getFAQ } from '../../api/customerService.api'; -import { CustomerService } from '../queries/user/keys'; +import { CustomerService } from '../queries/keys'; import type { SearchKeyword } from '../../models/customerService'; export const useGetFAQ = (keyword: SearchKeyword) => { diff --git a/src/hooks/user/useGetMyComments.ts b/src/hooks/user/useGetMyComments.ts index 188b7e8a..079f2b18 100644 --- a/src/hooks/user/useGetMyComments.ts +++ b/src/hooks/user/useGetMyComments.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { getMyComments } from '../../api/activityLog.api'; import useAuthStore from '../../store/authStore'; -import { ActivityLog } from '../queries/user/keys'; +import { ActivityLog } from '../queries/keys'; export const useGetMyComments = () => { const userId = useAuthStore.getState().userData?.id; diff --git a/src/hooks/user/useGetMyInquiries.ts b/src/hooks/user/useGetMyInquiries.ts index ec38dc8d..02e245e2 100644 --- a/src/hooks/user/useGetMyInquiries.ts +++ b/src/hooks/user/useGetMyInquiries.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { getMyInquiries } from '../../api/activityLog.api'; import useAuthStore from '../../store/authStore'; -import { ActivityLog } from '../queries/user/keys'; +import { ActivityLog } from '../queries/keys'; export const useGetMyInquiries = () => { const userId = useAuthStore.getState().userData?.id; diff --git a/src/hooks/user/useGetNotice.ts b/src/hooks/user/useGetNotice.ts index f367e266..1fa8370b 100644 --- a/src/hooks/user/useGetNotice.ts +++ b/src/hooks/user/useGetNotice.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import type { NoticeSearch } from '../../models/customerService'; import { getNotice } from '../../api/customerService.api'; -import { CustomerService } from '../queries/user/keys'; +import { CustomerService } from '../queries/keys'; export const useGetNotice = (searchProperty: NoticeSearch) => { const { keyword, page } = searchProperty; diff --git a/src/hooks/user/useGetNoticeDetail.ts b/src/hooks/user/useGetNoticeDetail.ts index 47193b7c..1685e134 100644 --- a/src/hooks/user/useGetNoticeDetail.ts +++ b/src/hooks/user/useGetNoticeDetail.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; import { getNoticeDetail } from '../../api/customerService.api'; -import { CustomerService } from '../queries/user/keys'; +import { CustomerService } from '../queries/keys'; export const useGetNoticeDetail = (id: string) => { const { data: noticeDetailData, isLoading } = useQuery({ diff --git a/src/hooks/user/useGetProjectData.ts b/src/hooks/user/useGetProjectData.ts index e245e100..39938225 100644 --- a/src/hooks/user/useGetProjectData.ts +++ b/src/hooks/user/useGetProjectData.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { managedProjectKey } from '../queries/user/keys'; +import { managedProjectKey } from '../queries/keys'; import { getProjectData } from '../../api/joinProject.api'; const useGetProjectData = (projectId: number) => { diff --git a/src/hooks/user/useGetUserProjectList.ts b/src/hooks/user/useGetUserProjectList.ts index a359f6bf..fc6889f6 100644 --- a/src/hooks/user/useGetUserProjectList.ts +++ b/src/hooks/user/useGetUserProjectList.ts @@ -3,7 +3,7 @@ import { getUserJoinedProjectList, getUserManagedProjectList, } from '../../api/userpage.api'; -import { userInfoKey } from '../queries/user/keys'; +import { userInfoKey } from '../queries/keys'; import { useLocation, useParams } from 'react-router-dom'; import type { ApiUserProject } from '../../models/userProject'; diff --git a/src/hooks/user/useManagedProjects.ts b/src/hooks/user/useManagedProjects.ts index a1ca74d1..d200d557 100644 --- a/src/hooks/user/useManagedProjects.ts +++ b/src/hooks/user/useManagedProjects.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { managedProjectKey } from '../queries/user/keys'; +import { managedProjectKey } from '../queries/keys'; import type { ApiManagedProjects } from '../../models/manageMyProject'; import { getMyProjectLists } from '../../api/myProjectList.api'; diff --git a/src/hooks/user/useMyInfo.ts b/src/hooks/user/useMyInfo.ts index a73ec422..74279aa0 100644 --- a/src/hooks/user/useMyInfo.ts +++ b/src/hooks/user/useMyInfo.ts @@ -1,7 +1,7 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { AxiosError } from 'axios'; import { useNavigate } from 'react-router-dom'; -import { myInfoKey, ProjectListKey } from '../queries/user/keys'; +import { myInfoKey, ProjectListKey } from '../queries/keys'; import useAuthStore from '../../store/authStore'; import type { ApiUserInfo, EditMyInfo } from '../../models/userInfo'; import { diff --git a/src/hooks/user/useNotification.ts b/src/hooks/user/useNotification.ts index 4416d107..3287dad0 100644 --- a/src/hooks/user/useNotification.ts +++ b/src/hooks/user/useNotification.ts @@ -1,6 +1,6 @@ import { useEffect, useRef } from 'react'; import { useQueryClient } from '@tanstack/react-query'; -import { AlarmList } from '../queries/user/keys'; +import { AlarmList } from '../queries/keys'; import type { AlarmLive } from '../../models/alarm'; import useAuthStore from '../../store/authStore'; import { useToast } from '../useToast'; @@ -55,13 +55,11 @@ const useNotification = () => { setSignal(eventData); showToast(eventData, 3000); } catch (error) { - console.error('SSE 메시지 파싱 실패:', error); } }); eventSource.onerror = (e) => { console.error('SSE 연결 오류:', e); - }; } diff --git a/src/hooks/user/usePassNonPassList.ts b/src/hooks/user/usePassNonPassList.ts index 8ed42a37..e631f54f 100644 --- a/src/hooks/user/usePassNonPassList.ts +++ b/src/hooks/user/usePassNonPassList.ts @@ -1,5 +1,5 @@ import { useSuspenseQuery } from '@tanstack/react-query'; -import { applicantKey } from '../queries/user/keys'; +import { applicantKey } from '../queries/keys'; import { getPassNonPassList } from '../../api/applicant.api'; export const usePassNonPassList = (projectId: number) => { diff --git a/src/hooks/user/usePassNonPassMutation.ts b/src/hooks/user/usePassNonPassMutation.ts index 4ab64d4e..67dccff1 100644 --- a/src/hooks/user/usePassNonPassMutation.ts +++ b/src/hooks/user/usePassNonPassMutation.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { AxiosError } from 'axios'; -import { applicantKey } from '../queries/user/keys'; +import { applicantKey } from '../queries/keys'; import { MODAL_MESSAGE } from '../../constants/user/modalMessage'; import { patchPassNonPassStatus } from '../../api/applicant.api'; diff --git a/src/hooks/user/usePostInquiry.ts b/src/hooks/user/usePostInquiry.ts index bca5d3a0..0901aa53 100644 --- a/src/hooks/user/usePostInquiry.ts +++ b/src/hooks/user/usePostInquiry.ts @@ -1,4 +1,4 @@ -import { ActivityLog } from '../queries/user/keys'; +import { ActivityLog } from '../queries/keys'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { AxiosError } from 'axios'; import { useNavigate } from 'react-router-dom'; diff --git a/src/hooks/user/useSendResultMutation.ts b/src/hooks/user/useSendResultMutation.ts index 528396e3..e44e8375 100644 --- a/src/hooks/user/useSendResultMutation.ts +++ b/src/hooks/user/useSendResultMutation.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { AxiosError } from 'axios'; -import { managedProjectKey } from '../queries/user/keys'; +import { managedProjectKey } from '../queries/keys'; import { patchSendResult } from '../../api/myProjectList.api'; import { MODAL_MESSAGE } from '../../constants/user/modalMessage'; diff --git a/src/hooks/user/useUserInfo.ts b/src/hooks/user/useUserInfo.ts index 71e128d6..7e66a1a1 100644 --- a/src/hooks/user/useUserInfo.ts +++ b/src/hooks/user/useUserInfo.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { userInfoKey } from '../queries/user/keys'; +import { userInfoKey } from '../queries/keys'; import useAuthStore from '../../store/authStore'; import type { ApiUserInfo } from '../../models/userInfo'; import { getUserInfo } from '../../api/userpage.api'; diff --git a/src/models/activityLog.ts b/src/models/activityLog.ts index d264daa1..8e0c7ec3 100644 --- a/src/models/activityLog.ts +++ b/src/models/activityLog.ts @@ -1,4 +1,4 @@ -import type { ApiCommonType } from './apiCommon'; +import type { ApiCommonType, User } from './apiCommon'; export interface MyInquiries { id: number; @@ -6,7 +6,10 @@ export interface MyInquiries { content: string; category: string; state: boolean; + answer: string; imageUrls: string[]; + createdAt: string; + user: User; } export interface ApiMyInquiries extends ApiCommonType { diff --git a/src/models/inquiry.ts b/src/models/inquiry.ts index 6899e943..7509a508 100644 --- a/src/models/inquiry.ts +++ b/src/models/inquiry.ts @@ -1,5 +1,29 @@ +import type { MyInquiries } from './activityLog'; +import type { ApiCommonType, User } from './apiCommon'; + export interface InquiryFormData { category: string; title: string; content: string; } + +export interface AdminInquiry { + id: number; + title: string; + user: User; + state: boolean; + createdAt: string; +} + +export interface ApiAdminInquiry extends ApiCommonType { + data: AdminInquiry[]; +} + +export interface ApiAdminInquiryDetail extends ApiCommonType { + data: MyInquiries; +} + +export interface InquiryAnswerBody { + id: string; + answer: string; +} diff --git a/src/pages/admin/adminInquiries/AdminInquiries.styled.ts b/src/pages/admin/adminInquiries/AdminInquiries.styled.ts deleted file mode 100644 index ce147df6..00000000 --- a/src/pages/admin/adminInquiries/AdminInquiries.styled.ts +++ /dev/null @@ -1,3 +0,0 @@ -import styled from 'styled-components'; - -export const AdminInquiriesContainer = styled.div``; diff --git a/src/pages/admin/adminInquiries/AdminInquiries.tsx b/src/pages/admin/adminInquiries/AdminInquiries.tsx index 09a40280..09112f9e 100644 --- a/src/pages/admin/adminInquiries/AdminInquiries.tsx +++ b/src/pages/admin/adminInquiries/AdminInquiries.tsx @@ -1,5 +1,5 @@ -import * as S from './AdminInquiries.styled'; +import CommonAdminPage from '../CommonAdminPage'; export default function AdminInquires() { - return ; + return ; } diff --git a/src/pages/admin/adminInquiries/adminInquiryDetail/AdminInquiryDetailPage.tsx b/src/pages/admin/adminInquiries/adminInquiryDetail/AdminInquiryDetailPage.tsx new file mode 100644 index 00000000..871fb79f --- /dev/null +++ b/src/pages/admin/adminInquiries/adminInquiryDetail/AdminInquiryDetailPage.tsx @@ -0,0 +1,5 @@ +import AdminInquiryDetail from '../../../../components/admin/adminInquiry/AdminInquiryDetail'; + +export default function AdminInquiryDetailPage() { + return ; +} diff --git a/src/pages/admin/adminInquiries/adminInquiryList/AdminInquiryListPage.tsx b/src/pages/admin/adminInquiries/adminInquiryList/AdminInquiryListPage.tsx new file mode 100644 index 00000000..a823bc2f --- /dev/null +++ b/src/pages/admin/adminInquiries/adminInquiryList/AdminInquiryListPage.tsx @@ -0,0 +1,5 @@ +import AdminInquiryList from '../../../../components/admin/adminInquiry/AdminInquiryList'; + +export default function AdminInquiryListPage() { + return ; +} diff --git a/src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx b/src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx new file mode 100644 index 00000000..cd3f5b47 --- /dev/null +++ b/src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx @@ -0,0 +1,3 @@ +export default function AdminInquiryWritePage() { + return
; +} diff --git a/src/routes/AdminRoutes.tsx b/src/routes/AdminRoutes.tsx index b8db82a0..53e64ed8 100644 --- a/src/routes/AdminRoutes.tsx +++ b/src/routes/AdminRoutes.tsx @@ -1,7 +1,8 @@ import NotFoundPage from '../pages/notFoundPage/NotFoundPage'; -import { lazy } from 'react'; +import { lazy, Suspense } from 'react'; import { ADMIN_ROUTE } from '../constants/routes'; import ProtectAdminRoute from './ProtectAdminRoute'; +import { Spinner } from '../components/common/loadingSpinner/LoadingSpinner.styled'; const Sidebar = lazy( () => import('../components/common/admin/sidebar/AdminSidebar') @@ -32,6 +33,27 @@ const Reports = lazy(() => import('../pages/admin/adminReports/AdminReports')); const Inquiries = lazy( () => import('../pages/admin/adminInquiries/AdminInquiries') ); +const InquiryList = lazy( + () => + import( + '../pages/admin/adminInquiries/adminInquiryList/AdminInquiryListPage' + ) +); +const InquiryDetail = lazy( + () => + import( + '../pages/admin/adminInquiries/adminInquiryDetail/AdminInquiryDetailPage' + ) +); +const InquiryAnswerContent = lazy( + () => import('../components/admin/adminInquiry/AdminInquiryAnswer') +); +const InquiryAnswerWrite = lazy( + () => + import( + '../pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage' + ) +); const Manage = lazy(() => import('../pages/admin/adminManage/AdminManage')); export const AdminRoutes = () => { @@ -39,9 +61,11 @@ export const AdminRoutes = () => { { path: ADMIN_ROUTE.admin, element: ( - - - + }> + + + + ), children: [ { @@ -98,6 +122,24 @@ export const AdminRoutes = () => { { path: ADMIN_ROUTE.inquiries, element: , + children: [ + { index: true, element: }, + { + path: `${ADMIN_ROUTE.detail}/:inquiryId`, + element: , + children: [ + { index: true, element: }, + { + path: ADMIN_ROUTE.write, + element: , + }, + { + pathname: ADMIN_ROUTE.modification, + element: , + }, + ], + }, + ], }, { path: ADMIN_ROUTE.manage, From 671973e2c6801998879ab0a3a657bfd9aef6ac4a Mon Sep 17 00:00:00 2001 From: YouD0313 <102004480+YouD0313@users.noreply.github.com> Date: Mon, 9 Jun 2025 21:04:47 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=EB=AC=B8=EC=9D=98=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=ED=8C=8C=EC=9D=BC=20=EC=9D=B4=EB=AF=B8=EC=A7=80,?= =?UTF-8?q?=20=ED=99=95=EB=8C=80=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/admin/customerService/Inquiry.api.ts | 8 +- .../admin/adminInquiry/AdminInquiry.styled.ts | 7 +- .../admin/adminInquiry/AdminInquiry.tsx | 1 + .../adminInquiry/AdminInquiryAnswer.styled.ts | 2 - .../admin/adminInquiry/AdminInquiryAnswer.tsx | 24 ++++-- .../AdminInquiryAnswerWrite.styled.ts | 43 ++++++++++ .../adminInquiry/AdminInquiryAnswerWrite.tsx | 80 +++++++++++++++++++ .../admin/adminInquiry/AdminInquiryDetail.tsx | 35 +++++++- .../AdminInquiryDetailContent.styled.ts | 40 ++++++++++ .../AdminInquiryDetailContent.tsx | 42 +++++++++- src/hooks/admin/useAdminFAQ.ts | 2 +- src/hooks/admin/useAdminInquiry.ts | 57 ++++++++++++- src/models/activityLog.ts | 1 + src/models/inquiry.ts | 1 + .../AdminInquiryWritePage.tsx | 4 +- src/pages/login/LoginSuccess.tsx | 1 - src/routes/AdminRoutes.tsx | 2 +- 17 files changed, 329 insertions(+), 21 deletions(-) create mode 100644 src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts create mode 100644 src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx diff --git a/src/api/admin/customerService/Inquiry.api.ts b/src/api/admin/customerService/Inquiry.api.ts index 7eb5ffa8..a6536a9c 100644 --- a/src/api/admin/customerService/Inquiry.api.ts +++ b/src/api/admin/customerService/Inquiry.api.ts @@ -31,7 +31,9 @@ export const getInquiryDetail = async (id: string) => { export const postInquiryAnswer = async ({ id, answer }: InquiryAnswerBody) => { try { - await httpClient.post(`/inquiry/${id}/answer`, answer); + await httpClient.post(`/inquiry/${id}/answer`, { + answer, + }); } catch (e) { console.error(e); throw e; @@ -40,7 +42,9 @@ export const postInquiryAnswer = async ({ id, answer }: InquiryAnswerBody) => { export const patchInquiryAnswer = async ({ id, answer }: InquiryAnswerBody) => { try { - await httpClient.patch(`/inquiry/${id}/answer`, answer); + await httpClient.patch(`/inquiry/${id}/answer`, { + answer, + }); } catch (e) { console.error(e); throw e; diff --git a/src/components/admin/adminInquiry/AdminInquiry.styled.ts b/src/components/admin/adminInquiry/AdminInquiry.styled.ts index d2495df0..46e4a6ef 100644 --- a/src/components/admin/adminInquiry/AdminInquiry.styled.ts +++ b/src/components/admin/adminInquiry/AdminInquiry.styled.ts @@ -6,7 +6,7 @@ export const AdminInquiryContainer = styled(Link)``; export const AdminInquiryWrapper = styled.div` padding: 0.8rem; display: grid; - grid-template-columns: 64% 15% 11% 10%; + grid-template-columns: 13% 51% 15% 11% 10%; justify-content: center; align-items: center; font-size: 1.1rem; @@ -14,6 +14,11 @@ export const AdminInquiryWrapper = styled.div` export const AdminInquiryTitle = styled.div``; +export const AdminInquiryCategory = styled.span` + font-size: 1.1rem; + font-weight: 500; +`; + export const AdminInquiryUser = styled.div``; export const ADminInquiryDate = styled.span` diff --git a/src/components/admin/adminInquiry/AdminInquiry.tsx b/src/components/admin/adminInquiry/AdminInquiry.tsx index 76ffec2a..3349b5cd 100644 --- a/src/components/admin/adminInquiry/AdminInquiry.tsx +++ b/src/components/admin/adminInquiry/AdminInquiry.tsx @@ -11,6 +11,7 @@ export default function AdminInquiry({ list }: AdminInquiryProps) { return ( + [{list.category}] {list.title} {list.user.nickname} {list.createdAt} diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts b/src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts index b5d6bb12..e482d45e 100644 --- a/src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts +++ b/src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts @@ -25,8 +25,6 @@ export const InquiryAnswerInfo = styled(InquiryInfo)` `; export const InquiryAnswerButton = styled(SendButton)` - align-items: start; - height: fit-content; font-size: 0.9rem; padding: 0.3rem 0.5rem; `; diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx b/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx index c51241b0..3cb1f886 100644 --- a/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx +++ b/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx @@ -1,17 +1,20 @@ import { useEffect, useState } from 'react'; import * as S from './AdminInquiryAnswer.styled'; -import { useOutletContext } from 'react-router-dom'; +import { Link, useOutletContext } from 'react-router-dom'; +import { ADMIN_ROUTE } from '../../../constants/routes'; interface AdminInquiryDetailContentOutletContext { createdAt: string; answerData: string; } +type LinkType = '작성하기' | '수정하기'; export default function AdminInquiryAnswer() { const { createdAt, answerData }: AdminInquiryDetailContentOutletContext = useOutletContext(); const [answer, setAnswer] = useState(''); + const selectButton: LinkType = answer === null ? '작성하기' : '수정하기'; useEffect(() => { setAnswer(answerData); @@ -24,10 +27,21 @@ export default function AdminInquiryAnswer() { {createdAt ? createdAt : ''} - - - {answer === null ? '작성하기' : '수정하기'} - + + {selectButton} {answer} diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts new file mode 100644 index 00000000..45b3c6c8 --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts @@ -0,0 +1,43 @@ +import styled from 'styled-components'; +import { + AdminInquiryContentContainer, + AdminInquiryContentWrapper, + InquiryContent, +} from './AdminInquiryDetailContent.styled'; +import { + AnswerHeaderWrapper, + InquiryAnswerButton, + InquiryAnswerInfo, +} from './AdminInquiryAnswer.styled'; + +export const InquiryAnswerContentContainer = styled( + AdminInquiryContentContainer +)``; + +export const InquiryAnswerWriteWrapper = styled(AdminInquiryContentWrapper)``; + +export const InquiryAnswerWriteHeaderWrapper = styled(AnswerHeaderWrapper)` + display: flex; + gap: 3rem; +`; + +export const InquiryAnswerWriteInfo = styled(InquiryAnswerInfo)` + display: flex; + align-items: center; +`; + +export const InquiryAnswerWriteButton = styled(InquiryAnswerButton)` + align-items: start; + height: fit-content; + font-size: 0.9rem; + padding: 0.3rem 0.5rem; +`; + +export const InquiryAnswerWriteButtonSpan = styled.span``; + +export const InquiryAnswerWrite = styled(InquiryContent)` + resize: none; + border: 1px solid ${({ theme }) => theme.color.placeholder}; + border-radius: ${({ theme }) => theme.borderRadius.primary}; + padding: 1rem; +`; diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx new file mode 100644 index 00000000..6d124a5a --- /dev/null +++ b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx @@ -0,0 +1,80 @@ +import { useOutletContext } from 'react-router-dom'; +import * as S from './AdminInquiryAnswerWrite.styled'; +import React, { useEffect, useRef, useState } from 'react'; +import { InquiryAnswerBody } from '../../../models/inquiry'; +import { UseMutationResult } from '@tanstack/react-query'; +import { AxiosError } from 'axios'; + +interface AdminInquiryAnswerWriteProps { + answerData: string; + isWrite: boolean; + id: string; + postInquiryAnswerMutate: UseMutationResult< + void, + AxiosError, + InquiryAnswerBody + >; + patchInquiryAnswerMutate: UseMutationResult< + void, + AxiosError, + InquiryAnswerBody + >; +} + +export default function AdminInquiryAnswerWrite() { + const { + answerData, + isWrite, + id, + postInquiryAnswerMutate, + patchInquiryAnswerMutate, + } = useOutletContext(); + const [answer, setAnswer] = useState(''); + const inputRef = useRef(null); + + useEffect(() => { + if (answerData) { + setAnswer(answerData); + } + }, [answerData]); + + const handleSubmitAnswer = (e: React.FormEvent) => { + e.preventDefault(); + + if (isWrite) { + postInquiryAnswerMutate.mutate({ id, answer: answer }); + } else { + patchInquiryAnswerMutate.mutate({ id, answer: answer }); + } + }; + + const handleChangeAnswer = (e: React.ChangeEvent) => { + const answerValue = e.target.value; + setAnswer(answerValue); + + if (inputRef && inputRef.current) { + inputRef.current.style.height = 'auto'; + inputRef.current.style.height = `${inputRef.current.scrollHeight}px`; + } + }; + + return ( + + + + + + 답변하기 + + + + + + + + ); +} diff --git a/src/components/admin/adminInquiry/AdminInquiryDetail.tsx b/src/components/admin/adminInquiry/AdminInquiryDetail.tsx index 8b8db608..98e9270d 100644 --- a/src/components/admin/adminInquiry/AdminInquiryDetail.tsx +++ b/src/components/admin/adminInquiry/AdminInquiryDetail.tsx @@ -1,13 +1,28 @@ -import { Outlet, useParams } from 'react-router-dom'; +import { Outlet, useLocation, useParams } from 'react-router-dom'; import * as S from './AdminInquiryDetail.styled'; import AdminInquiryDetailContent from './AdminInquiryDetailContent'; import { useAdminInquiry } from '../../../hooks/admin/useAdminInquiry'; import Spinner from '../../user/mypage/Spinner'; +import Modal from '../../common/modal/Modal'; +import { useModal } from '../../../hooks/useModal'; export default function AdminInquiryDetail() { + const location = useLocation(); + const pathname = location.pathname; + const isWrite = pathname.includes('write'); + const { isOpen, message, handleModalOpen, handleConfirm, handleModalClose } = + useModal(); const { inquiryId } = useParams(); const id = inquiryId || ''; - const { getInquiryDetailData } = useAdminInquiry(id); + const { + getInquiryDetailData, + postInquiryAnswerMutate, + patchInquiryAnswerMutate, + } = useAdminInquiry({ + handleModalOpen, + id, + handleConfirm, + }); const { data, isLoading } = getInquiryDetailData; if (isLoading) { @@ -24,8 +39,22 @@ export default function AdminInquiryDetail() { + + {message} + ); } diff --git a/src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts b/src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts index 888aed44..83fafc18 100644 --- a/src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts +++ b/src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts @@ -1,4 +1,11 @@ import styled from 'styled-components'; +import { SendButton } from '../../user/customerService/inquiry/Inquiry.styled'; +import { + ModalImg, + ModalImgContainer, + ModalImgMessageWrapper, + ModalImgWrapper, +} from '../../user/mypage/activityLog/inquiries/inquiry/Inquiry.styled'; export const AdminInquiryContentContainer = styled.section` width: 95%; @@ -19,12 +26,45 @@ export const InquiryTitle = styled.div` margin-bottom: 0.5rem; `; +export const InfoWrapper = styled.div` + display: flex; + align-items: center; + gap: 3rem; +`; + export const InquiryInfo = styled.div` font-size: 0.9rem; color: ${({ theme }) => theme.color.placeholder}; `; +export const InquiryDeleteButton = styled(SendButton)` + font-size: 0.9rem; + padding: 0.3rem 0.5rem; +`; + export const InquiryContent = styled.div` font-size: 1.1rem; width: 100%; `; + +export const InquiryFileImgBlowUpButton = styled.button``; + +export const InquiryFileImg = styled.img` + width: 5rem; +`; + +export const MessageWrapper = styled.div` + font-size: 0.8rem; +`; + +export const AdminInquiryModalImgContainer = styled(ModalImgContainer)` + z-index: 1000000000; +`; + +export const AdminInquiryModalImgWrapper = styled(ModalImgWrapper)``; + +export const AdminInquiryModalImgMessageWrapper = styled( + ModalImgMessageWrapper +)``; + +export const AdminInquiryModalImg = styled(ModalImg)``; diff --git a/src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx b/src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx index 62583e9a..30f82575 100644 --- a/src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx +++ b/src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx @@ -1,5 +1,7 @@ +import { useState } from 'react'; import type { MyInquiries } from '../../../models/activityLog'; import * as S from './AdminInquiryDetailContent.styled'; +import { My_INQUIRIES_MESSAGE } from '../../../constants/user/customerService'; interface AdminInquiryDetailContentProps { inquiry: MyInquiries; @@ -8,7 +10,10 @@ interface AdminInquiryDetailContentProps { export default function AdminInquiryDetailContent({ inquiry, }: AdminInquiryDetailContentProps) { - console.log(inquiry); + const [imageOpen, setImageOpen] = useState<{ + isImgOpen: boolean; + url: string; + }>({ isImgOpen: false, url: '' }); return ( @@ -18,7 +23,42 @@ export default function AdminInquiryDetailContent({ {`${inquiry.user.nickname} | ${inquiry.createdAt}`} {inquiry.content} + {inquiry.imageUrls.map((url) => ( + + setImageOpen({ + isImgOpen: true, + url, + }) + } + > + + + ))} + {inquiry.imageUrls.length > 0 && ( + + {My_INQUIRIES_MESSAGE.blowUpMessage} + + )} + {imageOpen.isImgOpen && ( + + + setImageOpen({ + isImgOpen: false, + url: '', + }) + } + > + + {My_INQUIRIES_MESSAGE.isImageOpenMessage} + + + + + )} ); } diff --git a/src/hooks/admin/useAdminFAQ.ts b/src/hooks/admin/useAdminFAQ.ts index a9eabc3d..7ef9e05d 100644 --- a/src/hooks/admin/useAdminFAQ.ts +++ b/src/hooks/admin/useAdminFAQ.ts @@ -11,7 +11,7 @@ import { useNavigate } from 'react-router-dom'; import { ADMIN_MODAL_MESSAGE } from '../../constants/admin/adminModal'; import { CustomerService } from '../queries/keys'; -type State = 'success' | 'fail'; +export type State = 'success' | 'fail'; export const useAdminFAQ = ({ handleModalOpen, diff --git a/src/hooks/admin/useAdminInquiry.ts b/src/hooks/admin/useAdminInquiry.ts index f63e4e9a..026d0533 100644 --- a/src/hooks/admin/useAdminInquiry.ts +++ b/src/hooks/admin/useAdminInquiry.ts @@ -2,14 +2,57 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { deleteInquiry, getInquiryDetail, + patchInquiryAnswer, postInquiryAnswer, } from '../../api/admin/customerService/Inquiry.api'; -import { InquiryAnswerBody } from '../../models/inquiry'; +import type { InquiryAnswerBody } from '../../models/inquiry'; import { AxiosError } from 'axios'; import { CustomerService } from '../queries/keys'; +import type { State } from './useAdminFAQ'; +import { useNavigate } from 'react-router-dom'; +import { ADMIN_MODAL_MESSAGE } from '../../constants/admin/adminModal'; -export const useAdminInquiry = (id: string) => { +export const useAdminInquiry = ({ + handleModalOpen, + id = '', + handleConfirm, +}: { + handleModalOpen: (message: string) => void; + id?: string; + handleConfirm?: () => void; +}) => { const queryClient = useQueryClient(); + const navigate = useNavigate(); + + const handleButtonState = (state: State, isDeleteApi: boolean = false) => { + switch (state) { + case 'success': + if (!isDeleteApi) { + handleModalOpen(ADMIN_MODAL_MESSAGE.writeSuccess); + } else { + handleConfirm?.(); + handleModalOpen(ADMIN_MODAL_MESSAGE.writeDeleteSuccess); + } + setTimeout(() => { + if (id) { + return navigate(`/admin/inquiries/detail/${id}`); + } else { + return navigate(-1); + } + }, 1000); + break; + case 'fail': + if (!isDeleteApi) { + handleModalOpen(ADMIN_MODAL_MESSAGE.writeFail); + } else { + handleModalOpen(ADMIN_MODAL_MESSAGE.writeDeleteFail); + } + break; + default: + handleModalOpen(ADMIN_MODAL_MESSAGE.writeError); + break; + } + }; const getInquiryDetailData = useQuery({ queryKey: [CustomerService.inquiryDetail, id], @@ -28,6 +71,10 @@ export const useAdminInquiry = (id: string) => { queryClient.invalidateQueries({ queryKey: [CustomerService.inquiryDetail, id], }); + handleButtonState('success'); + }, + onError: () => { + handleButtonState('fail'); }, }); @@ -37,11 +84,15 @@ export const useAdminInquiry = (id: string) => { InquiryAnswerBody >({ mutationFn: ({ id, answer }: InquiryAnswerBody) => - postInquiryAnswer({ id, answer }), + patchInquiryAnswer({ id, answer }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: [CustomerService.inquiryDetail, id], }); + handleButtonState('success'); + }, + onError: () => { + handleButtonState('fail'); }, }); diff --git a/src/models/activityLog.ts b/src/models/activityLog.ts index 8e0c7ec3..b037b973 100644 --- a/src/models/activityLog.ts +++ b/src/models/activityLog.ts @@ -9,6 +9,7 @@ export interface MyInquiries { answer: string; imageUrls: string[]; createdAt: string; + updatedAt: string; user: User; } diff --git a/src/models/inquiry.ts b/src/models/inquiry.ts index 7509a508..5b2e46e1 100644 --- a/src/models/inquiry.ts +++ b/src/models/inquiry.ts @@ -11,6 +11,7 @@ export interface AdminInquiry { id: number; title: string; user: User; + category: string; state: boolean; createdAt: string; } diff --git a/src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx b/src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx index cd3f5b47..f3c45dff 100644 --- a/src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx +++ b/src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx @@ -1,3 +1,5 @@ +import AdminInquiryAnswerWrite from '../../../../components/admin/adminInquiry/AdminInquiryAnswerWrite'; + export default function AdminInquiryWritePage() { - return
; + return ; } diff --git a/src/pages/login/LoginSuccess.tsx b/src/pages/login/LoginSuccess.tsx index 1a26f4c0..4acccee9 100644 --- a/src/pages/login/LoginSuccess.tsx +++ b/src/pages/login/LoginSuccess.tsx @@ -16,7 +16,6 @@ function LoginSuccess() { useEffect(() => { const accessToken = searchParams.get('accessToken'); - console.log('accessToken', accessToken); if (accessToken) { login(accessToken, null); diff --git a/src/routes/AdminRoutes.tsx b/src/routes/AdminRoutes.tsx index 53e64ed8..ea63ca29 100644 --- a/src/routes/AdminRoutes.tsx +++ b/src/routes/AdminRoutes.tsx @@ -134,7 +134,7 @@ export const AdminRoutes = () => { element: , }, { - pathname: ADMIN_ROUTE.modification, + path: ADMIN_ROUTE.modification, element: , }, ], From 93d0d002f46cf2f98044e0bcfa8238d22b55a948 Mon Sep 17 00:00:00 2001 From: YouD0313 <102004480+YouD0313@users.noreply.github.com> Date: Mon, 9 Jun 2025 21:33:39 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/adminInquiry/AdminInquiry.styled.ts | 2 +- .../admin/adminInquiry/AdminInquiry.tsx | 6 ++--- .../admin/adminInquiry/AdminInquiryAnswer.tsx | 7 +---- .../adminInquiry/AdminInquiryAnswerWrite.tsx | 26 ++++++++++++++++--- .../admin/adminInquiry/AdminInquiryList.tsx | 8 +++--- src/hooks/admin/useAdminInquiry.ts | 4 +++ src/models/activityLog.ts | 2 +- 7 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/components/admin/adminInquiry/AdminInquiry.styled.ts b/src/components/admin/adminInquiry/AdminInquiry.styled.ts index 46e4a6ef..7e9f145f 100644 --- a/src/components/admin/adminInquiry/AdminInquiry.styled.ts +++ b/src/components/admin/adminInquiry/AdminInquiry.styled.ts @@ -21,7 +21,7 @@ export const AdminInquiryCategory = styled.span` export const AdminInquiryUser = styled.div``; -export const ADminInquiryDate = styled.span` +export const AdminInquiryDate = styled.span` font-size: 0.9rem; color: ${({ theme }) => theme.color.deepGrey}; `; diff --git a/src/components/admin/adminInquiry/AdminInquiry.tsx b/src/components/admin/adminInquiry/AdminInquiry.tsx index 3349b5cd..da9933b5 100644 --- a/src/components/admin/adminInquiry/AdminInquiry.tsx +++ b/src/components/admin/adminInquiry/AdminInquiry.tsx @@ -1,10 +1,10 @@ import { ADMIN_ROUTE } from '../../../constants/routes'; -import type { AdminInquiry } from '../../../models/inquiry'; +import type { AdminInquiry as TAdminInquiry } from '../../../models/inquiry'; import ContentBorder from '../../common/contentBorder/ContentBorder'; import * as S from './AdminInquiry.styled'; interface AdminInquiryProps { - list: AdminInquiry; + list: TAdminInquiry; } export default function AdminInquiry({ list }: AdminInquiryProps) { @@ -14,7 +14,7 @@ export default function AdminInquiry({ list }: AdminInquiryProps) { [{list.category}] {list.title} {list.user.nickname} - {list.createdAt} + {list.createdAt} {list.state ? '답변완료' : '확인중'} diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx b/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx index 3cb1f886..d86c4e1b 100644 --- a/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx +++ b/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx @@ -9,6 +9,7 @@ interface AdminInquiryDetailContentOutletContext { } type LinkType = '작성하기' | '수정하기'; + export default function AdminInquiryAnswer() { const { createdAt, answerData }: AdminInquiryDetailContentOutletContext = useOutletContext(); @@ -34,12 +35,6 @@ export default function AdminInquiryAnswer() { ? ADMIN_ROUTE.write : ADMIN_ROUTE.modification } - state={{ - from: - selectButton === '작성하기' - ? ADMIN_ROUTE.write - : ADMIN_ROUTE.modification, - }} > {selectButton}
diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx index 6d124a5a..84e53284 100644 --- a/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx +++ b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx @@ -4,6 +4,10 @@ import React, { useEffect, useRef, useState } from 'react'; import { InquiryAnswerBody } from '../../../models/inquiry'; import { UseMutationResult } from '@tanstack/react-query'; import { AxiosError } from 'axios'; +import Modal from '../../common/modal/Modal'; +import { useModal } from '../../../hooks/useModal'; +import { INQUIRY_MESSAGE } from '../../../constants/user/customerService'; +import Spinner from '../../user/mypage/Spinner'; interface AdminInquiryAnswerWriteProps { answerData: string; @@ -31,6 +35,9 @@ export default function AdminInquiryAnswerWrite() { } = useOutletContext(); const [answer, setAnswer] = useState(''); const inputRef = useRef(null); + const { isOpen, message, handleModalOpen, handleModalClose } = useModal(); + const isLoading = + postInquiryAnswerMutate.isPending || patchInquiryAnswerMutate.isPending; useEffect(() => { if (answerData) { @@ -38,9 +45,17 @@ export default function AdminInquiryAnswerWrite() { } }, [answerData]); + if (isLoading) { + ; + } + const handleSubmitAnswer = (e: React.FormEvent) => { e.preventDefault(); + if (answer.trim() === '') { + return handleModalOpen(INQUIRY_MESSAGE.writeContent); + } + if (isWrite) { postInquiryAnswerMutate.mutate({ id, answer: answer }); } else { @@ -49,13 +64,14 @@ export default function AdminInquiryAnswerWrite() { }; const handleChangeAnswer = (e: React.ChangeEvent) => { - const answerValue = e.target.value; - setAnswer(answerValue); - if (inputRef && inputRef.current) { inputRef.current.style.height = 'auto'; inputRef.current.style.height = `${inputRef.current.scrollHeight}px`; } + + const answerValue = e.target.value; + + setAnswer(answerValue); }; return ( @@ -72,9 +88,13 @@ export default function AdminInquiryAnswerWrite() { + + {message} + ); } diff --git a/src/components/admin/adminInquiry/AdminInquiryList.tsx b/src/components/admin/adminInquiry/AdminInquiryList.tsx index 184c4ceb..18ae34bc 100644 --- a/src/components/admin/adminInquiry/AdminInquiryList.tsx +++ b/src/components/admin/adminInquiry/AdminInquiryList.tsx @@ -7,9 +7,11 @@ export default function AdminInquiryList() { const { allInquiriesData, isLoading } = useGetAllInquiries(); if (isLoading) { - - - ; + return ( + + + + ); } if (!allInquiriesData) return; diff --git a/src/hooks/admin/useAdminInquiry.ts b/src/hooks/admin/useAdminInquiry.ts index 026d0533..ebb7d3a1 100644 --- a/src/hooks/admin/useAdminInquiry.ts +++ b/src/hooks/admin/useAdminInquiry.ts @@ -102,6 +102,10 @@ export const useAdminInquiry = ({ queryClient.invalidateQueries({ queryKey: [CustomerService.inquiryDetail, id], }); + handleButtonState('success', true); + }, + onError: () => { + handleButtonState('fail'); }, }); diff --git a/src/models/activityLog.ts b/src/models/activityLog.ts index b037b973..29e5281f 100644 --- a/src/models/activityLog.ts +++ b/src/models/activityLog.ts @@ -6,7 +6,7 @@ export interface MyInquiries { content: string; category: string; state: boolean; - answer: string; + answer?: string; imageUrls: string[]; createdAt: string; updatedAt: string; From 7bfdc0c1ddf35f9c326b8cdb46360c58c2a15b16 Mon Sep 17 00:00:00 2001 From: YouD0313 <102004480+YouD0313@users.noreply.github.com> Date: Mon, 9 Jun 2025 21:36:20 +0900 Subject: [PATCH 4/6] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/admin/useAdminInquiry.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/hooks/admin/useAdminInquiry.ts b/src/hooks/admin/useAdminInquiry.ts index ebb7d3a1..ea4dc4e6 100644 --- a/src/hooks/admin/useAdminInquiry.ts +++ b/src/hooks/admin/useAdminInquiry.ts @@ -27,19 +27,22 @@ export const useAdminInquiry = ({ const handleButtonState = (state: State, isDeleteApi: boolean = false) => { switch (state) { case 'success': - if (!isDeleteApi) { - handleModalOpen(ADMIN_MODAL_MESSAGE.writeSuccess); - } else { - handleConfirm?.(); - handleModalOpen(ADMIN_MODAL_MESSAGE.writeDeleteSuccess); - } - setTimeout(() => { - if (id) { - return navigate(`/admin/inquiries/detail/${id}`); + { + if (!isDeleteApi) { + handleModalOpen(ADMIN_MODAL_MESSAGE.writeSuccess); } else { - return navigate(-1); + handleConfirm?.(); + handleModalOpen(ADMIN_MODAL_MESSAGE.writeDeleteSuccess); } - }, 1000); + const timer = setTimeout(() => { + if (id) { + return navigate(`/admin/inquiries/detail/${id}`); + } else { + return navigate(-1); + } + }, 1000); + clearTimeout(timer); + } break; case 'fail': if (!isDeleteApi) { From 2fc86dece3e0a1cc83bc24c5a9f0cddd056822b2 Mon Sep 17 00:00:00 2001 From: YouD0313 <102004480+YouD0313@users.noreply.github.com> Date: Mon, 9 Jun 2025 21:44:24 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/admin/adminInquiry/AdminInquiryAnswer.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx b/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx index d86c4e1b..4d4d486c 100644 --- a/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx +++ b/src/components/admin/adminInquiry/AdminInquiryAnswer.tsx @@ -18,7 +18,11 @@ export default function AdminInquiryAnswer() { const selectButton: LinkType = answer === null ? '작성하기' : '수정하기'; useEffect(() => { - setAnswer(answerData); + if (answerData === null) { + return setAnswer(''); + } else { + return setAnswer(answerData); + } }, [answerData]); return ( From 59f6af4fbe435906338d1a55f9fea2183e71e002 Mon Sep 17 00:00:00 2001 From: YouD0313 <102004480+YouD0313@users.noreply.github.com> Date: Mon, 9 Jun 2025 21:46:20 +0900 Subject: [PATCH 6/6] =?UTF-8?q?design:=20=EC=8A=A4=ED=94=BC=EB=84=88=20wra?= =?UTF-8?q?pper=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts | 3 +++ .../admin/adminInquiry/AdminInquiryAnswerWrite.tsx | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts index 45b3c6c8..477ee130 100644 --- a/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts +++ b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts @@ -9,6 +9,9 @@ import { InquiryAnswerButton, InquiryAnswerInfo, } from './AdminInquiryAnswer.styled'; +import { SpinnerWrapperStyled } from '../../user/mypage/Spinner.styled'; + +export const SpinnerWrapper = styled(SpinnerWrapperStyled)``; export const InquiryAnswerContentContainer = styled( AdminInquiryContentContainer diff --git a/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx index 84e53284..979901b4 100644 --- a/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx +++ b/src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx @@ -46,7 +46,11 @@ export default function AdminInquiryAnswerWrite() { }, [answerData]); if (isLoading) { - ; + return ( + + + + ); } const handleSubmitAnswer = (e: React.FormEvent) => {