Add landing page

This commit is contained in:
Jennie Robinson Faber 2025-11-03 11:17:51 +00:00
parent 3fea484585
commit bce86ee840
47 changed files with 7119 additions and 439 deletions

View file

@ -105,7 +105,7 @@
<!-- Status Message -->
<div
v-if="series.statistics.isOngoing"
v-if="series?.statistics?.isOngoing"
class="p-4 bg-green-500/10 border border-green-500/30 rounded mb-8"
>
<p class="text-green-600 dark:text-green-400 font-semibold mb-1">
@ -117,7 +117,7 @@
</div>
<div
v-else-if="series.statistics.isUpcoming"
v-else-if="series?.statistics?.isUpcoming"
class="p-4 bg-blue-500/10 border border-blue-500/30 rounded mb-8"
>
<p class="text-blue-600 dark:text-blue-400 font-semibold mb-1">
@ -129,7 +129,7 @@
</div>
<div
v-else-if="series.statistics.isCompleted"
v-else-if="series?.statistics?.isCompleted"
class="p-4 bg-gray-500/10 border border-gray-500/30 rounded mb-8"
>
<p class="text-[--ui-text] font-semibold mb-1">
@ -144,6 +144,30 @@
</UContainer>
</section>
<!-- Series Pass Purchase (if tickets enabled) -->
<section v-if="series?.tickets?.enabled" class="py-20 bg-[--ui-bg]">
<UContainer>
<div class="max-w-4xl mx-auto">
<h2 class="text-2xl font-bold text-[--ui-text] mb-8">
Get Your Series Pass
</h2>
<SeriesPassPurchase
:series-id="series.id || series._id"
:series-info="{
id: series.id,
title: series.title,
totalEvents: series?.statistics?.totalEvents || 0,
type: series.type,
}"
:series-events="series.events || []"
:user-email="user?.email"
:user-name="user?.name"
@purchase-success="handlePurchaseSuccess"
/>
</div>
</UContainer>
</section>
<!-- Events Timeline -->
<section class="py-20 bg-[--ui-bg-elevated]">
<UContainer>
@ -154,7 +178,7 @@
<div class="space-y-4">
<div
v-for="(event, index) in series.events"
v-for="(event, index) in series?.events || []"
:key="event.id"
class="group"
>
@ -170,7 +194,7 @@
{{ event.series?.position || index + 1 }}
</div>
<div
v-if="index < series.events.length - 1"
v-if="index < (series?.events?.length || 0) - 1"
class="w-0.5 h-12 bg-[--ui-border]"
></div>
</div>
@ -287,12 +311,18 @@
<script setup>
const route = useRoute();
const { data: session } = useAuth();
const toast = useToast();
// Get user info
const user = computed(() => session?.value?.user || null);
// Fetch series data from API
const {
data: series,
pending,
error,
refresh: refreshSeries,
} = await useFetch(`/api/series/${route.params.id}`);
// Handle series not found
@ -303,6 +333,15 @@ if (error.value?.statusCode === 404) {
});
}
// Handle successful series pass purchase
const handlePurchaseSuccess = async (response) => {
// Refresh series data to show updated registration status
await refreshSeries();
// Scroll to top to show success message
window.scrollTo({ top: 0, behavior: "smooth" });
};
// Helper functions
const formatSeriesType = (type) => {
const types = {
@ -335,6 +374,7 @@ const getSeriesTypeBadgeClass = (type) => {
};
const getSeriesStatusText = () => {
if (!series.value?.statistics) return "Active";
if (series.value.statistics.isOngoing) return "Ongoing";
if (series.value.statistics.isUpcoming) return "Starting Soon";
if (series.value.statistics.isCompleted) return "Completed";
@ -342,6 +382,8 @@ const getSeriesStatusText = () => {
};
const getSeriesStatusClass = () => {
if (!series.value?.statistics)
return "bg-purple-500/10 text-purple-600 dark:text-purple-400 border border-purple-500/30";
if (series.value.statistics.isOngoing)
return "bg-green-500/10 text-green-600 dark:text-green-400 border border-green-500/30";
if (series.value.statistics.isUpcoming)
@ -423,19 +465,32 @@ const getEventTimelineColor = (event) => {
};
// SEO Meta
useHead(() => ({
title: series.value
? `${series.value.title} - Event Series - Ghost Guild`
: "Event Series - Ghost Guild",
meta: [
{
name: "description",
content:
series.value?.description ||
"Explore our multi-event series designed for learning and growth",
},
],
}));
useHead(() => {
if (!series || !series.value) {
return {
title: "Event Series - Ghost Guild",
meta: [
{
name: "description",
content:
"Explore our multi-event series designed for learning and growth",
},
],
};
}
return {
title: `${series.value.title} - Event Series - Ghost Guild`,
meta: [
{
name: "description",
content:
series.value.description ||
"Explore our multi-event series designed for learning and growth",
},
],
};
});
</script>
<style scoped>