Lots of UI fixes

This commit is contained in:
Jennie Robinson Faber 2025-10-08 19:02:24 +01:00
parent 1f7a0f40c0
commit e8e3b84276
24 changed files with 3652 additions and 1770 deletions

View file

@ -202,14 +202,10 @@
v-if="!event.isCancelled"
class="bg-ghost-800 rounded-xl p-8 border border-ghost-700"
>
<h3 class="text-xl font-bold text-ghost-100 mb-6">
Register for This Event
</h3>
<!-- Registration Status -->
<div v-if="registrationStatus === 'registered'" class="mb-6">
<!-- Already Registered Status -->
<div v-if="registrationStatus === 'registered'">
<div
class="p-4 bg-green-900/20 rounded-lg border border-green-800"
class="p-4 bg-green-900/20 rounded-lg border border-green-800 mb-6"
>
<div class="flex items-start justify-between">
<div>
@ -233,40 +229,51 @@
</div>
</div>
<!-- Member Gate Warning -->
<!-- Logged In - Can Register -->
<div
v-if="
event.membersOnly &&
!isMember &&
registrationStatus !== 'registered'
"
class="mb-6"
v-else-if="memberData && (!event.membersOnly || isMember)"
class="text-center"
>
<div
class="p-4 bg-amber-900/20 rounded-lg border border-amber-800"
<p class="text-lg text-ghost-200 mb-6">
You are logged in, {{ memberData.name }}.
</p>
<UButton
color="primary"
size="xl"
@click="handleRegistration"
:loading="isRegistering"
class="px-12 py-4"
>
<p class="font-semibold text-amber-300">Membership Required</p>
<p class="text-sm text-amber-400 mt-1">
{{ isRegistering ? "Registering..." : "Register Now" }}
</UButton>
</div>
<!-- Member Gate Warning -->
<div v-else-if="event.membersOnly && !isMember" class="text-center">
<div
class="p-6 bg-amber-900/20 rounded-lg border border-amber-800 mb-6"
>
<p class="font-semibold text-amber-300 text-lg mb-2">
Membership Required
</p>
<p class="text-amber-400">
This event is exclusive to Ghost Guild members. Join any
circle to gain access.
</p>
<NuxtLink
to="/join"
class="inline-flex items-center text-sm font-medium text-amber-300 hover:underline mt-2"
>
Become a member
</NuxtLink>
</div>
<NuxtLink to="/join">
<UButton color="primary" size="xl" class="px-12 py-4">
Become a Member to Register
</UButton>
</NuxtLink>
</div>
<!-- Registration Form -->
<form
v-if="registrationStatus !== 'registered'"
@submit.prevent="handleRegistration"
class="space-y-4"
>
<!-- Show form fields only for public events OR for logged-in members -->
<template v-if="!event.membersOnly || isMember">
<!-- Not Logged In - Show Registration Form -->
<div v-else>
<h3 class="text-xl font-bold text-ghost-100 mb-6">
Register for This Event
</h3>
<form @submit.prevent="handleRegistration" class="space-y-4">
<div>
<label
for="name"
@ -312,26 +319,22 @@
:options="membershipOptions"
/>
</div>
</template>
<div class="pt-4">
<UButton
v-if="!event.membersOnly || isMember"
type="submit"
color="primary"
size="lg"
block
:loading="isRegistering"
>
{{ isRegistering ? "Registering..." : "Register for Event" }}
</UButton>
<NuxtLink v-else to="/join" class="block">
<UButton color="primary" size="lg" block>
Become a Member to Register
<div class="pt-4">
<UButton
type="submit"
color="primary"
size="lg"
block
:loading="isRegistering"
>
{{
isRegistering ? "Registering..." : "Register for Event"
}}
</UButton>
</NuxtLink>
</div>
</form>
</div>
</form>
</div>
<!-- Event Capacity -->
<div

View file

@ -42,7 +42,7 @@
<div class="flex-1 min-w-0">
<div class="flex items-start gap-2 mb-1">
<h3
class="text-lg font-semibold text-ghost-100 group-hover:text-blue-400 transition-colors"
class="text-lg font-semibold text-ghost-100 group-hover:text-primary transition-colors"
>
{{ event.title }}
</h3>
@ -72,7 +72,7 @@
<Icon
name="heroicons:arrow-right"
class="w-5 h-5 text-ghost-400 group-hover:text-blue-400 group-hover:translate-x-1 transition-all flex-shrink-0 mt-1"
class="w-5 h-5 text-ghost-400 group-hover:text-primary group-hover:translate-x-1 transition-all flex-shrink-0 mt-1"
/>
</NuxtLink>
</div>
@ -128,99 +128,89 @@
</section>
<!-- Event Series -->
<section
<div v-if="activeSeries.length > 0" class="text-center mb-12">
<h2 class="text-3xl font-bold text-ghost-100 mb-8">
Current Event Series
</h2>
</div>
<div
v-if="activeSeries.length > 0"
class="py-20 bg-ghost-800 dark:bg-ghost-900"
class="space-y-6 max-w-6xl mx-auto mb-20"
>
<UContainer>
<div class="text-center mb-12">
<h2 class="text-3xl font-bold text-ghost-100 mb-8">
Active Event Series
</h2>
<p class="text-ghost-300 max-w-2xl mx-auto">
Multi-part workshops and recurring events designed to deepen your
knowledge and build community connections.
</p>
</div>
<div
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 max-w-6xl mx-auto"
>
<div
v-for="series in activeSeries.slice(0, 6)"
:key="series.id"
class="bg-ghost-900 rounded-xl p-6 shadow-lg border border-ghost-700"
>
<div class="flex items-start justify-between mb-4">
<div
v-for="series in activeSeries.slice(0, 6)"
:key="series.id"
class="bg-ghost-900 rounded-xl p-6 shadow-lg border border-ghost-700"
:class="[
'inline-flex items-center px-3 py-1 rounded-full text-xs font-medium',
getSeriesTypeBadgeClass(series.type),
]"
>
<div class="flex items-start justify-between mb-4">
<div
:class="[
'inline-flex items-center px-3 py-1 rounded-full text-xs font-medium',
getSeriesTypeBadgeClass(series.type),
]"
>
{{ formatSeriesType(series.type) }}
</div>
<div class="flex items-center gap-1 text-xs text-ghost-400">
<Icon name="heroicons:calendar-days" class="w-4 h-4" />
<span>{{ series.eventCount }} events</span>
</div>
</div>
<h3 class="text-lg font-semibold text-ghost-100 mb-2">
{{ series.title }}
</h3>
<p class="text-sm text-ghost-300 mb-4 line-clamp-2">
{{ series.description }}
</p>
<div class="space-y-2 mb-4">
<div
v-for="event in series.events.slice(0, 3)"
:key="event.id"
class="flex items-center justify-between text-xs"
>
<div class="flex items-center gap-2">
<div
class="w-6 h-6 bg-purple-100 dark:bg-purple-900/30 text-purple-600 dark:text-purple-400 rounded-full flex items-center justify-center text-xs font-medium"
>
{{ event.series?.position || "?" }}
</div>
<span class="text-ghost-300 truncate">{{ event.title }}</span>
</div>
<span class="text-ghost-400">
{{ formatEventDate(event.startDate) }}
</span>
</div>
<div
v-if="series.events.length > 3"
class="text-xs text-ghost-400 text-center pt-1"
>
+{{ series.events.length - 3 }} more events
</div>
</div>
<div class="flex items-center justify-between text-sm">
<div class="text-ghost-400">
{{ formatDateRange(series.startDate, series.endDate) }}
</div>
<span
:class="[
'inline-flex items-center px-2 py-1 rounded-full text-xs font-medium',
series.status === 'active'
? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400'
: series.status === 'upcoming'
? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'
: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400',
]"
>
{{ series.status }}
</span>
</div>
{{ formatSeriesType(series.type) }}
</div>
<div class="flex items-center gap-1 text-xs text-ghost-400">
<Icon name="heroicons:calendar-days" class="w-4 h-4" />
<span>{{ series.eventCount }} events</span>
</div>
</div>
</UContainer>
</section>
<h3 class="text-lg font-semibold text-ghost-100 mb-2">
{{ series.title }}
</h3>
<p class="text-sm text-ghost-300 mb-4 line-clamp-2">
{{ series.description }}
</p>
<div class="space-y-2 mb-4">
<div
v-for="(event, index) in series.events.slice(0, 3)"
:key="event.id"
class="flex items-center justify-between text-xs"
>
<div class="flex items-center gap-2">
<div
class="w-6 h-6 bg-purple-100 dark:bg-purple-900/30 text-purple-600 dark:text-purple-400 rounded-full flex items-center justify-center text-xs font-medium"
>
{{ event.series?.position || index + 1 }}
</div>
<span class="text-ghost-300 truncate">{{ event.title }}</span>
</div>
<span class="text-ghost-400">
{{ formatEventDate(event.startDate) }}
</span>
</div>
<div
v-if="series.events.length > 3"
class="text-xs text-ghost-400 text-center pt-1"
>
+{{ series.events.length - 3 }} more events
</div>
</div>
<div class="flex items-center justify-between text-sm">
<div class="text-ghost-400">
{{ formatDateRange(series.startDate, series.endDate) }}
</div>
<span
:class="[
'inline-flex items-center px-2 py-1 rounded-full text-xs font-medium',
series.status === 'active'
? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400'
: series.status === 'upcoming'
? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'
: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400',
]"
>
{{ series.status }}
</span>
</div>
</div>
</div>
<!-- Attend Our Events -->
<section class="py-20 bg-ghost-800 dark:bg-ghost-900">
@ -354,11 +344,12 @@ const upcomingEvents = computed(() => {
// Format event date for display
const formatEventDate = (date) => {
const dateObj = date instanceof Date ? date : new Date(date);
return new Intl.DateTimeFormat("en-US", {
month: "short",
day: "numeric",
year: "numeric",
}).format(date);
}).format(dateObj);
};
// Get optimized Cloudinary image URL