From 9fc3763ba601d0756a5c9fdcba2da2ec889a39f9 Mon Sep 17 00:00:00 2001 From: Yan Zhylavy Date: Tue, 12 Nov 2024 10:17:44 +0200 Subject: [PATCH 01/43] sketch version of mobile view for profile editing, remove one general form submit button with current form handling in favor of individual buttons for each form. --- FrontEnd/public/svg/arrow-down.svg | 3 + FrontEnd/public/svg/arrow-up.svg | 3 + .../MiniComponents/CategoryBadges.jsx | 1 + .../FormComponents/AdditionalInfo.jsx | 4 +- .../FormComponents/ChangePassword.jsx | 6 -- .../FormComponents/ContactsInfo.jsx | 6 +- .../DeleteProfilePage.jsx | 8 +- .../FormFields/PasswordField.module.css | 1 - .../FormComponents/GeneralInfo.jsx | 47 ++++++------ .../FormComponents/ProductServiceInfo.jsx | 6 +- .../FormComponents/StartupInfo.jsx | 12 +-- .../ProfilePage/FormComponents/UserInfo.jsx | 48 ++++++------ .../pages/ProfilePage/Mobile/Accordion.jsx | 14 ++++ .../ProfilePage/Mobile/Accordion.module.css | 0 .../ProfilePage/Mobile/AccordionItem.jsx | 23 ++++++ .../Mobile/AccordionItem.module.css | 39 ++++++++++ .../ProfilePage/Mobile/EditProfileMobile.jsx | 38 ++++++++++ .../Mobile/EditProfileMobile.module.css | 13 ++++ .../src/pages/ProfilePage/ProfilePage.jsx | 73 ++++++++++++------- .../ProfilePageComponents/Description.jsx | 22 +++--- .../ProfilePageComponents/ProfileContent.jsx | 59 ++++----------- .../ProfileFormButton/ProfileFormButton.jsx | 3 +- 22 files changed, 277 insertions(+), 152 deletions(-) create mode 100644 FrontEnd/public/svg/arrow-down.svg create mode 100644 FrontEnd/public/svg/arrow-up.svg create mode 100644 FrontEnd/src/pages/ProfilePage/Mobile/Accordion.jsx create mode 100644 FrontEnd/src/pages/ProfilePage/Mobile/Accordion.module.css create mode 100644 FrontEnd/src/pages/ProfilePage/Mobile/AccordionItem.jsx create mode 100644 FrontEnd/src/pages/ProfilePage/Mobile/AccordionItem.module.css create mode 100644 FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.jsx create mode 100644 FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.module.css diff --git a/FrontEnd/public/svg/arrow-down.svg b/FrontEnd/public/svg/arrow-down.svg new file mode 100644 index 000000000..96d156440 --- /dev/null +++ b/FrontEnd/public/svg/arrow-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/FrontEnd/public/svg/arrow-up.svg b/FrontEnd/public/svg/arrow-up.svg new file mode 100644 index 000000000..224c57140 --- /dev/null +++ b/FrontEnd/public/svg/arrow-up.svg @@ -0,0 +1,3 @@ + + + diff --git a/FrontEnd/src/components/MiniComponents/CategoryBadges.jsx b/FrontEnd/src/components/MiniComponents/CategoryBadges.jsx index eacb7298b..be2cc7805 100644 --- a/FrontEnd/src/components/MiniComponents/CategoryBadges.jsx +++ b/FrontEnd/src/components/MiniComponents/CategoryBadges.jsx @@ -8,6 +8,7 @@ export default function CategoryBadges({ categories }) { fontFamily: 'Geologica', fontSize: 10, margin: 5, + boxShadow: 'none', }; return (
diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx index cc0f0fd14..7077f0f82 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx @@ -33,8 +33,8 @@ const AdditionalInfo = (props) => { }, [mainProfile, profile]); useEffect(() => { - props.currentFormNameHandler(props.curForm); - }, []); + setProfile(props.profile); + }, [props.profile]); const onUpdateFoundationYearField = (e) => { const currentYear = new Date().getFullYear(); diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/ChangePassword.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/ChangePassword.jsx index d466d07bf..6240b0d19 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/ChangePassword.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/ChangePassword.jsx @@ -11,7 +11,6 @@ import css from './ChangePassword.module.css'; export default function ChangePassword(props) { const { setFormIsDirty } = useContext(DirtyFormContext); - const { currentFormNameHandler, curForm } = props; const { register, handleSubmit, @@ -28,9 +27,6 @@ export default function ChangePassword(props) { }, }); - useEffect(() => { - currentFormNameHandler(curForm); - }, [currentFormNameHandler, curForm]); useEffect(() => { setFormIsDirty(isDirty); @@ -121,6 +117,4 @@ ChangePassword.propTypes = { profile_id: PropTypes.number.isRequired, is_staff: PropTypes.bool.isRequired, }).isRequired, - currentFormNameHandler: PropTypes.func.isRequired, - curForm: PropTypes.string.isRequired, }; diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx index 6d5f9fe88..38f0054d0 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx @@ -9,6 +9,7 @@ import { formatPhoneNumber } from '../../../utils/formatPhoneNumber'; import FullField from './FormFields/FullField'; import HalfFormField from './FormFields/HalfFormField'; import Loader from '../../../components/Loader/Loader'; +import ProfileFormButton from '../UI/ProfileFormButton/ProfileFormButton'; import css from './FormComponents.module.css'; import { useMask } from '@react-input/mask'; @@ -38,8 +39,8 @@ const ContactsInfo = (props) => { const inputRef = useMask({ mask: '+380XX XXX XX XX', replacement: { X: /\d/ } }); useEffect(() => { - props.currentFormNameHandler(props.curForm); - }, []); + setProfile(props.profile); + }, [props.profile]); useEffect(() => { if (mainProfile?.phone) { @@ -145,6 +146,7 @@ const ContactsInfo = (props) => { value={profile.address ?? ''} />
+ ) : ( diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/DeleteProfileComponent/DeleteProfilePage.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/DeleteProfileComponent/DeleteProfilePage.jsx index eef063fa3..b7875bc95 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/DeleteProfileComponent/DeleteProfilePage.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/DeleteProfileComponent/DeleteProfilePage.jsx @@ -1,15 +1,11 @@ import css from './DeleteProfilePage.module.css'; import DeleteProfileModal from './DeleteProfileModal'; import MyModal from '../../UI/MyModal/MyModal'; -import { useState, useEffect } from 'react'; +import { useState } from 'react'; -const DeleteProfilePage = (props) => { +const DeleteProfilePage = () => { const [modal, setModal] = useState(false); - useEffect(() => { - props.currentFormNameHandler(props.curForm); - }, []); - const cancelHandler = () => { setModal(false); }; diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.module.css b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.module.css index 1d9636d5b..4c298d864 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.module.css +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.module.css @@ -112,7 +112,6 @@ } .error-dot::before { - position: absolute; margin-left: -8px; content: "*"; color: #ff4d4f; diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx index 1de7f2ee7..763bd89eb 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx @@ -20,6 +20,7 @@ import Loader from '../../../components/Loader/Loader'; import validateEdrpou from '../../../utils/validateEdrpou'; import validateRnokpp from '../../../utils/validateRnokpp'; import BanerModeration from './BanerModeration'; +import ProfileFormButton from '../UI/ProfileFormButton/ProfileFormButton'; const LABELS = { name: 'Назва компанії', @@ -62,8 +63,8 @@ const GeneralInfo = (props) => { const { profile: mainProfile, mutate: profileMutate } = useProfile(); const [profile, setProfile] = useState(props.profile); const [formStateErr, setFormStateErr] = useState(ERRORS); - const [bannerImage, setBannerImage] = useState(props.profile.banner?.path); - const [logoImage, setLogoImage] = useState(props.profile.logo?.path); + const [bannerImage, setBannerImage] = useState(props.profile?.banner?.path); + const [logoImage, setLogoImage] = useState(props.profile?.logo?.path); const [bannerImageError, setBannerImageError] = useState(null); const [logoImageError, setLogoImageError] = useState(null); const [edrpouFieldError, setEdrpouFieldError] = useState(null); @@ -106,8 +107,8 @@ const GeneralInfo = (props) => { }, [mainProfile, profile]); useEffect(() => { - props.currentFormNameHandler(props.curForm); - }, []); + setProfile(props.profile); + }, [props.profile]); const checkRequiredFields = () => { let isValid = true; @@ -290,10 +291,12 @@ const GeneralInfo = (props) => { try { const response = await axios.post(url, formData); setProfile((prevState) => { - return { ...prevState, [imageKey]: { - ...prevState[imageKey], - uuid: response.data.uuid - }}; + return { + ...prevState, [imageKey]: { + ...prevState[imageKey], + uuid: response.data.uuid + } + }; }); } catch (error) { console.error( @@ -327,12 +330,12 @@ const GeneralInfo = (props) => { e.target.value = ''; const imageUrl = e.target.name === 'banner' - ? `${process.env.REACT_APP_BASE_API_URL}/api/image/banner/` - : `${process.env.REACT_APP_BASE_API_URL}/api/image/logo/`; + ? `${process.env.REACT_APP_BASE_API_URL}/api/image/banner/` + : `${process.env.REACT_APP_BASE_API_URL}/api/image/logo/`; const setImage = e.target.name === 'banner' - ? setBannerImage - : setLogoImage; + ? setBannerImage + : setLogoImage; if (file && checkMaxImageSize(e.target.name, file)) { setImage(URL.createObjectURL(file)); await uploadImage(imageUrl, e.target.name, file); @@ -342,8 +345,8 @@ const GeneralInfo = (props) => { const deleteImageHandler = async (name) => { const imageUrl = name === 'banner' - ? `${process.env.REACT_APP_BASE_API_URL}/api/image/banner/${profile.banner?.uuid}` - : `${process.env.REACT_APP_BASE_API_URL}/api/image/logo/${profile.logo?.uuid}`; + ? `${process.env.REACT_APP_BASE_API_URL}/api/image/banner/${profile.banner?.uuid}` + : `${process.env.REACT_APP_BASE_API_URL}/api/image/logo/${profile.logo?.uuid}`; try { await axios.delete(imageUrl); if (name === 'banner') setBannerImage(null); @@ -352,12 +355,12 @@ const GeneralInfo = (props) => { setProfile((prevState) => { const newState = { ...prevState, [name]: null }; return newState; - }); - } catch (error) { - console.error('Error deleting image:', - error.response ? error.response.data : error.message); - toast.error('Не вдалося видалити банер/лого, сталася помилка'); - } + }); + } catch (error) { + console.error('Error deleting image:', + error.response ? error.response.data : error.message); + toast.error('Не вдалося видалити банер/лого, сталася помилка'); + } }; const errorMessages = { @@ -396,7 +399,7 @@ const GeneralInfo = (props) => { try { const response = await axios.patch( `${process.env.REACT_APP_BASE_API_URL}/api/profiles/${user.profile_id}`, - data.profileChanges + data.profileChanges ); profileMutate(response.data); toast.success('Зміни успішно збережено'); @@ -558,6 +561,7 @@ const GeneralInfo = (props) => { requiredField={true} /> + ) : ( @@ -590,6 +594,5 @@ GeneralInfo.propTypes = { path: PropTypes.string, }), }).isRequired, - currentFormNameHandler: PropTypes.func, curForm: PropTypes.string, }; diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/ProductServiceInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/ProductServiceInfo.jsx index 54aade2c0..214b7d808 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/ProductServiceInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/ProductServiceInfo.jsx @@ -8,6 +8,7 @@ import defineChanges from '../../../utils/defineChanges'; import { useAuth, useProfile } from '../../../hooks'; import TextField from './FormFields/TextField'; import Loader from '../../../components/Loader/Loader'; +import ProfileFormButton from '../UI/ProfileFormButton/ProfileFormButton'; import css from './FormComponents.module.css'; const LABELS = { @@ -34,8 +35,8 @@ const ProductServiceInfo = (props) => { }, [mainProfile, profile]); useEffect(() => { - props.currentFormNameHandler(props.curForm); - }, []); + setProfile(props.profile); + }, [props.profile]); const onUpdateTextAreaField = (e) => { if (e.target.value.length <= TEXT_AREA_MAX_LENGTH) @@ -94,6 +95,7 @@ const ProductServiceInfo = (props) => { maxLength={TEXT_AREA_MAX_LENGTH} /> + ) : ( diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/StartupInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/StartupInfo.jsx index 376338db9..d3e23ff35 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/StartupInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/StartupInfo.jsx @@ -8,6 +8,7 @@ import defineChanges from '../../../utils/defineChanges'; import { useAuth, useProfile } from '../../../hooks'; import TextField from './FormFields/TextField'; import Loader from '../../../components/Loader/Loader'; +import ProfileFormButton from '../UI/ProfileFormButton/ProfileFormButton'; import css from './FormComponents.module.css'; const LABELS = { @@ -26,15 +27,15 @@ const StartupInfo = (props) => { startup_idea: { defaultValue: mainProfile?.startup_idea ?? null }, }; + useEffect(() => { + setProfile(props.profile); + }, [props.profile]); + useEffect(() => { const isDirty = checkFormIsDirty(fields, null, profile); setFormIsDirty(isDirty); }, [mainProfile, profile]); - useEffect(() => { - props.currentFormNameHandler(props.curForm); - }, []); - const onUpdateTextAreaField = (e) => { if (e.target.value.length <= TEXT_AREA_MAX_LENGTH) setProfile((prevState) => { @@ -80,10 +81,11 @@ const StartupInfo = (props) => { label={LABELS.startup_idea} updateHandler={onUpdateTextAreaField} requiredField={false} - value={profile.startup_idea ?? ''} + value={profile?.startup_idea ?? ''} maxLength={TEXT_AREA_MAX_LENGTH} /> + ) : ( diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx index 329f01315..58edfff0a 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx @@ -8,6 +8,7 @@ import checkFormIsDirty from '../../../utils/checkFormIsDirty'; import defineChanges from '../../../utils/defineChanges'; import HalfFormField from './FormFields/HalfFormField'; import Loader from '../../../components/Loader/Loader'; +import ProfileFormButton from '../UI/ProfileFormButton/ProfileFormButton'; import css from './FormComponents.module.css'; const LABELS = { @@ -46,14 +47,19 @@ const UserInfo = (props) => { person_position: { defaultValue: profile?.person_position ?? null }, }; + useEffect(() => { + setUpdateUser(props.user); + }, [props.user]); + + useEffect(() => { + setUpdateProfile(props.profile); + }, [props.profile]); + useEffect(() => { const isDirty = checkFormIsDirty(fields, updateUser, updateProfile); setFormIsDirty(isDirty); }, [user, profile, updateUser, updateProfile]); - useEffect(() => { - props.currentFormNameHandler(props.curForm); - }, []); const errorMessageTemplates = { requiredField: 'Обов’язкове поле', @@ -137,18 +143,18 @@ const UserInfo = (props) => { } }; - const onBlurHandler = (e) => { - const { value: rawFieldValue, name: fieldName } = e.target; - const fieldValue = rawFieldValue.replace(/\s{2,}/g, ' ').trim(); - if (fieldName === 'person_position') { - setUpdateProfile((prevState) => ({ - ...prevState, - [fieldName]: fieldValue, - })); - } else { - setUpdateUser((prevState) => ({ ...prevState, [fieldName]: fieldValue })); - } - }; + // const onBlurHandler = (e) => { + // const { value: rawFieldValue, name: fieldName } = e.target; + // const fieldValue = rawFieldValue.replace(/\s{2,}/g, ' ').trim(); + // if (fieldName === 'person_position') { + // setUpdateProfile((prevState) => ({ + // ...prevState, + // [fieldName]: fieldValue, + // })); + // } else { + // setUpdateUser((prevState) => ({ ...prevState, [fieldName]: fieldValue })); + // } + // }; const handleSubmit = async (event) => { event.preventDefault(); @@ -200,9 +206,8 @@ const UserInfo = (props) => { noValidate >
{ name="surname" label={LABELS.surname} updateHandler={onUpdateField} - onBlur={onBlurHandler} + // onBlur={onBlurHandler} error={ formStateErr['surname']['error'] ? formStateErr['surname']['message'] @@ -225,7 +230,7 @@ const UserInfo = (props) => { name="name" label={LABELS.name} updateHandler={onUpdateField} - onBlur={onBlurHandler} + // onBlur={onBlurHandler} error={ formStateErr['name']['error'] ? formStateErr['name']['message'] @@ -242,7 +247,7 @@ const UserInfo = (props) => { name="person_position" label={LABELS.person_position} updateHandler={onUpdateField} - onBlur={onBlurHandler} + // onBlur={onBlurHandler} error={ formStateErr['person_position']?.['error'] ? formStateErr['person_position']['message'] @@ -261,6 +266,7 @@ const UserInfo = (props) => { />
+ ) : ( diff --git a/FrontEnd/src/pages/ProfilePage/Mobile/Accordion.jsx b/FrontEnd/src/pages/ProfilePage/Mobile/Accordion.jsx new file mode 100644 index 000000000..95dc8c47b --- /dev/null +++ b/FrontEnd/src/pages/ProfilePage/Mobile/Accordion.jsx @@ -0,0 +1,14 @@ +import AccordionItem from './AccordionItem'; + +const Accordion = ({ sections }) => { + + return ( +
+ {sections.map((section, index) => ( + + ))} +
+ ); +}; + +export default Accordion; \ No newline at end of file diff --git a/FrontEnd/src/pages/ProfilePage/Mobile/Accordion.module.css b/FrontEnd/src/pages/ProfilePage/Mobile/Accordion.module.css new file mode 100644 index 000000000..e69de29bb diff --git a/FrontEnd/src/pages/ProfilePage/Mobile/AccordionItem.jsx b/FrontEnd/src/pages/ProfilePage/Mobile/AccordionItem.jsx new file mode 100644 index 000000000..39e1d03a5 --- /dev/null +++ b/FrontEnd/src/pages/ProfilePage/Mobile/AccordionItem.jsx @@ -0,0 +1,23 @@ +import { useState } from 'react'; +import css from './AccordionItem.module.css'; + +const AccordionItem = (props) => { + const [isOpen, setIsOpen] = useState(false); + + const toggle = () => { + setIsOpen(!isOpen); + }; + + return ( +
+ +
+ {props.content} +
+
+ ); +}; + +export default AccordionItem; \ No newline at end of file diff --git a/FrontEnd/src/pages/ProfilePage/Mobile/AccordionItem.module.css b/FrontEnd/src/pages/ProfilePage/Mobile/AccordionItem.module.css new file mode 100644 index 000000000..0d2e6e98e --- /dev/null +++ b/FrontEnd/src/pages/ProfilePage/Mobile/AccordionItem.module.css @@ -0,0 +1,39 @@ +.accordion-content { + max-height: 1100px; + transition: max-height 1s ease-in-out; + overflow: hidden; + border-radius: 6px; +} + +.accordion-content.close { + max-height: 0; +} + +.accordion-button { + display: flex; + background-color: var(--main-white); + font-family: var(--font-main); + font-size: 16px; + width: 335px; + margin-left: 3px; + text-align: left; + padding: 4px 6px; + position: relative; + border-radius: 10px; + padding-top: 13px; + height: 49px; + cursor: pointer; +} + +.accordion-button img { + top: 20px; + position: absolute; + right: 5px; +} + +.accordion-item { + border-radius: 6px; + width: 342px; + background-color: var(--main-white); + margin: 6px; +} \ No newline at end of file diff --git a/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.jsx b/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.jsx new file mode 100644 index 000000000..8f2b8eed0 --- /dev/null +++ b/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.jsx @@ -0,0 +1,38 @@ +import Accordion from './Accordion'; +import AdditionalInfo from '../FormComponents/AdditionalInfo'; +import ContactsInfo from '../FormComponents/ContactsInfo'; +import DeleteProfilePage from '../FormComponents/DeleteProfileComponent/DeleteProfilePage'; +import GeneralInfo from '../FormComponents/GeneralInfo'; +import ProductServiceInfo from '../FormComponents/ProductServiceInfo'; +import StartupInfo from '../FormComponents/StartupInfo'; +import UserInfo from '../FormComponents/UserInfo'; +import ChangePassword from '../FormComponents/ChangePassword'; +import { useAuth, useProfile } from '../../../hooks'; +import css from './EditProfileMobile.module.css'; + + + + +const EditProfileMobile = () => { + const { user } = useAuth(); + const { profile } = useProfile(); + const sections = [ + { title: 'Інформація про користувача', content: }, + { title: 'Загальна інформація', content: }, + { title: 'Контакти', content: }, + { title: 'Інформація про товари/послуги', content: }, + { title: 'Додаткова інформація', content: }, + { title: 'Стартап', content: }, + { title: 'Змінити пароль', content: }, + { title: 'Видалити профіль', content: }, + ]; + + return ( +
+

Профіль користувача

+ +
+ ); +}; + +export default EditProfileMobile; \ No newline at end of file diff --git a/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.module.css b/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.module.css new file mode 100644 index 000000000..142b6914c --- /dev/null +++ b/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.module.css @@ -0,0 +1,13 @@ +.container { + width: 375px; + padding: 20px 16px; + background-color: #F9F5EC; + margin: auto; +} + +.head { + font-family: var(--font-main); + font-size: 20px; + font-weight: 700; + padding: 14px 8px; +} \ No newline at end of file diff --git a/FrontEnd/src/pages/ProfilePage/ProfilePage.jsx b/FrontEnd/src/pages/ProfilePage/ProfilePage.jsx index 7de127d7b..4c16eae8e 100644 --- a/FrontEnd/src/pages/ProfilePage/ProfilePage.jsx +++ b/FrontEnd/src/pages/ProfilePage/ProfilePage.jsx @@ -1,41 +1,64 @@ import css from './ProfilePage.module.css'; import Description from './ProfilePageComponents/Description'; import ProfileContent from './ProfilePageComponents/ProfileContent'; -import { useState } from 'react'; -import BreadCrumbs from '../../components/BreadCrumbs/BreadCrumbs'; +import { useState, useEffect } from 'react'; +import { DirtyFormContext } from '../../context/DirtyFormContext'; import Loader from '../../components/Loader/Loader'; import { useAuth, useProfile } from '../../hooks'; +import useWindowWidth from '../../hooks/useWindowWidth'; +import EditProfileMobile from './Mobile/EditProfileMobile'; const ProfilePage = () => { + const [formIsDirty, setFormIsDirty] = useState(false); const { user } = useAuth(); const { profile } = useProfile(); - const [formName, setFormName] = useState(''); + const windowWidth = useWindowWidth(); - const currentFormNameHandler = (currentName) => { - setFormName(currentName); - }; + useEffect(() => { + const onBeforeUnload = (e) => { + if (formIsDirty) { + e.preventDefault(); + e.returnValue = ''; + } + }; + window.addEventListener('beforeunload', onBeforeUnload); + return () => { + window.removeEventListener('beforeunload', onBeforeUnload); + }; + }, [formIsDirty]); + + + if (windowWidth < 768) { + return ( + <> + + + + + ); + } return (
- - {!profile ? ( - - ) : ( - <> - - - - )} -
+ + {!profile ? ( + + ) : ( + <> + + + + )} + + ); }; diff --git a/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/Description.jsx b/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/Description.jsx index c1e2a89a9..3546e7fdc 100644 --- a/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/Description.jsx +++ b/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/Description.jsx @@ -1,16 +1,16 @@ import { PropTypes } from 'prop-types'; import css from './Description.module.css'; -const DESCRIPTIONS = { - UserInfo: 'Інформація про користувача платформи', - GeneralInfo: 'Інформація про компанію', - ContactsInfo: 'Інформація про компанію', - ProductServiceInfo: 'Інформація про компанію', - AdditionalInfo: 'Інформація про компанію', - StartupInfo: 'Інформація про стартап', - Delete: 'Видалення профілю', - ChangePassword: 'Зміна паролю користувача', -}; +// const DESCRIPTIONS = { +// UserInfo: 'Інформація про користувача платформи', +// GeneralInfo: 'Інформація про компанію', +// ContactsInfo: 'Інформація про компанію', +// ProductServiceInfo: 'Інформація про компанію', +// AdditionalInfo: 'Інформація про компанію', +// StartupInfo: 'Інформація про стартап', +// Delete: 'Видалення профілю', +// ChangePassword: 'Зміна паролю користувача', +// }; const Description = (props) => { return ( @@ -28,7 +28,6 @@ const Description = (props) => {
{props.companyName}
- {DESCRIPTIONS[props.formName]}
@@ -40,5 +39,4 @@ export default Description; Description.propTypes = { companyName: PropTypes.string, companyLogo: PropTypes.string, - formName: PropTypes.string, }; diff --git a/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/ProfileContent.jsx b/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/ProfileContent.jsx index 0e4e89ee0..1a0cb1875 100644 --- a/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/ProfileContent.jsx +++ b/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/ProfileContent.jsx @@ -1,7 +1,7 @@ import { Tooltip } from 'antd'; import { PropTypes } from 'prop-types'; import { Link, NavLink, Route, Routes, useBlocker } from 'react-router-dom'; -import { useEffect, useState } from 'react'; +import { useEffect, useState,useContext } from 'react'; import { DirtyFormContext } from '../../../context/DirtyFormContext'; import AdditionalInfo from '../FormComponents/AdditionalInfo'; import ContactsInfo from '../FormComponents/ContactsInfo'; @@ -10,19 +10,17 @@ import GeneralInfo from '../FormComponents/GeneralInfo'; import ProductServiceInfo from '../FormComponents/ProductServiceInfo'; import StartupInfo from '../FormComponents/StartupInfo'; import UserInfo from '../FormComponents/UserInfo'; -import ProfileFormButton from '../UI/ProfileFormButton/ProfileFormButton'; import MyModal from '../UI/MyModal/MyModal'; import WarnUnsavedDataModal from '../FormComponents/WarnUnsavedDataModal'; import ChangePassword from '../FormComponents/ChangePassword'; import css from './ProfileContent.module.css'; import tooltipInnerContentStyles from '../../CustomThemes/customProfileTooltipThemes'; import INFOLINKS from './TextInfoLinks'; -import FORM_NAMES from './TextFormNames'; const ProfileContent = (props) => { const [modal, setModal] = useState(false); - const [formIsDirty, setFormIsDirty] = useState(false); + const { formIsDirty, setFormIsDirty } = useContext(DirtyFormContext); const blocker = useBlocker( ({ currentLocation, nextLocation }) => formIsDirty && @@ -48,18 +46,7 @@ const ProfileContent = (props) => { setModal(false); }; - useEffect(() => { - const onBeforeUnload = (e) => { - if (formIsDirty) { - e.preventDefault(); - e.returnValue = ''; - } - }; - window.addEventListener('beforeunload', onBeforeUnload); - return () => { - window.removeEventListener('beforeunload', onBeforeUnload); - }; - }, [formIsDirty]); + return (
@@ -109,59 +96,41 @@ const ProfileContent = (props) => { Видалити профіль
- + } /> + profile={props.profile} />} /> } /> + profile={props.profile} />} /> } /> + profile={props.profile} />} /> } /> + profile={props.profile} />} /> } /> + profile={props.profile} />} /> } /> + profile={props.profile} />} /> } /> + element={} /> } /> + user={props.user} />} /> - - - {props.formName !== 'Delete' && } + {blocker.state === 'blocked' && ( @@ -198,6 +167,4 @@ ProfileContent.propTypes = { categories: PropTypes.array, activities: PropTypes.array, }).isRequired, - currentFormNameHandler: PropTypes.func, - formName: PropTypes.string, }; diff --git a/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.jsx b/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.jsx index 2f716b84b..e9b55bba7 100644 --- a/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.jsx +++ b/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.jsx @@ -4,10 +4,9 @@ const ProfileFormButton = (props) => { return (
From 769e3e2bc5bca09a382d305f4834f730130f3723 Mon Sep 17 00:00:00 2001 From: Yan Zhylavy Date: Tue, 12 Nov 2024 12:11:00 +0200 Subject: [PATCH 02/43] css adjustments for form fields, textareas --- .../ProfilePage/FormComponents/ContactsInfo.jsx | 3 +-- .../FormComponents/FormComponents.module.css | 3 ++- .../FormFields/HalfFormField.module.css | 12 ++++++++---- .../FormComponents/FormFields/TextField.module.css | 4 ++-- .../pages/ProfilePage/FormComponents/GeneralInfo.jsx | 3 +-- .../ProfilePage/Mobile/AccordionItem.module.css | 2 +- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx index 38f0054d0..b7abab15b 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx @@ -6,7 +6,6 @@ import { useAuth, useProfile } from '../../../hooks'; import checkFormIsDirty from '../../../utils/checkFormIsDirty'; import defineChanges from '../../../utils/defineChanges'; import { formatPhoneNumber } from '../../../utils/formatPhoneNumber'; -import FullField from './FormFields/FullField'; import HalfFormField from './FormFields/HalfFormField'; import Loader from '../../../components/Loader/Loader'; import ProfileFormButton from '../UI/ProfileFormButton/ProfileFormButton'; @@ -138,7 +137,7 @@ const ContactsInfo = (props) => { error={phoneNumberError} />
- { maxLength={100} /> - Date: Tue, 12 Nov 2024 12:47:32 +0200 Subject: [PATCH 03/43] Change css for submit button --- .../FormComponents/AdditionalInfo.jsx | 2 ++ .../ProfileFormButton/ProfileFormButton.jsx | 6 ++-- .../ProfileFormButton.module.css | 34 ++++--------------- 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx index 7077f0f82..07855becc 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx @@ -8,6 +8,7 @@ import defineChanges from '../../../utils/defineChanges'; import { useAuth, useProfile } from '../../../hooks'; import HalfFormField from './FormFields/HalfFormField'; import Loader from '../../../components/Loader/Loader'; +import ProfileFormButton from '../UI/ProfileFormButton/ProfileFormButton'; import css from './FormComponents.module.css'; const LABELS = { @@ -112,6 +113,7 @@ const AdditionalInfo = (props) => { /> + ) : ( diff --git a/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.jsx b/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.jsx index e9b55bba7..f8e357f00 100644 --- a/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.jsx +++ b/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.jsx @@ -2,13 +2,13 @@ import css from './ProfileFormButton.module.css'; const ProfileFormButton = (props) => { return ( -
+
); diff --git a/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.module.css b/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.module.css index a30e8a64a..3761e63e6 100644 --- a/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.module.css +++ b/FrontEnd/src/pages/ProfilePage/UI/ProfileFormButton/ProfileFormButton.module.css @@ -1,38 +1,18 @@ -.sign-up-footer__buttons { +.submit-button__conteiner { display: flex; align-items: flex-start; - padding: 6px 0px; - background: #EFFFF6; - width: var(--main-block-size); + padding: 11px 7px; + background-color: var(--main-white); } -.sign-up__button { - display: flex; - justify-content: center; - align-items: center; - gap: 10px; - border-radius: 4px; - border: 1px solid #1F9A7C; - background: #1F9A7C; - box-shadow: 0px 2px 0px 0px rgba(0, 0, 0, 0.04); - color: white; - text-align: center; - font-feature-settings: 'calt' off; - font-style: normal; - padding: 5px 15px 5px 15px; +.submit-button { border-radius: 4px; - border: 1px; - gap: 10px; + background: var(--main-button-color); + color: var(--main-white); + padding: 10px 16px; font-family: var(--font-main); font-size: 16px; font-weight: 600; line-height: 20px; - letter-spacing: -0.01em; - text-align: center; cursor: pointer; - margin-left: 430px; -} - -.sign-up__button:active { - transform: translateY(2px); } From 66d71403455f7267dd7867ad5b15835b5063e2ae Mon Sep 17 00:00:00 2001 From: Yan Zhylavy Date: Tue, 12 Nov 2024 13:52:31 +0200 Subject: [PATCH 04/43] Adjust ChangePassword inputs --- .../FormComponents/ChangePassword.module.css | 3 +-- .../FormFields/PasswordField.jsx | 2 +- .../FormFields/PasswordField.module.css | 19 +++++++------------ .../Mobile/EditProfileMobile.module.css | 2 +- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/ChangePassword.module.css b/FrontEnd/src/pages/ProfilePage/FormComponents/ChangePassword.module.css index 776533af1..1fba01340 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/ChangePassword.module.css +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/ChangePassword.module.css @@ -1,5 +1,4 @@ .form__container { word-wrap: break-word; - width: 530px; - margin-left: 10px; + margin-left: 15px; } \ No newline at end of file diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.jsx index 5f0060e1f..b1bf8bf39 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.jsx @@ -57,7 +57,7 @@ const PasswordField = (props) => { onKeyDown={preventEnterSubmit} id={inputId} type={showPassword ? 'text' : 'password'} - placeholder={label} + // placeholder={label} {...register(name, { required: errorMessages.requiredField, pattern: checkValid && { diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.module.css b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.module.css index 4c298d864..c8df65002 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.module.css +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.module.css @@ -45,6 +45,10 @@ .password-field__item input { border: none; + font-family: 'Geologica'; + font-size: 14px; + font-weight: 400; + line-height: 22px; } .password-field__item input:focus { @@ -52,17 +56,6 @@ outline: none; } -.password-field__item input::placeholder { - font-style: normal; - font-family: "Inter", sans-serif; - font-size: 14px; - font-weight: 400; - line-height: 22px; - letter-spacing: -0.01em; - text-align: left; - color: #00000040; -} - .password-field__password { display: flex; padding: 4px 12px; @@ -72,6 +65,8 @@ border-radius: 2px; border: 1px solid #d9d9d9; background: #fff; + height: 30.5px; + width: 285.5px; } .password-field__password:focus { @@ -112,7 +107,7 @@ } .error-dot::before { - margin-left: -8px; + margin-left: -11px; content: "*"; color: #ff4d4f; text-align: right; diff --git a/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.module.css b/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.module.css index 142b6914c..ddce67b96 100644 --- a/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.module.css +++ b/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.module.css @@ -1,5 +1,5 @@ .container { - width: 375px; + width: 343px; padding: 20px 16px; background-color: #F9F5EC; margin: auto; From 650910bb97d81355fb2523362f8217ff9380d067 Mon Sep 17 00:00:00 2001 From: Yan Zhylavy Date: Tue, 12 Nov 2024 14:09:20 +0200 Subject: [PATCH 05/43] Delete some redundant code --- .../FormFields/PasswordField.jsx | 1 - .../FormComponents/GeneralInfo.jsx | 22 +++++++------- .../ProfilePage/FormComponents/UserInfo.jsx | 30 +++++++++---------- .../ProfilePageComponents/Description.jsx | 11 ------- 4 files changed, 25 insertions(+), 39 deletions(-) diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.jsx index b1bf8bf39..ad32f908f 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/PasswordField.jsx @@ -57,7 +57,6 @@ const PasswordField = (props) => { onKeyDown={preventEnterSubmit} id={inputId} type={showPassword ? 'text' : 'password'} - // placeholder={label} {...register(name, { required: errorMessages.requiredField, pattern: checkValid && { diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx index 84620d474..ec2b0a8f8 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx @@ -290,12 +290,10 @@ const GeneralInfo = (props) => { try { const response = await axios.post(url, formData); setProfile((prevState) => { - return { - ...prevState, [imageKey]: { - ...prevState[imageKey], - uuid: response.data.uuid - } - }; + return { ...prevState, [imageKey]: { + ...prevState[imageKey], + uuid: response.data.uuid + }}; }); } catch (error) { console.error( @@ -329,12 +327,12 @@ const GeneralInfo = (props) => { e.target.value = ''; const imageUrl = e.target.name === 'banner' - ? `${process.env.REACT_APP_BASE_API_URL}/api/image/banner/` - : `${process.env.REACT_APP_BASE_API_URL}/api/image/logo/`; + ? `${process.env.REACT_APP_BASE_API_URL}/api/image/banner/` + : `${process.env.REACT_APP_BASE_API_URL}/api/image/logo/`; const setImage = e.target.name === 'banner' - ? setBannerImage - : setLogoImage; + ? setBannerImage + : setLogoImage; if (file && checkMaxImageSize(e.target.name, file)) { setImage(URL.createObjectURL(file)); await uploadImage(imageUrl, e.target.name, file); @@ -344,8 +342,8 @@ const GeneralInfo = (props) => { const deleteImageHandler = async (name) => { const imageUrl = name === 'banner' - ? `${process.env.REACT_APP_BASE_API_URL}/api/image/banner/${profile.banner?.uuid}` - : `${process.env.REACT_APP_BASE_API_URL}/api/image/logo/${profile.logo?.uuid}`; + ? `${process.env.REACT_APP_BASE_API_URL}/api/image/banner/${profile.banner?.uuid}` + : `${process.env.REACT_APP_BASE_API_URL}/api/image/logo/${profile.logo?.uuid}`; try { await axios.delete(imageUrl); if (name === 'banner') setBannerImage(null); diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx index 58edfff0a..63e41f35b 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx @@ -143,18 +143,18 @@ const UserInfo = (props) => { } }; - // const onBlurHandler = (e) => { - // const { value: rawFieldValue, name: fieldName } = e.target; - // const fieldValue = rawFieldValue.replace(/\s{2,}/g, ' ').trim(); - // if (fieldName === 'person_position') { - // setUpdateProfile((prevState) => ({ - // ...prevState, - // [fieldName]: fieldValue, - // })); - // } else { - // setUpdateUser((prevState) => ({ ...prevState, [fieldName]: fieldValue })); - // } - // }; + const onBlurHandler = (e) => { + const { value: rawFieldValue, name: fieldName } = e.target; + const fieldValue = rawFieldValue.replace(/\s{2,}/g, ' ').trim(); + if (fieldName === 'person_position') { + setUpdateProfile((prevState) => ({ + ...prevState, + [fieldName]: fieldValue, + })); + } else { + setUpdateUser((prevState) => ({ ...prevState, [fieldName]: fieldValue })); + } + }; const handleSubmit = async (event) => { event.preventDefault(); @@ -215,7 +215,7 @@ const UserInfo = (props) => { name="surname" label={LABELS.surname} updateHandler={onUpdateField} - // onBlur={onBlurHandler} + onBlur={onBlurHandler} error={ formStateErr['surname']['error'] ? formStateErr['surname']['message'] @@ -230,7 +230,7 @@ const UserInfo = (props) => { name="name" label={LABELS.name} updateHandler={onUpdateField} - // onBlur={onBlurHandler} + onBlur={onBlurHandler} error={ formStateErr['name']['error'] ? formStateErr['name']['message'] @@ -247,7 +247,7 @@ const UserInfo = (props) => { name="person_position" label={LABELS.person_position} updateHandler={onUpdateField} - // onBlur={onBlurHandler} + onBlur={onBlurHandler} error={ formStateErr['person_position']?.['error'] ? formStateErr['person_position']['message'] diff --git a/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/Description.jsx b/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/Description.jsx index 3546e7fdc..cda34aab2 100644 --- a/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/Description.jsx +++ b/FrontEnd/src/pages/ProfilePage/ProfilePageComponents/Description.jsx @@ -1,17 +1,6 @@ import { PropTypes } from 'prop-types'; import css from './Description.module.css'; -// const DESCRIPTIONS = { -// UserInfo: 'Інформація про користувача платформи', -// GeneralInfo: 'Інформація про компанію', -// ContactsInfo: 'Інформація про компанію', -// ProductServiceInfo: 'Інформація про компанію', -// AdditionalInfo: 'Інформація про компанію', -// StartupInfo: 'Інформація про стартап', -// Delete: 'Видалення профілю', -// ChangePassword: 'Зміна паролю користувача', -// }; - const Description = (props) => { return (
From 4cc2acad1422c422b28440df28926f0a1c2631cd Mon Sep 17 00:00:00 2001 From: Yan Zhylavy Date: Thu, 14 Nov 2024 10:20:50 +0200 Subject: [PATCH 06/43] Add optional chaining into checkFormIsDirty --- FrontEnd/src/utils/checkFormIsDirty.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrontEnd/src/utils/checkFormIsDirty.js b/FrontEnd/src/utils/checkFormIsDirty.js index 4c9b5dc1d..2d58f5809 100644 --- a/FrontEnd/src/utils/checkFormIsDirty.js +++ b/FrontEnd/src/utils/checkFormIsDirty.js @@ -45,7 +45,7 @@ const checkFormIsDirty = (fields, userData, profileData) => { } if (key === 'founded') { - if ((defaultValue !== null && currentValue !== null && defaultValue.toString() !== currentValue.toString()) || + if ((defaultValue !== null && currentValue !== null && defaultValue?.toString() !== currentValue?.toString()) || (defaultValue === null && (currentValue !== null && currentValue !== ''))) { return true; } From 22d3e8e73109cf75c29f765cb109a6d1e6d57aa3 Mon Sep 17 00:00:00 2001 From: Yan Zhylavy Date: Thu, 14 Nov 2024 11:20:09 +0200 Subject: [PATCH 07/43] Change structure and Loader rendering logic, remove apparently redundant useEffects from profile editing form components --- .../FormComponents/AdditionalInfo.jsx | 4 -- .../FormComponents/ContactsInfo.jsx | 4 -- .../FormComponents/FormFields/ImageField.jsx | 1 - .../FormComponents/GeneralInfo.jsx | 4 -- .../FormComponents/StartupInfo.jsx | 4 -- .../ProfilePage/FormComponents/UserInfo.jsx | 8 ---- .../ProfilePage/Mobile/EditProfileMobile.jsx | 38 ++++++++++--------- 7 files changed, 21 insertions(+), 42 deletions(-) diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx index 07855becc..61a982bc4 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/AdditionalInfo.jsx @@ -33,10 +33,6 @@ const AdditionalInfo = (props) => { setFormIsDirty(isDirty); }, [mainProfile, profile]); - useEffect(() => { - setProfile(props.profile); - }, [props.profile]); - const onUpdateFoundationYearField = (e) => { const currentYear = new Date().getFullYear(); const year = Number(e.target.value); diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx index b7abab15b..812020b6c 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/ContactsInfo.jsx @@ -37,10 +37,6 @@ const ContactsInfo = (props) => { const inputRef = useMask({ mask: '+380XX XXX XX XX', replacement: { X: /\d/ } }); - useEffect(() => { - setProfile(props.profile); - }, [props.profile]); - useEffect(() => { if (mainProfile?.phone) { setProfile((prevState) => ({ diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/ImageField.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/ImageField.jsx index 84b8c86c0..f262fb46b 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/ImageField.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/FormFields/ImageField.jsx @@ -121,7 +121,6 @@ const ImageField = ({
- {renderInput()} {renderUpdateImageLabel('змінити')} {renderDeleteButton('видалити')}
diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx index ec2b0a8f8..6dc8ef2a2 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/GeneralInfo.jsx @@ -105,10 +105,6 @@ const GeneralInfo = (props) => { setFormIsDirty(isDirty); }, [mainProfile, profile]); - useEffect(() => { - setProfile(props.profile); - }, [props.profile]); - const checkRequiredFields = () => { let isValid = true; const newFormState = {}; diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/StartupInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/StartupInfo.jsx index d3e23ff35..f4ce14bea 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/StartupInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/StartupInfo.jsx @@ -27,10 +27,6 @@ const StartupInfo = (props) => { startup_idea: { defaultValue: mainProfile?.startup_idea ?? null }, }; - useEffect(() => { - setProfile(props.profile); - }, [props.profile]); - useEffect(() => { const isDirty = checkFormIsDirty(fields, null, profile); setFormIsDirty(isDirty); diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx index 63e41f35b..2a1885d8a 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/UserInfo.jsx @@ -47,14 +47,6 @@ const UserInfo = (props) => { person_position: { defaultValue: profile?.person_position ?? null }, }; - useEffect(() => { - setUpdateUser(props.user); - }, [props.user]); - - useEffect(() => { - setUpdateProfile(props.profile); - }, [props.profile]); - useEffect(() => { const isDirty = checkFormIsDirty(fields, updateUser, updateProfile); setFormIsDirty(isDirty); diff --git a/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.jsx b/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.jsx index 8f2b8eed0..c2b03d6ad 100644 --- a/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.jsx +++ b/FrontEnd/src/pages/ProfilePage/Mobile/EditProfileMobile.jsx @@ -7,6 +7,7 @@ import ProductServiceInfo from '../FormComponents/ProductServiceInfo'; import StartupInfo from '../FormComponents/StartupInfo'; import UserInfo from '../FormComponents/UserInfo'; import ChangePassword from '../FormComponents/ChangePassword'; +import Loader from '../../../components/Loader/Loader'; import { useAuth, useProfile } from '../../../hooks'; import css from './EditProfileMobile.module.css'; @@ -16,23 +17,26 @@ import css from './EditProfileMobile.module.css'; const EditProfileMobile = () => { const { user } = useAuth(); const { profile } = useProfile(); - const sections = [ - { title: 'Інформація про користувача', content: }, - { title: 'Загальна інформація', content: }, - { title: 'Контакти', content: }, - { title: 'Інформація про товари/послуги', content: }, - { title: 'Додаткова інформація', content: }, - { title: 'Стартап', content: }, - { title: 'Змінити пароль', content: }, - { title: 'Видалити профіль', content: }, - ]; - - return ( -
-

Профіль користувача

- -
- ); + if (user && profile) { + const sections = [ + { title: 'Інформація про користувача', content: }, + { title: 'Загальна інформація', content: }, + { title: 'Контакти', content: }, + { title: 'Інформація про товари/послуги', content: }, + { title: 'Додаткова інформація', content: }, + { title: 'Стартап', content: }, + { title: 'Змінити пароль', content: }, + { title: 'Видалити профіль', content: }, + ]; + return ( +
+

Профіль користувача

+ +
+ ); + } else { + return ; + } }; export default EditProfileMobile; \ No newline at end of file From d9c1ebf0f494177d8c4d103aff81696e9307a71d Mon Sep 17 00:00:00 2001 From: Yan Zhylavy Date: Thu, 14 Nov 2024 12:12:34 +0200 Subject: [PATCH 08/43] Fix issues related to html inputs and labels --- .../DeleteProfileComponent/DeleteProfileModal.jsx | 7 +++++-- .../FormComponents/FormFields/CheckBoxField.jsx | 4 +++- .../FormComponents/FormFields/HalfFormField.jsx | 5 ++++- .../ProfilePage/FormComponents/FormFields/ImageField.jsx | 1 + .../FormComponents/FormFields/MultipleSelectChip.jsx | 4 +++- .../ProfilePage/FormComponents/FormFields/TextField.jsx | 4 +++- .../src/pages/ProfilePage/FormComponents/GeneralInfo.jsx | 1 - 7 files changed, 19 insertions(+), 7 deletions(-) diff --git a/FrontEnd/src/pages/ProfilePage/FormComponents/DeleteProfileComponent/DeleteProfileModal.jsx b/FrontEnd/src/pages/ProfilePage/FormComponents/DeleteProfileComponent/DeleteProfileModal.jsx index 6f3cf8658..6905c270c 100644 --- a/FrontEnd/src/pages/ProfilePage/FormComponents/DeleteProfileComponent/DeleteProfileModal.jsx +++ b/FrontEnd/src/pages/ProfilePage/FormComponents/DeleteProfileComponent/DeleteProfileModal.jsx @@ -68,23 +68,25 @@ const DeleteProfileModal = (props) => {
- +
{!isCorrectEmail && (
Некоректна пошта
)}
- +
{ placeholder="Пароль" onChange={passwordChangeHandler} onKeyDown={preventEnterSubmit} + autoComplete="off" /> {
{props.requiredField && ( - + * )}