feat: add site visit tracking middleware and admin dashboard stats

This commit is contained in:
2026-08-20 17:03:13 +03:30
parent 3e60fa13d3
commit dd8785514f
29 changed files with 335 additions and 3187 deletions
@@ -1,434 +0,0 @@
<?php $__env->startSection('breadcrumb'); ?>
<div>
<div>
<h1 class="page-title fw-medium fs-18 mb-2">ویرایش تور</h1>
<div>
<nav>
<ol class="breadcrumb mb-0">
<li class="breadcrumb-item"><a href="<?php echo e(route('admin.tours.index')); ?>">مدیریت تورها</a></li>
<li class="breadcrumb-item active" aria-current="page">ویرایش تور</li>
</ol>
</nav>
</div>
</div>
</div>
<?php $__env->stopSection(); ?>
<?php $__env->startSection('content'); ?>
<div class="container-fluid pt-4">
<?php if(session('success')): ?>
<span style="color: green"><?php echo e(session('success')); ?></span>
<?php endif; ?>
<?php if(session('error')): ?>
<span style="color: red"><?php echo e(session('error')); ?></span>
<?php endif; ?>
<div class="row">
<div class="col-xl-12">
<form action="<?php echo e(route('admin.tours.update', $tour->id)); ?>" method="POST" enctype="multipart/form-data">
<?php echo csrf_field(); ?>
<?php echo method_field('PUT'); ?>
<div class="card custom-card">
<div class="card-header">
<div class="card-title">مشخصات اصلی تور</div>
</div>
<div class="card-body pt-0">
<div class="row gy-3">
<div class="col-xl-6">
<label class="form-label">عنوان تور <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="title"
value="<?php echo e(old('title', $tour->title)); ?>">
<?php $__errorArgs = ['title'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-6">
<label class="form-label">گستره تور <span class="text-danger">*</span></label>
<select class="form-control" name="tour_scope" id="tourScopeSelect">
<option value="">یک مورد را انتخاب کنید</option>
<?php $__currentLoopData = \App\Enums\Admin\Tour\TourScope::cases(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $scope): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($scope->value); ?>"
<?php echo e(old('tour_scope', $tour->tour_scope?->value) == $scope->value ? 'selected' : ''); ?>>
<?php echo e($scope->label()); ?>
</option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
<?php $__errorArgs = ['tour_scope'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-6">
<label class="form-label">نوع حمل و نقل / سفر <span
class="text-danger">*</span></label>
<select class="form-control" name="tour_mode">
<option value="">یک مورد را انتخاب کنید</option>
<?php $__currentLoopData = \App\Enums\Admin\Tour\TourMode::cases(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $mode): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($mode->value); ?>"
<?php echo e(old('tour_mode', $tour->tour_mode?->value) == $mode->value ? 'selected' : ''); ?>>
<?php echo e($mode->label()); ?>
</option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
<?php $__errorArgs = ['tour_mode'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-6">
<label class="form-label">سبک تور <span class="text-danger">*</span></label>
<select class="form-control" name="tour_type">
<option value="">یک مورد را انتخاب کنید</option>
<?php $__currentLoopData = \App\Enums\Admin\Tour\TourType::cases(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $type): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($type->value); ?>"
<?php echo e(old('tour_type', $tour->tour_type?->value) == $type->value ? 'selected' : ''); ?>>
<?php echo e($type->label()); ?>
</option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
<?php $__errorArgs = ['tour_type'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-6">
<label class="form-label">شهر مبدا <span class="text-danger">*</span></label>
<select class="form-control select2" name="origin_city_id">
<option value="">شهر مبدا را انتخاب کنید</option>
<?php $__currentLoopData = $cities; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $city): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($city->id); ?>"
<?php echo e(old('origin_city_id', $tour->origin_city_id) == $city->id ? 'selected' : ''); ?>>
<?php echo e($city->name); ?>
</option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
<?php $__errorArgs = ['origin_city_id'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-6" id="countryWrapper"
style="<?php echo e($tour->tour_scope === \App\Enums\Admin\Tour\TourScope::INTERNATIONAL ? '' : 'display:none;'); ?>">
<label class="form-label">کشور مقصد</label>
<select class="form-control" id="country_id"
<?php echo e($tour->tour_scope === \App\Enums\Admin\Tour\TourScope::INTERNATIONAL ? '' : 'disabled'); ?>>
<option value="">یک مورد را انتخاب کنید</option>
<?php $__currentLoopData = $countries; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $country): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($country->id); ?>"
<?php echo e($selectedCountryId == $country->id ? 'selected' : ''); ?>>
<?php echo e($country->name); ?>
</option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
</div>
<div class="col-xl-6">
<label class="form-label">شهر مقصد <span class="text-danger">*</span></label>
<select class="form-control select2" name="destination_city_id">
<option value="">شهر مقصد را انتخاب کنید</option>
<?php $__currentLoopData = $destinationCities; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $city): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($city->id); ?>"
<?php echo e(old('destination_city_id', $tour->destination_city_id) == $city->id ? 'selected' : ''); ?>>
<?php echo e($city->name); ?>
</option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
<?php $__errorArgs = ['destination_city_id'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-12">
<label class="form-label">خلاصه تور</label>
<textarea class="form-control" name="summary"
rows="2"><?php echo e(old('summary', $tour->summary)); ?></textarea>
<?php $__errorArgs = ['summary'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-12">
<label class="form-label">توضیحات کامل و برنامه سفر</label>
<textarea class="form-control" name="description"
rows="5"><?php echo e(old('description', $tour->description)); ?></textarea>
<?php $__errorArgs = ['description'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
</div>
<hr class="my-4">
<h6 class="fw-bold mb-3">اطلاعات ظرفیت / زمان‌بندی حرکت</h6>
<div class="row gy-3">
<div class="col-xl-3">
<label class="form-label">تاریخ رفت (شروع)</label>
<input
type="text"
id="startDateInput"
class="form-control"
name="start_date"
value="<?php echo e(old(
'start_date',$departure?->start_date ? Verta::instance($departure->start_date)->format('Y/m/d H:i') : '' )); ?>">
<?php $__errorArgs = ['start_date'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-3">
<label class="form-label">تاریخ برگشت (پایان)</label>
<input
type="text"
id="endDateInput"
class="form-control"
name="end_date"
value="<?php echo e(old('end_date',$departure?->end_date ? Verta::instance($departure->end_date)->format('Y/m/d H:i') : '')); ?>">
<?php $__errorArgs = ['end_date'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-3">
<label class="form-label">قیمت (تومان)</label>
<input type="text" class="form-control" name="price"
value="<?php echo e(old('price', $departure?->price)); ?>">
<?php $__errorArgs = ['price'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="col-xl-3">
<label class="form-label">ظرفیت مسافر</label>
<input type="number" class="form-control" name="capacity"
value="<?php echo e(old('capacity', $departure?->capacity)); ?>">
<?php $__errorArgs = ['capacity'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
</div>
<hr class="my-4">
<h6 class="fw-bold mb-2">گالری تصاویر فعلی</h6>
<div class="d-flex flex-wrap gap-2 mb-3">
<?php $__empty_1 = true; $__currentLoopData = $tour->images; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $image): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
<div class="position-relative" style="width:120px;height:120px;">
<img src="<?php echo e(getFileUrl($image->file_id)); ?>"
class="w-100 h-100 rounded"
style="object-fit:cover;"
alt="<?php echo e($tour->title); ?>">
<?php if($image->is_default): ?>
<span
class="badge bg-primary position-absolute top-0 start-0 m-1">اصلی</span>
<?php endif; ?>
</div>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
<span class="text-muted">هیچ تصویری ثبت نشده است.</span>
<?php endif; ?>
</div>
<h6 class="fw-bold mb-2">افزودن تصاویر جدید</h6>
<div class="image-upload-wrapper d-flex flex-wrap gap-2 px-0 pt-0 mt-2"
id="imagePreviewContainer" style="border-radius: 8px; padding: 10px;">
<label id="uploadPlaceholder" class="upload-placeholder" for="imageInput"
style="cursor: pointer; width:150px; height:150px; display: flex; justify-content: center; align-items: center; border: 2px dashed #ccc; border-radius: 8px; padding: 20px; text-align: center;">
<div>📷<br><strong>آپلود تصاویر</strong></div>
<small style="color:#999;">JPG / PNG / WEBP</small>
</label>
<input id="imageInput" name="images[]" type="file"
accept=".jpg,.png,.jpeg,.webp" multiple style="display:none">
</div>
<?php $__errorArgs = ['images'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="text-danger small d-block"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="card-footer text-end">
<button type="submit" class="btn btn-primary">ذخیره تغییرات</button>
</div>
</div>
</form>
</div>
</div>
</div>
<?php $__env->startPush('scripts'); ?>
<script>
$(document).ready(function () {
$('#startDateInput').persianDatepicker({
format: 'YYYY/MM/DD HH:mm',
timePicker: {
enabled: true,
meridiem: {
enabled: false
}
},
autoClose: false,
initialValue: false,
initialValueType: 'persian',
toolbox: {
calendarSwitch: {
enabled: false
}
}
});
$('#endDateInput').persianDatepicker({
format: 'YYYY/MM/DD HH:mm',
timePicker: {
enabled: true,
meridiem: {
enabled: false
}
},
autoClose: false,
initialValue: false,
initialValueType: 'persian',
toolbox: {
calendarSwitch: {
enabled: false
}
}
});
function toggleScopeUI() {
const scope = $('#tourScopeSelect').val();
if (scope === '1') {
$('#countryWrapper').show();
$('#country_id').prop('disabled', false);
} else {
$('#countryWrapper').hide();
$('#country_id').prop('disabled', true).val('');
}
}
$('#tourScopeSelect').on('change', toggleScopeUI);
$('#country_id').on('change', function () {
const countryId = $(this).val();
if (!countryId) return;
$.get(`/admin/tours/cities-by-country/${countryId}`, function (cities) {
let options = '<option value="">شهر را انتخاب کنید</option>';
cities.forEach(function (city) {
options += `<option value="${city.id}">${city.name}</option>`;
});
$('select[name="destination_city_id"]').html(options).trigger('change');
}).fail(function () {
alert('خطا در دریافت لیست شهرهای این کشور');
});
});
});
</script>
<?php $__env->stopPush(); ?>
<?php $__env->stopSection(); ?>
<?php echo $__env->make('admin.layouts.app', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH C:\Users\ASUS\Desktop\airline-agency\resources\views/admin/tours/edit.blade.php ENDPATH**/ ?>