# ITG Group — Contexto de Seeders para Claude Code

## Objetivo
Migrar el contenido estático del sitio ITG Group (multilengaje) a la base de datos,
generando Seeders de Laravel para cada bloque de página en Filament.

---

## Reglas fijas para TODOS los seeders

- Tabla: `content_block_pages`
- Columnas: `id`, `type`, `content` (JSON), `sort_order`, `page_id`, `shared_section_id`, `created_at`, `updated_at`
- El `type` SIEMPRE debe coincidir con el valor del enum `PageBlockTypeEnum` (ver sección Enum)
- El JSON se genera con `json_encode($content, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)`
- Cada seeder elimina el registro existente antes de insertar (evitar duplicados)
- Namespace: `Database\Seeders`
- Comando: `php artisan db:seed --class=NombreDelSeeder`

---

## Idiomas soportados (6 locales)

| Clave en código | Idioma     | Archivo fuente              |
|-----------------|------------|-----------------------------|
| `en`            | Inglés     | `lang/en/messages.php`      |
| `es`            | Español    | `lang/es/messages_es.php`   |
| `it`            | Italiano   | `lang/it/messages_it.php`   |
| `fr`            | Francés    | `lang/fr/messages_fr.php`   |
| `pt`            | Portugués  | `lang/pt/messages_pt.php`   |
| `zh_CN`         | Chino      | `lang/zh/messages_zh.php`   |

> IMPORTANTE: el chino usa `zh_CN`, NO `zh`.
> Todo campo multiidioma es un objeto JSON: `{"en": "...", "es": "...", "it": "...", "fr": "...", "pt": "...", "zh_CN": "..."}`

---

## Enum PageBlockTypeEnum — valores exactos del campo `type`

```php
case HERO_CAROUSEL            = 'hero_carousel_main';
case PAGE_HEADER_BREADCRUMB   = 'page_header_breadcrumb';
case SIMPLE_RICH_TEXT         = 'simple_rich_text';
case SPLIT_CONTENT            = 'split_content';
case LIST_GROUP_IMAGES        = 'list_group_images';
case ICON_FEATURE_CARDS       = 'icon_feature_cards';
case SIDE_IMAGE_RICH_TEXT     = 'side_image_rich_text';
case GRID_IMAGE_CARDS         = 'grid_image_cards';
case SIDE_GALLERY_RICH_TEXT   = 'side_gallery_rich_text';
case TIMELINE_CONTENT         = 'timeline_content';
case IMAGE_BANNER_TEXT        = 'image_banner_text';
case NUMBERED_STEPS           = 'numbered_steps';
case CARDS_WITH_MODAL         = 'cards_with_modal';
case ACCORDION_MODAL_LIST     = 'accordion_modal_list';
case ICON_INFO_CARDS          = 'icon_info_cards';
case CAROUSEL_ICONS_DESC      = 'carousel_icons_description';
case CAROUSEL_TITLE_DESC      = 'carousel_title_description';
case CAROUSEL_IMAGE_TITLE_BUTTON = 'carousel_image_title_button';
case CAROUSEL_IMAGE_TITLE_DESC   = 'carousel_image_title_desc';
case CAROUSEL_BUTTON_LINKS    = 'carousel_button_links';
case YOUTUBE_VIDEO            = 'youtube_video';
case IMAGE_GALLERY            = 'image_gallery';
case GALLERY_ICON_CARDS       = 'gallery_icon_cards';
case FREQUENTLY_ASKED_QUESTIONS = 'freq_asked_questions';
case SHARED_SECTION           = 'shared_section';
```

---

## Páginas y sus page_id

| Página       | page_id |
|--------------|---------|
| Home         | 4       |
| About Us     | 5       |
| Partners     | 6       |
| Contacts     | 7       |

---

## Bloques ya generados — About Us (page_id = 5)

| sort_order | Tipo                       | Seeder generado                          | Estado   |
|------------|----------------------------|------------------------------------------|----------|
| 1          | `page_header_breadcrumb`   | `PageHeaderBreadcrumbAboutSeeder.php`    | ✅ listo |
| 2          | `icon_feature_cards`       | `IconFeatureCardsAboutSeeder.php`        | ✅ listo |
| 3          | `side_image_rich_text`     | `SideImageRichTextAboutSeeder.php`       | ✅ listo |
| 4          | `grid_image_cards`         | `GridImageCardsAboutSeeder.php`          | ✅ listo |
| 5          | `carousel_button_links`    | `CarouselButtonLinksDivisionsAboutSeeder.php` | ✅ listo |
| 6          | `simple_rich_text`         | `SimpleRichTextHistoryAboutSeeder.php`   | ✅ listo |
| 7          | `timeline_content`         | `TimelineContentAboutSeeder.php`         | ✅ listo |
| 8          | `youtube_video`            | `YoutubeVideoAboutSeeder.php`            | ✅ listo |
| 9          | `simple_rich_text`         | `SimpleRichTextOurPeopleAboutSeeder.php` | ✅ listo |
| 10         | `image_gallery`            | `ImageGalleryOurPeopleAboutSeeder.php`   | ✅ listo |
| 11         | `simple_rich_text`         | `SimpleRichTextCommercialAgentsAboutSeeder.php` | ✅ listo |

---

## Bloques ya generados — Partners (page_id = 6)

| sort_order | Tipo                       | Seeder generado                          | Estado   |
|------------|----------------------------|------------------------------------------|----------|
| 1          | `page_header_breadcrumb`   | `PageHeaderBreadcrumbPartnersSeeder.php` | ✅ listo |
| 2          | `simple_rich_text`         | `SimpleRichTextPartnersHeaderSeeder.php` | ✅ listo |
| 3          | `gallery_icon_cards`       | `GalleryIconCardsPartnersSeeder.php`     | ✅ listo |
| 4          | `numbered_steps`           | `NumberedStepsPartnersSeeder.php`        | ✅ listo |

---

## Bloques ya generados — Contacts (page_id = 7)

| sort_order | Tipo                       | Seeder generado                              | Estado   |
|------------|----------------------------|----------------------------------------------|----------|
| 1          | `page_header_breadcrumb`   | `PageHeaderBreadcrumbContactsSeeder.php`     | ✅ listo |
| 2          | `simple_rich_text`         | `SimpleRichTextContactDirectlySeeder.php`    | ✅ listo |
| 3          | `icon_info_cards`          | `IconInfoCardsContactsSeeder.php`            | ✅ listo |
| 4          | `numbered_steps`           | `NumberedStepsContactsSeeder.php`            | ✅ listo |
| 5          | `simple_rich_text`         | `SimpleRichTextContactFormSeeder.php`        | ✅ listo |
| 6          | `simple_rich_text`         | `SimpleRichTextDivisionChooseTitleContactsSeeder.php` | ✅ listo |
| 7          | `simple_rich_text`         | `SimpleRichTextDivisionSubtitleContactsSeeder.php`    | ✅ listo |

---

## Bloques ya generados — Home (page_id = 4)

| sort_order | Tipo                       | Seeder generado                          | Estado   |
|------------|----------------------------|------------------------------------------|----------|
| 1          | `hero_carousel_main`       | `HeroCarouselHomeSeeder.php`             | ✅ listo |
| 2          | `split_content`            | `SplitContentHomeSeeder.php`             | ✅ listo |
| 3          | `carousel_icons_description` | `CarouselIconsPartnersHomeSeeder.php`  | ✅ listo |
| 4          | `list_group_images`        | `ListGroupProductsHomeSeeder.php`        | ✅ listo |
| 5          | `carousel_title_description` | `CarouselTitleDescriptionHomeSeeder.php` | ✅ listo |
| 6          | `carousel_image_title_button` | `CarouselImageTitleButtonMachineryHomeSeeder.php` | ✅ listo |
| 7          | `carousel_image_title_desc` | `CarouselImageTitleDescDivisionsHomeSeeder.php` | ✅ listo |

---

## Estructura de archivos de traducción

Los archivos están en `lang/{locale}/messages.php`.
Grupos de claves relevantes ya identificados:

### Hero / Banner Home
`bn-home-title1`, `together`, `bn-home-subtitle2`
`homet-itg`, `homet-line`, `sl2-bn-home-subtitle2`
`sl4-bn-home-title1`, `sl4-bn-home-subtitle1`, `sl4-bn-home-subtitle2`

### Feature cards (hero)
`txt-title-card1` → "Textile products"
`txt-title-card2` → "Textile machinery"
`btn-card1` → "Read more"

### About / Split Content
`about-us`, `about-company`, `about-company-subtitle`
`about-company-text`, `about-company-text2`
`our-people`
`text-home-about-title1`, `text-home-about-description1`
`text-home-about-title2`, `text-home-about-description2`

### Partners (carousel)
`our-partner`, `partner-text-home`
`partner-{id}` → categoría corta (moly, iro, titan, rifa, henghui, dky, fiber, comsat, bonas, ferber, canalair)
`partner-text-{id}` → descripción larga

### Productos Home (list group)
`our-products`
`weaving`, `knitting`, `braiding`, `yarn`, `machinery`

### Maquinaria Home
`machinery-title-home`, `machinery-subtitle-home`

### Newsletter / Footer
`newsletter`, `newsletter-description`, `bnt-email`, `follow-us`

### Contacto
`name`, `email`, `phone`, `country`, `message`, `send-message`

---

## Convenciones de nombre de Seeder

`{BloquePascalCase}{SeccionPascalCase}Seeder.php`

Ejemplos:
- `HeroCarouselHomeSeeder`
- `SplitContentHomeSeeder`
- `CarouselIconsPartnersHomeSeeder`
- `ListGroupProductsHomeSeeder`

---

## Patrón base de un Seeder

```php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class NombreSeeder extends Seeder
{
    public function run(): void
    {
        DB::table('content_block_pages')
            ->where('page_id', PAGE_ID)
            ->where('type', 'tipo_enum_value')
            ->delete();

        $content = [
            // array PHP con estructura del bloque
            // campos multiidioma: ['en' => '', 'es' => '', 'it' => '', 'fr' => '', 'pt' => '', 'zh_CN' => '']
            // imágenes que el usuario sube manual: null
        ];

        DB::table('content_block_pages')->insert([
            'page_id'    => PAGE_ID,
            'type'       => 'tipo_enum_value',
            'sort_order' => N,
            'content'    => json_encode($content, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        $this->command->info('✅ Bloque insertado correctamente');
    }
}
```

---

## Notas importantes

1. **Imágenes**: siempre `null` — el usuario las sube manualmente desde el panel Filament.
2. **Botones**: estructura `button_wrapper` → `{ "button": { "label": {multiidioma}, "url": "...", "target": "_self" } }`
3. **TiptapEditor**: el campo `content` es HTML, puede incluir tags como `<h2>`, `<p>`, `<strong>`, `<ul>`, etc.
4. **Repeaters con mutateDehydratedStateUsing**: los `button_wrapper` con maxItems(1) se guardan como objeto directo (no array).
5. **sort_order**: incremental por página, empezando en 1.
6. **No usar SQL directo**: siempre Seeders PHP para evitar el problema de escape de comillas en JSON con HTML.