add functional AutstaffingForm and buttonInputFile
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useRef, useState } from "react";
|
||||
import SVG from "react-inlinesvg";
|
||||
|
||||
import { AuthHeader } from "@components/Common/AuthHeader/AuthHeader";
|
||||
@ -6,6 +6,7 @@ import { Footer } from "@components/Common/Footer/Footer";
|
||||
|
||||
import arrowReviewsLeft from "assets/icons/arrows/arrowReviewsLeft.png";
|
||||
import arrowReviewsRight from "assets/icons/arrows/arrowReviewsRight.png";
|
||||
import fileUploadIcon from "assets/icons/fileUploadIcon.svg";
|
||||
import Ellipse from "assets/images/EllipseIntro.svg";
|
||||
import backgroundOpp from "assets/images/backgroundOpportunity.png";
|
||||
import cat from "assets/images/cat.png";
|
||||
@ -103,8 +104,14 @@ export const Stack = () => {
|
||||
const [error, setError] = useState({
|
||||
name: false,
|
||||
companyName: false,
|
||||
email: false,
|
||||
phoneNumber: false,
|
||||
email: {
|
||||
state: false,
|
||||
text: ""
|
||||
},
|
||||
phoneNumber: {
|
||||
state: false,
|
||||
text: ""
|
||||
},
|
||||
requestDescription: false,
|
||||
agreement: false
|
||||
});
|
||||
@ -119,6 +126,24 @@ export const Stack = () => {
|
||||
agreement: false
|
||||
});
|
||||
|
||||
// Создаем ссылку на скрытый элемент input для файла
|
||||
const hiddenFileInput = useRef(null);
|
||||
|
||||
// Программно нажимаем на скрытый элемент input для файла
|
||||
// когда компонент Button будет нажат
|
||||
const handleClick = () => {
|
||||
hiddenFileInput.current.click();
|
||||
};
|
||||
|
||||
// Вызываем функцию для обработки выбранного пользователем файла
|
||||
const handleChangeFile = (event) => {
|
||||
const fileUploaded = event.target.files[0];
|
||||
setFormData((prevState) => ({
|
||||
...prevState,
|
||||
file: fileUploaded
|
||||
}));
|
||||
};
|
||||
|
||||
const handleChange = (e) => {
|
||||
const { name, value, type, checked } = e.target;
|
||||
setFormData((prevState) => ({
|
||||
@ -130,17 +155,41 @@ export const Stack = () => {
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
const phoneRegex = /^\+?\d+$/;
|
||||
|
||||
const newError = {
|
||||
name: !formData.name.trim(),
|
||||
companyName: !formData.companyName.trim(),
|
||||
email: !formData.email.trim(),
|
||||
phoneNumber: !formData.phoneNumber.trim(),
|
||||
email: {
|
||||
state: !formData.email.trim() || !emailRegex.test(formData.email),
|
||||
text: !formData.email.trim()
|
||||
? "поле обязательно для заполнения"
|
||||
: !emailRegex.test(formData.email)
|
||||
? "e-mail не соответствует формату"
|
||||
: ""
|
||||
},
|
||||
phoneNumber: {
|
||||
state:
|
||||
!formData.phoneNumber.trim() ||
|
||||
!phoneRegex.test(formData.phoneNumber),
|
||||
text: !formData.phoneNumber.trim()
|
||||
? "поле обязательно для заполнения"
|
||||
: !phoneRegex.test(formData.phoneNumber)
|
||||
? "введите корректный номер телефона"
|
||||
: ""
|
||||
},
|
||||
requestDescription: !formData.requestDescription.trim(),
|
||||
agreement: !formData.agreement
|
||||
};
|
||||
|
||||
setError(newError);
|
||||
const isValid = !Object.values(newError).some((err) => err);
|
||||
const isValid = Object.values(newError).every((err) => {
|
||||
if (typeof err === "object") {
|
||||
return !err.state;
|
||||
}
|
||||
return !err;
|
||||
});
|
||||
if (isValid) {
|
||||
// Данные формы валидны, можно отправлять форму
|
||||
console.log("Форма отправлена", formData);
|
||||
@ -155,7 +204,7 @@ export const Stack = () => {
|
||||
});
|
||||
} else {
|
||||
// Данные формы невалидны, показываем ошибки
|
||||
console.log("Форма содержит ошибки");
|
||||
console.log("Форма содержит ошибки", newError);
|
||||
}
|
||||
};
|
||||
|
||||
@ -431,6 +480,7 @@ export const Stack = () => {
|
||||
<div className="form-info">
|
||||
<div>
|
||||
<input
|
||||
className={error.name ? "input-error" : ""}
|
||||
type="text"
|
||||
name="name"
|
||||
value={formData.name}
|
||||
@ -439,12 +489,13 @@ export const Stack = () => {
|
||||
/>
|
||||
{error.name && (
|
||||
<span className="error">
|
||||
Поле обязательно для заполнения
|
||||
поле обязательно для заполнения
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
className={error.companyName ? "input-error" : ""}
|
||||
type="text"
|
||||
name="companyName"
|
||||
value={formData.companyName}
|
||||
@ -453,41 +504,40 @@ export const Stack = () => {
|
||||
/>
|
||||
{error.companyName && (
|
||||
<span className="error">
|
||||
Поле обязательно для заполнения
|
||||
поле обязательно для заполнения
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type="email"
|
||||
className={error.email.state ? "input-error" : ""}
|
||||
type="text"
|
||||
name="email"
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
placeholder="e-mail"
|
||||
/>
|
||||
{error.email && (
|
||||
<span className="error">
|
||||
Поле обязательно для заполнения
|
||||
</span>
|
||||
{error.email.state && (
|
||||
<span className="error">{error.email.text}</span>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
className={error.phoneNumber.state ? "input-error" : ""}
|
||||
type="tel"
|
||||
name="phoneNumber"
|
||||
value={formData.phoneNumber}
|
||||
onChange={handleChange}
|
||||
placeholder="+7"
|
||||
/>
|
||||
{error.phoneNumber && (
|
||||
<span className="error">
|
||||
Поле обязательно для заполнения
|
||||
</span>
|
||||
{error.phoneNumber.state && (
|
||||
<span className="error">{error.phoneNumber.text}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-description">
|
||||
<textarea
|
||||
className={error.requestDescription ? "input-error" : ""}
|
||||
name="requestDescription"
|
||||
value={formData.requestDescription}
|
||||
onChange={handleChange}
|
||||
@ -495,13 +545,23 @@ export const Stack = () => {
|
||||
/>
|
||||
{error.requestDescription && (
|
||||
<span className="error">
|
||||
Поле обязательно для заполнения
|
||||
поле обязательно для заполнения
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="form-file">
|
||||
<input type="file" name="file" onChange={handleChange} />
|
||||
<div className="button-upload" onClick={handleClick}>
|
||||
<img src={fileUploadIcon} alt="" />
|
||||
<span>прикрепить файл</span>
|
||||
</div>
|
||||
<input
|
||||
type="file"
|
||||
name="file"
|
||||
onChange={handleChangeFile}
|
||||
ref={hiddenFileInput}
|
||||
style={{ display: "none" }}
|
||||
/>
|
||||
<p>
|
||||
.eps, .ai, .psd, .jpg, .png, .pdf, .doc, .docx, .xlsx, .xls,
|
||||
.ppt, .jpeg <br />
|
||||
@ -524,7 +584,9 @@ export const Stack = () => {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button type="submit">оставить заявку</button>
|
||||
<button className="form-submit__button" type="submit">
|
||||
оставить заявку
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -909,9 +909,10 @@
|
||||
|
||||
h4 {
|
||||
color: #a7ca60;
|
||||
font-weight: 900;
|
||||
font-size: 66px;
|
||||
font-weight: 900;
|
||||
line-height: 64.94px;
|
||||
letter-spacing: 0.03em;
|
||||
text-transform: uppercase;
|
||||
margin: 20px 0 30px 0;
|
||||
}
|
||||
@ -970,6 +971,10 @@
|
||||
font-weight: 700;
|
||||
color: #607536;
|
||||
|
||||
.input-error {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
font-size: 11px;
|
||||
@ -1030,27 +1035,31 @@
|
||||
|
||||
&-file {
|
||||
display: flex;
|
||||
margin-top: 17px;
|
||||
input {
|
||||
width: 40%;
|
||||
}
|
||||
input::-webkit-file-upload-button {
|
||||
visibility: hidden;
|
||||
display: none;
|
||||
}
|
||||
input::before {
|
||||
margin: 17px 0 17px 0;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.button-upload {
|
||||
cursor: pointer;
|
||||
content: "прикрепите файл";
|
||||
width: 160px;
|
||||
height: 45px;
|
||||
color: #435225;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
border-radius: 8px;
|
||||
border: 0.2px solid #89a64f;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 0.2px solid #89a64f;
|
||||
border-radius: 8px;
|
||||
column-gap: 7px;
|
||||
|
||||
img {
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
line-height: 15.08px;
|
||||
color: #435225;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
@ -1091,7 +1100,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
&__button {
|
||||
width: 177px;
|
||||
height: 44px;
|
||||
background-color: #ffffff;
|
||||
@ -1100,6 +1109,12 @@
|
||||
color: #4a4a4a;
|
||||
border-radius: 44px;
|
||||
border: none;
|
||||
outline: none;
|
||||
|
||||
&:hover {
|
||||
color: #000000;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user