diff --git a/src/api/applicant.api.ts b/src/api/applicant.api.ts index 639284b9..2fe828b4 100644 --- a/src/api/applicant.api.ts +++ b/src/api/applicant.api.ts @@ -1,4 +1,4 @@ -import { ApiApplicantInfo, ApiApplicants } from '../models/applicant'; +import type { ApiApplicantInfo, ApiApplicants } from '../models/applicant'; import { httpClient } from './http.api'; export const getApplicantList = async (projectId: number) => { diff --git a/src/api/auth.api.ts b/src/api/auth.api.ts index b00e5634..31692e2d 100644 --- a/src/api/auth.api.ts +++ b/src/api/auth.api.ts @@ -1,4 +1,4 @@ -import { ApiVerifyNickname, VerifyEmail } from '../models/auth'; +import type { ApiVerifyNickname, VerifyEmail } from '../models/auth'; import { httpClient } from './http.api'; import { loginFormValues } from '../pages/login/Login'; import { registerFormValues } from '../pages/user/register/Register'; diff --git a/src/api/comment.api.ts b/src/api/comment.api.ts index 8de2df25..4c334148 100644 --- a/src/api/comment.api.ts +++ b/src/api/comment.api.ts @@ -1,4 +1,4 @@ -import { CommentType } from '../models/comment'; +import type { CommentType } from '../models/comment'; import { httpClient } from './http.api'; export const postComment = async (id: number, content: string) => { diff --git a/src/api/evaluation.api.ts b/src/api/evaluation.api.ts index 5bb99af1..4ff79d99 100644 --- a/src/api/evaluation.api.ts +++ b/src/api/evaluation.api.ts @@ -1,4 +1,4 @@ -import { apiEvaluatedUser } from '../models/evaluation'; +import type { apiEvaluatedUser } from '../models/evaluation'; import { httpClient } from './http.api'; export const postEvaluation = async (userEvaluation: apiEvaluatedUser) => { diff --git a/src/api/joinProject.api.ts b/src/api/joinProject.api.ts index bd529a96..32bb07fc 100644 --- a/src/api/joinProject.api.ts +++ b/src/api/joinProject.api.ts @@ -1,6 +1,6 @@ -import { FormData } from '../models/createProject'; -import { joinProject } from '../models/joinProject'; -import { ProjectDetailPlusExtended } from '../models/projectDetail'; +import type { FormData } from '../models/createProject'; +import type { joinProject } from '../models/joinProject'; +import type { ProjectDetailPlusExtended } from '../models/projectDetail'; import { httpClient } from './http.api'; export const getProjectData = async ( diff --git a/src/api/myProjectList.api.ts b/src/api/myProjectList.api.ts index 4371c0fc..798eda6b 100644 --- a/src/api/myProjectList.api.ts +++ b/src/api/myProjectList.api.ts @@ -1,4 +1,7 @@ -import { ManagedProject, ApiManagedProjects } from '../models/manageMyProject'; +import type { + ManagedProject, + ApiManagedProjects, +} from '../models/manageMyProject'; import { httpClient } from './http.api'; export const getMyProjectLists = async () => { diff --git a/src/api/mypage.api.ts b/src/api/mypage.api.ts index 1178f506..594a2593 100644 --- a/src/api/mypage.api.ts +++ b/src/api/mypage.api.ts @@ -1,5 +1,12 @@ -import { ApiUserInfo, ApiUserInfoImg, EditMyInfo } from '../models/userInfo'; -import { ApiAppliedProject, ApiJoinedProject } from '../models/userProject'; +import type { + ApiUserInfo, + ApiUserInfoImg, + EditMyInfo, +} from '../models/userInfo'; +import type { + ApiAppliedProject, + ApiJoinedProject, +} from '../models/userProject'; import { httpClient } from './http.api'; export const getMyInfo = async () => { diff --git a/src/api/projectLists.api.ts b/src/api/projectLists.api.ts index d47bead2..a2473dac 100644 --- a/src/api/projectLists.api.ts +++ b/src/api/projectLists.api.ts @@ -2,7 +2,7 @@ import type { ApiProjectLists, ApiProjectStatistic, } from '../models/mainProjectLists'; -import { SearchFilters } from '../models/SearchFilters'; +import type { SearchFilters } from '../models/SearchFilters'; import { httpClient } from './http.api'; export const getProjectLists = async (params: SearchFilters) => { diff --git a/src/api/reply.api.ts b/src/api/reply.api.ts index d1cfd4cc..804100ae 100644 --- a/src/api/reply.api.ts +++ b/src/api/reply.api.ts @@ -1,4 +1,4 @@ -import { ReplyType } from '../models/comment'; +import type { ReplyType } from '../models/comment'; import { httpClient } from './http.api'; export const getReply = async ( diff --git a/src/api/report.api.ts b/src/api/report.api.ts index 66653b8f..111ef186 100644 --- a/src/api/report.api.ts +++ b/src/api/report.api.ts @@ -1,4 +1,4 @@ -import { ApiPostContent } from '../models/report'; +import type { ApiPostContent } from '../models/report'; import { httpClient } from './http.api'; export const postReport = async (formData: ApiPostContent) => { diff --git a/src/assets/ArrowRight.svg b/src/assets/ArrowRight.svg new file mode 100644 index 00000000..5262e81d --- /dev/null +++ b/src/assets/ArrowRight.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/common/Toast/Toast.styled.ts b/src/components/common/Toast/Toast.styled.ts index e0d90ae2..beac879d 100644 --- a/src/components/common/Toast/Toast.styled.ts +++ b/src/components/common/Toast/Toast.styled.ts @@ -21,15 +21,16 @@ export const Container = styled.div` `; export const Item = styled.div<{ $exiting: boolean }>` - background-color: ${({ theme }) => theme.buttonScheme.grey.color}; + background-color: #ffffff; + border: 6px solid ${({ theme }) => theme.color.border}; padding: 12px 20px; - border-radius: ${({ theme }) => theme.borderRadius.small}; + border-radius: ${({ theme }) => theme.borderRadius.primary}; animation: ${fadeInUp} 0.3s ease-out, ${({ $exiting }) => $exiting && fadeOut} 0.3s ease-in forwards; `; export const LiveMessage = styled.p` - color: ${({ theme }) => theme.color.white}; + color: ${({ theme }) => theme.color.primary}; font-size: 0.95rem; white-space: nowrap; overflow: hidden; @@ -37,9 +38,22 @@ export const LiveMessage = styled.p` `; export const LiveDate = styled.p` - color: ${({ theme }) => theme.color.white}; + color: ${({ theme }) => theme.color.primary}; font-size: 0.95rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + margin-right: 5px; + opacity: 80%; +`; + +export const TypeArea = styled.div` + display: flex; + margin-left: 1px; +`; + +export const Type = styled.p``; + +export const TypeFilter = styled.p` + color: ${({ theme }) => theme.color.primary}; + font-size: 0.95rem; + opacity: 80%; + margin-right: 6px; `; diff --git a/src/components/common/Toast/ToastItem.tsx b/src/components/common/Toast/ToastItem.tsx index a0b08e04..b3dd58b2 100644 --- a/src/components/common/Toast/ToastItem.tsx +++ b/src/components/common/Toast/ToastItem.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import * as S from './Toast.styled'; -import { AlarmLive } from '../../../models/alarm'; +import type { AlarmLive } from '../../../models/alarm'; import { Link } from 'react-router-dom'; import { routeSelector } from '../../../util/routeSelector'; import { timeAgo } from '../../../util/timeAgo'; @@ -29,7 +29,18 @@ const ToastItem = ({ content, duration, onRemove }: ToastItemProps) => { {content.message} - {timeAgo(content.createAt)} + + {timeAgo(content.createAt)} | + + {content.alarmFilterId === 1 + ? '문의 답변' + : content.alarmFilterId === 2 + ? '지원자 확인' + : content.alarmFilterId === 3 + ? '댓글 답변' + : '기타'} + + ); diff --git a/src/components/common/Toast/ToastProvider.tsx b/src/components/common/Toast/ToastProvider.tsx index 46a54ea6..1a57fdff 100644 --- a/src/components/common/Toast/ToastProvider.tsx +++ b/src/components/common/Toast/ToastProvider.tsx @@ -1,7 +1,7 @@ import { PropsWithChildren, useCallback, useEffect, useState } from 'react'; import { ToastContext, ToastMessage } from '../../../context/ToastContext'; import ToastContainer from './ToastContainer'; -import { AlarmLive } from '../../../models/alarm'; +import type { AlarmLive } from '../../../models/alarm'; export const ToastProvider = ({ children }: PropsWithChildren) => { const [toasts, setToasts] = useState([]); diff --git a/src/components/common/avatar/AvatarList.tsx b/src/components/common/avatar/AvatarList.tsx index 5377257e..6ce87318 100644 --- a/src/components/common/avatar/AvatarList.tsx +++ b/src/components/common/avatar/AvatarList.tsx @@ -1,7 +1,7 @@ import * as S from './AvatarList.styled'; import Avatar from './Avatar'; import { formatImgPath } from '../../../util/formatImgPath'; -import { SkillTag } from '../../../models/tags'; +import type { SkillTag } from '../../../models/tags'; export interface AvatarListProps { avatars: SkillTag[] | null; size?: string; diff --git a/src/components/common/dropDown/DropDown.styled.ts b/src/components/common/dropDown/DropDown.styled.ts index 723df0e5..f9f3d83f 100644 --- a/src/components/common/dropDown/DropDown.styled.ts +++ b/src/components/common/dropDown/DropDown.styled.ts @@ -1,4 +1,4 @@ -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; export const DropDownContainer = styled.div` position: relative; @@ -11,12 +11,20 @@ export const DropDownButtonWrapper = styled.div` outline: none; `; -export const Panel = styled.div` +export const Panel = styled.div<{ $comment: boolean }>` position: absolute; - top: 50px; + top: 40px; right: 0; background-color: ${({ theme }) => theme.color.white}; border-radius: ${({ theme }) => theme.borderRadius.primary}; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); z-index: 100; + + ${({ $comment }) => + $comment && + css` + position: absolute; + top: 0px; + right: 30px; + `} `; diff --git a/src/components/common/dropDown/DropDown.tsx b/src/components/common/dropDown/DropDown.tsx index 515f87a0..32c40a6e 100644 --- a/src/components/common/dropDown/DropDown.tsx +++ b/src/components/common/dropDown/DropDown.tsx @@ -7,12 +7,14 @@ interface DropDownProps { children: React.ReactNode; toggleButton: React.ReactNode; isOpen?: boolean; + comment: boolean; } const DropDown = ({ children, toggleButton, isOpen = false, + comment, ...props }: DropDownProps) => { const [open, setOpen] = useState(isOpen); @@ -31,7 +33,7 @@ const DropDown = ({ > {toggleButton} - {open && {children}} + {open && {children}} ); diff --git a/src/components/common/header/Header.tsx b/src/components/common/header/Header.tsx index c2dc1aaf..a8c6c482 100644 --- a/src/components/common/header/Header.tsx +++ b/src/components/common/header/Header.tsx @@ -83,6 +83,7 @@ function Header() { ) } + comment={false} > <> {isLoggedIn && ( diff --git a/src/components/common/header/Notification/Notification.styled.ts b/src/components/common/header/Notification/Notification.styled.ts index 1250b3b1..c09ced8e 100644 --- a/src/components/common/header/Notification/Notification.styled.ts +++ b/src/components/common/header/Notification/Notification.styled.ts @@ -22,7 +22,26 @@ export const ScrollArea = styled.div` } `; +export const NotificationHeader = styled.div` + display: flex; + justify-content: right; + align-items: center; + height: fix-content; + margin-right: 15px; +`; + +export const MoreArea = styled.button``; + +export const More = styled.span``; + +export const Arrow = styled.img` + margin-bottom: 3px; +`; + export const NonContentsMessage = styled.p` + display: flex; + justify-content: center; + align-items: center; margin-left: 6px; `; diff --git a/src/components/common/header/Notification/Notification.tsx b/src/components/common/header/Notification/Notification.tsx index 9b74bc80..cf8daa84 100644 --- a/src/components/common/header/Notification/Notification.tsx +++ b/src/components/common/header/Notification/Notification.tsx @@ -3,8 +3,12 @@ import * as S from './Notification.styled'; import NotificationItem from './NotificationItem/NotificationItem'; import LoadingSpinner from '../../loadingSpinner/LoadingSpinner'; import useAlarmList from '../../../../hooks/user/useAlarmList'; +import arrow_right from '../../../../assets/ArrowRight.svg'; +import { useNavigate } from 'react-router-dom'; +import { ROUTES } from '../../../../constants/user/routes'; const Notification = () => { + const navigate = useNavigate(); const { alarmListData: AlarmData, isLoading, isFetching } = useAlarmList(); if (!AlarmData) { @@ -21,6 +25,17 @@ const Notification = () => { return ( + + + navigate(`${ROUTES.mypage}/${ROUTES.myPageNotifications}`) + } + > + 더보기 + + + + {AlarmData.map((item, index) => ( diff --git a/src/components/common/header/Notification/NotificationItem/NotificationItem.styled.ts b/src/components/common/header/Notification/NotificationItem/NotificationItem.styled.ts index 954f4a7e..ce92af65 100644 --- a/src/components/common/header/Notification/NotificationItem/NotificationItem.styled.ts +++ b/src/components/common/header/Notification/NotificationItem/NotificationItem.styled.ts @@ -1,16 +1,47 @@ -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; export const Container = styled.div` padding: 8px 0; font-size: 14px; `; +export const TypeArea = styled.div` + display: flex; + margin-left: 6px; +`; + +export const Type = styled.p``; + +export const TypeFilter = styled.p` + font-size: 12px; + opacity: 50%; + margin-right: 6px; +`; + export const ItemContent = styled.p` + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; margin-left: 6px; `; export const Time = styled.span` - margin-left: 6px; color: #999; font-size: 12px; + margin-left: 6px; + margin-right: 5px; +`; + +export const Dot = styled.span<{ $isRead: boolean }>` + width: 5px; + height: 5px; + background-color: #ff3b30; + border-radius: 50%; + margin-top: 6px; + + ${({ $isRead }) => + $isRead && + css` + background-color: #00db42; + `} `; diff --git a/src/components/common/header/Notification/NotificationItem/NotificationItem.tsx b/src/components/common/header/Notification/NotificationItem/NotificationItem.tsx index 5f0fae79..11cd27d5 100644 --- a/src/components/common/header/Notification/NotificationItem/NotificationItem.tsx +++ b/src/components/common/header/Notification/NotificationItem/NotificationItem.tsx @@ -1,5 +1,5 @@ import { Link } from 'react-router-dom'; -import { Alarm } from '../../../../../models/alarm'; +import type { Alarm } from '../../../../../models/alarm'; import * as S from './NotificationItem.styled'; import { routeSelector } from '../../../../../util/routeSelector'; import { useContext } from 'react'; @@ -17,7 +17,19 @@ const NotificationItem = ({ item }: NotificationItemProps) => { {item.content} - {timeAgo(item.createdAt)} + + {timeAgo(item.createdAt)} + + {item.alarmFilterId === 1 + ? '문의 답변' + : item.alarmFilterId === 2 + ? '지원자 확인' + : item.alarmFilterId === 3 + ? '댓글 답변' + : '기타'} + + + ); diff --git a/src/components/user/comment/CommentLayout.styled.ts b/src/components/user/comment/CommentLayout.styled.ts index d9a6394e..ecfb5aea 100644 --- a/src/components/user/comment/CommentLayout.styled.ts +++ b/src/components/user/comment/CommentLayout.styled.ts @@ -17,6 +17,7 @@ export const Count = styled.span` export const CommentContainer = styled.div``; export const CommentInput = styled.div` + display: flex; margin-bottom: 40px; `; diff --git a/src/components/user/comment/CommentLayout.tsx b/src/components/user/comment/CommentLayout.tsx index 055d3ec5..14ac08fe 100644 --- a/src/components/user/comment/CommentLayout.tsx +++ b/src/components/user/comment/CommentLayout.tsx @@ -3,6 +3,10 @@ import CommentInput from './commentInput/CommentInput'; import LoadingSpinner from '../../common/loadingSpinner/LoadingSpinner'; import useGetComment from '../../../hooks/user/CommentHooks/useGetComment'; import CommentComponentLayout from './commentComponent/CommentComponentLayout'; +import Avatar from '../../common/avatar/Avatar'; +import { useMyProfileInfo } from '../../../hooks/user/useMyInfo'; +import { formatImgPath } from '../../../util/formatImgPath'; +import DefaultImg from '../../../assets/defaultImg.png'; interface CommentLayoutProps { projectId: number; @@ -15,8 +19,15 @@ const CommentLayout = ({ createrId, loginUserId, }: CommentLayoutProps) => { + const { myData } = useMyProfileInfo(); const { getCommentList, isLoading, isFetching } = useGetComment(projectId); + const profileImg = myData?.profileImg + ? `${import.meta.env.VITE_APP_IMAGE_CDN_URL}/${formatImgPath( + myData.profileImg + )}?w=86&h=86&fit=crop&crop=entropy&auto=format,enhance&q=60` + : DefaultImg; + if (!getCommentList) { return ( @@ -37,6 +48,7 @@ const CommentLayout = ({ + diff --git a/src/components/user/comment/DropDownItem.styled.ts b/src/components/user/comment/DropDownItem.styled.ts index 3864d4ae..170fccb1 100644 --- a/src/components/user/comment/DropDownItem.styled.ts +++ b/src/components/user/comment/DropDownItem.styled.ts @@ -1,29 +1,32 @@ import styled from 'styled-components'; -export const Container = styled.div` - position: absolute; - top: -20px; - right: 0; - width: 120px; - background-color: #f7f7f7; - border: 1px solid #e0e0e0; - border-radius: 4px; - overflow: hidden; - z-index: 999; +export const Container = styled.ul` + display: flex; + flex-direction: column; + justify-content: center; + width: 5.5rem; `; export const Item = styled.div` padding: 12px 16px; - font-size: 14px; - color: #333; + font-size: 0.9rem; + font-weight: 600; + line-height: 1; + color: inherit; cursor: pointer; - background-color: #f7f7f7; &:hover { - background-color: #eaeaea; + color: ${({ theme }) => theme.color.white}; + background-color: ${({ theme }) => theme.color.navy}; } - & + & { - border-top: 1px solid #ccc; + &:last-child { + border-bottom-left-radius: ${({ theme }) => theme.borderRadius.primary}; + border-bottom-right-radius: ${({ theme }) => theme.borderRadius.primary}; } `; + +export const ReportItem = styled(Item)` + border-top-left-radius: ${({ theme }) => theme.borderRadius.primary}; + border-top-right-radius: ${({ theme }) => theme.borderRadius.primary}; +`; diff --git a/src/components/user/comment/DropDownItem.tsx b/src/components/user/comment/DropDownItem.tsx index f6de9cf5..27bcbb3b 100644 --- a/src/components/user/comment/DropDownItem.tsx +++ b/src/components/user/comment/DropDownItem.tsx @@ -1,8 +1,8 @@ import useDeleteComment from '../../../hooks/user/CommentHooks/useDeleteComment'; import useDeleteReply from '../../../hooks/user/CommentHooks/useDeleteReply'; -import { useModal } from '../../../hooks/useModal'; import ReportModal from '../reportComponent/ReportModal'; import * as S from './DropDownItem.styled'; +import useReportModal from '../../../hooks/user/useReportModal'; interface DropdownProps { projectId: number; @@ -29,7 +29,8 @@ const DropDownItem = ({ }: DropdownProps) => { const { removeComment } = useDeleteComment(projectId); const { removeReply } = useDeleteReply(commentId, projectId); - const { isOpen, handleOpenReportModal, handleCloseReportModal } = useModal(); + const { isOpen, handleOpenReportModal, handleCloseReportModal } = + useReportModal(); const onDelete = (commentId: number, recommentId?: number) => { if (reply && recommentId) { @@ -41,9 +42,8 @@ const DropDownItem = ({ return ( <> + 신고하기 - 신고하기 - {loginUserId === commentUserId && ( <> @@ -61,6 +61,7 @@ const DropDownItem = ({ targetId={recommentId ? recommentId : commentId} type={recommentId ? 'recomment' : 'comment'} onClose={handleCloseReportModal} + route={projectId} /> )} diff --git a/src/components/user/comment/commentComponent/CommentComponentLayout.styled.ts b/src/components/user/comment/commentComponent/CommentComponentLayout.styled.ts index 7e478c2f..e9f988c1 100644 --- a/src/components/user/comment/commentComponent/CommentComponentLayout.styled.ts +++ b/src/components/user/comment/commentComponent/CommentComponentLayout.styled.ts @@ -17,18 +17,18 @@ export const ReplyContainer = styled.div` cursor: pointer; `; -export const ReplyContent = styled.p` - margin-bottom: 30px; -`; +export const ReplyContent = styled.p``; export const CommentInput = styled.div` text-indent: 20px; `; export const ShowReply = styled.div` - padding-left: 85px; -`; - -export const ShowReplyButton = styled.span` - display: flex; + display: inline-flex; + align-items: center; + margin-left: 85px; + margin-bottom: 30px; + width: fit-content; + height: fit-content; + cursor: pointer; `; diff --git a/src/components/user/comment/commentComponent/CommentComponentLayout.tsx b/src/components/user/comment/commentComponent/CommentComponentLayout.tsx index a9316519..f0073fff 100644 --- a/src/components/user/comment/commentComponent/CommentComponentLayout.tsx +++ b/src/components/user/comment/commentComponent/CommentComponentLayout.tsx @@ -51,51 +51,44 @@ const CommentComponentLayout = ({ projectId={projectId} setActivateEditMode={setActivateEditMode} /> - - } - > - onEdit(item.id)} - loginUserId={loginUserId} - commentUserId={item.user.id} - reportTitle={item.content} - activateEditMode={activateEditMode} - /> - - - - - {item.recommentCount !== 0 && ( - handleShowReplyClick(item.id)}> - - - {isShowReply ? ( - - ) : ( - - )} - - - {item.recommentCount}개 답글 확인 - - - - )} - - {isShowReply === item.id && ( - - + } + comment={true} + > + onEdit(item.id)} + loginUserId={loginUserId} + commentUserId={item.user.id} + reportTitle={item.content} + activateEditMode={activateEditMode} /> - + )} - + + + {item.recommentCount !== 0 && ( + handleShowReplyClick(item.id)}> + + {isShowReply ? : } + + {item.recommentCount}개 답글 확인 + + )} + + {isShowReply === item.id && ( + + + + )} ))} diff --git a/src/components/user/comment/commentComponent/commentComponent/CommentComponent.styled.ts b/src/components/user/comment/commentComponent/commentComponent/CommentComponent.styled.ts index 2584fde7..a53dee1a 100644 --- a/src/components/user/comment/commentComponent/commentComponent/CommentComponent.styled.ts +++ b/src/components/user/comment/commentComponent/commentComponent/CommentComponent.styled.ts @@ -1,7 +1,17 @@ -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; -export const Container = styled.div` +export const Container = styled.div<{ $reply: boolean }>` flex: 1; + + ${({ $reply }) => + $reply && + css` + display: flex; + justify-content: space-between; + width: 100%; + margin-bottom: 20px; + padding-left: 85px; + `} `; export const Wrapper = styled.div` @@ -11,17 +21,18 @@ export const Wrapper = styled.div` export const CommentWrapper = styled.div` margin-top: 4px; - flex: 1; `; export const NickName = styled.p` font-size: ${({ theme }) => theme.heading.xsSmall.fontSize}; margin-left: 11px; margin-bottom: 3px; + opacity: 60%; `; export const Comment = styled.span` display: inline-block; + font-weight: 500; max-width: calc(100% - 12px); word-break: break-word; white-space: pre-wrap; diff --git a/src/components/user/comment/commentComponent/commentComponent/CommentComponent.tsx b/src/components/user/comment/commentComponent/commentComponent/CommentComponent.tsx index 85977be1..f07942d0 100644 --- a/src/components/user/comment/commentComponent/commentComponent/CommentComponent.tsx +++ b/src/components/user/comment/commentComponent/commentComponent/CommentComponent.tsx @@ -38,7 +38,7 @@ const CommentComponent = ({ projectId, }: CommentComponentProps) => { return ( - + ` opacity: ${({ $isFocused }) => ($isFocused ? 1.0 : 0.2)}; border: ${({ $isFocused }) => ($isFocused ? 2 : 1)}; + margin-top: 4px; margin-left: 10px; `; diff --git a/src/components/user/comment/commentInput/CommentInput.tsx b/src/components/user/comment/commentInput/CommentInput.tsx index 6e39312d..94f07d1d 100644 --- a/src/components/user/comment/commentInput/CommentInput.tsx +++ b/src/components/user/comment/commentInput/CommentInput.tsx @@ -1,9 +1,5 @@ import * as S from './CommentInput.styled'; import { Dispatch, SetStateAction, useEffect } from 'react'; -import { useMyProfileInfo } from '../../../../hooks/user/useMyInfo'; -import { formatImgPath } from '../../../../util/formatImgPath'; -import DefaultImg from '../../../../assets/defaultImg.png'; -import Avatar from '../../../common/avatar/Avatar'; import { useForm } from 'react-hook-form'; import useInputFocus from '../../../../hooks/user/useInputFocus'; import usePostReply from '../../../../hooks/user/CommentHooks/usePostReply'; @@ -36,7 +32,6 @@ const CommentInput = ({ recommentId, setActivateEditMode, }: CommentInputProps) => { - const { myData } = useMyProfileInfo(); const { handleSubmit: onSubmitHandler, watch, @@ -50,12 +45,6 @@ const CommentInput = ({ const { createReply } = usePostReply(projectId, commentId); const { changeReply } = usePatchReply(recommentId, commentId, projectId); - const profileImg = myData?.profileImg - ? `${import.meta.env.VITE_APP_IMAGE_CDN_URL}/${formatImgPath( - myData.profileImg - )}?w=86&h=86&fit=crop&crop=entropy&auto=format,enhance&q=60` - : DefaultImg; - const hasInput = Boolean(watch('commentInput', '')); const handleSubmit = (data: { commentInput: string }) => { @@ -86,7 +75,6 @@ const CommentInput = ({ return ( - {!activateEditMode && }
theme.heading.xsSmall.fontSize}; - margin-left: 11px; - margin-bottom: 3px; -`; - -export const Comment = styled.span` - display: inline-block; - max-width: calc(100% - 12px); - word-break: break-word; - white-space: pre-wrap; - margin-left: 12px; -`; - -export const ReplyContainer = styled.div` - margin-top: 11px; - margin-left: 11px; -`; - -export const ReplyButton = styled.div` - display: flex; - margin-top: 11px; -`; - -export const Icon = styled.div` - margin-left: 11px; -`; - -export const ReplyContent = styled.p` - margin-left: 10px; - margin-bottom: 10px; -`; - -export const CommentInput = styled.div` - text-indent: 20px; -`; - -export const ReplyInput = styled.div` - width: 100%; - padding-left: 15px; - margin-bottom: 10px; -`; - -export const ErrorMessage = styled.div` - padding-left: 15px; - margin-bottom: 10px; -`; diff --git a/src/components/user/comment/replyComponent/ReplyComponent.tsx b/src/components/user/comment/replyComponent/ReplyComponent.tsx index 985a9419..5cd9b6ae 100644 --- a/src/components/user/comment/replyComponent/ReplyComponent.tsx +++ b/src/components/user/comment/replyComponent/ReplyComponent.tsx @@ -1,5 +1,5 @@ import Avatar from '../../../common/avatar/Avatar'; -import * as S from './ReplyComponent.styled'; +import * as S from '../commentComponent/commentComponent/CommentComponent.styled'; import DefaultImg from '../../../../assets/defaultImg.png'; import useComment from '../../../../hooks/user/CommentHooks/useComment'; import DropDown from '../../../common/dropDown/DropDown'; @@ -35,7 +35,7 @@ const ReplyComponent = ({ } return getReplyList?.map((item, index) => ( - + - - } - > - onEdit(item.id)} - loginUserId={loginUserId} - commentUserId={item.user.id} - reportTitle={item.content} - activateEditMode={activateEditMode} - reply={true} - /> - + {loginUserId && ( + + } + comment={true} + > + onEdit(item.id)} + loginUserId={loginUserId} + commentUserId={item.user.id} + reportTitle={item.content} + activateEditMode={activateEditMode} + reply={true} + /> + + )} )); }; diff --git a/src/components/user/customerService/faq/FAQContent.tsx b/src/components/user/customerService/faq/FAQContent.tsx index 9df54089..4788dfcd 100644 --- a/src/components/user/customerService/faq/FAQContent.tsx +++ b/src/components/user/customerService/faq/FAQContent.tsx @@ -1,5 +1,5 @@ import { ChevronRightIcon, PlusIcon } from '@heroicons/react/24/outline'; -import { FAQ } from '../../../../models/customerService'; +import type { FAQ } from '../../../../models/customerService'; import * as S from './FAQContent.styled'; import { useState } from 'react'; diff --git a/src/components/user/customerService/noticeDetail/bottom/button/OtherNoticeButton.tsx b/src/components/user/customerService/noticeDetail/bottom/button/OtherNoticeButton.tsx index 6ac55ef8..7c98295d 100644 --- a/src/components/user/customerService/noticeDetail/bottom/button/OtherNoticeButton.tsx +++ b/src/components/user/customerService/noticeDetail/bottom/button/OtherNoticeButton.tsx @@ -1,5 +1,5 @@ import { ROUTES } from '../../../../../../constants/user/routes'; -import { OtherNotice } from '../../../../../../models/customerService'; +import type { OtherNotice } from '../../../../../../models/customerService'; import { formatDate } from '../../../../../../util/format'; import * as S from './OtherNoticeButton.styled'; diff --git a/src/components/user/evaluation/EvaluationContent.tsx b/src/components/user/evaluation/EvaluationContent.tsx index 568628f5..f66f1c14 100644 --- a/src/components/user/evaluation/EvaluationContent.tsx +++ b/src/components/user/evaluation/EvaluationContent.tsx @@ -1,7 +1,7 @@ import * as S from './EvaluationContent.styled'; import ScrollPreventor from '../../common/modal/ScrollPreventor'; import useEvaluationStep from '../../../hooks/user/evaluationHooks/useEvaluationStep'; -import { MemberList } from '../../../models/evaluation'; +import type { MemberList } from '../../../models/evaluation'; import { optionLabels, questions } from '../../../constants/user/evaluation'; interface EvaluationContentProps { projectId: number; diff --git a/src/components/user/manageProjects/ProjectHeader.tsx b/src/components/user/manageProjects/ProjectHeader.tsx index b4817e1f..9e9022c3 100644 --- a/src/components/user/manageProjects/ProjectHeader.tsx +++ b/src/components/user/manageProjects/ProjectHeader.tsx @@ -1,6 +1,6 @@ import * as S from './ProjectHeader.styled'; import Title from '../../common/title/Title'; -import { ProjectDetailPlusExtended } from '../../../models/projectDetail'; +import type { ProjectDetailPlusExtended } from '../../../models/projectDetail'; import RecruitmentDate from './RecruitmentDate'; import React from 'react'; interface ProjectHeaderProps { diff --git a/src/components/user/manageProjects/RecruitmentDate.tsx b/src/components/user/manageProjects/RecruitmentDate.tsx index c8b5fecf..66b85713 100644 --- a/src/components/user/manageProjects/RecruitmentDate.tsx +++ b/src/components/user/manageProjects/RecruitmentDate.tsx @@ -1,4 +1,4 @@ -import { ProjectDetailPlus } from '../../../models/projectDetail'; +import type { ProjectDetailPlus } from '../../../models/projectDetail'; import { formatDate } from '../../../util/formatDate'; import * as S from './RecruitmentDate.styled'; interface RecruitmentDateProps { diff --git a/src/components/user/manageProjects/applicantInfo/ApplicantInfo.tsx b/src/components/user/manageProjects/applicantInfo/ApplicantInfo.tsx index de693d47..c3ef8125 100644 --- a/src/components/user/manageProjects/applicantInfo/ApplicantInfo.tsx +++ b/src/components/user/manageProjects/applicantInfo/ApplicantInfo.tsx @@ -1,5 +1,5 @@ import * as S from './ApplicantInfo.styled'; -import { ApplicantInfo as MApplicantInfo } from '../../../../models/applicant'; +import type { ApplicantInfo as MApplicantInfo } from '../../../../models/applicant'; import AvatarList from '../../../common/avatar/AvatarList'; import { LabelWithContent } from './LabelWithContent'; import { formatDate } from '../../../../util/format'; diff --git a/src/components/user/manageProjects/applicantList/ApplicantItem.tsx b/src/components/user/manageProjects/applicantList/ApplicantItem.tsx index 4502599e..978ef5b6 100644 --- a/src/components/user/manageProjects/applicantList/ApplicantItem.tsx +++ b/src/components/user/manageProjects/applicantList/ApplicantItem.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef } from 'react'; -import { ApplicantInfo } from '../../../../models/applicant'; +import type { ApplicantInfo } from '../../../../models/applicant'; import * as S from './ApplicantItem.styled'; interface ApplicantItemProps { diff --git a/src/components/user/manageProjects/applicantList/ApplicantList.tsx b/src/components/user/manageProjects/applicantList/ApplicantList.tsx index d8edc662..7d609d18 100644 --- a/src/components/user/manageProjects/applicantList/ApplicantList.tsx +++ b/src/components/user/manageProjects/applicantList/ApplicantList.tsx @@ -1,5 +1,5 @@ import * as S from './ApplicantList.styled'; -import { ApplicantInfo } from '../../../../models/applicant'; +import type { ApplicantInfo } from '../../../../models/applicant'; import ApplicantItem from './ApplicantItem'; interface ApplicantListProps { selectedApplicant?: number; diff --git a/src/components/user/manageProjects/passNonPassList/PassNonPassItem.tsx b/src/components/user/manageProjects/passNonPassList/PassNonPassItem.tsx index 7ffed7c8..7584414b 100644 --- a/src/components/user/manageProjects/passNonPassList/PassNonPassItem.tsx +++ b/src/components/user/manageProjects/passNonPassList/PassNonPassItem.tsx @@ -1,6 +1,6 @@ import { useMutationParams } from '../../../../hooks/user/usePassNonPassMutation'; -import { ApplicantInfo } from '../../../../models/applicant'; -import { ProjectDetailPlusExtended } from '../../../../models/projectDetail'; +import type { ApplicantInfo } from '../../../../models/applicant'; +import type { ProjectDetailPlusExtended } from '../../../../models/projectDetail'; import DeleteButton from './DeleteButton'; import * as S from './PassNonPassItem.styled'; diff --git a/src/components/user/manageProjects/passNonPassList/PassNonPassList.tsx b/src/components/user/manageProjects/passNonPassList/PassNonPassList.tsx index d5d8b87a..6d2cd516 100644 --- a/src/components/user/manageProjects/passNonPassList/PassNonPassList.tsx +++ b/src/components/user/manageProjects/passNonPassList/PassNonPassList.tsx @@ -1,7 +1,7 @@ import { useNavigate } from 'react-router-dom'; import { useMutationParams } from '../../../../hooks/user/usePassNonPassMutation'; -import { ApplicantInfo } from '../../../../models/applicant'; -import { ProjectDetailPlusExtended } from '../../../../models/projectDetail'; +import type { ApplicantInfo } from '../../../../models/applicant'; +import type { ProjectDetailPlusExtended } from '../../../../models/projectDetail'; import PassNonPassItem from './PassNonPassItem'; import * as S from './PassNonPassList.styled'; diff --git a/src/components/user/mypage/activityLog/commentsActivity/commentActivity/CommentActivity.tsx b/src/components/user/mypage/activityLog/commentsActivity/commentActivity/CommentActivity.tsx index 93125d7c..0b70aaf0 100644 --- a/src/components/user/mypage/activityLog/commentsActivity/commentActivity/CommentActivity.tsx +++ b/src/components/user/mypage/activityLog/commentsActivity/commentActivity/CommentActivity.tsx @@ -1,7 +1,7 @@ import { Link } from 'react-router-dom'; import * as S from './CommentActivity.styled'; import { formatDate } from '../../../../../../util/formatDate'; -import { MyComments } from '../../../../../../models/activityLog'; +import type { MyComments } from '../../../../../../models/activityLog'; interface CommentActivityProps { list: MyComments; diff --git a/src/components/user/mypage/myProfile/editProfile/EditProfile.tsx b/src/components/user/mypage/myProfile/editProfile/EditProfile.tsx index 0926bc72..6c1fecb9 100644 --- a/src/components/user/mypage/myProfile/editProfile/EditProfile.tsx +++ b/src/components/user/mypage/myProfile/editProfile/EditProfile.tsx @@ -9,7 +9,7 @@ import { z } from 'zod'; import { SquaresPlusIcon, XMarkIcon } from '@heroicons/react/24/outline'; import { useNavigate, useOutletContext } from 'react-router-dom'; import MyProfileWrapper from '../MyProfileWrapper'; -import { UserInfo } from '../../../../../models/userInfo'; +import type { UserInfo } from '../../../../../models/userInfo'; import { useSearchFilteringSkillTag } from '../../../../../hooks/user/useSearchFilteringSkillTag'; import { useEditMyProfileInfo } from '../../../../../hooks/user/useMyInfo'; import useNickNameVerification from '../../../../../hooks/user/useNicknameVerification'; diff --git a/src/components/user/mypage/myProfile/profile/Profile.tsx b/src/components/user/mypage/myProfile/profile/Profile.tsx index 85ab6adb..38ea7627 100644 --- a/src/components/user/mypage/myProfile/profile/Profile.tsx +++ b/src/components/user/mypage/myProfile/profile/Profile.tsx @@ -1,14 +1,14 @@ import * as S from './Profile.styled'; import BeginnerIcon from '../../../../../assets/beginner.svg'; -import 'chart.js/auto'; -import { ChartOptions } from 'chart.js'; import { Link, useLocation, useOutletContext } from 'react-router-dom'; import { Radar } from 'react-chartjs-2'; import { useEffect } from 'react'; import MyProfileWrapper from '../MyProfileWrapper'; -import { UserInfo } from '../../../../../models/userInfo'; +import type { UserInfo } from '../../../../../models/userInfo'; import { PROFILE_DEFAULT_MESSAGE } from '../../../../../constants/user/myPageProfile'; import { ROUTES } from '../../../../../constants/user/routes'; +import 'chart.js/auto'; +import { chartOptions } from '../../../../../constants/evaluationChartData'; export default function Profile() { const { @@ -19,6 +19,19 @@ export default function Profile() { const location = useLocation(); const myPage = location.pathname.includes('mypage') ? true : false; + const chartData = { + labels: ['책임감', '기획력', '협업능력', '성실도', '문제해결', '기술력'], + datasets: [ + { + label: '팀 점수', + data: userInfoData.averageScores, + backgroundColor: 'rgba(255, 108, 61, 0.2)', + }, + ], + }; + + console.log(userInfoData.averageScores); + useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollTop = 0; @@ -151,64 +164,3 @@ export default function Profile() { ); } - -const chartData = { - labels: ['책임감', '기획력', '협업능력', '성실도', '문제해결', '기술력'], - datasets: [ - { - label: '팀 점수', - data: [6.6, 5.2, 9.1, 5.6, 5.5, 8.4], - backgroundColor: 'rgba(255, 108, 61, 0.2)', - }, - ], -}; - -const chartOptions: ChartOptions<'radar'> & ChartOptions = { - elements: { - //데이터 속성. - line: { - borderWidth: 2, - borderColor: '#ff0000', - }, - //데이터 꼭짓점. - // point: { - // pointBackgroundColor: '#ff0000', - // }, - }, - scales: { - r: { - ticks: { - stepSize: 2.5, - display: false, - }, - grid: { - color: '#ececec', - }, - //라벨 속성 지정. - pointLabels: { - font: { - size: 12, - weight: 200, - family: 'Pretendard', - }, - color: '#000000', - }, - angleLines: { - display: false, - }, - suggestedMin: 0, - suggestedMax: 10, - }, - }, - responsive: true, - //위에 생기는 데이터 속성 label 타이틀을 지워줍니다. - plugins: { - legend: { - display: false, - }, - }, - //기본 값은 가운데에서 펴져나가는 애니메이션 형태입니다. - animation: { - duration: 0, - }, -}; diff --git a/src/components/user/mypage/notifications/appliedProjects/appliedProjectsStatus/AppliedProjectsStatus.tsx b/src/components/user/mypage/notifications/appliedProjects/appliedProjectsStatus/AppliedProjectsStatus.tsx index 81906291..337c7481 100644 --- a/src/components/user/mypage/notifications/appliedProjects/appliedProjectsStatus/AppliedProjectsStatus.tsx +++ b/src/components/user/mypage/notifications/appliedProjects/appliedProjectsStatus/AppliedProjectsStatus.tsx @@ -1,5 +1,5 @@ import { MY_STATUS } from '../../../../../../constants/user/authConstants'; -import { AppliedProject } from '../../../../../../models/userProject'; +import type { AppliedProject } from '../../../../../../models/userProject'; import * as S from './AppliedProjectsStatus.styled'; interface StatusProps { diff --git a/src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.tsx b/src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.tsx index fad75cc8..6edd443e 100644 --- a/src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.tsx +++ b/src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.tsx @@ -4,8 +4,8 @@ import FieldCategoryComponent from './fieldCategoryComponent/FieldCategoryCompon import { Control, FieldErrors, UseFormSetValue } from 'react-hook-form'; import * as S from './ProjectInformationInput.styled'; import Input from '../inputComponent/InputComponent'; -import { ProjectDetailPlusExtended } from '../../../../models/projectDetail'; -import { CreateProjectFormValues } from '../../../../models/createProject'; +import type { ProjectDetailPlusExtended } from '../../../../models/projectDetail'; +import type { CreateProjectFormValues } from '../../../../models/createProject'; import { useSearchFilteringSkillTag } from '../../../../hooks/user/useSearchFilteringSkillTag'; import { PROJECT_DATA } from '../../../../constants/user/projectConstants'; diff --git a/src/components/user/projectFormComponents/projectInformationInput/fieldCategoryComponent/FieldCategoryComponent.tsx b/src/components/user/projectFormComponents/projectInformationInput/fieldCategoryComponent/FieldCategoryComponent.tsx index 42a1e524..d479a480 100644 --- a/src/components/user/projectFormComponents/projectInformationInput/fieldCategoryComponent/FieldCategoryComponent.tsx +++ b/src/components/user/projectFormComponents/projectInformationInput/fieldCategoryComponent/FieldCategoryComponent.tsx @@ -1,6 +1,6 @@ import useTagSelectors from '../../../../../hooks/user/ProjectHooks/useTagSelectors'; -import { CreateProjectFormValues } from '../../../../../models/createProject'; -import { MethodTag } from '../../../../../models/tags'; +import type { CreateProjectFormValues } from '../../../../../models/createProject'; +import type { MethodTag } from '../../../../../models/tags'; import * as S from './FieldCategoryComponent.styled'; import { FieldErrors, UseFormSetValue } from 'react-hook-form'; diff --git a/src/components/user/projectFormComponents/projectInformationInput/languageComponent/LanguageComponent.tsx b/src/components/user/projectFormComponents/projectInformationInput/languageComponent/LanguageComponent.tsx index e3b72f6f..51f8f05a 100644 --- a/src/components/user/projectFormComponents/projectInformationInput/languageComponent/LanguageComponent.tsx +++ b/src/components/user/projectFormComponents/projectInformationInput/languageComponent/LanguageComponent.tsx @@ -1,6 +1,6 @@ import useTagSelectors from '../../../../../hooks/user/ProjectHooks/useTagSelectors'; -import { CreateProjectFormValues } from '../../../../../models/createProject'; -import { SkillTag } from '../../../../../models/tags'; +import type { CreateProjectFormValues } from '../../../../../models/createProject'; +import type { SkillTag } from '../../../../../models/tags'; import SkillTagBox from '../../../../common/skillTagBox/SkillTagBox'; import * as S from './LanguageComponent.styled'; import { FieldErrors, UseFormSetValue } from 'react-hook-form'; diff --git a/src/components/user/projectFormComponents/projectInformationInput/positionComponent/PositionComponent.tsx b/src/components/user/projectFormComponents/projectInformationInput/positionComponent/PositionComponent.tsx index 06605ff8..ad267d8e 100644 --- a/src/components/user/projectFormComponents/projectInformationInput/positionComponent/PositionComponent.tsx +++ b/src/components/user/projectFormComponents/projectInformationInput/positionComponent/PositionComponent.tsx @@ -1,6 +1,6 @@ import useTagSelectors from '../../../../../hooks/user/ProjectHooks/useTagSelectors'; -import { CreateProjectFormValues } from '../../../../../models/createProject'; -import { PositionTag } from '../../../../../models/tags'; +import type { CreateProjectFormValues } from '../../../../../models/createProject'; +import type { PositionTag } from '../../../../../models/tags'; import * as S from './PositionComponent.styled'; import { FieldErrors, UseFormSetValue } from 'react-hook-form'; diff --git a/src/components/user/projectFormComponents/projectInformationText/ProjectInformation.tsx b/src/components/user/projectFormComponents/projectInformationText/ProjectInformation.tsx index 2acf1073..ed136378 100644 --- a/src/components/user/projectFormComponents/projectInformationText/ProjectInformation.tsx +++ b/src/components/user/projectFormComponents/projectInformationText/ProjectInformation.tsx @@ -1,19 +1,13 @@ -import { PROJECT_DATA_GET } from '../../../../constants/user/projectConstants'; -import { - ProjectDetailPlus, - ProjectDetailPlusExtended, -} from '../../../../models/projectDetail'; -import { formatDate } from '../../../../util/formatDate'; +import type { ProjectDetailPlusExtended } from '../../../../models/projectDetail'; import * as S from './ProjectInformation.styled'; import beginner from '../../../../assets/beginner.svg'; +import { formatDate } from '../../../../util/formatDate'; interface ProjectInformationProps { data: ProjectDetailPlusExtended; } const ProjectInformation = ({ data }: ProjectInformationProps) => { - data.startDate = formatDate(data.startDate); - return ( @@ -23,12 +17,20 @@ const ProjectInformation = ({ data }: ProjectInformationProps) => { )} - {PROJECT_DATA_GET.map((input, index) => ( - - {input.label} - {data[input.name as keyof ProjectDetailPlus]} - - ))} + + 모집 인원 + {data.totalMember} + + + + 시작 예정 + {formatDate(data.startDate)} + + + + 예상 기간 + {data.estimatedPeriod} + 모집 분야 diff --git a/src/constants/evaluationChartData.ts b/src/constants/evaluationChartData.ts new file mode 100644 index 00000000..f0182b52 --- /dev/null +++ b/src/constants/evaluationChartData.ts @@ -0,0 +1,51 @@ +import { ChartOptions } from 'chart.js'; + +export const chartOptions: ChartOptions<'radar'> & ChartOptions = { + elements: { + //데이터 속성. + line: { + borderWidth: 1, + borderColor: '#ff0000', + }, + //데이터 꼭짓점. + // point: { + // pointBackgroundColor: '#ff0000', + // }, + }, + scales: { + r: { + ticks: { + stepSize: 1, + display: false, + }, + grid: { + color: '#ececec', + }, + //라벨 속성 지정. + pointLabels: { + font: { + size: 12, + weight: 200, + family: 'Pretendard', + }, + color: '#000000', + }, + angleLines: { + display: false, + }, + suggestedMin: 0, + suggestedMax: 5, + }, + }, + responsive: true, + //위에 생기는 데이터 속성 label 타이틀을 지워줍니다. + plugins: { + legend: { + display: false, + }, + }, + //기본 값은 가운데에서 펴져나가는 애니메이션 형태입니다. + animation: { + duration: 0, + }, +}; diff --git a/src/constants/user/projectConstants.ts b/src/constants/user/projectConstants.ts index c210af0b..d0f89be4 100644 --- a/src/constants/user/projectConstants.ts +++ b/src/constants/user/projectConstants.ts @@ -35,24 +35,6 @@ export const PROJECT_DATA = [ }, ] as const; -export const PROJECT_DATA_GET = [ - { - id: '1', - name: 'totalMember', - label: '모집 인원', - }, - { - id: '2', - name: 'startDate', - label: '시작 예정', - }, - { - id: '3', - name: 'estimatedPeriod', - label: '예상 기간', - }, -] as const; - export const CAREER_INPUT = [ { name: 'name', diff --git a/src/context/ToastContext.tsx b/src/context/ToastContext.tsx index 7c5779de..82fa763c 100644 --- a/src/context/ToastContext.tsx +++ b/src/context/ToastContext.tsx @@ -1,5 +1,5 @@ import { createContext } from 'react'; -import { AlarmLive } from '../models/alarm'; +import type { AlarmLive } from '../models/alarm'; export interface ToastMessage { id: string; diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts index d0e3ecb3..aa2b5684 100644 --- a/src/hooks/useAuth.ts +++ b/src/hooks/useAuth.ts @@ -3,7 +3,7 @@ import { postLogin, postResetPassword, postSignUp } from '../api/auth.api'; import { loginFormValues } from '../pages/login/Login'; import useAuthStore from '../store/authStore'; import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { LoginResponse } from '../models/auth'; +import type { LoginResponse } from '../models/auth'; import { AxiosError } from 'axios'; import { myInfoKey } from './queries/user/keys'; import { MODAL_MESSAGE } from '../constants/user/modalMessage'; diff --git a/src/hooks/useModal.ts b/src/hooks/useModal.ts index d9c0dcfa..d87d29fc 100644 --- a/src/hooks/useModal.ts +++ b/src/hooks/useModal.ts @@ -25,22 +25,12 @@ export const useModal = () => { handleModalClose(); }, [onConfirm, handleModalClose]); - const handleOpenReportModal = () => { - setIsOpen(true); - }; - - const handleCloseReportModal = () => { - setIsOpen(false); - }; - return { isOpen, message, setIsOpen, handleModalClose, handleModalOpen, - handleOpenReportModal, - handleCloseReportModal, handleConfirm, }; }; diff --git a/src/hooks/user/ProjectHooks/useCreateProject.ts b/src/hooks/user/ProjectHooks/useCreateProject.ts index 68ebd2bd..84f5ac36 100644 --- a/src/hooks/user/ProjectHooks/useCreateProject.ts +++ b/src/hooks/user/ProjectHooks/useCreateProject.ts @@ -4,7 +4,7 @@ import { postProject } from '../../../api/joinProject.api'; import { MODAL_MESSAGE } from '../../../constants/user/modalMessage'; import { managedProjectKey } from '../../queries/user/keys'; import { ROUTES } from '../../../constants/user/routes'; -import { FormData } from '../../../models/createProject'; +import type { FormData } from '../../../models/createProject'; interface UseCreateProjectProps { handleModalOpen: (newMessage: string) => void; diff --git a/src/hooks/user/ProjectHooks/useTagSelectors.ts b/src/hooks/user/ProjectHooks/useTagSelectors.ts index fba121be..8007ef18 100644 --- a/src/hooks/user/ProjectHooks/useTagSelectors.ts +++ b/src/hooks/user/ProjectHooks/useTagSelectors.ts @@ -76,8 +76,6 @@ const useTagSelectors = ({ setValue(fieldName, idx); } - - console.log(selectedTag); }; return { selectedTag, handleClick }; diff --git a/src/hooks/user/ProjectHooks/useUpdateProject.ts b/src/hooks/user/ProjectHooks/useUpdateProject.ts index 33726f38..8a1cbcd2 100644 --- a/src/hooks/user/ProjectHooks/useUpdateProject.ts +++ b/src/hooks/user/ProjectHooks/useUpdateProject.ts @@ -2,7 +2,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 { FormData } from '../../../models/createProject'; +import type { FormData } from '../../../models/createProject'; import { MODAL_MESSAGE } from '../../../constants/user/modalMessage'; import { ROUTES } from '../../../constants/user/routes'; diff --git a/src/hooks/user/evaluationHooks/useEvaluationStep.ts b/src/hooks/user/evaluationHooks/useEvaluationStep.ts index 45935f13..3292496b 100644 --- a/src/hooks/user/evaluationHooks/useEvaluationStep.ts +++ b/src/hooks/user/evaluationHooks/useEvaluationStep.ts @@ -1,5 +1,5 @@ import { useEffect, useMemo, useState } from 'react'; -import { MemberList } from '../../../models/evaluation'; +import type { MemberList } from '../../../models/evaluation'; import { questions } from '../../../constants/user/evaluation'; import { usePostEvaluation } from './usePostEvaluation'; diff --git a/src/hooks/user/evaluationHooks/usePostEvaluation.ts b/src/hooks/user/evaluationHooks/usePostEvaluation.ts index d436546c..303071c0 100644 --- a/src/hooks/user/evaluationHooks/usePostEvaluation.ts +++ b/src/hooks/user/evaluationHooks/usePostEvaluation.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { postEvaluation } from '../../../api/evaluation.api'; import { ProjectMemberListEval } from '../../queries/user/keys'; -import { apiEvaluatedUser } from '../../../models/evaluation'; +import type { apiEvaluatedUser } from '../../../models/evaluation'; export const usePostEvaluation = (projectId: number) => { const queryClient = useQueryClient(); diff --git a/src/hooks/user/useApllicantList.ts b/src/hooks/user/useApllicantList.ts index e4b02e20..34956e90 100644 --- a/src/hooks/user/useApllicantList.ts +++ b/src/hooks/user/useApllicantList.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { applicantKey } from '../queries/user/keys'; import { getApplicantList } from '../../api/applicant.api'; -import { ApiApplicants } from '../../models/applicant'; +import type { ApiApplicants } from '../../models/applicant'; export const useApllicantList = (projectId: number) => { const { data, isLoading } = useQuery({ diff --git a/src/hooks/user/useApplicantInfo.ts b/src/hooks/user/useApplicantInfo.ts index 57219af5..9ed2e48e 100644 --- a/src/hooks/user/useApplicantInfo.ts +++ b/src/hooks/user/useApplicantInfo.ts @@ -3,7 +3,7 @@ import { useEffect, useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { applicantKey } from '../queries/user/keys'; import { useLocation } from 'react-router-dom'; -import { ApiApplicantInfo } from '../../models/applicant'; +import type { ApiApplicantInfo } from '../../models/applicant'; export const useApplicantInfo = (projectId: number) => { const [selectedApplicant, setSelectedUser] = useState(null); diff --git a/src/hooks/user/useGetFAQ.ts b/src/hooks/user/useGetFAQ.ts index 3d9e55c7..4ec4e0dd 100644 --- a/src/hooks/user/useGetFAQ.ts +++ b/src/hooks/user/useGetFAQ.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { getFAQ } from '../../api/customerService.api'; import { CustomerService } from '../queries/user/keys'; -import { SearchKeyword } from '../../models/customerService'; +import type { SearchKeyword } from '../../models/customerService'; export const useGetFAQ = (keyword: SearchKeyword) => { const { data: faqData, isLoading } = useQuery({ diff --git a/src/hooks/user/useManagedProjects.ts b/src/hooks/user/useManagedProjects.ts index 7705b37d..a1ca74d1 100644 --- a/src/hooks/user/useManagedProjects.ts +++ b/src/hooks/user/useManagedProjects.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; import { managedProjectKey } from '../queries/user/keys'; -import { ApiManagedProjects } from '../../models/manageMyProject'; +import type { ApiManagedProjects } from '../../models/manageMyProject'; import { getMyProjectLists } from '../../api/myProjectList.api'; export const useManagedProjects = () => { diff --git a/src/hooks/user/useMyInfo.ts b/src/hooks/user/useMyInfo.ts index 43df84e4..20e1504f 100644 --- a/src/hooks/user/useMyInfo.ts +++ b/src/hooks/user/useMyInfo.ts @@ -3,7 +3,7 @@ import { AxiosError } from 'axios'; import { useNavigate } from 'react-router-dom'; import { myInfoKey, ProjectListKey } from '../queries/user/keys'; import useAuthStore from '../../store/authStore'; -import { ApiUserInfo, EditMyInfo } from '../../models/userInfo'; +import type { ApiUserInfo, EditMyInfo } from '../../models/userInfo'; import { getMyAppliedStatusList, getMyInfo, @@ -13,7 +13,10 @@ import { } from '../../api/mypage.api'; import { MODAL_MESSAGE } from '../../constants/user/modalMessage'; import { ROUTES } from '../../constants/user/routes'; -import { ApiAppliedProject, ApiJoinedProject } from '../../models/userProject'; +import type { + ApiAppliedProject, + ApiJoinedProject, +} from '../../models/userProject'; export const useMyProfileInfo = () => { const isLoggedIn = useAuthStore((state) => state.isLoggedIn); diff --git a/src/hooks/user/useNotification.ts b/src/hooks/user/useNotification.ts index 42b542b0..7be16cdf 100644 --- a/src/hooks/user/useNotification.ts +++ b/src/hooks/user/useNotification.ts @@ -2,7 +2,7 @@ import { EventSourcePolyfill, NativeEventSource } from 'event-source-polyfill'; import { useEffect, useRef, useState } from 'react'; import { useQueryClient } from '@tanstack/react-query'; import { AlarmList } from '../queries/user/keys'; -import { AlarmLive } from '../../models/alarm'; +import type { AlarmLive } from '../../models/alarm'; import useAuthStore, { getTokens } from '../../store/authStore'; import { useToast } from '../useToast'; @@ -16,15 +16,19 @@ const useNotification = () => { const EventSourceImpl = EventSourcePolyfill || NativeEventSource; useEffect(() => { - if (eventSourceRef.current) { - eventSourceRef.current.close(); - eventSourceRef.current = null; + if (!userId) { + if (eventSourceRef.current) { + eventSourceRef.current.close(); + eventSourceRef.current = null; + } + return; } - if (!userId) { + if (eventSourceRef.current) { return; } + // 헤더가 아닌 파라미터 형태로 바꾸면서 Polyfill 제외 하기 -> CORS Preflight를 유발하여 요청 지연의 원인이 될 수 있음. const eventSource = new EventSourceImpl( `${import.meta.env.VITE_APP_API_BASE_URL}user/sse`, { @@ -61,13 +65,6 @@ const useNotification = () => { eventSource.onerror = (e) => { console.log(e); }; - - return () => { - if (eventSourceRef.current) { - eventSourceRef.current.close(); - eventSourceRef.current = null; - } - }; }, [queryClient, userId]); useEffect(() => { diff --git a/src/hooks/user/useReportModal.ts b/src/hooks/user/useReportModal.ts new file mode 100644 index 00000000..7f85f21b --- /dev/null +++ b/src/hooks/user/useReportModal.ts @@ -0,0 +1,21 @@ +import { useState } from 'react'; + +export const useReportModal = () => { + const [isOpen, setIsOpen] = useState(false); + + const handleOpenReportModal = () => { + setIsOpen(true); + }; + + const handleCloseReportModal = () => { + setIsOpen(false); + }; + + return { + handleOpenReportModal, + handleCloseReportModal, + isOpen, + }; +}; + +export default useReportModal; diff --git a/src/hooks/user/useSearchFilteringSkillTag.ts b/src/hooks/user/useSearchFilteringSkillTag.ts index e5373fdc..c5a87130 100644 --- a/src/hooks/user/useSearchFilteringSkillTag.ts +++ b/src/hooks/user/useSearchFilteringSkillTag.ts @@ -1,6 +1,6 @@ import { useQueries } from '@tanstack/react-query'; import { useEffect, useState } from 'react'; -import { MethodTag, PositionTag, SkillTag } from '../../models/tags'; +import type { MethodTag, PositionTag, SkillTag } from '../../models/tags'; import { getMethodTag, getPositionTag, diff --git a/src/hooks/user/useUserInfo.ts b/src/hooks/user/useUserInfo.ts index 61c5bcf8..be09dc80 100644 --- a/src/hooks/user/useUserInfo.ts +++ b/src/hooks/user/useUserInfo.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { userInfoKey } from '../queries/user/keys'; import useAuthStore from '../../store/authStore'; -import { ApiUserInfo } from '../../models/userInfo'; +import type { ApiUserInfo } from '../../models/userInfo'; import { getUserInfo } from '../../api/userpage.api'; export const useUserProfileInfo = (id: number) => { diff --git a/src/models/userInfo.ts b/src/models/userInfo.ts index 242c09fb..8567722a 100644 --- a/src/models/userInfo.ts +++ b/src/models/userInfo.ts @@ -20,6 +20,7 @@ export interface UserInfo { positions: Omit[]; skills: Omit[]; createdAt?: string; + averageScores: number[]; } export interface ApiUserInfo extends ApiCommonType { diff --git a/src/pages/user/apply/Apply.tsx b/src/pages/user/apply/Apply.tsx index 35c1c48f..c6d4371e 100644 --- a/src/pages/user/apply/Apply.tsx +++ b/src/pages/user/apply/Apply.tsx @@ -3,7 +3,7 @@ import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { useParams } from 'react-router-dom'; import { formatDate } from '../../../util/format'; -import { ApplySchemeType, joinProject } from '../../../models/joinProject'; +import type { ApplySchemeType, joinProject } from '../../../models/joinProject'; import { useModal } from '../../../hooks/useModal'; import useGetProjectData from '../../../hooks/user/useGetProjectData'; import useApplyProject from '../../../hooks/user/ProjectHooks/useApplyProject'; diff --git a/src/pages/user/apply/ApplyStep.tsx b/src/pages/user/apply/ApplyStep.tsx index 29f9f963..b049956c 100644 --- a/src/pages/user/apply/ApplyStep.tsx +++ b/src/pages/user/apply/ApplyStep.tsx @@ -7,7 +7,7 @@ import { useModal } from '../../../hooks/useModal'; import useGetProjectData from '../../../hooks/user/useGetProjectData'; import useApplyProject from '../../../hooks/user/ProjectHooks/useApplyProject'; import useAuthStore from '../../../store/authStore'; -import { ApplySchemeType, joinProject } from '../../../models/joinProject'; +import type { ApplySchemeType, joinProject } from '../../../models/joinProject'; import { ApplyScheme } from '../../../constants/user/projectConstants'; import Input from '../../../components/user/projectFormComponents/inputComponent/InputComponent'; import PhoneComponent from '../../../components/user/applyComponents/phoneComponent/PhoneComponent'; diff --git a/src/pages/user/createProject/CreateProject.tsx b/src/pages/user/createProject/CreateProject.tsx index 1f26b178..0abaed9c 100644 --- a/src/pages/user/createProject/CreateProject.tsx +++ b/src/pages/user/createProject/CreateProject.tsx @@ -2,7 +2,7 @@ import * as S from './CreateProject.styled'; import { z } from 'zod'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; -import { +import type { CreateProjectFormValues, FormData, } from '../../../models/createProject'; diff --git a/src/pages/user/customerService/faq/FAQ.tsx b/src/pages/user/customerService/faq/FAQ.tsx index d7d343dc..f064924d 100644 --- a/src/pages/user/customerService/faq/FAQ.tsx +++ b/src/pages/user/customerService/faq/FAQ.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import * as S from './FAQ.styled'; import { ChevronDownIcon } from '@heroicons/react/24/outline'; -import { SearchKeyword } from '../../../../models/customerService'; +import type { SearchKeyword } from '../../../../models/customerService'; import { useGetFAQ } from '../../../../hooks/user/useGetFAQ'; import { Spinner } from '../../../../components/common/loadingSpinner/LoadingSpinner.styled'; import CustomerServiceHeader from '../../../../components/user/customerService/CustomerServiceHeader'; diff --git a/src/pages/user/customerService/notice/Notice.tsx b/src/pages/user/customerService/notice/Notice.tsx index 44bed823..c53b4b3f 100644 --- a/src/pages/user/customerService/notice/Notice.tsx +++ b/src/pages/user/customerService/notice/Notice.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import * as S from './Notice.styled'; -import { NoticeSearch } from '../../../../models/customerService'; +import type { NoticeSearch } from '../../../../models/customerService'; import { useGetNotice } from '../../../../hooks/user/useGetNotice'; import { Spinner } from '../../../../components/common/loadingSpinner/LoadingSpinner.styled'; import CustomerServiceHeader from '../../../../components/user/customerService/CustomerServiceHeader'; diff --git a/src/pages/user/modifyProject/ModifyProject.tsx b/src/pages/user/modifyProject/ModifyProject.tsx index fbc2c6d5..609f240f 100644 --- a/src/pages/user/modifyProject/ModifyProject.tsx +++ b/src/pages/user/modifyProject/ModifyProject.tsx @@ -7,7 +7,7 @@ import { useEffect } from 'react'; import { useModal } from '../../../hooks/useModal'; import useGetProjectData from '../../../hooks/user/useGetProjectData'; import useUpdateProject from '../../../hooks/user/ProjectHooks/useUpdateProject'; -import { +import type { CreateProjectFormValues, FormData, } from '../../../models/createProject'; diff --git a/src/pages/user/projectDetail/ProjectDetail.tsx b/src/pages/user/projectDetail/ProjectDetail.tsx index 14079c45..c149ddc0 100644 --- a/src/pages/user/projectDetail/ProjectDetail.tsx +++ b/src/pages/user/projectDetail/ProjectDetail.tsx @@ -30,8 +30,7 @@ const ProjectDetail = () => { } }, [data, handleModalOpen]); - if (isLoading) return ; - if (isFetching) return ; + if (isLoading || isFetching) return ; if (!data) { return ( @@ -41,14 +40,6 @@ const ProjectDetail = () => { ); } - if (!userData) { - return ( - - {message} - - ); - } - const handleApplyClick = () => { navigate(`${ROUTES.apply}/${id}`); }; @@ -58,9 +49,6 @@ const ProjectDetail = () => { navigate(`/user/${userId}`); }; - console.log(data); - console.log(userData.id); - return ( @@ -91,7 +79,8 @@ const ProjectDetail = () => { - {userData.id !== data.user.id && + {userData && + userData.id !== data.user.id && !data.acceptedIds.includes(userData.id) && !data.applicantIds.includes(userData.id) ? (