156 lines
6.5 KiB
PHP
156 lines
6.5 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
require_once __DIR__ . '/includes/app.php';
|
||
|
||
$metrics = dashboardMetrics();
|
||
$recentRequests = recentLeaveRequests();
|
||
$pendingRequests = pendingLeaveRequests();
|
||
$trend = leaveRequestTrend();
|
||
|
||
renderPageStart(
|
||
'Leave Operations Dashboard',
|
||
'Track leave requests, approvals, and tenant-scoped HR activity for SMB teams.'
|
||
);
|
||
?>
|
||
<section class="hero-panel">
|
||
<div>
|
||
<span class="section-kicker">Today’s workspace</span>
|
||
<h2 class="section-title">A restrained, tenant-scoped HR command center for <?= htmlspecialchars(currentCompanyName()) ?>.</h2>
|
||
<p class="section-copy">This first delivery focuses on one meaningful end-to-end workflow: create leave requests, review them safely inside the active company, and monitor approval health from a single SaaS-style dashboard.</p>
|
||
</div>
|
||
<div class="hero-actions">
|
||
<a href="<?= htmlspecialchars(currentCompanyFilterQuery('/request_leave.php')) ?>" class="btn btn-dark">Start a new leave request</a>
|
||
<a href="<?= htmlspecialchars(currentCompanyFilterQuery('/leave_requests.php')) ?>" class="btn btn-outline-secondary">Review queue</a>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="row g-3 mb-4">
|
||
<div class="col-6 col-xl-3">
|
||
<article class="metric-card">
|
||
<div class="metric-label">Requests</div>
|
||
<div class="metric-value"><?= $metrics['total_requests'] ?></div>
|
||
<p class="metric-footnote">Scoped to current company only.</p>
|
||
</article>
|
||
</div>
|
||
<div class="col-6 col-xl-3">
|
||
<article class="metric-card">
|
||
<div class="metric-label">Pending approvals</div>
|
||
<div class="metric-value"><?= $metrics['pending_requests'] ?></div>
|
||
<p class="metric-footnote">Needs manager action.</p>
|
||
</article>
|
||
</div>
|
||
<div class="col-6 col-xl-3">
|
||
<article class="metric-card">
|
||
<div class="metric-label">Approved days</div>
|
||
<div class="metric-value"><?= $metrics['approved_days'] ?></div>
|
||
<p class="metric-footnote">Deductible leave usage.</p>
|
||
</article>
|
||
</div>
|
||
<div class="col-6 col-xl-3">
|
||
<article class="metric-card">
|
||
<div class="metric-label">Rejected</div>
|
||
<div class="metric-value"><?= $metrics['rejected_requests'] ?></div>
|
||
<p class="metric-footnote">With auditable reason.</p>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="row g-4">
|
||
<div class="col-xl-8">
|
||
<article class="panel-card h-100">
|
||
<div class="panel-head">
|
||
<div>
|
||
<span class="section-kicker">Recent requests</span>
|
||
<h3 class="panel-title">Latest leave activity</h3>
|
||
</div>
|
||
<a href="<?= htmlspecialchars(currentCompanyFilterQuery('/leave_requests.php')) ?>" class="btn btn-outline-secondary btn-sm">See all</a>
|
||
</div>
|
||
|
||
<?php if (!$recentRequests): ?>
|
||
<div class="empty-state">
|
||
<h4>No leave requests yet</h4>
|
||
<p>Create the first request to turn this into a live approval queue.</p>
|
||
<a href="<?= htmlspecialchars(currentCompanyFilterQuery('/request_leave.php')) ?>" class="btn btn-dark btn-sm">Create request</a>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="table-responsive">
|
||
<table class="table align-middle mb-0 hr-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Employee</th>
|
||
<th>Type</th>
|
||
<th>Dates</th>
|
||
<th>Status</th>
|
||
<th class="text-end">Detail</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($recentRequests as $request): ?>
|
||
<tr>
|
||
<td>
|
||
<div class="fw-semibold"><?= htmlspecialchars($request['employee_name']) ?></div>
|
||
<div class="text-secondary small"><?= htmlspecialchars($request['department']) ?></div>
|
||
</td>
|
||
<td><?= htmlspecialchars($request['leave_type']) ?></td>
|
||
<td><?= htmlspecialchars(formatDateLabel($request['start_date'])) ?> → <?= htmlspecialchars(formatDateLabel($request['end_date'])) ?></td>
|
||
<td><span class="badge <?= htmlspecialchars(requestStatusBadgeClass($request['status'])) ?>"><?= htmlspecialchars(ucfirst($request['status'])) ?></span></td>
|
||
<td class="text-end"><a href="<?= htmlspecialchars(currentCompanyFilterQuery('/leave_request.php', ['id' => (int)$request['id']])) ?>" class="btn btn-sm btn-outline-dark">Open</a></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<?php endif; ?>
|
||
</article>
|
||
</div>
|
||
|
||
<div class="col-xl-4">
|
||
<article class="panel-card mb-4">
|
||
<span class="section-kicker">Approval queue</span>
|
||
<h3 class="panel-title">Items requiring attention</h3>
|
||
<?php if (!$pendingRequests): ?>
|
||
<div class="empty-state compact">
|
||
<h4>All clear</h4>
|
||
<p>No pending requests for this tenant.</p>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="queue-list">
|
||
<?php foreach ($pendingRequests as $request): ?>
|
||
<a class="queue-item" href="<?= htmlspecialchars(currentCompanyFilterQuery('/leave_request.php', ['id' => (int)$request['id']])) ?>">
|
||
<div>
|
||
<div class="fw-semibold"><?= htmlspecialchars($request['employee_name']) ?></div>
|
||
<div class="small text-secondary"><?= htmlspecialchars($request['leave_type']) ?> · <?= (int)$request['days_requested'] ?> day(s)</div>
|
||
</div>
|
||
<span class="queue-date"><?= htmlspecialchars(formatDateLabel($request['start_date'])) ?></span>
|
||
</a>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</article>
|
||
|
||
<article class="panel-card">
|
||
<span class="section-kicker">Trend snapshot</span>
|
||
<h3 class="panel-title">Submission volume</h3>
|
||
<?php if (!$trend): ?>
|
||
<div class="empty-state compact">
|
||
<h4>No trend data</h4>
|
||
<p>Recent activity will appear after the first submission.</p>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="trend-list">
|
||
<?php foreach ($trend as $item): ?>
|
||
<div class="trend-row">
|
||
<span><?= htmlspecialchars($item['month_label']) ?></span>
|
||
<div class="trend-bar-wrap">
|
||
<div class="trend-bar" style="width: <?= max(18, min(100, ((int)$item['total']) * 24)) ?>%"></div>
|
||
</div>
|
||
<strong><?= (int)$item['total'] ?></strong>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
<?php renderPageEnd(); ?>
|