diff --git a/addIssueNumber.sh b/addIssueNumber.sh
new file mode 100755
index 00000000..fe0bcad1
--- /dev/null
+++ b/addIssueNumber.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+COMMIT_MSG_FILE=$1
+
+# 현재 브랜치 이름 가져오기
+branch_name=$(git rev-parse --abbrev-ref HEAD)
+
+# 브랜치 이름에서 마지막 숫자 추출
+issue_number=$(echo ${branch_name} | grep -o '[0-9]*$')
+
+# 커밋 메시지 파일의 첫 번째 줄 읽기
+first_line=$(head -n1 ${COMMIT_MSG_FILE})
+
+# 브랜치 이름에 숫자가 있는 경우에만 이슈 번호를 커밋 메시지 첫 번째 줄 끝에 추가
+if [ -n "$issue_number" ]; then
+ sed -i ".bak" "1s/\$/ (#$issue_number)/" ${COMMIT_MSG_FILE}
+fi
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 712cb832..6c44ae44 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -40,7 +40,8 @@
"typescript": "^4.9.5"
},
"devDependencies": {
- "@types/react-dom": "^18.2.18"
+ "@types/react-dom": "^18.2.18",
+ "husky": "4"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -6499,6 +6500,12 @@
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
},
+ "node_modules/compare-versions": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
+ "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
+ "dev": true
+ },
"node_modules/compressible": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@@ -8742,6 +8749,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/find-versions": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz",
+ "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==",
+ "dev": true,
+ "dependencies": {
+ "semver-regex": "^3.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/flat-cache": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
@@ -9649,6 +9671,124 @@
"node": ">=10.17.0"
}
},
+ "node_modules/husky": {
+ "version": "4.3.8",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz",
+ "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==",
+ "dev": true,
+ "hasInstallScript": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "ci-info": "^2.0.0",
+ "compare-versions": "^3.6.0",
+ "cosmiconfig": "^7.0.0",
+ "find-versions": "^4.0.0",
+ "opencollective-postinstall": "^2.0.2",
+ "pkg-dir": "^5.0.0",
+ "please-upgrade-node": "^3.2.0",
+ "slash": "^3.0.0",
+ "which-pm-runs": "^1.0.0"
+ },
+ "bin": {
+ "husky-run": "bin/run.js",
+ "husky-upgrade": "lib/upgrader/bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/husky"
+ }
+ },
+ "node_modules/husky/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/husky/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/husky/node_modules/ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "node_modules/husky/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/husky/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/husky/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/husky/node_modules/pkg-dir": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz",
+ "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/husky/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/hyphenate-style-name": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
@@ -13317,6 +13457,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/opencollective-postinstall": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
+ "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
+ "dev": true,
+ "bin": {
+ "opencollective-postinstall": "index.js"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
@@ -13668,6 +13817,15 @@
"node": ">=4"
}
},
+ "node_modules/please-upgrade-node": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+ "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+ "dev": true,
+ "dependencies": {
+ "semver-compare": "^1.0.0"
+ }
+ },
"node_modules/postcss": {
"version": "8.4.32",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
@@ -16115,6 +16273,24 @@
"node": ">=10"
}
},
+ "node_modules/semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
+ "dev": true
+ },
+ "node_modules/semver-regex": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz",
+ "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/semver/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -18443,6 +18619,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/which-pm-runs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz",
+ "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/which-typed-array": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz",
diff --git a/package.json b/package.json
index fb85a926..828bc74f 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,11 @@
"test": "react-scripts test",
"eject": "react-scripts eject"
},
+ "husky": {
+ "hooks": {
+ "prepare-commit-msg": "./addIssueNumber.sh $HUSKY_GIT_PARAMS"
+ }
+ },
"eslintConfig": {
"extends": [
"react-app",
@@ -59,6 +64,7 @@
]
},
"devDependencies": {
- "@types/react-dom": "^18.2.18"
+ "@types/react-dom": "^18.2.18",
+ "husky": "4"
}
}
diff --git a/public/index.html b/public/index.html
index 6582a0d7..3b706977 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,6 +1,22 @@
+
+
+
{
const navigate = useNavigate();
+ useViewResize();
+
//
//
//
diff --git a/src/api/delete.ts b/src/api/delete.ts
index 2f6adbcb..ddd29c18 100644
--- a/src/api/delete.ts
+++ b/src/api/delete.ts
@@ -1,3 +1,4 @@
+import { axiosDelete } from './axios';
import { deleteInstance } from './axios.deprecated';
//Auth Controller
@@ -11,9 +12,12 @@ export const deleteSearchWords = async (body: any) =>
//WishList Controller
//검색 결과 반환
-export const deleteWishLists = async (counselorId: number) =>
+export const deleteWishListsDeprecated = async (counselorId: number) =>
await deleteInstance(`/wishLists?counselorId=${counselorId}`);
+export const deleteWishLists = async (counselorId: number) =>
+ await axiosDelete(`/wishLists?counselorId=${counselorId}`);
+
// 일대다상담
// CommentLike Controller
export const deleteCommentLikes = async (commentId: any) =>
diff --git a/src/api/patch.ts b/src/api/patch.ts
index 60c51cc2..f113b1ef 100644
--- a/src/api/patch.ts
+++ b/src/api/patch.ts
@@ -1,3 +1,4 @@
+import { axiosPatch } from './axios';
import { patchInstance, patchPublicInstance } from './axios.deprecated';
//Admin Controller
//admin 미결제 상담 승인
@@ -81,9 +82,12 @@ export const patchSearchWordsPostsResults = async (
);
//Wishlist Controlloer
//찜하기 추가
-export const patchWishLists = async (counselorId: number) =>
+export const patchWishListsDeprecated = async (counselorId: number) =>
await patchInstance(`/wishLists?counselorId=${counselorId}`);
+export const patchWishLists = async (counselorId: number) =>
+ await axiosPatch(`/wishLists?counselorId=${counselorId}`);
+
//일대다상담
//Comment Controller
diff --git a/src/components/Buyer/BuyerAvailCounselor/AvailCounselorSearchResult.tsx b/src/components/Buyer/BuyerAvailCounselor/AvailCounselorSearchResult.tsx
index aa8b60c5..049718c4 100644
--- a/src/components/Buyer/BuyerAvailCounselor/AvailCounselorSearchResult.tsx
+++ b/src/components/Buyer/BuyerAvailCounselor/AvailCounselorSearchResult.tsx
@@ -1,8 +1,9 @@
-import { ReadyConsultCard } from '../Common/ReadyConsultCard';
import { SearchResultData } from 'utils/type';
import { AppendCategoryType } from 'utils/AppendCategoryType';
import { consultStyleToCharNum } from 'utils/convertStringToCharNum';
import { Flex } from 'components/Common/Flex';
+import CounselorCard from 'components/Common/CounselorCard';
+import EmptySection from 'components/Common/EmptySection';
//
//
@@ -19,16 +20,19 @@ interface AvailCounselorSearchResultsProps {
export const AvailCounselorSearchResults = ({
searchData,
}: AvailCounselorSearchResultsProps) => {
+ if (searchData.length === 0) {
+ return ;
+ }
+
return (
- {searchData.map((value, index) => {
+ {searchData.map((value) => {
return (
-
);
})}
diff --git a/src/components/Buyer/BuyerCategoryResult/CategorySearchResult.tsx b/src/components/Buyer/BuyerCategoryResult/CategorySearchResult.tsx
index b97457bd..5fad0ada 100644
--- a/src/components/Buyer/BuyerCategoryResult/CategorySearchResult.tsx
+++ b/src/components/Buyer/BuyerCategoryResult/CategorySearchResult.tsx
@@ -1,9 +1,9 @@
-import styled from 'styled-components';
-import { ReadyConsultCard } from '../Common/ReadyConsultCard';
import { SearchResultData } from 'utils/type';
import { AppendCategoryType } from 'utils/AppendCategoryType';
import { consultStyleToCharNum } from 'utils/convertStringToCharNum';
import { Flex } from 'components/Common/Flex';
+import CounselorCard from 'components/Common/CounselorCard';
+import EmptySection from 'components/Common/EmptySection';
interface CategorySearchResultsProps {
searchData: SearchResultData[];
}
@@ -12,11 +12,15 @@ interface CategorySearchResultsProps {
export const CategorySearchResults = ({
searchData,
}: CategorySearchResultsProps) => {
+ if (searchData.length === 0) {
+ return ;
+ }
+
return (
{searchData.map((value) => {
return (
-
);
})}
diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorFooter.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorFooter.tsx
index ce616332..504fbfad 100644
--- a/src/components/Buyer/BuyerCounselorProfile/CounselorFooter.tsx
+++ b/src/components/Buyer/BuyerCounselorProfile/CounselorFooter.tsx
@@ -5,8 +5,8 @@ import { Button } from 'components/Common/Button';
import { useState } from 'react';
import { White } from 'styles/color';
import { useNavigate } from 'react-router-dom';
-import { patchWishLists } from 'api/patch';
-import { deleteWishLists } from 'api/delete';
+import { patchWishListsDeprecated } from 'api/patch';
+import { deleteWishListsDeprecated } from 'api/delete';
import { APP_WIDTH } from 'styles/AppStyle';
import { Flex } from 'components/Common/Flex';
@@ -45,7 +45,7 @@ export const CounselorFooter = ({
}
try {
setIsSending(true);
- const res: any = await patchWishLists(counselorId);
+ const res: any = await patchWishListsDeprecated(counselorId);
if (res.response?.status === 400) {
alert('이미 찜하기 처리된 상담사입니다.');
} else if (res.response?.status === 404) {
@@ -68,7 +68,7 @@ export const CounselorFooter = ({
}
try {
setIsSending(true);
- const res: any = await deleteWishLists(counselorId);
+ const res: any = await deleteWishListsDeprecated(counselorId);
if (res.response?.status === 400) {
alert('이미 찜하기 취소된 상담사입니다.');
} else if (res.response?.status === 404) {
diff --git a/src/components/Buyer/BuyerHome/HomeConsultInReady.tsx b/src/components/Buyer/BuyerHome/HomeConsultInReady.tsx
index 3a27cf89..12ab6500 100644
--- a/src/components/Buyer/BuyerHome/HomeConsultInReady.tsx
+++ b/src/components/Buyer/BuyerHome/HomeConsultInReady.tsx
@@ -1,7 +1,6 @@
import styled from 'styled-components';
import { Caption2, Subtitle } from 'styles/font';
import { ReactComponent as More } from 'assets/icons/icon-more.svg';
-import { ReadyConsultCard } from '../Common/ReadyConsultCard';
import { useNavigate } from 'react-router-dom';
import { SearchResultData } from 'utils/type';
@@ -11,6 +10,7 @@ import { Green, Grey2 } from 'styles/color';
import { Space } from 'components/Common/Space';
import { getCurrentHour } from 'utils/getCurrentHour';
import { Flex } from 'components/Common/Flex';
+import CounselorCard from 'components/Common/CounselorCard';
///
///
///
@@ -51,7 +51,7 @@ export const HomeConsultInReady = ({ searchData }: HomeConsultInReadyProps) => {
>
{searchData.slice(0, 3).map((value) => {
return (
- {
value.consultStyle,
)}
consultStyle={consultStyleToCharNum(value.consultStyle)}
- consultTimes={value.consultTimes}
introduction={value.introduction}
nickname={value.nickname}
level={value.level}
isWishList={value.isWishList}
rating={value.ratingAverage}
totalReview={value.totalReview}
- consultType={value.consultTypes}
- letterPrice={value.consultCosts.편지}
- chattingPrice={value.consultCosts.채팅}
totalConsult={value.totalConsult}
+ isRealtime={value.isRealtime}
/>
);
})}
diff --git a/src/components/Buyer/BuyerSavedCounselor.tsx/SavedCounselorCard.tsx b/src/components/Buyer/BuyerSavedCounselor.tsx/SavedCounselorCard.tsx
deleted file mode 100644
index 09798e40..00000000
--- a/src/components/Buyer/BuyerSavedCounselor.tsx/SavedCounselorCard.tsx
+++ /dev/null
@@ -1,293 +0,0 @@
-import styled from 'styled-components';
-import { Grey1, Grey2, Grey3, Grey5, Grey6, White } from 'styles/color';
-import { TagA2Cartegory } from '../../Common/TagA2Cartegory';
-import { Body1, Body3, Caption2 } from 'styles/font';
-import { Characters } from 'utils/Characters';
-import { ReactComponent as HeartIcon } from 'assets/icons/icon-heart2.svg';
-import { ReactComponent as NoneBookMark } from 'assets/icons/icon-save1.svg';
-import { ReactComponent as BookMark } from 'assets/icons/icon-save2.svg';
-import { ReactComponent as DownIcon } from 'assets/icons/icon-down-toggle.svg';
-import { ReactComponent as UpIcon } from 'assets/icons/icon-up-toggle.svg';
-import { useState } from 'react';
-import { useNavigate } from 'react-router-dom';
-import { CartegoryState, ConsultTimes } from 'utils/type';
-import { convertTimeToString } from 'utils/convertTimeToString';
-import { deleteWishLists } from 'api/delete';
-
-//
-//
-//
-
-interface SavedCounselorCardProps {
- counselorId: number;
- tagList: CartegoryState[];
- consultTimes: ConsultTimes;
- introduction: string;
- nickname: string;
- level: number;
- wishlistId: number;
- rating: number;
- totalReview: number;
- consultType: string[];
- letterPrice: number;
- chattingPrice: number;
- consultStyle: number;
-}
-
-//
-//
-//
-
-export const SavedCounselorCard = ({
- counselorId,
- tagList,
- consultTimes,
- introduction,
- nickname,
- level,
- wishlistId,
- rating,
- totalReview,
- consultType,
- letterPrice,
- chattingPrice,
- consultStyle,
-}: SavedCounselorCardProps) => {
- const navigate = useNavigate();
- const [toggle, setToggle] = useState(false);
- const [isSending, setIsSending] = useState(false);
- const [isSaved, setIsSaved] = useState(true);
- const handleBookmark = async (
- e: React.MouseEvent | React.MouseEvent,
- ) => {
- e.stopPropagation();
- if (isSending) {
- return;
- }
- try {
- setIsSending(true);
- const res: any = await deleteWishLists(counselorId);
-
- if (res.status === 200) {
- // Handle success
- } else if (res.response?.status === 400) {
- alert('이미 찜하기 취소된 상담사입니다.');
- } else if (res.response?.status === 404) {
- alert('존재하지 않는 상담사입니다.');
- }
- } catch (error) {
- // Handle error
- console.error('Error:', error);
- } finally {
- setIsSending(false);
- setIsSaved(false);
- }
- };
- //
- //
- //
- if (isSaved) {
- return (
-
- {
- navigate(`/profile/${counselorId}`);
- }}
- >
-
- {tagList.map((value: CartegoryState) => {
- return (
-
- );
- })}
-
- {introduction}
-
- {
- navigate(`/profile/${counselorId}`);
- }}
- >
-
-
-
- {nickname}
- {'Lv. ' + level}
-
-
-
- {rating + ' (' + totalReview + ')'}
-
-
- {isSaved ? (
-
- ) : (
- ) => {
- e.stopPropagation();
- setIsSaved(true);
- }}
- />
- )}
-
- {toggle ? (
-
-
- 상담 방식
- {consultType.join(', ')}
-
-
-
상담 시간
-
- {consultTimes.MON !== undefined &&
- consultTimes.MON.length !== 0 ? (
-
- 월 {convertTimeToString(consultTimes.MON)}
-
- ) : null}
- {consultTimes.TUE !== undefined &&
- consultTimes.TUE.length !== 0 ? (
-
- 화 {convertTimeToString(consultTimes.TUE)}
-
- ) : null}
- {consultTimes.WED !== undefined &&
- consultTimes.WED.length !== 0 ? (
-
- 수 {convertTimeToString(consultTimes.WED)}
-
- ) : null}
- {consultTimes.THU !== undefined &&
- consultTimes.THU.length !== 0 ? (
-
- 목 {convertTimeToString(consultTimes.THU)}
-
- ) : null}
- {consultTimes.FRI !== undefined &&
- consultTimes.FRI.length !== 0 ? (
-
- 금 {convertTimeToString(consultTimes.FRI)}
-
- ) : null}
- {consultTimes.SAT !== undefined &&
- consultTimes.SAT.length !== 0 ? (
-
- 토 {convertTimeToString(consultTimes.SAT)}
-
- ) : null}
- {consultTimes.SUN !== undefined &&
- consultTimes.SUN.length !== 0 ? (
-
- 일 {convertTimeToString(consultTimes.SUN)}
-
- ) : null}
-
-
-
-
상담 금액
-
- {letterPrice !== undefined ? (
-
- 편지 1건 {letterPrice.toLocaleString()}원
-
- ) : null}
- {chattingPrice !== undefined ? (
-
- 채팅 30분당 {chattingPrice.toLocaleString()}원
-
- ) : null}
-
-
-
- ) : null}
- {
- setToggle(!toggle);
- }}
- >
- {toggle ? : }
-
-
- );
- } else {
- return <>>;
- }
-};
-const Wrapper = styled.div`
- width: 89%;
- border-radius: 0.8rem;
- margin-bottom: 0.9rem;
- background-color: ${Grey6};
-`;
-const UpperWrapper = styled.div`
- border-bottom: 1px solid ${White};
- cursor: pointer;
-`;
-const TagWrapper = styled.div`
- display: flex;
- margin-top: 1.6rem;
- gap: 0.8rem;
- margin-left: 1.6rem;
-`;
-const LowerWrapper = styled.div`
- height: 7.5rem;
- display: flex;
- gap: 0.8rem;
- position: relative;
- cursor: pointer;
- .row1 {
- display: flex;
- align-items: center;
- gap: 1.2rem;
- margin-top: 1.2rem;
- }
- .row2 {
- display: flex;
- align-items: center;
- gap: 0.6rem;
- }
-`;
-const BookMarkIcon = styled(BookMark)`
- position: absolute;
- right: 1.6rem;
- top: 1.2rem;
- cursor: pointer;
-`;
-const NoneBookMarkIcon = styled(NoneBookMark)`
- position: absolute;
- right: 1.6rem;
- top: 1.2rem;
- cursor: pointer;
-`;
-const ToggleWrapper = styled.div`
- padding: 1rem 2rem;
- .row1 {
- display: flex;
- gap: 6.1rem;
- }
- .row2 {
- margin-top: 0.8rem;
- display: flex;
- gap: 3.6rem;
- }
- .row3 {
- margin-top: 0.8rem;
- display: flex;
- gap: 7.6rem;
- }
-`;
-const ToggleBar = styled.div`
- height: 2.9rem;
- background-color: ${Grey5};
- border-bottom-left-radius: 0.8rem;
- border-bottom-right-radius: 0.8rem;
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
-`;
diff --git a/src/components/Buyer/BuyerSavedCounselor.tsx/SavedCounselorResults.tsx b/src/components/Buyer/BuyerSavedCounselor.tsx/SavedCounselorResults.tsx
index 0b22a918..7413814b 100644
--- a/src/components/Buyer/BuyerSavedCounselor.tsx/SavedCounselorResults.tsx
+++ b/src/components/Buyer/BuyerSavedCounselor.tsx/SavedCounselorResults.tsx
@@ -2,47 +2,55 @@ import styled from 'styled-components';
import { WishlistDataType } from 'utils/type';
import { AppendCategoryType } from 'utils/AppendCategoryType';
import { consultStyleToCharNum } from 'utils/convertStringToCharNum';
-import { SavedCounselorCard } from './SavedCounselorCard';
+import CounselorCard from 'components/Common/CounselorCard';
+
+//
+//
+//
+
interface SavedCounselorResultsProps {
wishlistData: WishlistDataType[];
}
-//임의로 ConsultInReady 그대로 사용
+//
+//
+//
+
export const SavedCounselorResults = ({
wishlistData,
}: SavedCounselorResultsProps) => {
return (
- {wishlistData.map((value, index) => {
+ {wishlistData.map((value) => {
return (
-
);
})}
);
};
+
const Wrapper = styled.div`
display: flex;
flex-direction: column;
+ gap: 0.8rem;
+ box-sizing: border-box;
+ padding: 0 2rem;
align-items: center;
width: 100%;
`;
diff --git a/src/components/Buyer/BuyerSearchResult/SearchResults.tsx b/src/components/Buyer/BuyerSearchResult/SearchResults.tsx
index df4e1dc8..62865db4 100644
--- a/src/components/Buyer/BuyerSearchResult/SearchResults.tsx
+++ b/src/components/Buyer/BuyerSearchResult/SearchResults.tsx
@@ -1,14 +1,21 @@
-import styled from 'styled-components';
-import { ReadyConsultCard } from '../Common/ReadyConsultCard';
import { SearchResultData } from 'utils/type';
import { AppendCategoryType } from 'utils/AppendCategoryType';
import { consultStyleToCharNum } from 'utils/convertStringToCharNum';
import { Flex } from 'components/Common/Flex';
+import CounselorCard from 'components/Common/CounselorCard';
+
+//
+//
+//
+
interface SearchResultsProps {
searchData: SearchResultData[];
}
-//임의로 ConsultInReady 그대로 사용
+//
+//
+//
+
export const SearchResults = ({ searchData }: SearchResultsProps) => {
return (
{
>
{searchData.map((value) => {
return (
- {
value.consultStyle,
)}
consultStyle={consultStyleToCharNum(value.consultStyle)}
- consultTimes={value.consultTimes}
introduction={value.introduction}
nickname={value.nickname}
level={value.level}
isWishList={value.isWishList}
rating={value.ratingAverage}
totalReview={value.totalReview}
- consultType={value.consultTypes}
- letterPrice={value.consultCosts.편지}
- chattingPrice={value.consultCosts.채팅}
totalConsult={value.totalConsult}
+ isRealtime={value.isRealtime}
/>
);
})}
diff --git a/src/components/Buyer/Common/ReadyConsultCard.tsx b/src/components/Buyer/Common/ReadyConsultCard.tsx
deleted file mode 100644
index b599fa99..00000000
--- a/src/components/Buyer/Common/ReadyConsultCard.tsx
+++ /dev/null
@@ -1,233 +0,0 @@
-import styled from 'styled-components';
-import { Green, Grey2, Grey3, Grey6, White } from 'styles/color';
-import { TagA2Cartegory } from '../../Common/TagA2Cartegory';
-import { Body1, Body3, Caption2 } from 'styles/font';
-import { Characters } from 'utils/Characters';
-import { ReactComponent as HeartIcon } from 'assets/icons/icon-heart2.svg';
-import { ReactComponent as NoneBookMark } from 'assets/icons/icon-save1.svg';
-import { ReactComponent as BookMark } from 'assets/icons/icon-save2.svg';
-import { useState } from 'react';
-import { useNavigate } from 'react-router-dom';
-import { CartegoryState, ConsultTimes } from 'utils/type';
-import { deleteWishLists } from 'api/delete';
-import { patchWishLists } from 'api/patch';
-import { Space } from 'components/Common/Space';
-import { Button } from 'components/Common/Button';
-
-//
-//
-//
-
-interface ReadyConsultCardProps {
- counselorId: number;
- tagList: CartegoryState[];
- consultTimes: ConsultTimes;
- introduction: string;
- nickname: string;
- level: number;
- isWishList: boolean;
- rating: number;
- totalReview: number;
- consultType: string[];
- letterPrice: number;
- chattingPrice: number;
- consultStyle: number | undefined;
- totalConsult: number;
-}
-
-//
-//
-//
-
-export const ReadyConsultCard = ({
- counselorId,
- tagList,
- consultTimes,
- introduction,
- nickname,
- level,
- isWishList,
- rating,
- totalReview,
- consultType,
- letterPrice,
- chattingPrice,
- consultStyle,
- totalConsult,
-}: ReadyConsultCardProps) => {
- const navigate = useNavigate();
- //찜하기 여부
- const [isSaved, setIsSaved] = useState(isWishList);
- //보내는 동안 중복 클릭 방지
- const [isSending, setIsSending] = useState(false);
- //찜하기 업데이트
- const handleBookmark = async (e: React.MouseEvent) => {
- e.stopPropagation();
- if (isSending) {
- return;
- }
- try {
- setIsSending(true);
- const res: any = await patchWishLists(counselorId);
- if (res.response?.status === 400) {
- alert('이미 찜하기 처리된 상담사입니다.');
- } else if (res.response?.status === 404) {
- alert('존재하지 않는 상담사입니다.');
- }
- } catch (error) {
- console.error('Error:', error);
- } finally {
- setIsSending(false);
- setIsSaved(true);
- }
- };
- const handleUnBookmark = async (e: React.MouseEvent) => {
- e.stopPropagation();
- if (isSending) {
- return;
- }
- try {
- setIsSending(true);
- const res: any = await deleteWishLists(counselorId);
- if (res.response?.status === 400) {
- alert('이미 찜하기 취소된 상담사입니다.');
- } else if (res.response?.status === 404) {
- alert('존재하지 않는 상담사입니다.');
- }
- } catch (error) {
- console.error('Error:', error);
- } finally {
- setIsSending(false);
- setIsSaved(false);
- }
- };
-
- //
- //
- //
-
- return (
-
-
- {introduction}
-
-
- {tagList.map((value: any) => {
- return (
-
- );
- })}
-
-
- {
- navigate(`/profile/${counselorId}`);
- }}
- >
-
-
-
-
-
-
- {nickname}
- {'LV. ' + level}
-
-
-
상담 {totalConsult}회
-
-
후기 {totalReview}회
-
-
-
- {rating}
-
-
-
-
-
-
-
- );
-};
-
-//
-//
-//
-
-const Wrapper = styled.div`
- width: 100%;
- border-radius: 0.8rem;
- background-color: ${Grey6};
-`;
-const UpperWrapper = styled.div`
- border-bottom: 1px solid ${White};
- background: linear-gradient(90deg, #2dc7bd 0%, #ecfaf9 100%);
- padding: 1.4rem 2rem 1.2rem 1.6rem;
- border-radius: 0.8rem 0.8rem 0 0;
-`;
-const TagWrapper = styled.div`
- display: flex;
- gap: 0.8rem;
-`;
-const LowerWrapper = styled.div`
- padding: 1.5rem 2rem;
- gap: 0.8rem;
- position: relative;
- .row1 {
- display: flex;
- align-items: center;
- gap: 1.2rem;
- }
- .character-circle {
- border-radius: 100%;
- background-color: white;
- width: 4.5rem;
- height: 4.1rem;
- }
- .row2 {
- display: flex;
- align-items: center;
- gap: 0.8rem;
- }
- .row2 .heart {
- display: flex;
- align-items: center;
- gap: 0.2rem;
- }
-`;
-const BookMarkIcon = styled(BookMark)`
- position: absolute;
- top: 3rem;
- right: 2rem;
- cursor: pointer;
-`;
-const NoneBookMarkIcon = styled(NoneBookMark)`
- position: absolute;
- top: 3rem;
- right: 2rem;
- cursor: pointer;
-`;
-
-const DivideLine = styled.div`
- width: 0.1rem;
- height: 1.5rem;
- background: #bbb;
-`;
diff --git a/src/components/Common/AppContainer.tsx b/src/components/Common/AppContainer.tsx
index dd7a1289..b5361aa2 100644
--- a/src/components/Common/AppContainer.tsx
+++ b/src/components/Common/AppContainer.tsx
@@ -1,4 +1,3 @@
-import { useViewResize } from 'hooks/useViewResize';
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { useLocation } from 'react-router-dom';
@@ -20,7 +19,6 @@ interface AppContainerProps {
//
export const AppContainer = ({ children }: AppContainerProps) => {
- useViewResize();
const scrollLock = useRecoilValue(scrollLockState);
var { pathname, search } = useLocation();
@@ -78,6 +76,7 @@ const StyledApp = styled.div<{ $isGray: boolean; $scrollLock: boolean }>`
@media (max-width: 767px) {
width: 100vw;
}
+
background-color: ${(props) => (props.$isGray ? Grey6 : White)};
overflow-y: ${(props) => (props.$scrollLock ? 'hidden' : 'scroll')};
box-shadow: 0 0 1rem 0 rgba(0, 0, 0, 0.1);
diff --git a/src/components/Common/CounselorCard.tsx b/src/components/Common/CounselorCard.tsx
new file mode 100644
index 00000000..902ea12f
--- /dev/null
+++ b/src/components/Common/CounselorCard.tsx
@@ -0,0 +1,306 @@
+import styled, { CSSProperties } from 'styled-components';
+import { Green, Grey1, Grey2, Grey6, Red, White } from 'styles/color';
+import { Body1, Body3, Caption2 } from 'styles/font';
+import { Characters } from 'utils/Characters';
+import { CartegoryState } from 'utils/type';
+import { Flex } from './Flex';
+import { ReactComponent as HeartIcon } from 'assets/open-consult/open-consult-heart.svg';
+import { Space } from './Space';
+import { TagA2Cartegory } from './TagA2Cartegory';
+import { Button } from './Button';
+import { useNavigate } from 'react-router-dom';
+
+import { ReactComponent as NoneBookMark } from 'assets/icons/icon-save1.svg';
+import { ReactComponent as BookMark } from 'assets/icons/icon-save2.svg';
+import { useState } from 'react';
+import { patchWishLists } from 'api/patch';
+import { useMutation } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+import { deleteWishLists } from 'api/delete';
+
+//
+//
+//
+
+interface CounselorCardProps {
+ counselorId: number;
+ tagList: CartegoryState[];
+ introduction: string;
+ nickname: string;
+ level: number;
+ isWishList: boolean;
+ rating: number;
+ totalReview: number;
+ totalConsult?: number;
+ isRealtime?: boolean;
+ consultStyle?: number;
+ isSavedCounselorPage?: boolean;
+}
+
+//
+//
+//
+
+const twoLineEllipsis: CSSProperties = {
+ display: '-webkit-box',
+ WebkitBoxOrient: 'vertical',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ WebkitLineClamp: 2,
+ lineClamp: 2,
+};
+
+//
+//
+//
+
+const PATCH_WISHLISTS_MUTATION_KEY = 'patchWishLists';
+
+const DELETE_WISHLISTS_MUTATION_KEY = 'deleteWishLists';
+
+//
+//
+//
+
+const CounselorCard = ({
+ counselorId,
+ tagList,
+ introduction,
+ nickname,
+ level,
+ isWishList,
+ rating,
+ totalReview,
+ consultStyle,
+ totalConsult,
+ isRealtime,
+ isSavedCounselorPage = false,
+}: CounselorCardProps) => {
+ const navigate = useNavigate();
+
+ const [isSaved, setIsSaved] = useState(isWishList);
+
+ const today = new Date();
+ const hours = today.getHours();
+
+ //
+ //
+ //
+ const { mutate: addWishListsMutate } = useMutation({
+ mutationKey: [PATCH_WISHLISTS_MUTATION_KEY],
+ mutationFn: (counselorId: number) => patchWishLists(counselorId),
+ onSuccess: () => {
+ setIsSaved(true);
+ },
+ onError: (error: AxiosError) => {
+ if (error.response?.status === 400) {
+ alert('이미 찜하기 처리된 상담사입니다.');
+ } else if (error.response?.status === 404) {
+ alert('존재하지 않는 상담사입니다.');
+ } else {
+ alert('찜하기 요청 도중 오류가 발생했습니다.');
+ }
+ },
+ });
+
+ //
+ //
+ //
+ const { mutate: deleteWishListsMutate } = useMutation({
+ mutationKey: [DELETE_WISHLISTS_MUTATION_KEY],
+ mutationFn: (counselorId: number) => deleteWishLists(counselorId),
+ onSuccess: () => {
+ setIsSaved(false);
+ },
+ onError: (error: AxiosError) => {
+ if (error.response?.status === 400) {
+ alert('이미 찜하기 취소된 상담사입니다.');
+ } else if (error.response?.status === 404) {
+ alert('존재하지 않는 상담사입니다.');
+ } else {
+ alert('찜하기 취소 요청 도중 오류가 발생했습니다.');
+ }
+ },
+ });
+
+ /**
+ *
+ */
+ const handleUnBookmark = () => {
+ deleteWishListsMutate(counselorId);
+ };
+
+ /**
+ *
+ */
+ const handleBookmark = () => {
+ addWishListsMutate(counselorId);
+ };
+
+ /**
+ *
+ */
+ const renderIntroSection = () => {
+ return (
+
+ {introduction}
+
+ );
+ };
+
+ /**
+ *
+ */
+ const renderInfoSection = () => {
+ return (
+
+ {isRealtime ? (
+
+ {`${hours}시 기준 실시간 상담 가능`}
+
+ ) : null}
+
+
+
+
+
+
+
+
+ {nickname}
+ {'LV. ' + level}
+
+
+ {/* TODO: TotalConsult is changed to optional, because get wishlist do not return total consult. It should be added later */}
+ {totalConsult ? (
+ <>
+ 상담 {totalConsult}회
+
+ >
+ ) : null}
+ 후기 {totalReview}개
+
+
+
+ {rating}
+
+
+
+
+
+ {tagList.map((value: any) => {
+ return (
+
+ );
+ })}
+
+
+
+
+ );
+ };
+
+ /**
+ *
+ */
+ const renderButtonSection = () => {
+ return (
+
+ {isSaved ? (
+
+ ) : (
+
+ )}
+
+ );
+ };
+
+ //
+ //
+ //
+
+ if (isSavedCounselorPage && !isSaved) {
+ return null;
+ }
+
+ return (
+
+ {renderIntroSection()}
+
+ {renderInfoSection()}
+
+ {renderButtonSection()}
+
+ );
+};
+
+//
+//
+//
+
+const Wrapper = styled.div`
+ width: 100%;
+ border-radius: 1rem;
+ box-sizing: border-box;
+ padding: 1.6rem 1.6rem 2rem 1.6rem;
+ background-color: ${Grey6};
+`;
+
+const InfoWrapper = styled.div<{ isRealtime?: boolean }>`
+ width: 100%;
+ background-color: ${White};
+ box-sizing: border-box;
+ padding: 1.2rem;
+ border-radius: ${({ isRealtime }) =>
+ isRealtime ? '0 1rem 1rem 1rem' : '1rem'};
+`;
+
+const TimeWrapper = styled.div`
+ box-sizing: border-box;
+ padding: 0.4rem 1.2rem;
+ width: fit-content;
+ border-radius: 1rem 1rem 0 0;
+ background-color: ${Red};
+`;
+
+const ImgWrapper = styled.div`
+ border-radius: 100%;
+ background-color: white;
+ width: 4.5rem;
+ height: 4.1rem;
+ background-color: ${Grey6};
+`;
+
+const Divider = styled.div`
+ width: 0.1rem;
+ height: 1.5rem;
+ background: #bbb;
+`;
+
+const BookMarkIcon = styled(BookMark)`
+ padding-left: 0.8rem;
+ cursor: pointer;
+`;
+const NoneBookMarkIcon = styled(NoneBookMark)`
+ padding-left: 0.8rem;
+ cursor: pointer;
+`;
+
+export default CounselorCard;
diff --git a/src/components/Common/TabA1.tsx b/src/components/Common/TabA1.tsx
index 6a84a2b4..8ab2c738 100644
--- a/src/components/Common/TabA1.tsx
+++ b/src/components/Common/TabA1.tsx
@@ -153,7 +153,7 @@ const Wrapper = styled.nav`
top: 6rem;
background-color: white;
z-index: 999;
- box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);
+ box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.1);
`;
const TabButton = styled.div<{ $tabState: number }>`
display: flex;
diff --git a/src/components/Seller/SellerMyPageModifyProfile/ModifyProfileMainSection.tsx b/src/components/Seller/SellerMyPageModifyProfile/ModifyProfileMainSection.tsx
index 9469cc22..f23c7d7f 100644
--- a/src/components/Seller/SellerMyPageModifyProfile/ModifyProfileMainSection.tsx
+++ b/src/components/Seller/SellerMyPageModifyProfile/ModifyProfileMainSection.tsx
@@ -282,11 +282,11 @@ function ModifyProfileMainSection({
50000
+ parseFloat(letterPrice?.value?.replace(/,/g, '')) < 3000 ||
+ parseFloat(letterPrice?.value?.replace(/,/g, '')) > 30000
? true
: false
}
@@ -457,8 +457,8 @@ function ModifyProfileMainSection({
? true
: false) ||
((selectType?.includes('편지') &&
- parseFloat(letterPrice?.value?.replace(/,/g, '')) < 5000) ||
- parseFloat(letterPrice?.value?.replace(/,/g, '')) > 50000
+ parseFloat(letterPrice?.value?.replace(/,/g, '')) < 3000) ||
+ parseFloat(letterPrice?.value?.replace(/,/g, '')) > 30000
? true
: false)
)
diff --git a/src/pages/Buyer/BuyerCategoryResult.tsx b/src/pages/Buyer/BuyerCategoryResult.tsx
index 67d14b18..ea0e8a73 100644
--- a/src/pages/Buyer/BuyerCategoryResult.tsx
+++ b/src/pages/Buyer/BuyerCategoryResult.tsx
@@ -110,6 +110,7 @@ export const BuyerCategoryResult = () => {
preventRef.current = true;
}
};
+
//현재 대상 및 option을 props로 전달
const { setTarget } = useIntersectionObserver({
root: null,
diff --git a/src/pages/Seller/SellerMyPageModifyProfile.tsx b/src/pages/Seller/SellerMyPageModifyProfile.tsx
index 65fc0955..acf3c233 100644
--- a/src/pages/Seller/SellerMyPageModifyProfile.tsx
+++ b/src/pages/Seller/SellerMyPageModifyProfile.tsx
@@ -150,13 +150,13 @@ export const SellerMypageModifyProfile = () => {
setIsLoading(false);
} else if (profileLevel?.data?.profileStatus === 'EVALUATION_PENDING') {
alert('판매 정보 검토 중이니 조금만 기다려주세요!');
- navigate('/seller/mypage/viewProfile');
+ navigate('/minder/mypage/viewProfile');
} else {
const profileRes: any = await getProfiles();
const data = profileRes.data;
if (profileRes.response?.status === 404) {
alert('판매 정보가 등록되어 있지 않습니다.');
- navigate('/seller/mypage');
+ navigate('/minder/mypage');
}
nickname.setValue(data?.nickname);
category.setViewValue(data?.consultCategories.join(', '));
@@ -189,7 +189,7 @@ export const SellerMypageModifyProfile = () => {
setIsLoading(false);
}
} catch (err) {
- navigate('/seller/mypage');
+ navigate('/minder/mypage');
alert(err);
}
// accountNum.setValue(profileDummyData.accountNum);
diff --git a/src/utils/type.ts b/src/utils/type.ts
index 3d7e2549..d9cba808 100644
--- a/src/utils/type.ts
+++ b/src/utils/type.ts
@@ -86,6 +86,7 @@ export type SearchResultData = {
ratingAverage: number;
totalReview: number;
totalConsult: number;
+ isRealtime: boolean;
};
export interface BuyerReview {
@@ -133,6 +134,7 @@ export type WishlistDataType = {
ratingAverage: number;
totalReview: number;
};
+
export interface PaymentInfo {
paymentId: number;
nickname: string;