Added About Page

This commit is contained in:
2025-09-19 00:33:32 +10:00
parent ee1436c6f0
commit ef9318b5a3
10 changed files with 395 additions and 42 deletions

View File

@@ -0,0 +1,137 @@
<script setup lang="ts">
import SectionContainer from "@/components/dredgy/SectionContainer.vue";
import SectionTitle from "@/components/dredgy/SectionTitle.vue";
import EdgyButton from "@/components/dredgy/EdgyButton.vue";
import ButtonLink from "@/components/dredgy/ButtonLink.vue";
import { computed } from "vue";
import type { TourDay } from "@/types";
interface Props {
day: TourDay
dayNumber?: number
previousHref?: string | null
nextHref?: string | null
}
const props = defineProps<Props>();
const hasPrev = computed(() => !!props.previousHref);
const hasNext = computed(() => !!props.nextHref);
</script>
<template>
<section class="tour-day" id="tour-day">
<div class="tour-decorations">
<div class="tour-decoration tour-decoration-1"></div>
<div class="tour-decoration tour-decoration-2"></div>
<div class="tour-decoration tour-decoration-3"></div>
</div>
<SectionContainer>
<div v-show-on-intersect="'fade-up'" class="tour-content">
<SectionTitle
:title="'Day ' + (dayNumber ?? '')"
gradient="Overview"
:subtitle="day.description"
/>
<div class="tour-card chamfer">
<div class="tour-media chamfer" v-show-on-intersect="{type:'slide-right'}">
<img
v-if="day.image"
:src="day.image"
:alt="`Day ${dayNumber ?? ''} image`"
loading="lazy"
/>
<div v-else class="tour-media__placeholder">
<span>No image available</span>
</div>
</div>
<div class="tour-body" v-show-on-intersect="{type:'slide-left'}">
<div class="tour-description" v-html="day.content || day.description" />
<footer class="tour-actions">
<template v-if="hasPrev">
<EdgyButton classes="btn-secondary chamfer" aria-label="Previous">
<ButtonLink :href="previousHref!"> Previous</ButtonLink>
</EdgyButton>
</template>
<template v-else>
<EdgyButton classes="btn-secondary chamfer" aria-label="Previous" @click="$emit('previous')">
Previous
</EdgyButton>
</template>
<div class="spacer" />
<template v-if="hasNext">
<EdgyButton classes="btn-primary chamfer" aria-label="Next">
<ButtonLink :href="nextHref!">Next </ButtonLink>
</EdgyButton>
</template>
<template v-else>
<EdgyButton classes="btn-primary chamfer" aria-label="Next" @click="$emit('next')">
Next
</EdgyButton>
</template>
</footer>
</div>
</div>
</div>
</SectionContainer>
</section>
</template>
<style scoped>
.tour-day {
position: relative;
padding: 5rem 0;
background: var(--background);
overflow: hidden;
}
.tour-decorations {
position: absolute; inset: 0; pointer-events: none;
}
.tour-decoration {
position: absolute; opacity: 0.05;
clip-path: polygon(0 0, calc(100% - 20px) 0, 100% 20px, 100% 100%, 20px 100%, 0 calc(100% - 20px));
}
.tour-decoration-1 { top: 2rem; right: 2rem; width: 100px; height: 100px; background: var(--gradient-adventure); }
.tour-decoration-2 { bottom: 3rem; left: 3rem; width: 80px; height: 80px; background: var(--gradient-accent); }
.tour-decoration-3 { top: 50%; right: 5rem; width: 6px; height: 100px; background: var(--gradient-adventure); }
.tour-card {
display: flex;
gap: 1.5rem;
background: var(--card);
color: var(--foreground);
border: 1px solid color-mix(in oklab, var(--foreground), transparent 85%);
padding: 1.25rem;
min-height: min(60dvh, 680px);
}
.chamfer {
--cut: 20px;
clip-path: polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, var(--cut) 100%, 0 calc(100% - var(--cut)));
}
.tour-media {
flex: 0 1 44%;
background: color-mix(in oklab, var(--card), black 4%);
border: 1px solid color-mix(in oklab, var(--foreground), transparent 88%);
display: grid; place-items: center; min-height: 260px;
}
.tour-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tour-media__placeholder { color: var(--muted-foreground); font-size: 0.95rem; padding: 1rem; }
.tour-body { flex: 1 1 56%; display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.tour-description { color: var(--muted-foreground); font-size: 1.08rem; line-height: 1.7; }
.tour-actions { margin-top: auto; display: flex; align-items: center; gap: 0.75rem; }
.spacer { flex: 1; }
@media (max-width: 1023px) {
.tour-card { flex-direction: column; }
.tour-media { min-height: 220px; }
}
@media (max-width: 767px) {
.tour-day { padding: 3rem 0; }
.tour-card { padding: 1rem; }
}
</style>

View File

@@ -1,25 +0,0 @@
<script setup lang="ts">
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
})
</script>
<template>
<section style="padding-top:20dvh;height: 100dvh">
{{tour.short_description}}
</section>
</template>
<style scoped>
</style>

View File

@@ -0,0 +1,36 @@
<script setup lang="ts">
import { usePage } from "@inertiajs/vue3";
import AppLayout from "@/layouts/AppLayout.vue";
import TourOverviewSection from "./TourOverviewSection.vue";
import type { Tour } from "@/types";
import TourQuickFacts from "@/components/TourNavigator/TourQuickFacts.vue";
import SectionTitle from "@/components/dredgy/SectionTitle.vue";
interface Properties {
tour: Tour;
nextHref?: string | null;
}
const { tour, nextHref } = usePage().props as unknown as Properties;
defineOptions({
layout: AppLayout,
});
</script>
<template>
<section class="tour-overview-section">
<SectionTitle
title=""
:gradient="tour.name"
:subtitle="tour.short_description ?? ''"
/>
</section>
<TourOverviewSection :tour="tour" />
</template>
<style scoped>
.tour-overview-section{
margin-top: 10dvh;
}
</style>

View File

@@ -0,0 +1,97 @@
<script setup lang="ts">
import SectionContainer from "@/components/dredgy/SectionContainer.vue";
import SectionTitle from "@/components/dredgy/SectionTitle.vue";
import GradientText from "@/components/dredgy/GradientText.vue";
import EdgyButton from "@/components/dredgy/EdgyButton.vue";
import ButtonLink from "@/components/dredgy/ButtonLink.vue";
import TourQuickFacts from "@/components/TourNavigator/TourQuickFacts.vue";
import type { Tour } from "@/types";
interface Props {
tour: Tour;
}
const props = defineProps<Props>();
</script>
<template>
<section class="tour-overview">
<SectionContainer>
<div
class="relative chamfer bg-neutral-900/70 border border-neutral-700/60 shadow-xl shadow-black/30 backdrop-blur-sm"
>
<!-- Banner with overlapping title -->
<div class="relative">
<div class="aspect-[16/7] md:aspect-[16/6] lg:aspect-[16/5] overflow-hidden">
<img
:src="`/img/tours/${props.tour.internal_name}.jpg`"
:alt="tour.name + 'Banner'"
class="w-full h-full object-cover"
loading="lazy"
/>
</div>
<!-- Overlapping H1 with glass background (no rounded, chamfered) -->
<div class="absolute left-6 md:left-8 -bottom-8">
<div
class="chamfer border border-white/10 glass shadow-lg shadow-black/30 px-4 md:px-5 py-2.5"
>
<h1 style="padding:0.5em" class="text-2xl md:text-3xl lg:text-4xl font-semibold tracking-tight">
<GradientText>About this Adventure</GradientText>
</h1>
</div>
</div>
</div>
<!-- Content area: flex columns, fixed height, right column flush with edge -->
<div>
<div class="flex gap-6 h-[560px] md:h-[600px] lg:h-[640px]">
<!-- Main description (wider column) -->
<div class="flex-1 pl-6 md:pl-8">
<div class="text-neutral-200 leading-relaxed h-full overflow-auto pr-1 pt-14 ">
<div
v-html="props.tour.long_description || 'No long description available'"
></div>
</div>
</div>
<!-- Quick facts (narrower right column, flush right, chamfer top-left only) -->
<aside class="w-80 md:w-88 lg:w-96 h-full">
<div
class="h-full chamfer-tl bg-neutral-900/40 backdrop-blur-sm ring-1 ring-neutral-700/50"
>
<TourQuickFacts :tour="props.tour" />
</div>
</aside>
</div>
</div>
</div>
</SectionContainer>
</section>
</template>
<style scoped>
.chamfer {
--cut: 20px;
clip-path: polygon(
0 0,
calc(100% - var(--cut)) 0,
100% var(--cut),
100% 100%,
var(--cut) 100%,
0 calc(100% - var(--cut))
);
}
/* Only the top-left corner chamfered (for the right column box) */
.chamfer-tl {
--cut: 20px;
clip-path: polygon(
var(--cut) 0,
100% 0,
100% 100%,
0 100%,
0 0
);
}
</style>