forked from M3-Academy/desafio-react-e-typescript
feat(main): Cria e aplica funcionalidades ao formulário Institucional
This commit is contained in:
parent
5a1d807e70
commit
f49da350bf
183
src/components/InstitucionalForm/InstitucionalForm.module.scss
Normal file
183
src/components/InstitucionalForm/InstitucionalForm.module.scss
Normal file
@ -0,0 +1,183 @@
|
||||
@use '../../variables';
|
||||
|
||||
.form {
|
||||
&__container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__inputs-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
color: variables.$black-100;
|
||||
margin-left: 15px;
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
font-size: 28px;
|
||||
line-height: 33px;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
height: 46px;
|
||||
background: variables.$white;
|
||||
border: 1px solid variables.$black-100;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
color: variables.$gray-200;
|
||||
border-radius: 25px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
padding: 15px 20px;
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
height: 63px;
|
||||
font-size: 28px;
|
||||
line-height: 33px;
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
color: variables.$gray-200;
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
font-size: 28px;
|
||||
line-height: 33px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__checkbox-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 12px;
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-left: 4px;
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
width: 36px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
@media (max-width: 289px) {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
&__checkbox,
|
||||
&__checkbox-alert {
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
font-size: 28px;
|
||||
line-height: 33px;
|
||||
}
|
||||
}
|
||||
|
||||
&__checkbox {
|
||||
color: variables.$black-100;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&__checkbox-alert {
|
||||
color: variables.$red;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&__invalid-feedback,
|
||||
&__invalid-feedback-terms {
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
color: variables.$red;
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
font-size: 24px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
&__invalid-feedback {
|
||||
right: 120px;
|
||||
margin-top: 12px;
|
||||
position: absolute;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
right: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&__invalid-feedback-terms {
|
||||
margin-left: 5px;
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
@media (max-width: 289px) {
|
||||
font-size: 11px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&__btn {
|
||||
width: 100%;
|
||||
height: 52px;
|
||||
background-color: variables.$black;
|
||||
border-radius: 25px;
|
||||
border: none;
|
||||
|
||||
font-size: 16px;
|
||||
line-height: 19px;
|
||||
letter-spacing: 0.05em;
|
||||
color: variables.$white;
|
||||
padding: 17px 0;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
filter: opacity(.85);
|
||||
}
|
||||
|
||||
&:active {
|
||||
filter: opacity(1);
|
||||
}
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
height: 71px;
|
||||
|
||||
font-size: 32px;
|
||||
line-height: 38px;
|
||||
}
|
||||
}
|
||||
|
||||
&__msg-submit {
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
color: variables.$green;
|
||||
margin-top: 12px;
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
font-size: 24px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
}
|
188
src/components/InstitucionalForm/InstitucionalForm.tsx
Normal file
188
src/components/InstitucionalForm/InstitucionalForm.tsx
Normal file
@ -0,0 +1,188 @@
|
||||
import {useState} from "react";
|
||||
|
||||
import { Formik, Form, Field, ErrorMessage, FormikHelpers} from "formik";
|
||||
|
||||
import styles from "./InstitucionalForm.module.scss";
|
||||
|
||||
import FormSchema from "./Schema/InstitucionalFormSchema";
|
||||
|
||||
interface FormValue {
|
||||
name: string;
|
||||
email: string;
|
||||
cpf: string;
|
||||
birthDate: string;
|
||||
phone: string;
|
||||
instagram: string;
|
||||
acceptTerms: boolean;
|
||||
}
|
||||
|
||||
const initialValue = {
|
||||
name: "",
|
||||
email: "",
|
||||
cpf: "",
|
||||
birthDate: "",
|
||||
phone: "",
|
||||
instagram: "",
|
||||
acceptTerms: false,
|
||||
}
|
||||
|
||||
let listClient: Array<FormValue> = [];
|
||||
|
||||
const InstitucionalForm = () => {
|
||||
|
||||
const [successMessage, setSuccessMessage] = useState(false);
|
||||
|
||||
const handleSubmit = async (values: FormValue, actions: FormikHelpers<FormValue>) => {
|
||||
listClient.push(values);
|
||||
console.log(listClient);
|
||||
actions.resetForm();
|
||||
|
||||
setSuccessMessage(true);
|
||||
setTimeout(() => setSuccessMessage(false), 3000);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles["form__container"]}>
|
||||
<Formik
|
||||
onSubmit={handleSubmit}
|
||||
initialValues={initialValue}
|
||||
validationSchema={FormSchema} >
|
||||
|
||||
{({errors, touched}) => (
|
||||
<Form>
|
||||
<div className={styles["form__inputs-container"]}>
|
||||
<label htmlFor="name">Nome</label>
|
||||
<Field
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
placeholder="Seu nome completo"
|
||||
className={errors.name && touched.name && "invalid"}
|
||||
/>
|
||||
<ErrorMessage
|
||||
component="span"
|
||||
name="name"
|
||||
className={styles["form__invalid-feedback"]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles["form__inputs-container"]}>
|
||||
<label htmlFor="email">E-mail</label>
|
||||
<Field
|
||||
type="text"
|
||||
id="email"
|
||||
name="email"
|
||||
placeholder="Seu e-mail"
|
||||
className={errors.email && touched.email && "invalid"}
|
||||
/>
|
||||
<ErrorMessage
|
||||
component="span"
|
||||
name="email"
|
||||
className={styles["form__invalid-feedback"]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles["form__inputs-container"]}>
|
||||
<label htmlFor="cpf">CPF</label>
|
||||
<Field
|
||||
type="text"
|
||||
id="cpf"
|
||||
name="cpf"
|
||||
placeholder="000.000.000-00"
|
||||
className={errors.cpf && touched.cpf && "invalid"}
|
||||
/>
|
||||
<ErrorMessage
|
||||
component="span"
|
||||
name="cpf"
|
||||
className={styles["form__invalid-feedback"]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles["form__inputs-container"]}>
|
||||
<label htmlFor="birthDate">Data de Nascimento</label>
|
||||
<Field
|
||||
type="text"
|
||||
id="birthDate"
|
||||
name="birthDate"
|
||||
placeholder="00.00.0000"
|
||||
className={errors.birthDate && touched.birthDate && "invalid"}
|
||||
/>
|
||||
<ErrorMessage
|
||||
component="span"
|
||||
name="birthDate"
|
||||
className={styles["form__invalid-feedback"]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles["form__inputs-container"]}>
|
||||
<label htmlFor="phone">Telefone</label>
|
||||
<Field
|
||||
type="text"
|
||||
id="phone"
|
||||
name="phone"
|
||||
placeholder="(00) 00000-0000"
|
||||
className={errors.phone && touched.phone && "invalid"}
|
||||
/>
|
||||
<ErrorMessage
|
||||
component="span"
|
||||
name="phone"
|
||||
className={styles["form__invalid-feedback"]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles["form__inputs-container"]}>
|
||||
<label htmlFor="instagram">Instagram</label>
|
||||
<Field
|
||||
type="text"
|
||||
id="instagram"
|
||||
name="instagram"
|
||||
placeholder="@seuuser"
|
||||
className={errors.instagram && touched.instagram && "invalid"}
|
||||
/>
|
||||
<ErrorMessage
|
||||
component="span"
|
||||
name="instagram"
|
||||
className={styles["form__invalid-feedback"]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles["form__checkbox-container"]}>
|
||||
<label htmlFor="acceptTerms">
|
||||
<span className={styles["form__checkbox-alert"]}>* </span>
|
||||
<a href="/" className={styles["form__checkbox"]}>
|
||||
Declaro que li e aceito
|
||||
</a>
|
||||
</label>
|
||||
<Field
|
||||
id="acceptTerms"
|
||||
name="acceptTerms"
|
||||
type="checkbox"
|
||||
className={
|
||||
errors.acceptTerms && touched.acceptTerms && "invalid"
|
||||
}
|
||||
/>
|
||||
<ErrorMessage
|
||||
component="span"
|
||||
name="acceptTerms"
|
||||
className={styles["form__invalid-feedback-terms"]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit" className={styles["form__btn"]}>
|
||||
CADASTRE-SE
|
||||
</button>
|
||||
|
||||
{successMessage
|
||||
? (<span className={styles["form__msg-submit"]}>*Formulário enviado com sucesso!</span> )
|
||||
: ("")
|
||||
}
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { InstitucionalForm };
|
@ -0,0 +1,17 @@
|
||||
import * as Yup from "yup";
|
||||
|
||||
export default Yup.object().shape({
|
||||
name: Yup.string().required("*Campo Obrigatório").matches(/^[a-zA-Z\u00C0-\u017F´]{3,}?[+\s+]?[a-zA-Z\u00C0-\u017F´]{0,}$/, "*Nome Inválido"),
|
||||
|
||||
email: Yup.string().required("*Campo Obrigatório").email("*E-mail Inválido"),
|
||||
|
||||
cpf: Yup.string().required("*Campo Obrigatório").matches(/^([0-9]{3}\.?[0-9]{3}\.?[0-9]{3}\-?[0-9]{2})$/, "*CPF Inválido"),
|
||||
|
||||
birthDate: Yup.string().required("*Campo Obrigatório").matches(/^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/, "*Data Inválida"),
|
||||
|
||||
phone: Yup.string().required("*Campo Obrigatório").matches(/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/, "*Número Inválido"),
|
||||
|
||||
instagram: Yup.string().matches(/^(?:@)([A-Za-z0-9_](?:(?:[A-Za-z0-9_]|(?:\.(?!\.))){0,28}(?:[A-Za-z0-9_]))?)$/, "*Instagram Inválido"),
|
||||
|
||||
acceptTerms: Yup.bool().oneOf([true], "*Aceitar termos"),
|
||||
});
|
@ -1,5 +1,7 @@
|
||||
import React from "react";
|
||||
|
||||
import { InstitucionalForm } from "../../InstitucionalForm/InstitucionalForm";
|
||||
|
||||
import styles from "./RoutesPages.module.scss";
|
||||
|
||||
const Contato = () => {
|
||||
@ -7,6 +9,8 @@ const Contato = () => {
|
||||
return (
|
||||
<section className={styles["institucional__content"]}>
|
||||
<h2 className={styles["institucional__content__title"]}>Preencha o Formulário </h2>
|
||||
|
||||
<InstitucionalForm />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
@ -1,15 +1,10 @@
|
||||
@use '../../../variables';
|
||||
|
||||
.institucional__content {
|
||||
width: 748px;
|
||||
width: 100%;
|
||||
margin-left: 30px;
|
||||
|
||||
@media (min-width: 2500px) {
|
||||
width: 1680px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user