diff --git a/src/api/http.api.ts b/src/api/http.api.ts index a5a163da..51b981b8 100644 --- a/src/api/http.api.ts +++ b/src/api/http.api.ts @@ -30,7 +30,7 @@ export const createClient = (config?: AxiosRequestConfig) => { return config; }, (error) => { - console.log('interceptors request error:', error); + console.error('interceptors request error:', error); return Promise.reject(error); } ); diff --git a/src/components/common/header/Notification/Notification.styled.ts b/src/components/common/header/Notification/Notification.styled.ts index c09ced8e..dcca0929 100644 --- a/src/components/common/header/Notification/Notification.styled.ts +++ b/src/components/common/header/Notification/Notification.styled.ts @@ -26,7 +26,7 @@ export const NotificationHeader = styled.div` display: flex; justify-content: right; align-items: center; - height: fix-content; + height: fit-content; margin-right: 15px; `; diff --git a/src/components/user/customerService/inquiry/Inquiry.tsx b/src/components/user/customerService/inquiry/Inquiry.tsx index af49aef4..e0982b51 100644 --- a/src/components/user/customerService/inquiry/Inquiry.tsx +++ b/src/components/user/customerService/inquiry/Inquiry.tsx @@ -65,8 +65,6 @@ export default function Inquiry() { content: form.content.trim() !== '', }; - console.log(isCategoryOpen); - if (!isValid.category) { return handleModalOpen(INQUIRY_MESSAGE.selectCategory); } diff --git a/src/components/user/manageProjects/Card.styled.ts b/src/components/user/manageProjects/Card.styled.ts index f22e8d7f..5afca4a2 100644 --- a/src/components/user/manageProjects/Card.styled.ts +++ b/src/components/user/manageProjects/Card.styled.ts @@ -1,3 +1,4 @@ +import { Link } from 'react-router-dom'; import styled from 'styled-components'; export const CardWrapper = styled.div` @@ -31,7 +32,7 @@ export const ButtonWrapper = styled.div` margin-top: 1rem; width: 100%; display: flex; - justify-content: end; + justify-content: space-between; `; export const CardTitle = styled.h3` @@ -89,3 +90,18 @@ export const RecruitmentEnd = styled.span` font-size: 0.8rem; font-weight: 800; `; + +export const EvaluateButton = styled(Link)` + display: inline-flex; + flex-shrink: 0; + padding: 0.2rem 0.65rem; + background-color: #3e5879; + font-size: 0.9rem; + color: ${({ theme }) => theme.color.white}; + border-radius: 10px; + text-align: center; + + @media ${({ theme }) => theme.mediaQuery.tablet} { + font-size: 0.78rem; + } +`; diff --git a/src/components/user/manageProjects/Card.tsx b/src/components/user/manageProjects/Card.tsx index 3800ea8e..ab5cfcab 100644 --- a/src/components/user/manageProjects/Card.tsx +++ b/src/components/user/manageProjects/Card.tsx @@ -2,6 +2,7 @@ import * as S from './Card.styled'; import type { ManagedProject } from '../../../models/manageMyProject'; import AvatarList from '../../common/avatar/AvatarList'; import { formatDate } from '../../../util/formatDate'; +import { ROUTES } from '../../../constants/user/routes'; interface CardProps { project: ManagedProject; } @@ -17,6 +18,14 @@ function Card({ project }: CardProps) { + {project.canEvaluate && ( + + 평가하기 + + )} {project.isDone && 모집 종료} diff --git a/src/components/user/mypage/joinedProject/MyJoinProjects.styled.ts b/src/components/user/mypage/joinedProject/MyJoinProjects.styled.ts index d1e9efeb..28cb3c6c 100644 --- a/src/components/user/mypage/joinedProject/MyJoinProjects.styled.ts +++ b/src/components/user/mypage/joinedProject/MyJoinProjects.styled.ts @@ -45,7 +45,7 @@ export const WrapperProject = styled.div` padding: 1rem; } - a { + & > a { display: inline-block; width: 46%; } diff --git a/src/components/user/mypage/joinedProject/MyJoinProjects.tsx b/src/components/user/mypage/joinedProject/MyJoinProjects.tsx index ab88846b..85f6babb 100644 --- a/src/components/user/mypage/joinedProject/MyJoinProjects.tsx +++ b/src/components/user/mypage/joinedProject/MyJoinProjects.tsx @@ -27,7 +27,7 @@ const MyJoinProjects = () => { key={project.id} to={`${ROUTES.projectDetail}/${project.id}`} > - + ))} diff --git a/src/components/user/mypage/joinedProject/Project.styled.ts b/src/components/user/mypage/joinedProject/Project.styled.ts index 9d9a9c60..0c7e22aa 100644 --- a/src/components/user/mypage/joinedProject/Project.styled.ts +++ b/src/components/user/mypage/joinedProject/Project.styled.ts @@ -1,3 +1,4 @@ +import { Link } from 'react-router-dom'; import styled from 'styled-components'; export const Container = styled.div` @@ -115,6 +116,7 @@ export const State = styled.span` export const Skill = styled.div` display: flex; flex-wrap: wrap; + justify-content: space-between; align-items: center; gap: 0.6rem; @@ -129,8 +131,8 @@ export const Skill = styled.div` border-radius: 50%; @media ${({ theme }) => theme.mediaQuery.tablet} { - width: 20px; - height: 20px; + width: 27px; + height: 27px; } } @@ -138,3 +140,21 @@ export const Skill = styled.div` color: rgb(196 196 196); } `; + +export const SkillArea = styled.div``; + +export const EvaluateButton = styled(Link)` + display: inline-flex; + flex-shrink: 0; + padding: 0.2rem 0.65rem; + background-color: #3e5879; + font-size: 0.9rem; + color: ${({ theme }) => theme.color.white}; + border-radius: 10px; + text-align: center; + margin-left: auto; + + @media ${({ theme }) => theme.mediaQuery.tablet} { + font-size: 0.78rem; + } +`; diff --git a/src/components/user/mypage/joinedProject/Project.tsx b/src/components/user/mypage/joinedProject/Project.tsx index 31cfd7b9..42d2f66d 100644 --- a/src/components/user/mypage/joinedProject/Project.tsx +++ b/src/components/user/mypage/joinedProject/Project.tsx @@ -2,12 +2,14 @@ import * as S from './Project.styled'; import { EllipsisHorizontalIcon } from '@heroicons/react/24/outline'; import type { JoinedProject } from '../../../../models/userProject'; import beginner from '../../../../assets/beginner.svg'; +import { ROUTES } from '../../../../constants/user/routes'; interface ProjectProps { project: JoinedProject; + canEvaluate?: boolean; } -const Project = ({ project }: ProjectProps) => { +const Project = ({ project, canEvaluate }: ProjectProps) => { const maxSkills = 4; const skillsShow = project.skills.slice(0, maxSkills); return ( @@ -29,11 +31,21 @@ const Project = ({ project }: ProjectProps) => { {project.isDone ? '모집 마감' : '모집 중'} - {skillsShow.map((skill) => ( - - ))} - {project.skills.length > maxSkills && ( - + + {skillsShow.map((skill) => ( + + ))} + {project.skills.length > maxSkills && ( + + )} + + {canEvaluate && ( + + 평가하기 + )} diff --git a/src/components/user/mypage/myProfile/profile/Profile.tsx b/src/components/user/mypage/myProfile/profile/Profile.tsx index 38ea7627..5e73c62e 100644 --- a/src/components/user/mypage/myProfile/profile/Profile.tsx +++ b/src/components/user/mypage/myProfile/profile/Profile.tsx @@ -30,8 +30,6 @@ export default function Profile() { ], }; - console.log(userInfoData.averageScores); - useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollTop = 0; diff --git a/src/constants/user/modalMessage.ts b/src/constants/user/modalMessage.ts index 6d8a5766..93b1fb95 100644 --- a/src/constants/user/modalMessage.ts +++ b/src/constants/user/modalMessage.ts @@ -25,4 +25,5 @@ export const MODAL_MESSAGE = { applyProjectFail: '해당 공고에 지원을 실패 되었습니다.', projectDetailFail: '해당 공고가 존재하지 않습니다.', alreadyApply: '이미 참여한/지원하신 공고 입니다.', + noMemberToEvaluate: '평가 할 멤버가 없습니다.', } as const; diff --git a/src/hooks/user/CommentHooks/usePatchReply.ts b/src/hooks/user/CommentHooks/usePatchReply.ts index 86e2d4b9..bdd2a558 100644 --- a/src/hooks/user/CommentHooks/usePatchReply.ts +++ b/src/hooks/user/CommentHooks/usePatchReply.ts @@ -18,7 +18,7 @@ const usePatchReply = ( }); }, onError: (error) => { - console.log(error); + console.error(error); }, }); diff --git a/src/hooks/user/CommentHooks/usePostComment.ts b/src/hooks/user/CommentHooks/usePostComment.ts index 030de7e1..ab4af545 100644 --- a/src/hooks/user/CommentHooks/usePostComment.ts +++ b/src/hooks/user/CommentHooks/usePostComment.ts @@ -14,7 +14,7 @@ const usePostComment = (id: number) => { }); }, onError: (error) => { - console.log(error); + console.error(error); }, }); diff --git a/src/hooks/user/CommentHooks/usePutComment.ts b/src/hooks/user/CommentHooks/usePutComment.ts index 4a372613..c1ac279c 100644 --- a/src/hooks/user/CommentHooks/usePutComment.ts +++ b/src/hooks/user/CommentHooks/usePutComment.ts @@ -13,7 +13,7 @@ const usePutComment = (id: number, commentId: number) => { }); }, onError: (error) => { - console.log(error); + console.error(error); }, }); diff --git a/src/hooks/user/ProjectHooks/useApplyProject.ts b/src/hooks/user/ProjectHooks/useApplyProject.ts index ffa091d8..7b7daf9c 100644 --- a/src/hooks/user/ProjectHooks/useApplyProject.ts +++ b/src/hooks/user/ProjectHooks/useApplyProject.ts @@ -35,7 +35,7 @@ const useApplyProject = ({ id, handleModalOpen }: UseApplyProjectProps) => { }, 3000); }, onError: (error) => { - console.log(error); + console.error(error); handleModalOpen(MODAL_MESSAGE.applyProjectFail); }, }); diff --git a/src/hooks/user/ProjectHooks/useCreateProject.ts b/src/hooks/user/ProjectHooks/useCreateProject.ts index 84f5ac36..b90a4829 100644 --- a/src/hooks/user/ProjectHooks/useCreateProject.ts +++ b/src/hooks/user/ProjectHooks/useCreateProject.ts @@ -28,7 +28,7 @@ const useCreateProject = ({ handleModalOpen }: UseCreateProjectProps) => { }, 3000); }, onError: (error) => { - console.log(error); + console.error(error); handleModalOpen(MODAL_MESSAGE.createProjectFail); }, }); diff --git a/src/hooks/user/ProjectHooks/useUpdateProject.ts b/src/hooks/user/ProjectHooks/useUpdateProject.ts index 8a1cbcd2..60dc103b 100644 --- a/src/hooks/user/ProjectHooks/useUpdateProject.ts +++ b/src/hooks/user/ProjectHooks/useUpdateProject.ts @@ -30,7 +30,7 @@ const useUpdateProject = ({ id, handleModalOpen }: UseUpdateProjectProps) => { }, onError: (error) => { handleModalOpen(MODAL_MESSAGE.ModifyProjectFail); - console.log(error); + console.error(error); }, }); diff --git a/src/hooks/user/evaluationHooks/useGetEvaluation.ts b/src/hooks/user/evaluationHooks/useGetEvaluation.ts index 07fab730..25b33338 100644 --- a/src/hooks/user/evaluationHooks/useGetEvaluation.ts +++ b/src/hooks/user/evaluationHooks/useGetEvaluation.ts @@ -1,14 +1,32 @@ import { useQuery } from '@tanstack/react-query'; import { getEvaluation } from '../../../api/evaluation.api'; import { ProjectMemberListEval } from '../../queries/user/keys'; +import { useEffect } from 'react'; +import { MODAL_MESSAGE } from '../../../constants/user/modalMessage'; +import { useNavigate } from 'react-router-dom'; -const useGetCompletedEvaluation = (id: number) => { +interface useGetCompletedEvaluationProps { + projectId: number; + handleModalOpen: (newMessage: string, callback?: () => void) => void; +} + +const useGetCompletedEvaluation = ({ + projectId, + handleModalOpen, +}: useGetCompletedEvaluationProps) => { + const navigate = useNavigate(); const { data, isLoading, isFetching, isError } = useQuery({ - queryKey: [ProjectMemberListEval.MemberListEval, id], - queryFn: () => getEvaluation(id), + queryKey: [ProjectMemberListEval.MemberListEval, projectId], + queryFn: () => getEvaluation(projectId), staleTime: 1000 * 60 * 5, }); + useEffect(() => { + if (data && (!data.userData || data.userData.length === 0)) { + handleModalOpen(MODAL_MESSAGE.noMemberToEvaluate, () => navigate(-1)); + } + }, [data, handleModalOpen, navigate]); + return { memberList: data, isLoading, diff --git a/src/hooks/user/useNotification.ts b/src/hooks/user/useNotification.ts index 7be16cdf..54f5c343 100644 --- a/src/hooks/user/useNotification.ts +++ b/src/hooks/user/useNotification.ts @@ -48,7 +48,6 @@ const useNotification = () => { eventSource.addEventListener('alarm', (e) => { const event = e as MessageEvent; try { - console.log(JSON.parse(event.data)); const eventData: AlarmLive = JSON.parse(event.data); if (eventData) { @@ -63,7 +62,7 @@ const useNotification = () => { } }); eventSource.onerror = (e) => { - console.log(e); + console.error(e); }; }, [queryClient, userId]); diff --git a/src/models/manageMyProject.ts b/src/models/manageMyProject.ts index 8a8a1cd9..c546b866 100644 --- a/src/models/manageMyProject.ts +++ b/src/models/manageMyProject.ts @@ -19,6 +19,7 @@ export interface ManagedProject { methodType: MethodType; positions: PositionTag[]; skills: SkillTag[]; + canEvaluate: boolean; } export interface MethodType { diff --git a/src/models/userProject.ts b/src/models/userProject.ts index 45cd7946..da9d676f 100644 --- a/src/models/userProject.ts +++ b/src/models/userProject.ts @@ -9,6 +9,7 @@ export interface JoinedProject { recruitmentEndDate: string; totalMember: number; skills: Omit[]; + canEvaluate: boolean; } export interface ApiJoinedProject extends ApiCommonType { diff --git a/src/pages/user/evaluation/Evaluation.tsx b/src/pages/user/evaluation/Evaluation.tsx index c2df6580..a3f12145 100644 --- a/src/pages/user/evaluation/Evaluation.tsx +++ b/src/pages/user/evaluation/Evaluation.tsx @@ -3,30 +3,41 @@ import * as S from './Evaluation.styled'; import useGetCompletedEvaluation from '../../../hooks/user/evaluationHooks/useGetEvaluation'; import LoadingSpinner from '../../../components/common/loadingSpinner/LoadingSpinner'; import EvaluationContent from '../../../components/user/evaluation/EvaluationContent'; +import Modal from '../../../components/common/modal/Modal'; +import { useModal } from '../../../hooks/useModal'; const Evaluation = () => { const { projectId: projectIdParam } = useParams(); const projectId = Number(projectIdParam); + const { isOpen, message, handleModalOpen, handleModalClose, handleConfirm } = + useModal(); - const { memberList, isLoading, isFetching } = - useGetCompletedEvaluation(projectId); + const { memberList, isLoading, isFetching } = useGetCompletedEvaluation({ + projectId, + handleModalOpen, + }); if (isLoading || isFetching) { return ; } - if (!memberList.userData.length) { - return 평가할 멤버가 없습니다.; - } - return ( - - - + <> + + + + + {message} + + ); }; diff --git a/src/pages/user/projectDetail/ProjectDetail.tsx b/src/pages/user/projectDetail/ProjectDetail.tsx index c149ddc0..73313c68 100644 --- a/src/pages/user/projectDetail/ProjectDetail.tsx +++ b/src/pages/user/projectDetail/ProjectDetail.tsx @@ -25,10 +25,10 @@ const ProjectDetail = () => { const { userData } = useAuthStore((state) => state); useEffect(() => { - if (!data) { + if (!isLoading && !isFetching && !data) { handleModalOpen(MODAL_MESSAGE.projectDetailFail); } - }, [data, handleModalOpen]); + }, [data, handleModalOpen, isLoading, isFetching]); if (isLoading || isFetching) return ;