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
+7
View File
@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Models\LeaveRequest;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
@@ -352,6 +353,11 @@ class AdminController extends Controller
$this->enrichUsersForDashboard($users);
$users = $users->sortByDesc('working');
$records = $this->loadPendingRequests($users);
$leaveRequests = LeaveRequest::query()
->where('status', 'pending')
->with('user:id,name,user_name')
->orderByDesc('created_at')
->get();
return view("admin..admin")->with(['message', [
'color' => '#ff8800ff',
@@ -359,6 +365,7 @@ class AdminController extends Controller
],
"users" => $users,
'reqs' => $records,
'leaveRequests' => $leaveRequests,
"userType" => $provider
]);
}
+238
View File
@@ -0,0 +1,238 @@
<?php
namespace App\Http\Controllers;
use App\Models\Attendance;
use App\Models\LeaveRequest;
use App\Models\User;
use App\Services\LatePenaltyService;
use App\Support\JalaliHelper;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Morilog\Jalali\Jalalian;
class LeaveController extends Controller
{
public function store(Request $request)
{
if (!isset($_COOKIE['user_identity'])) {
return redirect('/')->with('message', [
'color' => '#ff8800ff',
'text' => 'ابتدا باید وارد شوید!',
]);
}
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
if (!$user) {
return redirect('/')->with('message', [
'color' => '#ff8800ff',
'text' => 'کاربر یافت نشد!',
]);
}
$type = $request->input('type');
if (!in_array($type, ['daily', 'hourly'], true)) {
return back()->with('message', [
'color' => '#ff4400ff',
'text' => 'نوع مرخصی نامعتبر است.',
]);
}
if ($type === 'daily') {
$dateFrom = $this->parseJalaliDate($request->input('date_from'));
$dateTo = $this->parseJalaliDate($request->input('date_to'));
if (!$dateFrom || !$dateTo) {
return back()->with('message', [
'color' => '#ff4400ff',
'text' => 'بازه تاریخ مرخصی روزانه الزامی است.',
]);
}
if ($dateTo < $dateFrom) {
return back()->with('message', [
'color' => '#ff4400ff',
'text' => 'تاریخ پایان نمی‌تواند قبل از شروع باشد.',
]);
}
$timeFrom = null;
$timeTo = null;
} else {
$dateFrom = $this->parseJalaliDate($request->input('date'));
$dateTo = $dateFrom;
$timeFrom = $this->normalizeTime($request->input('time_from'));
$timeTo = $this->normalizeTime($request->input('time_to'));
if (!$dateFrom || !$timeFrom || !$timeTo) {
return back()->with('message', [
'color' => '#ff4400ff',
'text' => 'تاریخ و ساعت شروع/پایان مرخصی ساعتی الزامی است.',
]);
}
if ($timeTo <= $timeFrom) {
return back()->with('message', [
'color' => '#ff4400ff',
'text' => 'ساعت پایان باید بعد از ساعت شروع باشد.',
]);
}
}
$leave = LeaveRequest::create([
'user_id' => $user->id,
'user_identity' => $user->user_name,
'type' => $type,
'date_from' => $dateFrom,
'date_to' => $dateTo,
'time_from' => $timeFrom,
'time_to' => $timeTo,
'reason' => $request->input('reason'),
'status' => 'pending',
]);
$user->req_counts = (int) $user->req_counts + 1;
$user->save();
$this->notifyAdminsNewLeave($leave, $user);
return redirect('/')->with('message', [
'color' => '#00c300ff',
'text' => 'درخواست مرخصی ثبت شد و برای تأیید ادمین ارسال گردید.',
]);
}
public function decide(Request $request)
{
if (!isset($_COOKIE['user_identity'])) {
return back()->with('message', [
'color' => '#ff8800ff',
'text' => 'ابتدا باید وارد شوید!',
]);
}
$admin = User::where('user_name', $_COOKIE['user_identity'])->first();
if (!$admin || !in_array((string) $admin->is_admin, ['1', '2'], true)) {
return back()->with('message', [
'color' => '#ff8800ff',
'text' => 'دسترسی ندارید!',
]);
}
$leave = LeaveRequest::find($request->input('leave_id'));
if (!$leave || $leave->status !== 'pending') {
return back()->with('message', [
'color' => '#ff8800ff',
'text' => 'درخواست مرخصی یافت نشد.',
]);
}
$action = $request->input('update');
if (!in_array($action, ['approve', 'reject'], true)) {
return back()->with('message', [
'color' => '#ff4400ff',
'text' => 'عملیات نامعتبر است.',
]);
}
$leave->status = $action === 'approve' ? 'approved' : 'rejected';
$leave->reviewed_by = $admin->id;
$leave->reviewed_at = now();
$leave->save();
$owner = User::where('user_name', $leave->user_identity)->first();
if ($owner && (int) $owner->req_counts > 0) {
$owner->req_counts -= 1;
$owner->save();
}
if ($leave->status === 'approved') {
$this->recalculateLateForLeavePeriod($leave);
}
$statusFa = $leave->status === 'approved' ? 'تایید' : 'رد';
if ($owner) {
tel_notif($leave->user_identity, $statusFa);
}
return back()->with('message', [
'color' => '#6aff00ff',
'text' => "درخواست مرخصی با موفقیت {$statusFa} شد.",
]);
}
private function recalculateLateForLeavePeriod(LeaveRequest $leave): void
{
$service = app(LatePenaltyService::class);
$from = Carbon::parse($leave->date_from)->startOfDay();
$to = Carbon::parse($leave->date_to)->endOfDay();
$attendances = Attendance::query()
->where('user_identity', $leave->user_identity)
->whereBetween('entered_at', [$from, $to])
->orderBy('entered_at')
->get();
foreach ($attendances as $attendance) {
$service->syncAttendance($attendance);
}
}
private function notifyAdminsNewLeave(LeaveRequest $leave, User $user): void
{
$typeFa = $leave->type === 'daily' ? 'روزانه' : 'ساعتی';
$from = JalaliHelper::format($leave->date_from, 'Y/m/d');
$to = JalaliHelper::format($leave->date_to, 'Y/m/d');
$message = "درخواست مرخصی {$typeFa}\n";
$message .= "کارمند: {$user->name}\n";
if ($leave->type === 'daily') {
$message .= "از {$from} تا {$to}\n";
} else {
$timeFrom = substr((string) $leave->time_from, 0, 5);
$timeTo = substr((string) $leave->time_to, 0, 5);
$message .= "تاریخ: {$from}\nساعت: {$timeFrom} تا {$timeTo}\n";
}
if ($leave->reason) {
$message .= "دلیل: {$leave->reason}";
}
$this->send_admins($message);
}
private function parseJalaliDate(?string $value): ?string
{
if (!$value) {
return null;
}
$value = \Morilog\Jalali\CalendarUtils::convertNumbers(trim($value), true);
$value = str_replace('/', '-', $value);
try {
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
// اگر سال شمسی باشد (مثلاً 1404) با Jalalian تبدیل می‌شود
$year = (int) substr($value, 0, 4);
if ($year >= 1300 && $year <= 1500) {
return Jalalian::fromFormat('Y-m-d', $value)->toCarbon()->format('Y-m-d');
}
return $value;
}
return Carbon::parse($value)->format('Y-m-d');
} catch (\Throwable $e) {
return null;
}
}
private function normalizeTime(?string $value): ?string
{
if (!$value) {
return null;
}
$value = trim(\Morilog\Jalali\CalendarUtils::convertNumbers($value, true));
if (preg_match('/^(\d{1,2}):(\d{2})/', $value, $m)) {
return sprintf('%02d:%02d:00', (int) $m[1], (int) $m[2]);
}
return null;
}
}
+56
View File
@@ -0,0 +1,56 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class LeaveRequest extends Model
{
protected $fillable = [
'user_id',
'user_identity',
'type',
'date_from',
'date_to',
'time_from',
'time_to',
'reason',
'status',
'reviewed_by',
'reviewed_at',
];
protected function casts(): array
{
return [
'date_from' => 'date',
'date_to' => 'date',
'reviewed_at' => 'datetime',
];
}
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function reviewer()
{
return $this->belongsTo(User::class, 'reviewed_by');
}
public function isDaily(): bool
{
return $this->type === 'daily';
}
public function isHourly(): bool
{
return $this->type === 'hourly';
}
public function isApproved(): bool
{
return $this->status === 'approved';
}
}
+61 -2
View File
@@ -4,6 +4,7 @@ namespace App\Services;
use App\Models\Attendance;
use App\Models\LatePeriodFine;
use App\Models\LeaveRequest;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Collection;
@@ -17,7 +18,7 @@ class LatePenaltyService
public const WEEKLY_ALLOWANCE_MINUTES = 15;
public const FINE_PER_MINUTE = 2000;
public function calculateFromEnteredAt(?string $enteredAt): array
public function calculateFromEnteredAt(?string $enteredAt, ?string $userIdentity = null): array
{
if (!$enteredAt) {
return [
@@ -32,6 +33,21 @@ class LatePenaltyService
$entered = Carbon::parse($enteredAt)->startOfMinute();
$threshold = $entered->copy()->setTimeFromTimeString(self::WORK_START)->startOfMinute();
if ($userIdentity) {
$leaveThreshold = $this->approvedLeaveWorkThreshold($userIdentity, $entered);
if ($leaveThreshold === false) {
return [
'late_minutes' => 0,
'grace_late_minutes' => 0,
'daily_fine_minutes' => 0,
'daily_fine_amount' => 0,
];
}
if ($leaveThreshold instanceof Carbon) {
$threshold = $leaveThreshold->copy()->startOfMinute();
}
}
if ($entered->lte($threshold)) {
return [
'late_minutes' => 0,
@@ -54,6 +70,49 @@ class LatePenaltyService
];
}
/**
* مرخصی تأییدشده: false = معاف کامل، Carbon = شروع مؤثر کار، null = بدون تغییر.
*/
public function approvedLeaveWorkThreshold(string $userIdentity, Carbon $entered): Carbon|false|null
{
$day = $entered->toDateString();
$workStart = $entered->copy()->setTimeFromTimeString(self::WORK_START)->startOfMinute();
$leaves = LeaveRequest::query()
->where('user_identity', $userIdentity)
->where('status', 'approved')
->whereDate('date_from', '<=', $day)
->whereDate('date_to', '>=', $day)
->get();
$latestMorningLeaveEnd = null;
foreach ($leaves as $leave) {
if ($leave->type === 'daily') {
return false;
}
if ($leave->type !== 'hourly' || !$leave->time_from || !$leave->time_to) {
continue;
}
$leaveStart = Carbon::parse($day . ' ' . $leave->time_from)->startOfMinute();
$leaveEnd = Carbon::parse($day . ' ' . $leave->time_to)->startOfMinute();
// مرخصی صبح که شروع کار را پوشش می‌دهد
if ($leaveStart->lte($workStart) && $leaveEnd->gt($workStart)) {
if ($entered->lte($leaveEnd)) {
return false;
}
if ($latestMorningLeaveEnd === null || $leaveEnd->gt($latestMorningLeaveEnd)) {
$latestMorningLeaveEnd = $leaveEnd;
}
}
}
return $latestMorningLeaveEnd;
}
/** دقایق تأخیر داخل بازه ۸:۳۰–۸:۴۵ برای یک رکورد */
public function graceLateMinutes(Attendance $att): int
{
@@ -94,7 +153,7 @@ class LatePenaltyService
return $attendance;
}
$calc = $this->calculateFromEnteredAt($attendance->entered_at);
$calc = $this->calculateFromEnteredAt($attendance->entered_at, $attendance->user_identity);
$attendance->late_minutes = $calc['late_minutes'];
$attendance->daily_fine_minutes = $calc['daily_fine_minutes'];
$attendance->daily_fine_amount = $calc['daily_fine_amount'];
@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('leave_requests', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->nullable();
$table->string('user_identity');
$table->string('type'); // daily | hourly
$table->date('date_from');
$table->date('date_to');
$table->time('time_from')->nullable();
$table->time('time_to')->nullable();
$table->text('reason')->nullable();
$table->string('status')->default('pending'); // pending | approved | rejected
$table->unsignedBigInteger('reviewed_by')->nullable();
$table->timestamp('reviewed_at')->nullable();
$table->timestamps();
$table->index(['user_identity', 'status']);
$table->index(['date_from', 'date_to']);
});
}
public function down(): void
{
Schema::dropIfExists('leave_requests');
}
};
+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();
+3
View File
@@ -19,6 +19,7 @@ use GuzzleHttp\Client;
use App\Models\Tasks;
use App\Models\Pivot_Tasks;
use App\Http\Controllers\AttendanceController;
use App\Http\Controllers\LeaveController;
@@ -34,6 +35,8 @@ Route::post('/delete', [AdminController::class, 'delete'])->name('admin.delete')
Route::post('/update', [AdminController::class, 'update'])->name('admin.update');
Route::post('/leave/decide', [LeaveController::class, 'decide'])->name('admin.leave.decide');
Route::get('/job', function () {
+2
View File
@@ -20,6 +20,7 @@ use App\Models\Pivot_Tasks;
use App\Http\Controllers\AttendanceController;
use App\Http\Controllers\TaskController;
use App\Http\Controllers\FingerprintController;
use App\Http\Controllers\LeaveController;
Route::prefix('admin')->middleware('admin')->group(function () {
@@ -58,6 +59,7 @@ Route::get('/attendance/profile', [AttendanceController::class, 'profile'])->nam
Route::post('/attendance/profile', [AttendanceController::class, 'updateProfile'])->name('edit.profile');
Route::post('/leave', [LeaveController::class, 'store'])->name('leave.store');
//Task routes
Route::get('/tasks', [TaskController::class, 'Tasks']);