├── public ├── _redirects ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── manifest.json ├── index.html └── assets │ └── images │ ├── logo.svg │ └── javascript.svg ├── src ├── templates │ ├── Home │ │ ├── styles.js │ │ └── index.jsx │ ├── Loading │ │ ├── index.jsx │ │ └── styles.js │ ├── Base │ │ ├── styles.js │ │ ├── stories.jsx │ │ ├── mock.jsx │ │ └── index.jsx │ └── PageNotFound │ │ └── index.jsx ├── config │ └── index.js ├── components │ ├── TextComponent │ │ ├── styles.js │ │ ├── index.jsx │ │ ├── stories.jsx │ │ └── TextComponent.test.jsx │ ├── SectionContainer │ │ ├── styles.js │ │ ├── index.jsx │ │ ├── __snapshots__ │ │ │ └── SectionContainer.test.jsx.snap │ │ ├── SectionContainer.test.jsx │ │ └── stories.jsx │ ├── LogoLink │ │ ├── styles.js │ │ ├── stories.jsx │ │ ├── index.jsx │ │ ├── __snapshots__ │ │ │ └── LogoLink.test.jsx.snap │ │ └── LogoLink.test.jsx │ ├── GridText │ │ ├── stories.jsx │ │ ├── GridText.test.jsx │ │ ├── mock.js │ │ ├── styles.js │ │ ├── index.jsx │ │ └── __snapshots__ │ │ │ └── GridText.test.jsx.snap │ ├── GridTwoColumns │ │ ├── mock.js │ │ ├── stories.jsx │ │ ├── GridTwoColumns.test.jsx │ │ ├── styles.js │ │ ├── index.jsx │ │ └── __snapshots__ │ │ │ └── GridTwoColumns.test.jsx.snap │ ├── NavLinks │ │ ├── styles.js │ │ ├── stories.jsx │ │ ├── index.jsx │ │ ├── mock.js │ │ ├── NavLinks.test.jsx │ │ └── __snapshots__ │ │ │ └── NavLinks.test.jsx.snap │ ├── GridImage │ │ ├── stories.jsx │ │ ├── GridImage.test.jsx │ │ ├── mock.js │ │ ├── styles.js │ │ ├── index.jsx │ │ └── __snapshots__ │ │ │ └── GridImage.test.jsx.snap │ ├── GridContent │ │ ├── stories.jsx │ │ ├── styles.js │ │ ├── GridContent.test.jsx │ │ ├── index.jsx │ │ ├── mock.js │ │ └── __snapshots__ │ │ │ └── GridContent.test.jsx.snap │ ├── GoTop │ │ ├── index.jsx │ │ ├── styles.js │ │ ├── GoTop.test.jsx │ │ └── stories.jsx │ ├── Footer │ │ ├── stories.jsx │ │ ├── index.jsx │ │ ├── styles.js │ │ └── Footer.test.jsx │ ├── MenuLink │ │ ├── stories.jsx │ │ ├── index.jsx │ │ ├── styles.js │ │ └── MenuLink.test.jsx │ ├── Menu │ │ ├── stories.jsx │ │ ├── index.jsx │ │ ├── Menu.test.jsx │ │ ├── styles.js │ │ └── __snapshots__ │ │ │ └── Menu.test.jsx.snap │ ├── SectionBackground │ │ ├── styles.js │ │ ├── index.jsx │ │ ├── stories.jsx │ │ ├── SectionBackground.test.jsx │ │ └── __snapshots__ │ │ │ └── SectionBackground.test.jsx.snap │ └── Heading │ │ ├── stories.jsx │ │ ├── index.jsx │ │ ├── styles.js │ │ └── Heading.test.jsx ├── styles │ ├── render-theme.js │ ├── theme.js │ └── global-styles.js ├── setupTests.js ├── api │ ├── map-data.js │ ├── map-data.test.js │ ├── map-menu.js │ ├── map-menu.test.js │ ├── map-sections.js │ ├── map-sections.test.js │ └── dados.json └── index.jsx ├── .prettierrc.js ├── .editorconfig ├── .storybook ├── main.js └── preview.js ├── .gitignore ├── .eslintrc.js ├── package.json └── README.md /public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 2 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luizomf/curso-reactjs-nextjs-project-3/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luizomf/curso-reactjs-nextjs-project-3/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luizomf/curso-reactjs-nextjs-project-3/HEAD/public/logo512.png -------------------------------------------------------------------------------- /src/templates/Home/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const Wrapper = styled.div``; 4 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | trailingComma: 'all', 4 | singleQuote: true, 5 | printWidth: 80, 6 | tabWidth: 2 7 | } -------------------------------------------------------------------------------- /src/templates/Loading/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import * as Styled from './styles'; 3 | 4 | export const Loading = () => { 5 | return ; 6 | }; 7 | -------------------------------------------------------------------------------- /src/config/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | url: 'https://strapi-landing-pages-project-2.herokuapp.com/pages/?slug=', 3 | siteName: 'Otávio Miranda', 4 | defaultSlug: 'landing-page', 5 | }; 6 | -------------------------------------------------------------------------------- /src/components/TextComponent/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const Container = styled.div` 4 | ${({ theme }) => css` 5 | font-size: ${theme.font.sizes.medium}; 6 | `} 7 | `; 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true -------------------------------------------------------------------------------- /src/templates/Base/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const Container = styled.div` 4 | ${({ theme }) => css` 5 | padding-top: 5.4rem; 6 | 7 | @media ${theme.media.lteMedium} { 8 | padding-top: 0; 9 | } 10 | `} 11 | `; 12 | -------------------------------------------------------------------------------- /src/styles/render-theme.js: -------------------------------------------------------------------------------- 1 | import { render } from '@testing-library/react'; 2 | import { ThemeProvider } from 'styled-components'; 3 | import { theme } from './theme'; 4 | 5 | export const renderTheme = (children) => { 6 | return render({children}); 7 | }; 8 | -------------------------------------------------------------------------------- /src/components/SectionContainer/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const Container = styled.div` 4 | ${({ theme }) => css` 5 | max-width: 120rem; 6 | margin: 0 auto; 7 | padding: ${theme.spacings.large}; 8 | width: 100%; 9 | `} 10 | `; 11 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | import 'jest-styled-components'; 7 | -------------------------------------------------------------------------------- /src/components/SectionContainer/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import * as Styled from './styles'; 3 | 4 | export const SectionContainer = ({ children }) => { 5 | return {children}; 6 | }; 7 | 8 | SectionContainer.propTypes = { 9 | children: P.node.isRequired, 10 | }; 11 | -------------------------------------------------------------------------------- /src/components/TextComponent/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import * as Styled from './styles'; 3 | 4 | export const TextComponent = ({ children }) => { 5 | return ; 6 | }; 7 | 8 | TextComponent.propTypes = { 9 | children: P.node.isRequired, 10 | }; 11 | -------------------------------------------------------------------------------- /src/components/LogoLink/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const Container = styled.a` 4 | ${({ theme }) => css` 5 | display: flex; 6 | align-items: center; 7 | text-decoration: none; 8 | color: inherit; 9 | 10 | > img { 11 | height: 3rem; 12 | } 13 | `} 14 | `; 15 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "stories": [ 3 | "../src/**/*.stories.mdx", 4 | "../src/**/*.stories.@(js|jsx|ts|tsx)", 5 | "../src/**/stories.@(js|jsx|ts|tsx)", 6 | ], 7 | "addons": [ 8 | "@storybook/addon-links", 9 | "@storybook/addon-essentials", 10 | "@storybook/preset-create-react-app" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /src/components/GridText/stories.jsx: -------------------------------------------------------------------------------- 1 | import { GridText } from '.'; 2 | 3 | import mock from './mock'; 4 | 5 | export default { 6 | title: 'GridText', 7 | component: GridText, 8 | args: mock, 9 | }; 10 | 11 | export const Template = (args) => { 12 | return ( 13 |
14 | 15 |
16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /src/components/GridTwoColumns/mock.js: -------------------------------------------------------------------------------- 1 | export default { 2 | title: 'Grid two columns', 3 | text: `Lorem ipsum dolor sit amet consectetur adipisicing elit. Distinctio magnam culpa eveniet doloribus harum? Ipsam, a necessitatibus? Sequi sunt accusantium quod, animi iure a, aliquid dolor ea vel magni dolore?`, 4 | srcImg: 'assets/images/javascript.svg', 5 | }; 6 | -------------------------------------------------------------------------------- /src/components/NavLinks/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const Container = styled.nav` 4 | ${({ theme }) => css` 5 | display: flex; 6 | flex-flow: row wrap; 7 | 8 | @media ${theme.media.lteMedium} { 9 | flex-flow: column wrap; 10 | align-content: center; 11 | } 12 | `} 13 | `; 14 | -------------------------------------------------------------------------------- /src/components/GridImage/stories.jsx: -------------------------------------------------------------------------------- 1 | import { GridImage } from '.'; 2 | 3 | import mock from './mock'; 4 | 5 | export default { 6 | title: 'GridImage', 7 | component: GridImage, 8 | args: mock, 9 | }; 10 | 11 | export const Template = (args) => { 12 | return ( 13 |
14 | 15 |
16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /src/components/GridContent/stories.jsx: -------------------------------------------------------------------------------- 1 | import { GridContent } from '.'; 2 | 3 | import mock from './mock'; 4 | 5 | export default { 6 | title: 'GridContent', 7 | component: GridContent, 8 | args: mock, 9 | }; 10 | 11 | export const Template = (args) => { 12 | return ( 13 |
14 | 15 |
16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /src/templates/PageNotFound/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import { GridContent } from '../../components/GridContent'; 3 | 4 | export const PageNotFound = () => { 5 | return ( 6 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /src/components/GridContent/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const Container = styled.div` 4 | ${({ theme }) => css` 5 | text-align: center; 6 | max-width: 58rem; 7 | margin: 0 auto; 8 | `} 9 | `; 10 | 11 | export const Html = styled.div` 12 | ${({ theme }) => css` 13 | margin: ${theme.spacings.xhuge} 0; 14 | `} 15 | `; 16 | -------------------------------------------------------------------------------- /src/components/GoTop/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import * as Styled from './styles'; 3 | import { KeyboardArrowUp } from '@styled-icons/material-outlined/KeyboardArrowUp'; 4 | 5 | export const GoTop = () => { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /src/components/Footer/stories.jsx: -------------------------------------------------------------------------------- 1 | import { Footer } from '.'; 2 | 3 | export default { 4 | title: 'Footer', 5 | component: Footer, 6 | args: { 7 | footerHtml: `

Feito com ❤ por Otávio Miranda

`, 8 | }, 9 | }; 10 | 11 | export const Template = (args) => { 12 | return ( 13 |
14 |
15 |
16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /src/templates/Base/stories.jsx: -------------------------------------------------------------------------------- 1 | import { Base } from '.'; 2 | 3 | import mock, { mockBase } from './mock'; 4 | import { GridText } from '../../components/GridText'; 5 | 6 | export default { 7 | title: 'Templates/Base', 8 | component: Base, 9 | args: mockBase, 10 | }; 11 | 12 | export const Template = (args) => { 13 | return ( 14 |
15 | 16 |
17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/components/NavLinks/stories.jsx: -------------------------------------------------------------------------------- 1 | import { NavLinks } from '.'; 2 | import links from './mock'; 3 | 4 | export default { 5 | title: 'NavLinks', 6 | component: NavLinks, 7 | args: { 8 | links: links, 9 | }, 10 | argTypes: { 11 | links: { type: '' }, 12 | }, 13 | }; 14 | 15 | export const Template = (args) => { 16 | return ( 17 |
18 | 19 |
20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /src/components/SectionContainer/__snapshots__/SectionContainer.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should render content 1`] = ` 4 | .c0 { 5 | max-width: 120rem; 6 | margin: 0 auto; 7 | padding: 3.2rem; 8 | width: 100%; 9 | } 10 | 11 |
12 |
15 |

16 | Children 17 |

18 |
19 |
20 | `; 21 | -------------------------------------------------------------------------------- /src/components/GridTwoColumns/stories.jsx: -------------------------------------------------------------------------------- 1 | import { GridTwoColumns } from '.'; 2 | 3 | import mock from './mock'; 4 | 5 | export default { 6 | title: 'GridTwoColumns', 7 | component: GridTwoColumns, 8 | args: mock, 9 | argTypes: { 10 | children: { type: 'string' }, 11 | }, 12 | }; 13 | 14 | export const Template = (args) => { 15 | return ( 16 |
17 | 18 |
19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/GoTop/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const Container = styled.a` 4 | ${({ theme }) => css` 5 | position: fixed; 6 | background: ${theme.colors.primaryColor}; 7 | color: ${theme.colors.white}; 8 | display: flex; 9 | align-items: center; 10 | justify-content: center; 11 | width: 4rem; 12 | height: 4rem; 13 | bottom: 2rem; 14 | right: 2rem; 15 | z-index: 6; 16 | `} 17 | `; 18 | -------------------------------------------------------------------------------- /src/components/GridTwoColumns/GridTwoColumns.test.jsx: -------------------------------------------------------------------------------- 1 | import { screen } from '@testing-library/react'; 2 | import { renderTheme } from '../../styles/render-theme'; 3 | import { GridTwoColumns } from '.'; 4 | 5 | import mock from './mock'; 6 | 7 | describe('', () => { 8 | it('should render two column grid', () => { 9 | const { container } = renderTheme(); 10 | expect(container).toMatchSnapshot(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/components/MenuLink/stories.jsx: -------------------------------------------------------------------------------- 1 | import { MenuLink } from '.'; 2 | 3 | export default { 4 | title: 'MenuLink', 5 | component: MenuLink, 6 | args: { 7 | children: 'MenuLink', 8 | link: 'https://www.google.com.br/', 9 | }, 10 | argTypes: { 11 | children: { type: 'string' }, 12 | }, 13 | }; 14 | 15 | export const Template = (args) => { 16 | return ( 17 |
18 | 19 |
20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /src/components/Menu/stories.jsx: -------------------------------------------------------------------------------- 1 | import { Menu } from '.'; 2 | 3 | import linksMock from '../NavLinks/mock'; 4 | 5 | export default { 6 | title: 'Menu', 7 | component: Menu, 8 | args: { 9 | links: linksMock, 10 | logoData: { 11 | text: 'Logo', 12 | link: '#target', 13 | srcImg: '', 14 | }, 15 | }, 16 | }; 17 | 18 | export const Template = (args) => { 19 | return ( 20 |
21 | 22 |
23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /src/components/Footer/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import * as Styled from './styles'; 3 | import { TextComponent } from '../TextComponent'; 4 | import { SectionContainer } from '../SectionContainer'; 5 | 6 | export const Footer = ({ footerHtml }) => { 7 | return ( 8 | 9 | 10 | {footerHtml} 11 | 12 | 13 | ); 14 | }; 15 | 16 | Footer.propTypes = { 17 | footerHtml: P.string.isRequired, 18 | }; 19 | -------------------------------------------------------------------------------- /src/components/MenuLink/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import { Link } from 'react-router-dom'; 3 | import * as Styled from './styles'; 4 | 5 | export const MenuLink = ({ children, link, newTab = false }) => { 6 | const target = newTab ? '_blank' : '_self'; 7 | 8 | return ( 9 | 10 | {children} 11 | 12 | ); 13 | }; 14 | 15 | MenuLink.propTypes = { 16 | children: P.node.isRequired, 17 | link: P.string.isRequired, 18 | newTab: P.bool, 19 | }; 20 | -------------------------------------------------------------------------------- /src/api/map-data.js: -------------------------------------------------------------------------------- 1 | import { mapMenu } from './map-menu'; 2 | import { mapSections } from './map-sections'; 3 | 4 | export const mapData = (pagesData = [{}]) => { 5 | return pagesData.map((data) => { 6 | const { 7 | footer_text: footerHtml = '', 8 | slug = '', 9 | title = '', 10 | sections = [], 11 | menu = {}, 12 | } = data; 13 | 14 | return { 15 | footerHtml, 16 | slug, 17 | title, 18 | sections: mapSections(sections), 19 | menu: mapMenu(menu), 20 | }; 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /src/components/SectionContainer/SectionContainer.test.jsx: -------------------------------------------------------------------------------- 1 | import { screen } from '@testing-library/react'; 2 | import { renderTheme } from '../../styles/render-theme'; 3 | import { SectionContainer } from '.'; 4 | 5 | describe('', () => { 6 | it('should render content', () => { 7 | const { container } = renderTheme( 8 | 9 |

Children

10 |
, 11 | ); 12 | expect(screen.getByRole('heading')).toBeInTheDocument(); 13 | expect(container).toMatchSnapshot(); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /src/components/SectionBackground/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | const containerBackgroundActivate = (theme) => css` 4 | background: ${theme.colors.primaryColor}; 5 | color: ${theme.colors.white}; 6 | `; 7 | 8 | export const Container = styled.div` 9 | ${({ theme, background }) => css` 10 | background: ${theme.colors.white}; 11 | color: ${theme.colors.primaryColor}; 12 | ${background && containerBackgroundActivate(theme)}; 13 | min-height: 100vh; 14 | display: flex; 15 | align-items: center; 16 | `} 17 | `; 18 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/components/SectionBackground/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import { SectionContainer } from '../SectionContainer'; 3 | import * as Styled from './styles'; 4 | 5 | export const SectionBackground = ({ 6 | children, 7 | background = false, 8 | sectionId = '', 9 | }) => { 10 | return ( 11 | 12 | {children} 13 | 14 | ); 15 | }; 16 | 17 | SectionBackground.propTypes = { 18 | children: P.node.isRequired, 19 | background: P.bool, 20 | sectionId: P.string, 21 | }; 22 | -------------------------------------------------------------------------------- /src/components/LogoLink/stories.jsx: -------------------------------------------------------------------------------- 1 | import { LogoLink } from '.'; 2 | 3 | export default { 4 | title: 'LogoLink', 5 | component: LogoLink, 6 | args: { 7 | text: 'LogoLink', 8 | srcImg: 'assets/images/logo.svg', 9 | link: 'http://localhost', 10 | }, 11 | }; 12 | 13 | export const ImageOnly = (args) => { 14 | return ( 15 |
16 | 17 |
18 | ); 19 | }; 20 | 21 | export const TextOnly = (args) => { 22 | return ( 23 |
24 | 25 |
26 | ); 27 | }; 28 | 29 | TextOnly.args = { 30 | srcImg: '', 31 | }; 32 | -------------------------------------------------------------------------------- /src/components/NavLinks/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import * as Styled from './styles'; 3 | import { MenuLink } from '../MenuLink'; 4 | 5 | export const NavLinks = ({ links = [] }) => { 6 | return ( 7 | 8 | {links.map((link) => ( 9 | 10 | ))} 11 | 12 | ); 13 | }; 14 | 15 | NavLinks.propTypes = { 16 | links: P.arrayOf( 17 | P.shape({ 18 | children: P.string.isRequired, 19 | link: P.string.isRequired, 20 | newTab: P.bool, 21 | }), 22 | ), 23 | }; 24 | -------------------------------------------------------------------------------- /src/components/LogoLink/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import * as Styled from './styles'; 3 | import { Heading } from '../Heading'; 4 | import { Link } from 'react-router-dom'; 5 | 6 | export const LogoLink = ({ text, srcImg = '', link }) => { 7 | return ( 8 | 9 | 10 | {!!srcImg && {text}} 11 | {!srcImg && text} 12 | 13 | 14 | ); 15 | }; 16 | 17 | LogoLink.propTypes = { 18 | text: P.string.isRequired, 19 | srcImg: P.string, 20 | link: P.string.isRequired, 21 | }; 22 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | jest: true, 6 | }, 7 | extends: [ 8 | 'eslint:recommended', 9 | 'plugin:react/recommended', 10 | 'plugin:react-hooks/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | parserOptions: { 14 | ecmaFeatures: { 15 | jsx: true, 16 | }, 17 | ecmaVersion: 12, 18 | sourceType: 'module', 19 | }, 20 | plugins: ['react'], 21 | settings: { 22 | react: { 23 | version: 'detect', 24 | }, 25 | }, 26 | rules: { 27 | 'react/react-in-jsx-scope': 'off', 28 | 'no-unused-vars': 'off', 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /src/components/GridText/GridText.test.jsx: -------------------------------------------------------------------------------- 1 | import { screen } from '@testing-library/react'; 2 | import { renderTheme } from '../../styles/render-theme'; 3 | import { GridText } from '.'; 4 | 5 | import mock from './mock'; 6 | 7 | describe('', () => { 8 | it('should render with background', () => { 9 | const { container } = renderTheme(); 10 | expect(container).toMatchSnapshot(); 11 | }); 12 | 13 | it('should render without background', () => { 14 | const { container } = renderTheme( 15 | , 16 | ); 17 | expect(container).toMatchSnapshot(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/components/GridImage/GridImage.test.jsx: -------------------------------------------------------------------------------- 1 | import { screen } from '@testing-library/react'; 2 | import { renderTheme } from '../../styles/render-theme'; 3 | import { GridImage } from '.'; 4 | 5 | import mock from './mock'; 6 | 7 | describe('', () => { 8 | it('should render with background', () => { 9 | const { container } = renderTheme(); 10 | expect(container).toMatchSnapshot(); 11 | }); 12 | 13 | it('should render without background', () => { 14 | const { container } = renderTheme( 15 | , 16 | ); 17 | expect(container).toMatchSnapshot(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/components/GridContent/GridContent.test.jsx: -------------------------------------------------------------------------------- 1 | import { screen } from '@testing-library/react'; 2 | import { renderTheme } from '../../styles/render-theme'; 3 | import { GridContent } from '.'; 4 | 5 | import mock from './mock'; 6 | 7 | describe('', () => { 8 | it('should render grid content', () => { 9 | const { container } = renderTheme(); 10 | expect(container).toMatchSnapshot(); 11 | }); 12 | 13 | it('should render grid content', () => { 14 | const { container } = renderTheme( 15 | , 16 | ); 17 | expect(container).toMatchSnapshot(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/components/Heading/stories.jsx: -------------------------------------------------------------------------------- 1 | import { Heading } from '.'; 2 | 3 | export default { 4 | title: 'Heading', 5 | component: Heading, 6 | args: { 7 | children: 'O texto está escuro', 8 | }, 9 | argTypes: { 10 | children: { type: 'string' }, 11 | }, 12 | parameters: { 13 | backgrounds: { 14 | default: 'dark', 15 | }, 16 | }, 17 | }; 18 | 19 | export const Light = (args) => ; 20 | export const Dark = (args) => ; 21 | 22 | Light.parameters = { 23 | backgrounds: { 24 | default: 'light', 25 | }, 26 | }; 27 | 28 | Dark.args = { 29 | children: 'O texto está claro', 30 | colorDark: false, 31 | }; 32 | -------------------------------------------------------------------------------- /src/components/TextComponent/stories.jsx: -------------------------------------------------------------------------------- 1 | import { TextComponent } from '.'; 2 | 3 | export default { 4 | title: 'TextComponent', 5 | component: TextComponent, 6 | args: { 7 | children: ` 8 | Lorem ipsum dolor sit amet consectetur adipisicing elit. 9 | Ullam placeat unde harum. Facilis, quasi delectus 10 | obcaecati perferendis nobis alias ad aspernatur quod neque, 11 | corporis, aperiam numquam. Sint consequatur omnis voluptate.`, 12 | }, 13 | argTypes: { 14 | children: { type: 'string' }, 15 | }, 16 | }; 17 | 18 | export const Template = (args) => { 19 | return ( 20 |
21 | 22 |
23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /src/templates/Base/mock.jsx: -------------------------------------------------------------------------------- 1 | import linksMock from '../../components/NavLinks/mock'; 2 | 3 | import gridMock from '../../components/GridText/mock'; 4 | import { GridText } from '../../components/GridText'; 5 | 6 | export const mockBase = { 7 | children: ( 8 | <> 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ), 17 | links: linksMock, 18 | logoData: { 19 | text: 'Logo', 20 | link: '#', 21 | }, 22 | footerHtml: '

Teste de footer

', 23 | }; 24 | -------------------------------------------------------------------------------- /src/components/Footer/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | import { Container as TextComponent } from '../TextComponent/styles'; 3 | import { Container as SectionContainer } from '../SectionContainer/styles'; 4 | 5 | export const Container = styled.footer` 6 | ${({ theme }) => css` 7 | text-align: center; 8 | border-top: 0.1rem solid ${theme.colors.mediumGray}; 9 | 10 | a { 11 | color: inherit; 12 | text-decoration: none; 13 | } 14 | 15 | & ${TextComponent} { 16 | font-size: ${theme.font.sizes.small}; 17 | } 18 | 19 | & ${SectionContainer} { 20 | padding-top: 0; 21 | padding-bottom: 0; 22 | } 23 | `} 24 | `; 25 | -------------------------------------------------------------------------------- /src/components/Heading/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import * as Styled from './styles'; 3 | 4 | export const Heading = ({ 5 | children, 6 | colorDark = true, 7 | as = 'h1', 8 | size = 'huge', 9 | uppercase = false, 10 | }) => { 11 | return ( 12 | 18 | {children} 19 | 20 | ); 21 | }; 22 | 23 | Heading.propTypes = { 24 | children: P.node.isRequired, 25 | colorDark: P.bool, 26 | as: P.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']), 27 | size: P.oneOf(['small', 'medium', 'big', 'huge']), 28 | uppercase: P.bool, 29 | }; 30 | -------------------------------------------------------------------------------- /src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { BrowserRouter, Route, Switch } from 'react-router-dom'; 4 | import { ThemeProvider } from 'styled-components'; 5 | 6 | import { GlobalStyles } from './styles/global-styles'; 7 | import { theme } from './styles/theme'; 8 | import Home from './templates/Home'; 9 | 10 | ReactDOM.render( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | , 21 | document.getElementById('root'), 22 | ); 23 | -------------------------------------------------------------------------------- /src/templates/Base/index.jsx: -------------------------------------------------------------------------------- 1 | import P from 'prop-types'; 2 | import * as Styled from './styles'; 3 | import { Menu } from '../../components/Menu'; 4 | import { Footer } from '../../components/Footer'; 5 | import { GoTop } from '../../components/GoTop'; 6 | 7 | export const Base = ({ links, logoData, footerHtml, children }) => { 8 | return ( 9 | <> 10 | 11 | 12 | {children} 13 |