(null)
43 |
44 | async function configurarSessao(usuarioFirebase) {
45 | if (usuarioFirebase?.email) {
46 | const usuario = await usuarioNormalizado(usuarioFirebase)
47 | setUsuario(usuario)
48 | gerenciarCookie(true)
49 | setCarregando(false)
50 | return usuario.email
51 | } else {
52 | setUsuario(null)
53 | gerenciarCookie(false)
54 | setCarregando(false)
55 | return false
56 | }
57 | }
58 |
59 | async function login(email, senha) {
60 | try {
61 | setCarregando(true)
62 | const resp = await firebase.auth()
63 | .signInWithEmailAndPassword(email, senha)
64 |
65 | await configurarSessao(resp.user)
66 | route.push('/')
67 | } finally {
68 | setCarregando(false)
69 | }
70 | }
71 |
72 | async function cadastrar(email, senha) {
73 | try {
74 | setCarregando(true)
75 | const resp = await firebase.auth()
76 | .createUserWithEmailAndPassword(email, senha)
77 |
78 | await configurarSessao(resp.user)
79 | route.push('/')
80 | } finally {
81 | setCarregando(false)
82 | }
83 | }
84 |
85 | async function loginGoogle() {
86 | try {
87 | setCarregando(true)
88 | const resp = await firebase.auth().signInWithPopup(
89 | new firebase.auth.GoogleAuthProvider()
90 | )
91 |
92 | await configurarSessao(resp.user)
93 | route.push('/')
94 | } finally {
95 | setCarregando(false)
96 | }
97 | }
98 |
99 | async function logout() {
100 | try {
101 | setCarregando(true)
102 | await firebase.auth().signOut()
103 | await configurarSessao(null)
104 | } finally {
105 | setCarregando(false)
106 | }
107 | }
108 |
109 | useEffect(() => {
110 | if(Cookies.get('admin-template-cod3r-auth')) {
111 | const cancelar = firebase.auth().onIdTokenChanged(configurarSessao)
112 | return () => cancelar()
113 | } else {
114 | setCarregando(false)
115 | }
116 | }, [])
117 |
118 | return (
119 |
127 | {props.children}
128 |
129 | )
130 | }
131 |
132 |
133 | export default AuthContext
--------------------------------------------------------------------------------
/admin-template/src/data/hook/useAppData.ts:
--------------------------------------------------------------------------------
1 | import { useContext } from "react";
2 | import AppContext from '../context/AppContext'
3 |
4 | const useAppData = () => useContext(AppContext)
5 |
6 | export default useAppData
--------------------------------------------------------------------------------
/admin-template/src/data/hook/useAuth.ts:
--------------------------------------------------------------------------------
1 | import { useContext } from "react";
2 | import AuthContext from "../context/AuthContext";
3 |
4 | const useAuth = () => useContext(AuthContext)
5 |
6 | export default useAuth
--------------------------------------------------------------------------------
/admin-template/src/firebase/config.js:
--------------------------------------------------------------------------------
1 | import firebase from "firebase/app"
2 | import 'firebase/auth'
3 |
4 | if (!firebase.apps.length) {
5 | firebase.initializeApp({
6 | apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
7 | authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
8 | projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
9 | })
10 | }
11 |
12 | export default firebase
--------------------------------------------------------------------------------
/admin-template/src/model/Usuario.ts:
--------------------------------------------------------------------------------
1 | export default interface Usuario {
2 | uid: string
3 | email: string
4 | nome: string
5 | token: string
6 | provedor: string
7 | imagemUrl: string
8 | }
--------------------------------------------------------------------------------
/admin-template/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 | import 'tailwindcss/tailwind.css'
3 | import { AppProvider } from '../data/context/AppContext'
4 | import { AuthProvider } from '../data/context/AuthContext'
5 |
6 | function MyApp({ Component, pageProps }) {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 | )
14 | }
15 |
16 | export default MyApp
17 |
--------------------------------------------------------------------------------
/admin-template/src/pages/ajustes.tsx:
--------------------------------------------------------------------------------
1 | import Layout from '../components/template/Layout'
2 |
3 | export default function Ajustes() {
4 | return (
5 |
7 | Conteúdo!!!!
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/admin-template/src/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default function handler(req, res) {
4 | res.status(200).json({ name: 'John Doe' })
5 | }
6 |
--------------------------------------------------------------------------------
/admin-template/src/pages/autenticacao.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 | import AuthInput from "../components/auth/AuthInput"
3 | import { IconeAtencao } from "../components/icons"
4 | import useAuth from "../data/hook/useAuth"
5 |
6 | export default function Autenticacao() {
7 |
8 | const { cadastrar, login, loginGoogle } = useAuth()
9 |
10 | const [erro, setErro] = useState(null)
11 | const [modo, setModo] = useState<'login' | 'cadastro'>('login')
12 | const [email, setEmail] = useState('')
13 | const [senha, setSenha] = useState('')
14 |
15 | function exibirErro(msg, tempoEmSegundos = 5) {
16 | setErro(msg)
17 | setTimeout(() => setErro(null), tempoEmSegundos * 1000)
18 | }
19 |
20 | async function submeter() {
21 | try {
22 | if (modo === 'login') {
23 | await login(email, senha)
24 | } else {
25 | await cadastrar(email, senha)
26 | }
27 | } catch(e) {
28 | exibirErro(e?.message ?? 'Erro desconhecido!')
29 | }
30 | }
31 |
32 | return (
33 |
34 |
35 |

39 |
40 |
105 |
106 | )
107 | }
--------------------------------------------------------------------------------
/admin-template/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import Layout from '../components/template/Layout'
2 | export default function Home() {
3 | return (
4 |
5 | Conteúdo!!!!
6 |
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/admin-template/src/pages/notificacoes.tsx:
--------------------------------------------------------------------------------
1 | import Layout from '../components/template/Layout'
2 |
3 | export default function Notificacoes() {
4 | return (
5 |
7 | Notificações
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/admin-template/src/pages/perfil.tsx:
--------------------------------------------------------------------------------
1 | import Layout from '../components/template/Layout'
2 |
3 | export default function Perfil() {
4 | return (
5 |
7 | Perfil do Usuário
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/admin-template/src/styles/globals.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap');
2 |
3 | html,
4 | body {
5 | padding: 0;
6 | margin: 0;
7 | font-family: 'Poppins', sans-serif;
8 | }
9 |
10 | a {
11 | color: inherit;
12 | text-decoration: none;
13 | }
14 |
15 | * {
16 | box-sizing: border-box;
17 | }
18 |
--------------------------------------------------------------------------------
/admin-template/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | purge: [
3 | './src/pages/**/*.{js,ts,jsx,tsx}',
4 | './src/components/**/*.{js,ts,jsx,tsx}'
5 | ],
6 | darkMode: 'class', // or 'media' or 'class'
7 | theme: {
8 | extend: {},
9 | },
10 | variants: {
11 | extend: {},
12 | },
13 | plugins: [],
14 | }
15 |
--------------------------------------------------------------------------------
/admin-template/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": false,
12 | "forceConsistentCasingInFileNames": true,
13 | "noEmit": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "jsx": "preserve"
20 | },
21 | "include": [
22 | "next-env.d.ts",
23 | "**/*.ts",
24 | "**/*.tsx"
25 | ],
26 | "exclude": [
27 | "node_modules"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/exercicios/.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 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/exercicios/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/exercicios/components/Contador.jsx:
--------------------------------------------------------------------------------
1 | import { Component } from "react";
2 |
3 | export default class Contador extends Component {
4 | state = {
5 | numero: this.props.valorInicial ?? 0,
6 | passo: this.props.passo ?? 1
7 | }
8 |
9 | inc = () => {
10 | this.setState({
11 | numero: this.state.numero + this.state.passo
12 | })
13 | }
14 |
15 | dec = () => {
16 | this.setState({
17 | numero: this.state.numero - this.state.passo
18 | })
19 | }
20 |
21 | alterarPasso = (ev) => {
22 | this.setState({ passo: +ev.target.value })
23 | }
24 |
25 | renderForm() {
26 | return (
27 | <>
28 |
31 |
32 |
33 | >
34 | )
35 | }
36 |
37 | render() {
38 | return (
39 |
40 |
Contador (usando Classe)
41 | {this.state.numero}
42 | {this.renderForm()}
43 |
44 | )
45 | }
46 | }
47 |
48 | // export default Contador
--------------------------------------------------------------------------------
/exercicios/components/Estilo.jsx:
--------------------------------------------------------------------------------
1 | export default function Estilo(props) {
2 |
3 | return (
4 |
5 |
= 0 ? "#2D2" : "#D22",
7 | color: props.color,
8 | textAlign: props.direita ? "right" : "left",
9 | }}>
10 | Texto #01
11 |
12 | = 0 ? "azul" : "vermelho"}>
13 | Texto #02
14 |
15 |
16 | )
17 | }
--------------------------------------------------------------------------------
/exercicios/components/If.jsx:
--------------------------------------------------------------------------------
1 | export default function If(props) {
2 | if(props.teste) {
3 | return props.children
4 | } else {
5 | return null
6 | }
7 | }
--------------------------------------------------------------------------------
/exercicios/components/Item.jsx:
--------------------------------------------------------------------------------
1 | export default function Item(props) {
2 | return (
3 |
4 | {props.conteudo}
5 |
6 | )
7 | }
--------------------------------------------------------------------------------
/exercicios/components/Lista.jsx:
--------------------------------------------------------------------------------
1 | export default function Lista(props) {
2 | return (
3 |
4 |
Lista de Algo
5 |
9 | {props.children}
10 |
11 |
12 | )
13 | }
--------------------------------------------------------------------------------
/exercicios/components/NumeroDisplay.jsx:
--------------------------------------------------------------------------------
1 | export default function NumeroDisplay(props) {
2 | return (
3 |
15 | {props.numero}
16 |
17 | )
18 | }
--------------------------------------------------------------------------------
/exercicios/components/Pessoa.tsx:
--------------------------------------------------------------------------------
1 | interface PessoaProps {
2 | nome: string
3 | idade?: number
4 | }
5 |
6 | export default function Pessoa(props: PessoaProps) {
7 | return (
8 |
9 |
Nome: {props.nome}
10 |
Idade: {props.idade ?? 'Não informada'}
11 |
12 | )
13 | }
--------------------------------------------------------------------------------
/exercicios/components/SomaUm.jsx:
--------------------------------------------------------------------------------
1 | export default function SomaUm(props) {
2 | // props.numero++
3 | return (
4 |
5 |
{props.numero + 1}
6 |
7 | )
8 | }
--------------------------------------------------------------------------------
/exercicios/components/SomentePar.jsx:
--------------------------------------------------------------------------------
1 | export default function SomentePar(props) {
2 | const numeroPar = props.numero % 2 === 0
3 | return (
4 |
5 | {numeroPar ?
6 | {props.numero} :
7 | null
8 | }
9 |
10 | )
11 |
12 | // if(props.numero % 2 === 0) {
13 | // return {props.numero}
14 | // } else {
15 | // return null
16 | // }
17 | }
--------------------------------------------------------------------------------
/exercicios/components/Titulo.jsx:
--------------------------------------------------------------------------------
1 | export default function Titulo(props) {
2 | return props.pequeno ? (
3 | <>
4 | {props.principal}
5 | {props.secundario}
6 | >
7 | ) : (
8 | <>
9 | {props.principal}
10 | {props.secundario}
11 | >
12 | )
13 | }
--------------------------------------------------------------------------------
/exercicios/components/direta/Filho.jsx:
--------------------------------------------------------------------------------
1 | export default function Filho(props) {
2 | return (
3 |
4 |
{props.nome}
5 | {props.familia}
6 |
7 | )
8 | }
--------------------------------------------------------------------------------
/exercicios/components/direta/Pai.jsx:
--------------------------------------------------------------------------------
1 | import Filho from "./Filho";
2 |
3 | export default function Pai(props) {
4 | return (
5 |
6 |
Família {props.familia}
7 |
8 |
9 |
10 |
11 | )
12 | }
--------------------------------------------------------------------------------
/exercicios/components/indireta1/Filho.jsx:
--------------------------------------------------------------------------------
1 | export default function Filho(props) {
2 | //
3 | console.log(props.funcao)
4 | return (
5 |
6 |
Filho
7 |
8 |
13 |
14 | )
15 | }
--------------------------------------------------------------------------------
/exercicios/components/indireta1/Pai.jsx:
--------------------------------------------------------------------------------
1 | import Filho from "./Filho";
2 |
3 | export default function Pai(props) {
4 |
5 | function falarComigo(param1, param2, param3) {
6 | console.log(param1, param2, param3)
7 | }
8 |
9 | return (
10 |
11 |
12 |
13 | )
14 | }
--------------------------------------------------------------------------------
/exercicios/components/modulo/funcionais.jsx:
--------------------------------------------------------------------------------
1 | export function Comp1() {
2 | return (
3 |
4 |
Comp #01
5 |
6 | )
7 | }
8 |
9 | export const Comp2 = function() {
10 | return Comp #02
11 | }
12 |
13 | export default function () {
14 | return (
15 |
16 |
Comp #03
17 |
18 | )
19 | }
20 |
21 | export const Comp4 = () => {
22 | return Comp #04
23 | }
24 |
25 | const Comp5 = () => Comp #05
26 |
27 | const Comp6 = props => (
28 |
29 |
Comp #06 - {props.msg}
30 |
31 | )
32 |
33 | export {
34 | Comp5, Comp6,
35 | }
--------------------------------------------------------------------------------
/exercicios/data/listaProdutos.js:
--------------------------------------------------------------------------------
1 | import Produto from "../model/produto";
2 |
3 | export default [
4 | new Produto(1, "iPad", 7543),
5 | new Produto(2, "Monitor 24", 949),
6 | new Produto(3, "Computador Gamer", 6949),
7 | new Produto(4, "Samsung S20+", 2800),
8 | ]
--------------------------------------------------------------------------------
/exercicios/functions/mega.js:
--------------------------------------------------------------------------------
1 | export function mega(quantidade = 6, numeros = []) {
2 | let qtde = +quantidade
3 | if(qtde < 6 && qtde > 60) {
4 | throw "Quantidade inválida!"
5 | }
6 |
7 | if(numeros.length === qtde) {
8 | return numeros.sort((n1, n2) => n1 - n2)
9 | }
10 |
11 | const numeroAleatorio = parseInt(Math.random() * 60) + 1
12 | if(!numeros.includes(numeroAleatorio)) {
13 | return mega(qtde, [...numeros, numeroAleatorio])
14 | } else {
15 | return mega(qtde, numeros)
16 | }
17 | }
--------------------------------------------------------------------------------
/exercicios/model/produto.js:
--------------------------------------------------------------------------------
1 | export default class Produto {
2 | #id
3 | #nome
4 | #preco
5 |
6 | constructor(id, nome, preco) {
7 | this.#id = id
8 | this.#nome = nome
9 | this.#preco = preco
10 | }
11 |
12 | get id() {
13 | return this.#id
14 | }
15 |
16 | get nome() {
17 | return this.#nome
18 | }
19 |
20 | get preco() {
21 | return this.#preco
22 | }
23 | }
--------------------------------------------------------------------------------
/exercicios/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/exercicios/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercicios",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "next": "10.2.3",
12 | "react": "17.0.2",
13 | "react-dom": "17.0.2"
14 | },
15 | "devDependencies": {
16 | "@types/react": "^17.0.9",
17 | "typescript": "^4.3.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/exercicios/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 | import './css/integracao1.css'
3 |
4 | function MyApp({ Component, pageProps }) {
5 | return
6 | }
7 |
8 | export default MyApp
9 |
--------------------------------------------------------------------------------
/exercicios/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default (req, res) => {
4 | res.status(200).json({ name: 'John Doe' })
5 | }
6 |
--------------------------------------------------------------------------------
/exercicios/pages/basicos/Teste.jsx:
--------------------------------------------------------------------------------
1 | export default function teste() {
2 | return Teste
3 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/botao.jsx:
--------------------------------------------------------------------------------
1 | function acao1() {
2 | console.log("acao1")
3 | }
4 |
5 | export default function botao() {
6 | function acao2() {
7 | console.log("acao2")
8 | }
9 |
10 | function acao5(e) {
11 | console.log(e)
12 | }
13 |
14 | return (
15 |
16 |
17 |
18 |
21 |
24 |
27 |
30 |
31 | console.log(e.target.value)} />
32 |
33 |
34 | )
35 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/componenteComFilho.jsx:
--------------------------------------------------------------------------------
1 | import Item from "../../components/Item";
2 | import Lista from "../../components/Lista";
3 |
4 | export default function componenteComFilho() {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | )
17 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/fragment1.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default function fragment() {
4 | return (
5 |
6 | Título
7 | Subtítulo
8 |
9 | )
10 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/fragment2.jsx:
--------------------------------------------------------------------------------
1 | export default function fragment() {
2 | return (
3 | <>
4 | Título
5 | Subtítulo
6 | >
7 | )
8 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/jsx1.jsx:
--------------------------------------------------------------------------------
1 | // JSX
2 | export default function jsx1Diferente() {
3 | return (
4 |
5 |
JSX #01
6 |
7 | )
8 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/jsx2.jsx:
--------------------------------------------------------------------------------
1 | export default function jsx2() {
2 | const conteudo = (
3 |
4 |
JSX #02
5 |
6 | )
7 | return conteudo
8 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/jsx3.jsx:
--------------------------------------------------------------------------------
1 | export default function jsx3() {
2 | return (
3 |
4 |
JSX #03
5 |
6 | )
7 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/jsx4.jsx:
--------------------------------------------------------------------------------
1 | export default function jsx4() {
2 | const subtitulo = "Estou no JavaScript!"
3 | const trechoH3 = {3 * 3}
4 |
5 | return (
6 |
7 |
Integração JS e JSX
8 | {subtitulo}
9 | {trechoH3}
10 | {Math.max(13, 39)}
11 | {entre(9.6, 1, 10)}
12 |
13 | )
14 | }
15 |
16 | function entre(valor, min, max) {
17 | if(valor >= min && valor <= max) {
18 | return "Sim"
19 | } else {
20 | return "Não"
21 | }
22 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/lista1.jsx:
--------------------------------------------------------------------------------
1 | export default function lista() {
2 | return (
3 |
4 | 1,
5 | 2,
6 | 3,
7 | 4,
8 | 5,
9 | 6,
10 | 7,
11 | 8,
12 | 9,
13 | 10,
14 |
15 | )
16 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/lista2.jsx:
--------------------------------------------------------------------------------
1 | function gerarLista() {
2 | const lista = [
3 | 1,,
4 | 2,,
5 | 3,,
6 | 4,,
7 | 5,,
8 | 6,,
9 | 7,,
10 | 8,,
11 | 9,,
12 | 10,,
13 | ]
14 | return lista
15 | }
16 |
17 | export default function lista() {
18 | return (
19 |
20 | {gerarLista()}
21 |
22 | )
23 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/lista3.jsx:
--------------------------------------------------------------------------------
1 | function gerarLista(final = 10) {
2 | const lista = []
3 | for (let i = 1; i <= final; i++) {
4 | lista.push({i},)
5 | }
6 | return lista
7 | }
8 |
9 | export default function lista() {
10 | return (
11 |
12 |
13 | {gerarLista(20)}
14 |
15 |
16 | {gerarLista(3)}
17 |
18 |
19 | )
20 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/primeiro.jsx:
--------------------------------------------------------------------------------
1 | export default function primeiro() {
2 | return "Primeiro"
3 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/propsSomenteLeitura.jsx:
--------------------------------------------------------------------------------
1 | import SomaUm from "../../components/SomaUm";
2 |
3 | export default function propsSomenteLeitura() {
4 | return
5 | }
--------------------------------------------------------------------------------
/exercicios/pages/basicos/usandoTitulo.jsx:
--------------------------------------------------------------------------------
1 | import Titulo from "../../components/Titulo";
2 |
3 | export default function usandoTitulo() {
4 | return (
5 |
6 |
10 |
15 |
20 |
21 | )
22 | }
--------------------------------------------------------------------------------
/exercicios/pages/classe/contador.jsx:
--------------------------------------------------------------------------------
1 | import { Component } from "react";
2 | import Contador from "../../components/Contador"
3 |
4 | export default class ContadorPage extends Component {
5 |
6 | render() {
7 | return (
8 | <>
9 |
10 | >
11 | )
12 | }
13 | }
--------------------------------------------------------------------------------
/exercicios/pages/comunicacao/direta.jsx:
--------------------------------------------------------------------------------
1 | import Pai from "../../components/direta/Pai";
2 |
3 | export default function direta() {
4 | return (
5 |
8 | )
9 | }
--------------------------------------------------------------------------------
/exercicios/pages/comunicacao/indireta1.jsx:
--------------------------------------------------------------------------------
1 | import Pai from "../../components/indireta1/Pai";
2 |
3 | export default function indireta1() {
4 | return (
5 |
8 | )
9 | }
--------------------------------------------------------------------------------
/exercicios/pages/css/integracao1.css:
--------------------------------------------------------------------------------
1 | .integracao1 .vermelha {
2 | color: #f30;
3 | }
4 |
5 | .integracao1 .azul {
6 | color: #03a;
7 | }
8 |
9 | .integracao1 .branca {
10 | background-color: #444;
11 | color: #fff;
12 | }
--------------------------------------------------------------------------------
/exercicios/pages/css/integracao1.jsx:
--------------------------------------------------------------------------------
1 | // Não posso importar aqui!
2 | // O import foi feito dentro de _app.js
3 |
4 | export default function integracao() {
5 | return (
6 |
7 |
Texto #01
8 |
Texto #02
9 |
Texto #03
10 |
11 | )
12 | }
--------------------------------------------------------------------------------
/exercicios/pages/css/integracao2.jsx:
--------------------------------------------------------------------------------
1 | import styles from "./integracao2.module.css"
2 |
3 | export default function integracao2() {
4 | return (
5 |
6 |
Texto #01
7 |
Texto #02
8 |
Texto #03
9 |
10 | )
11 | }
--------------------------------------------------------------------------------
/exercicios/pages/css/integracao2.module.css:
--------------------------------------------------------------------------------
1 | #integracao2 {
2 | height: 100vh;
3 | display: flex;
4 | flex-direction: column;
5 | justify-content: center;
6 | align-items: center;
7 | }
8 |
9 | .vermelha {
10 | color: #f30;
11 | }
12 |
13 | .azul {
14 | color: #03a;
15 | }
16 |
17 | .branca {
18 | background-color: #444;
19 | color: #fff;
20 | }
--------------------------------------------------------------------------------
/exercicios/pages/css/usandoEstilo.jsx:
--------------------------------------------------------------------------------
1 | import Estilo from "../../components/Estilo";
2 |
3 | export default function usandoEstilo() {
4 | return (
5 |
6 |
7 |
8 |
9 | )
10 | }
--------------------------------------------------------------------------------
/exercicios/pages/estado/contador.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 | import NumeroDisplay from "../../components/NumeroDisplay"
3 |
4 | export default function contador() {
5 | const [numero, setNumero] = useState(0)
6 |
7 | const dec = () => setNumero(numero - 1)
8 |
9 | return (
10 |
16 |
Contador
17 |
18 |
19 |
20 |
21 |
22 |
23 | )
24 | }
--------------------------------------------------------------------------------
/exercicios/pages/estado/formulario.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 |
3 | export default function formulario() {
4 | const [valor, setValor] = useState("")
5 |
6 | function alterarInput() {
7 | setValor(valor + "!")
8 | }
9 |
10 | return (
11 |
15 | {valor}
16 | setValor(e.target.value)} />
18 |
19 |
20 | )
21 | }
--------------------------------------------------------------------------------
/exercicios/pages/estado/megasena.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react"
2 | import NumeroDisplay from "../../components/NumeroDisplay"
3 | import { mega } from "../../functions/mega"
4 |
5 | export default function megasena() {
6 |
7 | const [qtde, setQtde] = useState(6)
8 | const [numeros, setNumeros] = useState([])
9 |
10 | useEffect(() => {
11 | setNumeros(mega())
12 | }, [])
13 |
14 | function renderizarNumeros() {
15 | return numeros.map(
16 | numero =>
17 | )
18 | }
19 |
20 | return (
21 |
26 |
Mega Sena
27 |
32 | {renderizarNumeros()}
33 |
34 |
35 | setQtde(+ev.target.value)} />
37 |
40 |
41 |
42 | )
43 | }
--------------------------------------------------------------------------------
/exercicios/pages/estado/mouse.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 |
3 | export default function mouse() {
4 | // React Hooks
5 | const [x, setX] = useState(0)
6 |
7 | const arrayY = useState(0)
8 | let y = arrayY[0]
9 | const alterarY = arrayY[1]
10 |
11 | const estilo = {
12 | display: "flex",
13 | flexDirection: "column",
14 | justifyContent: "center",
15 | alignItems: "center",
16 | backgroundColor: "#222",
17 | color: "#fff",
18 | height: "100vh"
19 | }
20 |
21 | function quandoMover(ev) {
22 | setX(ev.clientX)
23 | alterarY(ev.clientY)
24 | }
25 |
26 | return (
27 |
28 | Eixo X: {x}
29 | Eixo Y: {y}
30 |
31 | )
32 | }
--------------------------------------------------------------------------------
/exercicios/pages/index.jsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import Image from 'next/image'
3 | import styles from '../styles/Home.module.css'
4 |
5 | export default function Home() {
6 | return (
7 |
8 |
9 |
Create Next App
10 |
11 |
12 |
13 |
14 |
15 |
16 | Welcome to Next.js!
17 |
18 |
19 |
20 | Get started by editing{' '}
21 | pages/index.js
22 |
23 |
24 |
53 |
54 |
55 |
67 |
68 | )
69 | }
70 |
--------------------------------------------------------------------------------
/exercicios/pages/modulo/teste.jsx:
--------------------------------------------------------------------------------
1 | import
2 | Padrao, { Comp1 as Blabla, Comp2, Comp4, Comp5, Comp6 }
3 | from "../../components/modulo/funcionais"
4 |
5 | export default function teste() {
6 | return (
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | )
16 | }
--------------------------------------------------------------------------------
/exercicios/pages/render/condicional1.jsx:
--------------------------------------------------------------------------------
1 | import SomentePar from "../../components/SomentePar";
2 |
3 | export default function condicional1() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | )
18 | }
--------------------------------------------------------------------------------
/exercicios/pages/render/condicional2.jsx:
--------------------------------------------------------------------------------
1 | import If from "../../components/If";
2 |
3 | export default function condicional1() {
4 | const numero = 5
5 | return (
6 |
7 |
8 | O número {numero} é par
9 |
10 |
11 | O número {numero} é ímpar
12 |
13 |
14 | )
15 | }
--------------------------------------------------------------------------------
/exercicios/pages/render/repeticao1.jsx:
--------------------------------------------------------------------------------
1 | export default function repeticao1() {
2 | const listaAprovados = [
3 | 'João',
4 | 'Maria',
5 | 'Ana',
6 | 'Bia',
7 | 'Carlos',
8 | 'Daniel',
9 | 'Laura',
10 | ]
11 |
12 | function renderizarLista() {
13 | return listaAprovados.map(function(nome, i) {
14 | return {nome}
15 | })
16 | }
17 |
18 | return (
19 |
20 | {renderizarLista()}
21 |
22 | )
23 | }
24 |
25 |
26 | // function renderizarLista() {
27 | // const itens = []
28 |
29 | // for (let i = 0; i < listaAprovados.length; i++) {
30 | // itens.push({listaAprovados[i]})
31 | // }
32 |
33 | // return itens
34 | // }
--------------------------------------------------------------------------------
/exercicios/pages/render/repeticao2.jsx:
--------------------------------------------------------------------------------
1 | import listaProdutos from '../../data/listaProdutos'
2 |
3 | export default function repeticao2() {
4 |
5 | const comBorda = {
6 | border: "1px solid #000",
7 | }
8 |
9 | function renderizarLinhas() {
10 | return listaProdutos.map(produto => {
11 | return (
12 |
13 | {produto.id} |
14 | {produto.nome} |
15 | {produto.preco} |
16 |
17 | )
18 | })
19 | }
20 |
21 |
22 |
23 | return (
24 |
25 |
26 |
27 |
28 | Código |
29 | Nome |
30 | Preço |
31 |
32 |
33 |
34 | {renderizarLinhas()}
35 |
36 |
37 |
38 | )
39 | }
--------------------------------------------------------------------------------
/exercicios/pages/ts/exemplo.tsx:
--------------------------------------------------------------------------------
1 | import Pessoa from "../../components/Pessoa";
2 |
3 | export default function exemploTS() {
4 | return (
5 |
9 | )
10 | }
--------------------------------------------------------------------------------
/exercicios/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod3rcursos/curso-nextjs/5c35f41e4da8c20753b5eca2827bcbba2bb31ce6/exercicios/public/favicon.ico
--------------------------------------------------------------------------------
/exercicios/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/exercicios/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | min-height: 100vh;
3 | padding: 0 0.5rem;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | align-items: center;
8 | height: 100vh;
9 | }
10 |
11 | .main {
12 | padding: 5rem 0;
13 | flex: 1;
14 | display: flex;
15 | flex-direction: column;
16 | justify-content: center;
17 | align-items: center;
18 | }
19 |
20 | .footer {
21 | width: 100%;
22 | height: 100px;
23 | border-top: 1px solid #eaeaea;
24 | display: flex;
25 | justify-content: center;
26 | align-items: center;
27 | }
28 |
29 | .footer a {
30 | display: flex;
31 | justify-content: center;
32 | align-items: center;
33 | flex-grow: 1;
34 | }
35 |
36 | .title a {
37 | color: #0070f3;
38 | text-decoration: none;
39 | }
40 |
41 | .title a:hover,
42 | .title a:focus,
43 | .title a:active {
44 | text-decoration: underline;
45 | }
46 |
47 | .title {
48 | margin: 0;
49 | line-height: 1.15;
50 | font-size: 4rem;
51 | }
52 |
53 | .title,
54 | .description {
55 | text-align: center;
56 | }
57 |
58 | .description {
59 | line-height: 1.5;
60 | font-size: 1.5rem;
61 | }
62 |
63 | .code {
64 | background: #fafafa;
65 | border-radius: 5px;
66 | padding: 0.75rem;
67 | font-size: 1.1rem;
68 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
69 | Bitstream Vera Sans Mono, Courier New, monospace;
70 | }
71 |
72 | .grid {
73 | display: flex;
74 | align-items: center;
75 | justify-content: center;
76 | flex-wrap: wrap;
77 | max-width: 800px;
78 | margin-top: 3rem;
79 | }
80 |
81 | .card {
82 | margin: 1rem;
83 | padding: 1.5rem;
84 | text-align: left;
85 | color: inherit;
86 | text-decoration: none;
87 | border: 1px solid #eaeaea;
88 | border-radius: 10px;
89 | transition: color 0.15s ease, border-color 0.15s ease;
90 | width: 45%;
91 | }
92 |
93 | .card:hover,
94 | .card:focus,
95 | .card:active {
96 | color: #0070f3;
97 | border-color: #0070f3;
98 | }
99 |
100 | .card h2 {
101 | margin: 0 0 1rem 0;
102 | font-size: 1.5rem;
103 | }
104 |
105 | .card p {
106 | margin: 0;
107 | font-size: 1.25rem;
108 | line-height: 1.5;
109 | }
110 |
111 | .logo {
112 | height: 1em;
113 | margin-left: 0.5rem;
114 | }
115 |
116 | @media (max-width: 600px) {
117 | .grid {
118 | width: 100%;
119 | flex-direction: column;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/exercicios/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | }
8 |
9 | a {
10 | color: inherit;
11 | text-decoration: none;
12 | }
13 |
14 | * {
15 | box-sizing: border-box;
16 | }
17 |
18 | .azul {
19 | background-color: dodgerblue;
20 | }
21 |
22 | .vermelho {
23 | background-color: crimson;
24 | }
--------------------------------------------------------------------------------
/exercicios/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": false,
12 | "forceConsistentCasingInFileNames": true,
13 | "noEmit": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "jsx": "preserve"
20 | },
21 | "include": [
22 | "next-env.d.ts",
23 | "**/*.ts",
24 | "**/*.tsx"
25 | ],
26 | "exclude": [
27 | "node_modules"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/next-basico/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next", "next/core-web-vitals"]
3 | }
4 |
--------------------------------------------------------------------------------
/next-basico/.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 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/next-basico/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/next-basico/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | reactStrictMode: true,
3 | }
4 |
--------------------------------------------------------------------------------
/next-basico/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-basico",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "next": "11.0.0",
13 | "react": "17.0.2",
14 | "react-dom": "17.0.2"
15 | },
16 | "devDependencies": {
17 | "eslint": "7.28.0",
18 | "eslint-config-next": "11.0.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/next-basico/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod3rcursos/curso-nextjs/5c35f41e4da8c20753b5eca2827bcbba2bb31ce6/next-basico/public/favicon.ico
--------------------------------------------------------------------------------
/next-basico/public/images/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/next-basico/src/pages/_app.jsx:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return
5 | }
6 |
7 | export default MyApp
8 |
--------------------------------------------------------------------------------
/next-basico/src/pages/_outraRota.jsx:
--------------------------------------------------------------------------------
1 | export default function OutraRota() {
2 | return (
3 |
4 |
_Outra Rota
5 |
6 | )
7 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/api/form.js:
--------------------------------------------------------------------------------
1 | const usuarios = []
2 |
3 | export default function form(req, res) {
4 | if (req.method === "POST") {
5 | post(req, res)
6 | } else if (req.method === "GET") {
7 | get(req, res)
8 | } else {
9 | res.status(405).send()
10 | }
11 |
12 | }
13 |
14 | function post(req, res) {
15 | const usuario = JSON.parse(req.body)
16 | usuarios.push(usuario)
17 | res.status(200).send()
18 | }
19 |
20 | function get(req, res) {
21 | res.status(200).json(usuarios)
22 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default function hello(req, res) {
4 | res.status(200).json([
5 | { name: 'John Doe' },
6 | { name: 'Joana' },
7 | { name: 'Maria' },
8 | { name: 'Pedro' },
9 | ])
10 | }
11 |
--------------------------------------------------------------------------------
/next-basico/src/pages/api/metodo.js:
--------------------------------------------------------------------------------
1 | const metodo = (req, res) => {
2 | if(req.method === "GET") {
3 | res.status(200).json({ nome: "Pedro" })
4 | } else {
5 | res.status(200).json({ nome: "Maria" })
6 | }
7 | }
8 |
9 | export default metodo
--------------------------------------------------------------------------------
/next-basico/src/pages/api/params/[[...array]].js:
--------------------------------------------------------------------------------
1 | export default function params(req, res) {
2 | res.status(200).json({
3 | params: req.query
4 | })
5 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/api/questao/[id].js:
--------------------------------------------------------------------------------
1 | export default function questao(req, res) {
2 | if (req.method === "GET") {
3 | get(req, res)
4 | } else {
5 | res.status(405).send()
6 | }
7 | }
8 |
9 | function get(req, res) {
10 | const id = req.query.id
11 | res.status(200).json({
12 | id,
13 | enunciado: 'Qual é a sua cor preferida?',
14 | respostas: [
15 | 'Branca', 'Vermelha', 'Amarela', 'Verde'
16 | ]
17 | })
18 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/estatico.jsx:
--------------------------------------------------------------------------------
1 | export function getStaticProps() {
2 | return {
3 | props: {
4 | numero: Math.random()
5 | }
6 | }
7 | }
8 |
9 | export default function Estatico(props) {
10 | return (
11 |
12 | Aleatório: {props.numero}
13 |
14 | )
15 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/form.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 |
3 | export default function Form(props) {
4 | const [nome, setNome] = useState("")
5 | const [idade, setIdade] = useState(0)
6 | const [usuarios, setUsuarios] = useState([])
7 |
8 | async function salvarUsuario() {
9 | await fetch('/api/form', {
10 | method: 'POST',
11 | body: JSON.stringify({ nome, idade })
12 | })
13 |
14 | setNome("")
15 | setIdade(0)
16 |
17 | const resp = await fetch('/api/form')
18 | const usuarios = await resp.json()
19 | setUsuarios(usuarios)
20 | }
21 |
22 | function renderizarUsuarios() {
23 | return usuarios.map((usuario, i) => {
24 | return {usuario.nome} tem {usuario.idade} anos
25 | })
26 | }
27 |
28 | return (
29 |
30 |
Integrando com API #02
31 |
setNome(e.target.value)}/>
33 |
setIdade(+e.target.value)} />
35 |
36 |
37 |
38 | {renderizarUsuarios()}
39 |
40 |
41 | )
42 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/index.jsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import Image from 'next/image'
3 | import styles from '../styles/Home.module.css'
4 |
5 | export default function Home() {
6 | return (
7 |
8 |
9 |
Recursos Básicos do NextJS
10 |
11 |
12 |
13 |
14 |
15 |
16 | Welcome to Next.js!
17 |
18 |
19 |
20 | Get started by editing{' '}
21 | pages/index.js
22 |
23 |
24 |
53 |
54 |
55 |
67 |
68 | )
69 | }
70 |
--------------------------------------------------------------------------------
/next-basico/src/pages/outraRota.jsx:
--------------------------------------------------------------------------------
1 | export default function OutraRota() {
2 | return (
3 |
4 |
Outra Rota
5 |
6 | )
7 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/questao.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react"
2 |
3 | export default function Questao() {
4 | const [questao, setQuestao] = useState(null)
5 |
6 | useEffect(() => {
7 | fetch('http://localhost:3000/api/questao/123')
8 | .then(resp => resp.json())
9 | .then(setQuestao)
10 | }, [])
11 |
12 | function renderizarRespostas() {
13 | if(questao) {
14 | return questao.respostas.map((resp, i) => {
15 | return {resp}
16 | })
17 | }
18 | return false
19 | }
20 |
21 | return (
22 |
23 |
Questão
24 |
25 |
{questao?.id} - {questao?.enunciado}
26 |
27 | {renderizarRespostas()}
28 |
29 |
30 |
31 | )
32 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/rotas/[codigo]/[nome].jsx:
--------------------------------------------------------------------------------
1 | import { useRouter } from 'next/router'
2 | import Link from 'next/link'
3 |
4 | export default function CodigoENome() {
5 | const router = useRouter()
6 | const codigo = router.query.codigo
7 | const nome = router.query.nome
8 |
9 | return (
10 |
11 |
Rotas / {codigo} / {nome}
12 |
13 |
14 |
15 |
16 | )
17 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/rotas/[codigo]/buscar.jsx:
--------------------------------------------------------------------------------
1 | import { useRouter } from 'next/router'
2 | import Link from 'next/link'
3 |
4 | export default function Buscar() {
5 | const router = useRouter()
6 | const codigo = router.query.codigo
7 |
8 |
9 | return (
10 |
18 | )
19 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/rotas/index.jsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import router from 'next/router'
3 |
4 | export default function Rotas() {
5 |
6 | function navegacaoSimples(url) {
7 | router.push(url)
8 | }
9 |
10 | function navegacaoComParams() {
11 | router.push({
12 | pathname: "/rotas/params",
13 | query: {
14 | id: 123,
15 | nome: 'Ana Silva'
16 | }
17 | })
18 | }
19 |
20 | return (
21 |
22 |
Rotas Index
23 |
24 |
25 | - Params
26 |
27 |
28 | - Buscar
29 |
30 |
31 | - Daniel
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | )
41 | }
--------------------------------------------------------------------------------
/next-basico/src/pages/rotas/params.jsx:
--------------------------------------------------------------------------------
1 | import { useRouter } from 'next/router'
2 | import Link from 'next/link'
3 |
4 | export default function Params() {
5 | const router = useRouter()
6 |
7 | const id = router.query.id
8 | const nome = router.query.nome
9 |
10 | return (
11 |
12 |
Rotas Params: {id} e {nome}
13 |
14 |
15 |
16 |
17 | )
18 | }
--------------------------------------------------------------------------------
/next-basico/src/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | min-height: 100vh;
3 | padding: 0 0.5rem;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | align-items: center;
8 | height: 100vh;
9 | }
10 |
11 | .main {
12 | padding: 5rem 0;
13 | flex: 1;
14 | display: flex;
15 | flex-direction: column;
16 | justify-content: center;
17 | align-items: center;
18 | }
19 |
20 | .footer {
21 | width: 100%;
22 | height: 100px;
23 | border-top: 1px solid #eaeaea;
24 | display: flex;
25 | justify-content: center;
26 | align-items: center;
27 | }
28 |
29 | .footer a {
30 | display: flex;
31 | justify-content: center;
32 | align-items: center;
33 | flex-grow: 1;
34 | }
35 |
36 | .title a {
37 | color: #0070f3;
38 | text-decoration: none;
39 | }
40 |
41 | .title a:hover,
42 | .title a:focus,
43 | .title a:active {
44 | text-decoration: underline;
45 | }
46 |
47 | .title {
48 | margin: 0;
49 | line-height: 1.15;
50 | font-size: 4rem;
51 | }
52 |
53 | .title,
54 | .description {
55 | text-align: center;
56 | }
57 |
58 | .description {
59 | line-height: 1.5;
60 | font-size: 1.5rem;
61 | }
62 |
63 | .code {
64 | background: #fafafa;
65 | border-radius: 5px;
66 | padding: 0.75rem;
67 | font-size: 1.1rem;
68 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
69 | Bitstream Vera Sans Mono, Courier New, monospace;
70 | }
71 |
72 | .grid {
73 | display: flex;
74 | align-items: center;
75 | justify-content: center;
76 | flex-wrap: wrap;
77 | max-width: 800px;
78 | margin-top: 3rem;
79 | }
80 |
81 | .card {
82 | margin: 1rem;
83 | padding: 1.5rem;
84 | text-align: left;
85 | color: inherit;
86 | text-decoration: none;
87 | border: 1px solid #eaeaea;
88 | border-radius: 10px;
89 | transition: color 0.15s ease, border-color 0.15s ease;
90 | width: 45%;
91 | }
92 |
93 | .card:hover,
94 | .card:focus,
95 | .card:active {
96 | color: #0070f3;
97 | border-color: #0070f3;
98 | }
99 |
100 | .card h2 {
101 | margin: 0 0 1rem 0;
102 | font-size: 1.5rem;
103 | }
104 |
105 | .card p {
106 | margin: 0;
107 | font-size: 1.25rem;
108 | line-height: 1.5;
109 | }
110 |
111 | .logo {
112 | height: 1em;
113 | margin-left: 0.5rem;
114 | }
115 |
116 | @media (max-width: 600px) {
117 | .grid {
118 | width: 100%;
119 | flex-direction: column;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/next-basico/src/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | background-color: #222;
6 | color: #ddd;
7 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
8 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
9 | }
10 |
11 | a {
12 | color: inherit;
13 | text-decoration: none;
14 | }
15 |
16 | * {
17 | box-sizing: border-box;
18 | }
19 |
--------------------------------------------------------------------------------
/portas/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next", "next/core-web-vitals"]
3 | }
4 |
--------------------------------------------------------------------------------
/portas/.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 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/portas/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/portas/components/Cartao.tsx:
--------------------------------------------------------------------------------
1 | import styles from "../styles/Cartao.module.css"
2 |
3 | interface CartaoProps {
4 | bgcolor?: string
5 | children?: any
6 | }
7 |
8 | export default function Cartao(props: CartaoProps) {
9 | return (
10 |
14 | {props.children}
15 |
16 | )
17 | }
--------------------------------------------------------------------------------
/portas/components/EntradaNumerica.tsx:
--------------------------------------------------------------------------------
1 | import styles from "../styles/EntradaNumerica.module.css"
2 |
3 | interface EntradaNumericaProps {
4 | text: string
5 | value: number
6 | onChange: (newValue: number) => void
7 | }
8 |
9 | export default function EntradaNumerica(props: EntradaNumericaProps) {
10 | const dec = () => props.onChange(props.value - 1)
11 | const inc = () => props.onChange(props.value + 1)
12 |
13 | return (
14 |
15 |
{props.text}
16 |
{props.value}
17 |
18 |
19 |
20 |
21 |
22 | )
23 | }
--------------------------------------------------------------------------------
/portas/components/Porta.tsx:
--------------------------------------------------------------------------------
1 | import styles from "../styles/Porta.module.css"
2 | import Presente from './Presente'
3 | import PortaModel from '../model/porta'
4 |
5 | interface PortaProps {
6 | value: PortaModel
7 | onChange: (novaPorta: PortaModel) => void
8 | }
9 |
10 | export default function Porta(props: PortaProps) {
11 | const porta = props.value
12 | const selecionada = porta.selecionada && !porta.aberta ? styles.selecionada : ''
13 |
14 | const alternarSelecao = e => props.onChange(porta.alternarSelecao())
15 | const abrir = e => {
16 | e.stopPropagation()
17 | props.onChange(porta.abrir())
18 | }
19 |
20 | function renderizarPorta() {
21 | return (
22 |
23 |
{porta.numero}
24 |
26 |
27 | )
28 | }
29 |
30 | return (
31 |
32 |
33 | {porta.fechada ?
34 | renderizarPorta() :
35 | porta.temPresente ?
: false
36 | }
37 |
38 |
39 |
40 | )
41 | }
--------------------------------------------------------------------------------
/portas/components/Presente.tsx:
--------------------------------------------------------------------------------
1 | import styles from "../styles/Presente.module.css"
2 |
3 | export default function Presente() {
4 | return (
5 |
11 | )
12 | }
--------------------------------------------------------------------------------
/portas/functions/portas.ts:
--------------------------------------------------------------------------------
1 | import PortaModel from "../model/porta";
2 |
3 | export function criarPortas(qtde: number, portaComPresente: number): PortaModel[] {
4 | return Array.from({ length: qtde }, (_, i) => {
5 | const numero = i + 1
6 | const temPresente = numero === portaComPresente
7 | return new PortaModel(numero, temPresente)
8 | })
9 | }
10 |
11 | export function atualizarPortas(portas: PortaModel[], portaModificada: PortaModel): PortaModel[] {
12 | return portas.map(portaAtual => {
13 | const igualAModificada = portaAtual.numero === portaModificada.numero
14 |
15 | if(igualAModificada) {
16 | return portaModificada
17 | } else {
18 | return portaModificada.aberta ? portaAtual : portaAtual.desselecionar()
19 | }
20 | })
21 | }
--------------------------------------------------------------------------------
/portas/model/porta.ts:
--------------------------------------------------------------------------------
1 | export default class PortaModel {
2 | #numero: number
3 | #temPresente: boolean
4 | #selecionada: boolean
5 | #aberta: boolean
6 |
7 | constructor(numero: number, temPresente = false, selecionada = false, aberta = false) {
8 | this.#numero = numero
9 | this.#temPresente = temPresente
10 | this.#selecionada = selecionada
11 | this.#aberta = aberta
12 | }
13 |
14 | get numero() {
15 | return this.#numero
16 | }
17 |
18 | get temPresente() {
19 | return this.#temPresente
20 | }
21 |
22 | get selecionada() {
23 | return this.#selecionada
24 | }
25 |
26 | get aberta() {
27 | return this.#aberta
28 | }
29 |
30 | get fechada() {
31 | return !this.aberta
32 | }
33 |
34 | desselecionar() {
35 | const selecionada = false
36 | return new PortaModel(this.numero, this.temPresente, selecionada, this.aberta)
37 | }
38 |
39 | alternarSelecao() {
40 | const selecionada = !this.selecionada
41 | return new PortaModel(this.numero, this.temPresente, selecionada, this.aberta)
42 | }
43 |
44 | abrir() {
45 | const aberta = true
46 | return new PortaModel(this.numero, this.temPresente, this.selecionada, aberta)
47 | }
48 | }
--------------------------------------------------------------------------------
/portas/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/portas/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | reactStrictMode: true,
3 | }
4 |
--------------------------------------------------------------------------------
/portas/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "portas",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "next": "11.0.0",
13 | "react": "17.0.2",
14 | "react-dom": "17.0.2"
15 | },
16 | "devDependencies": {
17 | "@types/react": "^17.0.11",
18 | "eslint": "7.28.0",
19 | "eslint-config-next": "11.0.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/portas/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return
5 | }
6 |
7 | export default MyApp
8 |
--------------------------------------------------------------------------------
/portas/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | const hello = (req, res) => {
4 | res.status(200).json({ name: 'John Doe' })
5 | }
6 |
7 | export default hello
8 |
--------------------------------------------------------------------------------
/portas/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import styles from "../styles/Formulario.module.css"
2 | import Cartao from "../components/Cartao";
3 | import Link from "next/link"
4 | import EntradaNumerica from "../components/EntradaNumerica";
5 | import { useState } from "react";
6 |
7 | export default function Formulario() {
8 | const [qtdePortas, setQtdePortas] = useState(3)
9 | const [comPresente, setComPresente] = useState(1)
10 |
11 | return (
12 |
13 |
14 |
15 | Monty Hall
16 |
17 |
18 | setQtdePortas(novaQtde)} />
21 |
22 |
23 |
24 |
25 | setComPresente(novaPortaComPresente)} />
28 |
29 |
30 |
31 | Iniciar
32 |
33 |
34 |
35 |
36 | )
37 | }
38 |
--------------------------------------------------------------------------------
/portas/pages/jogo/[portas]/[temPresente].tsx:
--------------------------------------------------------------------------------
1 | import styles from "../../../styles/Jogo.module.css"
2 | import { useEffect, useState } from "react"
3 | import Porta from "../../../components/Porta"
4 | import { atualizarPortas, criarPortas } from "../../../functions/portas"
5 | import Link from "next/link"
6 | import { useRouter } from "next/router"
7 |
8 | export default function Jogo() {
9 | const router = useRouter()
10 |
11 | const [valido, setValido] = useState(false)
12 | const [portas, setPortas] = useState([])
13 |
14 | useEffect(() => {
15 | const portas = +router.query.portas
16 | const temPresente = +router.query.temPresente
17 |
18 | const qtdePortasValida = portas >= 3 && portas <= 100
19 | const temPresenteValido = temPresente >= 1 && temPresente <= portas
20 |
21 | setValido(qtdePortasValida && temPresenteValido)
22 | }, [portas, router.query.portas, router.query.temPresente])
23 |
24 | useEffect(() => {
25 | const portas = +router.query.portas
26 | const temPresente = +router.query.temPresente
27 | setPortas(criarPortas(portas, temPresente))
28 | }, [router?.query])
29 |
30 | function renderizarPortas() {
31 | return portas.map(porta => {
32 | return setPortas(atualizarPortas(portas, novaPorta))} />
34 | })
35 | }
36 | return (
37 |
38 |
39 | {valido ?
40 | renderizarPortas() :
41 |
Valores inválidos
42 | }
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | )
51 | }
--------------------------------------------------------------------------------
/portas/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod3rcursos/curso-nextjs/5c35f41e4da8c20753b5eca2827bcbba2bb31ce6/portas/public/favicon.ico
--------------------------------------------------------------------------------
/portas/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/portas/styles/Cartao.module.css:
--------------------------------------------------------------------------------
1 | .cartao {
2 | display: flex;
3 | width: 300px;
4 | height: 300px;
5 | color: #fff;
6 | font-size: 2rem;
7 | padding: 20px;
8 | margin: 3px;
9 | }
--------------------------------------------------------------------------------
/portas/styles/EntradaNumerica.module.css:
--------------------------------------------------------------------------------
1 | .entradaNumerica {
2 | display: flex;
3 | flex: 1;
4 | flex-direction: column;
5 | align-items: center;
6 | justify-content: center;
7 | color: #000;
8 | }
9 |
10 | .text {
11 | color: #555;
12 | font-size: 1.5rem;
13 | }
14 |
15 | .value {
16 | font-size: 6rem;
17 | }
18 |
19 | .botoes {
20 | display: flex;
21 | }
22 |
23 | .btn {
24 | display: flex;
25 | justify-content: center;
26 | align-items: center;
27 | font-size: 3rem;
28 | height: 80px;
29 | width: 80px;
30 | margin: 5px;
31 | border: none;
32 | }
--------------------------------------------------------------------------------
/portas/styles/Formulario.module.css:
--------------------------------------------------------------------------------
1 | .formulario {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: center;
5 | align-items: center;
6 | height: 100vh;
7 | }
8 |
9 | .formulario > div {
10 | display: flex;
11 | }
12 |
13 | .link {
14 | display: flex;
15 | justify-content: center;
16 | align-items: center;
17 | flex: 1;
18 | margin: 0;
19 | cursor: pointer;
20 | }
--------------------------------------------------------------------------------
/portas/styles/Jogo.module.css:
--------------------------------------------------------------------------------
1 | #jogo {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: center;
5 | align-items: center;
6 | height: 100vh;
7 | }
8 |
9 | .portas {
10 | display: flex;
11 | align-self: stretch;
12 | justify-content: space-around;
13 | flex-wrap: wrap;
14 | }
15 |
16 | .botoes {
17 | display: flex;
18 | justify-content: center;
19 | margin-top: 40px;
20 | }
21 |
22 | .botoes button {
23 | background-color: #c0392c;
24 | color: #fff;
25 | font-size: 2rem;
26 | border: none;
27 | padding: 10px 25px;
28 | }
--------------------------------------------------------------------------------
/portas/styles/Porta.module.css:
--------------------------------------------------------------------------------
1 | .area {
2 | position: relative;
3 | display: flex;
4 | flex-direction: column;
5 | align-items: center;
6 | width: var(--area-porta-largura);
7 | height: var(--area-porta-altura);
8 | margin: 5px;
9 | }
10 |
11 | .estrutura {
12 | display: flex;
13 | flex-direction: column-reverse;
14 | flex-grow: 1;
15 | border-left: 5px solid brown;
16 | border-top: 5px solid brown;
17 | border-right: 5px solid brown;
18 | background-color: #0005;
19 | width: 90%;
20 | }
21 |
22 | .porta {
23 | display: flex;
24 | flex-direction: column;
25 | align-items: center;
26 | flex-grow: 1;
27 | background-color: chocolate;
28 | padding: 15px;
29 | }
30 |
31 | .numero {
32 | font-size: 3rem;
33 | }
34 |
35 | .macaneta {
36 | position: absolute;
37 |
38 | align-self: flex-start;
39 | top: calc(0.45 * var(--area-porta-altura));
40 | height: 20px;
41 | width: 20px;
42 | border-radius: 10px;
43 | background-color: brown;
44 | }
45 |
46 | .chao {
47 | height: 10px;
48 | width: 100%;
49 | background-color: #ddd;
50 | }
51 |
52 | .selecionada {
53 | border-left: 5px solid yellow;
54 | border-top: 5px solid yellow;
55 | border-right: 5px solid yellow;
56 | }
57 |
58 | .selecionada .numero {
59 | color: yellow;
60 | }
61 |
62 | .selecionada .macaneta {
63 | background-color: yellow;
64 | }
--------------------------------------------------------------------------------
/portas/styles/Presente.module.css:
--------------------------------------------------------------------------------
1 | .presente {
2 | position: relative;
3 | display: flex;
4 | flex-direction: column;
5 | align-items: center;
6 | }
7 |
8 | .tampa {
9 | width: 100px;
10 | height: 25px;
11 | background-color: #7aa944;
12 | }
13 |
14 | .corpo {
15 | width: 90px;
16 | height: 60px;
17 | background-color: #5c7e32;
18 | }
19 |
20 | .laco1 {
21 | position: absolute;
22 | width: 15px;
23 | height: 85px;
24 | background-color: red;
25 | }
26 |
27 | .laco2 {
28 | position: absolute;
29 | top: 40px;
30 | width: 90px;
31 | height: 15px;
32 | background-color: red;
33 | }
--------------------------------------------------------------------------------
/portas/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | background-color: #444;
8 | color: #fff;
9 | }
10 |
11 | a {
12 | color: inherit;
13 | text-decoration: none;
14 | }
15 |
16 | * {
17 | box-sizing: border-box;
18 | }
19 |
20 | :root {
21 | --area-porta-altura: 310px;
22 | --area-porta-largura: 200px;
23 | }
--------------------------------------------------------------------------------
/portas/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": false,
12 | "forceConsistentCasingInFileNames": true,
13 | "noEmit": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "jsx": "preserve"
20 | },
21 | "include": [
22 | "next-env.d.ts",
23 | "**/*.ts",
24 | "**/*.tsx"
25 | ],
26 | "exclude": [
27 | "node_modules"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/quiz/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next", "next/core-web-vitals"]
3 | }
4 |
--------------------------------------------------------------------------------
/quiz/.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 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/quiz/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/quiz/components/Botao.tsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Botao.module.css'
2 | import Link from 'next/link'
3 |
4 | interface BotaoProps {
5 | texto: string
6 | href?: string
7 | onClick?: (e: any) => void
8 | }
9 |
10 |
11 | export default function Botao(props: BotaoProps) {
12 |
13 | function renderizarBotao() {
14 | return (
15 |
19 | )
20 | }
21 |
22 | return props.href ? (
23 |
24 | {renderizarBotao()}
25 |
26 | ) : renderizarBotao()
27 | }
--------------------------------------------------------------------------------
/quiz/components/Enunciado.tsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Enunciado.module.css'
2 |
3 | interface EnunciadoProps {
4 | texto: string
5 | }
6 |
7 | export default function Enunciado(props: EnunciadoProps) {
8 | return (
9 |
10 | {props.texto}
11 |
12 | )
13 | }
--------------------------------------------------------------------------------
/quiz/components/Estatistica.tsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Estatistica.module.css'
2 |
3 | interface EstatisticaProps {
4 | valor: any
5 | texto: string
6 | corFundo?: string
7 | corFonte?: string
8 | }
9 |
10 | export default function Estatistica(props: EstatisticaProps) {
11 | return (
12 |
13 |
17 | {props.valor}
18 |
19 |
20 | {props.texto}
21 |
22 |
23 | )
24 | }
--------------------------------------------------------------------------------
/quiz/components/Questao.tsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Questao.module.css'
2 | import QuestaoModel from '../model/questao'
3 | import Enunciado from './Enunciado'
4 | import Temporizador from './Temporizador'
5 | import Resposta from './Resposta'
6 |
7 | const letras = [
8 | { valor: 'A', cor: '#F2C866' },
9 | { valor: 'B', cor: '#F266BA' },
10 | { valor: 'C', cor: '#85D4F2' },
11 | { valor: 'D', cor: '#BCE596' },
12 | ]
13 |
14 | interface QuestaoProps {
15 | valor: QuestaoModel
16 | tempoPraResposta?: number
17 | respostaFornecida: (indice: number) => void
18 | tempoEsgotado: () => void
19 | }
20 |
21 | export default function Questao(props: QuestaoProps) {
22 | const questao = props.valor
23 |
24 | function renderizarRespostas() {
25 | return questao.respostas.map((resposta, i) => {
26 | return (
27 |
35 | )
36 | })
37 | }
38 |
39 | return (
40 |
41 |
42 |
45 | {renderizarRespostas()}
46 |
47 | )
48 | }
--------------------------------------------------------------------------------
/quiz/components/Questionario.tsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Questionario.module.css'
2 | import Questao from './Questao'
3 | import Botao from './Botao'
4 | import QuestaoModel from "../model/questao"
5 |
6 | interface QuestionarioProps {
7 | questao: QuestaoModel
8 | ultima: boolean
9 | questaoRespondida: (questao: QuestaoModel) => void
10 | irPraProximoPasso: () => void
11 | }
12 |
13 | export default function Questionario(props: QuestionarioProps) {
14 |
15 | function respostaFornecida(indice: number) {
16 | if(props.questao.naoRespondida) {
17 | props.questaoRespondida(props.questao.responderCom(indice))
18 | }
19 | }
20 |
21 | return (
22 |
23 | {props.questao ?
24 |
29 | : false
30 | }
31 |
32 |
34 |
35 | )
36 | }
--------------------------------------------------------------------------------
/quiz/components/Resposta.tsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Resposta.module.css'
2 | import RespostaModel from "../model/resposta";
3 |
4 | interface RespostaProps {
5 | valor: RespostaModel
6 | indice: number
7 | letra: string
8 | corFundoLetra: string
9 | respostaFornecida: (indice: number) => void
10 | }
11 |
12 | export default function Resposta(props: RespostaProps) {
13 | const resposta = props.valor
14 | const respostaRevelada = resposta.revelada ? styles.respostaRevelada : ''
15 | return (
16 | props.respostaFornecida(props.indice)}>
18 |
19 |
20 |
22 | {props.letra}
23 |
24 |
25 | {resposta.valor}
26 |
27 |
28 |
29 | {resposta.certa ? (
30 |
31 |
A resposta certa é...
32 |
{resposta.valor}
33 |
34 | ) : (
35 |
36 |
A resposta informada está errada...
37 |
{resposta.valor}
38 |
39 | )}
40 |
41 |
42 |
43 | )
44 | }
--------------------------------------------------------------------------------
/quiz/components/Temporizador.tsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Temporizador.module.css'
2 |
3 | import { CountdownCircleTimer } from 'react-countdown-circle-timer'
4 |
5 | interface TemporizadorProps {
6 | key: any
7 | duracao: number
8 | tempoEsgotado: () => void
9 | }
10 |
11 | export default function Temporizador(props: TemporizadorProps) {
12 | return (
13 |
14 |
24 | {({ remainingTime }) => remainingTime}
25 |
26 |
27 | )
28 | }
--------------------------------------------------------------------------------
/quiz/functions/arrays.ts:
--------------------------------------------------------------------------------
1 | export function embaralhar(elementos: any[]): any[] {
2 | return elementos
3 | .map(valor => ({ valor, aleatorio: Math.random() }))
4 | .sort((obj1, obj2) => obj1.aleatorio - obj2.aleatorio)
5 | .map(obj => obj.valor)
6 | }
--------------------------------------------------------------------------------
/quiz/model/questao.ts:
--------------------------------------------------------------------------------
1 | import { embaralhar } from "../functions/arrays"
2 | import RespostaModel from "./resposta"
3 |
4 | export default class QuestaoModel {
5 | #id: number
6 | #enunciado: string
7 | #respostas: RespostaModel[]
8 | #acertou: boolean
9 |
10 | constructor(id: number, enunciado: string, respostas: RespostaModel[], acertou = false) {
11 | this.#id = id
12 | this.#enunciado = enunciado
13 | this.#respostas = respostas
14 | this.#acertou = acertou
15 | }
16 |
17 | get id() {
18 | return this.#id
19 | }
20 |
21 | get enunciado() {
22 | return this.#enunciado
23 | }
24 |
25 | get respostas() {
26 | return this.#respostas
27 | }
28 |
29 | get acertou() {
30 | return this.#acertou
31 | }
32 |
33 | get naoRespondida() {
34 | return !this.respondida
35 | }
36 |
37 | get respondida() {
38 | for (let resposta of this.#respostas) {
39 | if (resposta.revelada) return true
40 | }
41 | return false
42 | }
43 |
44 | responderCom(indice: number): QuestaoModel {
45 | const acertou = this.#respostas[indice]?.certa
46 | const respostas = this.#respostas.map((resposta, i) => {
47 | const respostaSelecionada = indice === i
48 | const deveRevelar = respostaSelecionada || resposta.certa
49 | return deveRevelar ? resposta.revelar() : resposta
50 | })
51 | return new QuestaoModel(this.id, this.enunciado, respostas, acertou)
52 | }
53 |
54 | embaralharRespostas(): QuestaoModel {
55 | let respostasEmbaralhadas = embaralhar(this.#respostas)
56 | return new QuestaoModel(this.#id, this.#enunciado, respostasEmbaralhadas, this.#acertou)
57 | }
58 |
59 | static criarUsandoObjeto(obj: QuestaoModel): QuestaoModel {
60 | const respostas = obj.respostas.map(resp => RespostaModel.criarUsandoObjeto(resp))
61 | return new QuestaoModel(obj.id, obj.enunciado, respostas, obj.acertou)
62 | }
63 |
64 | paraObjeto() {
65 | return {
66 | id: this.#id,
67 | enunciado: this.#enunciado,
68 | respondida: this.respondida,
69 | acertou: this.#acertou,
70 | respostas: this.#respostas.map(resp => resp.paraObjeto()),
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/quiz/model/resposta.ts:
--------------------------------------------------------------------------------
1 | export default class RespostaModel {
2 | #valor: string
3 | #certa: boolean
4 | #revelada: boolean
5 |
6 | constructor(valor: string, certa: boolean, revelada = false) {
7 | this.#valor = valor
8 | this.#certa = certa
9 | this.#revelada = revelada
10 | }
11 |
12 | static certa(valor: string) {
13 | return new RespostaModel(valor, true)
14 | }
15 |
16 | static errada(valor: string) {
17 | return new RespostaModel(valor, false)
18 | }
19 |
20 | get valor() {
21 | return this.#valor
22 | }
23 |
24 | get certa() {
25 | return this.#certa
26 | }
27 |
28 | get revelada() {
29 | return this.#revelada
30 | }
31 |
32 | revelar() {
33 | return new RespostaModel(this.#valor, this.#certa, true)
34 | }
35 |
36 | static criarUsandoObjeto(obj: RespostaModel): RespostaModel {
37 | return new RespostaModel(obj.valor, obj.certa, obj.revelada)
38 | }
39 |
40 | paraObjeto() {
41 | return {
42 | valor: this.#valor,
43 | certa: this.#certa,
44 | revelada: this.#revelada
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/quiz/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/quiz/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | reactStrictMode: true,
3 | }
4 |
--------------------------------------------------------------------------------
/quiz/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "quiz",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "next": "11.0.0",
13 | "react": "17.0.2",
14 | "react-countdown-circle-timer": "^2.5.3",
15 | "react-dom": "17.0.2"
16 | },
17 | "devDependencies": {
18 | "@types/react": "^17.0.11",
19 | "eslint": "7.28.0",
20 | "eslint-config-next": "11.0.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/quiz/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return
5 | }
6 |
7 | export default MyApp
8 |
--------------------------------------------------------------------------------
/quiz/pages/api/bancoDeQuestoes.ts:
--------------------------------------------------------------------------------
1 | import QuestaoModel from "../../model/questao";
2 | import RespostaModel from "../../model/resposta";
3 |
4 | const questoes: QuestaoModel[] = [
5 | new QuestaoModel(306, 'Qual bicho transmite a Doença de Chagas?', [
6 | RespostaModel.errada('Abelha'),
7 | RespostaModel.errada('Barata'),
8 | RespostaModel.errada('Pulga'),
9 | RespostaModel.certa('Barbeiro'),
10 | ]),
11 | new QuestaoModel(202, 'Qual fruto é conhecido no Norte e Nordeste como "jerimum"?', [
12 | RespostaModel.errada('Caju'),
13 | RespostaModel.errada('Côco'),
14 | RespostaModel.errada('Chuchu'),
15 | RespostaModel.certa('Abóbora'),
16 | ]),
17 | new QuestaoModel(203, 'Qual é o coletivo de cães?', [
18 | RespostaModel.errada('Manada'),
19 | RespostaModel.errada('Alcateia'),
20 | RespostaModel.errada('Rebanho'),
21 | RespostaModel.certa('Matilha'),
22 | ]),
23 | new QuestaoModel(204, 'Qual é o triângulo que tem todos os lados diferentes?', [
24 | RespostaModel.errada('Equilátero'),
25 | RespostaModel.errada('Isóceles'),
26 | RespostaModel.errada('Trapézio'),
27 | RespostaModel.certa('Escaleno'),
28 | ]),
29 | new QuestaoModel(205, 'Quem compôs o Hino da Independência?', [
30 | RespostaModel.errada('Castro Alves'),
31 | RespostaModel.errada('Manuel Bandeira'),
32 | RespostaModel.errada('Carlos Gomes'),
33 | RespostaModel.certa('Dom Pedro I'),
34 | ]),
35 | new QuestaoModel(206, 'Qual é o antônimo de "malograr"?', [
36 | RespostaModel.errada('Perder'),
37 | RespostaModel.errada('Fracassar'),
38 | RespostaModel.errada('Desprezar'),
39 | RespostaModel.certa('Conseguir'),
40 | ]),
41 | new QuestaoModel(207, 'Em que país nasceu Carmen Miranda?', [
42 | RespostaModel.errada('Argentina'),
43 | RespostaModel.errada('Espanha'),
44 | RespostaModel.errada('Brasil'),
45 | RespostaModel.certa('Portugal'),
46 | ]),
47 | new QuestaoModel(208, 'Qual foi o último Presidente do período da ditadura militar no Brasil?', [
48 | RespostaModel.errada('Costa e Silva'),
49 | RespostaModel.errada('Emílio Médici'),
50 | RespostaModel.errada('Ernesto Geisel'),
51 | RespostaModel.certa('João Figueiredo'),
52 | ]),
53 | new QuestaoModel(209, 'Seguindo a sequência do baralho, qual carta vem depois do dez?', [
54 | RespostaModel.errada('Ás'),
55 | RespostaModel.errada('Nove'),
56 | RespostaModel.errada('Rei'),
57 | RespostaModel.certa('Valete'),
58 | ]),
59 | new QuestaoModel(210, 'O adjetivo "venoso" está relacionado a:', [
60 | RespostaModel.errada('Vela'),
61 | RespostaModel.errada('Vento'),
62 | RespostaModel.errada('Vênia'),
63 | RespostaModel.certa('Veia'),
64 | ]),
65 | new QuestaoModel(211, 'Que nome se dá à purificação por meio da água?', [
66 | RespostaModel.errada('Abrupção'),
67 | RespostaModel.errada('Abolição'),
68 | RespostaModel.errada('Abnegação'),
69 | RespostaModel.certa('Ablução'),
70 | ]),
71 | new QuestaoModel(212, 'Qual montanha se localiza entre a fronteira do Tibet com o Nepal?', [
72 | RespostaModel.errada('Monte Branco'),
73 | RespostaModel.errada('Monte Fuji'),
74 | RespostaModel.errada('Monte Carlo'),
75 | RespostaModel.certa('Monte Everest'),
76 | ]),
77 | new QuestaoModel(213, 'Em que parte do corpo se encontra a epiglote?', [
78 | RespostaModel.errada('Estômago'),
79 | RespostaModel.errada('Pâncreas'),
80 | RespostaModel.errada('Rim'),
81 | RespostaModel.certa('Pescoço'),
82 | ]),
83 | new QuestaoModel(214, 'A compensação por perda é chamada de...', [
84 | RespostaModel.errada('Déficit'),
85 | RespostaModel.errada('Indexação'),
86 | RespostaModel.errada('Indébito'),
87 | RespostaModel.certa('Indenização'),
88 | ]),
89 | new QuestaoModel(215, 'Que personagem do folclore brasileiro tem uma perna só?', [
90 | RespostaModel.errada('Cuca'),
91 | RespostaModel.errada('Curupira'),
92 | RespostaModel.errada('Boitatá'),
93 | RespostaModel.certa('Saci-pererê'),
94 | ]),
95 | new QuestaoModel(216, 'Quem é o "patrono" do Exército Brasileiro?', [
96 | RespostaModel.errada('Marechal Deodoro'),
97 | RespostaModel.errada('Barão de Mauá'),
98 | RespostaModel.errada('Marquês de Pombal'),
99 | RespostaModel.certa('Duque de Caxias'),
100 | ]),
101 | ]
102 |
103 | export default questoes
--------------------------------------------------------------------------------
/quiz/pages/api/questionario/index.ts:
--------------------------------------------------------------------------------
1 | import { embaralhar } from '../../../functions/arrays'
2 | import questoes from '../bancoDeQuestoes'
3 |
4 | export default function questionario(req, res) {
5 | const ids = questoes.map(questao => questao.id)
6 | res.status(200).json(embaralhar(ids))
7 | }
--------------------------------------------------------------------------------
/quiz/pages/api/questoes/[id].ts:
--------------------------------------------------------------------------------
1 | import questoes from '../bancoDeQuestoes'
2 | export default function questoesProId(req, res) {
3 | const idSelecionado = +req.query.id
4 |
5 | const unicaQuestaoOuNada = questoes.filter(questao => questao.id === idSelecionado)
6 |
7 | if (unicaQuestaoOuNada.length === 1) {
8 | const questaoSelecionada = unicaQuestaoOuNada[0].embaralharRespostas()
9 | res.status(200).json(questaoSelecionada.paraObjeto())
10 | } else {
11 | res.status(204).send()
12 | }
13 | }
--------------------------------------------------------------------------------
/quiz/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 | import Questionario from '../components/Questionario'
3 | import QuestaoModel from '../model/questao'
4 | import { useRouter } from 'next/router'
5 |
6 | const BASE_URL = 'http://localhost:3000/api'
7 |
8 | export default function Home() {
9 | const router = useRouter()
10 |
11 | const [idsDasQuestoes, setIdsDasQuestoes] = useState([])
12 | const [questao, setQuestao] = useState()
13 | const [respostasCertas, setRespostasCertas] = useState(0)
14 |
15 | async function carregarIdsDasQuestoes() {
16 | const resp = await fetch(`${BASE_URL}/questionario`)
17 | const idsDasQuestoes = await resp.json()
18 | setIdsDasQuestoes(idsDasQuestoes)
19 | }
20 |
21 | async function carregarQuestao(idQuestao: number) {
22 | const resp = await fetch(`${BASE_URL}/questoes/${idQuestao}`)
23 | const json = await resp.json()
24 | const novaQuestao = QuestaoModel.criarUsandoObjeto(json)
25 | setQuestao(novaQuestao)
26 | }
27 |
28 | useEffect(() => {
29 | carregarIdsDasQuestoes()
30 | }, [])
31 |
32 | useEffect(() => {
33 | idsDasQuestoes.length > 0 && carregarQuestao(idsDasQuestoes[0])
34 | }, [idsDasQuestoes])
35 |
36 | function questaoRespondida(questaoRespondida: QuestaoModel) {
37 | setQuestao(questaoRespondida)
38 | const acertou = questaoRespondida.acertou
39 | setRespostasCertas(respostasCertas + (acertou ? 1 : 0))
40 | }
41 |
42 | function idProximaPergunta() {
43 | const proximoIndice = idsDasQuestoes.indexOf(questao.id) + 1
44 | return idsDasQuestoes[proximoIndice]
45 | }
46 |
47 | function irPraProximoPasso() {
48 | const proximoId = idProximaPergunta()
49 | proximoId ? irPraProximaQuestao(proximoId) : finalizar()
50 | }
51 |
52 | function irPraProximaQuestao(proximoId: number) {
53 | carregarQuestao(proximoId)
54 | }
55 |
56 | function finalizar() {
57 | router.push({
58 | pathname: "/resultado",
59 | query: {
60 | total: idsDasQuestoes.length,
61 | certas: respostasCertas
62 | }
63 | })
64 | }
65 |
66 | return questao ? (
67 |
72 | ) : false
73 | }
74 |
--------------------------------------------------------------------------------
/quiz/pages/resultado.tsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Resultado.module.css'
2 | import Estatistica from '../components/Estatistica'
3 | import Botao from '../components/Botao'
4 | import { useRouter } from 'next/router'
5 |
6 | export default function Resultado() {
7 | const router = useRouter()
8 |
9 | const total = +router.query.total
10 | const certas = +router.query.certas
11 | const percentual = Math.round((certas / total) * 100)
12 |
13 | return (
14 |
15 |
Resultado Final
16 |
17 |
18 |
20 |
22 |
23 |
24 |
25 | )
26 | }
--------------------------------------------------------------------------------
/quiz/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod3rcursos/curso-nextjs/5c35f41e4da8c20753b5eca2827bcbba2bb31ce6/quiz/public/favicon.ico
--------------------------------------------------------------------------------
/quiz/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/quiz/styles/Botao.module.css:
--------------------------------------------------------------------------------
1 | .botao {
2 | color: #fff;
3 | border-radius: 8px;
4 | font-weight: 200;
5 | font-size: 1.2rem;
6 | border: none;
7 | padding: 10px 25px;
8 | background-color: #9885F0;
9 | margin-top: 40px;
10 | cursor: pointer;
11 | transition: all .2s ease-in-out;
12 | }
13 |
14 | .botao:hover {
15 | transform: scale(1.1);
16 | }
--------------------------------------------------------------------------------
/quiz/styles/Enunciado.module.css:
--------------------------------------------------------------------------------
1 | .enunciado {
2 | display: flex;
3 | }
4 |
5 | .texto {
6 | font-size: 2.5rem;
7 | font-weight: 700;
8 | }
--------------------------------------------------------------------------------
/quiz/styles/Estatistica.module.css:
--------------------------------------------------------------------------------
1 | .estatistica {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | margin: 10px;
6 | }
7 |
8 | .valor {
9 | display: flex;
10 | justify-content: center;
11 | align-items: center;
12 | height: 180px;
13 | width: 180px;
14 | border-radius: 90px;
15 | font-size: 4rem;
16 | }
17 |
18 | .texto {
19 | color: #ddd;
20 | font-size: 1.7rem;
21 | font-weight: 200;
22 | }
--------------------------------------------------------------------------------
/quiz/styles/Questao.module.css:
--------------------------------------------------------------------------------
1 | .questao {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | }
--------------------------------------------------------------------------------
/quiz/styles/Questionario.module.css:
--------------------------------------------------------------------------------
1 | .questionario {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: center;
5 | align-items: center;
6 | height: 100vh;
7 | }
--------------------------------------------------------------------------------
/quiz/styles/Resposta.module.css:
--------------------------------------------------------------------------------
1 | .resposta {
2 | display: flex;
3 | min-width: 500px;
4 | width: 80%;
5 | height: 100px;
6 | margin: 10px;
7 | perspective: 1000px;
8 | }
9 |
10 | .conteudoResposta {
11 | position: relative;
12 | display: flex;
13 | flex: 1;
14 | transition: transform 0.8s;
15 | transform-style: preserve-3d;
16 | }
17 |
18 | .respostaRevelada.conteudoResposta {
19 | transform: rotateY(180deg);
20 | }
21 |
22 | .frente, .verso {
23 | position: absolute;
24 | display: flex;
25 | height: 100%;
26 | width: 100%;
27 | -webkit-backface-visibility: hidden;
28 | backface-visibility: hidden;
29 | }
30 |
31 | .frente {
32 | align-items: center;
33 | border-radius: 12px;
34 | padding: 15px;
35 | color: #000;
36 | background-color: #fff;
37 | }
38 |
39 | .verso {
40 | transform: rotateY(180deg);
41 | }
42 |
43 | .verso > div {
44 | display: flex;
45 | flex-direction: column;
46 | justify-content: center;
47 | align-items: center;
48 | flex: 1;
49 | border-radius: 12px;
50 | }
51 |
52 | .certa {
53 | background-color: #2BAA6D;
54 | }
55 |
56 | .errada {
57 | background-color: #E44A4C;
58 | }
59 |
60 | .certa .valor, .errada .valor {
61 | font-size: 1.5rem;
62 | }
63 |
64 | .letra {
65 | display: flex;
66 | justify-content: center;
67 | align-items: center;
68 | height: 40px;
69 | width: 40px;
70 | border-radius: 20px;
71 | font-size: 1.3rem;
72 | font-weight: 700;
73 | margin-right: 20px;
74 | color: #fff;
75 | }
76 |
77 | .valor {
78 | font-size: 1.3rem;
79 | font-weight: 700;
80 | }
--------------------------------------------------------------------------------
/quiz/styles/Resultado.module.css:
--------------------------------------------------------------------------------
1 | .resultado {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: center;
5 | align-items: center;
6 | height: 100vh;
7 | font-size: 2rem;
8 | }
--------------------------------------------------------------------------------
/quiz/styles/Temporizador.module.css:
--------------------------------------------------------------------------------
1 | .temporizador {
2 | display: flex;
3 | font-size: 2.5rem;
4 | margin: 20px 0px;
5 | }
--------------------------------------------------------------------------------
/quiz/styles/globals.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;700&display=swap');
2 |
3 | html,
4 | body {
5 | padding: 0;
6 | margin: 0;
7 | background-color: #6c54d8;
8 | color: #fff;
9 | }
10 |
11 | a {
12 | color: inherit;
13 | text-decoration: none;
14 | }
15 |
16 | * {
17 | box-sizing: border-box;
18 | font-family: 'Poppins', sans-serif;
19 | }
20 |
--------------------------------------------------------------------------------
/quiz/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": false,
12 | "forceConsistentCasingInFileNames": true,
13 | "noEmit": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "jsx": "preserve"
20 | },
21 | "include": [
22 | "next-env.d.ts",
23 | "**/*.ts",
24 | "**/*.tsx"
25 | ],
26 | "exclude": [
27 | "node_modules"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/renderizacao/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next", "next/core-web-vitals"]
3 | }
4 |
--------------------------------------------------------------------------------
/renderizacao/.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 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/renderizacao/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/renderizacao/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | reactStrictMode: true,
3 | }
4 |
--------------------------------------------------------------------------------
/renderizacao/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "renderizacao",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "next": "11.0.0",
13 | "react": "17.0.2",
14 | "react-dom": "17.0.2"
15 | },
16 | "devDependencies": {
17 | "eslint": "7.29.0",
18 | "eslint-config-next": "11.0.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/renderizacao/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return
5 | }
6 |
7 | export default MyApp
8 |
--------------------------------------------------------------------------------
/renderizacao/pages/alunos/[id].jsx:
--------------------------------------------------------------------------------
1 | export async function getStaticPaths() {
2 | const resp = await fetch('http://localhost:3000/api/alunos/tutores')
3 | const ids = await resp.json()
4 |
5 | const paths = ids.map(id => {
6 | return { params: { id: `${id}` } }
7 | })
8 |
9 | return {
10 | fallback: true, // false => 404
11 | paths
12 | }
13 | }
14 |
15 | export async function getStaticProps({ params }) {
16 | console.log(params)
17 | const resp = await fetch(`http://localhost:3000/api/alunos/${params.id}`)
18 | const aluno = await resp.json()
19 |
20 | return {
21 | props: {
22 | aluno
23 | }
24 | }
25 | }
26 |
27 | export default function AlunoPorId(props) {
28 | const { aluno } = props
29 | return (
30 |
31 |
Detalhes do Aluno
32 | {aluno ?
33 |
34 | - {aluno.id}
35 | - {aluno.nome}
36 | - {aluno.email}
37 |
38 | : false
39 | }
40 |
41 | )
42 | }
--------------------------------------------------------------------------------
/renderizacao/pages/api/alunos/[id].js:
--------------------------------------------------------------------------------
1 | export default function handler(req, res) {
2 | const id = +req.query.id
3 | res.status(200).json({
4 | id,
5 | nome: `João Almeida ${id}`,
6 | email: `jjjalalalmmm${id}@gmail.com`
7 | })
8 | }
--------------------------------------------------------------------------------
/renderizacao/pages/api/alunos/tutores.js:
--------------------------------------------------------------------------------
1 | export default function handler(req, res) {
2 | res.status(200).json([100, 200, 300, 400])
3 | }
--------------------------------------------------------------------------------
/renderizacao/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default function handler(req, res) {
4 | res.status(200).json({ name: 'John Doe' })
5 | }
6 |
--------------------------------------------------------------------------------
/renderizacao/pages/api/produtos.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | function numeroAleatorio(min = 1, max = 100000) {
4 | return parseInt(Math.random() * (max - min)) + min
5 | }
6 |
7 | export default function handler(req, res) {
8 | res.status(200).json([
9 | { id: numeroAleatorio(), nome: 'Caneta', preco: 5.60 },
10 | { id: numeroAleatorio(), nome: 'Caderno', preco: 15.60 },
11 | { id: numeroAleatorio(), nome: 'Borracha', preco: 7.30 },
12 | { id: numeroAleatorio(), nome: 'Tesoura', preco: 21.55 },
13 | ])
14 | }
15 |
--------------------------------------------------------------------------------
/renderizacao/pages/dinamico1.jsx:
--------------------------------------------------------------------------------
1 | export function getServerSideProps() {
2 | console.log('[Server] gerando props para o componente...')
3 | return {
4 | props: {
5 | numero: Math.random()
6 | }
7 | }
8 | }
9 |
10 | export default function Dinamico1(props) {
11 | return (
12 |
13 |
Dinâmico #01
14 | {props.numero}
15 |
16 | )
17 | }
--------------------------------------------------------------------------------
/renderizacao/pages/dinamico2.jsx:
--------------------------------------------------------------------------------
1 | export async function getServerSideProps() {
2 | console.log('[Server] gerando props para o componente...')
3 | const resp = await fetch('http://localhost:3000/api/produtos')
4 | const produtos = await resp.json()
5 |
6 | return {
7 | props: {
8 | produtos
9 | }
10 | }
11 | }
12 |
13 | export default function Dinamico2(props) {
14 | console.log('[Cliente] renderizando o componente...')
15 |
16 | function renderizarProdutos() {
17 | return props.produtos.map(produto => {
18 | return (
19 |
20 | {produto.id} - {produto.nome} tem preço de R${produto.preco}
21 |
22 | )
23 | })
24 | }
25 |
26 | return (
27 |
28 |
Dinâmico #02
29 |
30 | {renderizarProdutos()}
31 |
32 |
33 | )
34 | }
--------------------------------------------------------------------------------
/renderizacao/pages/estatico1.jsx:
--------------------------------------------------------------------------------
1 | // import { useEffect, useState } from "react"
2 |
3 | export default function Estatico1() {
4 | // const [num, setNum] = useState(0)
5 |
6 | // useEffect(() => {
7 | // setNum(Math.random())
8 | // }, [])
9 |
10 | return (
11 |
12 |
Estático #01
13 | {/* {num}
*/}
14 |
15 | )
16 | }
--------------------------------------------------------------------------------
/renderizacao/pages/estatico2.jsx:
--------------------------------------------------------------------------------
1 | export function getStaticProps() {
2 | return {
3 | props: {
4 | numero: Math.random()
5 | }
6 | }
7 | }
8 |
9 | export default function Estatico2(props) {
10 | return (
11 |
12 |
Estático #02
13 | {props.numero}
14 |
15 | )
16 | }
--------------------------------------------------------------------------------
/renderizacao/pages/estatico3.jsx:
--------------------------------------------------------------------------------
1 | export function getStaticProps() {
2 | return {
3 | revalidate: 7, // segundos!
4 | props: {
5 | numero: Math.random()
6 | }
7 | }
8 | }
9 |
10 | export default function Estatico3(props) {
11 | return (
12 |
13 |
Estático #03
14 | {props.numero}
15 |
16 | )
17 | }
--------------------------------------------------------------------------------
/renderizacao/pages/estatico4.jsx:
--------------------------------------------------------------------------------
1 | export async function getStaticProps() {
2 | console.log('[Server] gerando props para o componente...')
3 | const resp = await fetch('http://localhost:3000/api/produtos')
4 | const produtos = await resp.json()
5 |
6 | return {
7 | props: {
8 | produtos
9 | }
10 | }
11 | }
12 |
13 | export default function Estatico4(props) {
14 | console.log('[Cliente] renderizando o componente...')
15 |
16 | function renderizarProdutos() {
17 | return props.produtos.map(produto => {
18 | return (
19 |
20 | {produto.id} - {produto.nome} tem preço de R${produto.preco}
21 |
22 | )
23 | })
24 | }
25 |
26 | return (
27 |
28 |
Estático #04
29 |
30 | {renderizarProdutos()}
31 |
32 |
33 | )
34 | }
--------------------------------------------------------------------------------
/renderizacao/pages/index.js:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import Image from 'next/image'
3 | import styles from '../styles/Home.module.css'
4 |
5 | export default function Home() {
6 | return (
7 |
8 |
9 |
Create Next App
10 |
11 |
12 |
13 |
14 |
15 |
16 | Welcome to Next.js!
17 |
18 |
19 |
20 | Get started by editing{' '}
21 | pages/index.js
22 |
23 |
24 |
53 |
54 |
55 |
67 |
68 | )
69 | }
70 |
--------------------------------------------------------------------------------
/renderizacao/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod3rcursos/curso-nextjs/5c35f41e4da8c20753b5eca2827bcbba2bb31ce6/renderizacao/public/favicon.ico
--------------------------------------------------------------------------------
/renderizacao/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/renderizacao/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | min-height: 100vh;
3 | padding: 0 0.5rem;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | align-items: center;
8 | height: 100vh;
9 | }
10 |
11 | .main {
12 | padding: 5rem 0;
13 | flex: 1;
14 | display: flex;
15 | flex-direction: column;
16 | justify-content: center;
17 | align-items: center;
18 | }
19 |
20 | .footer {
21 | width: 100%;
22 | height: 100px;
23 | border-top: 1px solid #eaeaea;
24 | display: flex;
25 | justify-content: center;
26 | align-items: center;
27 | }
28 |
29 | .footer a {
30 | display: flex;
31 | justify-content: center;
32 | align-items: center;
33 | flex-grow: 1;
34 | }
35 |
36 | .title a {
37 | color: #0070f3;
38 | text-decoration: none;
39 | }
40 |
41 | .title a:hover,
42 | .title a:focus,
43 | .title a:active {
44 | text-decoration: underline;
45 | }
46 |
47 | .title {
48 | margin: 0;
49 | line-height: 1.15;
50 | font-size: 4rem;
51 | }
52 |
53 | .title,
54 | .description {
55 | text-align: center;
56 | }
57 |
58 | .description {
59 | line-height: 1.5;
60 | font-size: 1.5rem;
61 | }
62 |
63 | .code {
64 | background: #fafafa;
65 | border-radius: 5px;
66 | padding: 0.75rem;
67 | font-size: 1.1rem;
68 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
69 | Bitstream Vera Sans Mono, Courier New, monospace;
70 | }
71 |
72 | .grid {
73 | display: flex;
74 | align-items: center;
75 | justify-content: center;
76 | flex-wrap: wrap;
77 | max-width: 800px;
78 | margin-top: 3rem;
79 | }
80 |
81 | .card {
82 | margin: 1rem;
83 | padding: 1.5rem;
84 | text-align: left;
85 | color: inherit;
86 | text-decoration: none;
87 | border: 1px solid #eaeaea;
88 | border-radius: 10px;
89 | transition: color 0.15s ease, border-color 0.15s ease;
90 | width: 45%;
91 | }
92 |
93 | .card:hover,
94 | .card:focus,
95 | .card:active {
96 | color: #0070f3;
97 | border-color: #0070f3;
98 | }
99 |
100 | .card h2 {
101 | margin: 0 0 1rem 0;
102 | font-size: 1.5rem;
103 | }
104 |
105 | .card p {
106 | margin: 0;
107 | font-size: 1.25rem;
108 | line-height: 1.5;
109 | }
110 |
111 | .logo {
112 | height: 1em;
113 | margin-left: 0.5rem;
114 | }
115 |
116 | @media (max-width: 600px) {
117 | .grid {
118 | width: 100%;
119 | flex-direction: column;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/renderizacao/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | }
8 |
9 | a {
10 | color: inherit;
11 | text-decoration: none;
12 | }
13 |
14 | * {
15 | box-sizing: border-box;
16 | }
17 |
--------------------------------------------------------------------------------
/tabuleiro/.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 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/tabuleiro/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/tabuleiro/components/Linha.jsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Linha.module.css'
2 | import Subdivisao from "./Subdivisao";
3 |
4 | export default function Linha(props) {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | )
17 | }
--------------------------------------------------------------------------------
/tabuleiro/components/Subdivisao.jsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Subdivisao.module.css'
2 |
3 | export default function Subdivisao(props) {
4 | return (
5 |
10 |
11 |
12 | )
13 | }
--------------------------------------------------------------------------------
/tabuleiro/components/Tabuleiro.jsx:
--------------------------------------------------------------------------------
1 | import Linha from "./Linha";
2 |
3 | export default function Tabuleiro() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | )
16 | }
--------------------------------------------------------------------------------
/tabuleiro/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tabuleiro",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "next": "10.2.3",
12 | "react": "17.0.2",
13 | "react-dom": "17.0.2"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tabuleiro/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return
5 | }
6 |
7 | export default MyApp
8 |
--------------------------------------------------------------------------------
/tabuleiro/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default (req, res) => {
4 | res.status(200).json({ name: 'John Doe' })
5 | }
6 |
--------------------------------------------------------------------------------
/tabuleiro/pages/index.jsx:
--------------------------------------------------------------------------------
1 | import Tabuleiro from '../components/Tabuleiro'
2 | import styles from '../styles/Home.module.css'
3 |
4 | export default function Home() {
5 | return (
6 |
7 |
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/tabuleiro/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod3rcursos/curso-nextjs/5c35f41e4da8c20753b5eca2827bcbba2bb31ce6/tabuleiro/public/favicon.ico
--------------------------------------------------------------------------------
/tabuleiro/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tabuleiro/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | min-height: 100vh;
3 | padding: 0 0.5rem;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | align-items: center;
8 | height: 100vh;
9 | }
10 |
11 | .main {
12 | padding: 5rem 0;
13 | flex: 1;
14 | display: flex;
15 | flex-direction: column;
16 | justify-content: center;
17 | align-items: center;
18 | }
19 |
20 | .footer {
21 | width: 100%;
22 | height: 100px;
23 | border-top: 1px solid #eaeaea;
24 | display: flex;
25 | justify-content: center;
26 | align-items: center;
27 | }
28 |
29 | .footer a {
30 | display: flex;
31 | justify-content: center;
32 | align-items: center;
33 | flex-grow: 1;
34 | }
35 |
36 | .title a {
37 | color: #0070f3;
38 | text-decoration: none;
39 | }
40 |
41 | .title a:hover,
42 | .title a:focus,
43 | .title a:active {
44 | text-decoration: underline;
45 | }
46 |
47 | .title {
48 | margin: 0;
49 | line-height: 1.15;
50 | font-size: 4rem;
51 | }
52 |
53 | .title,
54 | .description {
55 | text-align: center;
56 | }
57 |
58 | .description {
59 | line-height: 1.5;
60 | font-size: 1.5rem;
61 | }
62 |
63 | .code {
64 | background: #fafafa;
65 | border-radius: 5px;
66 | padding: 0.75rem;
67 | font-size: 1.1rem;
68 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
69 | Bitstream Vera Sans Mono, Courier New, monospace;
70 | }
71 |
72 | .grid {
73 | display: flex;
74 | align-items: center;
75 | justify-content: center;
76 | flex-wrap: wrap;
77 | max-width: 800px;
78 | margin-top: 3rem;
79 | }
80 |
81 | .card {
82 | margin: 1rem;
83 | padding: 1.5rem;
84 | text-align: left;
85 | color: inherit;
86 | text-decoration: none;
87 | border: 1px solid #eaeaea;
88 | border-radius: 10px;
89 | transition: color 0.15s ease, border-color 0.15s ease;
90 | width: 45%;
91 | }
92 |
93 | .card:hover,
94 | .card:focus,
95 | .card:active {
96 | color: #0070f3;
97 | border-color: #0070f3;
98 | }
99 |
100 | .card h2 {
101 | margin: 0 0 1rem 0;
102 | font-size: 1.5rem;
103 | }
104 |
105 | .card p {
106 | margin: 0;
107 | font-size: 1.25rem;
108 | line-height: 1.5;
109 | }
110 |
111 | .logo {
112 | height: 1em;
113 | margin-left: 0.5rem;
114 | }
115 |
116 | @media (max-width: 600px) {
117 | .grid {
118 | width: 100%;
119 | flex-direction: column;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/tabuleiro/styles/Linha.module.css:
--------------------------------------------------------------------------------
1 | .linha {
2 | display: flex;
3 | }
--------------------------------------------------------------------------------
/tabuleiro/styles/Subdivisao.module.css:
--------------------------------------------------------------------------------
1 | .subdivisao {
2 | width: 100px;
3 | height: 100px;
4 | background-color: red;
5 | }
--------------------------------------------------------------------------------
/tabuleiro/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | background-color: #444;
6 | }
7 |
8 | a {
9 | color: inherit;
10 | text-decoration: none;
11 | }
12 |
13 | * {
14 | box-sizing: border-box;
15 | }
16 |
--------------------------------------------------------------------------------
/tarefas/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next", "next/core-web-vitals"]
3 | }
4 |
--------------------------------------------------------------------------------
/tarefas/.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 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/tarefas/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/tarefas/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/tarefas/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | reactStrictMode: true,
3 | }
4 |
--------------------------------------------------------------------------------
/tarefas/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tarefas",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@fortawesome/fontawesome-svg-core": "^1.2.35",
13 | "@fortawesome/free-brands-svg-icons": "^5.15.3",
14 | "@fortawesome/free-solid-svg-icons": "^5.15.3",
15 | "@fortawesome/react-fontawesome": "^0.1.14",
16 | "next": "11.0.0",
17 | "react": "17.0.2",
18 | "react-dom": "17.0.2"
19 | },
20 | "devDependencies": {
21 | "@types/react": "^17.0.11",
22 | "autoprefixer": "^10.2.6",
23 | "eslint": "7.29.0",
24 | "eslint-config-next": "11.0.0",
25 | "postcss": "^8.3.5",
26 | "tailwindcss": "^2.2.2",
27 | "typescript": "^4.3.4"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tarefas/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/tarefas/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod3rcursos/curso-nextjs/5c35f41e4da8c20753b5eca2827bcbba2bb31ce6/tarefas/public/favicon.ico
--------------------------------------------------------------------------------
/tarefas/public/images/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod3rcursos/curso-nextjs/5c35f41e4da8c20753b5eca2827bcbba2bb31ce6/tarefas/public/images/background.png
--------------------------------------------------------------------------------
/tarefas/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tarefas/src/components/formulario/Formulario.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 | import { faPlus } from '@fortawesome/free-solid-svg-icons'
3 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
4 | import Tarefa from "../../model/Tarefa"
5 |
6 | interface FormularioProps {
7 | novaTarefaCriada: (tarefa: Tarefa) => void
8 | }
9 |
10 | export default function Formulario(props: FormularioProps) {
11 | const [descricao, setDescricao] = useState('')
12 |
13 | function criarNovaTarefa() {
14 | if(descricao?.trim().length > 0) {
15 | const novaTarefa = Tarefa.criarAtiva(Math.random(), descricao)
16 | props.novaTarefaCriada(novaTarefa)
17 | setDescricao('')
18 | }
19 | }
20 |
21 | return (
22 |
23 | setDescricao(e.target.value)}
26 | onKeyDown={e => e.key === 'Enter' ? criarNovaTarefa() : false}
27 | className={`
28 | w-1/2 py-2 px-3 rounded-lg border-2 text-2xl
29 | border-purple-300 focus:outline-none
30 | focus:ring-2 focus:ring-purple-600
31 | `}
32 | />
33 |
39 |
40 | )
41 | }
--------------------------------------------------------------------------------
/tarefas/src/components/lista/Lista.tsx:
--------------------------------------------------------------------------------
1 | import ListaTarefas from "../../model/ListaTarefas";
2 | import ListaItem from './ListaItem'
3 | import ListaRodape from './ListaRodape'
4 |
5 | interface ListaProps {
6 | tarefas: ListaTarefas
7 | mudou: (tarefas: ListaTarefas) => void
8 | }
9 |
10 | export default function Lista(props: ListaProps) {
11 | const { tarefas } = props
12 |
13 | function renderizarTarefas() {
14 | return tarefas.itens.map(tarefa => {
15 | return (
16 | {
21 | const tarefaModificada = tarefa.alternarStatus()
22 | const novaLista = tarefas.modificarTarefa(tarefaModificada)
23 | props.mudou(novaLista)
24 | }}
25 | />
26 | )
27 | })
28 | }
29 |
30 | return (
31 |
32 |
37 | {renderizarTarefas()}
38 |
42 |
43 |
44 | )
45 | }
--------------------------------------------------------------------------------
/tarefas/src/components/lista/ListaBotao.tsx:
--------------------------------------------------------------------------------
1 | interface ListaBotaoProps {
2 | selecionado?: boolean
3 | className?: string
4 | children: any
5 | onClick: (evento: any) => void
6 | }
7 |
8 | export default function ListaBotao(props: ListaBotaoProps) {
9 | const borda = props.selecionado ?
10 | 'border-b-4 border-purple-400' : ''
11 | return (
12 |
18 | )
19 | }
--------------------------------------------------------------------------------
/tarefas/src/components/lista/ListaItem.tsx:
--------------------------------------------------------------------------------
1 | import Selecao from './Selecao'
2 |
3 | interface ListaItemProps {
4 | valor: string
5 | concluido: boolean
6 | alterarStatus: () => void
7 | }
8 |
9 | export default function ListaItem(props: ListaItemProps) {
10 | const estiloTexto = props.concluido ?
11 | 'line-through text-gray-300' : 'text-gray-500'
12 |
13 | return (
14 |
19 |
20 |
21 | {props.valor}
22 |
23 |
24 | )
25 | }
--------------------------------------------------------------------------------
/tarefas/src/components/lista/ListaRodape.tsx:
--------------------------------------------------------------------------------
1 | import ListaTarefas from "../../model/ListaTarefas"
2 | import ListaBotao from './ListaBotao'
3 |
4 | interface ListaRodapeProps {
5 | tarefas: ListaTarefas
6 | mudou: (tarefas: ListaTarefas) => void
7 | }
8 |
9 | export default function ListaRodape(props: ListaRodapeProps) {
10 | const { tarefas, mudou } = props
11 |
12 | function renderizarQtdeDeItens() {
13 | return (
14 | <>
15 |
16 | {tarefas.quantidade}
17 | {tarefas.quantidade === 0
18 | ? ' Nenhuma Tarefa Encontrada'
19 | : tarefas.quantidade === 1
20 | ? ' Tarefa Encontrada'
21 | : ' Tarefas Encontradas'}
22 |
23 |
24 | >
25 | )
26 | }
27 |
28 | function renderizarBotoesFiltro() {
29 | return (
30 | <>
31 | mudou(tarefas.removerFiltro())}
34 | className="hidden md:inline">
35 | Todas
36 |
37 | mudou(tarefas.filtrarAtivas())}
40 | className="mx-4">
41 | Ativas
42 |
43 | mudou(tarefas.filtrarConcluidas())}>
46 | Concluídas
47 |
48 | >
49 | )
50 | }
51 |
52 | function renderizarExcluirConcluidas() {
53 | return (
54 | <>
55 |
56 | mudou(tarefas.excluirConcluidas())}>
58 | Excluir Concluídas
59 |
60 | >
61 | )
62 | }
63 |
64 | return (
65 |
66 | {renderizarQtdeDeItens()}
67 | {renderizarBotoesFiltro()}
68 | {renderizarExcluirConcluidas()}
69 |
70 | )
71 | }
--------------------------------------------------------------------------------
/tarefas/src/components/lista/Selecao.tsx:
--------------------------------------------------------------------------------
1 | import { faCheck } from '@fortawesome/free-solid-svg-icons'
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3 |
4 | interface SelecaoProps {
5 | valor: boolean
6 | }
7 |
8 | export default function Selecao(props: SelecaoProps) {
9 | const gradiente = props.valor ?
10 | 'bg-gradient-to-br from-blue-400 to-purple-500' : ''
11 |
12 | return (
13 |
18 | {props.valor
19 | ?
20 | : ''
21 | }
22 |
23 | )
24 | }
--------------------------------------------------------------------------------
/tarefas/src/components/template/Cabecalho.tsx:
--------------------------------------------------------------------------------
1 | export default function Cabecalho(props) {
2 | return (
3 |
4 |
8 | {props.children}
9 |
10 |
11 | )
12 | }
--------------------------------------------------------------------------------
/tarefas/src/components/template/Conteudo.tsx:
--------------------------------------------------------------------------------
1 | export default function Conteudo(props) {
2 | return (
3 |
4 | {props.children}
5 |
6 | )
7 | }
--------------------------------------------------------------------------------
/tarefas/src/data/mock.ts:
--------------------------------------------------------------------------------
1 | import ListaTarefas from "../model/ListaTarefas";
2 | import Tarefa from "../model/Tarefa";
3 | import TipoFiltro from "../model/TipoFiltro";
4 |
5 | const tarefasIniciais: Tarefa[] = [
6 | // Tarefa.criarAtiva(1, 'Estudar Next'),
7 | // Tarefa.criarConcluida(2, 'Limpar carro'),
8 | // Tarefa.criarAtiva(3, 'Comprar livro do mês'),
9 | ]
10 |
11 | export default new ListaTarefas(tarefasIniciais, TipoFiltro.NENHUM)
--------------------------------------------------------------------------------
/tarefas/src/model/ListaTarefas.ts:
--------------------------------------------------------------------------------
1 | import Tarefa from "./Tarefa";
2 | import TipoFiltro from "./TipoFiltro";
3 |
4 | export default class ListaTarefas {
5 | #todas: Tarefa[]
6 | #filtroUtilizado: TipoFiltro
7 |
8 | constructor(todas: Tarefa[], filtroUtilizado = TipoFiltro.NENHUM) {
9 | this.#todas = todas
10 | this.#filtroUtilizado = filtroUtilizado ?? TipoFiltro.NENHUM
11 | }
12 |
13 | get itens() {
14 | return this.aplicarFiltroEm(this.#todas)
15 | }
16 |
17 | get quantidade() {
18 | return this.itens.length
19 | }
20 |
21 | get filtroUtilizado() {
22 | return this.#filtroUtilizado
23 | }
24 |
25 | adicionarTarefa(novaTarefa: Tarefa): ListaTarefas {
26 | const todas = [...this.#todas]
27 | todas.push(novaTarefa)
28 | return new ListaTarefas(todas, this.filtroUtilizado)
29 | }
30 |
31 | modificarTarefa(tarefaModificada: Tarefa): ListaTarefas {
32 | const todas = this.#todas.map(tarefa => {
33 | return tarefa.id === tarefaModificada.id ? tarefaModificada : tarefa
34 | })
35 | return new ListaTarefas(todas, this.filtroUtilizado)
36 | }
37 |
38 | filtrarAtivas(): ListaTarefas {
39 | if(!this.exibindoSomenteAtivas()) {
40 | return new ListaTarefas(this.#todas, TipoFiltro.ATIVAS)
41 | } else {
42 | return this
43 | }
44 | }
45 |
46 | excluirConcluidas(): ListaTarefas {
47 | const somenteAtivas = this.#todas.filter(tarefa => tarefa.ativa)
48 | return new ListaTarefas(somenteAtivas, TipoFiltro.NENHUM)
49 | }
50 |
51 | filtrarConcluidas(): ListaTarefas {
52 | if(!this.exibindoSomenteConcluidas()) {
53 | return new ListaTarefas(this.#todas, TipoFiltro.CONCLUIDAS)
54 | } else {
55 | return this
56 | }
57 | }
58 |
59 | removerFiltro(): ListaTarefas {
60 | if(!this.exibindoTodas()) {
61 | return new ListaTarefas(this.#todas, TipoFiltro.NENHUM)
62 | } else {
63 | return this
64 | }
65 | }
66 |
67 | exibindoTodas(): boolean {
68 | return this.#filtroUtilizado === TipoFiltro.NENHUM
69 | }
70 |
71 | exibindoSomenteAtivas(): boolean {
72 | return this.#filtroUtilizado === TipoFiltro.ATIVAS
73 | }
74 |
75 | exibindoSomenteConcluidas(): boolean {
76 | return this.#filtroUtilizado === TipoFiltro.CONCLUIDAS
77 | }
78 |
79 | private aplicarFiltroEm(tarefas: Tarefa[]): Tarefa[] {
80 | if(this.exibindoSomenteAtivas()) {
81 | return this.aplicarFiltroAtivas(tarefas)
82 | } else if(this.exibindoSomenteConcluidas()) {
83 | return this.aplicarFiltroConcluidas(tarefas)
84 | } else {
85 | return [...tarefas]
86 | }
87 | }
88 |
89 | private aplicarFiltroAtivas(tarefas: Tarefa[]): Tarefa[] {
90 | return tarefas.filter(tarefa => tarefa.ativa)
91 | }
92 |
93 | private aplicarFiltroConcluidas(tarefas: Tarefa[]): Tarefa[] {
94 | return tarefas.filter(tarefa => tarefa.concluida)
95 | }
96 | }
--------------------------------------------------------------------------------
/tarefas/src/model/Tarefa.ts:
--------------------------------------------------------------------------------
1 | export default class Tarefa {
2 | #id: number
3 | #descricao: string
4 | #concluida: boolean
5 |
6 | constructor(id: number, descricao: string, concluida = false) {
7 | this.#id = id
8 | this.#descricao = descricao
9 | this.#concluida = concluida
10 | }
11 |
12 | static criarAtiva(id: number, descricao: string) {
13 | return new Tarefa(id, descricao)
14 | }
15 |
16 | static criarConcluida(id: number, descricao: string) {
17 | return new Tarefa(id, descricao, true)
18 | }
19 |
20 | get id() {
21 | return this.#id
22 | }
23 |
24 | get descricao() {
25 | return this.#descricao
26 | }
27 |
28 | get concluida() {
29 | return this.#concluida
30 | }
31 |
32 | get ativa() {
33 | return !this.concluida
34 | }
35 |
36 | alternarStatus() {
37 | return this.concluida ? this.ativar() : this.concluir()
38 | }
39 |
40 | concluir() {
41 | return Tarefa.criarConcluida(this.id, this.descricao)
42 | }
43 |
44 | ativar() {
45 | return Tarefa.criarAtiva(this.id, this.descricao)
46 | }
47 | }
--------------------------------------------------------------------------------
/tarefas/src/model/TipoFiltro.ts:
--------------------------------------------------------------------------------
1 | enum TipoFiltro {
2 | NENHUM, ATIVAS, CONCLUIDAS
3 | }
4 |
5 | export default TipoFiltro
--------------------------------------------------------------------------------
/tarefas/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 | import 'tailwindcss/tailwind.css'
3 |
4 | function MyApp({ Component, pageProps }) {
5 | return
6 | }
7 |
8 | export default MyApp
9 |
--------------------------------------------------------------------------------
/tarefas/src/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default function handler(req, res) {
4 | res.status(200).json({ name: 'John Doe' })
5 | }
6 |
--------------------------------------------------------------------------------
/tarefas/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 | import Cabecalho from "../components/template/Cabecalho"
3 | import Conteudo from "../components/template/Conteudo"
4 | import Formulario from "../components/formulario/Formulario"
5 | import Lista from "../components/lista/Lista"
6 | import tarefasIniciais from '../data/mock'
7 | import Tarefa from "../model/Tarefa"
8 | import ListaTarefas from "../model/ListaTarefas"
9 |
10 | export default function Home() {
11 | const [tarefas, setTarefas] = useState(tarefasIniciais)
12 |
13 | function mudou(novasTarefas: ListaTarefas) {
14 | setTarefas(novasTarefas)
15 | }
16 |
17 | function novaTarefaCriada(novaTarefa: Tarefa) {
18 | setTarefas(tarefas.adicionarTarefa(novaTarefa))
19 | }
20 |
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/tarefas/src/styles/globals.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap');
2 |
3 | html,
4 | body {
5 | padding: 0;
6 | margin: 0;
7 | font-family: 'Poppins', sans-serif;
8 | }
9 |
10 | a {
11 | color: inherit;
12 | text-decoration: none;
13 | }
14 |
15 | * {
16 | box-sizing: border-box;
17 | }
18 |
--------------------------------------------------------------------------------
/tarefas/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | purge: [
3 | './src/pages/**/*.{js,ts,jsx,tsx}',
4 | './src/components/**/*.{js,ts,jsx,tsx}'
5 | ],
6 | darkMode: false, // or 'media' or 'class'
7 | theme: {
8 | extend: {
9 | backgroundImage: theme => ({
10 | 'img-tarefas': "url('/images/background.png')"
11 | })
12 | },
13 | },
14 | variants: {
15 | extend: {},
16 | },
17 | plugins: [],
18 | }
19 |
--------------------------------------------------------------------------------
/tarefas/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": false,
12 | "forceConsistentCasingInFileNames": true,
13 | "noEmit": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "jsx": "preserve"
20 | },
21 | "include": [
22 | "next-env.d.ts",
23 | "**/*.ts",
24 | "**/*.tsx"
25 | ],
26 | "exclude": [
27 | "node_modules"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------