fix: dynamic tours details view and null-safe relations
This commit is contained in:
@@ -25,10 +25,11 @@ class TourController extends Controller
|
||||
return view('tours.index', compact('title', 'tours', 'sort'));
|
||||
}
|
||||
|
||||
public function show(Tour $id)
|
||||
public function show(Tour $tour)
|
||||
{
|
||||
$title= 'جزئیات تور';
|
||||
$tour = Tour::findOrFail($id);
|
||||
$tour->load(['file', 'originCity', 'city', 'tourDepartures', 'comments.user']);
|
||||
|
||||
return view('tours.show', compact('title' , 'tour'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<span class="activity-price-amount">{{ number_format(optional($tour->tourDepartures->first())->price ?? 0) }} تومان</span>
|
||||
</div>
|
||||
<div class="activity-text-btn">
|
||||
<a href="#">نمایش جزئیات <i class="fas fa-arrow-left"></i></a>
|
||||
<a href="{{route('tours.show' , $tour->id)}}">نمایش جزئیات <i class="fas fa-arrow-left"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,52 +1,269 @@
|
||||
{{-- resources/views/flights/partials/main_content.blade.php --}}
|
||||
<div class="listing-content">
|
||||
|
||||
<div class="listing-slider owl-carousel owl-theme" dir="ltr">
|
||||
<img src="{{ asset('assets/img/flight/single-1.jpg') }}" alt="image">
|
||||
<img src="{{ asset('assets/img/flight/single-2.jpg') }}" alt="image">
|
||||
<img src="{{ asset('assets/img/flight/single-3.jpg') }}" alt="image">
|
||||
@if ($tour->images && $tour->images->count() > 0)
|
||||
@if ($tour->images->count() > 1)
|
||||
@foreach ($tour->images as $image)
|
||||
<img src="{{ asset($image->path) }}" alt="{{ $tour->title }}">
|
||||
@endforeach
|
||||
@else
|
||||
<img src="{{ asset($tour->images->first()->path) }}" alt="{{ $tour->title }}">
|
||||
@endif
|
||||
@else
|
||||
<img src="{{ asset('assets/img/flight/single-1.jpg') }}" alt="{{ $tour->title}}">
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="listing-header">
|
||||
<div class="listing-header-info">
|
||||
<h4 class="listing-title">نیویورک - لس آنجلس</h4>
|
||||
<p class="listing-stop">سفر یک طرفه <span class="badge">1 توقف</span></p>
|
||||
</div>
|
||||
<div class="listing-rate">
|
||||
<span class="badge"><i class="fal fa-star"></i> 5.0</span>
|
||||
<span class="listing-rate-type">عالی</span>
|
||||
<span class="listing-rate-review">(2 هزار بازخورد)</span>
|
||||
<h4 class="listing-title">{{ $tour->originCity?->name }} - {{ $tour->city?->name }}</h4>
|
||||
<p class="listing-stop"> سفر {{ $tour->tour_type }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$departure = $tour->tourDepartures->first();
|
||||
@endphp
|
||||
|
||||
<div class="listing-item listing-flight">
|
||||
|
||||
<div class="flight-booking-time">
|
||||
<div class="start-time">
|
||||
<div class="start-time-icon">
|
||||
<i class="fal fa-map-marker-alt"></i>
|
||||
</div>
|
||||
<div class="start-time-info">
|
||||
<h6 class="start-time-text"> شروع حرکت</h6>
|
||||
<p class="flight-full-date">
|
||||
{{ $departure && $departure->start_date ? Verta::instance($departure->start_date)->format('Y/m/d - H:i') : 'نامشخص' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="end-time">
|
||||
<div class="start-time-icon">
|
||||
<i class="fal fa-map-marker-alt"></i>
|
||||
</div>
|
||||
<div class="start-time-info">
|
||||
<h6 class="end-time-text">پایان سفر</h6>
|
||||
<p class="flight-full-date">
|
||||
{{ $departure && $departure->end_date ? Verta::instance($departure->end_date)->format('Y/m/d - H:i') : 'نامشخص' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="listing-item pt-5">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="listing-feature">
|
||||
<div class="listing-feature-icon">
|
||||
<i class="far fa-user-tie"></i>
|
||||
</div>
|
||||
<div class="listing-feature-content">
|
||||
<h6>نوع تور</h6>
|
||||
<span>{{ $tour->tour_type ?? 'نامشخص' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="listing-feature">
|
||||
<div class="listing-feature-icon">
|
||||
<i class="far fa-suitcase"></i>
|
||||
</div>
|
||||
<div class="listing-feature-content">
|
||||
<h6>ظرفیت</h6>
|
||||
<span>{{ $departure ? $departure->capacity . ' نفر' : 'تکمیل شده' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="listing-feature">
|
||||
<div class="listing-feature-icon">
|
||||
<i class="far fa-money-bill-wave"></i>
|
||||
</div>
|
||||
<div class="listing-feature-content">
|
||||
<h6>قیمت هر نفر</h6>
|
||||
<span>{{ $departure ? number_format($departure->price) . ' تومان' : 'نامشخص' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="listing-reviews">
|
||||
<h4 class="listing-title">نظرات</h4>
|
||||
<div class="listing-review-form">
|
||||
<h4 class="listing-title">نظر بدهید</h4>
|
||||
<form action="#">
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="اسم شما*">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group">
|
||||
<input type="email" class="form-control" placeholder="ایمیل شما*">
|
||||
</div>
|
||||
<div class="listing-item">
|
||||
<h4 class="mb-3">درباره {{ $tour->title }}</h4>
|
||||
<p>{{ $tour->description ?? $tour->summary }}</p>
|
||||
</div>
|
||||
|
||||
<div class="listing-item">
|
||||
<h4 class="mb-3"> ویژگی های هنگام سفر</h4>
|
||||
<div class="listing-amenity">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="far fa-wifi"></i> وای فای</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" cols="30" rows="5" placeholder="نظر خود را بنویسید*"></textarea>
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="far fa-tv"></i> تلویزیون</h6>
|
||||
</div>
|
||||
</div>
|
||||
<button class="theme-btn" type="button">نظر بدهید</button>
|
||||
</form>
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="far fa-music"></i> سرگرمی</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="far fa-cup-togo"></i> قهوه</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="far fa-air-conditioner"></i> تهویه مطبوع</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="fa-regular fa-salad"></i> غذا</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="far fa-gamepad-modern"></i> بازی ها</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="far fa-wine-bottle"></i> شربت ها</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="far fa-couch"></i> راحتی</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="listing-amenity-item">
|
||||
<h6><i class="far fa-image"></i> مجلات</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="listing-item">
|
||||
<h4 class="mb-3">بررسی ها</h4>
|
||||
<div class="listing-rating-box">
|
||||
<div class="listing-review">
|
||||
<h5>نظرات کاربران</h5>
|
||||
@forelse ($tour->comments as $comment)
|
||||
<div class="listing-review-item">
|
||||
<div class="listing-review-author">
|
||||
<img src="{{ asset('assets/img/account/DefaultAvatar.jpg') }}" alt="user">
|
||||
<div class="listing-review-author-info">
|
||||
<div>
|
||||
<h6>{{ $comment->guest_name ?? $comment->user?->first_name }}</h6>
|
||||
<span><i class="far fa-clock"></i> {{ Verta::instance($comment->created_at)->formatDifference() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>{{ $comment->content }}</p>
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-muted">هنوز نظری برای این تور ثبت نشده است.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<div class="listing-review-form">
|
||||
@if (session('success'))
|
||||
<div class="alert alert-success">
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (session('error'))
|
||||
<div class="alert alert-danger">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul class="mb-0">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<h4>نظر بدهید</h4>
|
||||
<form action="{{ route('tours.comments.store', $tour) }}" method="POST">
|
||||
@csrf
|
||||
<input type="hidden" name="parent_id" value="">
|
||||
@auth
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
value="{{ auth()->user()->first_name }}"
|
||||
disabled>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group">
|
||||
<input type="email"
|
||||
class="form-control"
|
||||
value="{{ auth()->user()->email }}"
|
||||
disabled>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group">
|
||||
<input type="text"
|
||||
name="guest_name"
|
||||
class="form-control"
|
||||
placeholder="اسم شما*"
|
||||
value="{{ old('guest_name') }}">
|
||||
@error('guest_name')
|
||||
<span style="color: red">{{$message}}</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group">
|
||||
<input type="email"
|
||||
name="guest_email"
|
||||
class="form-control"
|
||||
placeholder="ایمیل شما*"
|
||||
value="{{ old('guest_email') }}">
|
||||
@error('guest_email')
|
||||
<span style="color: red">{{$message}}</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endauth
|
||||
|
||||
<div class="form-group mt-3">
|
||||
<textarea name="content"
|
||||
class="form-control"
|
||||
cols="30"
|
||||
rows="5"
|
||||
placeholder="نظر خود را بنویسید*">{{ old('content') }}</textarea>
|
||||
@error('content')
|
||||
<span style="color: red">{{$message}}</span>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<button class="theme-btn mt-3" type="submit">نظر بدهید</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<div class="booking-sidebar listing-side-content">
|
||||
<div class="booking-item">
|
||||
<div class="listing-price">
|
||||
<h4 class="listing-price-tag">تور</h4>
|
||||
<div class="listing-price-amount">
|
||||
<span>{{ number_format($tour->price) }} تومان</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$departure = $tour->tourDepartures->first();
|
||||
@endphp
|
||||
|
||||
<div class="search-form">
|
||||
<form action="#">
|
||||
@csrf
|
||||
<input type="hidden" name="tour_id" value="{{ $tour->id }}">
|
||||
|
||||
<div class="tour-search-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="form-group">
|
||||
<div class="search-form-date">
|
||||
<label for="departure_date">تاریخ رفت</label>
|
||||
<input
|
||||
type="text"
|
||||
id="departure_date"
|
||||
class="form-control"
|
||||
value="{{ $departure && $departure->start_date ? verta($departure->start_date)->format('Y/m/d - H:i') : 'نامشخص' }}"
|
||||
disabled
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-12">
|
||||
<div class="form-group">
|
||||
<div class="search-form-date">
|
||||
<div class="search-form-return">
|
||||
<label for="return_date">تاریخ برگشت</label>
|
||||
<input
|
||||
type="text"
|
||||
id="return_date"
|
||||
class="form-control"
|
||||
value="{{ $departure && $departure->end_date ? verta($departure->end_date)->format('Y/m/d - H:i') : 'نامشخص' }}"
|
||||
disabled
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="listing-side-btn">
|
||||
<button type="submit" class="theme-btn">
|
||||
<span class="far fa-shopping-bag"></span>
|
||||
اکنون ثبت کن
|
||||
</button>
|
||||
<a href="#" class="border-btn">
|
||||
<i class="far fa-heart"></i>
|
||||
افزودن به علاقه مندی ها
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="listing-side-share">
|
||||
<a href="#"><i class="far fa-share-nodes"></i> اشتراک</a>
|
||||
<span><i class="far fa-eye"></i> 250 مشاهده</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,3 +1,36 @@
|
||||
<div>
|
||||
<!-- Be present above all else. - Naval Ravikant -->
|
||||
</div>
|
||||
@extends('layouts.app')
|
||||
|
||||
|
||||
@section('content')
|
||||
<main class="main">
|
||||
|
||||
<div class="site-breadcrumb" style="background: url(assets/img/breadcrumb/01.jpg)">
|
||||
<div class="container">
|
||||
<h2 class="breadcrumb-title"> {{$tour->title}}</h2>
|
||||
<ul class="breadcrumb-menu">
|
||||
<li><a href="{{route('index')}}">صفحه اصلی</a></li>
|
||||
<li class="active">تور</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hotel-single py-120">
|
||||
<div class="container">
|
||||
<div class="listing-wrapper">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-8">
|
||||
@include('tours.partials.main')
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
@include('tours.partials.sidebar')
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
@endsection
|
||||
|
||||
+5
-1
@@ -23,7 +23,11 @@ Route::prefix('flights')->controller(FlightController::class)->name('flights.')-
|
||||
|
||||
Route::prefix('tours')->controller(TourController::class)->name('tours.')->group(function () {
|
||||
Route::get('/', 'index')->name('index');
|
||||
Route::get('{tour}', 'show')->name('show');
|
||||
Route::prefix('{tour}')->group(function () {
|
||||
Route::get('/', 'show')->name('show');
|
||||
Route::post('/comment', 'commentStore')->name('comments.store');
|
||||
Route::post('/booking', [BookingController::class, 'store'])->name('booking.store');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user