From ee1436c6f0881b05b30dc931d5af87cdd88aec17 Mon Sep 17 00:00:00 2001
From: Josh
Date: Thu, 18 Sep 2025 17:41:24 +1000
Subject: [PATCH] Added About Page
---
app/Models/Tour.php | 6 +++++
app/Models/TourDay.php | 26 +++++++++++++++++++
database/factories/TourDayFactory.php | 22 ++++++++++++++++
...25_09_18_051804_create_tour_days_table.php | 26 +++++++++++++++++++
database/seeders/DatabaseSeeder.php | 5 +++-
resources/js/components/dredgy/ButtonLink.vue | 16 ++++++++++++
resources/js/components/dredgy/TourCard.vue | 10 ++++---
resources/js/components/home/About.vue | 6 ++---
resources/js/pages/AboutUs.vue | 2 ++
resources/js/pages/TourNavigator.vue | 25 ++++++++++++++++++
resources/js/types/index.d.ts | 19 +++++++++++++-
routes/web.php | 6 +++++
12 files changed, 161 insertions(+), 8 deletions(-)
create mode 100644 app/Models/TourDay.php
create mode 100644 database/factories/TourDayFactory.php
create mode 100644 database/migrations/2025_09_18_051804_create_tour_days_table.php
create mode 100644 resources/js/components/dredgy/ButtonLink.vue
create mode 100644 resources/js/pages/TourNavigator.vue
diff --git a/app/Models/Tour.php b/app/Models/Tour.php
index 6f37459..9dd3952 100644
--- a/app/Models/Tour.php
+++ b/app/Models/Tour.php
@@ -15,9 +15,15 @@ class Tour extends Model
return $this->belongsToMany(Country::class, 'tour_countries', 'tour_id', 'country_id');
}
+ public function tour_days()
+ {
+ return $this->hasMany(TourDay::class);
+ }
+
public static function featuredTours(){
return Tour::whereHas('countries.continent')
->with('countries.continent')
+ ->with('tour_days')
->inRandomOrder()
->limit(4)
->get();
diff --git a/app/Models/TourDay.php b/app/Models/TourDay.php
new file mode 100644
index 0000000..54e864b
--- /dev/null
+++ b/app/Models/TourDay.php
@@ -0,0 +1,26 @@
+belongsTo(Tour::class);
+ }
+}
diff --git a/database/factories/TourDayFactory.php b/database/factories/TourDayFactory.php
new file mode 100644
index 0000000..7180f58
--- /dev/null
+++ b/database/factories/TourDayFactory.php
@@ -0,0 +1,22 @@
+ Tour::whereInternalName('hebei_harmony')->first()->id,
+ 'description' => $this->faker->sentence(),
+ 'content' => $this->faker->paragraphs(3, true),
+ 'image' => $this->faker->imageUrl(800, 600, 'travel', true, 'Tour Day'),
+ ];
+ }
+}
diff --git a/database/migrations/2025_09_18_051804_create_tour_days_table.php b/database/migrations/2025_09_18_051804_create_tour_days_table.php
new file mode 100644
index 0000000..7aaa69d
--- /dev/null
+++ b/database/migrations/2025_09_18_051804_create_tour_days_table.php
@@ -0,0 +1,26 @@
+id();
+ $table->foreignId('tour_id')
+ ->constrained('tours')
+ ->onDelete('cascade');
+ $table->string('description')->nullable();
+ $table->text('content')->nullable();
+ $table->string('image')->nullable();
+ $table->timestamps();
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('tour_days');
+ }
+};
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index 99b7514..37fa0df 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -2,6 +2,7 @@
namespace Database\Seeders;
+use App\Models\TourDay;
use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
@@ -13,7 +14,7 @@ class DatabaseSeeder extends Seeder
*/
public function run(): void
{
- // User::factory(10)->create();
+ User::factory(10)->create();
$this
->call(ContinentSeeder::class)
->call(CountrySeeder::class)
@@ -21,6 +22,8 @@ class DatabaseSeeder extends Seeder
->call(TourCountrySeeder::class)
;
+ TourDay::factory()->count(5)->create();
+
User::factory()->create([
'name' => 'Test User',
'email' => 'test@example.com',
diff --git a/resources/js/components/dredgy/ButtonLink.vue b/resources/js/components/dredgy/ButtonLink.vue
new file mode 100644
index 0000000..08740a0
--- /dev/null
+++ b/resources/js/components/dredgy/ButtonLink.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/resources/js/components/dredgy/TourCard.vue b/resources/js/components/dredgy/TourCard.vue
index 06c4e14..91f2066 100644
--- a/resources/js/components/dredgy/TourCard.vue
+++ b/resources/js/components/dredgy/TourCard.vue
@@ -3,6 +3,8 @@ import {Tour} from "@/types";
import { defineProps } from 'vue'
import EdgyButton from "@/components/dredgy/EdgyButton.vue";
+import {Link} from "@inertiajs/vue3";
+import ButtonLink from "@/components/dredgy/ButtonLink.vue";
const formatPrice = (price: number) => {
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(price)
}
@@ -33,12 +35,12 @@ const props = defineProps<{
{{tour.name}}
{{tour.short_description}}
-
+
- {{tour.length}} Days
+
{{ tour.tour_days?.length }} Days
@@ -50,7 +52,9 @@ const props = defineProps<{
Maximum 6
-
View Details
+
+ Details
+
diff --git a/resources/js/components/home/About.vue b/resources/js/components/home/About.vue
index 9ad548c..648c23e 100644
--- a/resources/js/components/home/About.vue
+++ b/resources/js/components/home/About.vue
@@ -33,9 +33,9 @@
Dr Edgy was founded by two close friends who met travelling in North Korea. Both of us love adventure travel with a bit of luxury. One of us is even an actual doctor.
You are in safe hands.
-
+
GET TO KNOW US
-
+
@@ -149,7 +149,7 @@ import { ref } from 'vue'
import EdgyButton from "@/components/dredgy/EdgyButton.vue";
import SectionContainer from "@/components/dredgy/SectionContainer.vue";
import SectionTitle from "@/components/dredgy/SectionTitle.vue";
-import {Link} from "@inertiajs/vue3";
+import ButtonLink from "@/components/dredgy/ButtonLink.vue";
const isVisible = ref(false)
diff --git a/resources/js/pages/AboutUs.vue b/resources/js/pages/AboutUs.vue
index 967a95d..3ba7162 100644
--- a/resources/js/pages/AboutUs.vue
+++ b/resources/js/pages/AboutUs.vue
@@ -28,6 +28,7 @@ defineOptions({
or a punchy day tour, we’ll keep it flexible, intimate, and full of good stories.
+
@@ -36,6 +37,7 @@ defineOptions({
+
+import {Tour} from "@/types";
+import {usePage} from "@inertiajs/vue3";
+import AppLayout from "@/layouts/AppLayout.vue";
+
+interface Properties {
+ tour: Tour
+}
+
+const { tour } = usePage().props as unknown as Properties
+defineOptions({
+ layout: AppLayout
+})
+
+
+
+
+
+ {{tour.short_description}}
+
+
+
+
diff --git a/resources/js/types/index.d.ts b/resources/js/types/index.d.ts
index d5b2ed7..06b2253 100644
--- a/resources/js/types/index.d.ts
+++ b/resources/js/types/index.d.ts
@@ -53,6 +53,20 @@ export interface Country {
continent: Continent;
}
+/*
+ 'tour_id',
+ 'description',
+ 'content',
+ 'image',
+ */
+export interface TourDay {
+ id: number
+ tour_id: number
+ description: string
+ content: string
+ image: string | null
+}
+
export interface Tour {
id: number
name: string
@@ -61,5 +75,8 @@ export interface Tour {
price: number
level: string
short_description: string
- countries: ?Country[]
+ countries: Country[] | null
+ tour_days: TourDay[] | null
}
+
+
diff --git a/routes/web.php b/routes/web.php
index 133e07c..d07c827 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -15,5 +15,11 @@ Route::get('/about', function () {
return Inertia::render('AboutUs');
})->name('about');
+Route::get('/adventures/{tour}', function ($tour) {
+ return Inertia::render('TourNavigator',[
+ 'tour' => Tour::where('internal_name', $tour)->with('countries.continent')->first(),
+ ]);
+})->name('tour');
+
require __DIR__.'/settings.php';
require __DIR__.'/auth.php';