feat: adiciona formulario e corpo 4k

This commit is contained in:
Naian Felix dos Santos 2023-01-20 00:00:28 -03:00
parent 405206f1ac
commit 622d39ffc0
16 changed files with 10347 additions and 16 deletions

View File

@ -10,11 +10,14 @@
"@types/node": "^16.18.11",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.10",
"formik": "^2.2.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.4",
"web-vitals": "^2.1.4"
"web-vitals": "^2.1.4",
"yup": "^0.32.11",
"yupi": "^1.0.0"
},
"scripts": {
"start": "react-scripts start",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -1,7 +1,131 @@
import React from "react";
import React, { useState } from "react";
import style from "./form.module.scss";
import { Formik, Form, Field, ErrorMessage } from "formik";
import FormSchema from "../../../schema/FromSchema";
interface IFormikValues {
name: string;
email: string;
cpf: string;
nascimento: string;
telefone: string;
instagram: string;
terms: string;
}
const initialValues = {
name: "",
email: "",
cpf: "",
nascimento: "",
telefone: "",
instagram: "",
terms: "",
};
const Contato = () => {
return <></>;
const [success, setSuccess] = useState(false);
const handleFormikSubmit = (values: IFormikValues) => {};
return (
<div className={style["form-wrapper"]}>
<Formik
onSubmit={(values, { resetForm }) => {
handleFormikSubmit(values);
resetForm();
setSuccess(true);
}}
initialValues={initialValues}
validationSchema={FormSchema}>
{
<Form>
<h2 className="">Preencha o Formulário</h2>
<div className={style["form-col"]}>
<label htmlFor="name">Nome</label>
<ErrorMessage
component="span"
name="name"
className={style["form-invalid-feedback"]}
/>
<Field id="name" name="name" placeholder="Seu nome completo" />
</div>
<div className={style["form-col"]}>
<label htmlFor="email">E-mail</label>
<Field id="email" name="email" placeholder="Seu e-mail" />
<ErrorMessage
component="span"
name="email"
className={style["form-invalid-feedback"]}
/>
</div>
<div className={style["form-col"]}>
<label htmlFor="cpf">CPF</label>
<Field id="cpf" name="cpf" placeholder="000.000.000-00" />
<ErrorMessage
component="span"
name="cpf"
className={style["form-invalid-feedback"]}
/>
</div>
<div className={style["form-col"]}>
<label htmlFor="nascimento">Data de Nascimento:</label>
<Field
id="nascimento"
name="nascimento"
placeholder="00.00.0000"
/>
<ErrorMessage
component="span"
name="nascimento"
className={style["form-invalid-feedback"]}
/>
</div>
<div className={style["form-col"]}>
<label htmlFor="telefone">Telefone:</label>
<Field
id="telefone"
name="telefone"
placeholder="(00) 00000-0000"
/>
<ErrorMessage
component="span"
name="telefone"
className={style["form-invalid-feedback"]}
/>
</div>
<div className={style["form-col"]}>
<label htmlFor="instagram">Instagram</label>
<Field id="instagram" name="instagram" placeholder="@seuuser" />
<ErrorMessage
component="span"
name="instagram"
className={style["form-invalid-feedback"]}
/>
</div>
<div className={style["form-terms"]}>
<label className={style["declare"]} htmlFor="terms">
Declaro que li e aceito
</label>
<Field
className={style["terms"]}
type="checkbox"
id="terms"
name="terms"
required
/>
</div>
<button type="submit">Cadastre-se</button>
{success && (
<span className={style["success"]}>
*Formulário enviado com sucesso!
</span>
)}
</Form>
}
</Formik>
</div>
);
};
export default Contato;

View File

@ -0,0 +1,148 @@
.form-wrapper {
max-height: 100vh;
margin-left: 30px;
}
.form-wrapper h2 {
margin-bottom: 12px;
font-family: "Roboto", sans-serif;
font-style: normal;
font-weight: 700;
font-size: 24px;
line-height: 28px;
text-transform: unset;
}
.form-wrapper form {
width: 100%;
}
.form-col {
position: relative;
display: flex;
flex-direction: column;
margin-bottom: 12px;
}
.form-col label {
font-family: "Roboto", sans-serif;
font-size: 14px;
line-height: 16px;
color: #100d0e;
margin: 0 0 12px 15px;
}
.form-col input {
height: 46px;
border: 1px solid black;
border-radius: 25px;
padding: 15px 0px 15px 20px;
}
.form-col ::placeholder {
font-family: "Roboto", sans-serif;
font-size: 14px;
line-height: 16px;
color: #b9b7b7;
}
.form-wrapper button {
width: 100%;
height: 52px;
border: 1px solid black;
border-radius: 25px;
color: white;
font-family: "Roboto", sans-serif;
font-size: 16px;
line-height: 19px;
letter-spacing: 0.05em;
text-transform: uppercase;
background-color: #000;
}
.form-wrapper button:hover {
filter: brightness(80%);
}
.form-invalid-feedback {
position: absolute;
right: 0;
margin-right: 20px;
font-weight: 400;
font-size: 12px;
line-height: 14px;
text-align: right;
color: #ff0000;
}
.form-terms {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12px;
font-family: "Roboto", sans-serif;
font-size: 14px;
line-height: 16px;
}
.form-terms label::before {
content: "*";
color: red;
margin: 3.5px;
}
.form-terms input {
width: 18px;
height: 18px;
border-radius: 3px;
}
.success {
color: #008000;
}
@media screen and (min-width: 2500px) {
.form-wrapper h2 {
font-size: 48px;
line-height: 56px;
}
.form-col label {
font-size: 28px;
line-height: 33px;
}
.form-col input {
height: 63px;
padding: 15px 0px 15px 20px;
font-size: 28px;
}
.form-col ::placeholder {
font-size: 28px;
line-height: 33px;
}
.form-invalid-feedback {
font-size: 24px;
line-height: 28px;
}
.declare {
font-size: 28px;
line-height: 33px;
}
.form-terms input {
height: 36px;
width: 36px;
}
.form-wrapper button {
height: 71px;
font-size: 32px;
line-height: 38px;
}
}
@media screen and (max-width: 1024px) {
.form-wrapper {
margin: 0;
}
.form-wrapper h2 {
text-align: center;
}
}

View File

@ -65,6 +65,7 @@
}
.wrapper-text {
width: 100%;
margin-left: 30px;
.title-text {
@ -86,6 +87,7 @@
font-size: 13px;
line-height: 15px;
color: #7d7d7d;
text-transform: unset;
}
.last {
@ -94,3 +96,93 @@
}
}
}
@media screen and (min-width: 2500px) {
.body {
margin: 30px 100px 84px;
.breadcrumb {
.home {
width: 31px;
height: 31px;
}
.seta {
width: 9px;
height: 16px;
margin: 0 12px;
}
.breadcrumb-text {
font-size: 24px;
line-height: 28px;
}
}
.title-body {
font-weight: 400;
font-size: 48px;
line-height: 56px;
}
.container {
.list {
max-height: unset;
height: 495px;
li {
font-size: 32px;
line-height: 38px;
width: 590px;
}
li.active {
font-size: 32px;
line-height: 38px;
}
}
.wrapper-text {
.title-text {
font-size: 48px;
line-height: 56px;
}
.text {
font-weight: 400;
font-size: 26px;
line-height: 30px;
}
}
}
}
}
@media screen and (max-width: 1024px) {
.body {
margin: 30px 16px 80px;
.title-body {
margin: 80px 0 40px;
}
.container {
flex-direction: column;
.list {
border: 0;
width: 100%;
max-width: unset;
li {
width: 100%;
}
}
.wrapper-text {
margin: 0;
margin-top: 20px;
.title-text {
text-align: center;
margin-top: 0;
}
.text {
font-size: 12px;
line-height: 18px;
}
}
}
}
}

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useState, useEffect } from "react";
import master from "../../assets/img/Master.svg";
import visa from "../../assets/img/Visa.svg";
import amex from "../../assets/img/Diners.svg";
@ -17,6 +17,20 @@ import linkedin from "../../assets/img/link.svg";
import style from "./footer.module.scss";
const Footer = () => {
const [visible, setVisible] = useState(false);
useEffect(() => {
const handleResize = () => {
if (window.pageYOffset > 100) {
setVisible(true);
} else {
setVisible(false);
}
};
window.addEventListener("scroll", handleResize);
return () => {
window.removeEventListener("scroll", handleResize);
};
}, []);
return (
<>
<div className={style["footer-top"]}>
@ -111,9 +125,11 @@ const Footer = () => {
href="https://wa.me/+55022997886109">
{" "}
</a>
<a href="#header" className={style["up-button"]}>
{" "}
</a>
{visible && (
<a href="#header" className={style["up-button"]}>
{" "}
</a>
)}
</div>
</div>

View File

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import master from "../../assets/img/Master.svg";
import visa from "../../assets/img/Visa.svg";
import amex from "../../assets/img/Diners.svg";
@ -23,6 +23,20 @@ interface AccordionStates {
}
const FooterMobile = () => {
const [visible, setVisible] = useState(false);
useEffect(() => {
const handleResize = () => {
if (window.pageYOffset > 100) {
setVisible(true);
} else {
setVisible(false);
}
};
window.addEventListener("scroll", handleResize);
return () => {
window.removeEventListener("scroll", handleResize);
};
}, []);
const [accordions, setAccordions] = useState<AccordionStates>({
institucional: false,
duvidas: false,
@ -158,9 +172,11 @@ const FooterMobile = () => {
href="https://wa.me/+55022997886109">
{" "}
</a>
<a href="#header-mobile" className={style["up-button"]}>
{" "}
</a>
{visible && (
<a href="#header-mobile" className={style["up-button"]}>
{" "}
</a>
)}
</div>
</div>

View File

@ -169,6 +169,75 @@ p {
border: 0;
}
@media screen and (min-width: 2500px) {
h2 {
font-size: 28px;
line-height: 33px;
}
h3 {
font-size: 24px;
line-height: 28px;
}
a {
font-size: 24px;
line-height: 28px;
}
.icons-top {
width: 70px;
height: 70px;
}
.icon-facebook {
width: 70px;
height: 70px;
}
.url-link {
font-size: 28px;
line-height: 33px;
}
.float-buttons {
right: 1%;
}
.button-whats,
.up-button {
width: 66px;
height: 66px;
}
.footer-bottom p {
font-size: 20px;
line-height: 23px;
}
.icons {
width: 70px;
height: 40px;
}
.icon-vtex {
width: 106px;
height: 66px;
}
.vtexP {
width: 84px;
height: 30px;
margin: 0 12px;
}
.m3 {
width: 55px;
height: 30px;
margin-left: 12px;
}
}
@media screen and (max-width: 1024px) {
.footer-top,
.footer-bottom {

View File

@ -10,7 +10,7 @@ const Header = () => {
<div>
<div className={style["header-wrapper"]}>
<div>
<img src={logoM3} alt="logo M3" />
<img className={style["logo-m3"]} src={logoM3} alt="logo M3" />
</div>
<div className={style["search-box"]}>
<input

View File

@ -25,6 +25,11 @@ const HeaderMobile = () => {
</div>
</div>
</div>
<div
onClick={() => setOpen(false)}
className={`${style["overlay"]} ${
open ? style["overlay-active"] : ""
}`}></div>
<div
className={`${

View File

@ -6,9 +6,15 @@
padding: 22px 100px;
}
.logo-m3 {
width: 136px;
height: 26px;
}
.search-box {
display: flex;
justify-content: space-between;
align-items: center;
background: #ffffff;
border-radius: 5px;
width: 100%;
@ -101,6 +107,59 @@
margin-right: 55px;
}
@media screen and (min-width: 2500px) {
.logo-m3 {
width: unset;
height: unset;
}
.search-box {
max-width: 516px;
height: 57px;
}
.input-search {
height: 32px;
margin: 12px 0 12px 16px;
padding: 0;
font-style: normal;
font-weight: 400;
font-size: 28px;
line-height: 33px;
}
.input-search::placeholder {
font-style: normal;
font-weight: 400;
font-size: 28px;
line-height: 33px;
}
.lupa-img {
height: 35.15px;
width: 35.15px;
margin: 11px 11px 11px 10px;
}
.button-login {
font-size: 28px;
line-height: 33px;
}
.img-cart {
width: 55px;
height: 55px;
}
.cursos,
.saiba-mais,
.institucionais {
font-weight: 500;
font-size: 28px;
line-height: 33px;
}
}
@media screen and (max-width: 1024px) {
.header {
display: none;

View File

@ -86,18 +86,26 @@
position: fixed;
top: 0;
right: 4%;
z-index: 2;
transition: right 300ms ease-in-out;
}
.menu-burguer-container-active::after {
.overlay {
visibility: hidden;
opacity: 0;
width: 100vw;
height: 100vh;
background: rgba(69, 69, 69, 0.7);
content: "";
z-index: 1;
position: fixed;
top: 0;
left: 0;
z-index: -1;
transition: opacity 300ms linear;
&-active {
opacity: 1;
visibility: visible;
}
}
.menu-burguer-buttons {

View File

@ -1,5 +1,5 @@
import React from "react";
import style from "./newsletter.module.css";
import style from "./newsletter.module.scss";
const Newsletter = () => {
return (

View File

@ -67,6 +67,35 @@
color: #c4c4c4;
}
@media screen and (min-width: 2500px) {
.newsletter-label {
font-weight: 500;
font-size: 36px;
line-height: 42px;
}
.input-wrapper {
width: 668px;
}
.newsletter-wrapper input {
max-width: 668px;
height: 60px;
}
.newsletter-wrapper input::placeholder {
font-size: 28px;
line-height: 33px;
}
.button-submit {
height: 60px;
width: 246px;
font-size: 24px;
line-height: 28px;
}
}
@media screen and (max-width: 1024px) {
.newsletter-wrapper {
padding: 16px;

View File

@ -0,0 +1,30 @@
import * as Yup from "yup";
export default Yup.object().shape({
name: Yup.string()
.required("*Campo Obrigatório")
.min(3, "Insira um nome válido"),
email: Yup.string()
.matches(
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/,
"E-mail Inválido"
)
.required("*Campo Obrigatório"),
cpf: Yup.string()
.matches(/^(?:\d{3}\.){2}\d{3}-?\d{2}$/, "CPF inválido")
.required("*Campo obrigatório"),
nascimento: Yup.string()
.matches(
/^(?:0[1-9]|[12]\d|3[01])([/.-])(?:0[1-9]|1[012])\1(?:19|20)\d\d$/,
"Data de Nascimento inválida"
)
.required("*Campo Obrigatório"),
telefone: Yup.string()
.matches(/^(\d{2})\D*(\d{5}|\d{4})\D*(\d{4})$/, "Número Inválido")
.required("*Campo Obrigatório"),
instagram: Yup.string().matches(
/(?:@)(\w(?:(?:\w|(?:\.(?!\.))){0,28}(?:\w))?)/,
"Nome de usuário não é valido"
),
terms: Yup.boolean().oneOf([true], "você deve aceitar os termos").required(),
});

9732
desafio5/yarn.lock Normal file

File diff suppressed because it is too large Load Diff