Updated ERP with new modules and features
This commit is contained in:
200
resources/views/management/index.blade.php
Normal file
200
resources/views/management/index.blade.php
Normal file
@@ -0,0 +1,200 @@
|
||||
@extends('layouts.masterbeta')
|
||||
|
||||
@section('title', 'Click ERP - Management Dashboard')
|
||||
|
||||
@section('breadcrumbs')
|
||||
<a href="{{ url('/') }}" class="text-secondary text-decoration-none"><i class="bi bi-house me-2"></i></a>
|
||||
<i class="bi bi-chevron-right text-secondary me-2" style="font-size: 0.8rem;"></i>
|
||||
<span class="fw-bold" style="font-size: 0.95rem;">Management Dashboard</span>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h4 class="fw-bold mb-1">Management Hub</h4>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Centralized oversight for leave and reports</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-light-subtle shadow-sm mb-4">
|
||||
<div class="card-header bg-white py-3 border-bottom d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-3">
|
||||
<!-- Tabs Navigation -->
|
||||
<ul class="nav nav-tabs card-header-tabs m-0" id="managementTabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active fw-bold text-dark" id="leaves-tab" data-bs-toggle="tab" data-bs-target="#leaves-pane" type="button">
|
||||
<i class="bi bi-calendar-event text-primary me-1"></i> Leave Approvals
|
||||
@if($pendingLeaves->count() > 0)
|
||||
<span class="badge bg-danger rounded-pill ms-1">{{ $pendingLeaves->count() }}</span>
|
||||
@endif
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link fw-bold text-dark" id="reports-tab" data-bs-toggle="tab" data-bs-target="#reports-pane" type="button">
|
||||
<i class="bi bi-journal-text text-primary me-1"></i> Staff Reports
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-body tab-content bg-light p-4" id="managementTabsContent">
|
||||
|
||||
<!-- TAB 1: LEAVE MANAGEMENT -->
|
||||
<div class="tab-pane fade show active" id="leaves-pane" role="tabpanel">
|
||||
<h6 class="fw-bold mb-3 text-secondary">Pending Requests</h6>
|
||||
<div class="table-responsive bg-white border rounded shadow-sm">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light text-secondary" style="font-size: 0.85rem;">
|
||||
<tr>
|
||||
<th class="ps-3">Staff Member</th>
|
||||
<th>Leave Type</th>
|
||||
<th>Duration</th>
|
||||
<th>Requested On</th>
|
||||
<th class="text-end pe-3">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($pendingLeaves as $leave)
|
||||
<tr>
|
||||
<td class="ps-3 fw-bold text-dark">{{ $leave->user->name ?? 'N/A' }}</td>
|
||||
<td><span class="badge bg-info bg-opacity-10 text-info">{{ $leave->leave_type ?? 'Annual' }}</span></td>
|
||||
<td class="text-secondary small">
|
||||
{{ \Carbon\Carbon::parse($leave->start_date)->format('d M') }} - {{ \Carbon\Carbon::parse($leave->end_date)->format('d M Y') }}
|
||||
<br><span class="fw-medium text-dark">{{ $leave->total_days }} days</span>
|
||||
</td>
|
||||
<td class="text-secondary small">{{ $leave->created_at->format('d M Y') }}</td>
|
||||
<td class="text-end pe-3">
|
||||
<button class="btn btn-sm btn-success fw-bold px-3 btn-action-leave" data-id="{{ $leave->id }}" data-status="Approved">Approve</button>
|
||||
<button class="btn btn-sm btn-outline-danger fw-bold px-3 ms-1 btn-action-leave" data-id="{{ $leave->id }}" data-status="Rejected">Reject</button>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="5" class="text-center py-5 text-muted small">
|
||||
<i class="bi bi-check2-circle fs-3 d-block mb-2 text-success"></i> All caught up. No pending leave requests.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB 2: DAILY REPORTS TRACKING -->
|
||||
<div class="tab-pane fade" id="reports-pane" role="tabpanel">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6 class="fw-bold text-secondary mb-0">Report Submission Metrics</h6>
|
||||
<form class="d-flex gap-2" method="GET" action="{{ route('management.index') }}">
|
||||
<!-- Keeps the tab active on reload -->
|
||||
<input type="hidden" name="active_tab" value="reports-pane">
|
||||
<input type="date" name="start_date" class="form-control form-control-sm" value="{{ $startDate }}" required>
|
||||
<input type="date" name="end_date" class="form-control form-control-sm" value="{{ $endDate }}" required>
|
||||
<button type="submit" class="btn btn-sm btn-primary fw-bold">Filter</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive bg-white border rounded shadow-sm">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light text-secondary" style="font-size: 0.85rem;">
|
||||
<tr>
|
||||
<th class="ps-3">Staff Member</th>
|
||||
<th>Designation</th>
|
||||
<th>Reports Submitted</th>
|
||||
<th class="text-end pe-3">Performance (Approx)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($staffReports as $staff)
|
||||
@php
|
||||
// Calculate working days assuming 5-day work week roughly (can be refined based on actual business logic)
|
||||
$start = \Carbon\Carbon::parse($startDate);
|
||||
$end = \Carbon\Carbon::parse($endDate);
|
||||
$workDays = max($start->diffInDaysFiltered(function (Carbon\Carbon $date) {
|
||||
return $date->isWeekday();
|
||||
}, $end), 1); // Avoid division by zero
|
||||
|
||||
$completionPercentage = min(round(($staff->daily_reports_count / $workDays) * 100), 100);
|
||||
$barColor = $completionPercentage >= 80 ? 'bg-success' : ($completionPercentage >= 50 ? 'bg-warning' : 'bg-danger');
|
||||
@endphp
|
||||
<tr>
|
||||
<td class="ps-3 fw-bold text-dark">
|
||||
<i class="bi bi-person-circle text-secondary me-2"></i>{{ $staff->name }}
|
||||
</td>
|
||||
<td class="text-secondary small">{{ $staff->designation ?? 'Staff' }}</td>
|
||||
<td>
|
||||
<span class="badge bg-primary rounded-pill px-3">{{ $staff->daily_reports_count }}</span>
|
||||
<span class="text-muted small ms-1">/ ~{{ $workDays }} expected</span>
|
||||
</td>
|
||||
<td class="text-end pe-3" style="width: 25%;">
|
||||
<div class="d-flex align-items-center justify-content-end">
|
||||
<span class="fw-bold me-2" style="font-size: 0.8rem;">{{ $completionPercentage }}%</span>
|
||||
<div class="progress flex-grow-1" style="height: 6px; max-width: 100px;">
|
||||
<div class="progress-bar {{ $barColor }}" role="progressbar" style="width: {{ $completionPercentage }}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Keep active tab on reload if returning from a filter submission
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const activeTab = urlParams.get('active_tab');
|
||||
if (activeTab) {
|
||||
$('.nav-tabs button[data-bs-target="#' + activeTab + '"]').tab('show');
|
||||
}
|
||||
|
||||
// Handle Leave Approval / Rejection
|
||||
$('.btn-action-leave').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
let leaveId = $(this).data('id');
|
||||
let actionStatus = $(this).data('status');
|
||||
let confirmColor = actionStatus === 'Approved' ? '#198754' : '#dc3545';
|
||||
|
||||
Swal.fire({
|
||||
title: `Mark as ${actionStatus}?`,
|
||||
text: `This will update the staff member's leave request.`,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: confirmColor,
|
||||
confirmButtonText: `Yes, ${actionStatus}`
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
url: "{{ url('management/leaves') }}/" + leaveId,
|
||||
type: 'POST',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}',
|
||||
_method: 'PUT',
|
||||
status: actionStatus
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Updated',
|
||||
text: response.message,
|
||||
timer: 1500,
|
||||
showConfirmButton: false
|
||||
}).then(() => location.reload());
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
Swal.fire('Error', 'Could not update the leave status.', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
Reference in New Issue
Block a user