From 7eafc937f38a54e9ecda48bc14805672b97b9eec Mon Sep 17 00:00:00 2001 From: 2ood Date: Sat, 18 Mar 2023 18:53:41 +0900 Subject: [PATCH] refactor(page) : component-ize lecture room page(#47) --- frontend/package-lock.json | 49 ++++++ frontend/package.json | 2 + frontend/src/components/Components.jsx | 4 + frontend/src/components/GradeSelect.jsx | 2 +- frontend/src/components/LectureBox.jsx | 4 +- frontend/src/components/RecentLectures.jsx | 94 +++++++++++ frontend/src/components/TrendingLecture.jsx | 70 ++++++++ frontend/src/pages/LectureRoomPage.jsx | 150 ++++++------------ frontend/src/styles/ComponentStyles.jsx | 2 + .../styled-components/ButtonGroup.style.jsx | 2 +- .../styled-components/EmptyBox.style.jsx | 12 ++ .../LectureBoxComponents.style.jsx | 3 + .../styled-components/Lecturegroup.style.jsx | 1 + frontend/src/util/ModularRequest.jsx | 13 +- frontend/yarn.lock | 21 ++- 15 files changed, 318 insertions(+), 111 deletions(-) create mode 100644 frontend/src/components/RecentLectures.jsx create mode 100644 frontend/src/components/TrendingLecture.jsx create mode 100644 frontend/src/styles/styled-components/EmptyBox.style.jsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1ccf3a9..de781d3 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -20,8 +20,10 @@ "react-cookie": "^4.1.1", "react-dom": "^18.2.0", "react-native-elements": "^3.4.3", + "react-pull-to-refresh": "^2.0.1", "react-router-dom": "^6.8.1", "react-scripts": "5.0.1", + "react-simple-pull-to-refresh": "^1.3.3", "react-toastify": "^9.1.1", "styled-components": "^5.3.6", "web-vitals": "^2.1.4" @@ -12038,6 +12040,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/hammerjs": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", + "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -20301,6 +20311,17 @@ "async-limiter": "~1.0.0" } }, + "node_modules/react-pull-to-refresh": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/react-pull-to-refresh/-/react-pull-to-refresh-2.0.1.tgz", + "integrity": "sha512-mbNI9r3sBF4X+2fBO8c9CuXDLIywNuoZ24AIGU3Odi+L8C4MpS0tuhMQUSg5cSOuUtDFkE8Z/YnBYixo10QI6Q==", + "dependencies": { + "hammerjs": "^2.0.8" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -20424,6 +20445,15 @@ "react": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-simple-pull-to-refresh": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-simple-pull-to-refresh/-/react-simple-pull-to-refresh-1.3.3.tgz", + "integrity": "sha512-6qXsa5RtNVmKJhLWvDLIX8UK51HFtCEGjdqQGf+M1Qjrcc4qH4fki97sgVpGEFBRwbY7DiVDA5N5p97kF16DTw==", + "peerDependencies": { + "react": "^16.10.2 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.10.2 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-toastify": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.1.tgz", @@ -32945,6 +32975,11 @@ "duplexer": "^0.1.2" } }, + "hammerjs": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", + "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==" + }, "handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -38949,6 +38984,14 @@ "yargs": "^16.1.1" } }, + "react-pull-to-refresh": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/react-pull-to-refresh/-/react-pull-to-refresh-2.0.1.tgz", + "integrity": "sha512-mbNI9r3sBF4X+2fBO8c9CuXDLIywNuoZ24AIGU3Odi+L8C4MpS0tuhMQUSg5cSOuUtDFkE8Z/YnBYixo10QI6Q==", + "requires": { + "hammerjs": "^2.0.8" + } + }, "react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -39036,6 +39079,12 @@ "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" } }, + "react-simple-pull-to-refresh": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-simple-pull-to-refresh/-/react-simple-pull-to-refresh-1.3.3.tgz", + "integrity": "sha512-6qXsa5RtNVmKJhLWvDLIX8UK51HFtCEGjdqQGf+M1Qjrcc4qH4fki97sgVpGEFBRwbY7DiVDA5N5p97kF16DTw==", + "requires": {} + }, "react-toastify": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index e75576d..bd27a6b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,8 +15,10 @@ "react-cookie": "^4.1.1", "react-dom": "^18.2.0", "react-native-elements": "^3.4.3", + "react-pull-to-refresh": "^2.0.1", "react-router-dom": "^6.8.1", "react-scripts": "5.0.1", + "react-simple-pull-to-refresh": "^1.3.3", "react-toastify": "^9.1.1", "styled-components": "^5.3.6", "web-vitals": "^2.1.4" diff --git a/frontend/src/components/Components.jsx b/frontend/src/components/Components.jsx index b09a507..59cc706 100644 --- a/frontend/src/components/Components.jsx +++ b/frontend/src/components/Components.jsx @@ -6,6 +6,8 @@ import CertificateFrame from "components/CertificateFrame"; import LectureBox from "components/LectureBox"; import GradeSelect from "components/GradeSelect"; import ThemedToast from "components/ThemedToast"; +import TrendingLecture from "components/TrendingLecture"; +import RecentLectures from "components/RecentLectures"; export {Topbar}; export {VerticalInput}; @@ -15,3 +17,5 @@ export {CertificateFrame}; export {LectureBox}; export {GradeSelect}; export {ThemedToast}; +export {TrendingLecture}; +export {RecentLectures}; \ No newline at end of file diff --git a/frontend/src/components/GradeSelect.jsx b/frontend/src/components/GradeSelect.jsx index a9304e4..b704644 100644 --- a/frontend/src/components/GradeSelect.jsx +++ b/frontend/src/components/GradeSelect.jsx @@ -4,7 +4,7 @@ import * as Styled from "styles/ComponentStyles"; function GradeSelect(props){ return (<> {props.contents.set(e.target.value);}}> - + diff --git a/frontend/src/components/LectureBox.jsx b/frontend/src/components/LectureBox.jsx index efbfe05..b7d4e95 100644 --- a/frontend/src/components/LectureBox.jsx +++ b/frontend/src/components/LectureBox.jsx @@ -1,4 +1,5 @@ import * as Styled from "styles/ComponentStyles"; +import * as Component from "components/Components"; import { useNavigate } from "react-router-dom"; import blackboard from "img/blackboard-compressed.jpg"; import { useAtom } from "jotai"; @@ -19,12 +20,11 @@ function LectureBox(props){ var Likes="Likes"; if (LanguageChange===0){ Likes="Likes"; - } else if(LanguageChange===1){ Likes="μΆ”μ²œ"; - }; + return ( lecture-thumb diff --git a/frontend/src/components/RecentLectures.jsx b/frontend/src/components/RecentLectures.jsx new file mode 100644 index 0000000..cb96aff --- /dev/null +++ b/frontend/src/components/RecentLectures.jsx @@ -0,0 +1,94 @@ +import React , {useEffect, useState} from "react"; +import { useAtom } from "jotai"; +import { LanguageChangeAtom } from "util/atom"; +import { toast } from 'react-toastify'; + +import * as Styled from "styles/ComponentStyles"; +import * as Component from "components/Components"; +import ModularRequest from "util/ModularRequest"; + +import right from "img/right.png"; +import left from "img/left.png"; + +function RecentLectures(props){ + const [LanguageChange,setLanguageChange] = useAtom(LanguageChangeAtom); + const notify = (content)=> toast(content); + + const grade = props.grade; + + const [recentLectures, setRecentLectures] = useState([]); + const [isLoaded, setIsLoaded] = useState(false); + let [page, setPage] = useState(1); + const [isEmpty, setIsEmpty] = useState(true); + + const total = (Math.floor((recentLectures.length-1)/4)+1); + + var RecentVideos="Recent Videos"; + var emptyRecent = "there is no empty lecture to show."; + if (LanguageChange===0){ + RecentVideos="Recent Videos"; + emptyRecent = "there is no empty lecture to show."; + } + else if(LanguageChange===1){ + RecentVideos="졜근 올라온 κ°•μ˜"; + emptyRecent="졜근 κ°•μ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€"; + } + + useEffect(()=>{ + try{ + let m2 = new ModularRequest({ + "path" : `course/recent?grade=${grade}&number=16`, + "method" : "get", + "headers" : { + "Authorization" : `Bearer ${localStorage.getItem('login-token')}`, + "Content-Type": 'application/json', + } + }); + + m2.send().then((res)=>{ + if(res.status=== 200) { + setRecentLectures(res.data.details); + setIsLoaded(true); + setIsEmpty(false); + } else { + setIsEmpty(true); + setIsLoaded(true); + } + } + ); + } catch (e) { + setRecentLectures([]); + console.log("error in reading trendings"); + } + },[grade]); + + function handlePageShiftClick(toLeft){ + if(toLeft){ if(page>1) setPage(--page);} + else { if(page + {RecentVideos} + {isLoaded &&((isEmpty)?{emptyRecent}:<> + + + {recentLectures.map((dat)=>)} + + + + + left{handlePageShiftClick(true);}}/> + {page}/{total} + right{handlePageShiftClick(false);}}/> + + + )} + + ); +} + +export default RecentLectures; + diff --git a/frontend/src/components/TrendingLecture.jsx b/frontend/src/components/TrendingLecture.jsx new file mode 100644 index 0000000..3d8ee2b --- /dev/null +++ b/frontend/src/components/TrendingLecture.jsx @@ -0,0 +1,70 @@ +import React , {useEffect, useState} from "react"; +import { useAtom } from "jotai"; +import { LanguageChangeAtom } from "util/atom"; +import { toast } from 'react-toastify'; + +import * as Styled from "styles/ComponentStyles"; +import * as Component from "components/Components"; +import ModularRequest from "util/ModularRequest"; + + +function TrendingLecture(props){ + const [LanguageChange,setLanguageChange] = useAtom(LanguageChangeAtom); + const [trending, setTrending] = useState({}); + const [isEmpty, setIsEmpty] = useState(true); + const notify = (content)=> toast(content); + + var bestLecture="Best Lecture"; + var emptyTrending="there is no trending lecture to show."; + + if (LanguageChange===0){ + bestLecture="Trending Lecture"; + emptyTrending="there is no trending lecture to show."; + } + else if(LanguageChange===1){ + bestLecture="μΆ”μ²œμˆ˜ 높은 κ°•μ˜"; + emptyTrending = "μΆ”μ²œμˆ˜ 높은 κ°•μ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€."; + }; + + const grade = props.grade; + + + + useEffect(()=>{ + try { + let m1 = new ModularRequest({ + "path" : `course/trending?grade=${grade}`, + "method" : "get", + "headers" : { + "Authorization" : `Bearer ${localStorage.getItem('login-token')}`, + "Content-Type": 'application/json', + } + }); + + m1.send().then((res)=>{ + if(res.status=== 200) { + setIsEmpty(false); + setTrending(res.data.details); + } + } + ); + + } catch (e) { + setTrending({}); + console.log("error in reading trendings"); + console.error(e.message); + } + },[]); + + + + return ( + <> + {bestLecture} + {(!isEmpty)?:{emptyTrending}} + + ); +} + +export default TrendingLecture; + diff --git a/frontend/src/pages/LectureRoomPage.jsx b/frontend/src/pages/LectureRoomPage.jsx index a273f3f..a237abf 100644 --- a/frontend/src/pages/LectureRoomPage.jsx +++ b/frontend/src/pages/LectureRoomPage.jsx @@ -1,136 +1,86 @@ import React , {useEffect, useState} from "react"; import * as Component from "components/Components"; import * as Styled from "styles/ComponentStyles"; -import right from "img/right.png"; -import left from "img/left.png"; import ModularRequest from "util/ModularRequest"; import { toast } from 'react-toastify'; import { useNavigate } from "react-router-dom"; import { FE_PATH } from "util/Enums"; import { useAtom } from "jotai"; import { LanguageChangeAtom } from "util/atom"; +import PullToRefresh from 'react-simple-pull-to-refresh'; -function LectureRoomPage(props){ - let [page, setPage] = useState(1); + +function LectureRoomPage(){ const navigate = useNavigate(); + const notify = (content)=> toast(content); - //const recentLectureData = props.data; - - const [trending, setTrending] = useState({}); - const [recentLectures, setRecentLectures] = useState([]); - const total = (Math.floor((recentLectures.length-1)/4)+1); const [grade, setGrade] = useState(6); - const notify = (content)=> toast(content); + const [LanguageChange,setLanguageChange] = useAtom(LanguageChangeAtom); + const [isLoaded, setIsLoaded] = useState(false); const gradeState = { target : grade, set : (newInput)=>{ - setPage(1); setGrade(newInput); } }; + var UploadLecture="Upload Lecture"; - useEffect(()=>{ - function readContents(){ - try { - let m1 = new ModularRequest({ - "path" : `course/trending?grade=${grade}`, - "method" : "get", - "headers" : { - "Authorization" : `Bearer ${localStorage.getItem('login-token')}`, - "Content-Type": 'application/json', - } - }); - - m1.send().then((res)=>{ - if(res.status=== 200) { - setTrending(res.data.details); - } else { - notify("there was an error in reading trendings!"); - } - } - ); + if (LanguageChange===0){ UploadLecture="Upload Lecture";} + else if(LanguageChange===1){UploadLecture="κ°•μ˜ κ²Œμ‹œν•˜κΈ°";}; + + function loadUserInfo(){ + try{ + let m2 = new ModularRequest({ + "path" : `user/info`, + "method" : "get", + "headers" : { + "Authorization" : `Bearer ${localStorage.getItem('login-token')}`, + "Content-Type": 'application/json', + } + }); - let m2 = new ModularRequest({ - "path" : `course/recent?grade=${grade}&number=16`, - "method" : "get", - "headers" : { - "Authorization" : `Bearer ${localStorage.getItem('login-token')}`, - "Content-Type": 'application/json', - } - }); - - m2.send().then((res)=>{ - if(res.status=== 200) { - setRecentLectures(res.data.details) - //console.log(recentLectures); - } else { - notify("there was an error in adding lecture!"); - } - } - ); - } catch (e) { - console.log("error in reading trendings"); - console.error(e.message); + m2.send().then((res)=>{ + if(res.status=== 200) { + setGrade(res.data.details.grade); + setIsLoaded(true); + } else { + notify("there was an error in reading user info!"); + } } - } - readContents(); - },[grade]) - - - const [LanguageChange,setLanguageChange] = useAtom(LanguageChangeAtom); - - function handlePageShiftClick(toLeft){ - //offset is the number of offset that is needed to move to page {offset}. - //there are 4 lectures each in a page, - //so there are ({length}/4 + 1) when length%4!=0, or ({length}/4) pages in total. - //in page 1, offset is 0 - //in page 2, offset is -1 = -{page}+1 - if(toLeft){ - if(page>1) setPage(--page); - } - else { - if(page{ + loadUserInfo(); + },[]); + function handleRefresh() { + + return new Promise(res => { + loadUserInfo(); + res(); + }); } - else if(LanguageChange===1){ - BestLecture="μΆ”μ²œμˆ˜ 높은 κ°•μ˜"; - RecentVideos="졜근 올라온 κ°•μ˜"; - UploadLecture="κ°•μ˜ κ²Œμ‹œν•˜κΈ°"; - }; return (<> - - - {BestLecture} - - {RecentVideos} - - - {recentLectures.map((dat)=>)} - - - - left{handlePageShiftClick(true);}}/> - {page}/{total} - right{handlePageShiftClick(false);}}/> - - {navigate(FE_PATH.course.upload)}}>{UploadLecture} - - + + + {isLoaded && <> + + + + {navigate(FE_PATH.course.upload)}}>{UploadLecture} + } + + ); } diff --git a/frontend/src/styles/ComponentStyles.jsx b/frontend/src/styles/ComponentStyles.jsx index 5fe7fe6..3b27ffc 100644 --- a/frontend/src/styles/ComponentStyles.jsx +++ b/frontend/src/styles/ComponentStyles.jsx @@ -23,6 +23,7 @@ import { LectureBoxFrame, LectureDescBox, LectureLikes, LectureTitle, Lecturer } import { LectureGroupScrollWrapper, LectureGroup } from "styles/styled-components/Lecturegroup.style"; import {GradeSelect} from "styles/styled-components/GradeSelect.style"; import { ThemedTextBlock } from "styles/styled-components/ThemedTextBlock.style"; +import { EmptyBox } from "styles/styled-components/EmptyBox.style"; export {MainBodyFrame}; export {HorizontalInput, NoBorderInput}; @@ -47,3 +48,4 @@ export {LectureBoxFrame, LectureDescBox, LectureLikes, LectureTitle, Lecturer}; export {LectureGroupScrollWrapper, LectureGroup}; export {GradeSelect}; export {ThemedTextBlock}; +export {EmptyBox}; \ No newline at end of file diff --git a/frontend/src/styles/styled-components/ButtonGroup.style.jsx b/frontend/src/styles/styled-components/ButtonGroup.style.jsx index ffa274e..08b8d0c 100644 --- a/frontend/src/styles/styled-components/ButtonGroup.style.jsx +++ b/frontend/src/styles/styled-components/ButtonGroup.style.jsx @@ -6,7 +6,7 @@ const Buttongroup = styled.div` display : flex; justify-content : space-evenly; padding : 0 var(--body-padding); - margin-top : 30px; + margin-top : 10px; `; export {Buttongroup}; \ No newline at end of file diff --git a/frontend/src/styles/styled-components/EmptyBox.style.jsx b/frontend/src/styles/styled-components/EmptyBox.style.jsx new file mode 100644 index 0000000..66bb1b6 --- /dev/null +++ b/frontend/src/styles/styled-components/EmptyBox.style.jsx @@ -0,0 +1,12 @@ +import styled from "styled-components"; +import "styles/style.bootstrap.css"; + +const EmptyBox = styled.div` + display : inline-flex; + justify-content : center; + align-items : center; + width : ${(props)=>(props.width)}; + aspect-ratio ${(props)=>(props.aspect_ratio??"4 / 1")}; +`; + +export {EmptyBox}; \ No newline at end of file diff --git a/frontend/src/styles/styled-components/LectureBoxComponents.style.jsx b/frontend/src/styles/styled-components/LectureBoxComponents.style.jsx index 841af17..c47818f 100644 --- a/frontend/src/styles/styled-components/LectureBoxComponents.style.jsx +++ b/frontend/src/styles/styled-components/LectureBoxComponents.style.jsx @@ -18,6 +18,9 @@ const LectureBoxFrame = styled.div` const LectureTitle = styled.div` font-size : var(--font-size-h3); + overflow : hidden; + white-space : nowrap; + text-overflow: ellipsis; `; const LectureDescBox = styled.div` display : flex; diff --git a/frontend/src/styles/styled-components/Lecturegroup.style.jsx b/frontend/src/styles/styled-components/Lecturegroup.style.jsx index 6457d79..d0266ff 100644 --- a/frontend/src/styles/styled-components/Lecturegroup.style.jsx +++ b/frontend/src/styles/styled-components/Lecturegroup.style.jsx @@ -14,6 +14,7 @@ const LectureGroup = styled.div` const LectureGroupScrollWrapper = styled.div` overflow-x : hidden; + overflow-y : hidden; `; export {LectureGroupScrollWrapper, LectureGroup}; \ No newline at end of file diff --git a/frontend/src/util/ModularRequest.jsx b/frontend/src/util/ModularRequest.jsx index 038011a..1e994c3 100644 --- a/frontend/src/util/ModularRequest.jsx +++ b/frontend/src/util/ModularRequest.jsx @@ -27,14 +27,17 @@ class ModularRequest extends React.Component{ url : url, headers : this.state.headers, data : JSON.stringify(this.state.body) - }) - + }).catch(function (error) { + if(error.response) { + if(error.response.status=="406") { + return error.response; + } + } + }); return response; } catch (e) { - console.error("error occured in modularRequest"); - console.error(e.name); - console.error(e.message); + console.error("Unknown error occurred in ModularRequest"); } } diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 4a1838c..91ed445 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -5936,6 +5936,11 @@ gzip-size@^6.0.0: dependencies: duplexer "^0.1.2" +hammerjs@^2.0.8: + version "2.0.8" + resolved "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz" + integrity sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ== + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" @@ -9672,7 +9677,7 @@ react-devtools-core@^4.26.1: shell-quote "^1.6.1" ws "^7" -react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 16.8.0", react-dom@>=16, react-dom@>=16.8: +"react-dom@^16.10.2 || ^17.0.0 || ^18.0.0", react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 16.8.0", react-dom@>=16, 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== @@ -9799,6 +9804,13 @@ react-native@*: whatwg-fetch "^3.0.0" ws "^6.2.2" +react-pull-to-refresh@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/react-pull-to-refresh/-/react-pull-to-refresh-2.0.1.tgz" + integrity sha512-mbNI9r3sBF4X+2fBO8c9CuXDLIywNuoZ24AIGU3Odi+L8C4MpS0tuhMQUSg5cSOuUtDFkE8Z/YnBYixo10QI6Q== + dependencies: + hammerjs "^2.0.8" + react-refresh@^0.11.0, "react-refresh@>=0.10.0 <1.0.0": version "0.11.0" resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz" @@ -9887,6 +9899,11 @@ react-shallow-renderer@^16.15.0: object-assign "^4.1.1" react-is "^16.12.0 || ^17.0.0 || ^18.0.0" +react-simple-pull-to-refresh@^1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/react-simple-pull-to-refresh/-/react-simple-pull-to-refresh-1.3.3.tgz" + integrity sha512-6qXsa5RtNVmKJhLWvDLIX8UK51HFtCEGjdqQGf+M1Qjrcc4qH4fki97sgVpGEFBRwbY7DiVDA5N5p97kF16DTw== + react-toastify@^9.1.1: version "9.1.1" resolved "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.1.tgz" @@ -9894,7 +9911,7 @@ react-toastify@^9.1.1: dependencies: clsx "^1.1.1" -react@*, "react@^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, "react@>= 16", "react@>= 16.3.0", "react@>= 16.8.0", react@>=16, react@>=16.8, react@>=17.0.0, react@18.2.0: +react@*, "react@^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.10.2 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, "react@>= 16", "react@>= 16.3.0", "react@>= 16.8.0", react@>=16, react@>=16.8, react@>=16.8.0, react@>=17.0.0, react@18.2.0: version "18.2.0" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==