├── .env.example ├── .env ├── .prettierrc ├── public ├── _logo192.png ├── favicon.ico ├── logo192.png ├── logo512.png ├── robots.txt ├── routes.json ├── manifest.json └── index.html ├── src ├── img │ ├── icons │ │ ├── menu.png │ │ ├── close.png │ │ └── plus-icon.png │ ├── MarcoBrunoDev.png │ ├── cursoFrontEnd.png │ ├── live-28-04-2020.png │ ├── marcos-castro.png │ └── social-media │ │ ├── discord.png │ │ ├── github.png │ │ ├── twitch.png │ │ ├── twitter.png │ │ ├── youtube.png │ │ ├── facebook.png │ │ ├── instagram.png │ │ └── linkedin.png ├── libs │ ├── validation │ │ ├── required.js │ │ ├── email.js │ │ ├── maxLength.js │ │ ├── minLength.js │ │ ├── index.js │ │ └── useValidation.js │ ├── date │ │ └── index.js │ └── social │ │ └── index.js ├── components │ ├── PhotoLive │ │ └── index.js │ ├── PlusButton │ │ ├── index.js │ │ └── styles.js │ ├── MsgError │ │ └── index.js │ ├── LogoDev │ │ ├── index.js │ │ └── styles.js │ ├── ModalNes │ │ └── index.js │ ├── TextNes │ │ └── index.js │ ├── SocialMedia │ │ ├── styles.js │ │ └── index.js │ ├── FormNes │ │ ├── index.js │ │ └── styles.js │ ├── TextareaNes │ │ ├── styles.js │ │ └── index.js │ ├── TitleNes │ │ └── index.js │ ├── TagNes │ │ └── index.js │ ├── ActionNes │ │ └── index.js │ ├── FieldNes │ │ ├── styles.js │ │ └── index.js │ ├── ContainerNes │ │ └── index.js │ ├── ButtonShare │ │ └── index.js │ └── ButtonNes │ │ └── index.js ├── App.js ├── services │ ├── axios.js │ └── lives.service.js ├── pages │ ├── HomePage │ │ └── index.js │ ├── PostsDev │ │ └── index.js │ ├── ContactsDev │ │ └── index.js │ ├── ProjectsDev │ │ └── index.js │ ├── LiveNew │ │ └── index.js │ ├── Template │ │ └── index.js │ ├── LivesSchedule │ │ └── index.js │ └── LiveDetails │ │ └── index.js ├── styles │ ├── settings │ │ ├── Gaps.js │ │ ├── Size.js │ │ ├── Colors.js │ │ └── Cursor.js │ ├── tools │ │ └── _containers.js │ ├── elements │ │ └── Base.js │ └── generic │ │ └── Reset.js ├── containers │ ├── CardDescription │ │ └── index.js │ ├── ContainerDev │ │ └── index.js │ ├── HeaderDev │ │ ├── index.js │ │ └── styles.js │ ├── WrapperCard │ │ └── index.js │ ├── CardGuest │ │ ├── styles.js │ │ └── index.js │ ├── FooterDev │ │ ├── styles.js │ │ └── index.js │ ├── CardInfo │ │ ├── index.js │ │ └── styles.js │ ├── ShareSocial │ │ ├── styles.js │ │ └── index.js │ ├── CardDay │ │ ├── index.js │ │ └── styles.js │ ├── FormLive │ │ ├── validation.js │ │ └── index.js │ ├── MenuDev │ │ ├── index.js │ │ └── styles.js │ └── InfosLive │ │ ├── styles.js │ │ └── index.js ├── index.js └── Routes.js ├── .vscode └── settings.json ├── cypress ├── fixtures │ └── example.json ├── support │ ├── index.js │ └── commands.js ├── plugins │ └── index.js ├── data-builders │ └── lives.builder.js └── integration │ └── pages │ └── LiveNew.test.js ├── cypress.json ├── .gitignore ├── .eslintrc ├── package.json ├── .github └── workflows │ └── azure-static-web-apps-lemon-hill-0129ffe10.yml └── README.md /.env.example: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | REACT_APP_API=http://192.168.0.4:3001/api -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /public/_logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/public/_logo192.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/public/logo512.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/routes.json: -------------------------------------------------------------------------------- 1 | { "routes": [{ "route": "/*", "serve": "/index.html", "statusCode": 200 }] } 2 | -------------------------------------------------------------------------------- /src/img/icons/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/icons/menu.png -------------------------------------------------------------------------------- /src/img/icons/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/icons/close.png -------------------------------------------------------------------------------- /src/img/MarcoBrunoDev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/MarcoBrunoDev.png -------------------------------------------------------------------------------- /src/img/cursoFrontEnd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/cursoFrontEnd.png -------------------------------------------------------------------------------- /src/img/icons/plus-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/icons/plus-icon.png -------------------------------------------------------------------------------- /src/img/live-28-04-2020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/live-28-04-2020.png -------------------------------------------------------------------------------- /src/img/marcos-castro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/marcos-castro.png -------------------------------------------------------------------------------- /src/img/social-media/discord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/social-media/discord.png -------------------------------------------------------------------------------- /src/img/social-media/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/social-media/github.png -------------------------------------------------------------------------------- /src/img/social-media/twitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/social-media/twitch.png -------------------------------------------------------------------------------- /src/img/social-media/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/social-media/twitter.png -------------------------------------------------------------------------------- /src/img/social-media/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/social-media/youtube.png -------------------------------------------------------------------------------- /src/img/social-media/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/social-media/facebook.png -------------------------------------------------------------------------------- /src/img/social-media/instagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/social-media/instagram.png -------------------------------------------------------------------------------- /src/img/social-media/linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcobrunodev/portfolio/HEAD/src/img/social-media/linkedin.png -------------------------------------------------------------------------------- /src/libs/validation/required.js: -------------------------------------------------------------------------------- 1 | function required(value, msgError) { 2 | return !value && msgError; 3 | } 4 | 5 | export default required; 6 | -------------------------------------------------------------------------------- /src/components/PhotoLive/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const PhotoLive = styled.img``; 4 | 5 | export default PhotoLive; 6 | -------------------------------------------------------------------------------- /src/libs/validation/email.js: -------------------------------------------------------------------------------- 1 | function isEmail(value, msgError) { 2 | return !/\S+@\S+\.\S+/.test(value) && msgError; 3 | } 4 | 5 | export default isEmail; 6 | -------------------------------------------------------------------------------- /src/libs/validation/maxLength.js: -------------------------------------------------------------------------------- 1 | function maxLength(length, value, msgError) { 2 | return value.length > length && msgError; 3 | } 4 | 5 | export default maxLength; 6 | -------------------------------------------------------------------------------- /src/libs/validation/minLength.js: -------------------------------------------------------------------------------- 1 | function minLength(length, value, msgError) { 2 | return value.length < length && msgError; 3 | } 4 | 5 | export default minLength; 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2, 3 | "editor.formatOnSave": true, 4 | "[javascript]": { 5 | "editor.defaultFormatter": "esbenp.prettier-vscode" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-one-expression-per-line */ 2 | import React from 'react'; 3 | import Routes from './Routes'; 4 | 5 | const App = () => ; 6 | 7 | export default App; 8 | -------------------------------------------------------------------------------- /src/services/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const { REACT_APP_API } = process.env; 4 | 5 | const api = axios.create({ 6 | baseURL: REACT_APP_API, 7 | timeout: 1000, 8 | }); 9 | 10 | export default api; 11 | -------------------------------------------------------------------------------- /src/libs/validation/index.js: -------------------------------------------------------------------------------- 1 | import required from './required'; 2 | import isEmail from './email'; 3 | import minLength from './minLength'; 4 | import maxLength from './maxLength'; 5 | 6 | export { required, isEmail, minLength, maxLength }; 7 | -------------------------------------------------------------------------------- /src/components/PlusButton/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Plus, Action } from './styles'; 3 | 4 | const PlusButton = () => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default PlusButton; 11 | -------------------------------------------------------------------------------- /src/components/MsgError/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const MsgError = styled.span` 4 | font-size: var(--size-small); 5 | padding: var(--gap-smaller); 6 | color: var(--color-primary-dark); 7 | `; 8 | 9 | export default MsgError; 10 | -------------------------------------------------------------------------------- /src/components/LogoDev/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Wrapper, Logo, Title } from './styles'; 3 | 4 | const LogoDev = () => ( 5 | 6 | 7 | MarcoBrunoDev 8 | 9 | ); 10 | 11 | export default LogoDev; 12 | -------------------------------------------------------------------------------- /src/components/PlusButton/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Link } from 'react-router-dom'; 3 | import plus from '../../img/icons/plus-icon.png'; 4 | 5 | const Plus = styled.img.attrs({ src: plus })``; 6 | const Action = styled(Link)``; 7 | 8 | export { Plus, Action }; 9 | -------------------------------------------------------------------------------- /src/pages/HomePage/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TitleNes from '../../components/TitleNes'; 3 | import Template from '../Template'; 4 | 5 | const HomePage = () => ( 6 | 9 | ); 10 | 11 | export default HomePage; 12 | -------------------------------------------------------------------------------- /src/pages/PostsDev/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TitleNes from '../../components/TitleNes'; 3 | import Template from '../Template'; 4 | 5 | const PostsDev = () => ( 6 | 9 | ); 10 | 11 | export default PostsDev; 12 | -------------------------------------------------------------------------------- /src/components/ModalNes/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const ModalNes = styled.div` 4 | position: fixed; 5 | top: 0; 6 | bottom: 0; 7 | left: 0; 8 | right: 0; 9 | background-color: rgba(0, 0, 0, 0.8); 10 | z-index: 10; 11 | `; 12 | 13 | export default ModalNes; 14 | -------------------------------------------------------------------------------- /src/pages/ContactsDev/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Template from '../Template'; 3 | import TitleNes from '../../components/TitleNes'; 4 | 5 | const ContactsDev = () => ( 6 | 9 | ); 10 | 11 | export default ContactsDev; 12 | -------------------------------------------------------------------------------- /src/pages/ProjectsDev/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TitleNes from '../../components/TitleNes'; 3 | import Template from '../Template'; 4 | 5 | const ProjectsDev = () => ( 6 | 9 | ); 10 | 11 | export default ProjectsDev; 12 | -------------------------------------------------------------------------------- /src/styles/settings/Gaps.js: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components'; 2 | 3 | const Gaps = createGlobalStyle` 4 | :root{ 5 | --gap-smaller: 5rem; 6 | --gap-small: 10rem; 7 | --gap-medium: 20rem; 8 | --gap-big: 40rem; 9 | --gap-bigger: 80rem; 10 | } 11 | `; 12 | 13 | export default Gaps; -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "viewportWidth": 1920, 3 | "viewportHeight": 1080, 4 | "baseUrl": "http://localhost:3000", 5 | "video": false, 6 | "defaultCommandTimeout": 8000, 7 | "pageLoadTimeout": 90000, 8 | "numTestsKeptInMemory": 5, 9 | "chromeWebSecurity": false, 10 | "env": { 11 | "RETRIES": 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/components/TextNes/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const TextNes = styled.p` 4 | font-size: var(--size-small); 5 | line-height: 1.8em; 6 | color: var(--color-gray-lighter); 7 | 8 | @media (min-width: 700px) { 9 | font-size: var(--size-medium); 10 | } 11 | `; 12 | 13 | export default TextNes; 14 | -------------------------------------------------------------------------------- /src/components/SocialMedia/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Icon = styled.img` 4 | width: 100%; 5 | `; 6 | 7 | const Action = styled.a` 8 | display: inline-block; 9 | max-width: 60px; 10 | margin-left: var(--gap-small); 11 | margin-right: var(--gap-small); 12 | `; 13 | 14 | export { Icon, Action }; 15 | -------------------------------------------------------------------------------- /src/containers/CardDescription/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import ContainerNes from '../../components/ContainerNes'; 3 | 4 | const CardDescription = styled(ContainerNes)` 5 | font-family: 'Fira Code', cursive; 6 | line-height: 1.4; 7 | font-size: var(--size-big); 8 | `; 9 | 10 | export default CardDescription; 11 | -------------------------------------------------------------------------------- /src/containers/ContainerDev/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import _containers from '../../styles/tools/_containers'; 3 | 4 | const ContainerDev = styled.section` 5 | display: flex; 6 | flex-direction: column; 7 | align-items: center; 8 | padding-bottom: var(--gap-bigger); 9 | ${_containers}; 10 | `; 11 | 12 | export default ContainerDev; 13 | -------------------------------------------------------------------------------- /src/services/lives.service.js: -------------------------------------------------------------------------------- 1 | import api from './axios'; 2 | 3 | function create(live) { 4 | return api.post('/lives/', live); 5 | } 6 | 7 | function findLiveByUuid(uuid) { 8 | return api.get(`/lives/${uuid}`); 9 | } 10 | 11 | function findLivesFuture() { 12 | return api.get('/lives/future'); 13 | } 14 | 15 | export default { findLivesFuture, create, findLiveByUuid }; 16 | -------------------------------------------------------------------------------- /src/pages/LiveNew/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Template from '../Template'; 3 | import TitleNes from '../../components/TitleNes'; 4 | import FormLive from '../../containers/FormLive'; 5 | 6 | const LiveNew = () => ( 7 | 12 | ); 13 | 14 | export default LiveNew; 15 | -------------------------------------------------------------------------------- /src/styles/settings/Size.js: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components'; 2 | 3 | const Size = createGlobalStyle` 4 | :root { 5 | --size-smaller: 8rem; 6 | --size-small: 12rem; 7 | --size-medium: 16rem; 8 | --size-big: 22rem; 9 | --size-bigger: 34rem; 10 | 11 | --size-border: 4rem; 12 | --size-header: 50rem; 13 | } 14 | `; 15 | 16 | export default Size; 17 | -------------------------------------------------------------------------------- /src/containers/HeaderDev/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import LogoDev from '../../components/LogoDev'; 3 | import { Header, Logo } from './styles'; 4 | import MenuDev from '../MenuDev'; 5 | 6 | const HeaderDev = () => ( 7 |
8 | 9 | 10 | 11 | 12 | 13 |
14 | ); 15 | 16 | export default HeaderDev; 17 | -------------------------------------------------------------------------------- /.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/styles/tools/_containers.js: -------------------------------------------------------------------------------- 1 | const internal = ` 2 | padding-left: var(--gap-small); 3 | padding-right: var(--gap-small); 4 | `; 5 | 6 | const external = ` 7 | width: calc(100% - var(--gap-small)); 8 | margin-left: auto; 9 | margin-right: auto; 10 | ` 11 | 12 | const _containers = (type = 'internal') => { 13 | return type === 'internal' ? internal : external; 14 | } 15 | 16 | 17 | export default _containers; -------------------------------------------------------------------------------- /src/pages/Template/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import HeaderDev from '../../containers/HeaderDev'; 4 | import FooterDev from '../../containers/FooterDev'; 5 | 6 | const Template = ({ children }) => ( 7 | <> 8 | 9 | {children} 10 | 11 | 12 | ); 13 | 14 | Template.propTypes = { 15 | children: PropTypes.node.isRequired, 16 | }; 17 | 18 | export default Template; 19 | -------------------------------------------------------------------------------- /src/containers/WrapperCard/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Card } from '../CardDay/styles'; 3 | 4 | const WrapperCard = styled.section` 5 | display: flex; 6 | justify-content: space-around; 7 | flex-wrap: wrap; 8 | width: 100%; 9 | 10 | & > ${Card} { 11 | margin-right: var(--gap-small); 12 | margin-left: var(--gap-small); 13 | margin-bottom: var(--gap-bigger); 14 | } 15 | `; 16 | 17 | export default WrapperCard; 18 | -------------------------------------------------------------------------------- /src/components/FormNes/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Form } from './styles'; 4 | 5 | const FormNes = ({ children, onSubmit }) => ( 6 |
7 | {children} 8 |
9 | ); 10 | 11 | // oneOf([element, arrayOf(element)) 12 | 13 | FormNes.propTypes = { 14 | children: PropTypes.node.isRequired, 15 | onSubmit: PropTypes.func.isRequired, 16 | }; 17 | 18 | export default FormNes; 19 | -------------------------------------------------------------------------------- /src/components/LogoDev/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import logo from '../../img/MarcoBrunoDev.png'; 3 | 4 | const Wrapper = styled.figure` 5 | height: 100%; 6 | display: flex; 7 | align-items: center; 8 | `; 9 | const Logo = styled.img.attrs({ src: logo })` 10 | height: 100%; 11 | margin-right: var(--gap-small); 12 | `; 13 | const Title = styled.figcaption` 14 | color: var(--color-gray-lighter); 15 | `; 16 | 17 | export { Wrapper, Logo, Title }; 18 | -------------------------------------------------------------------------------- /src/containers/CardGuest/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Card } from '../CardInfo/styles'; 3 | 4 | const Photo = styled.img``; 5 | const Name = styled.p``; 6 | const Guest = styled(Card)` 7 | position: relative; 8 | 9 | & > ${Name} { 10 | position: absolute; 11 | bottom: 0; 12 | padding: var(--gap-smaller) var(--gap-small); 13 | background-color: var(--color-primary-medium); 14 | } 15 | `; 16 | 17 | export { Guest, Photo, Name }; 18 | -------------------------------------------------------------------------------- /src/components/FormNes/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import ContainerNes from '../ContainerNes'; 3 | import { Label } from '../FieldNes/styles'; 4 | 5 | const Form = styled(ContainerNes)` 6 | padding: var(--gap-big); 7 | `; 8 | 9 | const Half = styled.div` 10 | @media (min-width: 700px) { 11 | display: flex; 12 | justify-content: space-between; 13 | 14 | & > ${Label} { 15 | width: 49%; 16 | } 17 | } 18 | `; 19 | 20 | export { Form, Half }; 21 | -------------------------------------------------------------------------------- /src/components/TextareaNes/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Textarea = styled.textarea` 4 | border: var(--size-border) solid var(--color-gray-lighter); 5 | color: var(--color-gray-lighter); 6 | height: 100px; 7 | font: inherit; 8 | background-color: var(--color-gray-medium); 9 | padding: var(--gap-small); 10 | resize: vertical; 11 | 12 | &:focus { 13 | border-color: var(--color-secondary-medium); 14 | } 15 | `; 16 | 17 | export default Textarea; 18 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import Size from './styles/settings/Size'; 5 | import Colors from './styles/settings/Colors'; 6 | import Gaps from './styles/settings/Gaps'; 7 | import Reset from './styles/generic/Reset'; 8 | import Base from './styles/elements/Base'; 9 | 10 | import App from './App'; 11 | 12 | ReactDOM.render( 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | , 22 | document.getElementById('root') 23 | ); 24 | -------------------------------------------------------------------------------- /src/containers/FooterDev/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import ContainerNes from '../../components/ContainerNes'; 3 | import { Action } from '../../components/SocialMedia/styles'; 4 | 5 | const Navigation = styled.nav` 6 | display: flex; 7 | justify-content: center; 8 | 9 | & > ${Action} { 10 | margin: 0 var(--gap-small) var(--gap-medium); 11 | width: 60px; 12 | } 13 | `; 14 | 15 | const Footer = styled(ContainerNes)` 16 | margin-top: var(--gap-bigger); 17 | padding: var(--gap-medium) 0; 18 | text-align: center; 19 | `; 20 | 21 | export { Footer, Navigation }; 22 | -------------------------------------------------------------------------------- /src/libs/date/index.js: -------------------------------------------------------------------------------- 1 | import { utcToZonedTime, format } from 'date-fns-tz'; 2 | 3 | const { timeZone } = new Intl.DateTimeFormat().resolvedOptions(); 4 | 5 | const formatDate = (date) => { 6 | const dateStartLocal = utcToZonedTime(new Date(date), timeZone); 7 | const formtDateStartLocal = format(dateStartLocal, 'dd/MM/yyyy'); 8 | 9 | return formtDateStartLocal; 10 | }; 11 | 12 | const getHour = (date) => { 13 | const dateStartLocal = utcToZonedTime(new Date(date), timeZone); 14 | const hour = format(dateStartLocal, 'hh:mm'); 15 | 16 | return hour; 17 | }; 18 | 19 | export { formatDate, getHour }; 20 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "MarcoBrunoDev", 3 | "name": "Site do MarcoBrunoDev", 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/containers/CardGuest/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import TagNes from '../../components/TagNes'; 4 | import { Guest, Photo, Name } from './styles'; 5 | 6 | const CardGuest = (props) => { 7 | const { name, photo } = props; 8 | 9 | return ( 10 | 11 | Convidado 12 | 13 | 14 | {name} 15 | 16 | ); 17 | }; 18 | 19 | CardGuest.propTypes = { 20 | name: PropTypes.string.isRequired, 21 | photo: PropTypes.string.isRequired, 22 | }; 23 | 24 | export default CardGuest; 25 | -------------------------------------------------------------------------------- /src/styles/elements/Base.js: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components'; 2 | import { mickey, mickeyHover } from '../settings/Cursor'; 3 | 4 | const Base = createGlobalStyle` 5 | html { 6 | font-size: 1px; 7 | cursor: url(${mickey}),auto; 8 | } 9 | 10 | a:hover, button:hover { 11 | cursor: url(${mickeyHover}) 14 0,pointer; 12 | } 13 | 14 | body { 15 | padding-top: calc(var(--size-header) + var(--gap-medium)); 16 | font-size: var(--size-medium); 17 | font-family: 'Press Start 2P', cursive; 18 | min-width: 320px; 19 | background-color: var(--color-gray-light); 20 | } 21 | `; 22 | 23 | export default Base; 24 | -------------------------------------------------------------------------------- /src/styles/settings/Colors.js: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components'; 2 | 3 | const Colors = createGlobalStyle` 4 | :root { 5 | --color-primary-dark: #d04154; 6 | --color-primary-medium: #f25a6f; 7 | 8 | --color-secondary-dark: #63497d; 9 | --color-secondary-medium: #7c5e99; 10 | 11 | --color-tertiary-dark: #4e9859; 12 | --color-tertiary-medium: #62C370; 13 | 14 | --color-gray-dark: #212529; 15 | --color-gray-medium: #2f3439; 16 | --color-gray-light: #3f454c; 17 | --color-gray-lighter: #fff; 18 | 19 | --color-title: #F5D547; 20 | --color-link: #20A4F3; 21 | } 22 | `; 23 | 24 | export default Colors; 25 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "extends": ["plugin:react/recommended", "plugin:cypress/recommended", "airbnb", "prettier"], 7 | "globals": { 8 | "Atomics": "readonly", 9 | "SharedArrayBuffer": "readonly" 10 | }, 11 | "parserOptions": { 12 | "ecmaFeatures": { 13 | "jsx": true 14 | }, 15 | "ecmaVersion": 2018, 16 | "sourceType": "module" 17 | }, 18 | "plugins": ["react"], 19 | "rules": { 20 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 21 | "react/jsx-one-expression-per-line": [0], 22 | "no-use-before-define": ["error", { "functions": false }] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/components/TitleNes/index.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | const TitleNes = styled.h1` 4 | display: flex; 5 | align-items: center; 6 | justify-content: center; 7 | color: var(--color-title); 8 | font-size: var(--size-big); 9 | line-height: 1.4; 10 | text-align: center; 11 | padding: var(--gap-big) var(--gap-small) 0; 12 | margin-bottom: var(--gap-bigger); 13 | 14 | @media (min-width: 700px) { 15 | font-size: var(--size-bigger); 16 | padding-top: var(--gap-bigger); 17 | } 18 | 19 | ${({ shimmerEffect }) => 20 | shimmerEffect && 21 | css` 22 | filter: blur(2px); 23 | `} 24 | `; 25 | 26 | export default TitleNes; 27 | -------------------------------------------------------------------------------- /src/containers/CardInfo/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Card, Item } from './styles'; 4 | import TagNes from '../../components/TagNes'; 5 | 6 | const CardInfo = ({ label, items = [], shimmerEffect }) => ( 7 | 8 | {label} 9 | {items.map((item) => ( 10 | {item} 11 | ))} 12 | 13 | ); 14 | 15 | CardInfo.defaultProps = { 16 | items: [], 17 | shimmerEffect: false, 18 | }; 19 | 20 | CardInfo.propTypes = { 21 | label: PropTypes.string.isRequired, 22 | items: PropTypes.arrayOf(String), 23 | shimmerEffect: PropTypes.bool, 24 | }; 25 | 26 | export default CardInfo; 27 | -------------------------------------------------------------------------------- /cypress/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /src/components/TagNes/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const TagNes = styled.span` 4 | display: inline-flex; 5 | align-items: center; 6 | position: relative; 7 | background-color: var(--color-primary-medium); 8 | padding: var(--gap-small) var(--gap-medium); 9 | 10 | &::before, 11 | &::after { 12 | content: ''; 13 | display: inline-block; 14 | position: absolute; 15 | z-index: 2; 16 | background-color: var(--color-primary-medium); 17 | height: 68%; 18 | width: calc(var(--size-border) * 1.4); 19 | } 20 | &::before { 21 | left: 0; 22 | transform: translateX(-100%); 23 | } 24 | &::after { 25 | right: 0; 26 | transform: translateX(100%); 27 | } 28 | `; 29 | 30 | export default TagNes; 31 | -------------------------------------------------------------------------------- /src/containers/HeaderDev/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Link } from 'react-router-dom'; 3 | import ContainerNes from '../../components/ContainerNes'; 4 | import { Title } from '../../components/LogoDev/styles'; 5 | 6 | const Logo = styled(Link)` 7 | height: 100%; 8 | text-decoration: none; 9 | `; 10 | 11 | const Header = styled(ContainerNes)` 12 | position: fixed; 13 | top: 0; 14 | left: 0; 15 | right: 0; 16 | z-index: 10; 17 | display: flex; 18 | justify-content: space-between; 19 | align-items: center; 20 | height: var(--size-header); 21 | 22 | & ${Title} { 23 | display: none; 24 | 25 | @media (min-width: 450px) { 26 | display: block; 27 | } 28 | } 29 | `; 30 | 31 | export { Header, Logo }; 32 | -------------------------------------------------------------------------------- /cypress/plugins/index.js: -------------------------------------------------------------------------------- 1 | /// 2 | // *********************************************************** 3 | // This example plugins/index.js can be used to load plugins 4 | // 5 | // You can change the location of this file or turn off loading 6 | // the plugins file with the 'pluginsFile' configuration option. 7 | // 8 | // You can read more here: 9 | // https://on.cypress.io/plugins-guide 10 | // *********************************************************** 11 | 12 | // This function is called when a project is opened or re-opened (e.g. due to 13 | // the project's config changing) 14 | 15 | /** 16 | * @type {Cypress.PluginConfig} 17 | */ 18 | module.exports = (on, config) => { 19 | // `on` is used to hook into various events Cypress emits 20 | // `config` is the resolved Cypress config 21 | } 22 | -------------------------------------------------------------------------------- /src/components/ActionNes/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const ActionNes = styled.a` 4 | display: inline-flex; 5 | align-items: center; 6 | justify-content: center; 7 | position: relative; 8 | color: var(--color-link); 9 | text-decoration: none; 10 | transition: color 100ms linear; 11 | 12 | &::after { 13 | content: ''; 14 | position: absolute; 15 | bottom: 3px; 16 | background-color: var(--color-link); 17 | width: 100%; 18 | height: 80%; 19 | transform-origin: bottom center; 20 | transform: scaleY(0.08); 21 | z-index: -1; 22 | transition: transform 50ms linear; 23 | } 24 | 25 | &:hover { 26 | color: var(--color-gray-lighter); 27 | } 28 | 29 | &:hover::after { 30 | transform: scaleY(1); 31 | } 32 | `; 33 | 34 | export default ActionNes; 35 | -------------------------------------------------------------------------------- /src/containers/FooterDev/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Footer, Navigation } from './styles'; 3 | import SocialMedia from '../../components/SocialMedia'; 4 | 5 | const medias = [ 6 | { 7 | what: 'twitch', 8 | href: 'https://twitch.com/marcobrunodev', 9 | }, 10 | { 11 | what: 'discord', 12 | href: 'http://bit.ly/discord-collabcode', 13 | }, 14 | { 15 | what: 'twitter', 16 | href: 'https://twitter.com/marcobrunodev', 17 | }, 18 | { 19 | what: 'github', 20 | href: 'https://github.com/marcobrunodev', 21 | }, 22 | ]; 23 | 24 | const FooterDev = () => ( 25 |
26 | 27 | {medias.map(({ href, what }) => ( 28 | 29 | ))} 30 | 31 | 32 |

@MarcoBrunoDev

33 |
34 | ); 35 | 36 | export default FooterDev; 37 | -------------------------------------------------------------------------------- /src/components/FieldNes/styles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import MsgError from '../MsgError'; 3 | 4 | const Label = styled.label` 5 | position: relative; 6 | display: flex; 7 | flex-direction: column; 8 | margin-bottom: var(--gap-big); 9 | 10 | & > ${MsgError} { 11 | position: absolute; 12 | bottom: 0; 13 | transform: translateY(100%); 14 | } 15 | `; 16 | 17 | const Content = styled.span` 18 | margin-bottom: var(--gap-smaller); 19 | `; 20 | 21 | const Input = styled.input` 22 | border: var(--size-border) solid var(--color-gray-lighter); 23 | color: var(--color-gray-lighter); 24 | height: 30px; 25 | font: inherit; 26 | background-color: var(--color-gray-medium); 27 | padding: var(--gap-smaller) var(--gap-small); 28 | 29 | &:focus { 30 | border-color: var(--color-secondary-medium); 31 | } 32 | `; 33 | 34 | export { Label, Content, Input }; 35 | -------------------------------------------------------------------------------- /src/components/ContainerNes/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import _containers from '../../styles/tools/_containers'; 3 | 4 | const ContainerNes = styled.section` 5 | ${_containers('internal')}; 6 | position: relative; 7 | background-color: var(--color-gray-dark); 8 | color: var(--color-gray-lighter); 9 | font-size: var(--size-medium); 10 | padding: calc(var(--size-border) + var(--gap-smaller) * 2); 11 | 12 | &::after { 13 | content: ''; 14 | position: absolute; 15 | top: 50%; 16 | left: 50%; 17 | box-sizing: border-box; 18 | transform: translate(-50%, -50%); 19 | width: calc(100% - var(--gap-small)); 20 | height: calc(100% - var(--gap-small)); 21 | border: var(--size-border) solid var(--color-gray-lighter); 22 | } 23 | 24 | & > * { 25 | position: relative; 26 | z-index: 1; 27 | } 28 | `; 29 | 30 | export default ContainerNes; 31 | -------------------------------------------------------------------------------- /src/styles/settings/Cursor.js: -------------------------------------------------------------------------------- 1 | const mickey = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABFklEQVRYR9WXURLDIAhE6/0PbSdOtUpcd1Gnpv1KGpTHBpCE1/cXq+vrMph7dGvXZTtpfW10DCA5jrH1H0Jhs5E0hnZdCR+vb5S8Nn8mQCeS9BdSalYJqMBjAGzq59xAESN7VFVUgV8AZB/dZBR7QTFDCqGquvUBVVoEtgIwpQRzmANSFHgWQKExHdIrPeuMvQNDarXe6nC/AutgV3JW+6bgqQLeV8FekRtgV+ToDKEKnACYKsfZjjkam7a0ZpYTytwmgainpC3HvwBocgKOxqRjehoR9DFKNFYtOwCGYCszobeCbl26N6yyQ6g8X/Wex/rBPsNEV6qAMaJPMynIHQCoSqS9JSMmwef51LflTgCRszU7DvAGiV6mHWfsaVUAAAAASUVORK5CYII=`; 2 | const mickeyHover = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC`; 3 | 4 | export { mickey, mickeyHover }; 5 | -------------------------------------------------------------------------------- /src/containers/ShareSocial/styles.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | import ModalNes from '../../components/ModalNes'; 3 | import TitleNes from '../../components/TitleNes'; 4 | import ContainerNes from '../../components/ContainerNes'; 5 | import { Icon } from '../../components/SocialMedia/styles'; 6 | 7 | const Share = styled(ModalNes)` 8 | display: none; 9 | justify-content: center; 10 | align-items: center; 11 | text-align: center; 12 | 13 | & > ${ContainerNes} { 14 | box-sizing: border-box; 15 | width: calc(100% - var(--gap-small) * 2); 16 | min-height: 360px; 17 | max-width: 600px; 18 | } 19 | 20 | & ${TitleNes} { 21 | font-size: var(--size-big); 22 | } 23 | 24 | & ${Icon} { 25 | width: 60px; 26 | margin-left: var(--gap-small); 27 | margin-right: var(--gap-small); 28 | } 29 | 30 | ${({ active }) => 31 | active && 32 | css` 33 | display: flex; 34 | `} 35 | `; 36 | 37 | export default Share; 38 | -------------------------------------------------------------------------------- /cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | import 'cypress-file-upload'; 27 | -------------------------------------------------------------------------------- /src/components/FieldNes/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Label, Content, Input } from './styles'; 4 | import MsgError from '../MsgError'; 5 | 6 | const FieldNes = ({ content, type, name, placeholder, onChange, onBlur, msgError }) => ( 7 | 12 | ); 13 | 14 | FieldNes.defaultProps = { 15 | type: 'text', 16 | placeholder: '', 17 | msgError: '', 18 | }; 19 | 20 | FieldNes.propTypes = { 21 | content: PropTypes.string.isRequired, 22 | type: PropTypes.string, 23 | name: PropTypes.string.isRequired, 24 | placeholder: PropTypes.string, 25 | onChange: PropTypes.func.isRequired, 26 | onBlur: PropTypes.func.isRequired, 27 | msgError: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), 28 | }; 29 | 30 | export default FieldNes; 31 | -------------------------------------------------------------------------------- /src/Routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; 3 | import HomePage from './pages/HomePage'; 4 | import LivesSchedule from './pages/LivesSchedule'; 5 | import LiveDetail from './pages/LiveDetails'; 6 | import LiveNew from './pages/LiveNew'; 7 | import ProjectsDev from './pages/ProjectsDev'; 8 | import ContactsDev from './pages/ContactsDev'; 9 | import PostsDev from './pages/PostsDev'; 10 | 11 | const Routes = () => ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ); 24 | 25 | export default Routes; 26 | -------------------------------------------------------------------------------- /src/components/TextareaNes/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Label, Content } from '../FieldNes/styles'; 4 | import Textarea from './styles'; 5 | import MsgError from '../MsgError'; 6 | 7 | const TextareaNes = ({ name, content, placeholder, msgError, value, onChange, onBlur }) => ( 8 |