equest for leave

This commit is contained in:
2026-07-26 10:49:48 +03:30
parent c54038d986
commit 280d2748f9
9 changed files with 608 additions and 11 deletions
+56
View File
@@ -11,6 +11,62 @@ $usersChunked = $users->chunk(3);
@section('content')
<div class="container w-full flex flex-col items-center">
@if(isset($leaveRequests) && $leaveRequests->isNotEmpty())
<div class="ui-requests-card flex flex-col items-center w-full max-w-[350px] mb-4">
<p>درخواست‌های مرخصی</p>
<div class="ui-table-wrap w-full pt-2">
<table class="w-full table-auto text-sm">
<thead>
<tr>
<th class="px-2 py-2">کارمند</th>
<th class="px-2 py-2">نوع</th>
<th class="px-2 py-2">بازه</th>
<th class="px-2 py-2">وضعیت</th>
</tr>
</thead>
<tbody>
@foreach($leaveRequests as $leave)
@php
$ownerName = $leave->user->name ?? $leave->user_identity;
$fromJ = \App\Support\JalaliHelper::format($leave->date_from, 'Y/m/d');
$toJ = \App\Support\JalaliHelper::format($leave->date_to, 'Y/m/d');
if ($leave->type === 'daily') {
$range = $fromJ === $toJ ? $fromJ : "{$fromJ} تا {$toJ}";
} else {
$tf = substr((string) $leave->time_from, 0, 5);
$tt = substr((string) $leave->time_to, 0, 5);
$range = "{$fromJ}<br>{$tf}–{$tt}";
}
@endphp
<tr>
<td class="px-2 py-2 border">{{ $ownerName }}</td>
<td class="px-2 py-2 border">{{ $leave->type === 'daily' ? 'روزانه' : 'ساعتی' }}</td>
<td class="px-2 py-2 border">{!! $range !!}</td>
<td class="px-2 py-2 border">
@if($leave->reason)
<p class="text-xs mb-1 opacity-80">{{ $leave->reason }}</p>
@endif
<form method="post" action="{{ route('admin.leave.decide') }}" class="inline">
@csrf
<input type="hidden" name="leave_id" value="{{ $leave->id }}">
<input type="hidden" name="update" value="approve">
<button type="submit" class="ui-btn-approve">تایید</button>
</form>
<form method="post" action="{{ route('admin.leave.decide') }}" class="inline">
@csrf
<input type="hidden" name="leave_id" value="{{ $leave->id }}">
<input type="hidden" name="update" value="reject">
<button type="submit" class="ui-btn-reject">رد</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
@if(!collect($reqs)->pluck('attendances')->flatten()->isEmpty())
<div class="ui-requests-card flex flex-col items-center w-full max-w-[350px]">
<p>درخواست ها</p>
+150 -9
View File
@@ -82,19 +82,25 @@ if (!empty($user->tasks)) {
<div id="output" class="text-red-500 text-sm mt-2 text-center"></div>
<div class="flex justify-flex max-w-[240px]" style="align-items: center;">
<div class="flex justify-flex max-w-[240px] flex-wrap gap-2" style="align-items: center;">
<button type="button"
class="w-1/2 p-2 text-sm text-white text-center rounded-xl bg-cyan-500 hover:bg-cyan-600 cursor-pointer"
class="w-[calc(50%-4px)] p-2 text-sm text-white text-center rounded-xl bg-cyan-500 hover:bg-cyan-600 cursor-pointer"
onclick="openModal('ثبت روز کاری جدید', 'new')">
ثبت روز کاری
</button>
<button type="button" id="breakAttendance"
class="w-1/2 p-2 text-sm text-white text-center rounded-xl bg-cyan-500 hover:bg-cyan-600
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 cursor-pointer mx-auto"
class="w-[calc(50%-4px)] p-2 text-sm text-white text-center rounded-xl bg-cyan-500 hover:bg-cyan-600
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 cursor-pointer"
href="">
استراحت
</button>
<button type="button"
class="w-full p-2 text-sm text-white text-center rounded-xl bg-teal-500 hover:bg-teal-600 cursor-pointer"
onclick="openLeaveModal()">
درخواست مرخصی
</button>
</div>
<button type="button" id="tasksBtn"
class="text-white rounded-xl py-2 px-4 max-w-60 self-center bg-cyan-500 hover:bg-cyan-700 cursor-pointer w-full"
@@ -120,11 +126,19 @@ if (!empty($user->tasks)) {
{{$user->name}}
</label>
<button type="button"
class="w-1/2 p-2 text-sm text-white text-center rounded-xl bg-cyan-500 hover:bg-cyan-600 cursor-pointer"
onclick="openModal('ثبت روز کاری جدید', 'new')">
ثبت روز کاری
</button>
<div class="flex w-full max-w-[240px] flex-wrap gap-2 justify-center">
<button type="button"
class="w-[calc(50%-4px)] p-2 text-sm text-white text-center rounded-xl bg-cyan-500 hover:bg-cyan-600 cursor-pointer"
onclick="openModal('ثبت روز کاری جدید', 'new')">
ثبت روز کاری
</button>
<button type="button"
class="w-[calc(50%-4px)] p-2 text-sm text-white text-center rounded-xl bg-teal-500 hover:bg-teal-600 cursor-pointer"
onclick="openLeaveModal()">
درخواست مرخصی
</button>
</div>
</div>
@@ -403,6 +417,70 @@ if (!empty($user->tasks)) {
</div>
{{-- Leave Request Modal --}}
<div id="leave-modal-container"
class="ui-modal-backdrop centered hidden">
<div class="ui-modal-panel max-w-sm w-full">
<h2 class="ui-title">درخواست مرخصی</h2>
<p class="ui-subtitle">نوع و بازه مرخصی را مشخص کنید</p>
<form method="post" action="{{ route('leave.store') }}" class="flex flex-col gap-3 items-stretch px-2"
onsubmit="return confirm('درخواست مرخصی ارسال شود؟')">
@csrf
<div class="flex gap-2 justify-center">
<label class="flex items-center gap-1 text-sm cursor-pointer">
<input type="radio" name="type" value="daily" checked onchange="toggleLeaveType()">
روزانه
</label>
<label class="flex items-center gap-1 text-sm cursor-pointer">
<input type="radio" name="type" value="hourly" onchange="toggleLeaveType()">
ساعتی
</label>
</div>
<div id="leave-daily-fields" class="flex flex-col gap-2">
<label class="text-sm">از تاریخ</label>
<input type="text" name="date_from" id="leave_date_from"
class="leave-datepicker form-control border p-2 rounded" placeholder="تاریخ شروع" readonly>
<label class="text-sm">تا تاریخ</label>
<input type="text" name="date_to" id="leave_date_to"
class="leave-datepicker form-control border p-2 rounded" placeholder="تاریخ پایان" readonly>
</div>
<div id="leave-hourly-fields" class="flex flex-col gap-2" style="display:none;">
<label class="text-sm">تاریخ</label>
<input type="text" name="date" id="leave_date"
class="leave-datepicker form-control border p-2 rounded" placeholder="تاریخ" readonly>
<label class="text-sm">از ساعت</label>
<div class="input-group clockpicker border-2 border-gray-300 rounded-lg">
<input type="text" name="time_from" id="leave_time_from"
class="form-control cursor-default p-2 w-full" placeholder="08:30" readonly>
</div>
<label class="text-sm">تا ساعت</label>
<div class="input-group clockpicker border-2 border-gray-300 rounded-lg">
<input type="text" name="time_to" id="leave_time_to"
class="form-control cursor-default p-2 w-full" placeholder="12:00" readonly>
</div>
</div>
<label class="text-sm">دلیل (اختیاری)</label>
<textarea name="reason" rows="2" class="border p-2 rounded text-sm" placeholder="توضیح کوتاه..."></textarea>
<div class="flex gap-2 justify-center mt-2">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white rounded p-2 w-[70%]">
ارسال درخواست
</button>
<button type="button" class="bg-gray-400 hover:bg-gray-500 text-white rounded p-2 w-[30%]"
onclick="closeLeaveModal()">
بستن
</button>
</div>
</form>
</div>
</div>
{{-- START TASK MODAL --}}
<div id="taskModal"
class="ui-modal-backdrop hidden"
@@ -1065,6 +1143,69 @@ if (!empty($user->tasks)) {
document.getElementById('modal-container').classList.add('hidden');
}
function openLeaveModal() {
document.getElementById('leave-modal-container').classList.remove('hidden');
toggleLeaveType();
if (!window._leavePickersReady) {
$('.leave-datepicker').persianDatepicker({
format: "YYYY/MM/DD",
calendar: {
persian: {
locale: 'fa',
leapYearMode: "astronomical"
}
},
observer: true,
initialValue: false,
autoClose: true,
toolbox: {
calendarSwitch: {enabled: false},
todayButton: {enabled: true, text: {fa: "امروز"}}
},
});
$('#leave-modal-container .clockpicker').clockpicker({
autoclose: false,
placement: 'center',
donetext: 'ثبت',
vibrate: true,
});
window._leavePickersReady = true;
}
}
function closeLeaveModal() {
document.getElementById('leave-modal-container').classList.add('hidden');
}
function toggleLeaveType() {
const type = document.querySelector('input[name="type"]:checked')?.value || 'daily';
const daily = document.getElementById('leave-daily-fields');
const hourly = document.getElementById('leave-hourly-fields');
if (type === 'hourly') {
daily.style.display = 'none';
hourly.style.display = 'flex';
document.getElementById('leave_date_from').required = false;
document.getElementById('leave_date_to').required = false;
document.getElementById('leave_date').required = true;
document.getElementById('leave_time_from').required = true;
document.getElementById('leave_time_to').required = true;
} else {
daily.style.display = 'flex';
hourly.style.display = 'none';
document.getElementById('leave_date_from').required = true;
document.getElementById('leave_date_to').required = true;
document.getElementById('leave_date').required = false;
document.getElementById('leave_time_from').required = false;
document.getElementById('leave_time_to').required = false;
}
}
document.getElementById('leave-modal-container')?.addEventListener('click', (e) => {
if (e.target === document.getElementById('leave-modal-container')) {
closeLeaveModal();
}
});
document.getElementById('modal-container').addEventListener('click', (e) => {
if (e.target === document.getElementById('modal-container')) {
closeModal();