diff --git a/package.json b/package.json index 79251dd..26b7669 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "luxon": "^2.3.1", "rating-star": "^1.1.0", "react": "^17.0.2", + "react-chip-input": "^1.1.0", "react-dom": "^17.0.2", "react-i18next": "^11.16.2", "react-redux": "^8.0.1", diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 23887ff..62472ee 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -190,6 +190,16 @@ "verified": "Your email has been successfully verified", "canLog": "Now You can Log In!" }, + "profile": { + "username": "Name", + "useremail": "Email", + "firstname": "First Name", + "lastname": "Last Name", + "password": "Password", + "button": "Save", + "programming_language": "Programming language", + "button_change_password":"Edit" + }, "team": { "status": "Status", "places": { diff --git a/public/locales/pl/translation.json b/public/locales/pl/translation.json index e5fc526..287b787 100644 --- a/public/locales/pl/translation.json +++ b/public/locales/pl/translation.json @@ -188,6 +188,16 @@ "verified": "Twój email został pomyślnie zweryfikowany", "canLog": "Teraz możesz się zalogować!" }, + "profile": { + "username": "Nazwa użytkownika", + "useremail": "Email", + "firstname": "Imię", + "lastname": "Nazwisko", + "password": "Hasło", + "button": "Zapisz", + "programming_language": "Język programowania", + "button_change_password":"Edytuj" + }, "team": { "status": "Status", "places": { diff --git a/server b/server index 5760ac8..e840e90 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 5760ac8aa62dcbd8ce302c4f32827e4a16606fff +Subproject commit e840e90f95f8b56e5eee93074ca642bdc947f712 diff --git a/src/components/Profile/Profile.interface.ts b/src/components/Profile/Profile.interface.ts new file mode 100644 index 0000000..ee55fad --- /dev/null +++ b/src/components/Profile/Profile.interface.ts @@ -0,0 +1,13 @@ +import { IProgrammingLanguage } from "components/Team/IProgrammingLanguege"; + +export default interface ProfileInterface { + username: string, + email: string, + firstname: string, + lastname: string, + programmingLanguage?: Array, + oldPassword: string, + newPassword: string, + confirmNewPassword: string, + userData?: Array, +} diff --git a/src/components/Profile/Profile.tsx b/src/components/Profile/Profile.tsx new file mode 100644 index 0000000..6d3f148 --- /dev/null +++ b/src/components/Profile/Profile.tsx @@ -0,0 +1,336 @@ +import React, { useEffect, useState } from "react"; +import { Formik, Form } from "formik"; +import { useTranslation } from "react-i18next"; +import { Link, useNavigate} from "react-router-dom"; +import { toast } from "react-toastify"; +import { Modal } from "components"; +import { ProfileSchema } from "./validate"; +import ProfileInterface from "./Profile.interface"; +import { ProfileForm, LabelStyle, ErrorMsg, Footer, InputStyled, EditButton, ButtonInPassModal, InputStyledElement, StyledDiv, StyleFromModalTeam, ClosedButton, LabelLang, StyledLi } from "./ProfileForm.style"; +import { IconText, Input, IconEye, IconEyeHide } from "../../styles"; +import { LogoPageSmall } from "../../styles/LogoPage.style"; +import { paths } from "../../config/paths"; +import { getUserID } from "services/auth.service"; +import { getUser, updateUserData, updateUserLang, changePassword} from "services/user.service"; +import { IProgrammingLanguage } from "components/Team/IProgrammingLanguege"; +import { ButtonInModal} from "components/Team/AddTeam/AddTeam.style"; +import { options } from "config/languages"; +import { level_profile } from "config/level_profile"; + + +export const Profile = () => { + const { t } = useTranslation(); + let navigate = useNavigate(); + + const [id, setID] = useState(''); + const [username, setUserName] = useState(''); + const [email, setEmail] = useState(''); + const [firstname, setFirstName] = useState(''); + const [lastname, setLastName] = useState(''); + const [newPassword, setNewPassword] = useState(''); + const [confirmNewPassword, setConfirmNewPassword] = useState(''); + const [oldPassword, setOldPassword] = useState(''); + const [request, setRequest] = useState(false); + const [currentNameLang, setCurrentNameLang] = useState(); + const [currentLevel, setCurrentLevel] = useState(); + const [programmingLanguage, setLanguages] = useState>([]); + const [userData, setUserData] = useState>([]); + const [oldPassShown, setOldPassShown] = useState(false); + const [passShown, setPassShown] = useState(false); + const [conPassShown, setConPassShown] = useState(false); + + const toggleOldPass = () => { + setOldPassShown((prev) => !prev); + }; + + const togglePass = () => { + setPassShown((prev) => !prev); + }; + + const toggleConPass = () => { + setConPassShown((prev) => !prev); + }; + + useEffect(() => { + setID(getUserID()); + getUser(id) + .then((response: any) => { + setUserName (response.data.username); + setEmail(response.data.email); + setFirstName(response.data.firstname); + setLastName(response.data.lastname); + const data = response.data.programmingLanguage.filter((e:any) => delete e._id) + setUserData(data); + }) + .catch((e: Error) => { + toast.error(t`profile.error`); + }); + }, [email, firstname, id, lastname, t, username]); + + const handleClick = () => { + setLanguages((prevState) => [{ nameLang: currentNameLang, level: currentLevel }, ...prevState]); + + }; + + const initialValues: ProfileInterface = { + username: username, + email: email, + firstname: firstname, + lastname: lastname, + programmingLanguage: userData, + oldPassword: "", + newPassword: "", + confirmNewPassword: "", + userData: [], + }; + + const setPassword = () => { + setRequest(true); + setOldPassword(oldPassword); + setNewPassword(newPassword); + setConfirmNewPassword(confirmNewPassword); + } + + const deleteLanguage = ( itemIndex: number, array: any) => { + let languages = array; + languages.splice(itemIndex, 1); + if(array === programmingLanguage) { + setLanguages([...languages]); + } else if(array === userData) { + setUserData([...languages]); + } + + + } + + return ( + { + values.firstname = firstname; + values.lastname = lastname; + values.programmingLanguage = programmingLanguage; + values.userData = userData; + if(request){ + updateUserData(firstname, lastname); + changePassword(values.oldPassword, values.newPassword, values.confirmNewPassword); + updateUserLang(programmingLanguage, userData).then(() => navigate(paths.myProfile)); + setLanguages([]); + window.location.reload(); + } else { + updateUserData(firstname, lastname); + updateUserLang(programmingLanguage, userData).then(() => navigate(paths.myProfile)); + setLanguages([]); + window.location.reload(); + } + }}> + {({ values, errors, touched, handleChange, handleBlur, handleSubmit, isValid }) => { + return ( +
+ + + + + {t`profile.username`} + + + + + + + {t`profile.useremail`} + + + + + {t`profile.firstname`} + + + + + + {errors.firstname && touched.firstname && errors.firstname} + + + + + + {t`profile.lastname`} + + + + + + {errors.lastname && touched.lastname && errors.lastname} + + + + + {t`profile.password`} + + + + {values.oldPassword.length > 0 ? ( + <>{oldPassShown ? : } + ) : ( + "" + )} + + {values.newPassword.length > 0 ? ( + <>{passShown ? : } + ) : ( + "" + )} + + {values.confirmNewPassword.length > 0 ? ( + <>{conPassShown ? : } + ) : ( + "" + )} + + } + title={t`setNewPassword.title2`} + buttonText={t`profile.button_change_password`} + childrenButton={ + setPassword()}> + {t`setNewPassword.button2`}{" "} + + } + > + + + + {t`profile.programming_language`} + + {userData ? ( +
    + {userData.length > 0 && + userData.map(({ nameLang, level }, index) => ( + + + {nameLang} {level} + + deleteLanguage(index, userData)}/> + + ) + )} +
) + :("")} +
    + {programmingLanguage.length > 0 && + programmingLanguage.map(({ nameLang, level }, index) => ( + + + {nameLang} {level} + + deleteLanguage(index, programmingLanguage)}/> + + ) + )} +
+ + setCurrentNameLang(e.value)} + /> + setCurrentLevel(e.value)} + /> + + } + childrenButton={ + + {t`team.button.add`}{" "} + + } + title={t`team.languageName`} + buttonText={t`team.button.add`} + > + < EditButton type="submit" disabled={!isValid}> + {t`profile.button`} + +
+ {t`registration.foot.home`} +
+
+
+ ); + } + } +
+ ); +}; \ No newline at end of file diff --git a/src/components/Profile/ProfileForm.style.ts b/src/components/Profile/ProfileForm.style.ts new file mode 100644 index 0000000..b78ae15 --- /dev/null +++ b/src/components/Profile/ProfileForm.style.ts @@ -0,0 +1,92 @@ +import styled from "styled-components"; +import { Label, Foot, Button, Input, CloseButton } from "../../styles"; +import { StyledSelect} from "styles"; + +export const ProfileForm = styled.div` + display: flex; + flex-direction: column; + width: 375px; + align-items: center; + margin: auto; +`; + +export const ErrorMsg = styled.div` + color:${({ theme }) => theme.colors.warning || "#FF0000"} ; + align-self: flex-start; + font-size: 12px; + margin: 5px auto 0 60px; +`; + +export const View = styled.div` + position: relative; + + & > img { + position: absolute; + top: 25%; + right: 3%; + cursor: pointer; + } +`; + +export const LabelStyle = styled(Label)` + margin: 20px auto 10px 57px; +`; + +export const Footer = styled(Foot)` + margin-top: 20px; +`; + +export const EditButton = styled(Button)` + margin-top: 20px; +`; + +export const InputStyledElement = styled(Input)` + color: black; + &::placeholder { + text-align: left; + color: #e1e1e1; + border: 1px solid #e1e1e1; + } +`; +export const InputStyled = styled(Input)` + &::placeholder { + text-align: left; + } +`; +export const ButtonInPassModal = styled(Button)` + display:flex; + justify-content: center; + align-items: center; + margin-top: 20px; + max-width: 100px; +`; +export const StyledDiv = styled.div ` + min-height: 130px; +`; +export const StyleFromModalTeam = styled(StyledSelect)` + .Select__placeholder { + color: "#e1e1e1"; + } +`; +export const ClosedButton = styled(CloseButton)` + height: 12px; + width: 12px; + margin-left: 10px; +` +export const LabelLang = styled(Label)` + background: #fff; + border-radius: 12px; + padding: 3px 15px; +`; +export const StyledLi = styled.li ` + margin-bottom: 10px; +`; + +export const StyledCheckbox = styled.div` + display: inline-block; + width: 16px; + height: 16px; + background: ${({ theme }) => theme.colors.primary}; + border-radius: 3px; + transition: all 150ms; +` \ No newline at end of file diff --git a/src/components/Profile/index.ts b/src/components/Profile/index.ts new file mode 100644 index 0000000..b6f21ff --- /dev/null +++ b/src/components/Profile/index.ts @@ -0,0 +1 @@ +export * from "./Profile"; diff --git a/src/components/Profile/validate.ts b/src/components/Profile/validate.ts new file mode 100644 index 0000000..9bc97c1 --- /dev/null +++ b/src/components/Profile/validate.ts @@ -0,0 +1,9 @@ +import * as Yup from "yup"; +import { t } from "i18next"; + + export const ProfileSchema = () => Yup.object().shape({ + firstname: Yup.string() + .min(2, t`registration.validation.firstName`), + lastname: Yup.string() + .min(2, t`registration.validation.lastName`), + }); \ No newline at end of file diff --git a/src/components/Registration/RegistrationForm.tsx b/src/components/Registration/RegistrationForm.tsx index e0bd1c4..4e8803b 100644 --- a/src/components/Registration/RegistrationForm.tsx +++ b/src/components/Registration/RegistrationForm.tsx @@ -49,10 +49,7 @@ export const RegistrationForm = () => { setTimeout(() => { navigate(paths.login, { replace: true }); }, 3000); - toast.success(t`toast.registration.success`); }, - ({ response: { status } }) => - toast.error(status === 400 ? t`toast.registration.validation` : t`toast.registration.error`), ); }} > diff --git a/src/components/index.ts b/src/components/index.ts index d87dfae..8437921 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,6 +1,8 @@ export * from "./Registration"; export * from "./Login"; export * from "./ForgotPassword"; +export * from "./Profile"; +// export * from "./AllTeamProject"; export * from "./Team"; export * from "./UserProjects"; export * from "./Modal"; diff --git a/src/config/level_profile.ts b/src/config/level_profile.ts new file mode 100644 index 0000000..4ebf9c8 --- /dev/null +++ b/src/config/level_profile.ts @@ -0,0 +1,5 @@ +export const level_profile = [ + { value: "junior", label: "junior" }, + { value: "mid", label: "mid" }, + { value: "senior",label: "senior" }, + ]; \ No newline at end of file diff --git a/src/pages/MentorProfilePage.tsx b/src/pages/MentorProfilePage.tsx index 8097078..d743c65 100644 --- a/src/pages/MentorProfilePage.tsx +++ b/src/pages/MentorProfilePage.tsx @@ -1,13 +1,14 @@ import React from "react"; -import { useTranslation } from "react-i18next"; +import { Profile } from "components"; import { Navbar } from "components"; +import { useTranslation } from "react-i18next"; export const MentorProfilePage = () => { const { t } = useTranslation(); return ( <> - -

MentorProfilePage

- - ); + + + +); }; diff --git a/src/pages/NotFoundPage.tsx b/src/pages/NotFoundPage.tsx index 9a032c3..382322d 100644 --- a/src/pages/NotFoundPage.tsx +++ b/src/pages/NotFoundPage.tsx @@ -2,7 +2,7 @@ import React from "react"; import { useTranslation } from "react-i18next"; import { Navbar } from "components"; -import { Line, Page404 } from "styles"; +import { Line, Page404} from "../styles"; import { Footer, FooterWrapperLeft, FooterWrapperRight, Header, LinkFooter } from "styles/stylesPages/HomePage.style"; import { Page404Wrapper } from "styles/stylesPages/Page404.style"; import { paths } from "config/paths"; diff --git a/src/pages/UserProfilePage.tsx b/src/pages/UserProfilePage.tsx index 26b49a8..1bd138c 100644 --- a/src/pages/UserProfilePage.tsx +++ b/src/pages/UserProfilePage.tsx @@ -1,14 +1,12 @@ import React from "react"; -import { useTranslation } from "react-i18next"; - +import { Profile } from "components"; import { Navbar } from "components"; export const UserProfilePage = () => { - const { t } = useTranslation(); - return ( - <> - -

UserProfilePage

- - ); + return ( + <> + + + + ); }; diff --git a/src/services/auth.service.ts b/src/services/auth.service.ts index 6321a57..85e83a8 100644 --- a/src/services/auth.service.ts +++ b/src/services/auth.service.ts @@ -17,6 +17,10 @@ export const isMentorLogged = (): boolean => { return isUserLogged() && localStorage.getItem("mentor") === "true"; }; +export const getUserID = (): any => { + return localStorage.getItem("userID"); +} + const REGISTER_URL = "/users/register"; export const register = ( diff --git a/src/services/user.service.ts b/src/services/user.service.ts index 205af79..7a7c16c 100644 --- a/src/services/user.service.ts +++ b/src/services/user.service.ts @@ -9,6 +9,10 @@ export const getUser = async (id: any) => { return await axios.get(`/users/${id}`); }; +export const getUserLangs = async () => { + return await axios.get(`users/lang`); +} + export const getOnlyUsers = async () => { return await axios.get(`/users/only-users`); }; @@ -56,3 +60,47 @@ export const setNewPass = (newPassword: string, confirmNewPassword: string, toke return res.data; }); }; + +const USERSEDIT_URL = "/users/edit"; + +export const updateUserData = (firstname: string, lastname: string) => { + const token = localStorage.getItem("user") as string; + return axios + .patch( + USERSEDIT_URL, + { + firstname, + lastname + }, + { + headers: { + "x-auth-token": token, + }, + }, + ) + .then((res) => { + return res.data; + }); +}; + +const USERLANGEDIT_URL = "users/lang"; + +export const updateUserLang = (programmingLanguage: any, userData:any) => { + Array.prototype.push.apply(programmingLanguage, userData); + const token = localStorage.getItem("user") as string; + return axios + .patch( + USERLANGEDIT_URL, + { + programmingLanguage + }, + { + headers: { + "x-auth-token": token, + }, + }, + ) + .then((res) => { + return res.data; + }); +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e2ff817..e6389c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1127,7 +1127,7 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.0.0", "@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.10", "@babel/runtime@^7.14.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@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.10", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.18.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.0.tgz#6d77142a19cb6088f0af662af1ada37a604d34ae" integrity sha512-YMQvx/6nKEaucl0MY56mwIG483xk8SDNdlUwb2Ts6FUpr7fm85DxEmsY18LXBNhcTz6tO6JwZV8w1W06v8UKeg== @@ -1964,11 +1964,6 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" - integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== - "@mapbox/node-pre-gyp@^1.0.0": version "1.0.9" resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz#09a8781a3a036151cdebbe8719d6f8b25d4058bc" @@ -2084,6 +2079,11 @@ schema-utils "^3.0.0" source-map "^0.7.3" +"@popperjs/core@^2.8.6": + version "2.11.5" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" + integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== + "@reduxjs/toolkit@^1.8.1": version "1.8.1" resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.8.1.tgz#94ee1981b8cf9227cda40163a04704a9544c9a9f" @@ -2094,6 +2094,18 @@ redux-thunk "^2.4.1" reselect "^4.1.5" +"@restart/context@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@restart/context/-/context-2.1.4.tgz#a99d87c299a34c28bd85bb489cb07bfd23149c02" + integrity sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q== + +"@restart/hooks@^0.4.7": + version "0.4.7" + resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.7.tgz#d79ca6472c01ce04389fc73d4a79af1b5e33cd39" + integrity sha512-ZbjlEHcG+FQtpDPHd7i4FzNNvJf2enAwZfJbpM8CW7BhmOAbsHpZe3tsHwfQUrBuyrxWqPYp2x5UMnilWcY22A== + dependencies: + dequal "^2.0.2" + "@rollup/plugin-babel@^5.2.0": version "5.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" @@ -3280,13 +3292,13 @@ redent "^3.0.0" "@testing-library/react@^12.0.0": - version "12.1.5" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.5.tgz#bb248f72f02a5ac9d949dea07279095fa577963b" - integrity sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg== + version "12.1.4" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.4.tgz#09674b117e550af713db3f4ec4c0942aa8bbf2c0" + integrity sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA== dependencies: "@babel/runtime" "^7.12.5" "@testing-library/dom" "^8.0.0" - "@types/react-dom" "<18.0.0" + "@types/react-dom" "*" "@testing-library/user-event@^13.2.1": version "13.5.0" @@ -3497,6 +3509,11 @@ dependencies: "@types/node" "*" +"@types/invariant@^2.2.33": + version "2.2.35" + resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.35.tgz#cd3ebf581a6557452735688d8daba6cf0bd5a3be" + integrity sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg== + "@types/is-function@^1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.1.tgz#2d024eace950c836d9e3335a66b97960ae41d022" @@ -3654,7 +3671,7 @@ resolved "https://registry.yarnpkg.com/@types/promise-polyfill/-/promise-polyfill-6.0.4.tgz#c56670c70c601264c67191a85875fe2cf98a4cfd" integrity sha512-GSCjjH6mDS8jgpT22rEOkZVqZcYj7i9AHJu4ntpvoohEpa0mLAKP/Kz3POMKqABaFsS4TyNHOeoyWpzycddcoQ== -"@types/prop-types@*": +"@types/prop-types@*", "@types/prop-types@^15.7.3": version "15.7.5" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== @@ -3674,7 +3691,14 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/react-dom@<18.0.0", "@types/react-dom@^17.0.9": +"@types/react-dom@*": + version "18.0.4" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.4.tgz#dcbcadb277bcf6c411ceff70069424c57797d375" + integrity sha512-FgTtbqPOCI3dzZPZoC2T/sx3L34qxy99ITWn4eoSA95qPyXDMH0ALoAqUp49ITniiJFsXUVBtalh/KffMpg21Q== + dependencies: + "@types/react" "*" + +"@types/react-dom@^17.0.9": version "17.0.17" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1" integrity sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg== @@ -3705,14 +3729,14 @@ dependencies: "@types/react" "*" -"@types/react-transition-group@^4.4.0": +"@types/react-transition-group@^4.4.0", "@types/react-transition-group@^4.4.1": version "4.4.4" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e" integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug== dependencies: "@types/react" "*" -"@types/react@*": +"@types/react@*", "@types/react@>=16.14.8", "@types/react@>=16.9.11": version "18.0.9" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.9.tgz#d6712a38bd6cd83469603e7359511126f122e878" integrity sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw== @@ -3847,6 +3871,11 @@ resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== +"@types/warning@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52" + integrity sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA== + "@types/webpack-env@^1.16.0": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.17.0.tgz#f99ce359f1bfd87da90cc4a57cab0a18f34a48d0" @@ -5274,6 +5303,11 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +bootstrap@^4.3.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.1.tgz#bc25380c2c14192374e8dec07cf01b2742d222a2" + integrity sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og== + boxen@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" @@ -5883,6 +5917,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +classnames@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + clean-css@^4.2.3: version "4.2.4" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" @@ -6954,6 +6993,11 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +dequal@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d" + integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug== + des.js@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" @@ -7082,12 +7126,13 @@ dns-equal@^1.0.0: resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= -dns-packet@^5.2.2: - version "5.3.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.3.1.tgz#eb94413789daec0f0ebe2fcc230bdc9d7c91b43d" - integrity sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw== +dns-packet@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" + ip "^1.1.0" + safe-buffer "^5.0.1" doctrine@^2.1.0: version "2.1.0" @@ -7115,7 +7160,7 @@ dom-converter@^0.2.0: dependencies: utila "~0.4" -dom-helpers@^5.0.1: +dom-helpers@^5.0.1, dom-helpers@^5.2.0, dom-helpers@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== @@ -9471,7 +9516,14 @@ interpret@^2.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -ip@^1.1.5: +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +ip@^1.1.0, ip@^1.1.5: version "1.1.8" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== @@ -11397,7 +11449,7 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -13612,6 +13664,14 @@ prompts@^2.0.1, prompts@^2.4.0, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" +prop-types-extra@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" + integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== + dependencies: + react-is "^16.3.2" + warning "^4.0.0" + prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" @@ -13848,6 +13908,37 @@ react-app-polyfill@^3.0.0: regenerator-runtime "^0.13.9" whatwg-fetch "^3.6.2" +react-bootstrap@^1.0.0: + version "1.6.5" + resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.6.5.tgz#1e5e953a8efc4dc70897f61a6985bfa40f7c55cc" + integrity sha512-l2rm5LtDI7JMtdGrzaxNl4OJwH0fMIJDlvwQ2TMvs9h9d0E4ELLpG3J45Pox6xUkpuFfXdWUiGazZXyIuv/OKA== + dependencies: + "@babel/runtime" "^7.14.0" + "@restart/context" "^2.1.4" + "@restart/hooks" "^0.4.7" + "@types/invariant" "^2.2.33" + "@types/prop-types" "^15.7.3" + "@types/react" ">=16.14.8" + "@types/react-transition-group" "^4.4.1" + "@types/warning" "^3.0.0" + classnames "^2.3.1" + dom-helpers "^5.2.1" + invariant "^2.2.4" + prop-types "^15.7.2" + prop-types-extra "^1.1.0" + react-overlays "^5.1.2" + react-transition-group "^4.4.1" + uncontrollable "^7.2.1" + warning "^4.0.3" + +react-chip-input@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-chip-input/-/react-chip-input-1.1.0.tgz#13a0dceabd031491066b52a2214dc7b67a592253" + integrity sha512-/MN3juzviZOoBiPSIO3YTTvHRgLKoNIPSzCUM+Esju9y3R6yp7cfHGe5Y/zP13d01U6533rG0OdROlU57vkaYQ== + dependencies: + bootstrap "^4.3.1" + react-bootstrap "^1.0.0" + react-dev-utils@^12.0.0: version "12.0.1" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" @@ -13950,7 +14041,7 @@ react-is@17.0.2, react-is@^17.0.1: 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.7.0: +react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -13960,11 +14051,30 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + react-merge-refs@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06" integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ== +react-overlays@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-5.1.2.tgz#dbbe8ac8c63133a36e057c317135eadeee9b783e" + integrity sha512-kLCq0ngBtuVnp0eMx8gISD9FaCkifUZoOdHReTJGfnDikvvOjZpi/OduTgXEf6rGYm24WJbHFJFDaKD+ylQ03g== + dependencies: + "@babel/runtime" "^7.13.8" + "@popperjs/core" "^2.8.6" + "@restart/hooks" "^0.4.7" + "@types/warning" "^3.0.0" + dom-helpers "^5.2.0" + prop-types "^15.7.2" + uncontrollable "^7.2.1" + warning "^4.0.3" + react-redux@^8.0.1: version "8.0.2" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.2.tgz#bc2a304bb21e79c6808e3e47c50fe1caf62f7aad" @@ -14083,7 +14193,7 @@ react-toastify@^8.2.0: dependencies: clsx "^1.1.1" -react-transition-group@^4.3.0: +react-transition-group@^4.3.0, react-transition-group@^4.4.1: version "4.4.2" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470" integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg== @@ -16227,6 +16337,16 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +uncontrollable@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.2.1.tgz#1fa70ba0c57a14d5f78905d533cf63916dc75738" + integrity sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ== + dependencies: + "@babel/runtime" "^7.6.3" + "@types/react" ">=16.9.11" + invariant "^2.2.4" + react-lifecycles-compat "^3.0.4" + undefsafe@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" @@ -16686,6 +16806,13 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.12" +warning@^4.0.0, warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + watchpack-chokidar2@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957"