diff --git a/public/index.html b/public/index.html
index b27e247..a80ce2f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -17,6 +17,12 @@
+
+
+
Challenge - 5 | Institutional
diff --git a/src/App.tsx b/src/App.tsx
index 49cf0b4..4a416eb 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,5 +1,6 @@
-import { Introduction } from './pages/Introduction'
+import { Footer } from './template/Footer'
import { Header } from './template/Header'
+import { Introduction } from './pages/Introduction'
import './settings/styles/index.scss'
@@ -11,6 +12,8 @@ export function App() {
+
+
>
)
}
diff --git a/src/assets/brands/Boleto.png b/src/assets/brands/Boleto.png
new file mode 100644
index 0000000..da88e63
Binary files /dev/null and b/src/assets/brands/Boleto.png differ
diff --git a/src/assets/brands/Diners.png b/src/assets/brands/Diners.png
new file mode 100644
index 0000000..56edfee
Binary files /dev/null and b/src/assets/brands/Diners.png differ
diff --git a/src/assets/brands/Elo.png b/src/assets/brands/Elo.png
new file mode 100644
index 0000000..a887e53
Binary files /dev/null and b/src/assets/brands/Elo.png differ
diff --git a/src/assets/brands/Hiper.png b/src/assets/brands/Hiper.png
new file mode 100644
index 0000000..094a571
Binary files /dev/null and b/src/assets/brands/Hiper.png differ
diff --git a/src/assets/brands/Master.png b/src/assets/brands/Master.png
new file mode 100644
index 0000000..776953e
Binary files /dev/null and b/src/assets/brands/Master.png differ
diff --git a/src/assets/brands/Paypal.png b/src/assets/brands/Paypal.png
new file mode 100644
index 0000000..fc18c89
Binary files /dev/null and b/src/assets/brands/Paypal.png differ
diff --git a/src/assets/brands/Visa.png b/src/assets/brands/Visa.png
new file mode 100644
index 0000000..ba0cc36
Binary files /dev/null and b/src/assets/brands/Visa.png differ
diff --git a/src/assets/brands/svgs/M3.svg b/src/assets/brands/svgs/M3.svg
new file mode 100644
index 0000000..d05ea09
--- /dev/null
+++ b/src/assets/brands/svgs/M3.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/brands/svgs/Vtex.svg b/src/assets/brands/svgs/Vtex.svg
new file mode 100644
index 0000000..8d67613
--- /dev/null
+++ b/src/assets/brands/svgs/Vtex.svg
@@ -0,0 +1,7 @@
+
diff --git a/src/assets/brands/vtex-pci-200.png b/src/assets/brands/vtex-pci-200.png
new file mode 100644
index 0000000..bccc61e
Binary files /dev/null and b/src/assets/brands/vtex-pci-200.png differ
diff --git a/src/assets/icons/facebook.svg b/src/assets/icons/facebook.svg
new file mode 100644
index 0000000..c1eee79
--- /dev/null
+++ b/src/assets/icons/facebook.svg
@@ -0,0 +1,16 @@
+
diff --git a/src/assets/icons/instagram.svg b/src/assets/icons/instagram.svg
new file mode 100644
index 0000000..1e20d6f
--- /dev/null
+++ b/src/assets/icons/instagram.svg
@@ -0,0 +1,18 @@
+
diff --git a/src/assets/icons/linkedin.svg b/src/assets/icons/linkedin.svg
new file mode 100644
index 0000000..d8aa438
--- /dev/null
+++ b/src/assets/icons/linkedin.svg
@@ -0,0 +1,18 @@
+
diff --git a/src/assets/icons/twitter.svg b/src/assets/icons/twitter.svg
new file mode 100644
index 0000000..3b51e7a
--- /dev/null
+++ b/src/assets/icons/twitter.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/assets/icons/youtube.svg b/src/assets/icons/youtube.svg
new file mode 100644
index 0000000..8973940
--- /dev/null
+++ b/src/assets/icons/youtube.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/components/Accordion/@types/index.d.ts b/src/components/Accordion/@types/index.d.ts
new file mode 100644
index 0000000..8435179
--- /dev/null
+++ b/src/components/Accordion/@types/index.d.ts
@@ -0,0 +1,22 @@
+import { HTMLAttributes, ReactNode } from 'react'
+
+export interface MainProps
+ extends Omit,
+ HTMLAttributes {
+ children: ReactNode | ReactNode[]
+}
+
+export interface HeaderProps
+ extends Omit,
+ HTMLAttributes {
+ children: ReactNode | ReactNode[]
+}
+
+export interface ContentProps extends HTMLAttributes {
+ children: ReactNode | ReactNode[]
+}
+
+export interface AccordionProps {
+ customKey: string | number
+ setCurrentAccordion: (customKey) => void
+}
diff --git a/src/components/Accordion/context/Items.tsx b/src/components/Accordion/context/Items.tsx
new file mode 100644
index 0000000..459079e
--- /dev/null
+++ b/src/components/Accordion/context/Items.tsx
@@ -0,0 +1,28 @@
+import { createContext, ReactNode } from 'react'
+
+interface IAccordionItemsValues {
+ current: string | number | ''
+ handleSetCurrent: (customKey: string | number | '') => void
+}
+
+export let AccordionContextItems = createContext({
+ current: '',
+} as IAccordionItemsValues)
+
+interface AccordionProviderItemsProps {
+ children: ReactNode | ReactNode[]
+ value: IAccordionItemsValues
+}
+
+export const AccordionProviderItems = ({
+ children,
+ value,
+}: AccordionProviderItemsProps) => {
+ return (
+ <>
+
+ {children}
+
+ >
+ )
+}
diff --git a/src/components/Accordion/index.scss b/src/components/Accordion/index.scss
new file mode 100644
index 0000000..e61397f
--- /dev/null
+++ b/src/components/Accordion/index.scss
@@ -0,0 +1,72 @@
+.accordion {
+ position: relative;
+ overflow: hidden;
+ z-index: 10;
+
+ &-content {
+ height: 0;
+ transform: translateY(-5%);
+ transition: 180ms ease-in;
+ }
+}
+
+.accordion.active {
+ overflow: unset;
+ .accordion-content {
+ height: auto;
+ transform: translateY(0%);
+ }
+}
+
+.accordion.active {
+ .accordion-content {
+ margin-top: 12px;
+ }
+}
+
+.accordion {
+ header {
+ width: 100%;
+ display: inline-flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ &-icon {
+ position: relative;
+
+ width: 7.8px;
+ height: 8.28px;
+
+ &::before,
+ &::after {
+ content: '';
+ position: absolute;
+ width: 100%;
+ background-color: var(--clr-gray-800);
+ }
+
+ &::before {
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+ height: 2px;
+ }
+
+ &::after {
+ right: 50%;
+ transform: translateX(50%);
+ height: 100%;
+ width: 2px;
+ transition: 200ms linear;
+ }
+ }
+}
+
+.accordion.active {
+ .accordion-icon {
+ &::after {
+ height: 0;
+ }
+ }
+}
diff --git a/src/components/Accordion/index.tsx b/src/components/Accordion/index.tsx
new file mode 100644
index 0000000..b1d2d9d
--- /dev/null
+++ b/src/components/Accordion/index.tsx
@@ -0,0 +1,54 @@
+import { useContext } from 'react'
+import { ContentProps, HeaderProps, MainProps } from './@types/index'
+import { AccordionContextItems } from './context/Items'
+
+import './index.scss'
+
+const Main = ({ customKey, children, className, ...props }: MainProps) => {
+ const { current } = useContext(AccordionContextItems)
+
+ const isOpen = () => {
+ if (current === customKey) {
+ return 'active'
+ } else {
+ return ''
+ }
+ }
+
+ return (
+
+ {children}
+
+ )
+}
+
+const Header = ({ customKey, children, className, ...props }: HeaderProps) => {
+ const { handleSetCurrent } = useContext(AccordionContextItems)
+
+ return (
+ handleSetCurrent(customKey)}
+ role={'button'}
+ data-jsx="event"
+ {...props}
+ >
+ {children}
+
+
+ )
+}
+
+const Content = ({ children, className, ...props }: ContentProps) => {
+ return (
+
+ {children}
+
+ )
+}
+
+export const Accordion = Object.assign(Main, { Header, Content })
diff --git a/src/settings/styles/global/_reset.scss b/src/settings/styles/global/_reset.scss
index b7ae335..c323577 100644
--- a/src/settings/styles/global/_reset.scss
+++ b/src/settings/styles/global/_reset.scss
@@ -27,6 +27,7 @@ button {
background-color: transparent;
}
+[role='button'],
.btn-ref,
button {
cursor: pointer;
diff --git a/src/settings/styles/utils/helpers/_mixin.scss b/src/settings/styles/utils/helpers/_mixin.scss
index 80ec28f..48acbe9 100644
--- a/src/settings/styles/utils/helpers/_mixin.scss
+++ b/src/settings/styles/utils/helpers/_mixin.scss
@@ -2,3 +2,4 @@
width: #{$size};
height: #{$size};
}
+
diff --git a/src/template/Footer/components/Item.tsx b/src/template/Footer/components/Item.tsx
new file mode 100644
index 0000000..3d20dc2
--- /dev/null
+++ b/src/template/Footer/components/Item.tsx
@@ -0,0 +1,14 @@
+import { AnchorHTMLAttributes, HTMLAttributes, ReactNode } from 'react'
+
+interface ItemProps extends AnchorHTMLAttributes {
+ children: ReactNode | ReactNode[]
+ $container?: HTMLAttributes
+}
+
+export function Item({ children, $container, ...props }: ItemProps) {
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/template/Footer/fragments/Lists.tsx b/src/template/Footer/fragments/Lists.tsx
new file mode 100644
index 0000000..9c1d075
--- /dev/null
+++ b/src/template/Footer/fragments/Lists.tsx
@@ -0,0 +1,45 @@
+import { AccordionProviderItems } from '../../../components/Accordion/context/Items'
+import { ContactList } from './Lists/Contact'
+import { InstitutionalList } from './Lists/Institutional'
+import { QuestionsList } from './Lists/Question'
+import { Socials } from './Lists/Socials'
+
+import css from '../index.module.scss'
+
+interface ListProps {
+ accordionCurrentIsOpen: string | number | ''
+ handleSetCurrentAccordion: (customKey: string | number | '') => void
+}
+
+export function List({
+ accordionCurrentIsOpen,
+ handleSetCurrentAccordion,
+}: ListProps) {
+ return (
+ <>
+
+
+
+
+ >
+ )
+}
diff --git a/src/template/Footer/fragments/Lists/Contact.tsx b/src/template/Footer/fragments/Lists/Contact.tsx
new file mode 100644
index 0000000..6bd8f08
--- /dev/null
+++ b/src/template/Footer/fragments/Lists/Contact.tsx
@@ -0,0 +1,38 @@
+import { Accordion } from '../../../../components/Accordion'
+import { AccordionProps } from '../../../../components/Accordion/@types'
+import { Item } from '../../components/Item'
+
+import css from '../../index.module.scss'
+
+interface ContactListProps
+ extends Omit {}
+
+export function ContactList({ customKey }: ContactListProps) {
+ return (
+
+
+ Fale Conosco
+
+
+
+
+ -
+ Atendimento ao Consumidor
+
+ -
+ (11) 4159 9504
+
+ -
+ Atendimento Online
+
+ -
+ (11) 99433-8825
+
+
+
+
+ )
+}
diff --git a/src/template/Footer/fragments/Lists/Institutional.tsx b/src/template/Footer/fragments/Lists/Institutional.tsx
new file mode 100644
index 0000000..ad3e131
--- /dev/null
+++ b/src/template/Footer/fragments/Lists/Institutional.tsx
@@ -0,0 +1,37 @@
+import { Accordion } from '../../../../components/Accordion'
+import { AccordionProps } from '../../../../components/Accordion/@types'
+import { Item } from '../../components/Item'
+
+import css from '../../index.module.scss'
+
+interface InstitutionalListProps
+ extends Omit {}
+
+export function InstitutionalList({ customKey }: InstitutionalListProps) {
+ return (
+
+
+ Institucional
+
+
+
+ -
+ Quem somos nós
+
+ -
+ Política de Privacidade
+
+ -
+ Segurança
+
+ -
+ Seja um Revendedor
+
+
+
+
+ )
+}
diff --git a/src/template/Footer/fragments/Lists/Payment.tsx b/src/template/Footer/fragments/Lists/Payment.tsx
new file mode 100644
index 0000000..0a6cbee
--- /dev/null
+++ b/src/template/Footer/fragments/Lists/Payment.tsx
@@ -0,0 +1,40 @@
+import BoletoImg from '../../../../assets/brands/Boleto.png'
+import DinersBrandImg from '../../../../assets/brands/Diners.png'
+import EloBrandImg from '../../../../assets/brands/Elo.png'
+import HiperBrandImg from '../../../../assets/brands/Hiper.png'
+import PaypalBrandImg from '../../../../assets/brands/Paypal.png'
+import MasterCardBrandImg from '../../../../assets/brands/Master.png'
+import VisaBrandImg from '../../../../assets/brands/Visa.png'
+import VtexPCIImg from '../../../../assets/brands/vtex-pci-200.png'
+
+import css from '../../index.module.scss'
+
+export function PaymentsList() {
+ let images = [
+ MasterCardBrandImg,
+ VisaBrandImg,
+ DinersBrandImg,
+ EloBrandImg,
+ HiperBrandImg,
+ PaypalBrandImg,
+ BoletoImg,
+ ]
+
+ return (
+
+ {images.map((image, index) => {
+ return (
+ -
+
+
+ )
+ })}
+
+
+
+ -
+
+
+
+ )
+}
diff --git a/src/template/Footer/fragments/Lists/Question.tsx b/src/template/Footer/fragments/Lists/Question.tsx
new file mode 100644
index 0000000..6c0c17e
--- /dev/null
+++ b/src/template/Footer/fragments/Lists/Question.tsx
@@ -0,0 +1,37 @@
+import { Accordion } from '../../../../components/Accordion'
+import { AccordionProps } from '../../../../components/Accordion/@types'
+import { Item } from '../../components/Item'
+
+import css from '../../index.module.scss'
+
+interface QuestionsListProps
+ extends Omit {}
+
+export function QuestionsList({ customKey }: QuestionsListProps) {
+ return (
+
+
+ Dúvidas
+
+
+
+ -
+ Entrega
+
+ -
+ Pagamento
+
+ -
+ Trocas e Devoluções
+
+ -
+ Dúvidas Frequentes
+
+
+
+
+ )
+}
diff --git a/src/template/Footer/fragments/Lists/Socials.tsx b/src/template/Footer/fragments/Lists/Socials.tsx
new file mode 100644
index 0000000..b30ddad
--- /dev/null
+++ b/src/template/Footer/fragments/Lists/Socials.tsx
@@ -0,0 +1,39 @@
+import facebookIcon from '../../../../assets/icons/facebook.svg'
+import instagramIcon from '../../../../assets/icons/instagram.svg'
+import linkedinIcon from '../../../../assets/icons/linkedin.svg'
+import twitterIcon from '../../../../assets/icons/twitter.svg'
+import youtubeIcon from '../../../../assets/icons/youtube.svg'
+
+import css from '../../index.module.scss'
+
+export function Socials() {
+ return (
+
+ )
+}
diff --git a/src/template/Footer/index.module.scss b/src/template/Footer/index.module.scss
new file mode 100644
index 0000000..3024c43
--- /dev/null
+++ b/src/template/Footer/index.module.scss
@@ -0,0 +1,316 @@
+@use '../../settings/styles/utils/helpers/functions' as function;
+
+.footer {
+ border-top: 1px solid var(--clr-common-black);
+}
+
+.container-top,
+.container-bottom {
+ width: 100%;
+ padding: 0 16px;
+
+ @media screen and (min-width: 1025px) {
+ padding: 0;
+ }
+}
+
+.container-top {
+ display: flex;
+ align-items: flex-start;
+ flex-direction: column;
+
+ padding-top: 17px;
+ padding-bottom: 24px;
+
+ @media only screen and (min-width: 1025px) {
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ justify-content: space-between;
+
+ width: function.fluid(1080px, 1280px);
+ margin: 0 auto;
+ }
+
+ @media only screen and (min-width: 2500px) {
+ width: function.fluid(2299.68px, 2500px);
+ }
+}
+
+.container-bottom {
+ background-color: var(--clr-common-black);
+
+ .phrase {
+ width: function.fluid(258px, 343px);
+
+ &::before {
+ content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. .';
+ }
+
+ text-overflow: ellipsis;
+ text-transform: capitalize;
+ overflow: hidden;
+
+ @media only screen and (min-width: 1025px) {
+ width: function.fluid(234px, 1080px);
+
+ &::before {
+ content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor';
+ }
+ }
+
+ @media only screen and (min-width: 2500px) {
+ width: function.fluid(467px, 2299.68px);
+ }
+ }
+
+ * p,
+ * li {
+ color: var(--clr-common-white);
+ }
+}
+
+.container-bottom {
+ .phrase::before,
+ .actions-bottom .credits li p {
+ font-size: var(--txt-xxs);
+ }
+}
+
+.actions-bottom {
+ .credits {
+ gap: 12.73px;
+
+ &,
+ li {
+ display: inline-flex;
+ align-items: center;
+ }
+
+ @each $index, $value in ('1': 12.12px, '2': 12.97px) {
+ li:nth-child(#{$index}) {
+ gap: #{$value};
+ }
+ }
+ }
+}
+
+.accordion {
+ display: flex;
+ align-items: flex-start;
+ flex-direction: column;
+ justify-content: center;
+}
+
+// moved container bottom actions footer for large, medium devices
+.container-bottom {
+ .actions-bottom {
+ display: flex;
+ align-items: flex-start;
+ justify-content: center;
+ flex-direction: column;
+ gap: 15px;
+
+ width: 100%;
+ height: 100%;
+ padding: 15px 0;
+
+ @media only screen and (min-width: 1025px) {
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ gap: 0;
+
+ width: function.fluid(1080px, 1280px);
+ margin: 0 auto;
+ }
+
+ @media only screen and (min-width: 2500px) {
+ width: function.fluid(2299.68px, 2500px);
+ }
+ }
+}
+
+.lists {
+ width: 100%;
+ display: flex;
+ align-items: stretch;
+ flex-direction: column;
+ gap: 12px;
+
+ .content {
+ ul {
+ display: flex;
+ align-items: flex-start;
+ flex-direction: column;
+ gap: 12px;
+ }
+
+ li,
+ a {
+ font-weight: 400;
+ font-size: var(--txt-xs);
+
+ color: var(--clr-gray-800);
+ transition: color 200ms ease;
+
+ &:hover {
+ color: var(--clr-primary-blue-500);
+ }
+ }
+
+ li:last-child {
+ a {
+ text-decoration: underline;
+ }
+ }
+ }
+
+ @media only screen and (min-width: 1025px) {
+ flex-direction: row;
+ justify-content: space-between;
+
+ width: function.fluid(707px, 1080px);
+
+ & > li {
+ width: function.fluid(155px, 707px);
+ }
+
+ .content {
+ height: auto;
+ overflow: unset;
+ transform: translate(0, 0);
+ }
+ }
+
+ @media only screen and (min-width: 2500px) {
+ width: function.fluid(1531px, 2500px);
+
+ & > li {
+ width: function.fluid(315px, 1531px);
+ }
+ }
+}
+
+.list-header {
+ @media only screen and (min-width: 1025px) {
+ margin-bottom: 12px;
+
+ i {
+ display: none;
+ }
+ }
+
+ h4 {
+ font-weight: 500;
+ font-size: var(--txt-normal);
+ text-transform: uppercase;
+
+ color: var(--clr-gray-800);
+ }
+}
+
+.payments {
+ display: flex;
+ align-items: center;
+
+ .divider {
+ height: 20.36px;
+ border-left: 1px solid var(--clr-gray-400);
+
+ @media only screen and (min-width: 1025px) {
+ height: 24px;
+ }
+ }
+
+ @each $index,
+ $value
+ in(
+ '1': 11.33px,
+ '2': 11.22px,
+ '3': 11.22px,
+ '4': 11.44px,
+ '5': 11.22px,
+ '6': 11.33px,
+ '7': 10.33px
+ )
+ {
+ li:nth-child(#{$index}) {
+ margin-right: #{$value};
+ }
+ }
+
+ li:last-child {
+ margin-left: 10.49px;
+ }
+}
+
+.social {
+ & > a {
+ display: none;
+
+ @media only screen and (min-width: 1025px) {
+ display: block;
+ font-size: var(--txt-normal);
+
+ color: var(--clr-gray-800);
+
+ &:hover {
+ color: var(--clr-primary-blue-500);
+ }
+ }
+ }
+
+ @media only screen and (min-width: 1025px) {
+ width: function.fluid(215px, 1080px);
+ }
+
+ @media only screen and (min-width: 2500px) {
+ width: function.fluid(390px, 2299.68px);
+ }
+}
+
+.socials {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+
+ a {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ img {
+ width: 100%;
+ height: 100%;
+
+ @media only screen and (min-width: 2500px) {
+ width: 75px;
+ height: 75px;
+ }
+ }
+ }
+}
+
+// control view components order
+.container-bottom {
+ .phrase {
+ order: 2;
+ }
+
+ .payments {
+ order: 1;
+ }
+
+ .credits {
+ order: 3;
+ }
+
+ @media only screen and (min-width: 1025px) {
+ .phrase,
+ .payments,
+ .credits {
+ order: initial;
+ }
+ }
+}
diff --git a/src/template/Footer/index.tsx b/src/template/Footer/index.tsx
new file mode 100644
index 0000000..16a09ac
--- /dev/null
+++ b/src/template/Footer/index.tsx
@@ -0,0 +1,54 @@
+import { useState } from 'react'
+
+import vtexIcon from '../../assets/brands/svgs/Vtex.svg'
+import m3Icon from '../../assets/brands/svgs/M3.svg'
+
+import { List } from './fragments/Lists'
+import { PaymentsList } from './fragments/Lists/Payment'
+
+import css from './index.module.scss'
+
+export function Footer() {
+ const [accordionCurrentIsOpen, setAccordionCurrentIsOpen] = useState<
+ string | number | ''
+ >('')
+
+ function handleSetCurrentAccordion(customkey: string | number | '') {
+ if (window.innerWidth < 1024) {
+ if (customkey === accordionCurrentIsOpen) {
+ setAccordionCurrentIsOpen('')
+ } else {
+ setAccordionCurrentIsOpen(customkey)
+ }
+ }
+ }
+
+ return (
+
+ )
+}
diff --git a/src/template/Header/index.module.scss b/src/template/Header/index.module.scss
index 7442845..b362409 100644
--- a/src/template/Header/index.module.scss
+++ b/src/template/Header/index.module.scss
@@ -4,6 +4,7 @@
position: sticky;
top: 0;
left: 0;
+ z-index: 1000;
padding: 25px 0;