forked from M3-Academy/desafio-react-e-typescript
refactor/components #15
10
src/components/Atoms/CustomLink/@types/index.d.ts
vendored
Normal file
10
src/components/Atoms/CustomLink/@types/index.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import { AnchorHTMLAttributes, ReactNode } from 'react'
|
||||
import { LinkProps, To } from 'react-router-dom'
|
||||
|
||||
export interface CustomLinkProps
|
||||
extends AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
LinkProps {
|
||||
children: ReactNode | ReactNode[]
|
||||
href?: string
|
||||
to?: To | any
|
||||
}
|
18
src/components/Atoms/CustomLink/index.tsx
Normal file
18
src/components/Atoms/CustomLink/index.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { CustomLinkProps } from './@types'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
export function CustomLink({ children, href, to, ...props }: CustomLinkProps) {
|
||||
return (
|
||||
<>
|
||||
{href ? (
|
||||
<a href={href} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
) : (
|
||||
<Link to={to} {...props}>
|
||||
{children}
|
||||
</Link>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
7
src/components/Atoms/Icon/@types/index.d.ts
vendored
Normal file
7
src/components/Atoms/Icon/@types/index.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { HTMLAttributes } from 'react'
|
||||
|
||||
export interface IconProps extends HTMLAttributes<HTMLImageElement> {
|
||||
src: any
|
||||
alt: string
|
||||
$container?: HTMLAttributes<HTMLSpanElement>
|
||||
}
|
10
src/components/Atoms/Icon/index.tsx
Normal file
10
src/components/Atoms/Icon/index.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
/* eslint-disable jsx-a11y/alt-text */
|
||||
import { IconProps } from './@types'
|
||||
|
||||
export function Icon({ $container, src, alt, ...props }: IconProps) {
|
||||
return (
|
||||
<span {...$container}>
|
||||
<img src={src} alt={alt} {...props} />
|
||||
</span>
|
||||
)
|
||||
}
|
5
src/components/Atoms/Item/@types/index.d.ts
vendored
Normal file
5
src/components/Atoms/Item/@types/index.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { HTMLAttributes, ReactNode } from 'react'
|
||||
|
||||
export interface ItemProps extends HTMLAttributes<HTMLLIElement> {
|
||||
children: ReactNode | ReactNode[]
|
||||
}
|
5
src/components/Atoms/Item/index.tsx
Normal file
5
src/components/Atoms/Item/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { ItemProps } from './@types'
|
||||
|
||||
export function Item({ children, ...props }: ItemProps) {
|
||||
return <li {...props}>{children}</li>
|
||||
}
|
15
src/components/Molecules/ButtonIcon/index.tsx
Normal file
15
src/components/Molecules/ButtonIcon/index.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import { ButtonHTMLAttributes } from 'react'
|
||||
import { Icon } from '../../Atoms/Icon'
|
||||
|
||||
interface ButtonIconProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
src: any
|
||||
alt: string
|
||||
}
|
||||
|
||||
export function ButtonIcon({ src, alt, ...props }: ButtonIconProps) {
|
||||
return (
|
||||
<button {...props}>
|
||||
<Icon className="btn-icon icon" src={src} alt={alt} />
|
||||
</button>
|
||||
)
|
||||
}
|
12
src/components/Molecules/ItemList/@types/index.d.ts
vendored
Normal file
12
src/components/Molecules/ItemList/@types/index.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import { AnchorHTMLAttributes, ReactNode } from 'react'
|
||||
import { To } from 'react-router-dom'
|
||||
import { CustomLinkProps } from '../../Atoms/CustomLink/@types'
|
||||
import { ItemProps } from '../../Atoms/Item/@types'
|
||||
|
||||
export interface ItemListProps
|
||||
extends AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
CustomLinkProps {
|
||||
to?: To
|
||||
children: ReactNode | ReactNode[]
|
||||
$container?: ItemProps
|
||||
}
|
11
src/components/Molecules/ItemList/index.tsx
Normal file
11
src/components/Molecules/ItemList/index.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import { Item } from '../../Atoms/Item'
|
||||
import { CustomLink } from '../../Atoms/CustomLink'
|
||||
import { ItemListProps } from './@types'
|
||||
|
||||
export function ItemList({ $container, children, ...props }: ItemListProps) {
|
||||
return (
|
||||
<Item {...$container}>
|
||||
<CustomLink {...props}>{children}</CustomLink>
|
||||
</Item>
|
||||
)
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { AnchorHTMLAttributes, HTMLAttributes, ReactNode } from 'react'
|
||||
|
||||
interface ItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
||||
children: ReactNode | ReactNode[]
|
||||
$container?: HTMLAttributes<HTMLLIElement>
|
||||
}
|
||||
|
||||
export function Item({ children, $container, ...props }: ItemProps) {
|
||||
return (
|
||||
<li {...$container}>
|
||||
<a {...props}>{children}</a>
|
||||
</li>
|
||||
)
|
||||
}
|
@ -2,7 +2,7 @@ import { useMemo } from 'react'
|
||||
import { Outlet, Route, Routes } from 'react-router-dom'
|
||||
|
||||
import { Header } from '../template/Header'
|
||||
import { Breadcrumb } from '../modules/components/Breadcrumb'
|
||||
import { Breadcrumb } from '../components/Molecules/Breadcrumb'
|
||||
import { Sidebar } from '../template/Sidebar'
|
||||
import { About } from '../pages/Institutional/About'
|
||||
import { Contact } from '../pages/Institutional/Contact'
|
||||
|
2
src/template/Footer/@types/index.d.ts
vendored
2
src/template/Footer/@types/index.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { AccordionProps } from '../../../modules/components/Accordion/@types'
|
||||
import { AccordionProps } from '../../../components/Molecules/Accordion/@types'
|
||||
|
||||
export interface InstitutionalListProps
|
||||
extends Omit<AccordionProps, 'setCurrentAccordion'> {}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ListProps } from '../@types'
|
||||
|
||||
import { AccordionProviderItems } from '../../../modules/components/Accordion/context/Items'
|
||||
import { AccordionProviderItems } from '../../../components/Molecules/Accordion/context/Items'
|
||||
|
||||
import { ContactList } from './__Contact'
|
||||
import { InstitutionalList } from './__Institutional'
|
||||
@ -8,6 +8,8 @@ import { QuestionsList } from './__Question'
|
||||
import { Socials } from './__Socials'
|
||||
|
||||
import css from '../index.module.scss'
|
||||
import { Item } from '../../../components/Atoms/Item'
|
||||
import { CustomLink } from '../../../components/Atoms/CustomLink'
|
||||
|
||||
export function List({
|
||||
accordionCurrentIsOpen,
|
||||
@ -22,20 +24,20 @@ export function List({
|
||||
}}
|
||||
>
|
||||
<ul className={`${css['footer__lists']} ${css['lists']}`}>
|
||||
<li>
|
||||
<Item>
|
||||
<InstitutionalList customKey={'institutional'} />
|
||||
</li>
|
||||
<li>
|
||||
</Item>
|
||||
<Item>
|
||||
<QuestionsList customKey={'question'} />
|
||||
</li>
|
||||
</Item>
|
||||
|
||||
<li>
|
||||
<Item>
|
||||
<ContactList customKey={'contact'} />
|
||||
</li>
|
||||
</Item>
|
||||
</ul>
|
||||
<div className={css['footer__network']}>
|
||||
<Socials />
|
||||
<a href="/">www.loremipsum.com</a>
|
||||
<CustomLink href="/">www.loremipsum.com</CustomLink>
|
||||
</div>
|
||||
</AccordionProviderItems>
|
||||
</>
|
||||
|
@ -8,6 +8,7 @@ import VisaBrandImg from '../../../assets/brands/Visa.png'
|
||||
import VtexPCIImg from '../../../assets/brands/vtex-pci-200.png'
|
||||
|
||||
import styles from '../index.module.scss'
|
||||
import { Item } from '../../../components/Atoms/Item'
|
||||
|
||||
const assetsImg = [
|
||||
MasterCardBrandImg,
|
||||
@ -24,15 +25,15 @@ export function PaymentsList() {
|
||||
<ul className={`${styles['footer__payments']} ${styles['payments']}`}>
|
||||
{assetsImg.map((image, index) => {
|
||||
return (
|
||||
<li className={`${styles['payments__item']}`} key={index}>
|
||||
<Item className={`${styles['payments__item']}`} key={index}>
|
||||
<img className="payments__image" src={image} alt="" />
|
||||
</li>
|
||||
</Item>
|
||||
)
|
||||
})}
|
||||
<div className={`${styles['payments__divider']}`} role={'presentation'} />
|
||||
<li className={`${styles['payments__item']}`}>
|
||||
<Item className={`${styles['payments__item']}`}>
|
||||
<img src={VtexPCIImg} alt="" />
|
||||
</li>
|
||||
</Item>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ContactListProps } from '../@types'
|
||||
|
||||
import { Accordion } from '../../../modules/components/Accordion'
|
||||
import { Item } from '../../../components/Atoms/Item'
|
||||
import { Accordion } from '../../../components/Molecules/Accordion'
|
||||
|
||||
import styles from '../index.module.scss'
|
||||
|
||||
@ -16,10 +17,10 @@ export function ContactList({ customKey }: ContactListProps) {
|
||||
|
||||
<Accordion.Content className={`${styles['lists__content']}`}>
|
||||
<ul className={styles['lists__content-list']}>
|
||||
<li>Atendimento ao Consumidor</li>
|
||||
<li>(11) 4159 9504</li>
|
||||
<li>Atendimento Online</li>
|
||||
<li>(11) 99433-8825</li>
|
||||
<Item>Atendimento ao Consumidor</Item>
|
||||
<Item>(11) 4159 9504</Item>
|
||||
<Item>Atendimento Online</Item>
|
||||
<Item>(11) 99433-8825</Item>
|
||||
</ul>
|
||||
</Accordion.Content>
|
||||
</Accordion>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { InstitutionalListProps } from '../@types'
|
||||
|
||||
import { Accordion } from '../../../modules/components/Accordion'
|
||||
import { Item } from '../../../modules/common/Item'
|
||||
import { Accordion } from '../../../components/Molecules/Accordion'
|
||||
|
||||
import css from '../index.module.scss'
|
||||
import { ItemList } from '../../../components/Molecules/ItemList'
|
||||
|
||||
export function InstitutionalList({ customKey }: InstitutionalListProps) {
|
||||
return (
|
||||
@ -16,18 +16,18 @@ export function InstitutionalList({ customKey }: InstitutionalListProps) {
|
||||
</Accordion.Header>
|
||||
<Accordion.Content className={`${css['lists__content']}`}>
|
||||
<ul className={css['lists__content-list']}>
|
||||
<Item $container={{ className: '' }} href="/">
|
||||
<ItemList $container={{ className: '' }} href="/">
|
||||
Quem somos nós
|
||||
</Item>
|
||||
<Item $container={{ className: '' }} href="/">
|
||||
</ItemList>
|
||||
<ItemList $container={{ className: '' }} href="/">
|
||||
Política de Privacidade
|
||||
</Item>
|
||||
<Item $container={{ className: '' }} href="/">
|
||||
</ItemList>
|
||||
<ItemList $container={{ className: '' }} href="/">
|
||||
Segurança
|
||||
</Item>
|
||||
<Item $container={{ className: '' }} href="/">
|
||||
</ItemList>
|
||||
<ItemList $container={{ className: '' }} href="/">
|
||||
Seja um Revendedor
|
||||
</Item>
|
||||
</ItemList>
|
||||
</ul>
|
||||
</Accordion.Content>
|
||||
</Accordion>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { QuestionsListProps } from '../@types'
|
||||
|
||||
import { Accordion } from '../../../modules/components/Accordion'
|
||||
import { Item } from '../../../modules/common/Item'
|
||||
import { Accordion } from '../../../components/Molecules/Accordion'
|
||||
import { ItemList } from '../../../components/Molecules/ItemList'
|
||||
|
||||
import css from '../index.module.scss'
|
||||
|
||||
@ -16,18 +16,18 @@ export function QuestionsList({ customKey }: QuestionsListProps) {
|
||||
</Accordion.Header>
|
||||
<Accordion.Content className={`${css['lists__content']}`}>
|
||||
<ul className={`${css['lists__content-list']}`}>
|
||||
<Item $container={{ className: '' }} href="/">
|
||||
<ItemList $container={{ className: '' }} href="/">
|
||||
Entrega
|
||||
</Item>
|
||||
<Item $container={{ className: '' }} href="/">
|
||||
</ItemList>
|
||||
<ItemList $container={{ className: '' }} href="/">
|
||||
Pagamento
|
||||
</Item>
|
||||
<Item $container={{ className: '' }} href="/">
|
||||
</ItemList>
|
||||
<ItemList $container={{ className: '' }} href="/">
|
||||
Trocas e Devoluções
|
||||
</Item>
|
||||
<Item $container={{ className: '' }} href="/">
|
||||
</ItemList>
|
||||
<ItemList $container={{ className: '' }} href="/">
|
||||
Dúvidas Frequentes
|
||||
</Item>
|
||||
</ItemList>
|
||||
</ul>
|
||||
</Accordion.Content>
|
||||
</Accordion>
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { ItemList } from '../../../components/Molecules/ItemList'
|
||||
|
||||
import facebookIcon from '../../../assets/icons/facebook.svg'
|
||||
import instagramIcon from '../../../assets/icons/instagram.svg'
|
||||
import linkedinIcon from '../../../assets/icons/linkedin.svg'
|
||||
@ -9,31 +11,21 @@ import css from '../index.module.scss'
|
||||
export function Socials() {
|
||||
return (
|
||||
<ul className={css.socials}>
|
||||
<li>
|
||||
<a href="/">
|
||||
<img src={facebookIcon} alt="" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/">
|
||||
<img src={instagramIcon} alt="" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/">
|
||||
<img src={twitterIcon} alt="" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/">
|
||||
<img src={youtubeIcon} alt="" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/">
|
||||
<img src={linkedinIcon} alt="" />
|
||||
</a>
|
||||
</li>
|
||||
<ItemList href="/">
|
||||
<img src={facebookIcon} alt="" />
|
||||
</ItemList>
|
||||
<ItemList href="/">
|
||||
<img src={instagramIcon} alt="" />
|
||||
</ItemList>
|
||||
<ItemList href="/">
|
||||
<img src={twitterIcon} alt="" />
|
||||
</ItemList>
|
||||
<ItemList href="/">
|
||||
<img src={youtubeIcon} alt="" />
|
||||
</ItemList>
|
||||
<ItemList href="/">
|
||||
<img src={linkedinIcon} alt="" />
|
||||
</ItemList>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
11
src/template/Header/containers/@types/index.d.ts
vendored
11
src/template/Header/containers/@types/index.d.ts
vendored
@ -1,3 +1,5 @@
|
||||
import { HTMLAttributes, ButtonHTMLAttributes } from 'react'
|
||||
|
||||
export type ISearchProps = HTMLAttributes<HTMLDivElement>
|
||||
|
||||
export interface ITopProps {
|
||||
@ -5,6 +7,13 @@ export interface ITopProps {
|
||||
}
|
||||
|
||||
export interface IBottomProps {
|
||||
isMenuOpen: boolean
|
||||
handleClickClose: () => void
|
||||
isMenuOpen: boolean
|
||||
}
|
||||
|
||||
export interface ActionsProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
$container?: HTMLAttributes<HTMLDivElement>
|
||||
handleClick: () => any
|
||||
src: any
|
||||
alt: string
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { IBottomProps } from './@types'
|
||||
|
||||
import { ItemList } from '../../../components/Molecules/ItemList'
|
||||
import { Actions } from './__Actions'
|
||||
|
||||
import closeIcon from '../../../assets/icons/x.svg'
|
||||
|
||||
import styles from '../index.module.scss'
|
||||
@ -21,23 +24,20 @@ export function Bottom({ isMenuOpen, handleClickClose }: IBottomProps) {
|
||||
}`}
|
||||
>
|
||||
<div className={styles['menu__container']}>
|
||||
<div className={styles['actions__bottom']}>
|
||||
<a href="/">Entrar</a>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleClickClose}
|
||||
className={styles.close}
|
||||
>
|
||||
<img src={closeIcon} alt="ícone do botão para fechar o menu" />
|
||||
</button>
|
||||
</div>
|
||||
<Actions
|
||||
handleClick={handleClickClose}
|
||||
$container={{ className: styles['actions__bottom'] }}
|
||||
className={styles['button-close']}
|
||||
alt="ícone do botão para fechar o menu"
|
||||
src={closeIcon}
|
||||
/>
|
||||
|
||||
<ul className={styles['menu__list']}>
|
||||
{['Cursos', 'Saiba Mais', 'Institucionais'].map((item, index) => {
|
||||
return (
|
||||
<li key={'header-bottom-list-' + index}>
|
||||
<a href="/">{item}</a>
|
||||
</li>
|
||||
<ItemList href="/" key={'header-bottom-list-' + index}>
|
||||
{item}
|
||||
</ItemList>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
|
@ -2,6 +2,8 @@ import { useState } from 'react'
|
||||
|
||||
import { ISearchProps } from './@types'
|
||||
|
||||
import { ButtonIcon } from '../../../components/Molecules/ButtonIcon'
|
||||
|
||||
import searchIcon from '../../../assets/icons/search.svg'
|
||||
|
||||
export function Search({ ...props }: ISearchProps) {
|
||||
@ -20,9 +22,12 @@ export function Search({ ...props }: ISearchProps) {
|
||||
value={searchData}
|
||||
onChange={handleChangeValue}
|
||||
/>
|
||||
<button type="button" onClick={() => setSearchData('')}>
|
||||
<img src={searchIcon} alt="Search icon" />
|
||||
</button>
|
||||
<ButtonIcon
|
||||
type="button"
|
||||
onClick={() => setSearchData('')}
|
||||
src={searchIcon}
|
||||
alt="Search Icon"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { ITopProps } from './@types'
|
||||
|
||||
import { ButtonIcon } from '../../../components/Molecules/ButtonIcon'
|
||||
import { Actions } from './__Actions'
|
||||
import { Search } from './_Search'
|
||||
|
||||
import cartIcon from '../../../assets/icons/minicart.svg'
|
||||
@ -12,13 +14,13 @@ import styles from '../index.module.scss'
|
||||
export function Top({ handleClickOpen }: ITopProps) {
|
||||
return (
|
||||
<div className={`${styles['l-header__top']}`}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleClickOpen}
|
||||
<ButtonIcon
|
||||
className={styles['button-open']}
|
||||
>
|
||||
<img src={openIcon} alt="ícone do botão para abrir o menu" />
|
||||
</button>
|
||||
onClick={handleClickOpen}
|
||||
type="button"
|
||||
src={openIcon}
|
||||
alt="ícone do botão para abrir o menu"
|
||||
/>
|
||||
|
||||
<a className="top__logo" href="/">
|
||||
<picture>
|
||||
@ -29,13 +31,12 @@ export function Top({ handleClickOpen }: ITopProps) {
|
||||
|
||||
<Search className={`${styles['search']} ${styles['search--top']}`} />
|
||||
|
||||
<div className={styles['actions__top']}>
|
||||
<a href="/">Entrar</a>
|
||||
|
||||
<button type="button">
|
||||
<img src={cartIcon} alt="ícone de carrinho" />
|
||||
</button>
|
||||
</div>
|
||||
<Actions
|
||||
$container={{ className: styles['actions__top'] }}
|
||||
handleClick={() => console.log('Funcionando')}
|
||||
src={cartIcon}
|
||||
alt="ícone de carrinho"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
21
src/template/Header/containers/__Actions.tsx
Normal file
21
src/template/Header/containers/__Actions.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import { ActionsProps } from './@types'
|
||||
import { CustomLink } from '../../../components/Atoms/CustomLink'
|
||||
import { ButtonIcon } from '../../../components/Molecules/ButtonIcon'
|
||||
|
||||
export function Actions({
|
||||
handleClick,
|
||||
$container,
|
||||
src,
|
||||
alt,
|
||||
...props
|
||||
}: ActionsProps) {
|
||||
return (
|
||||
<div {...$container}>
|
||||
<CustomLink href="/">Entrar</CustomLink>
|
||||
{/* prettier-ignore */}
|
||||
<ButtonIcon onClick={handleClick} type="button" src={src}
|
||||
alt={alt} {...props}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
import { ItemList } from '../../components/Molecules/ItemList'
|
||||
|
||||
import styles from './index.module.scss'
|
||||
|
||||
@ -20,14 +22,13 @@ export function Sidebar() {
|
||||
<ul className={styles['sidebar__list']}>
|
||||
{paths.map(({ path, name }) => {
|
||||
return (
|
||||
<li key={name.replace(' ', '-').toLowerCase() + '-sidebar'}>
|
||||
<Link
|
||||
to={path}
|
||||
className={pathname === path ? styles['active'] : ''}
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
</li>
|
||||
<ItemList
|
||||
className={pathname === path ? styles['active'] : ''}
|
||||
key={name.replace(' ', '-').toLowerCase() + '-sidebar'}
|
||||
to={path}
|
||||
>
|
||||
{name}
|
||||
</ItemList>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
|
Loading…
Reference in New Issue
Block a user