# Fix: ModalBuilder Not Available Error - 2025-10-10

## Problem
The `PayrollTimeClockHandler.js` was attempting to use `window.ModalBuilder.buildAndOpenModal()` which resulted in the error:
```
ModalBuilder not available
```

## Root Cause
The application doesn't expose `ModalBuilder` directly to the window object. Instead, modals should be opened using the `ModuleLoader` class with its `loadDynamic()` method.

## Solution
Updated `PayrollTimeClockHandler.js` to use the correct pattern:

### Before (Broken)
```javascript
// Attempted to use non-existent ModalBuilder API
if (window.ModalBuilder) {
    await window.ModalBuilder.buildAndOpenModal(modalConfig);
} else {
    console.error('ModalBuilder not available');
}
```

### After (Fixed)
```javascript
import { ModalBuilder } from 'core/modalbuilder';

// Use ModalBuilder directly to render modal
const modalConfig = {
    title: `Time Clock Details - ${record.name}`,
    header: [],
    body: [...],
    footer: [...]
};

const builder = new ModalBuilder(modalConfig, record);
await builder.render('#module-modal');
```

## Changes Made

### File: `FrontEnd/js/modules/PayrollTimeClockHandler.js`

1. **Added Import**:
   ```javascript
   import { ModalBuilder } from 'core/modalbuilder';
   ```
   Note: Import path must be lowercase to match Dashboard.php import map

2. **Updated `viewTimeClockDetails()` method**:
   - Simplified modal config structure (removed wrapper object)
   - Use `new ModalBuilder(modalConfig, record)` to instantiate builder
   - Call `await builder.render('#module-modal')` to render the modal
   - Added proper error handling with try/catch

3. **Updated `viewTimeClockGpsMap()` method**:
   - Applied same pattern as `viewTimeClockDetails()`
   - Uses `ModalBuilder` class directly for dynamic modal rendering

## How ModalBuilder Works

The `ModalBuilder` class is used for rendering modals with dynamic configurations:

```javascript
const modalConfig = {
    title: 'Modal Title',
    header: [ /* header elements */ ],
    body: [ /* body elements */ ],
    footer: [ /* footer buttons */ ],
    mapLibraries: { /* optional map config */ }
};

const builder = new ModalBuilder(modalConfig, record);
await builder.render('#module-modal');
```

The `ModalBuilder`:
1. Takes the configuration and optional record data
2. Renders the modal structure (title, header, body, footer)
3. Processes all element types (tables, forms, maps, etc.)
4. Opens the modal in the specified selector (typically `#module-modal`)
5. Handles cleanup when the modal is closed

## Reference Pattern

**ModuleLoader** - For loading module definitions from the database:
```javascript
// From FrontEnd/js/modules/Dashboard.js
const loader = new ModuleLoader(modName);
await loader.load();  // Fetches config from 'modules' table
```

**ModalBuilder** - For rendering modals with dynamic configurations:
```javascript
// For dynamic modals not stored in database
const builder = new ModalBuilder(modalConfig, record);
await builder.render('#module-modal');
```

## Testing

Test both functions:

1. **View Details Button**:
   - Open Payroll module
   - Click "View Details" on any employee row
   - Should open a modal with time clock entries

2. **View GPS Map Button**:
   - Open Payroll module
   - Click "View GPS Map" on any employee row
   - Should open a modal with GPS tracking map

## Files Modified

- `FrontEnd/js/modules/PayrollTimeClockHandler.js` - Fixed modal opening logic
- `migrations/20251010_PAYROLL_MODULE_CHANGES.md` - Updated documentation

## Related Documentation

- `docs/frontend/ModalBuilder.md` - ModalBuilder JSON format and integration
- `FrontEnd/js/core/ModuleLoader.js` - ModuleLoader class implementation
- `AGENTS.md` - Project architecture guidelines

## Deployment Status

- ✅ Code fixed
- ✅ Documentation updated
- 🔲 Needs testing in UI
- 🔲 Ready for commit

## Error Prevention

To avoid similar issues in the future:

1. **Use `ModuleLoader`** for modals defined in the `modules` table
2. **Use `ModalBuilder`** directly for dynamic modals not stored in database
3. **Never access `window.ModalBuilder`** - it's not exposed globally
4. **Check existing code patterns** before implementing modal opening
5. **Import from correct paths**: `import { ModalBuilder } from 'core/modalbuilder'`
