Compare commits

..

15 Commits

45 changed files with 567 additions and 275 deletions

1
.gitignore vendored
View File

@ -21,3 +21,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.vercel

108
package-lock.json generated
View File

@ -18,17 +18,17 @@
"formik": "^2.2.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-imask": "^6.4.3",
"react-input-mask": "^2.0.4",
"react-router-dom": "^6.6.1",
"react-scripts": "5.0.1",
"react-text-mask": "^5.5.0",
"sass": "^1.57.1",
"typescript": "^4.9.4",
"web-vitals": "^2.1.4",
"yup": "^0.32.11"
},
"devDependencies": {
"@types/jquery": "^3.5.16",
"@types/jquery-mask-plugin": "^1.14.4",
"@types/react-input-mask": "^3.0.2"
}
},
@ -3809,6 +3809,24 @@
"pretty-format": "^27.0.0"
}
},
"node_modules/@types/jquery": {
"version": "3.5.16",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.16.tgz",
"integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==",
"dev": true,
"dependencies": {
"@types/sizzle": "*"
}
},
"node_modules/@types/jquery-mask-plugin": {
"version": "1.14.4",
"resolved": "https://registry.npmjs.org/@types/jquery-mask-plugin/-/jquery-mask-plugin-1.14.4.tgz",
"integrity": "sha512-8la3UoP0/hclp+Gknxx+Tx8H+puBLj+Ybp7swLFTLk7rnItC5biPzikT15MroQbPdrBqWdfpNPdHQdfcdyPnNg==",
"dev": true,
"dependencies": {
"@types/jquery": "*"
}
},
"node_modules/@types/json-schema": {
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
@ -3931,6 +3949,12 @@
"@types/node": "*"
}
},
"node_modules/@types/sizzle": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
"integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
"dev": true
},
"node_modules/@types/sockjs": {
"version": "0.3.33",
"resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz",
@ -8675,14 +8699,6 @@
"node": ">= 4"
}
},
"node_modules/imask": {
"version": "6.4.3",
"resolved": "https://registry.npmjs.org/imask/-/imask-6.4.3.tgz",
"integrity": "sha512-aH2GHemGkr3cbRBfhogHMIx05eUxdHrZNlKTTLmz8VxpSopuHHJ8+85FsDlBVQqxPlDLhZuwj4lpHHWbLOdBSw==",
"engines": {
"npm": ">=4.0.0"
}
},
"node_modules/immer": {
"version": "9.0.16",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz",
@ -14050,21 +14066,6 @@
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
},
"node_modules/react-imask": {
"version": "6.4.3",
"resolved": "https://registry.npmjs.org/react-imask/-/react-imask-6.4.3.tgz",
"integrity": "sha512-5WyCbubQErO8Wr/zLDyUyC1zCqQXP979QXW6BNirUGsM1VxFmVG0nNfXA1PSXlgdbaXWBiBj+VJBvg/8BDzieA==",
"dependencies": {
"imask": "^6.4.3",
"prop-types": "^15.7.2"
},
"engines": {
"npm": ">=4.0.0"
},
"peerDependencies": {
"react": ">=0.14.0"
}
},
"node_modules/react-input-mask": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/react-input-mask/-/react-input-mask-2.0.4.tgz",
@ -14193,17 +14194,6 @@
}
}
},
"node_modules/react-text-mask": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-text-mask/-/react-text-mask-5.5.0.tgz",
"integrity": "sha512-SLJlJQxa0uonMXsnXRpv5abIepGmHz77ylQcra0GNd7Jtk4Wj2Mtp85uGQHv1avba2uI8ZvRpIEQPpJKsqRGYw==",
"dependencies": {
"prop-types": "^15.5.6"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@ -19610,6 +19600,24 @@
"pretty-format": "^27.0.0"
}
},
"@types/jquery": {
"version": "3.5.16",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.16.tgz",
"integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==",
"dev": true,
"requires": {
"@types/sizzle": "*"
}
},
"@types/jquery-mask-plugin": {
"version": "1.14.4",
"resolved": "https://registry.npmjs.org/@types/jquery-mask-plugin/-/jquery-mask-plugin-1.14.4.tgz",
"integrity": "sha512-8la3UoP0/hclp+Gknxx+Tx8H+puBLj+Ybp7swLFTLk7rnItC5biPzikT15MroQbPdrBqWdfpNPdHQdfcdyPnNg==",
"dev": true,
"requires": {
"@types/jquery": "*"
}
},
"@types/json-schema": {
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
@ -19732,6 +19740,12 @@
"@types/node": "*"
}
},
"@types/sizzle": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
"integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
"dev": true
},
"@types/sockjs": {
"version": "0.3.33",
"resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz",
@ -23206,11 +23220,6 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ=="
},
"imask": {
"version": "6.4.3",
"resolved": "https://registry.npmjs.org/imask/-/imask-6.4.3.tgz",
"integrity": "sha512-aH2GHemGkr3cbRBfhogHMIx05eUxdHrZNlKTTLmz8VxpSopuHHJ8+85FsDlBVQqxPlDLhZuwj4lpHHWbLOdBSw=="
},
"immer": {
"version": "9.0.16",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz",
@ -26903,15 +26912,6 @@
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
},
"react-imask": {
"version": "6.4.3",
"resolved": "https://registry.npmjs.org/react-imask/-/react-imask-6.4.3.tgz",
"integrity": "sha512-5WyCbubQErO8Wr/zLDyUyC1zCqQXP979QXW6BNirUGsM1VxFmVG0nNfXA1PSXlgdbaXWBiBj+VJBvg/8BDzieA==",
"requires": {
"imask": "^6.4.3",
"prop-types": "^15.7.2"
}
},
"react-input-mask": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/react-input-mask/-/react-input-mask-2.0.4.tgz",
@ -27003,14 +27003,6 @@
"workbox-webpack-plugin": "^6.4.1"
}
},
"react-text-mask": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-text-mask/-/react-text-mask-5.5.0.tgz",
"integrity": "sha512-SLJlJQxa0uonMXsnXRpv5abIepGmHz77ylQcra0GNd7Jtk4Wj2Mtp85uGQHv1avba2uI8ZvRpIEQPpJKsqRGYw==",
"requires": {
"prop-types": "^15.5.6"
}
},
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",

View File

@ -13,11 +13,9 @@
"formik": "^2.2.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-imask": "^6.4.3",
"react-input-mask": "^2.0.4",
"react-router-dom": "^6.6.1",
"react-scripts": "5.0.1",
"react-text-mask": "^5.5.0",
"sass": "^1.57.1",
"typescript": "^4.9.4",
"web-vitals": "^2.1.4",
@ -48,6 +46,8 @@
]
},
"devDependencies": {
"@types/jquery": "^3.5.16",
"@types/jquery-mask-plugin": "^1.14.4",
"@types/react-input-mask": "^3.0.2"
}
}

View File

@ -16,7 +16,10 @@ const Header = () => {
};
return (
<header className={styles["page-header"]}>
<header
className={styles["page-header"]}
data-testid="header__container"
>
<div className={styles["page-header__container"]}>
<section className={styles["page-header__container-top"]}>
<div className={styles["page-header__menu"]}>
@ -35,24 +38,15 @@ const Header = () => {
onClick={activeMenuMobile}
/>
</div>
<a className={styles["page-header__logo"]} href="/">
<a
className={styles["page-header__logo"]}
href="/"
data-testid="header__logo"
>
<img src={Logo} alt="" />
</a>
<SearchBar />
<div className={styles["page-header__container-login"]}>
<Link link="/" text="ENTRAR" className={styles["link"]} />
<a
href="/"
aria-label="Carrinho"
className={styles["page-header__cart"]}
>
<img
src={Cart}
alt=""
className={styles["page-header__cart-image"]}
/>
</a>
</div>
<MenuTop />
</section>
<section className={styles["page-header__container-bottom-mobile"]}>
<SearchBar />
@ -65,4 +59,27 @@ const Header = () => {
);
};
export function MenuTop() {
return (
<div
className={styles["page-header__container-login"]}
data-testid="header__menuTop"
>
<Link link="/" text="ENTRAR" className={styles["link"]} testId="header__enter" />
<a
href="/"
aria-label="Carrinho"
className={styles["page-header__cart"]}
>
<img
src={Cart}
alt=""
className={styles["page-header__cart-image"]}
data-testid="header__cartIcon"
/>
</a>
</div>
)
}
export { Header };

View File

@ -3,11 +3,13 @@ import styles from "./header.module.scss";
const HeaderLinks = () => {
return (
<>
<div
data-testid="header__menuBottom"
>
<Link className={styles["link"]} link="/" text="CURSOS" />
<Link className={styles["link"]} link="/" text="SAIBA MAIS" />
<Link className={styles["link"]} link="/" text="INSTITUCIONAIS" />
</>
</div>
);
};

View File

@ -6,6 +6,7 @@ const SearchBar = () => {
return (
<div className={styles["page-header__busca"]}>
<input
data-testid="header__searchBar"
className={styles["page-header__busca-input"]}
type="text"
placeholder="Buscar..."

View File

@ -5,6 +5,22 @@
flex-direction: column;
background: $black;
@media (min-width: 2500px) {
height: 180px;
}
@media (min-width: 1200px) and (max-width: 2000px) {
height: 154px;
}
@media (min-width: 1000px) and (max-width: 1200px) {
height: 137px;
}
@media (max-width: 700px) {
height: 129px;
}
&__container-top {
height: 76px;
display: flex;
@ -41,6 +57,27 @@
outline: 0;
padding-left: 16px;
@media (min-width: 2500px) {
width: 600px;
height: 50px;
font-size: 26px;
}
@media (min-width: 1200px) and (max-width: 2000px) {
width: 400px;
height: 41px;
font-size: 20px;
}
@media (min-width: 1000px) and (max-width: 1200px) {
height: 35px;
font-size: 16px;
}
@media (max-width: 700px) {
height: 35px;
}
&::placeholder {
color: $gray-800;
@ -173,11 +210,6 @@
width: 22.4%;
}
&__busca-input {
height: 57px;
font-size: 28px;
line-height: 33px;
}
&__busca-icon {
top: 50%;

View File

@ -1,21 +1,38 @@
import iconHome from "./assets/iconHome.svg";
import arrow from "./assets/arrow.svg";
import { SubjectMain } from "./Subject/SubjectMain";
import styles from "./main.module.scss";
const Main = () => {
export const Main = () => {
return (
<main className={styles["page-main"]}>
<div className={styles["page-main__menu"]}>
<img className={styles["page-main__img-home"]} src={iconHome} alt="" />
<img className={styles["page-main__img-arrow"]} src={arrow} alt="" />
<strong className={styles["page-main__text"]}>INSTITUCIONAL</strong>
</div>
<h1 className={styles["page-main__title"]}>INSTITUCIONAL</h1>
<Breadcrumb />
<InstitucionalTitle />
<SubjectMain />
</main>
);
};
export { Main };
export const Breadcrumb = () => {
return (
<div
className={styles["page-main__menu"]}
data-testid="breadcrumb__container"
>
<img className={styles["page-main__img-home"]} src={iconHome} alt="" />
<img className={styles["page-main__img-arrow"]} src={arrow} alt="" />
<strong className={styles["page-main__text"]}>INSTITUCIONAL</strong>
</div>
)
}
export const InstitucionalTitle = () => {
return (
<h1
className={styles["page-main__title"]}
data-testid="title"
>
INSTITUCIONAL
</h1>
)
}

View File

@ -1,10 +1,18 @@
import react, { useState } from "react";
import styles from "./form.module.scss";
import React, { useState } from "react";
import stylesInput from "./input.module.scss";
import stylesCheckbox from "./checkbox.module.scss";
import { FormSchema } from "./schema/FormSchema";
import InputMask from "react-input-mask";
import {
Formik,
Form,
Field,
ErrorMessage,
FormikHelpers,
FieldProps,
} from "formik";
import { Formik, Form, Field, ErrorMessage } from "formik";
import styles from "./form.module.scss";
interface FormikValues {
name: string;
@ -26,16 +34,24 @@ const initialValues = {
acceptTerms: false,
};
let listClient: Array<any> = [];
const RegistrationForm = () => {
const [isSubmit, setIsSubmit] = useState(false);
const handleSubmit = (
values: FormikValues,
actions: FormikHelpers<FormikValues>
) => {
listClient.push(values);
console.log(listClient);
actions.resetForm();
setIsSubmit(!isSubmit);
};
return (
<div className={styles["page-main__form"]}>
<Formik
onSubmit={(values: FormikValues, { resetForm }) => {
console.log(values);
setIsSubmit(!isSubmit);
resetForm({ values: initialValues });
}}
onSubmit={handleSubmit}
initialValues={initialValues}
validationSchema={FormSchema}
>
@ -78,11 +94,16 @@ const RegistrationForm = () => {
CPF
</label>
<Field
className={stylesInput["page-main__input"]}
id="Cpf"
placeholder="000.000.000-00"
name="cpf"
mask="999.999.999-99"
render={({ field }: any) => (
<InputMask
{...field}
className={stylesInput["page-main__input"]}
id="Cpf"
placeholder="000.000.000-00"
mask={"999.999.999-99"}
/>
)}
/>
<ErrorMessage
component="span"
@ -95,11 +116,16 @@ const RegistrationForm = () => {
Data de Nascimento:
</label>
<Field
className={stylesInput["page-main__input"]}
id="Data"
placeholder="00.00.0000"
name="data"
mask="99.99.9999"
render={({ field }: FieldProps) => (
<InputMask
{...field}
mask="99.99.9999"
className={stylesInput["page-main__input"]}
id="Data"
placeholder="00.00.0000"
/>
)}
/>
<ErrorMessage
component="span"
@ -112,11 +138,16 @@ const RegistrationForm = () => {
Telefone:
</label>
<Field
className={stylesInput["page-main__input"]}
id="tel"
placeholder="(00) 00000-0000"
name="tel"
mask="(99) 99999-9999"
render={({ field }: any) => (
<InputMask
{...field}
className={stylesInput["page-main__input"]}
id="tel"
placeholder="(00) 00000-0000"
mask="(99) 99999-9999"
/>
)}
/>
<ErrorMessage
component="span"

View File

@ -6,10 +6,13 @@ const FormSchema = () =>
.min(3, "mínimo 3 caracteres")
.required("*Campo Obrigatório"),
email: Yup.string().required("*Campo Obrigatório").email("Email inválido"),
cpf: Yup.string().length(14).required("*Campo Obrigatório"),
cpf: Yup.string()
.min(14, "mínimo 14 caracteres")
.required("*Campo Obrigatório"),
data: Yup.date()
.required("*Campo Obrigatório")
.max(new Date(), "Não é possível incluir uma data futura"),
.min("01.01.1900", "data mínima 01.01.1900")
.max(new Date())
.required("*Campo obrigatório"),
tel: Yup.string().length(15).required("*Campo Obrigatório"),
instagram: Yup.string(),
acceptTerms: Yup.bool().oneOf([true], "*"),

View File

@ -4,14 +4,16 @@ import { NavLink, NavLinkProps } from "react-router-dom";
interface LiProps extends NavLinkProps {
text: string;
to: NavLinkProps["to"];
to: string;
}
const LiForm = (props: LiProps) => {
const { text, to } = props;
const LiForm = ({ text, to }: LiProps) => {
console.log(geDataTestId(to));
return (
<li>
<NavLink
data-testid={geDataTestId(to)}
to={to}
className={({ isActive }) =>
isActive
@ -25,4 +27,13 @@ const LiForm = (props: LiProps) => {
);
};
function geDataTestId(url: string ) {
return `lateralMenu__item${isTextUrl() ? " lateralMenu__itemActive" : ""}`;
function isTextUrl() {
return window.location.href.includes(url);
}
}
export { LiForm };

View File

@ -10,9 +10,12 @@ const Nav = () => {
return (
<>
<nav className={styles["page-subject__nav"]}>
<nav
className={styles["page-subject__nav"]}
data-testid="lateralMenu__container"
>
<ul className={styles["page-subject__menu"]}>
<LiForm to="/" text="Sobre" />
<LiForm to="/Sobre" text="Sobre" />
<LiForm to="/forma-de-pagamento" text="Forma de Pagamento" />
<LiForm to="/entrega" text="Entrega" />
<LiForm to="/troca-e-devolucao" text="Troca e Devolução" />

View File

@ -15,7 +15,7 @@ const SubjectMain = () => {
<Router>
<Nav />
<Routes>
<Route path="/" element={<Sobre />} />
<Route path="/sobre" element={<Sobre />} />
<Route path="/forma-de-pagamento" element={<FormaDePagamento />} />
<Route path="/entrega" element={<Entrega />} />
<Route path="/troca-e-devolucao" element={<TrocaEDevolucao />} />

View File

@ -1,23 +1,28 @@
import React from "react";
import styles from "./subject.module.scss";
interface SubjectTextProps {
title: string;
}
const SubjectText = (props: SubjectTextProps) => {
const { title } = props;
const SubjectText = ({title}: SubjectTextProps) => {
return (
<article className={styles["page-subject__container"]}>
<h2 className={styles["page-subject__title"]}>{title}</h2>
<p className={styles["page-subject__paragraph"]}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
<article
className={styles["page-subject__container"]}
data-testid="texts__container"
>
<Title title={title} />
<Text
text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
</p>
<p className={styles["page-subject__paragraph"]}>
mollit anim id est laborum."
/>
<Text
text="
Sed ut perspiciatis unde omnis iste natus error sit voluptatem
accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab
illo inventore veritatis et quasi architecto beatae vitae dicta sunt
@ -26,17 +31,47 @@ const SubjectText = (props: SubjectTextProps) => {
voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum
quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam
eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat
voluptatem.
</p>
<p className={styles["page-subject__paragraph"]}>
voluptatem." />
<Text
text="
Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis
suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis
autem vel eum iure reprehenderit qui in ea voluptate velit esse quam
nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo
voluptas nulla pariatur?
</p>
voluptas nulla pariatur?" />
</article>
);
};
export type TitleProps = {
title: string;
}
export const Title = ({title}: TitleProps) => {
return (
<h2
className={styles["texts__title"]}
data-testid="texts__title"
>
{title}
</h2>
)
}
export type TextProps = {
text: string;
}
export const Text = ({ text }: TextProps) => {
return (
<p
className={styles["page-subject__paragraph"]}
data-testid="texts__text"
>
{text}
</p>
)
}
export { SubjectText };

View File

@ -4,14 +4,17 @@ import styles from "../footer/footer.module.scss";
interface ButtonProps {
text: string;
testId?: string;
}
const Button = (props: ButtonProps) => {
return (
<button type="submit" className={styles["button"]}>
{props.text}
const Button = ({ text, testId }: ButtonProps) => (
<button
type="submit"
className={styles["button"]}
data-testid={testId}
>
{text}
</button>
);
};
export default Button;
export { Button };

View File

@ -1,14 +1,17 @@
import React from "react";
import FooterBottom from "./footer-bottom/footer-bottom";
import FooterTop from "./footer-top/footerTop";
import { Newsletter } from "./newsletter/Newsletter";
import { FooterTop } from "./footer-top/footerTop";
import { FooterBottom } from "./footer-bottom/footer-bottom";
import { IconFixed } from "./icon-fixed/icon-fixed";
import styles from "./footer.module.scss";
import IconFixed from "./icon-fixed/icon-fixed";
import Newsletter from "./newsletter/Newsletter";
const Footer = () => {
return (
<footer className={styles["page-footer"]}>
<footer
className={styles["page-footer"]}
data-testid="footer__container"
>
<Newsletter />
<FooterTop />
<FooterBottom />
@ -17,4 +20,4 @@ const Footer = () => {
);
};
export default Footer;
export { Footer };

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -1,23 +1,40 @@
import React from "react";
import { Img } from "../img-footer/img";
import { Text } from "../../text/Text";
import Vtex from "../assets/svg/Vtex.svg";
import M3 from "../assets/svg/M3.svg";
import styles from "../../footer.module.scss";
import Img from "../img-footer/img";
import Text from "../../text/Text";
import Vtex from "../assets/Vtex.svg";
import M3 from "../assets/M3.svg";
const Autores = () => {
return (
<section className={styles["page-footer__footer-autores"]}>
<Text className={styles["page-footer__footer-text"]} text="Powered by" />
<Img className={styles["autores-img"]} img={Vtex} text="vtex" />
<Text
className={styles["page-footer__footer-text"]}
text="Developed by"
/>
<Img className={styles["autores-img"]} img={M3} text="M3" />
<PoweredBy />
<DevelopedBy />
</section>
);
};
export default Autores;
export { Autores };
export const PoweredBy = () => (
<div
data-testid="footer__vtex"
>
<Text className={styles["page-footer__footer-text"]} text="Powered by" />
<Img className={styles["autores-img"]} img={Vtex} text="vtex" />
</div>
)
export const DevelopedBy = () => (
<div
data-testid="footer__m3"
>
<Text
className={styles["page-footer__footer-text"]}
text="Developed by"
/>
<Img className={styles["autores-img"]} img={M3} text="M3" />
</div>
)

View File

@ -1,21 +1,17 @@
import React from "react";
import { Autores } from "./autores/autores";
import { Text } from "../text/Text";
import { Imgs } from "./pagamento/imgs";
import styles from "../footer.module.scss";
import Autores from "./autores/autores";
import Text from "../text/Text";
import Imgs from "./pagamento/imgs";
const FooterBottom = () => {
return (
<section className={styles["page-footer__footer-bottom"]}>
<section
className={styles["page-footer__footer-bottom"]}
data-testid="footer__bottomContainer"
>
<div className={styles["page-footer__footer-bottom-container"]}>
<section className={styles["page-footer__container-footer-text"]}>
<Text
className={styles["page-footer__footer-text"]}
text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor"
/>
</section>
<Copyright />
<Imgs />
<Autores />
</div>
@ -23,4 +19,15 @@ const FooterBottom = () => {
);
};
export default FooterBottom;
export { FooterBottom };
export const Copyright = () => (
<section
className={styles["page-footer__container-footer-text"]}>
<Text
testId="footer__copyright"
className={styles["page-footer__footer-text"]}
text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tecmpor"
/>
</section>
)

View File

@ -1,15 +1,19 @@
import React from "react";
import styles from "../../../footer.module.scss";
interface ButtonProps {
export interface ImgProps {
img: string;
text: string;
className: string;
testId?: string
}
const Img = (props: ButtonProps) => {
return <img className={props.className} src={props.img} alt={props.text} />;
};
const Img = ({ img, text, testId, className }: ImgProps) => (
<img
className={className}
src={img}
alt={text}
data-testid={testId}
/>
)
export default Img;
export { Img };

View File

@ -1,34 +1,56 @@
import React from "react";
import styles from "../../footer.module.scss";
import Img from "../img-footer/img";
import Master from "../assets/Master.png";
import Visa from "../assets/Visa.png";
import Diners from "../assets/Diners.png";
import Elo from "../assets/Elo.png";
import Hiper from "../assets/Hiper.png";
import Pagseguro from "../assets/Pagseguro.png";
import Boleto from "../assets/Boleto.png";
import vtex from "../assets/vtex-pci-200.png";
import { Img, ImgProps } from "../img-footer/img";
import Master from "../assets/img/Master.png";
import Visa from "../assets/img/Visa.png";
import Diners from "../assets/img/Diners.png";
import Elo from "../assets/img/Elo.png";
import Hiper from "../assets/img/Hiper.png";
import Pagseguro from "../assets/img/Pagseguro.png";
import Boleto from "../assets/img/Boleto.png";
import vtex from "../assets/img/vtex-pci-200.png";
const imgs = () => {
const PaymentsMethods = () => {
return (
<section className={styles["page-footer__imgs"]}>
<Img className={styles["img"]} img={Master} text="Cartão master" />
<Img className={styles["img"]} img={Visa} text="Cartão visa" />
<section
className={styles["page-footer__imgs"]}
data-testid="footer__paymentMethods"
>
<PaymentMethod img={Master} text="Cartão master" />
<PaymentMethod img={Visa} text="Cartão visa" />
<Img
className={styles["img"]}
img={Diners}
text="Cartão american diners"
/>
<Img className={styles["img"]} img={Elo} text="Cartão elo" />
<Img className={styles["img"]} img={Hiper} text="Cartão hiper" />
<Img className={styles["img"]} img={Pagseguro} text="Pague Seguro" />
<Img className={styles["img"]} img={Boleto} text="Pagamento boleto" />
<PaymentMethod img={Elo} text="Cartão elo" />
<PaymentMethod img={Hiper} text="Cartão hiper" />
<PaymentMethod img={Pagseguro} text="Pague Seguro" />
<PaymentMethod img={Boleto} text="Pagamento boleto" />
<div className={styles["divisor"]}></div>
<Img className={styles["img-grande"]} img={vtex} text="Vtex" />
<PaymentMethod isBig img={vtex} text="Vtex" />
</section>
);
};
export default imgs;
export type PaymentMethodProps = Pick<ImgProps, "img" | "text"> & {
isBig?: boolean;
}
export const PaymentMethod = ({ img, text, isBig }: PaymentMethodProps) => {
return (
<Img
className={getClassName()}
img={img}
text={text}
testId="footer__paymentMethod"
/>
)
function getClassName() {
return isBig ? styles["img-grande"] : styles["img"]
}
}
export { PaymentsMethods as Imgs };

View File

@ -1,9 +1,9 @@
import React, { useState } from "react";
import Link from "../../../link/Link";
import { Link } from "../../../link/Link";
import { ButtonFooterMobile } from "../button/button";
import { Title } from "../title/Title";
import styles from "../../footer.module.scss";
import ButtonFooterMobile from "../button/button";
import Title from "../title/Title";
const Duvidas = () => {
const [isOpen, setIsOpen] = useState(false);
@ -35,4 +35,4 @@ const Duvidas = () => {
);
};
export default Duvidas;
export { Duvidas };

View File

@ -1,11 +1,10 @@
import React, { useState } from "react";
import Link from "../../../link/Link";
import { Link } from "../../../link/Link";
import { Text } from "../../text/Text";
import { ButtonFooterMobile } from "../button/button";
import { Title } from "../title/Title";
import styles from "../../footer.module.scss";
import Text from "../../text/Text";
import ButtonFooterMobile from "../button/button";
import Title from "../title/Title";
const FaleConosco = () => {
const [isOpen, setIsOpen] = useState(false);
@ -39,4 +38,4 @@ const FaleConosco = () => {
);
};
export default FaleConosco;
export { FaleConosco };

View File

@ -1,10 +1,9 @@
import React, { useState } from "react";
import Link from "../../../link/Link";
import { Link } from "../../../link/Link";
import { ButtonFooterMobile } from "../button/button";
import { Title } from "../title/Title";
import styles from "../../footer.module.scss";
import ButtonFooterMobile from "../button/button";
import Title from "../title/Title";
const Institucional = () => {
const [isOpen, setIsOpen] = useState(false);
@ -12,9 +11,15 @@ const Institucional = () => {
setIsOpen(!isOpen);
};
return (
<section className={styles["page-footer__container"]}>
<section
data-testid="footer__menuContainer"
className={styles["page-footer__container"]}>
<div className={styles["container-title"]} onClick={handleMenuFooter}>
<Title className={styles["title"]} text="INSTITUCIONAL" />
<Title
className={styles["title"]}
text="INSTITUCIONAL"
testId="footer__menuTitle"
/>
<ButtonFooterMobile
className={
isOpen ? styles["link-mobile-active"] : styles["link-mobile"]
@ -23,13 +28,22 @@ const Institucional = () => {
</div>
<div className={isOpen ? styles["active"] : styles["container-link"]}>
<Link className={styles["link"]} link="/" text="Quem Somos" />
<Link
testId="footer__menuItem"
className={styles["link"]}
link="/"
text="Quem Somos"
/>
<Link
className={styles["link"]}
link="/"
text="Política de Privacidade"
/>
<Link className={styles["link"]} link="/" text="Segurança" />
<Link
className={styles["link"]}
link="/"
text="Segurança"
/>
<Link
className={styles["link-underline"]}
link="/"
@ -40,4 +54,4 @@ const Institucional = () => {
);
};
export default Institucional;
export { Institucional };

View File

@ -6,14 +6,17 @@ interface IconProps {
img: string;
text: string;
href: string;
testId?: string;
}
const Icon = (props: IconProps) => {
return (
<a href={props.href} className={styles["icon"]}>
<img src={props.img} alt={props.text} />
const Icon = ({ img, text, href, testId }: IconProps) => (
<a href={href} target="_blank" className={styles["icon"]} rel="noreferrer">
<img
src={img}
alt={text}
data-testid={testId}
/>
</a>
);
};
)
export default Icon;
export { Icon };

View File

@ -1,27 +1,58 @@
import React from "react";
import { Link } from "../../../link/Link";
import { Icon } from "./Icon/Icon";
import styles from "../../footer.module.scss";
import Icon from "./Icon/Icon";
import facebook from "./assets/icon-facebook.svg";
import instagram from "./assets/icon-instagram.svg";
import twitter from "./assets/icon-twitter.svg";
import youtube from "./assets/icon-youtube.svg";
import linkedin from "./assets/icon-linkedin.svg";
import Link from "../../../link/Link";
import styles from "../../footer.module.scss";
const RedeSociais = () => {
return (
<div className={styles["page-footer__rede-sociais"]}>
<div className={styles["page-footer__rede-sociais-icons"]}>
<Icon img={facebook} href="/" text="icone facebook" />
<Icon img={instagram} href="/" text="icone instagram" />
<Icon img={twitter} href="/" text="icone facebook" />
<Icon img={youtube} href="/" text="icone youtube" />
<Icon img={linkedin} href="/" text="icone linkedin" />
<div
className={styles["page-footer__rede-sociais"]}
data-testid="footer__socialContainer"
>
<div
data-testid="footer__socialIcons"
className={styles["page-footer__rede-sociais-icons"]}>
<Icon
img={facebook}
href="https://pt-br.facebook.com/digitalm3/"
text="icone facebook"
testId="footer__socialIcon"
/>
<Icon
img={instagram}
href="https://www.instagram.com/m3.ecommerce/"
text="icone instagram"
testId="footer__socialIcon"
/>
<Icon img={twitter} href="https://twitter.com/" text="icone facebook" />
<Icon
img={youtube}
href="https://www.youtube.com/channel/UCW4o86gZG_ceA8CmHltXeXA"
text="icone youtube"
testId="footer__socialIcon"
/>
<Icon
img={linkedin}
href="https://www.linkedin.com/company/11412599/"
text="icone linkedin"
testId="footer__socialIcon"
/>
</div>
<Link className={styles["link"]} link="/" text="www.loremipsum.com" />
<Link
className={styles["link"]}
link="/"
text="www.loremipsum.com"
testId="footer__socialSite"
/>
</div>
);
};
export default RedeSociais;
export { RedeSociais };

View File

@ -1,13 +1,12 @@
import React from "react";
import styles from "../../footer.module.scss";
interface ButtonProps {
className: string;
}
const ButtonFooterMobile = (props: ButtonProps) => {
return <a className={props.className}></a>;
const { className } = props;
return <a className={className}></a>;
};
export default ButtonFooterMobile;
export { ButtonFooterMobile };

View File

@ -1,11 +1,10 @@
import React from "react";
import { Duvidas } from "./Duvidas/Duvidas";
import { FaleConosco } from "./Fale-conosco/FaleConosco";
import { Institucional } from "./Institucional/Institucional";
import { RedeSociais } from "./Rede-social/RedeSociais";
import styles from "../footer.module.scss";
import Duvidas from "./Duvidas/Duvidas";
import FaleConosco from "./Fale-conosco/FaleConosco";
import Institucional from "./Institucional/Institucional";
import RedeSociais from "./Rede-social/RedeSociais";
const FooterTop = () => {
return (
<section className={styles["page-footer__top"]}>
@ -19,4 +18,4 @@ const FooterTop = () => {
);
};
export default FooterTop;
export { FooterTop };

View File

@ -1,10 +1,16 @@
export interface TitleProps {
text: string;
className: string;
testId?: string
}
const Title = (props: TitleProps) => {
return <h3 className={props.className}>{props.text}</h3>;
const Title = ({ text, className, testId }: TitleProps) => {
return <h3
className={className}
data-testid={testId}
>
{text}
</h3>;
};
export default Title;
export { Title };

View File

@ -163,15 +163,16 @@
&__footer-bottom {
width: 100%;
background: $black;
padding: 15px 16px;
padding: 15px 0;
display: flex;
justify-content: center;
}
&__footer-bottom-container {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
width: 84.37%;
}
&__imgs {
@ -437,11 +438,25 @@
display: none;
}
&__footer-bottom {
padding: 15px 16px;
}
&__footer-bottom-container {
flex-direction: column;
gap: 15px;
align-items: flex-start;
max-width: 100%;
width: 100%;
}
.img {
width: 3.64%;
min-width: 30px;
}
.img-grande {
width: 5.55%;
min-width: 45px;
}
@ -471,11 +486,13 @@
.img {
width: 8.75%;
height: auto;
min-width: 20px;
}
.img-grande {
width: 13.12%;
height: auto;
min-width: 30px;
}
&__icon-fixed {

View File

@ -1,4 +1,4 @@
import LinkTop from "./link/Link";
import { LinkTop } from "./link/Link";
import Whatsapp from "./assets/whatsapp.svg";
import Seta from "./assets/Seta.svg";
@ -28,4 +28,4 @@ const IconFixed = () => {
);
};
export default IconFixed;
export { IconFixed };

View File

@ -8,11 +8,12 @@ interface LinkProps {
}
const LinkTop = (props: LinkProps) => {
const { img, className, href, onClick } = props;
return (
<a onClick={props.onClick} href={props.href} className={props.className}>
<img src={props.img} alt="" />
<a onClick={onClick} href={href} className={className}>
<img src={img} alt="" />
</a>
);
};
export default LinkTop;
export { LinkTop };

View File

@ -1,9 +1,10 @@
import React, { useState } from "react";
import Button from "../../button/Button";
import { Button } from "../../button/Button";
import { Formik, Form, Field, ErrorMessage } from "formik";
import styles from "../footer.module.scss";
import { NewsletterSchema } from "./schema/NewsletterSchema";
import styles from "../footer.module.scss";
interface FormikValues {
email: string;
}
@ -15,14 +16,14 @@ const initialValues = {
const Newsletter = () => {
const [isSubmit, setIsSubmit] = useState(false);
return (
<section className={styles["page-footer__newsletter"]}>
<section
data-testid="newsletter__container"
className={styles["page-footer__newsletter"]}
>
<div className={styles["page-footer__newsletter-container"]}>
<h3 className={styles["page-footer__newsletter-title"]}>
ASSINE NOSSA NEWSLETTER
</h3>
<Title />
<Formik
onSubmit={(values: FormikValues, { resetForm }) => {
console.log(values);
setIsSubmit(!isSubmit);
resetForm({ values: initialValues });
}}
@ -33,6 +34,7 @@ const Newsletter = () => {
<div className={styles["page-footer__newsletter-form"]}>
<Field
name="email"
data-testid="newsletter__input"
className={styles["input"]}
placeholder="E-mail"
/>
@ -42,7 +44,7 @@ const Newsletter = () => {
className={styles["page-footer__newsletter-error"]}
/>
</div>
<Button text="ENVIAR" />
<Button text="ENVIAR" testId="newsletter__submit" />
</Form>
</Formik>
</div>
@ -50,4 +52,15 @@ const Newsletter = () => {
);
};
export default Newsletter;
export { Newsletter };
export const Title = () => {
return (
<h3
className={styles["page-footer__newsletter-title"]}
data-testid="newsletter__title"
>
ASSINE NOSSA NEWSLETTER
</h3>
)
}

View File

@ -1,13 +1,16 @@
import React from "react";
import styles from "../../footer.module.scss";
interface TextProps {
text: string;
className: string;
testId?: string;
}
const Text = (props: TextProps) => {
return <p className={props.className}>{props.text}</p>;
};
const Text = ({ text, className, testId}: TextProps) => (
<p
className={className}
data-testid={testId}
>
{text}
</p>
);
export default Text;
export { Text };

View File

@ -2,12 +2,17 @@ export interface LinkProps {
link: string;
text: string;
className: string;
testId?: string;
}
const Link = (props: LinkProps) => {
const { link, text, className } = props;
return (
<a href={link} className={className}>
<a
href={link}
className={className}
data-testid={props.testId}
>
{text}
</a>
);

View File

@ -1,4 +1,5 @@
import Footer from "../components/footer/Footer";
import React from "react";
import { Footer } from "../components/footer/Footer";
import { Header } from "../components/Header/Header";
import { Main } from "../components/Main/Main";