Skip to content

Commit

Permalink
refactor: переписать валидацию попапов под кастомный хук; fix: исправ…
Browse files Browse the repository at this point in the history
…ить ошибку с отрицательным маргином при выходе из личного кабинета на десктопе
  • Loading branch information
elrouss committed Jan 28, 2023
1 parent ac9fd21 commit 41709b0
Show file tree
Hide file tree
Showing 18 changed files with 169 additions and 228 deletions.
3 changes: 0 additions & 3 deletions src/blocks/popup/__error/_visible/popup__error_visible.css

This file was deleted.

14 changes: 0 additions & 14 deletions src/blocks/popup/__error/popup__error.css
Original file line number Diff line number Diff line change
@@ -1,29 +1,15 @@
.popup__error {
display: none;
width: 358px;
padding-top: 5px;
font-weight: 400;
font-size: 12px;
line-height: calc(15 / 12 * 100%);
color: #f00;
position: absolute;
top: 204px;
left: 36px;
}

.popup__error:nth-child(2) {
top: 138px;
}

@media screen and (max-width: 696px) {
.popup__error {
width: 238px;
font-size: 11px;
line-height: 104%;
left: 23px;
}

.popup__error:nth-child(2) {
top: 149px;
}
}
8 changes: 0 additions & 8 deletions src/blocks/popup/__form-field/popup__form-field.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,9 @@
color: #c4c4c4;
}

.popup__form-field:nth-child(3) {
margin-top: 35px;
}

@media (max-width: 696px) {
.popup__form-field {
width: 238px;
padding-bottom: 9px;
}

.popup__form-field:nth-child(3) {
margin-top: 28px;
}
}
12 changes: 12 additions & 0 deletions src/blocks/popup/__input-wrapper/popup__input-wrapper.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.popup__input-wrapper {
min-height: 54px;
display: flex;
flex-direction: column;
row-gap: 7px;
}

@media screen and (max-width: 696px) {
.popup__input-wrapper {
min-height: 57px;
}
}
4 changes: 2 additions & 2 deletions src/blocks/popup/__submit-button/popup__submit-button.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.popup__submit-button {
width: 358px;
height: 50px;
margin: 46px 0 0;
margin: 28px 0 0;
padding: 0;
border: none;
background: #000;
Expand All @@ -22,7 +22,7 @@
.popup__submit-button {
width: 238px;
height: 46px;
margin-top: 44px;
margin-top: 14px;
font-size: 14px;
line-height: calc(17 / 14 * 100%);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.welcome-window__input_error {
border-bottom: 2px solid #e13939;
}
112 changes: 39 additions & 73 deletions src/components/AddPlacePopup/AddPlacePopup.js
Original file line number Diff line number Diff line change
@@ -1,101 +1,67 @@
import { useEffect, useState } from "react";
import PopupWithForm from "../PopupWithForm/PopupWithForm";

export default function AddPlacePopup(props) {
const { onAddPlace, isOpened, popupPackProps } = props;

const [name, setName] = useState('');
const [link, setLink] = useState('');

const [isFocusedName, setIsFocusedName] = useState(false);
const [isFocusedLink, setIsFocusedLink] = useState(false);

const newCardNameLength = name && name.length;
import { useEffect } from "react";

function isNewCardLink(url) {
const urlPattern = /(?:https?):\/\/(\w+:?\w*)?(\S+)(:\d+)?(\/|\/([\w#!:.?+=&%!\-/]))?/;
return urlPattern.test(url);
};
import PopupWithForm from "../PopupWithForm/PopupWithForm";
import useFormWithValidation from "../../hooks/useFormWithValidation";

function handleNewCardName(evt) {
const target = evt.target.value.replace(/^\s/, '');
setName(target);
};
export default function AddPlacePopup({ onAddPlace, isOpened, popupPackProps }) {
const { values, errors, isValid, handleChange, resetForm } = useFormWithValidation();

function handleNewCardLink(evt) {
const target = evt.target.value.replace(/^\s/, '');
setLink(target);
};
useEffect(() => {
if (isOpened) resetForm();
}, [isOpened, resetForm]);

function handleSubmit(evt) {
evt.preventDefault();

onAddPlace({
name: name.trim().replace(/\s+/g, ' '),
link: link.trim()
name: values.cardName.trim().replace(/\s+/g, ' '),
link: values.cardUrl.trim()
});
};

useEffect(() => {
if (isOpened) {
setName('');
setLink('');
};
}, [isOpened]);

function isInputValueValid(value) {
return value >= 1;
};

function isAddPlacePopupValid() {
return isInputValueValid(newCardNameLength) && isNewCardLink(link);
};

return (
<PopupWithForm
popupData={{
classSelector: "add-photocard",
classSelectorModifierForm: "popup__form_type_photocards",
formName: "photocardAdding",
title: "Новое место",
submitBtn: "Создать",
isPopupValid: isAddPlacePopupValid()
isPopupValid: isValid
}}

onSubmit={handleSubmit}
isOpened={isOpened}
popupPackProps={popupPackProps}
>
<fieldset className="popup__form-fieldset">
<input
className={`popup__form-field ${(isFocusedName && !isInputValueValid(newCardNameLength)) && 'popup__form-field_type_error'} popup__form-field_type_add-photocard-name`}
name="cardName"
type="text"
placeholder="Название"
maxLength="30"
required
value={name}
onChange={handleNewCardName}
onFocus={() => setIsFocusedName(true)}
onBlur={() => setIsFocusedName(false)}
/>
<span className={`popup__error ${(isFocusedName && !isInputValueValid(newCardNameLength)) && 'popup__error_visible'} photocard-name-error`}>
Заполните это поле.
</span>
<input
className={`popup__form-field ${((isFocusedLink && !isNewCardLink(link)) || (!isNewCardLink(link) && link !== '')) && 'popup__form-field_type_error'} popup__form-field_type_add-photocard-link`}
name="cardLink"
type="url"
placeholder="Ссылка на изображение"
required
value={link}
onChange={handleNewCardLink}
onFocus={() => setIsFocusedLink(true)}
onBlur={() => setIsFocusedLink(false)}
/>
<span className={`popup__error ${((isFocusedLink && !isNewCardLink(link)) || (!isNewCardLink(link) && link !== '')) && 'popup__error_visible'} photocard-url-error`}>
Введите URL.
</span>
<div className="popup__input-wrapper">
<input
className={`popup__form-field ${errors?.cardName && 'popup__form-field_type_error'}`}
name="cardName"
type="text"
placeholder="Название"
minLength="2"
maxLength="30"
required
value={values?.cardName || ''}
onChange={handleChange}
/>
<span className="popup__error">{errors?.cardName && 'Текст не должен быть короче 2 и длиннее 30 симв.'}</span>
</div>

<div className="popup__input-wrapper">
<input
className={`popup__form-field ${errors?.cardUrl && 'popup__form-field_type_error'}`}
name="cardUrl"
type="url"
placeholder="Ссылка на изображение"
required
value={values?.cardUrl || ''}
onChange={handleChange}
/>
<span className="popup__error">{errors?.cardUrl && 'Введите адрес сайта.'}</span>
</div>

</fieldset>
</PopupWithForm>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ export default function App() {
function toggleBurgerMenu() {
setIsActiveBurgerMenu(!isActiveBurgerMenu);
};
//TODO: переписать функцию под true/false (либо иначе прокидывать в header, иначе переключается margin)

function openInfoTooltip() {
setIsInfoTooltipOpened(true);
Expand Down Expand Up @@ -247,6 +246,7 @@ export default function App() {
onActive={toggleBurgerMenu}
userData={userData}
setIsLoggedIn={setIsLoggedIn}
isActiveBurgerMenu={isActiveBurgerMenu}
toggleBurgerMenu={toggleBurgerMenu}
/>
}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import PopupWithForm from "../PopupWithForm/PopupWithForm";
import useFormWithValidation from "../../hooks/useFormWithValidation";
import { useEffect } from "react";

export default function ConfirmCardDeletionPopup(props) {
const { activeCardId, onCardDelete, isOpened, popupPackProps } = props;
export default function ConfirmCardDeletionPopup({ activeCardId, onCardDelete, isOpened, popupPackProps }) {
const { isValid, setIsValid } = useFormWithValidation();

useEffect(() => {
if (isOpened) setIsValid(true);
}, [isOpened]);

function handleSubmit(evt) {
evt.preventDefault();
Expand All @@ -18,7 +24,8 @@ export default function ConfirmCardDeletionPopup(props) {
formName: "photocardConfirmationDeletion",
title: "Вы уверены?",
submitBtn: "Да",
submitBtnLoading: "Удаление..."
submitBtnLoading: "Удаление...",
isPopupValid: isValid
}}

onSubmit={handleSubmit}
Expand Down
59 changes: 21 additions & 38 deletions src/components/EditAvatarPopup/EditAvatarPopup.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,50 @@
import { useState, useEffect } from "react";
import PopupWithForm from "../PopupWithForm/PopupWithForm";
import { useEffect } from "react";

export default function EditAvatarPopup(props) {
const { onUpdateAvatar, isOpened, popupPackProps } = props;
import PopupWithForm from "../PopupWithForm/PopupWithForm";
import useFormWithValidation from "../../hooks/useFormWithValidation";

const [avatar, setAvatar] = useState('')
const [isFocusedLink, setIsFocusedLink] = useState(false);
export default function EditAvatarPopup({ onUpdateAvatar, isOpened, popupPackProps }) {
const { values, errors, isValid, handleChange, resetForm } = useFormWithValidation();

useEffect(() => {
if (isOpened) {
setAvatar('');
};
}, [isOpened]);

function handleAvatar(evt) {
setAvatar(evt.target.value);
};

function isEditAvatarPopupValid() {
const urlPattern = /(?:https?):\/\/(\w+:?\w*)?(\S+)(:\d+)?(\/|\/([\w#!:.?+=&%!\-/]))?/;
const isNewAvatarLink = url => urlPattern.test(url);

return isNewAvatarLink(avatar);
};
if (isOpened) resetForm();
}, [isOpened, resetForm]);

function handleSubmit(evt) {
evt.preventDefault();

onUpdateAvatar({
avatar: avatar.trim()
avatar: values.url.trim()
});
};

return (
<PopupWithForm
popupData={{
classSelector: "edit-avatar",
classSelectorModifierForm: "popup__form_type_avatar",
formName: "profileAvatarEditor",
title: "Обновить аватар",
submitBtn: "Сохранить",
isPopupValid: isEditAvatarPopupValid()
isPopupValid: isValid
}}

onSubmit={handleSubmit}
isOpened={isOpened}
popupPackProps={popupPackProps}
>
<fieldset className="popup__form-fieldset">
<input
className={`popup__form-field ${((!isEditAvatarPopupValid() && avatar !== '') || isFocusedLink) && 'popup__form-field_type_error'} popup__form-field_type_edit-avatar-link`}
name="userAvatar"
type="url"
placeholder="Ссылка на изображение"
required
value={avatar}
onChange={handleAvatar}
onFocus={() => setIsFocusedLink(true)}
onBlur={() => setIsFocusedLink(false)}
/>
{(avatar !== '' || isFocusedLink) && <span className={`popup__error ${!isEditAvatarPopupValid() && 'popup__error_visible'} avatar-url-error`}>
Введите URL.
</span>}
<div className="popup__input-wrapper">
<input
className={`popup__form-field ${errors?.url && 'popup__form-field_type_error'}`}
name="url"
type="url"
placeholder="Ссылка на изображение"
required
onChange={handleChange}
value={values?.url || ''}
/>
<span className="popup__error">{errors?.url && 'Введите адрес сайта.'}</span>
</div>
</fieldset>
</PopupWithForm>
);
Expand Down
Loading

0 comments on commit 41709b0

Please sign in to comment.