feat: Criado Header
65
react-academy/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "react-academy",
|
||||
"version": "0.1.0",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "react-academy",
|
||||
"version": "0.1.0",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
@ -17,6 +17,7 @@
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.6.1",
|
||||
"react-scripts": "5.0.1",
|
||||
"typescript": "^4.9.4",
|
||||
"web-vitals": "^2.1.4"
|
||||
@ -3074,6 +3075,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.2.1.tgz",
|
||||
"integrity": "sha512-XiY0IsyHR+DXYS5vBxpoBe/8veTeoRpMHP+vDosLZxL5bnpetzI0igkxkLZS235ldLzyfkxF+2divEwWHP3vMQ==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-babel": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
||||
@ -13941,6 +13950,36 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.6.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.6.1.tgz",
|
||||
"integrity": "sha512-YkvlYRusnI/IN0kDtosUCgxqHeulN5je+ew8W+iA1VvFhf86kA+JEI/X/8NqYcr11hCDDp906S+SGMpBheNeYQ==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.6.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.6.1.tgz",
|
||||
"integrity": "sha512-u+8BKUtelStKbZD5UcY0NY90WOzktrkJJhyhNg7L0APn9t1qJNLowzrM9CHdpB6+rcPt6qQrlkIXsTvhuXP68g==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.2.1",
|
||||
"react-router": "6.6.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-scripts": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||
@ -18833,6 +18872,11 @@
|
||||
"source-map": "^0.7.3"
|
||||
}
|
||||
},
|
||||
"@remix-run/router": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.2.1.tgz",
|
||||
"integrity": "sha512-XiY0IsyHR+DXYS5vBxpoBe/8veTeoRpMHP+vDosLZxL5bnpetzI0igkxkLZS235ldLzyfkxF+2divEwWHP3vMQ=="
|
||||
},
|
||||
"@rollup/plugin-babel": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
||||
@ -26573,6 +26617,23 @@
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
||||
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
|
||||
},
|
||||
"react-router": {
|
||||
"version": "6.6.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.6.1.tgz",
|
||||
"integrity": "sha512-YkvlYRusnI/IN0kDtosUCgxqHeulN5je+ew8W+iA1VvFhf86kA+JEI/X/8NqYcr11hCDDp906S+SGMpBheNeYQ==",
|
||||
"requires": {
|
||||
"@remix-run/router": "1.2.1"
|
||||
}
|
||||
},
|
||||
"react-router-dom": {
|
||||
"version": "6.6.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.6.1.tgz",
|
||||
"integrity": "sha512-u+8BKUtelStKbZD5UcY0NY90WOzktrkJJhyhNg7L0APn9t1qJNLowzrM9CHdpB6+rcPt6qQrlkIXsTvhuXP68g==",
|
||||
"requires": {
|
||||
"@remix-run/router": "1.2.1",
|
||||
"react-router": "6.6.1"
|
||||
}
|
||||
},
|
||||
"react-scripts": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-academy",
|
||||
"version": "0.1.0",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
@ -12,6 +12,7 @@
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.6.1",
|
||||
"react-scripts": "5.0.1",
|
||||
"typescript": "^4.9.4",
|
||||
"web-vitals": "^2.1.4"
|
||||
|
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 9.4 KiB |
@ -1,25 +0,0 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
44
react-academy/src/Components/Header/HeaderDesktop/index.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import React from "react";
|
||||
import "./style.css";
|
||||
import logoM3Desktop from "../ImagesHeader/Logo-M3-Desktop.png"
|
||||
import search from "../ImagesHeader/search.png"
|
||||
import cart from "../ImagesHeader/cart.png"
|
||||
import { NavLink } from "react-router-dom";
|
||||
|
||||
const HeaderDesktop = () =>{
|
||||
return (
|
||||
<section className="header-desktop">
|
||||
<div className="page-header">
|
||||
|
||||
<div className="page-header__container">
|
||||
<a href="/" className="page-header__logo">
|
||||
<img className="page-header__imgLogo" src={logoM3Desktop} alt="Logo M3 academy" />
|
||||
</a>
|
||||
<div className="page-header__input">
|
||||
<input type="text" placeholder="Buscar..." className="page-header__inputSearch" />
|
||||
<button className="page-header__iconSearch">
|
||||
<img className="page-header__imgSearch" src={search} alt="Icone Search Header" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="page-header__links">
|
||||
<NavLink to="/" className="page-header-join">ENTRAR</NavLink>
|
||||
<button className="page-header-iconCart">
|
||||
<img className="page-header__cart" src={cart} alt="Icone Cart Header" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="page-belowHeader">
|
||||
<div className="page-belowHeader__containerBelow">
|
||||
<div className="page-belowHeader__links">
|
||||
<NavLink to="/" className="page-belowHeader-nav">CURSOS</NavLink>
|
||||
<NavLink to="/" className="page-belowHeader-nav">SAIBA MAIS</NavLink>
|
||||
<NavLink to="/" className="page-belowHeader-nav">INSTITUCIONAIS</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
export default HeaderDesktop;
|
96
react-academy/src/Components/Header/HeaderTablets/index.tsx
Normal file
@ -0,0 +1,96 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import logoM3Desktop from "../ImagesHeader/Logo-M3-Desktop.png";
|
||||
import search from "../ImagesHeader/search.png";
|
||||
import cart from "../ImagesHeader/cart.png";
|
||||
import "./style.css";
|
||||
import menu from "../ImagesHeader/menu.png";
|
||||
import closeMenu from "../ImagesHeader/close-menu.png";
|
||||
|
||||
const HeaderTablets = () => {
|
||||
const [Open, setOpen] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const body = document.querySelector("body") as HTMLElement;
|
||||
body.classList.toggle("menu");
|
||||
}, [Open]);
|
||||
|
||||
return (
|
||||
<header className="header-tablets">
|
||||
<div className="page-header">
|
||||
<div className="page-header__container">
|
||||
<div className="page-header__menu">
|
||||
<button
|
||||
className="page-header__btnMenu"
|
||||
onClick={() => setOpen(!Open)}
|
||||
aria-label={`${Open ? "Fechar" : "Abrir"} menu`}
|
||||
type="button"
|
||||
>
|
||||
<img src={menu} alt="Menu tablet" />
|
||||
</button>
|
||||
|
||||
<div
|
||||
className={`menu-tablet ${Open ? "actived" : "disabled"}`}
|
||||
aria-hidden={!Open}
|
||||
>
|
||||
<div className="page-belowHeader__links">
|
||||
<div className="page-header__links">
|
||||
<Link to="/" className="page-header-join">
|
||||
ENTRAR
|
||||
</Link>
|
||||
</div>
|
||||
<Link to="/" className="page-belowHeader-nav cursos nav-cursos">
|
||||
CURSOS
|
||||
</Link>
|
||||
<Link to="/" className="page-belowHeader-nav">
|
||||
SAIBA MAIS
|
||||
</Link>
|
||||
<Link to="/" className="page-belowHeader-nav">
|
||||
INSITUCIONAIS
|
||||
</Link>
|
||||
|
||||
<button
|
||||
className="page-belowHeader__btnClose"
|
||||
type="button"
|
||||
onClick={() => setOpen(false)}
|
||||
>
|
||||
<img src={closeMenu} alt="Fechar Menu" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<a className="page-header__link-logo" href="sobre">
|
||||
<img
|
||||
className="page-header__logo"
|
||||
src={logoM3Desktop}
|
||||
alt="Logo M3 Academy"
|
||||
/>
|
||||
</a>
|
||||
|
||||
<div className="page-header__links">
|
||||
<button className="page-header__iconCart">
|
||||
<img className="page-header__cart" src={cart} alt="" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="page-header__input">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Buscar..."
|
||||
className="page-header__inputSearch"
|
||||
/>
|
||||
<button className="page-header__iconSearch">
|
||||
<img
|
||||
className="page-header__imgSearch"
|
||||
src={search}
|
||||
alt="Icone Search Header"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeaderTablets;
|
98
react-academy/src/Components/Header/HeaderTablets/style.css
Normal file
@ -0,0 +1,98 @@
|
||||
@media screen and (max-width: 1024px) {
|
||||
header .page-header {
|
||||
flex-direction: initial;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
header .page-header__container {
|
||||
flex-direction: column;
|
||||
justify-content: initial;
|
||||
padding: 0 16px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
header .page-header__menu {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
header .page-header__btnMenu {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
header .page-header__iconCart {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
header .page-header__input {
|
||||
width: 100%;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
header .page-belowHeader__links {
|
||||
display: flex;
|
||||
line-height: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
header .page-header-join {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
header .menu-tablet {
|
||||
position: fixed;
|
||||
background-color: var(--color-white);
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
header .actived {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
header .disabled {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
header .page-header__links {
|
||||
background-color: var(--color-black);
|
||||
margin: 0;
|
||||
height: 78px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header .page-belowHeader-nav {
|
||||
padding: 0 0 12px 16px;
|
||||
color: var(--color-gray-200);
|
||||
}
|
||||
|
||||
header .nav-cursos {
|
||||
margin-top: 31px;
|
||||
}
|
||||
|
||||
header .page-belowHeader__btnClose {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
align-self: self-end;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
color: var(--color-white);
|
||||
top: 30px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 2.9 KiB |
BIN
react-academy/src/Components/Header/ImagesHeader/Logo-M3.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
react-academy/src/Components/Header/ImagesHeader/cart.png
Normal file
After Width: | Height: | Size: 732 B |
BIN
react-academy/src/Components/Header/ImagesHeader/close-menu.png
Normal file
After Width: | Height: | Size: 268 B |
BIN
react-academy/src/Components/Header/ImagesHeader/menu.png
Normal file
After Width: | Height: | Size: 217 B |
BIN
react-academy/src/Components/Header/ImagesHeader/search.png
Normal file
After Width: | Height: | Size: 943 B |
22
react-academy/src/Components/Header/index.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React, {useEffect, useState} from "react"
|
||||
import HeaderDesktop from "./HeaderDesktop";
|
||||
import HeaderTablets from "./HeaderTablets";
|
||||
import "./style.css"
|
||||
|
||||
const Header = ()=>{
|
||||
const [width, setWidth] = useState<number>(window.innerWidth);
|
||||
|
||||
const handleWindow = ()=>{
|
||||
setWidth(window.innerWidth);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("resize", handleWindow);
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleWindow);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <header>{width <= 1024 ? <HeaderTablets /> : <HeaderDesktop />}</header>
|
||||
}
|
||||
export default Header;
|
99
react-academy/src/Components/Header/style.css
Normal file
@ -0,0 +1,99 @@
|
||||
.page-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--color-black);
|
||||
}
|
||||
|
||||
.page-header__container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 100px;
|
||||
border-bottom: 1px solid var(--color-gray-200);
|
||||
}
|
||||
|
||||
.page-header__logo,
|
||||
.page-header__imgLogo {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page-header__input {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 264px;
|
||||
}
|
||||
|
||||
.page-header__inputSearch {
|
||||
height: 16px;
|
||||
width: 100%;
|
||||
outline: 0;
|
||||
background-color: var(--color-white);
|
||||
border: 2px solid var(--color-white-100);
|
||||
border-radius: 5px;
|
||||
padding: 8px 10px 8px 16px;
|
||||
}
|
||||
|
||||
.page-header__iconSearch {
|
||||
position: absolute;
|
||||
border: none;
|
||||
outline: 0;
|
||||
background-color: transparent;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.page-header__imgSearch {
|
||||
max-width: 18px;
|
||||
max-height: 18px;
|
||||
}
|
||||
|
||||
.page-header__links {
|
||||
display: flex;
|
||||
margin: 22px 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.page-header-join {
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
color: var(--color-white);
|
||||
text-decoration: none;
|
||||
margin-right: 55px;
|
||||
}
|
||||
|
||||
.page-header-iconCart {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.page-header__cart {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.page-belowHeader {
|
||||
padding: 0 100px;
|
||||
}
|
||||
|
||||
.page-belowHeader__links {
|
||||
padding: 14px 0;
|
||||
}
|
||||
|
||||
.page-belowHeader-nav {
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500px;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
margin-right: 55px;
|
||||
text-decoration: none;
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.page-belowHeader-nav:last-child {
|
||||
margin-right: 0px;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@ -1,13 +1,23 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||
monospace;
|
||||
}
|
||||
|
||||
/*COLORS*/
|
||||
:root {
|
||||
--color-black: #000;
|
||||
|
||||
--color-white: #fff;
|
||||
--color-white-100: #f0f0f0;
|
||||
|
||||
--color-gray-200: #c4c4c4;
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import './global.css';
|
||||
import App from './Pages/Home';
|
||||
|
||||
import Router from "./router";
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
<BrowserRouter>
|
||||
<Router/>
|
||||
</BrowserRouter>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
|
14
react-academy/src/router.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import ReactDOM from "react-dom/client";
|
||||
import { Routes, Route, Navigate } from "react-router-dom";
|
||||
import Header from "./Components/Header";
|
||||
|
||||
export default function Router(){
|
||||
return (
|
||||
<>
|
||||
<Header/>
|
||||
<Routes>
|
||||
<Route></Route>
|
||||
</Routes>
|
||||
</>
|
||||
)
|
||||
}
|