Event fixes
This commit is contained in:
parent
707447fc88
commit
19d519b153
5 changed files with 696 additions and 606 deletions
|
|
@ -1,72 +1,42 @@
|
|||
<template>
|
||||
<div
|
||||
class="ticket-card rounded-xl border p-6 transition-all duration-200"
|
||||
:class="[
|
||||
isSelected
|
||||
? 'border-primary bg-primary/5'
|
||||
: 'border-guild-600 bg-guild-800/50',
|
||||
isAvailable && !alreadyRegistered
|
||||
? 'hover:border-primary/50 cursor-pointer'
|
||||
: 'opacity-60 cursor-not-allowed',
|
||||
]"
|
||||
class="ticket-card"
|
||||
:class="{
|
||||
'is-selected': isSelected,
|
||||
'is-unavailable': !isAvailable || alreadyRegistered,
|
||||
}"
|
||||
@click="handleClick"
|
||||
>
|
||||
<!-- Ticket Header -->
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div class="ticket-header">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-guild-100">
|
||||
{{ ticketInfo.name }}
|
||||
</h3>
|
||||
<p v-if="ticketInfo.description" class="text-sm text-guild-300 mt-1">
|
||||
<h3 class="ticket-name">{{ ticketInfo.name }}</h3>
|
||||
<p v-if="ticketInfo.description" class="ticket-desc">
|
||||
{{ ticketInfo.description }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Badge -->
|
||||
<div v-if="ticketInfo.isMember" class="flex-shrink-0 ml-4">
|
||||
<span
|
||||
class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-candlelight-900/20 text-candlelight-500 dark:bg-candlelight-900/30 dark:text-candlelight-400"
|
||||
>
|
||||
Members Only
|
||||
</span>
|
||||
</div>
|
||||
<span v-if="ticketInfo.isMember" class="badge">Members Only</span>
|
||||
</div>
|
||||
|
||||
<!-- Price Display -->
|
||||
<div class="mb-4">
|
||||
<div class="flex items-baseline gap-2">
|
||||
<div class="ticket-price-block">
|
||||
<div class="ticket-price-row">
|
||||
<span
|
||||
class="text-3xl font-bold text-ui-mono"
|
||||
:class="ticketInfo.isFree ? 'text-candlelight-400' : 'text-guild-100'"
|
||||
class="ticket-price"
|
||||
:class="{ 'is-free': ticketInfo.isFree }"
|
||||
>
|
||||
{{ ticketInfo.formattedPrice }}
|
||||
</span>
|
||||
|
||||
<!-- Early Bird Badge -->
|
||||
<span
|
||||
v-if="ticketInfo.isEarlyBird"
|
||||
class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-candlelight-900/20 text-candlelight-600 dark:bg-candlelight-900/35 dark:text-candlelight-400"
|
||||
>
|
||||
<span v-if="ticketInfo.isEarlyBird" class="badge early-bird">
|
||||
Early Bird
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Regular Price (if early bird) -->
|
||||
<div
|
||||
v-if="ticketInfo.isEarlyBird && ticketInfo.formattedRegularPrice"
|
||||
class="mt-1"
|
||||
>
|
||||
<span class="text-sm text-guild-400 line-through">
|
||||
Regular: {{ ticketInfo.formattedRegularPrice }}
|
||||
</span>
|
||||
<div v-if="ticketInfo.isEarlyBird && ticketInfo.formattedRegularPrice" class="ticket-regular-price">
|
||||
Regular: {{ ticketInfo.formattedRegularPrice }}
|
||||
</div>
|
||||
|
||||
<!-- Early Bird Countdown -->
|
||||
<div
|
||||
v-if="ticketInfo.isEarlyBird && ticketInfo.earlyBirdDeadline"
|
||||
class="mt-2 text-xs text-candlelight-500 dark:text-candlelight-400"
|
||||
>
|
||||
<Icon name="heroicons:clock" class="w-4 h-4 inline mr-1" />
|
||||
<div v-if="ticketInfo.isEarlyBird && ticketInfo.earlyBirdDeadline" class="ticket-deadline">
|
||||
Early bird ends {{ formatDeadline(ticketInfo.earlyBirdDeadline) }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -74,59 +44,38 @@
|
|||
<!-- Member Savings -->
|
||||
<div
|
||||
v-if="ticketInfo.publicTicket && ticketInfo.memberSavings > 0"
|
||||
class="mb-4 p-3 bg-candlelight-900/20 rounded-lg border border-candlelight-800"
|
||||
class="ticket-savings"
|
||||
>
|
||||
<p class="text-sm text-candlelight-400">
|
||||
<Icon name="heroicons:check-circle" class="w-4 h-4 inline mr-1" />
|
||||
You save {{ formatPrice(ticketInfo.memberSavings) }} as a member!
|
||||
</p>
|
||||
<p class="text-xs text-guild-400 mt-1">
|
||||
<p>You save {{ formatPrice(ticketInfo.memberSavings) }} as a member!</p>
|
||||
<p class="ticket-savings-detail">
|
||||
Public price: {{ ticketInfo.publicTicket.formattedPrice }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Availability -->
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<div>
|
||||
<span
|
||||
v-if="alreadyRegistered"
|
||||
class="text-candlelight-400 flex items-center gap-1"
|
||||
>
|
||||
<Icon name="heroicons:check-circle-solid" class="w-4 h-4" />
|
||||
You're registered
|
||||
</span>
|
||||
<span
|
||||
v-else-if="!isAvailable"
|
||||
class="text-ember-400 flex items-center gap-1"
|
||||
>
|
||||
<Icon name="heroicons:x-circle-solid" class="w-4 h-4" />
|
||||
Sold Out
|
||||
</span>
|
||||
<span v-else-if="ticketInfo.remaining !== null" class="text-guild-300">
|
||||
{{ ticketInfo.remaining }} remaining
|
||||
</span>
|
||||
<span v-else class="text-guild-300"> Unlimited availability </span>
|
||||
</div>
|
||||
|
||||
<!-- Selection Indicator -->
|
||||
<div v-if="isSelected && isAvailable && !alreadyRegistered">
|
||||
<Icon name="heroicons:check-circle-solid" class="w-5 h-5 text-primary" />
|
||||
</div>
|
||||
<div class="ticket-availability">
|
||||
<span v-if="alreadyRegistered" class="status-registered">
|
||||
You're registered
|
||||
</span>
|
||||
<span v-else-if="!isAvailable" class="status-sold-out">
|
||||
Sold Out
|
||||
</span>
|
||||
<span v-else-if="ticketInfo.remaining !== null" class="status-remaining">
|
||||
{{ ticketInfo.remaining }} remaining
|
||||
</span>
|
||||
<span v-else class="status-remaining">
|
||||
Unlimited availability
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Waitlist Option -->
|
||||
<div
|
||||
v-if="!isAvailable && ticketInfo.waitlistAvailable && !alreadyRegistered"
|
||||
class="mt-4 pt-4 border-t border-guild-600"
|
||||
class="ticket-waitlist"
|
||||
>
|
||||
<UButton
|
||||
color="gray"
|
||||
size="sm"
|
||||
block
|
||||
@click.stop="$emit('join-waitlist')"
|
||||
>
|
||||
<button class="btn" @click.stop="$emit('join-waitlist')">
|
||||
Join Waitlist
|
||||
</UButton>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -164,13 +113,11 @@ const formatDeadline = (deadline) => {
|
|||
const now = new Date();
|
||||
const diff = date - now;
|
||||
|
||||
// If less than 24 hours, show hours
|
||||
if (diff < 24 * 60 * 60 * 1000) {
|
||||
const hours = Math.floor(diff / (60 * 60 * 1000));
|
||||
return `in ${hours} hour${hours !== 1 ? "s" : ""}`;
|
||||
}
|
||||
|
||||
// Otherwise show date
|
||||
return `on ${date.toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
|
|
@ -187,6 +134,103 @@ const formatPrice = (amount) => {
|
|||
|
||||
<style scoped>
|
||||
.ticket-card {
|
||||
position: relative;
|
||||
border-bottom: 1px dashed var(--border);
|
||||
padding: 20px 24px;
|
||||
transition: border-color 0.15s;
|
||||
cursor: default;
|
||||
}
|
||||
.ticket-card.is-selected {
|
||||
border-color: var(--candle-faint);
|
||||
}
|
||||
.ticket-card.is-unavailable {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.ticket-card:not(.is-unavailable) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ticket-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ticket-name {
|
||||
font-family: "Brygada 1918", serif;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
.ticket-desc {
|
||||
font-size: 11px;
|
||||
color: var(--text-dim);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.ticket-price-block {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ticket-price-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
}
|
||||
.ticket-price {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
.ticket-price.is-free {
|
||||
color: var(--candle);
|
||||
}
|
||||
.ticket-regular-price {
|
||||
font-size: 11px;
|
||||
color: var(--text-faint);
|
||||
text-decoration: line-through;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.ticket-deadline {
|
||||
font-size: 10px;
|
||||
color: var(--candle-dim);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.early-bird {
|
||||
color: var(--candle-dim);
|
||||
border-color: rgba(122, 90, 16, 0.35);
|
||||
}
|
||||
|
||||
.ticket-savings {
|
||||
border: 1px dashed var(--candle-faint);
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 11px;
|
||||
color: var(--candle);
|
||||
}
|
||||
.ticket-savings-detail {
|
||||
font-size: 10px;
|
||||
color: var(--text-faint);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.ticket-availability {
|
||||
font-size: 11px;
|
||||
}
|
||||
.status-registered {
|
||||
color: var(--green);
|
||||
}
|
||||
.status-sold-out {
|
||||
color: var(--ember);
|
||||
}
|
||||
.status-remaining {
|
||||
color: var(--text-dim);
|
||||
}
|
||||
|
||||
.ticket-waitlist {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px dashed var(--border);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue