david-rosval commited on
Commit
3ef08c5
·
1 Parent(s): f0716c2

catalogo hecho

Browse files
src/App.jsx CHANGED
@@ -3,6 +3,7 @@ import { NavBar } from "./NavBar";
3
  import { Prescripcion } from "./Prescripcion";
4
  import { Catalogo } from "./Catalogo";
5
  import { useState } from "react";
 
6
 
7
  const Home = () => {
8
  return <div>Home</div>;
@@ -14,6 +15,8 @@ const Pedidos = () => {
14
 
15
  export default function App() {
16
 
 
 
17
  return (
18
  <div className="flex flex-col items-center h-screen">
19
  <NavBar />
@@ -21,7 +24,8 @@ export default function App() {
21
  <Route path="/" element={<Home />} />
22
  <Route path="/pedidos" element={<Pedidos />} />
23
  <Route path="/prescripcion" element={<Prescripcion />} />
24
- <Route path="/catalogo" element={<Catalogo />} />
 
25
  </Routes>
26
  </div>
27
  );
 
3
  import { Prescripcion } from "./Prescripcion";
4
  import { Catalogo } from "./Catalogo";
5
  import { useState } from "react";
6
+ import { Carrito } from "./Carrito";
7
 
8
  const Home = () => {
9
  return <div>Home</div>;
 
15
 
16
  export default function App() {
17
 
18
+ const [carrito, setCarrito] = useState([])
19
+
20
  return (
21
  <div className="flex flex-col items-center h-screen">
22
  <NavBar />
 
24
  <Route path="/" element={<Home />} />
25
  <Route path="/pedidos" element={<Pedidos />} />
26
  <Route path="/prescripcion" element={<Prescripcion />} />
27
+ <Route path="/catalogo" element={<Catalogo setCarrito={setCarrito} carrito={carrito}/>} />
28
+ <Route path="/carrito" element={<Carrito setCarrito={setCarrito} carrito={carrito}/>} />
29
  </Routes>
30
  </div>
31
  );
src/Carrito.jsx ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import React from 'react'
2
+
3
+ export const Carrito = () => {
4
+ return (
5
+ <div>Carrito</div>
6
+ )
7
+ }
src/Catalogo.jsx CHANGED
@@ -1,8 +1,84 @@
1
- import React from 'react'
2
- import CatalogoMonturaCard from './components/CatalogoMonturaCard'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
- export const Catalogo = () => {
5
  return (
6
- <CatalogoMonturaCard/>
7
- )
8
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useEffect, useState } from "react";
2
+ import CatalogoMonturaCard from "./components/CatalogoMonturaCard";
3
+ import {
4
+ actualizarPut,
5
+ cargarApi,
6
+ obtenerEspecifico,
7
+ registrarPost,
8
+ obtenerGet,
9
+ } from "./lib/conexionApi";
10
+ import ModalVerCarrito from "./components/ModalVerCarrito";
11
+
12
+ export const Catalogo = ({ setCarrito, carrito }) => {
13
+ // Se obtienen primero los detalles de cada montura
14
+ const [monturas, setMonturas] = useState([]);
15
+ // se obtienen los datos de precio, stock y código
16
+ const [monturasInventario, setmonturasInventario] = useState([]);
17
+
18
+ const [montura, setMontura] = useState({})
19
+ const [monturaInventario, setMonturaInventario] = useState({})
20
+
21
+ const [errorConsultaMonturas, setsetErrorConsultaMonturas] = useState(false);
22
+ const [errorConsultaMonturasInv, setsetErrorConsultaMonturasInv] =
23
+ useState(false);
24
+
25
+ const [btnBuscarMonturaCodigo, setbtnBuscarMonturaCodigo] = useState(false);
26
+
27
+ const [modalVerCarrito, setModalVerCarrito] = useState(false)
28
+
29
+ // obtener detalle de monturas
30
+ useEffect(() => {
31
+ obtenerGet("monturas", setMonturas, setsetErrorConsultaMonturas);
32
+ }, []);
33
+ // obtener catalogo de monturas
34
+ useEffect(() => {
35
+ obtenerGet(
36
+ "monturas_inventario",
37
+ setmonturasInventario,
38
+ setsetErrorConsultaMonturasInv
39
+ );
40
+ }, []);
41
 
 
42
  return (
43
+ <div className="mx-20 mt-5">
44
+
45
+ <div className="flex flex-col justify-center items-center">
46
+ <h1 className="my-10 text-5xl font-semibold text-center">Catálogo de monturas</h1>
47
+ <div className="flex flex-row gap-2 mb-2 w-1/3">
48
+ <input
49
+ className="border w-3/4 py-2 px-3 rounded-md"
50
+ id="input-buscar-cliente "
51
+ type="text"
52
+ placeholder="Código de montura"
53
+ />
54
+ <button className="rounded-md w-1/4 bg-slate-700 hover:bg-slate-800 text-white font-semibold px-2 text-center">
55
+ Buscar
56
+ </button>
57
+ </div>
58
+ </div>
59
+ <div className="mt-5 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2">
60
+ {monturasInventario.map((monturaInventario) => {
61
+ const montura = monturas.find(
62
+ (montura) =>
63
+ montura["id_montura"] === monturaInventario["id_montura"]
64
+ );
65
+ return (
66
+ <CatalogoMonturaCard
67
+ key={montura["id_montura"]}
68
+ montura={montura}
69
+ monturaInventario={monturaInventario}
70
+ setModalVerCarrito={setModalVerCarrito}
71
+ setMontura={setMontura}
72
+ setMonturaInventario={setMonturaInventario}
73
+ setCarrito={setCarrito}
74
+ carrito={carrito}
75
+ />
76
+ );
77
+ })}
78
+ </div>
79
+ {modalVerCarrito && (
80
+ <ModalVerCarrito montura={montura} monturaInventario={monturaInventario} setModalVerCarrito={setModalVerCarrito} setMontura={setMontura} setMonturaInventario={setMonturaInventario} />
81
+ )}
82
+ </div>
83
+ );
84
+ };
src/NavBar.jsx CHANGED
@@ -5,31 +5,36 @@ export const NavBar = () => {
5
  return (
6
  <header className="w-full ">
7
  <div className="bg-slate-500 text-white text-center pt-20 pb-10">
8
- <h1 className="text-5xl font-semibold ">Óptica Arte Visual</h1>
9
  <p className="mt-5">La mejor calidad en monturas con modelos exclusivos y resinas de alta calidad</p>
10
  </div>
11
  <nav className="bg-slate-700">
12
  <ul id="nav-ul" className="flex flex-row justify-center text-xl">
13
- <NavLink className="w-1/4 text-center" to="/">
14
  <li className="hover:bg-slate-800 text-white py-2 hover:font-semibold">
15
  Home
16
  </li>
17
  </NavLink>
18
- <NavLink className="w-1/4 text-center" to="/pedidos">
19
  <li className="hover:bg-slate-800 text-white py-2 hover:font-semibold">
20
  Pedidos
21
  </li>
22
  </NavLink>
23
- <NavLink className="w-1/4 text-center" to="/prescripcion">
24
  <li className="hover:bg-slate-800 text-white py-2 hover:font-semibold">
25
  Emitir Prescripción
26
  </li>
27
  </NavLink>
28
- <NavLink className="w-1/4 text-center" to="/catalogo">
29
  <li className="hover:bg-slate-800 text-white py-2 hover:font-semibold">
30
  Catálogo
31
  </li>
32
  </NavLink>
 
 
 
 
 
33
  </ul>
34
  </nav>
35
  </header>
 
5
  return (
6
  <header className="w-full ">
7
  <div className="bg-slate-500 text-white text-center pt-20 pb-10">
8
+ <h1 className="text-4xl font-semibold ">Óptica Arte Visual</h1>
9
  <p className="mt-5">La mejor calidad en monturas con modelos exclusivos y resinas de alta calidad</p>
10
  </div>
11
  <nav className="bg-slate-700">
12
  <ul id="nav-ul" className="flex flex-row justify-center text-xl">
13
+ <NavLink className="w-1/5 text-center" to="/">
14
  <li className="hover:bg-slate-800 text-white py-2 hover:font-semibold">
15
  Home
16
  </li>
17
  </NavLink>
18
+ <NavLink className="w-1/5 text-center" to="/pedidos">
19
  <li className="hover:bg-slate-800 text-white py-2 hover:font-semibold">
20
  Pedidos
21
  </li>
22
  </NavLink>
23
+ <NavLink className="w-1/5 text-center" to="/prescripcion">
24
  <li className="hover:bg-slate-800 text-white py-2 hover:font-semibold">
25
  Emitir Prescripción
26
  </li>
27
  </NavLink>
28
+ <NavLink className="w-1/5 text-center" to="/catalogo">
29
  <li className="hover:bg-slate-800 text-white py-2 hover:font-semibold">
30
  Catálogo
31
  </li>
32
  </NavLink>
33
+ <NavLink className="w-1/5 text-center" to="/carrito">
34
+ <li className="hover:bg-slate-800 text-white py-2 hover:font-semibold">
35
+ Carrito de compras
36
+ </li>
37
+ </NavLink>
38
  </ul>
39
  </nav>
40
  </header>
src/Prescripcion.jsx CHANGED
@@ -222,7 +222,7 @@ export const Prescripcion = () => {
222
  return (
223
  <div className=" w-3/5 flex flex-row my-5 p-5 h-auto">
224
  <div className="w-2/5">
225
- {btnBuscarClick && error && <ErrorMessage mensaje={'No se encontraron resultados'}/>}
226
  <div className=" flex flex-row">
227
  <div className="w-full pr-5">
228
  {/* BARRA DE BÚSQUEDA DE CLIENTE */}
@@ -366,6 +366,8 @@ export const Prescripcion = () => {
366
  setTelefono={setTelefono}
367
  direccion={direccion}
368
  setDireccion={setDireccion}
 
 
369
  />
370
  )}
371
  {openModalPrescripcion && (
 
222
  return (
223
  <div className=" w-3/5 flex flex-row my-5 p-5 h-auto">
224
  <div className="w-2/5">
225
+ {(btnBuscarClick && error) && <ErrorMessage mensaje={'No se encontraron resultados'}/>}
226
  <div className=" flex flex-row">
227
  <div className="w-full pr-5">
228
  {/* BARRA DE BÚSQUEDA DE CLIENTE */}
 
366
  setTelefono={setTelefono}
367
  direccion={direccion}
368
  setDireccion={setDireccion}
369
+ setError={setError}
370
+ setClienteBusqueda={setClienteBusqueda}
371
  />
372
  )}
373
  {openModalPrescripcion && (
src/components/CatalogoMonturaCard.jsx CHANGED
@@ -1,8 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
- const CatalogoMonturaCard = () => {
3
  return (
4
- <div>montura</div>
5
- )
6
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
- export default CatalogoMonturaCard
 
1
+ import { formatearStringUrlImagen } from "../lib/funciones";
2
+
3
+ const CatalogoMonturaCard = ({
4
+ montura = {
5
+ "id_montura": 10,
6
+ "nombre_montura": "Nombre monturaaaaaaaaaaaaaaaaaaa",
7
+ "imagen":
8
+ '<img src="https://i.ibb.co/jHWcz8B/EBJ8-NK3-Ko81-301-C5-Frontal.png" alt="EBJ8-NK3-Ko81-301-C5-Frontal" border="0">',
9
+ "marca": "Marca montura",
10
+ "color": "Color montura",
11
+ "material": "Material Montura",
12
+ },
13
+ monturaInventario = {
14
+ "id_montura_inventario": 10,
15
+ "id_montura": 8,
16
+ "precio_unit": 90,
17
+ "stock": 20,
18
+ "codigo": "montura8",
19
+ },
20
+ setModalVerCarrito,
21
+ setMontura,
22
+ setMonturaInventario,
23
+ setCarrito,
24
+ carrito
25
+ }) => {
26
+ const { src, alt, border } = formatearStringUrlImagen(montura["imagen"]);
27
 
 
28
  return (
29
+ <div className="p-5 hover:bg-slate-50 w-[360px]">
30
+ <div className="w-30 h-[150px] p-5">
31
+ <img src={src} alt={alt} border={border} className=" mb-5" />
32
+ </div>
33
+ <div className="flex flex-col items-center">
34
+ <h3 className="text-center px-6 w-full uppercase text-xl font-semibold truncate ">{montura["nombre_montura"]}</h3>
35
+ <div className="flex flex-row gap-2 items-center">
36
+ <p className="text-sm ">S/.
37
+ <span className="text-2xl">
38
+ {monturaInventario["precio_unit"]}
39
+ </span>
40
+ </p>
41
+ <div className="hover:bg-slate-300 rounded-full p-2">
42
+ <svg
43
+ xmlns="http://www.w3.org/2000/svg"
44
+ className="icon icon-tabler icon-tabler-shopping-cart-plus"
45
+ width="30"
46
+ height="30"
47
+ viewBox="0 0 24 24"
48
+ strokeWidth="1.5"
49
+ stroke="#000000"
50
+ fill="none"
51
+ strokeLinecap="round"
52
+ strokeLinejoin="round"
53
+ onClick={(e) => {
54
+ e.preventDefault();
55
+ setMontura(montura);
56
+ setMonturaInventario(monturaInventario);
57
+ setModalVerCarrito(true)
58
+ setCarrito([...carrito, {
59
+ "id_montura_inventario":monturaInventario["id_montura_inventario"],
60
+ "cantidad":1,
61
+ "precio":monturaInventario["precio_unit"],
62
+ "id_boleta": NaN
63
+ }])
64
+ }}
65
+ >
66
+ <path stroke="none" d="M0 0h24v24H0z" fill="none" />
67
+ <path d="M4 19a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
68
+ <path d="M12.5 17h-6.5v-14h-2" />
69
+ <path d="M6 5l14 1l-.86 6.017m-2.64 .983h-10.5" />
70
+ <path d="M16 19h6" />
71
+ <path d="M19 16v6" />
72
+ </svg>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ );
78
+ };
79
 
80
+ export default CatalogoMonturaCard;
src/components/Modal.jsx CHANGED
@@ -12,6 +12,8 @@ const Modal = ({
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">
@@ -93,6 +95,8 @@ const Modal = ({
93
  setEdad("");
94
  setTelefono("");
95
  setDireccion("");
 
 
96
  }}
97
  >
98
  Agregar cliente
@@ -108,6 +112,7 @@ const Modal = ({
108
  setEdad("");
109
  setTelefono("");
110
  setDireccion("");
 
111
  }}
112
  >
113
  Cancelar
 
12
  setTelefono,
13
  direccion,
14
  setDireccion,
15
+ setError,
16
+ setClienteBusqueda
17
  }) => {
18
  return (
19
  <div className="fixed inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex justify-center items-center">
 
95
  setEdad("");
96
  setTelefono("");
97
  setDireccion("");
98
+ setError(false);
99
+ setClienteBusqueda("");
100
  }}
101
  >
102
  Agregar cliente
 
112
  setEdad("");
113
  setTelefono("");
114
  setDireccion("");
115
+ setClienteBusqueda("");
116
  }}
117
  >
118
  Cancelar
src/components/ModalVerCarrito.jsx ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { formatearStringUrlImagen } from "../lib/funciones";
3
+
4
+ const ModalVerCarrito = ({
5
+ montura = {
6
+ "id_montura": 10,
7
+ "nombre_montura": "Nombre monturaaaaaaaaaaaaaaaaaaa",
8
+ "imagen":
9
+ '<img src="https://i.ibb.co/jHWcz8B/EBJ8-NK3-Ko81-301-C5-Frontal.png" alt="EBJ8-NK3-Ko81-301-C5-Frontal" border="0">',
10
+ "marca": "Marca montura",
11
+ "color": "Color montura",
12
+ "material": "Material Montura",
13
+ },
14
+ monturaInventario = {
15
+ "id_montura_inventario": 10,
16
+ "id_montura": 8,
17
+ "precio_unit": 90,
18
+ "stock": 20,
19
+ "codigo": "montura8",
20
+ },
21
+ setModalVerCarrito,
22
+ carrito,
23
+ setMontura,
24
+ setMonturaInventario
25
+ }) => {
26
+ const { src, alt, border } = formatearStringUrlImagen(montura["imagen"]);
27
+
28
+ return (
29
+ <div className="fixed inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex justify-center items-center">
30
+ <div className="bg-white px-10 py-5 w-[790.5px] shadow-md rounded-lg ">
31
+ <div className=" flex items-center justify-between border-b-2 border-black pb-2">
32
+ <p className="uppercase">Recién añadido a tu carrito de compra</p>
33
+ <svg
34
+ xmlns="http://www.w3.org/2000/svg"
35
+ className="icon icon-tabler icon-tabler-x w-10 h-10 rounded-full cursor-pointer p-1"
36
+ width="25"
37
+ height="25"
38
+ viewBox="0 0 24 24"
39
+ strokeWidth="2"
40
+ stroke="#000000"
41
+ fill="none"
42
+ strokeLinecap="round"
43
+ strokeLinejoin="round"
44
+ onClick={() => {
45
+ setMonturaInventario({})
46
+ setMontura({})
47
+ setModalVerCarrito(false)
48
+ }}
49
+ >
50
+ <path stroke="none" d="M0 0h24v24H0z" fill="none" />
51
+ <path d="M18 6l-12 12" />
52
+ <path d="M6 6l12 12" />
53
+ </svg>
54
+ </div>
55
+ <div className="flex w-full my-10 ">
56
+ <div className="w-1/2">
57
+ <img src={src} alt={alt} border={border} />
58
+ </div>
59
+ <div className="w-1/2">
60
+ <div className="flex flex-col gap-2">
61
+ <p className="w-full text-xl truncate uppercase">
62
+ {montura["nombre_montura"]}
63
+ </p>
64
+ <p className="text-xl uppercase">{montura["marca"]}</p>
65
+ <p className="mt-3">
66
+ Color: <span className="uppercase">{montura["color"]}</span>
67
+ </p>
68
+ <p className="">
69
+ Material:{" "}
70
+ <span className="uppercase">{montura["material"]}</span>
71
+ </p>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ <button className="w-full text-xl py-4 uppercase border-2 cursor-pointer border-black hover:bg-gray-300">
76
+ Ver Carrito {0}
77
+ </button>
78
+ </div>
79
+ </div>
80
+ );
81
+ };
82
+
83
+ export default ModalVerCarrito;
src/lib/conexionApi.js CHANGED
@@ -8,10 +8,13 @@ export const cargarApi = async () => {
8
  }
9
  }
10
 
11
- export const obtenerGet = async (endpoint) => {
12
  const response = await fetch(`${url}/${endpoint}`)
13
  const data = await response.json()
14
- return data
 
 
 
15
  }
16
 
17
  export const registrarPost = async (endpoint, data) => {
@@ -57,4 +60,9 @@ export const getEspecifico = async (endpoint, dato) => {
57
  const response = await fetch(`${url}/${endpoint}`)
58
  const data = await response.json()
59
  return data
60
- }
 
 
 
 
 
 
8
  }
9
  }
10
 
11
+ export const obtenerGet = async (endpoint, funcionSet, funcionSetError) => {
12
  const response = await fetch(`${url}/${endpoint}`)
13
  const data = await response.json()
14
+ if (data.error || data.length === 0) {
15
+ funcionSetError(true)
16
+ }
17
+ funcionSet(data)
18
  }
19
 
20
  export const registrarPost = async (endpoint, data) => {
 
60
  const response = await fetch(`${url}/${endpoint}`)
61
  const data = await response.json()
62
  return data
63
+ }
64
+
65
+ export const emitirPdfPrescripcion = (idPrescripcion) => {
66
+ const urlPdf = `${url}/prescripcion/pdf/${idPrescripcion}`
67
+ return urlPdf
68
+ }
src/lib/funciones.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export function formatearStringUrlImagen(stringImagen='<img src="https://i.ibb.co/TTmWTjV/df-BBqw-TYjvfrontal-tom-silver-optimania.png" alt="df-BBqw-TYjvfrontal-tom-silver-optimania" border="0">') {
2
+ // Crear un elemento temporal para parsear el string HTML
3
+ const tempElement = document.createElement('div');
4
+ tempElement.innerHTML = stringImagen;
5
+
6
+ // Obtener los atributos necesarios del elemento
7
+ const src = tempElement.querySelector('img').getAttribute('src');
8
+ const alt = tempElement.querySelector('img').getAttribute('alt');
9
+ const border = tempElement.querySelector('img').getAttribute('border');
10
+
11
+ // Crear un objeto con los valores obtenidos
12
+ const imagenObj = {
13
+ src: src,
14
+ alt: alt,
15
+ border: border
16
+ };
17
+
18
+ return imagenObj;
19
+ }