Repository: ucb-scz-dims/SIS-213-ON
Pull request #41: checkout diseño completo
Author: login: henrrycoronado
Created: 2025-04-24T04:13:10Z | Merged: 2025-04-30T18:25:32Z

# RESUMEN
De manera rapida se expondra los cambios solicitados.
## No relevantes
El cambio en el "Button.jsx" es correccion a una advertencia que aparece al ejecutar.

## Cambios relevantes
Se crean 3 componentes nuevos :
- "EditSelec" : este componente hace el trabajo de plantilla para secciones editables con opciones ya definidas.
- "Notification.jsx" : este componente tendra de trabajo enviar los mensajes para diferentes secciones que se le aplique, actualmente solo tiene uso en el checkout, ademas este componente tiene dos versiones, en donde se puede pedir un mensaje "full" que abarca toda la pantalla y el otro es un mensaje emergente , ambos son temporalizados
- "OrderResume" : este componente solo tiene el deber de listar en tabla , la lista de productos que se le asigne bajo una estructura ya esperada

Y tambien por ultimo se actualiza la page "CheckOut" : la que se encarga de consumir los componentes y dar paso a el registro del pedido

## OBSERVACION
La pagina aun no envia los datos a supabase, se añadira esta funcionalidad en el siguiente pr

@RaidenMT @MaBelenBecerra 


Diff:
diff --git a/OrderNow-React/src/assets/constants.js b/OrderNow-React/src/assets/constants.js
new file mode 100644
index 0000000..01af5b0
--- /dev/null
+++ b/OrderNow-React/src/assets/constants.js
@@ -0,0 +1,33 @@
+export const COLORS = {
+    primary: "#007bff",
+    secondary: "#6c757d",
+    success: "#28a745",
+    danger: "#dc3545",
+    warning: "#ffc107",
+    info: "#17a2b8",
+    light: "#f8f9fa",
+    dark: "#343a40",
+    white: "#ffffff",
+    black: "#000000",
+    gray: "#6c757d",
+    red: "#dc3545",
+    green: "#28a745",
+}
+
+
+export const ICONS = {
+    cart: "🛒",
+    check: "✅",
+    warning: "⚠️",
+    error: "❌",
+    success: "🎉",
+    info: "ℹ️",
+    close: "X",
+    edit: "✏️",
+    delete: "🗑️",
+    add: "➕",
+    remove: "➖",
+    search: "🔍",
+    filter: "🔧",
+    sort: "🔽",
+}
\ No newline at end of file
diff --git a/OrderNow-React/src/components/EditSelect/EditSelect.jsx b/OrderNow-React/src/components/EditSelect/EditSelect.jsx
new file mode 100644
index 0000000..cab9597
--- /dev/null
+++ b/OrderNow-React/src/components/EditSelect/EditSelect.jsx
@@ -0,0 +1,33 @@
+import React, {useState} from "react";
+import Button from "../atoms/Button";
+
+export const EditSelect = ({name = "title", edit = false, options = ["vacio"], additionalText = ""}) => {
+    const [stateEdit, setStateEdit] = useState(edit);
+    const [currentOption, setCurrentOption] = useState(options[0]);
+    return (
+        <div className="bg-gray-100 rounded-lg p-4 space-y-2">
+            <h3 className="text-sm font-semibold text-gray-700">{name}</h3>
+            <div className="flex justify-between items-center">
+                {stateEdit ? (
+                    <div className="flex justify-between items-center">
+                        <select value={currentOption} onChange={(e) => setCurrentOption(e.target.value)}
+                        className="text-sm text-gray-800 border px-2 py-1 rounded mr-2 w-full">
+                            {options.map((opcion) => (
+                                <option key={opcion} value={opcion}>
+                                    {opcion}
+                                </option>
+                            ))}
+                        </select>
+                        <Button onClick={() => setStateEdit(false)} label="Guardar" type="button"/>
+                    </div>
+                ) : (
+                    <div className="flex justify-between items-center">
+                        <p className="text-sm px-2 py-1"> {currentOption} {additionalText} </p>
+                        <Button onClick={() => setStateEdit(true)} label="Editar" type="button"/>
+                    </div>
+                )}
+            </div>
+        </div>
+    );
+}
+export default EditSelect;
\ No newline at end of file
diff --git a/OrderNow-React/src/components/Notification/Notification.jsx b/OrderNow-React/src/components/Notification/Notification.jsx
new file mode 100644
index 0000000..ed5bb94
--- /dev/null
+++ b/OrderNow-React/src/components/Notification/Notification.jsx
@@ -0,0 +1,44 @@
+import React, {useState} from 'react';
+import { COLORS } from '../../assets/constants';
+import { ICONS } from '../../assets/constants';
+
+const Notification = ({
+    message = 'message',
+    subMessage = 'submessage',
+    success = true ,
+    full = false,
+    visible = false
+}) => {
+    const topOffset = '80px';
+    const [icon, setIcon] = useState(ICONS.check);
+    const [bgColor, setBgColor] = useState(COLORS.green);
+    if(!success){
+        setIcon(ICONS.error);
+        setBgColor(COLORS.red);
+    }
+    if(full && visible){
+        return (
+            <div style={{ backgroundColor: bgColor }}
+                className="w-screen h-screen flex flex-col justify-center items-center text-white text-center p-4 fixed top-0 left-0 z-50"
+            >
+                <div className="text-6xl mb-6">{icon}</div>
+                <h1 className="text-2xl font-bold">{message}</h1>
+                <p className="text-md mt-2">{subMessage}</p>
+            </div>
+        );
+    }
+    if(!full && visible){ 	
+        return (
+            <div style={{ backgroundColor: bgColor, top: topOffset, color: '#fff'}}
+                className="w-full max-w-md mx-auto py-3 px-4 flex items-center justify-between gap-3 shadow-lg rounded-md fixed left-0 right-0 z-50"
+            >
+                <div className="flex items-center gap-3">
+                    <span className="text-xl">{icon}</span>
+                    <span className="text-sm font-medium">{message}</span>
+                </div>
+            </div>
+        );
+    }
+};
+
+export default Notification;
\ No newline at end of file
diff --git a/OrderNow-React/src/components/OrderResume/OrderResume.jsx b/OrderNow-React/src/components/OrderResume/OrderResume.jsx
new file mode 100644
index 0000000..88e8495
--- /dev/null
+++ b/OrderNow-React/src/components/OrderResume/OrderResume.jsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import { useNavigate } from "react-router-dom";
+import Button from "../atoms/Button";
+
+const OrderResume = ({products = []}) => {
+    const navigate = useNavigate();
+    return (
+        <div className="overflow-x-auto transition-all duration-300 ease-in-out mt-2">
+            <div className="flex justify-end mb-2">
+                <Button onClick={() => navigate(`/cart/test`)} type="button" label="editar pedido"/>
+            </div>
+            <table className="min-w-full text-sm text-gray-700">
+                <thead>
+                    <tr className="bg-gray-200 text-xs text-gray-600 uppercase tracking-wide">
+                        <th className="px-3 py-2 text-left">Producto</th>
+                        <th className="px-3 py-2 text-center">Cant.</th>
+                        <th className="px-3 py-2 text-right">Precio Unit.</th>
+                        <th className="px-3 py-2 text-right">Subtotal</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    {products.map((product) => (
+                        <tr key={product.id} className="border-b border-gray-200 last:border-none">
+                            <td className="px-3 py-2">{product.title}</td>
+                            <td className="px-3 py-2 text-center">{product.quantity}</td>
+                            <td className="px-3 py-2 text-right">Bs. {product.price.toFixed(2)}</td>
+                            <td className="px-3 py-2 text-right">Bs. {(product.price * product.quantity).toFixed(2)}
+                            </td>
+                        </tr>
+                    ))}
+                </tbody>
+            </table>
+        </div>
+    );
+};
+
+export default OrderResume;
\ No newline at end of file
diff --git a/OrderNow-React/src/pages/Checkout.jsx b/OrderNow-React/src/pages/Checkout.jsx
index e8f47ab..8e72625 100644
--- a/OrderNow-React/src/pages/Checkout.jsx
+++ b/OrderNow-React/src/pages/Checkout.jsx
@@ -1,62 +1,86 @@
-import Button from "../components/atoms/Button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState } from "react";
-import { useCart, useCartDispatch, useRestaurant } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
+import Button from "../components/atoms/Button";
 
 const Checkout = () => {
   const products = useCart();
-  const dispatch = useCartDispatch();
-  const { setRestaurantId } = useRestaurant();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const handleConfirmOrder = () => {
-    dispatch({ type: 'reset' });
-    setRestaurantId(null);
-    navigate('/');
-  }
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const [notificationConfig, setNotificationConfig] = useState({
+    message: "Tu pedido se ha realizado con exito",
+    subMessage: "Puedes seguir comprando",
+    success: true,
+    full: true,
+    visible: false
+  });
+
+  const [showResumen, setShowResumen] = useState(false);
+
+  const goToBusiness = async () => {
+    setNotificationConfig(prev => ({...prev, visible: true }));
+    setTimeout(() => {
+      setNotificationConfig(prev => ({...prev, visible: false }));
+      navigate("/restaurantes");
+    }, 3000);
+  };
+
   return (
-    <div className="space-y-4 flex flex-col items-center mt-3 pt-24">
-      <h1>Confirmación del producto</h1>
-      <div className="relative overflow-x-auto shadow-md sm:rounded-lg">
-        <table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
-          <thead>
-            <tr className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
-              <th class="px-6 py-3">Producto</th>
-              <th class="px-6 py-3">Cantidad</th>
-              <th class="px-6 py-3">Precio unit.</th>
-              <th class="px-6 py-3">Precio total</th>
-            </tr>
-          </thead>
-          <tbody>
-            {products.map((product) => (
-              <tr class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700 border-gray-200">
-                <td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
-                  {product.title}
-                </td>
-                <td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
-                  {product.quantity}
-                </td>
-                <td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
-                  {product.price}
-                </td>
-                <td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
-                  {product.price * product.quantity}
-                </td>
-              </tr>
-            ))}
-          </tbody>
-        </table>
-      </div>
-      <div className="flex flex-col items-center">
-        <h3 className="text-xl m-2">Total del pedido: {price} Bs.</h3>
-        <div onClick={handleConfirmOrder}>
-          <Button label="Confirmar pedido" type="button" />
+    <div className="max-w-md mx-auto mt-28 p-4 space-y-4 bg-white rounded-xl shadow-lg">
+      <Notification {...notificationConfig}/>
+      <h2 className="text-lg font-bold text-center">Confirma tu pedido</h2>
+
+      {/* Detalle de entrega */}
+      <EditSelect name="Direccion de entrega" edit={false} options={opcionesDireccion}/>
+
+      {/* Métodos de pago */}
+      <EditSelect name="Metodo de pago" edit={false} options={opcionesPago} additionalText={"➡️ " + totalPrice}/>
+
+      {/* Sección de resumen */}
+      <div className="bg-gray-100 rounded-lg p-4 space-y-2">
+        <div className="flex justify-between items-center">
+          <span>Resumen del pedido</span>
+          <Button onClick={() => setShowResumen(!showResumen)} type="button" label={showResumen ? "−" : "+"}/>
         </div>
+        {showResumen? ( <OrderResume products={products}/> ) : (null)}
+        
+        {/* Desglose de precios */}
+        <div className="text-sm space-y-1 pt-2 border-t border-gray-300">
+          <div className="flex justify-between">
+            <span>Productos</span>
+            <span>Bs. {totalcarrito.toFixed(2)}</span>
+          </div>
+          <div className="flex justify-between">
+            <span>Envío</span>
+            <span>Bs. {sendPrice}</span>
+          </div>
+          <div className="flex justify-between">
+            <span>Servicio</span>
+            <span>Bs. {servicePrice}</span>
+          </div>
+          <hr className="my-2" />
+          <div className="flex justify-between font-bold">
+            <span>Total</span>
+            <span>{totalPrice}</span>
+          </div>
+        </div>
+      </div>
+
+      {/* Botón de confirmación */}
+      <div className="flex justify-center mt-4">
+
+        <Button onClick={goToBusiness} label={"Pedir " + totalPrice} type="button"/>
       </div>
     </div>
   );


Reviews:
user: login: RaidenMakio
body: Corregir
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T22:55:51Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T04:57:21Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T04:58:24Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T04:58:38Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T04:58:49Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T04:59:03Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T04:59:13Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T05:00:19Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T05:00:27Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T05:00:34Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T05:00:39Z
user: login: henrrycoronado
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-26T05:00:47Z
user: login: RaidenMT
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T19:26:05Z

Review comments:
diff_hunk: @@ -0,0 +1,36 @@
+import React, {useState} from "react";
+
+export const EditSelect = ({name = "title", edit = false, options = ["vacio"], additionalText = ""}) => {
+    const [stateEdit, setStateEdit] = useState(edit);
+    const [currentOption, setCurrentOption] = useState(options[0]);
+    return (
+        <div className="bg-gray-100 rounded-lg p-4 space-y-2">
+            <h3 className="text-sm font-semibold text-gray-700">{name}</h3>
+            <div className="flex justify-between items-center">
+                {stateEdit ? (
+                    <div>
+                        <select value={currentOption} onChange={(e) => setCurrentOption(e.target.value)}
+                        className="text-sm text-gray-800 border px-2 py-1 rounded mr-2 w-full">
+                            {options.map((opcion) => (
+                                <option key={opcion} value={opcion}>
+                                    {opcion}
+                                </option>
+                            ))}
+                        </select>
+                        <button onClick={() => setStateEdit(false)} className="text-blue-500 text-sm ml-2">
+                            Guardar
+                        </button>
+                    </div>
+                ) : (
+                    <div>
+                        <p className="text-sm"> {currentOption} {additionalText} </p>
+                        <button onClick={() => setStateEdit(true)} className="text-blue-500 text-sm ml-2">
path: OrderNow-React/src/components/EditSelect/EditSelect.jsx
user: login: RaidenMakio
body: Componente Button
created_at: 2025-04-25T22:51:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+import React, {useState} from 'react';
+
+const Notification = ({
+    message = 'message',
+    subMessage = 'submessage',
+    success = true ,
+    full = false,
+    visible = false,
+}) => {
+    const [icon, setIcon] = useState('✅');
+    const [bgColor, setBgColor] = useState('#00C48C');
+    const topOffset = '80px';
+    if (!visible) return null;
+    if(!success){
+        setIcon('⚠️');
+        setBgColor('#FF4D4F');
+    }
+    if(full){
path: OrderNow-React/src/components/Notification/Notification.jsx
user: login: RaidenMakio
body: Convertir a ternario
created_at: 2025-04-25T22:53:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+import React, {useState} from 'react';
+
+const Notification = ({
+    message = 'message',
+    subMessage = 'submessage',
+    success = true ,
+    full = false,
+    visible = false,
+}) => {
+    const [icon, setIcon] = useState('✅');
+    const [bgColor, setBgColor] = useState('#00C48C');
+    const topOffset = '80px';
+    if (!visible) return null;
+    if(!success){
+        setIcon('⚠️');
+        setBgColor('#FF4D4F');
+    }
+    if(full){
+        return (
+            <div style={{ backgroundColor: bgColor }}
+                className="w-screen h-screen flex flex-col justify-center items-center text-white text-center p-4 fixed top-0 left-0 z-50"
+            >
+                <div className="text-6xl mb-6">{icon}</div>
+                <h1 className="text-2xl font-bold">{message}</h1>
+                <p className="text-md mt-2">{subMessage}</p>
+            </div>
+        );
+    }else{
path: OrderNow-React/src/components/Notification/Notification.jsx
user: login: RaidenMakio
body: Unificar con lo de arriba
created_at: 2025-04-25T22:53:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+import React, {useState} from 'react';
+
+const Notification = ({
+    message = 'message',
+    subMessage = 'submessage',
+    success = true ,
+    full = false,
+    visible = false,
+}) => {
+    const [icon, setIcon] = useState('✅');
+    const [bgColor, setBgColor] = useState('#00C48C');
+    const topOffset = '80px';
+    if (!visible) return null;
path: OrderNow-React/src/components/Notification/Notification.jsx
user: login: RaidenMakio
body: Bajar la lógica en el return
created_at: 2025-04-25T22:53:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+import React, {useState} from 'react';
+
+const Notification = ({
+    message = 'message',
+    subMessage = 'submessage',
+    success = true ,
+    full = false,
+    visible = false,
+}) => {
+    const [icon, setIcon] = useState('✅');
+    const [bgColor, setBgColor] = useState('#00C48C');
path: OrderNow-React/src/components/Notification/Notification.jsx
user: login: RaidenMakio
body: Convertir en constante en un archivo con la lista de colores
created_at: 2025-04-25T22:54:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,38 @@
+import React from 'react';
+import { useNavigate } from "react-router-dom";
+
+const OrderResume = ({products = []}) => {
+    const navigate = useNavigate();
+    return (
+        <div className="overflow-x-auto transition-all duration-300 ease-in-out mt-2">
+            <div className="flex justify-end mb-2">
+                <button onClick={() => navigate(`/cart/test`)} className="text-blue-500 text-sm">
path: OrderNow-React/src/components/OrderResume/OrderResume.jsx
user: login: RaidenMakio
body: Componente Button
created_at: 2025-04-25T22:54:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
+  const[fullNoti, setFullNoti] = useState(true);
+  const[visibleNoti, setVisibleNoti] = useState(false);
+
+  const [showResumen, setShowResumen] = useState(false);
+
+  const goToBusiness = async () => {
+    setVisibleNoti(true);
+    setTimeout(() => {
+      setVisibleNoti(false);
+      navigate(`/restaurantes`);
+    }, 3000);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: RaidenMakio
body: Por qué hay un timeout
created_at: 2025-04-25T22:54:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
+  const[fullNoti, setFullNoti] = useState(true);
+  const[visibleNoti, setVisibleNoti] = useState(false);
+
+  const [showResumen, setShowResumen] = useState(false);
+
+  const goToBusiness = async () => {
+    setVisibleNoti(true);
+    setTimeout(() => {
+      setVisibleNoti(false);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: RaidenMakio
body: Escribir el nombre completo para mayor legibilidad
created_at: 2025-04-25T22:54:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
+  const[fullNoti, setFullNoti] = useState(true);
+  const[visibleNoti, setVisibleNoti] = useState(false);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: RaidenMakio
body: Refactorizar nombre para mayor legibilidad
created_at: 2025-04-25T22:55:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
+  const[fullNoti, setFullNoti] = useState(true);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: RaidenMakio
body: Refactorizar nombre para mayor legibilidad
created_at: 2025-04-25T22:55:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: RaidenMakio
body: Refactorizar nombre para mayor legibilidad
created_at: 2025-04-25T22:55:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,36 @@
+import React, {useState} from "react";
+
+export const EditSelect = ({name = "title", edit = false, options = ["vacio"], additionalText = ""}) => {
+    const [stateEdit, setStateEdit] = useState(edit);
+    const [currentOption, setCurrentOption] = useState(options[0]);
+    return (
+        <div className="bg-gray-100 rounded-lg p-4 space-y-2">
+            <h3 className="text-sm font-semibold text-gray-700">{name}</h3>
+            <div className="flex justify-between items-center">
+                {stateEdit ? (
+                    <div>
+                        <select value={currentOption} onChange={(e) => setCurrentOption(e.target.value)}
+                        className="text-sm text-gray-800 border px-2 py-1 rounded mr-2 w-full">
+                            {options.map((opcion) => (
+                                <option key={opcion} value={opcion}>
+                                    {opcion}
+                                </option>
+                            ))}
+                        </select>
+                        <button onClick={() => setStateEdit(false)} className="text-blue-500 text-sm ml-2">
+                            Guardar
+                        </button>
+                    </div>
+                ) : (
+                    <div>
+                        <p className="text-sm"> {currentOption} {additionalText} </p>
+                        <button onClick={() => setStateEdit(true)} className="text-blue-500 text-sm ml-2">
path: OrderNow-React/src/components/EditSelect/EditSelect.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit
created_at: 2025-04-26T04:57:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+import React, {useState} from 'react';
+
+const Notification = ({
+    message = 'message',
+    subMessage = 'submessage',
+    success = true ,
+    full = false,
+    visible = false,
+}) => {
+    const [icon, setIcon] = useState('✅');
+    const [bgColor, setBgColor] = useState('#00C48C');
+    const topOffset = '80px';
+    if (!visible) return null;
+    if(!success){
+        setIcon('⚠️');
+        setBgColor('#FF4D4F');
+    }
+    if(full){
path: OrderNow-React/src/components/Notification/Notification.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit
created_at: 2025-04-26T04:58:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+import React, {useState} from 'react';
+
+const Notification = ({
+    message = 'message',
+    subMessage = 'submessage',
+    success = true ,
+    full = false,
+    visible = false,
+}) => {
+    const [icon, setIcon] = useState('✅');
+    const [bgColor, setBgColor] = useState('#00C48C');
+    const topOffset = '80px';
+    if (!visible) return null;
+    if(!success){
+        setIcon('⚠️');
+        setBgColor('#FF4D4F');
+    }
+    if(full){
+        return (
+            <div style={{ backgroundColor: bgColor }}
+                className="w-screen h-screen flex flex-col justify-center items-center text-white text-center p-4 fixed top-0 left-0 z-50"
+            >
+                <div className="text-6xl mb-6">{icon}</div>
+                <h1 className="text-2xl font-bold">{message}</h1>
+                <p className="text-md mt-2">{subMessage}</p>
+            </div>
+        );
+    }else{
path: OrderNow-React/src/components/Notification/Notification.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit de otra forma
created_at: 2025-04-26T04:58:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+import React, {useState} from 'react';
+
+const Notification = ({
+    message = 'message',
+    subMessage = 'submessage',
+    success = true ,
+    full = false,
+    visible = false,
+}) => {
+    const [icon, setIcon] = useState('✅');
+    const [bgColor, setBgColor] = useState('#00C48C');
+    const topOffset = '80px';
+    if (!visible) return null;
path: OrderNow-React/src/components/Notification/Notification.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit
created_at: 2025-04-26T04:58:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+import React, {useState} from 'react';
+
+const Notification = ({
+    message = 'message',
+    subMessage = 'submessage',
+    success = true ,
+    full = false,
+    visible = false,
+}) => {
+    const [icon, setIcon] = useState('✅');
+    const [bgColor, setBgColor] = useState('#00C48C');
path: OrderNow-React/src/components/Notification/Notification.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit
created_at: 2025-04-26T04:59:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,38 @@
+import React from 'react';
+import { useNavigate } from "react-router-dom";
+
+const OrderResume = ({products = []}) => {
+    const navigate = useNavigate();
+    return (
+        <div className="overflow-x-auto transition-all duration-300 ease-in-out mt-2">
+            <div className="flex justify-end mb-2">
+                <button onClick={() => navigate(`/cart/test`)} className="text-blue-500 text-sm">
path: OrderNow-React/src/components/OrderResume/OrderResume.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit
created_at: 2025-04-26T04:59:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
+  const[fullNoti, setFullNoti] = useState(true);
+  const[visibleNoti, setVisibleNoti] = useState(false);
+
+  const [showResumen, setShowResumen] = useState(false);
+
+  const goToBusiness = async () => {
+    setVisibleNoti(true);
+    setTimeout(() => {
+      setVisibleNoti(false);
+      navigate(`/restaurantes`);
+    }, 3000);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: henrrycoronado
body: por que mis notificaciones no manejan un cerrado manual sino uno temporizado y lo controlo fuera del componente definiendo en la hoja por cuanto tiempo se mantendra el componente visible
created_at: 2025-04-26T05:00:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
+  const[fullNoti, setFullNoti] = useState(true);
+  const[visibleNoti, setVisibleNoti] = useState(false);
+
+  const [showResumen, setShowResumen] = useState(false);
+
+  const goToBusiness = async () => {
+    setVisibleNoti(true);
+    setTimeout(() => {
+      setVisibleNoti(false);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit
created_at: 2025-04-26T05:00:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
+  const[fullNoti, setFullNoti] = useState(true);
+  const[visibleNoti, setVisibleNoti] = useState(false);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit
created_at: 2025-04-26T05:00:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
+  const[fullNoti, setFullNoti] = useState(true);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit
created_at: 2025-04-26T05:00:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,59 +1,84 @@
-import Button from "../components/button/button";
 import { useNavigate } from "react-router-dom";
-import React from "react";
-import { useState, useContext } from "react";
-import { useCart, useCartDispatch } from "../context/CartContext";
+import React, { useState } from "react";
+import { useCart } from "../context/CartContext";
+import Notification from "../components/Notification/Notification";
+import EditSelect from "../components/EditSelect/EditSelect";
+import OrderResume from "../components/OrderResume/OrderResume";
 
 const Checkout = () => {
   const products = useCart();
-  let totalPrice = products.reduce(
-    (partialSum, { price, quantity }) => partialSum + price * quantity,
-    0
-  );
-  const [price, setPrice] = useState(totalPrice);
   const navigate = useNavigate();
-  const goToHome = () => {
-    navigate(`/`);
+
+  const servicePrice = 0.5;
+  const sendPrice = 4.5;
+  const totalcarrito = products.reduce( (sum, { price, quantity }) => sum + price * quantity, 0);
+  const totalPrice = "Bs. " + (totalcarrito + sendPrice + servicePrice).toFixed(2);
+
+  const opcionesDireccion = ["Av. Palmar", "Universidad", "Postgrado"];
+  const opcionesPago = ["Efectivo", "Tarjeta", "QR"];
+  
+  const[messageNoti, setMessageNoti] = useState("Tu pedido se ha realizado con exito");
+  const[subMessageNoti, setSubMessageNoti] = useState("Puedes seguir comprando");
+  const[successNoti, setSuccessNoti] = useState(true);
path: OrderNow-React/src/pages/Checkout.jsx
user: login: henrrycoronado
body: ya corregido en el ultimo commit
created_at: 2025-04-26T05:00:47Z
author_association: CONTRIBUTOR

PR comments:
user: login: netlify[bot]
created_at: 2025-04-24T04:13:50Z
body: ### <span aria-hidden="true">❌</span> Deploy Preview for *ordernowapp-sis213* failed. **[Why did it fail? →](https://app.netlify.com/sites/ordernowapp-sis213/deploys/68123f9ed8576900089428fa?deploy_diagnostics=true)**


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | ce9cd17cc878003d8b493a5967a44353a770680c |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/ordernowapp-sis213/deploys/68123f9ed8576900089428fa |
author_association: NONE
user: login: RaidenMT
created_at: 2025-04-25T21:27:50Z
body: Adjuntar link de HU y copiar y pegar descripción
author_association: CONTRIBUTOR
user: login: henrrycoronado
created_at: 2025-04-25T21:34:14Z
body: http://159.69.123.44/isw/browse/TALLE-264/
http://159.69.123.44/isw/browse/TALLE-193/
http://159.69.123.44/isw/browse/TALLE-191/

author_association: CONTRIBUTOR
user: login: henrrycoronado
created_at: 2025-04-26T05:02:30Z
body: corregido los cambios solicitados en el ultimo commit
author_association: CONTRIBUTOR