diff --git a/afew-test-dataset/workbook/workbook1.json b/afew-test-dataset/workbook/workbook1.json new file mode 100644 index 0000000..3aded8a --- /dev/null +++ b/afew-test-dataset/workbook/workbook1.json @@ -0,0 +1,6 @@ +{ + "title": "사소한 것의 역사 - 기술편", + "articleIds": [ + + ] +} \ No newline at end of file diff --git a/afew-test-dataset/writer/writer.json b/afew-test-dataset/writer/writer.json new file mode 100644 index 0000000..e69de29 diff --git a/afew-test-dataset/writer/writer1/article1/article1.json b/afew-test-dataset/writer/writer1/article1/article1.json new file mode 100644 index 0000000..e69de29 diff --git a/afew-test-dataset/writer/writer1/article1/article1.md b/afew-test-dataset/writer/writer1/article1/article1.md new file mode 100644 index 0000000..21050ef --- /dev/null +++ b/afew-test-dataset/writer/writer1/article1/article1.md @@ -0,0 +1,109 @@ +# 예나 지금이나 같은 킥보드 문제 + +소재: 전동 킥보드의 역사 +발행일: 2024년 6월 10일 +인사이트: No + + + +***Comment.*** + +--- + +시작하기에 앞서 자료 조사를 하면서 가장 애를 먹었던 부분은 킥보드와 스쿠터의 차이가 무엇인지에 대한 것이었습니다. 우리나라에서는 안장 여부로 킥보드와 스쿠터를 구분합니다. 하지만 영어로는 안장 여부와 상관없이 모두 스쿠터입니다. 킥보드는 ‘수영 발차기를 연습할 때 사용하는 물에 뜨는 직사각형 판’을 의미하죠. + +그러면 왜 우리나라에서는 스쿠터를 킥보드라고 부르는 걸까요? 1999년 K2 Sports에서 출시한 스쿠터 브랜드 킥보드*Kickboard* 에서 유래된 것으로 추정됩니다. 이 제품은 2000년 4월 한국에 처음 들어와 대학가를 시작으로 인기를 끌었고, 킥보드라는 브랜드 이름이 일반 명사가 된 것이죠. + +이 글에서는 보드형 바닥이 있고, 두 발이 보드 위에 얹는 형태의 탈 것을 스쿠터라고 정의하고 조사했습니다. + +**- 목차 -** + +### *Fig.1* 100년 전 킥보드 + +![***Figure.1*** 1916년 오토페드를 타고 있는 영국의 참정권 운동가인 플로렌스 노먼 부인](res/1.png) + +***Figure.1*** 1916년 오토페드를 타고 있는 영국의 참정권 운동가인 플로렌스 노먼 부인 + +최초의 전동 스쿠터는 뉴욕의 롱아일랜드 시티 오토페디드 컴퍼니*Autoped Company of Long Island City* 에서 1915년에 출시했습니다. 앞바퀴를 동력으로 하는 155cc 4기통 가솔린 엔진을 탑재해 시속 57km까지 달릴 수 있었죠. 게다가 보관이 용이하도록 핸들 바가 접혔는데요. 무게가 110kg에 육박해 휴대용으로 쓰였는지는 미지수입니다. + +오토페드의 가격는 100달러로 당시 미국인들 평균 연봉이 687달러인 것을 감안하면 2~3달 치 월급에 해당했지만 그래도 자동차보다는 저렴했기 때문에 “가격이 매우 저렴해서 거의 모든 사람이 구입할 수 있다고”고 광고했죠. + +![***Figure.2*** 미국 우정국에서 오토페드를 사용하는 모습](res/2.png) + +***Figure.2*** 미국 우정국에서 오토페드를 사용하는 모습 + +오토페드는 미국 우정국과 경찰청과 계약을 맺기도 했고, 캘리포니아 해변에서는 관광용 대여 사업을 하기도 했죠. 오토페드는 저렴(?)하고 쉽게 탈 수 있었기 때문에 불량 청소년들과 갱단들에게도 퍼졌습니다. 그리고 브루클린, 퀸스, 맨해튼에서 이들의 난폭 운전이 사회적으로 문제가 되었죠. 이런저런 이유에서 판매가 부진했고, 1921년 미국 생산이 중단되었습니다. + +### *Fig.1* 대공항 고연비의 스쿠터의 등장 + +![***Figure.3*** 오토글라이드 광고 ⓒAACA Library](res/3.png) + +***Figure.3*** 오토글라이드 광고 ⓒAACA Library + +오토페드의 몰락 이후 스쿠터가 사라지나 싶었는데, 1929년 미국에서 대공항 시기에 되살아납니다. 당시 가장 유명했던 스쿠터 모델은 오토글라이드*auto.glide* 였습니다. 엔진을 제조하던 쿠시맨*Cushman* 이라는 회사에서 대공항으로 엔진이 팔리지 않자 자사 엔진을 탑재한 값싼 스쿠터를 제작한 것이었죠. 의자와 전조등을 추가해 우리나라에서 의미하는 스쿠터의 모습을 보입니다. 오토글라이드는 저렴하고 연비가 좋아 인기를 끕니다. 쿠시맨 스쿠터는 제2차 세계대전 당시 미군에서 널리 사용되었고, 전쟁 전후에도 자동차 대안으로 사용되었죠. + +![***Figure.4*** 1938년 험프리 보가트와 앨런 젠킨스가 워너 브라더스의 경비원에게 스쿠터를 타고 과속을 하다 제지당하는 모습 ⒸGetty Images, via Mashable](res/4.png) + +***Figure.4*** 1938년 험프리 보가트와 앨런 젠킨스가 워너 브라더스의 경비원에게 스쿠터를 타고 과속을 하다 제지당하는 모습 ⒸGetty Images, via Mashable + +또한 스쿠터는 할리우드의 넓은 스튜디오 부지를 돌아다니는 이동 수단으로 쓰였는데요. 험프리 보가트*Humphrey Bogart* 와 같은 스타들이 스쿠터를 타고 있는 모습이 사진으로 찍히며 더욱 인기를 얻게 되었죠. + +그러나 1930년대 들어 미국의 교통법규가 강화되고 청소년들의 운전에 대한 규제 수위도 높아지면서, 오토글라이드는 판매에 직격탄을 맞게 되었습니다. + +### *Fig.1* 스쿠터의 역사 + +![***Figure.5*** 로마의 휴일에서 나오는 베스파](res/5.png) + +***Figure.5*** 로마의 휴일에서 나오는 베스파 + +2차 세계대전 당시 항공기 부품을 만들던 이탈리아의 피아지오*Piaggio*는 전쟁이 끝난 후 연합군에 의한 제재 및 항공기 제작 수요가 없어 어려움을 겪었는데요. 피아지오는 1946년 항공기 부품을 만들던 기술을 응용해 스쿠터 베스파*Vespa* 를 제작합니다. + +베스파는 당시 패전 이후 열악한 이탈리아의 경제 사정과 도로 상황에 맞아떨어지며 이탈리아에서 폭발적인 인기를 얻게 됩니다. 게다가 영화 <로마의 휴일>에서 오드리 햅번과 그레고리 펙이 베스파를 타는 장면이 나오며 세계적으로도 인지도를 얻게 되었죠. + +### *Fig.1* 전기 킥보드의 등장 + +![***Figure.5*** 1985년에 등장한 고페드](res/Go-Ped.png) + +***Figure.5*** 1985년에 등장한 고페드 + +앉아 타는 스쿠터가 발전하는 사이 두 발로 서서 타는 스쿠터는 암흑기를 맞이했는데요. 1985년 스티브 패트몬트*Steve Patmont* 가 고-페드*Go-Ped* 특허를 취득하면서 다시 두 발로 서서 타는 스쿠터가 주목받기 시작하죠. 고-페드는 처음에는 가스 구동식 스쿠터였지만, 2001년 리튬이온 배터리로 작동하는 전기 스쿠터를 출시합니다. 이 2001년 모델인 후버보드*Hoverboard* 에는 바퀴에 서스펜션을 갖추면서 승차감이 훨씬 좋아졌죠. + +### *Fig.1* 전동킥보드 공유서비스 + +![***Figure.6*** 2017년 시작한 전동 킥보드 공유 서비스, 버드](res/7.png) + +***Figure.6*** 2017년 시작한 전동 킥보드 공유 서비스, 버드 + +오늘날 전동 킥보드의 인기는 누가 뭐래도 전동 킥보드 공유 서비스가 등장하면서부터입니다. 공유 서비스가 등장하기 이전 전동 킥보드는 주로 레저용으로 사용되다가 공유형 전동킥보드 서비스가 등장하면서 이동 수단으로 사용되기 시작합니다. + +스쿠터 대여 서비스는 2012년 캘리포니아에서 시작한 스쿠터 네트웍스*Scooter Networks* 가 최초입니다. 두 발로 서서 타는 스쿠터 공유서비스의 최초는 2017년 역시 캘리포니아에서 서비스를 시작한 버드*Bird* 입니다. 참고로 스쿠터 네트웍스는 2018년에 킥보드와 전기 자전거로 확장했고 2019년 버드에 합병되었고, 버드는 2023년 12월 파산신청을 했죠. + +우리나라에서는 2018년 ‘고고씽’을 필두로 ‘씽씽’과 ‘킥고잉’ 등의 전동 킥보드 공유 서비스 업체들이 생기면서 전동 킥보드가 대중화됩니다. + +하지만 전동 킥보드에 대한 인식은 좋지 않은데요. 사용자들의 무단 주차와 난폭운전으로 인한 사고가 끊이지 않기 때문이었습니다. 국내에서는 2018년 최초로 전동킥보드로 인한 보행자 사망 사고가 발생했고, 2021년 전동 킥보드 관련 법이 개정되었죠. 파리에서는 2023년 9월부터 사용을 금지했습니다. + +### *Fig.1* 세그웨이 + +![***Figure.7*** 2001년 등장한 세그웨이](res/8.png) + +***Figure.7*** 2001년 등장한 세그웨이 + +가장 미래적인 형태의 스쿠터가 무엇일까 하면 단연 세그웨이입니다. 세그웨이는 여러 의료용 장치를 발명한 것으로 유명한 딘 카멘*Dean Kamen* 이 2001년 12월에 공개한 1인용 스쿠터입니다. 참고로 그가 개발한 의료용 기기로는 휴대용 인슐린 펌프, 서류 가방 크기의 신장투석기, 계단을 오르내릴 수 있는 휠체어 등이 있죠. + +세그웨이는 자이로 센서로 구동되어 자동으로 중심을 잡고 몸의 움직임만으로 방향 전환이 가능한 스쿠터로 최대 20km의 속도를 낼 수 있습니다. 하지만 가격이 거의 천만 원대를 호가하였고, 안정성 문제, 타 이동 수단에 비해 장점이 명확하지 않은 점 등으로 인해 인기가 사그라듭니다. 2015년에는 중국의 나인봇이 세그웨이를 인수하고, 2020년에는 생산이 중단되죠. + +***Reference.*** + +--- + +- Mike Hanlon. (2016). (The original) 100 year-old motorscooter up for sale. NEW ATLAS. URL : https://newatlas.com/original-scooter-eveready-autoped/45714/ +- TAUR. (2020). **The History of Electric Scooters. Lotus Fruit. [URL:](https://medium.com/lotus-fruit/the-history-of-the-first-electric-scooter-5c00e0053468#id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjY3NGRiYmE4ZmFlZTY5YWNhZTFiYzFiZTE5MDQ1MzY3OGY0NzI4MDMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiIyMTYyOTYwMzU4MzQtazFrNnFlMDYwczJ0cDJhMmphbTRsamRjbXMwMHN0dGcuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiIyMTYyOTYwMzU4MzQtazFrNnFlMDYwczJ0cDJhMmphbTRsamRjbXMwMHN0dGcuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDE0MjE5MDExMDI3MzgxMDMxMTciLCJlbWFpbCI6ImtzZDIxMEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmJmIjoxNzE3NjQzODgyLCJuYW1lIjoic3VkYW0ga3UgKERhbSBLKSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS9BQ2c4b2NKTHYwRHpkQzZtc1k4Q2ctQ0ZOUGJYcEkzRzhxQXY2MFVEQzQ4Vm16NFNGSjhmUEE9czk2LWMiLCJnaXZlbl9uYW1lIjoic3VkYW0iLCJmYW1pbHlfbmFtZSI6Imt1IiwiaWF0IjoxNzE3NjQ0MTgyLCJleHAiOjE3MTc2NDc3ODIsImp0aSI6ImQzODk5NzFmN2ExM2RlZGNiZmYyNTQyNmUwMjA1NWM4Mjk0MTE5N2IifQ.jLUBitT2qBBPbqTxS1_nXpsPpyB6bBzhzLqll1yFDt2OVeL4ThPByDX-VvFIEgOZla0D36fES6lIgG3MyMvpy_zVmqOocKVPAt6x8cyIdzRnnV61Uv9A0phZDqdDbv4b6uu8AVp-4vpwfmKI3y0vEt6xzmjMWZf-jSmsq83brbYM2olUdDr_YbwXcI-WGkpT8aHZeZplQcZwHpVNzyxXQ90RKlf0Ow_JL1cSVTn1BwuX3CJ7lI0ciqPTND_wUMFqKdgeyupUocCEhl3Ows2x_GF3c6AQVCDXhnlxo40F93UfFAjKeNK42WshQH898tmoxoZOlmIzhxsCTGOJJn4BBw)** +- Unkown. (2021). The amazing history of motorised scooters. ANADUE. URL : https://www.anadue.com/post/the-amazing-history-of-motorised-scooters +- Vespa Hompage. URL : https://www.vespa.com/us_EN/timeline/ +- 민병권. (2019). [토요워치]전동킥보드 원조는 1915년 美 '오토패드'...고가에 의자 없어 흥행 실패. 서울경제. URL : https://www.sedaily.com/NewsView/1VPHCS6LED +- 박혜민. (2020). **[번역기도 모르는 진짜 영어] scooter. 중앙일보. URL :** https://www.joongang.co.kr/article/23875686#home \ No newline at end of file diff --git a/afew-test-dataset/writer/writer1/article1/problems.json b/afew-test-dataset/writer/writer1/article1/problems.json new file mode 100644 index 0000000..b6b7042 --- /dev/null +++ b/afew-test-dataset/writer/writer1/article1/problems.json @@ -0,0 +1,35 @@ +[ + { + "title": "우리나라에서 스쿠터를 킥보드라고 부르게 된 이유는 무엇인가요?", + "choices": [ + "수영 발차기를 연습할 때 사용하는 판을 의미해서", + "1999년 K2 Sports에서 출시한 스쿠터 브랜드 '킥보드'에서 유래해서", + "영어로 스쿠터를 킥보드라고 부르기 때문에", + "우리나라에서는 안장 여부로 구분하기 때문에" + ], + "answer": 1, + "reason": "우리나라에서 스쿠터를 킥보드라고 부르는 이유는 1999년 K2 Sports에서 출시한 스쿠터 브랜드 '킥보드(Kickboard)'에서 유래되었기 때문입니다." + }, + { + "title": "오토페드가 판매 부진을 겪은 주요 이유는 무엇인가요?", + "choices": [ + "고가의 가격 때문에", + "자동차의 대중화 때문에", + "불량 청소년들과 갱단들에 의해 이미지가 나빠져서", + "무게가 너무 무거워서" + ], + "answer": 2, + "reason": "오토페드는 불량 청소년들과 갱단들에 의해 이미지가 나빠졌고, 이들의 난폭 운전이 사회적으로 문제가 되어 판매 부진을 겪었습니다." + }, + { + "title": "전동 킥보드가 대중화된 주요 계기는 무엇인가요?", + "choices": [ + "리튬이온 배터리의 발전", + "영화와 미디어의 홍보", + "공유 서비스의 등장", + "정부의 지원" + ], + "answer": 2, + "reason": "전동 킥보드는 공유 서비스의 등장으로 인해 대중화되었습니다. 공유형 전동 킥보드 서비스가 등장하면서 이동 수단으로 널리 사용되기 시작했습니다." + } + ] \ No newline at end of file diff --git a/afew-test-dataset/writer/writer1/article1/res/1.png b/afew-test-dataset/writer/writer1/article1/res/1.png new file mode 100644 index 0000000..6b3f5a3 Binary files /dev/null and b/afew-test-dataset/writer/writer1/article1/res/1.png differ diff --git a/afew-test-dataset/writer/writer1/article1/res/2.png b/afew-test-dataset/writer/writer1/article1/res/2.png new file mode 100644 index 0000000..21cb3cd Binary files /dev/null and b/afew-test-dataset/writer/writer1/article1/res/2.png differ diff --git a/afew-test-dataset/writer/writer1/article1/res/3.png b/afew-test-dataset/writer/writer1/article1/res/3.png new file mode 100644 index 0000000..873645d Binary files /dev/null and b/afew-test-dataset/writer/writer1/article1/res/3.png differ diff --git a/afew-test-dataset/writer/writer1/article1/res/4.png b/afew-test-dataset/writer/writer1/article1/res/4.png new file mode 100644 index 0000000..c5b2df0 Binary files /dev/null and b/afew-test-dataset/writer/writer1/article1/res/4.png differ diff --git a/afew-test-dataset/writer/writer1/article1/res/5.png b/afew-test-dataset/writer/writer1/article1/res/5.png new file mode 100644 index 0000000..56e424a Binary files /dev/null and b/afew-test-dataset/writer/writer1/article1/res/5.png differ diff --git a/afew-test-dataset/writer/writer1/article1/res/6.png b/afew-test-dataset/writer/writer1/article1/res/6.png new file mode 100644 index 0000000..0edcd27 Binary files /dev/null and b/afew-test-dataset/writer/writer1/article1/res/6.png differ diff --git a/afew-test-dataset/writer/writer1/article1/res/7.png b/afew-test-dataset/writer/writer1/article1/res/7.png new file mode 100644 index 0000000..44056db Binary files /dev/null and b/afew-test-dataset/writer/writer1/article1/res/7.png differ diff --git a/afew-test-dataset/writer/writer1/article1/res/8.png b/afew-test-dataset/writer/writer1/article1/res/8.png new file mode 100644 index 0000000..0edcd27 Binary files /dev/null and b/afew-test-dataset/writer/writer1/article1/res/8.png differ diff --git a/afew-test-dataset/writer/writer1/article1/res/Go-Ped.png b/afew-test-dataset/writer/writer1/article1/res/Go-Ped.png new file mode 100644 index 0000000..6fa3219 Binary files /dev/null and b/afew-test-dataset/writer/writer1/article1/res/Go-Ped.png differ diff --git a/afew-test-dataset/writer/writer1/writer1.json b/afew-test-dataset/writer/writer1/writer1.json new file mode 100644 index 0000000..5b6ec8f --- /dev/null +++ b/afew-test-dataset/writer/writer1/writer1.json @@ -0,0 +1,4 @@ +{ + "name": "구수담", + "articles": ["article1", "article2"] +} \ No newline at end of file diff --git a/afew-web/README.md b/afew-web/README.md index 58beeac..b87cb00 100644 --- a/afew-web/README.md +++ b/afew-web/README.md @@ -9,10 +9,10 @@ In the project directory, you can run: ### `npm start` Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in your browser. +Open [http://localhost:3000](http://localhost:3000) to view it in the browser. -The page will reload when you make changes.\ -You may also see any lint errors in the console. +The page will reload if you make edits.\ +You will also see any lint errors in the console. ### `npm test` @@ -31,40 +31,16 @@ See the section about [deployment](https://facebook.github.io/create-react-app/d ### `npm run eject` -**Note: this is a one-way operation. Once you `eject`, you can't go back!** +**Note: this is a one-way operation. Once you `eject`, you can’t go back!** -If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. +If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. -Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. -You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. +You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. ## Learn More You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). To learn React, check out the [React documentation](https://reactjs.org/). - -### Code Splitting - -This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) - -### Analyzing the Bundle Size - -This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) - -### Making a Progressive Web App - -This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) - -### Advanced Configuration - -This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) - -### Deployment - -This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) - -### `npm run build` fails to minify - -This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/afew-web/package-lock.json b/afew-web/package-lock.json index c842501..2276257 100644 --- a/afew-web/package-lock.json +++ b/afew-web/package-lock.json @@ -11,9 +11,16 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.5.2", + "@types/node": "^16.18.101", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "antd": "^5.18.3", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-router-dom": "^6.23.1", "react-scripts": "5.0.1", + "typescript": "^4.9.5", "web-vitals": "^2.1.4" } }, @@ -45,6 +52,71 @@ "node": ">=6.0.0" } }, + "node_modules/@ant-design/colors": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.0.2.tgz", + "integrity": "sha512-7KJkhTiPiLHSu+LmMJnehfJ6242OCxSlR3xHVBecYxnMW8MS/878NXct1GqYARyL59fyeFdKRxXTfvR9SnDgJg==", + "dependencies": { + "@ctrl/tinycolor": "^3.6.1" + } + }, + "node_modules/@ant-design/cssinjs": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.21.0.tgz", + "integrity": "sha512-gIilraPl+9EoKdYxnupxjHB/Q6IHNRjEXszKbDxZdsgv4sAZ9pjkCq8yanDWNvyfjp4leir2OVAJm0vxwKK8YA==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "@emotion/hash": "^0.8.0", + "@emotion/unitless": "^0.7.5", + "classnames": "^2.3.1", + "csstype": "^3.1.3", + "rc-util": "^5.35.0", + "stylis": "^4.0.13" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/@ant-design/icons": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.3.7.tgz", + "integrity": "sha512-bCPXTAg66f5bdccM4TT21SQBDO1Ek2gho9h3nO9DAKXJP4sq+5VBjrQMSxMVXSB3HyEz+cUbHQ5+6ogxCOpaew==", + "dependencies": { + "@ant-design/colors": "^7.0.0", + "@ant-design/icons-svg": "^4.4.0", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-util": "^5.31.1" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/@ant-design/icons-svg": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", + "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==" + }, + "node_modules/@ant-design/react-slick": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-1.1.2.tgz", + "integrity": "sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==", + "dependencies": { + "@babel/runtime": "^7.10.4", + "classnames": "^2.2.5", + "json2mq": "^0.2.0", + "resize-observer-polyfill": "^1.5.1", + "throttle-debounce": "^5.0.0" + }, + "peerDependencies": { + "react": ">=16.9.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", @@ -2299,6 +2371,24 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2743,25 +2833,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils/node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/@jest/fake-timers": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", @@ -3320,6 +3391,137 @@ } } }, + "node_modules/@rc-component/async-validator": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.0.4.tgz", + "integrity": "sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==", + "dependencies": { + "@babel/runtime": "^7.24.4" + }, + "engines": { + "node": ">=14.x" + } + }, + "node_modules/@rc-component/color-picker": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.3.tgz", + "integrity": "sha512-+tGGH3nLmYXTalVe0L8hSZNs73VTP5ueSHwUlDC77KKRaN7G4DS4wcpG5DTDzdcV/Yas+rzA6UGgIyzd8fS4cw==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@ctrl/tinycolor": "^3.6.1", + "classnames": "^2.2.6", + "rc-util": "^5.38.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/context": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-1.4.0.tgz", + "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/mini-decimal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rc-component/mini-decimal/-/mini-decimal-1.1.0.tgz", + "integrity": "sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==", + "dependencies": { + "@babel/runtime": "^7.18.0" + }, + "engines": { + "node": ">=8.x" + } + }, + "node_modules/@rc-component/mutate-observer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rc-component/mutate-observer/-/mutate-observer-1.1.0.tgz", + "integrity": "sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==", + "dependencies": { + "@babel/runtime": "^7.18.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/portal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rc-component/portal/-/portal-1.1.2.tgz", + "integrity": "sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==", + "dependencies": { + "@babel/runtime": "^7.18.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/tour": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.15.0.tgz", + "integrity": "sha512-h6hyILDwL+In9GAgRobwRWihLqqsD7Uft3fZGrJ7L4EiyCoxbnNYwzPXDfz7vNDhWeVyvAWQJj9fJCzpI4+b4g==", + "dependencies": { + "@babel/runtime": "^7.18.0", + "@rc-component/portal": "^1.0.0-9", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/trigger": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.0.tgz", + "integrity": "sha512-QarBCji02YE9aRFhZgRZmOpXBj0IZutRippsVBv85sxvG4FGk/vRxwAlkn3MS9zK5mwbETd86mAVg2tKqTkdJA==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@rc-component/portal": "^1.1.0", + "classnames": "^2.3.2", + "rc-motion": "^2.0.0", + "rc-resize-observer": "^1.3.1", + "rc-util": "^5.38.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@remix-run/router": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz", + "integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3639,9 +3841,9 @@ } }, "node_modules/@testing-library/dom": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", - "integrity": "sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.2.0.tgz", + "integrity": "sha512-CytIvb6tVOADRngTHGWNxH8LPgO/3hi/BdCEHOf7Qd2GvZVClhVP0Wo/QHzWhpki49Bk0b4VT6xpt3fx8HTSIw==", "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", @@ -4117,239 +4319,12 @@ } }, "node_modules/@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/jest/node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" - }, - "node_modules/@types/jest/node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/jest/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@types/jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/@types/jest/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@types/jest/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==" - }, - "node_modules/@types/jest/node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@types/jest/node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@types/jest/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/@types/jest/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==", + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" } }, "node_modules/@types/json-schema": { @@ -4368,12 +4343,9 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { - "version": "20.14.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.7.tgz", - "integrity": "sha512-uTr2m2IbJJucF3KUxgnGOZvYbN0QgkGyWxG6973HCpMYFy2KfcgYuIwkJQMQkt1VbBMlvWRbpshFTLxnxCZjKQ==", - "dependencies": { - "undici-types": "~5.26.4" - } + "version": "16.18.101", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.101.tgz", + "integrity": "sha512-AAsx9Rgz2IzG8KJ6tXd6ndNkVcu+GYB6U/SnFAaokSPNx2N7dcIIfnighYUNumvj6YS2q39Dejz5tT0NCV7CWA==" }, "node_modules/@types/node-forge": { "version": "1.3.11", @@ -5104,11 +5076,74 @@ "node": ">=4" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, + "node_modules/antd": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.18.3.tgz", + "integrity": "sha512-Dm3P8HBxoo/DiR/QZLj5Mk+rQZsSXxCCArSZACHGiklkkjW6klzlebAElOUr9NyDeFX7UnQ6LVk7vznXlnjTqQ==", + "dependencies": { + "@ant-design/colors": "^7.0.2", + "@ant-design/cssinjs": "^1.21.0", + "@ant-design/icons": "^5.3.7", + "@ant-design/react-slick": "~1.1.2", + "@babel/runtime": "^7.24.7", + "@ctrl/tinycolor": "^3.6.1", + "@rc-component/color-picker": "~1.5.3", + "@rc-component/mutate-observer": "^1.1.0", + "@rc-component/tour": "~1.15.0", + "@rc-component/trigger": "^2.2.0", + "classnames": "^2.5.1", + "copy-to-clipboard": "^3.3.3", + "dayjs": "^1.11.11", + "qrcode.react": "^3.1.0", + "rc-cascader": "~3.26.0", + "rc-checkbox": "~3.3.0", + "rc-collapse": "~3.7.3", + "rc-dialog": "~9.5.2", + "rc-drawer": "~7.2.0", + "rc-dropdown": "~4.2.0", + "rc-field-form": "~2.2.1", + "rc-image": "~7.9.0", + "rc-input": "~1.5.1", + "rc-input-number": "~9.1.0", + "rc-mentions": "~2.14.0", + "rc-menu": "~9.14.0", + "rc-motion": "^2.9.2", + "rc-notification": "~5.6.0", + "rc-pagination": "~4.0.4", + "rc-picker": "~4.5.0", + "rc-progress": "~4.0.0", + "rc-rate": "~2.13.0", + "rc-resize-observer": "^1.4.0", + "rc-segmented": "~2.3.0", + "rc-select": "~14.14.0", + "rc-slider": "~10.6.2", + "rc-steps": "~6.0.1", + "rc-switch": "~4.1.0", + "rc-table": "~7.45.7", + "rc-tabs": "~15.1.1", + "rc-textarea": "~1.7.0", + "rc-tooltip": "~6.2.0", + "rc-tree": "~5.8.8", + "rc-tree-select": "~5.21.0", + "rc-upload": "~4.5.2", + "rc-util": "^5.43.0", + "scroll-into-view-if-needed": "^3.1.0", + "throttle-debounce": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ant-design" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -5181,6 +5216,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-tree-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -6087,6 +6127,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==" }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", @@ -6244,6 +6289,11 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/compute-scroll-into-view": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz", + "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6299,6 +6349,14 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, "node_modules/core-js": { "version": "3.37.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", @@ -6793,6 +6851,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" + }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", @@ -7177,9 +7240,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.808", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.808.tgz", - "integrity": "sha512-0ItWyhPYnww2VOuCGF4s1LTfbrdAV2ajy/TN+ZTuhR23AHI6rWHCrBXJ/uxoXOvRRqw8qjYVrG81HFI7x/2wdQ==" + "version": "1.4.810", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.810.tgz", + "integrity": "sha512-Kaxhu4T7SJGpRQx99tq216gCq2nMxJo+uuT6uzz9l8TVN2stL7M06MIIXAtr9jsrLs2Glflgf2vMQRepxawOdQ==" }, "node_modules/emittery": { "version": "0.8.1", @@ -7376,9 +7439,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", - "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==" + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" }, "node_modules/es-object-atoms": { "version": "1.0.0", @@ -12203,6 +12266,14 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, + "node_modules/json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "dependencies": { + "string-convert": "^0.2.0" + } + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -12829,9 +12900,12 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -14666,6 +14740,14 @@ "teleport": ">=0.2.0" } }, + "node_modules/qrcode.react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", + "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -14761,6 +14843,583 @@ "node": ">=0.10.0" } }, + "node_modules/rc-cascader": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.26.0.tgz", + "integrity": "sha512-L1dml383TPSJD1I11YwxuVbmqaJY64psZqFp1ETlgl3LEOwDu76Cyl11fw5dmjJhMlUWwM5dECQfqJgfebhUjg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "array-tree-filter": "^2.1.0", + "classnames": "^2.3.1", + "rc-select": "~14.14.0", + "rc-tree": "~5.8.1", + "rc-util": "^5.37.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-checkbox": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.3.0.tgz", + "integrity": "sha512-Ih3ZaAcoAiFKJjifzwsGiT/f/quIkxJoklW4yKGho14Olulwn8gN7hOBve0/WGDg5o/l/5mL0w7ff7/YGvefVw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.3.2", + "rc-util": "^5.25.2" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-collapse": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.3.tgz", + "integrity": "sha512-60FJcdTRn0X5sELF18TANwtVi7FtModq649H11mYF1jh83DniMoM4MqY627sEKRCTm4+WXfGDcB7hY5oW6xhyw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dialog": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.5.2.tgz", + "integrity": "sha512-qVUjc8JukG+j/pNaHVSRa2GO2/KbV2thm7yO4hepQ902eGdYK913sGkwg/fh9yhKYV1ql3BKIN2xnud3rEXAPw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/portal": "^1.0.0-8", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.21.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-drawer": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.2.0.tgz", + "integrity": "sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@rc-component/portal": "^1.1.1", + "classnames": "^2.2.6", + "rc-motion": "^2.6.1", + "rc-util": "^5.38.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dropdown": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.2.0.tgz", + "integrity": "sha512-odM8Ove+gSh0zU27DUj5cG1gNKg7mLWBYzB5E4nNLrLwBmYEgYP43vHKDGOVZcJSVElQBI0+jTQgjnq0NfLjng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.2.6", + "rc-util": "^5.17.0" + }, + "peerDependencies": { + "react": ">=16.11.0", + "react-dom": ">=16.11.0" + } + }, + "node_modules/rc-field-form": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-2.2.1.tgz", + "integrity": "sha512-uoNqDoR7A4tn4QTSqoWPAzrR7ZwOK5I+vuZ/qdcHtbKx+ZjEsTg7QXm2wk/jalDiSksAQmATxL0T5LJkRREdIA==", + "dependencies": { + "@babel/runtime": "^7.18.0", + "@rc-component/async-validator": "^5.0.3", + "rc-util": "^5.32.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-image": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.9.0.tgz", + "integrity": "sha512-l4zqO5E0quuLMCtdKfBgj4Suv8tIS011F5k1zBBlK25iMjjiNHxA0VeTzGFtUZERSA45gvpXDg8/P6qNLjR25g==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "@rc-component/portal": "^1.0.2", + "classnames": "^2.2.6", + "rc-dialog": "~9.5.2", + "rc-motion": "^2.6.2", + "rc-util": "^5.34.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-input": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.5.1.tgz", + "integrity": "sha512-+nOzQJDeIfIpNP/SgY45LXSKbuMlp4Yap2y8c+ZpU7XbLmNzUd6+d5/S75sA/52jsVE6S/AkhkkDEAOjIu7i6g==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.18.1" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/rc-input-number": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.1.0.tgz", + "integrity": "sha512-NqJ6i25Xn/AgYfVxynlevIhX3FuKlMwIFpucGG1h98SlK32wQwDK0zhN9VY32McOmuaqzftduNYWWooWz8pXQA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/mini-decimal": "^1.0.1", + "classnames": "^2.2.5", + "rc-input": "~1.5.0", + "rc-util": "^5.40.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-mentions": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.14.0.tgz", + "integrity": "sha512-qKR59FMuF8PK4ZqsbWX3UuA5P1M/snzyqV6Yt3y1DCFbCEdqUGIBgQp6vEfLCO6Z0RoRFlzXtCeSlBTcDDpg1A==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.2.6", + "rc-input": "~1.5.0", + "rc-menu": "~9.14.0", + "rc-textarea": "~1.7.0", + "rc-util": "^5.34.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-menu": { + "version": "9.14.1", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.14.1.tgz", + "integrity": "sha512-5wlRb3M8S4yGlWhSoEYJ7ZVRElyScdcpUHxgiLxkeig1tEdyKrnED3B2fhpN0Rrpdp9jyhnmZR/Lwq2fH5VvDQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^2.0.0", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.3.1", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-motion": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.2.tgz", + "integrity": "sha512-fUAhHKLDdkAXIDLH0GYwof3raS58dtNUmzLF2MeiR8o6n4thNpSDQhOqQzWE4WfFZDCi9VEN8n7tiB7czREcyw==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.43.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-notification": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.6.0.tgz", + "integrity": "sha512-TGQW5T7waOxLwgJG7fXcw8l7AQiFOjaZ7ISF5PrU526nunHRNcTMuzKihQHaF4E/h/KfOCDk3Mv8eqzbu2e28w==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.9.0", + "rc-util": "^5.20.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-overflow": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.3.2.tgz", + "integrity": "sha512-nsUm78jkYAoPygDAcGZeC2VwIg/IBGSodtOY3pMof4W3M9qRJgqaDYm03ZayHlde3I6ipliAxbN0RUcGf5KOzw==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.37.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-pagination": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-4.0.4.tgz", + "integrity": "sha512-GGrLT4NgG6wgJpT/hHIpL9nELv27A1XbSZzECIuQBQTVSf4xGKxWr6I/jhpRPauYEWEbWVw22ObG6tJQqwJqWQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.3.2", + "rc-util": "^5.38.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-picker": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.5.0.tgz", + "integrity": "sha512-suqz9bzuhBQlf7u+bZd1bJLPzhXpk12w6AjQ9BTPTiFwexVZgUKViG1KNLyfFvW6tCUZZK0HmCCX7JAyM+JnCg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.2.1", + "rc-overflow": "^1.3.2", + "rc-resize-observer": "^1.4.0", + "rc-util": "^5.38.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "date-fns": ">= 2.x", + "dayjs": ">= 1.x", + "luxon": ">= 3.x", + "moment": ">= 2.x", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + }, + "peerDependenciesMeta": { + "date-fns": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + } + } + }, + "node_modules/rc-progress": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-4.0.0.tgz", + "integrity": "sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-util": "^5.16.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-rate": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.13.0.tgz", + "integrity": "sha512-oxvx1Q5k5wD30sjN5tqAyWTvJfLNNJn7Oq3IeS4HxWfAiC4BOXMITNAsw7u/fzdtO4MS8Ki8uRLOzcnEuoQiAw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-resize-observer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz", + "integrity": "sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==", + "dependencies": { + "@babel/runtime": "^7.20.7", + "classnames": "^2.2.1", + "rc-util": "^5.38.0", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-segmented": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.3.0.tgz", + "integrity": "sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-motion": "^2.4.4", + "rc-util": "^5.17.0" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/rc-select": { + "version": "14.14.0", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.14.0.tgz", + "integrity": "sha512-Uo2wulrjoPPRLCPd7zlK4ZFVJxlTN//yp1xWP/U+TUOQCyXrT+Duvq/Si5OzVcmQyWAUSbsplc2OwNNhvbOeKQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^2.1.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.3.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-slider": { + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.6.2.tgz", + "integrity": "sha512-FjkoFjyvUQWcBo1F3RgSglky3ar0+qHLM41PlFVYB4Bj3RD8E/Mv7kqMouLFBU+3aFglMzzctAIWRwajEuueSw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.36.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-steps": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-6.0.1.tgz", + "integrity": "sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==", + "dependencies": { + "@babel/runtime": "^7.16.7", + "classnames": "^2.2.3", + "rc-util": "^5.16.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-switch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-4.1.0.tgz", + "integrity": "sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "classnames": "^2.2.1", + "rc-util": "^5.30.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-table": { + "version": "7.45.7", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.45.7.tgz", + "integrity": "sha512-wi9LetBL1t1csxyGkMB2p3mCiMt+NDexMlPbXHvQFmBBAsMxrgNSAPwUci2zDLUq9m8QdWc1Nh8suvrpy9mXrg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/context": "^1.4.0", + "classnames": "^2.2.5", + "rc-resize-observer": "^1.1.0", + "rc-util": "^5.37.0", + "rc-virtual-list": "^3.14.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tabs": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-15.1.1.tgz", + "integrity": "sha512-Tc7bJvpEdkWIVCUL7yQrMNBJY3j44NcyWS48jF/UKMXuUlzaXK+Z/pEL5LjGcTadtPvVmNqA40yv7hmr+tCOAw==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "2.x", + "rc-dropdown": "~4.2.0", + "rc-menu": "~9.14.0", + "rc-motion": "^2.6.2", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.34.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-textarea": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.7.0.tgz", + "integrity": "sha512-UxizYJkWkmxP3zofXgc487QiGyDmhhheDLLjIWbFtDmiru1ls30KpO8odDaPyqNUIy9ugj5djxTEuezIn6t3Jg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-input": "~1.5.0", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tooltip": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.2.0.tgz", + "integrity": "sha512-iS/3iOAvtDh9GIx1ulY7EFUXUtktFccNLsARo3NPgLf0QW9oT0w3dA9cYWlhqAKmD+uriEwdWz1kH0Qs4zk2Aw==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tree": { + "version": "5.8.8", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.8.8.tgz", + "integrity": "sha512-S+mCMWo91m5AJqjz3PdzKilGgbFm7fFJRFiTDOcoRbD7UfMOPnerXwMworiga0O2XIo383UoWuEfeHs1WOltag==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.1" + }, + "engines": { + "node": ">=10.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-tree-select": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.21.0.tgz", + "integrity": "sha512-w+9qEu6zh0G3wt9N/hzWNSnqYH1i9mH1Nqxo0caxLRRFXF5yZWYmpCDoDTMdQM1Y4z3Q5yj08qyrPH/d4AtumA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-select": "~14.14.0", + "rc-tree": "~5.8.1", + "rc-util": "^5.16.1" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-upload": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.5.2.tgz", + "integrity": "sha512-QO3ne77DwnAPKFn0bA5qJM81QBjQi0e0NHdkvpFyY73Bea2NfITiotqJqVjHgeYPOJu5lLVR32TNGP084aSoXA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.5", + "rc-util": "^5.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.43.0.tgz", + "integrity": "sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "react-is": "^18.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/rc-virtual-list": { + "version": "3.14.3", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.14.3.tgz", + "integrity": "sha512-6+6wiEhdqakNBnbRJymgMlh+90qpkgqherTRo1l1cX7mK6F9hWsazPczmP0lA+64yhC9/t+M9Dh5pjvDWimn8A==", + "dependencies": { + "@babel/runtime": "^7.20.0", + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.36.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -14997,6 +15656,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz", + "integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==", + "dependencies": { + "@remix-run/router": "1.16.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz", + "integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==", + "dependencies": { + "@remix-run/router": "1.16.1", + "react-router": "6.23.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -15271,6 +15960,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -15670,6 +16364,14 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, + "node_modules/scroll-into-view-if-needed": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", + "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==", + "dependencies": { + "compute-scroll-into-view": "^3.0.2" + } + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -16185,6 +16887,11 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -16431,6 +17138,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -16856,6 +17568,14 @@ "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" }, + "node_modules/throttle-debounce": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", + "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", + "engines": { + "node": ">=12.22" + } + }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -16885,6 +17605,11 @@ "node": ">=8.0" } }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -17113,7 +17838,6 @@ "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -17141,11 +17865,6 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", diff --git a/afew-web/package.json b/afew-web/package.json index c122cba..ea4aee8 100644 --- a/afew-web/package.json +++ b/afew-web/package.json @@ -6,9 +6,16 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.5.2", + "@types/node": "^16.18.101", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "antd": "^5.18.3", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-router-dom": "^6.23.1", "react-scripts": "5.0.1", + "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, "scripts": { diff --git a/afew-web/src/App.css b/afew-web/src/App.css index 74b5e05..3fb5b35 100644 --- a/afew-web/src/App.css +++ b/afew-web/src/App.css @@ -36,3 +36,13 @@ transform: rotate(360deg); } } + +/* src/App.css */ +body, html, #root { + height: 100%; +} + +#root { + padding: 20px; + box-sizing: border-box; +} \ No newline at end of file diff --git a/afew-web/src/App.js b/afew-web/src/App.js deleted file mode 100644 index 3784575..0000000 --- a/afew-web/src/App.js +++ /dev/null @@ -1,25 +0,0 @@ -import logo from './logo.svg'; -import './App.css'; - -function App() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); -} - -export default App; diff --git a/afew-web/src/App.test.js b/afew-web/src/App.test.tsx similarity index 90% rename from afew-web/src/App.test.js rename to afew-web/src/App.test.tsx index 1f03afe..2a68616 100644 --- a/afew-web/src/App.test.js +++ b/afew-web/src/App.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { render, screen } from '@testing-library/react'; import App from './App'; diff --git a/afew-web/src/App.tsx b/afew-web/src/App.tsx new file mode 100644 index 0000000..ed5a21f --- /dev/null +++ b/afew-web/src/App.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { BrowserRouter as Router, Routes, Route, useNavigate } from 'react-router-dom'; +import AdminPage from './pages/AdminPage'; +import WriterDetailPage from './pages/WriterDetailPage'; +import WorkbookDetailPage from './pages/WorkbookDetailPage'; +import './App.css'; + +const App: React.FC = () => ( + + + } /> + } /> + } /> + + +); + +export default App; \ No newline at end of file diff --git a/afew-web/src/components/ArticleSearch.tsx b/afew-web/src/components/ArticleSearch.tsx new file mode 100644 index 0000000..616acb9 --- /dev/null +++ b/afew-web/src/components/ArticleSearch.tsx @@ -0,0 +1,45 @@ +import React, { useState } from 'react'; +import { Input, List, Button } from 'antd'; +import { searchArticles } from '../services/ArticleService'; +import { Article } from '../types/Article'; + +interface ArticleSearchProps { + onAdd: (articleId: string) => void; +} + +const ArticleSearch: React.FC = ({ onAdd }) => { + const [query, setQuery] = useState(''); + const [results, setResults] = useState([]); + + const handleSearch = async () => { + const articles = await searchArticles(query); + setResults(articles); + }; + + return ( +
+ setQuery(e.target.value)} + onSearch={handleSearch} + /> + ( + onAdd(item.id)}>Add]} + > + + + )} + /> +
+ ); +}; + +export default ArticleSearch; \ No newline at end of file diff --git a/afew-web/src/components/WriterList.tsx b/afew-web/src/components/WriterList.tsx new file mode 100644 index 0000000..2ff82b9 --- /dev/null +++ b/afew-web/src/components/WriterList.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { List } from 'antd'; +import { useNavigate } from 'react-router-dom'; +import { Writer } from '../types/Writer'; + +interface WriterListProps { + writers: Writer[]; +} + +const WriterList: React.FC = ({ writers }) => { + const navigate = useNavigate(); + + const goToDetail = (id: number) => { + navigate(`/writers/${id}`); + }; + + return ( + ( + + goToDetail(item.id)}>{item.name}} + description={item.description} + /> + + )} + /> + ); +}; + +export default WriterList; \ No newline at end of file diff --git a/afew-web/src/components/workbook/WorkbookList.tsx b/afew-web/src/components/workbook/WorkbookList.tsx new file mode 100644 index 0000000..0ebf0ba --- /dev/null +++ b/afew-web/src/components/workbook/WorkbookList.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { List } from 'antd'; +import { useNavigate } from 'react-router-dom'; +import { Workbook } from '../../types/Workbook'; + +interface WorkbookListProps { + workbooks: Workbook[]; +} + +const WorkbookList: React.FC = ({ workbooks }) => { + const navigate = useNavigate(); + + const goToDetail = (id: number) => { + navigate(`/workbooks/${id}`); + }; + + return ( + ( + + goToDetail(item.id)}>{item.title}} + description={item.description} + /> + + )} + /> + ); +}; + +export default WorkbookList; \ No newline at end of file diff --git a/afew-web/src/index.js b/afew-web/src/index.tsx similarity index 85% rename from afew-web/src/index.js rename to afew-web/src/index.tsx index d563c0f..032464f 100644 --- a/afew-web/src/index.js +++ b/afew-web/src/index.tsx @@ -4,7 +4,9 @@ import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; -const root = ReactDOM.createRoot(document.getElementById('root')); +const root = ReactDOM.createRoot( + document.getElementById('root') as HTMLElement +); root.render( diff --git a/afew-web/src/pages/AdminPage.tsx b/afew-web/src/pages/AdminPage.tsx new file mode 100644 index 0000000..80e5c53 --- /dev/null +++ b/afew-web/src/pages/AdminPage.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Tabs } from 'antd'; +import WritersPage from './WritersPage'; +import WorkbooksPage from './WorkbooksPage'; + +const { TabPane } = Tabs; + +const AdminPage: React.FC = () => ( + + + + + + + + +); + +export default AdminPage; \ No newline at end of file diff --git a/afew-web/src/pages/WorkbookDetailPage.tsx b/afew-web/src/pages/WorkbookDetailPage.tsx new file mode 100644 index 0000000..1b534f4 --- /dev/null +++ b/afew-web/src/pages/WorkbookDetailPage.tsx @@ -0,0 +1,80 @@ +import React, { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import { Form, Input, Button, List } from 'antd'; +import { getWorkbook, updateWorkbook } from '../services/WorkbookService'; +import { Workbook } from '../types/Workbook'; +import ArticleSearch from '../components/ArticleSearch'; + +const WorkbookDetailPage: React.FC = () => { + const { id } = useParams<{ id: string }>(); + const [workbook, setWorkbook] = useState(null); + const [form] = Form.useForm(); + + useEffect(() => { + const fetchWorkbook = async () => { + const workbookData = await getWorkbook(Number(id)); + if (workbookData) { + setWorkbook(workbookData); + form.setFieldsValue(workbookData); + } else { + // Handle the case when the workbook is not found + console.error('Workbook not found'); + } + }; + fetchWorkbook(); + }, [id, form]); + + const onFinish = async (values: any) => { + if (workbook) { + const updatedWorkbook = { ...workbook, ...values }; + await updateWorkbook(workbook.id, updatedWorkbook); + setWorkbook(updatedWorkbook); + } + }; + + const addArticleToWorkbook = (articleId: string) => { + if (workbook) { + const updatedArticles = [...workbook.referencedArticles, articleId]; + const updatedWorkbook = { ...workbook, referencedArticles: updatedArticles }; + setWorkbook(updatedWorkbook); + form.setFieldsValue(updatedWorkbook); + } + }; + + return workbook ? ( +
+

{workbook.title} 상세 페이지

+
+ + + + + + + + + + + + +
+

아티클 리스트

+ + ( + + + + )} + /> +
+ ) : ( +
Loading...
+ ); +}; + +export default WorkbookDetailPage; \ No newline at end of file diff --git a/afew-web/src/pages/WorkbooksPage.tsx b/afew-web/src/pages/WorkbooksPage.tsx new file mode 100644 index 0000000..fd1f07b --- /dev/null +++ b/afew-web/src/pages/WorkbooksPage.tsx @@ -0,0 +1,25 @@ +import React, { useState, useEffect } from 'react'; +import WorkbookList from '../components/workbook/WorkbookList'; +import { getWorkbooks } from '../services/WorkbookService'; +import { Workbook } from '../types/Workbook'; + +const WorkbooksPage: React.FC = () => { + const [workbooks, setWorkbooks] = useState([]); + + useEffect(() => { + const fetchWorkbooks = async () => { + const workbooks = await getWorkbooks(); + setWorkbooks(workbooks); + }; + fetchWorkbooks(); + }, []); + + return ( +
+

학습지 관리

+ +
+ ); +}; + +export default WorkbooksPage; \ No newline at end of file diff --git a/afew-web/src/pages/WriterDetailPage.tsx b/afew-web/src/pages/WriterDetailPage.tsx new file mode 100644 index 0000000..94c774a --- /dev/null +++ b/afew-web/src/pages/WriterDetailPage.tsx @@ -0,0 +1,59 @@ +import React, { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import { Form, Input, Button } from 'antd'; +import { getWriter, updateWriter } from '../services/WriterService'; +import { Writer } from '../types/Writer'; + +const WriterDetailPage: React.FC = () => { + const { id } = useParams<{ id: string }>(); + const [writer, setWriter] = useState(null); + const [form] = Form.useForm(); + + useEffect(() => { + const fetchWriter = async () => { + const writerData = await getWriter(Number(id)); + if (writerData) { + setWriter(writerData); + form.setFieldsValue(writerData); + } else { + // Handle the case when the writer is not found + console.error('Writer not found'); + } + }; + fetchWriter(); + }, [id, form]); + + const onFinish = async (values: any) => { + if (writer) { + await updateWriter(writer.id, values); + setWriter({ ...writer, ...values }); + } + }; + + return writer ? ( +
+

{writer.name} 상세 페이지

+
+ + + + + + + + + +
+

아티클 리스트

+
    + {writer.articles.map(article => ( +
  • {article}
  • + ))} +
+
+ ) : ( +
Loading...
+ ); +}; + +export default WriterDetailPage; \ No newline at end of file diff --git a/afew-web/src/pages/WritersPage.tsx b/afew-web/src/pages/WritersPage.tsx new file mode 100644 index 0000000..3328092 --- /dev/null +++ b/afew-web/src/pages/WritersPage.tsx @@ -0,0 +1,25 @@ +import React, { useState, useEffect } from 'react'; +import WriterList from '../components/WriterList'; +import { getWriters } from '../services/WriterService'; +import { Writer } from '../types/Writer'; + +const WritersPage: React.FC = () => { + const [writers, setWriters] = useState([]); + + useEffect(() => { + const fetchWriters = async () => { + const writers = await getWriters(); + setWriters(writers); + }; + fetchWriters(); + }, []); + + return ( +
+

작가 관리

+ +
+ ); +}; + +export default WritersPage; \ No newline at end of file diff --git a/afew-web/src/react-app-env.d.ts b/afew-web/src/react-app-env.d.ts new file mode 100644 index 0000000..6431bc5 --- /dev/null +++ b/afew-web/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/afew-web/src/reportWebVitals.js b/afew-web/src/reportWebVitals.ts similarity index 75% rename from afew-web/src/reportWebVitals.js rename to afew-web/src/reportWebVitals.ts index 5253d3a..49a2a16 100644 --- a/afew-web/src/reportWebVitals.js +++ b/afew-web/src/reportWebVitals.ts @@ -1,4 +1,6 @@ -const reportWebVitals = onPerfEntry => { +import { ReportHandler } from 'web-vitals'; + +const reportWebVitals = (onPerfEntry?: ReportHandler) => { if (onPerfEntry && onPerfEntry instanceof Function) { import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { getCLS(onPerfEntry); diff --git a/afew-web/src/services/ArticleService.ts b/afew-web/src/services/ArticleService.ts new file mode 100644 index 0000000..266e938 --- /dev/null +++ b/afew-web/src/services/ArticleService.ts @@ -0,0 +1,12 @@ +import { Article } from '../types/Article'; + +const articles: Article[] = [ + { id: '1', title: '아티클 1', description: '아티클 1 소개' }, + { id: '2', title: '아티클 2', description: '아티클 2 소개' }, + { id: '3', title: '아티클 3', description: '아티클 3 소개' }, + { id: '4', title: '아티클 4', description: '아티클 4 소개' } +]; + +export const searchArticles = async (query: string): Promise => { + return articles.filter(article => article.title.includes(query) || article.description.includes(query)); +}; \ No newline at end of file diff --git a/afew-web/src/services/WorkbookService.ts b/afew-web/src/services/WorkbookService.ts new file mode 100644 index 0000000..5589881 --- /dev/null +++ b/afew-web/src/services/WorkbookService.ts @@ -0,0 +1,18 @@ +import { Workbook } from '../types/Workbook'; + +let workbooks: Workbook[] = [ + { id: 1, thumbnail: '', title: '학습지 1', description: '학습지 1 소개', referencedArticles: ['아티클 1', '아티클 3'] }, + { id: 2, thumbnail: '', title: '학습지 2', description: '학습지 2 소개', referencedArticles: ['아티클 2', '아티클 4'] } +]; + +export const getWorkbooks = async (): Promise => { + return workbooks; +}; + +export const getWorkbook = async (id: number): Promise => { + return workbooks.find(workbook => workbook.id === id); +}; + +export const updateWorkbook = async (id: number, data: Partial): Promise => { + workbooks = workbooks.map(workbook => (workbook.id === id ? { ...workbook, ...data } : workbook)); +}; \ No newline at end of file diff --git a/afew-web/src/services/WriterService.ts b/afew-web/src/services/WriterService.ts new file mode 100644 index 0000000..bc7b57b --- /dev/null +++ b/afew-web/src/services/WriterService.ts @@ -0,0 +1,18 @@ +import { Writer } from '../types/Writer'; + +let writers: Writer[] = [ + { id: 1, name: '작가 1', description: '작가 1 소개', articles: ['아티클 1', '아티클 2'] }, + { id: 2, name: '작가 2', description: '작가 2 소개', articles: ['아티클 3', '아티클 4'] } +]; + +export const getWriters = async (): Promise => { + return writers; +}; + +export const getWriter = async (id: number): Promise => { + return writers.find(writer => writer.id === id); +}; + +export const updateWriter = async (id: number, data: Partial): Promise => { + writers = writers.map(writer => (writer.id === id ? { ...writer, ...data } : writer)); +}; \ No newline at end of file diff --git a/afew-web/src/setupTests.js b/afew-web/src/setupTests.ts similarity index 100% rename from afew-web/src/setupTests.js rename to afew-web/src/setupTests.ts diff --git a/afew-web/src/types/Article.ts b/afew-web/src/types/Article.ts new file mode 100644 index 0000000..9675301 --- /dev/null +++ b/afew-web/src/types/Article.ts @@ -0,0 +1,5 @@ +export interface Article { + id: string; + title: string; + description: string; + } \ No newline at end of file diff --git a/afew-web/src/types/Workbook.ts b/afew-web/src/types/Workbook.ts new file mode 100644 index 0000000..920bfcc --- /dev/null +++ b/afew-web/src/types/Workbook.ts @@ -0,0 +1,7 @@ +export interface Workbook { + id: number; + thumbnail: string; + title: string; + description: string; + referencedArticles: string[]; + } \ No newline at end of file diff --git a/afew-web/src/types/Writer.ts b/afew-web/src/types/Writer.ts new file mode 100644 index 0000000..7ffa9ca --- /dev/null +++ b/afew-web/src/types/Writer.ts @@ -0,0 +1,6 @@ +export interface Writer { + id: number; + name: string; + description: string; + articles: string[]; +} \ No newline at end of file diff --git a/afew-web/tsconfig.json b/afew-web/tsconfig.json new file mode 100644 index 0000000..a273b0c --- /dev/null +++ b/afew-web/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": [ + "src" + ] +}