├── src ├── components │ ├── Title │ │ ├── index.jsx │ │ └── styles.jsx │ ├── Card │ │ ├── index.jsx │ │ └── styles.jsx │ └── Toast │ │ ├── index.jsx │ │ └── styles.jsx ├── main.jsx ├── pages │ └── App │ │ ├── styles.jsx │ │ └── index.jsx ├── index.css └── utils │ └── index.js ├── README.md ├── vite.config.js ├── .gitignore ├── index.html ├── package.json └── public └── vite.svg /src/components/Title/index.jsx: -------------------------------------------------------------------------------- 1 | import { H1 } from './styles.jsx' 2 | 3 | const Title = () =>

🐈 Tu michi de confianza te aconseja 🥛

4 | 5 | export default Title -------------------------------------------------------------------------------- /src/components/Title/styles.jsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export const H1 = styled.h1` 4 | margin: 0; 5 | text-align: center; 6 | font-size: 2rem; 7 | font-weight: 500; 8 | max-width: 26rem; 9 | ` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ✨ Tu michi de confianza te aconseja 🐈 2 | 3 | Captura de Pantalla 2023-03-19 a la(s) 8 51 09 p m 4 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | base: '/tu-michi-de-confianza-react/' 8 | }) 9 | -------------------------------------------------------------------------------- /src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './pages/App' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /src/pages/App/styles.jsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export const Header = styled.header` 4 | margin: 4.6rem 0 3.6rem; 5 | ` 6 | 7 | export const Section = styled.section` 8 | margin: 0 0 2.4rem; 9 | ` 10 | 11 | export const Footer = styled.footer` 12 | margin: 0 0 2.4rem; 13 | ` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700&display=swap'); 2 | 3 | :root { 4 | --gray: rgba(209, 209, 209, 1); 5 | --purple: rgba(173, 162, 255, 0.5); 6 | --green: rgba(165, 241, 233, 0.3); 7 | } 8 | html { 9 | font-size: 62.5%; 10 | } 11 | body { 12 | display: flex; 13 | align-items: center; 14 | flex-direction: column; 15 | font-family: 'Poppins', sans-serif; 16 | margin: 0; 17 | } -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | export const BASE_API = 'https://api.thecatapi.com/v1/images/search' 2 | 3 | export const phrases = [ 4 | { 5 | emoji: '🌷', 6 | phrase: '"Florecer exige pasar por todas las estaciones."' 7 | }, 8 | { 9 | emoji: '🥲', 10 | phrase: '"No culpes a una versión más pequeña de ti por no saber antes lo que sabes ahora."' 11 | }, 12 | { 13 | emoji: '🛤', 14 | phrase: '"Si crees que puedes, ya estás a medio camino."' 15 | } 16 | ] -------------------------------------------------------------------------------- /src/components/Card/index.jsx: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react' 2 | import { michiContext } from '../../pages/App/index.jsx' 3 | import { Container, Figure, Img, P, Button } from './styles.jsx' 4 | 5 | const Card = () => { 6 | const context = useContext(michiContext) 7 | 8 | return ( 9 | 10 |
11 | michi de confianza 14 |
15 |

Soy tu michi de confianza y estoy aquí para que le eches más ganas a todo we

16 | 17 |
18 | ) 19 | } 20 | 21 | export default Card -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tu-michi-de-confianza-react", 3 | "homepage": "https://teffcode.github.io//tu-michi-de-confianza-react/", 4 | "private": true, 5 | "version": "0.0.0", 6 | "type": "module", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "vite build", 10 | "preview": "vite preview", 11 | "predeploy": "npm run build", 12 | "deploy": "gh-pages -d dist" 13 | }, 14 | "dependencies": { 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "styled-components": "^5.3.9" 18 | }, 19 | "devDependencies": { 20 | "@types/react": "^18.0.28", 21 | "@types/react-dom": "^18.0.11", 22 | "@vitejs/plugin-react": "^3.1.0", 23 | "gh-pages": "^5.0.0", 24 | "vite": "^4.2.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/components/Toast/index.jsx: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react' 2 | import { michiContext } from '../../pages/App/index.jsx' 3 | import { Container, Emoji, P, CloseIcon } from './styles.jsx' 4 | import { phrases } from '../../utils/index.js' 5 | 6 | const Toast = () => { 7 | const context = useContext(michiContext) 8 | 9 | const setPhrase = () => { 10 | const randomNumber = Math.floor(Math.random() * phrases.length) 11 | return phrases[randomNumber] 12 | } 13 | 14 | const handleClick = () => { 15 | context.setToastVisibility('hidden') 16 | context.setSendRequest(true) 17 | } 18 | 19 | return ( 20 | 21 | {setPhrase().emoji} 22 |

{setPhrase().phrase}

23 | handleClick()}> 24 |
25 | ) 26 | } 27 | 28 | export default Toast -------------------------------------------------------------------------------- /src/components/Card/styles.jsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export const Container = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | width: 24rem; 8 | height: auto; 9 | border: 0.1rem solid var(--gray); 10 | border-radius: 1.6rem; 11 | padding: 2.4rem 1.6rem; 12 | ` 13 | 14 | export const Figure = styled.figure` 15 | border-radius: 1.6rem; 16 | width: 10rem; 17 | height: 10rem; 18 | overflow: hidden; 19 | margin: 0; 20 | ` 21 | 22 | export const Img = styled.img` 23 | width: 100%; 24 | height: 100%; 25 | object-fit: cover; 26 | ` 27 | 28 | export const P = styled.p` 29 | font-size: 1.4rem; 30 | font-weight: 100; 31 | text-align: center; 32 | ` 33 | 34 | export const Button = styled.button` 35 | background-color: var(--purple); 36 | border: none; 37 | border-radius: 1.6rem; 38 | cursor: pointer; 39 | margin-top: 1.2rem; 40 | padding: 1.2rem; 41 | font-family: 'Poppins', sans-serif; 42 | font-size: 1.6rem; 43 | font-weight: 500; 44 | width: 100%; 45 | ` -------------------------------------------------------------------------------- /src/components/Toast/styles.jsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export const Container = styled.div` 4 | display: flex; 5 | align-items: center; 6 | gap: 1.2rem; 7 | width: 24rem; 8 | height: auto; 9 | background-color: var(--green); 10 | border-radius: 1.6rem; 11 | padding: 2.4rem 1.6rem; 12 | visibility: ${({visibility}) => visibility}; 13 | ` 14 | export const Emoji = styled.div` 15 | align-self: self-start; 16 | background-color: white; 17 | border-radius: 1.6rem; 18 | font-size: 1.8rem; 19 | padding: 0.8rem 1.4rem; 20 | ` 21 | export const P = styled.p` 22 | font-size: 1.6rem; 23 | font-weight: 100; 24 | margin: 0; 25 | ` 26 | export const CloseIcon = styled.button` 27 | border: none; 28 | cursor: pointer; 29 | width: 24px; 30 | height: 24px; 31 | background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjBweCIgeT0iMHB4Igp3aWR0aD0iMjQiIGhlaWdodD0iMjQiCnZpZXdCb3g9IjAgMCAyNCAyNCI+CjxwYXRoIGQ9Ik0gNC43MDcwMzEyIDMuMjkyOTY4OCBMIDMuMjkyOTY4OCA0LjcwNzAzMTIgTCAxMC41ODU5MzggMTIgTCAzLjI5Mjk2ODggMTkuMjkyOTY5IEwgNC43MDcwMzEyIDIwLjcwNzAzMSBMIDEyIDEzLjQxNDA2MiBMIDE5LjI5Mjk2OSAyMC43MDcwMzEgTCAyMC43MDcwMzEgMTkuMjkyOTY5IEwgMTMuNDE0MDYyIDEyIEwgMjAuNzA3MDMxIDQuNzA3MDMxMiBMIDE5LjI5Mjk2OSAzLjI5Mjk2ODggTCAxMiAxMC41ODU5MzggTCA0LjcwNzAzMTIgMy4yOTI5Njg4IHoiPjwvcGF0aD4KPC9zdmc+') 50% 50% no-repeat; 32 | background-size: 100%; 33 | ` -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/App/index.jsx: -------------------------------------------------------------------------------- 1 | import { createContext, useEffect, useState } from 'react' 2 | import Title from '../../components/Title' 3 | import Card from '../../components/Card' 4 | import Toast from '../../components/Toast' 5 | import { BASE_API } from '../../utils' 6 | import { Header, Section, Footer } from './styles.jsx' 7 | 8 | export const michiContext = createContext({}) 9 | 10 | const App = () => { 11 | const [toastVisibility, setToastVisibility] = useState('hidden') 12 | const [michis, setMichis] = useState(null) 13 | const [sendRequest, setSendRequest] = useState(true) 14 | 15 | useEffect(() => { 16 | if (sendRequest) { 17 | (async () => { 18 | const response = await fetch(BASE_API, { 19 | 'mode': 'cors', 20 | 'headers': { 21 | 'Access-Control-Allow-Origin': '*', 22 | } 23 | }) 24 | const michi = await response.json() 25 | setMichis(michi[0].url) 26 | setSendRequest(false) 27 | })() 28 | } 29 | }, [sendRequest]) 30 | 31 | return ( 32 | 38 |
39 | 40 | </Header> 41 | <Section> 42 | <Card /> 43 | </Section> 44 | <Footer> 45 | <Toast /> 46 | </Footer> 47 | </michiContext.Provider> 48 | ) 49 | } 50 | 51 | export default App 52 | --------------------------------------------------------------------------------