# JavaScript Module Source Directory

This directory contains the source files for Vite-bundled JavaScript modules.

## Vendor Bundle

The `vendor.js` entry is special - it's built as an **IIFE** (not ES module) and loaded
synchronously in `<head>` so legacy scripts can depend on jQuery and Bootstrap being
available immediately.

**Bundled Libraries:**
- jQuery 3.7.x (`window.$`, `window.jQuery`)
- jQuery Migrate 3.x (warns about deprecated API usage)
- Bootstrap 5.3.x (`window.bootstrap`)
- Popper.js (`window.Popper`)
- Bootstrap Select 1.13.x (`$.fn.selectpicker`)
- DataTables 2.x (`$.fn.DataTable`, `window.DataTable`)
  - Includes: Buttons, Responsive, Select extensions

**Output Files:**
- `vendor.js` - JavaScript bundle (~410 KB, ~127 KB gzipped)
- `buyerkiosk-web.css` - CSS for Bootstrap Select + DataTables (~31 KB)

**Build Command:**
```bash
npm run build:vendor  # Build vendor.js only
npm run build         # Build vendor + all modules
```

**Template Usage:**
```html
<!-- In <head> - CSS first, then JS -->
<link rel="stylesheet" href="/js/dist/buyerkiosk-web.css">
<script src="/js/dist/vendor.js"></script>
```

## Entry Point Convention

Each `.js` file in the root of this directory becomes a separate Vite entry point:

```
resources/js/
├── workspace.js      → Entry: "workspace"
├── admin.js          → Entry: "admin"
├── checkout.js       → Entry: "checkout"
└── components/       → Shared modules (not entry points)
    └── modal.js
```

## Usage in Templates

Use the Twig helpers to include bundled assets:

```twig
{# In <head> for CSS (prevents FOUC) #}
{{ vite_styles('workspace') }}

{# At end of <body> for JS #}
{{ vite_scripts('workspace') }}
```

## Template Insertion Points

### Workspace Templates

**CSS (in `<head>`):**
- File: `userfrosting/templates/themes/default/workspace/layouts/workspace-head.html`
- Location: After line ~107 (after admin-theme.min.css)
- Look for: `{# ========== VITE BUNDLED STYLES ========== #}`

**JS (at end of `<body>`):**
- File: `userfrosting/templates/themes/default/workspace/layouts/workspace-foot.html`
- Location: After line ~122 (after workspace.js)
- Look for: `{# ========== VITE BUNDLED SCRIPTS ========== #}`

### Other Templates

For other page templates, follow the same pattern:
1. `vite_styles()` goes in `<head>` after other CSS
2. `vite_scripts()` goes at end of `<body>` after legacy scripts

## Build Commands

```bash
# Development with HMR (Hot Module Replacement)
npm run dev

# Production build (commits to public_html/js/dist/)
npm run build

# Preview production build locally
npm run preview
```

## Import Conventions

Use the `@` alias for clean imports:

```javascript
// Instead of: import { modal } from '../../components/modal.js'
import { modal } from '@/components/modal.js';
```

## Hybrid Loading Notes

- Legacy scripts in `public_html/js/` continue to work unchanged
- Bundled modules can read globals from `window` (if legacy scripts run first)
- To expose module APIs to legacy code, attach to `window` explicitly:
  ```javascript
  window.MyModule = { init: () => { ... } };
  ```

## Dev Server Mode

Enable dev server mode for HMR during local development:

1. Add to `.env`:
   ```
   VITE_DEV_SERVER_ENABLED=true
   VITE_DEV_SERVER_URL=http://localhost:5173
   ```

2. Start the dev server:
   ```bash
   npm run dev
   ```

3. Refresh your browser - HMR will now update modules without page reload.

**Note:** Dev server mode is **disabled by default** in production. The `VITE_DEV_SERVER_ENABLED` environment variable must be explicitly set to `true`.

## Committed Artifacts

This project uses a "committed artifacts" deployment model:

- `public_html/js/dist/` build outputs are committed to git
- No Node.js required on production servers
- `manifest.json` maps entry names to hashed filenames

### When to Rebuild

Run `npm run build` and commit the changes when:
1. Adding or modifying any file in `resources/js/`
2. Adding new npm dependencies used in bundled code
3. Updating `vite.config.js`

### Files to Commit

After running `npm run build`, commit:
- `public_html/js/dist/` (all generated files)
- `package.json` (if dependencies changed)
- `package-lock.json` (if dependencies changed)

## Syncfusion EJ2

The `syncfusion.js` entry provides the full Syncfusion Essential JS 2 suite.

### License Key Setup

1. Add to your `.env` file:
   ```
   SYNCFUSION_LICENSE=your-license-key-here
   ```

2. Pass to templates (in your controller/route):
   ```php
   $app->render('page.html', [
       'syncfusion_license' => $_ENV['SYNCFUSION_LICENSE'] ?? '',
   ]);
   ```

3. The license is injected via `<script>window.SYNCFUSION_LICENSE = '...';</script>`

### Usage in JavaScript

All components are exposed on `window.ej`:

```javascript
// Create a Grid
const grid = new ej.grids.Grid({
  dataSource: myData,
  columns: [
    { field: 'id', headerText: 'ID' },
    { field: 'name', headerText: 'Name' },
  ],
});
grid.appendTo('#grid-container');

// Create a Chart
const chart = new ej.charts.Chart({
  series: [{ type: 'Line', dataSource: data }],
});
chart.appendTo('#chart-container');

// Use DataManager for API calls
const dm = new DataManager({
  url: '/api/data',
  adaptor: new ej.data.UrlAdaptor(),
});
```

### Available Namespaces

- `ej.grids` - Grid, Page, Sort, Filter, etc.
- `ej.schedule` - Schedule, Day, Week, Month, etc.
- `ej.charts` - Chart, LineSeries, BarSeries, etc.
- `ej.inputs` - TextBox, NumericTextBox, etc.
- `ej.dropdowns` - DropDownList, MultiSelect, etc.
- `ej.calendars` - DatePicker, DateTimePicker, etc.
- `ej.buttons` - Button, CheckBox, Switch, etc.
- `ej.navigations` - Tab, Menu, Sidebar, etc.
- `ej.popups` - Dialog, Tooltip, Spinner
- `ej.data` - DataManager, Query, Adaptors
