forked from M3-Academy/desafio-react-e-typescript
Merge branch 'feature/modal' into development
This commit is contained in:
commit
3cff37b2ab
@ -1,15 +1,23 @@
|
||||
import React from "react";
|
||||
import React, { useContext } from "react";
|
||||
|
||||
import styles from "./MenuButton.module.scss";
|
||||
|
||||
import menuButton from "../assets/menu-icon.svg";
|
||||
import { ModalContext } from "../../../contexts/ModalContext";
|
||||
|
||||
// const openMenu = () => {};
|
||||
|
||||
const MenuButton = () => {
|
||||
|
||||
const { isOpen, setIsOpen } = useContext(ModalContext);
|
||||
|
||||
return (
|
||||
<button className={styles["open-menu"]}>
|
||||
<>
|
||||
<button className={styles["open-menu"]} onClick={() => setIsOpen(true)}>
|
||||
<img src={menuButton} alt="Ícone de menu hambúrguer" />
|
||||
</button>
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export { MenuButton };
|
||||
export { MenuButton };
|
||||
|
@ -42,6 +42,7 @@
|
||||
right: 12.78%; //46px;
|
||||
top: 8px;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
|
||||
img {
|
||||
height: 18px;
|
||||
|
23
src/components/List/List.tsx
Normal file
23
src/components/List/List.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
interface ListProps {
|
||||
className: string;
|
||||
itemsList: { value: string; name: string }[];
|
||||
}
|
||||
|
||||
const List = (props: ListProps) => {
|
||||
const { className, itemsList } = props;
|
||||
|
||||
return (
|
||||
<ul className={className}>
|
||||
{itemsList.map((item, index) => (
|
||||
<li key={index}>
|
||||
<Link to={item.value}>{item.name}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
export { List };
|
@ -1,15 +1,20 @@
|
||||
import React from "react";
|
||||
import React, { useContext } from "react";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { ModalContext } from "../../contexts/ModalContext";
|
||||
import { AsideMenu } from "../AsideMenu/AsideMenu";
|
||||
import { Footer } from "../Footer/Footer";
|
||||
import { Header } from "../Header/Header";
|
||||
import { Modal } from "../Modal/Modal";
|
||||
import { Breadcrumbs } from "./Breadcrumbs/Breadcrumbs";
|
||||
|
||||
import styles from "./MainLayout.module.scss";
|
||||
|
||||
const MainLayout = () => {
|
||||
const { isOpen, setIsOpen } = useContext(ModalContext);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal isOpen={isOpen} setIsOpen={setIsOpen} />
|
||||
<Header />
|
||||
<main className={styles["main-container"]}>
|
||||
<Breadcrumbs />
|
||||
|
81
src/components/Modal/Modal.module.scss
Normal file
81
src/components/Modal/Modal.module.scss
Normal file
@ -0,0 +1,81 @@
|
||||
.modal-wrapper {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
display: flex;
|
||||
z-index: 5;
|
||||
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: all 0.4s ease-in-out;
|
||||
|
||||
&.opened {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
width: 96.48%;
|
||||
height: 585px;
|
||||
|
||||
background: #ffffff;
|
||||
z-index: 10;
|
||||
|
||||
@media screen and (width <= 480px) {
|
||||
width: 90.4%;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
background: #000000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 31px 16px;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar {
|
||||
padding: 31px 16px;
|
||||
|
||||
.navbar-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
a {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
text-transform: uppercase;
|
||||
color: #c4c4c4;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
background: rgba(69, 69, 69, 0.7);
|
||||
}
|
||||
}
|
49
src/components/Modal/Modal.tsx
Normal file
49
src/components/Modal/Modal.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import React from "react";
|
||||
|
||||
import { LoginButton } from "../Header/LoginButton/LoginButton";
|
||||
import { List } from "../List/List";
|
||||
|
||||
import closeIcon from "./assets/close-icon.svg";
|
||||
|
||||
import styles from "./Modal.module.scss";
|
||||
|
||||
interface ModalProps {
|
||||
isOpen: boolean;
|
||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const navLinks = [
|
||||
{ name: "Cursos", value: "cursos" },
|
||||
{ name: "Saiba Mais", value: "saiba-mais" },
|
||||
{ name: "Institucionais", value: "intitucionais" },
|
||||
];
|
||||
|
||||
const Modal = ({ isOpen, setIsOpen }: ModalProps) => {
|
||||
return (
|
||||
<div
|
||||
className={`${styles["modal-wrapper"]} ${
|
||||
isOpen ? `${styles["opened"]}` : ""
|
||||
}`}
|
||||
>
|
||||
<div className={styles["modal-content"]}>
|
||||
<div className={styles["modal-header"]}>
|
||||
<LoginButton />
|
||||
<img
|
||||
src={closeIcon}
|
||||
alt="Ícone de fechar modal"
|
||||
onClick={() => setIsOpen(false)}
|
||||
/>
|
||||
</div>
|
||||
<nav className={styles["navbar"]}>
|
||||
<List className={styles["navbar-list"]} itemsList={navLinks} />
|
||||
</nav>
|
||||
</div>
|
||||
<div
|
||||
className={styles["modal-overlay"]}
|
||||
onClick={() => setIsOpen(false)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { Modal };
|
4
src/components/Modal/assets/close-icon.svg
Normal file
4
src/components/Modal/assets/close-icon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.2284 1.28215L1.22996 10.9942C0.550673 11.6541 0.568968 12.7044 1.27083 13.3401C1.97268 13.9759 3.09232 13.9564 3.77161 13.2966L13.77 3.58449C14.4493 2.92466 14.431 1.87436 13.7292 1.23858C13.0273 0.602806 11.9077 0.622311 11.2284 1.28215Z" fill="white"/>
|
||||
<path d="M1.65213 3.40819L10.8751 13.7186C11.5082 14.4263 12.6262 14.5239 13.3724 13.9366C14.1185 13.3493 14.2102 12.2995 13.5771 11.5918L4.35414 1.28143C3.72107 0.573715 2.603 0.476092 1.85686 1.06338C1.11072 1.65067 1.01906 2.70048 1.65213 3.40819Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 638 B |
22
src/contexts/ModalContext.tsx
Normal file
22
src/contexts/ModalContext.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { createContext, useState } from 'react';
|
||||
|
||||
interface ModalContextData {
|
||||
isOpen: boolean;
|
||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const ModalContext = createContext({} as ModalContextData);
|
||||
|
||||
export const ModalProvider: React.FC<Props> = ({children}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<ModalContext.Provider value={{isOpen: isOpen, setIsOpen: setIsOpen}}>
|
||||
{children}
|
||||
</ModalContext.Provider>
|
||||
)
|
||||
}
|
@ -4,12 +4,15 @@ import ReactDOM from "react-dom/client";
|
||||
import Institucional from "./pages/Institucional";
|
||||
|
||||
import "./global.scss";
|
||||
import { ModalProvider } from "./contexts/ModalContext";
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById("root") as HTMLElement
|
||||
);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<Institucional />
|
||||
<ModalProvider>
|
||||
<Institucional />
|
||||
</ModalProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user