diff --git a/package-lock.json b/package-lock.json
index 136530ae..6c5d085b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,9 +11,8 @@
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@tanstack/react-query": "^5.17.19",
- "@tanstack/react-query-devtools": "^5.17.19",
"axios": "^1.5.1",
- "concept-be-design-system": "^0.4.1",
+ "concept-be-design-system": "^0.4.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.15.0",
@@ -22,6 +21,7 @@
},
"devDependencies": {
"@emotion/babel-plugin": "^11.11.0",
+ "@tanstack/react-query-devtools": "^5.17.19",
"@types/node": "^20.10.6",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
@@ -1381,6 +1381,7 @@
"version": "5.17.21",
"resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.17.21.tgz",
"integrity": "sha512-WWfcnNjTEqcuAS5GyKkVGkseuES6yd197MJWGImBu+MoCjWPqxSXKCCfm+utSXJauJUGm7xoMmhqCphiQdjf8w==",
+ "dev": true,
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
@@ -1405,6 +1406,7 @@
"version": "5.17.21",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.17.21.tgz",
"integrity": "sha512-Ri1AuWpN67eyPdMTlPxx1TMGNUaxTHrGv0ll0S20ZObz/Xms5wfANV3c6OX0HZTY0igudP1k5jpRLXNkd249mg==",
+ "dev": true,
"dependencies": {
"@tanstack/query-devtools": "5.17.21"
},
@@ -2468,9 +2470,9 @@
"license": "MIT"
},
"node_modules/concept-be-design-system": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/concept-be-design-system/-/concept-be-design-system-0.4.1.tgz",
- "integrity": "sha512-194MNlf3ZNWVvLsqclpwYOiFV7q2kIBiwpE1rXxqA75VmnCXBZTPafDsnAR9SNFGx5cdZXkcpJOz1/ZZuIXVEQ==",
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/concept-be-design-system/-/concept-be-design-system-0.4.3.tgz",
+ "integrity": "sha512-33G/XWi2dQUCJwRqXfjilCOV1HDqXZCMMbgEuJ1W7+yS26ttiUd9+x0CnLunEeEf09TNmLnTUL9tKT5m7GJRwg==",
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
diff --git a/package.json b/package.json
index fb9783a5..48f3abcd 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
"@emotion/styled": "^11.11.0",
"@tanstack/react-query": "^5.17.19",
"axios": "^1.5.1",
- "concept-be-design-system": "^0.4.1",
+ "concept-be-design-system": "^0.4.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.15.0",
diff --git a/src/components/ProfileInfo.tsx b/src/components/ProfileInfo.tsx
index fa08a1e4..78f305de 100644
--- a/src/components/ProfileInfo.tsx
+++ b/src/components/ProfileInfo.tsx
@@ -1,5 +1,8 @@
import styled from '@emotion/styled';
import { Text, TextDivider, Box, Flex } from 'concept-be-design-system';
+import { Fragment } from 'react';
+
+import { DEFAULT_IMAGE_URL } from '../constants';
interface Props {
imageUrl: string;
@@ -8,7 +11,6 @@ interface Props {
}
// TODO: 프로필 이미지 사진 오류 시 보여줄 기본 프로필 이미지 사진 URL
-const DEFAULT_IMAGE_URL = '';
const ProfileInfo = ({ imageUrl, nickname, skillList }: Props) => {
return (
@@ -22,12 +24,12 @@ const ProfileInfo = ({ imageUrl, nickname, skillList }: Props) => {
{skillList.map((skill, idx) => (
- <>
+
{skill}
{idx !== skillList.length - 1 && }
- >
+
))}
diff --git a/src/constants/index.ts b/src/constants/index.ts
index 78fce2f9..53ea7dc4 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -1 +1,6 @@
export const BASE_URL = 'http://conceptbe.kr:8080';
+
+// 서버 작업으로 인한 임시 상수값
+export const ROOT_COMMENT_ID = '0';
+
+export const DEFAULT_IMAGE_URL = '';
diff --git a/src/pages/FeedDetail/FeedDetail.page.tsx b/src/pages/FeedDetail/FeedDetail.page.tsx
index 50ee6c9e..01779bf4 100644
--- a/src/pages/FeedDetail/FeedDetail.page.tsx
+++ b/src/pages/FeedDetail/FeedDetail.page.tsx
@@ -1,32 +1,18 @@
-import styled from '@emotion/styled';
-import {
- Badge,
- Divider,
- Header,
- Spacer,
- Text,
- TextDivider,
- theme,
- SVGTripleDots,
- SVGFeedLike,
- SVGFeedMessage,
- SVGFeedPencil,
- SVGFeedUnScrap,
- SVGCancel,
- Flex,
- Box,
-} from 'concept-be-design-system';
-import { useParams } from 'react-router-dom';
+import { Badge, Divider, Header, Spacer, Text, TextDivider, Flex, Box } from 'concept-be-design-system';
+import { useNavigate, useParams } from 'react-router-dom';
import Comments from './components/Comments';
-import useGetFeedDetail from './hooks/useGetFeedDetail';
-import useHandleClickOutside from './hooks/useHandleClickOutside';
+import ModifyDropdown from './components/ModifyDropdown';
+import ReactionBar from './components/ReactionBar';
+import { CommentFocusProvider } from './contexts/CommentFocusContext';
+import useFeedDetailQuery from './hooks/queries/useFeedDetailQuery';
import ProfileInfo from '../../components/ProfileInfo';
import Back from '../../layouts/Back';
import Logo from '../../layouts/Logo';
import { formatCommentDate } from '../Feed/utils/formatCommentDate';
const FeedDetailPage = () => {
+ const navigate = useNavigate();
const { id: feedId } = useParams() as { id: string };
const {
imageUrl,
@@ -39,47 +25,36 @@ const FeedDetailPage = () => {
purposeList,
cooperationWay,
recruitmentPlace,
- teamRecruitmentsList,
+ skillCategories,
likesCount,
commentsCount,
bookmarksCount,
hits,
- commentParentResponses,
- } = useGetFeedDetail(feedId);
+ owner,
+ ownerScrap,
+ ownerLike,
+ } = useFeedDetailQuery(feedId);
- const { dropdownRef, isOpenModifyDropdown, toggleModifyDropdown } = useHandleClickOutside();
+ const onModifyFeedDetail = () => {
+ // 게시글 수정 로직 필요
+ };
+
+ const onDeleteFeedDetail = () => {
+ // 게시글 삭제 로직 필요
+ navigate(-1);
+ };
return (
- <>
+
-
-
- {isOpenModifyDropdown && (
-
-
-
- 수정하기
-
-
-
-
-
-
- 삭제하기
-
-
-
-
- )}
-
+
+
-
-
@@ -162,7 +137,7 @@ const FeedDetailPage = () => {
- {teamRecruitmentsList.map((badge) => (
+ {skillCategories.map((badge) => (
{badge}
@@ -171,60 +146,23 @@ const FeedDetailPage = () => {
-
-
-
-
-
- 댓글
-
-
- {commentsCount > 999 ? '999+' : commentsCount}
-
-
-
-
-
- 좋아요
-
-
- {likesCount > 999 ? '999+' : likesCount}
-
-
-
-
-
- 스크랩
-
-
- {bookmarksCount > 999 ? '999+' : bookmarksCount}
-
-
-
+
-
- >
+
+
);
};
export default FeedDetailPage;
-
-const DropDownBox = styled.div`
- position: absolute;
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- background-color: ${theme.color.w1};
- width: 88px;
- height: 70px;
- border-radius: 6px;
- padding: 10px;
- top: 40px;
- right: -6px;
- box-shadow: 0px 6px 10px 0px rgba(0, 0, 0, 0.18);
-`;
diff --git a/src/pages/FeedDetail/components/Comment.tsx b/src/pages/FeedDetail/components/Comment.tsx
index ecea8840..5cea8908 100644
--- a/src/pages/FeedDetail/components/Comment.tsx
+++ b/src/pages/FeedDetail/components/Comment.tsx
@@ -1,50 +1,138 @@
-import { Box, Flex, SVGFeedMessage, SVGFeedUnLike, Spacer, Text } from 'concept-be-design-system';
+import { Box, Flex, SVGFeedLike, SVGFeedMessage, SVGFeedUnLike, Spacer, Text } from 'concept-be-design-system';
+import { useState } from 'react';
+import CommentProfileInfo from './CommentProfileInfo';
+import EditComment from './EditComment';
+import ModifyDropdown from './ModifyDropdown';
import Recomment from './Recomment';
-import ProfileInfo from '../../../components/ProfileInfo';
+import WriteRecomment from './WriteRecomment';
+import { get999PlusCount } from '../../utils';
+import useDeleteCommentMutation from '../hooks/mutations/useDeleteComment';
+import useFocusEditComment from '../hooks/useFocusEditComment';
+import useFocusRecomment from '../hooks/useFocusRecomment';
+import useToggleLikeComment from '../hooks/useToggleLikeComment';
import { CommentParentResponse } from '../types';
interface Props {
+ feedId: string;
+ myImageUrl: string;
+ myNickname: string;
+ mySkillList: string[];
comment: CommentParentResponse;
}
const Comment = ({
- comment: { nickname, memberSkills, content, likesCount, commentCount, commentChildResponses },
+ feedId,
+ myImageUrl,
+ myNickname,
+ comment: {
+ parentCommentId,
+ nickname,
+ profileImageUrl,
+ createdAt,
+ memberSkills,
+ content,
+ likesCount,
+ commentCount,
+ commentChildResponses,
+ owner,
+ deleted,
+ likes,
+ },
}: Props) => {
+ const [isEditComment, setIsEditComment] = useState(false);
+ const [isOpenRecommentTextarea, setIsOpenRecommentTextarea] = useState(false);
+ const { deleteComment } = useDeleteCommentMutation({ feedId });
+ const toggleLikeComment = useToggleLikeComment({ feedId, commentId: parentCommentId, isLike: likes });
+
+ useFocusEditComment({ focusCondition: isEditComment });
+ useFocusRecomment({ focusCondition: isOpenRecommentTextarea });
+
+ const onOpenRecommentTextarea = () => {
+ if (isOpenRecommentTextarea) return;
+ setIsOpenRecommentTextarea(true);
+ };
+
+ const onCloseRecommentTextarea = () => {
+ setIsOpenRecommentTextarea(false);
+ };
+
+ const onCloseEditCommentTextarea = () => {
+ setIsEditComment(false);
+ };
+
+ const onEditComment = () => {
+ setIsEditComment(true);
+ };
+
+ const onDeleteComment = () => {
+ //TODO: #54 머지 후 Confirm 컴포넌트로 대체
+ if (confirm('댓글을 삭제하시겠습니까?')) deleteComment(parentCommentId);
+ };
+
return (
<>
-
-
-
-
- {content}
-
-
-
-
-
-
- 댓글
-
-
- {commentCount > 999 ? '999+' : commentCount}
-
+ {isEditComment ? (
+
+ ) : (
+
+
+
+ {!deleted && }
-
-
-
-
- 좋아요
-
-
- {likesCount > 999 ? '999+' : likesCount}
-
+
+
+ {deleted ? '삭제된 댓글입니다.' : content}
+
+
+
+
+
+
+ {commentCount > 0 ? get999PlusCount(commentCount) : '댓글작성'}
+
+
+
+
+ {likes ? : }
+
+ {get999PlusCount(likesCount)}
+
+
-
-
- {commentChildResponses.map((recomment, idx) => (
-
+
+ )}
+
+ {commentChildResponses.map((recomment) => (
+
))}
+ {isOpenRecommentTextarea && (
+
+ )}
>
);
};
diff --git a/src/pages/FeedDetail/components/CommentProfileInfo.tsx b/src/pages/FeedDetail/components/CommentProfileInfo.tsx
new file mode 100644
index 00000000..50a7d56a
--- /dev/null
+++ b/src/pages/FeedDetail/components/CommentProfileInfo.tsx
@@ -0,0 +1,48 @@
+import styled from '@emotion/styled';
+import { Box, Flex, Text, TextDivider } from 'concept-be-design-system';
+import { Fragment } from 'react';
+
+import { DEFAULT_IMAGE_URL } from '../../../constants';
+import { formatCommentDate } from '../../Feed/utils/formatCommentDate';
+
+interface Props {
+ imageUrl: string;
+ nickname: string;
+ skillList: string[];
+ createdAt: string;
+}
+
+const CommentProfileInfo = ({ imageUrl, nickname, skillList, createdAt }: Props) => {
+ return (
+
+
+
+
+
+
+ {nickname}
+
+
+ {skillList.map((skill) => (
+
+
+ {skill}
+
+
+
+ ))}
+
+ {formatCommentDate(createdAt)}
+
+
+
+
+ );
+};
+
+const Img = styled.img`
+ width: 100%;
+ height: 100%;
+`;
+
+export default CommentProfileInfo;
diff --git a/src/pages/FeedDetail/components/Comments.tsx b/src/pages/FeedDetail/components/Comments.tsx
index 8ab5f2dd..7c11edae 100644
--- a/src/pages/FeedDetail/components/Comments.tsx
+++ b/src/pages/FeedDetail/components/Comments.tsx
@@ -1,48 +1,41 @@
-import styled from '@emotion/styled';
-import { Spacer, theme } from 'concept-be-design-system';
+import { Box, Divider } from 'concept-be-design-system';
+import { Fragment, useRef } from 'react';
import Comment from './Comment';
-import { CommentParentResponse } from '../types';
+import WriteComment from './WriteComment';
+import { useMemberInfoQuery } from '../../Profile/hooks/queries/useMemberInfoQuery';
+import useCommentsQuery from '../hooks/queries/useCommentsQuery';
+import useCommentInfiniteFetch from '../hooks/useCommentInfiniteFetch';
interface Props {
- comments: CommentParentResponse[];
+ feedId: string;
}
-const Comments = ({ comments }: Props) => (
-
-
-
-
-
- {comments.map((comment, idx) => (
-
- ))}
-
-);
+const Comments = ({ feedId }: Props) => {
+ const { comments, fetchNextPage } = useCommentsQuery(feedId);
+ const { profileImageUrl: myImageUrl, nickname: myNickname, skills: mySkillList } = useMemberInfoQuery();
-export default Comments;
-
-const CommentWrapper = styled.div`
- padding: 20px 22px 20px 22px;
-`;
+ const intersectionRef = useRef(null);
+ useCommentInfiniteFetch(intersectionRef, fetchNextPage);
-const InputBox = styled.div`
- position: relative;
-`;
+ return (
+
+
+ {comments.map((comment, idx) => (
+
+
+ {idx !== comments.length - 1 ? : <>>}
+
+ ))}
+
+
+ );
+};
-const Input = styled.input`
- border-radius: 6px;
- width: 100%;
- padding: 10px 20px;
- box-sizing: border-box;
- border: none;
- background-color: ${theme.color.bg1};
- color: ${theme.color.t};
- font-style: normal;
- font-family: SUIT;
- font-weight: 400;
- line-height: normal;
- ::placeholder {
- color: ${theme.color.ba};
- }
-`;
+export default Comments;
diff --git a/src/pages/FeedDetail/components/EditComment.tsx b/src/pages/FeedDetail/components/EditComment.tsx
new file mode 100644
index 00000000..70d7c298
--- /dev/null
+++ b/src/pages/FeedDetail/components/EditComment.tsx
@@ -0,0 +1,129 @@
+import styled from '@emotion/styled';
+import { Box, Button, Divider, Flex, theme, Text } from 'concept-be-design-system';
+import { ChangeEvent, useState } from 'react';
+
+import WriteCommentProfileInfo from './WriteCommentProfileInfo';
+import { useFocusEditCommentTextareaContext } from '../contexts/CommentFocusContext';
+import usePatchComment from '../hooks/mutations/usePatchComment';
+
+interface Props {
+ isRecomment?: boolean;
+ content: string;
+ commentId: string;
+ feedId: string;
+ myImageUrl: string;
+ myNickname: string;
+ onCloseEditCommentTextarea: () => void;
+}
+
+const EditComment = ({
+ isRecomment,
+ content,
+ feedId,
+ commentId,
+ myImageUrl,
+ myNickname,
+ onCloseEditCommentTextarea,
+}: Props) => {
+ const [commentInput, setCommentInput] = useState(content);
+ const { editCommentTextareaRef, initEditCommentTextarea } = useFocusEditCommentTextareaContext();
+ const { editComment } = usePatchComment({
+ feedId,
+ commentId,
+ onSuccess: () => {
+ initEditCommentTextarea();
+ onCloseEditCommentTextarea();
+ },
+ });
+
+ const onChangeTextarea = (e: ChangeEvent) => {
+ setCommentInput(e.target.value.substring(0, 500));
+ };
+
+ const onCancelEditComment = () => {
+ setCommentInput('');
+ onCloseEditCommentTextarea();
+ initEditCommentTextarea();
+ };
+
+ const onSubmitComment = () => {
+ editComment({ content: commentInput });
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ {commentInput.length}
+ /500
+
+
+
+ 취소
+
+ 수정
+
+
+
+
+ );
+};
+
+const Textarea = styled.textarea`
+ display: block;
+ width: 100%;
+ height: 80px;
+ padding: 10px 20px;
+ box-sizing: border-box;
+ border: none;
+ background-color: ${theme.color.bg1};
+ color: ${theme.color.b4};
+ font-size: ${theme.font.suit14r.fontSize}px;
+ font-weight: ${theme.font.suit14r.fontWeight};
+ line-height: 160%;
+
+ ::placeholder {
+ color: ${theme.color.ba};
+ }
+`;
+
+const CancelButton = styled(Button)`
+ width: 43px;
+ height: 32px;
+ color: ${theme.color.b6};
+ background-color: ${theme.color.l3};
+ font-size: ${theme.font.suit13m.fontSize}px;
+ font-weight: ${theme.font.suit13m.fontWeight};
+ padding: 6px 10px;
+`;
+
+const ConfirmButton = styled(Button)`
+ width: 43px;
+ height: 32px;
+ font-size: ${theme.font.suit13m.fontSize}px;
+ font-weight: ${theme.font.suit13m.fontWeight};
+ padding: 6px 10px;
+`;
+
+export default EditComment;
diff --git a/src/pages/FeedDetail/components/ModifyDropdown.tsx b/src/pages/FeedDetail/components/ModifyDropdown.tsx
new file mode 100644
index 00000000..d5a109e8
--- /dev/null
+++ b/src/pages/FeedDetail/components/ModifyDropdown.tsx
@@ -0,0 +1,76 @@
+import styled from '@emotion/styled';
+import {
+ Box,
+ Flex,
+ Text,
+ Divider,
+ SVGCancel,
+ Spacer,
+ SVGTripleDots,
+ SVGFeedPencil,
+ theme,
+} from 'concept-be-design-system';
+
+import { ReactComponent as SVGMore24 } from '../../components/NewIdeaCard/assets/more24.svg';
+import useHandleModifyDropdown from '../hooks/useHandleModifyDropdown';
+
+interface Props {
+ owner: boolean;
+ isInComment?: boolean;
+ onEdit: () => void;
+ onDelete: () => void;
+}
+
+const ModifyDropdown = ({ owner, isInComment, onEdit, onDelete }: Props) => {
+ const { dropdownRef, isOpenModifyDropdown, toggleModifyDropdown } = useHandleModifyDropdown();
+
+ return (
+ <>
+ {owner ? (
+
+ {isInComment ? (
+
+ ) : (
+
+ )}
+ {isOpenModifyDropdown && (
+
+
+
+ 수정하기
+
+
+
+
+
+
+ 삭제하기
+
+
+
+
+ )}
+
+ ) : (
+
+ )}
+ >
+ );
+};
+
+export default ModifyDropdown;
+
+const DropDownBox = styled.div`
+ position: absolute;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-around;
+ background-color: ${theme.color.w1};
+ width: 88px;
+ height: 70px;
+ border-radius: 6px;
+ padding: 10px;
+ top: 40px;
+ right: -6px;
+ box-shadow: 0px 6px 10px 0px rgba(0, 0, 0, 0.18);
+`;
diff --git a/src/pages/FeedDetail/components/ReactionBar.tsx b/src/pages/FeedDetail/components/ReactionBar.tsx
new file mode 100644
index 00000000..23802599
--- /dev/null
+++ b/src/pages/FeedDetail/components/ReactionBar.tsx
@@ -0,0 +1,75 @@
+import {
+ Flex,
+ SVGFeedLike,
+ SVGFeedMessage,
+ SVGFeedScrap,
+ SVGFeedUnLike,
+ SVGFeedUnScrap,
+ Text,
+} from 'concept-be-design-system';
+
+import { get999PlusCount } from '../../utils';
+import { useFocusCommentTextareaContext } from '../contexts/CommentFocusContext';
+import useDeleteFeedLike from '../hooks/mutations/useDeleteFeedLike';
+import useDeleteFeedScrap from '../hooks/mutations/useDeleteFeedScrap';
+import usePostFeedLike from '../hooks/mutations/usePostFeedLike';
+import usePostFeedScrap from '../hooks/mutations/usePostFeedScrap';
+
+interface Props {
+ feedId: string;
+ commentsCount: number;
+ likesCount: number;
+ bookmarksCount: number;
+ ownerScrap: boolean;
+ ownerLike: boolean;
+}
+
+const ReactionBar = ({ feedId, commentsCount, likesCount, bookmarksCount, ownerLike, ownerScrap }: Props) => {
+ const { openCommentTextarea } = useFocusCommentTextareaContext();
+ const { postScrap } = usePostFeedScrap(feedId);
+ const { deleteScrap } = useDeleteFeedScrap(feedId);
+ const { postLike } = usePostFeedLike(feedId);
+ const { deleteLike } = useDeleteFeedLike(feedId);
+
+ const toggleScrap = () => {
+ ownerScrap ? deleteScrap(feedId) : postScrap(feedId);
+ };
+
+ const toggleLike = () => {
+ ownerLike ? deleteLike(feedId) : postLike(feedId);
+ };
+
+ return (
+
+
+
+
+ 댓글
+
+
+ {get999PlusCount(commentsCount)}
+
+
+
+ {ownerLike ? : }
+
+ 좋아요
+
+
+ {get999PlusCount(likesCount)}
+
+
+
+ {ownerScrap ? : }
+
+ 스크랩
+
+
+ {get999PlusCount(bookmarksCount)}
+
+
+
+ );
+};
+
+export default ReactionBar;
diff --git a/src/pages/FeedDetail/components/Recomment.tsx b/src/pages/FeedDetail/components/Recomment.tsx
index d162cbdd..1d96f22b 100644
--- a/src/pages/FeedDetail/components/Recomment.tsx
+++ b/src/pages/FeedDetail/components/Recomment.tsx
@@ -1,38 +1,86 @@
-import { Box, Flex, SVGFeedReCommentLine, SVGFeedUnLike, Spacer, Text } from 'concept-be-design-system';
+import { Box, Flex, SVGFeedLike, SVGFeedReCommentLine, SVGFeedUnLike, Spacer, Text } from 'concept-be-design-system';
+import { useState } from 'react';
+import EditComment from './EditComment';
+import ModifyDropdown from './ModifyDropdown';
import ProfileInfo from '../../../components/ProfileInfo';
+import { get999PlusCount } from '../../utils';
+import useDeleteCommentMutation from '../hooks/mutations/useDeleteComment';
+import useFocusEditComment from '../hooks/useFocusEditComment';
+import useToggleLikeComment from '../hooks/useToggleLikeComment';
import { CommentChildResponse } from '../types';
interface Props {
+ feedId: string;
recomment: CommentChildResponse;
+ myImageUrl: string;
+ myNickname: string;
}
-const Recomment = ({ recomment: { nickname, memberSkills, content, likesCount } }: Props) => {
+const Recomment = ({
+ feedId,
+ myImageUrl,
+ myNickname,
+ recomment: { childCommentId, profileImageUrl, nickname, memberSkills, content, likesCount, owner, deleted, likes },
+}: Props) => {
+ const [isEditComment, setIsEditComment] = useState(false);
+ const { deleteComment } = useDeleteCommentMutation({ feedId });
+ const toggleLikeComment = useToggleLikeComment({ feedId, commentId: childCommentId, isLike: likes });
+
+ useFocusEditComment({ focusCondition: isEditComment });
+
+ const onCloseEditCommentTextarea = () => {
+ setIsEditComment(false);
+ };
+
+ const onEditComment = () => {
+ setIsEditComment(true);
+ };
+
+ const onDeleteComment = () => {
+ //TODO: #54 머지 후 Confirm 컴포넌트로 대체
+ if (confirm('답글을 삭제하시겠습니까?')) deleteComment(childCommentId);
+ };
+
return (
-
-
-
-
-
-
-
-
- {content}
-
-
-
-
-
-
- 좋아요
-
-
- {likesCount > 999 ? '999+' : likesCount}
-
+ <>
+ {isEditComment ? (
+
+ ) : (
+
+
+
+
+
+
+
+
+
+ {content}
+
+
+
+
+ {likes ? : }
+
+ {get999PlusCount(likesCount)}
+
+
+
+
+ {!deleted && }
-
-
+ )}
+ >
);
};
diff --git a/src/pages/FeedDetail/components/WriteComment.tsx b/src/pages/FeedDetail/components/WriteComment.tsx
new file mode 100644
index 00000000..3a078663
--- /dev/null
+++ b/src/pages/FeedDetail/components/WriteComment.tsx
@@ -0,0 +1,129 @@
+import styled from '@emotion/styled';
+import { Box, Button, Divider, Flex, Text, theme } from 'concept-be-design-system';
+import { ChangeEvent, useState } from 'react';
+
+import WriteCommentProfileInfo from './WriteCommentProfileInfo';
+import { ROOT_COMMENT_ID } from '../../../constants';
+import { useFocusCommentTextareaContext } from '../contexts/CommentFocusContext';
+import usePostComment from '../hooks/mutations/usePostComment';
+
+interface Props {
+ feedId: string;
+ myImageUrl: string;
+ myNickname: string;
+}
+
+const WriteComment = ({ feedId, myImageUrl, myNickname }: Props) => {
+ const [commentInput, setCommentInput] = useState('');
+ const { commentTextareaRef, isFocusComment, openCommentTextarea, closeCommentTextarea } =
+ useFocusCommentTextareaContext();
+ const { postComment } = usePostComment({ feedId });
+
+ const onChangeTextarea = (e: ChangeEvent) => {
+ setCommentInput(e.target.value.substring(0, 500));
+ };
+
+ const onBlurTextarea = () => {
+ if (commentInput.length > 0) return;
+ closeCommentTextarea();
+ };
+
+ const onCancelComment = () => {
+ setCommentInput('');
+ closeCommentTextarea();
+ };
+
+ const onSubmitComment = () => {
+ postComment(
+ { ideaId: feedId, parentId: ROOT_COMMENT_ID, content: commentInput },
+ {
+ onSuccess: () => {
+ setCommentInput('');
+ closeCommentTextarea();
+ },
+ },
+ );
+ };
+
+ return (
+
+ {isFocusComment && (
+
+
+
+ )}
+
+ {isFocusComment && (
+
+
+
+
+ {commentInput.length}
+ /500
+
+
+
+ 취소
+
+ 등록
+
+
+
+ )}
+
+ );
+};
+
+const Textarea = styled.textarea<{ isFocus: boolean }>`
+ display: block;
+ border-radius: ${({ isFocus }) => (isFocus ? '0' : '6px')};
+ width: 100%;
+ height: ${({ isFocus }) => isFocus && '80px'};
+ padding: 10px 20px;
+ box-sizing: border-box;
+ border: none;
+ background-color: ${theme.color.bg1};
+ color: ${theme.color.b4};
+ font-size: ${theme.font.suit14r.fontSize}px;
+ font-weight: ${theme.font.suit14r.fontWeight};
+ line-height: 160%;
+
+ ::placeholder {
+ color: ${theme.color.ba};
+ }
+`;
+
+const CancelButton = styled(Button)`
+ width: 43px;
+ height: 32px;
+ color: ${theme.color.b6};
+ background-color: ${theme.color.l3};
+ font-size: ${theme.font.suit13m.fontSize}px;
+ font-weight: ${theme.font.suit13m.fontWeight};
+ padding: 6px 10px;
+`;
+
+const ConfirmButton = styled(Button)`
+ width: 43px;
+ height: 32px;
+ font-size: ${theme.font.suit13m.fontSize}px;
+ font-weight: ${theme.font.suit13m.fontWeight};
+ padding: 6px 10px;
+`;
+
+export default WriteComment;
diff --git a/src/pages/FeedDetail/components/WriteCommentProfileInfo.tsx b/src/pages/FeedDetail/components/WriteCommentProfileInfo.tsx
new file mode 100644
index 00000000..9c60091b
--- /dev/null
+++ b/src/pages/FeedDetail/components/WriteCommentProfileInfo.tsx
@@ -0,0 +1,31 @@
+import styled from '@emotion/styled';
+import { Text, Box, Flex } from 'concept-be-design-system';
+
+import { DEFAULT_IMAGE_URL } from '../../../constants';
+
+interface Props {
+ imageUrl: string;
+ nickname: string;
+}
+
+// TODO: 프로필 이미지 사진 오류 시 보여줄 기본 프로필 이미지 사진 URL
+
+const WriteCommentProfileInfo = ({ imageUrl, nickname }: Props) => {
+ return (
+
+
+
+
+
+ {nickname}
+
+
+ );
+};
+
+export default WriteCommentProfileInfo;
+
+const Img = styled.img`
+ width: 100%;
+ height: 100%;
+`;
diff --git a/src/pages/FeedDetail/components/WriteRecomment.tsx b/src/pages/FeedDetail/components/WriteRecomment.tsx
new file mode 100644
index 00000000..cebbdd2a
--- /dev/null
+++ b/src/pages/FeedDetail/components/WriteRecomment.tsx
@@ -0,0 +1,120 @@
+import styled from '@emotion/styled';
+import { Box, Button, Divider, Flex, theme, Text } from 'concept-be-design-system';
+import { ChangeEvent, useState } from 'react';
+
+import WriteCommentProfileInfo from './WriteCommentProfileInfo';
+import { useFocusRecommentTextareaContext } from '../contexts/CommentFocusContext';
+import usePostComment from '../hooks/mutations/usePostComment';
+
+interface Props {
+ feedId: string;
+ parentCommentId: string;
+ myImageUrl: string;
+ myNickname: string;
+ onCloseRecommentTextarea: () => void;
+}
+
+const WriteRecomment = ({ feedId, parentCommentId, myImageUrl, myNickname, onCloseRecommentTextarea }: Props) => {
+ const [recommentInput, setRecommentInput] = useState('');
+ const { recommentTextareaRef, initRecommentTextarea } = useFocusRecommentTextareaContext();
+ const { postComment } = usePostComment({ feedId });
+
+ const onChangeTextarea = (e: ChangeEvent) => {
+ setRecommentInput(e.target.value.substring(0, 500));
+ };
+
+ const onCancelComment = () => {
+ setRecommentInput('');
+ onCloseRecommentTextarea();
+ initRecommentTextarea();
+ };
+
+ const onSubmitComment = () => {
+ postComment(
+ { ideaId: feedId, parentId: parentCommentId, content: recommentInput },
+ {
+ onSuccess: () => {
+ setRecommentInput('');
+ onCloseRecommentTextarea();
+ },
+ },
+ );
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ {recommentInput.length}
+ /500
+
+
+
+ 취소
+
+ 등록
+
+
+
+
+ );
+};
+
+const Textarea = styled.textarea`
+ display: block;
+ width: 100%;
+ height: 80px;
+ padding: 10px 20px;
+ box-sizing: border-box;
+ border: none;
+ background-color: ${theme.color.bg1};
+ color: ${theme.color.b4};
+ font-size: ${theme.font.suit14r.fontSize}px;
+ font-weight: ${theme.font.suit14r.fontWeight};
+ line-height: 160%;
+
+ ::placeholder {
+ color: ${theme.color.ba};
+ }
+`;
+
+const CancelButton = styled(Button)`
+ width: 43px;
+ height: 32px;
+ color: ${theme.color.b6};
+ background-color: ${theme.color.l3};
+ font-size: ${theme.font.suit13m.fontSize}px;
+ font-weight: ${theme.font.suit13m.fontWeight};
+ padding: 6px 10px;
+`;
+
+const ConfirmButton = styled(Button)`
+ width: 43px;
+ height: 32px;
+ font-size: ${theme.font.suit13m.fontSize}px;
+ font-weight: ${theme.font.suit13m.fontWeight};
+ padding: 6px 10px;
+`;
+
+export default WriteRecomment;
diff --git a/src/pages/FeedDetail/contexts/CommentFocusContext.tsx b/src/pages/FeedDetail/contexts/CommentFocusContext.tsx
new file mode 100644
index 00000000..5ee4537e
--- /dev/null
+++ b/src/pages/FeedDetail/contexts/CommentFocusContext.tsx
@@ -0,0 +1,110 @@
+import { useContext, useState, createContext, MutableRefObject, useRef } from 'react';
+
+type CommentFocusContextType = {
+ isFocusComment: boolean;
+ openCommentTextarea: () => void;
+ focusRecommentTextarea: () => void;
+ closeCommentTextarea: () => void;
+ initRecommentTextarea: () => void;
+ focusEditCommentTextarea: () => void;
+ initEditCommentTextarea: () => void;
+ commentTextareaRef: MutableRefObject;
+ recommentTextareaRef: MutableRefObject;
+ editCommentTextareaRef: MutableRefObject;
+};
+
+type Props = {
+ children: React.ReactNode;
+};
+
+const CommentFocusContext = createContext(null);
+
+const focusTextareaRef = (textareaRef: MutableRefObject) => {
+ if (!textareaRef.current) return;
+
+ textareaRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' });
+ textareaRef.current.focus();
+};
+
+const initTextareaRef = (textareaRef: MutableRefObject) => {
+ textareaRef.current = null;
+};
+
+export const CommentFocusProvider = ({ children }: Props) => {
+ const [isFocusComment, setIsFocusComment] = useState(false);
+ const commentTextareaRef = useRef(null);
+ const recommentTextareaRef = useRef(null);
+ const editCommentTextareaRef = useRef(null);
+
+ const openCommentTextarea = () => {
+ focusTextareaRef(commentTextareaRef);
+
+ setIsFocusComment(true);
+ };
+
+ const closeCommentTextarea = () => {
+ setIsFocusComment(false);
+ };
+
+ const focusRecommentTextarea = () => {
+ focusTextareaRef(recommentTextareaRef);
+ };
+
+ const initRecommentTextarea = () => {
+ initTextareaRef(recommentTextareaRef);
+ };
+
+ const focusEditCommentTextarea = () => {
+ focusTextareaRef(editCommentTextareaRef);
+ };
+
+ const initEditCommentTextarea = () => {
+ initTextareaRef(editCommentTextareaRef);
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useFocusCommentTextareaContext = () => {
+ const context = useContext(CommentFocusContext);
+ if (context === null) {
+ throw new Error('useFocusComment 은 CommentFocusProvider 내부에서 호출해주세요.');
+ }
+ const { isFocusComment, openCommentTextarea, closeCommentTextarea, commentTextareaRef } = context;
+ return { isFocusComment, openCommentTextarea, closeCommentTextarea, commentTextareaRef };
+};
+
+export const useFocusRecommentTextareaContext = () => {
+ const context = useContext(CommentFocusContext);
+ if (context === null) {
+ throw new Error('useFocusComment 은 CommentFocusProvider 내부에서 호출해주세요.');
+ }
+ const { focusRecommentTextarea, initRecommentTextarea, recommentTextareaRef } = context;
+ return { focusRecommentTextarea, initRecommentTextarea, recommentTextareaRef };
+};
+
+export const useFocusEditCommentTextareaContext = () => {
+ const context = useContext(CommentFocusContext);
+ if (context === null) {
+ throw new Error('useFocusComment 은 CommentFocusProvider 내부에서 호출해주세요.');
+ }
+ const { focusEditCommentTextarea, initEditCommentTextarea, editCommentTextareaRef } = context;
+ return { focusEditCommentTextarea, initEditCommentTextarea, editCommentTextareaRef };
+};
diff --git a/src/pages/FeedDetail/hooks/mutations/useDeleteComment.ts b/src/pages/FeedDetail/hooks/mutations/useDeleteComment.ts
new file mode 100644
index 00000000..7c725d2c
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/mutations/useDeleteComment.ts
@@ -0,0 +1,28 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { http } from '../../../../api/http';
+
+interface Props {
+ feedId: string;
+}
+
+const _deleteComment = (commentId: string) => http.delete(`/comments/${commentId}`);
+
+const useDeleteCommentMutation = ({ feedId }: Props) => {
+ const queryClient = useQueryClient();
+ const { mutate: deleteComment, ...rest } = useMutation({
+ mutationFn: _deleteComment,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['comments', feedId] });
+ queryClient.invalidateQueries({ queryKey: ['feed', 'detail', feedId] });
+ },
+ onError: (error: AxiosError<{ message: string }>) => {
+ alert(error.response?.data.message ?? '댓글 삭제에 실패했습니다.');
+ },
+ });
+
+ return { deleteComment, ...rest };
+};
+
+export default useDeleteCommentMutation;
diff --git a/src/pages/FeedDetail/hooks/mutations/useDeleteCommentLike.ts b/src/pages/FeedDetail/hooks/mutations/useDeleteCommentLike.ts
new file mode 100644
index 00000000..8057e48d
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/mutations/useDeleteCommentLike.ts
@@ -0,0 +1,25 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { http } from '../../../../api/http';
+
+const _deleteLikeComment = (commentId: string) => {
+ return http.delete(`/comments/likes/${commentId}`);
+};
+
+const useDeleteCommentLike = ({ feedId }: { feedId: string }) => {
+ const queryClient = useQueryClient();
+ const { mutate: deleteLikeComment, ...rest } = useMutation({
+ mutationFn: _deleteLikeComment,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['comments', feedId] });
+ },
+ onError: (error: AxiosError<{ message: string }>) => {
+ alert(error.response?.data.message ?? '좋아요 해제에 실패했습니다.');
+ },
+ });
+
+ return { deleteLikeComment, ...rest };
+};
+
+export default useDeleteCommentLike;
diff --git a/src/pages/FeedDetail/hooks/mutations/useDeleteFeedLike.ts b/src/pages/FeedDetail/hooks/mutations/useDeleteFeedLike.ts
new file mode 100644
index 00000000..043114e9
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/mutations/useDeleteFeedLike.ts
@@ -0,0 +1,25 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { http } from '../../../../api/http';
+
+const _deleteLike = (id: string) => {
+ return http.delete(`/ideas/likes/${id}`);
+};
+
+const useDeleteFeedLike = (id: string) => {
+ const queryClient = useQueryClient();
+ const { mutate: deleteLike, ...rest } = useMutation({
+ mutationFn: _deleteLike,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['feed', 'detail', id] });
+ },
+ onError: (error: AxiosError<{ message: string }>) => {
+ alert(error.response?.data.message ?? '좋아요 해제에 실패했습니다.');
+ },
+ });
+
+ return { deleteLike, ...rest };
+};
+
+export default useDeleteFeedLike;
diff --git a/src/pages/FeedDetail/hooks/mutations/useDeleteFeedScrap.ts b/src/pages/FeedDetail/hooks/mutations/useDeleteFeedScrap.ts
new file mode 100644
index 00000000..c2fb896f
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/mutations/useDeleteFeedScrap.ts
@@ -0,0 +1,25 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { http } from '../../../../api/http';
+
+const _deleteScrap = (id: string) => {
+ return http.delete(`/bookmark/${id}`);
+};
+
+const useDeleteFeedScrap = (id: string) => {
+ const queryClient = useQueryClient();
+ const { mutate: deleteScrap, ...rest } = useMutation({
+ mutationFn: _deleteScrap,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['feed', 'detail', id] });
+ },
+ onError: (error: AxiosError<{ message: string }>) => {
+ alert(error.response?.data.message ?? '스크랩 해제에 실패했습니다.');
+ },
+ });
+
+ return { deleteScrap, ...rest };
+};
+
+export default useDeleteFeedScrap;
diff --git a/src/pages/FeedDetail/hooks/mutations/usePatchComment.ts b/src/pages/FeedDetail/hooks/mutations/usePatchComment.ts
new file mode 100644
index 00000000..3f5cfb70
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/mutations/usePatchComment.ts
@@ -0,0 +1,34 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { http } from '../../../../api/http';
+
+interface CommentPayload {
+ content: string;
+}
+
+interface Props {
+ feedId: string;
+ commentId: string;
+ onSuccess?: () => void;
+}
+
+const _editComment = (commentId: string, payload: CommentPayload) => http.patch(`/comments/${commentId}`, payload);
+
+const usePatchComment = ({ feedId, commentId, onSuccess }: Props) => {
+ const queryClient = useQueryClient();
+ const { mutate: editComment, ...rest } = useMutation({
+ mutationFn: (payload: CommentPayload) => _editComment(commentId, payload),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['comments', feedId] });
+ if (onSuccess) onSuccess();
+ },
+ onError: (error: AxiosError<{ message: string }>) => {
+ alert(error.response?.data.message ?? '댓글 수정에 실패했습니다.');
+ },
+ });
+
+ return { editComment, ...rest };
+};
+
+export default usePatchComment;
diff --git a/src/pages/FeedDetail/hooks/mutations/usePostComment.ts b/src/pages/FeedDetail/hooks/mutations/usePostComment.ts
new file mode 100644
index 00000000..dfb37672
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/mutations/usePostComment.ts
@@ -0,0 +1,34 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { http } from '../../../../api/http';
+
+interface CommentPayload {
+ ideaId: string;
+ parentId: string;
+ content: string;
+}
+
+interface Props {
+ feedId: string;
+}
+
+const _postComment = (payload: CommentPayload) => http.post('/comments', payload);
+
+const usePostComment = ({ feedId }: Props) => {
+ const queryClient = useQueryClient();
+ const { mutate: postComment, ...rest } = useMutation({
+ mutationFn: _postComment,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['comments', feedId] });
+ queryClient.invalidateQueries({ queryKey: ['feed', 'detail', feedId] });
+ },
+ onError: (error: AxiosError<{ message: string }>) => {
+ alert(error.response?.data.message ?? '댓글 작성에 실패했습니다.');
+ },
+ });
+
+ return { postComment, ...rest };
+};
+
+export default usePostComment;
diff --git a/src/pages/FeedDetail/hooks/mutations/usePostCommentLike.ts b/src/pages/FeedDetail/hooks/mutations/usePostCommentLike.ts
new file mode 100644
index 00000000..604451fe
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/mutations/usePostCommentLike.ts
@@ -0,0 +1,23 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { http } from '../../../../api/http';
+
+const _postLikeComment = (commentId: string) => http.post(`/comments/likes/${commentId}`);
+
+const usePostCommentLike = ({ feedId }: { feedId: string }) => {
+ const queryClient = useQueryClient();
+ const { mutate: postLikeComment, ...rest } = useMutation({
+ mutationFn: _postLikeComment,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['comments', feedId] });
+ },
+ onError: (error: AxiosError<{ message: string }>) => {
+ alert(error.response?.data.message ?? '좋아요에 실패했습니다.');
+ },
+ });
+
+ return { postLikeComment, ...rest };
+};
+
+export default usePostCommentLike;
diff --git a/src/pages/FeedDetail/hooks/mutations/usePostFeedLike.ts b/src/pages/FeedDetail/hooks/mutations/usePostFeedLike.ts
new file mode 100644
index 00000000..8924b116
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/mutations/usePostFeedLike.ts
@@ -0,0 +1,25 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { http } from '../../../../api/http';
+
+const _postLike = (id: string) => {
+ return http.post(`/ideas/likes/${id}`);
+};
+
+const usePostFeedLike = (id: string) => {
+ const queryClient = useQueryClient();
+ const { mutate: postLike, ...rest } = useMutation({
+ mutationFn: _postLike,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['feed', 'detail', id] });
+ },
+ onError: (error: AxiosError<{ message: string }>) => {
+ alert(error.response?.data.message ?? '좋아요에 실패했습니다.');
+ },
+ });
+
+ return { postLike, ...rest };
+};
+
+export default usePostFeedLike;
diff --git a/src/pages/FeedDetail/hooks/mutations/usePostFeedScrap.ts b/src/pages/FeedDetail/hooks/mutations/usePostFeedScrap.ts
new file mode 100644
index 00000000..1aa60036
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/mutations/usePostFeedScrap.ts
@@ -0,0 +1,25 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { http } from '../../../../api/http';
+
+const _postScrap = (id: string) => {
+ return http.post(`/bookmark/${id}`);
+};
+
+const usePostFeedScrap = (id: string) => {
+ const queryClient = useQueryClient();
+ const { mutate: postScrap, ...rest } = useMutation({
+ mutationFn: _postScrap,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['feed', 'detail', id] });
+ },
+ onError: (error: AxiosError<{ message: string }>) => {
+ alert(error.response?.data.message ?? '스크랩에 실패했습니다.');
+ },
+ });
+
+ return { postScrap, ...rest };
+};
+
+export default usePostFeedScrap;
diff --git a/src/pages/FeedDetail/hooks/queries/useCommentsQuery.ts b/src/pages/FeedDetail/hooks/queries/useCommentsQuery.ts
new file mode 100644
index 00000000..fd7ea608
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/queries/useCommentsQuery.ts
@@ -0,0 +1,31 @@
+import { useSuspenseInfiniteQuery } from '@tanstack/react-query';
+
+import { http } from '../../../../api/http';
+import { CommentParentResponse } from '../../types';
+
+interface GetCommentsProps {
+ page: number;
+ size: number;
+}
+
+const getComments = (feedId: string, { page, size }: GetCommentsProps) =>
+ http.get(`/ideas/${feedId}/comments?page=${page}&size=${size}`);
+
+const useCommentsQuery = (feedId: string) => {
+ const sizePerPage = 10;
+ const { data, fetchNextPage, ...rest } = useSuspenseInfiniteQuery({
+ queryKey: ['comments', feedId],
+ initialPageParam: { page: 0, size: sizePerPage },
+ queryFn: ({ pageParam }) => getComments(feedId, pageParam),
+ getNextPageParam: (lastPage, allPages, lastPageParam) => {
+ const nextPageParam = { page: lastPageParam.page + 1, size: sizePerPage };
+
+ // 대댓글 또한 댓글로 간주되어 lastPage.length < sizePerPage 조건문이 정상적으로 동작하지 않아 제거했습니다.
+ return lastPage.length === 0 ? undefined : nextPageParam;
+ },
+ });
+
+ return { comments: data.pages.flat(), fetchNextPage, ...rest };
+};
+
+export default useCommentsQuery;
diff --git a/src/pages/FeedDetail/hooks/useGetFeedDetail.ts b/src/pages/FeedDetail/hooks/queries/useFeedDetailQuery.ts
similarity index 56%
rename from src/pages/FeedDetail/hooks/useGetFeedDetail.ts
rename to src/pages/FeedDetail/hooks/queries/useFeedDetailQuery.ts
index ee0ede0d..af9a0a6e 100644
--- a/src/pages/FeedDetail/hooks/useGetFeedDetail.ts
+++ b/src/pages/FeedDetail/hooks/queries/useFeedDetailQuery.ts
@@ -1,10 +1,10 @@
import { useSuspenseQuery } from '@tanstack/react-query';
-import { getFeedDetail } from '../../../api';
+import { getFeedDetail } from '../../../../api';
-const useGetFeedDetail = (id: string) => {
+const useFeedDetailQuery = (id: string) => {
const { data: feedDetail } = useSuspenseQuery({
- queryKey: ['feedDetail', id],
+ queryKey: ['feed', 'detail', id],
queryFn: () => getFeedDetail(id),
select: (data) => ({ ...data }),
});
@@ -12,4 +12,4 @@ const useGetFeedDetail = (id: string) => {
return feedDetail;
};
-export default useGetFeedDetail;
+export default useFeedDetailQuery;
diff --git a/src/pages/FeedDetail/hooks/useCommentInfiniteFetch.ts b/src/pages/FeedDetail/hooks/useCommentInfiniteFetch.ts
new file mode 100644
index 00000000..c4e65506
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/useCommentInfiniteFetch.ts
@@ -0,0 +1,18 @@
+import { MutableRefObject, useEffect } from 'react';
+import { useIntersection } from 'react-use';
+
+const useCommentInfiniteFetch = (intersectionRef: MutableRefObject, fetchCallback: () => void) => {
+ const intersection = useIntersection(intersectionRef, {
+ root: null,
+ rootMargin: `0px`,
+ threshold: 1,
+ });
+
+ useEffect(() => {
+ if (intersection?.isIntersecting) {
+ fetchCallback();
+ }
+ }, [intersection, fetchCallback]);
+};
+
+export default useCommentInfiniteFetch;
diff --git a/src/pages/FeedDetail/hooks/useFocusEditComment.ts b/src/pages/FeedDetail/hooks/useFocusEditComment.ts
new file mode 100644
index 00000000..aa298c47
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/useFocusEditComment.ts
@@ -0,0 +1,22 @@
+import { useEffect } from 'react';
+
+import { useFocusEditCommentTextareaContext } from '../contexts/CommentFocusContext';
+
+interface Props {
+ focusCondition: boolean;
+}
+
+const useFocusEditComment = ({ focusCondition }: Props) => {
+ const { focusEditCommentTextarea, initEditCommentTextarea } = useFocusEditCommentTextareaContext();
+
+ useEffect(() => {
+ if (!focusCondition) {
+ initEditCommentTextarea();
+ return;
+ }
+
+ focusEditCommentTextarea();
+ }, [focusCondition, focusEditCommentTextarea, initEditCommentTextarea]);
+};
+
+export default useFocusEditComment;
diff --git a/src/pages/FeedDetail/hooks/useFocusRecomment.ts b/src/pages/FeedDetail/hooks/useFocusRecomment.ts
new file mode 100644
index 00000000..2632d824
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/useFocusRecomment.ts
@@ -0,0 +1,22 @@
+import { useEffect } from 'react';
+
+import { useFocusRecommentTextareaContext } from '../contexts/CommentFocusContext';
+
+interface Props {
+ focusCondition: boolean;
+}
+
+const useFocusRecomment = ({ focusCondition }: Props) => {
+ const { focusRecommentTextarea, initRecommentTextarea } = useFocusRecommentTextareaContext();
+
+ useEffect(() => {
+ if (!focusCondition) {
+ initRecommentTextarea();
+ return;
+ }
+
+ focusRecommentTextarea();
+ }, [focusCondition, focusRecommentTextarea, initRecommentTextarea]);
+};
+
+export default useFocusRecomment;
diff --git a/src/pages/FeedDetail/hooks/useHandleClickOutside.ts b/src/pages/FeedDetail/hooks/useHandleModifyDropdown.ts
similarity index 92%
rename from src/pages/FeedDetail/hooks/useHandleClickOutside.ts
rename to src/pages/FeedDetail/hooks/useHandleModifyDropdown.ts
index 956f702f..5e674c3e 100644
--- a/src/pages/FeedDetail/hooks/useHandleClickOutside.ts
+++ b/src/pages/FeedDetail/hooks/useHandleModifyDropdown.ts
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useRef, useState } from 'react';
-const useHandleClickOutside = () => {
+const useHandleModifyDropdown = () => {
const dropdownRef = useRef(null);
const [isOpenModifyDropdown, setIsOpenModifyDropdown] = useState(false);
@@ -34,4 +34,4 @@ const useHandleClickOutside = () => {
return { dropdownRef, isOpenModifyDropdown, toggleModifyDropdown };
};
-export default useHandleClickOutside;
+export default useHandleModifyDropdown;
diff --git a/src/pages/FeedDetail/hooks/useToggleLikeComment.ts b/src/pages/FeedDetail/hooks/useToggleLikeComment.ts
new file mode 100644
index 00000000..069de419
--- /dev/null
+++ b/src/pages/FeedDetail/hooks/useToggleLikeComment.ts
@@ -0,0 +1,21 @@
+import useDeleteCommentLike from './mutations/useDeleteCommentLike';
+import usePostCommentLike from './mutations/usePostCommentLike';
+
+interface Props {
+ feedId: string;
+ commentId: string;
+ isLike: boolean;
+}
+
+const useToggleLikeComment = ({ feedId, commentId, isLike }: Props) => {
+ const { postLikeComment } = usePostCommentLike({ feedId });
+ const { deleteLikeComment } = useDeleteCommentLike({ feedId });
+
+ const toggleLikeComment = () => {
+ isLike ? deleteLikeComment(commentId) : postLikeComment(commentId);
+ };
+
+ return toggleLikeComment;
+};
+
+export default useToggleLikeComment;
diff --git a/src/pages/FeedDetail/types/index.ts b/src/pages/FeedDetail/types/index.ts
index 849a5ba2..05c32986 100644
--- a/src/pages/FeedDetail/types/index.ts
+++ b/src/pages/FeedDetail/types/index.ts
@@ -3,32 +3,46 @@ export interface FeedDetailResponse {
nickname: string;
skillList: string[];
title: string;
- date: Date;
+ date: string;
introduce: string;
branchList: string[];
purposeList: string[];
cooperationWay: string;
recruitmentPlace: string;
- teamRecruitmentsList: string[];
+ skillCategories: string[];
likesCount: number;
commentsCount: number;
bookmarksCount: number;
hits: number;
- commentParentResponses: CommentParentResponse[];
+ owner: boolean;
+ ownerScrap: boolean;
+ ownerLike: boolean;
}
-export interface CommentChildResponse {
+export interface CommentParentResponse {
+ parentCommentId: string;
nickname: string;
+ profileImageUrl: string;
memberSkills: string[];
content: string;
+ createdAt: string;
likesCount: number;
+ commentCount: number;
+ commentChildResponses: CommentChildResponse[];
+ owner: boolean;
+ deleted: boolean;
+ likes: boolean;
}
-export interface CommentParentResponse {
+export interface CommentChildResponse {
+ childCommentId: string;
nickname: string;
+ profileImageUrl: string;
memberSkills: string[];
content: string;
+ createAt: string;
likesCount: number;
- commentCount: number;
- commentChildResponses: CommentChildResponse[];
+ owner: boolean;
+ deleted: boolean;
+ likes: boolean;
}
diff --git a/src/router.tsx b/src/router.tsx
index 9efefeec..dc21027f 100644
--- a/src/router.tsx
+++ b/src/router.tsx
@@ -34,7 +34,11 @@ const routes: RouteElement[] = [
children: [
{
path: '',
- element: ,
+ element: (
+
+
+
+ ),
withAuth: false,
},
{
diff --git a/yarn.lock b/yarn.lock
index 09529660..f51d66b3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -27,7 +27,7 @@
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz"
integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==
-"@babel/core@^7.21.3", "@babel/core@^7.22.9":
+"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.21.3", "@babel/core@^7.22.9":
version "7.22.9"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz"
integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==
@@ -264,7 +264,7 @@
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz"
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
-"@emotion/react@^11.11.1":
+"@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.11.1":
version "11.11.1"
resolved "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz"
integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==
@@ -326,116 +326,11 @@
resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz"
integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
-"@esbuild/android-arm64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.18.tgz#a52e0a1276065b1bf6b2de45b482cf36b6b945bd"
- integrity sha512-dkAPYzRHq3dNXIzOyAknYOzsx8o3KWaNiuu56B2rP9IFPmFWMS58WQcTlUQi6iloku8ZyHHMluCe5sTWhKq/Yw==
-
-"@esbuild/android-arm@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.18.tgz#ffd591b956ced1c96e1224edfbed1001adadf2ae"
- integrity sha512-oBymf7ZwplAawSxmiSlBCf+FMcY0f4bs5QP2jn43JKUf0M9DnrUTjqa5RvFPl1elw+sMfcpfBRPK+rb+E1q7zg==
-
-"@esbuild/android-x64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.18.tgz#6e8a7b41fc80265849e0a1de928fe162b27990c7"
- integrity sha512-r7/pVcrUQMYkjvtE/1/n6BxhWM+/9tvLxDG1ev1ce4z3YsqoxMK9bbOM6bFcj0BowMeGQvOZWcBV182lFFKmrw==
-
"@esbuild/darwin-arm64@0.18.18":
version "0.18.18"
resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.18.tgz"
integrity sha512-MSe2iV9MAH3wfP0g+vzN9bp36rtPPuCSk+bT5E2vv/d8krvW5uB/Pi/Q5+txUZuxsG3GcO8dhygjnFq0wJU9hQ==
-"@esbuild/darwin-x64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.18.tgz#8aa691d0cbd3fb67f9f9083375c0c72e0463b8b2"
- integrity sha512-ARFYISOWkaifjcr48YtO70gcDNeOf1H2RnmOj6ip3xHIj66f3dAbhcd5Nph5np6oHI7DhHIcr9MWO18RvUL1bw==
-
-"@esbuild/freebsd-arm64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.18.tgz#0aafde382df508d7863360950d5f491c07024806"
- integrity sha512-BHnXmexzEWRU2ZySJosU0Ts0NRnJnNrMB6t4EiIaOSel73I8iLsNiTPLH0rJulAh19cYZutsB5XHK6N8fi5eMg==
-
-"@esbuild/freebsd-x64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.18.tgz#f00e54a3b65824ac3c749173bec9cd56d95fe73b"
- integrity sha512-n823w35wm0ZOobbuE//0sJjuz1Qj619+AwjgOcAJMN2pomZhH9BONCtn+KlfrmM/NWZ+27yB/eGVFzUIWLeh3w==
-
-"@esbuild/linux-arm64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.18.tgz#e04203429670257126a1bfee79bbd56448b24f5e"
- integrity sha512-zANxnwF0sCinDcAqoMohGoWBK9QaFJ65Vgh0ZE+RXtURaMwx+RfmfLElqtnn7X8OYNckMoIXSg7u+tZ3tqTlrA==
-
-"@esbuild/linux-arm@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.18.tgz#863236dc47df2269f860001ca5c5ff50931e9933"
- integrity sha512-Kck3jxPLQU4VeAGwe8Q4NU+IWIx+suULYOFUI9T0C2J1+UQlOHJ08ITN+MaJJ+2youzJOmKmcphH/t3SJxQ1Tw==
-
-"@esbuild/linux-ia32@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.18.tgz#9ef6c7eeb8c86c5c1b7234a9684c6f45cbc2ed57"
- integrity sha512-+VHz2sIRlY5u8IlaLJpdf5TL2kM76yx186pW7bpTB+vLWpzcFQVP04L842ZB2Ty13A1VXUvy3DbU1jV65P2skg==
-
-"@esbuild/linux-loong64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.18.tgz#dca8624674924ac92c9e56399af160479283f130"
- integrity sha512-fXPEPdeGBvguo/1+Na8OIWz3667BN1cwbGtTEZWTd0qdyTsk5gGf9jVX8MblElbDb/Cpw6y5JiaQuL96YmvBwQ==
-
-"@esbuild/linux-mips64el@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.18.tgz#e6525b60ae9d8c3bdc652a773e6ebf66caa3fdd3"
- integrity sha512-dLvRB87pIBIRnEIC32LIcgwK1JzlIuADIRjLKdUIpxauKwMuS/xMpN+cFl+0nN4RHNYOZ57DmXFFmQAcdlFOmw==
-
-"@esbuild/linux-ppc64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.18.tgz#2ea6a4e0c6b0db21770d2c3c1525623dceadfe46"
- integrity sha512-fRChqIJZ7hLkXSKfBLYgsX9Ssb5OGCjk3dzCETF5QSS1qjTgayLv0ALUdJDB9QOh/nbWwp+qfLZU6md4XcjL7w==
-
-"@esbuild/linux-riscv64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.18.tgz#296c25d5bdeb3bab9ca79ad5279a8cc0a42fbeea"
- integrity sha512-ALK/BT3u7Hoa/vHjow6W6+MKF0ohYcVcVA1EpskI4bkBPVuDLrUDqt2YFifg5UcZc8qup0CwQqWmFUd6VMNgaA==
-
-"@esbuild/linux-s390x@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.18.tgz#bec4e9c982e778c51deaa754e1ed3f0546705647"
- integrity sha512-crT7jtOXd9iirY65B+mJQ6W0HWdNy8dtkZqKGWNcBnunpLcTCfne5y5bKic9bhyYzKpQEsO+C/VBPD8iF0RhRw==
-
-"@esbuild/linux-x64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.18.tgz#22c9666920d3b7ef453289516ccff1c3ecbfdddd"
- integrity sha512-/NSgghjBOW9ELqjXDYxOCCIsvQUZpvua1/6NdnA9Vnrp9UzEydyDdFXljUjMMS9p5KxMzbMO9frjHYGVHBfCHg==
-
-"@esbuild/netbsd-x64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.18.tgz#99b6125868c5ba8f0131bacc3f2bd05918245f45"
- integrity sha512-8Otf05Vx5sZjLLDulgr5QS5lsWXMplKZEyHMArH9/S4olLlhzmdhQBPhzhJTNwaL2FJNdWcUPNGAcoD5zDTfUA==
-
-"@esbuild/openbsd-x64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.18.tgz#c2685bdd1e5aa11be1e212db371f474812a9b158"
- integrity sha512-tFiFF4kT5L5qhVrWJUNxEXWvvX8nK/UX9ZrB7apuTwY3f6+Xy4aFMBPwAVrBYtBd5MOUuyOVHK6HBZCAHkwUlw==
-
-"@esbuild/sunos-x64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.18.tgz#277b2f5727119fe3004e673eb9f6ead0b4ff0738"
- integrity sha512-MPogVV8Bzh8os4OM+YDGGsSzCzmNRiyKGtHoJyZLtI4BMmd6EcxmGlcEGK1uM46h1BiOyi7Z7teUtzzQhvkC+w==
-
-"@esbuild/win32-arm64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.18.tgz#e94d9e6d058e0ccb92d858badd4a6aa74772150e"
- integrity sha512-YKD6LF/XXY9REu+ZL5RAsusiG48n602qxsMVh/E8FFD9hp4OyTQaL9fpE1ovxwQXqFio+tT0ITUGjDSSSPN13w==
-
-"@esbuild/win32-ia32@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.18.tgz#454916b1d0b85d2f82252192ae7bd5ea65c98ea1"
- integrity sha512-NjSBmBsyZBTsZB6ga6rA6PfG/RHnwruUz/9YEVXcm4STGauFWvhYhOMhEyw1yU5NVgYYm8CH5AltCm77TS21/Q==
-
-"@esbuild/win32-x64@0.18.18":
- version "0.18.18"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.18.tgz#914c007ab1dbd28ca84e79ee666adeee6ccf92b4"
- integrity sha512-eTSg/gC3p3tdjj4roDhe5xu94l1s2jMazP8u2FsYO8SEKvSpPOO71EucprDn/IuErDPvTFUhV9lTw5z5WJCRKQ==
-
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
version "4.4.0"
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
@@ -506,16 +401,29 @@
resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz"
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
-"@jridgewell/sourcemap-codec@1.4.14":
- version "1.4.14"
- resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz"
- integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
+"@jridgewell/source-map@^0.3.3":
+ version "0.3.5"
+ resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz"
+ integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.3.0"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@jridgewell/sourcemap-codec@^1.4.10":
+ version "1.4.15"
+ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
+ integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
-"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.15":
+"@jridgewell/sourcemap-codec@^1.4.15":
version "1.4.15"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
+"@jridgewell/sourcemap-codec@1.4.14":
+ version "1.4.14"
+ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz"
+ integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
+
"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9":
version "0.3.18"
resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz"
@@ -532,7 +440,7 @@
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
-"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
+"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
version "2.0.5"
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
@@ -550,7 +458,7 @@
resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz"
integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==
-"@octokit/core@^4.2.1":
+"@octokit/core@^4.2.1", "@octokit/core@>=3", "@octokit/core@>=4":
version "4.2.4"
resolved "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz"
integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==
@@ -776,7 +684,23 @@
dependencies:
"@tanstack/query-core" "5.17.19"
-"@types/estree@^1.0.0":
+"@types/eslint-scope@^3.7.3":
+ version "3.7.7"
+ resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz"
+ integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==
+ dependencies:
+ "@types/eslint" "*"
+ "@types/estree" "*"
+
+"@types/eslint@*":
+ version "8.44.9"
+ resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.9.tgz"
+ integrity sha512-6yBxcvwnnYoYT1Uk2d+jvIfsuP4mb2EdIxFnrPABj5a/838qe5bGkNLFOiipX4ULQ7XVQvTxOh7jO+BTAiqsEw==
+ dependencies:
+ "@types/estree" "*"
+ "@types/json-schema" "*"
+
+"@types/estree@*", "@types/estree@^1.0.0":
version "1.0.1"
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz"
integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==
@@ -786,7 +710,7 @@
resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz"
integrity sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==
-"@types/json-schema@^7.0.12":
+"@types/json-schema@*", "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.8":
version "7.0.12"
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz"
integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
@@ -796,7 +720,7 @@
resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
-"@types/node@^20.10.6":
+"@types/node@*", "@types/node@^20.10.6", "@types/node@>= 14":
version "20.10.6"
resolved "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz"
integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==
@@ -820,7 +744,7 @@
dependencies:
"@types/react" "*"
-"@types/react@*", "@types/react@^18.2.15":
+"@types/react@*", "@types/react@^18.2.15", "@types/react@>=16.8":
version "18.2.18"
resolved "https://registry.npmjs.org/@types/react/-/react-18.2.18.tgz"
integrity sha512-da4NTSeBv/P34xoZPhtcLkmZuJ+oYaCxHmyHzwaDQo9RQPBeXV+06gEk2FpqEcsX9XrnNLvRpVh6bdavDSjtiQ==
@@ -857,7 +781,7 @@
semver "^7.5.4"
ts-api-utils "^1.0.1"
-"@typescript-eslint/parser@^6.0.0":
+"@typescript-eslint/parser@^6.0.0", "@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha":
version "6.2.1"
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz"
integrity sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==
@@ -940,22 +864,163 @@
"@babel/plugin-transform-react-jsx-source" "^7.22.5"
react-refresh "^0.14.0"
+"@webassemblyjs/ast@^1.11.5", "@webassemblyjs/ast@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz"
+ integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==
+ dependencies:
+ "@webassemblyjs/helper-numbers" "1.11.6"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.6"
+
+"@webassemblyjs/floating-point-hex-parser@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz"
+ integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==
+
+"@webassemblyjs/helper-api-error@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz"
+ integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==
+
+"@webassemblyjs/helper-buffer@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz"
+ integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==
+
+"@webassemblyjs/helper-numbers@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz"
+ integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==
+ dependencies:
+ "@webassemblyjs/floating-point-hex-parser" "1.11.6"
+ "@webassemblyjs/helper-api-error" "1.11.6"
+ "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/helper-wasm-bytecode@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz"
+ integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==
+
+"@webassemblyjs/helper-wasm-section@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz"
+ integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.6"
+ "@webassemblyjs/helper-buffer" "1.11.6"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.6"
+ "@webassemblyjs/wasm-gen" "1.11.6"
+
+"@webassemblyjs/ieee754@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz"
+ integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==
+ dependencies:
+ "@xtuc/ieee754" "^1.2.0"
+
+"@webassemblyjs/leb128@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz"
+ integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==
+ dependencies:
+ "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/utf8@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz"
+ integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==
+
+"@webassemblyjs/wasm-edit@^1.11.5":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz"
+ integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.6"
+ "@webassemblyjs/helper-buffer" "1.11.6"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.6"
+ "@webassemblyjs/helper-wasm-section" "1.11.6"
+ "@webassemblyjs/wasm-gen" "1.11.6"
+ "@webassemblyjs/wasm-opt" "1.11.6"
+ "@webassemblyjs/wasm-parser" "1.11.6"
+ "@webassemblyjs/wast-printer" "1.11.6"
+
+"@webassemblyjs/wasm-gen@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz"
+ integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.6"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.6"
+ "@webassemblyjs/ieee754" "1.11.6"
+ "@webassemblyjs/leb128" "1.11.6"
+ "@webassemblyjs/utf8" "1.11.6"
+
+"@webassemblyjs/wasm-opt@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz"
+ integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.6"
+ "@webassemblyjs/helper-buffer" "1.11.6"
+ "@webassemblyjs/wasm-gen" "1.11.6"
+ "@webassemblyjs/wasm-parser" "1.11.6"
+
+"@webassemblyjs/wasm-parser@^1.11.5", "@webassemblyjs/wasm-parser@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz"
+ integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.6"
+ "@webassemblyjs/helper-api-error" "1.11.6"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.6"
+ "@webassemblyjs/ieee754" "1.11.6"
+ "@webassemblyjs/leb128" "1.11.6"
+ "@webassemblyjs/utf8" "1.11.6"
+
+"@webassemblyjs/wast-printer@1.11.6":
+ version "1.11.6"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz"
+ integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.6"
+ "@xtuc/long" "4.2.2"
+
"@xobotyi/scrollbar-width@^1.9.5":
version "1.9.5"
resolved "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz"
integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==
+"@xtuc/ieee754@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz"
+ integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
+
+"@xtuc/long@4.2.2":
+ version "4.2.2"
+ resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz"
+ integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
+
+acorn-import-assertions@^1.9.0:
+ version "1.9.0"
+ resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz"
+ integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==
+
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
-acorn@^8.9.0:
+"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0:
version "8.10.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz"
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
-ajv@^6.12.4:
+ajv-keywords@^3.5.2:
+ version "3.5.2"
+ resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz"
+ integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
+
+ajv@^6.12.4, ajv@^6.12.5, ajv@^6.9.1:
version "6.12.6"
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@@ -1120,7 +1185,7 @@ braces@^3.0.2:
dependencies:
fill-range "^7.0.1"
-browserslist@^4.21.9:
+browserslist@^4.14.5, browserslist@^4.21.9, "browserslist@>= 4.21.0":
version "4.21.10"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz"
integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==
@@ -1130,6 +1195,11 @@ browserslist@^4.21.9:
node-releases "^2.0.13"
update-browserslist-db "^1.0.11"
+buffer-from@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
+ integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+
call-bind@^1.0.0, call-bind@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz"
@@ -1170,6 +1240,11 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
+chrome-trace-event@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz"
+ integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
+
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
@@ -1184,16 +1259,16 @@ color-convert@^2.0.1:
dependencies:
color-name "~1.1.4"
-color-name@1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
- integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
-
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+color-name@1.1.3:
+ version "1.1.3"
+ resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
+ integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
+
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
@@ -1201,15 +1276,20 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
+commander@^2.20.0:
+ version "2.20.3"
+ resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
+ integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
-concept-be-design-system@^0.4.1:
- version "0.4.1"
- resolved "https://registry.npmjs.org/concept-be-design-system/-/concept-be-design-system-0.4.1.tgz"
- integrity sha512-194MNlf3ZNWVvLsqclpwYOiFV7q2kIBiwpE1rXxqA75VmnCXBZTPafDsnAR9SNFGx5cdZXkcpJOz1/ZZuIXVEQ==
+concept-be-design-system@^0.4.3:
+ version "0.4.3"
+ resolved "https://registry.npmjs.org/concept-be-design-system/-/concept-be-design-system-0.4.3.tgz"
+ integrity sha512-33G/XWi2dQUCJwRqXfjilCOV1HDqXZCMMbgEuJ1W7+yS26ttiUd9+x0CnLunEeEf09TNmLnTUL9tKT5m7GJRwg==
dependencies:
"@emotion/react" "^11.11.1"
"@emotion/styled" "^11.11.0"
@@ -1358,6 +1438,14 @@ enhanced-resolve@^5.12.0:
graceful-fs "^4.2.4"
tapable "^2.2.0"
+enhanced-resolve@^5.15.0:
+ version "5.15.0"
+ resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz"
+ integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==
+ dependencies:
+ graceful-fs "^4.2.4"
+ tapable "^2.2.0"
+
entities@^4.4.0:
version "4.5.0"
resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
@@ -1422,6 +1510,11 @@ es-abstract@^1.22.1:
unbox-primitive "^1.0.2"
which-typed-array "^1.1.10"
+es-module-lexer@^1.2.1:
+ version "1.4.1"
+ resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz"
+ integrity sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==
+
es-set-tostringtag@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz"
@@ -1536,7 +1629,7 @@ eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0:
dependencies:
debug "^3.2.7"
-eslint-plugin-import@^2.28.1:
+eslint-plugin-import@*, eslint-plugin-import@^2.28.1, eslint-plugin-import@>=1.4.0:
version "2.28.1"
resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz"
integrity sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==
@@ -1577,12 +1670,20 @@ eslint-scope@^7.2.2:
esrecurse "^4.3.0"
estraverse "^5.2.0"
+eslint-scope@5.1.1:
+ version "5.1.1"
+ resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"
+ integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
+ dependencies:
+ esrecurse "^4.3.0"
+ estraverse "^4.1.1"
+
eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.2:
version "3.4.2"
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz"
integrity sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==
-eslint@^8.45.0:
+eslint@*, "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.45.0, eslint@>=7:
version "8.46.0"
resolved "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz"
integrity sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==
@@ -1648,6 +1749,11 @@ esrecurse@^4.3.0:
dependencies:
estraverse "^5.2.0"
+estraverse@^4.1.1:
+ version "4.3.0"
+ resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
+ integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
+
estraverse@^5.1.0, estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
@@ -1663,6 +1769,11 @@ esutils@^2.0.2:
resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+events@^3.2.0:
+ version "3.3.0"
+ resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
+ integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
+
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
@@ -1846,6 +1957,11 @@ glob-parent@^6.0.2:
dependencies:
is-glob "^4.0.3"
+glob-to-regexp@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz"
+ integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
+
glob@^7.1.3:
version "7.2.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
@@ -1896,7 +2012,7 @@ gopd@^1.0.1:
dependencies:
get-intrinsic "^1.1.3"
-graceful-fs@^4.1.2, graceful-fs@^4.2.4:
+graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9:
version "4.2.11"
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
@@ -2157,6 +2273,15 @@ isexe@^2.0.0:
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+jest-worker@^27.4.5:
+ version "27.5.1"
+ resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz"
+ integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==
+ dependencies:
+ "@types/node" "*"
+ merge-stream "^2.0.0"
+ supports-color "^8.0.0"
+
js-cookie@^2.2.1:
version "2.2.1"
resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz"
@@ -2179,7 +2304,7 @@ jsesc@^2.5.1:
resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
-json-parse-even-better-errors@^2.3.0:
+json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
@@ -2219,6 +2344,11 @@ lines-and-columns@^1.1.6:
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
+loader-runner@^4.2.0:
+ version "4.3.0"
+ resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz"
+ integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
+
locate-path@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz"
@@ -2267,6 +2397,11 @@ memory-fs@^0.2.0:
resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz"
integrity sha512-+y4mDxU4rvXXu5UDSGCGNiesFmwCHuefGMoPCO1WYucNYj7DsLqrFaa2fXVI0H+NNiPTwwzKwspn9yTZqUGqng==
+merge-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
+ integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
+
merge2@^1.3.0, merge2@^1.4.1:
version "1.4.1"
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
@@ -2285,7 +2420,7 @@ mime-db@1.52.0:
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
-mime-types@^2.1.12:
+mime-types@^2.1.12, mime-types@^2.1.27:
version "2.1.35"
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
@@ -2304,7 +2439,7 @@ minimist@^1.2.0, minimist@^1.2.6:
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
-ms@2.1.2, ms@^2.1.1:
+ms@^2.1.1, ms@2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
@@ -2338,6 +2473,11 @@ natural-compare@^1.4.0:
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
+neo-async@^2.6.2:
+ version "2.6.2"
+ resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz"
+ integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
+
node-fetch@^2.6.7:
version "2.7.0"
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz"
@@ -2517,7 +2657,14 @@ queue-microtask@^1.2.2:
resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
-react-dom@^18.2.0:
+randombytes@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz"
+ integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
+ dependencies:
+ safe-buffer "^5.1.0"
+
+react-dom@*, react-dom@^18.2.0, react-dom@>=16.8:
version "18.2.0"
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
@@ -2575,7 +2722,7 @@ react-use@^17.5.0:
ts-easing "^0.2.0"
tslib "^2.1.0"
-react@^18.2.0:
+react@*, "react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, react@>=16.8, react@>=16.8.0:
version "18.2.0"
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
@@ -2641,7 +2788,7 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
-rollup@^3.25.2:
+rollup@^1.20.0||^2.0.0||^3.0.0, rollup@^3.25.2:
version "3.27.2"
resolved "https://registry.npmjs.org/rollup/-/rollup-3.27.2.tgz"
integrity sha512-YGwmHf7h2oUHkVBT248x0yt6vZkYQ3/rvE5iQuVBh3WO8GcJ6BNeOkpoX1yMHIiBm18EMLjBPIoUDkhgnyxGOQ==
@@ -2672,6 +2819,11 @@ safe-array-concat@^1.0.0:
has-symbols "^1.0.3"
isarray "^2.0.5"
+safe-buffer@^5.1.0:
+ version "5.2.1"
+ resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
safe-regex-test@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz"
@@ -2688,6 +2840,15 @@ scheduler@^0.23.0:
dependencies:
loose-envify "^1.1.0"
+schema-utils@^3.1.1, schema-utils@^3.2.0:
+ version "3.3.0"
+ resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz"
+ integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==
+ dependencies:
+ "@types/json-schema" "^7.0.8"
+ ajv "^6.12.5"
+ ajv-keywords "^3.5.2"
+
screenfull@^5.1.0:
version "5.2.0"
resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz"
@@ -2710,6 +2871,13 @@ semver@^7.5.4:
dependencies:
lru-cache "^6.0.0"
+serialize-javascript@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz"
+ integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==
+ dependencies:
+ randombytes "^2.1.0"
+
set-harmonic-interval@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz"
@@ -2746,21 +2914,34 @@ source-map-js@^1.0.2:
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
-source-map@0.5.6:
- version "0.5.6"
- resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz"
- integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==
+source-map-support@~0.5.20:
+ version "0.5.21"
+ resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz"
+ integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
source-map@^0.5.7:
version "0.5.7"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
+source-map@^0.6.0:
+ version "0.6.1"
+ resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+source-map@0.5.6:
+ version "0.5.6"
+ resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz"
+ integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==
+
stack-generator@^2.0.5:
version "2.0.10"
resolved "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz"
@@ -2834,16 +3015,16 @@ strip-json-comments@^3.1.1:
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
-stylis@4.2.0:
- version "4.2.0"
- resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz"
- integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==
-
stylis@^4.3.0:
version "4.3.1"
resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz"
integrity sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==
+stylis@4.2.0:
+ version "4.2.0"
+ resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz"
+ integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==
+
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
@@ -2858,6 +3039,13 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
+supports-color@^8.0.0:
+ version "8.1.1"
+ resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz"
+ integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
+ dependencies:
+ has-flag "^4.0.0"
+
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
@@ -2873,11 +3061,32 @@ tapable@^0.1.8:
resolved "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz"
integrity sha512-jX8Et4hHg57mug1/079yitEKWGB3LCwoxByLsNim89LABq8NqgiX+6iYVOsq0vX8uJHkU+DZ5fnq95f800bEsQ==
-tapable@^2.2.0:
+tapable@^2.1.1, tapable@^2.2.0:
version "2.2.1"
resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
+terser-webpack-plugin@^5.3.7:
+ version "5.3.9"
+ resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz"
+ integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==
+ dependencies:
+ "@jridgewell/trace-mapping" "^0.3.17"
+ jest-worker "^27.4.5"
+ schema-utils "^3.1.1"
+ serialize-javascript "^6.0.1"
+ terser "^5.16.8"
+
+terser@^5.16.8, terser@^5.4.0:
+ version "5.26.0"
+ resolved "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz"
+ integrity sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==
+ dependencies:
+ "@jridgewell/source-map" "^0.3.3"
+ acorn "^8.8.2"
+ commander "^2.20.0"
+ source-map-support "~0.5.20"
+
text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
@@ -2930,7 +3139,7 @@ tsconfig-paths@^3.14.2:
minimist "^1.2.6"
strip-bom "^3.0.0"
-tslib@^2.1.0:
+tslib@*, tslib@^2.1.0:
version "2.6.2"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
@@ -2986,7 +3195,7 @@ typed-array-length@^1.0.4:
for-each "^0.3.3"
is-typed-array "^1.1.9"
-typescript@^5.0.2:
+typescript@^5.0.2, typescript@>=4.2.0, typescript@>=4.9.5:
version "5.1.6"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz"
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
@@ -3050,7 +3259,7 @@ vite-plugin-svgr@^3.2.0:
"@svgr/core" "^7.0.0"
"@svgr/plugin-jsx" "^7.0.0"
-vite@^4.4.5:
+"vite@^2.6.0 || 3 || 4", "vite@^3.0.0 || ^4.0.0", vite@^4.2.0, vite@^4.4.5, vite@>=3:
version "4.4.8"
resolved "https://registry.npmjs.org/vite/-/vite-4.4.8.tgz"
integrity sha512-LONawOUUjxQridNWGQlNizfKH89qPigK36XhMI7COMGztz8KNY0JHim7/xDd71CZwGT4HtSRgI7Hy+RlhG0Gvg==
@@ -3061,11 +3270,54 @@ vite@^4.4.5:
optionalDependencies:
fsevents "~2.3.2"
+watchpack@^2.4.0:
+ version "2.4.0"
+ resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz"
+ integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==
+ dependencies:
+ glob-to-regexp "^0.4.1"
+ graceful-fs "^4.1.2"
+
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz"
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
+webpack-sources@^3.2.3:
+ version "3.2.3"
+ resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz"
+ integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
+
+webpack@^5.1.0, webpack@>=1.11.0:
+ version "5.89.0"
+ resolved "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz"
+ integrity sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==
+ dependencies:
+ "@types/eslint-scope" "^3.7.3"
+ "@types/estree" "^1.0.0"
+ "@webassemblyjs/ast" "^1.11.5"
+ "@webassemblyjs/wasm-edit" "^1.11.5"
+ "@webassemblyjs/wasm-parser" "^1.11.5"
+ acorn "^8.7.1"
+ acorn-import-assertions "^1.9.0"
+ browserslist "^4.14.5"
+ chrome-trace-event "^1.0.2"
+ enhanced-resolve "^5.15.0"
+ es-module-lexer "^1.2.1"
+ eslint-scope "5.1.1"
+ events "^3.2.0"
+ glob-to-regexp "^0.4.1"
+ graceful-fs "^4.2.9"
+ json-parse-even-better-errors "^2.3.1"
+ loader-runner "^4.2.0"
+ mime-types "^2.1.27"
+ neo-async "^2.6.2"
+ schema-utils "^3.2.0"
+ tapable "^2.1.1"
+ terser-webpack-plugin "^5.3.7"
+ watchpack "^2.4.0"
+ webpack-sources "^3.2.3"
+
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz"