Compare commits

...

97 Commits

Author SHA1 Message Date
shahrzad 5e3924d929 feat: add charts to admin dashboard 2026-08-22 11:47:39 +03:30
shahrzad 691290c340 chore: finalize project updates 2026-08-22 11:42:16 +03:30
shahrzad 7719d750e9 feat: add favorites management 2026-08-22 11:27:55 +03:30
shahrzad 6addcf73bb chore: add latest database backup 2026-08-22 11:27:28 +03:30
shahrzad 9e38c63614 feat: add user password update validation 2026-08-22 11:27:09 +03:30
shahrzad f73800fa50 feat: add public comment management 2026-08-22 11:26:32 +03:30
shahrzad e322ddda8f feat: add province and city management 2026-08-22 11:26:01 +03:30
shahrzad 64bfa2b94f feat: add province and city management 2026-08-22 11:25:31 +03:30
shahrzad 07e6dc7f5d feat: add comment status view 2026-08-22 07:57:24 +03:30
shahrzad 1544aed64d feat: add archive page styles 2026-08-22 07:56:53 +03:30
shahrzad 17090d0666 feat: add account page styles 2026-08-22 07:56:40 +03:30
shahrzad 4462237c44 chore: add latest database backup 2026-08-22 07:56:20 +03:30
shahrzad fad359f1c5 fix: update tour functionality 2026-08-22 07:55:56 +03:30
shahrzad 2195f10016 fix: update homepage data 2026-08-22 07:55:32 +03:30
shahrzad 178219b699 fix: update admin user management 2026-08-22 07:54:50 +03:30
shahrzad 281b82fc5b fix: update admin dashboard 2026-08-22 07:54:26 +03:30
shahrzad 65c4863f30 fix: update profile editing 2026-08-22 07:53:15 +03:30
shahrzad cb494a933e fix: update account comment handling 2026-08-22 07:52:16 +03:30
shahrzad 7c0bc5b08b fix: update authentication flow 2026-08-20 08:28:45 +03:30
shahrzad 2a980ecc55 fix: update public tour functionality 2026-08-20 08:27:53 +03:30
shahrzad 9b7934c0ba fix: update flight functionality 2026-08-20 08:27:00 +03:30
shahrzad f9dd90f1ac fix: update admin management 2026-08-20 08:25:43 +03:30
shahrzad ecb2e9ff08 chore: update composer dependencies 2026-08-20 08:24:37 +03:30
shahrzad ea2333cc68 fix: update web routes 2026-08-20 08:24:19 +03:30
shahrzad 6f99b8fb1c fix: update frontend styles 2026-08-20 08:24:00 +03:30
shahrzad f23ce338b3 fix: update frontend layout 2026-08-20 08:23:41 +03:30
shahrzad 409b8bb7f9 fix: update account favorites view 2026-08-20 08:22:54 +03:30
shahrzad c770921377 fix: update admin model 2026-08-20 08:22:19 +03:30
shahrzad d4e96f614a fix: update user model 2026-08-20 08:21:55 +03:30
shahrzad 2d9b56a83e fix: update homepage 2026-08-20 08:21:27 +03:30
shahrzad 854324813e fix: update public tour functionality 2026-08-20 08:20:29 +03:30
shahrzad 99e7d4ee95 fix: update flight functionality 2026-08-20 08:19:33 +03:30
shahrzad 39386b8155 fix: update authentication flow 2026-08-20 08:18:39 +03:30
shahrzad 66cc0d64ad fix: update admin tour management 2026-08-20 08:17:05 +03:30
shahrzad ccee91fdc4 feat: add user favorites management 2026-08-20 08:15:42 +03:30
shahrzad 52a8633787 feat: add profile editing 2026-08-20 08:15:20 +03:30
shahrzad 9e4baaa08d feat: add flight controller 2026-08-20 08:12:35 +03:30
shahrzad 793a3dc06e feat: add user authentication 2026-08-20 08:10:51 +03:30
shahrzad bbdfb48812 chore: add latest database backup 2026-08-20 08:06:32 +03:30
shahrzad a6d0cc2d41 fix: update application routes 2026-08-19 08:30:30 +03:30
shahrzad 2a69d676e1 fix: update airport management 2026-08-19 08:29:08 +03:30
shahrzad 157efd8df0 fix: update dashboard functionality 2026-08-19 08:28:03 +03:30
shahrzad 25bb569cfb feat: add account comments controller 2026-08-19 08:26:54 +03:30
shahrzad e74e6c1377 fix: update application routes 2026-08-19 08:24:50 +03:30
shahrzad 771d4d4b00 fix: update frontend styles and scripts 2026-08-19 08:24:36 +03:30
shahrzad de190fb550 fix: update admin styles 2026-08-19 08:24:16 +03:30
shahrzad 82e48faf0f fix: update application service provider 2026-08-19 08:23:08 +03:30
shahrzad 761411e959 fix: update homepage 2026-08-19 08:22:05 +03:30
shahrzad 92daccd47a fix: update frontend layouts and components 2026-08-19 08:21:13 +03:30
shahrzad 6e46594233 fix: update admin layout 2026-08-19 08:20:39 +03:30
shahrzad 7d557bebff fix: update admin settings views 2026-08-19 08:19:31 +03:30
shahrzad 2bf9ba1577 fix: update admin favorites views 2026-08-19 08:18:41 +03:30
shahrzad 68d11dcbd5 fix: update airport management 2026-08-19 08:17:48 +03:30
shahrzad 97c01a17a3 fix: update comment management 2026-08-19 08:17:06 +03:30
shahrzad 552b23d5ff fix: update tour management 2026-08-19 08:14:34 +03:30
shahrzad 852ea9d105 fix: update tour management 2026-08-19 08:13:26 +03:30
shahrzad c790091131 fix: update user model 2026-08-19 08:11:50 +03:30
shahrzad a9d46fe64c fix: update travel models 2026-08-19 08:11:32 +03:30
shahrzad 4aa2e9fb65 chore: add latest database backup 2026-08-19 08:10:16 +03:30
shahrzad b4399e638f feat: add bootstrap assets 2026-08-19 08:09:56 +03:30
shahrzad ad58f114fd feat: add custom frontend styles 2026-08-19 08:08:34 +03:30
shahrzad c500bdd1b7 feat: add province and city models 2026-08-19 08:07:35 +03:30
shahrzad b01507ed7d feat: add flight controller 2026-08-19 08:07:01 +03:30
shahrzad f251fd800f feat: add booking management 2026-08-19 08:06:30 +03:30
shahrzad f27e676b87 feat: add booking management 2026-08-19 08:05:38 +03:30
shahrzad 84f095b00f feat: add user authentication 2026-08-19 08:04:02 +03:30
shahrzad a10bdd20fa chore: add database backup snapshot 2026-08-18 08:08:06 +03:30
shahrzad 05731b3670 feat: add account favorites view 2026-08-18 08:06:41 +03:30
shahrzad 9f9047a656 feat: add account dashboard view 2026-08-18 08:06:14 +03:30
shahrzad 34f8066009 feat: add account comments view 2026-08-18 08:05:52 +03:30
shahrzad 8878e1106c feat: add account profile editing views 2026-08-18 08:05:18 +03:30
shahrzad 4769a8d99d fix: update composer configuration 2026-08-18 08:04:14 +03:30
shahrzad cae482535f fix: update admin dashboard view 2026-08-18 08:03:39 +03:30
shahrzad c6919bcead fix: update admin management views 2026-08-18 08:03:11 +03:30
shahrzad a31375a20f fix: update travel type controller 2026-08-18 08:02:17 +03:30
shahrzad 2b04b84624 fix: update composer dependencies 2026-08-17 20:01:07 +03:30
shahrzad b5a7d757bd fix: update application routes 2026-08-17 20:00:34 +03:30
shahrzad 0c44670850 fix: update application routes 2026-08-17 20:00:19 +03:30
shahrzad 528f6c07f3 fix: update admin layouts 2026-08-17 19:59:00 +03:30
shahrzad b946c65d1e fix: update admin model 2026-08-17 19:58:01 +03:30
shahrzad ca745df725 fix: update user management 2026-08-17 19:57:08 +03:30
shahrzad 3ec77fd4d8 fix: update travel type management 2026-08-17 19:55:26 +03:30
shahrzad 123b43fb38 fix: update tour management 2026-08-17 19:53:12 +03:30
shahrzad 81d2aa1acb fix: update flight management 2026-08-17 19:50:38 +03:30
shahrzad 931d67cdd8 fix: update admin dashboard 2026-08-17 19:47:25 +03:30
shahrzad 7107286c1a fix: update admin management controller 2026-08-17 19:46:45 +03:30
shahrzad 994add824f feat: add user password change interface 2026-08-17 19:45:47 +03:30
shahrzad 0b7e0b8e94 feat: add visits export 2026-08-17 19:44:50 +03:30
shahrzad 152807d7c1 feat: add permission model 2026-08-17 19:44:19 +03:30
shahrzad c1162f70e9 feat: add user update request validation 2026-08-17 19:43:34 +03:30
shahrzad 12d56c2c9f feat: add travel type request validation 2026-08-17 19:42:44 +03:30
shahrzad cb15c63a05 feat: add flight request validation 2026-08-17 19:41:52 +03:30
shahrzad fbabc034a5 feat: add admin request validation 2026-08-17 19:40:43 +03:30
shahrzad 242284f01e feat: add payment update form request 2026-08-17 08:26:27 +03:30
shahrzad 55344ee240 feat: add admin and payment status enums 2026-08-17 08:25:52 +03:30
shahrzad 27c0b3d8e8 "feat: add latest database backup snapshot (yesterday) 2026-08-17 08:25:03 +03:30
shahrzad b7e595ce7b feat: add database backup snapshot (two days ago) 2026-08-17 08:24:36 +03:30
179 changed files with 77943 additions and 4382 deletions
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App\Enums;
enum AdminStatus:int
{
case DISABLE= 0;
case ENABLE= 1;
}
+1
View File
@@ -12,6 +12,7 @@ enum PaymentStatus: int
// برچسب فارسی برای نمایش در ویو
public function label(): string
{
return match ($this) {
self::Pending => 'در انتظار پرداخت',
self::Success => 'پرداخت موفق',
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
class VisitsExport implements FromArray, WithHeadings, ShouldAutoSize
{
protected $rows;
public function __construct(array $rows)
{
$this->rows = $rows;
}
public function headings(): array
{
return [
'شناسه',
'نام',
'نام خانوادگی',
'ایمیل',
'موبایل',
'تاریخ ثبت‌نام',
];
}
public function array(): array
{
return $this->rows;
}
}
@@ -0,0 +1,47 @@
<?php
namespace App\Http\Controllers\Account;
use App\Http\Requests\CommentStoreRequest;
use App\Http\Controllers\Controller;
use App\Models\Flight;
use App\Models\Tour;
class CommentController extends Controller
{
//ثبت نظر برای تور
public function storeTour(CommentStoreRequest $request, Tour $tour)
{
$tour->comments()->create([
'user_id' => auth()->id(),
'body' => $request->validated('body'),
'status' => 1,
]);
return back()->with('success', 'نظر شما با موفقیت ثبت شد.');
}
//ثبت نظر برای پرواز
public function storeFlight(CommentStoreRequest $request, Flight $flight)
{
$flight->comments()->create([
'user_id' => auth()->id(),
'body' => $request->validated('body'),
'status' => 1,
]);
return back()->with('success', 'نظر شما با موفقیت ثبت شد.');
}
public function myComments()
{
$comments = auth()->user()->comments()
->with('commentable')
->latest()
->paginate(10);
return view('account.comments', compact('comments'));
}
}
@@ -0,0 +1,54 @@
<?php
namespace App\Http\Controllers\Account;
use App\Http\Controllers\Controller;
use App\Http\Requests\EditProfilePostRequest;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class EditProfileController extends Controller
{
public function index()
{
$user = Auth::user()->load(['comments.commentable', 'favorites.favoritable']);
return view('account.edit-profile.index', compact('user'));
}
public function post(EditProfilePostRequest $request)
{
$user = Auth::user();
// به‌روزرسانی فیلدها
$user->first_name = $request->first_name;
$user->last_name = $request->last_name;
$user->email = $request->email;
$user->username = $request->username;
if ($request->filled('password')) {
$user->password = Hash::make($request->password);
}
if ($request->hasFile('image')) {
if ($user->image) {
Storage::disk('public')->delete($user->image);
}
$path = $request->file('image')->store('avatars', 'public');
$user->image = $path;
}
$user->save();
return redirect()
->route('account.edit-profile.index')
->with('success', 'اطلاعات پروفایل با موفقیت ویرایش شد.');
}
}
@@ -0,0 +1,72 @@
<?php
namespace App\Http\Controllers\Account;
use App\Http\Controllers\Controller;
use App\Models\Favorite;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class FavoriteController extends Controller
{
public function index()
{
// dd(Auth::id(), Favorite::with('favoritable')->where('user_id', Auth::id())->get());
$user = Auth::user();
$favorites = Favorite::with('favoritable')
->where('user_id', $user->id)
->orderByDesc('id')
->paginate(9);
return view('account.favorites', compact('favorites'));
}
public function toggle(Request $request)
{
// چک اینکه کاربر ورود شدهست
if (!Auth::check()) {
return back()->with('error', 'برای افزودن به علاقهمندی باید ورود شوی');
}
$data = $request->validate([
'favoritable_type' => 'required|string',
'favoritable_id' => 'required|integer',
]);
$type = $data['favoritable_type'];
$id = $data['favoritable_id'];
if (!class_exists($type)) {
return back()->with('error', 'مدل معتبر نیست');
}
$model = $type::find($id);
if (!$model) {
return back()->with('error', 'مورد یافت نشد');
}
// یافتن علاقهمندی موجود
$favorite = Favorite::where('user_id', Auth::id())
->where('favoritable_type', $type)
->where('favoritable_id', $id)
->first();
if ($favorite) {
$favorite->delete(); // حذف از علاقهمندیها
$message = 'از علاقهمندیها حذف شد';
} else {
Favorite::create([
'user_id' => Auth::id(),
'favoritable_type' => $type,
'favoritable_id' => $id,
]);
$message = 'به علاقهمندیها افزوده شد';
}
return back()->with('success', $message);
}
}
@@ -0,0 +1,45 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginPostRequest;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function index()
{
return view('auth.login');
}
public function post(LoginPostRequest $request)
{
$login = $request->validated();
$field = filter_var($login['username'], FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
$credentials = [
$field => $login['username'],
'password' => $login['password'],
];
$remember = $request->boolean('remember');
if (Auth::attempt($credentials, $remember)) {
$request->session()->regenerate();
return redirect()
->intended(route('account.index'))
->with('success', 'با موفقیت وارد حساب کاربری شدید.');
}
return back()
->withInput($request->only('username'))
->withErrors([
'username' => 'نام کاربری، ایمیل یا رمز عبور اشتباه است.',
]);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LogoutController extends Controller
{
public function index(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->route('auth.login.index')->with('success', 'با موفقیت از حساب کاربری خارج شدید.');
}
}
@@ -0,0 +1,96 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\RegisterPostRequest;
use App\Models\City;
use App\Models\Province;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class RegisterController extends Controller
{
public function index()
{
$provinces = Province::orderBy('name')->get();
return view('auth.register', compact('provinces'));
}
public function post(RegisterPostRequest $request)
{
// $data = $request->validated();
$imagePath = null;
if ($request->hasFile('image')) {
$imagePath = $request
->file('image')
->store('users', 'public');
}
$user = User::create([
'first_name' => $request['first_name'],
'last_name' => $request['last_name'],
'national_code' => $request['national_code'],
'gender' => $request['gender'],
'marital_status' => $request['marital_status'],
'spouse_name' => $request['marital_status'] == 2
? ($data['spouse_name'] ?? null)
: null,
'mobile' => $request['mobile'],
'email' => $request['email'],
'username' => $request['username'],
'password' => Hash::make($request['password']),
'image' => $imagePath,
'province_id' => $data['province_id'] ?? null,
'city_id' => $request['city_id'] ?? null,
'status' => 1,
]);
Auth::guard('web')->login($user);
// $request->session()->regenerate();
return redirect()
->route('account.index')
->with('success', 'ثبت‌نام شما با موفقیت انجام شد.');
}
public function cities(Province $province)
{
$cities = City::where('province_id', $province->id)
->orderBy('name')
->get([
'id',
'name'
]);
return response()->json($cities);
}
}
@@ -0,0 +1,76 @@
<?php
namespace App\Http\Controllers;
use App\Models\Flight;
use Illuminate\Http\Request;
class BookingController extends Controller
{
public function flight(Flight $flight)
{
// فقط پرواز فعال
if ((int)$flight->status !== 1) {
abort(404);
}
$flight->load([
'travelType',
'origin',
'destination',
]);
return view('account.bookings', compact('flight'));
}
public function storeFlight(Request $request, Flight $flight)
{
// بررسی فعال بودن پرواز
if ((int) $flight->status !== 1) {
abort(404);
}
// اعتبارسنجی
$validated = $request->validate([
'first_name' => [
'required',
'string',
'max:100',
],
'last_name' => [
'required',
'string',
'max:100',
],
'national_code' => [
'required',
'string',
'max:20',
],
'phone' => [
'required',
'string',
'max:20',
],
'passengers' => [
'required',
'integer',
'min:1',
'max:10',
],
]);
// فعلاً برای تست
return redirect()
->route('flights.show', $flight)
->with(
'success',
'درخواست رزرو پرواز با موفقیت ثبت شد.'
);
}
}
@@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class CommentController extends Controller
{
//
}
@@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers;
use App\Models\Tour;
use Illuminate\Http\Request;
class FavoriteController extends Controller
{
public function toggle(Request $request)
{
$type = $request->input('favoritable_type');
$id = $request->input('favoritable_id');
// چک کنید اگر null بود، متوقف شود
if (!$type || !$id) {
return back()->withErrors('اطلاعات ارسالی ناقص است!');
}
$user = auth()->user();
$exists = $user->favorites()
->where('favoritable_type', $type)
->where('favoritable_id', $id)
->first();
if ($exists) {
// اگر وجود داشت، حذفش کن
$exists->delete();
$message = 'از علاقه‌مندی‌ها حذف شد.';
} else {
// اگر وجود نداشت، یک رکورد جدید بساز
$user->favorites()->create([
'favoritable_type' => $type,
'favoritable_id' => $id,
]);
$message = 'به علاقه‌مندی‌ها اضافه شد.';
}
return back()->with('success', $message);
}
}
+118
View File
@@ -0,0 +1,118 @@
<?php
namespace App\Http\Controllers;
use App\Models\Flight;
use Illuminate\Http\Request;
class FlightController extends Controller
{
public function index(Request $request)
{
$query = Flight::query()
->active()
->with([
'travelType',
'tours',
]);
// شماره پرواز
if ($request->filled('flight_number')) {
$query->where(
'flight_number',
'like',
'%' . $request->input('flight_number') . '%'
);
}
// مبدا
if ($request->filled('origin')) {
$query->where(
'origin',
'like',
'%' . $request->input('origin') . '%'
);
}
// مقصد
if ($request->filled('destination')) {
$query->where(
'destination',
'like',
'%' . $request->input('destination') . '%'
);
}
$flights = $query
->latest()
->paginate(12)
->withQueryString();
return view('flights.index', compact('flights'));
}
public function search(Request $request)
{
$query = Flight::query()
->active()
->with([
'travelType',
'tours',
]);
if ($request->filled('origin')) {
$query->where(
'origin',
'like',
'%' . $request->input('origin') . '%'
);
}
if ($request->filled('destination')) {
$query->where(
'destination',
'like',
'%' . $request->input('destination') . '%'
);
}
if ($request->filled('departure_date')) {
$query->whereDate(
'departure_date',
$request->input('departure_date')
);
}
if ($request->filled('flight_number')) {
$query->where(
'flight_number',
'like',
'%' . $request->input('flight_number') . '%'
);
}
$flights = $query
->latest()
->paginate(12)
->withQueryString();
return view('flights.index', compact('flights'));
}
public function show(Flight $flight)
{
$flight->load([
'travelType',
'tours',
]);
return view('flights.show', compact('flight'));
}
}
+21 -2
View File
@@ -2,12 +2,31 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Flight;
use App\Models\Tour;
class IndexController extends Controller
{
public function index()
{
return view('index');
$tours = Tour::query()
->where('status', 1)
->orderByDesc('created_at')
->paginate(3, ['*'], 'tours_page');
$flights = Flight::query()
->where('status', 1)
->orderByDesc('created_at')
->paginate(3, ['*'], 'flights_page');
$latestTours= Tour::latest()->limit(6)->get();
$latestFlights = Flight::latest()->limit(6)->get();
return view('index', [
'tours' => $tours,
'flights' => $flights,
compact('latestTours', 'latestFlights')
]);
}
}
+62 -39
View File
@@ -1,99 +1,122 @@
<?php
namespace App\Http\Controllers;
use App\Models\Favorite;
use App\Models\Tour;
use App\Models\Comment;
// اضافه شد
use App\Models\TravelType;
use Illuminate\Http\Request;
class TourController extends Controller
{
//لیست/آرشیو تورها با قابلیت فیلتر
public function index(Request $request)
{
$query = Tour::query()
->where('status', 1) // فقط تورهای فعال
->with(['travelType', 'flights']); // بارگذاری زودهنگام برای جلوگیری از N+1
->where('status', 1)
->with(['travelType', 'flights']);
// فیلتر بر اساس نوع سفر (travel_type_id)
if ($request->filled('travel_type')) {
$query->where('travel_type_id', $request->input('travel_type'));
}
// فیلتر جستجوی متنی (عنوان)
if ($request->filled('q')) {
$query->where('title', 'like', '%' . $request->input('q') . '%');
}
// فیلتر بازه قیمتی
if ($request->filled('price_min')) {
$query->where('price', '>=', $request->input('price_min'));
}
if ($request->filled('price_max')) {
$query->where('price', '<=', $request->input('price_max'));
}
// مرتب‌سازی بر اساس قیمت (اگر خواستی)
if ($request->filled('sort')) {
$query->orderBy('price', $request->input('sort') === 'desc' ? 'desc' : 'asc');
} else {
$query->latest(); // جدیدترین‌ها اول
$query->latest();
}
$tours = $query->paginate(12);
$travelTypes = TravelType::where('status', 1)->get(); // برای منوی فیلتر
if ($request->routeIs('index')) {
return view('tours.index', compact('tours', 'travelTypes'));
$tours = $query->latest()->limit(4)->get();
return view('index', compact('tours'));
} else {
$tours = $query->latest()->paginate(2);
$travelTypes = TravelType::where('status', 1)->get();
return view('tours.index', compact('tours', 'travelTypes'));
}
}
//حذف فیلترها و بازگشت به آرشیو کامل
public function removeFilters()
{
// ساده: فقط برگشت به آرشیو بدون هیچ پارامتری.
// (اگر از کوکی/سشن استفاده می‌کنی، اینجا آن‌ها را هم پاک کن)
return redirect()->route('tours.index');
}
//صفحه‌ی جزئیات یک تور
public function show(Tour $tour)
{
// فقط اگر تور غیرفعال بود از دسترسی جلوگیری کن (مثلاً ریدایرکت)
if ($tour->status == 0) {
if ($tour->status != 1) {
abort(404);
}
// بارگذاری پروازها + نوع سفر + نظرات تاییدشده
$tour->increment('views_count');
// بارگذاری اطلاعات مورد نیاز + نظرات تایید شده
$tour->load([
'flights',
'travelType',
// توجه: این رابطه را باید در مدل Tour تعریف کنی (morphMany)
'comments' => function ($q) {
$q->where('status', 1)->latest();
}
'comments' => function ($query) {
$query->where('status', 1)->latest();
},
'comments.user' // برای نمایش نام کاربری در نظرات
]);
// تورهای پیشنهادی مرتبط (هم‌دسته) برای نمایش کنار صفحه
$relatedTours = Tour::where('status', 1)
->where('travel_type_id', $tour->travel_type_id)
->where('id', '!=', $tour->id)
->limit(4)
->latest()
->limit(3)
->get();
return view('tours.show', compact('tour', 'relatedTours'));
$isFav = false;
if (auth()->check()) {
$isFav = Favorite::where('user_id', auth()->id())
->where('favoritable_type', Tour::class)
->where('favoritable_id', $tour->id)
->exists();
}
return view('tours.show', compact('tour', 'relatedTours', 'isFav'));
}
//جستجوی پیشنهادی (Typeahead / AJAX) — خروجی JSON
//ثبت نظر جدید برای تور
public function storeComment(Request $request, Tour $tour)
{
$request->validate([
'body' => 'required|string|min:5|max:1000',
]);
$tour->comments()->create([
'user_id' => auth()->id(),
'body' => $request->body,
'status' => 0, // در انتظار تایید
]);
return back()->with('success', 'نظر شما ثبت شد و پس از تایید مدیریت نمایش داده می‌شود.');
}
//جستجوی پیشنهادی
public function searchSuggestion(Request $request)
{
$q = $request->input('q', '');
$tours = Tour::where('status', 1)
->where('title', 'like', '%' . $q . '%')
->limit(8)
->get(['id', 'title', 'slug', 'price']);
return response()->json($tours);
return response()->json(
Tour::where('status', 1)
->where('title', 'like', '%' . $q . '%')
->limit(8)
->get(['id', 'title', 'slug', 'price'])
);
}
}
+93 -2
View File
@@ -1,19 +1,110 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\AdminStoreRequest;
use App\Http\Requests\AdminUpdateRequest;
use App\Models\Admin;
use App\Models\Permission;
use Illuminate\Support\Facades\Hash;
class AdminController extends Controller
{
public function index()
{
$admins = Admin::query()
$admins = Admin::with('permissions')
->latest()
->paginate(10);
return view('admin.admins.index', compact('admins'));
}
public function create()
{
$permissions = Permission::orderBy('id')->get();
return view(
'admin.admins.create',
compact('permissions')
);
}
public function store(AdminStoreRequest $request)
{
$data = $request->validated();
$permissions = $data['permissions'] ?? [];
unset($data['permissions']);
$data['password'] = Hash::make($data['password']);
$admin = Admin::create($data);
$admin->permissions()->sync($permissions);
return redirect()
->route('admin.admins.index')
->with('success', 'مدیر با موفقیت ایجاد شد.');
}
public function edit(Admin $admin)
{
$permissions = Permission::orderBy('id')->get();
$admin->load('permissions');
return view(
'admin.admins.edit',
compact('admin', 'permissions')
);
}
public function update(
AdminUpdateRequest $request,
Admin $admin
)
{
$data = $request->validated();
$permissions = $data['permissions'] ?? [];
unset($data['permissions']);
if (!empty($data['password'])) {
$data['password'] = Hash::make(
$data['password']
);
} else {
unset($data['password']);
}
$admin->update($data);
$admin->permissions()->sync($permissions);
return redirect()
->route('admin.admins.index')
->with('success', 'مدیر با موفقیت ویرایش شد.');
}
public function destroy(Admin $admin)
{
$admin->permissions()->detach();
$admin->delete();
return redirect()
->route('admin.admins.index')
->with('success', 'مدیر با موفقیت حذف شد.');
}
}
@@ -0,0 +1,55 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\CityStoreRequest;
use App\Http\Requests\CityUpdateRequest;
use App\Models\City;
use App\Models\Province;
use Illuminate\Http\Request;
class CityController extends Controller
{
public function index(Request $request)
{
$query = City::with('province');
if ($request->filled('province_id')) {
$query->where('province_id', $request->province_id);
}
$cities = $query->paginate(20);
$provinces = Province::all();
return view('admin.cities.index', compact('cities', 'provinces'));
}
public function create()
{
$provinces = Province::all();
return view('admin.cities.create', compact('provinces'));
}
// استفاده از CityRequest به جای Request
public function store(CityStoreRequest $request)
{
City::create($request->validated());
return redirect()->route('admin.locations.cities.index')->with('success', 'شهر با موفقیت ایجاد شد.');
}
public function edit(City $city)
{
$provinces = Province::all();
return view('admin.cities.edit', compact('city', 'provinces'));
}
public function update(CityUpdateRequest $request, City $city)
{
$city->update($request->validated());
return redirect()->route('admin.locations.cities.index')->with('success', 'شهر ویرایش شد.');
}
public function destroy(City $city)
{
$city->delete();
return back()->with('success', 'شهر حذف شد.');
}
}
@@ -3,7 +3,7 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\UpdateCommentRequest;
use App\Http\Requests\CommentUpdateRequest;
use App\Models\Comment;
class CommentController extends Controller
@@ -22,12 +22,8 @@ class CommentController extends Controller
return view('admin.comments.show', compact('comment'));
}
public function edit(Comment $comment)
{
return view('admin.comments.edit', compact('comment'));
}
public function update(UpdateCommentRequest $request, Comment $comment)
public function update(CommentUpdateRequest $request, Comment $comment)
{
$comment->update($request->validated());
@@ -7,27 +7,44 @@ use App\Models\Airport;
use App\Models\Comment;
use App\Models\Favorite;
use App\Models\Flight;
use App\Models\Payment;
use App\Models\Tour;
use App\Models\User;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\VisitsExport;
use Illuminate\Support\Carbon;
use Hekmatinasser\Verta\Verta;
class DashboardController extends Controller
{
public function index()
{
$usersCount = User::count();
$toursCount = Tour::count();
$flightsCount = Flight::count();
$airportsCount = Airport::count();
$commentsCount = Comment::count();
$favoritesCount = Favorite::count();
$paymentsCount = Payment::count();
/*
|--------------------------------------------------------------------------
| داده‌های نمودار
|--------------------------------------------------------------------------
*/
$chartLabels = [];
$chartValues = [];
for ($i = 9; $i >= 0; $i--) {
$date = Carbon::now()
->subDays($i);
$chartLabels[] = Verta::instance($date)
->format('Y/m/d');
// فعلاً برای تست
$chartValues[] = rand(5, 100);
}
return view('admin.dashboard', compact(
'usersCount',
@@ -36,7 +53,36 @@ class DashboardController extends Controller
'airportsCount',
'commentsCount',
'favoritesCount',
'paymentsCount'
'chartLabels',
'chartValues'
));
}
public function exportExcel()
{
$users = User::select(
'id',
'first_name',
'last_name',
'email',
'mobile',
'created_at'
)->get();
$rows = $users->map(fn ($user) => [
$user->id,
$user->first_name,
$user->last_name,
$user->email,
$user->mobile,
$user->created_at
? Verta::instance($user->created_at)->format('Y/m/d')
: '-',
])->toArray();
return Excel::download(
new VisitsExport($rows),
'users-report-' . now()->format('Y-m-d') . '.xlsx'
);
}
}
+64 -65
View File
@@ -4,6 +4,12 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\FlightStoreRequest;
use App\Http\Requests\FlightUpdateRequest;
use App\Models\Flight;
use App\Models\TravelType;
use Illuminate\Http\Request;
class FlightController extends Controller
@@ -13,103 +19,96 @@ class FlightController extends Controller
*/
public function index()
{
return 'Flights index';
}
abort_unless(auth('admin')->user()?->canManageFlights('view'), 403);
$flights = Flight::query()
->with('travelType')
->latest()
->when(request('q'), function ($query, $q) {
$query->where(function ($query) use ($q) {
$query->where('flight_number', 'like', "%{$q}%")
->orWhere('airline_name', 'like', "%{$q}%")
->orWhere('origin', 'like', "%{$q}%")
->orWhere('destination', 'like', "%{$q}%");
});
})
->when(request('status') !== null, function ($query) {
$query->where('status', request('status'));
})
->paginate(10)
->withQueryString();
$travelTypes = TravelType::where('status', 1)->get();
return view('admin.flights.index', compact('flights', 'travelTypes'));
}
/**
* نمایش فرم ایجاد پرواز
*/
public function create()
{
return 'Flights create';
}
abort_unless(auth('admin')->user()?->canManageFlights('create'), 403);
$travelTypes = TravelType::where('status', 1)->get();
return view('admin.flights.create', compact('travelTypes'));
}
/**
* ذخیره پرواز جدید
*/
public function store(Request $request)
public function store(FlightStoreRequest $request)
{
//
}
abort_unless(auth('admin')->user()?->canManageFlights('create'), 403);
Flight::create($request->validated());
return redirect()->route('admin.flights.index')
->with('success', 'پرواز با موفقیت ثبت شد.');
}
/**
* نمایش جزئیات یک پرواز
*/
public function show($flight)
public function show(Flight $flight)
{
return 'Flights show';
abort_unless(auth('admin')->user()?->canManageFlights('view'), 403);
return view('admin.flights.show', compact('flight'));
}
/**
* نمایش فرم ویرایش پرواز
*/
public function edit($flight)
public function edit(Flight $flight)
{
return 'Flights edit';
abort_unless(auth('admin')->user()?->canManageFlights('update'), 403);
$travelTypes = TravelType::where('status', 1)->get();
return view('admin.flights.edit', compact('flight', 'travelTypes'));
}
/**
* بروزرسانی پرواز
*/
public function update(Request $request, $flight)
public function update(FlightUpdateRequest $request, Flight $flight)
{
//
}
abort_unless(auth('admin')->user()?->canManageFlights('update'), 403);
$flight->update($request->validated());
return redirect()->route('admin.flights.index')
->with('success', 'پرواز با موفقیت به‌روزرسانی شد.');
}
/**
* حذف پرواز
*/
public function destroy($flight)
public function destroy(Flight $flight)
{
//
abort_unless(auth('admin')->user()?->canManageFlights('delete'), 403);
$flight->delete();
return redirect()->route('admin.flights.index')
->with('success', 'پرواز با موفقیت حذف شد.');
}
}
//
//namespace App\Http\Controllers\Admin;
//
//use App\Http\Controllers\Controller;
//use Illuminate\Http\Request;
//
//class FlightController extends Controller
//{
// public function index()
// {
// return 'Flights index';
// }
//
// public function create()
// {
// return 'Flights create';
// }
//
// public function store()
// {
// //
// }
//
// public function show($flight)
// {
// return 'Flights show';
// }
//
// public function edit($flight)
// {
// return 'Flights edit';
// }
//
// public function update($flight)
// {
// //
// }
//
// public function destroy($flight)
// {
// //
// }
//}
@@ -0,0 +1,45 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\ProvinceUpdateRequest;
use App\Models\Province;
class ProvinceController extends Controller
{
public function index()
{
$provinces = Province::paginate(20);
return view('admin.provinces.index', compact('provinces'));
}
public function create()
{
return view('admin.provinces.create');
}
public function store(ProvinceUpdateRequest $request)
{
Province::create($request->validated());
return redirect()->route('admin.locations.provinces.index')->with('success', 'استان با موفقیت ایجاد شد.');
}
public function edit(Province $province)
{
return view('admin.provinces.edit', compact('province'));
}
public function update(ProvinceUpdateRequest $request, Province $province)
{
$province->update($request->validated());
return redirect()->route('admin.locations.provinces.index')->with('success', 'استان ویرایش شد.');
}
public function destroy(Province $province)
{
$province->delete();
return back()->with('success', 'استان حذف شد.');
}
}
+230 -27
View File
@@ -4,55 +4,258 @@ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\TourStoreRequest;
use App\Models\Flight;
use App\Models\Tour;
use Illuminate\Http\Request;
use App\Models\TravelType;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class TourController extends Controller
{
public function index()
{
$tour = Tour::latest()->paginate(10);
return view('admin.tours.index', compact($tour));
}
// ->where('status', 2)
$tours = Tour::latest()->paginate(20);
public function create()
// آخرین پروازهای تایید شده
$flights = Flight::where('status', 2)
->latest()
->paginate(3);
return view('admin.tours.index', compact('tours', 'flights'));
}
/**
* فرم ایجاد تور
*/
public function create()
{
return view('admin.tours.create');
}
$travelTypes = TravelType::all();
public function store(TourStoreRequest $request)
return view('admin.tours.create', compact('travelTypes'));
}
/**
* ذخیره تور جدید
*/
public function store(TourStoreRequest $request)
{
DB::beginTransaction();
try {
$data = $request->validated();
// ساخت slug در صورت خالی بودن
if (empty($data['slug'])) {
$data['slug'] = Str::slug($data['title']);
}
$data['status'] = 2;
// ایجاد تور
$tour = Tour::create($data);
// آپلود تصویر
if ($request->hasFile('image')) {
$image = $request->file('image');
$newFileName =
time()
. '.tour-image'
. rand(11111, 99999)
. '.'
. $image->extension();
$path = $image->storeAs(
'tours',
$newFileName,
'public'
);
$tour->update([
'image' => $path
]);
}
DB::commit();
return redirect()
->route('admin.tours.index')
->with('success', 'تور با موفقیت ایجاد شد.');
} catch (\Exception $exception) {
DB::rollBack();
Log::error($exception);
return back()
->withInput()
->withErrors([
'general' => 'خطایی در ثبت تور رخ داد.'
]);
}
}
Tour::create($request->validated());
return view('admin.tours.index')
->with('success', 'تور با موفقیت ایجاد شد.');
}
public function show(Tour $tour)
{
return view('admin.tours.show', compact('tour'));
}
public function edit(Tour $tour)
{
return view('admin.tours.edit', compact('tour'));
}
public function update(TourStoreRequest $request, Tour $tour)
{
$tour->update($request->validated());
$travelTypes = TravelType::all();
return redirect()->route('admin.tours.index')
->with('success', 'تور با موفقیت به‌روزرسانی شد.');
return view(
'admin.tours.edit',
compact('tour', 'travelTypes')
);
}
public function update(
TourStoreRequest $request,
Tour $tour
) {
DB::beginTransaction();
try {
$data = $request->validated();
// ساخت slug
if (empty($data['slug'])) {
$data['slug'] = Str::slug($data['title']);
}
if (!isset($data['status'])) {
$data['status'] = $tour->status ?? 2;
}
// اگر تصویر جدید آپلود شده
if ($request->hasFile('image')) {
// حذف تصویر قبلی
if (
$tour->image &&
Storage::disk('public')->exists($tour->image)
) {
Storage::disk('public')->delete($tour->image);
}
$image = $request->file('image');
$newFileName =
time()
. '.tour-image'
. rand(11111, 99999)
. '.'
. $image->extension();
$path = $image->storeAs(
'tours',
$newFileName,
'public'
);
$data['image'] = $path;
}
// بروزرسانی
$tour->update($data);
DB::commit();
return redirect()
->route('admin.tours.index')
->with(
'success',
'تور با موفقیت به‌روزرسانی شد.'
);
} catch (\Exception $exception) {
DB::rollBack();
Log::error($exception);
return back()
->withInput()
->withErrors([
'general' =>
'خطایی در به‌روزرسانی تور رخ داد.'
]);
}
}
public function removeImage(Tour $tour)
{
try {
if (
$tour->image &&
Storage::disk('public')->exists($tour->image)
) {
Storage::disk('public')->delete($tour->image);
}
$tour->update([
'image' => null
]);
return back()->with(
'success',
'تصویر تور با موفقیت حذف شد.'
);
} catch (\Exception $exception) {
Log::error($exception);
return back()->withErrors([
'general' =>
'حذف تصویر با خطا مواجه شد.'
]);
}
}
public function destroy(Tour $tour)
{
$tour->delete();
try {
return redirect()->route('admin.tours.index')
->with('success', 'تور با موفقیت حذف شد.');
}
// حذف تصویر
if (
$tour->image &&
Storage::disk('public')->exists($tour->image)
) {
Storage::disk('public')->delete($tour->image);
}
public function removeImage(Tour $tour, $image)
{
// منطق حذف تصویر — بسته به جدول تصاویر
return back()->with('success', 'تصویر حذف شد.');
// حذف تور
$tour->delete();
return redirect()
->route('admin.tours.index')
->with(
'success',
'تور با موفقیت حذف شد.'
);
} catch (\Exception $exception) {
Log::error($exception);
return back()->withErrors([
'general' =>
'حذف تور با خطا مواجه شد.'
]);
}
}
}
@@ -3,9 +3,79 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\TravelTypeStoreRequest;
use App\Http\Requests\TravelTypeUpdateRequest;
use App\Models\TravelType;
use Illuminate\Http\Request;
class TravelTypeController extends Controller
{
public function index(Request $request)
{
abort_unless(auth('admin')->user()->canManageTravelTypes('view'), 403);
$query = TravelType::query();
// جستجو بر اساس عنوان / اسلاگ
if ($request->filled('search')) {
$query->where(function ($q) use ($request) {
$q->where('title', 'like', '%' . $request->search . '%')
->orWhere('slug', 'like', '%' . $request->search . '%');
});
}
// فیلتر وضعیت
if ($request->filled('status')) {
$query->where('status', $request->status);
}
$travelTypes = $query->latest()->paginate(10)->withQueryString();
return view('admin.travel_types.index', compact('travelTypes'));
}
public function create()
{
abort_unless(auth('admin')->user()->canManageTravelTypes('create'), 403);
return view('admin.travel_types.create');
}
public function store(TravelTypeStoreRequest $request)
{
abort_unless(auth('admin')->user()->canManageTravelTypes('create'), 403);
TravelType::create($request->validated());
return redirect()->route('admin.travelTypes.index')
->with('success', 'نوع سفر با موفقیت ثبت شد.');
}
public function edit(TravelType $travelType)
{
abort_unless(auth('admin')->user()->canManageTravelTypes('edit'), 403);
return view('admin.travel_types.edit', compact('travelType'));
}
public function update(TravelTypeUpdateRequest $request, TravelType $travelType)
{
abort_unless(auth('admin')->user()->canManageTravelTypes('edit'), 403);
$travelType->update($request->validated());
return redirect()->route('admin.travelTypes.index')
->with('success', 'نوع سفر با موفقیت ویرایش شد.');
}
public function destroy(TravelType $travelType)
{
abort_unless(auth('admin')->user()->canManageTravelTypes('delete'), 403);
$travelType->delete();
return redirect()->route('admin.travelTypes.index')
->with('success', 'نوع سفر با موفقیت حذف شد.');
}
}
+71 -15
View File
@@ -1,45 +1,101 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\UserStoreRequest;
use App\Http\Requests\UserPasswordUpdateRequest;
use App\Http\Requests\UserUpdateRequest;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
public function index()
public function index(Request $request)
{
$users = User::latest()->paginate(15);
// چک دسترسی: فقط مدیرانی که مجوز «مشاهده کاربران» دارند
// abort_unless(auth('admin')->user()->canManageUsers('view'), 403);
$query = User::query();
// جستجوی کلی: نام / ایمیل / موبایل
if ($request->filled('search')) {
$query->where(function ($q) use ($request) {
$q->where('first_name', 'like', '%' . $request->search . '%')
->orWhere('email', 'like', '%' . $request->search . '%')
->orWhere('mobile', 'like', '%' . $request->search . '%');
});
}
// فیلتر وضعیت
if ($request->filled('status')) {
$query->where('status', $request->status);
}
// فیلتر تاریخ عضویت
if ($request->filled('from_date')) {
$query->whereDate('created_at', '>=', $request->from_date);
}
if ($request->filled('to_date')) {
$query->whereDate('created_at', '<=', $request->to_date);
}
// withQueryString => فیلترها هنگام صفحه‌بندی حفظ می‌شوند
$users = $query->latest()->paginate(10)->withQueryString();
return view('admin.users.index', compact('users'));
}
public function show(User $user)
{
return view('admin.users.show', compact('user'));
}
public function edit(User $user)
{
abort_unless(auth('admin')->user()->canManageUsers('edit'), 403);
return view('admin.users.edit', compact('user'));
}
public function update(UserStoreRequest $request, User $user)
public function update(UserUpdateRequest $request, User $user)
{
$user->update($request->validated());
// abort_unless(auth('admin')->user()->canManageUsers('edit'), 403);
return redirect()
->route('admin.users.index')
->with('success', 'کاربر با موفقیت بروزرسانی شد.');
$data = $request->validated();
// اگر رمز خالی بود تغییرش نده (گزینه‌ای)
unset($data['password']);
$user->update($data);
return redirect()->route('admin.users.index')
->with('success', 'اطلاعات کاربر با موفقیت ویرایش شد.');
}
public function destroy(User $user)
{
abort_unless(auth('admin')->user()->canManageUsers('delete'), 403);
$user->delete();
return redirect()
->route('admin.users.index')
return redirect()->route('admin.users.index')
->with('success', 'کاربر با موفقیت حذف شد.');
}
public function changePassword(User $user)
{
// abort_unless(auth('admin')->user()->canManageUsers('password'), 403);
return view('admin.users.change-password', compact('user'));
}
public function updatePassword(UserPasswordUpdateRequest $request, User $user)
{
// abort_unless(auth('admin')->user()->canManageUsers('password'), 403);
$user->update([
'password' => Hash::make($request->password),
]);
return redirect()->route('admin.users.index')
->with('success', 'رمز عبور کاربر با موفقیت تغییر کرد.');
}
}
+78
View File
@@ -0,0 +1,78 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class AdminStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'full_name' => [
'required',
'string',
'max:100',
],
'username' => [
'required',
'string',
'alpha_num',
'min:3',
'max:32',
'unique:admins,username',
],
'email' => [
'required',
'email',
'max:150',
'unique:admins,email',
],
'mobile' => [
'required',
'string',
'digits:11',
'unique:admins,mobile',
],
'password' => [
'required',
'string',
'min:8',
'max:255',
],
'status' => [
'required',
'boolean',
],
'permissions' => [
'nullable',
'array',
],
'permissions.*' => [
'exists:permissions,id',
],
];
}
}
+81
View File
@@ -0,0 +1,81 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class AdminUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$admin = $this->route('admin');
return [
'full_name' => [
'required',
'string',
'max:100',
],
'username' => [
'required',
'string',
'alpha_num',
'min:3',
'max:32',
Rule::unique('admins', 'username')->ignore($admin),
],
'email' => [
'required',
'email',
'max:150',
Rule::unique('admins', 'email')->ignore($admin),
],
'mobile' => [
'required',
'string',
'digits:11',
Rule::unique('admins', 'mobile')->ignore($admin),
],
'password' => [
'nullable',
'string',
'min:8',
'max:255',
],
'status' => [
'required',
'boolean',
],
'permissions' => [
'nullable',
'array',
],
'permissions.*' => [
'exists:permissions,id',
],
];
}
}
+20 -14
View File
@@ -15,6 +15,16 @@ class AirportStoreRequest extends FormRequest
return true;
}
protected function prepareForValidation(): void
{
// کد فرودگاه همیشه با حروف بزرگ ذخیره شود (IATA)
if ($this->has('code')) {
$this->merge([
'code' => strtoupper($this->input('code')),
]);
}
}
/**
* Get the validation rules that apply to the request.
*
@@ -35,7 +45,7 @@ class AirportStoreRequest extends FormRequest
'string',
'max:100'
],
'country' =>
'province' =>
[
'required',
'string',
@@ -50,17 +60,13 @@ class AirportStoreRequest extends FormRequest
];
}
// public function messages(): array
// {
// return [
// 'name.required' => 'نام فرودگاه الزامی است.',
// 'name.max' => 'نام فرودگاه حداکثر ۱۵۰ کاراکتر باشد.',
// 'city.required' => 'نام شهر الزامی است.',
// 'city.max' => 'نام شهر حداکثر ۱۰۰ کاراکتر باشد.',
// 'country.required' => 'نام کشور الزامی است.',
// 'country.max' => 'نام کشور حداکثر ۱۰۰ کاراکتر باشد.',
// 'code.required' => 'کد فرودگاه (IATA) الزامی است.',
// 'code.max' => 'کد فرودگاه حداکثر ۱۰ کاراکتر باشد.',
// ];
// }
public function attributes(): array
{
return [
'name' => 'نام فرودگاه',
'city' => 'شهر',
'country' => 'کشور',
'code' => 'کد فرودگاه',
];
}
}
@@ -0,0 +1,45 @@
<?php
namespace App\Http\Requests\Auth;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class LoginPostRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
// 'email' => [
// 'required',
// 'email',
// ],
'username' => [
'required',
'string',
],
'password' => [
'required',
'string',
],
];
}
}
@@ -0,0 +1,131 @@
<?php
namespace App\Http\Requests\Auth;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class RegisterPostRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'first_name' => [
'required',
'persian_alpha',
'string',
'min:3',
'max:100'
],
'last_name' => [
'required',
'persian_alpha',
'string',
'max:100'
],
'national_code' => [
'required',
// 'ir_national_id',
'digits:10',
'unique:users,national_code',
],
'gender' => [
'required',
'integer',
Rule::in([1, 2]),
],
'marital_status' => [
'required',
'integer',
Rule::in([1, 2, 3]),
],
'spouse_name' => [
'nullable',
'string',
'max:200',
'required_if:marital_status,2'
],
'mobile' => [
'required',
'digits:11',
'ir_mobile:zero',
'unique:users,mobile',
],
'email' => [
'required',
'email',
'max:150',
'unique:users,email',
],
'username' => [
'required',
'persian_not_accept',
'string',
'min:3',
'max:50',
'unique:users,username',
],
'password' => [
'required',
'string',
'min:8',
'confirmed',
],
'image' => [
'nullable',
'image',
'mimes:jpg,jpeg,png,webp',
'max:800',
],
'province_id' => [
'nullable',
'integer',
],
'city_id' => [
'nullable',
'integer',
],
];
}
}
+39
View File
@@ -0,0 +1,39 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class CityStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' =>
[
'required',
'string',
'max:100'
],
'province_id' =>
[
'required',
'exists:provinces,id'
],
];
}
}
+42
View File
@@ -0,0 +1,42 @@
<?php
namespace App\Http\Requests;
use App\Enums\PaymentStatus;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class CityUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' =>
[
'required',
'string',
'max:100'
],
'province_id' =>
[
'required',
'exists:provinces,id'
],
];
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class CommentStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'body' =>
[
'required',
'string',
'min:3',
'max:1000'
],
];
}
}
+3 -1
View File
@@ -27,7 +27,9 @@ class CommentUpdateRequest extends FormRequest
'body' =>
[
'required',
'string'
'string',
'min:3',
'max:1000'
],
'status' =>
[
@@ -0,0 +1,66 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class EditProfilePostRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
// دریافت آیدی کاربر از طریق سشن لاگین
$userId = auth()->id();
return [
'first_name' =>
[
'required',
'string',
'max:100'
],
'last_name' =>
[
'required',
'string',
'max:100'
],
'username' =>
[
'required',
'string',
'max:50',
'unique:users,username,' . $userId,
],
'email' => [
'required',
'email',
'max:150',
'unique:users,email,' . $userId,
],
'password' =>
[
'nullable',
'string',
'min:8',
'confirmed'
],
];
}
}
+121
View File
@@ -0,0 +1,121 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class FlightStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
// return true;
return auth('admin')->user()?->canManageFlights('create') ?? false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'travel_type_id' =>
[
'required',
'exists:travel_types,id'
],
'flight_number' => [
'required',
'string',
'max:50'
],
'airline_name' =>
[
'required',
'string',
'max:150'
],
'origin' =>
[
'required',
'string',
'max:150'
],
'destination' =>
[
'required',
'string',
'max:100'
],
'departure_date' =>
[
'required',
'date'
],
'departure_time' =>
[
'required',
'date_format:H:i'
],
'arrival_date' =>
[
'required',
'date',
'after_or_equal:departure_date'
],
'arrival_time' =>
[
'required',
'date_format:H:i'
],
'duration' =>
[
'required',
'string',
'max:50'
],
'price' =>
[
'required',
'numeric',
'min:0'
],
'capacity' =>
[
'required',
'integer',
'min:1'
],
'status' =>
[
'required',
'in:0,1'
],
];
}
public function messages(): array
{
return [
'travel_type_id.required' => 'نوع سفر را انتخاب کنید.',
'travel_type_id.exists' => 'نوع سفر انتخاب‌شده معتبر نیست.',
'flight_number.required' => 'شماره پرواز الزامی است.',
'airline_name.required' => 'نام ایرلاین الزامی است.',
'origin.required' => 'مبدأ الزامی است.',
'destination.required' => 'مقصد الزامی است.',
'departure_date.required' => 'تاریخ حرکت الزامی است.',
'departure_date.after_or_equal:today' => 'تاریخ حرکت نمی‌تواند قبل از امروز باشد.',
'arrival_date.required' => 'تاریخ رسیدن الزامی است.',
'arrival_date.after_or_equal:departure_date' => 'تاریخ رسیدن باید بعد از تاریخ حرکت باشد.',
'price.required' => 'قیمت الزامی است.',
'price.min' => 'قیمت نمی‌تواند منفی باشد.',
'capacity.min' => 'ظرفیت باید حداقل ۱ باشد.',
];
}
}
+101
View File
@@ -0,0 +1,101 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class FlightUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'travel_type_id' =>
[
'required',
'exists:travel_types,id'
],
'flight_number' =>
[
'required',
'string',
'max:50'
],
'airline_name' =>
[
'required',
'string',
'max:150'
],
'origin' =>
[
'required',
'string',
'max:150'
],
'destination' =>
[
'required',
'string',
'max:100'
],
'departure_date' =>
[
'required',
'date'
],
'departure_time' =>
[
'required',
'date_format:H:i'
],
'arrival_date' =>
[
'required',
'date',
'after_or_equal:departure_date'
],
'arrival_time' =>
[
'required',
'date_format:H:i'
],
'duration' =>
[
'required',
'string',
'max:50'
],
'price' =>
[
'required',
'numeric',
'min:0'
],
'capacity' =>
[
'required',
'integer',
'min:1'
],
'status' =>
[
'required',
'in:0,1'
],
];
}
}
@@ -0,0 +1,37 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class ProvinceUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' =>
[
'required',
'string',
'max:100'
],
];
}
}
+1 -3
View File
@@ -29,9 +29,7 @@ class SettingUpdateRequest extends FormRequest
$this->merge($filtered);
}
/**
* قوانین اعتبارسنجی.
*/
public function rules(): array
{
$codes = Setting::pluck('code')->all();
+49 -37
View File
@@ -23,57 +23,69 @@ class TourStoreRequest extends FormRequest
public function rules(): array
{
return [
'travel_type_id' =>
[
'required',
'exists:travel_types,id'
],
// 'travel_type_id' =>
// [
// 'nullable',
// 'exists:travel_types,id'
// ],
'title' =>
[
'required',
'string',
'max:200'
],
'slug' =>
['required', 'string',
'max:200',
'regex:/^[a-z0-9-]+$/',
'unique:tours,slug,' . $this->tour
],
// 'slug' =>
// ['nullable', 'string',
// 'max:200',
// 'regex:/^[a-z0-9-]+$/',
// 'unique:tours,slug,' . $this->tour
// ],
'description' =>
[
'required',
'string'
],
'duration' =>
[
'required',
'string',
'max:50'
],
'start_date' =>
[
'required',
'date'
],
'end_date' =>
[
'required',
'date',
'after_or_equal:start_date'
],
// 'description' =>
// [
// 'nullable',
// 'string'
// ],
// 'duration' =>
// [
// 'nullable',
// 'string',
// 'max:50'
// ],
// 'start_date' =>
// [
// 'nullable',
// 'date'
// ],
// 'end_date' =>
// [
// 'nullable',
// 'date',
// 'after_or_equal:start_date'
// ],
'price' =>
[
'required',
'numeric',
'min:0'
],
'capacity' =>
// 'capacity' =>
// [
// 'nullable',
// 'integer',
// 'min:0'],
'images' =>
[
'required',
'integer',
'min:0'],
'nullable',
'array'
],
'images.*' =>
[
'image',
'mimes:jpeg,png,jpg,webp',
'max:2048'
],
'status' =>
[
'nullable',
@@ -0,0 +1,46 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class TravelTypeStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'title' =>
[
'required',
'string',
'max:100'
],
'slug' =>
[
'required',
'string',
'max:150',
'unique:travel_types,slug'
],
'status' =>
[
'sometimes',
'in:0,1'
],
];
}
}
@@ -0,0 +1,45 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class TravelTypeUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'title' =>
['required',
'string',
'max:100'
],
'slug' =>
[
'required',
'string',
'max:150',
Rule::unique('travel_types', 'slug')->ignore($this->travelType)],
'status' =>
[
'sometimes',
'in:0,1'
],
];
}
}
@@ -0,0 +1,41 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class UserPasswordUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
// چک کردن رمز فعلی کاربر
'current_password' =>
[
'nullable',
'current_password'
],
'password' =>
[
'required',
'string',
'min:8',
'confirmed'
],
];
}
}
-11
View File
@@ -47,15 +47,4 @@ class UserStoreRequest extends FormRequest
],
];
}
// public function messages(): array
// {
// return [
// 'name.required' => 'نام و نام خانوادگی الزامی است.',
// 'email.required' => 'ایمیل الزامی است.',
// 'email.email' => 'فرمت ایمیل معتبر نیست.',
// 'email.unique' => 'این ایمیل قبلاً ثبت شده است.',
// 'password.required' => 'رمز عبور الزامی است.',
// 'password.confirmed' => 'تکرار رمز عبور مطابقت ندارد.',
// ];
// }
}
+59
View File
@@ -0,0 +1,59 @@
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class UserUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'first_name' =>
[
'required',
'string',
'max:100'
],
'last_name' =>
[
'required',
'string',
'max:100'
],
'email' =>
[
'nullable',
'email',
'max:255',
'unique:users,email,' . $this->user->id,
],
'mobile' =>
[
'nullable',
'string',
'max:20'
],
'status' =>
[
'required',
'boolean'
],
];
}
}
+40 -5
View File
@@ -1,17 +1,16 @@
<?php
/**
* Created by Reliese Model.
*/
namespace App\Models;
use App\Enums\AdminStatus;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
//use Illuminate\Foundation\Auth\Admin as Authenticate;
//use Illuminate\Foundation\Auth\Admin as Authenticate;
/**
* Class Admin
@@ -28,8 +27,10 @@ use Illuminate\Database\Eloquent\Model;
*
* @package App\Models
*/
class Admin extends User
class Admin extends Authenticatable
{
use HasFactory;
protected $table = 'admins';
public static $snakeAttributes = false;
@@ -40,6 +41,7 @@ class Admin extends User
protected $hidden = [
'password',
'remember_token',
];
protected $fillable = [
@@ -50,4 +52,37 @@ class Admin extends User
'password',
'status',
];
public function permissions()
{
return $this->belongsToMany(
Permission::class,
'admin_permission',
'admin_id',
'permission_id'
);
}
/**
* بررسی دسترسی مدیر به ماژول مدیریت کاربران
*/
public function canManageUsers(string $action): bool
{
return $this->status == 1;
}
public function canManageTravelTypes(string $action): bool
{
return $this->status == 1;
}
public function canManageFlights(string $action): bool
{
return $this->status == 1;
}
public function canManageTours(string $action): bool
{
return $this->status == 1;
}
}
+5 -3
View File
@@ -6,6 +6,7 @@
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
/**
@@ -14,21 +15,22 @@ use Illuminate\Database\Eloquent\Model;
* @property int $id
* @property string $name
* @property string $city
* @property string $country
* @property string $province
* @property string $code
* @property Carbon $created_at
* @property Carbon $updated_at
*
* @package App\Models
*/
class Airport extends Model
{
protected $table = 'airports';
public $timestamps = false;
public static $snakeAttributes = false;
protected $fillable = [
'name',
'city',
'country',
'province',
'code'
];
}
+84
View File
@@ -0,0 +1,84 @@
<?php
/**
* Created by Reliese Model.
*/
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
/**
* Class Booking
*
* @property int $id
* @property int $user_id
* @property int|null $tour_id
* @property int|null $flight_id
* @property string $booking_code
* @property string $first_name
* @property string $last_name
* @property string|null $national_code
* @property string $mobile
* @property string|null $email
* @property int $passengers
* @property float $price
* @property int $status
* @property string $payment_status
* @property string|null $notes
* @property Carbon $created_at
* @property Carbon $updated_at
*
* @property User $user
* @property Tour|null $tour
* @property Flight|null $flight
*
* @package App\Models
*/
class Booking extends Model
{
protected $table = 'bookings';
public static $snakeAttributes = false;
protected $casts = [
'user_id' => 'int',
'tour_id' => 'int',
'flight_id' => 'int',
'passengers' => 'int',
'price' => 'float',
'status' => 'int'
];
protected $fillable = [
'user_id',
'tour_id',
'flight_id',
'booking_code',
'first_name',
'last_name',
'national_code',
'mobile',
'email',
'passengers',
'price',
'status',
'payment_status',
'notes'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function tour()
{
return $this->belongsTo(Tour::class);
}
public function flight()
{
return $this->belongsTo(Flight::class);
}
}
+43
View File
@@ -0,0 +1,43 @@
<?php
/**
* Created by Reliese Model.
*/
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
/**
* Class City
*
* @property int $id
* @property int $province_id
* @property string $name
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @property Province $province
*
* @package App\Models
*/
class City extends Model
{
protected $table = 'cities';
public static $snakeAttributes = false;
protected $casts = [
'province_id' => 'int'
];
protected $fillable = [
'province_id',
'name'
];
public function province()
{
return $this->belongsTo(Province::class);
}
}
+1 -11
View File
@@ -53,19 +53,9 @@ class Comment extends Model
return $this->belongsTo(User::class);
}
// ✅ رابطه پلیمورفیک: نظر میتونه متعلق به محصول، خبر، پست و... باشه
// رابطه پلیمورفیک
public function commentable(): MorphTo
{
return $this->morphTo();
}
// public function comment()
// {
// return $this->belongsTo(Comment::class, 'commentable_id');
// }
//
// public function comments()
// {
// return $this->hasMany(Comment::class, 'commentable_id');
// }
}
+1 -1
View File
@@ -47,7 +47,7 @@ class Favorite extends Model
return $this->belongsTo(User::class);
}
// رابطه پلیمورفیک: علاقهمندی میتونه به محصول، خبر، پست و... وصل باشه
// رابطه پلیمورفیک
public function favoritable(): MorphTo
{
return $this->morphTo();
+80 -63
View File
@@ -1,75 +1,92 @@
<?php
/**
* Created by Reliese Model.
*/
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Model;
/**
* Class Flight
*
* @property int $id
* @property int $travel_type_id
* @property string $flight_number
* @property string $airline_name
* @property string $origin
* @property string $destination
* @property Carbon $departure_date
* @property Carbon $departure_time
* @property Carbon $arrival_date
* @property Carbon $arrival_time
* @property string $duration
* @property float $price
* @property int $capacity
* @property int $status
* @property Carbon $created_at
* @property Carbon $updated_at
*
* @property Collection|Tour[] $tours
*
* @package App\Models
*/
class Flight extends Model
{
protected $table = 'flights';
public static $snakeAttributes = false;
protected $table = 'flights';
protected $casts = [
'travel_type_id' => 'int',
'departure_date' => 'datetime',
'departure_time' => 'datetime',
'arrival_date' => 'datetime',
'arrival_time' => 'datetime',
'price' => 'float',
'capacity' => 'int',
'status' => 'int'
];
protected $casts = [
'travel_type_id' => 'integer',
protected $fillable = [
'travel_type_id',
'flight_number',
'airline_name',
'origin',
'destination',
'departure_date',
'departure_time',
'arrival_date',
'arrival_time',
'duration',
'price',
'capacity',
'status'
];
'departure_date' => 'date',
'arrival_date' => 'date',
public function tours()
{
return $this->belongsToMany(Tour::class, 'tour_flights')
->withPivot('id')
->withTimestamps();
}
'departure_time' => 'datetime',
'arrival_time' => 'datetime',
'price' => 'decimal:2',
'capacity' => 'integer',
'status' => 'integer',
];
protected $fillable = [
'travel_type_id',
'flight_number',
'airline_name',
'origin',
'destination',
'departure_date',
'departure_time',
'arrival_date',
'arrival_time',
'duration',
'price',
'capacity',
'status',
];
public function travelType()
{
return $this->belongsTo(
TravelType::class,
'travel_type_id'
);
}
public function tours()
{
return $this->belongsToMany(
Tour::class,
'tour_flights'
)
->withPivot('id')
->withTimestamps();
}
public function statusLabel(): string
{
return (int)$this->status === 1
? 'فعال'
: 'غیرفعال';
}
public function isActive(): bool
{
return (int)$this->status === 1;
}
#[Scope]
public function scopeActive($query)
{
return $query->where('status', 1);
}
public function getRouteKeyName(): string
{
return 'id';
}
}
+48
View File
@@ -0,0 +1,48 @@
<?php
/**
* Created by Reliese Model.
*/
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
/**
* Class Permission
*
* @property int $id
* @property string $name
* @property string $slug
* @property string|null $description
* @property Carbon $created_at
* @property Carbon $updated_at
*
* @property Collection|Admin[] $admins
*
* @package App\Models
*/
class Permission extends Model
{
protected $table = 'permissions';
public static $snakeAttributes = false;
protected $fillable = [
'name',
'slug',
'description',
];
public function admins()
{
return $this->belongsToMany(
Admin::class,
'admin_permission',
'permission_id',
'admin_id'
);
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* Created by Reliese Model.
*/
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
/**
* Class Province
*
* @property int $id
* @property string $name
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @property Collection|City[] $cities
*
* @package App\Models
*/
class Province extends Model
{
protected $table = 'provinces';
public static $snakeAttributes = false;
protected $fillable = [
'name'
];
public function cities()
{
return $this->hasMany(City::class);
}
}
+38 -17
View File
@@ -14,20 +14,22 @@ use Illuminate\Database\Eloquent\Model;
* Class Tour
*
* @property int $id
* @property int $travel_type_id
* @property int|null $travel_type_id
* @property string $title
* @property string $slug
* @property string $description
* @property string $duration
* @property Carbon $start_date
* @property Carbon $end_date
* @property string|null $slug
* @property string|null $image
* @property string|null $description
* @property string|null $duration
* @property Carbon|null $start_date
* @property Carbon|null $end_date
* @property float $price
* @property int $capacity
* @property int|null $capacity
* @property int $views_count
* @property int $status
* @property Carbon $created_at
* @property Carbon $updated_at
*
* @property TravelType $travelType
* @property TravelType|null $travelType
* @property Collection|Flight[] $flights
*
* @package App\Models
@@ -43,6 +45,7 @@ class Tour extends Model
'end_date' => 'datetime',
'price' => 'float',
'capacity' => 'int',
'views_count' => 'int',
'status' => 'int'
];
@@ -50,12 +53,14 @@ class Tour extends Model
'travel_type_id',
'title',
'slug',
'image',
'description',
'duration',
'start_date',
'end_date',
'price',
'capacity',
'views_count',
'status'
];
@@ -71,7 +76,8 @@ class Tour extends Model
->withTimestamps();
}
//اضافه شده (بعدا بررسی بشه)
// در فایل App\Models\Tour.php و App\Models\Flight.php
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
@@ -79,19 +85,34 @@ class Tour extends Model
public function favorites()
{
return $this->morphMany(Favorite::class, 'favoritable');
return $this->morphMany(\App\Models\Favorite::class, 'favoritable');
}
public function files()
public function isFavoritedBy($user)
{
return $this->morphMany(File::class, 'fileable');
if (!$user) return false;
// استفاده از فیلدهای پلی‌مورفیک به جای tour_id
return $this->favorites()
->where('user_id', $user->id)
->where('favoritable_id', $this->id)
->where('favoritable_type', Tour::class)
->exists();
}
public function getRouteKeyName()
protected static function booted()
{
return 'slug';
static::creating(function ($tour) {
// اگر مقداری تعیین نشده بود، پیش‌فرض‌ها را اعمال کن
if (is_null($tour->views_count)) {
$tour->views_count = 0;
}
if (is_null($tour->status)) {
// فرض بر اینکه 0 یعنی غیرفعال یا پیش‌نویس
$tour->status = 0;
}
});
}
}
+27 -2
View File
@@ -7,8 +7,9 @@
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Auth\User as Authenticate;
use Illuminate\Database\Eloquent\Model;
/**
* Class User
@@ -21,22 +22,34 @@ use Illuminate\Foundation\Auth\User as Authenticate;
* @property string $password
* @property string|null $national_code
* @property Carbon|null $birth_date
* @property bool $gender
* @property bool $marital_status
* @property string|null $spouse_name
* @property string|null $image
* @property string $username
* @property int $province_id
* @property int|null $city_id
* @property int $status
* @property Carbon $created_at
* @property Carbon $updated_at
*
* @property Collection|Booking[] $bookings
* @property Collection|Comment[] $comments
* @property Collection|Favorite[] $favorites
*
* @package App\Models
*/
class User extends Authenticate
class User extends Authenticatable
{
protected $table = 'users';
public static $snakeAttributes = false;
protected $casts = [
'birth_date' => 'datetime',
'gender' => 'bool',
'marital_status' => 'bool',
'province_id' => 'int',
'city_id' => 'int',
'status' => 'int'
];
@@ -52,9 +65,21 @@ class User extends Authenticate
'password',
'national_code',
'birth_date',
'gender',
'marital_status',
'spouse_name',
'image',
'username',
'province_id',
'city_id',
'status'
];
public function bookings()
{
return $this->hasMany(Booking::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Providers;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
@@ -19,6 +20,6 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
//
Paginator::useBootstrapFive();
}
}
+3 -1
View File
@@ -12,7 +12,9 @@
"php": "^8.2",
"hekmatinasser/verta": "^9.0",
"laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1"
"laravel/tinker": "^2.10.1",
"maatwebsite/excel": "^4.0",
"sadegh19b/laravel-persian-validation": "^2.1"
},
"require-dev": {
"fakerphp/faker": "^1.23",
Generated
+600 -1
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "6eb320be5b7c6bcce727a7fc0fb89f52",
"content-hash": "338165288c07f7469e57955c0c1ad7c3",
"packages": [
{
"name": "brick/math",
@@ -135,6 +135,159 @@
],
"time": "2024-02-09T16:56:22+00:00"
},
{
"name": "composer/pcre",
"version": "3.4.0",
"source": {
"type": "git",
"url": "https://github.com/composer/pcre.git",
"reference": "d5a341b3fb61f3001970940afb1d332968a183ed"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/pcre/zipball/d5a341b3fb61f3001970940afb1d332968a183ed",
"reference": "d5a341b3fb61f3001970940afb1d332968a183ed",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0"
},
"conflict": {
"phpstan/phpstan": "<2.2.2"
},
"require-dev": {
"phpstan/phpstan": "^2",
"phpstan/phpstan-deprecation-rules": "^2",
"phpstan/phpstan-strict-rules": "^2",
"phpunit/phpunit": "^9"
},
"type": "library",
"extra": {
"phpstan": {
"includes": [
"extension.neon"
]
},
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Composer\\Pcre\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
"keywords": [
"PCRE",
"preg",
"regex",
"regular expression"
],
"support": {
"issues": "https://github.com/composer/pcre/issues",
"source": "https://github.com/composer/pcre/tree/3.4.0"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
}
],
"time": "2026-06-07T11:47:49+00:00"
},
{
"name": "composer/semver",
"version": "3.4.4",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95",
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95",
"shasum": ""
},
"require": {
"php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.11",
"symfony/phpunit-bridge": "^3 || ^7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Composer\\Semver\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nils Adermann",
"email": "naderman@naderman.de",
"homepage": "http://www.naderman.de"
},
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
},
{
"name": "Rob Bast",
"email": "rob.bast@gmail.com",
"homepage": "http://robbast.nl"
}
],
"description": "Semver library that offers utilities, version constraint parsing and validation.",
"keywords": [
"semantic",
"semver",
"validation",
"versioning"
],
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.4.4"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
}
],
"time": "2025-08-20T19:15:30+00:00"
},
{
"name": "dflydev/dot-access-data",
"version": "v3.0.3",
@@ -2208,6 +2361,280 @@
],
"time": "2026-03-08T20:05:35+00:00"
},
{
"name": "maatwebsite/excel",
"version": "4.0.0",
"source": {
"type": "git",
"url": "https://github.com/SpartnerNL/Laravel-Excel.git",
"reference": "367e92a78008291684b791b3712d46e6fca77343"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/367e92a78008291684b791b3712d46e6fca77343",
"reference": "367e92a78008291684b791b3712d46e6fca77343",
"shasum": ""
},
"require": {
"composer/semver": "^3.4",
"illuminate/support": "^12.0 || ^13.0",
"php": "^8.3",
"phpoffice/phpspreadsheet": "^5.8",
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
"brianium/paratest": "^7.20",
"driftingly/rector-laravel": "^2.5",
"ext-sqlite3": "*",
"larastan/larastan": "^3.10",
"laravel/pint": "^1.29",
"laravel/scout": "^10.25 || ^11.2",
"orchestra/testbench": "^10.11 || ^11.1",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan-mockery": "^2.0",
"phpunit/phpunit": "^12.5 || ~13.1.14",
"predis/predis": "^2.3 || ^3.0",
"rector/rector": "^2.4.2"
},
"type": "library",
"extra": {
"laravel": {
"aliases": {
"Excel": "Maatwebsite\\Excel\\Facades\\Excel"
},
"providers": [
"Maatwebsite\\Excel\\ExcelServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Maatwebsite\\Excel\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Patrick Brouwers",
"email": "patrick@spartner.nl"
}
],
"description": "Supercharged Excel exports and imports in Laravel",
"keywords": [
"PHPExcel",
"batch",
"csv",
"excel",
"export",
"import",
"laravel",
"php",
"phpspreadsheet"
],
"support": {
"issues": "https://github.com/SpartnerNL/Laravel-Excel/issues",
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/4.0.0"
},
"funding": [
{
"url": "https://laravel-excel.com/commercial-support",
"type": "custom"
},
{
"url": "https://github.com/patrickbrouwers",
"type": "github"
}
],
"time": "2026-08-13T10:52:49+00:00"
},
{
"name": "maennchen/zipstream-php",
"version": "3.2.2",
"source": {
"type": "git",
"url": "https://github.com/maennchen/ZipStream-PHP.git",
"reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e",
"reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-zlib": "*",
"php-64bit": "^8.3"
},
"require-dev": {
"brianium/paratest": "^7.7",
"ext-zip": "*",
"friendsofphp/php-cs-fixer": "^3.86",
"guzzlehttp/guzzle": "^7.5",
"mikey179/vfsstream": "^1.6",
"php-coveralls/php-coveralls": "^2.5",
"phpunit/phpunit": "^12.0",
"vimeo/psalm": "^6.0"
},
"suggest": {
"guzzlehttp/psr7": "^2.4",
"psr/http-message": "^2.0"
},
"type": "library",
"autoload": {
"psr-4": {
"ZipStream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paul Duncan",
"email": "pabs@pablotron.org"
},
{
"name": "Jonatan Männchen",
"email": "jonatan@maennchen.ch"
},
{
"name": "Jesse Donat",
"email": "donatj@gmail.com"
},
{
"name": "András Kolesár",
"email": "kolesar@kolesar.hu"
}
],
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
"keywords": [
"stream",
"zip"
],
"support": {
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.2"
},
"funding": [
{
"url": "https://github.com/maennchen",
"type": "github"
}
],
"time": "2026-04-11T18:38:28+00:00"
},
{
"name": "markbaker/complex",
"version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPComplex.git",
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"phpcompatibility/php-compatibility": "^9.3",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Complex\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"description": "PHP Class for working with complex numbers",
"homepage": "https://github.com/MarkBaker/PHPComplex",
"keywords": [
"complex",
"mathematics"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
},
"time": "2022-12-06T16:21:08+00:00"
},
{
"name": "markbaker/matrix",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPMatrix.git",
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"phpcompatibility/php-compatibility": "^9.3",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "^4.0",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"sebastian/phpcpd": "^4.0",
"squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Matrix\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@demon-angel.eu"
}
],
"description": "PHP Class for working with matrices",
"homepage": "https://github.com/MarkBaker/PHPMatrix",
"keywords": [
"mathematics",
"matrix",
"vector"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
},
"time": "2022-12-02T22:17:43+00:00"
},
{
"name": "monolog/monolog",
"version": "3.10.0",
@@ -2718,6 +3145,115 @@
],
"time": "2026-02-16T23:10:27+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
"version": "5.9.0",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "05e99ebf61238a70227b4d9cc02d0030d34f6339"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/05e99ebf61238a70227b4d9cc02d0030d34f6339",
"reference": "05e99ebf61238a70227b4d9cc02d0030d34f6339",
"shasum": ""
},
"require": {
"composer/pcre": "^1||^2||^3",
"ext-ctype": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-filter": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"maennchen/zipstream-php": "^2.1 || ^3.0",
"markbaker/complex": "^3.0",
"markbaker/matrix": "^3.0",
"php": "^8.2",
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
"dompdf/dompdf": "^2.0 || ^3.0",
"ext-intl": "*",
"friendsofphp/php-cs-fixer": "^3.2",
"mitoteam/jpgraph": "^10.5",
"mpdf/mpdf": "^8.1.1",
"phpcompatibility/php-compatibility": "^9.3",
"phpstan/phpstan": "^1.1 || ^2.0",
"phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0",
"phpstan/phpstan-phpunit": "^1.0 || ^2.0",
"phpunit/phpunit": "^10.5 || ^11.0",
"squizlabs/php_codesniffer": "^3.7",
"tecnickcom/tcpdf": "^6.5"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
"ext-intl": "PHP Internationalization Functions, required for NumberFormat Wizard and StringHelper::setLocale()",
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maarten Balliauw",
"homepage": "https://blog.maartenballiauw.be"
},
{
"name": "Mark Baker",
"homepage": "https://markbakeruk.net"
},
{
"name": "Franck Lefevre",
"homepage": "https://rootslabs.net"
},
{
"name": "Erik Tilt"
},
{
"name": "Adrien Crivelli"
},
{
"name": "Owen Leibman"
}
],
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
"keywords": [
"OpenXML",
"excel",
"gnumeric",
"ods",
"php",
"spreadsheet",
"xls",
"xlsx"
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.9.0"
},
"time": "2026-07-12T19:17:39+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.9.5",
@@ -3482,6 +4018,69 @@
},
"time": "2026-06-18T03:57:49+00:00"
},
{
"name": "sadegh19b/laravel-persian-validation",
"version": "v2.1.0",
"source": {
"type": "git",
"url": "https://github.com/sadegh19b/laravel-persian-validation.git",
"reference": "827b446c54121d9fcb0e06415788645c62f7dcd0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sadegh19b/laravel-persian-validation/zipball/827b446c54121d9fcb0e06415788645c62f7dcd0",
"reference": "827b446c54121d9fcb0e06415788645c62f7dcd0",
"shasum": ""
},
"require": {
"illuminate/support": "^11.0|^12.0|^13.0",
"php": ">=8.2"
},
"require-dev": {
"orchestra/testbench": "^9.0",
"phpunit/phpunit": "^11.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Sadegh19b\\LaravelPersianValidation\\PersianValidationServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Sadegh19b\\LaravelPersianValidation\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Sadegh Barzegar",
"email": "sadegh19b@gmail.com",
"homepage": "https://github.com/sadegh19b",
"role": "Developer"
}
],
"description": "A comprehensive Laravel validation package for Persian text, numbers, dates, and Iranian national identifiers",
"homepage": "https://github.com/sadegh19b/laravel-persian-validation",
"keywords": [
"farsi",
"laravel",
"persian",
"validate",
"validation",
"validator"
],
"support": {
"issues": "https://github.com/sadegh19b/laravel-persian-validation/issues",
"source": "https://github.com/sadegh19b/laravel-persian-validation/tree/v2.1.0"
},
"time": "2026-04-25T07:43:18+00:00"
},
{
"name": "symfony/clock",
"version": "v8.1.0",
-1
View File
@@ -11,7 +11,6 @@ SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+307
View File
@@ -0,0 +1,307 @@
-- phpMyAdmin SQL Dump
-- version 5.2.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1:3308
-- Generation Time: Aug 16, 2026 at 01:33 PM
-- Server version: 8.4.7
-- PHP Version: 8.3.28
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `airline_agency`
--
-- --------------------------------------------------------
--
-- Table structure for table `admins`
--
DROP TABLE IF EXISTS `admins`;
CREATE TABLE IF NOT EXISTS `admins` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`full_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`username` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1' COMMENT '0:disable 1:enable',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `admins`
--
INSERT INTO `admins` (`id`, `full_name`, `username`, `email`, `mobile`, `password`, `status`, `created_at`, `updated_at`) VALUES
(1, 'مدیر سیستم', 'admin', 'admin@gmail.com', '09123456789', '$2y$12$gZFpJW2bCE/.G8aI/maL8.dma2GqnWSwnecp1SAQsEhtrPhQOv.iq', 1, '2026-08-16 05:27:16', '2026-08-16 05:27:16');
-- --------------------------------------------------------
--
-- Table structure for table `airports`
--
DROP TABLE IF EXISTS `airports`;
CREATE TABLE IF NOT EXISTS `airports` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`city` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`country` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`code` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `comments`
--
DROP TABLE IF EXISTS `comments`;
CREATE TABLE IF NOT EXISTS `comments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`commentable_id` bigint UNSIGNED NOT NULL,
`commentable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`body` text COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_ comments` (`user_id`),
KEY `fk2_ comments` (`commentable_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `favorites`
--
DROP TABLE IF EXISTS `favorites`;
CREATE TABLE IF NOT EXISTS `favorites` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`favoritable_id` bigint UNSIGNED NOT NULL,
`favoritable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_favorites` (`user_id`),
KEY `fk2_favorites` (`favoritable_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `files`
--
DROP TABLE IF EXISTS `files`;
CREATE TABLE IF NOT EXISTS `files` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`fileable_id` bigint DEFAULT NULL,
`fileable_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`extension` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`size` bigint UNSIGNED NOT NULL,
`original_name` varchar(350) COLLATE utf8mb4_unicode_ci NOT NULL,
`path` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `flights`
--
DROP TABLE IF EXISTS `flights`;
CREATE TABLE IF NOT EXISTS `flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED NOT NULL,
`flight_number` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`airline_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`origin` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`destination` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`departure_date` date NOT NULL,
`departure_time` time NOT NULL,
`arrival_date` date NOT NULL,
`arrival_time` time NOT NULL,
`duration` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED NOT NULL,
`status` tinyint NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `payments`
--
DROP TABLE IF EXISTS `payments`;
CREATE TABLE IF NOT EXISTS `payments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`payable_id` bigint UNSIGNED NOT NULL,
`amount` decimal(12,2) NOT NULL,
`authority` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`transaction_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint NOT NULL COMMENT 'pending:0 | success:1| failed:2 | canceled:3',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `settings`
--
DROP TABLE IF EXISTS `settings`;
CREATE TABLE IF NOT EXISTS `settings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`code` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `tours`
--
DROP TABLE IF EXISTS `tours`;
CREATE TABLE IF NOT EXISTS `tours` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED NOT NULL,
`title` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci NOT NULL,
`duration` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`start_date` date NOT NULL,
`end_date` date NOT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tours` (`travel_type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `tour_flights`
--
DROP TABLE IF EXISTS `tour_flights`;
CREATE TABLE IF NOT EXISTS `tour_flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`tour_id` bigint UNSIGNED NOT NULL,
`flight_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tour_flights` (`flight_id`),
KEY `fk2_tour_flights` (`tour_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `travel_types`
--
DROP TABLE IF EXISTS `travel_types`;
CREATE TABLE IF NOT EXISTS `travel_types` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`title` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`birth_date` date DEFAULT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `comments`
--
ALTER TABLE `comments`
ADD CONSTRAINT `fk1_ comments` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_ comments` FOREIGN KEY (`commentable_id`) REFERENCES `comments` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `favorites`
--
ALTER TABLE `favorites`
ADD CONSTRAINT `fk1_favorites` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_favorites` FOREIGN KEY (`favoritable_id`) REFERENCES `favorites` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tours`
--
ALTER TABLE `tours`
ADD CONSTRAINT `fk1_tours` FOREIGN KEY (`travel_type_id`) REFERENCES `travel_types` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tour_flights`
--
ALTER TABLE `tour_flights`
ADD CONSTRAINT `fk1_tour_flights` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_tour_flights` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+376
View File
@@ -0,0 +1,376 @@
-- phpMyAdmin SQL Dump
-- version 5.2.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1:3308
-- Generation Time: Aug 17, 2026 at 04:32 PM
-- Server version: 8.4.7
-- PHP Version: 8.3.28
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `airline_agency`
--
-- --------------------------------------------------------
--
-- Table structure for table `admins`
--
DROP TABLE IF EXISTS `admins`;
CREATE TABLE IF NOT EXISTS `admins` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`full_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`username` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1' COMMENT '0:disable 1:enable',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `admins`
--
INSERT INTO `admins` (`id`, `full_name`, `username`, `email`, `mobile`, `password`, `status`, `created_at`, `updated_at`) VALUES
(2, 'شهرزاد زندی', 'shahrzad', 'shahrzad.zandi@gmail.com', '09359359350', '$2y$12$KpHLJK1kIz/TxVUOn4FV7udVA3xGLLDtEknPZyfh13Z2WPkRmHwni', 1, '2026-08-17 07:24:19', '2026-08-17 07:24:19'),
(3, 'مدیر سیستم', 'admin', 'admin@gmail.com', '09123456789', '$2y$12$ElsUA1CqyK6euG6adWhXRuayR/Jzcq1zH28eoN3ypfeVrmTIr/zAe', 1, '2026-08-17 07:44:25', '2026-08-17 09:12:14');
-- --------------------------------------------------------
--
-- Table structure for table `admin_permission`
--
DROP TABLE IF EXISTS `admin_permission`;
CREATE TABLE IF NOT EXISTS `admin_permission` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`admin_id` bigint UNSIGNED NOT NULL,
`permission_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `fk1_admin_permission` (`permission_id`),
KEY `fk2_admin_permission` (`admin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `airports`
--
DROP TABLE IF EXISTS `airports`;
CREATE TABLE IF NOT EXISTS `airports` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`city` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`country` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`code` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `comments`
--
DROP TABLE IF EXISTS `comments`;
CREATE TABLE IF NOT EXISTS `comments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`commentable_id` bigint UNSIGNED NOT NULL,
`commentable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`body` text COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_ comments` (`user_id`),
KEY `fk2_ comments` (`commentable_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `favorites`
--
DROP TABLE IF EXISTS `favorites`;
CREATE TABLE IF NOT EXISTS `favorites` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`favoritable_id` bigint UNSIGNED NOT NULL,
`favoritable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_favorites` (`user_id`),
KEY `fk2_favorites` (`favoritable_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `files`
--
DROP TABLE IF EXISTS `files`;
CREATE TABLE IF NOT EXISTS `files` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`fileable_id` bigint DEFAULT NULL,
`fileable_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`extension` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`size` bigint UNSIGNED NOT NULL,
`original_name` varchar(350) COLLATE utf8mb4_unicode_ci NOT NULL,
`path` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `flights`
--
DROP TABLE IF EXISTS `flights`;
CREATE TABLE IF NOT EXISTS `flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED NOT NULL,
`flight_number` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`airline_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`origin` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`destination` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`departure_date` date NOT NULL,
`departure_time` time NOT NULL,
`arrival_date` date NOT NULL,
`arrival_time` time NOT NULL,
`duration` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED NOT NULL,
`status` tinyint NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `flights`
--
INSERT INTO `flights` (`id`, `travel_type_id`, `flight_number`, `airline_name`, `origin`, `destination`, `departure_date`, `departure_time`, `arrival_date`, `arrival_time`, `duration`, `price`, `capacity`, `status`, `created_at`, `updated_at`) VALUES
(1, 2, 'IR-725', 'ایران ایر', 'تهران', 'مشهد', '1405-06-03', '14:30:00', '1405-06-03', '16:00:00', '1 ساعت و 30 دقیقه', 2500000.00, 180, 0, '2026-08-17 13:52:44', '2026-08-17 13:56:00'),
(2, 3, 'TK-182', 'ترکیش ایرلاینز', 'تهران', 'استانبول', '2026-08-28', '20:00:00', '2026-08-29', '07:31:00', '11 ساعت و 31', 18500000.00, 220, 1, '2026-08-17 14:01:19', '2026-08-17 14:01:19'),
(3, 4, 'CH-401', 'وارش', 'تهران', 'کیش', '2026-09-01', '10:30:00', '2026-09-01', '20:33:00', '10 ساعت و3 دقیقه', 4200000.00, 160, 1, '2026-08-17 14:04:34', '2026-08-17 14:04:34');
-- --------------------------------------------------------
--
-- Table structure for table `payments`
--
DROP TABLE IF EXISTS `payments`;
CREATE TABLE IF NOT EXISTS `payments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`payable_id` bigint UNSIGNED NOT NULL,
`amount` decimal(12,2) NOT NULL,
`authority` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`transaction_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint NOT NULL COMMENT 'pending:0 | success:1| failed:2 | canceled:3',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `permissions`
--
DROP TABLE IF EXISTS `permissions`;
CREATE TABLE IF NOT EXISTS `permissions` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `settings`
--
DROP TABLE IF EXISTS `settings`;
CREATE TABLE IF NOT EXISTS `settings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`code` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `tours`
--
DROP TABLE IF EXISTS `tours`;
CREATE TABLE IF NOT EXISTS `tours` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED NOT NULL,
`title` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` text COLLATE utf8mb4_unicode_ci NOT NULL,
`duration` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`start_date` date NOT NULL,
`end_date` date NOT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tours` (`travel_type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `tour_flights`
--
DROP TABLE IF EXISTS `tour_flights`;
CREATE TABLE IF NOT EXISTS `tour_flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`tour_id` bigint UNSIGNED NOT NULL,
`flight_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tour_flights` (`flight_id`),
KEY `fk2_tour_flights` (`tour_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `travel_types`
--
DROP TABLE IF EXISTS `travel_types`;
CREATE TABLE IF NOT EXISTS `travel_types` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`title` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `travel_types`
--
INSERT INTO `travel_types` (`id`, `title`, `slug`, `status`, `created_at`, `updated_at`) VALUES
(2, 'تور داخلی', 'domestic-tour', 1, '2026-08-17 11:36:22', '2026-08-17 11:36:22'),
(3, 'تور خارجی', 'international-tour', 1, '2026-08-17 11:46:33', '2026-08-17 11:46:33'),
(4, 'تور چارتر', 'charter-tour', 1, '2026-08-17 11:46:59', '2026-08-17 11:46:59'),
(5, 'تور ترکیبی', 'combined-tour', 1, '2026-08-17 11:47:41', '2026-08-17 11:47:41'),
(6, 'پرواز خارجی', 'international-flight', 1, '2026-08-17 11:48:19', '2026-08-17 11:48:19'),
(7, 'پرواز داخلی', 'domestic-flight', 1, '2026-08-17 11:48:44', '2026-08-17 11:48:44'),
(8, 'تور لحظه آخری', 'last-minute', 1, '2026-08-17 11:49:11', '2026-08-17 11:49:11'),
(9, 'پیشنویس نمونه', 'draft-sample', 0, '2026-08-17 11:49:33', '2026-08-17 11:56:13');
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`birth_date` date DEFAULT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `admin_permission`
--
ALTER TABLE `admin_permission`
ADD CONSTRAINT `fk1_admin_permission` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_admin_permission` FOREIGN KEY (`admin_id`) REFERENCES `admins` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `comments`
--
ALTER TABLE `comments`
ADD CONSTRAINT `fk1_ comments` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_ comments` FOREIGN KEY (`commentable_id`) REFERENCES `comments` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `favorites`
--
ALTER TABLE `favorites`
ADD CONSTRAINT `fk1_favorites` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_favorites` FOREIGN KEY (`favoritable_id`) REFERENCES `favorites` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tours`
--
ALTER TABLE `tours`
ADD CONSTRAINT `fk1_tours` FOREIGN KEY (`travel_type_id`) REFERENCES `travel_types` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tour_flights`
--
ALTER TABLE `tour_flights`
ADD CONSTRAINT `fk1_tour_flights` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_tour_flights` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+504
View File
@@ -0,0 +1,504 @@
-- phpMyAdmin SQL Dump
-- version 5.2.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1:3308
-- Generation Time: Aug 18, 2026 at 04:23 PM
-- Server version: 8.4.7
-- PHP Version: 8.3.28
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `airline_agency`
--
-- --------------------------------------------------------
--
-- Table structure for table `admins`
--
DROP TABLE IF EXISTS `admins`;
CREATE TABLE IF NOT EXISTS `admins` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`full_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`username` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1' COMMENT '0:disable 1:enable',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `admins`
--
INSERT INTO `admins` (`id`, `full_name`, `username`, `email`, `mobile`, `password`, `status`, `created_at`, `updated_at`) VALUES
(2, 'شهرزاد زندی', 'shahrzad', 'shahrzad.zandi@gmail.com', '09359359350', '$2y$12$KpHLJK1kIz/TxVUOn4FV7udVA3xGLLDtEknPZyfh13Z2WPkRmHwni', 1, '2026-08-17 07:24:19', '2026-08-17 07:24:19'),
(3, 'مدیر سیستم', 'admin', 'admin@gmail.com', '09123456789', '$2y$12$ElsUA1CqyK6euG6adWhXRuayR/Jzcq1zH28eoN3ypfeVrmTIr/zAe', 1, '2026-08-17 07:44:25', '2026-08-17 09:12:14');
-- --------------------------------------------------------
--
-- Table structure for table `admin_permission`
--
DROP TABLE IF EXISTS `admin_permission`;
CREATE TABLE IF NOT EXISTS `admin_permission` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`admin_id` bigint UNSIGNED NOT NULL,
`permission_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `fk1_admin_permission` (`permission_id`),
KEY `fk2_admin_permission` (`admin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `airports`
--
DROP TABLE IF EXISTS `airports`;
CREATE TABLE IF NOT EXISTS `airports` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`city` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`province` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`code` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `airports`
--
INSERT INTO `airports` (`id`, `name`, `city`, `province`, `code`, `created_at`, `updated_at`) VALUES
(1, 'فرودگاه بین‌المللی اهواز', 'اهواز', 'خوزستان', 'AWZ', '0000-00-00 00:00:00', '0000-00-00 00:00:00');
-- --------------------------------------------------------
--
-- Table structure for table `bookings`
--
DROP TABLE IF EXISTS `bookings`;
CREATE TABLE IF NOT EXISTS `bookings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`tour_id` bigint UNSIGNED DEFAULT NULL,
`flight_id` bigint UNSIGNED DEFAULT NULL,
`booking_code` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`passengers` int UNSIGNED NOT NULL DEFAULT '1',
`price` decimal(15,2) NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`payment_status` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`notes` text COLLATE utf8mb4_unicode_ci,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_bookings` (`user_id`),
KEY `fk2_bookings` (`tour_id`),
KEY `fk3_bookings` (`flight_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `cities`
--
DROP TABLE IF EXISTS `cities`;
CREATE TABLE IF NOT EXISTS `cities` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`province_id` bigint UNSIGNED NOT NULL,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk1_cities` (`province_id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `cities`
--
INSERT INTO `cities` (`id`, `province_id`, `name`, `created_at`, `updated_at`) VALUES
(7, 2, 'ساری', NULL, NULL),
(8, 1, 'تهران', NULL, NULL),
(9, 5, 'شیراز', NULL, NULL),
(10, 4, 'اصفهان', NULL, NULL),
(11, 1, 'ری', NULL, NULL),
(12, 2, 'آمل', NULL, NULL);
-- --------------------------------------------------------
--
-- Table structure for table `comments`
--
DROP TABLE IF EXISTS `comments`;
CREATE TABLE IF NOT EXISTS `comments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`commentable_id` bigint UNSIGNED NOT NULL,
`commentable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`body` text COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_ comments` (`user_id`),
KEY `fk2_ comments` (`commentable_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `favorites`
--
DROP TABLE IF EXISTS `favorites`;
CREATE TABLE IF NOT EXISTS `favorites` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`favoritable_id` bigint UNSIGNED NOT NULL,
`favoritable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_favorites` (`user_id`),
KEY `fk2_favorites` (`favoritable_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `files`
--
DROP TABLE IF EXISTS `files`;
CREATE TABLE IF NOT EXISTS `files` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`fileable_id` bigint DEFAULT NULL,
`fileable_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`extension` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`size` bigint UNSIGNED NOT NULL,
`original_name` varchar(350) COLLATE utf8mb4_unicode_ci NOT NULL,
`path` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `flights`
--
DROP TABLE IF EXISTS `flights`;
CREATE TABLE IF NOT EXISTS `flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED NOT NULL,
`flight_number` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`airline_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`origin` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`destination` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`departure_date` date NOT NULL,
`departure_time` time NOT NULL,
`arrival_date` date NOT NULL,
`arrival_time` time NOT NULL,
`duration` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED NOT NULL,
`status` tinyint NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `flights`
--
INSERT INTO `flights` (`id`, `travel_type_id`, `flight_number`, `airline_name`, `origin`, `destination`, `departure_date`, `departure_time`, `arrival_date`, `arrival_time`, `duration`, `price`, `capacity`, `status`, `created_at`, `updated_at`) VALUES
(1, 2, 'IR-725', 'ایران ایر', 'تهران', 'مشهد', '1405-06-03', '14:30:00', '1405-06-03', '16:00:00', '1 ساعت و 30 دقیقه', 2500000.00, 180, 0, '2026-08-17 13:52:44', '2026-08-17 13:56:00'),
(2, 3, 'TK-182', 'ترکیش ایرلاینز', 'تهران', 'استانبول', '2026-08-28', '20:00:00', '2026-08-29', '07:31:00', '11 ساعت و 31', 18500000.00, 220, 1, '2026-08-17 14:01:19', '2026-08-17 14:01:19'),
(3, 4, 'CH-401', 'وارش', 'تهران', 'کیش', '2026-09-01', '10:30:00', '2026-09-01', '20:33:00', '10 ساعت و3 دقیقه', 4200000.00, 160, 1, '2026-08-17 14:04:34', '2026-08-17 14:04:34');
-- --------------------------------------------------------
--
-- Table structure for table `payments`
--
DROP TABLE IF EXISTS `payments`;
CREATE TABLE IF NOT EXISTS `payments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`payable_id` bigint UNSIGNED NOT NULL,
`amount` decimal(12,2) NOT NULL,
`authority` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`transaction_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint NOT NULL COMMENT 'pending:0 | success:1| failed:2 | canceled:3',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `permissions`
--
DROP TABLE IF EXISTS `permissions`;
CREATE TABLE IF NOT EXISTS `permissions` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `provinces`
--
DROP TABLE IF EXISTS `provinces`;
CREATE TABLE IF NOT EXISTS `provinces` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `provinces`
--
INSERT INTO `provinces` (`id`, `name`, `created_at`, `updated_at`) VALUES
(1, 'تهران', NULL, NULL),
(2, 'مازندران', NULL, NULL),
(3, 'گیلان', NULL, NULL),
(4, 'اصفهان', NULL, NULL),
(5, 'فارس', NULL, NULL),
(6, 'یزد', NULL, NULL),
(7, 'آذربایجان غربی', NULL, NULL),
(8, 'آذربایجان شرقی', NULL, NULL);
-- --------------------------------------------------------
--
-- Table structure for table `settings`
--
DROP TABLE IF EXISTS `settings`;
CREATE TABLE IF NOT EXISTS `settings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`code` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `tours`
--
DROP TABLE IF EXISTS `tours`;
CREATE TABLE IF NOT EXISTS `tours` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED DEFAULT NULL,
`title` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`duration` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED DEFAULT NULL,
`views_count` int NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tours` (`travel_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `tours`
--
INSERT INTO `tours` (`id`, `travel_type_id`, `title`, `slug`, `image`, `description`, `duration`, `start_date`, `end_date`, `price`, `capacity`, `views_count`, `status`, `created_at`, `updated_at`) VALUES
(3, NULL, 'تور سه‌روزه اصفهان با راهنمای تخصصی', 'tor-shrozh-asfhan-ba-rahnmay-tkhssy', 'tours/1787037667.tour-image56011.jpg', NULL, NULL, NULL, NULL, 2850000.00, NULL, 5, 1, '2026-08-18 07:21:07', '2026-08-18 12:12:55'),
(4, NULL, 'تور لوکس پنج‌روزه کیش با پرواز مستقیم', 'tor-loks-pngrozh-kysh-ba-proaz-mstkym', 'tours/1787037718.tour-image49479.jpg', NULL, NULL, NULL, NULL, 12500000.00, NULL, 4, 1, '2026-08-18 07:21:58', '2026-08-18 12:13:45');
-- --------------------------------------------------------
--
-- Table structure for table `tour_flights`
--
DROP TABLE IF EXISTS `tour_flights`;
CREATE TABLE IF NOT EXISTS `tour_flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`tour_id` bigint UNSIGNED NOT NULL,
`flight_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tour_flights` (`flight_id`),
KEY `fk2_tour_flights` (`tour_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `travel_types`
--
DROP TABLE IF EXISTS `travel_types`;
CREATE TABLE IF NOT EXISTS `travel_types` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`title` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `travel_types`
--
INSERT INTO `travel_types` (`id`, `title`, `slug`, `status`, `created_at`, `updated_at`) VALUES
(2, 'تور داخلی', 'domestic-tour', 1, '2026-08-17 11:36:22', '2026-08-17 11:36:22'),
(3, 'تور خارجی', 'international-tour', 1, '2026-08-17 11:46:33', '2026-08-17 11:46:33'),
(4, 'تور چارتر', 'charter-tour', 1, '2026-08-17 11:46:59', '2026-08-17 11:46:59'),
(5, 'تور ترکیبی', 'combined-tour', 1, '2026-08-17 11:47:41', '2026-08-17 11:47:41'),
(6, 'پرواز خارجی', 'international-flight', 1, '2026-08-17 11:48:19', '2026-08-17 11:48:19'),
(7, 'پرواز داخلی', 'domestic-flight', 1, '2026-08-17 11:48:44', '2026-08-17 11:48:44'),
(8, 'تور لحظه آخری', 'last-minute', 1, '2026-08-17 11:49:11', '2026-08-17 11:49:11'),
(9, 'پیشنویس نمونه', 'draft-sample', 0, '2026-08-17 11:49:33', '2026-08-17 11:56:13');
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`birth_date` date DEFAULT NULL,
`gender` tinyint(1) NOT NULL COMMENT '1:Male | 2:Female',
`marital_status` tinyint(1) NOT NULL COMMENT '1:Single | 2:Married | 3:Divorced/Separated',
`spouse_name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`username` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`province_id` bigint UNSIGNED NOT NULL,
`city_id` bigint UNSIGNED DEFAULT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `admin_permission`
--
ALTER TABLE `admin_permission`
ADD CONSTRAINT `fk1_admin_permission` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_admin_permission` FOREIGN KEY (`admin_id`) REFERENCES `admins` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `bookings`
--
ALTER TABLE `bookings`
ADD CONSTRAINT `fk1_bookings` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_bookings` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk3_bookings` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `cities`
--
ALTER TABLE `cities`
ADD CONSTRAINT `fk1_cities` FOREIGN KEY (`province_id`) REFERENCES `provinces` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `comments`
--
ALTER TABLE `comments`
ADD CONSTRAINT `fk1_ comments` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_ comments` FOREIGN KEY (`commentable_id`) REFERENCES `comments` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `favorites`
--
ALTER TABLE `favorites`
ADD CONSTRAINT `fk1_favorites` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_favorites` FOREIGN KEY (`favoritable_id`) REFERENCES `favorites` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tours`
--
ALTER TABLE `tours`
ADD CONSTRAINT `fk1_tours` FOREIGN KEY (`travel_type_id`) REFERENCES `travel_types` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tour_flights`
--
ALTER TABLE `tour_flights`
ADD CONSTRAINT `fk1_tour_flights` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_tour_flights` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+526
View File
@@ -0,0 +1,526 @@
-- phpMyAdmin SQL Dump
-- version 5.2.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1:3308
-- Generation Time: Aug 20, 2026 at 04:33 AM
-- Server version: 8.4.7
-- PHP Version: 8.3.28
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `airline_agency`
--
-- --------------------------------------------------------
--
-- Table structure for table `admins`
--
DROP TABLE IF EXISTS `admins`;
CREATE TABLE IF NOT EXISTS `admins` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`full_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`username` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1' COMMENT '0:disable 1:enable',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `admins`
--
INSERT INTO `admins` (`id`, `full_name`, `username`, `email`, `mobile`, `password`, `status`, `created_at`, `updated_at`) VALUES
(2, 'شهرزاد زندی', 'shahrzad', 'shahrzad.zandi@gmail.com', '09359359350', '$2y$12$KpHLJK1kIz/TxVUOn4FV7udVA3xGLLDtEknPZyfh13Z2WPkRmHwni', 1, '2026-08-17 07:24:19', '2026-08-17 07:24:19'),
(3, 'مدیر سیستم', 'admin', 'admin@gmail.com', '09123456789', '$2y$12$ElsUA1CqyK6euG6adWhXRuayR/Jzcq1zH28eoN3ypfeVrmTIr/zAe', 1, '2026-08-17 07:44:25', '2026-08-17 09:12:14');
-- --------------------------------------------------------
--
-- Table structure for table `admin_permission`
--
DROP TABLE IF EXISTS `admin_permission`;
CREATE TABLE IF NOT EXISTS `admin_permission` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`admin_id` bigint UNSIGNED NOT NULL,
`permission_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `fk1_admin_permission` (`permission_id`),
KEY `fk2_admin_permission` (`admin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `airports`
--
DROP TABLE IF EXISTS `airports`;
CREATE TABLE IF NOT EXISTS `airports` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`city` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`province` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`code` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `airports`
--
INSERT INTO `airports` (`id`, `name`, `city`, `province`, `code`, `created_at`, `updated_at`) VALUES
(1, 'فرودگاه بین‌المللی اهواز', 'اهواز', 'خوزستان', 'AWZ', '0000-00-00 00:00:00', '0000-00-00 00:00:00');
-- --------------------------------------------------------
--
-- Table structure for table `bookings`
--
DROP TABLE IF EXISTS `bookings`;
CREATE TABLE IF NOT EXISTS `bookings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`tour_id` bigint UNSIGNED DEFAULT NULL,
`flight_id` bigint UNSIGNED DEFAULT NULL,
`booking_code` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`passengers` int UNSIGNED NOT NULL DEFAULT '1',
`price` decimal(15,2) NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`payment_status` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`notes` text COLLATE utf8mb4_unicode_ci,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_bookings` (`user_id`),
KEY `fk2_bookings` (`tour_id`),
KEY `fk3_bookings` (`flight_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `cities`
--
DROP TABLE IF EXISTS `cities`;
CREATE TABLE IF NOT EXISTS `cities` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`province_id` bigint UNSIGNED NOT NULL,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk1_cities` (`province_id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `cities`
--
INSERT INTO `cities` (`id`, `province_id`, `name`, `created_at`, `updated_at`) VALUES
(7, 2, 'ساری', NULL, NULL),
(8, 1, 'تهران', NULL, NULL),
(9, 5, 'شیراز', NULL, NULL),
(10, 4, 'اصفهان', NULL, NULL),
(11, 1, 'ری', NULL, NULL),
(12, 2, 'آمل', NULL, NULL);
-- --------------------------------------------------------
--
-- Table structure for table `comments`
--
DROP TABLE IF EXISTS `comments`;
CREATE TABLE IF NOT EXISTS `comments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`commentable_id` bigint UNSIGNED NOT NULL,
`commentable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`body` text COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_ comments` (`user_id`),
KEY `fk2_ comments` (`commentable_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `favorites`
--
DROP TABLE IF EXISTS `favorites`;
CREATE TABLE IF NOT EXISTS `favorites` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`favoritable_id` bigint UNSIGNED NOT NULL,
`favoritable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_favorites` (`user_id`),
KEY `fk2_favorites` (`favoritable_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `favorites`
--
INSERT INTO `favorites` (`id`, `user_id`, `favoritable_id`, `favoritable_type`, `created_at`, `updated_at`) VALUES
(3, 1, 3, 'App\\Models\\Tour', '2026-08-19 16:05:52', '2026-08-19 16:05:52'),
(4, 1, 4, 'App\\Models\\Tour', '2026-08-19 16:11:50', '2026-08-19 16:11:50');
-- --------------------------------------------------------
--
-- Table structure for table `files`
--
DROP TABLE IF EXISTS `files`;
CREATE TABLE IF NOT EXISTS `files` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`fileable_id` bigint DEFAULT NULL,
`fileable_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`extension` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`size` bigint UNSIGNED NOT NULL,
`original_name` varchar(350) COLLATE utf8mb4_unicode_ci NOT NULL,
`path` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `flights`
--
DROP TABLE IF EXISTS `flights`;
CREATE TABLE IF NOT EXISTS `flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED NOT NULL,
`flight_number` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`airline_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`origin` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`destination` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`departure_date` date NOT NULL,
`departure_time` time NOT NULL,
`arrival_date` date NOT NULL,
`arrival_time` time NOT NULL,
`duration` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED NOT NULL,
`status` tinyint NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `flights`
--
INSERT INTO `flights` (`id`, `travel_type_id`, `flight_number`, `airline_name`, `origin`, `destination`, `departure_date`, `departure_time`, `arrival_date`, `arrival_time`, `duration`, `price`, `capacity`, `status`, `created_at`, `updated_at`) VALUES
(1, 2, 'IR-725', 'ایران ایر', 'تهران', 'مشهد', '1405-06-03', '14:30:00', '1405-06-03', '16:00:00', '1 ساعت و 30 دقیقه', 2500000.00, 180, 0, '2026-08-17 13:52:44', '2026-08-17 13:56:00'),
(2, 3, 'TK-182', 'ترکیش ایرلاینز', 'تهران', 'استانبول', '2026-08-28', '20:00:00', '2026-08-29', '07:31:00', '11 ساعت و 31', 18500000.00, 220, 1, '2026-08-17 14:01:19', '2026-08-17 14:01:19'),
(3, 4, 'CH-401', 'وارش', 'تهران', 'کیش', '2026-09-01', '10:30:00', '2026-09-01', '20:33:00', '10 ساعت و3 دقیقه', 4200000.00, 160, 1, '2026-08-17 14:04:34', '2026-08-17 14:04:34'),
(4, 2, 'ia33', 'test', 'test', 'test', '1405-05-06', '20:12:00', '1405-05-06', '22:06:00', '2', 850000.00, 2, 1, '2026-08-19 13:38:25', '2026-08-19 13:38:25');
-- --------------------------------------------------------
--
-- Table structure for table `payments`
--
DROP TABLE IF EXISTS `payments`;
CREATE TABLE IF NOT EXISTS `payments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`payable_id` bigint UNSIGNED NOT NULL,
`amount` decimal(12,2) NOT NULL,
`authority` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`transaction_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint NOT NULL COMMENT 'pending:0 | success:1| failed:2 | canceled:3',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `permissions`
--
DROP TABLE IF EXISTS `permissions`;
CREATE TABLE IF NOT EXISTS `permissions` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `provinces`
--
DROP TABLE IF EXISTS `provinces`;
CREATE TABLE IF NOT EXISTS `provinces` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `provinces`
--
INSERT INTO `provinces` (`id`, `name`, `created_at`, `updated_at`) VALUES
(1, 'تهران', NULL, NULL),
(2, 'مازندران', NULL, NULL),
(3, 'گیلان', NULL, NULL),
(4, 'اصفهان', NULL, NULL),
(5, 'فارس', NULL, NULL),
(6, 'یزد', NULL, NULL),
(7, 'آذربایجان غربی', NULL, NULL),
(8, 'آذربایجان شرقی', NULL, NULL);
-- --------------------------------------------------------
--
-- Table structure for table `settings`
--
DROP TABLE IF EXISTS `settings`;
CREATE TABLE IF NOT EXISTS `settings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`code` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `tours`
--
DROP TABLE IF EXISTS `tours`;
CREATE TABLE IF NOT EXISTS `tours` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED DEFAULT NULL,
`title` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`duration` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED DEFAULT NULL,
`views_count` int NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tours` (`travel_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `tours`
--
INSERT INTO `tours` (`id`, `travel_type_id`, `title`, `slug`, `image`, `description`, `duration`, `start_date`, `end_date`, `price`, `capacity`, `views_count`, `status`, `created_at`, `updated_at`) VALUES
(3, NULL, 'تور سه‌روزه اصفهان با راهنمای تخصصی', 'tor-shrozh-asfhan-ba-rahnmay-tkhssy', 'tours/1787037667.tour-image56011.jpg', NULL, NULL, NULL, NULL, 2850000.00, NULL, 28, 1, '2026-08-18 07:21:07', '2026-08-20 01:19:33'),
(4, NULL, 'تور لوکس پنج‌روزه کیش با پرواز مستقیم', 'tor-loks-pngrozh-kysh-ba-proaz-mstkym', 'tours/1787037718.tour-image49479.jpg', NULL, NULL, NULL, NULL, 12500000.00, NULL, 31, 1, '2026-08-18 07:21:58', '2026-08-20 01:20:50'),
(5, NULL, 'تور خانوادگی پنج‌روزه قشم و هرمز', 'tor-khanoadgy-pngrozh-kshm-o-hrmz', 'tours/1787138709.tour-image35820.jpg', NULL, NULL, NULL, NULL, 9750000.00, NULL, 0, 0, '2026-08-19 11:25:09', '2026-08-19 11:25:11'),
(6, NULL, 'تور شش‌روزه رم و فلورانس', 'tor-shshrozh-rm-o-florans', 'tours/1787138776.tour-image35964.jpg', NULL, NULL, NULL, NULL, 76500000.00, NULL, 0, 0, '2026-08-19 11:26:16', '2026-08-19 11:26:16'),
(7, NULL, 'تور لوکس هفت‌روزه پاریس', 'tor-loks-hftrozh-parys', 'tours/1787138834.tour-image66216.jpg', NULL, NULL, NULL, NULL, 89000000.00, NULL, 0, 0, '2026-08-19 11:27:14', '2026-08-19 11:27:14'),
(8, NULL, 'تور اقتصادی چهارروزه باکو', 'tor-aktsady-chharrozh-bako', 'tours/1787138868.tour-image42665.jpg', NULL, NULL, NULL, NULL, 15800000.00, NULL, 0, 0, '2026-08-19 11:27:48', '2026-08-19 11:27:48'),
(9, NULL, 'test', 'test', 'tours/1787146812.tour-image88373.jpg', NULL, NULL, NULL, NULL, 2000000.00, NULL, 0, 0, '2026-08-19 13:40:12', '2026-08-19 13:40:14');
-- --------------------------------------------------------
--
-- Table structure for table `tour_flights`
--
DROP TABLE IF EXISTS `tour_flights`;
CREATE TABLE IF NOT EXISTS `tour_flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`tour_id` bigint UNSIGNED NOT NULL,
`flight_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tour_flights` (`flight_id`),
KEY `fk2_tour_flights` (`tour_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `travel_types`
--
DROP TABLE IF EXISTS `travel_types`;
CREATE TABLE IF NOT EXISTS `travel_types` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`title` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `travel_types`
--
INSERT INTO `travel_types` (`id`, `title`, `slug`, `status`, `created_at`, `updated_at`) VALUES
(2, 'تور داخلی', 'domestic-tour', 1, '2026-08-17 11:36:22', '2026-08-17 11:36:22'),
(3, 'تور خارجی', 'international-tour', 1, '2026-08-17 11:46:33', '2026-08-17 11:46:33'),
(4, 'تور چارتر', 'charter-tour', 1, '2026-08-17 11:46:59', '2026-08-17 11:46:59'),
(5, 'تور ترکیبی', 'combined-tour', 1, '2026-08-17 11:47:41', '2026-08-17 11:47:41'),
(6, 'پرواز خارجی', 'international-flight', 1, '2026-08-17 11:48:19', '2026-08-17 11:48:19'),
(7, 'پرواز داخلی', 'domestic-flight', 1, '2026-08-17 11:48:44', '2026-08-17 11:48:44'),
(8, 'تور لحظه آخری', 'last-minute', 1, '2026-08-17 11:49:11', '2026-08-17 11:49:11'),
(9, 'پیشنویس نمونه', 'draft-sample', 0, '2026-08-17 11:49:33', '2026-08-17 11:56:13');
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`birth_date` date DEFAULT NULL,
`gender` tinyint(1) NOT NULL COMMENT '1:Male | 2:Female',
`marital_status` tinyint(1) NOT NULL COMMENT '1:Single | 2:Married | 3:Divorced/Separated',
`spouse_name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`username` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`province_id` bigint UNSIGNED NOT NULL,
`city_id` bigint UNSIGNED DEFAULT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `first_name`, `last_name`, `email`, `mobile`, `password`, `national_code`, `birth_date`, `gender`, `marital_status`, `spouse_name`, `image`, `username`, `province_id`, `city_id`, `status`, `created_at`, `updated_at`) VALUES
(1, 'شهرزاد', 'زندی', 'shahrzad.zandi011@gmail.com', '09118909120', '$2y$12$LzDaglfvgypwHT20MAffJOnjpIePJbwJjIcbnoRW8tLy53wNbfFqa', '2080706640', NULL, 2, 1, NULL, 'users/zCDeIumAUhjqbKYwlu8wsDiKgl462J48eiBrF7wN.jpg', 'shahrzad011', 2, NULL, 1, '2026-08-19 01:09:30', '2026-08-19 01:09:30'),
(2, 'حاتمه', 'اندرزا', 'hatame19@gmail.com', '09119533286', '$2y$12$6AxXNTIpJAK0czNU78PeAObgC.Nl0dTbqKyyMHSGTUrr0GynKyfhq', '2081391693', NULL, 2, 1, NULL, 'users/MU5t6XmUmS558EO4EPQUdO2kDL7XSeDEtoeP83LD.jpg', 'hatame19', 2, NULL, 1, '2026-08-19 06:23:09', '2026-08-19 06:23:09');
--
-- Constraints for dumped tables
--
--
-- Constraints for table `admin_permission`
--
ALTER TABLE `admin_permission`
ADD CONSTRAINT `fk1_admin_permission` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_admin_permission` FOREIGN KEY (`admin_id`) REFERENCES `admins` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `bookings`
--
ALTER TABLE `bookings`
ADD CONSTRAINT `fk1_bookings` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_bookings` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk3_bookings` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `cities`
--
ALTER TABLE `cities`
ADD CONSTRAINT `fk1_cities` FOREIGN KEY (`province_id`) REFERENCES `provinces` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `comments`
--
ALTER TABLE `comments`
ADD CONSTRAINT `fk1_ comments` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_ comments` FOREIGN KEY (`commentable_id`) REFERENCES `comments` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `favorites`
--
ALTER TABLE `favorites`
ADD CONSTRAINT `fk1_favorites` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_favorites` FOREIGN KEY (`favoritable_id`) REFERENCES `favorites` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tours`
--
ALTER TABLE `tours`
ADD CONSTRAINT `fk1_tours` FOREIGN KEY (`travel_type_id`) REFERENCES `travel_types` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tour_flights`
--
ALTER TABLE `tour_flights`
ADD CONSTRAINT `fk1_tour_flights` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_tour_flights` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+532
View File
@@ -0,0 +1,532 @@
-- phpMyAdmin SQL Dump
-- version 5.2.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1:3308
-- Generation Time: Aug 20, 2026 at 01:33 PM
-- Server version: 8.4.7
-- PHP Version: 8.3.28
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `airline_agency`
--
-- --------------------------------------------------------
--
-- Table structure for table `admins`
--
DROP TABLE IF EXISTS `admins`;
CREATE TABLE IF NOT EXISTS `admins` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`full_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`username` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1' COMMENT '0:disable 1:enable',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `admins`
--
INSERT INTO `admins` (`id`, `full_name`, `username`, `email`, `mobile`, `password`, `status`, `created_at`, `updated_at`) VALUES
(2, 'شهرزاد زندی', 'shahrzad', 'shahrzad.zandi@gmail.com', '09359359350', '$2y$12$KpHLJK1kIz/TxVUOn4FV7udVA3xGLLDtEknPZyfh13Z2WPkRmHwni', 1, '2026-08-17 07:24:19', '2026-08-17 07:24:19'),
(3, 'مدیر سیستم', 'admin', 'admin@gmail.com', '09123456789', '$2y$12$ElsUA1CqyK6euG6adWhXRuayR/Jzcq1zH28eoN3ypfeVrmTIr/zAe', 1, '2026-08-17 07:44:25', '2026-08-17 09:12:14');
-- --------------------------------------------------------
--
-- Table structure for table `admin_permission`
--
DROP TABLE IF EXISTS `admin_permission`;
CREATE TABLE IF NOT EXISTS `admin_permission` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`admin_id` bigint UNSIGNED NOT NULL,
`permission_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `fk1_admin_permission` (`permission_id`),
KEY `fk2_admin_permission` (`admin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `airports`
--
DROP TABLE IF EXISTS `airports`;
CREATE TABLE IF NOT EXISTS `airports` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`city` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`province` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`code` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `airports`
--
INSERT INTO `airports` (`id`, `name`, `city`, `province`, `code`, `created_at`, `updated_at`) VALUES
(1, 'فرودگاه بین‌المللی اهواز', 'اهواز', 'خوزستان', 'AWZ', '0000-00-00 00:00:00', '0000-00-00 00:00:00');
-- --------------------------------------------------------
--
-- Table structure for table `bookings`
--
DROP TABLE IF EXISTS `bookings`;
CREATE TABLE IF NOT EXISTS `bookings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`tour_id` bigint UNSIGNED DEFAULT NULL,
`flight_id` bigint UNSIGNED DEFAULT NULL,
`booking_code` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`passengers` int UNSIGNED NOT NULL DEFAULT '1',
`price` decimal(15,2) NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`payment_status` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`notes` text COLLATE utf8mb4_unicode_ci,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_bookings` (`user_id`),
KEY `fk2_bookings` (`tour_id`),
KEY `fk3_bookings` (`flight_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `cities`
--
DROP TABLE IF EXISTS `cities`;
CREATE TABLE IF NOT EXISTS `cities` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`province_id` bigint UNSIGNED NOT NULL,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk1_cities` (`province_id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `cities`
--
INSERT INTO `cities` (`id`, `province_id`, `name`, `created_at`, `updated_at`) VALUES
(7, 2, 'ساری', NULL, NULL),
(8, 1, 'تهران', NULL, NULL),
(9, 5, 'شیراز', NULL, NULL),
(10, 4, 'اصفهان', NULL, NULL),
(11, 1, 'ری', NULL, NULL),
(12, 2, 'آمل', NULL, NULL);
-- --------------------------------------------------------
--
-- Table structure for table `comments`
--
DROP TABLE IF EXISTS `comments`;
CREATE TABLE IF NOT EXISTS `comments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`commentable_id` bigint UNSIGNED NOT NULL,
`commentable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`body` text COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_ comments` (`user_id`),
KEY `fk2_ comments` (`commentable_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `comments`
--
INSERT INTO `comments` (`id`, `user_id`, `commentable_id`, `commentable_type`, `body`, `status`, `created_at`, `updated_at`) VALUES
(2, 1, 3, 'App\\Models\\Tour', 'بسیار خوب بود', 1, '2026-08-20 10:15:43', '2026-08-20 10:15:43'),
(3, 1, 3, 'App\\Models\\Tour', 'خیلی هم عالی', 1, '2026-08-20 10:17:07', '2026-08-20 10:17:07'),
(4, 1, 3, 'App\\Models\\Tour', 'من این تور را پسندیدم.', 1, '2026-08-20 13:15:04', '2026-08-20 13:15:04');
-- --------------------------------------------------------
--
-- Table structure for table `favorites`
--
DROP TABLE IF EXISTS `favorites`;
CREATE TABLE IF NOT EXISTS `favorites` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`favoritable_id` bigint UNSIGNED NOT NULL,
`favoritable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_favorites` (`user_id`),
KEY `fk2_favorites` (`favoritable_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `favorites`
--
INSERT INTO `favorites` (`id`, `user_id`, `favoritable_id`, `favoritable_type`, `created_at`, `updated_at`) VALUES
(3, 1, 3, 'App\\Models\\Tour', '2026-08-19 16:05:52', '2026-08-19 16:05:52');
-- --------------------------------------------------------
--
-- Table structure for table `files`
--
DROP TABLE IF EXISTS `files`;
CREATE TABLE IF NOT EXISTS `files` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`fileable_id` bigint DEFAULT NULL,
`fileable_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`extension` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`size` bigint UNSIGNED NOT NULL,
`original_name` varchar(350) COLLATE utf8mb4_unicode_ci NOT NULL,
`path` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `flights`
--
DROP TABLE IF EXISTS `flights`;
CREATE TABLE IF NOT EXISTS `flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED NOT NULL,
`flight_number` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`airline_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`origin` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`destination` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`departure_date` date NOT NULL,
`departure_time` time NOT NULL,
`arrival_date` date NOT NULL,
`arrival_time` time NOT NULL,
`duration` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED NOT NULL,
`status` tinyint NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `flights`
--
INSERT INTO `flights` (`id`, `travel_type_id`, `flight_number`, `airline_name`, `origin`, `destination`, `departure_date`, `departure_time`, `arrival_date`, `arrival_time`, `duration`, `price`, `capacity`, `status`, `created_at`, `updated_at`) VALUES
(1, 2, 'IR-725', 'ایران ایر', 'تهران', 'مشهد', '1405-06-03', '14:30:00', '1405-06-03', '16:00:00', '1 ساعت و 30 دقیقه', 2500000.00, 180, 0, '2026-08-17 13:52:44', '2026-08-17 13:56:00'),
(2, 3, 'TK-182', 'ترکیش ایرلاینز', 'تهران', 'استانبول', '2026-08-28', '20:00:00', '2026-08-29', '07:31:00', '11 ساعت و 31', 18500000.00, 220, 1, '2026-08-17 14:01:19', '2026-08-17 14:01:19'),
(3, 4, 'CH-401', 'وارش', 'تهران', 'کیش', '2026-09-01', '10:30:00', '2026-09-01', '20:33:00', '10 ساعت و3 دقیقه', 4200000.00, 160, 1, '2026-08-17 14:04:34', '2026-08-17 14:04:34'),
(4, 2, 'ia33', 'test', 'test', 'test', '1405-05-06', '20:12:00', '1405-05-06', '22:06:00', '2', 850000.00, 2, 1, '2026-08-19 13:38:25', '2026-08-19 13:38:25');
-- --------------------------------------------------------
--
-- Table structure for table `payments`
--
DROP TABLE IF EXISTS `payments`;
CREATE TABLE IF NOT EXISTS `payments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`payable_id` bigint UNSIGNED NOT NULL,
`amount` decimal(12,2) NOT NULL,
`authority` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`transaction_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint NOT NULL COMMENT 'pending:0 | success:1| failed:2 | canceled:3',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `permissions`
--
DROP TABLE IF EXISTS `permissions`;
CREATE TABLE IF NOT EXISTS `permissions` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `provinces`
--
DROP TABLE IF EXISTS `provinces`;
CREATE TABLE IF NOT EXISTS `provinces` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `provinces`
--
INSERT INTO `provinces` (`id`, `name`, `created_at`, `updated_at`) VALUES
(1, 'تهران', NULL, NULL),
(2, 'مازندران', NULL, NULL),
(3, 'گیلان', NULL, NULL),
(4, 'اصفهان', NULL, NULL),
(5, 'فارس', NULL, NULL),
(6, 'یزد', NULL, NULL),
(7, 'آذربایجان غربی', NULL, NULL),
(8, 'آذربایجان شرقی', NULL, NULL);
-- --------------------------------------------------------
--
-- Table structure for table `settings`
--
DROP TABLE IF EXISTS `settings`;
CREATE TABLE IF NOT EXISTS `settings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`code` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `tours`
--
DROP TABLE IF EXISTS `tours`;
CREATE TABLE IF NOT EXISTS `tours` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED DEFAULT NULL,
`title` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`duration` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED DEFAULT NULL,
`views_count` int NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tours` (`travel_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `tours`
--
INSERT INTO `tours` (`id`, `travel_type_id`, `title`, `slug`, `image`, `description`, `duration`, `start_date`, `end_date`, `price`, `capacity`, `views_count`, `status`, `created_at`, `updated_at`) VALUES
(3, NULL, 'تور سه‌روزه اصفهان با راهنمای تخصصی', 'tor-shrozh-asfhan-ba-rahnmay-tkhssy', 'tours/1787037667.tour-image56011.jpg', NULL, NULL, NULL, NULL, 2850000.00, NULL, 63, 1, '2026-08-18 07:21:07', '2026-08-20 13:15:04'),
(4, NULL, 'تور لوکس پنج‌روزه کیش با پرواز مستقیم', 'tor-loks-pngrozh-kysh-ba-proaz-mstkym', 'tours/1787037718.tour-image49479.jpg', NULL, NULL, NULL, NULL, 12500000.00, NULL, 36, 1, '2026-08-18 07:21:58', '2026-08-20 08:02:13'),
(5, NULL, 'تور خانوادگی پنج‌روزه قشم و هرمز', 'tor-khanoadgy-pngrozh-kshm-o-hrmz', 'tours/1787138709.tour-image35820.jpg', NULL, NULL, NULL, NULL, 9750000.00, NULL, 0, 0, '2026-08-19 11:25:09', '2026-08-19 11:25:11'),
(6, NULL, 'تور شش‌روزه رم و فلورانس', 'tor-shshrozh-rm-o-florans', 'tours/1787138776.tour-image35964.jpg', NULL, NULL, NULL, NULL, 76500000.00, NULL, 0, 0, '2026-08-19 11:26:16', '2026-08-19 11:26:16'),
(7, NULL, 'تور لوکس هفت‌روزه پاریس', 'tor-loks-hftrozh-parys', 'tours/1787138834.tour-image66216.jpg', NULL, NULL, NULL, NULL, 89000000.00, NULL, 0, 0, '2026-08-19 11:27:14', '2026-08-19 11:27:14'),
(8, NULL, 'تور اقتصادی چهارروزه باکو', 'tor-aktsady-chharrozh-bako', 'tours/1787138868.tour-image42665.jpg', NULL, NULL, NULL, NULL, 15800000.00, NULL, 0, 0, '2026-08-19 11:27:48', '2026-08-19 11:27:48'),
(9, NULL, 'test', 'test', 'tours/1787146812.tour-image88373.jpg', NULL, NULL, NULL, NULL, 2000000.00, NULL, 0, 0, '2026-08-19 13:40:12', '2026-08-19 13:40:14');
-- --------------------------------------------------------
--
-- Table structure for table `tour_flights`
--
DROP TABLE IF EXISTS `tour_flights`;
CREATE TABLE IF NOT EXISTS `tour_flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`tour_id` bigint UNSIGNED NOT NULL,
`flight_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tour_flights` (`flight_id`),
KEY `fk2_tour_flights` (`tour_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `travel_types`
--
DROP TABLE IF EXISTS `travel_types`;
CREATE TABLE IF NOT EXISTS `travel_types` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`title` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `travel_types`
--
INSERT INTO `travel_types` (`id`, `title`, `slug`, `status`, `created_at`, `updated_at`) VALUES
(2, 'تور داخلی', 'domestic-tour', 1, '2026-08-17 11:36:22', '2026-08-17 11:36:22'),
(3, 'تور خارجی', 'international-tour', 1, '2026-08-17 11:46:33', '2026-08-17 11:46:33'),
(4, 'تور چارتر', 'charter-tour', 1, '2026-08-17 11:46:59', '2026-08-17 11:46:59'),
(5, 'تور ترکیبی', 'combined-tour', 1, '2026-08-17 11:47:41', '2026-08-17 11:47:41'),
(6, 'پرواز خارجی', 'international-flight', 1, '2026-08-17 11:48:19', '2026-08-17 11:48:19'),
(7, 'پرواز داخلی', 'domestic-flight', 1, '2026-08-17 11:48:44', '2026-08-17 11:48:44'),
(8, 'تور لحظه آخری', 'last-minute', 1, '2026-08-17 11:49:11', '2026-08-17 11:49:11'),
(9, 'پیشنویس نمونه', 'draft-sample', 0, '2026-08-17 11:49:33', '2026-08-17 11:56:13');
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`birth_date` date DEFAULT NULL,
`gender` tinyint(1) NOT NULL COMMENT '1:Male | 2:Female',
`marital_status` tinyint(1) NOT NULL COMMENT '1:Single | 2:Married | 3:Divorced/Separated',
`spouse_name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`username` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`province_id` bigint UNSIGNED NOT NULL,
`city_id` bigint UNSIGNED DEFAULT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `first_name`, `last_name`, `email`, `mobile`, `password`, `national_code`, `birth_date`, `gender`, `marital_status`, `spouse_name`, `image`, `username`, `province_id`, `city_id`, `status`, `created_at`, `updated_at`) VALUES
(1, 'شهرزاد', 'زندی', 'shahrzad2020@gmail.com', '09118909120', '$2y$12$LzDaglfvgypwHT20MAffJOnjpIePJbwJjIcbnoRW8tLy53wNbfFqa', '2080706640', NULL, 2, 1, NULL, 'avatars/FevHjQ0JjviBzlNOGXiI0k1JmshmUIxrDXF3xBAC.jpg', 'shahrzad011', 2, NULL, 1, '2026-08-19 01:09:30', '2026-08-20 13:16:51'),
(2, 'حاتمه', 'اندرزا', 'hatame19@gmail.com', '09119533286', '$2y$12$6AxXNTIpJAK0czNU78PeAObgC.Nl0dTbqKyyMHSGTUrr0GynKyfhq', '2081391693', NULL, 2, 1, NULL, 'users/MU5t6XmUmS558EO4EPQUdO2kDL7XSeDEtoeP83LD.jpg', 'hatame19', 2, NULL, 1, '2026-08-19 06:23:09', '2026-08-19 06:23:09');
--
-- Constraints for dumped tables
--
--
-- Constraints for table `admin_permission`
--
ALTER TABLE `admin_permission`
ADD CONSTRAINT `fk1_admin_permission` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_admin_permission` FOREIGN KEY (`admin_id`) REFERENCES `admins` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `bookings`
--
ALTER TABLE `bookings`
ADD CONSTRAINT `fk1_bookings` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_bookings` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk3_bookings` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `cities`
--
ALTER TABLE `cities`
ADD CONSTRAINT `fk1_cities` FOREIGN KEY (`province_id`) REFERENCES `provinces` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `comments`
--
ALTER TABLE `comments`
ADD CONSTRAINT `fk1_ comments` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `favorites`
--
ALTER TABLE `favorites`
ADD CONSTRAINT `fk1_favorites` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tours`
--
ALTER TABLE `tours`
ADD CONSTRAINT `fk1_tours` FOREIGN KEY (`travel_type_id`) REFERENCES `travel_types` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tour_flights`
--
ALTER TABLE `tour_flights`
ADD CONSTRAINT `fk1_tour_flights` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_tour_flights` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+538
View File
@@ -0,0 +1,538 @@
-- phpMyAdmin SQL Dump
-- version 5.2.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1:3308
-- Generation Time: Aug 22, 2026 at 07:47 AM
-- Server version: 8.4.7
-- PHP Version: 8.3.28
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `airline_agency`
--
-- --------------------------------------------------------
--
-- Table structure for table `admins`
--
DROP TABLE IF EXISTS `admins`;
CREATE TABLE IF NOT EXISTS `admins` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`full_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`username` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1' COMMENT '0:disable 1:enable',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `admins`
--
INSERT INTO `admins` (`id`, `full_name`, `username`, `email`, `mobile`, `password`, `status`, `created_at`, `updated_at`) VALUES
(2, 'شهرزاد زندی', 'shahrzad', 'shahrzad.zandi@gmail.com', '09359359350', '$2y$12$KpHLJK1kIz/TxVUOn4FV7udVA3xGLLDtEknPZyfh13Z2WPkRmHwni', 1, '2026-08-17 07:24:19', '2026-08-17 07:24:19'),
(3, 'مدیر سیستم', 'admin', 'admin@gmail.com', '09123456789', '$2y$12$ElsUA1CqyK6euG6adWhXRuayR/Jzcq1zH28eoN3ypfeVrmTIr/zAe', 1, '2026-08-17 07:44:25', '2026-08-17 09:12:14');
-- --------------------------------------------------------
--
-- Table structure for table `admin_permission`
--
DROP TABLE IF EXISTS `admin_permission`;
CREATE TABLE IF NOT EXISTS `admin_permission` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`admin_id` bigint UNSIGNED NOT NULL,
`permission_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `fk1_admin_permission` (`permission_id`),
KEY `fk2_admin_permission` (`admin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `airports`
--
DROP TABLE IF EXISTS `airports`;
CREATE TABLE IF NOT EXISTS `airports` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`city` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`province` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`code` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `airports`
--
INSERT INTO `airports` (`id`, `name`, `city`, `province`, `code`, `created_at`, `updated_at`) VALUES
(1, 'فرودگاه بین‌المللی اهواز', 'اهواز', 'خوزستان', 'AWZ', '0000-00-00 00:00:00', '0000-00-00 00:00:00');
-- --------------------------------------------------------
--
-- Table structure for table `bookings`
--
DROP TABLE IF EXISTS `bookings`;
CREATE TABLE IF NOT EXISTS `bookings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`tour_id` bigint UNSIGNED DEFAULT NULL,
`flight_id` bigint UNSIGNED DEFAULT NULL,
`booking_code` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`passengers` int UNSIGNED NOT NULL DEFAULT '1',
`price` decimal(15,2) NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`payment_status` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`notes` text COLLATE utf8mb4_unicode_ci,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_bookings` (`user_id`),
KEY `fk2_bookings` (`tour_id`),
KEY `fk3_bookings` (`flight_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `cities`
--
DROP TABLE IF EXISTS `cities`;
CREATE TABLE IF NOT EXISTS `cities` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`province_id` bigint UNSIGNED NOT NULL,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk1_cities` (`province_id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `cities`
--
INSERT INTO `cities` (`id`, `province_id`, `name`, `created_at`, `updated_at`) VALUES
(7, 2, 'ساری', NULL, NULL),
(8, 1, 'تهران', NULL, NULL),
(9, 5, 'شیراز', NULL, NULL),
(10, 4, 'اصفهان', NULL, NULL),
(11, 1, 'ری', NULL, NULL),
(12, 2, 'آمل', NULL, NULL),
(13, 9, 'کرمان', '2026-08-22 04:57:54', '2026-08-22 04:57:54');
-- --------------------------------------------------------
--
-- Table structure for table `comments`
--
DROP TABLE IF EXISTS `comments`;
CREATE TABLE IF NOT EXISTS `comments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`commentable_id` bigint UNSIGNED NOT NULL,
`commentable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`body` text COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_ comments` (`user_id`),
KEY `fk2_ comments` (`commentable_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `comments`
--
INSERT INTO `comments` (`id`, `user_id`, `commentable_id`, `commentable_type`, `body`, `status`, `created_at`, `updated_at`) VALUES
(2, 1, 3, 'App\\Models\\Tour', 'بسیار خوب بود', 1, '2026-08-20 10:15:43', '2026-08-20 10:15:43'),
(3, 1, 3, 'App\\Models\\Tour', 'خیلی هم عالی', 1, '2026-08-20 10:17:07', '2026-08-20 10:17:07'),
(4, 1, 3, 'App\\Models\\Tour', 'من این تور را پسندیدم.', 1, '2026-08-20 13:15:04', '2026-08-20 13:15:04'),
(5, 1, 6, 'App\\Models\\Tour', 'بسیار سفر خوبی بود با این تور', 1, '2026-08-22 06:47:37', '2026-08-22 06:47:37');
-- --------------------------------------------------------
--
-- Table structure for table `favorites`
--
DROP TABLE IF EXISTS `favorites`;
CREATE TABLE IF NOT EXISTS `favorites` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`favoritable_id` bigint UNSIGNED NOT NULL,
`favoritable_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_favorites` (`user_id`),
KEY `fk2_favorites` (`favoritable_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `favorites`
--
INSERT INTO `favorites` (`id`, `user_id`, `favoritable_id`, `favoritable_type`, `created_at`, `updated_at`) VALUES
(3, 1, 3, 'App\\Models\\Tour', '2026-08-19 16:05:52', '2026-08-19 16:05:52'),
(6, 1, 6, 'App\\Models\\Tour', '2026-08-22 06:39:47', '2026-08-22 06:39:47'),
(7, 1, 8, 'App\\Models\\Tour', '2026-08-22 06:48:01', '2026-08-22 06:48:01'),
(8, 1, 5, 'App\\Models\\Tour', '2026-08-22 07:37:20', '2026-08-22 07:37:20');
-- --------------------------------------------------------
--
-- Table structure for table `files`
--
DROP TABLE IF EXISTS `files`;
CREATE TABLE IF NOT EXISTS `files` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`fileable_id` bigint DEFAULT NULL,
`fileable_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`extension` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`size` bigint UNSIGNED NOT NULL,
`original_name` varchar(350) COLLATE utf8mb4_unicode_ci NOT NULL,
`path` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `flights`
--
DROP TABLE IF EXISTS `flights`;
CREATE TABLE IF NOT EXISTS `flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED NOT NULL,
`flight_number` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`airline_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`origin` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`destination` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`departure_date` date NOT NULL,
`departure_time` time NOT NULL,
`arrival_date` date NOT NULL,
`arrival_time` time NOT NULL,
`duration` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED NOT NULL,
`status` tinyint NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `flights`
--
INSERT INTO `flights` (`id`, `travel_type_id`, `flight_number`, `airline_name`, `origin`, `destination`, `departure_date`, `departure_time`, `arrival_date`, `arrival_time`, `duration`, `price`, `capacity`, `status`, `created_at`, `updated_at`) VALUES
(1, 2, 'IR-725', 'ایران ایر', 'تهران', 'مشهد', '1405-06-03', '14:30:00', '1405-06-03', '16:00:00', '1 ساعت و 30 دقیقه', 2500000.00, 180, 0, '2026-08-17 13:52:44', '2026-08-17 13:56:00'),
(2, 3, 'TK-182', 'ترکیش ایرلاینز', 'تهران', 'استانبول', '2026-08-28', '20:00:00', '2026-08-29', '07:31:00', '11 ساعت و 31', 18500000.00, 220, 1, '2026-08-17 14:01:19', '2026-08-17 14:01:19'),
(3, 4, 'CH-401', 'وارش', 'تهران', 'کیش', '2026-09-01', '10:30:00', '2026-09-01', '20:33:00', '10 ساعت و3 دقیقه', 4200000.00, 160, 1, '2026-08-17 14:04:34', '2026-08-17 14:04:34'),
(4, 2, 'ia33', 'test', 'test', 'test', '1405-05-06', '20:12:00', '1405-05-06', '22:06:00', '2', 850000.00, 2, 1, '2026-08-19 13:38:25', '2026-08-19 13:38:25');
-- --------------------------------------------------------
--
-- Table structure for table `payments`
--
DROP TABLE IF EXISTS `payments`;
CREATE TABLE IF NOT EXISTS `payments` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` bigint UNSIGNED NOT NULL,
`payable_id` bigint UNSIGNED NOT NULL,
`amount` decimal(12,2) NOT NULL,
`authority` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`transaction_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint NOT NULL COMMENT 'pending:0 | success:1| failed:2 | canceled:3',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `permissions`
--
DROP TABLE IF EXISTS `permissions`;
CREATE TABLE IF NOT EXISTS `permissions` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `provinces`
--
DROP TABLE IF EXISTS `provinces`;
CREATE TABLE IF NOT EXISTS `provinces` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `provinces`
--
INSERT INTO `provinces` (`id`, `name`, `created_at`, `updated_at`) VALUES
(1, 'تهران', NULL, NULL),
(2, 'مازندران', NULL, NULL),
(3, 'گیلان', NULL, NULL),
(4, 'اصفهان', NULL, NULL),
(5, 'فارس', NULL, NULL),
(6, 'یزد', NULL, NULL),
(7, 'آذربایجان غربی', NULL, NULL),
(8, 'آذربایجان شرقی', NULL, NULL),
(9, 'کرمان', '2026-08-22 04:57:33', '2026-08-22 04:57:33');
-- --------------------------------------------------------
--
-- Table structure for table `settings`
--
DROP TABLE IF EXISTS `settings`;
CREATE TABLE IF NOT EXISTS `settings` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`code` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `tours`
--
DROP TABLE IF EXISTS `tours`;
CREATE TABLE IF NOT EXISTS `tours` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`travel_type_id` bigint UNSIGNED DEFAULT NULL,
`title` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`duration` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
`price` decimal(12,2) NOT NULL,
`capacity` int UNSIGNED DEFAULT NULL,
`views_count` int NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tours` (`travel_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `tours`
--
INSERT INTO `tours` (`id`, `travel_type_id`, `title`, `slug`, `image`, `description`, `duration`, `start_date`, `end_date`, `price`, `capacity`, `views_count`, `status`, `created_at`, `updated_at`) VALUES
(3, NULL, 'تور سه‌روزه اصفهان با راهنمای تخصصی', 'tor-shrozh-asfhan-ba-rahnmay-tkhssy', 'tours/1787037667.tour-image56011.jpg', NULL, NULL, NULL, NULL, 2850000.00, NULL, 80, 1, '2026-08-18 07:21:07', '2026-08-22 06:35:20'),
(4, NULL, 'تور لوکس پنج‌روزه کیش با پرواز مستقیم', 'tor-loks-pngrozh-kysh-ba-proaz-mstkym', 'tours/1787037718.tour-image49479.jpg', NULL, NULL, NULL, NULL, 12500000.00, NULL, 41, 1, '2026-08-18 07:21:58', '2026-08-21 15:21:22'),
(5, NULL, 'تور خانوادگی پنج‌روزه قشم و هرمز', 'tor-khanoadgy-pngrozh-kshm-o-hrmz', 'tours/1787138709.tour-image35820.jpg', NULL, NULL, NULL, NULL, 9750000.00, NULL, 4, 1, '2026-08-19 11:25:09', '2026-08-22 07:37:20'),
(6, NULL, 'تور شش‌روزه رم و فلورانس', 'tor-shshrozh-rm-o-florans', 'tours/1787138776.tour-image35964.jpg', NULL, NULL, NULL, NULL, 76500000.00, NULL, 5, 1, '2026-08-19 11:26:16', '2026-08-22 06:47:38'),
(7, NULL, 'تور لوکس هفت‌روزه پاریس', 'tor-loks-hftrozh-parys', 'tours/1787138834.tour-image66216.jpg', NULL, NULL, NULL, NULL, 89000000.00, NULL, 0, 0, '2026-08-19 11:27:14', '2026-08-22 05:54:45'),
(8, NULL, 'تور اقتصادی چهارروزه باکو', 'tor-aktsady-chharrozh-bako', 'tours/1787138868.tour-image42665.jpg', NULL, NULL, NULL, NULL, 15800000.00, NULL, 2, 1, '2026-08-19 11:27:48', '2026-08-22 06:48:01'),
(9, NULL, 'test', 'test', 'tours/1787146812.tour-image88373.jpg', NULL, NULL, NULL, NULL, 2000000.00, NULL, 0, 0, '2026-08-19 13:40:12', '2026-08-22 05:55:01');
-- --------------------------------------------------------
--
-- Table structure for table `tour_flights`
--
DROP TABLE IF EXISTS `tour_flights`;
CREATE TABLE IF NOT EXISTS `tour_flights` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`tour_id` bigint UNSIGNED NOT NULL,
`flight_id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `fk1_tour_flights` (`flight_id`),
KEY `fk2_tour_flights` (`tour_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `travel_types`
--
DROP TABLE IF EXISTS `travel_types`;
CREATE TABLE IF NOT EXISTS `travel_types` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`title` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `travel_types`
--
INSERT INTO `travel_types` (`id`, `title`, `slug`, `status`, `created_at`, `updated_at`) VALUES
(2, 'تور داخلی', 'domestic-tour', 1, '2026-08-17 11:36:22', '2026-08-17 11:36:22'),
(3, 'تور خارجی', 'international-tour', 1, '2026-08-17 11:46:33', '2026-08-17 11:46:33'),
(4, 'تور چارتر', 'charter-tour', 1, '2026-08-17 11:46:59', '2026-08-17 11:46:59'),
(5, 'تور ترکیبی', 'combined-tour', 1, '2026-08-17 11:47:41', '2026-08-17 11:47:41'),
(6, 'پرواز خارجی', 'international-flight', 1, '2026-08-17 11:48:19', '2026-08-17 11:48:19'),
(7, 'پرواز داخلی', 'domestic-flight', 1, '2026-08-17 11:48:44', '2026-08-17 11:48:44'),
(8, 'تور لحظه آخری', 'last-minute', 1, '2026-08-17 11:49:11', '2026-08-17 11:49:11'),
(9, 'پیشنویس نمونه', 'draft-sample', 0, '2026-08-17 11:49:33', '2026-08-17 11:56:13');
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`national_code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`birth_date` date DEFAULT NULL,
`gender` tinyint(1) NOT NULL COMMENT '1:Male | 2:Female',
`marital_status` tinyint(1) NOT NULL COMMENT '1:Single | 2:Married | 3:Divorced/Separated',
`spouse_name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`username` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`province_id` bigint UNSIGNED NOT NULL,
`city_id` bigint UNSIGNED DEFAULT NULL,
`status` tinyint UNSIGNED NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `first_name`, `last_name`, `email`, `mobile`, `password`, `national_code`, `birth_date`, `gender`, `marital_status`, `spouse_name`, `image`, `username`, `province_id`, `city_id`, `status`, `created_at`, `updated_at`) VALUES
(1, 'شهرزاد', 'زندی', 'shahrzad2020@gmail.com', '09118909120', '$2y$12$exJ7bGMeL8lsMJvdJXYhl.pDRg2tT7tRr.cVstjx0rbQuw04dWgNC', '2080706640', NULL, 2, 1, NULL, 'avatars/FevHjQ0JjviBzlNOGXiI0k1JmshmUIxrDXF3xBAC.jpg', 'shahrzad011', 2, NULL, 1, '2026-08-19 01:09:30', '2026-08-22 06:48:45'),
(2, 'حاتمه', 'اندرزا', 'hatame19@gmail.com', '09119533286', '$2y$12$6AxXNTIpJAK0czNU78PeAObgC.Nl0dTbqKyyMHSGTUrr0GynKyfhq', '2081391693', NULL, 2, 1, NULL, 'users/MU5t6XmUmS558EO4EPQUdO2kDL7XSeDEtoeP83LD.jpg', 'hatame19', 2, NULL, 1, '2026-08-19 06:23:09', '2026-08-19 06:23:09');
--
-- Constraints for dumped tables
--
--
-- Constraints for table `admin_permission`
--
ALTER TABLE `admin_permission`
ADD CONSTRAINT `fk1_admin_permission` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_admin_permission` FOREIGN KEY (`admin_id`) REFERENCES `admins` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `bookings`
--
ALTER TABLE `bookings`
ADD CONSTRAINT `fk1_bookings` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_bookings` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk3_bookings` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `cities`
--
ALTER TABLE `cities`
ADD CONSTRAINT `fk1_cities` FOREIGN KEY (`province_id`) REFERENCES `provinces` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `comments`
--
ALTER TABLE `comments`
ADD CONSTRAINT `fk1_ comments` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `favorites`
--
ALTER TABLE `favorites`
ADD CONSTRAINT `fk1_favorites` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tours`
--
ALTER TABLE `tours`
ADD CONSTRAINT `fk1_tours` FOREIGN KEY (`travel_type_id`) REFERENCES `travel_types` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `tour_flights`
--
ALTER TABLE `tour_flights`
ADD CONSTRAINT `fk1_tour_flights` FOREIGN KEY (`flight_id`) REFERENCES `flights` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `fk2_tour_flights` FOREIGN KEY (`tour_id`) REFERENCES `tours` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+122
View File
@@ -0,0 +1,122 @@
/* ================================================
استایل‌های صفحه حساب کاربری (account pages)
================================================ */
/* ---------- کارت پروفایل (سایدبار) ---------- */
.profile-sidebar {
background: linear-gradient(145deg, #ffffff, #f8fbff);
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 20px;
box-shadow: 0 12px 35px rgba(0, 82, 165, 0.10);
padding: 30px 20px;
transition: transform .3s ease;
}
.profile-sidebar:hover {
transform: translateY(-4px);
}
.profile-avatar {
width: 120px;
height: 120px;
border-radius: 50%;
object-fit: cover;
border: 4px solid #e8f0fe;
box-shadow: 0 6px 18px rgba(0, 123, 255, .25);
}
.profile-name {
font-weight: 700;
color: #1f2d3d;
margin-bottom: 0;
}
.profile-username {
color: #6c757d;
font-size: .85rem;
}
/* ---------- تب‌ها ---------- */
.nav-tabs .nav-link {
color: #6c757d;
font-weight: 600;
border-radius: 12px 12px 0 0;
padding: 10px 18px;
}
.nav-tabs .nav-link.active {
color: #007bff;
border-color: #dee2e6 #dee2e6 #fff;
background: #f8fbff;
}
/* ---------- فرم‌ها ---------- */
.form-card {
background: #ffffff;
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 20px;
box-shadow: 0 5px 22px rgba(0, 0, 0, 0.05);
padding: 25px;
}
.form-card .form-control {
border-radius: 12px;
border: 2px solid #e9ecef;
padding: 11px 15px;
transition: all .3s;
}
.form-card .form-control:focus {
border-color: #007bff;
box-shadow: 0 0 0 .2rem rgba(0, 123, 255, .15);
}
.form-label {
font-weight: 600;
color: #495057;
font-size: .9rem;
}
/* ---------- علاقه‌مندی‌ها ---------- */
.favorite-item {
background: #fff3f5;
color: #d63384;
border: 1.5px solid #f7c8d4;
border-radius: 50px;
padding: 9px 18px;
margin: 4px;
display: inline-flex;
align-items: center;
gap: 6px;
font-weight: 600;
font-size: .9rem;
transition: all .25s;
}
.favorite-item i { font-size: .95rem; }
.favorite-item:hover {
background: #d63384;
color: #fff;
cursor: pointer;
}
/* ---------- کامنت‌ها ---------- */
.comment-box {
background: #f8f9fa;
border-right: 4px solid #17a2b8;
border-radius: 12px;
padding: 14px 16px;
color: #495057;
}
.comment-box small {
color: #17a2b8;
font-weight: 600;
}
/* ---------- دکمه ذخیره ---------- */
.btn-save {
background: linear-gradient(135deg, #007bff, #0d6efd);
border: none;
border-radius: 12px;
padding: 12px 28px;
color: #fff;
font-weight: 600;
box-shadow: 0 6px 15px rgba(0, 123, 255, .3);
transition: all .3s;
}
.btn-save:hover {
transform: translateY(-2px);
box-shadow: 0 9px 20px rgba(0, 123, 255, .4);
color: #fff;
}
+246
View File
@@ -0,0 +1,246 @@
/* ========================================
Admin Panel
Airline Agency
======================================== */
body {
background-color: #f5f7fb;
}
/* Main admin layout */
.admin-wrapper {
min-height: 100vh;
}
/* Sidebar */
.admin-sidebar {
width: 260px;
min-height: 100vh;
background: #ffffff;
border-left: 1px solid #e9ecef;
}
/* Main content */
.admin-content {
min-height: 100vh;
padding: 24px;
}
/* Cards */
.admin-card {
background: #ffffff;
border: 1px solid #e9ecef;
border-radius: 12px;
}
/* Dashboard stat cards */
.admin-stat-card {
transition: all .2s ease;
}
.admin-stat-card:hover {
transform: translateY(-2px);
}
/* Sidebar links */
.admin-sidebar .nav-link {
color: #495057;
border-radius: 8px;
margin-bottom: 4px;
padding: 10px 12px;
}
.admin-sidebar .nav-link:hover {
background-color: #f1f5f9;
}
.admin-sidebar .nav-link.active {
background-color: #eaf2ff;
color: #0d6efd;
}
/* Airline icon box */
.admin-icon-box {
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 12px;
}
/* Tables */
.admin-table th {
white-space: nowrap;
}
.admin-table td {
vertical-align: middle;
}
/* Breadcrumb */
.admin-breadcrumb {
margin-bottom: 20px;
}
/* Responsive */
@media (max-width: 991px) {
.admin-sidebar {
width: 100%;
min-height: auto;
}
.admin-content {
padding: 16px;
}
}
body {
background: #f5f7fa;
}
.admin-wrapper {
min-height: 100vh;
}
.admin-sidebar {
width: 260px;
min-height: 100vh;
background: #fff;
border-left: 1px solid #e5e7eb;
position: fixed;
right: 0;
top: 0;
bottom: 0;
z-index: 1000;
overflow-y: auto;
}
.admin-main {
margin-right: 260px;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.admin-header {
height: 70px;
background: #fff;
border-bottom: 1px solid #e5e7eb;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 25px;
}
.admin-content {
padding: 25px;
flex: 1;
}
.admin-logo {
height: 70px;
display: flex;
align-items: center;
padding: 0 20px;
border-bottom: 1px solid #eee;
}
.admin-logo a {
text-decoration: none;
font-size: 18px;
font-weight: bold;
color: #0d6efd;
}
.admin-menu {
padding: 15px 10px;
}
.admin-menu-title {
font-size: 11px;
color: #9ca3af;
padding: 10px;
margin-top: 10px;
}
.admin-menu a {
display: flex;
align-items: center;
gap: 10px;
padding: 11px 12px;
margin-bottom: 4px;
border-radius: 8px;
color: #4b5563;
text-decoration: none;
transition: .2s;
}
.admin-menu a:hover,
.admin-menu a.active {
background: #eef5ff;
color: #0d6efd;
}
.admin-menu i {
width: 22px;
text-align: center;
font-size: 16px;
}
.admin-user {
display: flex;
align-items: center;
gap: 10px;
}
.admin-user-avatar {
width: 38px;
height: 38px;
border-radius: 50%;
background: #eef5ff;
display: flex;
align-items: center;
justify-content: center;
color: #0d6efd;
}
.admin-card {
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 12px;
}
@media (max-width: 991px) {
.admin-sidebar {
transform: translateX(100%);
}
}
+277
View File
@@ -0,0 +1,277 @@
/* ==========================================
استایل صفحات آرشیو تورها و پروازها
========================================== */
.archive-page {
background: #f6f8fb;
min-height: 60vh;
padding: 50px 0;
}
/* هدر صفحه آرشیو */
.archive-header {
background: linear-gradient(135deg, #1e3a8a, #3b82f6);
border-radius: 16px;
padding: 28px 30px;
margin-bottom: 35px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 15px;
box-shadow: 0 8px 24px rgba(30, 58, 138, 0.25);
}
.archive-header h4 {
color: #fff;
font-weight: 700;
margin: 0;
font-size: 1.4rem;
}
.archive-header .btn-back {
background: rgba(255, 255, 255, 0.15);
color: #fff;
border: 1px solid rgba(255, 255, 255, 0.4);
border-radius: 50px;
padding: 7px 22px;
font-size: 0.9rem;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 6px;
}
.archive-header .btn-back:hover {
background: #fff;
color: #1e3a8a;
}
/* کارت تور */
.tour-card {
background: #fff;
border-radius: 14px;
overflow: hidden;
border: none;
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.08);
transition: transform 0.3s ease, box-shadow 0.3s ease;
height: 100%;
}
.tour-card:hover {
transform: translateY(-6px);
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.14);
}
.tour-card .tour-image-wrap {
position: relative;
height: 200px;
overflow: hidden;
}
.tour-card .tour-image-wrap img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
}
.tour-card:hover .tour-image-wrap img {
transform: scale(1.08);
}
.tour-card .tour-body {
padding: 20px;
}
.tour-card .tour-title {
font-size: 1.1rem;
font-weight: 700;
margin-bottom: 10px;
}
.tour-card .tour-title a {
color: #1e3a8a;
text-decoration: none;
transition: color 0.3s;
}
.tour-card .tour-title a:hover {
color: #3b82f6;
}
.tour-card .tour-desc {
color: #6c757d;
font-size: 0.88rem;
line-height: 1.8;
margin-bottom: 15px;
min-height: 48px;
}
.tour-card .tour-footer {
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px dashed #e5e7eb;
padding-top: 14px;
}
.tour-card .tour-price {
background: #eef2ff;
color: #4338ca;
border-radius: 50px;
padding: 5px 16px;
font-size: 0.85rem;
font-weight: 600;
}
/* کارت پرواز */
.flight-card {
background: #fff;
border-radius: 14px;
border: none;
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.08);
transition: transform 0.3s ease, box-shadow 0.3s ease;
height: 100%;
}
.flight-card:hover {
transform: translateY(-6px);
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.14);
}
.flight-card .flight-body {
padding: 22px 20px;
}
.flight-card .flight-route {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 18px;
}
.flight-card .flight-city {
text-align: center;
flex: 1;
}
.flight-card .flight-city span {
display: block;
font-size: 0.75rem;
color: #9ca3af;
margin-bottom: 4px;
}
.flight-card .flight-city strong {
font-size: 1.05rem;
color: #1e293b;
}
.flight-card .flight-line {
flex: 0 0 auto;
display: flex;
align-items: center;
color: #3b82f6;
font-size: 1.1rem;
padding: 0 12px;
}
.flight-card .flight-line .plane-icon {
margin: 0 6px;
font-size: 1.2rem;
}
.flight-card .flight-info {
background: #f8fafc;
border-radius: 10px;
padding: 12px 15px;
margin-bottom: 15px;
font-size: 0.85rem;
color: #475569;
}
.flight-card .flight-info p {
margin-bottom: 5px;
display: flex;
align-items: center;
gap: 6px;
}
.flight-card .flight-info p:last-child {
margin-bottom: 0;
}
.flight-card .flight-price {
background: #eef2ff;
color: #4338ca;
border-radius: 50px;
padding: 5px 16px;
font-size: 0.85rem;
font-weight: 600;
display: inline-block;
}
/* صفحه‌بندی */
.archive-pagination {
margin-top: 40px;
}
.archive-pagination .pagination {
justify-content: center;
gap: 5px;
}
.archive-pagination .page-item .page-link {
border-radius: 8px;
border: 1px solid #e5e7eb;
color: #475569;
padding: 8px 15px;
min-width: 42px;
text-align: center;
transition: all 0.3s;
background: #fff;
}
.archive-pagination .page-item .page-link:hover {
background: #eef2ff;
color: #4338ca;
border-color: #c7d2fe;
}
.archive-pagination .page-item.active .page-link {
background: #1e3a8a;
border-color: #1e3a8a;
color: #fff;
box-shadow: 0 4px 12px rgba(30, 58, 138, 0.3);
}
/* پیام خالی */
.archive-empty {
background: #fff;
border: 2px dashed #d1d5db;
border-radius: 14px;
padding: 60px 20px;
text-align: center;
color: #9ca3af;
}
.archive-empty i {
font-size: 3rem;
display: block;
margin-bottom: 15px;
color: #cbd5e1;
}
/* ریسپانسیو */
@media (max-width: 575.98px) {
.archive-header {
flex-direction: column;
text-align: center;
}
.tour-card .tour-image-wrap {
height: 180px;
}
}
+379
View File
@@ -0,0 +1,379 @@
/* =========================================
AUTH PAGE
========================================= */
.auth-page {
min-height: 80vh;
padding: 70px 0;
background: #f5f7fb;
direction: rtl;
}
/* =========================================
CARD
========================================= */
.auth-card {
width: 100%;
max-width: 900px;
margin: 0 auto;
background: #fff;
border-radius: 18px;
padding: 40px;
box-shadow:
0 15px 45px rgba(0, 0, 0, 0.10);
}
.login-card {
max-width: 500px;
}
/* =========================================
HEADER
========================================= */
.auth-header {
text-align: center;
margin-bottom: 35px;
}
.auth-icon {
width: 70px;
height: 70px;
margin: 0 auto 18px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #eef5ff;
color: #1473e6;
font-size: 28px;
}
.auth-header h1 {
margin: 0 0 10px;
font-size: 27px;
font-weight: 700;
color: #222;
}
.auth-header p {
margin: 0;
color: #777;
font-size: 14px;
line-height: 1.8;
}
/* =========================================
FORM SECTION
========================================= */
.form-section {
margin-bottom: 30px;
padding-bottom: 25px;
border-bottom: 1px solid #eee;
}
.form-section:last-of-type {
border-bottom: none;
}
.form-section-title {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 22px;
font-size: 17px;
font-weight: 700;
color: #333;
}
.form-section-title i {
color: #1473e6;
font-size: 19px;
}
/* =========================================
FORM
========================================= */
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-size: 14px;
font-weight: 600;
color: #333;
}
.form-group label span {
color: #e53935;
}
.form-control {
width: 100%;
height: 48px;
border: 1px solid #ddd;
border-radius: 9px;
padding: 0 14px;
background: #fff;
color: #333;
font-size: 14px;
transition: all 0.2s ease;
box-shadow: none;
}
.form-control:focus {
border-color: #1473e6;
outline: none;
box-shadow:
0 0 0 3px rgba(20, 115, 230, 0.10);
}
textarea.form-control {
height: auto;
padding-top: 12px;
}
select.form-control {
cursor: pointer;
}
.form-help {
display: block;
margin-top: 6px;
color: #888;
font-size: 12px;
line-height: 1.7;
}
/* =========================================
ALERT
========================================= */
.auth-alert {
display: flex;
gap: 12px;
padding: 15px;
margin-bottom: 25px;
border-radius: 10px;
font-size: 14px;
line-height: 1.8;
}
.auth-alert-danger {
background: #fff1f1;
color: #b42318;
border: 1px solid #ffd5d5;
}
.auth-alert-success {
background: #effbf3;
color: #16733a;
border: 1px solid #ccefd9;
}
.auth-alert i {
margin-top: 4px;
}
.auth-alert ul {
margin: 7px 0 0;
padding-right: 18px;
}
/* =========================================
LOGIN OPTIONS
========================================= */
.login-options {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
}
.remember-me {
display: flex;
align-items: center;
gap: 7px;
cursor: pointer;
font-size: 13px;
color: #666;
}
.remember-me input {
cursor: pointer;
}
/* =========================================
BUTTON
========================================= */
.auth-btn {
width: 100%;
height: 52px;
border: none;
border-radius: 10px;
background: #1473e6;
color: #fff;
font-size: 15px;
font-weight: 700;
cursor: pointer;
transition: all 0.25s ease;
}
.auth-btn:hover {
background: #0d5fc5;
transform: translateY(-1px);
box-shadow:
0 8px 20px rgba(20, 115, 230, 0.22);
}
.auth-btn i {
margin-left: 7px;
}
/* =========================================
FOOTER
========================================= */
.auth-footer {
margin-top: 25px;
padding-top: 22px;
border-top: 1px solid #eee;
text-align: center;
color: #777;
font-size: 14px;
}
.auth-footer a {
color: #1473e6;
font-weight: 700;
text-decoration: none;
margin-right: 5px;
}
.auth-footer a:hover {
text-decoration: underline;
}
/* =========================================
RESPONSIVE
========================================= */
@media (max-width: 767px) {
.auth-page {
padding: 30px 15px;
}
.auth-card {
padding: 25px 18px;
border-radius: 14px;
}
.auth-header h1 {
font-size: 23px;
}
.form-section-title {
font-size: 16px;
}
}
+178
View File
@@ -0,0 +1,178 @@
/* =========================================================
تایپوگرافی و تنظیمات پایه (یکپارچه)
========================================================= */
body, html {
font-family: 'Tahoma', 'Arial', sans-serif !important;
/*font-size: 13px !important; !* متن اصلی خواناتر *!*/
line-height: 1.8 !important;
color: #374151 !important;
/*background: #f5f7fa;*/
}
h1, h2, h3, h4, h5 {
font-family: 'Tahoma', sans-serif !important;
color: #1f2937 !important;
}
/* اصلاح فرم‌ها */
.form-control, input, select, textarea {
font-size: 12px !important;
padding: 10px 14px !important;
}
/* =========================================================
استایل‌های کارت‌ها (مشترک بین همه صفحات)
========================================================= */
.travel-card, .flight-card, .tour-card, .tour-details-card {
background: #fff;
border-radius: 16px;
border: 1px solid #eef0f5;
transition: all .3s ease;
}
.travel-card:hover, .flight-card:hover, .tour-details-card:hover {
box-shadow: 0 10px 25px rgba(20, 50, 90, .10);
}
/* دکمه‌های اصلی */
.travel-btn {
display: inline-block;
background: #1687d9;
color: #fff !important;
font-size: 12px;
font-weight: 400;
padding: 10px 20px;
border-radius: 8px;
text-decoration: none;
}
.travel-btn:hover { background: #0e6bb0; }
/* دکمه علاقه‌مندی */
.travel-favorite-btn {
display: inline-flex;
align-items: center;
gap: 8px;
background: transparent;
border: 1px solid #e0245e;
color: #e0245e;
border-radius: 25px;
padding: 8px 20px;
font-size: 12px;
cursor: pointer;
transition: all .2s ease;
}
.travel-favorite-btn:hover, .travel-favorite-btn.active {
background: #e0245e;
color: #fff;
}
/* =========================================================
بخش اختصاصی جزئیات تور (tour-details-page)
========================================================= */
.tour-details-page { padding: 30px 0; }
.tour-details-card { padding: 30px; margin-bottom: 30px; }
.tour-details-image {
width: 100%;
height: 350px;
overflow: hidden;
border-radius: 12px;
margin-bottom: 20px;
}
.tour-details-image img { width: 100%; height: 100%; object-fit: cover; }
.tour-details-info {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 15px;
margin: 25px 0;
}
.tour-info-box {
background: #f8fafc;
padding: 15px;
border-radius: 10px;
text-align: center;
border: 1px solid #eef0f5;
}
.tour-info-label {
display: block;
font-size: 12px;
color: #8a93a3;
margin-bottom: 5px;
}
.tour-info-box strong {
font-size: 13px;
color: #1f2937;
display: block;
}
.tour-flights .flight-item {
background: #f8fafc;
padding: 15px;
border-radius: 10px;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
}
/* =========================================================
عنوان بخش‌ها (Global Header Style)
========================================================= */
h2 {
font-size: 15px !important;
font-weight: 500 !important;
padding-right: 15px;
position: relative;
margin-bottom: 20px !important;
}
h2::before {
content: "";
position: absolute;
right: 0;
top: 2px;
width: 5px;
height: 24px;
/*background: #1687d9;*/
border-radius: 4px;
}
/* =========================================================
حفظ رنگ سفید در هیرو (travel-hero)
این قانون باید بعد از قانون سراسری h1 قرار بگیرد
========================================================= */
.travel-hero-content h1,
.travel-hero-content h1 span {
color: #ffffff !important;
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
/* متن‌های دیگر هیرو هم سفید و خوانا */
.travel-hero-label,
.travel-hero-content p {
color: #ffffff !important;
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
.travel-card {
display: flex;
flex-direction: column;
border-radius: 8px;
overflow: hidden;
background: #fff;
transition: transform 0.3s ease;
}
.travel-card-image img {
width: 100%;
height: 200px;
object-fit: cover;
}
.travel-card-body {
padding: 15px;
flex-grow: 1;
}
+740 -4
View File
@@ -14569,9 +14569,7 @@ jdp-container .jdp-icon-plus.not-in-range svg, jdp-container .jdp-icon-minus.not
opacity: 0.3;
}
jdp-container .jdp-years, jdp-container .jdp-months {
display: -webkit-inline-box;
display: -webkit-flex;
display: -ms-inline-flexbox;
/*display: -webkit-flex;*/
display: inline-flex;
margin: 0 2.5%;
font-size: 120%;
@@ -14746,4 +14744,742 @@ jdp-container .jdp-btn-today, jdp-container .jdp-btn-empty {
}
.datepic:focus {
outline: none;
}
}
/* =========================================================
TRAVEL HERO HEADER
========================================================= */
.travel-header {
position: relative;
min-height: 560px;
overflow: hidden;
direction: rtl;
color: #fff;
}
/* Background */
.travel-header-bg {
position: absolute;
inset: 0;
z-index: 0;
}
.travel-header-bg-image {
position: absolute;
inset: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
transform: scale(1.02);
}
.travel-header-overlay {
position: absolute;
inset: 0;
background:
linear-gradient(
180deg,
rgba(5, 20, 40, .78) 0%,
rgba(5, 20, 40, .48) 45%,
rgba(5, 20, 40, .72) 100%
);
}
/* Content */
.travel-header-content {
position: relative;
z-index: 2;
}
/* =========================================================
NAVBAR
========================================================= */
.travel-navbar {
min-height: 90px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid rgba(255,255,255,.18);
position: relative;
}
/* Logo */
.travel-logo a {
display: flex;
align-items: center;
gap: 12px;
text-decoration: none !important;
color: #fff;
}
.travel-logo-icon {
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 14px;
background: rgba(255,255,255,.15);
border: 1px solid rgba(255,255,255,.28);
backdrop-filter: blur(8px);
font-size: 21px;
}
.travel-logo-content {
display: flex;
flex-direction: column;
line-height: 1.5;
}
.travel-logo-content strong {
font-size: 17px;
font-weight: 800;
}
.travel-logo-content small {
font-size: 11px;
opacity: .75;
}
/* =========================================================
MENU
========================================================= */
.travel-menu ul {
display: flex;
align-items: center;
margin: 0;
padding: 0;
list-style: none;
gap: 4px;
}
.travel-menu li {
position: relative;
}
.travel-menu a {
display: block;
padding: 12px 17px;
color: rgba(255,255,255,.88);
text-decoration: none !important;
font-size: 14px;
font-weight: 600;
border-radius: 9px;
transition: all .25s ease;
}
.travel-menu a:hover {
color: #fff;
background: rgba(255,255,255,.12);
}
.travel-menu li.active a {
color: #fff;
background: rgba(255,255,255,.15);
}
/* خط زیر آیتم فعال */
.travel-menu li.active::after {
content: "";
position: absolute;
bottom: -1px;
left: 17px;
right: 17px;
height: 3px;
background: #fff;
border-radius: 10px 10px 0 0;
}
/* =========================================================
ACTION
========================================================= */
.travel-navbar-actions {
display: flex;
align-items: center;
gap: 10px;
}
.travel-login {
display: flex;
align-items: center;
gap: 8px;
padding: 11px 18px;
color: #fff !important;
text-decoration: none !important;
border-radius: 10px;
background: rgba(255,255,255,.14);
border: 1px solid rgba(255,255,255,.25);
backdrop-filter: blur(8px);
font-size: 13px;
font-weight: 700;
transition: all .25s ease;
}
.travel-login:hover {
background: rgba(255,255,255,.23);
transform: translateY(-2px);
}
/* =========================================================
HERO CONTENT
========================================================= */
.travel-hero {
min-height: 465px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.travel-hero-content {
max-width: 800px;
margin: auto;
padding: 70px 20px 80px;
}
.travel-hero-label {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
border-radius: 50px;
background: rgba(255,255,255,.13);
border: 1px solid rgba(255,255,255,.2);
backdrop-filter: blur(8px);
font-size: 13px;
}
.travel-hero h1 {
margin: 20px 0 15px;
color: #fff;
font-size: 48px;
line-height: 1.45;
font-weight: 800;
text-shadow: 0 4px 20px rgba(0,0,0,.25);
}
.travel-hero h1 span {
color: #fff;
}
.travel-hero p {
max-width: 620px;
margin: 0 auto;
color: rgba(255,255,255,.88);
font-size: 16px;
line-height: 2;
}
/* =========================================================
HERO BUTTONS
========================================================= */
.travel-hero-buttons {
margin-top: 30px;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
.hero-btn {
min-width: 160px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 13px 22px;
border-radius: 11px;
text-decoration: none !important;
font-size: 14px;
font-weight: 700;
transition: all .25s ease;
}
.hero-btn-primary {
color: #1268d8 !important;
background: #fff;
box-shadow: 0 10px 30px rgba(0,0,0,.18);
}
.hero-btn-primary:hover {
transform: translateY(-3px);
box-shadow: 0 14px 35px rgba(0,0,0,.25);
}
.hero-btn-outline {
color: #fff !important;
border: 1px solid rgba(255,255,255,.45);
background: rgba(255,255,255,.08);
backdrop-filter: blur(8px);
}
.hero-btn-outline:hover {
color: #1268d8 !important;
background: #fff;
transform: translateY(-3px);
}
/* =========================================================
MOBILE
========================================================= */
.travel-mobile-toggle {
display: none;
width: 42px;
height: 42px;
border: 1px solid rgba(255,255,255,.25);
border-radius: 10px;
background: rgba(255,255,255,.12);
color: #fff;
cursor: pointer;
}
.travel-mobile-menu {
display: none;
}
/* =========================================================
RESPONSIVE
========================================================= */
@media (max-width: 991px) {
.travel-menu {
display: none;
}
.travel-mobile-toggle {
display: flex;
align-items: center;
justify-content: center;
}
.travel-header {
min-height: 500px;
}
.travel-hero h1 {
font-size: 38px;
}
}
@media (max-width: 576px) {
.travel-navbar {
min-height: 72px;
}
.travel-logo-icon {
width: 42px;
height: 42px;
}
.travel-logo-content strong {
font-size: 14px;
}
.travel-logo-content small {
display: none;
}
.travel-login {
padding: 9px 11px;
font-size: 12px;
}
.travel-login i {
display: none;
}
.travel-hero {
min-height: 420px;
}
.travel-hero-content {
padding: 50px 15px;
}
.travel-hero h1 {
font-size: 30px;
line-height: 1.6;
}
.travel-hero p {
font-size: 13px;
}
.travel-hero-buttons {
flex-direction: column;
}
.hero-btn {
width: 100%;
max-width: 260px;
}
}
/* =========================================
User Menu
========================================= */
.travel-user-menu {
position: relative;
display: inline-block;
}
/* دکمه حساب کاربری */
.travel-user-button {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
border: 1px solid rgba(255, 255, 255, 0.35);
border-radius: 30px;
background: rgba(255, 255, 255, 0.12);
color: #fff;
cursor: pointer;
font-family: inherit;
font-size: 14px;
transition: all 0.25s ease;
backdrop-filter: blur(8px);
}
.travel-user-button:hover {
background: rgba(255, 255, 255, 0.22);
}
.travel-user-button > i:first-child {
font-size: 20px;
}
.travel-user-arrow {
font-size: 12px;
transition: transform 0.25s ease;
}
/* =========================================
Dropdown
========================================= */
.travel-user-dropdown {
position: absolute;
top: calc(100% + 12px);
left: 0;
width: 220px;
padding: 8px;
background: #fff;
border-radius: 12px;
box-shadow:
0 10px 30px rgba(0, 0, 0, 0.15),
0 3px 10px rgba(0, 0, 0, 0.08);
opacity: 0;
visibility: hidden;
transform: translateY(-8px);
transition:
opacity 0.25s ease,
visibility 0.25s ease,
transform 0.25s ease;
z-index: 999;
}
/* باز شدن منو */
.travel-user-menu:hover .travel-user-dropdown {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
/* فلش */
.travel-user-menu:hover .travel-user-arrow {
transform: rotate(180deg);
}
/* =========================================
Dropdown Items
========================================= */
.travel-user-dropdown a {
display: flex;
align-items: center;
gap: 10px;
padding: 11px 12px;
border-radius: 8px;
color: #333;
text-decoration: none;
font-size: 14px;
transition: all 0.2s ease;
}
.travel-user-dropdown a i {
width: 20px;
text-align: center;
font-size: 16px;
}
.travel-user-dropdown a:hover {
background: #f1f5f9;
color: #2563eb;
transform: translateX(-3px);
}
/* =========================================
Divider
========================================= */
.travel-dropdown-divider {
height: 1px;
margin: 6px 4px;
background: #e5e7eb;
}
/* =========================================
Logout
========================================= */
.travel-user-dropdown .travel-logout-link {
color: #dc2626;
}
.travel-user-dropdown .travel-logout-link:hover {
background: #fef2f2;
color: #dc2626;
}
/* =========================================
Login / Register
========================================= */
.travel-navbar-actions {
display: flex;
align-items: center;
gap: 10px;
}
.travel-login,
.travel-register {
display: inline-flex;
align-items: center;
gap: 7px;
padding: 9px 15px;
border-radius: 25px;
text-decoration: none;
font-size: 14px;
transition: all 0.25s ease;
}
.travel-login {
color: #fff;
border: 1px solid rgba(255, 255, 255, 0.4);
background: rgba(255, 255, 255, 0.1);
}
.travel-login:hover {
background: rgba(255, 255, 255, 0.2);
color: #fff;
}
.travel-register {
color: #fff;
background: #2563eb;
border: 1px solid #2563eb;
box-shadow: 0 5px 15px rgba(37, 99, 235, 0.25);
}
.travel-register:hover {
background: #1d4ed8;
color: #fff;
transform: translateY(-2px);
}
/* =========================================
Mobile
========================================= */
@media (max-width: 768px) {
.travel-user-button span {
display: none;
}
.travel-user-button {
padding: 9px 12px;
}
.travel-user-dropdown {
left: auto;
right: 0;
}
.travel-login span,
.travel-register span {
display: none;
}
}
File diff suppressed because one or more lines are too long
+28
View File
@@ -359,3 +359,31 @@ $('.mobile-picker').each(function(i, item){
});
}
});
document.addEventListener('DOMContentLoaded', function () {
const menuButton = document.querySelector('.mobile-menu-toggle');
const mobileNavigation = document.querySelector('.mobile-navigation');
if (!menuButton || !mobileNavigation) {
return;
}
menuButton.addEventListener('click', function () {
const isOpen = mobileNavigation.style.display === 'block';
mobileNavigation.style.display = isOpen ? 'none' : 'block';
const icon = menuButton.querySelector('i');
if (icon) {
icon.className = isOpen
? 'fa fa-bars'
: 'fa fa-times';
}
});
});
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+601
View File
@@ -0,0 +1,601 @@
/*!
* Bootstrap Reboot v5.3.8 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
:root,
[data-bs-theme=light] {
--bs-blue: #0d6efd;
--bs-indigo: #6610f2;
--bs-purple: #6f42c1;
--bs-pink: #d63384;
--bs-red: #dc3545;
--bs-orange: #fd7e14;
--bs-yellow: #ffc107;
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-black: #000;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
--bs-gray-100: #f8f9fa;
--bs-gray-200: #e9ecef;
--bs-gray-300: #dee2e6;
--bs-gray-400: #ced4da;
--bs-gray-500: #adb5bd;
--bs-gray-600: #6c757d;
--bs-gray-700: #495057;
--bs-gray-800: #343a40;
--bs-gray-900: #212529;
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
--bs-light: #f8f9fa;
--bs-dark: #212529;
--bs-primary-rgb: 13, 110, 253;
--bs-secondary-rgb: 108, 117, 125;
--bs-success-rgb: 25, 135, 84;
--bs-info-rgb: 13, 202, 240;
--bs-warning-rgb: 255, 193, 7;
--bs-danger-rgb: 220, 53, 69;
--bs-light-rgb: 248, 249, 250;
--bs-dark-rgb: 33, 37, 41;
--bs-primary-text-emphasis: #052c65;
--bs-secondary-text-emphasis: #2b2f32;
--bs-success-text-emphasis: #0a3622;
--bs-info-text-emphasis: #055160;
--bs-warning-text-emphasis: #664d03;
--bs-danger-text-emphasis: #58151c;
--bs-light-text-emphasis: #495057;
--bs-dark-text-emphasis: #495057;
--bs-primary-bg-subtle: #cfe2ff;
--bs-secondary-bg-subtle: #e2e3e5;
--bs-success-bg-subtle: #d1e7dd;
--bs-info-bg-subtle: #cff4fc;
--bs-warning-bg-subtle: #fff3cd;
--bs-danger-bg-subtle: #f8d7da;
--bs-light-bg-subtle: #fcfcfd;
--bs-dark-bg-subtle: #ced4da;
--bs-primary-border-subtle: #9ec5fe;
--bs-secondary-border-subtle: #c4c8cb;
--bs-success-border-subtle: #a3cfbb;
--bs-info-border-subtle: #9eeaf9;
--bs-warning-border-subtle: #ffe69c;
--bs-danger-border-subtle: #f1aeb5;
--bs-light-border-subtle: #e9ecef;
--bs-dark-border-subtle: #adb5bd;
--bs-white-rgb: 255, 255, 255;
--bs-black-rgb: 0, 0, 0;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
--bs-body-font-family: var(--bs-font-sans-serif);
--bs-body-font-size: 1rem;
--bs-body-font-weight: 400;
--bs-body-line-height: 1.5;
--bs-body-color: #212529;
--bs-body-color-rgb: 33, 37, 41;
--bs-body-bg: #fff;
--bs-body-bg-rgb: 255, 255, 255;
--bs-emphasis-color: #000;
--bs-emphasis-color-rgb: 0, 0, 0;
--bs-secondary-color: rgba(33, 37, 41, 0.75);
--bs-secondary-color-rgb: 33, 37, 41;
--bs-secondary-bg: #e9ecef;
--bs-secondary-bg-rgb: 233, 236, 239;
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
--bs-tertiary-color-rgb: 33, 37, 41;
--bs-tertiary-bg: #f8f9fa;
--bs-tertiary-bg-rgb: 248, 249, 250;
--bs-heading-color: inherit;
--bs-link-color: #0d6efd;
--bs-link-color-rgb: 13, 110, 253;
--bs-link-decoration: underline;
--bs-link-hover-color: #0a58ca;
--bs-link-hover-color-rgb: 10, 88, 202;
--bs-code-color: #d63384;
--bs-highlight-color: #212529;
--bs-highlight-bg: #fff3cd;
--bs-border-width: 1px;
--bs-border-style: solid;
--bs-border-color: #dee2e6;
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
--bs-border-radius: 0.375rem;
--bs-border-radius-sm: 0.25rem;
--bs-border-radius-lg: 0.5rem;
--bs-border-radius-xl: 1rem;
--bs-border-radius-xxl: 2rem;
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
--bs-border-radius-pill: 50rem;
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
--bs-focus-ring-width: 0.25rem;
--bs-focus-ring-opacity: 0.25;
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
--bs-form-valid-color: #198754;
--bs-form-valid-border-color: #198754;
--bs-form-invalid-color: #dc3545;
--bs-form-invalid-border-color: #dc3545;
}
[data-bs-theme=dark] {
color-scheme: dark;
--bs-body-color: #dee2e6;
--bs-body-color-rgb: 222, 226, 230;
--bs-body-bg: #212529;
--bs-body-bg-rgb: 33, 37, 41;
--bs-emphasis-color: #fff;
--bs-emphasis-color-rgb: 255, 255, 255;
--bs-secondary-color: rgba(222, 226, 230, 0.75);
--bs-secondary-color-rgb: 222, 226, 230;
--bs-secondary-bg: #343a40;
--bs-secondary-bg-rgb: 52, 58, 64;
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
--bs-tertiary-color-rgb: 222, 226, 230;
--bs-tertiary-bg: #2b3035;
--bs-tertiary-bg-rgb: 43, 48, 53;
--bs-primary-text-emphasis: #6ea8fe;
--bs-secondary-text-emphasis: #a7acb1;
--bs-success-text-emphasis: #75b798;
--bs-info-text-emphasis: #6edff6;
--bs-warning-text-emphasis: #ffda6a;
--bs-danger-text-emphasis: #ea868f;
--bs-light-text-emphasis: #f8f9fa;
--bs-dark-text-emphasis: #dee2e6;
--bs-primary-bg-subtle: #031633;
--bs-secondary-bg-subtle: #161719;
--bs-success-bg-subtle: #051b11;
--bs-info-bg-subtle: #032830;
--bs-warning-bg-subtle: #332701;
--bs-danger-bg-subtle: #2c0b0e;
--bs-light-bg-subtle: #343a40;
--bs-dark-bg-subtle: #1a1d20;
--bs-primary-border-subtle: #084298;
--bs-secondary-border-subtle: #41464b;
--bs-success-border-subtle: #0f5132;
--bs-info-border-subtle: #087990;
--bs-warning-border-subtle: #997404;
--bs-danger-border-subtle: #842029;
--bs-light-border-subtle: #495057;
--bs-dark-border-subtle: #343a40;
--bs-heading-color: inherit;
--bs-link-color: #6ea8fe;
--bs-link-hover-color: #8bb9fe;
--bs-link-color-rgb: 110, 168, 254;
--bs-link-hover-color-rgb: 139, 185, 254;
--bs-code-color: #e685b5;
--bs-highlight-color: #dee2e6;
--bs-highlight-bg: #664d03;
--bs-border-color: #495057;
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
--bs-form-valid-color: #75b798;
--bs-form-valid-border-color: #75b798;
--bs-form-invalid-color: #ea868f;
--bs-form-invalid-border-color: #ea868f;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
border: 0;
border-top: var(--bs-border-width) solid;
opacity: 0.25;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
color: var(--bs-heading-color);
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.1875em;
color: var(--bs-highlight-color);
background-color: var(--bs-highlight-bg);
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
text-decoration: underline;
}
a:hover {
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: var(--bs-font-monospace);
font-size: 1em;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: var(--bs-code-color);
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.1875rem 0.375rem;
font-size: 0.875em;
color: var(--bs-body-bg);
background-color: var(--bs-body-color);
border-radius: 0.25rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: var(--bs-secondary-color);
text-align: left;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
display: none !important;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: left;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
line-height: inherit;
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: left;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type=search]::-webkit-search-cancel-button {
cursor: pointer;
filter: grayscale(1);
}
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
::file-selector-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,598 @@
/*!
* Bootstrap Reboot v5.3.8 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
:root,
[data-bs-theme=light] {
--bs-blue: #0d6efd;
--bs-indigo: #6610f2;
--bs-purple: #6f42c1;
--bs-pink: #d63384;
--bs-red: #dc3545;
--bs-orange: #fd7e14;
--bs-yellow: #ffc107;
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-black: #000;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
--bs-gray-100: #f8f9fa;
--bs-gray-200: #e9ecef;
--bs-gray-300: #dee2e6;
--bs-gray-400: #ced4da;
--bs-gray-500: #adb5bd;
--bs-gray-600: #6c757d;
--bs-gray-700: #495057;
--bs-gray-800: #343a40;
--bs-gray-900: #212529;
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
--bs-light: #f8f9fa;
--bs-dark: #212529;
--bs-primary-rgb: 13, 110, 253;
--bs-secondary-rgb: 108, 117, 125;
--bs-success-rgb: 25, 135, 84;
--bs-info-rgb: 13, 202, 240;
--bs-warning-rgb: 255, 193, 7;
--bs-danger-rgb: 220, 53, 69;
--bs-light-rgb: 248, 249, 250;
--bs-dark-rgb: 33, 37, 41;
--bs-primary-text-emphasis: #052c65;
--bs-secondary-text-emphasis: #2b2f32;
--bs-success-text-emphasis: #0a3622;
--bs-info-text-emphasis: #055160;
--bs-warning-text-emphasis: #664d03;
--bs-danger-text-emphasis: #58151c;
--bs-light-text-emphasis: #495057;
--bs-dark-text-emphasis: #495057;
--bs-primary-bg-subtle: #cfe2ff;
--bs-secondary-bg-subtle: #e2e3e5;
--bs-success-bg-subtle: #d1e7dd;
--bs-info-bg-subtle: #cff4fc;
--bs-warning-bg-subtle: #fff3cd;
--bs-danger-bg-subtle: #f8d7da;
--bs-light-bg-subtle: #fcfcfd;
--bs-dark-bg-subtle: #ced4da;
--bs-primary-border-subtle: #9ec5fe;
--bs-secondary-border-subtle: #c4c8cb;
--bs-success-border-subtle: #a3cfbb;
--bs-info-border-subtle: #9eeaf9;
--bs-warning-border-subtle: #ffe69c;
--bs-danger-border-subtle: #f1aeb5;
--bs-light-border-subtle: #e9ecef;
--bs-dark-border-subtle: #adb5bd;
--bs-white-rgb: 255, 255, 255;
--bs-black-rgb: 0, 0, 0;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
--bs-body-font-family: var(--bs-font-sans-serif);
--bs-body-font-size: 1rem;
--bs-body-font-weight: 400;
--bs-body-line-height: 1.5;
--bs-body-color: #212529;
--bs-body-color-rgb: 33, 37, 41;
--bs-body-bg: #fff;
--bs-body-bg-rgb: 255, 255, 255;
--bs-emphasis-color: #000;
--bs-emphasis-color-rgb: 0, 0, 0;
--bs-secondary-color: rgba(33, 37, 41, 0.75);
--bs-secondary-color-rgb: 33, 37, 41;
--bs-secondary-bg: #e9ecef;
--bs-secondary-bg-rgb: 233, 236, 239;
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
--bs-tertiary-color-rgb: 33, 37, 41;
--bs-tertiary-bg: #f8f9fa;
--bs-tertiary-bg-rgb: 248, 249, 250;
--bs-heading-color: inherit;
--bs-link-color: #0d6efd;
--bs-link-color-rgb: 13, 110, 253;
--bs-link-decoration: underline;
--bs-link-hover-color: #0a58ca;
--bs-link-hover-color-rgb: 10, 88, 202;
--bs-code-color: #d63384;
--bs-highlight-color: #212529;
--bs-highlight-bg: #fff3cd;
--bs-border-width: 1px;
--bs-border-style: solid;
--bs-border-color: #dee2e6;
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
--bs-border-radius: 0.375rem;
--bs-border-radius-sm: 0.25rem;
--bs-border-radius-lg: 0.5rem;
--bs-border-radius-xl: 1rem;
--bs-border-radius-xxl: 2rem;
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
--bs-border-radius-pill: 50rem;
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
--bs-focus-ring-width: 0.25rem;
--bs-focus-ring-opacity: 0.25;
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
--bs-form-valid-color: #198754;
--bs-form-valid-border-color: #198754;
--bs-form-invalid-color: #dc3545;
--bs-form-invalid-border-color: #dc3545;
}
[data-bs-theme=dark] {
color-scheme: dark;
--bs-body-color: #dee2e6;
--bs-body-color-rgb: 222, 226, 230;
--bs-body-bg: #212529;
--bs-body-bg-rgb: 33, 37, 41;
--bs-emphasis-color: #fff;
--bs-emphasis-color-rgb: 255, 255, 255;
--bs-secondary-color: rgba(222, 226, 230, 0.75);
--bs-secondary-color-rgb: 222, 226, 230;
--bs-secondary-bg: #343a40;
--bs-secondary-bg-rgb: 52, 58, 64;
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
--bs-tertiary-color-rgb: 222, 226, 230;
--bs-tertiary-bg: #2b3035;
--bs-tertiary-bg-rgb: 43, 48, 53;
--bs-primary-text-emphasis: #6ea8fe;
--bs-secondary-text-emphasis: #a7acb1;
--bs-success-text-emphasis: #75b798;
--bs-info-text-emphasis: #6edff6;
--bs-warning-text-emphasis: #ffda6a;
--bs-danger-text-emphasis: #ea868f;
--bs-light-text-emphasis: #f8f9fa;
--bs-dark-text-emphasis: #dee2e6;
--bs-primary-bg-subtle: #031633;
--bs-secondary-bg-subtle: #161719;
--bs-success-bg-subtle: #051b11;
--bs-info-bg-subtle: #032830;
--bs-warning-bg-subtle: #332701;
--bs-danger-bg-subtle: #2c0b0e;
--bs-light-bg-subtle: #343a40;
--bs-dark-bg-subtle: #1a1d20;
--bs-primary-border-subtle: #084298;
--bs-secondary-border-subtle: #41464b;
--bs-success-border-subtle: #0f5132;
--bs-info-border-subtle: #087990;
--bs-warning-border-subtle: #997404;
--bs-danger-border-subtle: #842029;
--bs-light-border-subtle: #495057;
--bs-dark-border-subtle: #343a40;
--bs-heading-color: inherit;
--bs-link-color: #6ea8fe;
--bs-link-hover-color: #8bb9fe;
--bs-link-color-rgb: 110, 168, 254;
--bs-link-hover-color-rgb: 139, 185, 254;
--bs-code-color: #e685b5;
--bs-highlight-color: #dee2e6;
--bs-highlight-bg: #664d03;
--bs-border-color: #495057;
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
--bs-form-valid-color: #75b798;
--bs-form-valid-border-color: #75b798;
--bs-form-invalid-color: #ea868f;
--bs-form-invalid-border-color: #ea868f;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
border: 0;
border-top: var(--bs-border-width) solid;
opacity: 0.25;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
color: var(--bs-heading-color);
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-right: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-right: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.1875em;
color: var(--bs-highlight-color);
background-color: var(--bs-highlight-bg);
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
text-decoration: underline;
}
a:hover {
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: var(--bs-font-monospace);
font-size: 1em;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: var(--bs-code-color);
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.1875rem 0.375rem;
font-size: 0.875em;
color: var(--bs-body-bg);
background-color: var(--bs-body-color);
border-radius: 0.25rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: var(--bs-secondary-color);
text-align: right;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
display: none !important;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: right;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
line-height: inherit;
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: right;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type=search]::-webkit-search-cancel-button {
cursor: pointer;
filter: grayscale(1);
}
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
::file-selector-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More