├── 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 |
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 |
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 |
41 |
44 |
47 |
48 | )
49 | }
50 |
51 | export default App
52 |
--------------------------------------------------------------------------------