diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..626401c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,70 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Next.js build output +.next +out + +# Environment variables +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# IDE +.vscode +.idea + +# OS +.DS_Store +Thumbs.db + +# Git +.git +.gitignore + +# Docker +Dockerfile* +docker-compose*.yml +deploy.sh + +# Documentation +*.md +API_TESTING_GUIDE.md +DEPLOYMENT_README.md + +# Testing +coverage +.nyc_output + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage/ + +# Dependency directories +node_modules/ + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity \ No newline at end of file diff --git a/.env.evolution b/.env.evolution new file mode 100644 index 0000000..2d95a35 --- /dev/null +++ b/.env.evolution @@ -0,0 +1,44 @@ +# Evolution API Environment Variables + +# Server +SERVER_TYPE=http +SERVER_PORT=8080 +SERVER_URL=http://localhost:8080 + +# Telemetry +TELEMETRY=false + +# CORS +CORS_ORIGIN=* +CORS_METHODS=GET,POST,PUT,DELETE +CORS_CREDENTIALS=true + +# Logs +LOG_LEVEL=ERROR,WARN,DEBUG,INFO +LOG_COLOR=true +LOG_BAILEYS=error + +# Instances +DEL_INSTANCE=false + +# Persistent Storage (using local for now, can change to Supabase later) +DATABASE_ENABLED=false +DATABASE_PROVIDER=postgresql +DATABASE_CONNECTION_URI=postgresql://dummy:dummy@localhost:5432/dummy + +# Use local cache instead +CACHE_LOCAL_ENABLED=true + +# Authentication +AUTHENTICATION_API_KEY=ANCHOR23_API_KEY_CHANGE_THIS + +# Language +LANGUAGE=en + +# Session Config +CONFIG_SESSION_PHONE_CLIENT=Anchor23 API +CONFIG_SESSION_PHONE_NAME=Chrome + +# QR Code +QRCODE_LIMIT=30 +QRCODE_COLOR=#175197 \ No newline at end of file diff --git a/.env.example b/.env.example index d8319d5..b5c3596 100644 --- a/.env.example +++ b/.env.example @@ -21,5 +21,14 @@ TWILIO_WHATSAPP_FROM=whatsapp:+14155238886 NEXTAUTH_URL=http://localhost:3000 NEXTAUTH_SECRET=your-nextauth-secret +# Email Service (Resend) +RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxxxx + # App NEXT_PUBLIC_APP_URL=http://localhost:3000 + +# Optional: Redis para caching +REDIS_URL=redis://redis:6379 + +# Optional: Analytics +NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX diff --git a/API_TESTING_GUIDE.md b/API_TESTING_GUIDE.md new file mode 100644 index 0000000..f2c8017 --- /dev/null +++ b/API_TESTING_GUIDE.md @@ -0,0 +1,116 @@ +# AnchorOS API Testing Guide + +## 📋 **Rutas a Probar - Testing Endpoints** + +### **🔐 Autenticación** +- `POST /api/auth/login` - Login de usuario + - Body: `{ email, password }` + - Buscar: Token JWT en respuesta +- `POST /api/auth/register` - Registro de cliente + - Body: `{ first_name, last_name, email, phone, password }` + - Buscar: Usuario creado con ID + +### **👥 Gestión de Clientes** +- `GET /api/customers` - Listar clientes + - Headers: Authorization Bearer token + - Buscar: Array de clientes con datos completos +- `POST /api/customers` - Crear cliente + - Headers: Authorization Bearer token + - Body: `{ first_name, last_name, email, phone }` + - Buscar: Cliente creado +- `GET /api/customers/[id]` - Detalles de cliente + - Buscar: Datos completos del cliente + bookings + +### **💺 Reservas (Bookings)** +- `GET /api/bookings` - Listar reservas + - Query params: `?status=confirmed&date=2024-01-01` + - Buscar: Array de bookings con relaciones (customer, service, staff) +- `POST /api/bookings` - Crear reserva + - Body: `{ customer_id, service_id, staff_id, location_id, date, notes }` + - Buscar: Booking creado + email enviado automáticamente +- `PUT /api/bookings/[id]` - Actualizar reserva + - Body: `{ status: 'confirmed' }` + - Buscar: Status actualizado +- `DELETE /api/bookings/[id]` - Cancelar reserva + - Buscar: Status cambiado a 'cancelled' + +### **🏢 Ubicaciones** +- `GET /api/locations` - Listar ubicaciones + - Buscar: Array de locations con servicios disponibles + +### **👨‍💼 Staff** +- `GET /api/staff` - Listar personal + - Buscar: Array de staff con especialidades + +### **💅 Servicios** +- `GET /api/services` - Listar servicios + - Buscar: 22 servicios de Anchor 23 con precios + +### **📅 Disponibilidad** +- `GET /api/availability?service_id=1&date=2024-01-01&location_id=1` + - Buscar: Slots disponibles por staff +- `POST /api/availability/blocks` - Bloquear horario + - Body: `{ staff_id, start_time, end_time, reason }` + - Buscar: Bloqueo creado + +### **🏪 Kiosk (Auto-servicio)** +- `GET /api/kiosk/locations` - Ubicaciones disponibles + - Buscar: Locations con servicios activos +- `POST /api/kiosk/bookings` - Reserva desde kiosk + - Body: `{ service_id, customer_data, date }` + - Buscar: Booking creado + email enviado +- `POST /api/kiosk/walkin` - Reserva inmediata + - Body: `{ service_id, customer_data }` + - Buscar: Booking inmediato confirmado + +### **📊 Aperture (Dashboard Admin)** +- `GET /api/aperture/stats` - Estadísticas generales + - Buscar: Métricas de negocio (revenue, bookings, etc.) +- `GET /api/aperture/reports` - Reportes detallados + - Buscar: Datos para gráficos y análisis +- `GET /api/aperture/pos` - Sistema POS + - Buscar: Servicios disponibles para venta + +### **🧾 Recibos** +- `GET /api/receipts/[bookingId]` - Descargar PDF + - Buscar: PDF generado con datos de reserva +- `POST /api/receipts/[bookingId]/email` - Enviar por email + - Buscar: Email enviado con PDF adjunto + +### **⚙️ Sistema** +- `GET /api/health` - Health check + - Buscar: `{ status: 'ok' }` +- `POST /api/cron/reset-invitations` - Reset diario + - Buscar: Invitaciones expiradas reseteadas + +## 🔍 **Qué Buscar en Cada Respuesta** + +### **✅ Éxito** +- Status codes: 200, 201 +- Estructura de datos correcta +- Relaciones cargadas (joins) +- Emails enviados (para bookings) + +### **❌ Errores** +- Status codes: 400, 401, 403, 404, 500 +- Mensajes de error descriptivos +- Validación de datos +- Autenticación requerida + +### **🔄 Estados** +- Bookings: `pending` → `confirmed` → `completed` +- Pagos: `pending` → `paid` +- Recursos: `available` → `booked` + +## 🧪 **Casos de Edge** + +- **Autenticación**: Token expirado, permisos insuficientes +- **Reservas**: Doble booking, horarios conflictivos +- **Pagos**: Montos inválidos, métodos no soportados +- **Kiosk**: Datos faltantes, servicios no disponibles + +## 📈 **Performance** + +- Response time < 500ms para GET +- Response time < 2s para POST complejos +- Conexiones concurrentes soportadas \ No newline at end of file diff --git a/ASSETS_PLAN.md b/ASSETS_PLAN.md new file mode 100644 index 0000000..0bb72ad --- /dev/null +++ b/ASSETS_PLAN.md @@ -0,0 +1,392 @@ +# 🖼️ Assets & Images Plan + +Este documento describe todos los recursos de imagen necesarios para AnchorOS y el plan de implementación del logo SVG original. + +--- + +## 📁 1. Imágenes de Sucursales (@src/location) + +**Ubicación existente:** +```text +src/location/ + ├─ A23_VIA_K01.png + ├─ A23_VIA_K02.png + ├─ A23_VIA_K03.png + ├─ A23_VIA_K04.png + └─ A23_VIA_K05.png +``` + +**Plan de uso sugerido:** + +| Archivo | Uso sugerido | Dimensiones recomendadas | Comentarios | +|-------------------|----------------------------------------------|--------------------------|-------------------------------------| +| A23_VIA_K01.png | Hero banner página de franquicias | 1920×800 px (desktop) / 800×600 (mobile) | Optimizar JPEG 80-85% | +| A23_VIA_K02.png | Galería de sucursales en página franquicias | 400×300 px (thumbnails) / 1200×600 (modal) | PNG o WebP optimizado | +| A23_VIA_K03.png | Slider mobile página de franquicias | 375×250 px (ratio 3:2) | Comprimir para mobile | +| A23_VIA_K04.png | Card destacado primera sucursal | 600×400 px | PNG con transparencia si aplica | +| A23_VIA_K05.png | Background sección información | 1920×900 px (parallax) o 1920×1080 (cover) | Considerar overlay oscuro | + +--- + +## 📁 2. Imágenes de Servicios + +**Ubicación sugerida:** `src/public/images/services/` o `public/images/services/` + +**Categorías según código:** +- `core` - CORE EXPERIENCES +- `nails` - NAIL COUTURE +- `hair` - HAIR FINISHING RITUALS +- `lashes` - LASH & BROW RITUALS +- `events` - EVENT EXPERIENCES +- `permanent` - PERMANENT RITUALS + +**Estructura sugerida:** +```text +public/images/services/ + ├─ core/ + │ ├─ spa-hero.jpg (1920×1080) + │ ├─ facial-hero.jpg (1920×1080) + │ └─ experience-1.jpg (1200×800) + ├─ nails/ + │ ├─ manicure-thumb.jpg (600×800) + │ ├─ pedicure-thumb.jpg (600×800) + │ └─ nail-art.jpg (800×600) + ├─ hair/ + │ ├─ blowout.jpg (800×800) + │ ├─ styling.jpg (800×800) + │ └─ treatment.jpg (800×600) + ├─ lashes/ + │ ├─ extensions.jpg (800×800) + │ └─ brows.jpg (600×800) + ├─ events/ + │ └─ event-thumb.jpg (1200×800) + └─ permanent/ + └─ treatment.jpg (800×600) +``` + +**Tamaños mínimos sugeridos:** +- Hero de categoría: 1920×1080 px +- Thumbnails verticales: 600×800 px +- Cuadrados: 800×800 px +- Formatos: JPG 80-85% (fotos), PNG/WebP (gráficos) + +--- + +## 📁 3. Imágenes de Sucursales para Franquicias + +**Ubicación sugerida:** `public/images/franchises/` o `src/public/images/franchises/` + +**Imágenes necesarias:** +- `franchise-landing-hero.jpg` - Banner principal (1920×900 px) +- `location-hero-1.jpg` - Hero sucursal 1 (1200×600 px) +- `location-hero-2.jpg` - Hero sucursal 2 (1200×600 px) +- `location-hero-3.jpg` - Hero sucursal 3 (1200×600 px) +- `franchise-team.jpg` - Foto del equipo (1200×600 px) +- `success-badge.jpg` - Badge de éxito (300×300 px) + +--- + +## 📁 4. Imágenes de Página Principal + +**Ubicación sugerida:** `public/images/home/` + +**Imágenes actuales en código:** +1. `hero-bg.jpg` - Imagen Hero Section (1920×1080 px, parallax) + - Uso: `
` en app/page.tsx:22 + - Recomendación: Foto de spa elegante, tonos cálidos, luz suave + +2. `foundation-bg.jpg` - Imagen Sección Fundamento (1200×600 px) + - Uso: `
{booking.notes && (
-

"{booking.notes}"

+

"{booking.notes}"

)} diff --git a/app/booking/perfil/page.tsx b/app/booking/perfil/page.tsx index 91bbcd0..2b754f0 100644 --- a/app/booking/perfil/page.tsx +++ b/app/booking/perfil/page.tsx @@ -32,6 +32,13 @@ export default function PerfilPage() { } }, [user, authLoading, router]) + useEffect(() => { + if (!authLoading && user) { + loadCustomerProfile() + loadCustomerBookings() + } + }, [user, authLoading]) + if (authLoading) { return (
@@ -46,11 +53,6 @@ export default function PerfilPage() { return null } - useEffect(() => { - loadCustomerProfile() - loadCustomerBookings() - }, []) - const loadCustomerProfile = async () => { try { // En una implementación real, esto vendría de autenticación diff --git a/app/contacto/page.tsx b/app/contacto/page.tsx index 25f50bc..bb5c282 100644 --- a/app/contacto/page.tsx +++ b/app/contacto/page.tsx @@ -1,176 +1,135 @@ 'use client' -import { useState } from 'react' +import { AnimatedLogo } from '@/components/animated-logo' +import { RollingPhrases } from '@/components/rolling-phrases' import { MapPin, Phone, Mail, Clock } from 'lucide-react' +import { WebhookForm } from '@/components/webhook-form' /** @description Contact page component with contact information and contact form for inquiries. */ export default function ContactoPage() { - const [formData, setFormData] = useState({ - nombre: '', - email: '', - telefono: '', - mensaje: '' - }) - const [submitted, setSubmitted] = useState(false) - - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault() - setSubmitted(true) - } - - const handleChange = (e: React.ChangeEvent) => { - setFormData({ - ...formData, - [e.target.name]: e.target.value - }) - } return ( -
-
-

Contáctanos

-

- Estamos aquí para responder tus preguntas y atender tus necesidades. -

-
- -
-
-
-
-

Información de Contacto

- -
-
- -
-

Ubicación

-

Saltillo, Coahuila, México

-
-
- -
- -
-

Teléfono

-

+52 844 123 4567

-
-
- -
- -
-

Email

-

contacto@anchor23.mx

-
-
- -
- -
-

Horario

-

Lunes - Sábado: 10:00 - 21:00

-
-
-
-
- -
-

¿Necesitas reservar una cita?

-

- Utiliza nuestro sistema de reservas en línea para mayor comodidad. -

- - Reservar Cita - -
-
- -
-

Envíanos un Mensaje

- - {submitted ? ( -
-

- Mensaje Enviado -

-

- Gracias por contactarnos. Te responderemos lo antes posible. -

-
- ) : ( -
-
- - -
- -
- - -
- -
- - -
- -
- -