---

````markdown
MỤC TIÊU CHUNG
-------------- 
Xóa toàn bộ cơ chế tạo template tĩnh hiện tại trong module UiBuilder.  
Thay thế bằng UI Builder theo phong cách **Elementor**:  
- Cho phép admin chọn **structure/layout** (hàng / cột),  
- Sau đó **thêm / xoá / chỉnh sửa / kéo-thả** các **element** vào từng ô,  
- Lưu toàn bộ layout + nội dung dưới dạng **JSON cấu trúc** (structure + elements + settings),  
- Mỗi cấu trúc được gán cho **tenant_id + domain_id + component**, support multi-domain per tenant,  
- Có preview responsive (Desktop / Tablet / Mobile), undo/redo cơ bản, upload ảnh, sanitize, cache, versioning nhẹ (optionally),  
- FE (Next.js) gọi API để nhận HTML hoàn chỉnh (server-side render bằng cách merge JSON + renderer).

YÊU CẦU CHUNG KỸ THUẬT
-----------------------
- Module: `app/Modules/UiBuilder/` (Laravel 11, PHP 8.2+).  
- UI admin: Blade + Vite + Vue 3 (single-file components) + Tailwind CSS độc lập (không dùng CSS project CMS).  
- Drag & drop: dùng `sortablejs` / `vue.draggable.next`.  
- Inline editing: contenteditable cho text, image upload modal cho hình, color picker cho màu.  
- Store images: `storage/app/public/uibuilder/` -> public via `/storage/uibuilder/...`.  
- Sanitize: server-side sanitize (HTMLPurifier) khi render/export HTML; client-side sanitize on save as fallback.  
- Caching: `tenant_ui:{tenant_id}:{domain_id}:{component}` TTL 3600; clear on save.  
- Auth: admin APIs protected by existing `auth` middleware (sanctum or session).  
- Version: save `version` number and `created_by`, `updated_by` metadata for each saved config.

DB / MIGRATIONS
----------------
1) Bảng `ui_structures` (lưu cấu trúc template do user tạo)
- id (bigIncrements)
- tenant_id (unsignedBigInteger, FK -> hocmai_tenants.id) nullable? false
- domain_id (unsignedBigInteger, FK -> hocmai_tenant_domains.id) nullable? true (cần domain-level)
- component (varchar 50) e.g. 'footer'
- name (string) tên cấu trúc
- slug (string) unique per tenant+domain+component
- structure (json) -- lưu cấu trúc layout + element list (mảng)
- version (integer) default 1
- is_active (boolean) default true
- created_by, updated_by (unsignedBigInteger) nullable
- timestamps
- unique index (tenant_id, domain_id, component) optional if you want single active per domain+component

2) (Option) Bảng `ui_structure_revisions` (lưu lịch sử nếu muốn)
- id, ui_structure_id, structure(json), version, created_by, created_at

MODEL
-----
- `UiStructure` model (casts: structure => array)
- methods: getActiveFor(domain_id, tenant_id, component), latestVersion(), incrementVersionOnSave()

API ENDPOINTS
-------------
Web UI (Blade pages builder):
- GET `/admin/ui-builder` -> builder dashboard (list structures, create new structure -> choose layout)
- GET `/admin/ui-builder/structures/create` -> choose layout modal -> open builder
- GET `/admin/ui-builder/structures/{id}/edit` -> load builder with structure JSON
- GET `/admin/ui-builder/structures/{id}/preview` -> preview page (iframe) with responsive controls

Admin JSON API (protected):
- GET `/api/admin/ui/structures` -> list (filter tenant_id, domain_id, component)
- POST `/api/admin/ui/structures` -> create (body: tenant_id, domain_id, component, name, slug, structure JSON)
- GET `/api/admin/ui/structures/{id}` -> show
- PUT `/api/admin/ui/structures/{id}` -> update (increments version)
- DELETE `/api/admin/ui/structures/{id}` -> delete
- POST `/api/admin/ui/upload` -> upload image (returns URL)
- POST `/api/admin/ui/structures/{id}/publish` -> optionally set active and clear cache

Public API for FE:
- GET `/api/ui/render` with headers or query: `X-Tenant-Code` or domain host and component param e.g. `/api/ui/render?component=footer`
  - Server resolves tenant & domain (use HocmaiTenantDomain table), finds active structure for domain, renders HTML server-side (see RENDERER below) and returns `{ html, css }` or full HTML page.
- Optional: GET `/api/ui/structure?tenant_id=...&domain_id=...&component=...` returns structure JSON for debugging.

RENDERER (SERVER-SIDE)
----------------------
- Implement a `UiRenderer` service class in module:
  - Accepts template `structure` JSON and optionally `config` overrides,
  - Produces sanitized HTML string and CSS string (if elements include per-element CSS),
  - Use Mustache/Blade-like placeholder rendering internally for element fields,
  - Ensure to strip `<script>` tags and inline JS, only allow safe tags.

STRUCTURE JSON SPEC (KIỂU CHUẨN)
--------------------------------
Top-level:
```json
{
  "rows": [
    {
      "id": "row_1",
      "columns": [
        {
          "id": "col_1",
          "width": 6,                // grid units e.g. 12 grid system
          "elements": [
            {
              "id": "el_1",
              "type": "text",
              "settings": { "content": "Welcome", "tag": "p", "class":"..." }
            },
            {
              "id": "el_2",
              "type": "image",
              "settings": { "src": "/storage/uibuilder/logo.png", "alt":"Logo", "width":"120" }
            }
          ]
        },
        { "id":"col_2", "width":6, "elements":[ ... ] }
      ]
    }
  ],
  "styles": { "background":"#fff" },
  "meta": { "name":"Footer 3 columns" }
}
````

ELEMENT TYPES (ít nhất implement các loại sau)

* `text` — settings: `{ content, tag (p/h1/h2), align, class }`
* `image` — settings: `{ src, alt, width, link? }`
* `links` (list) — settings: `{ items: [{text, url}], layout: vertical|horizontal }`
* `social` — settings: `{ networks: [{name, url}], style }`
* `menu` — settings: `{ menu_slug }` (tự fetch menu nếu project có)
* `newsletter` — settings: `{ placeholder, button_text, action_url }`
* `html` — settings: `{ content }` (allow but will sanitize)
* `divider` — settings: `{ height, style }`
* `spacer` — settings: `{ height }`

## BUILDER UI (DETAILED)

* Page `edit.blade.php` loads Vue 3 app (Vite entry) that mounts builder.
* Left panel: **Blocks / Elements palette** (drag element into column)
* Middle: **Canvas** (iframe or div sandbox) showing live rendering of structure; implement using iframe to isolate module CSS.
* Right panel: **Element settings** (auto-generated form based on element type)
* Top bar: responsive controls Desktop/Tablet/Mobile, undo/redo buttons, Save, Publish
* Drag/drop reorder elements within column and between columns via `vue.draggable.next`
* Inline editing: double-click text elements in canvas -> open small editor or edit in right panel.
* Image upload button opens modal -> uploads to `/api/admin/ui/upload` and returns URL to set in element settings.

## SAVE / LOAD FLOW

* Save: POST structure JSON to `/api/admin/ui/structures` -> DB `ui_structures.structure` stores JSON, version increment.
* Publish: optional mark as active for tenant+domain+component -> clear cache key.
* Load: GET structure JSON to populate builder.

## PREVIEW

* Preview button renders structure via `UiRenderer` server-side and loads result in iframe (or client-side Mustache merge for immediate preview).
* Responsive controls set iframe width to Desktop/Tablet/Mobile.

## SECURITY

* Sanitize HTML on render with HTMLPurifier (strip `<script>`).
* Validate uploaded images MIME types and size limits.
* Ensure only admin can access builder API.

## MIGRATION CHANGES (XÓA/THAY THẾ)

* Remove previous `ui_templates` table usage for static templates (or keep for compatibility but ignore in builder). Prefer to create new `ui_structures` table as above.
* Add `ui_structure_revisions` table if revision history required.

## ACCEPTANCE CRITERIA

1. Admin can create new Structure: choose a layout (1/2/3 columns, custom widths), then enter builder canvas.
2. Admin can drag & drop elements into columns, edit element settings (text/image/link/color), reorder elements, delete elements.
3. Image upload works and images stored at `/storage/uibuilder/*`.
4. Save stores full JSON structure to DB `ui_structures.structure`. Version increments on update.
5. Publish sets active mapping for tenant+domain+component and clears cache.
6. FE can call `/api/ui/render?component=footer` and receive sanitized HTML (rendered from structure JSON) ready to inject.
7. Preview responsive (Desktop/Tablet/Mobile) works in builder.
8. All admin APIs are protected by auth.
9. Code uses Vue 3 for builder, Tailwind module CSS (isolated), and is ready to be extracted into separate app.

## DELIVERABLES TO GENERATE (CHO CURSOR)

* Remove or disable old template CRUD view that required raw HTML input.
* Create new migrations, models, controllers, API routes, and blade views for builder.
* Create Vue 3 Vite entry under module resources and components (blocks palette, canvas, settings panel).
* Implement `/api/admin/ui/upload` and renderer service.
* Documentation README explaining structure JSON, how to add new element types, how to render in FE, and commands to migrate/seed.
* Provide 2 example starter layouts (3-column footer, 4-column footer) and sample saved structure JSON for quick testing.

## IMPLEMENTATION NOTES (SUGGESTED LIBS & PATTERNS)

* Vue 3 + Composition API, use `vue-draggable-next` for drag/drop.
* For iframe communication, use postMessage or directly write into iframe contentDocument for preview.
* Use `HTMLPurifier` for sanitizing server-side before sending HTML to FE.
* Use `Cache::put()` / `Cache::forget()` for caching per tenant+domain+component.

## HÃY THỰC HIỆN

Hãy **xóa toàn bộ phần tạo template cũ** và scaffold module UiBuilder mới theo spec ở trên (Elementor-like builder).
Sinh code backend + frontend builder (Blade page mounting Vue app), migration, models, controllers, routes, upload API, renderer service, README, và example structures.
Code rõ comment, chuẩn PSR-12, sẵn sàng plug vào project Laravel hiện tại.

```

---
