> **SUPERSEDED — 13 Aug 2026.** This document describes the Sneat / Bootstrap 5
> integration, which no longer exists. The frontend runs Tailwind CSS 4 only:
> `bootstrap`, `bootstrap-icons`, `@popperjs/core` and the vendored `src/styles/sneat/`
> tree were all removed, along with the SCSS pipeline. The design system now lives in
> `frontend/src/shared/components/ui/` and its tokens in `frontend/src/styles/tailwind.css`.
>
> Kept for the history of how the frontend got here — do not follow it.

---

# ERPFlow Frontend Template Integration Plan

Sneat Bootstrap 5 admin template integration guide for the ERPFlow React frontend.

**Goal:** Adopt Sneat as the design system with all frontend-related assets living inside `frontend/`. No separate template folder at the repository root.

**Principle:** SCSS + Vite (single build pipeline), React layout port, no jQuery/Gulp. Existing module registry, auth, and API architecture stay unchanged.

---

## Current State

| Layer | Today | Target |
|-------|-------|--------|
| UI | Vanilla Bootstrap 5.3 + minimal custom SCSS | Sneat extended Bootstrap theme |
| Icons | Bootstrap Icons (`bi-*`) | Bootstrap Icons (keep — no menu DB changes) |
| Layout | Custom `d-flex` sidebar + header | Sneat `layout-wrapper` shell |
| Template source | `sneat-1.0.0/` at repo root (temporary) | Copied into `frontend/`, then removed |

---

## Target Directory Structure

```
frontend/
├── src/
│   ├── styles/
│   │   ├── sneat/                    # Sneat SCSS (one-time copy, then owned by us)
│   │   │   ├── core.scss
│   │   │   ├── theme-default.scss
│   │   │   ├── _custom-variables/
│   │   │   ├── fonts/
│   │   │   ├── libs/                 # perfect-scrollbar, etc.
│   │   │   └── pages/                # page-auth.scss, etc.
│   │   ├── erpflow.scss              # Brand overrides (colors, spacing)
│   │   └── app.scss                  # Entry: imports sneat + erpflow
│   ├── assets/
│   │   └── sneat/                    # favicon, illustrations, avatars
│   ├── core/hooks/
│   │   └── useLayoutMenu.ts          # Menu accordion/mobile (replaces menu.js)
│   └── modules/core/components/layout/
│       ├── AppLayout.tsx             # Sneat shell
│       ├── Sidebar.tsx               # Sneat menu structure
│       ├── Header.tsx                # Sneat navbar
│       └── AppBrand.tsx              # Logo component (new)
├── index.html                        # Public Sans font + layout html classes
└── package.json
```

---

## What to Copy from Sneat (One-Time)

| Copy into `frontend/` | Do not copy |
|-----------------------|-------------|
| `scss/` | `html/` (reference only) |
| `fonts/` | `gulpfile.js`, `tasks/`, `build-config.js` |
| `assets/img/` | `jquery`, `js/menu.js`, `assets/js/main.js` |
| `libs/perfect-scrollbar/` (optional) | Sneat `node_modules/` |
| `scss/pages/page-auth.scss` | Entire `sneat-1.0.0/` after migration |

After migration, delete `sneat-1.0.0/` from the repository root.

---

## Key Decisions

### 1. SCSS via Vite (not Gulp pre-build)

Import Sneat SCSS directly in Vite. One `npm run build`, one Docker image, full theme customization via `erpflow.scss`.

Do **not** run Sneat's Gulp pipeline as a separate build step.

### 2. Keep Bootstrap Icons

Sneat demos use Boxicons (`bx-*`). ERPFlow uses Bootstrap Icons (`bi-*`) in navigation, seeders, and forms.

Keeping Bootstrap Icons avoids backend/menu data changes. Sneat look comes from layout classes and SCSS, not icon font.

### 3. No jQuery

Sneat's `menu.js` and `helpers.js` are replaced by React:

- `useLayoutMenu` hook for accordion, mobile toggle, optional Perfect Scrollbar
- Bootstrap 5 JS only where needed (tooltips, modals)

### 4. Single Bootstrap source

Remove `import 'bootstrap/dist/css/bootstrap.min.css'` from `main.tsx`. Load Bootstrap only through Sneat SCSS to avoid style conflicts.

Align Bootstrap version with Sneat SCSS (test `5.1.3` first; adjust if needed).

---

## Implementation Phases

### Phase 0 — Preparation (½ day)

- [ ] Finalize copy list from `sneat-1.0.0/`
- [ ] Confirm icon strategy: Bootstrap Icons
- [ ] Confirm Bootstrap version alignment
- [ ] Remove root `sneat-1.0.0/` after copy

---

### Phase 1 — Theme Foundation (1 day)

**Goal:** Sneat styles load through Vite; app runs without CSS conflicts.

**Tasks**

1. Copy SCSS, fonts, images, and optional libs into `frontend/src/styles/sneat/` and `frontend/src/assets/sneat/`
2. Wire SCSS entry chain:

   ```
   app.scss
     ├── erpflow.scss
     ├── sneat/core.scss
     ├── sneat/theme-default.scss
     └── sneat/pages/page-auth.scss
   ```

3. Update `main.tsx` — remove vanilla Bootstrap CSS; import `./styles/app.scss`
4. Update `index.html` — Public Sans font; `class="light-style layout-menu-fixed"` on `<html>`
5. Add Vite SCSS `includePaths` if import paths need it
6. Add dependencies: `@popperjs/core`, `perfect-scrollbar` (optional); align `bootstrap` version

**Files**

| File | Action |
|------|--------|
| `frontend/src/styles/sneat/**` | Add (copied) |
| `frontend/src/styles/erpflow.scss` | Add |
| `frontend/src/styles/app.scss` | Update |
| `frontend/src/main.tsx` | Update imports |
| `frontend/index.html` | Font + html classes |
| `frontend/vite.config.ts` | SCSS options if needed |
| `frontend/package.json` | Dependencies |

**Acceptance:** `npm run dev` works; Sneat colors and typography visible; no duplicate Bootstrap styles.

---

### Phase 2 — Auth Pages (½ day)

**Goal:** Login page matches Sneat auth layout.

**Reference:** `sneat-1.0.0/html/auth-login-basic.html`

**Files**

| File | Change |
|------|--------|
| `frontend/src/modules/auth/pages/Login.tsx` | `authentication-wrapper`, `authentication-inner`, Sneat card |
| `frontend/src/modules/core/components/layout/AppBrand.tsx` | New — logo + "ERPFlow" text |

**Unchanged:** `AuthContext`, `authApi`, form logic, error handling.

**Acceptance:** Login looks like Sneat demo; login flow still works.

---

### Phase 3 — App Shell (1–1.5 days)

**Goal:** Authenticated layout uses Sneat structure.

**Reference:** `sneat-1.0.0/html/index.html` (layout wrapper, menu, navbar)

**Target `AppLayout` structure**

```tsx
<div className="layout-wrapper layout-content-navbar">
  <div className="layout-container">
    <Sidebar />
    <div className="layout-page">
      <Header />
      <div className="content-wrapper">
        <div className="container-xxl flex-grow-1 container-p-y">
          <Breadcrumb />
          <Outlet />
        </div>
      </div>
    </div>
  </div>
</div>
```

**Sidebar menu markup**

- `layout-menu menu-vertical menu bg-menu-theme`
- `menu-inner`, `menu-item`, `menu-link`, `menu-toggle`, `menu-sub`, `menu-header`
- `NavLink` → `active` on current route
- Nested items → `open` + accordion state

**New hook:** `useLayoutMenu.ts` — mobile toggle, submenu accordion, optional Perfect Scrollbar.

**Header:** `layout-navbar navbar navbar-expand-xl navbar-detached bg-navbar-theme`

**Files**

| File | Action |
|------|--------|
| `AppLayout.tsx` | Restructure |
| `Sidebar.tsx` | Sneat menu markup |
| `Header.tsx` | Sneat navbar |
| `Breadcrumb.tsx` | Sneat breadcrumb style (optional) |
| `useLayoutMenu.ts` | New |

**Acceptance:** Shell matches Sneat; dynamic navigation works; responsive on mobile.

---

### Phase 4 — Shared Components (1 day)

**Goal:** Update once; all pages benefit.

**References:** `tables-basic.html`, `ui-modals.html`, `forms-basic-inputs.html`, `cards-basic.html`

| Component | Sneat pattern |
|-----------|---------------|
| `PageHeader.tsx` | Title area + actions |
| `DataTable.tsx` | `card` → `table-responsive text-nowrap` → `table` |
| `FormInput.tsx` | Sneat form-control |
| `FormSelect.tsx` | Sneat form-select |
| `Modal.tsx` | Sneat modal classes |
| `ConfirmDialog.tsx` | Sneat confirm modal |

**Acceptance:** List pages (e.g. `UserList`, `RoleList`) use Sneat card + table look.

---

### Phase 5 — Core Pages (½ day)

| Page | Reference | Priority |
|------|-----------|----------|
| `Dashboard.tsx` | `index.html` stat cards | High |
| `EmployeeHomePage.tsx` | Card pattern | Medium |
| `EmployeeAttendancePage.tsx` | Table pattern | Medium |

**Acceptance:** Dashboard uses Sneat-style stat cards.

---

### Phase 6 — Platform Module Pages (2–3 days)

**Batch A — List pages**

`UserList`, `RoleList`, `MenuList`, `ModuleList`, `ActionList`, `ApprovalWorkflowList`, `ApprovalRequestList`, `ActivityLogList`

Pattern: `PageHeader` + `card` + `DataTable` + action buttons.

**Batch B — Form pages**

`RoleForm`, `MenuForm`, `ModuleForm`, `ActionForm`, `ApprovalWorkflowForm`

Pattern: `card` + vertical form (`form-layouts-vertical.html`).

**Batch C — Complex pages**

`PermissionMatrixPage`, `MenuTreeBuilder`, `WorkflowStepBuilder`, `ApprovalRequestDetail`, `ApprovalSettingsPage`, `UserRoles`, `UserPermissionOverrides`

**Acceptance:** All platform pages consistent; functionality unchanged.

---

### Phase 7 — Polish & Cleanup (1 day)

- [ ] Error / maintenance page patterns
- [ ] Loading states (Sneat spinners)
- [ ] Empty states
- [ ] Favicon from `assets/sneat/`
- [ ] Delete root `sneat-1.0.0/`
- [ ] Update `frontend/README.md` with theme notes
- [ ] Verify `npm run build` and Docker production build

---

## Timeline

| Phase | Duration | Cumulative |
|-------|----------|------------|
| 0 — Preparation | ½ day | 0.5 day |
| 1 — Theme foundation | 1 day | 1.5 days |
| 2 — Login | ½ day | 2 days |
| 3 — App shell | 1–1.5 days | 3.5 days |
| 4 — Shared components | 1 day | 4.5 days |
| 5 — Core pages | ½ day | 5 days |
| 6 — Platform pages | 2–3 days | 7–8 days |
| 7 — Polish & cleanup | 1 day | **8–9 days** |

**MVP (usable Sneat UI):** Phases 0–3 (~3.5 days)  
**Full rollout:** ~8–9 days

**Recommended order:** Phase 1 → 2 → 3 → 4 → 5 → 6 → 7

---

## Sneat HTML → React Mapping

| Sneat reference | ERPFlow file |
|-----------------|--------------|
| `html/auth-login-basic.html` | `modules/auth/pages/Login.tsx` |
| `html/index.html` (layout) | `AppLayout`, `Sidebar`, `Header` |
| `html/index.html` (dashboard) | `modules/core/pages/Dashboard.tsx` |
| `html/tables-basic.html` | `shared/components/common/DataTable.tsx` |
| `html/forms-basic-inputs.html` | `FormInput`, `FormSelect` |
| `html/ui-modals.html` | `Modal`, `ConfirmDialog` |
| `html/pages-misc-error.html` | Future error page |

---

## Risks & Mitigation

| Risk | Mitigation |
|------|------------|
| Bootstrap 5.1 vs 5.3 conflict | Test in Phase 1; align package version |
| SCSS import path errors | Vite `includePaths`; fix relative imports |
| Broken menu accordion | `useLayoutMenu` hook; test nested routes |
| Icon visual mismatch | Accept Bootstrap Icons or migrate to Boxicons later |
| Future Sneat updates | Keep `styles/sneat/` isolated; override in `erpflow.scss` |

---

## Definition of Done

- [ ] No dependency on root `sneat-1.0.0/`
- [ ] Single `npm run dev` / `npm run build` for frontend
- [ ] Login + app shell match Sneat look
- [ ] Dynamic sidebar navigation works
- [ ] Shared components follow Sneat patterns
- [ ] Auth, API, and module registry logic unchanged
- [ ] Docker production build passes

---

## What Not to Do

1. Do not run Sneat Gulp dev server as the ERPFlow frontend
2. Do not load Sneat CSS and `bootstrap.min.css` together
3. Do not keep `sneat-1.0.0/` at repo root after migration
4. Do not port all 40+ Sneat demo HTML pages — only patterns in use
5. Do not import jQuery for the sidebar menu

---

## License

Sneat Free is [MIT licensed](https://github.com/themeselection/sneat-html-admin-template-free/blob/master/LICENSE.md) (ThemeSelection). Keep `LICENSE` attribution if required by your compliance process when copying SCSS/assets into `frontend/`.
