JairoDanielMT commited on
Commit
c0dc9e8
·
1 Parent(s): 8a4948d

test con node-js 20 + react + huggingface

Browse files
.eslintrc.cjs ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ root: true,
3
+ env: { browser: true, es2020: true },
4
+ extends: [
5
+ 'eslint:recommended',
6
+ 'plugin:react/recommended',
7
+ 'plugin:react/jsx-runtime',
8
+ 'plugin:react-hooks/recommended',
9
+ ],
10
+ ignorePatterns: ['dist', '.eslintrc.cjs'],
11
+ parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12
+ settings: { react: { version: '18.2' } },
13
+ plugins: ['react-refresh'],
14
+ rules: {
15
+ 'react-refresh/only-export-components': [
16
+ 'warn',
17
+ { allowConstantExport: true },
18
+ ],
19
+ },
20
+ }
.gitattributes CHANGED
@@ -32,4 +32,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
32
  *.xz filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
32
  *.xz filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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?
Dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Usa la imagen de Node con la etiqueta 20.10-alpine3.18 como base
2
+ FROM node:20.10-alpine3.18
3
+
4
+ # Establece el directorio de trabajo en la aplicación
5
+ WORKDIR /usr/src/app
6
+
7
+ # Copia los archivos de configuración y el package.json a la imagen
8
+ COPY package*.json ./
9
+
10
+ # Instala las dependencias
11
+ RUN npm install
12
+
13
+ # Copia el resto de la aplicación a la imagen
14
+ COPY . .
15
+
16
+ # Otorga permisos de lectura, escritura y ejecución a todos los archivos y directorios
17
+ RUN chmod -R 777 /usr/src/app
18
+
19
+ # Expone el puerto 7860 (ajusta según sea necesario)
20
+ EXPOSE 7860
21
+
22
+ # Comando para ejecutar la aplicación
23
+ CMD ["npm", "run", "dev"]
README.md CHANGED
@@ -6,6 +6,4 @@ colorTo: blue
6
  sdk: docker
7
  pinned: false
8
  license: cc-by-4.0
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
6
  sdk: docker
7
  pinned: false
8
  license: cc-by-4.0
9
+ ---
 
 
index.html ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/logo.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Arte Visual</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.jsx"></script>
12
+ </body>
13
+ </html>
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "intento5",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite --port 7860",
8
+ "build": "vite build",
9
+ "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
10
+ "preview": "vite preview"
11
+ },
12
+ "dependencies": {
13
+ "react": "^18.2.0",
14
+ "react-dom": "^18.2.0",
15
+ "react-router": "^6.20.1",
16
+ "react-router-dom": "6.20.1"
17
+ },
18
+ "devDependencies": {
19
+ "@types/react": "^18.2.37",
20
+ "@types/react-dom": "^18.2.15",
21
+ "@vitejs/plugin-react": "^4.2.0",
22
+ "autoprefixer": "^10.4.16",
23
+ "eslint": "^8.53.0",
24
+ "eslint-plugin-react": "^7.33.2",
25
+ "eslint-plugin-react-hooks": "^4.6.0",
26
+ "eslint-plugin-react-refresh": "^0.4.4",
27
+ "postcss": "^8.4.32",
28
+ "standard": "^17.1.0",
29
+ "tailwindcss": "^3.3.5",
30
+ "vite": "^5.0.0"
31
+ }
32
+ }
postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
public/logo.svg ADDED
public/vite.svg ADDED
src/App.jsx ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Route, Routes } from "react-router-dom";
2
+ import { NavBar } from "./NavBar";
3
+ import { Prescripcion } from "./Prescripcion";
4
+
5
+ const Home = () => {
6
+ return <div>Home</div>;
7
+ };
8
+
9
+ const Pedidos = () => {
10
+ return <div>Pedidos</div>;
11
+ };
12
+
13
+ export default function App() {
14
+ return (
15
+ <div className="flex flex-col items-center h-screen">
16
+ <NavBar />
17
+ <Routes>
18
+ <Route path="/" element={<Home />} />
19
+ <Route path="/pedidos" element={<Pedidos />} />
20
+ <Route path="/prescripcion" element={<Prescripcion />} />
21
+ </Routes>
22
+ </div>
23
+ );
24
+ }
src/NavBar.jsx ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { Link } from "react-router-dom";
3
+
4
+ export const NavBar = () => {
5
+ return (
6
+ <header className="w-4/5">
7
+ <h1 className="text-5xl font-extrabold mt-20 mb-20 text-center">
8
+ Óptica Arte Visual
9
+ </h1>
10
+ <nav>
11
+ <ul className="flex flex-row justify-center text-xl">
12
+
13
+ <Link className="w-1/3 text-center" to="/">
14
+ <li className="hover:bg-slate-700 hover:text-white py-2 hover:font-semibold">
15
+ Home
16
+ </li>
17
+ </Link>
18
+ <Link className="w-1/3 text-center" to="/pedidos">
19
+ <li className="hover:bg-slate-700 hover:text-white py-2 hover:font-semibold">
20
+ Pedidos
21
+ </li>
22
+ </Link>
23
+ <Link className="w-1/3 text-center" to="/prescripcion">
24
+ <li className="hover:bg-slate-700 hover:text-white py-2 hover:font-semibold">
25
+ Emitir Prescripción
26
+ </li>
27
+ </Link>
28
+ </ul>
29
+ </nav>
30
+ </header>
31
+ );
32
+ };
src/Prescripcion.jsx ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useEffect, useState } from "react";
2
+ import { obtenerLike } from "./lib/conexionApi";
3
+ import Modal from "./components/Modal";
4
+
5
+ export const Prescripcion = () => {
6
+ // States para la búsqueda de clientes
7
+ const [clienteBusqueda, setClienteBusqueda] = useState("");
8
+ const [btnBuscarClick, setBtnBuscarClick] = useState(false);
9
+ const [clientes, setClientes] = useState([]);
10
+ const [cliente, setCliente] = useState({});
11
+ const [openModal, setOpenModal] = useState(false);
12
+
13
+ // States para crear nuevo cliente
14
+ const [nombresYApellidos, setNombresYApellidos] = useState("");
15
+ const [edad, setEdad] = useState("");
16
+ const [telefono, setTelefono] = useState("");
17
+ const [direccion, setDireccion] = useState("");
18
+
19
+ useEffect(() => {
20
+ if (btnBuscarClick) {
21
+ obtenerLike(
22
+ "clientes/busqueda",
23
+ { nombres_y_apellidos: clienteBusqueda },
24
+ setClientes
25
+ );
26
+ } else return;
27
+ }, [btnBuscarClick]);
28
+
29
+ const handleButtonBuscarCliente = (e) => {
30
+ e.preventDefault();
31
+ if (clienteBusqueda !== "") {
32
+ setBtnBuscarClick(true);
33
+ } else setBtnBuscarClick(false);
34
+ //console.log(clientes);
35
+ };
36
+
37
+ return (
38
+ <div className="pb-20 w-3/5 flex flex-row mt-10 px-5 h-[calc(100vh-208px)]">
39
+ <div className="w-2/5 pr-5">
40
+ {/* BARRA DE BÚSQUEDA DE CLIENTE */}
41
+ <div className="flex flex-row gap-2 mb-2">
42
+ <input
43
+ className="border w-3/4 py-2 px-3 rounded-md"
44
+ id="input-buscar-cliente"
45
+ type="text"
46
+ placeholder="Nombre del cliente"
47
+ onChange={(e) => {
48
+ setClienteBusqueda(e.target.value);
49
+ setBtnBuscarClick(false);
50
+ }}
51
+ value={clienteBusqueda}
52
+ />
53
+ <button
54
+ className="rounded-md w-1/4 bg-slate-700 hover:bg-slate-800 text-white font-semibold px-2 text-center"
55
+ onClick={handleButtonBuscarCliente}
56
+ >
57
+ Buscar
58
+ </button>
59
+ </div>
60
+
61
+ {/* DROPDOWN DE CLIENTES ENCONTRADOS */}
62
+ <ul>
63
+ {clientes && clienteBusqueda !== "" && btnBuscarClick !== false
64
+ ? clientes.map((cliente) => {
65
+ const nombresYApellidos = "nombres_y_apellidos";
66
+ const idCliente = "id_cliente";
67
+ return (
68
+ <li
69
+ key={cliente[idCliente]}
70
+ onClick={() => {
71
+ setBtnBuscarClick(false);
72
+ setClienteBusqueda("");
73
+ setCliente(cliente);
74
+ }}
75
+ className="cursor-pointer hover:font-semibold hover:bg-slate-50 p-2"
76
+ >
77
+ <p>{cliente[nombresYApellidos]}</p>
78
+ <p className="text-sm text-slate-400">{cliente["edad"]}</p>
79
+ <p className="text-sm text-slate-400">
80
+ {cliente["telefono"]}
81
+ </p>
82
+ <p className="text-sm text-slate-400">
83
+ {cliente["direccion"]}
84
+ </p>
85
+ </li>
86
+ );
87
+ })
88
+ : ""}
89
+ </ul>
90
+ </div>
91
+
92
+ <svg
93
+ xmlns="http://www.w3.org/2000/svg"
94
+ className="icon icon-tabler icon-tabler-user-plus cursor-pointer hover:stroke-slate-800 mr-5"
95
+ width="40"
96
+ height="40"
97
+ viewBox="0 0 24 24"
98
+ strokeWidth="2.5"
99
+ stroke="#334155"
100
+ fill="none"
101
+ strokeLinecap="round"
102
+ strokeLinejoin="round"
103
+ /* ABRIR MODAL PARA AGREGAR CLIENTE */
104
+ onClick={() => {
105
+ console.log("agregar");
106
+ setOpenModal(true);
107
+ }}
108
+ >
109
+ <path stroke="none" d="M0 0h24v24H0z" fill="none" />
110
+ <path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0" />
111
+ <path d="M16 19h6" />
112
+ <path d="M19 16v6" />
113
+ <path d="M6 21v-2a4 4 0 0 1 4 -4h4" />
114
+ </svg>
115
+
116
+ {/* MOSTRAR CLIENTE SELECCIONADO */}
117
+ {Object.keys(cliente).length !== 0 ? (
118
+ <div className="px-5 flex flex-col w-3/5 h-full pb-20 border-l-2">
119
+ <div className="w-full">
120
+ <p className=" font-semibold text-4xl mb-8">
121
+ {cliente["nombres_y_apellidos"]}
122
+ </p>
123
+ <div className="flex flex-row">
124
+ <p className="w-1/2 mb-2">Edad: {cliente["edad"]}</p>
125
+ <p className="w-1/2 mb-2">Teléfono: {cliente["telefono"]}</p>
126
+ </div>
127
+ <p className="mb-2"> Dirección: {cliente["direccion"]}</p>
128
+ <label htmlFor="notaAdicional">Nota adicional: {""}</label>
129
+ <textarea
130
+ className="mt-2 border w-full py-2 px-3 rounded-md"
131
+ id="notaAdicional"
132
+ type="text"
133
+ placeholder="Detalle de lunas"
134
+ ></textarea>
135
+ </div>
136
+ <div className="flex flex-col items-center gap-8 justify-center mt-10 px-5">
137
+ <table className="text-center border-2 table-fixed w-4/5 h-[6.5rem] border-separate lg:border-collapse">
138
+ <thead className="border-2">
139
+ <tr>
140
+ <th className="border">Esfera</th>
141
+ <th className="border">Cilindro</th>
142
+ <th className="border">Eje</th>
143
+ <th className="border">A/Y</th>
144
+ </tr>
145
+ </thead>
146
+ <tbody>
147
+ <tr>
148
+ <td className="border">
149
+ <input type="text" className="w-full h-full" />
150
+ </td>
151
+ <td className="border">
152
+ <input type="text" className="w-full h-full" />
153
+ </td>
154
+ <td className="border">
155
+ <input type="text" className="w-full h-full" />
156
+ </td>
157
+ <td className="border">
158
+ <input type="text" className="w-full h-full" />
159
+ </td>
160
+ </tr>
161
+ <tr>
162
+ <td className="border">
163
+ <input type="text" className="w-full h-full" />
164
+ </td>
165
+ <td className="border">
166
+ <input type="text" className="w-full h-full" />
167
+ </td>
168
+ <td className="border">
169
+ <input type="text" className="w-full h-full" />
170
+ </td>
171
+ <td className="border">
172
+ <input type="text" className="w-full h-full" />
173
+ </td>
174
+ </tr>
175
+ </tbody>
176
+ </table>
177
+ <table className="text-center border-2 table-fixed w-4/5 h-[6.5rem] border-separate lg:border-collapse">
178
+ <thead>
179
+ <tr>
180
+ <th className="border">Esfera</th>
181
+ <th className="border">Cilindro</th>
182
+ <th className="border">Eje</th>
183
+ <th className="border">A/Y</th>
184
+ </tr>
185
+ </thead>
186
+ <tbody>
187
+ <tr>
188
+ <td className="border">
189
+ <input type="text" className="w-full h-full" />
190
+ </td>
191
+ <td className="border">
192
+ <input type="text" className="w-full h-full" />
193
+ </td>
194
+ <td className="border">
195
+ <input type="text" className="w-full h-full" />
196
+ </td>
197
+ <td className="border">
198
+ <input type="text" className="w-full h-full" />
199
+ </td>
200
+ </tr>
201
+ <tr>
202
+ <td className="border">
203
+ <input type="text" className="w-full h-full" />
204
+ </td>
205
+ <td className="border">
206
+ <input type="text" className="w-full h-full" />
207
+ </td>
208
+ <td className="border">
209
+ <input type="text" className="w-full h-full" />
210
+ </td>
211
+ <td className="border">
212
+ <input type="text" className="w-full h-full" />
213
+ </td>
214
+ </tr>
215
+ </tbody>
216
+ </table>
217
+ </div>
218
+ <button className="rounded-md w-full py-3 mt-10 bg-slate-700 hover:bg-slate-800 text-white font-semibold uppercase ">
219
+ Emitir Prescripción
220
+ </button>
221
+ </div>
222
+ ) : (
223
+ <div className="px-5 flex flex-col w-3/5 h-full pb-20 border-l-2">
224
+ <p className="text-gray-400 text-2xl font-semibold">
225
+ No se ha seleccionado ningún cliente
226
+ </p>
227
+ </div>
228
+ )}
229
+
230
+ {openModal && <Modal
231
+ openModal={openModal}
232
+ setOpenModal={setOpenModal}
233
+ nombresYApellidos={nombresYApellidos}
234
+ setNombresYApellidos={setNombresYApellidos}
235
+ edad={edad}
236
+ setEdad={setEdad}
237
+ telefono={telefono}
238
+ setTelefono={setTelefono}
239
+ direccion={direccion}
240
+ setDireccion={setDireccion}
241
+ />}
242
+ </div>
243
+ );
244
+ };
src/assets/react.svg ADDED
src/components/Modal.jsx ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { registrarPost } from "../lib/conexionApi";
3
+
4
+ const Modal = ({
5
+ openModal,
6
+ setOpenModal,
7
+ nombresYApellidos,
8
+ setNombresYApellidos,
9
+ edad,
10
+ setEdad,
11
+ telefono,
12
+ setTelefono,
13
+ direccion,
14
+ setDireccion,
15
+ }) => {
16
+ return (
17
+ <div className="fixed inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex justify-center items-center">
18
+ <div className="bg-white p-5 w-1/3 shadow-md rounded-lg">
19
+ <form>
20
+ <h3 className="text-center text-3xl text-bold mb-8">
21
+ Agregar nuevo cliente
22
+ </h3>
23
+ <div className="">
24
+ <label htmlFor="nombresYApellidos" className="block">
25
+ Nombres y apellidos
26
+ </label>
27
+ <input
28
+ type="text"
29
+ id="nombresYApellidos"
30
+ className="block w-full border p-2 rounded-md"
31
+ placeholder="Ej. Juan Perez"
32
+ onChange={(e) => setNombresYApellidos(e.target.value)}
33
+ value={nombresYApellidos}
34
+ />
35
+ </div>
36
+ <div className="flex flex-row gap-3 my-3">
37
+ <div className="w-1/2">
38
+ <label htmlFor="edad" className="block">
39
+ Edad
40
+ </label>
41
+ <input
42
+ type="number"
43
+ id="edad"
44
+ className="block w-full border p-2 rounded-md"
45
+ placeholder="Ej. 40"
46
+ onChange={(e) => setEdad(e.target.value)}
47
+ value={edad}
48
+ />
49
+ </div>
50
+ <div className="w-1/2">
51
+ <label htmlFor="telefono" className="">
52
+ Telefono
53
+ </label>
54
+ <input
55
+ type="text"
56
+ id="telefono"
57
+ className="block w-full border p-2 rounded-md"
58
+ placeholder="Ej. 999888777"
59
+ onChange={(e) => setTelefono(e.target.value)}
60
+ value={telefono}
61
+ />
62
+ </div>
63
+ </div>
64
+ <div>
65
+ <label htmlFor="direccion" className="">
66
+ Direccion
67
+ </label>
68
+ <input
69
+ type="text"
70
+ id="direccion"
71
+ className="block w-full border p-2 rounded-md"
72
+ placeholder="Ej. Calle 123"
73
+ onChange={(e) => setDireccion(e.target.value)}
74
+ value={direccion}
75
+ />
76
+ </div>
77
+ <div>
78
+ <div>
79
+ <button
80
+ type="submit"
81
+ className="cursor-pointer py-2 w-full bg-slate-700 hover:bg-slate-800 text-white font-semibold text-center rounded-md mt-5"
82
+ onClick={(e) => {
83
+ e.preventDefault();
84
+ const nuevoCliente = {
85
+ "nombres_y_apellidos": nombresYApellidos,
86
+ "edad": edad,
87
+ "telefono": telefono,
88
+ "direccion": direccion
89
+ }
90
+ registrarPost("clientes", nuevoCliente);
91
+ setOpenModal(false);
92
+ }}
93
+ >
94
+ Agregar cliente
95
+ </button>
96
+ </div>
97
+ <div>
98
+ <button
99
+ className="cursor-pointer py-2 w-full bg-slate-300 hover:bg-slate-400 text-gray-700 font-semibold text-center rounded-md mt-2"
100
+ onClick={(e) => {
101
+ e.preventDefault();
102
+ setOpenModal(false);
103
+ }}
104
+ >
105
+ {" "}
106
+ Cancelar
107
+ </button>
108
+ </div>
109
+ </div>
110
+ </form>
111
+ </div>
112
+ </div>
113
+ );
114
+ };
115
+
116
+ export default Modal;
src/index.css ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
src/lib/conexionApi.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const url = 'https://jairodanielmt-opticaads.hf.space'
2
+
3
+ export const obtenerGet = async (endpoint) => {
4
+ const response = await fetch(`${url}/${endpoint}`)
5
+ const data = await response.json()
6
+ return data
7
+ }
8
+
9
+ export const registrarPost = async (endpoint, data) => {
10
+ const response = await fetch(`${url}/${endpoint}`, {
11
+ method: 'POST',
12
+ body: JSON.stringify(data),
13
+ headers: {
14
+ 'Content-type': 'application/json'
15
+ }
16
+ })
17
+ const res = await response.json()
18
+ return res
19
+ }
20
+
21
+ export const obtenerLike = async (endpoint, dato, funcionSet) => {
22
+ const response = await fetch(`${url}/${endpoint}`, {
23
+ method: 'POST',
24
+ headers: {
25
+ 'Content-type': 'application/json'
26
+ },
27
+ body: JSON.stringify(dato),
28
+ })
29
+ const data = await response.json()
30
+ funcionSet(data)
31
+ }
src/main.jsx ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react'
2
+ import ReactDOM from "react-dom/client";
3
+ import App from "./App.jsx";
4
+ import "./index.css";
5
+ import { BrowserRouter } from "react-router-dom";
6
+
7
+ ReactDOM.createRoot(document.getElementById("root")).render(
8
+ <React.StrictMode>
9
+ <BrowserRouter>
10
+ <App />
11
+ </BrowserRouter>
12
+ </React.StrictMode>
13
+ );
tailwind.config.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: ["index.html", "./src/**/*.jsx"],
4
+ theme: {
5
+ extend: {},
6
+ },
7
+ plugins: []
8
+ }
9
+
vite.config.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
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
+ })