diff --git a/package.json b/package.json index 577fdf64..c9316486 100644 --- a/package.json +++ b/package.json @@ -21,28 +21,22 @@ "@types/node": "^20.10.5", "@types/react-custom-scrollbars": "^4.0.13", "@types/react-facebook-login": "^4.1.10", - "@types/react-modal": "^3.16.3", - "@types/yup": "^0.32.0", - "antd": "^5.12.5", "axios": "^1.6.3", "crypto-js": "^4.2.0", - "formik": "^2.4.5", - "modal": "^1.2.0", - "moment": "^2.30.1", + "date-fns": "^4.1.0", "nanoid": "^5.0.5", "qs": "^6.11.2", "react": "^18.2.0", "react-custom-scrollbars": "^4.2.1", + "react-datepicker": "^7.5.0", "react-dom": "^18.2.0", "react-error-boundary": "^4.0.13", "react-facebook-login": "^4.1.1", + "react-hook-form": "^7.54.2", "react-intersection-observer": "^9.8.1", - "react-modal": "^3.16.1", "react-query": "^3.39.3", "react-router-dom": "^6.21.1", - "swiper": "^11.0.7", "tailwind-scrollbar-hide": "^1.1.7", - "yup": "^1.3.3", "zustand": "^4.5.2" }, "devDependencies": { @@ -60,6 +54,7 @@ "@types/crypto-js": "^4.2.2", "@types/jest": "^29.5.11", "@types/react": "^18.2.43", + "@types/react-datepicker": "^7.0.0", "@types/react-dom": "^18.2.17", "@types/react-query": "^1.2.9", "@typescript-eslint/eslint-plugin": "^6.14.0", diff --git a/src/apis/axios/request.ts b/src/apis/axios/request.ts index d51cfd08..8ab1d0cd 100644 --- a/src/apis/axios/request.ts +++ b/src/apis/axios/request.ts @@ -6,6 +6,7 @@ const requests = { fetchLogout: `/logout`, fetchTopic: `/admin/topic`, fetchInstance: `/admin/instance`, + fetchTopicInstnaces: `/admin/topic/instances`, fetchChallenges: `/challenges`, fetchChallengesLatest: `/challenges/latest`, fetchChallengesActivity: `/challenges/my/activity`, diff --git a/src/apis/getAdminInstanceListApi.ts b/src/apis/getAdminInstanceListApi.ts index a263b3e1..fac66b6b 100644 --- a/src/apis/getAdminInstanceListApi.ts +++ b/src/apis/getAdminInstanceListApi.ts @@ -3,13 +3,15 @@ import requests from "./axios/request"; type adminInstanceListApiType = { pageNumber?: number; + topicId: number; }; const getAdminInstanceListPageApi = async ({ pageNumber, + topicId, }: adminInstanceListApiType) => { const data = await instance - .get(`${requests.fetchInstance}?page=${pageNumber}&size=5`) + .get(`${requests.fetchTopicInstnaces}/${topicId}?page=${pageNumber}&size=5`) .then((res) => { const list = res.data.data; return list || {}; diff --git a/src/apis/getSearchedChallengeItem.ts b/src/apis/getSearchedChallengeItem.ts index 61e9fe24..15819ea9 100644 --- a/src/apis/getSearchedChallengeItem.ts +++ b/src/apis/getSearchedChallengeItem.ts @@ -14,7 +14,7 @@ interface Data { participantCount: number; pointPerPerson: number; fileResponse: { - accessURI: string; + source: string; }; } diff --git a/src/apis/patchAdminInstanceFileEditApi.ts b/src/apis/patchAdminInstanceFileEditApi.ts index 988125fc..23c95a87 100644 --- a/src/apis/patchAdminInstanceFileEditApi.ts +++ b/src/apis/patchAdminInstanceFileEditApi.ts @@ -3,7 +3,7 @@ import { multiInstance } from "./axios/axios"; type editInstacneType = { instanceId: number; - instanceImg?: File; + instanceImg?: File | null; }; const patchAdminInstanceFileEditApi = async ({ diff --git a/src/apis/patchProfileImage.ts b/src/apis/patchProfileImage.ts index e9d0886d..d258aa6d 100644 --- a/src/apis/patchProfileImage.ts +++ b/src/apis/patchProfileImage.ts @@ -1,7 +1,8 @@ import requests from "./axios/request"; import { multiInstance } from "./axios/axios"; + type PostSignUpProfileImageParams = { - files: any; + files: File | null; userId: number; }; @@ -10,19 +11,15 @@ const patchProfileImage = async ({ userId, }: PostSignUpProfileImageParams) => { if (!files) return; + const formData = new FormData(); - const realFile = files?.file?.originFileObj; - const blob = new Blob([realFile], { type: files?.file?.type }); - formData.append("files", blob, `profile-image.jpg`); + formData.append("files", files, `profile-image.jpg`); + + const data = await multiInstance.patch( + `${requests.fetchFile}/${userId}?type=profile`, + formData + ); - const data = await multiInstance - .patch(`${requests.fetchFile}/${userId}?type=profile`, formData) - .then((res) => { - return res; - }) - .catch((err) => { - throw err; - }); return data; }; diff --git a/src/apis/postInterestEditApi.ts b/src/apis/postInterestEditApi.ts index 70e11418..9753aa96 100644 --- a/src/apis/postInterestEditApi.ts +++ b/src/apis/postInterestEditApi.ts @@ -1,9 +1,8 @@ -import { CheckboxValueType } from "antd/es/checkbox/Group"; import requests from "./axios/request"; import { instance } from "./axios/axios"; type postInterestEditApiType = { - interestEditData: CheckboxValueType[]; + interestEditData: string[]; }; const postInterestEditApi = async ({ interestEditData, diff --git a/src/apis/postSignUpApi.ts b/src/apis/postSignUpApi.ts index 7af63520..49ac8690 100644 --- a/src/apis/postSignUpApi.ts +++ b/src/apis/postSignUpApi.ts @@ -1,11 +1,10 @@ -import { CheckboxValueType } from "antd/es/checkbox/Group"; import requests from "./axios/request"; import { acceptInstance } from "./axios/axios"; type SignUpApiParams = { identifier: string; nickname: string; information: string; - interest: CheckboxValueType[]; + interest: string[]; }; const signUpApi = async ({ diff --git a/src/components/Admin/AdminInstance/InstanceListComponent/AdminInstanceContent/AdminInstanceContent.tsx b/src/components/Admin/AdminInstance/InstanceListComponent/AdminInstanceContent/AdminInstanceContent.tsx index 77909105..1c99f3cd 100644 --- a/src/components/Admin/AdminInstance/InstanceListComponent/AdminInstanceContent/AdminInstanceContent.tsx +++ b/src/components/Admin/AdminInstance/InstanceListComponent/AdminInstanceContent/AdminInstanceContent.tsx @@ -1,55 +1,46 @@ import { AdminListLayOut } from "@/components/Admin/AdminLayOut/AdminListLayOut/AdminListLayOut"; import CreateBtn from "@/components/Admin/CreateBtn/CreateBtn"; import { useInstanceListQuery } from "@/hooks/queries/useAdminInstanceQuery"; -import { useTopicDetailQuery } from "@/hooks/queries/useAdminTopicQuery"; import { decrypt } from "@/hooks/useCrypto"; -import { Pagination } from "antd"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import { useLocation } from "react-router-dom"; import InstanceListComponent from "../InstanceListComponent"; +import { Pagination } from "@/components/Common/Pagination"; function AdminInstanceContent() { - const [pageNumber, setPageNumber] = useState(0); - const [totalNumber, setTotalNumber] = useState(0); + const [pageNumber, setPageNumber] = useState(1); const location = useLocation(); const topicId = location.state.topicId; const decryptTopicId = decrypt(topicId); - const { data: topicDetail } = useTopicDetailQuery({ - topicId: decryptTopicId, - }); const { data: instanceContent } = useInstanceListQuery({ pageNumber: pageNumber - 1, + topicId: decryptTopicId, }); const handlePageChange = (page: number) => { setPageNumber(page); }; - useEffect(() => { - setTotalNumber(instanceContent.totalElements); - }, [instanceContent]); - return ( <> <> - + - + {instanceContent.totalElements > 0 && ( + + )} ); diff --git a/src/components/Admin/AdminInstance/InstanceListComponent/InstanceListComponent.tsx b/src/components/Admin/AdminInstance/InstanceListComponent/InstanceListComponent.tsx index b5cca7c0..06fc622d 100644 --- a/src/components/Admin/AdminInstance/InstanceListComponent/InstanceListComponent.tsx +++ b/src/components/Admin/AdminInstance/InstanceListComponent/InstanceListComponent.tsx @@ -1,22 +1,18 @@ import Button from "@/components/Common/Button"; -import moment from "moment"; import deleteAdminInstanceApi from "@/apis/deleteAdminInstanceApi"; -import { adminTopicDataType, instanceListDataType } from "@/types/adminType"; +import { instanceListDataType } from "@/types/adminType"; import InstanceTitle from "./InstanceTitle/InstanceTitle"; import { useNavigate } from "react-router-dom"; import { useQueryClient } from "react-query"; import { encrypt } from "@/hooks/useCrypto"; import { PATH } from "@/constants/path"; +import { format } from "date-fns"; type instanceListPropsType = { - instanceList: any; - topicDetail?: adminTopicDataType; + instanceList: instanceListDataType[]; }; -const InstanceListComponent = ({ - instanceList, - topicDetail, -}: instanceListPropsType) => { +const InstanceListComponent = ({ instanceList }: instanceListPropsType) => { const navigate = useNavigate(); const queryClient = useQueryClient(); @@ -25,19 +21,14 @@ const InstanceListComponent = ({ navigate(`${PATH.ADMIN_INSTANCE}/${InstanceCryptoId}/edit`); }; - const topicPropsId = topicDetail?.topicId; - const instanceFilterList = instanceList.filter( - (item: instanceListDataType) => item.topicId === topicPropsId - ); - return ( <>
    <> - {instanceFilterList.map((item: instanceListDataType) => { - const imageData = item.fileResponse.accessURI; - const startDate = moment(item.startedAt).format("YYYY-MM-DD"); - const completedDate = moment(item.completedAt).format("YYYY-MM-DD"); + {instanceList.map((item: instanceListDataType) => { + const imageData = item.fileResponse.source; + const startDate = format(item.startedAt, "yyyy-MM-dd"); + const completedDate = format(item.completedAt, "yyyy-MM-dd"); return (
  • (0); - const [totalNumber, setTotalNumber] = useState(0); + const [pageNumber, setPageNumber] = useState(1); const { data: adminData } = useTopicListQuery({ pageNumber: pageNumber - 1, @@ -18,10 +17,6 @@ function AdminTopicContent() { setPageNumber(page); }; - useEffect(() => { - setTotalNumber(adminData.totalElements); - }, [adminData]); - return ( <> @@ -31,13 +26,15 @@ function AdminTopicContent() { - + {adminData.totalElements > 0 && ( + + )} ); diff --git a/src/components/Certification/Certification/ChallengeInformation/ChallengeInformation.tsx b/src/components/Certification/Certification/ChallengeInformation/ChallengeInformation.tsx index 13a86f3c..0179eb95 100644 --- a/src/components/Certification/Certification/ChallengeInformation/ChallengeInformation.tsx +++ b/src/components/Certification/Certification/ChallengeInformation/ChallengeInformation.tsx @@ -29,7 +29,7 @@ function ChallengeInformation() { <>
    diff --git a/src/components/Certification/MyAllCurrentCertification/MyProfile/MyProfile.tsx b/src/components/Certification/MyAllCurrentCertification/MyProfile/MyProfile.tsx index 3e3a88a6..d175b163 100644 --- a/src/components/Certification/MyAllCurrentCertification/MyProfile/MyProfile.tsx +++ b/src/components/Certification/MyAllCurrentCertification/MyProfile/MyProfile.tsx @@ -24,7 +24,7 @@ function MyProfile({ decryptedUserId }: Props) { /> )} diff --git a/src/components/Certification/OthersAllCurrentCertification/OthersProfile/OthersProfile.tsx b/src/components/Certification/OthersAllCurrentCertification/OthersProfile/OthersProfile.tsx index 1656b063..58f494a5 100644 --- a/src/components/Certification/OthersAllCurrentCertification/OthersProfile/OthersProfile.tsx +++ b/src/components/Certification/OthersAllCurrentCertification/OthersProfile/OthersProfile.tsx @@ -20,7 +20,7 @@ function OthersProfile({ decryptedUserId }: Props) { /> )} diff --git a/src/components/ChallengeDetail/ChallengeDetailContent/ChallengeDetailContent.tsx b/src/components/ChallengeDetail/ChallengeDetailContent/ChallengeDetailContent.tsx index 7f6e011f..ce99d8df 100644 --- a/src/components/ChallengeDetail/ChallengeDetailContent/ChallengeDetailContent.tsx +++ b/src/components/ChallengeDetail/ChallengeDetailContent/ChallengeDetailContent.tsx @@ -26,7 +26,7 @@ function ChallengeDetailContent({ decryptId }: Props) { return ( <>
    - {"챌린지 + {"챌린지 { { - onClick(); + onClick && onClick(); } }} > diff --git a/src/components/Common/Button.tsx b/src/components/Common/Button.tsx index ceeb5e98..cfc998ee 100644 --- a/src/components/Common/Button.tsx +++ b/src/components/Common/Button.tsx @@ -1,12 +1,15 @@ -interface Props { +import { ButtonHTMLAttributes } from "react"; + +interface Props extends ButtonHTMLAttributes { content: string; - width: string; - height: string; - backgroundColor: string; - textSize: string; - fontWeight: string; - textColor: string; - handleClick: () => void; + width?: string; + height?: string; + backgroundColor?: string; + textSize?: string; + fontWeight?: string; + textColor?: string; + handleClick?: () => void; + className?: string; } function Button({ @@ -18,12 +21,14 @@ function Button({ fontWeight, textColor, handleClick, + className, + ...props }: Props) { return ( diff --git a/src/components/Common/Form/index.tsx b/src/components/Common/Form/index.tsx new file mode 100644 index 00000000..561a87a7 --- /dev/null +++ b/src/components/Common/Form/index.tsx @@ -0,0 +1,223 @@ +import InterestBtn from "@/components/Interest/InterestButton/InterestBtn"; +import { + InputHTMLAttributes, + ReactNode, + SelectHTMLAttributes, + TextareaHTMLAttributes, +} from "react"; +import { FieldError, Merge, UseFormRegisterReturn } from "react-hook-form"; +import { faPlus } from "@fortawesome/free-solid-svg-icons"; +import { faCheck } from "@fortawesome/free-solid-svg-icons"; + +interface InputProps extends InputHTMLAttributes { + id: string; + label: string; + error?: FieldError; + information?: string; + registration?: UseFormRegisterReturn; + children?: ReactNode; +} + +export const Input = ({ + id, + label, + error, + registration, + information, + children, + ...props +}: InputProps) => { + const { ref, ...restRegistration } = registration || {}; + return ( +
    +
    + + {children ? ( + children + ) : ( + + )} +
    + {error && ( +

    {error.message}

    + )} + {information && ( +

    {information}

    + )} +
    + ); +}; + +interface TextAreaProps extends TextareaHTMLAttributes { + id: string; + label: string; + error?: FieldError; + registration: UseFormRegisterReturn; + information?: string; +} + +export const TextArea = ({ + id, + label, + error, + registration, + information, + ...props +}: TextAreaProps) => { + const { ref, ...restRegistration } = registration; + + return ( +
    +
    + +