From 39c6e89daa8bcdeee2adc48438b0d46c448573e2 Mon Sep 17 00:00:00 2001 From: sangminee <81500474+sangminee@users.noreply.github.com> Date: Mon, 11 Mar 2024 18:09:45 +0900 Subject: [PATCH] [RELEASE] v1.4 (#45) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * header color 구분 * sideBar Active 상태 useState 적용 및 색상 변경 * [FEAT] 관리자 웹 수정 (#13) * [FEAT] 관리자 사업계획서 리스트 띄우기 * [FIX] 로그인 페이지 UI 수정 * [FEAT] 사업계획서 상세 보기 API 연결 * [FEAT] 사업계획서 상세 보기 버튼 UI * [FEAT] 사업체 detail 버튼 디테일 수정 * [FEAT] alert 달기 * [FEAT] 사용자 목록 제목 수정, 페이지네이션 달기 * [CHORE] 유저 목록 추가 * [CHORE] 사용자 요소 값 수정 * [CHORE] 필요없는 파일 삭제 * [CHORE] 오류 수정 * 대시보드 기초 구조 생성 및 현황 view생성 * [FEAT] 로그인 기능 추가 (#14) * [FEAT] 관리자 사업계획서 리스트 띄우기 * [FIX] 로그인 페이지 UI 수정 * [FEAT] 사업계획서 상세 보기 API 연결 * [FEAT] 사업계획서 상세 보기 버튼 UI * [FEAT] 사업체 detail 버튼 디테일 수정 * [FEAT] alert 달기 * [FEAT] 사용자 목록 제목 수정, 페이지네이션 달기 * [CHORE] 유저 목록 추가 * [CHORE] 사용자 요소 값 수정 * [CHORE] 필요없는 파일 삭제 * [CHORE] 오류 수정 * [FEAT] 로그인 api 연결 * [FEAT] 팝업스토어 순위 적용 및 게시글 목록 기초 생성 * 내 팝업스토어 게시글 목록 생성 * [FEAT] Statistics Chart 적용 * [FEAT]axios baseApi 세팅 * [FEAT] user, admin Base Api 분리 * authApi 실제서버 기반 URL로 변경 * [FEAT] 디테일 변경 (#17) * [FEAT] 로그아웃 추가 * [FEAT] 사업계획서에 따른 팝업 게시글 정보 보기 api 연결 * [FEAT] 마크다운 형식으로 값 저장 (수정필요) * [FEAT] 관리자, 사업체 채팅 목록 보기 * [CHORE] 채팅 url 변경 * [CHORE] dev 머지 * [FEAT]BaseApi class명 수정 및 통계 수정 및 데이터 적용 * [FEAT] 대시보드 통신 구현 * [FEAT] 토스페이 결제 기능 구현 (#19) * [REFACTOR] develop 충돌 해결 * [REFACTOR] 중첩 try-catch 문 제거 * [REFACTOR] 토스페이 위젯 모달창으로 띄우기 * [FEAT] 구매자 정보 조회 API 연동 * [REFACTOR] 광고 분류 선택 시 결제 금액 변경 * [REFACTOR] develop 충돌 해결 * [REFACTOR] 광고 분류에 따라 게시글 리스트 전환 * [REFACTOR] 광고 게시글 체크박스 처리 * [FEAT] 팝업스토어 게시글 이미지 업로드 추가 * [REFACTOR] 사업계획서 제안 및 광고 신청 시 이미지 업로드 기능 구현 (#20) * [REFACTOR] 광고 결제 시 메인 이미지 업로드 기능 구현 * [REFACTOR] 광고 결제 시 게시글 아이디 추출 기능 구현 * [REFACTOR] API 호출 방식 변경 * [REFACTOR] 달력 컴포넌트 type date 로 변경 * [FEAT] 사업계획서 제안 API 연동 * [REFACTOR] 내비바 페이지 연결 및 디자인 일부 수정 (#21) * [REFACTOR] 사용자에 따라 홈 위치 변경 * [REFACTOR] 내비바 페이지 연결 * [REFACTOR] 관리자용 토큰 접근으로 수정 * [REFACTOR] 로그인 시 엔터 이벤트 추가 * [REFACTOR] 내비바 텍스트 및 배경색 변경 * [REFACTOR] 대시보드 텍스트 색상 변경 * [REFACTOR] 팝업스토어 게시글 상세정보 조회 * [FIX] 드롭다운 문제 해결 * [REFACTOR] 드롭다운 항목 선택 시 검색 조건 설정 * [REFACTOR] 조건 검색 버튼 변경 * [FEATURE] 채팅 기능 (#22) * [FEAT] 로그아웃 추가 * [FEAT] 사업계획서에 따른 팝업 게시글 정보 보기 api 연결 * [FEAT] 마크다운 형식으로 값 저장 (수정필요) * [FEAT] 관리자, 사업체 채팅 목록 보기 * [CHORE] 채팅 url 변경 * [CHORE] dev 머지 * [FEAT] 팝업 게시글 글+사진 서버에 저장 * [FEAT] 채팅 구현 * [CHORE] 머지해결 * [FEATURE] not defined 해결 (#24) * [FEAT] 로그아웃 추가 * [FEAT] 사업계획서에 따른 팝업 게시글 정보 보기 api 연결 * [FEAT] 마크다운 형식으로 값 저장 (수정필요) * [FEAT] 관리자, 사업체 채팅 목록 보기 * [CHORE] 채팅 url 변경 * [CHORE] dev 머지 * [FEAT] 팝업 게시글 글+사진 서버에 저장 * [FEAT] 채팅 구현 * [CHORE] 머지해결 * [CHORE] not defined 해결 * [REFACTOR] 각종 에러 수정 * [REFACTOR] 결제 수단 버튼 추가 및 디자인 세부 수정 (#28) * [REFACTOR] 결제 방법 추가 * [REFACTOR] 결제하기 버튼 추가 * [REFACTOR] 드롭다운 오른쪽 정렬 * [REFACTOR] 드롭다운 버튼 색상 변경 * [REFACTOR] Home 이미지 bg 추가 * [Refactor] 펭지ㅣ 이동 버튼 수정 * [Refactor] 로그인view수정, 표시 favicon 변경 * [FEAUTRE] 문의하기 수정 (#33) * [FEAT] 채팅방 리스트 보여주기 * [FEAT] 채팅방 디테일 수정 * [FEAT] 채팅방 제목 CSS 수정 * [FEAT] css 변경 * [CHORE] 파일 위치 및 css 변경 * [CHORE] 머지 해결 * [REFACTOR] Ranking y축 간격 오류 수정 * [FEAT] 사업체 플로팅 버튼 추가 --------- Co-authored-by: LSMJJAng <127660101+LSMJJAng@users.noreply.github.com> * [FIX] 광고 팝업스토어 게시글 조회 시 잘못된 아이디 매핑 수정 (#35) * [FEATURE] 채팅 UI 수정 (#36) * [FEAT] 채팅방 리스트 보여주기 * [FEAT] 채팅방 디테일 수정 * [FEAT] 채팅방 제목 CSS 수정 * [FEAT] css 변경 * [CHORE] 파일 위치 및 css 변경 * [CHORE] 머지 해결 * [REFACTOR] Ranking y축 간격 오류 수정 * [FEAT] 사업체 플로팅 버튼 추가 * [FEAT] 사업체 채팅 ui 변경 * [CHORE] 오타 수정 --------- Co-authored-by: LSMJJAng <127660101+LSMJJAng@users.noreply.github.com> * [FEAT] 채팅리스트 조회 ui 변경 (#37) * [FEAT] 채팅방 리스트 보여주기 * [FEAT] 채팅방 디테일 수정 * [FEAT] 채팅방 제목 CSS 수정 * [FEAT] css 변경 * [CHORE] 파일 위치 및 css 변경 * [CHORE] 머지 해결 * [REFACTOR] Ranking y축 간격 오류 수정 * [FEAT] 사업체 플로팅 버튼 추가 * [FEAT] 사업체 채팅 ui 변경 * [CHORE] 오타 수정 --------- Co-authored-by: LSMJJAng <127660101+LSMJJAng@users.noreply.github.com> * [REFACTOR] 환경변수값 설정 (#39) * [CHORE] CICD 에 환경변수 파일 추가 * [CHORE] 하드코딩 값 환경변수로 수정 * [CHORE] 환경변수 저장 경로 수정 (#41) * [CHORE] 환경변수 파일 경로 수정 * [CHORE] 환경변수 저장 경로 수정 * [REFACTOR] 자잘한 버그 해결 (#43) * [REFACTOR] 팝업스토어 광고 금액 수정 * [REFACTOR] 관리자 로그인 후 경로 수정 * [REFACTOR] 사업계획서 제안 시 상세정보 페이지로 이동 * [REFACTOR] 팝업스토어 작성 시 리프레시 * [REFACTOR] 사업계획서 상세정보 조회 시 오픈 일정 추가 * [REFACTOR] 사업계획서 상태 변화 시 리프레시 * [REFACTOR] 사업계획서 단계에 따른 팝업스토어 게시글 작성 여부 판단 * [FEAT] 사업계획서 철회 API 연동 * [FEATURE] 알람 추가 (#44) * [FEAT] 채팅방 리스트 보여주기 * [FEAT] 채팅방 디테일 수정 * [FEAT] 채팅방 제목 CSS 수정 * [FEAT] css 변경 * [CHORE] 파일 위치 및 css 변경 * [CHORE] 머지 해결 * [REFACTOR] Ranking y축 간격 오류 수정 * [FEAT] 사업체 플로팅 버튼 추가 * [FEAT] 사업체 채팅 ui 변경 * [CHORE] 오타 수정 * [FEAT] 알람 추가 --------- Co-authored-by: LSMJJAng <127660101+LSMJJAng@users.noreply.github.com> --------- Co-authored-by: LSMJJAng <127660101+LSMJJAng@users.noreply.github.com> Co-authored-by: kyukong <92148749+kyukong@users.noreply.github.com> Co-authored-by: yukong --- package-lock.json | 627 ++++++++++++++++++++ package.json | 5 +- public/firebase-messaging-sw.js | 31 + src/App.js | 4 +- src/api/Common/notificationApi.js | 31 + src/api/business/planDetail/withdrawPlan.js | 20 + src/api/chatApi.js | 2 +- src/components/Plan/AdminPlanDetail.jsx | 2 +- src/components/Plan/PlanDetail.jsx | 79 +-- src/components/common/Input/InputDate.js | 3 +- src/firebase-messaging-sw.js | 70 +++ src/pages/administrator/adminPlanDetail.jsx | 14 +- src/pages/business/ad.jsx | 2 +- src/pages/business/createPlan.jsx | 5 +- src/pages/business/plan.jsx | 74 ++- 15 files changed, 908 insertions(+), 61 deletions(-) create mode 100644 public/firebase-messaging-sw.js create mode 100644 src/api/Common/notificationApi.js create mode 100644 src/api/business/planDetail/withdrawPlan.js create mode 100644 src/firebase-messaging-sw.js diff --git a/package-lock.json b/package-lock.json index 3caa740..36338d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@uiw/react-md-editor": "^4.0.3", "axios": "^1.6.7", "chart.js": "^4.4.2", + "firebase": "^8.10.0", "flowbite": "^2.3.0", "flowbite-datepicker": "^1.2.6", "http-proxy-middleware": "^2.0.6", @@ -2424,6 +2425,371 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@firebase/analytics": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.6.18.tgz", + "integrity": "sha512-FXNtYDxbs9ynPbzUVuG94BjFPOPpgJ7156660uvCBuKgoBCIVcNqKkJQQ7TH8384fqvGjbjdcgARY9jgAHbtog==", + "dependencies": { + "@firebase/analytics-types": "0.6.0", + "@firebase/component": "0.5.6", + "@firebase/installations": "0.4.32", + "@firebase/logger": "0.2.6", + "@firebase/util": "1.3.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.6.0.tgz", + "integrity": "sha512-kbMawY0WRPyL/lbknBkme4CNLl+Gw+E9G4OpNeXAauqoQiNkBgpIvZYy7BRT4sNGhZbxdxXxXbruqUwDzLmvTw==" + }, + "node_modules/@firebase/app": { + "version": "0.6.30", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.6.30.tgz", + "integrity": "sha512-uAYEDXyK0mmpZ8hWQj5TNd7WVvfsU8PgsqKpGljbFBG/HhsH8KbcykWAAA+c1PqL7dt/dbt0Reh1y9zEdYzMhg==", + "dependencies": { + "@firebase/app-types": "0.6.3", + "@firebase/component": "0.5.6", + "@firebase/logger": "0.2.6", + "@firebase/util": "1.3.0", + "dom-storage": "2.1.0", + "tslib": "^2.1.0", + "xmlhttprequest": "1.8.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.3.2.tgz", + "integrity": "sha512-YjpsnV1xVTO1B836IKijRcDeceLgHQNJ/DWa+Vky9UHkm1Mi4qosddX8LZzldaWRTWKX7BN1MbZOLY8r7M/MZQ==", + "dependencies": { + "@firebase/app-check-interop-types": "0.1.0", + "@firebase/app-check-types": "0.3.1", + "@firebase/component": "0.5.6", + "@firebase/logger": "0.2.6", + "@firebase/util": "1.3.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.1.0.tgz", + "integrity": "sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA==" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.3.1.tgz", + "integrity": "sha512-KJ+BqJbdNsx4QT/JIT1yDj5p6D+QN97iJs3GuHnORrqL+DU3RWc9nSYQsrY6Tv9jVWcOkMENXAgDT484vzsm2w==" + }, + "node_modules/@firebase/app-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.3.tgz", + "integrity": "sha512-/M13DPPati7FQHEQ9Minjk1HGLm/4K4gs9bR4rzLCWJg64yGtVC0zNg9gDpkw9yc2cvol/mNFxqTtd4geGrwdw==" + }, + "node_modules/@firebase/auth": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.16.8.tgz", + "integrity": "sha512-mR0UXG4LirWIfOiCWxVmvz1o23BuKGxeItQ2cCUgXLTjNtWJXdcky/356iTUsd7ZV5A78s2NHeN5tIDDG6H4rg==", + "dependencies": { + "@firebase/auth-types": "0.10.3" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/auth-types": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.10.3.tgz", + "integrity": "sha512-zExrThRqyqGUbXOFrH/sowuh2rRtfKHp9SBVY2vOqKWdCX1Ztn682n9WLtlUDsiYVIbBcwautYWk2HyCGFv0OA==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.6.tgz", + "integrity": "sha512-GyQJ+2lrhsDqeGgd1VdS7W+Y6gNYyI0B51ovNTxeZVG/W8I7t9MwEiCWsCvfm5wQgfsKp9dkzOcJrL5k8oVO/Q==", + "dependencies": { + "@firebase/util": "1.3.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.11.0.tgz", + "integrity": "sha512-b/kwvCubr6G9coPlo48PbieBDln7ViFBHOGeVt/bt82yuv5jYZBEYAac/mtOVSxpf14aMo/tAN+Edl6SWqXApw==", + "dependencies": { + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.6", + "@firebase/database-types": "0.8.0", + "@firebase/logger": "0.2.6", + "@firebase/util": "1.3.0", + "faye-websocket": "0.11.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.8.0.tgz", + "integrity": "sha512-7IdjAFRfPWyG3b4wcXyghb3Y1CLCSJFZIg1xl5GbTVMttSQFT4B5NYdhsfA34JwAsv5pMzPpjOaS3/K9XJ2KiA==", + "dependencies": { + "@firebase/app-types": "0.6.3", + "@firebase/util": "1.3.0" + } + }, + "node_modules/@firebase/database/node_modules/faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@firebase/firestore": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-2.4.0.tgz", + "integrity": "sha512-PQ6+lWNrvh74GvFTHT4gCutFipDmtu8D1tNNawKe+/SyL6XFgeuMYgZIpKQgkTSezVDogC7EGQTJBFnewF9pOg==", + "dependencies": { + "@firebase/component": "0.5.6", + "@firebase/firestore-types": "2.4.0", + "@firebase/logger": "0.2.6", + "@firebase/util": "1.3.0", + "@firebase/webchannel-wrapper": "0.5.1", + "@grpc/grpc-js": "^1.3.2", + "@grpc/proto-loader": "^0.6.0", + "node-fetch": "2.6.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.4.0.tgz", + "integrity": "sha512-0dgwfuNP7EN6/OlK2HSNSQiQNGLGaRBH0gvgr1ngtKKJuJFuq0Z48RBMeJX9CGjV4TP9h2KaB+KrUKJ5kh1hMg==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.6.15", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.6.15.tgz", + "integrity": "sha512-b7RpLwFXi0N+HgkfK8cmkarSOoBeSrc1jNdadkCacQt+vIePkKM3E9EJXF4roWSa8GwTruodpBsvH+lK9iCAKQ==", + "dependencies": { + "@firebase/component": "0.5.6", + "@firebase/functions-types": "0.4.0", + "@firebase/messaging-types": "0.5.0", + "node-fetch": "2.6.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.4.0.tgz", + "integrity": "sha512-3KElyO3887HNxtxNF1ytGFrNmqD+hheqjwmT3sI09FaDCuaxGbOnsXAXH2eQ049XRXw9YQpHMgYws/aUNgXVyQ==" + }, + "node_modules/@firebase/installations": { + "version": "0.4.32", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.4.32.tgz", + "integrity": "sha512-K4UlED1Vrhd2rFQQJih+OgEj8OTtrtH4+Izkx7ip2bhXSc+unk8ZhnF69D0kmh7zjXAqEDJrmHs9O5fI3rV6Tw==", + "dependencies": { + "@firebase/component": "0.5.6", + "@firebase/installations-types": "0.3.4", + "@firebase/util": "1.3.0", + "idb": "3.0.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.3.4.tgz", + "integrity": "sha512-RfePJFovmdIXb6rYwtngyxuEcWnOrzdZd9m7xAW0gRxDIjBT20n3BOhjpmgRWXo/DAxRmS7bRjWAyTHY9cqN7Q==", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/installations/node_modules/idb": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/idb/-/idb-3.0.2.tgz", + "integrity": "sha512-+FLa/0sTXqyux0o6C+i2lOR0VoS60LU/jzUo5xjfY6+7sEEgy4Gz1O7yFBXvjd7N0NyIGWIRg8DcQSLEG+VSPw==" + }, + "node_modules/@firebase/logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.6.tgz", + "integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw==" + }, + "node_modules/@firebase/messaging": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.8.0.tgz", + "integrity": "sha512-hkFHDyVe1kMcY9KEG+prjCbvS6MtLUgVFUbbQqq7JQfiv58E07YCzRUcMrJolbNi/1QHH6Jv16DxNWjJB9+/qA==", + "dependencies": { + "@firebase/component": "0.5.6", + "@firebase/installations": "0.4.32", + "@firebase/messaging-types": "0.5.0", + "@firebase/util": "1.3.0", + "idb": "3.0.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/messaging-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-types/-/messaging-types-0.5.0.tgz", + "integrity": "sha512-QaaBswrU6umJYb/ZYvjR5JDSslCGOH6D9P136PhabFAHLTR4TWjsaACvbBXuvwrfCXu10DtcjMxqfhdNIB1Xfg==", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/messaging/node_modules/idb": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/idb/-/idb-3.0.2.tgz", + "integrity": "sha512-+FLa/0sTXqyux0o6C+i2lOR0VoS60LU/jzUo5xjfY6+7sEEgy4Gz1O7yFBXvjd7N0NyIGWIRg8DcQSLEG+VSPw==" + }, + "node_modules/@firebase/performance": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.4.18.tgz", + "integrity": "sha512-lvZW/TVDne2TyOpWbv++zjRn277HZpbjxbIPfwtnmKjVY1gJ+H77Qi1c2avVIc9hg80uGX/5tNf4pOApNDJLVg==", + "dependencies": { + "@firebase/component": "0.5.6", + "@firebase/installations": "0.4.32", + "@firebase/logger": "0.2.6", + "@firebase/performance-types": "0.0.13", + "@firebase/util": "1.3.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.0.13.tgz", + "integrity": "sha512-6fZfIGjQpwo9S5OzMpPyqgYAUZcFzZxHFqOyNtorDIgNXq33nlldTL/vtaUZA8iT9TT5cJlCrF/jthKU7X21EA==" + }, + "node_modules/@firebase/polyfill": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.36.tgz", + "integrity": "sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg==", + "dependencies": { + "core-js": "3.6.5", + "promise-polyfill": "8.1.3", + "whatwg-fetch": "2.0.4" + } + }, + "node_modules/@firebase/polyfill/node_modules/core-js": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/@firebase/polyfill/node_modules/whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + }, + "node_modules/@firebase/remote-config": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.1.43.tgz", + "integrity": "sha512-laNM4MN0CfeSp7XCVNjYOC4DdV6mj0l2rzUh42x4v2wLTweCoJ/kc1i4oWMX9TI7Jw8Am5Wl71Awn1J2pVe5xA==", + "dependencies": { + "@firebase/component": "0.5.6", + "@firebase/installations": "0.4.32", + "@firebase/logger": "0.2.6", + "@firebase/remote-config-types": "0.1.9", + "@firebase/util": "1.3.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.1.9.tgz", + "integrity": "sha512-G96qnF3RYGbZsTRut7NBX0sxyczxt1uyCgXQuH/eAfUCngxjEGcZQnBdy6mvSdqdJh5mC31rWPO4v9/s7HwtzA==" + }, + "node_modules/@firebase/storage": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.7.0.tgz", + "integrity": "sha512-ebDFKJbM5HOxVtZV+RhVEBVtlWHK+Z5L3kA5uDBA2jMYcn+8NV/crozJnEE+iRsGEco6dLK5JS+Er4qtKLpH5A==", + "dependencies": { + "@firebase/component": "0.5.6", + "@firebase/storage-types": "0.5.0", + "@firebase/util": "1.3.0", + "node-fetch": "2.6.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.5.0.tgz", + "integrity": "sha512-6Wv3Lu7s18hsgW7HG4BFwycTquZ3m/C8bjBoOsmPu0TD6M1GKwCzOC7qBdN7L6tRYPh8ipTj5+rPFrmhGfUVKA==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.3.0.tgz", + "integrity": "sha512-SESvmYwuKOVCZ1ZxLbberbx+9cnbxpCa4CG2FUSQYqN6Ab8KyltegMDIsqMw5KyIBZ4n1phfHoOa22xo5NzAlQ==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.5.1.tgz", + "integrity": "sha512-dZMzN0uAjwJXWYYAcnxIwXqRTZw3o14hGe7O6uhwjD1ZQWPVYA5lASgnNskEBra0knVBsOXB4KXg+HnlKewN/A==" + }, "node_modules/@floating-ui/core": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", @@ -2517,6 +2883,119 @@ "react": ">=16.3" } }, + "node_modules/@grpc/grpc-js": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.1.tgz", + "integrity": "sha512-55ONqFytZExfOIjF1RjXPcVmT/jJqFzbbDqxK9jmRV4nxiYWtL9hENSW1Jfx0SdZfrvoqd44YJ/GJTqfRrawSQ==", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", + "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/grpc-js/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@grpc/grpc-js/node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/@grpc/grpc-js/node_modules/protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@grpc/grpc-js/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@heroicons/react": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.1.1.tgz", @@ -3613,6 +4092,60 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "node_modules/@remix-run/router": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz", @@ -4325,6 +4858,11 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "node_modules/@types/mdast": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", @@ -7434,6 +7972,14 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, + "node_modules/dom-storage": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.1.0.tgz", + "integrity": "sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q==", + "engines": { + "node": "*" + } + }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -8909,6 +9455,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/firebase": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-8.10.0.tgz", + "integrity": "sha512-GCABTbJdo88QgzX5OH/vsfKBWvTRbLUylGlYXtO7uYo1VErfGd2BWW9ATlJP5Gxx+ClDfyvVTvcs2rcNWn3uUA==", + "dependencies": { + "@firebase/analytics": "0.6.18", + "@firebase/app": "0.6.30", + "@firebase/app-check": "0.3.2", + "@firebase/app-types": "0.6.3", + "@firebase/auth": "0.16.8", + "@firebase/database": "0.11.0", + "@firebase/firestore": "2.4.0", + "@firebase/functions": "0.6.15", + "@firebase/installations": "0.4.32", + "@firebase/messaging": "0.8.0", + "@firebase/performance": "0.4.18", + "@firebase/polyfill": "0.3.36", + "@firebase/remote-config": "0.1.43", + "@firebase/storage": "0.7.0", + "@firebase/util": "1.3.0" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", @@ -13221,6 +13792,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -13246,6 +13822,11 @@ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -14435,6 +15016,14 @@ "tslib": "^2.0.3" } }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -16394,6 +16983,11 @@ "asap": "~2.0.6" } }, + "node_modules/promise-polyfill": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz", + "integrity": "sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==" + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -16505,6 +17099,31 @@ "prosemirror-transform": "^1.1.0" } }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -20977,6 +21596,14 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 590b0ad..d00021a 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@uiw/react-md-editor": "^4.0.3", "axios": "^1.6.7", "chart.js": "^4.4.2", + "firebase": "^8.10.0", "flowbite": "^2.3.0", "flowbite-datepicker": "^1.2.6", "http-proxy-middleware": "^2.0.6", @@ -43,7 +44,9 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "start:mac": "HTTPS=true SSL_CRT_FILE=./.cert/cert.pem SSL_KEY_FILE=./.cert/key.pem npm run start", + "start:windows": "set HTTPS=true&&set SSL_CRT_FILE=localhost.pem&&set SSL_KEY_FILE=localhost-key.pem&&npm run start" }, "eslintConfig": { "extends": [ diff --git a/public/firebase-messaging-sw.js b/public/firebase-messaging-sw.js new file mode 100644 index 0000000..a63822f --- /dev/null +++ b/public/firebase-messaging-sw.js @@ -0,0 +1,31 @@ +import firebase from "firebase/app"; + +importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"); +importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js"); + +const firebaseConfig = { + apiKey: "AIzaSyBVEo-5nnfPpRvDW69oS1DnCgSmtzzlj1g", + projectId: "thepop-18582", + messagingSenderId: "23824278236", + appId: "1:23824278236:web:841437d42a805d7af50a19", +}; + +firebase.initializeApp(firebaseConfig); +const messaging = firebase.messaging(); + +self.addEventListener("push", function (e) { + if (!e.data.json()) return; + + const resultData = e.data.json().notification; + const notificationTitle = resultData.title; + + const notificationOptions = { + body: resultData.body, + }; + + console.log(resultData.title, { + body: resultData.body, + }); + + e.waitUntil(self.registration.showNotification(notificationTitle, notificationOptions)); +}); diff --git a/src/App.js b/src/App.js index 485e353..e92f630 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,7 @@ import {BrowserRouter, Route, Routes} from "react-router-dom"; import React from "react"; +import './firebase-messaging-sw.js' import './index.css'; @@ -42,7 +43,7 @@ function App() { ]; const businessHomeUrl = "/dashboard" - const adminHomeUrl = "/admin/plan" + const adminHomeUrl = "/admin/business" return ( @@ -72,7 +73,6 @@ function App() { ); } - const generateRoute = (color, sideBarColor, sideBarList, homeUrl, path, Component) => ( { + return await userBaseApi.post(`/notification/new`, { token }); + }, + + /** + * 토큰 저장 알림 + * + * @since 2024.03.08 + * @author 이상민 + */ + saveAdminNotification: async (token) => { + return await adminBaseApi.post(`/notification/new`, { token }); + }, +} + +export default NotificationApi; diff --git a/src/api/business/planDetail/withdrawPlan.js b/src/api/business/planDetail/withdrawPlan.js new file mode 100644 index 0000000..a6899bc --- /dev/null +++ b/src/api/business/planDetail/withdrawPlan.js @@ -0,0 +1,20 @@ +import userInstance from "../../userBaseApi"; + +/** + * @since 2024.03.10 + * @author 김유빈 + */ +const WithdrawPlan = { + + /** + * 사업계획서 철회 + * + * @since 2024.03.10 + * @author 김유빈 + */ + withdraw: async (planId) => { + return await userInstance.post(`/plans/${planId}/withdraw`) + } +} + +export default WithdrawPlan; diff --git a/src/api/chatApi.js b/src/api/chatApi.js index 5e40dee..01ed104 100644 --- a/src/api/chatApi.js +++ b/src/api/chatApi.js @@ -1,7 +1,7 @@ import userBaseApi from "./userBaseApi"; /** - * @since 2024.03.52 + * @since 2024.03.02 * @author 이상민 */ const ChatApi = { diff --git a/src/components/Plan/AdminPlanDetail.jsx b/src/components/Plan/AdminPlanDetail.jsx index c7d6a98..43d01e5 100644 --- a/src/components/Plan/AdminPlanDetail.jsx +++ b/src/components/Plan/AdminPlanDetail.jsx @@ -58,7 +58,7 @@ const AdminPlanDetail = ( {planId, onChangeStatus}) => { return ( <> } + firstInput={} secondInput={} /> { - /** - * PlanDetail 컴포넌트 Plan으로 분리 및 API 연결 - * - * @since 2024.02.29 - * @author 이상민 - */ - const [planData, setPlanData] = useState(null); - const [planDetailStatus, setPlanDetailStatus] = useState(''); - useEffect(() => { - const fetchPlanData = async () => { - try { - const response = await MyPlanDetailApi.getPlan(planId); - console.log(response); - setPlanData(response.data.data); - - setPlanDetailStatus(response.data.data.entranceStatus); - } catch (error) { - console.error('Error fetching plan data:', error); - } - }; - fetchPlanData(); - }, [planId]); +const PlanDetail = ({planData}) => { if (!planData) { return

Loading...

; } - onChangeStatus(planDetailStatus); - /** * 파일 다운로드 * @@ -55,19 +30,36 @@ const PlanDetail = ( {planId, onChangeStatus}) => { document.body.removeChild(link); }; + /** + * 입점 철회 api 연동 + * + * @since 2024.03.10 + * @author 김유빈 + */ + const handleWithdraw = async () => { + try { + const response = await WithdrawPlan.withdraw(planData.planId); + if (response.status === 200) { + window.location.href = `/plans/${planData.planId}` + } + } catch (error) { + console.error('Error approving plan:', error); + } + }; + return ( <> } - secondInput={} + firstInput={} + secondInput={} /> } - secondInput={} + firstInput={} + secondInput={} /> } - secondInput={} + firstInput={} + secondInput={} />
@@ -81,6 +73,27 @@ const PlanDetail = ( {planId, onChangeStatus}) => { 파일 다운로드
+
+
+ { + planData.entranceStatus === '입점 요청' && ( + + ) + } +
+
) } diff --git a/src/components/common/Input/InputDate.js b/src/components/common/Input/InputDate.js index c03a132..a342314 100644 --- a/src/components/common/Input/InputDate.js +++ b/src/components/common/Input/InputDate.js @@ -7,7 +7,7 @@ import 'flowbite/dist/datepicker.turbo.js'; * @since 2024.02.25 * @author 김유빈 */ -function InputDate({title, placeholder, onChange}) { +function InputDate({title, placeholder, value, onChange}) { return (
) diff --git a/src/firebase-messaging-sw.js b/src/firebase-messaging-sw.js new file mode 100644 index 0000000..bb7b95a --- /dev/null +++ b/src/firebase-messaging-sw.js @@ -0,0 +1,70 @@ +import firebase from 'firebase/app' +import 'firebase/messaging' +import NotificationApi from "./api/Common/notificationApi"; + +const firebaseConfig = { + apiKey: `${process.env.REACT_APP_API_KEY}`, + authDomain: `${process.env.REACT_APP_AUTH_DOMAIN}`, + projectId: `${process.env.REACT_APP_PROJECT_ID}`, + storageBucket: `${process.env.REACT_APP_STORAGE_BUCKET}`, + messagingSenderId: `${process.env.REACT_APP_MESSAGING_SENDER_ID}`, + appId: `${process.env.REACT_APP_APP_ID}`, + measurementId: `${process.env.REACT_APP_MEASUREMENT_ID}` +}; + +firebase.initializeApp(firebaseConfig) +const messaging = firebase.messaging() + +function requestPermission() { + console.log('Requesting permission...'); + + void Notification.requestPermission().then((permission) => { + if (permission === 'granted') { + console.log('Notification permission granted.'); + console.log(`${process.env.REACT_APP_VAPID_KEY}`); + messaging.getToken({vapidKey: `${process.env.REACT_APP_VAPID_KEY}`}) + .then(async (currentToken) => { + if (currentToken) { + console.log('currenToken : ' + currentToken); + try { + const currentPagePath = window.location.pathname; + let response; + if (currentPagePath.startsWith('/admin/')) { + response = await NotificationApi.saveAdminNotification(currentToken); + } else { + response = await NotificationApi.saveNotification(currentToken); + } + try { + console.log("FCM 토큰 보내기 성공!", response); + } catch (error) { + console.log("FCM 토큰 보내기 실패!", error); + // 여기서 추가적인 에러 처리 또는 다른 작업을 수행할 수 있습니다. + } + } catch (error) { + console.error("token 저장 실패", error); + } + + } else { + console.log('Can not get token'); + } + }); + + }else{ + console.log('Do not have permission.'); + } + }); +} + +requestPermission(); + +messaging.onMessage((payload) => { + console.log(payload.notification.title); + console.log(payload.notification.body); +}); + +messaging.onMessage((payload) => { + console.log(payload.notification.title); + console.log(payload.notification.body); +}); + +export default firebase; diff --git a/src/pages/administrator/adminPlanDetail.jsx b/src/pages/administrator/adminPlanDetail.jsx index 74a7891..a48aacb 100644 --- a/src/pages/administrator/adminPlanDetail.jsx +++ b/src/pages/administrator/adminPlanDetail.jsx @@ -27,9 +27,11 @@ const AdminPlainDetail = () => { console.log(longPlanId); try { alert("정말 입점 대기 시키실 건가요?") - await AdminPlanApi.postWait(longPlanId); + const response = await AdminPlanApi.postWait(longPlanId); alert("입정 대기 완료되었습니다.") - navigate("/admin/plan"); // 페이지 이동 + if (response.status === 200) { + window.location.href = `/admin/plan/${longPlanId}` + } } catch (error) { console.error('Error approving plan:', error); } @@ -40,7 +42,9 @@ const AdminPlainDetail = () => { alert("정말 입정 승인 시키실 건가요?") const response = await AdminPlanApi.postApprove(longPlanId); alert('입점이 승인되었습니다.'); - navigate('/admin/plan'); // 페이지 이동 + if (response.status === 200) { + window.location.href = `/admin/plan/${longPlanId}` + } } catch (error) { console.error('Error approving plan:', error); } @@ -51,7 +55,9 @@ const AdminPlainDetail = () => { alert("정말 입정 거절 시키실 건가요?") const response = await AdminPlanApi.postDeny(longPlanId); alert('입점이 거절되었습니다.'); - navigate('/admin/plan'); // 페이지 이동 + if (response.status === 200) { + window.location.href = `/admin/plan/${longPlanId}` + } } catch (error) { console.error('Error rejecting plan:', error); } diff --git a/src/pages/business/ad.jsx b/src/pages/business/ad.jsx index 3c1ec42..8795349 100644 --- a/src/pages/business/ad.jsx +++ b/src/pages/business/ad.jsx @@ -123,7 +123,7 @@ function convertAboutPost(setPrice, setPostType, setMainImage, setPosts, onChang let data = null let mainImage = <> if (value === "popup") { - price = 1_000_000 + price = 500_000 const response = await MyPopupApi.getMyPopups(0, 5) data = response.data.data.popups.map(popup => { const createdDate = popup.pulledDate.split(" ")[0]; diff --git a/src/pages/business/createPlan.jsx b/src/pages/business/createPlan.jsx index b6876db..f29a74d 100644 --- a/src/pages/business/createPlan.jsx +++ b/src/pages/business/createPlan.jsx @@ -48,7 +48,10 @@ const CreatePlan = () => { "contactInformation": phoneNumber, "category": category } - const response = await PlanApi.save(data, file); + const response = await PlanApi.save(data, file) + if (response.status === 200) { + window.location.href = `/plans/${response.data.data}` + } } catch (error) { console.error("저장 중 에러 발생: ", error); } diff --git a/src/pages/business/plan.jsx b/src/pages/business/plan.jsx index e97bcf1..e7ab59e 100644 --- a/src/pages/business/plan.jsx +++ b/src/pages/business/plan.jsx @@ -15,6 +15,7 @@ import 'tui-color-picker/dist/tui-color-picker.css'; import '@toast-ui/editor-plugin-color-syntax/dist/toastui-editor-plugin-color-syntax.css'; import './planViewer.css'; import FloatingButton from "../../components/business/FloatingButton/FloatingButton"; +import MyPlanDetailApi from "../../api/business/planDetail/myPlanDetailApi"; /** * Plan 페이지 제작 @@ -24,8 +25,8 @@ import FloatingButton from "../../components/business/FloatingButton/FloatingBut const Plan = () => { const { planId } = useParams(); - const [planDetailStatus, setPlanDetailStatus] = useState(''); + const [planData, setPlanData] = useState(null); const [popupTitle, setPopupTitle] = useState(""); const [popupDescription, setPopupDescription] = useState(""); @@ -42,6 +43,37 @@ const Plan = () => { popupView: 0 }); + /** + * PlanDetail 컴포넌트 Plan으로 분리 및 API 연결 + * + * @since 2024.02.29 + * @author 이상민 + */ + useEffect(() => { + const fetchPlanData = async () => { + try { + const response = await MyPlanDetailApi.getPlan(planId); + const data = response.data.data; + const plan = { + planId: data.planId, + openDate: data.openDate.replaceAll(".", "-"), + entranceStatus: data.entranceStatus ? data.entranceStatus : '', + category: data.category ? data.category : '', + office: data.office ? data.office : '', + floor: data.floor ? data.floor : '', + contactInformation: data.contactInformation ? data.contactInformation : '', + createdDate: data.createdDate ? data.createdDate : '', + businessPlanUrl: data.businessPlanUrl, + } + console.log(plan) + setPlanData(plan); + } catch (error) { + console.error('Error fetching plan data:', error); + } + }; + fetchPlanData(); + }, [planId]); + /** * 사업계획서에 따른 팝업 게시글 정보 보기 api 연결 * @@ -78,6 +110,9 @@ const Plan = () => { if (result.data.message) { alert(result.data.message); } + if (result.status === 200) { + window.location.href = `/plans/${planId}` + } const response = await PopupApi.findByPlanId(planId); setPopupData(response.data.data); } catch (error) { @@ -88,21 +123,28 @@ const Plan = () => { return (
}/> - - - {popupData.popupWritten === false && ( -
);