# Centralized Layout System - Education for Life ERP

## Overview

The Centralized Layout System provides a unified, consistent interface across all portals in the EFL ERP system. It includes notification management, global search, role-based portal detection, and consistent UI components.

## Features

### 1. Portal Detection
- Automatically detects user portal based on their role
- Supported portals: admin, finance, inventory, library, procurement, lab, staff
- Each portal has its own title, menu, and permissions

### 2. Notification System
- Real-time notifications with badge counter
- Portal-specific notifications
- Mark as read / Mark all as read functionality
- Auto-refresh every 30 seconds
- Notification types: info, success, warning, danger
- Automatic cleanup of old notifications (30+ days)

### 3. Global Search
- Admin-only feature
- Search across:
  - Users (name, email, username)
  - Companies (name, code)
  - Branches (name, code)
  - Departments (name, code)
  - Inventory items (name, SKU)
- Debounced search (300ms delay)
- Live results dropdown

### 4. User Menu
- Profile dropdown with avatar
- Quick links to profile, settings
- Logout functionality
- Displays user name and role

## Files Created

### Core Files
1. **app/Layout/CentralizedLayout.php** - Main layout class with all helper methods
2. **app/Helpers/NotificationHelper.php** - Notification management helper
3. **app/Layout/Controllers/NotificationController.php** - API controller for notifications
4. **resources/views/layouts/app.blade.php** - Updated centralized layout template

### Routes
- Added to **routes/api.php**:
  - `GET /api/notifications` - Get all notifications
  - `GET /api/notifications/count` - Get unread count
  - `POST /api/notifications/mark-read` - Mark notification as read
  - `POST /api/notifications/mark-all-read` - Mark all as read

## Usage

### Basic Usage

The centralized layout is automatically included when you use `app.blade.php`:

```php
<?php
$title = 'My Page';
$user = $_SESSION['user'] ?? [];

// Sidebar content
ob_start();
?>
<ul class="sidebar-menu">
    <li><a href="/dashboard"><i class="bi bi-speedometer2"></i> Dashboard</a></li>
    <!-- More menu items -->
</ul>
<?php
$sidebar = ob_get_clean();

// Page content
ob_start();
?>
<h1>My Page Content</h1>
<?php
$content = ob_get_clean();

// Include layout
require __DIR__ . '/../layouts/app.blade.php';
```

### Creating Notifications

```php
use App\Helpers\NotificationHelper;

// Create notification for specific user
NotificationHelper::create(
    $userId,
    'New Message',
    'You have received a new message',
    'info',
    '/messages'
);

// Create notification for all admins
NotificationHelper::notifyAllAdmins(
    'System Update',
    'The system will be updated tonight at 10 PM',
    'warning',
    '/admin/settings'
);
```

### Portal Detection

```php
use App\Layout\CentralizedLayout;

// Get current portal
$portal = CentralizedLayout::getCurrentPortal();

// Get portal title
$title = CentralizedLayout::getPortalTitle($portal);

// Check if user can search all
if (CentralizedLayout::canSearchAll()) {
    // Show search box
}
```

### Custom Portal Menus

The `CentralizedLayout::getPortalMenu($portal)` method returns the menu structure for each portal. You can customize menus by editing this method in `app/Layout/CentralizedLayout.php`.

## Database Schema

### Notifications Table

The system will auto-create the `notifications` table if it doesn't exist:

```sql
CREATE TABLE notifications (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NULL,
    title VARCHAR(255) NOT NULL,
    message TEXT NOT NULL,
    type ENUM('info', 'success', 'warning', 'danger') DEFAULT 'info',
    link VARCHAR(500) NULL,
    is_read TINYINT(1) DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_user_id (user_id),
    INDEX idx_is_read (is_read),
    INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

## Customization

### Adding a New Portal

1. Add role mapping in `CentralizedLayout::ROLE_PORTAL_MAP`
2. Add portal title in `CentralizedLayout::PORTAL_TITLES`
3. Add menu structure in `CentralizedLayout::getPortalMenu()`
4. Update notification endpoints if needed

### Styling

All styles are in `app.blade.php` within the `<style>` tag. Key CSS classes:

- `.notification-container` - Notification bell container
- `.notification-dropdown` - Notification dropdown panel
- `.notification-item` - Individual notification
- `.search-container` - Search box container
- `.search-results` - Search results dropdown
- `.user-menu` - User profile menu

### JavaScript Events

The layout includes two main JavaScript modules:

1. **NotificationSystem** - Handles notification loading, marking as read, auto-refresh
2. **SearchSystem** - Handles global search with debouncing

Both are initialized on `DOMContentLoaded`.

## Best Practices

1. **Always use the centralized layout** - Don't create separate layouts per module
2. **Use NotificationHelper** - Don't insert notifications directly into the database
3. **Test permissions** - Use `CentralizedLayout::canSearchAll()` for admin-only features
4. **Clean old notifications** - Run cleanup periodically:
   ```php
   NotificationHelper::deleteOld(30); // Delete read notifications older than 30 days
   ```

## Security Considerations

1. **CSRF Protection** - All POST requests include CSRF token
2. **User ID Validation** - Notifications are user-specific
3. **Admin-only features** - Search is restricted to admin roles
4. **SQL Injection Protection** - All queries use prepared statements
5. **XSS Protection** - All output is HTML-escaped

## Troubleshooting

### Notifications not appearing
- Check if notifications table exists
- Verify user is logged in (`$_SESSION['user']['id']`)
- Check browser console for JavaScript errors
- Verify API endpoint returns data: `/api/notifications`

### Search not working
- Verify user has admin role
- Check if search data is loaded (see browser console)
- Ensure database tables exist (users, companies, etc.)

### Portal detection incorrect
- Check user role in session: `$_SESSION['role']` or `$_SESSION['user']['role']`
- Verify role mapping in `ROLE_PORTAL_MAP`
- Check role format (should be lowercase string)

## Future Enhancements

Possible improvements:

1. **Real-time notifications** - Use WebSockets for instant notifications
2. **Notification preferences** - Let users configure notification types
3. **Advanced search** - Add filters, sorting, pagination
4. **Mobile app** - Create API endpoints for mobile applications
5. **Notification templates** - Create reusable notification templates
6. **Multi-language support** - Internationalize notification messages

## API Documentation

### GET /api/notifications
Returns all notifications for the current user.

**Response:**
```json
{
    "success": true,
    "notifications": [...],
    "count": 10,
    "unread": 3
}
```

### GET /api/notifications/count
Returns unread notification count.

**Response:**
```json
{
    "success": true,
    "count": 3
}
```

### POST /api/notifications/mark-read
Marks a notification as read.

**Parameters:**
- `id` (int) - Notification ID

**Response:**
```json
{
    "success": true,
    "message": "Notification marked as read"
}
```

### POST /api/notifications/mark-all-read
Marks all user notifications as read.

**Response:**
```json
{
    "success": true,
    "message": "All notifications marked as read"
}
```

## Support

For issues or questions:
1. Check this documentation
2. Review error logs in `storage/logs/`
3. Check browser console for JavaScript errors
4. Verify database connection and table structures
