From 926223b7b6180986919e78b16a04f1e1bbb6499b Mon Sep 17 00:00:00 2001 From: klay964 Date: Wed, 24 Mar 2021 09:54:59 +0300 Subject: [PATCH] Feat: create add pet component and link firebase create the page, validate it and link it to the firebase and perform translation and test Closes #23 --- package.json | 6 +- src/Containers/AddPet/AddPet.css | 289 +++++++++++++ src/Containers/AddPet/AddPet.jsx | 381 ++++++++++++++++++ src/Images/icons/paw.svg | 21 + src/Images/pets-vectors/addPetCat.svg | 10 + src/firebase.js | 23 +- src/index.js | 10 +- src/test/AddPet/AddPet.test.js | 8 + .../AddPet/__snapshots__/AddPet.test.js.snap | 374 +++++++++++++++++ src/translations/ar/translation.json | 27 ++ src/translations/en/translation.json | 27 ++ yarn.lock | 97 ++++- 12 files changed, 1252 insertions(+), 21 deletions(-) create mode 100644 src/Containers/AddPet/AddPet.css create mode 100644 src/Containers/AddPet/AddPet.jsx create mode 100644 src/Images/icons/paw.svg create mode 100644 src/Images/pets-vectors/addPetCat.svg create mode 100644 src/test/AddPet/AddPet.test.js create mode 100644 src/test/AddPet/__snapshots__/AddPet.test.js.snap diff --git a/package.json b/package.json index 62a7fec..262ce99 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,12 @@ "bootstrap": "^4.6.0", "eslint-config-prettier": "^8.1.0", "firebase": "^8.3.0", + "formik": "^2.2.6", "i18next": "^19.9.2", "i18next-browser-languagedetector": "^6.0.1", "i18next-http-backend": "^1.1.1", "prettier": "^2.2.1", + "prop-types": "^15.7.2", "react": "^17.0.1", "react-bootstrap": "^1.5.2", "react-dom": "^17.0.1", @@ -20,8 +22,10 @@ "react-redux": "^7.2.2", "react-router-dom": "^5.2.0", "react-scripts": "4.0.3", + "react-test-renderer": "^17.0.2", "redux": "^4.0.5", - "web-vitals": "^1.0.1" + "web-vitals": "^1.0.1", + "yup": "^0.32.9" }, "scripts": { "start": "react-scripts start", diff --git a/src/Containers/AddPet/AddPet.css b/src/Containers/AddPet/AddPet.css new file mode 100644 index 0000000..91e4133 --- /dev/null +++ b/src/Containers/AddPet/AddPet.css @@ -0,0 +1,289 @@ +/* page header */ +.header { + display: flex; + justify-content: space-between; +} + +.add-pet-header { + display: flex; + margin-top: 20px; +} +.header__text { + padding: 30px 100px; +} + +.add-pet-header h1 { + color: #e79559; + font-weight: bold; +} + +.add-pet-header img { + width: 50px; + height: 50px; +} +.add-pet-subheader { + padding: 40px 20px; + margin-bottom: 50px; + color: #4b4b4b; +} + +.header__photo img { + width: 35rem; + height: 35rem; + margin-top: -70px; + z-index: 1; + position: absolute; + z-index: 10; + top: 0; + right: 0; +} + +/* page form */ + +.addpet-form { + background-color: #f2f2f2; + padding: 30px 100px; +} +.addpet-form h2 { + color: #e79559; + font-weight: bold; + margin-bottom: 50px; +} +.error-message { + color: red; + font-size: 14px; + margin-top: 8px; +} +.field-margin { + margin-bottom: 60px; +} +.addpet-form input { + background-color: #f2f2f2; + border: none; + border-bottom: 2px solid #e79559; + border-radius: 0; +} +.addpet-row-space { + margin: 0 0 0 90px; +} +.addpet-radios { + display: flex; + justify-content: flex-start; +} +.addpet-radio { + margin: 0 4px 0 0; +} + +.addpet-form label { + padding: 0 30px 0 0px; +} +input[type='file'] { + display: none; +} +.custom-file-upload { + border: 1px solid #e79559; + border-radius: 30px; + background-color: transparent; + text-align: center; + display: block; + margin: auto; + padding: 8px 8px 0; + font-size: 16px; + cursor: pointer; +} +.upload-image { + display: block; + margin: 0 auto; + width: 8rem; + height: 8rem; +} +.upload-container .form-label { + text-align: center !important; + padding: 8px 8px 0 !important; + margin-bottom: 40px !important; +} + +input[type='radio'] { + background-color: #e79559; + + color: #e79559; +} +input[type='radio']:checked { + background-color: #e79559; +} + +.button-container { + display: flex; + justify-content: center; +} +.addpet-form button { + background-color: #e79559; + border: none; + border-radius: 30px; + width: 10rem; +} +.form-control:focus { + box-shadow: none; + border-bottom: 3px #f2726f solid; + background-color: #f2f2f2; +} +.btn:hover { + background-color: #f2726f; + border: none !important; + outline: none !important; +} +.btn:active { + background-color: #f2726f; + + border: none !important; + outline: none !important; +} +.btn:focus { + background-color: #f2726f; + border: none !important; + outline: none !important; +} + +@media (max-width: 400px) { + .addpet-form h2 { + color: #e79559; + font-weight: bold; + margin-bottom: 50px; + margin-top: 20px; + text-align: center; + font-size: 30px; + } +} +@media (max-width: 768px) { + .header { + display: flex; + flex-direction: column; + justify-content: flex-start; + } + .add-pet-header { + display: flex; + flex-direction: column-reverse; + align-items: center; + margin-top: 20px; + } + .add-pet-header img { + margin-top: 20px; + width: 50px; + height: 50px; + } + .add-pet-subheader { + padding: 1px 20px; + margin-bottom: 1px; + color: #4b4b4b; + } + .addpet-form h2 { + color: #e79559; + font-weight: bold; + margin-bottom: 50px; + margin-top: 20px; + text-align: center; + } + + .header__text { + padding: 30px 0; + text-align: center; + } + .header__photo img { + display: block; + margin: 0 auto; + width: 15rem; + height: 15rem; + margin-top: 1px; + z-index: 1; + position: static; + } + .addpet-row-space { + margin: 0 0 0 0; + } + .upload-container { + display: flex; + justify-content: center; + } +} + +@media (min-width: 769px) and (max-width: 992px) { + .header { + display: flex; + flex-direction: column; + justify-content: flex-start; + } + .add-pet-header { + display: flex; + justify-content: center; + align-items: center; + margin-top: 20px; + } + + .add-pet-subheader { + padding: 1px 20px; + text-align: center; + margin-top: 40px; + margin-bottom: 1px; + color: #4b4b4b; + } + .addpet-row-space { + margin: 0 0 0 0; + } + .header__photo img { + display: block; + margin: 0 auto; + width: 25rem; + height: 25rem; + margin-top: 1px; + z-index: 1; + position: static; + } + .addpet-form h2 { + color: #e79559; + font-weight: bold; + margin-bottom: 50px; + margin-top: 20px; + text-align: center; + } + .upload-container { + display: flex; + justify-content: center; + } +} + +@media (min-width: 1089px) and (max-width: 1300px) { + .header__photo img { + width: 20rem; + height: 30rem; + margin-top: -70px; + z-index: 1; + position: absolute; + z-index: 10; + top: 0; + right: 0; + } +} +@media (min-width: 1024px) and (max-width: 1300px) { + .header__photo img { + width: 15rem; + height: 30rem; + margin-top: -70px; + z-index: 1; + position: absolute; + z-index: 10; + top: 0; + right: 0; + } +} + +@media (min-width: 992px) and (max-width: 1024px) { + .header__photo img { + width: 12rem; + height: 30rem; + margin-top: -70px; + position: absolute; + z-index: 10; + top: 0; + right: 0; + } +} diff --git a/src/Containers/AddPet/AddPet.jsx b/src/Containers/AddPet/AddPet.jsx new file mode 100644 index 0000000..4810b94 --- /dev/null +++ b/src/Containers/AddPet/AddPet.jsx @@ -0,0 +1,381 @@ +import React, { useState } from 'react' +import './AddPet.css' +import { useFormik } from 'formik' +import * as Yup from 'yup' +import { useTranslation } from 'react-i18next' +import { Form, Col, Button } from 'react-bootstrap' +import firebase, { storage } from '../../firebase' +import 'firebase/firestore' +import Cat from '../../Images/pets-vectors/addPetCat.svg' +import Paw from '../../Images/icons/paw.svg' + +function AddPet() { + const { t } = useTranslation() + const [file, setFile] = useState(null) + const [url, setUrl] = useState('') + + const validationSchema = Yup.object().shape({ + petName: Yup.string().required(t('add-pet.required')), + species: Yup.string().required(t('add-pet.required')), + color: Yup.string().required(t('add-pet.required')), + story: Yup.string().required(t('add-pet.required')), + ownerName: Yup.string().required(t('add-pet.required')), + email: Yup.string() + .required(t('add-pet.required')) + .email(t('add-pet.email-validation')), + phoneNumber: Yup.string(t('add-pet.example-number')) + .required(t('add-pet.required')) + .matches(/^[0-9]{11}$/, t('add-pet.phone-validation')), + city: Yup.string().required(t('add-pet.required')), + address: Yup.string().required(t('add-pet.required')), + }) + const { + handleSubmit, + setFieldValue, + resetForm, + handleChange, + handleBlur, + values, + errors, + touched, + } = useFormik({ + initialValues: { + petName: '', + age: '', + species: '', + weight: '', + color: '', + gender: '', + story: '', + file: null, + ownerName: '', + aboutOwner: '', + email: '', + phoneNumber: '', + city: '', + address: '', + }, + validationSchema, + onSubmit() { + const uploadTask = storage + .ref(`petImages/${values.file.name}`) + .put(values.file) + uploadTask.on( + 'state_changed', + + () => { + storage + .ref('petImages') + .child(values.file.name) + .getDownloadURL() + .then((link) => { + setUrl(link) + }) + } + ) + + firebase + .firestore() + .collection('pets') + .add({ + ...values, + file: url, + }) + .then(() => resetForm()) + }, + }) + + const reader = new FileReader() + + reader.onloadend = () => { + setFile(reader.result) + } + if (values.file != null) { + reader.readAsDataURL(values.file) + } + return ( +
+ {/* page header */} +
+
+
+ paw +

{t('add-pet.add for adoption')}

+
+
+

{t('add-pet.make-pets-happy')}

+
+
+
+ cat +
+
+ {/* end of page header */} + {/* page form */} +
+

{t('add-pet.pets-info')}

+
+ + + + {touched.petName && errors.petName ? ( +
+ {errors.petName} +
+ ) : ( +
+ {' '} +
+ )} + + + +
+ +
+ + + + {touched.species && errors.species ? ( +
+ {errors.species} +
+ ) : ( +
+ )} + + + +
+ +
+ + + + {touched.color && errors.color ? ( +
+ {errors.color} +
+ ) : ( +
+ )} + + +

{t('add-pet.gender')}

+
+ { + values.gender = 'male' + }} + type="radio" + onBlur={handleBlur} + name="gender" + value="Male" + /> + + {t('add-pet.male')} + { + values.gender = 'female' + }} + type="radio" + name="gender" + value="Female" + /> + {t('add-pet.female')} +
+
+ +
+ + + + {touched.story && errors.story ? ( +
+ {errors.story} +
+ ) : ( +
+ )} + + +
+ +

{t('add-pet.upload-photo')}

+
+
+ { + setFieldValue( + 'file', + e.currentTarget.files[0] + ) + }} + /> + + {file && ( + your pet + )} + +
+

{t('add-pet.contact-info')}

+ + + + {touched.ownerName && errors.ownerName ? ( +
+ {errors.ownerName} +
+ ) : ( +
+ )} + + + +
+ +
+ + + + {touched.email && errors.email ? ( +
+ {errors.email} +
+ ) : ( +
+ )} + + + + {touched.phoneNumber && errors.phoneNumber ? ( +
+ {errors.phoneNumber} +
+ ) : ( +
+ )} + +
+ + + + {touched.city && errors.city ? ( +
+ {errors.city} +
+ ) : ( +
+ )} + + + + {touched.address && errors.address ? ( +
+ {errors.address} +
+ ) : ( +
+ )} + +
+
+ +
+
+
+
+ ) +} + +export default AddPet diff --git a/src/Images/icons/paw.svg b/src/Images/icons/paw.svg new file mode 100644 index 0000000..414164b --- /dev/null +++ b/src/Images/icons/paw.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Images/pets-vectors/addPetCat.svg b/src/Images/pets-vectors/addPetCat.svg new file mode 100644 index 0000000..12d2633 --- /dev/null +++ b/src/Images/pets-vectors/addPetCat.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/firebase.js b/src/firebase.js index d4224c5..80c1275 100644 --- a/src/firebase.js +++ b/src/firebase.js @@ -1,16 +1,17 @@ -import firebase from "firebase/app" -import "firebase/firestore" +import firebase from 'firebase/app' +import 'firebase/firestore' +import 'firebase/storage' const firebaseConfig = { - apiKey: "AIzaSyBoWWO2wP7w5K5t8X98Two9xJ0MojAwA9E", - authDomain: "pawfive-eb9d4.firebaseapp.com", - projectId: "pawfive-eb9d4", - storageBucket: "pawfive-eb9d4.appspot.com", - messagingSenderId: "275629003440", - appId: "1:275629003440:web:69429a61a2226adf966175" - }; - + apiKey: 'AIzaSyBoWWO2wP7w5K5t8X98Two9xJ0MojAwA9E', + authDomain: 'pawfive-eb9d4.firebaseapp.com', + projectId: 'pawfive-eb9d4', + storageBucket: 'pawfive-eb9d4.appspot.com', + messagingSenderId: '275629003440', + appId: '1:275629003440:web:69429a61a2226adf966175', +} firebase.initializeApp(firebaseConfig) +const storage = firebase.storage() -export default firebase; +export { storage, firebase as default } diff --git a/src/index.js b/src/index.js index 1b32e93..f03706d 100644 --- a/src/index.js +++ b/src/index.js @@ -1,20 +1,22 @@ -import React, {Suspense} from 'react' +import React, { Suspense } from 'react' import ReactDOM from 'react-dom' import { createStore } from 'redux' import { Provider } from 'react-redux' +import './i18n' +import 'bootstrap/dist/css/bootstrap.min.css' + import './index.css' import App from './App' import reportWebVitals from './reportWebVitals' import AllReducers from './redux/reducers/AllReducers' -import './i18n' const store = createStore(AllReducers) ReactDOM.render( - Loding ~~~~)}> - + Loding ~~~~}> + , diff --git a/src/test/AddPet/AddPet.test.js b/src/test/AddPet/AddPet.test.js new file mode 100644 index 0000000..4c71338 --- /dev/null +++ b/src/test/AddPet/AddPet.test.js @@ -0,0 +1,8 @@ +import React from 'react' +import renderer from 'react-test-renderer' +import AddPet from '../../Containers/AddPet/AddPet' + +it('renders correctly', () => { + const tree = renderer.create().toJSON() + expect(tree).toMatchSnapshot() +}) diff --git a/src/test/AddPet/__snapshots__/AddPet.test.js.snap b/src/test/AddPet/__snapshots__/AddPet.test.js.snap new file mode 100644 index 0000000..0a92999 --- /dev/null +++ b/src/test/AddPet/__snapshots__/AddPet.test.js.snap @@ -0,0 +1,374 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+
+
+
+ paw +

+ add-pet.add for adoption +

+
+
+

+ add-pet.make-pets-happy +

+
+
+
+ cat +
+
+
+

+ add-pet.pets-info +

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

+ add-pet.gender +

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

+ add-pet.contact-info +

+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+`; diff --git a/src/translations/ar/translation.json b/src/translations/ar/translation.json index 410d737..b92c507 100644 --- a/src/translations/ar/translation.json +++ b/src/translations/ar/translation.json @@ -13,5 +13,32 @@ ], "logIn": "تسجيل الدخول", "signUp": "انشاء حساب" + }, + "add-pet":{ + "required":"هذا الحقل مطلوب", + "email.validation":"يرجى كتابة بريد الكتروني صالح", + "example:number":" رقم الهاتف يجب ان يكتب بهذة الطريقة 07700000000", + "phone-validation":"رقم الهاتف يجب ان يتكون من 11 رقم", + "add for adoption":"ضع حيوانك الأليف للتبني", + "make-pets-happy":"هنا تستطيع وضع حيواناتك الأليفة للتبني وجعلهم سعداء", + "pets-info":"معلومات حيوانك الأليف", + "pet-name":"اسم الحيوان الأليف", + "pet-age":" (اختياري)العمر ", + "pet-species":"صنف الحيوان الأليف", + "pet-weight":"(اختياري)وزن الحيوان الأليف", + "pet-color":"لون الحيوان الأليف", + "gender":"(اختياري)الجنس ", + "male":"ذكر", + "female":"انثى", + "pet-story":" قصة حيوانك الأليف", + "upload-photo": "ارفع صورة", + "contact-info":"معلومات للأتصال بك", + "ownerName":"اسم المالك", + "aboutOwner":"(اختياري)عن المالك", + "email":"البريد الألكتروني", + "phoneNumber":"رقم الهاتف", + "city":"المدينة", + "address":"العنوان", + "submit":"إرسال" } } \ No newline at end of file diff --git a/src/translations/en/translation.json b/src/translations/en/translation.json index 61019f4..46f1b41 100644 --- a/src/translations/en/translation.json +++ b/src/translations/en/translation.json @@ -13,5 +13,32 @@ "about": "About", "logIn": "Log In", "signUp": "Sign Up" + }, + "add-pet":{ + "required":"This field is required !!", + "email.validation":"You need to write a valid email", + "example:number":" Your phone number must be something like this 077xxxxxxxx", + "phone-validation":"Your phone number must conatin 11 digits", + "add for adoption":"Add your Pet for Adoption", + "make-pets-happy":" Here you can put pets for adoption and make them happy and safe", + "pets-info":"Pets Info", + "pet-name":"Pet Name", + "pet-age":"Pet Age (optional)", + "pet-species":"Pet Species", + "pet-weight":"Pet Weight (optional)", + "pet-color":"Pet Color", + "gender":"Pet gender (optional)", + "male":"Male", + "female":"Female", + "pet-story":"Pet story", + "upload-photo": "Upload Photo", + "contact-info":"Contact Info", + "ownerName":"Owner Name", + "aboutOwner":"About Owner (optional)", + "email":"Email", + "phoneNumber":"Phone Number", + "city":"City", + "address":"Address", + "submit":"Submit" } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 876621d..41f9474 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1070,7 +1070,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.6", "@babel/runtime@^7.13.8", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.6", "@babel/runtime@^7.13.8", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== @@ -2060,6 +2060,11 @@ resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/lodash@^4.14.165": + version "4.14.168" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" + integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== + "@types/long@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" @@ -4322,6 +4327,11 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +deepmerge@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" + integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== + deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz" @@ -5542,6 +5552,19 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +formik@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/formik/-/formik-2.2.6.tgz#378a4bafe4b95caf6acf6db01f81f3fe5147559d" + integrity sha512-Kxk2zQRafy56zhLmrzcbryUpMBvT0tal5IvcifK5+4YNGelKsnrODFJ0sZQRMQboblWNym4lAW3bt+tf2vApSA== + dependencies: + deepmerge "^2.1.1" + hoist-non-react-statics "^3.3.0" + lodash "^4.17.14" + lodash-es "^4.17.14" + react-fast-compare "^2.0.1" + tiny-warning "^1.0.2" + tslib "^1.10.0" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz" @@ -5984,7 +6007,7 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -7574,7 +7597,7 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash-es@^4.17.20: +lodash-es@^4.17.14, lodash-es@^4.17.15, lodash-es@^4.17.20: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== @@ -8015,6 +8038,11 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== +nanoclone@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4" + integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA== + nanoid@^3.1.20: version "3.1.20" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz" @@ -9521,6 +9549,11 @@ prop-types@^15.6.2, prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +property-expr@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.4.tgz#37b925478e58965031bb612ec5b3260f8241e910" + integrity sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg== + protobufjs@^6.8.6: version "6.10.2" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.2.tgz#b9cb6bd8ec8f87514592ba3fdfd28e93f33a469b" @@ -9775,6 +9808,11 @@ react-error-overlay@^6.0.9: resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz" integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== +react-fast-compare@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" + integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== + react-i18next@^11.8.10: version "11.8.10" resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.8.10.tgz#aa64bc20410ee8f660a5b918d53f4e41271edf00" @@ -9783,6 +9821,11 @@ react-i18next@^11.8.10: "@babel/runtime" "^7.13.6" html-parse-stringify2 "^2.0.1" +"react-is@^16.12.0 || ^17.0.0", react-is@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-is@^16.13.1, react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" @@ -9923,6 +9966,24 @@ react-scripts@4.0.3: optionalDependencies: fsevents "^2.1.3" +react-shallow-renderer@^16.13.1: + version "16.14.1" + resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz#bf0d02df8a519a558fd9b8215442efa5c840e124" + integrity sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg== + dependencies: + object-assign "^4.1.1" + react-is "^16.12.0 || ^17.0.0" + +react-test-renderer@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-17.0.2.tgz#4cd4ae5ef1ad5670fc0ef776e8cc7e1231d9866c" + integrity sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ== + dependencies: + object-assign "^4.1.1" + react-is "^17.0.2" + react-shallow-renderer "^16.13.1" + scheduler "^0.20.2" + react-transition-group@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" @@ -10475,6 +10536,14 @@ scheduler@^0.20.1: loose-envify "^1.1.0" object-assign "^4.1.1" +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + schema-utils@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz" @@ -11373,7 +11442,7 @@ tiny-invariant@^1.0.2: resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz" integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== -tiny-warning@^1.0.0, tiny-warning@^1.0.3: +tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== @@ -11430,6 +11499,11 @@ toidentifier@1.0.0: resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= + tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" @@ -11474,7 +11548,7 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -12390,3 +12464,16 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yup@^0.32.9: + version "0.32.9" + resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.9.tgz#9367bec6b1b0e39211ecbca598702e106019d872" + integrity sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg== + dependencies: + "@babel/runtime" "^7.10.5" + "@types/lodash" "^4.14.165" + lodash "^4.17.20" + lodash-es "^4.17.15" + nanoclone "^0.2.1" + property-expr "^2.0.4" + toposort "^2.0.2"