Saltar al contenido principal
Logo de Deanny Bruces Deanny Bruces

Aplicación Calculadora de propinas

🧮 Probar calculadora | 📂 Código en GitHub


El Momento Incómodo

Todos hemos estado ahí:

  • 🍽️ Terminas de comer con amigos en un restaurante
  • 💵 Llega la cuenta de $2,450 pesos
  • 🤔 ¿Cuánto de propina es justo? ¿10%, 15%, 20%?
  • 👥 ¿Cómo dividimos esto entre 6 personas sin que alguien salga perdiendo?
  • 📱 Alguien saca la calculadora del celular y empieza a hacer cuentas mentales
  • ⏰ 5 minutos después… todavía sin respuesta clara

El problema no es la matemática. Es el contexto: múltiples platillos, diferentes precios, distintos porcentajes de propina, y gente esperando para irse.

La Solución

Una calculadora diseñada específicamente para restaurantes que hace en 10 segundos lo que te tomaría 5 minutos:

  1. Seleccionas platillos del menú (con nombres reales y precios)
  2. Ajustas el porcentaje de propina (10%, 15%, 20% o custom)
  3. Ves el total instantáneo (consumo + propina = total a pagar)

No más matemática mental. No más discusiones sobre “¿cuánto nos falta?”. Solo números claros.


Características Principales

🍕 Menú Interactivo

Selecciona platillos con un clic:

  • Pizza Hawaiana - $190
  • Hamburguesa Clásica - $150
  • Ensalada Caesar - $120
  • Tacos al Pastor (3) - $85
  • Bebidas y postres incluidos

¿Por qué esto importa? No tienes que escribir “Hamburguesa - 150”. Solo haces clic y se agrega. Rápido, sin errores.

📊 Cálculo Automático en Tiempo Real

Matemática instantánea mientras agregas platillos:

Ejemplo de pedido:

  • 2x Hamburguesa ($150) = $300
  • 1x Pizza Hawaiana ($190) = $190
  • 3x Bebidas ($45) = $135
  • Subtotal: $625
  • Propina 15%: $93.75
  • Total: $718.75

Todo actualizado mientras seleccionas, sin botón de “calcular”.

💡 Porcentajes de Propina Flexibles

Opciones predeterminadas:

  • 10% - Servicio básico
  • 15% - Servicio bueno (estándar en México)
  • 20% - Servicio excelente
  • Custom - Ingresa cualquier porcentaje (5%, 18%, 25%)

¿Sin efectivo exacto? El sistema muestra centavos precisos: $718.75 (no redondeos confusos).

🗑️ Gestión de Pedido

  • Eliminar platillos: Alguien canceló? Un clic y se quita
  • Ajustar cantidades: Cambia 2 pizzas a 3 pizzas sin reiniciar
  • Limpiar todo: Botón de reset para nuevo pedido

📱 Diseño Responsivo

Funciona perfecto en:

  • 📱 Móvil (cuando estás en la mesa del restaurante)
  • 💻 Desktop (para planear pedidos grupales)
  • 📲 Tablet (pantalla ideal para compartir)

Stack Técnico

Arquitectura Moderna

Construido con las herramientas más eficientes para apps React en 2025:

TecnologíaVersiónPropósito
React19.0UI reactiva con hooks modernos
TypeScript5.6Type safety para prevenir bugs
Vite6.0Dev server ultrarrápido (<50ms HMR)
CSS ModernoResponsive design con Grid + Flexbox

¿Por Qué Esta Combinación?

React 19

  • Hooks avanzados: useReducer para estado predecible
  • Componentes funcionales: Código más limpio que clases
  • Virtual DOM: Actualizaciones instantáneas sin recargar

TypeScript

type MenuItem = {
  id: number;
  name: string;
  price: number;
}

type OrderItem = MenuItem & {
  quantity: number;
}

Beneficio: Si intentas agregar un platillo sin precio, TypeScript te lo impide ANTES de compilar.

Vite

  • Dev server en 0.3s (vs. 5-10s de Webpack)
  • Hot Module Replacement: Cambios visibles en <50ms
  • Build optimizado: Bundle final de solo 42KB

Casos de Uso Real

🎉 Caso 1: Cena de Cumpleaños (8 personas)

Escenario: Familia celebrando cumpleaños en restaurante italiano.

Pedido:

  • 4x Pizza Margarita ($190) = $760
  • 3x Pasta Carbonara ($165) = $495
  • 8x Bebidas ($45) = $360
  • 2x Postres ($95) = $190

Resultados:

  • Subtotal: $1,805
  • Propina 18%: $324.90
  • Total: $2,129.90
  • Por persona: $266.24

Sin la app: 10 minutos de discusión, cuentas manuales, alguien paga de más. Con la app: 30 segundos, todos pagan lo justo.

💼 Caso 2: Comida de Trabajo (4 personas)

Escenario: Reunión de negocios en café.

Pedido:

  • 4x Café Americano ($55) = $220
  • 2x Ensalada ($120) = $240
  • 2x Sandwich ($110) = $220

Resultados:

  • Subtotal: $680
  • Propina 10%: $68
  • Total: $748
  • Por persona: $187

Ventaja: Divide profesionalmente sin calculadora del celular.

🌮 Caso 3: Tacos con Amigos (Pedido Complejo)

Escenario: 5 amigos, cada uno ordenó diferente.

Pedido:

  • 6x Tacos al Pastor ($85) = $510
  • 3x Quesadillas ($95) = $285
  • 5x Aguas Frescas ($30) = $150
  • 2x Guacamole Extra ($50) = $100

Resultados:

  • Subtotal: $1,045
  • Propina 15%: $156.75
  • Total: $1,201.75
  • Por persona: $240.35

Sin app: Caos total. Con app: División clara y justa.


Arquitectura del Código

Componentes Principales

App.tsx (Raíz)
├── MenuList.tsx (Menú de platillos disponibles)
├── OrderSummary.tsx (Resumen del pedido actual)
├── TipCalculator.tsx (Selector de propina + totales)
└── OrderItem.tsx (Platillo individual en el pedido)

Gestión de Estado con useReducer

Actions tipadas:

type OrderActions =
  | { type: 'ADD_ITEM', payload: MenuItem }
  | { type: 'REMOVE_ITEM', payload: number }
  | { type: 'SET_TIP', payload: number }
  | { type: 'RESET_ORDER' }

Ventajas:

  • ✅ Estado predecible (no bugs de sincronización)
  • ✅ Lógica centralizada (fácil de testear)
  • ✅ Acciones tipadas (TypeScript previene errores)

Cálculos Optimizados

const calculateTotals = useMemo(() => {
  const subtotal = order.reduce((sum, item) =>
    sum + (item.price * item.quantity), 0
  );
  const tipAmount = subtotal * (tipPercentage / 100);
  const total = subtotal + tipAmount;

  return { subtotal, tipAmount, total };
}, [order, tipPercentage]);

Beneficio: Solo recalcula cuando cambia el pedido, no en cada render.


Desafíos Técnicos Resueltos

1. Precisión Decimal

Problema: JavaScript hace 0.1 + 0.2 = 0.30000000000000004 Solución:

const roundToTwo = (num: number) => Math.round(num * 100) / 100;

Resultado: Propinas exactas sin decimales raros.

2. Validación de Cantidades

Problema: Usuarios intentando agregar -5 pizzas o 0 tacos Solución:

if (quantity < 1) return; // Ignora cantidades inválidas
if (quantity > 99) quantity = 99; // Límite razonable

3. Responsive sin Media Queries Manuales

Problema: Diseño se rompía en pantallas pequeñas Solución: CSS Grid con auto-fit

.menu-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
}

Resultado: Se adapta automáticamente a cualquier pantalla.


Optimizaciones Técnicas

Stack Eficiente

  • React + TypeScript: Type safety y componentes reutilizables
  • 📦 Vite: Build tool moderno con HMR instantáneo
  • 🎨 CSS moderno: Diseño responsivo sin librerías adicionales
  • 💾 Local Storage: Persistencia sin backend

Características de Rendimiento

  • Bundle optimizado: Solo las dependencias necesarias
  • Carga rápida: Sin librerías pesadas innecesarias
  • Responsive: Funciona en cualquier dispositivo
  • Offline capable: Funciona sin conexión a internet

Aprendizajes del Proyecto

Desafíos de UX

¿Botón de “Calcular” o automático?

  • Iteración 1: Agregué botón “Calcular Propina”
  • Consideración: Requiere paso extra del usuario
  • Iteración 2: Cálculo automático en tiempo real
  • Beneficio: Feedback inmediato sin clicks adicionales

¿Pesos ($) o porcentaje (%) primero?

  • Iteración 1: Mostraba “Total: 15% = $187.50”
  • Consideración: Puede confundir qué número es más importante
  • Iteración 2: “Total: $187.50 (15% propina incluida)”
  • Beneficio: Prioriza el valor final que el usuario necesita

Optimizaciones Aplicadas

  1. Lazy loading de menú: Cargar platillos bajo demanda (no los 50 al inicio)
  2. Debounce en custom tip: Esperar 300ms antes de recalcular
  3. Memoización agresiva: Evitar re-renders innecesarios
  4. Virtual scrolling: Manejar menús de 200+ platillos sin lag

Próximas Mejoras

Funcionalidades Planeadas

  • División personalizada: “Juan paga 2 pizzas, María 1 ensalada”
  • Historial de pedidos: Guardar pedidos recurrentes
  • Modo dark: Para restaurantes con luz tenue
  • Compartir cuenta: Generar link para dividir con otros
  • PWA: Instalar como app nativa

Integraciones Futuras

  • API de restaurantes: Menús reales de negocios locales
  • Pagos integrados: Pagar directamente desde la app
  • QR codes: Escanear mesa para menú automático

¿Por Qué Este Proyecto Importa?

Esta app resuelve un problema universal pero ignorado:

  • Todos comemos fuera: 60% de personas van a restaurantes semanalmente
  • Todos calculan propina: Momento incómodo garantizado
  • Nadie tiene buena solución: Calculadoras genéricas no funcionan

La mejor tecnología es invisible. Esta app funciona tan rápido que ni notas que estás calculando.


Lecciones de Desarrollo

Técnicas

  • TypeScript evitó 12 bugs antes de llegar a producción
  • useReducer es mejor que useState para lógica compleja
  • Vite cambió mi vida: Nunca volvería a Webpack para proyectos nuevos

Negocio

  • Simplicidad vende: Eliminé 8 funciones “cool” que nadie pedía
  • Móvil primero: 85% de usuarios abrieron la app desde su teléfono en el restaurante
  • Feedback real > teoría: Cambié el diseño 3 veces basándome en pruebas con amigos

🧮 Úsala en tu próxima comida📂 Explora el código💡 Sugiere mejoras

¡Escribeme por WhatsApp!