Files
a.montask/resources/views/admin/show.blade.php
T
2026-04-25 11:46:02 +00:00

189 lines
10 KiB
PHP
Executable File

<?php
use Morilog\Jalali\Jalalian;
use Carbon\Carbon;
// پیدا کردن نام ماه قبل به تاریخ شمسی (مثلا اگر الان اسفند است، خروجی "بهمن" خواهد بود)
$previousMonthName = Jalalian::now()->subMonths(1)->format('%B');
// محاسبه مجموع کارکرد برای هر کارمند به تفکیک ماه
$employeeTotals = [];
foreach ($data as $employee) {
// تبدیل آبجکت به آرایه در صورت نیاز برای حلقه
$recordsGrouped = is_array($employee->records) ? $employee->records : (array)$employee->records;
$monthlyTotals = [];
foreach ($recordsGrouped as $month => $attendances) {
$tsec = 0;
foreach ($attendances as $attendance) {
// اگر duration موجود باشه استفاده می‌کنیم
if (!empty($attendance->duration)) {
[$h, $m, $s] = explode(':', $attendance->duration);
$tsec += (int)$h * 3600 + (int)$m * 60 + (int)$s;
}
}
$hours = floor($tsec / 3600);
$minutes = floor(($tsec % 3600) / 60);
// ذخیره زمان برای این ماه
$monthlyTotals[$month] = sprintf('%02d:%02d', $hours, $minutes);
}
// ذخیره کل ماه‌ها برای این کارمند
$employeeTotals[$employee->id] = $monthlyTotals;
}
?>
@extends('app')
@section('content')
<div class="container flex flex-col items-center justify-center mx-auto pb-10">
@if(empty($data) || count($data) == 0)
<div class="mt-80 text-gray-500 text-xl font-bold italic">
<h1>اطلاعاتی موجود نمیباشد</h1>
</div>
@else
<div class="flex flex-wrap justify-center gap-2 mt-10 mb-6 max-w-3xl">
@foreach($data as $employee)
<button class="emp-btn px-4 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-cyan-500 hover:text-white transition-colors duration-300 font-bold shadow-sm"
onclick="openEmployee(event, 'emp_{{ $employee->id }}', '{{ $employee->id }}')">
{{ $employee->name }}
</button>
@endforeach
</div>
@foreach($data as $employee)
<div id="emp_{{ $employee->id }}" class="employee-content hidden flex-col items-center justify-center w-full">
<div class="flex justify-between items-center mb-4 w-[350px]">
<h2 class="text-xl font-bold text-cyan-700">{{ $employee->name }}</h2>
<span class="text-xs bg-cyan-50 text-cyan-800 px-3 py-1.5 rounded-full border border-cyan-200 shadow-sm flex items-center gap-1">
<span>کارکرد ماه قبل ({{ $previousMonthName }}):</span>
<strong class="text-sm font-black">{{ $employeeTotals[$employee->id][$previousMonthName] ?? '00:00' }}</strong>
</span>
</div>
@php
$recordsGrouped = is_array($employee->records) ? $employee->records : (array)$employee->records;
@endphp
@if(empty($recordsGrouped))
<div class="my-10 text-gray-500 text-lg font-bold italic">
رکورد ترددی برای این شخص ثبت نشده است.
</div>
@else
<div class="tab rounded-t-2xl max-w-[350px] mx-auto flex overflow-x-auto whitespace-nowrap hide-scrollbar" style="max-width: 350px">
@foreach(array_keys($recordsGrouped) as $month)
<button class="tablinks-{{ $employee->id }} active rounded-t-2xl cursor-pointer px-4 py-2 bg-gray-100 border-b-2 border-transparent hover:bg-gray-200 flex-shrink-0"
onclick="openMonth(event, 'month_{{ $employee->id }}_{{ $month }}', '{{ $employee->id }}')">
{{ $month }}
</button>
@endforeach
</div>
@foreach($recordsGrouped as $month => $records)
<div id="month_{{ $employee->id }}_{{ $month }}" class="tabcontent-{{ $employee->id }} hidden w-[350px] bg-white rounded-b-xl rounded-tl-2xl cursor-default leading-7 shadow-lg border border-gray-100">
<table style="width:100%; border-collapse: collapse; text-align: center">
<thead>
<tr style="border-bottom: 1px solid #ddd; background-color: #f8f9fa;">
<th style="border-right: 1px solid #ddd; padding: 8px 0;">تاریخ</th>
<th style="border-right: 1px solid #ddd;">روز</th>
<th style="border-right: 1px solid #ddd;">ورود</th>
<th style="border-right: 1px solid #ddd;">خروج</th>
<th style="border-right: 1px solid #ddd;">مدت</th>
</tr>
</thead>
<tbody>
@foreach($records as $row)
<tr class="hover:bg-cyan-100 transition-colors" style="border-bottom: 1px solid #ddd;">
<td style="border-right: 1px solid #ddd; padding: 4px 0;">
{{ Jalalian::fromCarbon(\Carbon\Carbon::parse($row->entered_at))->format('m/d') ?? '-' }}
</td>
<td style="border-right: 1px solid #ddd;">
{{ Jalalian::fromCarbon(\Carbon\Carbon::parse($row->entered_at))->format('%A') ?? '-' }}
</td>
<td style="border-right: 1px solid #ddd;">
{{ \Carbon\Carbon::parse($row->entered_at)->format('H:i') ?? '-' }}
</td>
<td style="border-right: 1px solid #ddd;">
{{ $row->exited_at ? \Carbon\Carbon::parse($row->exited_at)->format('H:i') : '-' }}
</td>
<td style="border-right: 1px solid #ddd;">
{{ $row->duration ? \Carbon\Carbon::parse($row->duration)->format('H:i') : '-' }}
</td>
</tr>
@endforeach
<tr>
<td colspan="5" class="bg-cyan-50 font-bold text-gray-700 rounded-b-xl" style="border-top: 2px solid #ddd; text-align: center; padding: 10px 0;">
مجموع کارکرد این ماه: {{ $employeeTotals[$employee->id][$month] ?? '00:00' }}
</td>
</tr>
</tbody>
</table>
</div>
@endforeach
@endif
</div>
@endforeach
@endif
</div>
<style>
/* مخفی کردن اسکرول‌بار برای تب‌های ماه‌ها اگر تعدادشان زیاد شد */
.hide-scrollbar::-webkit-scrollbar { display: none; }
.hide-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
</style>
<script>
function openEmployee(evt, empContainerId, empId) {
let employeeContents = document.getElementsByClassName("employee-content");
for (let i = 0; i < employeeContents.length; i++) {
employeeContents[i].style.display = "none";
}
let empBtns = document.getElementsByClassName("emp-btn");
for (let i = 0; i < empBtns.length; i++) {
empBtns[i].classList.remove("bg-cyan-500", "text-white", "shadow-md");
empBtns[i].classList.add("bg-gray-200", "text-gray-700");
}
document.getElementById(empContainerId).style.display = "flex";
evt.currentTarget.classList.remove("bg-gray-200", "text-gray-700");
evt.currentTarget.classList.add("bg-cyan-500", "text-white", "shadow-md");
let firstMonthTab = document.querySelector("#" + empContainerId + " .tablinks-" + empId);
if (firstMonthTab) {
firstMonthTab.click();
}
}
function openMonth(evt, monthId, empId) {
let tabcontents = document.getElementsByClassName("tabcontent-" + empId);
for (let i = 0; i < tabcontents.length; i++) {
tabcontents[i].style.display = "none";
}
let tablinks = document.getElementsByClassName("tablinks-" + empId);
for (let i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove("bg-white", "border-cyan-500");
tablinks[i].classList.add("bg-gray-100", "border-transparent");
}
document.getElementById(monthId).style.display = "block";
evt.currentTarget.classList.remove("bg-gray-100", "border-transparent");
evt.currentTarget.classList.add("bg-white", "border-cyan-500");
}
document.addEventListener("DOMContentLoaded", function () {
let firstEmployeeBtn = document.querySelector(".emp-btn");
if (firstEmployeeBtn) {
firstEmployeeBtn.click();
}
});
</script>
@endsection