# Spanish Template Implementation Plan

> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

**Goal:** Add Spanish language support for public dealer landing pages with a language toggle.

**Architecture:** Simple TypeScript translation object approach. Language context wraps DealerTemplate for client-side language switching. Dealer sets default language in editor; visitors can toggle in header. Same URL for both languages (client-side only).

**Tech Stack:** React Context, TypeScript, Prisma migration, Next.js App Router

---

## Task 1: Add preferredLanguage to Prisma Schema

**Files:**

- Modify: `prisma/schema.prisma:82-152` (Dealer model)

**Step 1: Add the field to Dealer model**

In `prisma/schema.prisma`, add after line 131 (after `status` field):

```prisma
  preferredLanguage    String           @default("en")  // "en" or "es"
```

**Step 2: Run migration**

Run: `npx prisma migrate dev --name add-dealer-preferred-language`

Expected: Migration created and applied successfully

**Step 3: Generate Prisma client**

Run: `npx prisma generate`

Expected: Prisma Client generated successfully

**Step 4: Commit**

```bash
git add prisma/schema.prisma prisma/migrations/
git commit -m "feat: add preferredLanguage field to Dealer model"
```

---

## Task 2: Create Translation File

**Files:**

- Create: `lib/translations/dealer-template.ts`

**Step 1: Create the translations file**

Create `lib/translations/dealer-template.ts`:

```typescript
/**
 * Translations for DealerTemplate and ContactSection components.
 *
 * IMPORTANT: Do NOT translate:
 * - "AMSOIL" brand name
 * - Dealer business information (name, address, phone, email)
 * - Product names that are proper nouns
 */

export type Language = 'en' | 'es';

export const dealerTemplateTranslations = {
  en: {
    // Header
    independentDealer: 'INDEPENDENT DEALER',

    // Section 3: Product Categories
    findProducts: 'FIND YOUR PRODUCTS',
    findProductsDesc: 'Select your vehicle type to view only the AMSOIL products that work for it.',

    // Vehicle categories
    vehicles: {
      autoLt: 'Auto/LT',
      motorcycle: 'Motorcycle',
      atv: 'ATV',
      utv: 'UTV',
      snowmobile: 'Snowmobile',
      marine: 'Marine',
      pwc: 'PWC',
      smallEngine: 'Small Engine',
      heavyDuty: 'Heavy Duty',
    },

    // Section 4: Featured Products (Three Tiers)
    threeTiers: 'THREE TIERS OF PREMIUM PERFORMANCE',
    threeTiersDesc: 'Select your vehicle type to view only the AMSOIL products that work for it.',

    // Product tiers - Note: Product names are not translated, only descriptions
    tiers: {
      signatureSeries: 'SIGNATURE SERIES',
      extendedLife: 'EXTENDED-LIFE',
      oeSynthetic: 'OE 100%',
      syntheticMotorOil: '100% SYNTHETIC MOTOR OIL',
      syntheticMotorOilOe: 'SYNTHETIC MOTOR OIL',
      maxProtection: 'Maximum Engine Protection',
      boostedProtection: 'Boosted Engine Protection',
      advancedProtection: 'Advanced Engine Protection',
      interval25k: 'Up to 25,000 miles or 1-year*',
      interval20k: 'Up to 20,000 miles or 1-year*',
      intervalOem: 'OEM-recommended drain interval',
    },
    disclaimer: '* Whichever comes first. In normal service.',
    shopMotorOil: 'SHOP MOTOR OIL',

    // Section 5: Request Catalog
    rightProduct: 'WE HAVE THE RIGHT PRODUCT FOR ALL OF YOUR PROJECTS.',
    catalogDesc1: 'Browse the full line of premium AMSOIL products in',
    catalogDesc2: 'the latest AMSOIL factory direct catalog.',
    requestCatalog: 'REQUEST YOUR FREE CATALOG',

    // Section 6: Dealer Info
    fullServiceDealer: 'Full Service Dealer',
    notSureProduct: 'Not Sure Which Product Is Right For You?',
    contactUsHelp:
      'Contact us for more information on AMSOIL products, for help determining which products you need or to place an order.',
    getInTouch: 'GET IN TOUCH',

    // Section 7: Preferred Customer
    becomePreferred: 'BECOME A PREFERRED CUSTOMER AND SAVE',
    preferredDesc: 'Enjoy instant savings, free shipping, and special promotions.',

    // Benefits
    benefits: {
      reducedPricing: 'Reduced Pricing',
      reducedPricingDesc: 'Save up to 25% on every order.',
      freeShipping: 'FREE Shipping',
      freeShippingDesc: 'Free shipping on orders more than $100.',
      birthdayGift: 'Birthday Gift',
      birthdayGiftDesc: 'Celebrate your day with a $5 coupon from us.',
      fiveBack: '$5 Back',
      fiveBackDesc: 'Get a $5 coupon with every $100 you spend.',
      exclusivePromos: 'Exclusive Promotions',
      exclusivePromosDesc: 'Receive exclusive offers throughout the year.',
      freeMembership: 'Free Membership',
      freeMembershipDesc: 'Complimentary membership renewal when you spend $500 or more.',
    },

    findMoreAt: 'Find more at',
    orContactDealer: 'or',
    contactYourDealer: 'contact your dealer',
    today: 'today!',
    joinAndSave: 'JOIN & START SAVING!',

    // Section 8: Pick a Category
    pickCategory: 'PICK A CATEGORY TO SHOP',

    // Category names
    categories: {
      motorOils: 'Motor Oils',
      transmissionFluids: 'Transmission Fluids',
      filtrationProducts: 'Filtration Products',
      fuelAdditives: 'Fuel Additives',
      gearLubes: 'Gear Lubes',
      greases: 'Greases',
      hydraulicOils: 'Hydraulic Oils',
      compressorOils: 'Compressor Oils',
    },
    shopNow: 'SHOP NOW',

    // Footer
    footer: {
      products: 'PRODUCTS',
      vehicle: 'VEHICLE',
      contact: 'CONTACT',
      motorOil: 'Motor Oil',
      hydraulicOil: 'Hydraulic Oil',
      compressorOil: 'Compressor Oil',
      transmissionFluid: 'Transmission Fluid',
      gearLube: 'Gear Lube',
      fuelAdditives: 'Fuel Additives',
      greases: 'Greases',
      filters: 'Filters',
      autoLightTruck: 'Auto / Light Truck',
      motorcycle: 'Motorcycle',
      atvUtv: 'ATV & UTV',
      marine: 'Marine',
      diesel: 'Diesel',
      snowmobile: 'Snowmobile',
      pwc: 'PWC',
      smallEngine: 'Small Engine',
      heavyDuty: 'Heavy Duty',
    },

    // Contact Section
    contact: {
      eyebrow: 'Contact Us',
      heading: 'Have questions?',
      description: 'Let us know how we can help.',
      nameLabel: 'Name *',
      emailLabel: 'Email *',
      phoneLabel: 'Phone',
      phonePlaceholder: '(555) 555-5555',
      messageLabel: 'Message *',
      submitButton: 'Send message',
      submitting: 'Sending...',
      requiredFields: 'Please complete all required fields.',
      securityVerification: 'Please complete the security verification.',
      thankYou: 'Thank you!',
      willReachOut: 'will reach out shortly.',
      weWillReachOut: 'We will reach out shortly.',
      genericError: 'Something went wrong. Please try again.',
    },
  },

  es: {
    // Header
    independentDealer: 'DISTRIBUIDOR INDEPENDIENTE',

    // Section 3: Product Categories
    findProducts: 'ENCUENTRA TUS PRODUCTOS',
    findProductsDesc:
      'Selecciona tu tipo de vehiculo para ver solo los productos AMSOIL compatibles.',

    // Vehicle categories
    vehicles: {
      autoLt: 'Auto/Camioneta',
      motorcycle: 'Motocicleta',
      atv: 'ATV',
      utv: 'UTV',
      snowmobile: 'Motonieve',
      marine: 'Marino',
      pwc: 'Moto Acuatica',
      smallEngine: 'Motor Pequeno',
      heavyDuty: 'Trabajo Pesado',
    },

    // Section 4: Featured Products (Three Tiers)
    threeTiers: 'TRES NIVELES DE RENDIMIENTO PREMIUM',
    threeTiersDesc:
      'Selecciona tu tipo de vehiculo para ver solo los productos AMSOIL compatibles.',

    // Product tiers
    tiers: {
      signatureSeries: 'SIGNATURE SERIES',
      extendedLife: 'EXTENDED-LIFE',
      oeSynthetic: 'OE 100%',
      syntheticMotorOil: 'ACEITE DE MOTOR 100% SINTETICO',
      syntheticMotorOilOe: 'ACEITE DE MOTOR SINTETICO',
      maxProtection: 'Maxima Proteccion del Motor',
      boostedProtection: 'Proteccion Mejorada del Motor',
      advancedProtection: 'Proteccion Avanzada del Motor',
      interval25k: 'Hasta 25,000 millas o 1 ano*',
      interval20k: 'Hasta 20,000 millas o 1 ano*',
      intervalOem: 'Intervalo de cambio recomendado por el fabricante',
    },
    disclaimer: '* Lo que ocurra primero. En servicio normal.',
    shopMotorOil: 'COMPRAR ACEITE DE MOTOR',

    // Section 5: Request Catalog
    rightProduct: 'TENEMOS EL PRODUCTO ADECUADO PARA TODOS TUS PROYECTOS.',
    catalogDesc1: 'Explora la linea completa de productos premium AMSOIL en',
    catalogDesc2: 'el catalogo mas reciente directo de fabrica.',
    requestCatalog: 'SOLICITA TU CATALOGO GRATIS',

    // Section 6: Dealer Info
    fullServiceDealer: 'Distribuidor de Servicio Completo',
    notSureProduct: 'No Estas Seguro Cual Producto Es El Adecuado?',
    contactUsHelp:
      'Contactanos para mas informacion sobre productos AMSOIL, ayuda para determinar que productos necesitas o para hacer un pedido.',
    getInTouch: 'CONTACTANOS',

    // Section 7: Preferred Customer
    becomePreferred: 'CONVIERTETE EN CLIENTE PREFERIDO Y AHORRA',
    preferredDesc: 'Disfruta de ahorros instantaneos, envio gratis y promociones especiales.',

    // Benefits
    benefits: {
      reducedPricing: 'Precios Reducidos',
      reducedPricingDesc: 'Ahorra hasta 25% en cada pedido.',
      freeShipping: 'Envio GRATIS',
      freeShippingDesc: 'Envio gratis en pedidos mayores a $100.',
      birthdayGift: 'Regalo de Cumpleanos',
      birthdayGiftDesc: 'Celebra tu dia con un cupon de $5 de nuestra parte.',
      fiveBack: '$5 de Vuelta',
      fiveBackDesc: 'Recibe un cupon de $5 por cada $100 que gastes.',
      exclusivePromos: 'Promociones Exclusivas',
      exclusivePromosDesc: 'Recibe ofertas exclusivas durante todo el ano.',
      freeMembership: 'Membresia Gratis',
      freeMembershipDesc: 'Renovacion de membresia gratis cuando gastas $500 o mas.',
    },

    findMoreAt: 'Encuentra mas en',
    orContactDealer: 'o',
    contactYourDealer: 'contacta a tu distribuidor',
    today: 'hoy!',
    joinAndSave: 'UNETE Y EMPIEZA A AHORRAR!',

    // Section 8: Pick a Category
    pickCategory: 'ELIGE UNA CATEGORIA PARA COMPRAR',

    // Category names
    categories: {
      motorOils: 'Aceites de Motor',
      transmissionFluids: 'Fluidos de Transmision',
      filtrationProducts: 'Productos de Filtracion',
      fuelAdditives: 'Aditivos de Combustible',
      gearLubes: 'Lubricantes para Engranajes',
      greases: 'Grasas',
      hydraulicOils: 'Aceites Hidraulicos',
      compressorOils: 'Aceites para Compresores',
    },
    shopNow: 'COMPRAR AHORA',

    // Footer
    footer: {
      products: 'PRODUCTOS',
      vehicle: 'VEHICULO',
      contact: 'CONTACTO',
      motorOil: 'Aceite de Motor',
      hydraulicOil: 'Aceite Hidraulico',
      compressorOil: 'Aceite para Compresor',
      transmissionFluid: 'Fluido de Transmision',
      gearLube: 'Lubricante para Engranajes',
      fuelAdditives: 'Aditivos de Combustible',
      greases: 'Grasas',
      filters: 'Filtros',
      autoLightTruck: 'Auto / Camioneta',
      motorcycle: 'Motocicleta',
      atvUtv: 'ATV y UTV',
      marine: 'Marino',
      diesel: 'Diesel',
      snowmobile: 'Motonieve',
      pwc: 'Moto Acuatica',
      smallEngine: 'Motor Pequeno',
      heavyDuty: 'Trabajo Pesado',
    },

    // Contact Section
    contact: {
      eyebrow: 'Contactanos',
      heading: 'Tienes preguntas?',
      description: 'Cuentanos como podemos ayudarte.',
      nameLabel: 'Nombre *',
      emailLabel: 'Correo Electronico *',
      phoneLabel: 'Telefono',
      phonePlaceholder: '(555) 555-5555',
      messageLabel: 'Mensaje *',
      submitButton: 'Enviar mensaje',
      submitting: 'Enviando...',
      requiredFields: 'Por favor completa todos los campos requeridos.',
      securityVerification: 'Por favor completa la verificacion de seguridad.',
      thankYou: 'Gracias!',
      willReachOut: 'se comunicara contigo pronto.',
      weWillReachOut: 'Nos comunicaremos contigo pronto.',
      genericError: 'Algo salio mal. Por favor intenta de nuevo.',
    },
  },
} as const;

export type TranslationKeys = typeof dealerTemplateTranslations.en;

/**
 * Get a translation by dot-notation key path.
 * Example: t('es', 'vehicles.motorcycle') => 'Motocicleta'
 */
export function t(lang: Language, keyPath: string): string {
  const keys = keyPath.split('.');
  let current: unknown = dealerTemplateTranslations[lang];

  for (const key of keys) {
    if (current && typeof current === 'object' && key in current) {
      current = (current as Record<string, unknown>)[key];
    } else {
      // Fallback to English if key not found in target language
      current = dealerTemplateTranslations.en;
      for (const fallbackKey of keys) {
        if (current && typeof current === 'object' && fallbackKey in current) {
          current = (current as Record<string, unknown>)[fallbackKey];
        } else {
          return keyPath; // Return key path if not found at all
        }
      }
      break;
    }
  }

  return typeof current === 'string' ? current : keyPath;
}
```

**Step 2: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 3: Commit**

```bash
git add lib/translations/dealer-template.ts
git commit -m "feat: add English/Spanish translation file for dealer template"
```

---

## Task 3: Create LanguageProvider Component

**Files:**

- Create: `components/LanguageProvider.tsx`

**Step 1: Create the provider**

Create `components/LanguageProvider.tsx`:

```typescript
'use client';

import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { Language } from '@/lib/translations/dealer-template';

interface LanguageContextValue {
  language: Language;
  setLanguage: (lang: Language) => void;
}

const LanguageContext = createContext<LanguageContextValue | null>(null);

interface LanguageProviderProps {
  defaultLanguage: Language;
  subdomain: string;
  children: ReactNode;
}

/**
 * Provides language state for dealer template.
 *
 * Language is stored in sessionStorage per subdomain so:
 * - Choice persists during browser session
 * - Different dealers can have different language choices
 * - No cookies/consent needed
 */
export function LanguageProvider({
  defaultLanguage,
  subdomain,
  children,
}: LanguageProviderProps) {
  const storageKey = `dlp-lang-${subdomain}`;

  // Initialize with default, then check sessionStorage on client
  const [language, setLanguageState] = useState<Language>(defaultLanguage);
  const [isHydrated, setIsHydrated] = useState(false);

  // On mount, check sessionStorage for saved language preference
  useEffect(() => {
    const saved = sessionStorage.getItem(storageKey);
    if (saved === 'en' || saved === 'es') {
      setLanguageState(saved);
    }
    setIsHydrated(true);
  }, [storageKey]);

  // Persist language changes to sessionStorage
  const setLanguage = (lang: Language) => {
    setLanguageState(lang);
    sessionStorage.setItem(storageKey, lang);
  };

  // During SSR/hydration, use default language to avoid mismatch
  const effectiveLanguage = isHydrated ? language : defaultLanguage;

  return (
    <LanguageContext.Provider value={{ language: effectiveLanguage, setLanguage }}>
      {children}
    </LanguageContext.Provider>
  );
}

/**
 * Hook to access language context.
 * Must be used within a LanguageProvider.
 */
export function useLanguage(): LanguageContextValue {
  const context = useContext(LanguageContext);
  if (!context) {
    throw new Error('useLanguage must be used within a LanguageProvider');
  }
  return context;
}
```

**Step 2: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 3: Commit**

```bash
git add components/LanguageProvider.tsx
git commit -m "feat: add LanguageProvider for client-side language state"
```

---

## Task 4: Create LanguageSwitcher Component

**Files:**

- Create: `components/LanguageSwitcher.tsx`

**Step 1: Create the switcher component**

Create `components/LanguageSwitcher.tsx`:

```typescript
'use client';

import { useLanguage } from './LanguageProvider';

/**
 * Language toggle displayed in dealer page header.
 * Allows visitors to switch between English and Spanish.
 */
export function LanguageSwitcher() {
  const { language, setLanguage } = useLanguage();

  return (
    <div className="language-switcher">
      <button
        type="button"
        onClick={() => setLanguage('en')}
        className={`language-switcher__btn ${language === 'en' ? 'language-switcher__btn--active' : ''}`}
        aria-pressed={language === 'en'}
        aria-label="English"
      >
        EN
      </button>
      <span className="language-switcher__divider">|</span>
      <button
        type="button"
        onClick={() => setLanguage('es')}
        className={`language-switcher__btn ${language === 'es' ? 'language-switcher__btn--active' : ''}`}
        aria-pressed={language === 'es'}
        aria-label="Espanol"
      >
        ES
      </button>
    </div>
  );
}
```

**Step 2: Add styles to dealer-template.css**

Add to `app/dealer-template.css` (at the end, before closing comments):

```css
/* Language Switcher */
.language-switcher {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  margin-left: 1rem;
}

.language-switcher__btn {
  background: none;
  border: none;
  color: #ffffff80;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
  transition: color 0.2s ease;
}

.language-switcher__btn:hover {
  color: #ffffff;
}

.language-switcher__btn--active {
  color: #f8981d;
  font-weight: 600;
}

.language-switcher__divider {
  color: #ffffff40;
  font-size: 0.875rem;
}

/* Mobile adjustments */
@media (max-width: 768px) {
  .language-switcher {
    margin-left: 0.5rem;
  }

  .language-switcher__btn {
    padding: 0.25rem;
    font-size: 0.75rem;
  }
}
```

**Step 3: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 4: Commit**

```bash
git add components/LanguageSwitcher.tsx app/dealer-template.css
git commit -m "feat: add LanguageSwitcher component with styling"
```

---

## Task 5: Update DealerInfo Type

**Files:**

- Modify: `types/dealer.ts`

**Step 1: Add preferredLanguage to DealerInfo interface**

In `types/dealer.ts`, add after line 65 (after `socialLinks`):

```typescript
  preferredLanguage?: 'en' | 'es'; // Default language for dealer page
```

**Step 2: Update PLACEHOLDER_DEALER**

In `types/dealer.ts`, add to PLACEHOLDER_DEALER (around line 83, before closing brace):

```typescript
  preferredLanguage: 'en',
```

**Step 3: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 4: Commit**

```bash
git add types/dealer.ts
git commit -m "feat: add preferredLanguage to DealerInfo type"
```

---

## Task 6: Update Dealer Update Validation

**Files:**

- Modify: `lib/dealer-validation.ts`

**Step 1: Add preferredLanguage to DealerUpdateData interface**

In `lib/dealer-validation.ts`, add after line 27 (after `socialLinks`):

```typescript
  preferredLanguage?: 'en' | 'es';
```

**Step 2: Add validation for preferredLanguage**

In the `validateDealerUpdate` function, add after socialLinks validation (around line 295):

```typescript
// Preferred language validation (if provided)
if (sanitizedData.preferredLanguage !== undefined) {
  const validLanguages = ['en', 'es'];
  if (!validLanguages.includes(sanitizedData.preferredLanguage)) {
    const error = 'preferredLanguage must be "en" or "es"';
    errors.push(error);
    fieldErrors.preferredLanguage = error;
  }
}
```

**Step 3: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 4: Commit**

```bash
git add lib/dealer-validation.ts
git commit -m "feat: add preferredLanguage validation"
```

---

## Task 7: Update Dealer Update API Route

**Files:**

- Modify: `app/api/dealer/update/route.ts`

**Step 1: Add preferredLanguage handling**

In `app/api/dealer/update/route.ts`, add after line 337 (after socialLinks handling):

```typescript
// Handle preferredLanguage
if (sanitizedBody.preferredLanguage !== undefined) {
  updateData.preferredLanguage = sanitizedBody.preferredLanguage;
}
```

**Step 2: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 3: Commit**

```bash
git add app/api/dealer/update/route.ts
git commit -m "feat: handle preferredLanguage in dealer update API"
```

---

## Task 8: Update EditorForm Component

**Files:**

- Modify: `app/dashboard/editor/EditorForm.tsx`

**Step 1: Add preferredLanguage to initialData interface**

In `EditorForm.tsx`, add to the initialData interface (around line 36):

```typescript
preferredLanguage: 'en' | 'es';
```

**Step 2: Add to formData state**

In the useState for formData (around line 75), add:

```typescript
    preferredLanguage: initialData.preferredLanguage || 'en',
```

**Step 3: Add language dropdown in Business Information section**

Add after the description field (around line 682, before the closing `</div>` of Business Information grid):

```typescript
              {/* Default Page Language */}
              <div className="md:col-span-2">
                <label
                  htmlFor="preferredLanguage"
                  className="block text-sm font-medium text-white/70 mb-1"
                >
                  Default Page Language
                </label>
                <select
                  id="preferredLanguage"
                  value={formData.preferredLanguage}
                  onChange={(e) =>
                    setFormData({
                      ...formData,
                      preferredLanguage: e.target.value as 'en' | 'es',
                    })
                  }
                  className="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-800/30 text-white focus:ring-2 focus:ring-sky-400"
                >
                  <option value="en">English</option>
                  <option value="es">Spanish (Espanol)</option>
                </select>
                <p className="mt-1 text-xs text-white/50">
                  Choose the default language for your dealer page. Visitors can switch languages
                  using the toggle on your page.
                </p>
              </div>
```

**Step 4: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 5: Commit**

```bash
git add app/dashboard/editor/EditorForm.tsx
git commit -m "feat: add language selection dropdown to editor form"
```

---

## Task 9: Update Editor Page Server Component

**Files:**

- Modify: `app/dashboard/editor/page.tsx`

**Step 1: Add preferredLanguage to dealer select and pass to EditorForm**

Read the current file first, then add `preferredLanguage` to the dealer query select and ensure it's passed to `EditorForm` in the initialData prop.

**Step 2: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 3: Commit**

```bash
git add app/dashboard/editor/page.tsx
git commit -m "feat: pass preferredLanguage to editor form"
```

---

## Task 10: Update ContactSection for Translations

**Files:**

- Modify: `app/components/contact-section.tsx`

**Step 1: Add language prop and use translations**

Update the component to accept a `language` prop and use the translation helper. The component needs to import the translation function and use it for all user-facing strings.

Add import at top:

```typescript
import { Language, t } from '@/lib/translations/dealer-template';
```

Add to interface:

```typescript
  language?: Language;
```

Update default props:

```typescript
  language = 'en',
```

Replace hardcoded strings with `t(language, 'contact.keyName')` calls.

**Step 2: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 3: Commit**

```bash
git add app/components/contact-section.tsx
git commit -m "feat: add translation support to ContactSection"
```

---

## Task 11: Create DealerTemplateClient Wrapper

**Files:**

- Create: `components/DealerTemplateClient.tsx`

**Step 1: Create client wrapper component**

Create `components/DealerTemplateClient.tsx`:

```typescript
'use client';

import { DealerInfo } from '@/types/dealer';
import { DealerTemplate } from './DealerTemplate';
import { LanguageProvider } from './LanguageProvider';
import { Language } from '@/lib/translations/dealer-template';

interface DealerTemplateClientProps {
  dealer: DealerInfo;
  dealerNumber?: string;
  leadFormEnabled?: boolean;
  turnstileSiteKey?: string | null;
  defaultLanguage: Language;
}

/**
 * Client wrapper for DealerTemplate that provides language context.
 * This allows the template to be rendered with ISR while supporting
 * client-side language switching.
 */
export function DealerTemplateClient({
  dealer,
  dealerNumber,
  leadFormEnabled,
  turnstileSiteKey,
  defaultLanguage,
}: DealerTemplateClientProps) {
  return (
    <LanguageProvider defaultLanguage={defaultLanguage} subdomain={dealer.subdomain}>
      <DealerTemplate
        dealer={dealer}
        dealerNumber={dealerNumber}
        leadFormEnabled={leadFormEnabled}
        turnstileSiteKey={turnstileSiteKey}
      />
    </LanguageProvider>
  );
}
```

**Step 2: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 3: Commit**

```bash
git add components/DealerTemplateClient.tsx
git commit -m "feat: add DealerTemplateClient wrapper with LanguageProvider"
```

---

## Task 12: Update DealerTemplate for Translations

**Files:**

- Modify: `components/DealerTemplate.tsx`

This is the largest task. The DealerTemplate needs to:

1. Import useLanguage hook and t function
2. Add 'use client' directive (needed for useLanguage hook)
3. Replace all hardcoded strings with t() calls
4. Add LanguageSwitcher to header
5. Pass language to ContactSection

**Step 1: Add client directive and imports**

At the top of the file, add:

```typescript
'use client';
```

Add imports:

```typescript
import { useLanguage } from './LanguageProvider';
import { LanguageSwitcher } from './LanguageSwitcher';
import { t } from '@/lib/translations/dealer-template';
```

**Step 2: Get language from context**

Inside the component function, after the helper functions, add:

```typescript
const { language } = useLanguage();
```

**Step 3: Replace hardcoded strings**

Replace each hardcoded string with the appropriate t() call. Key replacements:

- `"INDEPENDENT DEALER"` -> `{t(language, 'independentDealer')}`
- `"FIND YOUR PRODUCTS"` -> `{t(language, 'findProducts')}`
- `"Auto/LT"` -> `{t(language, 'vehicles.autoLt')}`
- etc.

**Step 4: Add LanguageSwitcher to header**

In the header-row-1 div, after the header-contact div, add:

```tsx
<LanguageSwitcher />
```

**Step 5: Pass language to ContactSection**

Update the ContactSection call to include language:

```tsx
<ContactSection
  dealerName={dealer.name}
  dealerNumber={dealerNumber}
  subdomain={dealer.subdomain}
  isEnabled={leadFormEnabled}
  turnstileSiteKey={turnstileSiteKey}
  language={language}
/>
```

**Step 6: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors (may have warnings about unused vars during refactor)

**Step 7: Commit**

```bash
git add components/DealerTemplate.tsx
git commit -m "feat: add translation support to DealerTemplate"
```

---

## Task 13: Update Dealer Page to Use Client Wrapper

**Files:**

- Modify: `app/dealers/[subdomain]/page.tsx`

**Step 1: Update imports**

Replace DealerTemplate import with DealerTemplateClient:

```typescript
import { DealerTemplateClient } from '@/components/DealerTemplateClient';
```

**Step 2: Add preferredLanguage to getCachedDealer select**

Add `preferredLanguage: true` to the select in getCachedDealer function.

**Step 3: Pass preferredLanguage to template**

In transformToTemplateProps, add:

```typescript
preferredLanguage: dealer.preferredLanguage || 'en',
```

**Step 4: Update component usage**

Replace:

```tsx
<DealerTemplate
  dealer={dealerInfo}
  ...
/>
```

With:

```tsx
<DealerTemplateClient
  dealer={dealerInfo}
  dealerNumber={dealer.dealerNumber || undefined}
  leadFormEnabled={leadFormEnabled}
  turnstileSiteKey={turnstileSiteKey}
  defaultLanguage={(dealer.preferredLanguage as 'en' | 'es') || 'en'}
/>
```

**Step 5: Verify TypeScript compiles**

Run: `npx tsc --noEmit`

Expected: No errors

**Step 6: Commit**

```bash
git add app/dealers/[subdomain]/page.tsx
git commit -m "feat: use DealerTemplateClient with language support"
```

---

## Task 14: Run Tests and Fix Issues

**Step 1: Run all tests**

Run: `npm test`

Expected: Tests pass or identify issues to fix

**Step 2: Fix any failing tests**

Update test files as needed for the new props and structure.

**Step 3: Run build**

Run: `npm run build`

Expected: Build succeeds

**Step 4: Commit any test fixes**

```bash
git add -A
git commit -m "test: update tests for Spanish template feature"
```

---

## Task 15: Manual Testing

**Step 1: Start dev server**

Run: `npm run dev`

**Step 2: Test language toggle**

1. Visit a dealer page (e.g., http://localhost:3000/dealers/test-starter)
2. Verify English content displays by default
3. Click "ES" in language switcher
4. Verify Spanish content displays
5. Refresh page - verify Spanish persists (sessionStorage)
6. Close browser, reopen - verify English default (session cleared)

**Step 3: Test editor**

1. Log in as a test dealer
2. Go to /dashboard/editor
3. Find "Default Page Language" dropdown
4. Change to Spanish
5. Publish
6. Visit public page - verify Spanish is now default

**Step 4: Commit test verification**

No code changes needed - just verification.

---

## Task 16: Final Commit and PR Prep

**Step 1: Run linter**

Run: `npm run lint`

Fix any issues.

**Step 2: Run final build**

Run: `npm run build`

**Step 3: Verify git status**

Run: `git status`

Ensure all changes are committed.

**Step 4: Summary**

The feature is complete when:

- [ ] Dealer can select default language in editor
- [ ] Public page shows language switcher in header
- [ ] All template text translates to Spanish when ES is selected
- [ ] Language choice persists during browser session
- [ ] Same URL works for both languages
- [ ] Tests pass
- [ ] Build succeeds
