From 6365777b047e8c5deb3a9ccaee80002d1b6b487d Mon Sep 17 00:00:00 2001 From: "Glitch (a4-neha-kuchipudi)" Date: Tue, 4 Oct 2022 03:22:27 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=9F=A6=F0=9F=95=98=20Updated=20with?= =?UTF-8?q?=20Glitch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 + .glitch-assets | 2 + LICENSE | 197 ++++++ README.md | 74 +- TODO.md | 38 + index.html | 16 + package.json | 34 + shrinkwrap.yaml | 998 +++++++++++++++++++++++++++ src/AddBookForm.jsx | 33 + src/BookTable.jsx | 47 ++ src/EditBookForm.jsx | 34 + src/app.jsx | 91 +++ src/components/router.jsx | 19 + src/components/seo.jsx | 37 + src/hooks/prefers-reduced-motion.jsx | 22 + src/hooks/wiggle.jsx | 55 ++ src/index.jsx | 5 + src/pages/about.jsx | 72 ++ src/pages/home.jsx | 78 +++ src/seo.json | 7 + src/styles/styles.css | 180 +++++ vite.config.js | 16 + watch.json | 17 + 23 files changed, 2057 insertions(+), 21 deletions(-) create mode 100644 .gitignore create mode 100644 .glitch-assets create mode 100644 LICENSE create mode 100644 TODO.md create mode 100644 index.html create mode 100644 package.json create mode 100644 shrinkwrap.yaml create mode 100644 src/AddBookForm.jsx create mode 100644 src/BookTable.jsx create mode 100644 src/EditBookForm.jsx create mode 100644 src/app.jsx create mode 100644 src/components/router.jsx create mode 100644 src/components/seo.jsx create mode 100644 src/hooks/prefers-reduced-motion.jsx create mode 100644 src/hooks/wiggle.jsx create mode 100644 src/index.jsx create mode 100644 src/pages/about.jsx create mode 100644 src/pages/home.jsx create mode 100644 src/seo.json create mode 100644 src/styles/styles.css create mode 100644 vite.config.js create mode 100644 watch.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..2ef5a0221 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules +web_modules +.firebase +.firebaserc +.glitchdotcom.json +build \ No newline at end of file diff --git a/.glitch-assets b/.glitch-assets new file mode 100644 index 000000000..02ecc7695 --- /dev/null +++ b/.glitch-assets @@ -0,0 +1,2 @@ +{"name":"illustration.svg","date":"2021-04-12T03:02:59.405Z","url":"https://cdn.glitch.com/2f80c958-3bc4-4f47-8e97-6a5c8684ac2c%2Fillustration.svg","type":"image/svg+xml","size":23220,"imageWidth":541,"imageHeight":457,"thumbnail":"https://cdn.glitch.com/2f80c958-3bc4-4f47-8e97-6a5c8684ac2c%2Fthumbnails%2Fillustration.svg","thumbnailWidth":330,"thumbnailHeight":279,"uuid":"Lw1QEsxPiPIxc4fR"} +{"name":"books.png","date":"2022-10-04T02:19:05.241Z","url":"https://cdn.glitch.global/853df0d5-2f4b-473e-8b63-34f080880c96/books.png","type":"image/png","size":55795,"imageWidth":1965,"imageHeight":912,"thumbnail":"https://cdn.glitch.global/853df0d5-2f4b-473e-8b63-34f080880c96/thumbnails%2Fbooks.png","thumbnailWidth":330,"thumbnailHeight":154,"uuid":"dRHCUsBKmq9W3BU1"} diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..f526e5768 --- /dev/null +++ b/LICENSE @@ -0,0 +1,197 @@ +The LICENSE file for any project gives credit to the creator/author of the +project, copyright information for the project, and the legal terms under +which it's being shared. In other words, this is us using an MIT license to +say "we wrote this and you can do whatever you want with it." + +****************************************************************************** +~glitch-hello-react +****************************************************************************** +MIT License + +Copyright (c) 2021, Glitch, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + + +****************************************************************************** + +THIRD-PARTY SOFTWARE +This is all the software we used to build this starter project. All of these +licenses are compatible with the license above. We've included links so you +can learn more if you want. + +1. react: React is a JavaScript library for building user interfaces. +2. react-spring: A spring-physics based animation library. +3. vite: Vite is a new breed of frontend build tool. +4. @vitejs/plugin-react: An all in one Vite plugin for React. +5. wouter: wouter is a tiny router for modern React and Preact apps. +6. HK Grotesk: The font we're using. + + +****************************************************************************** +1. react +URL: https://reactjs.org/ + https://github.com/facebook/react +****************************************************************************** +MIT License + +Copyright (c) Facebook, Inc. and its affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +****************************************************************************** +END, react +****************************************************************************** + + +****************************************************************************** +2. react-spring +URL: https://www.react-spring.io/ + https://github.com/pmndrs/react-spring +****************************************************************************** +MIT License + +Copyright (c) 2018-present Paul Henschel, react-spring, all contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +****************************************************************************** +END, react-spring +****************************************************************************** + + +****************************************************************************** +3. vite +URL: https://vitejs.dev/ + https://github.com/vitejs/vite +****************************************************************************** +MIT License + +Copyright (c) 2019-present, Yuxi (Evan) You and Vite contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +****************************************************************************** +END, vite +****************************************************************************** + + +****************************************************************************** +4. @vitejs/plugin-react +URL: https://github.com/vitejs/vite +****************************************************************************** +MIT License + +Copyright (c) 2020-present, Yuxi (Evan) You + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +****************************************************************************** +END, @vitejs/plugin-react +****************************************************************************** + + +****************************************************************************** +5. wouter +URL: https://github.com/molefrog/wouter + https://www.npmjs.com/package/wouter +****************************************************************************** +ISC License + +wouter is published to npm (https://www.npmjs.com/package/wouter) under an +ISC license. No additional copyright information is present on the project's +github or npm pages as of April 11, 2021. +****************************************************************************** +END, wouter +****************************************************************************** + + +****************************************************************************** +6. HK Grotesk +URL: https://hanken.co/products/hk-grotesk +****************************************************************************** +HK Grotesk was designed by Hanken Design Co. It is shared using a SIL OFL +license. Full license text can be found at: + +https://hanken.co/pages/web-fonts-eula +****************************************************************************** +END, HK Grotesk +****************************************************************************** \ No newline at end of file diff --git a/README.md b/README.md index 027584c5e..95e26e321 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,65 @@ -Assignment 4 - Components -=== +# Hello React! -Due: October 4th, by 11:59 AM. +This project contains a foundation for building and learning about React apps. The site includes two routes showing how navigation works in a single page app. We manage the page head and body using a standard React flow. The homepage features a click effect that demonstrates using state, and an animation you can try out yourself by following the steps in `TODO.md`. 💫 -For this assignment you will re-implement the client side portion of *either* A2 or A3 using either React or Svelte components. If you choose A3 you only need to use components for the data display / updating; you can leave your login UI as is. +[React](https://reactjs.org/) is a popular UI library for building web apps. [Vite](https://vitejs.dev/) is a powerful tool for building javascript apps that bundles all of your code and shows immediate changes while you're editing. -[Svelte Tutorial](https://github.com/cs4241-21a/cs4241-21a.github.io/blob/main/using_svelte.md) -[React Tutorial](https://github.com/cs4241-21a/cs4241-21a.github.io/blob/main/using_react.md) +_While you're in the editor working, Glitch is running your `start` script in the background (`vite dev`). The site will be in dev mode and you'll see your changes happen ✨ immediately in the preview window. Once you close the editor window and your app goes to sleep, Glitch runs the `build` script and Vite builds your app for modern browsers._ -This project can be implemented on any hosting service (Glitch, DigitalOcean, Heroku etc.), however, you must include all files in your GitHub repo so that the course staff can view them. +## Prerequisites -Deliverables ---- +You'll get best use out of this project if you're familiar with basic JavaScript. This project is a static site, which means that the server builds the site from the content of the `src` folder while you're developing it, then it's able to serve the pages super quickly when the user requests them. -Do the following to complete this assignment: +## What's in this project? -1. Implement your project with the above requirements. -3. Test your project to make sure that when someone goes to your main page on Glitch/Heroku/etc., it displays correctly. -4. Ensure that your project has the proper naming scheme `a4-firstname-lastname` so we can find it. -5. Fork this repository and modify the README to the specifications below. Be sure to add *all* project files. -6. Create and submit a Pull Request to the original repo. Name the pull request using the following template: `a4-firstname-lastname`. +← `README.md`: That’s this file, where you can tell people what your cool website does and how you built it. -Sample Readme (delete the above when you're ready to submit, and modify the below so with your links and descriptions) ---- +← `index.html`: This is the main page template React uses to build your site–it imports `index.jsx` to kick things off. When you're ready to share your site or add a custom domain, change SEO/meta settings in here. -## Your Web Application Title +← `src/`: This folder contains all the files React will use to build your site. -your hosting link e.g. http://a4-charlieroberts.glitch.me +### Working in the `src/` folder 📁 -Include a very brief summary of your project here and what you changed / added to assignment #3. Briefly (3–4 sentences) answer the following question: did the new technology improve or hinder the development experience? +React defines site components in [JSX](https://reactjs.org/docs/introducing-jsx.html), an extended version of JavaScript, so you'll see lots of `.jsx` files in the project. -Unlike previous assignments, this assignment will be solely graded on whether or not you successfully complete it. Partial credit will be generously given. +← `src/index.jsx`: This is the root of your React app. The index script is imported in the site home template `index.html`. If you add libraries like [chakra-ui](https://chakra-ui.com) or [redux](https://react-redux.js.org), you'll insert their providers here. The ` is an example of a provider you'd use. + +← `src/app.jsx`: The base for defining your React app, this script imports the components that make up the site content. The `index.jsx` file imports the App script. The router (from [wouter](https://github.com/molefrog/wouter) 🐰) is also imported here. + +← `src/styles`: CSS files add styling rules to your content. You have [a lot of](https://vitejs.dev/guide/features.html#css) importing options for CSS including CSS modules if that's your jam. + +← `src/components/router.jsx`: One of the most important parts of a single page app is the router. It's how we know what page to show–the code maps the paths to the Home and About components. We're using [Wouter](https://github.com/molefrog/wouter), a tiny minimalist router. You could replace it for something like [React Router](https://reactrouter.com/). + +← `src/components/seo.jsx`: When you share your site on social media, you'll want to make sure the meta tags are correct and that you've got an image. All of the settings for this file are in `src/seo.json`. + +### Hooks 🪝 + +← `src/hooks/`: [Hooks](https://reactjs.org/docs/hooks-intro.html) are a powerful way to provide interaction with your app. + +← `src/hooks/prefers-reduced-motion.jsx`: For accessibility reasons, some users will indicate in their system settings that they prefer motion effects to be minimized–this allows you to hold off on these effects in such cases. + +← `src/hooks/wiggle.jsx`: The wiggle effect animates elements, as you'll see if you hover over the image (or text below it) on the homepage. You can apply the effect anywhere you like in the site as outlined in `TODO.md`. + +### Pages 📃 + +← `src/pages/`: These files include components that specify the content of the Home and About pages. Each one is defined as a function and referenced in `router.jsx`. The content is built into the page outline specified in `app.jsx`. + +← `src/pages/about.jsx`: The content of the About page, defined as a component function. + +← `src/pages/home.jsx` The content of the Home page, also defined as a component function. The page includes the animated effect on hover, and title change effect on click (which is also a handy demo of using state data in React). + +## Try this next 🏗️ + +Take a look in `TODO.md` for next steps you can try out in your new site! + +**_Want a minimal version of this project to build your own React app? Check out [Blank React](https://glitch.com/edit/#!/remix/glitch-blank-react)!_** + +![Glitch](https://cdn.glitch.com/a9975ea6-8949-4bab-addb-8a95021dc2da%2FLogo_Color.svg?v=1602781328576) + +## You built this with Glitch! + +[Glitch](https://glitch.com) is a friendly community where millions of people come together to build web apps and websites. + +- Want more details about React on Glitch? We've got a [Help Center article](https://help.glitch.com/kb/article/112) for you. +- Need more help? [Check out our Help Center](https://help.glitch.com/) for answers to any common questions. +- Ready to make it official? [Become a paid Glitch member](https://glitch.com/pricing) to boost your app with private sharing, more storage and memory, domains and more. diff --git a/TODO.md b/TODO.md new file mode 100644 index 000000000..2b434603a --- /dev/null +++ b/TODO.md @@ -0,0 +1,38 @@ +# TODO 🚧 + +Your new site is all yours so it doesn't matter if you break it! Try editing the code. + +Let's add the wiggle function to other elements in the site–you'll see comments in the code with `TODO` in them for each step. + +In `pages/about.jsx`, add the imports at the top: + +```js +import { useWiggle } from "../hooks/wiggle"; +import { animated } from "react-spring"; +``` + +Bring the wiggle style and trigger function in before the `return` statement, this time with slightly different parameters: + +```js +const [style, trigger] = useWiggle({ x: 50, rotation: 1, scale: 1.2 }); +``` + +Replace the header element to use `animated` and apply the wiggle style: + +```js + + About this site + +``` + +Let's make the effect happen when the user hovers over the first paragraph element by replacing its opening tag: + +```js +

+``` + +Hover over the paragraph to see the effect on the About page header! + +## Keep going! 🚀 + +Try experimenting with the `useWiggle` properties for different effects! diff --git a/index.html b/index.html new file mode 100644 index 000000000..7ebe8eb39 --- /dev/null +++ b/index.html @@ -0,0 +1,16 @@ + + + + + + + Hello React! + + + + + +

+ + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 000000000..8c14bb54b --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "glitch-hello-react", + "version": "0.0.5", + "description": "A simple React single page app, built with Vite and React.", + "scripts": { + "start": "vite", + "build": "vite build", + "serve": "vite preview" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-spring": "^9.4.5", + "wouter": "^2.7.4", + "react-helmet-async": "^1.3.0", + "@vitejs/plugin-react": "^1.3.2" + }, + "devDependencies": { + "vite": "^2.4.4" + }, + "browserslist": [ + ">0.2%", + "not dead" + ], + "engines": { + "node": "12.x" + }, + "repository": { + "url": "https://glitch.com/edit/#!/glitch-hello-react" + }, + "glitch": { + "projectType": "generated_static" + } +} \ No newline at end of file diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml new file mode 100644 index 000000000..1afeb4f64 --- /dev/null +++ b/shrinkwrap.yaml @@ -0,0 +1,998 @@ +dependencies: + '@vitejs/plugin-react': 1.3.2 + react: 18.0.0 + react-dom: 18.0.0 + react-helmet-async: 1.3.0 + react-spring: 9.4.5 + wouter: 2.7.5 +devDependencies: + vite: 2.7.13 +packages: + /@ampproject/remapping/2.2.0: + dependencies: + '@jridgewell/gen-mapping': 0.1.1 + '@jridgewell/trace-mapping': 0.3.10 + dev: false + engines: + node: '>=6.0.0' + resolution: + integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + /@babel/code-frame/7.16.7: + dependencies: + '@babel/highlight': 7.17.9 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + /@babel/compat-data/7.17.10: + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw== + /@babel/core/7.17.10/@babel!core@7.17.10: + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.16.7 + '@babel/generator': 7.17.10 + '@babel/helper-compilation-targets': /@babel/helper-compilation-targets/7.17.10/@babel!core@7.17.10 + '@babel/helper-module-transforms': 7.17.7 + '@babel/helpers': 7.17.9 + '@babel/parser': 7.17.10 + '@babel/template': 7.16.7 + '@babel/traverse': 7.17.10 + '@babel/types': 7.17.10 + convert-source-map: 1.8.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.1 + semver: 6.3.0 + dev: false + engines: + node: '>=6.9.0' + id: registry.npmjs.org/@babel/core/7.17.10 + resolution: + integrity: sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA== + /@babel/generator/7.17.10: + dependencies: + '@babel/types': 7.17.10 + '@jridgewell/gen-mapping': 0.1.1 + jsesc: 2.5.2 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg== + /@babel/helper-annotate-as-pure/7.16.7: + dependencies: + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== + /@babel/helper-compilation-targets/7.17.10/@babel!core@7.17.10: + dependencies: + '@babel/compat-data': 7.17.10 + '@babel/core': /@babel/core/7.17.10/@babel!core@7.17.10 + '@babel/helper-validator-option': 7.16.7 + browserslist: 4.20.3 + semver: 6.3.0 + dev: false + engines: + node: '>=6.9.0' + id: registry.npmjs.org/@babel/helper-compilation-targets/7.17.10 + peerDependencies: + '@babel/core': ^7.0.0 + resolution: + integrity: sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ== + /@babel/helper-environment-visitor/7.16.7: + dependencies: + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + /@babel/helper-function-name/7.17.9: + dependencies: + '@babel/template': 7.16.7 + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== + /@babel/helper-hoist-variables/7.16.7: + dependencies: + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + /@babel/helper-module-imports/7.16.7: + dependencies: + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + /@babel/helper-module-transforms/7.17.7: + dependencies: + '@babel/helper-environment-visitor': 7.16.7 + '@babel/helper-module-imports': 7.16.7 + '@babel/helper-simple-access': 7.17.7 + '@babel/helper-split-export-declaration': 7.16.7 + '@babel/helper-validator-identifier': 7.16.7 + '@babel/template': 7.16.7 + '@babel/traverse': 7.17.10 + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== + /@babel/helper-plugin-utils/7.16.7: + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== + /@babel/helper-simple-access/7.17.7: + dependencies: + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== + /@babel/helper-split-export-declaration/7.16.7: + dependencies: + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + /@babel/helper-validator-identifier/7.16.7: + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + /@babel/helper-validator-option/7.16.7: + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + /@babel/helpers/7.17.9: + dependencies: + '@babel/template': 7.16.7 + '@babel/traverse': 7.17.10 + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== + /@babel/highlight/7.17.9: + dependencies: + '@babel/helper-validator-identifier': 7.16.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== + /@babel/parser/7.17.10: + dev: false + engines: + node: '>=6.0.0' + hasBin: true + resolution: + integrity: sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ== + /@babel/plugin-syntax-jsx/7.16.7/@babel!core@7.17.10: + dependencies: + '@babel/core': /@babel/core/7.17.10/@babel!core@7.17.10 + '@babel/helper-plugin-utils': 7.16.7 + dev: false + engines: + node: '>=6.9.0' + id: registry.npmjs.org/@babel/plugin-syntax-jsx/7.16.7 + peerDependencies: + '@babel/core': ^7.0.0-0 + resolution: + integrity: sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q== + /@babel/plugin-transform-react-jsx-development/7.16.7/@babel!core@7.17.10: + dependencies: + '@babel/core': /@babel/core/7.17.10/@babel!core@7.17.10 + '@babel/plugin-transform-react-jsx': /@babel/plugin-transform-react-jsx/7.17.3/@babel!core@7.17.10 + dev: false + engines: + node: '>=6.9.0' + id: registry.npmjs.org/@babel/plugin-transform-react-jsx-development/7.16.7 + peerDependencies: + '@babel/core': ^7.0.0-0 + resolution: + integrity: sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A== + /@babel/plugin-transform-react-jsx-self/7.16.7/@babel!core@7.17.10: + dependencies: + '@babel/core': /@babel/core/7.17.10/@babel!core@7.17.10 + '@babel/helper-plugin-utils': 7.16.7 + dev: false + engines: + node: '>=6.9.0' + id: registry.npmjs.org/@babel/plugin-transform-react-jsx-self/7.16.7 + peerDependencies: + '@babel/core': ^7.0.0-0 + resolution: + integrity: sha512-oe5VuWs7J9ilH3BCCApGoYjHoSO48vkjX2CbA5bFVhIuO2HKxA3vyF7rleA4o6/4rTDbk6r8hBW7Ul8E+UZrpA== + /@babel/plugin-transform-react-jsx-source/7.16.7/@babel!core@7.17.10: + dependencies: + '@babel/core': /@babel/core/7.17.10/@babel!core@7.17.10 + '@babel/helper-plugin-utils': 7.16.7 + dev: false + engines: + node: '>=6.9.0' + id: registry.npmjs.org/@babel/plugin-transform-react-jsx-source/7.16.7 + peerDependencies: + '@babel/core': ^7.0.0-0 + resolution: + integrity: sha512-rONFiQz9vgbsnaMtQlZCjIRwhJvlrPET8TabIUK2hzlXw9B9s2Ieaxte1SCOOXMbWRHodbKixNf3BLcWVOQ8Bw== + /@babel/plugin-transform-react-jsx/7.17.3/@babel!core@7.17.10: + dependencies: + '@babel/core': /@babel/core/7.17.10/@babel!core@7.17.10 + '@babel/helper-annotate-as-pure': 7.16.7 + '@babel/helper-module-imports': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + '@babel/plugin-syntax-jsx': /@babel/plugin-syntax-jsx/7.16.7/@babel!core@7.17.10 + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + id: registry.npmjs.org/@babel/plugin-transform-react-jsx/7.17.3 + peerDependencies: + '@babel/core': ^7.0.0-0 + resolution: + integrity: sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ== + /@babel/runtime/7.17.9: + dependencies: + regenerator-runtime: 0.13.9 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== + /@babel/template/7.16.7: + dependencies: + '@babel/code-frame': 7.16.7 + '@babel/parser': 7.17.10 + '@babel/types': 7.17.10 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + /@babel/traverse/7.17.10: + dependencies: + '@babel/code-frame': 7.16.7 + '@babel/generator': 7.17.10 + '@babel/helper-environment-visitor': 7.16.7 + '@babel/helper-function-name': 7.17.9 + '@babel/helper-hoist-variables': 7.16.7 + '@babel/helper-split-export-declaration': 7.16.7 + '@babel/parser': 7.17.10 + '@babel/types': 7.17.10 + debug: 4.3.4 + globals: 11.12.0 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw== + /@babel/types/7.17.10: + dependencies: + '@babel/helper-validator-identifier': 7.16.7 + to-fast-properties: 2.0.0 + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A== + /@jridgewell/gen-mapping/0.1.1: + dependencies: + '@jridgewell/set-array': 1.1.1 + '@jridgewell/sourcemap-codec': 1.4.13 + dev: false + engines: + node: '>=6.0.0' + resolution: + integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + /@jridgewell/resolve-uri/3.0.7: + dev: false + engines: + node: '>=6.0.0' + resolution: + integrity: sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA== + /@jridgewell/set-array/1.1.1: + dev: false + engines: + node: '>=6.0.0' + resolution: + integrity: sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ== + /@jridgewell/sourcemap-codec/1.4.13: + dev: false + resolution: + integrity: sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w== + /@jridgewell/trace-mapping/0.3.10: + dependencies: + '@jridgewell/resolve-uri': 3.0.7 + '@jridgewell/sourcemap-codec': 1.4.13 + dev: false + resolution: + integrity: sha512-Q0YbBd6OTsXm8Y21+YUSDXupHnodNC2M4O18jtd3iwJ3+vMZNdKGols0a9G6JOK0dcJ3IdUUHoh908ZI6qhk8Q== + /@react-spring/animated/9.4.5: + dependencies: + '@react-spring/shared': 9.4.5 + '@react-spring/types': 9.4.5 + dev: false + peerDependencies: + react: ^16.8.0 || >=17.0.0 || >=18.0.0 + resolution: + integrity: sha512-KWqrtvJSMx6Fj9nMJkhTwM9r6LIriExDRV6YHZV9HKQsaolUFppgkOXpC+rsL1JEtEvKv6EkLLmSqHTnuYjiIA== + /@react-spring/core/9.4.5: + dependencies: + '@react-spring/animated': 9.4.5 + '@react-spring/rafz': 9.4.5 + '@react-spring/shared': 9.4.5 + '@react-spring/types': 9.4.5 + dev: false + peerDependencies: + react: ^16.8.0 || >=17.0.0 || >=18.0.0 + resolution: + integrity: sha512-83u3FzfQmGMJFwZLAJSwF24/ZJctwUkWtyPD7KYtNagrFeQKUH1I05ZuhmCmqW+2w1KDW1SFWQ43RawqfXKiiQ== + /@react-spring/konva/9.4.5: + dependencies: + '@react-spring/animated': 9.4.5 + '@react-spring/core': 9.4.5 + '@react-spring/shared': 9.4.5 + '@react-spring/types': 9.4.5 + dev: false + peerDependencies: + konva: '>=2.6' + react: ^16.8.0 || >=17.0.0 || >=18.0.0 + react-konva: ^16.8.0 || ^17.0.0 + resolution: + integrity: sha512-b3wTs7YT5102+Gs488r2JCNBoyZQd+SWg35AdxmiI6FARBFvBjIA0z7VJx8ILAlmTVBows5UwiDWvk2vmWmLLw== + /@react-spring/native/9.4.5: + dependencies: + '@react-spring/animated': 9.4.5 + '@react-spring/core': 9.4.5 + '@react-spring/shared': 9.4.5 + '@react-spring/types': 9.4.5 + dev: false + peerDependencies: + react: ^16.8.0 || >=17.0.0 || >=18.0.0 + react-native: '>=0.58' + resolution: + integrity: sha512-11GcqFZfIhOOVQI25FcDLdeJLOSVOgIh2AF6WMXpCNWguhIv6N33zLL8d4cYfhYhsLOVXprU/8uefNorj7/h3g== + /@react-spring/rafz/9.4.5: + dev: false + resolution: + integrity: sha512-swGsutMwvnoyTRxvqhfJBtGM8Ipx6ks0RkIpNX9F/U7XmyPvBMGd3GgX/mqxZUpdlsuI1zr/jiYw+GXZxAlLcQ== + /@react-spring/shared/9.4.5: + dependencies: + '@react-spring/rafz': 9.4.5 + '@react-spring/types': 9.4.5 + dev: false + peerDependencies: + react: ^16.8.0 || >=17.0.0 || >=18.0.0 + resolution: + integrity: sha512-JhMh3nFKsqyag0KM5IIM8BQANGscTdd0mMv3BXsUiMZrcjQTskyfnv5qxEeGWbJGGar52qr5kHuBHtCjQOzniA== + /@react-spring/three/9.4.5: + dependencies: + '@react-spring/animated': 9.4.5 + '@react-spring/core': 9.4.5 + '@react-spring/shared': 9.4.5 + '@react-spring/types': 9.4.5 + dev: false + peerDependencies: + '@react-three/fiber': '>=6.0' + react: ^16.11.0 || >=17.0.0 || >=18.0.0 + three: '>=0.126' + resolution: + integrity: sha512-mArxfIhg9kyFL/8Y09TarS/ZKLd/qAWS4T3Ro/B46ILPfPnoPywDdw9/rknZihy/tslnviCgMrB4pZ29X1Dfxw== + /@react-spring/types/9.4.5: + dev: false + resolution: + integrity: sha512-mpRIamoHwql0ogxEUh9yr4TP0xU5CWyZxVQeccGkHHF8kPMErtDXJlxyo0lj+telRF35XNihtPTWoflqtyARmg== + /@react-spring/web/9.4.5: + dependencies: + '@react-spring/animated': 9.4.5 + '@react-spring/core': 9.4.5 + '@react-spring/shared': 9.4.5 + '@react-spring/types': 9.4.5 + dev: false + peerDependencies: + react: ^16.8.0 || >=17.0.0 || >=18.0.0 + react-dom: ^16.8.0 || >=17.0.0 || >=18.0.0 + resolution: + integrity: sha512-NGAkOtKmOzDEctL7MzRlQGv24sRce++0xAY7KlcxmeVkR7LRSGkoXHaIfm9ObzxPMcPHQYQhf3+X9jepIFNHQA== + /@react-spring/zdog/9.4.5: + dependencies: + '@react-spring/animated': 9.4.5 + '@react-spring/core': 9.4.5 + '@react-spring/shared': 9.4.5 + '@react-spring/types': 9.4.5 + dev: false + peerDependencies: + react: ^16.8.0 || >=17.0.0 || >=18.0.0 + react-dom: ^16.8.0 || >=17.0.0 || >=18.0.0 + react-zdog: '>=1.0' + zdog: '>=1.0' + resolution: + integrity: sha512-STrePM34ZK1T3oK8mo71pvKxvIzELJTpVi0U0qDh0s15e9rmN6XYkd406LqFtuchhmLoy24lD4ds7LAqhIEraw== + /@rollup/pluginutils/4.2.1: + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: false + engines: + node: '>= 8.0.0' + resolution: + integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== + /@vitejs/plugin-react/1.3.2: + dependencies: + '@babel/core': /@babel/core/7.17.10/@babel!core@7.17.10 + '@babel/plugin-transform-react-jsx': /@babel/plugin-transform-react-jsx/7.17.3/@babel!core@7.17.10 + '@babel/plugin-transform-react-jsx-development': /@babel/plugin-transform-react-jsx-development/7.16.7/@babel!core@7.17.10 + '@babel/plugin-transform-react-jsx-self': /@babel/plugin-transform-react-jsx-self/7.16.7/@babel!core@7.17.10 + '@babel/plugin-transform-react-jsx-source': /@babel/plugin-transform-react-jsx-source/7.16.7/@babel!core@7.17.10 + '@rollup/pluginutils': 4.2.1 + react-refresh: 0.13.0 + resolve: 1.22.0 + dev: false + engines: + node: '>=12.0.0' + resolution: + integrity: sha512-aurBNmMo0kz1O4qRoY+FM4epSA39y3ShWGuqfLRA/3z0oEJAdtoSfgA3aO98/PCCHAqMaduLxIxErWrVKIFzXA== + /ansi-styles/3.2.1: + dependencies: + color-convert: 1.9.3 + dev: false + engines: + node: '>=4' + resolution: + integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + /browserslist/4.20.3: + dependencies: + caniuse-lite: 1.0.30001338 + electron-to-chromium: 1.4.137 + escalade: 3.1.1 + node-releases: 2.0.4 + picocolors: 1.0.0 + dev: false + engines: + node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 + hasBin: true + resolution: + integrity: sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg== + /caniuse-lite/1.0.30001338: + dev: false + resolution: + integrity: sha512-1gLHWyfVoRDsHieO+CaeYe7jSo/MT7D7lhaXUiwwbuR5BwQxORs0f1tAwUSQr3YbxRXJvxHM/PA5FfPQRnsPeQ== + /chalk/2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: false + engines: + node: '>=4' + resolution: + integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + /color-convert/1.9.3: + dependencies: + color-name: 1.1.3 + dev: false + resolution: + integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + /color-name/1.1.3: + dev: false + resolution: + integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + /convert-source-map/1.8.0: + dependencies: + safe-buffer: 5.1.2 + dev: false + resolution: + integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + /debug/4.3.4: + dependencies: + ms: 2.1.2 + dev: false + engines: + node: '>=6.0' + resolution: + integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + /electron-to-chromium/1.4.137: + dev: false + resolution: + integrity: sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA== + /esbuild-android-arm64/0.13.15: + cpu: + - arm64 + dev: true + optional: true + os: + - android + resolution: + integrity: sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg== + /esbuild-darwin-64/0.13.15: + cpu: + - x64 + dev: true + optional: true + os: + - darwin + resolution: + integrity: sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ== + /esbuild-darwin-arm64/0.13.15: + cpu: + - arm64 + dev: true + optional: true + os: + - darwin + resolution: + integrity: sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ== + /esbuild-freebsd-64/0.13.15: + cpu: + - x64 + dev: true + optional: true + os: + - freebsd + resolution: + integrity: sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA== + /esbuild-freebsd-arm64/0.13.15: + cpu: + - arm64 + dev: true + optional: true + os: + - freebsd + resolution: + integrity: sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ== + /esbuild-linux-32/0.13.15: + cpu: + - ia32 + dev: true + optional: true + os: + - linux + resolution: + integrity: sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g== + /esbuild-linux-64/0.13.15: + cpu: + - x64 + dev: true + optional: true + os: + - linux + resolution: + integrity: sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA== + /esbuild-linux-arm/0.13.15: + cpu: + - arm + dev: true + optional: true + os: + - linux + resolution: + integrity: sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA== + /esbuild-linux-arm64/0.13.15: + cpu: + - arm64 + dev: true + optional: true + os: + - linux + resolution: + integrity: sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA== + /esbuild-linux-mips64le/0.13.15: + cpu: + - mips64el + dev: true + optional: true + os: + - linux + resolution: + integrity: sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg== + /esbuild-linux-ppc64le/0.13.15: + cpu: + - ppc64 + dev: true + optional: true + os: + - linux + resolution: + integrity: sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ== + /esbuild-netbsd-64/0.13.15: + cpu: + - x64 + dev: true + optional: true + os: + - netbsd + resolution: + integrity: sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w== + /esbuild-openbsd-64/0.13.15: + cpu: + - x64 + dev: true + optional: true + os: + - openbsd + resolution: + integrity: sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g== + /esbuild-sunos-64/0.13.15: + cpu: + - x64 + dev: true + optional: true + os: + - sunos + resolution: + integrity: sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw== + /esbuild-windows-32/0.13.15: + cpu: + - ia32 + dev: true + optional: true + os: + - win32 + resolution: + integrity: sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw== + /esbuild-windows-64/0.13.15: + cpu: + - x64 + dev: true + optional: true + os: + - win32 + resolution: + integrity: sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ== + /esbuild-windows-arm64/0.13.15: + cpu: + - arm64 + dev: true + optional: true + os: + - win32 + resolution: + integrity: sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA== + /esbuild/0.13.15: + dev: true + hasBin: true + optionalDependencies: + esbuild-android-arm64: 0.13.15 + esbuild-darwin-64: 0.13.15 + esbuild-darwin-arm64: 0.13.15 + esbuild-freebsd-64: 0.13.15 + esbuild-freebsd-arm64: 0.13.15 + esbuild-linux-32: 0.13.15 + esbuild-linux-64: 0.13.15 + esbuild-linux-arm: 0.13.15 + esbuild-linux-arm64: 0.13.15 + esbuild-linux-mips64le: 0.13.15 + esbuild-linux-ppc64le: 0.13.15 + esbuild-netbsd-64: 0.13.15 + esbuild-openbsd-64: 0.13.15 + esbuild-sunos-64: 0.13.15 + esbuild-windows-32: 0.13.15 + esbuild-windows-64: 0.13.15 + esbuild-windows-arm64: 0.13.15 + requiresBuild: true + resolution: + integrity: sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw== + /escalade/3.1.1: + dev: false + engines: + node: '>=6' + resolution: + integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + /escape-string-regexp/1.0.5: + dev: false + engines: + node: '>=0.8.0' + resolution: + integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + /estree-walker/2.0.2: + dev: false + resolution: + integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + /fsevents/2.3.2: + dev: true + engines: + node: ^8.16.0 || ^10.6.0 || >=11.0.0 + optional: true + os: + - darwin + resolution: + integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + /function-bind/1.1.1: + resolution: + integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + /gensync/1.0.0-beta.2: + dev: false + engines: + node: '>=6.9.0' + resolution: + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + /globals/11.12.0: + dev: false + engines: + node: '>=4' + resolution: + integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + /has-flag/3.0.0: + dev: false + engines: + node: '>=4' + resolution: + integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + /has/1.0.3: + dependencies: + function-bind: 1.1.1 + engines: + node: '>= 0.4.0' + resolution: + integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + /invariant/2.2.4: + dependencies: + loose-envify: 1.4.0 + dev: false + resolution: + integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + /is-core-module/2.8.1: + dependencies: + has: 1.0.3 + resolution: + integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + /js-tokens/4.0.0: + dev: false + resolution: + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + /jsesc/2.5.2: + dev: false + engines: + node: '>=4' + hasBin: true + resolution: + integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + /json5/2.2.1: + dev: false + engines: + node: '>=6' + hasBin: true + resolution: + integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + /loose-envify/1.4.0: + dependencies: + js-tokens: 4.0.0 + dev: false + hasBin: true + resolution: + integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + /ms/2.1.2: + dev: false + resolution: + integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + /nanoid/3.2.0: + dev: true + engines: + node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 + hasBin: true + resolution: + integrity: sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== + /node-releases/2.0.4: + dev: false + resolution: + integrity: sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ== + /object-assign/4.1.1: + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + /path-parse/1.0.7: + resolution: + integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + /picocolors/1.0.0: + resolution: + integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + /picomatch/2.3.1: + dev: false + engines: + node: '>=8.6' + resolution: + integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + /postcss/8.4.5: + dependencies: + nanoid: 3.2.0 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + engines: + node: ^10 || ^12 || >=14 + resolution: + integrity: sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== + /prop-types/15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: false + resolution: + integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + /react-dom/18.0.0: + dependencies: + loose-envify: 1.4.0 + scheduler: 0.21.0 + dev: false + peerDependencies: + react: ^18.0.0 + resolution: + integrity: sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw== + /react-fast-compare/3.2.0: + dev: false + resolution: + integrity: sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== + /react-helmet-async/1.3.0: + dependencies: + '@babel/runtime': 7.17.9 + invariant: 2.2.4 + prop-types: 15.8.1 + react-fast-compare: 3.2.0 + shallowequal: 1.1.0 + dev: false + peerDependencies: + react: ^16.6.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0 + resolution: + integrity: sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg== + /react-is/16.13.1: + dev: false + resolution: + integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + /react-refresh/0.13.0: + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha512-XP8A9BT0CpRBD+NYLLeIhld/RqG9+gktUjW1FkE+Vm7OCinbG1SshcK5tb9ls4kzvjZr9mOQc7HYgBngEyPAXg== + /react-spring/9.4.5: + dependencies: + '@react-spring/core': 9.4.5 + '@react-spring/konva': 9.4.5 + '@react-spring/native': 9.4.5 + '@react-spring/three': 9.4.5 + '@react-spring/web': 9.4.5 + '@react-spring/zdog': 9.4.5 + dev: false + resolution: + integrity: sha512-FRIXQGR+jG+Fx4UcqhF0b5jMEU3Q5QcZ8rEVWKqZgrrn92C1HcqtuZy7dH+rZ6uNGjnlV7HBf8iprJaJ+350LA== + /react/18.0.0: + dependencies: + loose-envify: 1.4.0 + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A== + /regenerator-runtime/0.13.9: + dev: false + resolution: + integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + /resolve/1.22.0: + dependencies: + is-core-module: 2.8.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + hasBin: true + resolution: + integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + /rollup/2.66.1: + dev: true + engines: + node: '>=10.0.0' + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + resolution: + integrity: sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w== + /safe-buffer/5.1.2: + dev: false + resolution: + integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + /scheduler/0.21.0: + dependencies: + loose-envify: 1.4.0 + dev: false + resolution: + integrity: sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ== + /semver/6.3.0: + dev: false + hasBin: true + resolution: + integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + /shallowequal/1.1.0: + dev: false + resolution: + integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + /source-map-js/1.0.2: + dev: true + engines: + node: '>=0.10.0' + resolution: + integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + /supports-color/5.5.0: + dependencies: + has-flag: 3.0.0 + dev: false + engines: + node: '>=4' + resolution: + integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + /supports-preserve-symlinks-flag/1.0.0: + engines: + node: '>= 0.4' + resolution: + integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + /to-fast-properties/2.0.0: + dev: false + engines: + node: '>=4' + resolution: + integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + /vite/2.7.13: + dependencies: + esbuild: 0.13.15 + postcss: 8.4.5 + resolve: 1.22.0 + rollup: 2.66.1 + dev: true + engines: + node: '>=12.2.0' + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + peerDependencies: + less: '*' + sass: '*' + stylus: '*' + resolution: + integrity: sha512-Mq8et7f3aK0SgSxjDNfOAimZGW9XryfHRa/uV0jseQSilg+KhYDSoNb9h1rknOy6SuMkvNDLKCYAYYUMCE+IgQ== + /wouter/2.7.5: + dev: false + peerDependencies: + react: '>=16.8.0' + resolution: + integrity: sha512-TOI9gD1wa7a8wW+lh3rjg0C+MjYGKMV3eC+++6D+7n1z36ZJIBPWe2G9Hs1jYNPsV7oKiPTI3UFC5TGhZjQfrQ== +registry: 'https://registry.npmjs.org/' +shrinkwrapMinorVersion: 9 +shrinkwrapVersion: 3 +specifiers: + '@vitejs/plugin-react': ^1.3.2 + react: ^18.0.0 + react-dom: ^18.0.0 + react-helmet-async: ^1.3.0 + react-spring: ^9.4.5 + vite: ^2.4.4 + wouter: ^2.7.4 diff --git a/src/AddBookForm.jsx b/src/AddBookForm.jsx new file mode 100644 index 000000000..916015ffe --- /dev/null +++ b/src/AddBookForm.jsx @@ -0,0 +1,33 @@ +import React, {useState} from 'react'; + +const AddUserForm = (props) => { + + const initBook = {id: null, bookName: '', author: '', totalPages: '', pagesRead: '', pagesLeft: ''}; + + const [book, setBook] = useState(initBook); + + const handleChange = e => { + const {name, value} = e.target; + setBook({...book, [name]: value}); + } + + const handleSubmit = e => { + e.preventDefault(); + book.pagesLeft = book.totalPages - book.pagesRead; + if (book.bookName && book.author && book.totalPages && book.pagesRead && book.pagesLeft) { + handleChange(e, props.addBook(book)); + } + } + + return ( +
+ + + + + +
+ ) +} + +export default AddUserForm; \ No newline at end of file diff --git a/src/BookTable.jsx b/src/BookTable.jsx new file mode 100644 index 000000000..93479c8ae --- /dev/null +++ b/src/BookTable.jsx @@ -0,0 +1,47 @@ +import React from 'react'; + +const UserTable = (props) => { + return ( + + + + + + + + + + + + + + { props.books.length > 0 ? ( + props.books.map(book => { + const {id, bookName, author, totalPages, pagesRead, pagesLeft} = book; + return ( + + + + + + + + + + ) + }) + ) : ( + + + + ) + } + +
IDBook NameAuthorTotal PagesPages ReadPages LeftActions
{id}{bookName}{author}{totalPages}{pagesRead}{pagesLeft} + + +
No books on your bookshelf.
+ ) +} + +export default UserTable; \ No newline at end of file diff --git a/src/EditBookForm.jsx b/src/EditBookForm.jsx new file mode 100644 index 000000000..8631cd2ca --- /dev/null +++ b/src/EditBookForm.jsx @@ -0,0 +1,34 @@ +import React, {useState, useEffect} from 'react'; + +const EditUserForm = (props) => { + + useEffect(() => { + setBook(props.currentBook) + }, [props]) + + const [book, setBook] = useState(props.currentBook); + + const handleChange = e => { + const {name, value} = e.target; + setBook({...book, [name]: value}); + } + + const handleSubmit = e => { + e.preventDefault(); + book.pagesLeft = book.totalPages - book.pagesRead; + if (book.bookName && book.author && book.totalPages && book.pagesRead && book.pagesLeft) props.updateBook(book); + } + + return ( +
+ + + + + + +
+ ) +} + +export default EditUserForm; \ No newline at end of file diff --git a/src/app.jsx b/src/app.jsx new file mode 100644 index 000000000..a601cdefc --- /dev/null +++ b/src/app.jsx @@ -0,0 +1,91 @@ +import React, { useState, useEffect } from "react"; +import UserTable from "./BookTable.jsx"; +import './styles/styles.css'; +import AddUserForm from "./AddBookForm.jsx"; +import EditUserForm from "./EditBookForm.jsx"; + +const App = () => { + const [books, setBooks] = useState(() => { + const savedBooks = localStorage.getItem("books"); + if (savedBooks) { + return JSON.parse(savedBooks); + } else { + return []; + } + }); + + useEffect(() => { + localStorage.setItem("books", JSON.stringify(books)); + }, [books]); + + const addBook = (book) => { + var max = 0; + for(let i = 0; i < books.length; i++){ + if(books[i].id > max){ + max = books[i].id; + } + } + book.id = max + 1; + setBooks([...books, book]); + }; + + const deleteBook = (id) => { + setBooks(books.filter((book) => book.id !== id)); + }; + + const [editing, setEditing] = useState(false); + + const initialBook = { id: null, bookName: "", author: "", totalPages: "" ,pagesRead: "", pagesLeft:"" }; + + const [currentBook, setCurrentBook] = useState(initialBook); + + const editBook = (id, book) => { + setEditing(true); + setCurrentBook(book); + }; + + const updateBook = (newBook) => { + setBooks( + books.map((book) => (book.id === currentBook.id ? newBook : book)) + ); + setCurrentBook(initialBook); + setEditing(false); + }; + + return ( +
+
+
+ +

Bookshelf

+
+
+ {editing ? ( +
+

Use the form below to edit the selected book ⤵

+ +
+ ) : ( +
+

Use the form below to add a book ⤵

+ +
+ )} +
+
+ +
+
+
+ ); +}; + +export default App; \ No newline at end of file diff --git a/src/components/router.jsx b/src/components/router.jsx new file mode 100644 index 000000000..be13952ac --- /dev/null +++ b/src/components/router.jsx @@ -0,0 +1,19 @@ +import * as React from "react"; +import { Switch, Route, Router } from "wouter"; +import Home from "../pages/home"; +import About from "../pages/about"; + +/** +* The router is imported in app.jsx +* +* Our site just has two routes in it–Home and About +* Each one is defined as a component in /pages +* We use Switch to only render one route at a time https://github.com/molefrog/wouter#switch- +*/ + +export default () => ( + + + + +); diff --git a/src/components/seo.jsx b/src/components/seo.jsx new file mode 100644 index 000000000..24ccb174a --- /dev/null +++ b/src/components/seo.jsx @@ -0,0 +1,37 @@ +import * as React from "react"; +import SEO from "../seo.json"; +import { Helmet } from 'react-helmet-async'; + +const Seo = () => { + // If url is set to 'glitch-default', we use the hostname for the current page + // Otherwise we use the value set in seo.json + const url = SEO.url === 'glitch-default' ? window.location.hostname : SEO.url + + // React Helmet manages the content of the page head such as meta tags + // We use the async package https://github.com/staylor/react-helmet-async + return + {SEO.title} + + + + + + + + + + + + +}; + +export default Seo; diff --git a/src/hooks/prefers-reduced-motion.jsx b/src/hooks/prefers-reduced-motion.jsx new file mode 100644 index 000000000..0c48f2bc3 --- /dev/null +++ b/src/hooks/prefers-reduced-motion.jsx @@ -0,0 +1,22 @@ +import React from "react"; + +// User system can indicate reduced motion setting https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion + +const query = "(prefers-reduced-motion: no-preference)"; + +export function usePrefersReducedMotion() { + const [prefersReducedMotion, setPrefersReducedMotion] = React.useState( + !window.matchMedia(query).matches + ); + React.useEffect(() => { + const mediaQueryList = window.matchMedia(query); + const listener = event => { + setPrefersReducedMotion(!event.matches); + }; + mediaQueryList.addListener(listener); + return () => { + mediaQueryList.removeListener(listener); + }; + }, []); + return prefersReducedMotion; +} diff --git a/src/hooks/wiggle.jsx b/src/hooks/wiggle.jsx new file mode 100644 index 000000000..e23bdf259 --- /dev/null +++ b/src/hooks/wiggle.jsx @@ -0,0 +1,55 @@ +import React, { useState, useCallback } from "react"; +import { useSpring } from "react-spring"; +import { usePrefersReducedMotion } from "./prefers-reduced-motion"; +// Heavily inspired by Josh Comeau: https://www.joshwcomeau.com/react/boop/ 💖 + +// Wiggle function accepts various parameters specifying properties for the animation +export function useWiggle({ + x = 0, + y = 0, + rotation = 0, + scale = 1, + timing = 150, + springConfig = { + tension: 300, + friction: 10 + } +}) { + // Accessibility setting from the user system indicating that they prefer to minimize motion + const prefersReducedMotion = usePrefersReducedMotion(); + + // Declare state variable isActive, set initially to false + const [isActive, setIsActive] = useState(false); + + // We offload the actual animation to spring: https://www.react-spring.io/docs/hooks/use-spring + const style = useSpring({ + transform: isActive + ? `translate(${x}px, ${y}px) rotate(${rotation}deg) scale(${scale})` + : `translate(0px, 0px) rotate(0deg) scale(1)`, + config: springConfig + }); + + // Timing parameter determines how long the wiggle lasts using browser setTimeout function + // React useEffect function https://reactjs.org/docs/hooks-effect.html + React.useEffect(() => { + if (!isActive) { + return; + } + const timeoutId = window.setTimeout(() => { + setIsActive(false); + }, timing); + return () => { + window.clearTimeout(timeoutId); + }; + }, [isActive]); // Continue wiggle until isActive is set false when timeout elapses + + // Set wiggle to active when the triggering event occurs - will be set false when effect completes above + const trigger = useCallback(() => { + setIsActive(true); + }, []); + + let appliedStyle = prefersReducedMotion ? {} : style; + + // Return animation style effect and function to apply on trigger in page + return [appliedStyle, trigger]; +} diff --git a/src/index.jsx b/src/index.jsx new file mode 100644 index 000000000..8887e58c7 --- /dev/null +++ b/src/index.jsx @@ -0,0 +1,5 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './app.jsx'; + +ReactDOM.render(, document.getElementById('root')); \ No newline at end of file diff --git a/src/pages/about.jsx b/src/pages/about.jsx new file mode 100644 index 000000000..d64eff643 --- /dev/null +++ b/src/pages/about.jsx @@ -0,0 +1,72 @@ +import * as React from "react"; +/* ADD IMPORTS FROM TODO ON THE NEXT LINE */ + + +/** +* The About function defines the component that makes up the About page +* This component is attached to the /about path in router.jsx +*/ + +export default function About() { + /* DECLARE STYLE AND TRIGGER FOR WIGGLE EFFECT FROM TODO ON NEXT LINE */ + + return ( +
+ {/* REPLACE H1 ELEMENT BELOW WITH CODE FROM TODO */} +

+ About this site +

+ {/* REPLACE OPENING P TAG BELOW WITH CODE FROM TODO */} +

+ Welcome to the Glitch React starter, where you can instantly create a + React site that's fully customizable. +

+

+ + If you're completely new to React, learning the{" "} + main concepts{" "} + will get you off to a great start. You'll also see comments and links + to supporting resources throughout the code. + +

+

+ This page is a great spot to tell the world a few details about the new + React app you built on Glitch! Check out your project's{" "} + readme file to learn more about how to customize your + content. +

+
    +
  • + 🎉 Right now, your site is live on the web 🌐 with a + real URL (a secure HTTPS address!) that updates as soon as you make + changes. +
  • +
  • + 💥 Add a domain to your new Glitch project! Just go + to the Tools menu in the Glitch editor, and click{" "} + Custom Domains. +
  • +
  • + 🌈 Use the Share button in the Glitch editor to + invite others in to edit your new React project by typing in their + email address or Glitch username.
    Tip: 👀Make + your code, or even your entire app, private to just those you invite, + by{" "} + upgrading your Glitch account + . +
  • +
+ +

+ {" "} + The Glitch community is glad to welcome you, and the Internet is better + when it's made by real people. We can't wait to see what you create! +

+

+ Built with React and{" "} + Vite on{" "} + Glitch. +

+
+ ); +} diff --git a/src/pages/home.jsx b/src/pages/home.jsx new file mode 100644 index 000000000..90e5d6122 --- /dev/null +++ b/src/pages/home.jsx @@ -0,0 +1,78 @@ +import * as React from "react"; +import { animated } from "react-spring"; +import { useWiggle } from "../hooks/wiggle"; +import { Link } from "wouter"; + +// Our language strings for the header +const strings = [ + "Hello React", + "Salut React", + "Hola React", + "안녕 React", + "Hej React" +]; + +// Utility function to choose a random value from the language array +function randomLanguage() { + return strings[Math.floor(Math.random() * strings.length)]; +} + +/** +* The Home function defines the content that makes up the main content of the Home page +* +* This component is attached to the /about path in router.jsx +* The function in app.jsx defines the page wrapper that this appears in along with the footer +*/ + +export default function Home() { + /* We use state to set the hello string from the array https://reactjs.org/docs/hooks-state.html + - We'll call setHello when the user clicks to change the string + */ + const [hello, setHello] = React.useState(strings[0]); + + /* The wiggle function defined in /hooks/wiggle.jsx returns the style effect and trigger function + - We can attach this to events on elements in the page and apply the resulting style + */ + const [style, trigger] = useWiggle({ x: 5, y: 5, scale: 1 }); + + // When the user clicks we change the header language + const handleChangeHello = () => { + + // Choose a new Hello from our languages + const newHello = randomLanguage(); + + // Call the function to set the state string in our component + setHello(newHello); + }; + return ( + <> +

{hello}!

+ {/* When the user hovers over the image we apply the wiggle style to it */} + + Illustration click to change language + +
+ {/* When the user hovers over this text, we apply the wiggle function to the image style */} + + + Psst, click me + + +
+
+

Using this project

+

+ This is the Glitch Hello React project. You can use + it to build your own app. See more info in the{" "} + About page, and check out README.md in the + editor for additional detail plus next steps you can take! +

+
+ + ); +} diff --git a/src/seo.json b/src/seo.json new file mode 100644 index 000000000..51e12766b --- /dev/null +++ b/src/seo.json @@ -0,0 +1,7 @@ +{ + "glitch-help-instructions": "For a custom domain, change the 'url' parameter from 'glitch-default' to your domain _without_ a traling slash, like 'https://www.example.com'", + "title": "Hello React!", + "description": "A simple React single page app, built with Glitch. Remix it to get your own!!!!", + "url": "glitch-default", + "image": "https://cdn.glitch.com/605e2a51-d45f-4d87-a285-9410ad350515%2Fhello-react-social.png?v=1616712747908" +} diff --git a/src/styles/styles.css b/src/styles/styles.css new file mode 100644 index 000000000..c9dac7661 --- /dev/null +++ b/src/styles/styles.css @@ -0,0 +1,180 @@ +.header { + padding: 100px; + text-align: center; + background: #f1dbe1; + color: white; + font-size: 30px; +}/*Style your own assignment! This is fun! */ + +img{ + width: 130px; + height: 80px; + position: absolute; + top: 160px; + left: 70px; +} + +h1{ + padding-top: 60px; + padding-left: 70px; + font-size: 50px; + font-family: 'Montserrat'; + color: #363738; +} + + +h2{ + padding-left: 18px; + font-family: 'Montserrat'; + color: #75777b; + font-weight: 200; + font-size: 19px; + background-color: #f1f1f2; + padding-top: 18px; + padding-bottom: 18px; + margin-left: 70px; + margin-right: 70px; + margin-top: -10px; + border-radius: 8px; +} + +.u-full-width{ + font-family: 'Montserrat'; + padding: 13px; + width: 140px; + border-width: 2px; + border-radius: 5px; + border-color: #75777b #75777b #75777b; + border-style: solid; + margin-top: 20px; + margin-left: 70px; +} + +.u-full-width1{ + font-family: 'Montserrat'; + padding: 13px; + width: 140px; + border-width: 2px; + border-radius: 5px; + border-color: #75777b #75777b #75777b; + border-style: solid; + margin-top: 20px; + margin-left: 15px; +} + + +.u-full-width2{ + font-family: 'Montserrat'; + padding: 13px; + width: 140px; + border-width: 2px; + border-radius: 5px; + border-color: #75777b #75777b #75777b; + border-style: solid; + margin-top: 20px; + margin-left: 15px; +} + +.u-full-width3{ + font-family: 'Montserrat'; + padding: 13px; + width: 140px; + border-width: 2px; + border-radius: 5px; + border-color: #75777b #75777b #75777b; + border-style: solid; + margin-top: 20px; + margin-left: 15px; +} + +.button-primary{ + border-width: 0; + background-color: #811731; + color: #ffffff; + margin-left: 15px; + margin-top: 0px; + padding: 10px 20px; + border-radius: 5px; + font-size: 20px; + margin-bottom:60px; + font-family: 'Montserrat'; + font-size: 16px; +} + +.button-primary:hover{ + border-width: 0; + background-color: #e54885; + color: #ffffff; + padding: 10px 20px; + border-radius: 5px; + font-size: 20px; + margin-bottom:60px; + font-family: 'Montserrat'; + font-size: 16px; +} + +.cancel{ + border-width: 0; + background-color: #808080; + color: #ffffff; + margin-left: 15px; + margin-top: 0px; + padding: 10px 20px; + border-radius: 5px; + font-size: 20px; + margin-bottom:60px; + font-family: 'Montserrat'; + font-size: 16px; +} + +.cancel:hover{ + border-width: 0; + background-color: #A9A9A9; + color: #ffffff; + padding: 10px 20px; + border-radius: 5px; + font-size: 20px; + margin-bottom:60px; + font-family: 'Montserrat'; + font-size: 16px; +} + +th{ + color: #000000; + font-family: 'Montserrat'; + text-align: center; + font-size: 1em; + font-weight: bold; + padding-right: 60px; +} +td{ +padding-top: 20px; + font-family: 'Montserrat'; + color: #363738; +} +table{ + margin-left: 80px; +} + +.button-primary2{ + border-width: 0; + background-color: #811731; + color: #ffffff; + margin-left: 15px; + border-radius: 5px; + font-size: 20px; + padding: 10px 20px; + font-family: 'Montserrat'; + font-size: 16px; +} + +.button-primary2:hover{ + border-width: 0; + background-color: #e54885; + color: #ffffff; + border-radius: 5px; + font-size: 20px; + padding: 10px 20px; + font-family: 'Montserrat'; + font-size: 16px; +} \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 000000000..d4bb1911e --- /dev/null +++ b/vite.config.js @@ -0,0 +1,16 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + build: { + outDir: "build" + }, + server: { + strictPort: true, + hmr: { + port: 443 // Run the websocket server on the SSL port + } + } +}); diff --git a/watch.json b/watch.json new file mode 100644 index 000000000..06dbb08a4 --- /dev/null +++ b/watch.json @@ -0,0 +1,17 @@ +{ + "install": { + "include": [ + "^package\\.json$" + ], + "exclude": [] + }, + "restart": { + "include": [ + "^backend/" + ], + "exclude": [ + "src/" + ] + }, + "noSavedEvents": true +} From 81bbe472af4d44ccb0b9ba6aaab34e4fab120f89 Mon Sep 17 00:00:00 2001 From: nkuchipudi2020 <98354759+nkuchipudi2020@users.noreply.github.com> Date: Mon, 3 Oct 2022 23:28:46 -0400 Subject: [PATCH 2/2] update readme description --- README.md | 66 ++++--------------------------------------------------- 1 file changed, 4 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 95e26e321..906b172bf 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,7 @@ -# Hello React! +# README -This project contains a foundation for building and learning about React apps. The site includes two routes showing how navigation works in a single page app. We manage the page head and body using a standard React flow. The homepage features a click effect that demonstrates using state, and an animation you can try out yourself by following the steps in `TODO.md`. 💫 +## Bookshelf -[React](https://reactjs.org/) is a popular UI library for building web apps. [Vite](https://vitejs.dev/) is a powerful tool for building javascript apps that bundles all of your code and shows immediate changes while you're editing. +Link: https://a4-neha-kuchipudi.glitch.me/ -_While you're in the editor working, Glitch is running your `start` script in the background (`vite dev`). The site will be in dev mode and you'll see your changes happen ✨ immediately in the preview window. Once you close the editor window and your app goes to sleep, Glitch runs the `build` script and Vite builds your app for modern browsers._ - -## Prerequisites - -You'll get best use out of this project if you're familiar with basic JavaScript. This project is a static site, which means that the server builds the site from the content of the `src` folder while you're developing it, then it's able to serve the pages super quickly when the user requests them. - -## What's in this project? - -← `README.md`: That’s this file, where you can tell people what your cool website does and how you built it. - -← `index.html`: This is the main page template React uses to build your site–it imports `index.jsx` to kick things off. When you're ready to share your site or add a custom domain, change SEO/meta settings in here. - -← `src/`: This folder contains all the files React will use to build your site. - -### Working in the `src/` folder 📁 - -React defines site components in [JSX](https://reactjs.org/docs/introducing-jsx.html), an extended version of JavaScript, so you'll see lots of `.jsx` files in the project. - -← `src/index.jsx`: This is the root of your React app. The index script is imported in the site home template `index.html`. If you add libraries like [chakra-ui](https://chakra-ui.com) or [redux](https://react-redux.js.org), you'll insert their providers here. The ` is an example of a provider you'd use. - -← `src/app.jsx`: The base for defining your React app, this script imports the components that make up the site content. The `index.jsx` file imports the App script. The router (from [wouter](https://github.com/molefrog/wouter) 🐰) is also imported here. - -← `src/styles`: CSS files add styling rules to your content. You have [a lot of](https://vitejs.dev/guide/features.html#css) importing options for CSS including CSS modules if that's your jam. - -← `src/components/router.jsx`: One of the most important parts of a single page app is the router. It's how we know what page to show–the code maps the paths to the Home and About components. We're using [Wouter](https://github.com/molefrog/wouter), a tiny minimalist router. You could replace it for something like [React Router](https://reactrouter.com/). - -← `src/components/seo.jsx`: When you share your site on social media, you'll want to make sure the meta tags are correct and that you've got an image. All of the settings for this file are in `src/seo.json`. - -### Hooks 🪝 - -← `src/hooks/`: [Hooks](https://reactjs.org/docs/hooks-intro.html) are a powerful way to provide interaction with your app. - -← `src/hooks/prefers-reduced-motion.jsx`: For accessibility reasons, some users will indicate in their system settings that they prefer motion effects to be minimized–this allows you to hold off on these effects in such cases. - -← `src/hooks/wiggle.jsx`: The wiggle effect animates elements, as you'll see if you hover over the image (or text below it) on the homepage. You can apply the effect anywhere you like in the site as outlined in `TODO.md`. - -### Pages 📃 - -← `src/pages/`: These files include components that specify the content of the Home and About pages. Each one is defined as a function and referenced in `router.jsx`. The content is built into the page outline specified in `app.jsx`. - -← `src/pages/about.jsx`: The content of the About page, defined as a component function. - -← `src/pages/home.jsx` The content of the Home page, also defined as a component function. The page includes the animated effect on hover, and title change effect on click (which is also a handy demo of using state data in React). - -## Try this next 🏗️ - -Take a look in `TODO.md` for next steps you can try out in your new site! - -**_Want a minimal version of this project to build your own React app? Check out [Blank React](https://glitch.com/edit/#!/remix/glitch-blank-react)!_** - -![Glitch](https://cdn.glitch.com/a9975ea6-8949-4bab-addb-8a95021dc2da%2FLogo_Color.svg?v=1602781328576) - -## You built this with Glitch! - -[Glitch](https://glitch.com) is a friendly community where millions of people come together to build web apps and websites. - -- Want more details about React on Glitch? We've got a [Help Center article](https://help.glitch.com/kb/article/112) for you. -- Need more help? [Check out our Help Center](https://help.glitch.com/) for answers to any common questions. -- Ready to make it official? [Become a paid Glitch member](https://glitch.com/pricing) to boost your app with private sharing, more storage and memory, domains and more. +I made my assignment two into a React web app. I used React to create a virtural bookshelf where users can add books to the table and keep track of how many pages they have read and how many pages are left in their book. They can edit books on their shelf to keep tracking their books. They can also delete books if they finish them. Personally, React was easier to implement than the original assignment two as there was so much resouces, tutorials and documentation. I believe it improved the development experience.