docs: add Cabo Pickleball Club implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
672
docs/plans/2026-03-01-cabo-pickleball-implementation.md
Normal file
672
docs/plans/2026-03-01-cabo-pickleball-implementation.md
Normal file
@@ -0,0 +1,672 @@
|
||||
# Cabo Pickleball Club Adaptation - Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Adapt SmashPoint from a Spanish-language padel club system to an English-language pickleball club system branded for Cabo Pickleball Club.
|
||||
|
||||
**Architecture:** Direct string replacement across ~30 files. No structural changes to components, API routes, or database schema. Hide unused features (Tournaments, POS) by removing sidebar links. Update color palette and seed data.
|
||||
|
||||
**Tech Stack:** Next.js 14, TailwindCSS, Prisma, TypeScript (all unchanged)
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Update Color Palette
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/tailwind.config.ts`
|
||||
|
||||
**Step 1: Replace primary color scale**
|
||||
|
||||
Change primary from dark navy (#1E3A5F) to Cabo blue (#2990EA). Change accent from green (#22C55E) to amber (#F59E0B).
|
||||
|
||||
Replace the entire `colors` object in tailwind.config.ts with:
|
||||
|
||||
```typescript
|
||||
primary: {
|
||||
50: "#E8F4FD",
|
||||
100: "#C5E3FA",
|
||||
200: "#9DCEF6",
|
||||
300: "#75B9F2",
|
||||
400: "#4DA4EE",
|
||||
500: "#2990EA",
|
||||
600: "#2177C8",
|
||||
700: "#195DA6",
|
||||
800: "#124484",
|
||||
900: "#0B2B62",
|
||||
DEFAULT: "#2990EA",
|
||||
},
|
||||
accent: {
|
||||
50: "#FEF7EC",
|
||||
100: "#FDEACC",
|
||||
200: "#FBD89D",
|
||||
300: "#F9C66E",
|
||||
400: "#F7B43F",
|
||||
500: "#F59E0B",
|
||||
600: "#D48509",
|
||||
700: "#A36807",
|
||||
800: "#724A05",
|
||||
900: "#412B03",
|
||||
DEFAULT: "#F59E0B",
|
||||
},
|
||||
```
|
||||
|
||||
**Step 2: Build to verify colors compile**
|
||||
|
||||
Run: `cd /root/Padel && pnpm build 2>&1 | tail -5`
|
||||
Expected: Build succeeds
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/tailwind.config.ts
|
||||
git commit -m "feat: update color palette to Cabo blue (#2990EA) and amber accent"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Update Branding (Landing, Login, Sidebar, Metadata)
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/app/layout.tsx`
|
||||
- Modify: `apps/web/app/page.tsx`
|
||||
- Modify: `apps/web/app/(auth)/login/page.tsx`
|
||||
- Modify: `apps/web/components/layout/sidebar.tsx`
|
||||
- Modify: `apps/web/app/icon.svg`
|
||||
|
||||
**Step 1: Update root layout metadata**
|
||||
|
||||
In `apps/web/app/layout.tsx`:
|
||||
- title: `"Cabo Pickleball Club | SmashPoint"`
|
||||
- description: `"Court Management System for Cabo Pickleball Club"`
|
||||
- keywords: `["pickleball", "cabo", "courts", "bookings", "club"]`
|
||||
- authors: `[{ name: "SmashPoint" }]`
|
||||
- Change `<html lang="es">` to `<html lang="en">`
|
||||
|
||||
**Step 2: Update landing page**
|
||||
|
||||
In `apps/web/app/page.tsx`:
|
||||
- Logo container: change `bg-amber-500` to `bg-primary`
|
||||
- h1: `"Cabo Pickleball Club"` (instead of "SmashPoint")
|
||||
- Add subtitle: `<p className="text-sm text-primary-400">Powered by SmashPoint</p>`
|
||||
- Tagline: `"Court Management System"` (replacing Spanish)
|
||||
- Change "Reservas" button text to `"Book a Court"` and href to `/bookings`
|
||||
|
||||
**Step 3: Update login page**
|
||||
|
||||
In `apps/web/app/(auth)/login/page.tsx`:
|
||||
- Logo containers: change `bg-amber-500/20` and `border-amber-400/30` to `bg-primary/20` and `border-primary-300/30`
|
||||
- SVG fill colors: change `#FBBF24` to `currentColor` and add `className="text-white"`
|
||||
- Desktop h1: `"Cabo Pickleball Club"`
|
||||
- Add after h1: `<p className="text-sm text-primary-300 mb-2">Powered by SmashPoint</p>`
|
||||
- Desktop tagline: `"Court Management System"`
|
||||
- Feature 1: `"Court Bookings"` / `"Manage your courts and schedules"`
|
||||
- Feature 2: `"Player Management"` / `"Memberships and player profiles"`
|
||||
- Feature 3: `"Reports & Analytics"` / `"Analyze your club's performance"`
|
||||
- Mobile h1: `"Cabo Pickleball Club"`
|
||||
- Mobile tagline: `"Court Management System"`
|
||||
- Footer: `"© {year} SmashPoint. All rights reserved."`
|
||||
|
||||
**Step 4: Update sidebar**
|
||||
|
||||
In `apps/web/components/layout/sidebar.tsx`:
|
||||
- Logo container: change `bg-amber-500` to `bg-primary`
|
||||
- Brand text: `"Cabo Pickleball"` (instead of "SmashPoint")
|
||||
- Remove Tournaments entry: `{ label: 'Torneos', href: '/tournaments', icon: Trophy }`
|
||||
- Remove POS entry: `{ label: 'Ventas', href: '/pos', icon: ShoppingCart }`
|
||||
- Remove Trophy and ShoppingCart imports from lucide-react
|
||||
- Translate remaining labels:
|
||||
- `'Reservas'` → `'Bookings'`
|
||||
- `'Clientes'` → `'Players'`
|
||||
- `'Membresías'` → `'Memberships'`
|
||||
- `'Reportes'` → `'Reports'`
|
||||
- `'Configuración'` → `'Settings'`
|
||||
|
||||
**Step 5: Update favicon**
|
||||
|
||||
In `apps/web/app/icon.svg`:
|
||||
- Change `fill="#F59E0B"` to `fill="#2990EA"` (rect background)
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/app/layout.tsx apps/web/app/page.tsx apps/web/app/\(auth\)/login/page.tsx apps/web/components/layout/sidebar.tsx apps/web/app/icon.svg
|
||||
git commit -m "feat: rebrand to Cabo Pickleball Club with English UI"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Translate Auth & Layout Components
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/components/auth/login-form.tsx`
|
||||
- Modify: `apps/web/components/layout/header.tsx`
|
||||
|
||||
**Step 1: Translate login-form.tsx**
|
||||
|
||||
All Spanish strings → English:
|
||||
- `'El correo electrónico es requerido'` → `'Email is required'`
|
||||
- `'Ingresa un correo electrónico válido'` → `'Enter a valid email address'`
|
||||
- `'La contraseña es requerida'` → `'Password is required'`
|
||||
- `'La contraseña debe tener al menos 6 caracteres'` → `'Password must be at least 6 characters'`
|
||||
- `'Credenciales inválidas...'` → `'Invalid credentials. Please check your email and password.'`
|
||||
- `'Ocurrió un error al iniciar sesión...'` → `'An error occurred while signing in. Please try again.'`
|
||||
- `Iniciar Sesión` (heading) → `Sign In`
|
||||
- `Ingresa tus credenciales para acceder al sistema` → `Enter your credentials to access the system`
|
||||
- `Correo Electrónico` → `Email`
|
||||
- `"correo@ejemplo.com"` → `"email@example.com"`
|
||||
- `Contraseña` → `Password`
|
||||
- `Recordarme` → `Remember me`
|
||||
- `¿Olvidaste tu contraseña?` → `Forgot your password?`
|
||||
- `Iniciando sesión...` → `Signing in...`
|
||||
- Button: `'Iniciar Sesión'` → `'Sign In'`
|
||||
|
||||
**Step 2: Translate header.tsx**
|
||||
|
||||
- `'Usuario'` → `'User'`
|
||||
- `"Cerrar sesión"` → `"Log out"`
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/components/auth/login-form.tsx apps/web/components/layout/header.tsx
|
||||
git commit -m "feat: translate auth and layout components to English"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Translate Dashboard Page & Components
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/app/(admin)/dashboard/page.tsx`
|
||||
- Modify: `apps/web/components/dashboard/quick-actions.tsx`
|
||||
- Modify: `apps/web/components/dashboard/occupancy-chart.tsx`
|
||||
- Modify: `apps/web/components/dashboard/recent-bookings.tsx`
|
||||
- Modify: `apps/web/components/dashboard/stat-card.tsx`
|
||||
|
||||
**Step 1: Translate dashboard/page.tsx**
|
||||
|
||||
- `"Error al cargar los datos del dashboard"` → `"Error loading dashboard data"`
|
||||
- `"Error desconocido"` → `"Unknown error"`
|
||||
- `"Usuario"` → `"User"`
|
||||
- `` `Bienvenido, ${userName}` `` → `` `Welcome, ${userName}` ``
|
||||
- `Panel de administracion` → `Admin panel`
|
||||
- `` `Mostrando: ${selectedSite.name}` `` → `` `Showing: ${selectedSite.name}` ``
|
||||
- `"Reservas Hoy"` → `"Today's Bookings"`
|
||||
- `"Ingresos Hoy"` → `"Today's Revenue"`
|
||||
- `"Ocupacion"` → `"Occupancy"`
|
||||
- `"Miembros Activos"` → `"Active Members"`
|
||||
- `"Reservas Pendientes"` → `"Pending Bookings"`
|
||||
- `"Torneos Proximos"` → `"Upcoming Events"` (generic since tournaments hidden)
|
||||
|
||||
**Step 2: Translate quick-actions.tsx**
|
||||
|
||||
- `"Nueva Reserva"` → `"New Booking"`
|
||||
- `"Crear una nueva reserva de cancha"` → `"Create a new court booking"`
|
||||
- `"Abrir Caja"` → `"Open Register"`
|
||||
- `"Iniciar turno de caja registradora"` → `"Start cash register shift"`
|
||||
- `"Nueva Venta"` → `"New Sale"`
|
||||
- `"Registrar venta en el punto de venta"` → `"Record a point of sale transaction"`
|
||||
- `"Registrar Cliente"` → `"Register Player"`
|
||||
- `"Agregar un nuevo cliente al sistema"` → `"Add a new player to the system"`
|
||||
- `Acciones Rapidas` → `Quick Actions`
|
||||
|
||||
**Step 3: Translate occupancy-chart.tsx**
|
||||
|
||||
- `Ocupacion de Canchas` → `Court Occupancy` (appears twice)
|
||||
- `No hay canchas configuradas` → `No courts configured`
|
||||
- `{court.occupancyPercent}% ocupado` → `{court.occupancyPercent}% booked`
|
||||
- `disponible` → `available`
|
||||
- `Ocupado` → `Booked`
|
||||
- `Disponible` → `Available`
|
||||
|
||||
**Step 4: Translate recent-bookings.tsx**
|
||||
|
||||
- `"Pendiente"` → `"Pending"`
|
||||
- `"Confirmada"` → `"Confirmed"`
|
||||
- `"Completada"` → `"Completed"`
|
||||
- `"Cancelada"` → `"Cancelled"`
|
||||
- `"No asistio"` → `"No Show"`
|
||||
- `Reservas de Hoy` → `Today's Bookings`
|
||||
- `Ver todas` → `View all`
|
||||
- `No hay reservas para hoy` → `No bookings for today`
|
||||
- `"Sin cliente"` → `"Walk-in"`
|
||||
|
||||
**Step 5: Translate stat-card.tsx**
|
||||
|
||||
- `vs ayer` → `vs yesterday`
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/app/\(admin\)/dashboard/page.tsx apps/web/components/dashboard/
|
||||
git commit -m "feat: translate dashboard page and components to English"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Translate Bookings Page & Components
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/app/(admin)/bookings/page.tsx`
|
||||
- Modify: `apps/web/components/bookings/booking-calendar.tsx`
|
||||
- Modify: `apps/web/components/bookings/booking-dialog.tsx`
|
||||
|
||||
**Step 1: Translate bookings/page.tsx**
|
||||
|
||||
- `Reservas` → `Bookings`
|
||||
- `Gestiona las reservas de canchas...` → `Manage court bookings. Select a time slot to create or view a booking.`
|
||||
|
||||
**Step 2: Translate booking-calendar.tsx**
|
||||
|
||||
All Spanish strings → English (12 strings):
|
||||
- Error messages: `"Error al cargar..."` → `"Error loading..."`
|
||||
- `Reintentar` → `Retry`
|
||||
- `Calendario` → `Calendar`
|
||||
- `Hoy` → `Today`
|
||||
- `Cargando disponibilidad...` → `Loading availability...`
|
||||
- `No hay canchas disponibles.` → `No courts available.`
|
||||
- `"Interior"` → `"Indoor"`, `"Exterior"` → `"Outdoor"`
|
||||
- `No disponible` → `Not available`
|
||||
- `No hay horarios disponibles para este día.` → `No time slots available for this day.`
|
||||
|
||||
**Step 3: Translate booking-dialog.tsx**
|
||||
|
||||
All Spanish strings → English (35 strings):
|
||||
- Form labels: `Buscar Cliente` → `Search Player`, `Cliente seleccionado:` → `Selected player:`
|
||||
- Status labels: `"Confirmada"` → `"Confirmed"`, `"Pendiente"` → `"Pending"`, etc.
|
||||
- Payment types: `"Efectivo"` → `"Cash"`, `"Tarjeta"` → `"Card"`, `"Transferencia"` → `"Transfer"`, `"Membresia"` → `"Membership"`, `"Gratuito"` → `"Free"`
|
||||
- Field labels: `Cancha:` → `Court:`, `Fecha:` → `Date:`, `Hora:` → `Time:`, `Precio:` → `Price:`
|
||||
- Buttons: `"Crear Reserva"` → `"Create Booking"`, `"Cancelar Reserva"` → `"Cancel Booking"`
|
||||
- Error messages: all `"Error al..."` → `"Error..."`
|
||||
- Placeholders: `"Nombre, email o telefono..."` → `"Name, email or phone..."`
|
||||
- Note: Change all instances of "Cliente" to "Player" in this file
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/app/\(admin\)/bookings/page.tsx apps/web/components/bookings/
|
||||
git commit -m "feat: translate bookings page and components to English"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Translate Clients Page (rename to Players)
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/app/(admin)/clients/page.tsx`
|
||||
|
||||
**Step 1: Translate all strings**
|
||||
|
||||
17 Spanish strings → English. Key translations:
|
||||
- `Clientes` → `Players`
|
||||
- `Gestiona los clientes de tu centro` → `Manage your club's players`
|
||||
- `Nuevo Cliente` → `New Player`
|
||||
- `"Total Clientes"` → `"Total Players"`
|
||||
- `"Con Membresia"` → `"With Membership"`
|
||||
- `"Nuevos Este Mes"` → `"New This Month"`
|
||||
- `"Buscar por nombre, email o telefono..."` → `"Search by name, email or phone..."`
|
||||
- `"Todos"` → `"All"`, `"Con membresia"` → `"With membership"`, `"Sin membresia"` → `"Without membership"`
|
||||
- All error messages: translate from Spanish to English
|
||||
- Confirmation dialog: translate to English
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/app/\(admin\)/clients/page.tsx
|
||||
git commit -m "feat: translate clients/players page to English"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: Translate Memberships Page & Components
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/app/(admin)/memberships/page.tsx`
|
||||
- Modify: `apps/web/components/memberships/plan-card.tsx`
|
||||
- Modify: `apps/web/components/memberships/plan-form.tsx`
|
||||
|
||||
**Step 1: Translate memberships/page.tsx (30 strings)**
|
||||
|
||||
- `Membresias` → `Memberships`
|
||||
- `Gestiona planes y membresias de tus clientes` → `Manage plans and memberships for your players`
|
||||
- Status filters: `"Todos"` → `"All"`, `"Activas"` → `"Active"`, `"Expiradas"` → `"Expired"`, `"Canceladas"` → `"Cancelled"`
|
||||
- Stats: `Membresias Activas` → `Active Memberships`, `Por Expirar` → `Expiring Soon`, `Planes Activos` → `Active Plans`, `Total Suscriptores` → `Total Subscribers`
|
||||
- `Planes de Membresia` → `Membership Plans`
|
||||
- `Nuevo Plan` → `New Plan`
|
||||
- `Cargando planes...` → `Loading plans...`
|
||||
- `No hay planes` → `No plans`, `Crea tu primer plan de membresia` → `Create your first membership plan`
|
||||
- `Crear Plan` → `Create Plan`
|
||||
- `Asignar Membresia` → `Assign Membership`
|
||||
- `"Buscar por nombre de cliente..."` → `"Search by player name..."`
|
||||
- `"Todos los planes"` → `"All plans"`
|
||||
- All error messages and confirmation dialogs → English
|
||||
|
||||
**Step 2: Translate plan-card.tsx (11 strings)**
|
||||
|
||||
- `suscriptor` / `suscriptores` → `subscriber` / `subscribers`
|
||||
- `mes` / `meses` → `month` / `months`
|
||||
- `horas gratis` → `free hours`
|
||||
- `de cancha al mes` → `of court time per month`
|
||||
- `descuento` → `discount`
|
||||
- `en reservas adicionales` → `on additional bookings`
|
||||
- `en tienda` → `in store`
|
||||
- `Beneficios adicionales:` → `Additional benefits:`
|
||||
- `Editar` → `Edit`, `Eliminar` → `Delete`
|
||||
|
||||
**Step 3: Translate plan-form.tsx (25 strings)**
|
||||
|
||||
- Duration labels: `"1 mes"` → `"1 month"`, `"3 meses"` → `"3 months"`, etc.
|
||||
- Validation: all Spanish error messages → English
|
||||
- Form title: `"Nuevo Plan de Membresia"` → `"New Membership Plan"`, `"Editar Plan"` → `"Edit Plan"`
|
||||
- Labels: `Nombre del Plan *` → `Plan Name *`, `Descripcion` → `Description`, `Precio *` → `Price *`, `Duracion` → `Duration`
|
||||
- Section headers: `Beneficios` → `Benefits`, `Horas Gratis de Cancha (por mes)` → `Free Court Hours (per month)`, `Descuento en Reservas (%)` → `Booking Discount (%)`, `Descuento en Tienda (%)` → `Store Discount (%)`
|
||||
- Buttons: `Cancelar` → `Cancel`, `Guardando...` → `Saving...`, `"Crear Plan"` → `"Create Plan"`, `"Guardar Cambios"` → `"Save Changes"`
|
||||
- Placeholders: translate to English equivalents
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/app/\(admin\)/memberships/page.tsx apps/web/components/memberships/
|
||||
git commit -m "feat: translate memberships page and components to English"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 8: Translate Reports Page
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/app/(admin)/reports/page.tsx`
|
||||
|
||||
**Step 1: Translate all strings (28 strings)**
|
||||
|
||||
- `Reportes` → `Reports`
|
||||
- `Análisis y estadísticas del negocio` → `Business analysis and statistics`
|
||||
- Period filters: `"Última semana"` → `"Last week"`, `"Último mes"` → `"Last month"`, `"Último trimestre"` → `"Last quarter"`, `"Último año"` → `"Last year"`
|
||||
- `Exportar` → `Export`
|
||||
- KPIs: `"Ingresos Totales"` → `"Total Revenue"`, `"Reservas"` → `"Bookings"`, `"Clientes Activos"` → `"Active Players"`, `"Ocupación Promedio"` → `"Average Occupancy"`
|
||||
- Charts: `Ingresos por Día` → `Revenue by Day`, `Reservas` → `Bookings`, `Ventas` → `Sales`
|
||||
- `Productos Más Vendidos` → `Top Selling Products`
|
||||
- `unidades` → `units`
|
||||
- `Rendimiento por Cancha` → `Court Performance`
|
||||
- Table headers: `Cancha` → `Court`, `Sede` → `Site`, `Reservas` → `Bookings`, `Ingresos` → `Revenue`, `Ocupación` → `Occupancy`
|
||||
- Day names: `"Lun"` → `"Mon"`, `"Mar"` → `"Tue"`, `"Mié"` → `"Wed"`, `"Jue"` → `"Thu"`, `"Vie"` → `"Fri"`, `"Sáb"` → `"Sat"`, `"Dom"` → `"Sun"`
|
||||
- Insights: `Mejor Día` → `Best Day`, `Sábado` → `Saturday`, `en ingresos promedio` → `in average revenue`, `Hora Pico` → `Peak Hour`, `Ticket Promedio` → `Average Ticket`
|
||||
- `vs período anterior` → `vs previous period`
|
||||
- Rename "Cancha" to "Court" in mock data court names (lines 110-115)
|
||||
- Rename "Raqueta alquiler" to "Paddle Rental" in mock products (line 106)
|
||||
- Rename "Pelotas HEAD" to "Pickleballs" in mock products (line 105)
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/app/\(admin\)/reports/page.tsx
|
||||
git commit -m "feat: translate reports page to English"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 9: Translate Settings Page
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/app/(admin)/settings/page.tsx`
|
||||
|
||||
**Step 1: Translate all Spanish strings**
|
||||
|
||||
Key translations (the file has ~60 Spanish strings):
|
||||
- `Configuración` → `Settings`
|
||||
- `Administra la configuración del sistema` → `Manage system settings`
|
||||
- `Configuración guardada correctamente` → `Settings saved successfully`
|
||||
- Tab labels: `Organización` → `Organization`, `Sedes` → `Sites`, `Canchas` → `Courts`, `Usuarios` → `Users`
|
||||
- Organization form: `Nombre de la organización` → `Organization name`, `Email de contacto` → `Contact email`, `Teléfono` → `Phone`, `Moneda` → `Currency`, `Zona horaria` → `Timezone`
|
||||
- Currency options: `"MXN - Peso Mexicano"`, `"USD - Dólar"`, `"EUR - Euro"` → `"MXN - Mexican Peso"`, `"USD - US Dollar"`, `"EUR - Euro"`
|
||||
- Timezone options: `"Ciudad de México"` → `"Mexico City"`, etc.
|
||||
- Booking config: `Duración por defecto (minutos)` → `Default duration (minutes)`, `Anticipación mínima (horas)` → `Minimum notice (hours)`, `Anticipación máxima (días)` → `Maximum advance (days)`, `Horas para cancelar` → `Cancellation window (hours)`
|
||||
- Buttons: `Guardar cambios` → `Save changes`, `Guardando...` → `Saving...`
|
||||
- Sites section: `Sedes` → `Sites`, `Nueva Sede` → `New Site`, `Activa` / `Inactiva` → `Active` / `Inactive`
|
||||
- Courts section: `Canchas` → `Courts`, `Nueva Cancha` → `New Court`, `Cancha` → `Court`, `Sede` → `Site`, `Tipo` → `Type`, `Precio/hora` → `Price/hour`, `Estado` → `Status`, `Acciones` → `Actions`
|
||||
- Court types: `Indoor` stays, `Outdoor` stays, `"Techada"` → `"Covered"`
|
||||
- Court status: `"Activa"` → `"Active"`, `"Mantenimiento"` → `"Maintenance"`, `"Inactiva"` → `"Inactive"`
|
||||
- Users section: `Usuarios` → `Users`, `Nuevo Usuario` → `New User`, `Usuario` → `User`, `Rol` → `Role`, `"Super Admin"` stays, `"Admin Sede"` → `"Site Admin"`, `"Staff"` stays
|
||||
- Messages: `"Cancha actualizada"` → `"Court updated"`, `"Cancha creada"` → `"Court created"`, `"Cancha eliminada"` → `"Court deleted"`, etc.
|
||||
- Site form: `"Editar Sede"` → `"Edit Site"`, `"Nueva Sede"` → `"New Site"`, `Nombre` → `Name`, `Dirección` → `Address`, `Teléfono` → `Phone`, `Hora apertura` → `Opening time`, `Hora cierre` → `Closing time`, `Sede activa` → `Site active`
|
||||
- Court form: `"Editar Cancha"` → `"Edit Court"`, `"Nueva Cancha"` → `"New Court"`, `Precio hora pico` → `Peak hour price`
|
||||
- All `Cancelar` → `Cancel`, `Guardar` → `Save`, `Guardando...` → `Saving...`
|
||||
- Error/success: `"Sede actualizada"` → `"Site updated"`, `"Sede creada"` → `"Site created"`, `"Error al guardar..."` → `"Error saving..."`, `"Error de conexión"` → `"Connection error"`
|
||||
- Confirmation: `"¿Estás seguro de eliminar esta cancha?"` → `"Are you sure you want to delete this court?"`
|
||||
- `"Todas"` → `"All"` (for site assignment)
|
||||
- `"Activo"` / `"Inactivo"` → `"Active"` / `"Inactive"` (user status)
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/app/\(admin\)/settings/page.tsx
|
||||
git commit -m "feat: translate settings page to English"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 10: Translate API Error Messages
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/app/api/bookings/route.ts`
|
||||
- Modify: `apps/web/app/api/clients/route.ts`
|
||||
- Check and modify any other API routes with Spanish strings
|
||||
|
||||
**Step 1: Translate bookings/route.ts**
|
||||
|
||||
- `'No autorizado'` → `'Unauthorized'`
|
||||
- `'Error al obtener las reservas'` → `'Error fetching bookings'`
|
||||
- `'Datos de reserva inválidos'` → `'Invalid booking data'`
|
||||
- `'Cancha no encontrada o no pertenece a su organización'` → `'Court not found or does not belong to your organization'`
|
||||
- `'La cancha no está disponible para reservas'` → `'The court is not available for bookings'`
|
||||
- `'Cliente no encontrado o no pertenece a su organización'` → `'Client not found or does not belong to your organization'`
|
||||
- `'Ya existe una reserva en ese horario...'` → `'A booking already exists for that time slot. Please select another time.'`
|
||||
- `'Error al crear la reserva'` → `'Error creating booking'`
|
||||
|
||||
**Step 2: Scan and translate all other API routes**
|
||||
|
||||
Search for Spanish strings in all files under `apps/web/app/api/` and translate them.
|
||||
|
||||
Run: `grep -rn "'" apps/web/app/api/ | grep -i "[áéíóúñ]\|Error al\|No autorizado\|no encontrad"` to find remaining Spanish.
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/app/api/
|
||||
git commit -m "feat: translate API error messages to English"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 11: Update Seed Data for Cabo Pickleball
|
||||
|
||||
**Files:**
|
||||
- Modify: `apps/web/prisma/seed.ts`
|
||||
|
||||
**Step 1: Update organization**
|
||||
|
||||
```typescript
|
||||
name: 'Cabo Pickleball Club',
|
||||
slug: 'cabo-pickleball-club',
|
||||
settings: {
|
||||
currency: 'MXN',
|
||||
timezone: 'America/Mazatlan',
|
||||
language: 'en',
|
||||
},
|
||||
```
|
||||
|
||||
**Step 2: Update site (single site instead of 3)**
|
||||
|
||||
Replace the 3 sites with 1:
|
||||
```typescript
|
||||
const sitesData = [
|
||||
{
|
||||
name: 'Corridor Courts',
|
||||
slug: 'corridor-courts',
|
||||
address: 'Corridor area, Cabo San Lucas, BCS',
|
||||
phone: '+52-624-151-5455',
|
||||
email: 'topdogcabo@yahoo.com',
|
||||
timezone: 'America/Mazatlan',
|
||||
openTime: '07:00',
|
||||
closeTime: '22:00',
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
**Step 3: Update courts (6 outdoor courts)**
|
||||
|
||||
Replace the 2-per-site pattern with 6 courts for the single site:
|
||||
```typescript
|
||||
const courtData = [
|
||||
{ name: 'Court 1', type: CourtType.OUTDOOR, status: CourtStatus.AVAILABLE, pricePerHour: 300, description: 'Outdoor court with night lighting', features: ['Night lighting', 'Court dividers'], displayOrder: 1 },
|
||||
{ name: 'Court 2', type: CourtType.OUTDOOR, status: CourtStatus.AVAILABLE, pricePerHour: 300, description: 'Outdoor court with night lighting', features: ['Night lighting', 'Court dividers'], displayOrder: 2 },
|
||||
{ name: 'Court 3', type: CourtType.OUTDOOR, status: CourtStatus.AVAILABLE, pricePerHour: 300, description: 'Outdoor court with night lighting', features: ['Night lighting', 'Court dividers'], displayOrder: 3 },
|
||||
{ name: 'Court 4', type: CourtType.OUTDOOR, status: CourtStatus.AVAILABLE, pricePerHour: 300, description: 'Outdoor court with night lighting', features: ['Night lighting', 'Court dividers'], displayOrder: 4 },
|
||||
{ name: 'Court 5', type: CourtType.OUTDOOR, status: CourtStatus.AVAILABLE, pricePerHour: 300, description: 'Outdoor court with night lighting', features: ['Night lighting', 'Court dividers'], displayOrder: 5 },
|
||||
{ name: 'Court 6', type: CourtType.OUTDOOR, status: CourtStatus.AVAILABLE, pricePerHour: 300, description: 'Outdoor court with night lighting', features: ['Night lighting', 'Court dividers'], displayOrder: 6 },
|
||||
];
|
||||
```
|
||||
|
||||
**Step 4: Update admin user**
|
||||
|
||||
```typescript
|
||||
email: 'ivan@horuxfin.com',
|
||||
password: await bcrypt.hash('Aasi940812', 10),
|
||||
```
|
||||
|
||||
Remove the site admin users (single-site operation).
|
||||
|
||||
**Step 5: Update product categories and products**
|
||||
|
||||
Change to pickleball-relevant items:
|
||||
- Category: `'Equipment'` → `'Pickleball equipment and accessories'`
|
||||
- Products: `'Pickleballs'` (Franklin X-40), `'Paddle Rental'`, `'Paddle Grip'`
|
||||
- Category: `'Drinks'` stays but translate names to English
|
||||
- Remove `'Alquiler'` category (merge rental into Equipment)
|
||||
|
||||
**Step 6: Update membership plans**
|
||||
|
||||
```typescript
|
||||
const membershipPlansData = [
|
||||
{
|
||||
name: 'Day Pass',
|
||||
description: 'Single day access to all courts',
|
||||
price: 300,
|
||||
durationMonths: 1,
|
||||
courtHours: 0,
|
||||
discountPercent: 0,
|
||||
benefits: ['Full day access', 'All courts', 'Night play included'],
|
||||
},
|
||||
{
|
||||
name: '10-Day Pass',
|
||||
description: '10 visits, any time of day',
|
||||
price: 2500,
|
||||
durationMonths: 3,
|
||||
courtHours: 10,
|
||||
discountPercent: 15,
|
||||
benefits: ['10 day passes', 'Valid any time', 'Save vs single day pass'],
|
||||
},
|
||||
{
|
||||
name: '10-Morning Pass',
|
||||
description: '10 morning sessions (7am-12pm)',
|
||||
price: 2000,
|
||||
durationMonths: 3,
|
||||
courtHours: 10,
|
||||
discountPercent: 10,
|
||||
benefits: ['10 morning passes', '7:00 AM - 12:00 PM only', 'Best value for morning players'],
|
||||
},
|
||||
{
|
||||
name: 'Monthly Individual',
|
||||
description: 'Unlimited monthly access for one player',
|
||||
price: 4000,
|
||||
durationMonths: 1,
|
||||
courtHours: 30,
|
||||
discountPercent: 25,
|
||||
benefits: ['Unlimited court access', 'Priority booking', 'All time slots'],
|
||||
},
|
||||
{
|
||||
name: 'Monthly Family',
|
||||
description: 'Unlimited monthly access for up to 4 family members',
|
||||
price: 6500,
|
||||
durationMonths: 1,
|
||||
courtHours: 60,
|
||||
discountPercent: 30,
|
||||
benefits: ['Up to 4 family members', 'Unlimited court access', 'Priority booking', 'All time slots'],
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
**Step 7: Update seed summary output**
|
||||
|
||||
Change all console.log messages to English and update credential display:
|
||||
```
|
||||
Login credentials:
|
||||
Admin: ivan@horuxfin.com / Aasi940812
|
||||
```
|
||||
|
||||
**Step 8: Commit**
|
||||
|
||||
```bash
|
||||
git add apps/web/prisma/seed.ts
|
||||
git commit -m "feat: update seed data for Cabo Pickleball Club"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 12: Sport Terminology Sweep
|
||||
|
||||
**Files:**
|
||||
- All `.tsx`, `.ts` files containing "padel", "pádel", "cancha", "raqueta", "pelota"
|
||||
|
||||
**Step 1: Global search and replace**
|
||||
|
||||
Run targeted searches and replace remaining sport terms:
|
||||
- `grep -rn "padel\|pádel\|Padel\|Pádel" apps/web/ --include="*.tsx" --include="*.ts"` — replace with "pickleball"
|
||||
- `grep -rn "cancha" apps/web/ --include="*.tsx" --include="*.ts"` — replace with "court" (should already be done in earlier tasks)
|
||||
- `grep -rn "raqueta\|Raqueta" apps/web/ --include="*.tsx" --include="*.ts"` — replace with "paddle"
|
||||
- `grep -rn "pelota\|Pelota" apps/web/ --include="*.tsx" --include="*.ts"` — replace with "pickleball ball" or "pickleballs"
|
||||
|
||||
**Step 2: Verify no Spanish sport terms remain**
|
||||
|
||||
Run: `grep -rni "padel\|cancha\|raqueta\|pelota" apps/web/ --include="*.tsx" --include="*.ts"`
|
||||
Expected: No matches (or only in comments/prisma generated code)
|
||||
|
||||
**Step 3: Commit if any changes**
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "feat: replace all padel terminology with pickleball"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 13: Build, Verify & Final Commit
|
||||
|
||||
**Step 1: Clean build**
|
||||
|
||||
```bash
|
||||
rm -rf apps/web/.next .turbo
|
||||
pnpm build
|
||||
```
|
||||
|
||||
Expected: Build succeeds with 0 errors.
|
||||
|
||||
**Step 2: Verify no Spanish remains in user-facing code**
|
||||
|
||||
Run: `grep -rni "[áéíóúñ]" apps/web/app/ apps/web/components/ --include="*.tsx" --include="*.ts" | grep -v node_modules | grep -v ".next"`
|
||||
|
||||
Review any remaining Spanish strings and translate.
|
||||
|
||||
**Step 3: Restart server and verify**
|
||||
|
||||
```bash
|
||||
fuser -k 3000/tcp 2>/dev/null
|
||||
sleep 2
|
||||
cd apps/web && npx next start --port 3000 &
|
||||
```
|
||||
|
||||
**Step 4: Push**
|
||||
|
||||
```bash
|
||||
git push origin main
|
||||
```
|
||||
Reference in New Issue
Block a user