Readying for design

This commit is contained in:
Jennie Robinson Faber 2026-03-04 18:24:20 +00:00
parent d73256ca2b
commit fadf473dde
50 changed files with 1478 additions and 1259 deletions

11
.claude/launch.json Normal file
View file

@ -0,0 +1,11 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "ghostguild",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"port": 3003
}
]
}

View file

@ -1,5 +1,6 @@
<template> <template>
<UApp> <UApp>
<SvgFilters />
<NuxtLayout> <NuxtLayout>
<NuxtPage /> <NuxtPage />
</NuxtLayout> </NuxtLayout>

View file

@ -199,11 +199,11 @@
--color-circle-founder-dark: #76432a; --color-circle-founder-dark: #76432a;
--color-circle-founder-bg: rgba(178, 104, 64, 0.1); --color-circle-founder-bg: rgba(178, 104, 64, 0.1);
/* Practitioner - deep gold/ochre */ /* Practitioner - sage green (growth, wisdom, mentorship) */
--color-circle-practitioner: #8a7658; --color-circle-practitioner: #6b7c58;
--color-circle-practitioner-light: #b7a487; --color-circle-practitioner-light: #8fa47a;
--color-circle-practitioner-dark: #5a4d39; --color-circle-practitioner-dark: #4a5a39;
--color-circle-practitioner-bg: rgba(138, 118, 88, 0.1); --color-circle-practitioner-bg: rgba(107, 124, 88, 0.1);
/* Typographic scale */ /* Typographic scale */
--text-display-xl: 3.5rem; --text-display-xl: 3.5rem;
@ -250,23 +250,23 @@
--halftone-size: 8px 8px; --halftone-size: 8px 8px;
} }
/* Dark mode */ /* Dark mode - doubled opacity for perceptible candlelight warmth */
.dark:root { .dark:root {
--ambient-bg: --ambient-bg:
radial-gradient( radial-gradient(
circle at 20% 80%, circle at 20% 80%,
rgba(224, 184, 110, 0.03) 0%, rgba(224, 184, 110, 0.06) 0%,
transparent 50% transparent 50%
), ),
radial-gradient( radial-gradient(
circle at 80% 20%, circle at 80% 20%,
rgba(218, 154, 114, 0.02) 0%, rgba(218, 154, 114, 0.04) 0%,
transparent 50% transparent 50%
), ),
radial-gradient( radial-gradient(
circle at 40% 40%, circle at 50% 50%,
rgba(183, 164, 135, 0.01) 0%, rgba(183, 164, 135, 0.02) 0%,
transparent 50% transparent 60%
); );
--halftone-pattern: radial-gradient( --halftone-pattern: radial-gradient(
@ -351,7 +351,7 @@ body {
text-shadow: 0 0 10px rgba(224, 184, 110, 0.25); text-shadow: 0 0 10px rgba(224, 184, 110, 0.25);
} }
/* Subtle noise overlay */ /* Subtle noise overlay - SVG filter based, no image dependency */
.ink-grain { .ink-grain {
position: relative; position: relative;
} }
@ -359,19 +359,15 @@ body {
.ink-grain::before { .ink-grain::before {
content: ""; content: "";
position: absolute; position: absolute;
top: 0; inset: 0;
left: 0; filter: url(#grain-fine);
right: 0;
bottom: 0;
background-image: url("/textures/grain.png");
background-repeat: repeat;
background-size: 128px 128px;
mix-blend-mode: overlay; mix-blend-mode: overlay;
opacity: 0.04; opacity: 0.04;
pointer-events: none; pointer-events: none;
z-index: 1;
} }
/* Paper fiber overlay */ /* Paper fiber overlay - SVG filter based */
.paper-texture { .paper-texture {
position: relative; position: relative;
} }
@ -379,15 +375,27 @@ body {
.paper-texture::before { .paper-texture::before {
content: ""; content: "";
position: absolute; position: absolute;
top: 0; inset: 0;
left: 0; filter: url(#grain-paper);
right: 0;
bottom: 0;
background-image: url("/textures/paper.png");
background-repeat: repeat;
background-size: 256px 256px;
opacity: 0.04; opacity: 0.04;
pointer-events: none; pointer-events: none;
z-index: 1;
}
/* Generic grain overlay utility */
.texture-grain-overlay {
position: relative;
}
.texture-grain-overlay::after {
content: "";
position: absolute;
inset: 0;
filter: url(#grain-fine);
opacity: 0.035;
mix-blend-mode: overlay;
pointer-events: none;
z-index: 1;
} }
/* Irregular line border */ /* Irregular line border */
@ -410,10 +418,14 @@ body {
border-radius: 50%; border-radius: 50%;
} }
/* Warm interior feel for content areas */ /* Warm interior feel for content areas - enclosed, lit space */
.guild-interior { .guild-interior {
background: var(--ambient-bg); background:
box-shadow: inset 0 2px 8px rgba(26, 21, 16, 0.06); linear-gradient(180deg, rgba(26, 21, 16, 0.2) 0%, transparent 200px),
var(--ambient-bg);
box-shadow:
inset 0 2px 12px rgba(26, 21, 16, 0.12),
inset 0 0 60px rgba(26, 21, 16, 0.04);
} }
/* Dithered gradients */ /* Dithered gradients */
@ -446,6 +458,112 @@ body {
-2px 0px; -2px 0px;
} }
/* Fine dither - 2px, subtle surface texture */
.dithered-fine {
background-image:
linear-gradient(45deg, var(--color-guild-700) 25%, transparent 25%),
linear-gradient(-45deg, var(--color-guild-700) 25%, transparent 25%);
background-size: 2px 2px;
}
/* Dither fade - gradient from dithered to solid */
.dithered-fade-top {
background-image:
repeating-linear-gradient(
0deg,
var(--color-guild-800) 0px,
var(--color-guild-800) 1px,
transparent 1px,
transparent 3px
);
mask-image: linear-gradient(to bottom, black, transparent);
-webkit-mask-image: linear-gradient(to bottom, black, transparent);
}
.dithered-fade-bottom {
background-image:
repeating-linear-gradient(
0deg,
var(--color-guild-800) 0px,
var(--color-guild-800) 1px,
transparent 1px,
transparent 3px
);
mask-image: linear-gradient(to top, black, transparent);
-webkit-mask-image: linear-gradient(to top, black, transparent);
}
/* Circle badge utilities */
.circle-badge-community {
background-color: var(--color-circle-community-bg);
color: var(--color-circle-community-light);
border: 1px solid color-mix(in srgb, var(--color-circle-community) 40%, transparent);
}
.circle-badge-founder {
background-color: var(--color-circle-founder-bg);
color: var(--color-circle-founder-light);
border: 1px solid color-mix(in srgb, var(--color-circle-founder) 40%, transparent);
}
.circle-badge-practitioner {
background-color: var(--color-circle-practitioner-bg);
color: var(--color-circle-practitioner-light);
border: 1px solid color-mix(in srgb, var(--color-circle-practitioner) 40%, transparent);
}
/* Circle surface treatments - subtle background for circle-specific sections */
.circle-surface-community {
background-color: var(--color-circle-community-bg);
}
.circle-surface-founder {
background-color: var(--color-circle-founder-bg);
}
.circle-surface-practitioner {
background-color: var(--color-circle-practitioner-bg);
}
/* Parchment surface for elevated content panels */
.parchment-surface {
background-color: var(--color-parchment-950);
border: 1px solid var(--color-parchment-800);
}
.dark .parchment-surface {
background-color: var(--color-guild-800);
border-color: var(--color-guild-700);
}
/* UI typography utilities */
.text-ui-label {
font-family: var(--font-mono);
font-size: var(--text-overline);
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
}
.text-ui-mono {
font-family: var(--font-mono);
font-size: var(--text-body-sm);
}
/* Illustration integration utilities */
.guild-illustration {
max-width: 100%;
height: auto;
filter: drop-shadow(0 0 20px rgba(184, 135, 58, 0.08));
}
.guild-illustration-adaptive {
color: var(--color-guild-300);
}
.dark .guild-illustration-adaptive {
color: var(--color-guild-600);
}
/* Prose overrides for guild wiki/long-form content */ /* Prose overrides for guild wiki/long-form content */
.prose-guild { .prose-guild {
max-width: 72ch; max-width: 72ch;

View file

@ -7,11 +7,14 @@
]" ]"
> >
<!-- Logo/Brand at top (desktop only) --> <!-- Logo/Brand at top (desktop only) -->
<div v-if="!isMobile" class="p-8 border-b border-guild-700 bg-primary-500"> <!-- Logo/Brand: designer will replace text with logo asset -->
<div v-if="!isMobile" class="p-8 border-b border-guild-700 bg-guild-900">
<NuxtLink to="/" class="flex flex-col items-center gap-3 group"> <NuxtLink to="/" class="flex flex-col items-center gap-3 group">
<span class="text-xl font-bold text-white warm-text tracking-wider" <slot name="logo">
>Ghost Guild Logo</span <span class="text-display-sm font-bold text-candlelight-400 warm-text tracking-wider"
> >Ghost Guild</span
>
</slot>
</NuxtLink> </NuxtLink>
</div> </div>
@ -112,16 +115,16 @@
<div <div
v-if="loginSuccess" v-if="loginSuccess"
class="p-3 bg-green-900/20 rounded border border-green-800" class="p-3 bg-candlelight-900/20 rounded border border-candlelight-800"
> >
<p class="text-green-300 text-sm"> Check your email!</p> <p class="text-candlelight-400 text-sm">Check your email!</p>
</div> </div>
<div <div
v-if="loginError" v-if="loginError"
class="p-3 bg-red-900/20 rounded border border-red-800" class="p-3 bg-ember-900/20 rounded border border-ember-800"
> >
<p class="text-red-300 text-sm">{{ loginError }}</p> <p class="text-ember-400 text-sm">{{ loginError }}</p>
</div> </div>
</div> </div>
</div> </div>

View file

@ -4,33 +4,33 @@
> >
<!-- Header --> <!-- Header -->
<div <div
class="bg-gradient-to-br from-purple-600 to-purple-800 dark:from-purple-700 dark:to-purple-900 p-6" class="bg-gradient-to-br from-candlelight-500 to-candlelight-700 dark:from-candlelight-600 dark:to-candlelight-800 p-6"
> >
<div class="flex items-start justify-between gap-4"> <div class="flex items-start justify-between gap-4">
<div class="flex-1"> <div class="flex-1">
<div class="flex items-center gap-2 mb-2"> <div class="flex items-center gap-2 mb-2">
<Icon <Icon
name="heroicons:ticket" name="heroicons:ticket"
class="w-5 h-5 text-purple-200 dark:text-purple-300" class="w-5 h-5 text-candlelight-900 dark:text-candlelight-200"
/> />
<span class="text-sm font-semibold text-purple-200 dark:text-purple-300"> <span class="text-sm font-semibold text-candlelight-900 dark:text-candlelight-200">
Series Pass Series Pass
</span> </span>
</div> </div>
<h3 class="text-xl font-bold text-white mb-1"> <h3 class="text-xl font-bold text-white mb-1">
{{ ticket.name }} {{ ticket.name }}
</h3> </h3>
<p v-if="ticket.description" class="text-sm text-purple-200 dark:text-purple-300"> <p v-if="ticket.description" class="text-sm text-candlelight-900 dark:text-candlelight-200">
{{ ticket.description }} {{ ticket.description }}
</p> </p>
</div> </div>
<div class="text-right flex-shrink-0"> <div class="text-right flex-shrink-0">
<div class="text-3xl font-bold text-white"> <div class="text-3xl font-bold text-white text-ui-mono">
{{ formatPrice(ticket.price, ticket.currency) }} {{ formatPrice(ticket.price, ticket.currency) }}
</div> </div>
<div <div
v-if="ticket.isEarlyBird" v-if="ticket.isEarlyBird"
class="text-xs text-purple-200 dark:text-purple-300 mt-1" class="text-xs text-candlelight-900 dark:text-candlelight-200 mt-1"
> >
Early Bird Price Early Bird Price
</div> </div>
@ -47,21 +47,21 @@
</h4> </h4>
<div class="space-y-2"> <div class="space-y-2">
<div class="flex items-center gap-2 text-guild-300 dark:text-guild-300"> <div class="flex items-center gap-2 text-guild-300 dark:text-guild-300">
<Icon name="heroicons:check-circle" class="w-5 h-5 text-green-400" /> <Icon name="heroicons:check-circle" class="w-5 h-5 text-candlelight-400" />
<span>Access to all {{ totalEvents }} events in the series</span> <span>Access to all {{ totalEvents }} events in the series</span>
</div> </div>
<div <div
v-if="ticket.isFree && !isMember" v-if="ticket.isFree && !isMember"
class="flex items-center gap-2 text-guild-300 dark:text-guild-300" class="flex items-center gap-2 text-guild-300 dark:text-guild-300"
> >
<Icon name="heroicons:check-circle" class="w-5 h-5 text-green-400" /> <Icon name="heroicons:check-circle" class="w-5 h-5 text-candlelight-400" />
<span>Automatic registration for all sessions</span> <span>Automatic registration for all sessions</span>
</div> </div>
<div <div
v-if="memberSavings > 0" v-if="memberSavings > 0"
class="flex items-center gap-2 text-guild-300 dark:text-guild-300" class="flex items-center gap-2 text-guild-300 dark:text-guild-300"
> >
<Icon name="heroicons:check-circle" class="w-5 h-5 text-green-400" /> <Icon name="heroicons:check-circle" class="w-5 h-5 text-candlelight-400" />
<span>Save {{ formatPrice(memberSavings, ticket.currency) }} as a member</span> <span>Save {{ formatPrice(memberSavings, ticket.currency) }} as a member</span>
</div> </div>
</div> </div>
@ -79,9 +79,9 @@
class="flex items-start gap-3 p-3 bg-guild-700/50 dark:bg-guild-600/30 rounded-lg" class="flex items-start gap-3 p-3 bg-guild-700/50 dark:bg-guild-600/30 rounded-lg"
> >
<div <div
class="w-8 h-8 rounded-full bg-purple-600/20 border border-purple-500/30 flex items-center justify-center flex-shrink-0" class="w-8 h-8 rounded-full bg-candlelight-600/20 border border-candlelight-500/30 flex items-center justify-center flex-shrink-0"
> >
<span class="text-sm font-bold text-purple-300">{{ index + 1 }}</span> <span class="text-sm font-bold text-candlelight-300">{{ index + 1 }}</span>
</div> </div>
<div class="flex-1 min-w-0"> <div class="flex-1 min-w-0">
<div class="font-medium text-guild-100 dark:text-guild-100 text-sm"> <div class="font-medium text-guild-100 dark:text-guild-100 text-sm">
@ -104,13 +104,13 @@
<!-- Member Benefit Callout --> <!-- Member Benefit Callout -->
<div <div
v-if="ticket.isFree && isMember" v-if="ticket.isFree && isMember"
class="p-4 bg-green-900/20 border border-green-700/30 rounded-lg mb-6" class="p-4 bg-candlelight-900/20 border border-candlelight-700/30 rounded-lg mb-6"
> >
<div class="flex items-start gap-3"> <div class="flex items-start gap-3">
<Icon name="heroicons:sparkles" class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5" /> <Icon name="heroicons:sparkles" class="w-5 h-5 text-candlelight-400 flex-shrink-0 mt-0.5" />
<div> <div>
<div class="font-semibold text-green-300 mb-1">Member Benefit</div> <div class="font-semibold text-candlelight-300 mb-1">Member Benefit</div>
<div class="text-sm text-green-400"> <div class="text-sm text-candlelight-400">
This series pass is free for Ghost Guild members! Complete registration to secure your spot. This series pass is free for Ghost Guild members! Complete registration to secure your spot.
</div> </div>
</div> </div>
@ -120,13 +120,13 @@
<!-- Public vs Member Pricing --> <!-- Public vs Member Pricing -->
<div <div
v-if="!ticket.isFree && publicPrice && ticket.type === 'member'" v-if="!ticket.isFree && publicPrice && ticket.type === 'member'"
class="p-4 bg-blue-900/20 border border-blue-700/30 rounded-lg mb-6" class="p-4 bg-candlelight-900/20 border border-candlelight-700/30 rounded-lg mb-6"
> >
<div class="flex items-start gap-3"> <div class="flex items-start gap-3">
<Icon name="heroicons:tag" class="w-5 h-5 text-blue-400 flex-shrink-0 mt-0.5" /> <Icon name="heroicons:tag" class="w-5 h-5 text-candlelight-400 flex-shrink-0 mt-0.5" />
<div class="flex-1"> <div class="flex-1">
<div class="font-semibold text-blue-300 mb-1">Member Savings</div> <div class="font-semibold text-candlelight-300 mb-1">Member Savings</div>
<div class="text-sm text-blue-400"> <div class="text-sm text-candlelight-400">
You're saving {{ formatPrice(memberSavings, ticket.currency) }} as a member. You're saving {{ formatPrice(memberSavings, ticket.currency) }} as a member.
Public price: {{ formatPrice(publicPrice, ticket.currency) }} Public price: {{ formatPrice(publicPrice, ticket.currency) }}
</div> </div>
@ -144,13 +144,13 @@
:name="availability.remaining > 5 ? 'heroicons:check-circle' : 'heroicons:exclamation-triangle'" :name="availability.remaining > 5 ? 'heroicons:check-circle' : 'heroicons:exclamation-triangle'"
:class="[ :class="[
'w-5 h-5', 'w-5 h-5',
availability.remaining > 5 ? 'text-green-400' : 'text-yellow-400' availability.remaining > 5 ? 'text-candlelight-400' : 'text-ember-400'
]" ]"
/> />
<span <span
:class="[ :class="[
'text-sm font-medium', 'text-sm font-medium',
availability.remaining > 5 ? 'text-green-300' : 'text-yellow-300' availability.remaining > 5 ? 'text-candlelight-300' : 'text-ember-300'
]" ]"
> >
{{ availability.remaining }} series pass{{ availability.remaining !== 1 ? 'es' : '' }} remaining {{ availability.remaining }} series pass{{ availability.remaining !== 1 ? 'es' : '' }} remaining
@ -160,12 +160,12 @@
<!-- Sold Out / Waitlist --> <!-- Sold Out / Waitlist -->
<div v-if="!available" class="space-y-3"> <div v-if="!available" class="space-y-3">
<div class="p-4 bg-red-900/20 border border-red-700/30 rounded-lg"> <div class="p-4 bg-ember-900/20 border border-ember-700/30 rounded-lg">
<div class="flex items-start gap-3"> <div class="flex items-start gap-3">
<Icon name="heroicons:exclamation-circle" class="w-5 h-5 text-red-400 flex-shrink-0 mt-0.5" /> <Icon name="heroicons:exclamation-circle" class="w-5 h-5 text-ember-400 flex-shrink-0 mt-0.5" />
<div> <div>
<div class="font-semibold text-red-300 mb-1">Series Pass Sold Out</div> <div class="font-semibold text-ember-300 mb-1">Series Pass Sold Out</div>
<div class="text-sm text-red-400"> <div class="text-sm text-ember-400">
All series passes have been claimed. All series passes have been claimed.
</div> </div>
</div> </div>
@ -183,12 +183,12 @@
</div> </div>
<!-- Already Registered --> <!-- Already Registered -->
<div v-else-if="alreadyRegistered" class="p-4 bg-green-900/20 border border-green-700/30 rounded-lg"> <div v-else-if="alreadyRegistered" class="p-4 bg-candlelight-900/20 border border-candlelight-700/30 rounded-lg">
<div class="flex items-start gap-3"> <div class="flex items-start gap-3">
<Icon name="heroicons:check-badge" class="w-6 h-6 text-green-400 flex-shrink-0" /> <Icon name="heroicons:check-badge" class="w-6 h-6 text-candlelight-400 flex-shrink-0" />
<div> <div>
<div class="font-semibold text-green-300 mb-1">You're Registered!</div> <div class="font-semibold text-candlelight-300 mb-1">You're Registered!</div>
<div class="text-sm text-green-400"> <div class="text-sm text-candlelight-400">
You have a series pass and are registered for all {{ totalEvents }} events. You have a series pass and are registered for all {{ totalEvents }} events.
</div> </div>
</div> </div>

View file

@ -25,7 +25,7 @@
<!-- Badge --> <!-- Badge -->
<div v-if="ticketInfo.isMember" class="flex-shrink-0 ml-4"> <div v-if="ticketInfo.isMember" class="flex-shrink-0 ml-4">
<span <span
class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400" 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 Members Only
</span> </span>
@ -36,8 +36,8 @@
<div class="mb-4"> <div class="mb-4">
<div class="flex items-baseline gap-2"> <div class="flex items-baseline gap-2">
<span <span
class="text-3xl font-bold" class="text-3xl font-bold text-ui-mono"
:class="ticketInfo.isFree ? 'text-green-400' : 'text-guild-100'" :class="ticketInfo.isFree ? 'text-candlelight-400' : 'text-guild-100'"
> >
{{ ticketInfo.formattedPrice }} {{ ticketInfo.formattedPrice }}
</span> </span>
@ -74,9 +74,9 @@
<!-- Member Savings --> <!-- Member Savings -->
<div <div
v-if="ticketInfo.publicTicket && ticketInfo.memberSavings > 0" v-if="ticketInfo.publicTicket && ticketInfo.memberSavings > 0"
class="mb-4 p-3 bg-green-900/20 rounded-lg border border-green-800" class="mb-4 p-3 bg-candlelight-900/20 rounded-lg border border-candlelight-800"
> >
<p class="text-sm text-green-400"> <p class="text-sm text-candlelight-400">
<Icon name="heroicons:check-circle" class="w-4 h-4 inline mr-1" /> <Icon name="heroicons:check-circle" class="w-4 h-4 inline mr-1" />
You save {{ formatPrice(ticketInfo.memberSavings) }} as a member! You save {{ formatPrice(ticketInfo.memberSavings) }} as a member!
</p> </p>
@ -90,14 +90,14 @@
<div> <div>
<span <span
v-if="alreadyRegistered" v-if="alreadyRegistered"
class="text-green-400 flex items-center gap-1" class="text-candlelight-400 flex items-center gap-1"
> >
<Icon name="heroicons:check-circle-solid" class="w-4 h-4" /> <Icon name="heroicons:check-circle-solid" class="w-4 h-4" />
You're registered You're registered
</span> </span>
<span <span
v-else-if="!isAvailable" v-else-if="!isAvailable"
class="text-red-400 flex items-center gap-1" class="text-ember-400 flex items-center gap-1"
> >
<Icon name="heroicons:x-circle-solid" class="w-4 h-4" /> <Icon name="heroicons:x-circle-solid" class="w-4 h-4" />
Sold Out Sold Out

View file

@ -11,26 +11,26 @@
<!-- Error State --> <!-- Error State -->
<div <div
v-else-if="error" v-else-if="error"
class="p-6 bg-red-900/20 rounded-xl border border-red-800" class="p-6 bg-ember-900/20 rounded-xl border border-ember-800"
> >
<h3 class="text-lg font-semibold text-red-300 mb-2"> <h3 class="text-lg font-semibold text-ember-300 mb-2">
Unable to Load Tickets Unable to Load Tickets
</h3> </h3>
<p class="text-red-400">{{ error }}</p> <p class="text-ember-400">{{ error }}</p>
</div> </div>
<!-- Series Pass Required --> <!-- Series Pass Required -->
<div <div
v-else-if="ticketInfo?.requiresSeriesPass" v-else-if="ticketInfo?.requiresSeriesPass"
class="p-6 bg-purple-900/20 rounded-xl border border-purple-800" class="p-6 bg-candlelight-900/20 rounded-xl border border-candlelight-800"
> >
<h3 <h3
class="text-lg font-semibold text-purple-300 mb-2 flex items-center gap-2" class="text-lg font-semibold text-candlelight-300 mb-2 flex items-center gap-2"
> >
<Icon name="heroicons:ticket" class="w-6 h-6" /> <Icon name="heroicons:ticket" class="w-6 h-6" />
Series Pass Required Series Pass Required
</h3> </h3>
<p class="text-purple-400 mb-4"> <p class="text-candlelight-400 mb-4">
This event is part of This event is part of
<strong>{{ ticketInfo.series?.title }}</strong> and requires a series <strong>{{ ticketInfo.series?.title }}</strong> and requires a series
pass to attend. pass to attend.
@ -51,15 +51,15 @@
<!-- Already Registered --> <!-- Already Registered -->
<div <div
v-else-if="ticketInfo?.alreadyRegistered" v-else-if="ticketInfo?.alreadyRegistered"
class="p-6 bg-green-900/20 rounded-xl border border-green-800" class="p-6 bg-candlelight-900/20 rounded-xl border border-candlelight-800"
> >
<h3 <h3
class="text-lg font-semibold text-green-300 mb-2 flex items-center gap-2" class="text-lg font-semibold text-candlelight-300 mb-2 flex items-center gap-2"
> >
<Icon name="heroicons:check-circle-solid" class="w-6 h-6" /> <Icon name="heroicons:check-circle-solid" class="w-6 h-6" />
You're Registered! You're Registered!
</h3> </h3>
<p class="text-green-400 mb-4"> <p class="text-candlelight-400 mb-4">
<template v-if="ticketInfo.viaSeriesPass"> <template v-if="ticketInfo.viaSeriesPass">
You have access to this event via your series pass for You have access to this event via your series pass for
<strong>{{ ticketInfo.series?.title }}</strong <strong>{{ ticketInfo.series?.title }}</strong
@ -136,9 +136,9 @@
<!-- Member Benefits Notice --> <!-- Member Benefits Notice -->
<div <div
v-if="ticketInfo.isMember && ticketInfo.isFree" v-if="ticketInfo.isMember && ticketInfo.isFree"
class="p-4 bg-purple-900/20 rounded-lg border border-purple-800" class="p-4 bg-candlelight-900/20 rounded-lg border border-candlelight-800"
> >
<p class="text-sm text-purple-300 flex items-center gap-2"> <p class="text-sm text-candlelight-300 flex items-center gap-2">
<Icon name="heroicons:sparkles" class="w-4 h-4" /> <Icon name="heroicons:sparkles" class="w-4 h-4" />
This event is free for Ghost Guild members This event is free for Ghost Guild members
</p> </p>
@ -147,9 +147,9 @@
<!-- Payment Required Notice --> <!-- Payment Required Notice -->
<div <div
v-if="!ticketInfo.isFree" v-if="!ticketInfo.isFree"
class="p-4 bg-blue-900/20 rounded-lg border border-blue-800" class="p-4 bg-candlelight-900/20 rounded-lg border border-candlelight-800"
> >
<p class="text-sm text-blue-300 flex items-center gap-2"> <p class="text-sm text-candlelight-300 flex items-center gap-2">
<Icon name="heroicons:credit-card" class="w-4 h-4" /> <Icon name="heroicons:credit-card" class="w-4 h-4" />
Payment of {{ ticketInfo.formattedPrice }} will be processed Payment of {{ ticketInfo.formattedPrice }} will be processed
securely securely
@ -201,7 +201,7 @@
<div v-else-if="!ticketInfo.available" class="text-center py-8"> <div v-else-if="!ticketInfo.available" class="text-center py-8">
<Icon <Icon
name="heroicons:x-circle" name="heroicons:x-circle"
class="w-16 h-16 text-red-400 mx-auto mb-4" class="w-16 h-16 text-ember-400 mx-auto mb-4"
/> />
<h3 class="text-xl font-bold text-guild-100 mb-2">Event Sold Out</h3> <h3 class="text-xl font-bold text-guild-100 mb-2">Event Sold Out</h3>
<p class="text-guild-300"> <p class="text-guild-300">

View file

@ -0,0 +1,47 @@
<template>
<div :class="['guild-divider', spacing]" role="separator" aria-hidden="true">
<!-- Woodcut: irregular hand-drawn line -->
<svg
v-if="variant === 'woodcut'"
viewBox="0 0 800 12"
preserveAspectRatio="none"
class="w-full h-3 text-guild-600"
>
<path
d="M0,6 Q50,3 100,7 T200,5 T300,8 T400,4 T500,7 T600,5 T700,8 T800,6"
stroke="currentColor"
stroke-width="1.5"
fill="none"
stroke-dasharray="8,3,15,4,6,5"
/>
</svg>
<!-- Dither: warm amber dithered line -->
<div v-else-if="variant === 'dither'" class="h-px dithered-warm opacity-60" />
<!-- Dots: halftone dot row -->
<div
v-else-if="variant === 'dots'"
class="h-2 halftone-texture opacity-30"
/>
<!-- Simple: plain rule -->
<hr v-else class="border-guild-700" />
</div>
</template>
<script setup>
const props = defineProps({
variant: {
type: String,
default: 'simple',
validator: (v) => ['simple', 'woodcut', 'dither', 'dots'].includes(v),
},
compact: {
type: Boolean,
default: false,
},
})
const spacing = computed(() => props.compact ? 'my-4' : 'my-8')
</script>

View file

@ -5,14 +5,14 @@
<img <img
:src="transformedImageUrl" :src="transformedImageUrl"
:alt="modelValue.alt || 'Event image'" :alt="modelValue.alt || 'Event image'"
class="w-full h-48 object-cover rounded-lg border border-neutral-200" class="w-full h-48 object-cover rounded-lg border border-guild-700"
@error="console.log('Image failed to load:', transformedImageUrl)" @error="console.log('Image failed to load:', transformedImageUrl)"
@load="console.log('Image loaded successfully:', transformedImageUrl)" @load="console.log('Image loaded successfully:', transformedImageUrl)"
/> />
<button <button
@click="removeImage" @click="removeImage"
type="button" type="button"
class="absolute top-2 right-2 p-1 bg-red-500 text-white rounded-full hover:bg-red-600 transition-colors" class="absolute top-2 right-2 p-1 bg-ember-500 text-white rounded-full hover:bg-ember-600 transition-colors"
> >
<Icon name="heroicons:x-mark" class="w-4 h-4" /> <Icon name="heroicons:x-mark" class="w-4 h-4" />
</button> </button>
@ -21,11 +21,11 @@
<!-- Upload Area --> <!-- Upload Area -->
<div <div
v-if="!modelValue?.url" v-if="!modelValue?.url"
class="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center hover:border-gray-400 transition-colors" class="border-2 border-dashed border-guild-700 rounded-lg p-6 text-center hover:border-guild-600 transition-colors"
@dragover.prevent="isDragging = true" @dragover.prevent="isDragging = true"
@dragleave.prevent="isDragging = false" @dragleave.prevent="isDragging = false"
@drop.prevent="handleDrop" @drop.prevent="handleDrop"
:class="{ 'border-blue-400 bg-blue-50': isDragging }" :class="{ 'border-candlelight-400 bg-candlelight-900/20': isDragging }"
> >
<input <input
ref="fileInput" ref="fileInput"
@ -36,52 +36,52 @@
/> />
<div class="space-y-3"> <div class="space-y-3">
<Icon name="heroicons:photo" class="w-12 h-12 text-gray-400 mx-auto" /> <Icon name="heroicons:photo" class="w-12 h-12 text-guild-400 mx-auto" />
<div> <div>
<p class="text-gray-600"> <p class="text-guild-400">
<button <button
type="button" type="button"
@click="$refs.fileInput.click()" @click="$refs.fileInput.click()"
class="text-primary-600 hover:text-primary-500 font-medium" class="text-candlelight-400 hover:text-candlelight-300 font-medium"
> >
Click to upload Click to upload
</button> </button>
or drag and drop or drag and drop
</p> </p>
<p class="text-sm text-gray-500">PNG, JPG, GIF up to 10MB</p> <p class="text-sm text-guild-500">PNG, JPG, GIF up to 10MB</p>
</div> </div>
</div> </div>
</div> </div>
<!-- Alt Text Input --> <!-- Alt Text Input -->
<div v-if="modelValue?.url"> <div v-if="modelValue?.url">
<label class="block text-sm font-medium text-gray-700 mb-1"> <label class="block text-sm font-medium text-guild-100 mb-1">
Alt Text (for accessibility) Alt Text (for accessibility)
</label> </label>
<input <input
:value="modelValue.alt || ''" :value="modelValue.alt || ''"
@input="updateAltText($event.target.value)" @input="updateAltText($event.target.value)"
placeholder="Describe this image..." placeholder="Describe this image..."
class="w-full border border-neutral-200 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="w-full bg-guild-800 border border-guild-700 rounded-lg px-3 py-2 text-guild-100 placeholder-guild-500 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
/> />
</div> </div>
<!-- Upload Progress --> <!-- Upload Progress -->
<div v-if="isUploading" class="space-y-2"> <div v-if="isUploading" class="space-y-2">
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<span class="text-gray-600">Uploading...</span> <span class="text-guild-400">Uploading...</span>
<span class="text-gray-600">{{ uploadProgress }}%</span> <span class="text-guild-400">{{ uploadProgress }}%</span>
</div> </div>
<div class="w-full bg-gray-200 rounded-full h-2"> <div class="w-full bg-guild-800 rounded-full h-2">
<div <div
class="bg-blue-600 h-2 rounded-full transition-all duration-300" class="bg-candlelight-600 h-2 rounded-full transition-all duration-300"
:style="`width: ${uploadProgress}%`" :style="`width: ${uploadProgress}%`"
/> />
</div> </div>
</div> </div>
<!-- Error Message --> <!-- Error Message -->
<div v-if="errorMessage" class="text-sm text-red-600"> <div v-if="errorMessage" class="text-sm text-ember-400">
{{ errorMessage }} {{ errorMessage }}
</div> </div>
</div> </div>

View file

@ -17,8 +17,8 @@
<div class="space-y-6"> <div class="space-y-6">
<!-- Success State --> <!-- Success State -->
<div v-if="loginSuccess" class="text-center py-4"> <div v-if="loginSuccess" class="text-center py-4">
<div class="w-16 h-16 bg-green-500/20 rounded-full flex items-center justify-center mx-auto mb-4"> <div class="w-16 h-16 bg-candlelight-500/20 rounded-full flex items-center justify-center mx-auto mb-4">
<Icon name="heroicons:check-circle" class="w-10 h-10 text-green-400" /> <Icon name="heroicons:check-circle" class="w-10 h-10 text-candlelight-400" />
</div> </div>
<h3 class="text-lg font-semibold text-guild-100 mb-2">Check your email</h3> <h3 class="text-lg font-semibold text-guild-100 mb-2">Check your email</h3>
<p class="text-guild-300"> <p class="text-guild-300">
@ -55,9 +55,9 @@
<!-- Error Message --> <!-- Error Message -->
<div <div
v-if="loginError" v-if="loginError"
class="mb-4 p-3 bg-red-500/10 border border-red-500/30 rounded-lg" class="mb-4 p-3 bg-ember-500/10 border border-ember-500/30 rounded-lg"
> >
<p class="text-red-400 text-sm">{{ loginError }}</p> <p class="text-ember-400 text-sm">{{ loginError }}</p>
</div> </div>
<!-- Submit Button --> <!-- Submit Button -->

View file

@ -97,11 +97,11 @@ const handleActionClick = async () => {
// Map color names to UButton color props // Map color names to UButton color props
const getButtonColor = (color) => { const getButtonColor = (color) => {
const colorMap = { const colorMap = {
orange: "orange", orange: "warning",
blue: "blue", blue: "primary",
gray: "gray", gray: "neutral",
}; };
return colorMap[color] || "blue"; return colorMap[color] || "primary";
}; };
// Only show banner if status is not active // Only show banner if status is not active
@ -117,8 +117,8 @@ const nextAction = computed(() => getNextAction());
const getActionButtonClass = (color) => { const getActionButtonClass = (color) => {
const baseClass = "hover:scale-105 active:scale-95"; const baseClass = "hover:scale-105 active:scale-95";
const colorClasses = { const colorClasses = {
orange: "bg-orange-600 text-white hover:bg-orange-700", orange: "bg-candlelight-600 text-white hover:bg-candlelight-700",
blue: "bg-blue-600 text-white hover:bg-blue-700", blue: "bg-guild-600 text-white hover:bg-guild-500",
gray: "bg-guild-700 text-guild-100 hover:bg-guild-600", gray: "bg-guild-700 text-guild-100 hover:bg-guild-600",
}; };
return `${baseClass} ${colorClasses[color] || colorClasses.blue}`; return `${baseClass} ${colorClasses[color] || colorClasses.blue}`;

View file

@ -18,12 +18,12 @@
<Icon <Icon
v-if="isValidParse && naturalInput.trim()" v-if="isValidParse && naturalInput.trim()"
name="heroicons:check-circle" name="heroicons:check-circle"
class="w-5 h-5 text-green-500" class="w-5 h-5 text-candlelight-500"
/> />
<Icon <Icon
v-else-if="hasError && naturalInput.trim()" v-else-if="hasError && naturalInput.trim()"
name="heroicons:exclamation-circle" name="heroicons:exclamation-circle"
class="w-5 h-5 text-red-500" class="w-5 h-5 text-ember-500"
/> />
</template> </template>
</UInput> </UInput>
@ -31,7 +31,7 @@
<div <div
v-if="parsedDate && isValidParse" v-if="parsedDate && isValidParse"
class="text-sm text-green-700 bg-green-50 px-3 py-2 rounded-lg border border-green-200" class="text-sm text-candlelight-400 bg-candlelight-900/20 px-3 py-2 rounded-lg border border-candlelight-800"
> >
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<Icon name="heroicons:calendar" class="w-4 h-4" /> <Icon name="heroicons:calendar" class="w-4 h-4" />
@ -41,7 +41,7 @@
<div <div
v-if="hasError && naturalInput.trim()" v-if="hasError && naturalInput.trim()"
class="text-sm text-red-700 bg-red-50 px-3 py-2 rounded-lg border border-red-200" class="text-sm text-ember-400 bg-ember-900/20 px-3 py-2 rounded-lg border border-ember-800"
> >
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<Icon name="heroicons:exclamation-triangle" class="w-4 h-4" /> <Icon name="heroicons:exclamation-triangle" class="w-4 h-4" />
@ -51,7 +51,7 @@
<!-- Fallback datetime-local input --> <!-- Fallback datetime-local input -->
<details class="text-sm"> <details class="text-sm">
<summary class="cursor-pointer text-muted hover:text-default"> <summary class="cursor-pointer text-guild-400 hover:text-guild-100">
Use traditional date picker Use traditional date picker
</summary> </summary>
<div class="mt-2"> <div class="mt-2">

View file

@ -1,105 +1,60 @@
<template> <template>
<header <header
class="relative py-16 md:py-24 bg-cover bg-center" class="relative py-16 md:py-24 bg-cover bg-center"
style="background-image: url(&quot;/background-dither.png&quot;)" style="background-image: url('/background-dither.webp')"
> >
<div class="absolute inset-0 bg-black/40"></div> <div class="absolute inset-0 bg-black/40"></div>
<UContainer class="relative z-10"> <UContainer class="relative z-10">
<div class="text-center max-w-4xl mx-auto"> <div class="text-center max-w-4xl mx-auto">
<h1 <h1
class="font-bold mb-6 md:mb-8" class="font-bold mb-6 md:mb-8 text-white"
:class="[titleSizeClass, titleColorClass]" :class="titleSizeClass"
> >
{{ title }} {{ title }}
</h1> </h1>
<p <p
v-if="subtitle" v-if="subtitle"
class="text-lg md:text-xl leading-relaxed mb-8" class="text-lg md:text-xl leading-relaxed mb-8 text-white/90"
:class="subtitleColorClass"
> >
{{ subtitle }} {{ subtitle }}
</p> </p>
<!-- Interactive Content Area (for hero sections with carousels, etc.) --> <!-- Interactive Content Area (for hero sections with carousels) -->
<div <div
v-if="showInteractiveArea" v-if="showInteractiveArea"
:class="[ class="rounded-2xl p-6 md:p-8 mb-12 backdrop-blur-sm bg-guild-800/60 border border-guild-700 candlelight-glow halftone-texture"
'rounded-2xl p-6 md:p-8 mb-12 backdrop-blur-sm',
props.theme === 'guild'
? 'bg-guild-800/60 border border-guild-700 candlelight-glow halftone-texture'
: 'bg-[--ui-bg-elevated] shadow-xl border border-blue-200',
]"
> >
<div class="flex items-center justify-between gap-3 md:gap-4"> <div class="flex items-center justify-between gap-3 md:gap-4">
<button <button
:class="[ class="p-2 md:p-3 rounded-full transition-all duration-300 flex-shrink-0 bg-candlelight-600/80 text-guild-100 hover:bg-candlelight-500 candlelight-glow"
'p-2 md:p-3 rounded-full transition-all duration-300 flex-shrink-0',
props.theme === 'guild'
? 'bg-candlelight-600/80 text-guild-100 hover:bg-candlelight-500 candlelight-glow'
: 'bg-blue-500 text-white hover:bg-blue-600',
]"
@click="$emit('prev')" @click="$emit('prev')"
> >
<svg <UIcon name="i-lucide-chevron-left" class="size-5 md:size-6" />
class="w-5 h-5 md:w-6 md:h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 19l-7-7 7-7"
/>
</svg>
</button> </button>
<div class="text-center flex-1 min-w-0"> <div class="text-center flex-1 min-w-0">
<slot name="interactive-content"> <slot name="interactive-content">
<p <p class="text-base md:text-lg text-guild-200">
:class="[ {{ interactiveContent }}
'text-base md:text-lg',
props.theme === 'guild'
? 'text-guild-200'
: 'text-[--ui-text-muted]',
]"
>
{{
interactiveContent ||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit."
}}
</p> </p>
</slot> </slot>
</div> </div>
<button <button
:class="[ class="p-2 md:p-3 rounded-full transition-all duration-300 flex-shrink-0 bg-candlelight-600/80 text-guild-100 hover:bg-candlelight-500 candlelight-glow"
'p-2 md:p-3 rounded-full transition-all duration-300 flex-shrink-0',
props.theme === 'guild'
? 'bg-candlelight-600/80 text-guild-100 hover:bg-candlelight-500 candlelight-glow'
: 'bg-blue-500 text-white hover:bg-blue-600',
]"
@click="$emit('next')" @click="$emit('next')"
> >
<svg <UIcon name="i-lucide-chevron-right" class="size-5 md:size-6" />
class="w-5 h-5 md:w-6 md:h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</button> </button>
</div> </div>
</div> </div>
<!-- Illustration slot for designer-provided assets -->
<div v-if="$slots.illustration" class="mb-8">
<slot name="illustration" />
</div>
<!-- Call to Action Button --> <!-- Call to Action Button -->
<div v-if="showCta" class="flex justify-center"> <div v-if="showCta" class="flex justify-center">
<UButton <UButton
@ -122,8 +77,6 @@
</template> </template>
<script setup> <script setup>
import { computed } from "vue";
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
@ -131,18 +84,12 @@ const props = defineProps({
}, },
subtitle: { subtitle: {
type: String, type: String,
default: "", default: '',
},
theme: {
type: String,
default: "blue",
validator: (value) =>
["blue", "purple", "emerald", "gray", "guild"].includes(value),
}, },
size: { size: {
type: String, type: String,
default: "large", default: 'large',
validator: (value) => ["small", "medium", "large", "hero"].includes(value), validator: (value) => ['small', 'medium', 'large', 'hero'].includes(value),
}, },
showInteractiveArea: { showInteractiveArea: {
type: Boolean, type: Boolean,
@ -150,7 +97,7 @@ const props = defineProps({
}, },
interactiveContent: { interactiveContent: {
type: String, type: String,
default: "", default: '',
}, },
showCta: { showCta: {
type: Boolean, type: Boolean,
@ -158,55 +105,31 @@ const props = defineProps({
}, },
ctaText: { ctaText: {
type: String, type: String,
default: "Get Started", default: 'Get Started',
}, },
ctaLink: { ctaLink: {
type: String, type: String,
default: "/join", default: '/join',
}, },
ctaSize: { ctaSize: {
type: String, type: String,
default: "lg", default: 'lg',
}, },
ctaColor: { ctaColor: {
type: String, type: String,
default: "primary", default: 'primary',
}, },
}); })
defineEmits(["prev", "next"]); defineEmits(['prev', 'next'])
const backgroundClass = computed(() => {
const themes = {
blue: "bg-gradient-to-br from-blue-50 to-indigo-100",
purple: "bg-gradient-to-br from-purple-50 to-violet-100",
emerald: "bg-gradient-to-br from-emerald-50 to-teal-100",
gray: "bg-neutral-100",
guild:
"bg-gradient-to-br from-guild-900 via-guild-800 to-candlelight-900 halftone-texture",
};
return themes[props.theme] || themes.blue;
});
const titleSizeClass = computed(() => { const titleSizeClass = computed(() => {
const sizes = { const sizes = {
small: "text-2xl md:text-3xl", small: 'text-display-sm',
medium: "text-3xl md:text-4xl", medium: 'text-display',
large: "text-4xl md:text-5xl", large: 'text-display-lg',
hero: "text-5xl md:text-6xl", hero: 'text-display-xl',
}; }
return sizes[props.size] || sizes.large; return sizes[props.size] || sizes.large
}); })
const titleColorClass = computed(() => {
return "text-white";
});
const subtitleColorClass = computed(() => {
return "text-white";
});
const textColorClass = computed(() => {
return "text-white";
});
</script> </script>

View file

@ -17,7 +17,7 @@
> >
<path <path
d="M500 70 150 175.3v217.1C150 785 500 930 500 930s350-145 350-537.6V175.2L500 70Z" d="M500 70 150 175.3v217.1C150 785 500 930 500 930s350-145 350-537.6V175.2L500 70Z"
class="fill-purple-500" class="fill-candlelight-500"
/> />
</svg> </svg>
@ -31,7 +31,7 @@
<!-- Sparkle effect --> <!-- Sparkle effect -->
<div <div
class="absolute top-0 right-1 w-2 h-2 bg-yellow-300 rounded-full animate-pulse" class="absolute top-0 right-1 w-2 h-2 bg-candlelight-300 rounded-full animate-pulse"
></div> ></div>
</div> </div>
</div> </div>
@ -42,11 +42,11 @@
:class="[ :class="[
'inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full border text-xs font-medium transition-all', 'inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full border text-xs font-medium transition-all',
variant === 'default' && variant === 'default' &&
'bg-purple-500/20 text-purple-300 border-purple-500/40 hover:bg-purple-500/30', 'bg-candlelight-900/20 text-candlelight-400 border-candlelight-500/40 hover:bg-candlelight-900/30',
variant === 'subtle' && variant === 'subtle' &&
'bg-purple-500/10 text-purple-400 border-purple-500/20', 'bg-candlelight-900/10 text-candlelight-500 border-candlelight-500/20',
variant === 'solid' && variant === 'solid' &&
'bg-purple-500 text-white border-purple-600 hover:bg-purple-600', 'bg-candlelight-500 text-white border-candlelight-600 hover:bg-candlelight-600',
]" ]"
:title="title" :title="title"
> >
@ -54,8 +54,8 @@
name="heroicons:chat-bubble-left-right" name="heroicons:chat-bubble-left-right"
:class="[ :class="[
'w-3.5 h-3.5', 'w-3.5 h-3.5',
variant === 'default' && 'text-purple-300', variant === 'default' && 'text-candlelight-400',
variant === 'subtle' && 'text-purple-400', variant === 'subtle' && 'text-candlelight-500',
variant === 'solid' && 'text-white', variant === 'solid' && 'text-white',
]" ]"
/> />

View file

@ -1,6 +1,6 @@
<template> <template>
<div class="flex items-center gap-3 text-sm"> <div class="flex items-center gap-3 text-sm">
<span class="text-gray-700 dark:text-guild-400 text-xs font-medium" <span class="text-guild-400 text-xs font-medium"
>{{ label }}:</span >{{ label }}:</span
> >
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
@ -8,8 +8,8 @@
class="text-xs transition-colors" class="text-xs transition-colors"
:class=" :class="
isPrivate isPrivate
? 'text-gray-500 dark:text-guild-500' ? 'text-guild-500'
: 'text-blue-600 dark:text-blue-400 font-semibold' : 'text-candlelight-500 font-semibold'
" "
> >
Members Members
@ -24,8 +24,8 @@
class="text-xs transition-colors" class="text-xs transition-colors"
:class=" :class="
isPrivate isPrivate
? 'text-blue-600 dark:text-blue-400 font-semibold' ? 'text-candlelight-500 font-semibold'
: 'text-gray-500 dark:text-guild-500' : 'text-guild-500'
" "
> >
Private Private
@ -38,19 +38,19 @@
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: String, type: String,
default: "members", default: 'members',
}, },
label: { label: {
type: String, type: String,
default: "Privacy", default: 'Privacy',
}, },
}); })
const emit = defineEmits(["update:modelValue"]); const emit = defineEmits(['update:modelValue'])
const isPrivate = computed(() => props.modelValue === "private"); const isPrivate = computed(() => props.modelValue === 'private')
const togglePrivacy = (value) => { const togglePrivacy = (value) => {
emit("update:modelValue", value ? "private" : "members"); emit('update:modelValue', value ? 'private' : 'members')
}; }
</script> </script>

View file

@ -0,0 +1,61 @@
<template>
<div class="section-header" :class="[spacing]">
<p v-if="overline" class="text-ui-label text-candlelight-500 mb-2">
{{ overline }}
</p>
<component :is="tag" :class="[sizeClass, 'text-guild-100']">
<slot>{{ title }}</slot>
</component>
<p v-if="subtitle" class="mt-3 text-guild-400 text-lg leading-relaxed">
{{ subtitle }}
</p>
<GuildDivider v-if="divider" :variant="divider" compact class="mt-4" />
</div>
</template>
<script setup>
const props = defineProps({
title: {
type: String,
default: '',
},
subtitle: {
type: String,
default: '',
},
overline: {
type: String,
default: '',
},
size: {
type: String,
default: 'md',
validator: (v) => ['xl', 'lg', 'md', 'sm'].includes(v),
},
tag: {
type: String,
default: 'h2',
},
divider: {
type: String,
default: '',
validator: (v) => ['', 'simple', 'woodcut', 'dither', 'dots'].includes(v),
},
compact: {
type: Boolean,
default: false,
},
})
const sizeClass = computed(() => {
const sizes = {
xl: 'text-display-xl',
lg: 'text-display-lg',
md: 'text-display',
sm: 'text-display-sm',
}
return sizes[props.size]
})
const spacing = computed(() => props.compact ? 'mb-4' : 'mb-8')
</script>

View file

@ -11,12 +11,12 @@
<!-- Error State --> <!-- Error State -->
<div <div
v-else-if="error" v-else-if="error"
class="p-6 bg-red-900/20 rounded-xl border border-red-800" class="p-6 bg-ember-900/20 rounded-xl border border-ember-800"
> >
<h3 class="text-lg font-semibold text-red-300 mb-2"> <h3 class="text-lg font-semibold text-ember-300 mb-2">
Unable to Load Series Pass Unable to Load Series Pass
</h3> </h3>
<p class="text-red-400">{{ error }}</p> <p class="text-ember-400">{{ error }}</p>
</div> </div>
<!-- Content --> <!-- Content -->
@ -93,18 +93,18 @@
<!-- Member Benefits Notice --> <!-- Member Benefits Notice -->
<div <div
v-if="passInfo.ticket.isFree && passInfo.memberInfo?.isMember" v-if="passInfo.ticket.isFree && passInfo.memberInfo?.isMember"
class="p-4 bg-green-900/20 border border-green-700/30 rounded-lg" class="p-4 bg-candlelight-900/20 border border-candlelight-700/30 rounded-lg"
> >
<div class="flex items-start gap-3"> <div class="flex items-start gap-3">
<Icon <Icon
name="heroicons:sparkles" name="heroicons:sparkles"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5" class="w-5 h-5 text-candlelight-400 flex-shrink-0 mt-0.5"
/> />
<div> <div>
<div class="font-semibold text-green-300 mb-1"> <div class="font-semibold text-candlelight-300 mb-1">
Member Benefit Member Benefit
</div> </div>
<div class="text-sm text-green-400"> <div class="text-sm text-candlelight-400">
This series pass is free for Ghost Guild members! This series pass is free for Ghost Guild members!
</div> </div>
</div> </div>

View file

@ -0,0 +1,42 @@
<template>
<!-- Hidden SVG filter definitions available to entire app -->
<svg class="absolute w-0 h-0 overflow-hidden" aria-hidden="true">
<defs>
<!-- Fine grain noise - for ink-grain effect -->
<filter id="grain-fine" x="0" y="0" width="100%" height="100%">
<feTurbulence
type="fractalNoise"
baseFrequency="0.65"
numOctaves="3"
stitchTiles="stitch"
result="noise"
/>
<feColorMatrix type="saturate" values="0" in="noise" result="mono" />
</filter>
<!-- Paper fiber texture - for paper-texture effect -->
<filter id="grain-paper" x="0" y="0" width="100%" height="100%">
<feTurbulence
type="fractalNoise"
baseFrequency="0.04"
numOctaves="5"
stitchTiles="stitch"
result="noise"
/>
<feColorMatrix type="saturate" values="0" in="noise" result="mono" />
</filter>
<!-- Coarse grain - for workshop/craft surface textures -->
<filter id="grain-coarse" x="0" y="0" width="100%" height="100%">
<feTurbulence
type="turbulence"
baseFrequency="0.3"
numOctaves="2"
stitchTiles="stitch"
result="noise"
/>
<feColorMatrix type="saturate" values="0" in="noise" result="mono" />
</filter>
</defs>
</svg>
</template>

View file

@ -93,9 +93,9 @@
<!-- Error Message --> <!-- Error Message -->
<div <div
v-if="error" v-if="error"
class="bg-red-500/10 border border-red-500/30 rounded-lg p-4" class="bg-ember-900/20 border border-ember-400/30 rounded-lg p-4"
> >
<p class="text-red-300">{{ error }}</p> <p class="text-ember-400">{{ error }}</p>
</div> </div>
</div> </div>
</template> </template>

View file

@ -1,13 +1,13 @@
<template> <template>
<div class="min-h-screen bg-muted"> <div class="min-h-screen bg-guild-950">
<!-- Admin Navigation --> <!-- Admin Navigation -->
<nav class="bg-elevated border-b border-default shadow-sm"> <nav class="bg-guild-900 border-b border-guild-700 shadow-sm">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center py-4"> <div class="flex justify-between items-center py-4">
<div class="flex items-center gap-8"> <div class="flex items-center gap-8">
<NuxtLink <NuxtLink
to="/" to="/"
class="text-xl font-bold text-highlighted hover:text-primary" class="text-xl font-bold font-serif warm-text text-guild-100 hover:text-candlelight-400"
> >
Ghost Guild Ghost Guild
</NuxtLink> </NuxtLink>
@ -18,8 +18,8 @@
:class="[ :class="[
'px-4 py-2 rounded-lg text-sm font-medium transition-all duration-200', 'px-4 py-2 rounded-lg text-sm font-medium transition-all duration-200',
$route.path === '/admin' $route.path === '/admin'
? 'bg-primary/10 text-primary shadow-sm' ? 'bg-candlelight-900/30 text-candlelight-400 shadow-sm'
: 'text-muted hover:text-primary hover:bg-primary/5', : 'text-guild-400 hover:text-candlelight-400 hover:bg-candlelight-900/10',
]" ]"
> >
<svg <svg
@ -49,8 +49,8 @@
:class="[ :class="[
'px-4 py-2 rounded-lg text-sm font-medium transition-all duration-200', 'px-4 py-2 rounded-lg text-sm font-medium transition-all duration-200',
$route.path.includes('/admin/members') $route.path.includes('/admin/members')
? 'bg-primary/10 text-primary shadow-sm' ? 'bg-candlelight-900/30 text-candlelight-400 shadow-sm'
: 'text-muted hover:text-primary hover:bg-primary/5', : 'text-guild-400 hover:text-candlelight-400 hover:bg-candlelight-900/10',
]" ]"
> >
<svg <svg
@ -74,8 +74,8 @@
:class="[ :class="[
'px-4 py-2 rounded-lg text-sm font-medium transition-all duration-200', 'px-4 py-2 rounded-lg text-sm font-medium transition-all duration-200',
$route.path.includes('/admin/events') $route.path.includes('/admin/events')
? 'bg-primary/10 text-primary shadow-sm' ? 'bg-candlelight-900/30 text-candlelight-400 shadow-sm'
: 'text-muted hover:text-primary hover:bg-primary/5', : 'text-guild-400 hover:text-candlelight-400 hover:bg-candlelight-900/10',
]" ]"
> >
<svg <svg
@ -99,8 +99,8 @@
:class="[ :class="[
'px-4 py-2 rounded-lg text-sm font-medium transition-all duration-200', 'px-4 py-2 rounded-lg text-sm font-medium transition-all duration-200',
$route.path.includes('/admin/series') $route.path.includes('/admin/series')
? 'bg-primary/10 text-primary shadow-sm' ? 'bg-candlelight-900/30 text-candlelight-400 shadow-sm'
: 'text-muted hover:text-primary hover:bg-primary/5', : 'text-guild-400 hover:text-candlelight-400 hover:bg-candlelight-900/10',
]" ]"
> >
<svg <svg
@ -129,10 +129,10 @@
v-click-outside="() => (showUserMenu = false)" v-click-outside="() => (showUserMenu = false)"
> >
<button <button
class="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-muted cursor-pointer transition-colors" class="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-guild-800 cursor-pointer transition-colors"
> >
<div <div
class="w-8 h-8 bg-blue-600 rounded-full flex items-center justify-center" class="w-8 h-8 bg-candlelight-600 rounded-full flex items-center justify-center"
> >
<svg <svg
class="w-4 h-4 text-white" class="w-4 h-4 text-white"
@ -148,11 +148,11 @@
/> />
</svg> </svg>
</div> </div>
<span class="hidden md:block text-sm font-medium text-default" <span class="hidden md:block text-sm font-medium text-guild-100"
>Admin</span >Admin</span
> >
<svg <svg
class="w-4 h-4 text-gray-400" class="w-4 h-4 text-guild-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -169,14 +169,14 @@
<!-- User Menu Dropdown --> <!-- User Menu Dropdown -->
<div <div
v-if="showUserMenu" v-if="showUserMenu"
class="absolute right-0 mt-2 w-56 bg-elevated rounded-lg shadow-lg border border-default py-1 z-50" class="absolute right-0 mt-2 w-56 bg-guild-800 rounded-lg shadow-lg border border-guild-700 py-1 z-50"
> >
<NuxtLink <NuxtLink
to="/" to="/"
class="flex items-center px-4 py-2 text-sm text-default hover:bg-muted" class="flex items-center px-4 py-2 text-sm text-guild-100 hover:bg-guild-700"
> >
<svg <svg
class="w-4 h-4 mr-3 text-gray-400" class="w-4 h-4 mr-3 text-guild-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -198,10 +198,10 @@
</NuxtLink> </NuxtLink>
<NuxtLink <NuxtLink
to="/admin/settings" to="/admin/settings"
class="flex items-center px-4 py-2 text-sm text-default hover:bg-muted" class="flex items-center px-4 py-2 text-sm text-guild-100 hover:bg-guild-700"
> >
<svg <svg
class="w-4 h-4 mr-3 text-gray-400" class="w-4 h-4 mr-3 text-guild-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -221,13 +221,13 @@
</svg> </svg>
Settings Settings
</NuxtLink> </NuxtLink>
<hr class="my-1 border-default" /> <hr class="my-1 border-guild-700" />
<button <button
@click="logout" @click="logout"
class="flex items-center w-full px-4 py-2 text-sm text-red-600 hover:bg-red-50" class="flex items-center w-full px-4 py-2 text-sm text-ember-400 hover:bg-ember-900/20"
> >
<svg <svg
class="w-4 h-4 mr-3 text-red-500" class="w-4 h-4 mr-3 text-ember-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -249,7 +249,7 @@
</nav> </nav>
<!-- Mobile Navigation --> <!-- Mobile Navigation -->
<div class="md:hidden bg-elevated border-b border-default"> <div class="md:hidden bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center gap-2 py-3 overflow-x-auto"> <div class="flex items-center gap-2 py-3 overflow-x-auto">
<NuxtLink <NuxtLink
@ -257,8 +257,8 @@
:class="[ :class="[
'px-3 py-2 rounded-lg text-sm font-medium whitespace-nowrap transition-colors', 'px-3 py-2 rounded-lg text-sm font-medium whitespace-nowrap transition-colors',
$route.path === '/admin' $route.path === '/admin'
? 'bg-primary/10 text-primary' ? 'bg-candlelight-900/30 text-candlelight-400'
: 'text-muted hover:text-primary hover:bg-primary/5', : 'text-guild-400 hover:text-candlelight-400 hover:bg-candlelight-900/10',
]" ]"
> >
Dashboard Dashboard
@ -269,8 +269,8 @@
:class="[ :class="[
'px-3 py-2 rounded-lg text-sm font-medium whitespace-nowrap transition-colors', 'px-3 py-2 rounded-lg text-sm font-medium whitespace-nowrap transition-colors',
$route.path.includes('/admin/members') $route.path.includes('/admin/members')
? 'bg-primary/10 text-primary' ? 'bg-candlelight-900/30 text-candlelight-400'
: 'text-muted hover:text-primary hover:bg-primary/5', : 'text-guild-400 hover:text-candlelight-400 hover:bg-candlelight-900/10',
]" ]"
> >
Members Members
@ -281,8 +281,8 @@
:class="[ :class="[
'px-3 py-2 rounded-lg text-sm font-medium whitespace-nowrap transition-colors', 'px-3 py-2 rounded-lg text-sm font-medium whitespace-nowrap transition-colors',
$route.path.includes('/admin/events') $route.path.includes('/admin/events')
? 'bg-primary/10 text-primary' ? 'bg-candlelight-900/30 text-candlelight-400'
: 'text-muted hover:text-primary hover:bg-primary/5', : 'text-guild-400 hover:text-candlelight-400 hover:bg-candlelight-900/10',
]" ]"
> >
Events Events
@ -293,8 +293,8 @@
:class="[ :class="[
'px-3 py-2 rounded-lg text-sm font-medium whitespace-nowrap transition-colors', 'px-3 py-2 rounded-lg text-sm font-medium whitespace-nowrap transition-colors',
$route.path.includes('/admin/series') $route.path.includes('/admin/series')
? 'bg-primary/10 text-primary' ? 'bg-candlelight-900/30 text-candlelight-400'
: 'text-muted hover:text-primary hover:bg-primary/5', : 'text-guild-400 hover:text-candlelight-400 hover:bg-candlelight-900/10',
]" ]"
> >
Series Series
@ -309,10 +309,10 @@
</main> </main>
<!-- Footer --> <!-- Footer -->
<footer class="bg-elevated border-t border-default mt-auto"> <footer class="bg-guild-900 border-t border-guild-700 mt-auto">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-8 text-center"> <div class="py-8 text-center">
<p class="text-sm text-muted"> <p class="text-sm text-guild-400">
&copy; 2025 Ghost Guild. Admin Panel. &copy; 2025 Ghost Guild. Admin Panel.
</p> </p>
</div> </div>

View file

@ -4,7 +4,7 @@
<div <div
class="absolute inset-x-0 pointer-events-none z-0" class="absolute inset-x-0 pointer-events-none z-0"
style=" style="
background-image: url(&quot;/background-dither.png&quot;); background-image: url(&quot;/background-dither.webp&quot;);
background-size: 100% auto; background-size: 100% auto;
background-position: top center; background-position: top center;
background-repeat: no-repeat; background-repeat: no-repeat;
@ -28,7 +28,7 @@
<div class="flex items-center justify-between p-4"> <div class="flex items-center justify-between p-4">
<NuxtLink <NuxtLink
to="/" to="/"
class="text-lg font-bold text-white warm-text tracking-wider" class="text-display-sm font-bold text-candlelight-400 warm-text tracking-wider"
> >
Ghost Guild Ghost Guild
</NuxtLink> </NuxtLink>

View file

@ -4,7 +4,7 @@
<nav class="w-full px-6 md:px-8 py-4"> <nav class="w-full px-6 md:px-8 py-4">
<div class="max-w-6xl mx-auto flex items-center justify-between"> <div class="max-w-6xl mx-auto flex items-center justify-between">
<!-- Logo/Wordmark --> <!-- Logo/Wordmark -->
<NuxtLink to="/" class="text-xl font-bold text-primary-400 tracking-wide"> <NuxtLink to="/" class="text-display-sm font-bold text-candlelight-400 warm-text tracking-wide">
Ghost Guild Ghost Guild
</NuxtLink> </NuxtLink>

View file

@ -4,7 +4,6 @@
<PageHeader <PageHeader
title="About Ghost Guild" title="About Ghost Guild"
subtitle="" subtitle=""
theme="blue"
size="large" size="large"
/> />
@ -129,7 +128,7 @@
<section class="py-20 bg-[--ui-bg-elevated]"> <section class="py-20 bg-[--ui-bg-elevated]">
<UContainer> <UContainer>
<div class="max-w-3xl"> <div class="max-w-3xl">
<h2 class="text-2xl font-bold text-[--ui-text] mb-4"> <h2 class="text-display-sm font-bold text-[--ui-text] mb-4">
Membership Circles Membership Circles
</h2> </h2>
<p class="text-lg text-[--ui-text-muted] mb-6"> <p class="text-lg text-[--ui-text-muted] mb-6">

View file

@ -4,7 +4,6 @@
<PageHeader <PageHeader
title="About Our Membership Circles" title="About Our Membership Circles"
subtitle="All members of Ghost Guild share the Baby Ghosts mission: Advancing cooperative and worker-centric labour models in the Canadian interactive digital arts sector." subtitle="All members of Ghost Guild share the Baby Ghosts mission: Advancing cooperative and worker-centric labour models in the Canadian interactive digital arts sector."
theme="blue"
size="large" size="large"
/> />
@ -12,7 +11,7 @@
<section class="py-20 bg-[--ui-bg]"> <section class="py-20 bg-[--ui-bg]">
<UContainer> <UContainer>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<h2 class="text-3xl font-bold text-[--ui-text] mb-6"> <h2 class="text-display font-bold text-[--ui-text] mb-6">
How membership works How membership works
</h2> </h2>
@ -43,7 +42,7 @@
<section class="py-20 bg-[--ui-bg-elevated]"> <section class="py-20 bg-[--ui-bg-elevated]">
<UContainer> <UContainer>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<h2 class="text-3xl font-bold text-[--ui-text] mb-4"> <h2 class="text-display font-bold text-[--ui-text] mb-4">
Find your circle Find your circle
</h2> </h2>
<p class="text-lg text-[--ui-text-muted] mb-12"> <p class="text-lg text-[--ui-text-muted] mb-12">
@ -53,8 +52,8 @@
<div class="space-y-12"> <div class="space-y-12">
<!-- Community Circle --> <!-- Community Circle -->
<div class=""> <div class="circle-surface-community rounded-xl p-6">
<h3 class="text-2xl font-bold text-[--ui-text] mb-2"> <h3 class="text-display-sm font-bold text-[--ui-text] mb-2">
Community Circle Community Circle
</h3> </h3>
@ -88,8 +87,8 @@
</div> </div>
<!-- Founder Circle --> <!-- Founder Circle -->
<div class=""> <div class="circle-surface-founder rounded-xl p-6">
<h3 class="text-2xl font-bold text-[--ui-text] mb-2"> <h3 class="text-display-sm font-bold text-[--ui-text] mb-2">
Founder Circle Founder Circle
</h3> </h3>
@ -138,8 +137,8 @@
</div> </div>
<!-- Practitioner Circle --> <!-- Practitioner Circle -->
<div class=""> <div class="circle-surface-practitioner rounded-xl p-6">
<h3 class="text-2xl font-bold text-[--ui-text] mb-2"> <h3 class="text-display-sm font-bold text-[--ui-text] mb-2">
Practitioner Circle Practitioner Circle
</h3> </h3>
@ -178,7 +177,7 @@
<section class="py-20 bg-[--ui-bg]"> <section class="py-20 bg-[--ui-bg]">
<UContainer> <UContainer>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<h2 class="text-3xl font-bold text-[--ui-text] mb-8"> <h2 class="text-display font-bold text-[--ui-text] mb-8">
Important Notes Important Notes
</h2> </h2>

View file

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<div class="bg-elevated border-b border-default"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<h1 class="text-2xl font-bold text-highlighted">Admin Dashboard</h1> <h1 class="text-display font-bold text-guild-100">Admin Dashboard</h1>
<p class="text-muted"> <p class="text-guild-400">
Manage Ghost Guild members, events, and community operations Manage Ghost Guild members, events, and community operations
</p> </p>
</div> </div>
@ -14,19 +14,19 @@
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Quick Stats --> <!-- Quick Stats -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8"> <div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="text-sm text-muted">Total Members</p> <p class="text-sm text-guild-400">Total Members</p>
<p class="text-2xl font-bold text-blue-600"> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">
{{ stats.totalMembers || 0 }} {{ stats.totalMembers || 0 }}
</p> </p>
</div> </div>
<div <div
class="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center" class="w-12 h-12 bg-candlelight-900/20 rounded-xl flex items-center justify-center"
> >
<svg <svg
class="w-6 h-6 text-blue-600" class="w-6 h-6 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -42,19 +42,19 @@
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="text-sm text-muted">Active Events</p> <p class="text-sm text-guild-400">Active Events</p>
<p class="text-2xl font-bold text-green-600"> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">
{{ stats.activeEvents || 0 }} {{ stats.activeEvents || 0 }}
</p> </p>
</div> </div>
<div <div
class="w-12 h-12 bg-green-100 rounded-xl flex items-center justify-center" class="w-12 h-12 bg-candlelight-900/20 rounded-xl flex items-center justify-center"
> >
<svg <svg
class="w-6 h-6 text-green-600" class="w-6 h-6 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -70,19 +70,19 @@
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="text-sm text-muted">Monthly Revenue</p> <p class="text-sm text-guild-400">Monthly Revenue</p>
<p class="text-2xl font-bold text-purple-600"> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">
${{ stats.monthlyRevenue || 0 }} ${{ stats.monthlyRevenue || 0 }}
</p> </p>
</div> </div>
<div <div
class="w-12 h-12 bg-purple-100 rounded-xl flex items-center justify-center" class="w-12 h-12 bg-candlelight-900/20 rounded-xl flex items-center justify-center"
> >
<svg <svg
class="w-6 h-6 text-purple-600" class="w-6 h-6 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -98,19 +98,19 @@
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="text-sm text-muted">Pending Slack Invites</p> <p class="text-sm text-guild-400">Pending Slack Invites</p>
<p class="text-2xl font-bold text-orange-600"> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">
{{ stats.pendingSlackInvites || 0 }} {{ stats.pendingSlackInvites || 0 }}
</p> </p>
</div> </div>
<div <div
class="w-12 h-12 bg-orange-100 rounded-xl flex items-center justify-center" class="w-12 h-12 bg-candlelight-900/20 rounded-xl flex items-center justify-center"
> >
<svg <svg
class="w-6 h-6 text-orange-600" class="w-6 h-6 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -129,13 +129,13 @@
<!-- Quick Actions --> <!-- Quick Actions -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="text-center"> <div class="text-center">
<div <div
class="w-16 h-16 bg-blue-100 rounded-2xl flex items-center justify-center mx-auto mb-4" class="w-16 h-16 bg-candlelight-900/20 rounded-2xl flex items-center justify-center mx-auto mb-4"
> >
<svg <svg
class="w-8 h-8 text-blue-600" class="w-8 h-8 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -148,28 +148,28 @@
></path> ></path>
</svg> </svg>
</div> </div>
<h3 class="text-lg font-semibold text-highlighted mb-2"> <h3 class="text-display-sm font-semibold text-guild-100 mb-2">
Add New Member Add New Member
</h3> </h3>
<p class="text-muted text-sm mb-4"> <p class="text-guild-400 text-sm mb-4">
Add a new member to the Ghost Guild community Add a new member to the Ghost Guild community
</p> </p>
<button <button
@click="navigateTo('/admin/members-working')" @click="navigateTo('/admin/members-working')"
class="w-full bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2" class="w-full bg-candlelight-600 text-white py-2 px-4 rounded-lg hover:bg-candlelight-700 focus:ring-2 focus:ring-candlelight-500 focus:ring-offset-2"
> >
Manage Members Manage Members
</button> </button>
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="text-center"> <div class="text-center">
<div <div
class="w-16 h-16 bg-green-100 rounded-2xl flex items-center justify-center mx-auto mb-4" class="w-16 h-16 bg-candlelight-900/20 rounded-2xl flex items-center justify-center mx-auto mb-4"
> >
<svg <svg
class="w-8 h-8 text-green-600" class="w-8 h-8 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -182,15 +182,15 @@
></path> ></path>
</svg> </svg>
</div> </div>
<h3 class="text-lg font-semibold text-highlighted mb-2"> <h3 class="text-display-sm font-semibold text-guild-100 mb-2">
Create Event Create Event
</h3> </h3>
<p class="text-muted text-sm mb-4"> <p class="text-guild-400 text-sm mb-4">
Schedule a new community event or workshop Schedule a new community event or workshop
</p> </p>
<button <button
@click="navigateTo('/admin/events-working')" @click="navigateTo('/admin/events-working')"
class="w-full bg-green-600 text-white py-2 px-4 rounded-lg hover:bg-green-700 focus:ring-2 focus:ring-green-500 focus:ring-offset-2" class="w-full bg-candlelight-600 text-white py-2 px-4 rounded-lg hover:bg-candlelight-700 focus:ring-2 focus:ring-candlelight-500 focus:ring-offset-2"
> >
Manage Events Manage Events
</button> </button>
@ -200,15 +200,15 @@
<!-- Recent Activity --> <!-- Recent Activity -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6"> <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-elevated rounded-lg shadow"> <div class="bg-guild-900 rounded-lg shadow">
<div class="px-6 py-4 border-b border-default"> <div class="px-6 py-4 border-b border-guild-700">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<h3 class="text-lg font-semibold text-highlighted"> <h3 class="text-display-sm font-semibold text-guild-100">
Recent Members Recent Members
</h3> </h3>
<button <button
@click="navigateTo('/admin/members-working')" @click="navigateTo('/admin/members-working')"
class="text-sm text-primary hover:text-primary" class="text-sm text-candlelight-400 hover:text-candlelight-300"
> >
View All View All
</button> </button>
@ -218,20 +218,20 @@
<div class="p-6"> <div class="p-6">
<div v-if="pending" class="text-center py-4"> <div v-if="pending" class="text-center py-4">
<div <div
class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600 mx-auto" class="animate-spin rounded-full h-6 w-6 border-b-2 border-candlelight-500 mx-auto"
></div> ></div>
</div> </div>
<div v-else-if="recentMembers.length" class="space-y-3"> <div v-else-if="recentMembers.length" class="space-y-3">
<div <div
v-for="member in recentMembers" v-for="member in recentMembers"
:key="member._id" :key="member._id"
class="flex items-center justify-between p-3 rounded-lg border border-default" class="flex items-center justify-between p-3 rounded-lg border border-guild-700"
> >
<div> <div>
<p class="font-medium text-highlighted"> <p class="font-medium text-guild-100">
{{ member.name }} {{ member.name }}
</p> </p>
<p class="text-sm text-muted"> <p class="text-sm text-guild-400">
{{ member.email }} {{ member.email }}
</p> </p>
</div> </div>
@ -242,27 +242,27 @@
> >
{{ member.circle }} {{ member.circle }}
</span> </span>
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500 text-ui-mono">
{{ formatDate(member.createdAt) }} {{ formatDate(member.createdAt) }}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div v-else class="text-center py-6 text-dimmed"> <div v-else class="text-center py-6 text-guild-500">
No recent members No recent members
</div> </div>
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow"> <div class="bg-guild-900 rounded-lg shadow">
<div class="px-6 py-4 border-b border-default"> <div class="px-6 py-4 border-b border-guild-700">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<h3 class="text-lg font-semibold text-highlighted"> <h3 class="text-display-sm font-semibold text-guild-100">
Upcoming Events Upcoming Events
</h3> </h3>
<button <button
@click="navigateTo('/admin/events-working')" @click="navigateTo('/admin/events-working')"
class="text-sm text-primary hover:text-primary" class="text-sm text-candlelight-400 hover:text-candlelight-300"
> >
View All View All
</button> </button>
@ -272,20 +272,20 @@
<div class="p-6"> <div class="p-6">
<div v-if="pending" class="text-center py-4"> <div v-if="pending" class="text-center py-4">
<div <div
class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600 mx-auto" class="animate-spin rounded-full h-6 w-6 border-b-2 border-candlelight-500 mx-auto"
></div> ></div>
</div> </div>
<div v-else-if="upcomingEvents.length" class="space-y-3"> <div v-else-if="upcomingEvents.length" class="space-y-3">
<div <div
v-for="event in upcomingEvents" v-for="event in upcomingEvents"
:key="event._id" :key="event._id"
class="flex items-center justify-between p-3 rounded-lg border border-default" class="flex items-center justify-between p-3 rounded-lg border border-guild-700"
> >
<div> <div>
<p class="font-medium text-highlighted"> <p class="font-medium text-guild-100">
{{ event.title }} {{ event.title }}
</p> </p>
<p class="text-sm text-muted"> <p class="text-sm text-guild-400">
{{ formatDateTime(event.startDate) }} {{ formatDateTime(event.startDate) }}
</p> </p>
</div> </div>
@ -296,13 +296,13 @@
> >
{{ event.eventType }} {{ event.eventType }}
</span> </span>
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
{{ event.location || "Online" }} {{ event.location || "Online" }}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div v-else class="text-center py-6 text-dimmed"> <div v-else class="text-center py-6 text-guild-500">
No upcoming events No upcoming events
</div> </div>
</div> </div>
@ -327,21 +327,21 @@ const upcomingEvents = computed(
const getCircleBadgeClasses = (circle) => { const getCircleBadgeClasses = (circle) => {
const classes = { const classes = {
community: "bg-blue-100 text-blue-800", community: "bg-candlelight-900/20 text-candlelight-400",
founder: "bg-purple-100 text-purple-800", founder: "bg-earth-900/20 text-earth-400",
practitioner: "bg-green-100 text-green-800", practitioner: "bg-candlelight-900/20 text-candlelight-400",
}; };
return classes[circle] || "bg-gray-100 text-gray-800"; return classes[circle] || "bg-guild-800 text-guild-300";
}; };
const getEventTypeBadgeClasses = (type) => { const getEventTypeBadgeClasses = (type) => {
const classes = { const classes = {
community: "bg-blue-100 text-blue-800", community: "bg-candlelight-900/20 text-candlelight-400",
workshop: "bg-green-100 text-green-800", workshop: "bg-candlelight-900/20 text-candlelight-400",
social: "bg-purple-100 text-purple-800", social: "bg-earth-900/20 text-earth-400",
showcase: "bg-orange-100 text-orange-800", showcase: "bg-ember-900/20 text-ember-400",
}; };
return classes[type] || "bg-gray-100 text-gray-800"; return classes[type] || "bg-guild-800 text-guild-300";
}; };
const formatDate = (dateString) => { const formatDate = (dateString) => {

View file

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<div class="bg-elevated border-b"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<h1 class="text-2xl font-bold text-highlighted">Event Management</h1> <h1 class="text-display font-bold text-guild-100">Event Management</h1>
<p class="text-muted"> <p class="text-guild-400">
Create, manage, and monitor Ghost Guild events and workshops Create, manage, and monitor Ghost Guild events and workshops
</p> </p>
</div> </div>
@ -44,73 +44,73 @@
</div> </div>
<button <button
@click="showCreateModal = true" @click="showCreateModal = true"
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2" class="bg-candlelight-600 text-white px-4 py-2 rounded-lg hover:bg-candlelight-700 focus:ring-2 focus:ring-candlelight-500 focus:ring-offset-2"
> >
Create Event Create Event
</button> </button>
</div> </div>
<!-- Events Table --> <!-- Events Table -->
<div class="bg-elevated rounded-lg shadow overflow-hidden"> <div class="bg-guild-900 rounded-lg shadow overflow-hidden">
<div v-if="pending" class="p-8 text-center"> <div v-if="pending" class="p-8 text-center">
<div class="inline-flex items-center"> <div class="inline-flex items-center">
<div <div
class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600 mr-3" class="animate-spin rounded-full h-6 w-6 border-b-2 border-candlelight-500 mr-3"
></div> ></div>
Loading events... Loading events...
</div> </div>
</div> </div>
<div v-else-if="error" class="p-8 text-center text-red-600"> <div v-else-if="error" class="p-8 text-center text-ember-400">
Error loading events: {{ error }} Error loading events: {{ error }}
</div> </div>
<table v-else class="w-full"> <table v-else class="w-full">
<thead class="bg-muted"> <thead class="bg-guild-950">
<tr> <tr>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Title Title
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Type Type
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Start Date Start Date
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Status Status
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Registration Registration
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Actions Actions
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody class="bg-elevated divide-y divide-default"> <tbody class="bg-guild-900 divide-y divide-guild-700">
<tr <tr
v-for="event in filteredEvents" v-for="event in filteredEvents"
:key="event._id" :key="event._id"
class="hover:bg-muted" class="hover:bg-guild-800"
> >
<td class="px-6 py-4"> <td class="px-6 py-4">
<div class="text-sm font-medium text-highlighted"> <div class="text-sm font-medium text-guild-100">
{{ event.title }} {{ event.title }}
</div> </div>
<div class="text-sm text-dimmed"> <div class="text-sm text-guild-500">
{{ event.description.substring(0, 100) }}... {{ event.description.substring(0, 100) }}...
</div> </div>
</td> </td>
@ -122,7 +122,7 @@
{{ event.eventType }} {{ event.eventType }}
</span> </span>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-muted"> <td class="px-6 py-4 whitespace-nowrap text-sm text-guild-400">
{{ formatDateTime(event.startDate) }} {{ formatDateTime(event.startDate) }}
</td> </td>
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
@ -137,31 +137,31 @@
<span <span
:class=" :class="
event.registrationRequired event.registrationRequired
? 'bg-blue-100 text-blue-800' ? 'bg-candlelight-900/20 text-candlelight-400'
: 'bg-accented text-default' : 'bg-guild-800 text-guild-300'
" "
class="inline-flex px-2 py-1 text-xs font-semibold rounded-full" class="inline-flex px-2 py-1 text-xs font-semibold rounded-full"
> >
{{ event.registrationRequired ? "Required" : "Open" }} {{ event.registrationRequired ? "Required" : "Open" }}
</span> </span>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-default"> <td class="px-6 py-4 whitespace-nowrap text-sm text-guild-100">
<div class="flex gap-2"> <div class="flex gap-2">
<button <button
@click="editEvent(event)" @click="editEvent(event)"
class="text-primary hover:text-primary" class="text-candlelight-400 hover:text-candlelight-300"
> >
Edit Edit
</button> </button>
<button <button
@click="duplicateEvent(event)" @click="duplicateEvent(event)"
class="text-primary hover:text-primary" class="text-candlelight-400 hover:text-candlelight-300"
> >
Duplicate Duplicate
</button> </button>
<button <button
@click="deleteEvent(event)" @click="deleteEvent(event)"
class="text-red-600 hover:text-red-900" class="text-ember-400 hover:text-ember-300"
> >
Delete Delete
</button> </button>
@ -173,7 +173,7 @@
<div <div
v-if="!pending && !error && filteredEvents.length === 0" v-if="!pending && !error && filteredEvents.length === 0"
class="p-8 text-center text-dimmed" class="p-8 text-center text-guild-500"
> >
No events found matching your criteria No events found matching your criteria
</div> </div>
@ -185,9 +185,9 @@
v-if="showCreateModal" v-if="showCreateModal"
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 overflow-y-auto" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 overflow-y-auto"
> >
<div class="bg-elevated rounded-lg shadow-xl max-w-2xl w-full mx-4 my-8"> <div class="bg-guild-900 rounded-lg shadow-xl max-w-2xl w-full mx-4 my-8">
<div class="px-6 py-4 border-b"> <div class="px-6 py-4 border-b border-guild-700">
<h3 class="text-lg font-semibold"> <h3 class="text-display-sm font-semibold text-guild-100">
{{ editingEvent ? "Edit Event" : "Create New Event" }} {{ editingEvent ? "Edit Event" : "Create New Event" }}
</h3> </h3>
</div> </div>
@ -195,7 +195,7 @@
<form @submit.prevent="saveEvent" class="p-6 space-y-4"> <form @submit.prevent="saveEvent" class="p-6 space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="md:col-span-2"> <div class="md:col-span-2">
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Event Title</label >Event Title</label
> >
<UInput <UInput
@ -207,7 +207,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Event Type</label >Event Type</label
> >
<USelect <USelect
@ -223,7 +223,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Location</label >Location</label
> >
<UInput <UInput
@ -234,7 +234,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Start Date & Time</label >Start Date & Time</label
> >
<UInput <UInput
@ -246,7 +246,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>End Date & Time</label >End Date & Time</label
> >
<UInput <UInput
@ -258,7 +258,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Max Attendees</label >Max Attendees</label
> >
<UInput <UInput
@ -270,7 +270,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Registration Deadline</label >Registration Deadline</label
> >
<UInput <UInput
@ -283,7 +283,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Description</label >Description</label
> >
<UTextarea <UTextarea
@ -296,7 +296,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Additional Content</label >Additional Content</label
> >
<UTextarea <UTextarea
@ -312,17 +312,17 @@
<input <input
v-model="eventForm.isOnline" v-model="eventForm.isOnline"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500"
/> />
<span class="ml-2 text-sm text-default">Online Event</span> <span class="ml-2 text-sm text-guild-100">Online Event</span>
</label> </label>
<label class="flex items-center"> <label class="flex items-center">
<input <input
v-model="eventForm.registrationRequired" v-model="eventForm.registrationRequired"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500"
/> />
<span class="ml-2 text-sm text-default" <span class="ml-2 text-sm text-guild-100"
>Registration Required</span >Registration Required</span
> >
</label> </label>
@ -332,14 +332,14 @@
<button <button
type="button" type="button"
@click="cancelEdit" @click="cancelEdit"
class="px-4 py-2 text-muted hover:text-highlighted" class="px-4 py-2 text-guild-400 hover:text-guild-100 font-medium"
> >
Cancel Cancel
</button> </button>
<button <button
type="submit" type="submit"
:disabled="creating" :disabled="creating"
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed" class="bg-candlelight-600 text-white px-4 py-2 rounded-lg hover:bg-candlelight-700 disabled:opacity-50 disabled:cursor-not-allowed"
> >
{{ {{
creating creating
@ -411,12 +411,12 @@ const filteredEvents = computed(() => {
const getEventTypeClasses = (type) => { const getEventTypeClasses = (type) => {
const classes = { const classes = {
community: "bg-blue-100 text-blue-800", community: "bg-candlelight-900/20 text-candlelight-400",
workshop: "bg-green-100 text-green-800", workshop: "bg-candlelight-900/20 text-candlelight-400",
social: "bg-purple-100 text-purple-800", social: "bg-earth-900/20 text-earth-400",
showcase: "bg-orange-100 text-orange-800", showcase: "bg-ember-900/20 text-ember-400",
}; };
return classes[type] || "bg-gray-100 text-gray-800"; return classes[type] || "bg-guild-800 text-guild-300";
}; };
const getEventStatus = (event) => { const getEventStatus = (event) => {
@ -432,11 +432,11 @@ const getEventStatus = (event) => {
const getStatusClasses = (event) => { const getStatusClasses = (event) => {
const status = getEventStatus(event); const status = getEventStatus(event);
const classes = { const classes = {
Upcoming: "bg-blue-100 text-blue-800", Upcoming: "bg-candlelight-900/20 text-candlelight-400",
Ongoing: "bg-green-100 text-green-800", Ongoing: "bg-candlelight-900/20 text-candlelight-400",
Past: "bg-gray-100 text-gray-800", Past: "bg-guild-800 text-guild-300",
}; };
return classes[status] || "bg-gray-100 text-gray-800"; return classes[status] || "bg-guild-800 text-guild-300";
}; };
const formatDateTime = (dateString) => { const formatDateTime = (dateString) => {

View file

@ -1,17 +1,17 @@
<template> <template>
<div> <div>
<div class="bg-elevated border-b"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<div class="flex items-center gap-4 mb-2"> <div class="flex items-center gap-4 mb-2">
<NuxtLink to="/admin/events" class="text-dimmed hover:text-default"> <NuxtLink to="/admin/events" class="text-guild-500 hover:text-guild-100">
<Icon name="heroicons:arrow-left" class="w-5 h-5" /> <Icon name="heroicons:arrow-left" class="w-5 h-5" />
</NuxtLink> </NuxtLink>
<h1 class="text-2xl font-bold text-highlighted"> <h1 class="text-display font-bold text-guild-100">
{{ editingEvent ? "Edit Event" : "Create New Event" }} {{ editingEvent ? "Edit Event" : "Create New Event" }}
</h1> </h1>
</div> </div>
<p class="text-muted"> <p class="text-guild-400">
Fill out the form below to create or update an event Fill out the form below to create or update an event
</p> </p>
</div> </div>
@ -22,18 +22,18 @@
<!-- Error Summary --> <!-- Error Summary -->
<div <div
v-if="formErrors.length > 0" v-if="formErrors.length > 0"
class="mb-6 p-4 bg-red-50 border border-red-200 rounded-lg" class="mb-6 p-4 bg-ember-900/20 border border-ember-800 rounded-lg"
> >
<div class="flex"> <div class="flex">
<Icon <Icon
name="heroicons:exclamation-circle" name="heroicons:exclamation-circle"
class="w-5 h-5 text-red-500 mr-3 mt-0.5" class="w-5 h-5 text-ember-400 mr-3 mt-0.5"
/> />
<div> <div>
<h3 class="text-sm font-medium text-red-800 mb-2"> <h3 class="text-sm font-medium text-ember-400 mb-2">
Please fix the following errors: Please fix the following errors:
</h3> </h3>
<ul class="text-sm text-red-700 space-y-1"> <ul class="text-sm text-ember-400 space-y-1">
<li v-for="error in formErrors" :key="error"> {{ error }}</li> <li v-for="error in formErrors" :key="error"> {{ error }}</li>
</ul> </ul>
</div> </div>
@ -43,15 +43,15 @@
<!-- Success Message --> <!-- Success Message -->
<div <div
v-if="showSuccessMessage" v-if="showSuccessMessage"
class="mb-6 p-4 bg-green-50 border border-green-200 rounded-lg" class="mb-6 p-4 bg-candlelight-900/20 border border-candlelight-800 rounded-lg"
> >
<div class="flex"> <div class="flex">
<Icon <Icon
name="heroicons:check-circle" name="heroicons:check-circle"
class="w-5 h-5 text-green-500 mr-3 mt-0.5" class="w-5 h-5 text-candlelight-400 mr-3 mt-0.5"
/> />
<div> <div>
<h3 class="text-sm font-medium text-green-800"> <h3 class="text-sm font-medium text-candlelight-400">
{{ {{
editingEvent editingEvent
? "Event updated successfully!" ? "Event updated successfully!"
@ -65,14 +65,14 @@
<form @submit.prevent="saveEvent"> <form @submit.prevent="saveEvent">
<!-- Basic Information --> <!-- Basic Information -->
<div class="mb-8"> <div class="mb-8">
<h2 class="text-lg font-semibold text-highlighted mb-4"> <h2 class="text-lg font-semibold text-guild-100 mb-4">
Basic Information Basic Information
</h2> </h2>
<div class="grid grid-cols-1 gap-6"> <div class="grid grid-cols-1 gap-6">
<div> <div>
<label class="block text-sm font-medium text-default mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Event Title <span class="text-red-500">*</span> Event Title <span class="text-ember-400">*</span>
</label> </label>
<UInput <UInput
v-model="eventForm.title" v-model="eventForm.title"
@ -81,25 +81,25 @@
:color="fieldErrors.title ? 'error' : undefined" :color="fieldErrors.title ? 'error' : undefined"
class="w-full" class="w-full"
/> />
<p v-if="fieldErrors.title" class="mt-1 text-sm text-red-600"> <p v-if="fieldErrors.title" class="mt-1 text-sm text-ember-400">
{{ fieldErrors.title }} {{ fieldErrors.title }}
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Feature Image</label >Feature Image</label
> >
<ImageUpload v-model="eventForm.featureImage" /> <ImageUpload v-model="eventForm.featureImage" />
<p class="mt-1 text-sm text-dimmed"> <p class="mt-1 text-sm text-guild-500">
Upload a high-quality image (1200x630px recommended) to Upload a high-quality image (1200x630px recommended) to
represent your event represent your event
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Event Description <span class="text-red-500">*</span> Event Description <span class="text-ember-400">*</span>
</label> </label>
<UTextarea <UTextarea
v-model="eventForm.description" v-model="eventForm.description"
@ -111,17 +111,17 @@
/> />
<p <p
v-if="fieldErrors.description" v-if="fieldErrors.description"
class="mt-1 text-sm text-red-600" class="mt-1 text-sm text-ember-400"
> >
{{ fieldErrors.description }} {{ fieldErrors.description }}
</p> </p>
<p class="mt-1 text-sm text-dimmed"> <p class="mt-1 text-sm text-guild-500">
This will be displayed on the event listing and detail pages This will be displayed on the event listing and detail pages
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Additional Content</label >Additional Content</label
> >
<UTextarea <UTextarea
@ -130,7 +130,7 @@
:rows="6" :rows="6"
class="w-full" class="w-full"
/> />
<p class="mt-1 text-sm text-dimmed"> <p class="mt-1 text-sm text-guild-500">
Optional: Provide additional context, agenda items, or detailed Optional: Provide additional context, agenda items, or detailed
requirements requirements
</p> </p>
@ -140,14 +140,14 @@
<!-- Event Details --> <!-- Event Details -->
<div class="mb-8"> <div class="mb-8">
<h2 class="text-lg font-semibold text-highlighted mb-4"> <h2 class="text-lg font-semibold text-guild-100 mb-4">
Event Details Event Details
</h2> </h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div> <div>
<label class="block text-sm font-medium text-default mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Event Type <span class="text-red-500">*</span> Event Type <span class="text-ember-400">*</span>
</label> </label>
<USelect <USelect
v-model="eventForm.eventType" v-model="eventForm.eventType"
@ -159,14 +159,14 @@
]" ]"
class="w-full" class="w-full"
/> />
<p class="mt-1 text-sm text-dimmed"> <p class="mt-1 text-sm text-guild-500">
Choose the category that best describes your event Choose the category that best describes your event
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Location <span class="text-red-500">*</span> Location <span class="text-ember-400">*</span>
</label> </label>
<UInput <UInput
v-model="eventForm.location" v-model="eventForm.location"
@ -175,50 +175,50 @@
:color="fieldErrors.location ? 'error' : undefined" :color="fieldErrors.location ? 'error' : undefined"
class="w-full" class="w-full"
/> />
<p v-if="fieldErrors.location" class="mt-1 text-sm text-red-600"> <p v-if="fieldErrors.location" class="mt-1 text-sm text-ember-400">
{{ fieldErrors.location }} {{ fieldErrors.location }}
</p> </p>
<p class="mt-1 text-sm text-dimmed"> <p class="mt-1 text-sm text-guild-500">
Enter a video conference link or Slack channel (starting with #) Enter a video conference link or Slack channel (starting with #)
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Start Date & Time <span class="text-red-500">*</span> Start Date & Time <span class="text-ember-400">*</span>
</label> </label>
<NaturalDateInput <NaturalDateInput
v-model="eventForm.startDate" v-model="eventForm.startDate"
placeholder="e.g., 'tomorrow at 3pm', 'next Friday at 9am'" placeholder="e.g., 'tomorrow at 3pm', 'next Friday at 9am'"
:required="true" :required="true"
:input-class="{ :input-class="{
'border-red-300 focus:ring-red-500': fieldErrors.startDate, 'border-ember-700 focus:ring-ember-500': fieldErrors.startDate,
}" }"
/> />
<p v-if="fieldErrors.startDate" class="mt-1 text-sm text-red-600"> <p v-if="fieldErrors.startDate" class="mt-1 text-sm text-ember-400">
{{ fieldErrors.startDate }} {{ fieldErrors.startDate }}
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
End Date & Time <span class="text-red-500">*</span> End Date & Time <span class="text-ember-400">*</span>
</label> </label>
<NaturalDateInput <NaturalDateInput
v-model="eventForm.endDate" v-model="eventForm.endDate"
placeholder="e.g., 'tomorrow at 5pm', 'next Friday at 11am'" placeholder="e.g., 'tomorrow at 5pm', 'next Friday at 11am'"
:required="true" :required="true"
:input-class="{ :input-class="{
'border-red-300 focus:ring-red-500': fieldErrors.endDate, 'border-ember-700 focus:ring-ember-500': fieldErrors.endDate,
}" }"
/> />
<p v-if="fieldErrors.endDate" class="mt-1 text-sm text-red-600"> <p v-if="fieldErrors.endDate" class="mt-1 text-sm text-ember-400">
{{ fieldErrors.endDate }} {{ fieldErrors.endDate }}
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Max Attendees</label >Max Attendees</label
> >
<UInput <UInput
@ -228,20 +228,20 @@
placeholder="Leave blank for unlimited" placeholder="Leave blank for unlimited"
class="w-full" class="w-full"
/> />
<p class="mt-1 text-sm text-dimmed"> <p class="mt-1 text-sm text-guild-500">
Set a maximum number of attendees (optional) Set a maximum number of attendees (optional)
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Registration Deadline</label >Registration Deadline</label
> >
<NaturalDateInput <NaturalDateInput
v-model="eventForm.registrationDeadline" v-model="eventForm.registrationDeadline"
placeholder="e.g., 'tomorrow at noon', '1 hour before event'" placeholder="e.g., 'tomorrow at noon', '1 hour before event'"
/> />
<p class="mt-1 text-sm text-dimmed"> <p class="mt-1 text-sm text-guild-500">
When should registration close? (optional) When should registration close? (optional)
</p> </p>
</div> </div>
@ -250,12 +250,12 @@
<!-- Target Audience --> <!-- Target Audience -->
<div class="mb-8"> <div class="mb-8">
<h2 class="text-lg font-semibold text-highlighted mb-4"> <h2 class="text-lg font-semibold text-guild-100 mb-4">
Target Audience Target Audience
</h2> </h2>
<div> <div>
<label class="block text-sm font-medium text-default mb-3" <label class="block text-sm font-medium text-guild-100 mb-3"
>Target Circles</label >Target Circles</label
> >
<div class="space-y-3"> <div class="space-y-3">
@ -264,13 +264,13 @@
v-model="eventForm.targetCircles" v-model="eventForm.targetCircles"
value="community" value="community"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Community Circle</span >Community Circle</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
New members and those exploring the community New members and those exploring the community
</p> </p>
</div> </div>
@ -280,13 +280,13 @@
v-model="eventForm.targetCircles" v-model="eventForm.targetCircles"
value="founder" value="founder"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Founder Circle</span >Founder Circle</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Entrepreneurs and business leaders Entrepreneurs and business leaders
</p> </p>
</div> </div>
@ -296,19 +296,19 @@
v-model="eventForm.targetCircles" v-model="eventForm.targetCircles"
value="practitioner" value="practitioner"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Practitioner Circle</span >Practitioner Circle</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Experts and professionals sharing knowledge Experts and professionals sharing knowledge
</p> </p>
</div> </div>
</label> </label>
</div> </div>
<p class="mt-2 text-sm text-dimmed"> <p class="mt-2 text-sm text-guild-500">
Select which circles this event is most relevant for (leave blank Select which circles this event is most relevant for (leave blank
for all circles) for all circles)
</p> </p>
@ -317,20 +317,20 @@
<!-- Ticketing --> <!-- Ticketing -->
<div class="mb-8"> <div class="mb-8">
<h2 class="text-lg font-semibold text-highlighted mb-4">Ticketing</h2> <h2 class="text-lg font-semibold text-guild-100 mb-4">Ticketing</h2>
<div class="space-y-6"> <div class="space-y-6">
<label class="flex items-start"> <label class="flex items-start">
<input <input
v-model="eventForm.tickets.enabled" v-model="eventForm.tickets.enabled"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Enable Ticketing</span >Enable Ticketing</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Allow ticket sales for this event Allow ticket sales for this event
</p> </p>
</div> </div>
@ -338,19 +338,19 @@
<div <div
v-if="eventForm.tickets.enabled" v-if="eventForm.tickets.enabled"
class="ml-6 space-y-4 p-4 bg-muted rounded-lg" class="ml-6 space-y-4 p-4 bg-guild-950 rounded-lg"
> >
<label class="flex items-start"> <label class="flex items-start">
<input <input
v-model="eventForm.tickets.public.available" v-model="eventForm.tickets.public.available"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Public Tickets Available</span >Public Tickets Available</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Allow non-members to purchase tickets Allow non-members to purchase tickets
</p> </p>
</div> </div>
@ -359,7 +359,7 @@
<div v-if="eventForm.tickets.public.available" class="space-y-4"> <div v-if="eventForm.tickets.public.available" class="space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Ticket Name</label >Ticket Name</label
> >
<UInput <UInput
@ -370,7 +370,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Price (CAD)</label >Price (CAD)</label
> >
<UInput <UInput
@ -381,14 +381,14 @@
placeholder="0.00" placeholder="0.00"
class="w-full" class="w-full"
/> />
<p class="mt-1 text-xs text-dimmed"> <p class="mt-1 text-xs text-guild-500">
Set to 0 for free public events Set to 0 for free public events
</p> </p>
</div> </div>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Ticket Description</label >Ticket Description</label
> >
<UTextarea <UTextarea
@ -401,7 +401,7 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Quantity Available</label >Quantity Available</label
> >
<UInput <UInput
@ -414,7 +414,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Early Bird Price (Optional)</label >Early Bird Price (Optional)</label
> >
<UInput <UInput
@ -429,7 +429,7 @@
</div> </div>
<div v-if="eventForm.tickets.public.earlyBirdPrice > 0"> <div v-if="eventForm.tickets.public.earlyBirdPrice > 0">
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Early Bird Deadline</label >Early Bird Deadline</label
> >
<div class="md:w-1/2"> <div class="md:w-1/2">
@ -438,15 +438,15 @@
placeholder="e.g., '1 week before event', 'next Monday'" placeholder="e.g., '1 week before event', 'next Monday'"
/> />
</div> </div>
<p class="mt-1 text-xs text-dimmed"> <p class="mt-1 text-xs text-guild-500">
Price increases to regular price after this date Price increases to regular price after this date
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div class="p-3 bg-blue-50 rounded-lg"> <div class="p-3 bg-candlelight-900/20 rounded-lg">
<p class="text-sm text-blue-700"> <p class="text-sm text-candlelight-400">
<strong>Note:</strong> Members always get free access to all <strong>Note:</strong> Members always get free access to all
events regardless of ticket settings. events regardless of ticket settings.
</p> </p>
@ -456,7 +456,7 @@
<!-- Series Management --> <!-- Series Management -->
<div class="mb-8"> <div class="mb-8">
<h2 class="text-lg font-semibold text-highlighted mb-4"> <h2 class="text-lg font-semibold text-guild-100 mb-4">
Series Management Series Management
</h2> </h2>
@ -465,13 +465,13 @@
<input <input
v-model="eventForm.series.isSeriesEvent" v-model="eventForm.series.isSeriesEvent"
type="checkbox" type="checkbox"
class="rounded border-default text-purple-600 focus:ring-purple-500 mt-1" class="rounded border-guild-700 text-earth-500 focus:ring-earth-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Part of Event Series</span >Part of Event Series</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
This event is part of a multi-event series This event is part of a multi-event series
</p> </p>
</div> </div>
@ -479,11 +479,11 @@
<div <div
v-if="eventForm.series.isSeriesEvent" v-if="eventForm.series.isSeriesEvent"
class="ml-6 space-y-4 p-4 bg-purple-500/10 rounded-lg border border-purple-500/20" class="ml-6 space-y-4 p-4 bg-earth-900/20 rounded-lg border border-earth-800"
> >
<div> <div>
<label class="block text-sm font-medium text-default mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Select Series <span class="text-red-500">*</span> Select Series <span class="text-ember-400">*</span>
</label> </label>
<div class="flex gap-2"> <div class="flex gap-2">
<USelect <USelect
@ -501,12 +501,12 @@
/> />
<NuxtLink <NuxtLink
to="/admin/series/create" to="/admin/series/create"
class="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 text-sm font-medium whitespace-nowrap" class="px-4 py-2 bg-earth-600 text-white rounded-lg hover:bg-earth-700 text-sm font-medium whitespace-nowrap"
> >
New Series New Series
</NuxtLink> </NuxtLink>
</div> </div>
<p class="text-xs text-dimmed mt-1"> <p class="text-xs text-guild-500 mt-1">
Select an existing series or create a new one Select an existing series or create a new one
</p> </p>
</div> </div>
@ -516,18 +516,18 @@
class="space-y-4" class="space-y-4"
> >
<div> <div>
<label class="block text-sm font-medium text-default mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Series Title <span class="text-red-500">*</span> Series Title <span class="text-ember-400">*</span>
</label> </label>
<UInput <UInput
v-model="eventForm.series.title" v-model="eventForm.series.title"
placeholder="e.g., Cooperative Game Development Fundamentals" placeholder="e.g., Cooperative Game Development Fundamentals"
required required
:readonly="selectedSeriesId" :readonly="selectedSeriesId"
:class="{ 'bg-accented': selectedSeriesId }" :class="{ 'bg-guild-800': selectedSeriesId }"
class="w-full" class="w-full"
/> />
<p class="text-xs text-dimmed mt-1"> <p class="text-xs text-guild-500 mt-1">
{{ {{
selectedSeriesId selectedSeriesId
? "From selected series" ? "From selected series"
@ -537,8 +537,8 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Series Description <span class="text-red-500">*</span> Series Description <span class="text-ember-400">*</span>
</label> </label>
<UTextarea <UTextarea
v-model="eventForm.series.description" v-model="eventForm.series.description"
@ -546,10 +546,10 @@
required required
:rows="3" :rows="3"
:readonly="selectedSeriesId" :readonly="selectedSeriesId"
:class="{ 'bg-accented': selectedSeriesId }" :class="{ 'bg-guild-800': selectedSeriesId }"
class="w-full" class="w-full"
/> />
<p class="text-xs text-dimmed mt-1"> <p class="text-xs text-guild-500 mt-1">
{{ {{
selectedSeriesId selectedSeriesId
? "From selected series" ? "From selected series"
@ -560,9 +560,9 @@
<div <div
v-if="selectedSeriesId" v-if="selectedSeriesId"
class="p-3 bg-blue-500/10 rounded-lg border border-blue-500/20" class="p-3 bg-candlelight-900/20 rounded-lg border border-candlelight-800"
> >
<p class="text-sm text-blue-600 dark:text-blue-400"> <p class="text-sm text-candlelight-400">
<strong>Note:</strong> This event will be added to the <strong>Note:</strong> This event will be added to the
existing "{{ eventForm.series.title }}" series. existing "{{ eventForm.series.title }}" series.
</p> </p>
@ -574,7 +574,7 @@
<!-- Event Agenda --> <!-- Event Agenda -->
<div class="mb-8"> <div class="mb-8">
<h2 class="text-lg font-semibold text-highlighted mb-4"> <h2 class="text-lg font-semibold text-guild-100 mb-4">
Event Agenda Event Agenda
</h2> </h2>
@ -592,7 +592,7 @@
<button <button
type="button" type="button"
@click="removeAgendaItem(index)" @click="removeAgendaItem(index)"
class="px-3 py-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors" class="px-3 py-2 text-ember-400 hover:bg-ember-900/20 rounded-lg transition-colors"
> >
<Icon name="heroicons:trash" class="w-5 h-5" /> <Icon name="heroicons:trash" class="w-5 h-5" />
</button> </button>
@ -601,14 +601,14 @@
<button <button
type="button" type="button"
@click="addAgendaItem" @click="addAgendaItem"
class="flex items-center gap-2 px-4 py-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors font-medium" class="flex items-center gap-2 px-4 py-2 text-candlelight-400 hover:bg-candlelight-900/20 rounded-lg transition-colors font-medium"
> >
<Icon name="heroicons:plus" class="w-5 h-5" /> <Icon name="heroicons:plus" class="w-5 h-5" />
Add Agenda Item Add Agenda Item
</button> </button>
</div> </div>
<p class="mt-2 text-sm text-dimmed"> <p class="mt-2 text-sm text-guild-500">
Add agenda items to help attendees know what to expect during the Add agenda items to help attendees know what to expect during the
event event
</p> </p>
@ -616,7 +616,7 @@
<!-- Event Settings --> <!-- Event Settings -->
<div class="mb-8"> <div class="mb-8">
<h2 class="text-lg font-semibold text-highlighted mb-4"> <h2 class="text-lg font-semibold text-guild-100 mb-4">
Event Settings Event Settings
</h2> </h2>
@ -626,13 +626,13 @@
<input <input
v-model="eventForm.isOnline" v-model="eventForm.isOnline"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Online Event</span >Online Event</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Event will be conducted virtually Event will be conducted virtually
</p> </p>
</div> </div>
@ -642,13 +642,13 @@
<input <input
v-model="eventForm.registrationRequired" v-model="eventForm.registrationRequired"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Registration Required</span >Registration Required</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Attendees must register before attending Attendees must register before attending
</p> </p>
</div> </div>
@ -660,13 +660,13 @@
<input <input
v-model="eventForm.isVisible" v-model="eventForm.isVisible"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Visible on Public Calendar</span >Visible on Public Calendar</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Event will appear on the public events page Event will appear on the public events page
</p> </p>
</div> </div>
@ -676,13 +676,13 @@
<input <input
v-model="eventForm.isCancelled" v-model="eventForm.isCancelled"
type="checkbox" type="checkbox"
class="rounded border-default text-red-600 focus:ring-red-500 mt-1" class="rounded border-guild-700 text-ember-500 focus:ring-ember-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Event Cancelled</span >Event Cancelled</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Mark this event as cancelled Mark this event as cancelled
</p> </p>
</div> </div>
@ -693,7 +693,7 @@
<!-- Cancellation Message (conditional) --> <!-- Cancellation Message (conditional) -->
<div v-if="eventForm.isCancelled" class="mb-8"> <div v-if="eventForm.isCancelled" class="mb-8">
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Cancellation Message</label >Cancellation Message</label
> >
<UTextarea <UTextarea
@ -703,18 +703,18 @@
color="error" color="error"
class="w-full" class="w-full"
/> />
<p class="text-xs text-dimmed mt-1"> <p class="text-xs text-guild-500 mt-1">
This message will be displayed to users viewing the event page This message will be displayed to users viewing the event page
</p> </p>
</div> </div>
<!-- Form Actions --> <!-- Form Actions -->
<div <div
class="flex justify-between items-center pt-6 border-t border-default" class="flex justify-between items-center pt-6 border-t border-guild-700"
> >
<NuxtLink <NuxtLink
to="/admin/events" to="/admin/events"
class="px-4 py-2 text-muted hover:text-highlighted font-medium" class="px-4 py-2 text-guild-400 hover:text-guild-100 font-medium"
> >
Cancel Cancel
</NuxtLink> </NuxtLink>
@ -725,7 +725,7 @@
type="button" type="button"
@click="saveAndCreateAnother" @click="saveAndCreateAnother"
:disabled="creating" :disabled="creating"
class="px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium" class="px-4 py-2 bg-guild-600 text-white rounded-lg hover:bg-guild-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium"
> >
{{ creating ? "Saving..." : "Save & Create Another" }} {{ creating ? "Saving..." : "Save & Create Another" }}
</button> </button>
@ -733,7 +733,7 @@
<button <button
type="submit" type="submit"
:disabled="creating" :disabled="creating"
class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium" class="px-6 py-2 bg-candlelight-600 text-white rounded-lg hover:bg-candlelight-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium"
> >
{{ {{
creating creating

View file

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<div class="bg-elevated border-b"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<h1 class="text-2xl font-bold text-highlighted">Event Management</h1> <h1 class="text-display font-bold text-guild-100">Event Management</h1>
<p class="text-muted"> <p class="text-guild-400">
Create, manage, and monitor Ghost Guild events and workshops Create, manage, and monitor Ghost Guild events and workshops
</p> </p>
</div> </div>
@ -53,7 +53,7 @@
</div> </div>
<NuxtLink <NuxtLink
to="/admin/events/create" to="/admin/events/create"
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 inline-flex items-center" class="bg-candlelight-600 text-white px-4 py-2 rounded-lg hover:bg-candlelight-700 focus:ring-2 focus:ring-candlelight-500 focus:ring-offset-2 inline-flex items-center"
> >
<Icon name="heroicons:plus" class="w-4 h-4 mr-2" /> <Icon name="heroicons:plus" class="w-4 h-4 mr-2" />
Create Event Create Event
@ -61,65 +61,65 @@
</div> </div>
<!-- Events Table --> <!-- Events Table -->
<div class="bg-elevated rounded-lg shadow overflow-hidden"> <div class="bg-guild-900 rounded-lg shadow overflow-hidden">
<div v-if="pending" class="p-8 text-center"> <div v-if="pending" class="p-8 text-center text-guild-100">
<div class="inline-flex items-center"> <div class="inline-flex items-center">
<div <div
class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600 mr-3" class="animate-spin rounded-full h-6 w-6 border-b-2 border-candlelight-500 mr-3"
></div> ></div>
Loading events... Loading events...
</div> </div>
</div> </div>
<div v-else-if="error" class="p-8 text-center text-red-600"> <div v-else-if="error" class="p-8 text-center text-ember-400">
Error loading events: {{ error }} Error loading events: {{ error }}
</div> </div>
<table v-else class="w-full"> <table v-else class="w-full">
<thead class="bg-muted"> <thead class="bg-guild-950">
<tr> <tr>
<th <th
class="px-6 py-4 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-4 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Title Title
</th> </th>
<th <th
class="px-4 py-4 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-4 py-4 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Type Type
</th> </th>
<th <th
class="px-4 py-4 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-4 py-4 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Date Date
</th> </th>
<th <th
class="px-4 py-4 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-4 py-4 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Status Status
</th> </th>
<th <th
class="px-4 py-4 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-4 py-4 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Registration Registration
</th> </th>
<th <th
class="px-4 py-4 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-4 py-4 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Tickets Tickets
</th> </th>
<th <th
class="px-6 py-4 text-right text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-4 text-right text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Actions Actions
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody class="bg-elevated divide-y divide-default"> <tbody class="bg-guild-900 divide-y divide-guild-700">
<tr <tr
v-for="event in filteredEvents" v-for="event in filteredEvents"
:key="event._id" :key="event._id"
class="hover:bg-muted" class="hover:bg-guild-800"
> >
<!-- Title Column --> <!-- Title Column -->
<td class="px-6 py-6"> <td class="px-6 py-6">
@ -128,7 +128,7 @@
v-if=" v-if="
event.featureImage?.url && !event.featureImage?.publicId event.featureImage?.url && !event.featureImage?.publicId
" "
class="flex-shrink-0 w-12 h-12 bg-accented rounded-lg overflow-hidden" class="flex-shrink-0 w-12 h-12 bg-guild-800 rounded-lg overflow-hidden"
> >
<img <img
:src="event.featureImage.url" :src="event.featureImage.url"
@ -139,26 +139,26 @@
</div> </div>
<div <div
v-else v-else
class="flex-shrink-0 w-12 h-12 bg-accented rounded-lg flex items-center justify-center" class="flex-shrink-0 w-12 h-12 bg-guild-800 rounded-lg flex items-center justify-center"
> >
<Icon <Icon
name="heroicons:calendar-days" name="heroicons:calendar-days"
class="w-6 h-6 text-muted" class="w-6 h-6 text-guild-400"
/> />
</div> </div>
<div class="flex-1 min-w-0"> <div class="flex-1 min-w-0">
<div class="text-sm font-semibold text-highlighted mb-1"> <div class="text-sm font-semibold text-guild-100 mb-1">
{{ event.title }} {{ event.title }}
</div> </div>
<div class="text-sm text-dimmed line-clamp-2"> <div class="text-sm text-guild-500 line-clamp-2">
{{ event.description.substring(0, 100) }}... {{ event.description.substring(0, 100) }}...
</div> </div>
<div v-if="event.series?.isSeriesEvent" class="mt-2 mb-2"> <div v-if="event.series?.isSeriesEvent" class="mt-2 mb-2">
<div <div
class="inline-flex items-center gap-1 px-2 py-1 bg-purple-100 text-purple-700 text-xs font-medium rounded-full" class="inline-flex items-center gap-1 px-2 py-1 bg-earth-900/20 text-earth-400 text-xs font-medium rounded-full"
> >
<div <div
class="w-4 h-4 bg-purple-200 text-purple-700 rounded-full flex items-center justify-center text-xs font-bold" class="w-4 h-4 bg-earth-800 text-earth-400 rounded-full flex items-center justify-center text-xs font-bold"
> >
{{ event.series.position }} {{ event.series.position }}
</div> </div>
@ -168,7 +168,7 @@
<div class="flex items-center space-x-4 mt-2"> <div class="flex items-center space-x-4 mt-2">
<div <div
v-if="event.membersOnly" v-if="event.membersOnly"
class="flex items-center text-xs text-purple-600" class="flex items-center text-xs text-earth-400"
> >
<Icon <Icon
name="heroicons:lock-closed" name="heroicons:lock-closed"
@ -184,15 +184,15 @@
> >
<Icon <Icon
name="heroicons:user-group" name="heroicons:user-group"
class="w-3 h-3 text-muted" class="w-3 h-3 text-guild-400"
/> />
<span class="text-xs text-dimmed">{{ <span class="text-xs text-guild-500">{{
event.targetCircles.join(", ") event.targetCircles.join(", ")
}}</span> }}</span>
</div> </div>
<div <div
v-if="!event.isVisible" v-if="!event.isVisible"
class="flex items-center text-xs text-dimmed" class="flex items-center text-xs text-guild-500"
> >
<Icon name="heroicons:eye-slash" class="w-3 h-3 mr-1" /> <Icon name="heroicons:eye-slash" class="w-3 h-3 mr-1" />
Hidden Hidden
@ -213,12 +213,12 @@
</td> </td>
<!-- Date Column --> <!-- Date Column -->
<td class="px-4 py-6 whitespace-nowrap text-sm text-muted"> <td class="px-4 py-6 whitespace-nowrap text-sm text-guild-400">
<div class="space-y-1"> <div class="space-y-1">
<div class="font-medium"> <div class="font-medium">
{{ formatDate(event.startDate) }} {{ formatDate(event.startDate) }}
</div> </div>
<div class="text-xs text-dimmed"> <div class="text-xs text-guild-500">
{{ formatTime(event.startDate) }} {{ formatTime(event.startDate) }}
</div> </div>
</div> </div>
@ -235,7 +235,7 @@
</span> </span>
<div <div
v-if="event.isCancelled" v-if="event.isCancelled"
class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800" class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-ember-900/20 text-ember-400"
> >
Cancelled Cancelled
</div> </div>
@ -247,17 +247,17 @@
<div class="space-y-2"> <div class="space-y-2">
<div <div
v-if="event.registrationRequired" v-if="event.registrationRequired"
class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800" class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-candlelight-900/20 text-candlelight-400"
> >
Required Required
</div> </div>
<div <div
v-else v-else
class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-accented text-default" class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-guild-800 text-guild-300"
> >
Optional Optional
</div> </div>
<div v-if="event.maxAttendees" class="text-xs text-dimmed"> <div v-if="event.maxAttendees" class="text-xs text-guild-500">
{{ event.registeredCount || 0 }} / {{ event.maxAttendees }} {{ event.registeredCount || 0 }} / {{ event.maxAttendees }}
</div> </div>
</div> </div>
@ -270,20 +270,20 @@
<div class="flex items-center gap-1 text-xs"> <div class="flex items-center gap-1 text-xs">
<Icon <Icon
name="heroicons:ticket" name="heroicons:ticket"
class="w-3.5 h-3.5 text-blue-600" class="w-3.5 h-3.5 text-candlelight-400"
/> />
<span class="font-medium text-default">Ticketing On</span> <span class="font-medium text-guild-100">Ticketing On</span>
</div> </div>
<div <div
v-if="event.tickets?.requiresSeriesTicket" v-if="event.tickets?.requiresSeriesTicket"
class="text-xs text-purple-600" class="text-xs text-earth-400"
> >
Series Pass Required Series Pass Required
</div> </div>
<div v-else class="space-y-0.5"> <div v-else class="space-y-0.5">
<div <div
v-if="event.tickets.member?.available" v-if="event.tickets.member?.available"
class="text-xs text-dimmed" class="text-xs text-guild-500"
> >
Member: Member:
{{ {{
@ -294,7 +294,7 @@
</div> </div>
<div <div
v-if="event.tickets.public?.available" v-if="event.tickets.public?.available"
class="text-xs text-dimmed" class="text-xs text-guild-500"
> >
Public: ${{ event.tickets.public.price || 0 }} Public: ${{ event.tickets.public.price || 0 }}
<span v-if="event.tickets.public.quantity" class="ml-1"> <span v-if="event.tickets.public.quantity" class="ml-1">
@ -305,7 +305,7 @@
</div> </div>
</div> </div>
</div> </div>
<div v-else class="text-xs text-dimmed">No tickets</div> <div v-else class="text-xs text-guild-500">No tickets</div>
</div> </div>
</td> </td>
@ -314,28 +314,28 @@
<div class="flex items-center justify-end space-x-2"> <div class="flex items-center justify-end space-x-2">
<NuxtLink <NuxtLink
:to="`/events/${event.slug || String(event._id)}`" :to="`/events/${event.slug || String(event._id)}`"
class="p-2 text-dimmed hover:text-default hover:bg-accented rounded-full transition-colors" class="p-2 text-guild-500 hover:text-guild-100 hover:bg-guild-800 rounded-full transition-colors"
title="View Event" title="View Event"
> >
<Icon name="heroicons:eye" class="w-4 h-4" /> <Icon name="heroicons:eye" class="w-4 h-4" />
</NuxtLink> </NuxtLink>
<button <button
@click="editEvent(event)" @click="editEvent(event)"
class="p-2 text-primary hover:text-primary hover:bg-primary/10 rounded-full transition-colors" class="p-2 text-candlelight-400 hover:text-candlelight-300 hover:bg-candlelight-900/20 rounded-full transition-colors"
title="Edit Event" title="Edit Event"
> >
<Icon name="heroicons:pencil-square" class="w-4 h-4" /> <Icon name="heroicons:pencil-square" class="w-4 h-4" />
</button> </button>
<button <button
@click="duplicateEvent(event)" @click="duplicateEvent(event)"
class="p-2 text-primary hover:text-primary hover:bg-primary/10 rounded-full transition-colors" class="p-2 text-candlelight-400 hover:text-candlelight-300 hover:bg-candlelight-900/20 rounded-full transition-colors"
title="Duplicate Event" title="Duplicate Event"
> >
<Icon name="heroicons:document-duplicate" class="w-4 h-4" /> <Icon name="heroicons:document-duplicate" class="w-4 h-4" />
</button> </button>
<button <button
@click="deleteEvent(event)" @click="deleteEvent(event)"
class="p-2 text-red-500 hover:text-red-700 hover:bg-red-50 rounded-full transition-colors" class="p-2 text-ember-400 hover:text-ember-300 hover:bg-ember-900/20 rounded-full transition-colors"
title="Delete Event" title="Delete Event"
> >
<Icon name="heroicons:trash" class="w-4 h-4" /> <Icon name="heroicons:trash" class="w-4 h-4" />
@ -348,7 +348,7 @@
<div <div
v-if="!pending && !error && filteredEvents.length === 0" v-if="!pending && !error && filteredEvents.length === 0"
class="p-8 text-center text-dimmed" class="p-8 text-center text-guild-500"
> >
No events found matching your criteria No events found matching your criteria
</div> </div>
@ -402,12 +402,12 @@ const filteredEvents = computed(() => {
const getEventTypeClasses = (type) => { const getEventTypeClasses = (type) => {
const classes = { const classes = {
community: "bg-blue-100 text-blue-800", community: "bg-candlelight-900/20 text-candlelight-400",
workshop: "bg-green-100 text-green-800", workshop: "bg-candlelight-900/20 text-candlelight-400",
social: "bg-purple-100 text-purple-800", social: "bg-earth-900/20 text-earth-400",
showcase: "bg-orange-100 text-orange-800", showcase: "bg-ember-900/20 text-ember-400",
}; };
return classes[type] || "bg-gray-100 text-gray-800"; return classes[type] || "bg-guild-800 text-guild-300";
}; };
const getEventStatus = (event) => { const getEventStatus = (event) => {
@ -423,11 +423,11 @@ const getEventStatus = (event) => {
const getStatusClasses = (event) => { const getStatusClasses = (event) => {
const status = getEventStatus(event); const status = getEventStatus(event);
const classes = { const classes = {
Upcoming: "bg-blue-100 text-blue-800", Upcoming: "bg-candlelight-900/20 text-candlelight-400",
Ongoing: "bg-green-100 text-green-800", Ongoing: "bg-candlelight-900/20 text-candlelight-400",
Past: "bg-gray-100 text-gray-800", Past: "bg-guild-800 text-guild-300",
}; };
return classes[status] || "bg-gray-100 text-gray-800"; return classes[status] || "bg-guild-800 text-guild-300";
}; };
const formatDateTime = (dateString) => { const formatDateTime = (dateString) => {

View file

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<div class="bg-white border-b"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<h1 class="text-2xl font-bold text-gray-900">Admin Interface - Working Version</h1> <h1 class="text-display font-bold text-guild-100">Admin Interface - Working Version</h1>
<p class="text-gray-600">Fully functional admin interface without Nuxt UI component issues</p> <p class="text-guild-400">Fully functional admin interface without Nuxt UI component issues</p>
</div> </div>
</div> </div>
</div> </div>
@ -12,56 +12,56 @@
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Navigation Cards --> <!-- Navigation Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<NuxtLink to="/admin/dashboard" class="block bg-white rounded-lg shadow hover:shadow-lg transition-shadow p-6 text-center border-2 border-transparent hover:border-blue-200"> <NuxtLink to="/admin/dashboard" class="block bg-guild-900 rounded-lg shadow hover:shadow-lg transition-shadow p-6 text-center border-2 border-transparent hover:border-candlelight-800">
<div class="w-16 h-16 bg-blue-100 rounded-2xl flex items-center justify-center mx-auto mb-4"> <div class="w-16 h-16 bg-candlelight-900/20 rounded-2xl flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-8 h-8 text-candlelight-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
</svg> </svg>
</div> </div>
<h3 class="text-lg font-semibold mb-2">Dashboard</h3> <h3 class="text-lg font-semibold text-guild-100 mb-2">Dashboard</h3>
<p class="text-gray-600 text-sm">Overview & statistics</p> <p class="text-guild-400 text-sm">Overview & statistics</p>
</NuxtLink> </NuxtLink>
<NuxtLink to="/admin/members-working" class="block bg-white rounded-lg shadow hover:shadow-lg transition-shadow p-6 text-center border-2 border-transparent hover:border-green-200"> <NuxtLink to="/admin/members-working" class="block bg-guild-900 rounded-lg shadow hover:shadow-lg transition-shadow p-6 text-center border-2 border-transparent hover:border-candlelight-800">
<div class="w-16 h-16 bg-green-100 rounded-2xl flex items-center justify-center mx-auto mb-4"> <div class="w-16 h-16 bg-candlelight-900/20 rounded-2xl flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-8 h-8 text-candlelight-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197m13.5-.5a4 4 0 110 5.292M4 19.5a4 4 0 010-5.292"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197m13.5-.5a4 4 0 110 5.292M4 19.5a4 4 0 010-5.292"></path>
</svg> </svg>
</div> </div>
<h3 class="text-lg font-semibold mb-2">Members</h3> <h3 class="text-lg font-semibold text-guild-100 mb-2">Members</h3>
<p class="text-gray-600 text-sm">Manage members</p> <p class="text-guild-400 text-sm">Manage members</p>
</NuxtLink> </NuxtLink>
<NuxtLink to="/admin/events-working" class="block bg-white rounded-lg shadow hover:shadow-lg transition-shadow p-6 text-center border-2 border-transparent hover:border-purple-200"> <NuxtLink to="/admin/events-working" class="block bg-guild-900 rounded-lg shadow hover:shadow-lg transition-shadow p-6 text-center border-2 border-transparent hover:border-earth-800">
<div class="w-16 h-16 bg-purple-100 rounded-2xl flex items-center justify-center mx-auto mb-4"> <div class="w-16 h-16 bg-earth-900/20 rounded-2xl flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-8 h-8 text-earth-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg> </svg>
</div> </div>
<h3 class="text-lg font-semibold mb-2">Events</h3> <h3 class="text-lg font-semibold text-guild-100 mb-2">Events</h3>
<p class="text-gray-600 text-sm">Manage events</p> <p class="text-guild-400 text-sm">Manage events</p>
</NuxtLink> </NuxtLink>
<div class="bg-gray-100 rounded-lg p-6 text-center border-2 border-dashed border-gray-300"> <div class="bg-guild-950 rounded-lg p-6 text-center border-2 border-dashed border-guild-700">
<div class="w-16 h-16 bg-gray-200 rounded-2xl flex items-center justify-center mx-auto mb-4"> <div class="w-16 h-16 bg-guild-800 rounded-2xl flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-8 h-8 text-guild-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg> </svg>
</div> </div>
<h3 class="text-lg font-semibold mb-2 text-gray-600">More</h3> <h3 class="text-lg font-semibold mb-2 text-guild-400">More</h3>
<p class="text-gray-500 text-sm">Coming soon</p> <p class="text-guild-500 text-sm">Coming soon</p>
</div> </div>
</div> </div>
<!-- Status Information --> <!-- Status Information -->
<div class="bg-green-50 border border-green-200 rounded-lg p-6"> <div class="bg-candlelight-900/20 border border-candlelight-800 rounded-lg p-6">
<div class="flex items-start"> <div class="flex items-start">
<svg class="w-6 h-6 text-green-600 mt-0.5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-6 h-6 text-candlelight-400 mt-0.5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg> </svg>
<div> <div>
<h3 class="text-lg font-semibold text-green-800 mb-2">Admin Interface Status: Fully Working</h3> <h3 class="text-lg font-semibold text-candlelight-400 mb-2">Admin Interface Status: Fully Working</h3>
<div class="space-y-2 text-green-700"> <div class="space-y-2 text-candlelight-400">
<p> <strong>Dashboard:</strong> Shows statistics, recent members, and upcoming events</p> <p> <strong>Dashboard:</strong> Shows statistics, recent members, and upcoming events</p>
<p> <strong>Member Management:</strong> Full CRUD operations, search, filter, create members</p> <p> <strong>Member Management:</strong> Full CRUD operations, search, filter, create members</p>
<p> <strong>Event Management:</strong> Create, edit, delete, duplicate events with full forms</p> <p> <strong>Event Management:</strong> Create, edit, delete, duplicate events with full forms</p>
@ -75,21 +75,21 @@
<!-- Quick Stats Preview --> <!-- Quick Stats Preview -->
<div class="mt-8 grid grid-cols-2 md:grid-cols-4 gap-4"> <div class="mt-8 grid grid-cols-2 md:grid-cols-4 gap-4">
<div class="bg-white rounded-lg shadow p-4 text-center"> <div class="bg-guild-900 rounded-lg shadow p-4 text-center">
<p class="text-2xl font-bold text-blue-600">{{ memberCount }}</p> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">{{ memberCount }}</p>
<p class="text-sm text-gray-600">Members</p> <p class="text-sm text-guild-400">Members</p>
</div> </div>
<div class="bg-white rounded-lg shadow p-4 text-center"> <div class="bg-guild-900 rounded-lg shadow p-4 text-center">
<p class="text-2xl font-bold text-green-600">{{ eventCount }}</p> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">{{ eventCount }}</p>
<p class="text-sm text-gray-600">Events</p> <p class="text-sm text-guild-400">Events</p>
</div> </div>
<div class="bg-white rounded-lg shadow p-4 text-center"> <div class="bg-guild-900 rounded-lg shadow p-4 text-center">
<p class="text-2xl font-bold text-purple-600">${{ monthlyRevenue }}</p> <p class="text-2xl font-bold text-earth-400 text-ui-mono">${{ monthlyRevenue }}</p>
<p class="text-sm text-gray-600">Monthly Revenue</p> <p class="text-sm text-guild-400">Monthly Revenue</p>
</div> </div>
<div class="bg-white rounded-lg shadow p-4 text-center"> <div class="bg-guild-900 rounded-lg shadow p-4 text-center">
<p class="text-2xl font-bold text-orange-600">{{ pendingInvites }}</p> <p class="text-2xl font-bold text-ember-400 text-ui-mono">{{ pendingInvites }}</p>
<p class="text-sm text-gray-600">Pending Invites</p> <p class="text-sm text-guild-400">Pending Invites</p>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<div class="bg-elevated border-b border-default"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<h1 class="text-2xl font-bold text-highlighted">Admin Dashboard</h1> <h1 class="text-display font-bold text-guild-100">Admin Dashboard</h1>
<p class="text-muted"> <p class="text-guild-400">
Manage Ghost Guild members, events, and community operations Manage Ghost Guild members, events, and community operations
</p> </p>
</div> </div>
@ -14,19 +14,19 @@
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Quick Stats --> <!-- Quick Stats -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8"> <div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="text-sm text-muted">Total Members</p> <p class="text-sm text-guild-400">Total Members</p>
<p class="text-2xl font-bold text-blue-600"> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">
{{ stats.totalMembers || 0 }} {{ stats.totalMembers || 0 }}
</p> </p>
</div> </div>
<div <div
class="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center" class="w-12 h-12 bg-candlelight-900/20 rounded-xl flex items-center justify-center"
> >
<svg <svg
class="w-6 h-6 text-blue-600" class="w-6 h-6 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -42,19 +42,19 @@
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="text-sm text-muted">Active Events</p> <p class="text-sm text-guild-400">Active Events</p>
<p class="text-2xl font-bold text-green-600"> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">
{{ stats.activeEvents || 0 }} {{ stats.activeEvents || 0 }}
</p> </p>
</div> </div>
<div <div
class="w-12 h-12 bg-green-100 rounded-xl flex items-center justify-center" class="w-12 h-12 bg-candlelight-900/20 rounded-xl flex items-center justify-center"
> >
<svg <svg
class="w-6 h-6 text-green-600" class="w-6 h-6 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -70,19 +70,19 @@
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="text-sm text-muted">Monthly Revenue</p> <p class="text-sm text-guild-400">Monthly Revenue</p>
<p class="text-2xl font-bold text-purple-600"> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">
${{ stats.monthlyRevenue || 0 }} ${{ stats.monthlyRevenue || 0 }}
</p> </p>
</div> </div>
<div <div
class="w-12 h-12 bg-purple-100 rounded-xl flex items-center justify-center" class="w-12 h-12 bg-candlelight-900/20 rounded-xl flex items-center justify-center"
> >
<svg <svg
class="w-6 h-6 text-purple-600" class="w-6 h-6 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -98,19 +98,19 @@
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="text-sm text-muted">Pending Slack Invites</p> <p class="text-sm text-guild-400">Pending Slack Invites</p>
<p class="text-2xl font-bold text-orange-600"> <p class="text-2xl font-bold text-candlelight-400 text-ui-mono">
{{ stats.pendingSlackInvites || 0 }} {{ stats.pendingSlackInvites || 0 }}
</p> </p>
</div> </div>
<div <div
class="w-12 h-12 bg-orange-100 rounded-xl flex items-center justify-center" class="w-12 h-12 bg-candlelight-900/20 rounded-xl flex items-center justify-center"
> >
<svg <svg
class="w-6 h-6 text-orange-600" class="w-6 h-6 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -129,13 +129,13 @@
<!-- Quick Actions --> <!-- Quick Actions -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="text-center"> <div class="text-center">
<div <div
class="w-16 h-16 bg-blue-100 rounded-2xl flex items-center justify-center mx-auto mb-4" class="w-16 h-16 bg-candlelight-900/20 rounded-2xl flex items-center justify-center mx-auto mb-4"
> >
<svg <svg
class="w-8 h-8 text-blue-600" class="w-8 h-8 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -148,28 +148,28 @@
></path> ></path>
</svg> </svg>
</div> </div>
<h3 class="text-lg font-semibold mb-2 text-highlighted"> <h3 class="text-display-sm font-semibold mb-2 text-guild-100">
Add New Member Add New Member
</h3> </h3>
<p class="text-muted text-sm mb-4"> <p class="text-guild-400 text-sm mb-4">
Add a new member to the Ghost Guild community Add a new member to the Ghost Guild community
</p> </p>
<button <button
@click="navigateTo('/admin/members')" @click="navigateTo('/admin/members')"
class="w-full bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2" class="w-full bg-candlelight-600 text-white py-2 px-4 rounded-lg hover:bg-candlelight-700 focus:ring-2 focus:ring-candlelight-500 focus:ring-offset-2"
> >
Manage Members Manage Members
</button> </button>
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="text-center"> <div class="text-center">
<div <div
class="w-16 h-16 bg-green-100 rounded-2xl flex items-center justify-center mx-auto mb-4" class="w-16 h-16 bg-candlelight-900/20 rounded-2xl flex items-center justify-center mx-auto mb-4"
> >
<svg <svg
class="w-8 h-8 text-green-600" class="w-8 h-8 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -182,15 +182,15 @@
></path> ></path>
</svg> </svg>
</div> </div>
<h3 class="text-lg font-semibold mb-2 text-highlighted"> <h3 class="text-display-sm font-semibold mb-2 text-guild-100">
Create Event Create Event
</h3> </h3>
<p class="text-muted text-sm mb-4"> <p class="text-guild-400 text-sm mb-4">
Schedule a new community event or workshop Schedule a new community event or workshop
</p> </p>
<button <button
@click="navigateTo('/admin/events')" @click="navigateTo('/admin/events')"
class="w-full bg-green-600 text-white py-2 px-4 rounded-lg hover:bg-green-700 focus:ring-2 focus:ring-green-500 focus:ring-offset-2" class="w-full bg-candlelight-600 text-white py-2 px-4 rounded-lg hover:bg-candlelight-700 focus:ring-2 focus:ring-candlelight-500 focus:ring-offset-2"
> >
Manage Events Manage Events
</button> </button>
@ -200,15 +200,15 @@
<!-- Recent Activity --> <!-- Recent Activity -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6"> <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-elevated rounded-lg shadow"> <div class="bg-guild-900 rounded-lg shadow">
<div class="px-6 py-4 border-b border-default"> <div class="px-6 py-4 border-b border-guild-700">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<h3 class="text-lg font-semibold text-highlighted"> <h3 class="text-display-sm font-semibold text-guild-100">
Recent Members Recent Members
</h3> </h3>
<button <button
@click="navigateTo('/admin/members')" @click="navigateTo('/admin/members')"
class="text-sm text-primary hover:text-primary" class="text-sm text-candlelight-400 hover:text-candlelight-300"
> >
View All View All
</button> </button>
@ -218,20 +218,20 @@
<div class="p-6"> <div class="p-6">
<div v-if="pending" class="text-center py-4"> <div v-if="pending" class="text-center py-4">
<div <div
class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600 mx-auto" class="animate-spin rounded-full h-6 w-6 border-b-2 border-candlelight-500 mx-auto"
></div> ></div>
</div> </div>
<div v-else-if="recentMembers.length" class="space-y-3"> <div v-else-if="recentMembers.length" class="space-y-3">
<div <div
v-for="member in recentMembers" v-for="member in recentMembers"
:key="member._id" :key="member._id"
class="flex items-center justify-between p-3 rounded-lg border border-default" class="flex items-center justify-between p-3 rounded-lg border border-guild-700"
> >
<div> <div>
<p class="font-medium text-highlighted"> <p class="font-medium text-guild-100">
{{ member.name }} {{ member.name }}
</p> </p>
<p class="text-sm text-muted"> <p class="text-sm text-guild-400">
{{ member.email }} {{ member.email }}
</p> </p>
</div> </div>
@ -242,27 +242,27 @@
> >
{{ member.circle }} {{ member.circle }}
</span> </span>
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500 text-ui-mono">
{{ formatDate(member.createdAt) }} {{ formatDate(member.createdAt) }}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div v-else class="text-center py-6 text-dimmed"> <div v-else class="text-center py-6 text-guild-500">
No recent members No recent members
</div> </div>
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow"> <div class="bg-guild-900 rounded-lg shadow">
<div class="px-6 py-4 border-b border-default"> <div class="px-6 py-4 border-b border-guild-700">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<h3 class="text-lg font-semibold text-highlighted"> <h3 class="text-display-sm font-semibold text-guild-100">
Upcoming Events Upcoming Events
</h3> </h3>
<button <button
@click="navigateTo('/admin/events')" @click="navigateTo('/admin/events')"
class="text-sm text-primary hover:text-primary" class="text-sm text-candlelight-400 hover:text-candlelight-300"
> >
View All View All
</button> </button>
@ -272,20 +272,20 @@
<div class="p-6"> <div class="p-6">
<div v-if="pending" class="text-center py-4"> <div v-if="pending" class="text-center py-4">
<div <div
class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600 mx-auto" class="animate-spin rounded-full h-6 w-6 border-b-2 border-candlelight-500 mx-auto"
></div> ></div>
</div> </div>
<div v-else-if="upcomingEvents.length" class="space-y-3"> <div v-else-if="upcomingEvents.length" class="space-y-3">
<div <div
v-for="event in upcomingEvents" v-for="event in upcomingEvents"
:key="event._id" :key="event._id"
class="flex items-center justify-between p-3 rounded-lg border border-default" class="flex items-center justify-between p-3 rounded-lg border border-guild-700"
> >
<div> <div>
<p class="font-medium text-highlighted"> <p class="font-medium text-guild-100">
{{ event.title }} {{ event.title }}
</p> </p>
<p class="text-sm text-muted"> <p class="text-sm text-guild-400">
{{ formatDateTime(event.startDate) }} {{ formatDateTime(event.startDate) }}
</p> </p>
</div> </div>
@ -296,13 +296,13 @@
> >
{{ event.eventType }} {{ event.eventType }}
</span> </span>
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
{{ event.location || "Online" }} {{ event.location || "Online" }}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div v-else class="text-center py-6 text-dimmed"> <div v-else class="text-center py-6 text-guild-500">
No upcoming events No upcoming events
</div> </div>
</div> </div>
@ -327,21 +327,21 @@ const upcomingEvents = computed(
const getCircleBadgeClasses = (circle) => { const getCircleBadgeClasses = (circle) => {
const classes = { const classes = {
community: "bg-blue-100 text-blue-800", community: "bg-candlelight-900/20 text-candlelight-400",
founder: "bg-purple-100 text-purple-800", founder: "bg-earth-900/20 text-earth-400",
practitioner: "bg-green-100 text-green-800", practitioner: "bg-candlelight-900/20 text-candlelight-400",
}; };
return classes[circle] || "bg-accented text-default"; return classes[circle] || "bg-guild-800 text-guild-300";
}; };
const getEventTypeBadgeClasses = (type) => { const getEventTypeBadgeClasses = (type) => {
const classes = { const classes = {
community: "bg-blue-100 text-blue-800", community: "bg-candlelight-900/20 text-candlelight-400",
workshop: "bg-green-100 text-green-800", workshop: "bg-candlelight-900/20 text-candlelight-400",
social: "bg-purple-100 text-purple-800", social: "bg-earth-900/20 text-earth-400",
showcase: "bg-orange-100 text-orange-800", showcase: "bg-ember-900/20 text-ember-400",
}; };
return classes[type] || "bg-accented text-default"; return classes[type] || "bg-guild-800 text-guild-300";
}; };
const formatDate = (dateString) => { const formatDate = (dateString) => {

View file

@ -1,45 +1,45 @@
<template> <template>
<div> <div>
<h1 class="text-2xl font-bold mb-6">Members</h1> <h1 class="text-display font-bold mb-6 text-guild-100">Members</h1>
<div v-if="pending" class="text-center">Loading...</div> <div v-if="pending" class="text-center text-guild-400">Loading...</div>
<div v-else-if="error" class="text-red-600"> <div v-else-if="error" class="text-ember-400">
Error loading members: {{ error }} Error loading members: {{ error }}
</div> </div>
<div v-else class="space-y-4"> <div v-else class="space-y-4">
<div class="bg-white rounded-lg border p-4"> <div class="bg-guild-900 rounded-lg border border-guild-700 p-4">
<h3 class="font-semibold mb-2">Total Members: {{ members?.length || 0 }}</h3> <h3 class="font-semibold mb-2 text-guild-100">Total Members: {{ members?.length || 0 }}</h3>
<div v-for="member in members" :key="member._id" class="border-b pb-2 mb-2 last:border-b-0"> <div v-for="member in members" :key="member._id" class="border-b border-guild-700 pb-2 mb-2 last:border-b-0">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<div> <div>
<p class="font-medium">{{ member.name }}</p> <p class="font-medium text-guild-100">{{ member.name }}</p>
<p class="text-gray-600 text-sm">{{ member.email }}</p> <p class="text-guild-400 text-sm">{{ member.email }}</p>
</div> </div>
<div class="text-right"> <div class="text-right">
<span class="inline-block px-2 py-1 text-xs rounded bg-blue-100 text-blue-800"> <span class="inline-block px-2 py-1 text-xs rounded bg-candlelight-900/20 text-candlelight-400">
{{ member.circle }} {{ member.circle }}
</span> </span>
<p class="text-sm text-gray-500">${{ member.contributionTier }}/month</p> <p class="text-sm text-guild-500 text-ui-mono">${{ member.contributionTier }}/month</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- Simple Add Member Form --> <!-- Simple Add Member Form -->
<div class="bg-white rounded-lg border p-4"> <div class="bg-guild-900 rounded-lg border border-guild-700 p-4">
<h3 class="font-semibold mb-4">Add Member</h3> <h3 class="text-display-sm font-semibold mb-4 text-guild-100">Add Member</h3>
<div class="grid grid-cols-2 gap-4"> <div class="grid grid-cols-2 gap-4">
<input v-model="newMember.name" placeholder="Name" class="border rounded p-2" /> <input v-model="newMember.name" placeholder="Name" class="border border-guild-700 bg-guild-800 text-guild-100 placeholder-guild-500 rounded p-2" />
<input v-model="newMember.email" placeholder="Email" class="border rounded p-2" /> <input v-model="newMember.email" placeholder="Email" class="border border-guild-700 bg-guild-800 text-guild-100 placeholder-guild-500 rounded p-2" />
<select v-model="newMember.circle" class="border rounded p-2"> <select v-model="newMember.circle" class="border border-guild-700 bg-guild-800 text-guild-100 rounded p-2">
<option value="community">Community</option> <option value="community">Community</option>
<option value="founder">Founder</option> <option value="founder">Founder</option>
<option value="practitioner">Practitioner</option> <option value="practitioner">Practitioner</option>
</select> </select>
<select v-model="newMember.contributionTier" class="border rounded p-2"> <select v-model="newMember.contributionTier" class="border border-guild-700 bg-guild-800 text-guild-100 rounded p-2">
<option value="0">$0/month</option> <option value="0">$0/month</option>
<option value="5">$5/month</option> <option value="5">$5/month</option>
<option value="15">$15/month</option> <option value="15">$15/month</option>
@ -47,7 +47,7 @@
<option value="50">$50/month</option> <option value="50">$50/month</option>
</select> </select>
</div> </div>
<button @click="createMember" :disabled="creating" class="mt-4 bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 disabled:opacity-50"> <button @click="createMember" :disabled="creating" class="mt-4 bg-candlelight-600 text-white px-4 py-2 rounded hover:bg-candlelight-700 disabled:opacity-50">
{{ creating ? 'Adding...' : 'Add Member' }} {{ creating ? 'Adding...' : 'Add Member' }}
</button> </button>
</div> </div>
@ -75,21 +75,21 @@ const createMember = async () => {
alert('Please fill in name and email') alert('Please fill in name and email')
return return
} }
creating.value = true creating.value = true
try { try {
await $fetch('/api/admin/members', { await $fetch('/api/admin/members', {
method: 'POST', method: 'POST',
body: newMember body: newMember
}) })
Object.assign(newMember, { Object.assign(newMember, {
name: '', name: '',
email: '', email: '',
circle: 'community', circle: 'community',
contributionTier: '0' contributionTier: '0'
}) })
await refresh() await refresh()
alert('Member added successfully!') alert('Member added successfully!')
} catch (error) { } catch (error) {
@ -98,4 +98,4 @@ const createMember = async () => {
creating.value = false creating.value = false
} }
} }
</script> </script>

View file

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<div class="bg-white border-b"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<h1 class="text-2xl font-bold text-gray-900">Member Management</h1> <h1 class="text-display font-bold text-guild-100">Member Management</h1>
<p class="text-gray-600"> <p class="text-guild-400">
Manage Ghost Guild members, their contributions, and access levels Manage Ghost Guild members, their contributions, and access levels
</p> </p>
</div> </div>
@ -18,11 +18,11 @@
<input <input
v-model="searchQuery" v-model="searchQuery"
placeholder="Search members..." placeholder="Search members..."
class="border border-gray-300 rounded-lg px-4 py-2 w-80 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="border border-guild-700 bg-guild-900 text-guild-100 placeholder-guild-500 rounded-lg px-4 py-2 w-80 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
/> />
<select <select
v-model="circleFilter" v-model="circleFilter"
class="border border-gray-300 rounded-lg px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="border border-guild-700 bg-guild-900 text-guild-100 rounded-lg px-4 py-2 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
> >
<option value="">All Circles</option> <option value="">All Circles</option>
<option value="community">Community</option> <option value="community">Community</option>
@ -32,80 +32,80 @@
</div> </div>
<button <button
@click="showCreateModal = true" @click="showCreateModal = true"
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2" class="bg-candlelight-600 text-white px-4 py-2 rounded-lg hover:bg-candlelight-700 focus:ring-2 focus:ring-candlelight-500 focus:ring-offset-2"
> >
Add Member Add Member
</button> </button>
</div> </div>
<!-- Members Table --> <!-- Members Table -->
<div class="bg-white rounded-lg shadow overflow-hidden"> <div class="bg-guild-900 rounded-lg shadow overflow-hidden">
<div v-if="pending" class="p-8 text-center"> <div v-if="pending" class="p-8 text-center text-guild-100">
<div class="inline-flex items-center"> <div class="inline-flex items-center">
<div <div
class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600 mr-3" class="animate-spin rounded-full h-6 w-6 border-b-2 border-candlelight-500 mr-3"
></div> ></div>
Loading members... Loading members...
</div> </div>
</div> </div>
<div v-else-if="error" class="p-8 text-center text-red-600"> <div v-else-if="error" class="p-8 text-center text-ember-400">
Error loading members: {{ error }} Error loading members: {{ error }}
</div> </div>
<table v-else class="w-full"> <table v-else class="w-full">
<thead class="bg-gray-50"> <thead class="bg-guild-950">
<tr> <tr>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Name Name
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Email Email
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Circle Circle
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Contribution Contribution
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Slack Status Slack Status
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Joined Joined
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Actions Actions
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody class="bg-white divide-y divide-gray-200"> <tbody class="bg-guild-900 divide-y divide-guild-700">
<tr <tr
v-for="member in filteredMembers" v-for="member in filteredMembers"
:key="member._id" :key="member._id"
class="hover:bg-gray-50" class="hover:bg-guild-800"
> >
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-gray-900"> <div class="text-sm font-medium text-guild-100">
{{ member.name }} {{ member.name }}
</div> </div>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-600">{{ member.email }}</div> <div class="text-sm text-guild-400">{{ member.email }}</div>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
<span <span
@ -117,7 +117,7 @@
</td> </td>
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
<span <span
class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800" class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-candlelight-900/20 text-candlelight-400"
> >
${{ member.contributionTier }}/month ${{ member.contributionTier }}/month
</span> </span>
@ -126,28 +126,28 @@
<span <span
:class=" :class="
member.slackInvited member.slackInvited
? 'bg-green-100 text-green-800' ? 'bg-candlelight-900/20 text-candlelight-400'
: 'bg-gray-100 text-gray-800' : 'bg-guild-800 text-guild-300'
" "
class="inline-flex px-2 py-1 text-xs font-semibold rounded-full" class="inline-flex px-2 py-1 text-xs font-semibold rounded-full"
> >
{{ member.slackInvited ? "Invited" : "Pending" }} {{ member.slackInvited ? "Invited" : "Pending" }}
</span> </span>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600"> <td class="px-6 py-4 whitespace-nowrap text-sm text-guild-400 text-ui-mono">
{{ formatDate(member.createdAt) }} {{ formatDate(member.createdAt) }}
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600"> <td class="px-6 py-4 whitespace-nowrap text-sm text-guild-400">
<div class="flex gap-2"> <div class="flex gap-2">
<button <button
@click="sendSlackInvite(member)" @click="sendSlackInvite(member)"
class="text-primary-600 hover:text-primary-900" class="text-candlelight-400 hover:text-candlelight-300"
> >
Slack Invite Slack Invite
</button> </button>
<button <button
@click="editMember(member)" @click="editMember(member)"
class="text-primary-600 hover:text-primary-900" class="text-candlelight-400 hover:text-candlelight-300"
> >
Edit Edit
</button> </button>
@ -159,7 +159,7 @@
<div <div
v-if="!pending && !error && filteredMembers.length === 0" v-if="!pending && !error && filteredMembers.length === 0"
class="p-8 text-center text-gray-500" class="p-8 text-center text-guild-500"
> >
No members found matching your criteria No members found matching your criteria
</div> </div>
@ -171,26 +171,26 @@
v-if="showCreateModal" v-if="showCreateModal"
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
> >
<div class="bg-white rounded-lg shadow-xl max-w-md w-full mx-4"> <div class="bg-guild-900 rounded-lg shadow-xl max-w-md w-full mx-4 border border-guild-700">
<div class="px-6 py-4 border-b"> <div class="px-6 py-4 border-b border-guild-700">
<h3 class="text-lg font-semibold">Add New Member</h3> <h3 class="text-display-sm font-semibold text-guild-100">Add New Member</h3>
</div> </div>
<form @submit.prevent="createMember" class="p-6 space-y-4"> <form @submit.prevent="createMember" class="p-6 space-y-4">
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Name</label >Name</label
> >
<input <input
v-model="newMember.name" v-model="newMember.name"
placeholder="Full name" placeholder="Full name"
required required
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="w-full border border-guild-700 bg-guild-800 text-guild-100 placeholder-guild-500 rounded-lg px-3 py-2 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
/> />
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Email</label >Email</label
> >
<input <input
@ -198,17 +198,17 @@
type="email" type="email"
placeholder="email@example.com" placeholder="email@example.com"
required required
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="w-full border border-guild-700 bg-guild-800 text-guild-100 placeholder-guild-500 rounded-lg px-3 py-2 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
/> />
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Circle</label >Circle</label
> >
<select <select
v-model="newMember.circle" v-model="newMember.circle"
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="w-full border border-guild-700 bg-guild-800 text-guild-100 rounded-lg px-3 py-2 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
> >
<option value="community">Community</option> <option value="community">Community</option>
<option value="founder">Founder</option> <option value="founder">Founder</option>
@ -217,12 +217,12 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Contribution Tier</label >Contribution Tier</label
> >
<select <select
v-model="newMember.contributionTier" v-model="newMember.contributionTier"
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="w-full border border-guild-700 bg-guild-800 text-guild-100 rounded-lg px-3 py-2 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
> >
<option value="0">$0/month</option> <option value="0">$0/month</option>
<option value="5">$5/month</option> <option value="5">$5/month</option>
@ -236,14 +236,14 @@
<button <button
type="button" type="button"
@click="showCreateModal = false" @click="showCreateModal = false"
class="px-4 py-2 text-gray-600 hover:text-gray-900" class="px-4 py-2 text-guild-400 hover:text-guild-100"
> >
Cancel Cancel
</button> </button>
<button <button
type="submit" type="submit"
:disabled="creating" :disabled="creating"
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed" class="bg-candlelight-600 text-white px-4 py-2 rounded-lg hover:bg-candlelight-700 disabled:opacity-50 disabled:cursor-not-allowed"
> >
{{ creating ? "Creating..." : "Create Member" }} {{ creating ? "Creating..." : "Create Member" }}
</button> </button>
@ -296,11 +296,11 @@ const filteredMembers = computed(() => {
const getCircleClasses = (circle) => { const getCircleClasses = (circle) => {
const classes = { const classes = {
community: "bg-blue-100 text-blue-800", community: "bg-candlelight-900/20 text-candlelight-400",
founder: "bg-purple-100 text-purple-800", founder: "bg-earth-900/20 text-earth-400",
practitioner: "bg-green-100 text-green-800", practitioner: "bg-candlelight-900/20 text-candlelight-400",
}; };
return classes[circle] || "bg-gray-100 text-gray-800"; return classes[circle] || "bg-guild-800 text-guild-300";
}; };
const formatDate = (dateString) => { const formatDate = (dateString) => {

View file

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<div class="bg-elevated border-b border-default"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<h1 class="text-2xl font-bold text-highlighted">Member Management</h1> <h1 class="text-display font-bold text-guild-100">Member Management</h1>
<p class="text-muted"> <p class="text-guild-400">
Manage Ghost Guild members, their contributions, and access levels Manage Ghost Guild members, their contributions, and access levels
</p> </p>
</div> </div>
@ -18,11 +18,11 @@
<input <input
v-model="searchQuery" v-model="searchQuery"
placeholder="Search members..." placeholder="Search members..."
class="border border-default bg-elevated text-default placeholder-dimmed rounded-lg px-4 py-2 w-80 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="border border-guild-700 bg-guild-900 text-guild-100 placeholder-guild-500 rounded-lg px-4 py-2 w-80 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
/> />
<select <select
v-model="circleFilter" v-model="circleFilter"
class="border border-default bg-elevated text-default rounded-lg px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="border border-guild-700 bg-guild-900 text-guild-100 rounded-lg px-4 py-2 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
> >
<option value="">All Circles</option> <option value="">All Circles</option>
<option value="community">Community</option> <option value="community">Community</option>
@ -32,80 +32,80 @@
</div> </div>
<button <button
@click="showCreateModal = true" @click="showCreateModal = true"
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2" class="bg-candlelight-600 text-white px-4 py-2 rounded-lg hover:bg-candlelight-700 focus:ring-2 focus:ring-candlelight-500 focus:ring-offset-2"
> >
Add Member Add Member
</button> </button>
</div> </div>
<!-- Members Table --> <!-- Members Table -->
<div class="bg-elevated rounded-lg shadow overflow-hidden"> <div class="bg-guild-900 rounded-lg shadow overflow-hidden">
<div v-if="pending" class="p-8 text-center text-default"> <div v-if="pending" class="p-8 text-center text-guild-100">
<div class="inline-flex items-center"> <div class="inline-flex items-center">
<div <div
class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600 mr-3" class="animate-spin rounded-full h-6 w-6 border-b-2 border-candlelight-500 mr-3"
></div> ></div>
Loading members... Loading members...
</div> </div>
</div> </div>
<div v-else-if="error" class="p-8 text-center text-red-600"> <div v-else-if="error" class="p-8 text-center text-ember-400">
Error loading members: {{ error }} Error loading members: {{ error }}
</div> </div>
<table v-else class="w-full"> <table v-else class="w-full">
<thead class="bg-muted"> <thead class="bg-guild-950">
<tr> <tr>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Name Name
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Email Email
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Circle Circle
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Contribution Contribution
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Slack Status Slack Status
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Joined Joined
</th> </th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-dimmed uppercase tracking-wider" class="px-6 py-3 text-left text-xs font-medium text-guild-500 uppercase tracking-wider"
> >
Actions Actions
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody class="bg-elevated divide-y divide-default"> <tbody class="bg-guild-900 divide-y divide-guild-700">
<tr <tr
v-for="member in filteredMembers" v-for="member in filteredMembers"
:key="member._id" :key="member._id"
class="hover:bg-muted" class="hover:bg-guild-800"
> >
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-highlighted"> <div class="text-sm font-medium text-guild-100">
{{ member.name }} {{ member.name }}
</div> </div>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-muted"> <div class="text-sm text-guild-400">
{{ member.email }} {{ member.email }}
</div> </div>
</td> </td>
@ -119,7 +119,7 @@
</td> </td>
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
<span <span
class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800" class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-candlelight-900/20 text-candlelight-400"
> >
${{ member.contributionTier }}/month ${{ member.contributionTier }}/month
</span> </span>
@ -128,28 +128,28 @@
<span <span
:class=" :class="
member.slackInvited member.slackInvited
? 'bg-green-100 text-green-800' ? 'bg-candlelight-900/20 text-candlelight-400'
: 'bg-accented text-default' : 'bg-guild-800 text-guild-300'
" "
class="inline-flex px-2 py-1 text-xs font-semibold rounded-full" class="inline-flex px-2 py-1 text-xs font-semibold rounded-full"
> >
{{ member.slackInvited ? "Invited" : "Pending" }} {{ member.slackInvited ? "Invited" : "Pending" }}
</span> </span>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-muted"> <td class="px-6 py-4 whitespace-nowrap text-sm text-guild-400 text-ui-mono">
{{ formatDate(member.createdAt) }} {{ formatDate(member.createdAt) }}
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-muted"> <td class="px-6 py-4 whitespace-nowrap text-sm text-guild-400">
<div class="flex gap-2"> <div class="flex gap-2">
<button <button
@click="sendSlackInvite(member)" @click="sendSlackInvite(member)"
class="text-primary hover:text-primary" class="text-candlelight-400 hover:text-candlelight-300"
> >
Slack Invite Slack Invite
</button> </button>
<button <button
@click="editMember(member)" @click="editMember(member)"
class="text-primary hover:text-primary" class="text-candlelight-400 hover:text-candlelight-300"
> >
Edit Edit
</button> </button>
@ -161,7 +161,7 @@
<div <div
v-if="!pending && !error && filteredMembers.length === 0" v-if="!pending && !error && filteredMembers.length === 0"
class="p-8 text-center text-dimmed" class="p-8 text-center text-guild-500"
> >
No members found matching your criteria No members found matching your criteria
</div> </div>
@ -173,26 +173,26 @@
v-if="showCreateModal" v-if="showCreateModal"
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
> >
<div class="bg-elevated rounded-lg shadow-xl max-w-md w-full mx-4"> <div class="bg-guild-900 rounded-lg shadow-xl max-w-md w-full mx-4 border border-guild-700">
<div class="px-6 py-4 border-b border-default"> <div class="px-6 py-4 border-b border-guild-700">
<h3 class="text-lg font-semibold text-highlighted">Add New Member</h3> <h3 class="text-display-sm font-semibold text-guild-100">Add New Member</h3>
</div> </div>
<form @submit.prevent="createMember" class="p-6 space-y-4"> <form @submit.prevent="createMember" class="p-6 space-y-4">
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Name</label >Name</label
> >
<input <input
v-model="newMember.name" v-model="newMember.name"
placeholder="Full name" placeholder="Full name"
required required
class="w-full border border-default bg-elevated text-default placeholder-dimmed rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="w-full border border-guild-700 bg-guild-800 text-guild-100 placeholder-guild-500 rounded-lg px-3 py-2 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
/> />
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Email</label >Email</label
> >
<input <input
@ -200,12 +200,12 @@
type="email" type="email"
placeholder="email@example.com" placeholder="email@example.com"
required required
class="w-full border border-default bg-elevated text-default placeholder-dimmed rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-transparent" class="w-full border border-guild-700 bg-guild-800 text-guild-100 placeholder-guild-500 rounded-lg px-3 py-2 focus:ring-2 focus:ring-candlelight-500 focus:border-transparent"
/> />
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Circle</label >Circle</label
> >
<USelect <USelect
@ -220,7 +220,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-1" <label class="block text-sm font-medium text-guild-100 mb-1"
>Contribution Tier</label >Contribution Tier</label
> >
<USelect <USelect
@ -240,14 +240,14 @@
<button <button
type="button" type="button"
@click="showCreateModal = false" @click="showCreateModal = false"
class="px-4 py-2 text-muted hover:text-default" class="px-4 py-2 text-guild-400 hover:text-guild-100"
> >
Cancel Cancel
</button> </button>
<button <button
type="submit" type="submit"
:disabled="creating" :disabled="creating"
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed" class="bg-candlelight-600 text-white px-4 py-2 rounded-lg hover:bg-candlelight-700 disabled:opacity-50 disabled:cursor-not-allowed"
> >
{{ creating ? "Creating..." : "Create Member" }} {{ creating ? "Creating..." : "Create Member" }}
</button> </button>
@ -300,11 +300,11 @@ const filteredMembers = computed(() => {
const getCircleClasses = (circle) => { const getCircleClasses = (circle) => {
const classes = { const classes = {
community: "bg-blue-100 text-blue-800", community: "bg-candlelight-900/20 text-candlelight-400",
founder: "bg-purple-100 text-purple-800", founder: "bg-earth-900/20 text-earth-400",
practitioner: "bg-green-100 text-green-800", practitioner: "bg-candlelight-900/20 text-candlelight-400",
}; };
return classes[circle] || "bg-gray-100 text-gray-800"; return classes[circle] || "bg-guild-800 text-guild-300";
}; };
const formatDate = (dateString) => { const formatDate = (dateString) => {

View file

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<div class="bg-elevated border-b border-default"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<h1 class="text-2xl font-bold text-highlighted">Series Management</h1> <h1 class="text-display font-bold text-guild-100">Series Management</h1>
<p class="text-muted">Manage event series and their relationships</p> <p class="text-guild-400">Manage event series and their relationships</p>
</div> </div>
</div> </div>
</div> </div>
@ -13,49 +13,49 @@
<!-- Series Overview --> <!-- Series Overview -->
<div class="mb-8"> <div class="mb-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6"> <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center"> <div class="flex items-center">
<div class="p-3 bg-purple-100 rounded-full"> <div class="p-3 bg-earth-900/20 rounded-full">
<Icon <Icon
name="heroicons:squares-2x2" name="heroicons:squares-2x2"
class="w-6 h-6 text-purple-600" class="w-6 h-6 text-earth-400"
/> />
</div> </div>
<div class="ml-4"> <div class="ml-4">
<p class="text-sm text-dimmed">Active Series</p> <p class="text-sm text-guild-500">Active Series</p>
<p class="text-2xl font-semibold text-highlighted"> <p class="text-2xl font-semibold text-guild-100 text-ui-mono">
{{ activeSeries.length }} {{ activeSeries.length }}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center"> <div class="flex items-center">
<div class="p-3 bg-blue-100 rounded-full"> <div class="p-3 bg-candlelight-900/20 rounded-full">
<Icon <Icon
name="heroicons:calendar-days" name="heroicons:calendar-days"
class="w-6 h-6 text-blue-600" class="w-6 h-6 text-candlelight-400"
/> />
</div> </div>
<div class="ml-4"> <div class="ml-4">
<p class="text-sm text-dimmed">Total Series Events</p> <p class="text-sm text-guild-500">Total Series Events</p>
<p class="text-2xl font-semibold text-highlighted"> <p class="text-2xl font-semibold text-guild-100 text-ui-mono">
{{ totalSeriesEvents }} {{ totalSeriesEvents }}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div class="bg-elevated rounded-lg shadow p-6"> <div class="bg-guild-900 rounded-lg shadow p-6">
<div class="flex items-center"> <div class="flex items-center">
<div class="p-3 bg-green-100 rounded-full"> <div class="p-3 bg-candlelight-900/20 rounded-full">
<Icon <Icon
name="heroicons:chart-bar" name="heroicons:chart-bar"
class="w-6 h-6 text-green-600" class="w-6 h-6 text-candlelight-400"
/> />
</div> </div>
<div class="ml-4"> <div class="ml-4">
<p class="text-sm text-dimmed">Avg Events/Series</p> <p class="text-sm text-guild-500">Avg Events/Series</p>
<p class="text-2xl font-semibold text-highlighted"> <p class="text-2xl font-semibold text-guild-100 text-ui-mono">
{{ {{
activeSeries.length > 0 activeSeries.length > 0
? Math.round(totalSeriesEvents / activeSeries.length) ? Math.round(totalSeriesEvents / activeSeries.length)
@ -74,11 +74,11 @@
<input <input
v-model="searchQuery" v-model="searchQuery"
placeholder="Search series..." placeholder="Search series..."
class="border border-default bg-elevated text-default placeholder-dimmed rounded-lg px-4 py-2 w-80 focus:ring-2 focus:ring-purple-500 focus:border-transparent" class="border border-guild-700 bg-guild-900 text-guild-100 placeholder-guild-500 rounded-lg px-4 py-2 w-80 focus:ring-2 focus:ring-earth-500 focus:border-transparent"
/> />
<select <select
v-model="statusFilter" v-model="statusFilter"
class="border border-default bg-elevated text-default rounded-lg px-4 py-2 focus:ring-2 focus:ring-purple-500 focus:border-transparent" class="border border-guild-700 bg-guild-900 text-guild-100 rounded-lg px-4 py-2 focus:ring-2 focus:ring-earth-500 focus:border-transparent"
> >
<option value="">All Status</option> <option value="">All Status</option>
<option value="active">Active</option> <option value="active">Active</option>
@ -89,14 +89,14 @@
<div class="flex gap-3"> <div class="flex gap-3">
<button <button
@click="showBulkModal = true" @click="showBulkModal = true"
class="bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 inline-flex items-center" class="bg-guild-600 text-white px-4 py-2 rounded-lg hover:bg-guild-700 inline-flex items-center"
> >
<Icon name="heroicons:cog-6-tooth" class="w-4 h-4 mr-2" /> <Icon name="heroicons:cog-6-tooth" class="w-4 h-4 mr-2" />
Bulk Operations Bulk Operations
</button> </button>
<NuxtLink <NuxtLink
to="/admin/series/create" to="/admin/series/create"
class="bg-purple-600 text-white px-4 py-2 rounded-lg hover:bg-purple-700 inline-flex items-center" class="bg-earth-600 text-white px-4 py-2 rounded-lg hover:bg-earth-700 inline-flex items-center"
> >
<Icon name="heroicons:plus" class="w-4 h-4 mr-2" /> <Icon name="heroicons:plus" class="w-4 h-4 mr-2" />
Create Series Create Series
@ -107,19 +107,19 @@
<!-- Series List --> <!-- Series List -->
<div v-if="pending" class="text-center py-12"> <div v-if="pending" class="text-center py-12">
<div <div
class="animate-spin rounded-full h-8 w-8 border-b-2 border-purple-500 mx-auto mb-4" class="animate-spin rounded-full h-8 w-8 border-b-2 border-earth-500 mx-auto mb-4"
></div> ></div>
<p class="text-muted">Loading series...</p> <p class="text-guild-400">Loading series...</p>
</div> </div>
<div v-else-if="filteredSeries.length > 0" class="space-y-6"> <div v-else-if="filteredSeries.length > 0" class="space-y-6">
<div <div
v-for="series in filteredSeries" v-for="series in filteredSeries"
:key="series.id" :key="series.id"
class="bg-elevated rounded-lg shadow overflow-hidden" class="bg-guild-900 rounded-lg shadow overflow-hidden"
> >
<!-- Series Header --> <!-- Series Header -->
<div class="px-6 py-4 bg-muted border-b border-default"> <div class="px-6 py-4 bg-guild-950 border-b border-guild-700">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<div <div
@ -131,10 +131,10 @@
{{ formatSeriesType(series.type) }} {{ formatSeriesType(series.type) }}
</div> </div>
<div> <div>
<h3 class="text-lg font-semibold text-highlighted"> <h3 class="text-display-sm font-semibold text-guild-100">
{{ series.title }} {{ series.title }}
</h3> </h3>
<p class="text-sm text-muted">{{ series.description }}</p> <p class="text-sm text-guild-400">{{ series.description }}</p>
</div> </div>
</div> </div>
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
@ -142,15 +142,15 @@
:class="[ :class="[
'inline-flex items-center px-2 py-1 rounded-full text-xs font-medium', 'inline-flex items-center px-2 py-1 rounded-full text-xs font-medium',
series.status === 'active' series.status === 'active'
? 'bg-green-100 text-green-700' ? 'bg-candlelight-900/20 text-candlelight-400'
: series.status === 'upcoming' : series.status === 'upcoming'
? 'bg-blue-100 text-blue-700' ? 'bg-earth-900/20 text-earth-400'
: 'bg-accented text-default', : 'bg-guild-800 text-guild-300',
]" ]"
> >
{{ series.status }} {{ series.status }}
</span> </span>
<span class="text-sm text-dimmed"> <span class="text-sm text-guild-500">
{{ series.eventCount }} events {{ series.eventCount }} events
</span> </span>
</div> </div>
@ -158,24 +158,24 @@
</div> </div>
<!-- Series Events --> <!-- Series Events -->
<div class="divide-y divide-default"> <div class="divide-y divide-guild-700">
<div <div
v-for="event in series.events" v-for="event in series.events"
:key="event.id" :key="event.id"
class="px-6 py-4 hover:bg-muted" class="px-6 py-4 hover:bg-guild-800"
> >
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<div <div
class="w-8 h-8 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center text-sm font-semibold" class="w-8 h-8 bg-earth-800 text-earth-400 rounded-full flex items-center justify-center text-sm font-semibold"
> >
{{ event.series?.position || "?" }} {{ event.series?.position || "?" }}
</div> </div>
<div> <div>
<h4 class="text-sm font-medium text-highlighted"> <h4 class="text-sm font-medium text-guild-100">
{{ event.title }} {{ event.title }}
</h4> </h4>
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
{{ formatEventDate(event.startDate) }} {{ formatEventDate(event.startDate) }}
</p> </p>
</div> </div>
@ -192,21 +192,21 @@
<div class="flex gap-1"> <div class="flex gap-1">
<NuxtLink <NuxtLink
:to="`/events/${event.slug || event.id}`" :to="`/events/${event.slug || event.id}`"
class="p-1 text-muted hover:text-default rounded" class="p-1 text-guild-500 hover:text-guild-100 rounded"
title="View Event" title="View Event"
> >
<Icon name="heroicons:eye" class="w-4 h-4" /> <Icon name="heroicons:eye" class="w-4 h-4" />
</NuxtLink> </NuxtLink>
<button <button
@click="editEvent(event)" @click="editEvent(event)"
class="p-1 text-muted hover:text-primary rounded" class="p-1 text-candlelight-400 hover:text-candlelight-300 rounded"
title="Edit Event" title="Edit Event"
> >
<Icon name="heroicons:pencil-square" class="w-4 h-4" /> <Icon name="heroicons:pencil-square" class="w-4 h-4" />
</button> </button>
<button <button
@click="removeFromSeries(event)" @click="removeFromSeries(event)"
class="p-1 text-muted hover:text-red-600 rounded" class="p-1 text-ember-400 hover:text-ember-300 rounded"
title="Remove from Series" title="Remove from Series"
> >
<Icon name="heroicons:x-mark" class="w-4 h-4" /> <Icon name="heroicons:x-mark" class="w-4 h-4" />
@ -220,16 +220,16 @@
<!-- Series Ticketing Info --> <!-- Series Ticketing Info -->
<div <div
v-if="series.tickets?.enabled" v-if="series.tickets?.enabled"
class="px-6 py-3 bg-blue-50 dark:bg-blue-950/20 border-t border-default" class="px-6 py-3 bg-candlelight-900/20 border-t border-guild-700"
> >
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<Icon name="heroicons:ticket" class="w-5 h-5 text-blue-600" /> <Icon name="heroicons:ticket" class="w-5 h-5 text-candlelight-400" />
<div> <div>
<span class="text-sm font-medium text-default"> <span class="text-sm font-medium text-guild-100">
Series Pass Ticketing Enabled Series Pass Ticketing Enabled
</span> </span>
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
<span v-if="series.tickets.public?.available"> <span v-if="series.tickets.public?.available">
Public: ${{ series.tickets.public.price || 0 }} Public: ${{ series.tickets.public.price || 0 }}
</span> </span>
@ -246,7 +246,7 @@
</div> </div>
<button <button
@click="manageSeriesTickets(series)" @click="manageSeriesTickets(series)"
class="text-sm text-blue-600 hover:text-blue-700 font-medium" class="text-sm text-candlelight-400 hover:text-candlelight-300 font-medium"
> >
Manage Tickets Manage Tickets
</button> </button>
@ -254,39 +254,39 @@
</div> </div>
<!-- Series Actions --> <!-- Series Actions -->
<div class="px-6 py-3 bg-muted border-t border-default"> <div class="px-6 py-3 bg-guild-950 border-t border-guild-700">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<div class="text-sm text-dimmed"> <div class="text-sm text-guild-500">
{{ formatDateRange(series.startDate, series.endDate) }} {{ formatDateRange(series.startDate, series.endDate) }}
</div> </div>
<div class="flex gap-2"> <div class="flex gap-2">
<button <button
@click="manageSeriesTickets(series)" @click="manageSeriesTickets(series)"
class="text-sm text-primary hover:text-primary font-medium" class="text-sm text-candlelight-400 hover:text-candlelight-300 font-medium"
> >
Ticketing Ticketing
</button> </button>
<button <button
@click="editSeries(series)" @click="editSeries(series)"
class="text-sm text-primary hover:text-primary font-medium" class="text-sm text-candlelight-400 hover:text-candlelight-300 font-medium"
> >
Edit Series Edit Series
</button> </button>
<button <button
@click="addEventToSeries(series)" @click="addEventToSeries(series)"
class="text-sm text-primary hover:text-primary font-medium" class="text-sm text-candlelight-400 hover:text-candlelight-300 font-medium"
> >
Add Event Add Event
</button> </button>
<button <button
@click="duplicateSeries(series)" @click="duplicateSeries(series)"
class="text-sm text-primary hover:text-primary font-medium" class="text-sm text-candlelight-400 hover:text-candlelight-300 font-medium"
> >
Duplicate Series Duplicate Series
</button> </button>
<button <button
@click="deleteSeries(series)" @click="deleteSeries(series)"
class="text-sm text-red-600 hover:text-red-700 font-medium" class="text-sm text-ember-400 hover:text-ember-300 font-medium"
> >
Delete Series Delete Series
</button> </button>
@ -296,13 +296,13 @@
</div> </div>
</div> </div>
<div v-else class="text-center py-12 bg-elevated rounded-lg shadow"> <div v-else class="text-center py-12 bg-guild-900 rounded-lg shadow">
<Icon <Icon
name="heroicons:squares-2x2" name="heroicons:squares-2x2"
class="w-12 h-12 text-muted mx-auto mb-3" class="w-12 h-12 text-guild-400 mx-auto mb-3"
/> />
<p class="text-muted">No event series found</p> <p class="text-guild-400">No event series found</p>
<p class="text-sm text-dimmed mt-2"> <p class="text-sm text-guild-500 mt-2">
Create events and group them into series to get started Create events and group them into series to get started
</p> </p>
</div> </div>
@ -311,17 +311,17 @@
<!-- Edit Series Modal --> <!-- Edit Series Modal -->
<div <div
v-if="editingSeriesId" v-if="editingSeriesId"
class="fixed inset-0 bg-gray-600 bg-opacity-50 flex items-center justify-center p-4 z-50" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50"
> >
<div <div
class="bg-elevated rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto" class="bg-guild-900 rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto"
> >
<div class="px-6 py-4 border-b border-default"> <div class="px-6 py-4 border-b border-guild-700">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<h3 class="text-lg font-semibold text-highlighted">Edit Series</h3> <h3 class="text-display-sm font-semibold text-guild-100">Edit Series</h3>
<button <button
@click="cancelEditSeries" @click="cancelEditSeries"
class="text-muted hover:text-default" class="text-guild-400 hover:text-guild-100"
> >
<Icon name="heroicons:x-mark" class="w-5 h-5" /> <Icon name="heroicons:x-mark" class="w-5 h-5" />
</button> </button>
@ -330,31 +330,31 @@
<div class="p-6 space-y-6"> <div class="p-6 space-y-6">
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Series Title</label >Series Title</label
> >
<input <input
v-model="editingSeriesData.title" v-model="editingSeriesData.title"
type="text" type="text"
class="w-full border border-default bg-elevated text-default placeholder-dimmed rounded-lg px-4 py-2 focus:ring-2 focus:ring-purple-500 focus:border-transparent" class="w-full border border-guild-700 bg-guild-900 text-guild-100 placeholder-guild-500 rounded-lg px-4 py-2 focus:ring-2 focus:ring-earth-500 focus:border-transparent"
placeholder="e.g., Co-op Game Dev Workshop Series" placeholder="e.g., Co-op Game Dev Workshop Series"
/> />
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Description</label >Description</label
> >
<textarea <textarea
v-model="editingSeriesData.description" v-model="editingSeriesData.description"
rows="3" rows="3"
class="w-full border border-default bg-elevated text-default placeholder-dimmed rounded-lg px-4 py-2 focus:ring-2 focus:ring-purple-500 focus:border-transparent" class="w-full border border-guild-700 bg-guild-900 text-guild-100 placeholder-guild-500 rounded-lg px-4 py-2 focus:ring-2 focus:ring-earth-500 focus:border-transparent"
placeholder="Brief description of this series" placeholder="Brief description of this series"
/> />
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Series Type</label >Series Type</label
> >
<USelect <USelect
@ -370,7 +370,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Total Events (optional)</label >Total Events (optional)</label
> >
<UInput <UInput
@ -383,16 +383,16 @@
</div> </div>
</div> </div>
<div class="px-6 py-4 border-t border-default flex justify-end gap-3"> <div class="px-6 py-4 border-t border-guild-700 flex justify-end gap-3">
<button <button
@click="cancelEditSeries" @click="cancelEditSeries"
class="px-4 py-2 text-muted hover:text-default" class="px-4 py-2 text-guild-400 hover:text-guild-100"
> >
Cancel Cancel
</button> </button>
<button <button
@click="saveSeriesEdit" @click="saveSeriesEdit"
class="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700" class="px-4 py-2 bg-earth-600 text-white rounded-lg hover:bg-earth-700"
> >
Save Changes Save Changes
</button> </button>
@ -403,19 +403,19 @@
<!-- Bulk Operations Modal --> <!-- Bulk Operations Modal -->
<div <div
v-if="showBulkModal" v-if="showBulkModal"
class="fixed inset-0 bg-gray-600 bg-opacity-50 flex items-center justify-center p-4 z-50" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50"
> >
<div <div
class="bg-elevated rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto" class="bg-guild-900 rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto"
> >
<div class="px-6 py-4 border-b border-default"> <div class="px-6 py-4 border-b border-guild-700">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<h3 class="text-lg font-semibold text-highlighted"> <h3 class="text-display-sm font-semibold text-guild-100">
Bulk Series Operations Bulk Series Operations
</h3> </h3>
<button <button
@click="showBulkModal = false" @click="showBulkModal = false"
class="text-muted hover:text-default" class="text-guild-400 hover:text-guild-100"
> >
<Icon name="heroicons:x-mark" class="w-5 h-5" /> <Icon name="heroicons:x-mark" class="w-5 h-5" />
</button> </button>
@ -424,24 +424,24 @@
<div class="p-6 space-y-6"> <div class="p-6 space-y-6">
<div> <div>
<h4 class="text-sm font-medium text-highlighted mb-3"> <h4 class="text-sm font-medium text-guild-100 mb-3">
Series Management Tools Series Management Tools
</h4> </h4>
<div class="space-y-3"> <div class="space-y-3">
<button <button
@click="reorderAllSeries" @click="reorderAllSeries"
class="w-full text-left p-3 border border-default rounded-lg hover:bg-muted" class="w-full text-left p-3 border border-guild-700 rounded-lg hover:bg-guild-800"
> >
<div class="flex items-center"> <div class="flex items-center">
<Icon <Icon
name="heroicons:arrows-up-down" name="heroicons:arrows-up-down"
class="w-5 h-5 text-muted mr-3" class="w-5 h-5 text-guild-400 mr-3"
/> />
<div> <div>
<p class="text-sm font-medium text-highlighted"> <p class="text-sm font-medium text-guild-100">
Auto-Reorder Series Auto-Reorder Series
</p> </p>
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Fix position numbers based on event dates Fix position numbers based on event dates
</p> </p>
</div> </div>
@ -450,18 +450,18 @@
<button <button
@click="validateAllSeries" @click="validateAllSeries"
class="w-full text-left p-3 border border-default rounded-lg hover:bg-muted" class="w-full text-left p-3 border border-guild-700 rounded-lg hover:bg-guild-800"
> >
<div class="flex items-center"> <div class="flex items-center">
<Icon <Icon
name="heroicons:check-circle" name="heroicons:check-circle"
class="w-5 h-5 text-muted mr-3" class="w-5 h-5 text-guild-400 mr-3"
/> />
<div> <div>
<p class="text-sm font-medium text-highlighted"> <p class="text-sm font-medium text-guild-100">
Validate Series Data Validate Series Data
</p> </p>
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Check for consistency issues Check for consistency issues
</p> </p>
</div> </div>
@ -470,18 +470,18 @@
<button <button
@click="exportSeriesData" @click="exportSeriesData"
class="w-full text-left p-3 border border-default rounded-lg hover:bg-muted" class="w-full text-left p-3 border border-guild-700 rounded-lg hover:bg-guild-800"
> >
<div class="flex items-center"> <div class="flex items-center">
<Icon <Icon
name="heroicons:document-arrow-down" name="heroicons:document-arrow-down"
class="w-5 h-5 text-muted mr-3" class="w-5 h-5 text-guild-400 mr-3"
/> />
<div> <div>
<p class="text-sm font-medium text-highlighted"> <p class="text-sm font-medium text-guild-100">
Export Series Data Export Series Data
</p> </p>
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Download series information as JSON Download series information as JSON
</p> </p>
</div> </div>
@ -491,10 +491,10 @@
</div> </div>
</div> </div>
<div class="px-6 py-4 border-t border-default flex justify-end"> <div class="px-6 py-4 border-t border-guild-700 flex justify-end">
<button <button
@click="showBulkModal = false" @click="showBulkModal = false"
class="px-4 py-2 text-muted hover:text-default" class="px-4 py-2 text-guild-400 hover:text-guild-100"
> >
Close Close
</button> </button>
@ -505,22 +505,22 @@
<!-- Series Ticketing Modal --> <!-- Series Ticketing Modal -->
<div <div
v-if="editingTicketsSeriesId" v-if="editingTicketsSeriesId"
class="fixed inset-0 bg-gray-600 bg-opacity-50 flex items-center justify-center p-4 z-50" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50"
> >
<div <div
class="bg-elevated rounded-lg shadow-xl max-w-4xl w-full max-h-[90vh] overflow-y-auto" class="bg-guild-900 rounded-lg shadow-xl max-w-4xl w-full max-h-[90vh] overflow-y-auto"
> >
<div class="px-6 py-4 border-b border-default"> <div class="px-6 py-4 border-b border-guild-700">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<h3 class="text-lg font-semibold text-highlighted"> <h3 class="text-display-sm font-semibold text-guild-100">
Series Pass Ticketing Series Pass Ticketing
</h3> </h3>
<p class="text-sm text-muted">{{ editingTicketsData.title }}</p> <p class="text-sm text-guild-400">{{ editingTicketsData.title }}</p>
</div> </div>
<button <button
@click="cancelTicketsEdit" @click="cancelTicketsEdit"
class="text-muted hover:text-default" class="text-guild-400 hover:text-guild-100"
> >
<Icon name="heroicons:x-mark" class="w-5 h-5" /> <Icon name="heroicons:x-mark" class="w-5 h-5" />
</button> </button>
@ -529,18 +529,18 @@
<div class="p-6 space-y-6"> <div class="p-6 space-y-6">
<!-- Enable Ticketing Toggle --> <!-- Enable Ticketing Toggle -->
<div class="p-4 bg-muted rounded-lg"> <div class="p-4 bg-guild-950 rounded-lg">
<label class="flex items-start cursor-pointer"> <label class="flex items-start cursor-pointer">
<input <input
v-model="editingTicketsData.tickets.enabled" v-model="editingTicketsData.tickets.enabled"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Enable Series Pass Ticketing</span >Enable Series Pass Ticketing</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Allow users to purchase a pass for all events in this series Allow users to purchase a pass for all events in this series
</p> </p>
</div> </div>
@ -550,7 +550,7 @@
<div v-if="editingTicketsData.tickets.enabled" class="space-y-6"> <div v-if="editingTicketsData.tickets.enabled" class="space-y-6">
<!-- Ticketing Behavior --> <!-- Ticketing Behavior -->
<div class="space-y-4"> <div class="space-y-4">
<h4 class="text-sm font-semibold text-highlighted"> <h4 class="text-sm font-semibold text-guild-100">
Ticketing Behavior Ticketing Behavior
</h4> </h4>
@ -558,13 +558,13 @@
<input <input
v-model="editingTicketsData.tickets.requiresSeriesTicket" v-model="editingTicketsData.tickets.requiresSeriesTicket"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Require Series Pass</span >Require Series Pass</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Users must buy the series pass; individual event tickets are Users must buy the series pass; individual event tickets are
not available not available
</p> </p>
@ -577,14 +577,14 @@
editingTicketsData.tickets.allowIndividualEventTickets editingTicketsData.tickets.allowIndividualEventTickets
" "
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500 mt-1" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500 mt-1"
:disabled="editingTicketsData.tickets.requiresSeriesTicket" :disabled="editingTicketsData.tickets.requiresSeriesTicket"
/> />
<div class="ml-3"> <div class="ml-3">
<span class="text-sm font-medium text-default" <span class="text-sm font-medium text-guild-100"
>Allow Individual Event Tickets</span >Allow Individual Event Tickets</span
> >
<p class="text-xs text-dimmed"> <p class="text-xs text-guild-500">
Users can attend single events without buying the full Users can attend single events without buying the full
series pass series pass
</p> </p>
@ -593,17 +593,17 @@
</div> </div>
<!-- Member Tickets --> <!-- Member Tickets -->
<div class="border border-default rounded-lg p-4"> <div class="border border-guild-700 rounded-lg p-4">
<div class="flex items-center justify-between mb-4"> <div class="flex items-center justify-between mb-4">
<h4 class="text-sm font-semibold text-highlighted"> <h4 class="text-sm font-semibold text-guild-100">
Member Series Pass Member Series Pass
</h4> </h4>
<label class="flex items-center cursor-pointer"> <label class="flex items-center cursor-pointer">
<span class="text-xs text-muted mr-2">Available</span> <span class="text-xs text-guild-400 mr-2">Available</span>
<input <input
v-model="editingTicketsData.tickets.member.available" v-model="editingTicketsData.tickets.member.available"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500"
/> />
</label> </label>
</div> </div>
@ -614,7 +614,7 @@
> >
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Pass Name</label >Pass Name</label
> >
<UInput <UInput
@ -625,7 +625,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Price (CAD)</label >Price (CAD)</label
> >
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
@ -644,16 +644,16 @@
<input <input
v-model="editingTicketsData.tickets.member.isFree" v-model="editingTicketsData.tickets.member.isFree"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500"
/> />
<span class="ml-1 text-xs text-muted">Free</span> <span class="ml-1 text-xs text-guild-400">Free</span>
</label> </label>
</div> </div>
</div> </div>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Description</label >Description</label
> >
<UTextarea <UTextarea
@ -667,17 +667,17 @@
</div> </div>
<!-- Public Tickets --> <!-- Public Tickets -->
<div class="border border-default rounded-lg p-4"> <div class="border border-guild-700 rounded-lg p-4">
<div class="flex items-center justify-between mb-4"> <div class="flex items-center justify-between mb-4">
<h4 class="text-sm font-semibold text-highlighted"> <h4 class="text-sm font-semibold text-guild-100">
Public Series Pass Public Series Pass
</h4> </h4>
<label class="flex items-center cursor-pointer"> <label class="flex items-center cursor-pointer">
<span class="text-xs text-muted mr-2">Available</span> <span class="text-xs text-guild-400 mr-2">Available</span>
<input <input
v-model="editingTicketsData.tickets.public.available" v-model="editingTicketsData.tickets.public.available"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500"
/> />
</label> </label>
</div> </div>
@ -688,7 +688,7 @@
> >
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Pass Name</label >Pass Name</label
> >
<UInput <UInput
@ -699,7 +699,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Price (CAD)</label >Price (CAD)</label
> >
<UInput <UInput
@ -714,7 +714,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Description</label >Description</label
> >
<UTextarea <UTextarea
@ -727,7 +727,7 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Quantity Available</label >Quantity Available</label
> >
<UInput <UInput
@ -739,7 +739,7 @@
placeholder="Leave blank for unlimited" placeholder="Leave blank for unlimited"
class="w-full" class="w-full"
/> />
<p class="text-xs text-dimmed mt-1"> <p class="text-xs text-guild-500 mt-1">
{{ editingTicketsData.tickets.public.sold || 0 }} sold, {{ editingTicketsData.tickets.public.sold || 0 }} sold,
{{ editingTicketsData.tickets.public.reserved || 0 }} {{ editingTicketsData.tickets.public.reserved || 0 }}
reserved reserved
@ -747,7 +747,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Early Bird Price (Optional)</label >Early Bird Price (Optional)</label
> >
<UInput <UInput
@ -766,7 +766,7 @@
<div <div
v-if="editingTicketsData.tickets.public.earlyBirdPrice > 0" v-if="editingTicketsData.tickets.public.earlyBirdPrice > 0"
> >
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Early Bird Deadline</label >Early Bird Deadline</label
> >
<UInput <UInput
@ -776,7 +776,7 @@
type="datetime-local" type="datetime-local"
class="w-full" class="w-full"
/> />
<p class="text-xs text-dimmed mt-1"> <p class="text-xs text-guild-500 mt-1">
Price increases to ${{ Price increases to ${{
editingTicketsData.tickets.public.price editingTicketsData.tickets.public.price
}} }}
@ -787,14 +787,14 @@
</div> </div>
<!-- Capacity Management --> <!-- Capacity Management -->
<div class="border border-default rounded-lg p-4"> <div class="border border-guild-700 rounded-lg p-4">
<h4 class="text-sm font-semibold text-highlighted mb-4"> <h4 class="text-sm font-semibold text-guild-100 mb-4">
Capacity Management Capacity Management
</h4> </h4>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Total Capacity</label >Total Capacity</label
> >
<UInput <UInput
@ -804,13 +804,13 @@
placeholder="Leave blank for unlimited" placeholder="Leave blank for unlimited"
class="w-full" class="w-full"
/> />
<p class="text-xs text-dimmed mt-1"> <p class="text-xs text-guild-500 mt-1">
Maximum series pass holders across all types Maximum series pass holders across all types
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Currently Reserved</label >Currently Reserved</label
> >
<UInput <UInput
@ -820,9 +820,9 @@
type="number" type="number"
min="0" min="0"
disabled disabled
class="w-full bg-accented" class="w-full bg-guild-800"
/> />
<p class="text-xs text-dimmed mt-1"> <p class="text-xs text-guild-500 mt-1">
Auto-calculated during checkout Auto-calculated during checkout
</p> </p>
</div> </div>
@ -830,21 +830,21 @@
</div> </div>
<!-- Waitlist Configuration --> <!-- Waitlist Configuration -->
<div class="border border-default rounded-lg p-4"> <div class="border border-guild-700 rounded-lg p-4">
<div class="flex items-center justify-between mb-4"> <div class="flex items-center justify-between mb-4">
<h4 class="text-sm font-semibold text-highlighted">Waitlist</h4> <h4 class="text-sm font-semibold text-guild-100">Waitlist</h4>
<label class="flex items-center cursor-pointer"> <label class="flex items-center cursor-pointer">
<span class="text-xs text-muted mr-2">Enable Waitlist</span> <span class="text-xs text-guild-400 mr-2">Enable Waitlist</span>
<input <input
v-model="editingTicketsData.tickets.waitlist.enabled" v-model="editingTicketsData.tickets.waitlist.enabled"
type="checkbox" type="checkbox"
class="rounded border-default text-blue-600 focus:ring-blue-500" class="rounded border-guild-700 text-candlelight-500 focus:ring-candlelight-500"
/> />
</label> </label>
</div> </div>
<div v-if="editingTicketsData.tickets.waitlist.enabled"> <div v-if="editingTicketsData.tickets.waitlist.enabled">
<label class="block text-sm font-medium text-default mb-2" <label class="block text-sm font-medium text-guild-100 mb-2"
>Max Waitlist Size</label >Max Waitlist Size</label
> >
<UInput <UInput
@ -854,7 +854,7 @@
placeholder="Leave blank for unlimited" placeholder="Leave blank for unlimited"
class="w-full" class="w-full"
/> />
<p class="text-xs text-dimmed mt-1"> <p class="text-xs text-guild-500 mt-1">
{{ editingTicketsData.tickets.waitlist.entries?.length || 0 }} {{ editingTicketsData.tickets.waitlist.entries?.length || 0 }}
people currently on waitlist people currently on waitlist
</p> </p>
@ -863,16 +863,16 @@
</div> </div>
</div> </div>
<div class="px-6 py-4 border-t border-default flex justify-end gap-3"> <div class="px-6 py-4 border-t border-guild-700 flex justify-end gap-3">
<button <button
@click="cancelTicketsEdit" @click="cancelTicketsEdit"
class="px-4 py-2 text-muted hover:text-default" class="px-4 py-2 text-guild-400 hover:text-guild-100"
> >
Cancel Cancel
</button> </button>
<button <button
@click="saveTicketsEdit" @click="saveTicketsEdit"
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700" class="px-4 py-2 bg-candlelight-600 text-white rounded-lg hover:bg-candlelight-700"
> >
Save Ticketing Settings Save Ticketing Settings
</button> </button>
@ -986,12 +986,12 @@ const formatSeriesType = (type) => {
const getSeriesTypeBadgeClass = (type) => { const getSeriesTypeBadgeClass = (type) => {
const classes = { const classes = {
workshop_series: "bg-emerald-100 text-emerald-700", workshop_series: "bg-candlelight-900/20 text-candlelight-400",
recurring_meetup: "bg-blue-100 text-blue-700", recurring_meetup: "bg-candlelight-900/20 text-candlelight-400",
multi_day: "bg-purple-100 text-purple-700", multi_day: "bg-earth-900/20 text-earth-400",
course: "bg-amber-100 text-amber-700", course: "bg-candlelight-900/20 text-candlelight-400",
}; };
return classes[type] || "bg-gray-100 text-gray-700"; return classes[type] || "bg-guild-800 text-guild-300";
}; };
const formatEventDate = (date) => { const formatEventDate = (date) => {
@ -1029,11 +1029,11 @@ const getEventStatus = (event) => {
const getEventStatusClass = (event) => { const getEventStatusClass = (event) => {
const status = getEventStatus(event); const status = getEventStatus(event);
const classes = { const classes = {
Upcoming: "bg-blue-100 text-blue-700", Upcoming: "bg-candlelight-900/20 text-candlelight-400",
Ongoing: "bg-green-100 text-green-700", Ongoing: "bg-candlelight-900/20 text-candlelight-400",
Completed: "bg-gray-100 text-gray-700", Completed: "bg-guild-800 text-guild-300",
}; };
return classes[status] || "bg-gray-100 text-gray-700"; return classes[status] || "bg-guild-800 text-guild-300";
}; };
// Actions // Actions

View file

@ -1,27 +1,27 @@
<template> <template>
<div> <div>
<div class="bg-white border-b"> <div class="bg-guild-900 border-b border-guild-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="py-6"> <div class="py-6">
<div class="flex items-center gap-4 mb-2"> <div class="flex items-center gap-4 mb-2">
<NuxtLink to="/admin/series-management" class="text-gray-500 hover:text-gray-700"> <NuxtLink to="/admin/series-management" class="text-guild-500 hover:text-guild-100">
<Icon name="heroicons:arrow-left" class="w-5 h-5" /> <Icon name="heroicons:arrow-left" class="w-5 h-5" />
</NuxtLink> </NuxtLink>
<h1 class="text-2xl font-bold text-gray-900">Create New Series</h1> <h1 class="text-display font-bold text-guild-100">Create New Series</h1>
</div> </div>
<p class="text-gray-600">Create a new event series to group related events together</p> <p class="text-guild-400">Create a new event series to group related events together</p>
</div> </div>
</div> </div>
</div> </div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Error Summary --> <!-- Error Summary -->
<div v-if="formErrors.length > 0" class="mb-6 p-4 bg-red-50 border border-red-200 rounded-lg"> <div v-if="formErrors.length > 0" class="mb-6 p-4 bg-ember-900/20 border border-ember-800 rounded-lg">
<div class="flex"> <div class="flex">
<Icon name="heroicons:exclamation-circle" class="w-5 h-5 text-red-500 mr-3 mt-0.5" /> <Icon name="heroicons:exclamation-circle" class="w-5 h-5 text-ember-400 mr-3 mt-0.5" />
<div> <div>
<h3 class="text-sm font-medium text-red-800 mb-2">Please fix the following errors:</h3> <h3 class="text-sm font-medium text-ember-400 mb-2">Please fix the following errors:</h3>
<ul class="text-sm text-red-700 space-y-1"> <ul class="text-sm text-ember-400 space-y-1">
<li v-for="error in formErrors" :key="error"> {{ error }}</li> <li v-for="error in formErrors" :key="error"> {{ error }}</li>
</ul> </ul>
</div> </div>
@ -29,11 +29,11 @@
</div> </div>
<!-- Success Message --> <!-- Success Message -->
<div v-if="showSuccessMessage" class="mb-6 p-4 bg-green-50 border border-green-200 rounded-lg"> <div v-if="showSuccessMessage" class="mb-6 p-4 bg-candlelight-900/20 border border-candlelight-800 rounded-lg">
<div class="flex"> <div class="flex">
<Icon name="heroicons:check-circle" class="w-5 h-5 text-green-500 mr-3 mt-0.5" /> <Icon name="heroicons:check-circle" class="w-5 h-5 text-candlelight-400 mr-3 mt-0.5" />
<div> <div>
<h3 class="text-sm font-medium text-green-800">Series created successfully!</h3> <h3 class="text-sm font-medium text-candlelight-400">Series created successfully!</h3>
</div> </div>
</div> </div>
</div> </div>
@ -41,56 +41,56 @@
<form @submit.prevent="createSeries"> <form @submit.prevent="createSeries">
<!-- Series Information --> <!-- Series Information -->
<div class="mb-8"> <div class="mb-8">
<h2 class="text-lg font-semibold text-gray-900 mb-4">Series Information</h2> <h2 class="text-lg font-semibold text-guild-100 mb-4">Series Information</h2>
<div class="grid grid-cols-1 gap-6"> <div class="grid grid-cols-1 gap-6">
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Series Title <span class="text-red-500">*</span> Series Title <span class="text-ember-400">*</span>
</label> </label>
<input <input
v-model="seriesForm.title" v-model="seriesForm.title"
type="text" type="text"
placeholder="e.g., Cooperative Game Development Fundamentals" placeholder="e.g., Cooperative Game Development Fundamentals"
required required
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-purple-500 focus:border-transparent" class="w-full bg-guild-800 border border-guild-700 rounded-lg px-3 py-2 text-guild-100 placeholder-guild-500 focus:ring-2 focus:ring-earth-500 focus:border-transparent"
:class="{ 'border-red-300 focus:ring-red-500': fieldErrors.title }" :class="{ 'border-ember-700 focus:ring-ember-500': fieldErrors.title }"
@input="generateSlugFromTitle" @input="generateSlugFromTitle"
/> />
<p v-if="fieldErrors.title" class="mt-1 text-sm text-red-600">{{ fieldErrors.title }}</p> <p v-if="fieldErrors.title" class="mt-1 text-sm text-ember-400">{{ fieldErrors.title }}</p>
</div> </div>
<div v-if="generatedSlug"> <div v-if="generatedSlug">
<label class="block text-sm font-medium text-gray-700 mb-2">Generated Series ID</label> <label class="block text-sm font-medium text-guild-100 mb-2">Generated Series ID</label>
<div class="w-full bg-gray-100 border border-gray-300 rounded-lg px-3 py-2 text-gray-700 font-mono text-sm"> <div class="w-full bg-guild-800 border border-guild-700 rounded-lg px-3 py-2 text-guild-100 font-mono text-sm">
{{ generatedSlug }} {{ generatedSlug }}
</div> </div>
<p class="mt-1 text-sm text-gray-500"> <p class="mt-1 text-sm text-guild-500">
This unique identifier will be automatically generated from your title This unique identifier will be automatically generated from your title
</p> </p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-2"> <label class="block text-sm font-medium text-guild-100 mb-2">
Series Description <span class="text-red-500">*</span> Series Description <span class="text-ember-400">*</span>
</label> </label>
<textarea <textarea
v-model="seriesForm.description" v-model="seriesForm.description"
placeholder="Describe what the series covers and its goals" placeholder="Describe what the series covers and its goals"
required required
rows="4" rows="4"
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-purple-500 focus:border-transparent" class="w-full bg-guild-800 border border-guild-700 rounded-lg px-3 py-2 text-guild-100 placeholder-guild-500 focus:ring-2 focus:ring-earth-500 focus:border-transparent"
:class="{ 'border-red-300 focus:ring-red-500': fieldErrors.description }" :class="{ 'border-ember-700 focus:ring-ember-500': fieldErrors.description }"
></textarea> ></textarea>
<p v-if="fieldErrors.description" class="mt-1 text-sm text-red-600">{{ fieldErrors.description }}</p> <p v-if="fieldErrors.description" class="mt-1 text-sm text-ember-400">{{ fieldErrors.description }}</p>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-2">Series Type</label> <label class="block text-sm font-medium text-guild-100 mb-2">Series Type</label>
<select <select
v-model="seriesForm.type" v-model="seriesForm.type"
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-purple-500 focus:border-transparent" class="w-full bg-guild-800 border border-guild-700 rounded-lg px-3 py-2 text-guild-100 focus:ring-2 focus:ring-earth-500 focus:border-transparent"
> >
<option value="workshop_series">Workshop Series</option> <option value="workshop_series">Workshop Series</option>
<option value="recurring_meetup">Recurring Meetup</option> <option value="recurring_meetup">Recurring Meetup</option>
@ -101,25 +101,25 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-2">Total Events Planned</label> <label class="block text-sm font-medium text-guild-100 mb-2">Total Events Planned</label>
<input <input
v-model.number="seriesForm.totalEvents" v-model.number="seriesForm.totalEvents"
type="number" type="number"
min="1" min="1"
placeholder="e.g., 4" placeholder="e.g., 4"
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-purple-500 focus:border-transparent" class="w-full bg-guild-800 border border-guild-700 rounded-lg px-3 py-2 text-guild-100 placeholder-guild-500 focus:ring-2 focus:ring-earth-500 focus:border-transparent"
/> />
<p class="text-sm text-gray-500 mt-1">How many events will be in this series? (optional)</p> <p class="text-sm text-guild-500 mt-1">How many events will be in this series? (optional)</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- Form Actions --> <!-- Form Actions -->
<div class="flex justify-between items-center pt-6 border-t border-gray-200"> <div class="flex justify-between items-center pt-6 border-t border-guild-700">
<NuxtLink <NuxtLink
to="/admin/series-management" to="/admin/series-management"
class="px-4 py-2 text-gray-600 hover:text-gray-900 font-medium" class="px-4 py-2 text-guild-400 hover:text-guild-100 font-medium"
> >
Cancel Cancel
</NuxtLink> </NuxtLink>
@ -129,7 +129,7 @@
type="button" type="button"
@click="createAndAddEvent" @click="createAndAddEvent"
:disabled="creating" :disabled="creating"
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium" class="px-4 py-2 bg-candlelight-600 text-white rounded-lg hover:bg-candlelight-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium"
> >
{{ creating ? 'Creating...' : 'Create & Add Event' }} {{ creating ? 'Creating...' : 'Create & Add Event' }}
</button> </button>
@ -137,7 +137,7 @@
<button <button
type="submit" type="submit"
:disabled="creating" :disabled="creating"
class="px-6 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium" class="px-6 py-2 bg-earth-600 text-white rounded-lg hover:bg-earth-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium"
> >
{{ creating ? 'Creating...' : 'Create Series' }} {{ creating ? 'Creating...' : 'Create Series' }}
</button> </button>

View file

@ -1,8 +1,8 @@
<template> <template>
<div class="min-h-screen w-full flex flex-col items-center justify-center"> <div class="min-h-screen w-full flex flex-col items-center justify-center">
<a href="https://babyghosts.fund/ghost-guild" class="text-center"> <a href="https://babyghosts.fund/ghost-guild" class="text-center">
<h1 class="text-5xl md:text-6xl font-bold mb-4">Ghost Guild</h1> <h1 class="text-display-xl font-bold mb-4">Ghost Guild</h1>
<p class="text-xl md:text-2xl">Coming Soon</p> <p class="text-display-sm text-guild-400">Coming Soon</p>
</a> </a>
<button <button
class="mt-12 text-sm text-guild-500 hover:text-guild-300 transition-colors" class="mt-12 text-sm text-guild-500 hover:text-guild-300 transition-colors"

View file

@ -5,7 +5,7 @@
> >
<div class="text-center"> <div class="text-center">
<div <div
class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mx-auto mb-4" class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4"
></div> ></div>
<p class="text-guild-200">Loading event details...</p> <p class="text-guild-200">Loading event details...</p>
</div> </div>
@ -20,7 +20,7 @@
<p class="text-guild-300 mb-6"> <p class="text-guild-300 mb-6">
The event you're looking for doesn't exist. The event you're looking for doesn't exist.
</p> </p>
<NuxtLink to="/events" class="text-blue-400 hover:underline"> <NuxtLink to="/events" class="text-candlelight-500 hover:underline">
Back to Events Back to Events
</NuxtLink> </NuxtLink>
</div> </div>
@ -38,7 +38,7 @@
<!-- Members Only Banner --> <!-- Members Only Banner -->
<div <div
v-if="event.membersOnly" v-if="event.membersOnly"
class="absolute top-0 left-0 right-0 z-10 bg-purple-600/95 backdrop-blur-sm py-2" class="absolute top-0 left-0 right-0 z-10 bg-candlelight-500/95 backdrop-blur-sm py-2"
> >
<UContainer> <UContainer>
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
@ -62,7 +62,7 @@
<div class="absolute inset-0 flex items-center"> <div class="absolute inset-0 flex items-center">
<UContainer> <UContainer>
<div class="max-w-4xl"> <div class="max-w-4xl">
<h1 class="text-4xl md:text-5xl font-bold text-white mb-4"> <h1 class="text-display-xl font-bold text-white mb-4">
{{ event.title }} {{ event.title }}
</h1> </h1>
</div> </div>
@ -71,7 +71,7 @@
</div> </div>
<!-- Page Header (fallback when no image) --> <!-- Page Header (fallback when no image) -->
<PageHeader v-else :title="event.title" theme="blue" size="medium" /> <PageHeader v-else :title="event.title" size="medium" />
<!-- Event Details Section --> <!-- Event Details Section -->
<section class="py-16 bg-guild-900"> <section class="py-16 bg-guild-900">
@ -81,21 +81,21 @@
<div class="mb-8"> <div class="mb-8">
<div class="grid grid-cols-1 md:grid-cols-4 gap-6"> <div class="grid grid-cols-1 md:grid-cols-4 gap-6">
<div> <div>
<p class="text-sm text-guild-400">Date</p> <p class="text-ui-label text-guild-400">Date</p>
<p class="font-semibold text-guild-100"> <p class="text-ui-mono font-semibold text-guild-100">
{{ formatDate(event.startDate) }} {{ formatDate(event.startDate) }}
</p> </p>
</div> </div>
<div> <div>
<p class="text-sm text-guild-400">Time</p> <p class="text-ui-label text-guild-400">Time</p>
<p class="font-semibold text-guild-100"> <p class="text-ui-mono font-semibold text-guild-100">
{{ formatTime(event.startDate, event.endDate) }} {{ formatTime(event.startDate, event.endDate) }}
</p> </p>
</div> </div>
<div> <div>
<p class="text-sm text-guild-400">Location</p> <p class="text-ui-label text-guild-400">Location</p>
<p class="font-semibold text-guild-100"> <p class="font-semibold text-guild-100">
{{ event.location }} {{ event.location }}
</p> </p>
@ -119,14 +119,14 @@
<!-- Event Cancelled Notice --> <!-- Event Cancelled Notice -->
<div v-if="event.isCancelled" class="mb-8"> <div v-if="event.isCancelled" class="mb-8">
<div class="p-6 bg-red-900/20 rounded-xl border border-red-800"> <div class="p-6 bg-ember-900/20 rounded-xl border border-ember-800">
<h3 class="text-lg font-semibold text-red-300 mb-2"> <h3 class="text-lg font-semibold text-ember-300 mb-2">
Event Cancelled Event Cancelled
</h3> </h3>
<p class="text-red-400" v-if="event.cancellationMessage"> <p class="text-ember-400" v-if="event.cancellationMessage">
{{ event.cancellationMessage }} {{ event.cancellationMessage }}
</p> </p>
<p class="text-red-400" v-else> <p class="text-ember-400" v-else>
This event has been cancelled. We apologize for any This event has been cancelled. We apologize for any
inconvenience. inconvenience.
</p> </p>
@ -150,14 +150,14 @@
> >
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<span <span
class="text-sm font-medium text-gray-800 dark:text-guild-200" class="text-sm font-medium text-guild-200"
>Recommended for:</span >Recommended for:</span
> >
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<span <span
v-for="circle in event.targetCircles" v-for="circle in event.targetCircles"
:key="circle" :key="circle"
class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-400 border border-blue-300 dark:border-blue-800/50" class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-candlelight-900/20 dark:bg-candlelight-900/30 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700 dark:border-candlelight-800/50"
> >
{{ formatCircleName(circle) }} {{ formatCircleName(circle) }}
</span> </span>
@ -167,7 +167,7 @@
<!-- Event Description --> <!-- Event Description -->
<div class="prose prose-lg dark:prose-invert max-w-none mb-12"> <div class="prose prose-lg dark:prose-invert max-w-none mb-12">
<h2 class="text-2xl font-bold text-guild-100 mb-4"> <h2 class="text-display-sm font-bold text-guild-100 mb-4">
About This Event About This Event
</h2> </h2>
@ -191,7 +191,7 @@
</p> </p>
<div v-if="event.agenda && event.agenda.length > 0" class="mt-8"> <div v-if="event.agenda && event.agenda.length > 0" class="mt-8">
<h3 class="text-xl font-semibold text-guild-100 mb-4"> <h3 class="text-display-sm font-semibold text-guild-100 mb-4">
Event Agenda Event Agenda
</h3> </h3>
<ul class="space-y-3"> <ul class="space-y-3">
@ -201,7 +201,7 @@
class="flex items-start" class="flex items-start"
> >
<span <span
class="inline-block w-6 h-6 bg-blue-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5" class="inline-block w-6 h-6 bg-candlelight-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5"
> >
{{ index + 1 }} {{ index + 1 }}
</span> </span>
@ -214,7 +214,7 @@
v-if="event.speakers && event.speakers.length > 0" v-if="event.speakers && event.speakers.length > 0"
class="mt-8" class="mt-8"
> >
<h3 class="text-xl font-semibold text-guild-100 mb-4"> <h3 class="text-display-sm font-semibold text-guild-100 mb-4">
Speakers Speakers
</h3> </h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
@ -257,18 +257,18 @@
<!-- Already Registered Status --> <!-- Already Registered Status -->
<div v-if="registrationStatus === 'registered'"> <div v-if="registrationStatus === 'registered'">
<div <div
class="p-4 bg-green-100 dark:bg-green-900/20 rounded-lg border border-green-400 dark:border-green-800 mb-6" class="p-4 bg-candlelight-900/20 dark:bg-candlelight-900/20 rounded-lg border border-candlelight-700 dark:border-candlelight-800 mb-6"
> >
<div <div
class="flex flex-col md:flex-row md:items-start md:justify-between gap-4" class="flex flex-col md:flex-row md:items-start md:justify-between gap-4"
> >
<div> <div>
<p <p
class="font-semibold text-green-800 dark:text-green-300" class="font-semibold text-candlelight-500 dark:text-candlelight-400"
> >
You're registered! You're registered!
</p> </p>
<p class="text-sm text-green-700 dark:text-green-400"> <p class="text-sm text-candlelight-600 dark:text-candlelight-500">
We've sent a confirmation to your email We've sent a confirmation to your email
</p> </p>
</div> </div>
@ -324,7 +324,7 @@
v-else-if="isCancelled" v-else-if="isCancelled"
to="/member/profile#account" to="/member/profile#account"
> >
<UButton color="blue" size="lg" class="px-8"> <UButton color="primary" size="lg" class="px-8">
Reactivate Membership Reactivate Membership
</UButton> </UButton>
</NuxtLink> </NuxtLink>
@ -383,7 +383,7 @@
<!-- Not Logged In - Show Registration Form --> <!-- Not Logged In - Show Registration Form -->
<div v-else> <div v-else>
<h3 class="text-xl font-bold text-guild-100 mb-6"> <h3 class="text-display-sm font-bold text-guild-100 mb-6">
Register for This Event Register for This Event
</h3> </h3>
<form @submit.prevent="handleRegistration" class="space-y-4"> <form @submit.prevent="handleRegistration" class="space-y-4">
@ -465,7 +465,7 @@
class="w-24 h-2 bg-guild-700 rounded-full overflow-hidden" class="w-24 h-2 bg-guild-700 rounded-full overflow-hidden"
> >
<div <div
class="h-full bg-blue-500 rounded-full" class="h-full bg-candlelight-500 rounded-full"
:style="`width: ${((event.registeredCount || 0) / event.maxAttendees) * 100}%`" :style="`width: ${((event.registeredCount || 0) / event.maxAttendees) * 100}%`"
/> />
</div> </div>
@ -541,7 +541,7 @@
</p> </p>
<a <a
href="mailto:events@ghostguild.org" href="mailto:events@ghostguild.org"
class="text-blue-400 hover:underline" class="text-candlelight-500 hover:underline"
> >
events@ghostguild.org events@ghostguild.org
</a> </a>

View file

@ -129,10 +129,10 @@
class="group flex items-start gap-4 py-2 hover:opacity-80 transition-opacity" class="group flex items-start gap-4 py-2 hover:opacity-80 transition-opacity"
> >
<div class="flex-shrink-0 text-center"> <div class="flex-shrink-0 text-center">
<div class="text-2xl font-bold text-guild-100"> <div class="text-2xl font-display font-bold text-guild-100">
{{ event.start.getDate() }} {{ event.start.getDate() }}
</div> </div>
<div class="text-xs text-guild-400 uppercase"> <div class="text-ui-label text-guild-400">
{{ {{
event.start.toLocaleDateString("en-US", { event.start.toLocaleDateString("en-US", {
month: "short", month: "short",
@ -151,7 +151,7 @@
<Icon <Icon
v-if="event.membersOnly" v-if="event.membersOnly"
name="heroicons:lock-closed" name="heroicons:lock-closed"
class="w-4 h-4 text-purple-500 flex-shrink-0 mt-1" class="w-4 h-4 text-candlelight-500 flex-shrink-0 mt-1"
/> />
</div> </div>
@ -229,7 +229,7 @@
<!-- Event Series --> <!-- Event Series -->
<div v-if="activeSeries.length > 0" class="text-center my-12"> <div v-if="activeSeries.length > 0" class="text-center my-12">
<h2 class="text-3xl font-bold text-guild-100 mb-8"> <h2 class="text-display font-bold text-guild-100 mb-8">
Current Event Series Current Event Series
</h2> </h2>
</div> </div>
@ -261,10 +261,10 @@
:class="[ :class="[
'series-list-item__status inline-flex items-center px-2 py-1 rounded-full text-xs font-medium', 'series-list-item__status inline-flex items-center px-2 py-1 rounded-full text-xs font-medium',
series.status === 'active' series.status === 'active'
? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' ? 'bg-candlelight-900/20 text-candlelight-500 dark:bg-candlelight-900/30 dark:text-candlelight-400'
: series.status === 'upcoming' : series.status === 'upcoming'
? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400' ? 'bg-guild-800 text-guild-300 dark:bg-guild-700/30 dark:text-guild-300'
: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400', : 'bg-guild-800 text-guild-400 dark:bg-guild-700/30 dark:text-guild-400',
]" ]"
> >
{{ series.status }} {{ series.status }}
@ -326,7 +326,7 @@
<section class="py-20 bg-guild-800 dark:bg-guild-900"> <section class="py-20 bg-guild-800 dark:bg-guild-900">
<UContainer> <UContainer>
<div class="text-center mb-16"> <div class="text-center mb-16">
<h2 class="text-3xl font-bold text-guild-100 mb-8"> <h2 class="text-display font-bold text-guild-100 mb-8">
Attend Our Events Attend Our Events
</h2> </h2>
</div> </div>
@ -613,18 +613,18 @@ const formatSeriesType = (type) => {
const getSeriesTypeBadgeClass = (type) => { const getSeriesTypeBadgeClass = (type) => {
const classes = { const classes = {
workshop_series: workshop_series:
"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400", "bg-candlelight-900/20 text-candlelight-500 dark:bg-candlelight-900/30 dark:text-candlelight-400",
recurring_meetup: recurring_meetup:
"bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400", "bg-guild-800 text-guild-300 dark:bg-guild-700/30 dark:text-guild-300",
multi_day: multi_day:
"bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400", "bg-ember-900/20 text-ember-500 dark:bg-ember-900/30 dark:text-ember-400",
course: course:
"bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400", "bg-candlelight-900/20 text-candlelight-500 dark:bg-candlelight-900/30 dark:text-candlelight-400",
tournament: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400", tournament: "bg-ember-900/20 text-ember-500 dark:bg-ember-900/30 dark:text-ember-400",
}; };
return ( return (
classes[type] || classes[type] ||
"bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400" "bg-guild-800 text-guild-400 dark:bg-guild-700/30 dark:text-guild-400"
); );
}; };
</script> </script>
@ -661,27 +661,27 @@ const getSeriesTypeBadgeClass = (type) => {
} }
.guild-calendar :deep(.vuecal__event.event-community) { .guild-calendar :deep(.vuecal__event.event-community) {
background-color: #2563eb; background-color: var(--color-guild-400);
color: #f5f5f4; color: #f5f5f4;
border-color: #1d4ed8; border-color: var(--color-guild-500);
} }
.guild-calendar :deep(.vuecal__event.event-workshop) { .guild-calendar :deep(.vuecal__event.event-workshop) {
background-color: #059669; background-color: var(--color-candlelight-500);
color: #f5f5f4; color: #f5f5f4;
border-color: #047857; border-color: var(--color-candlelight-600);
} }
.guild-calendar :deep(.vuecal__event.event-social) { .guild-calendar :deep(.vuecal__event.event-social) {
background-color: #7c3aed; background-color: var(--color-guild-400);
color: #f5f5f4; color: #f5f5f4;
border-color: #6d28d9; border-color: var(--color-guild-500);
} }
.guild-calendar :deep(.vuecal__event.event-showcase) { .guild-calendar :deep(.vuecal__event.event-showcase) {
background-color: #d97706; background-color: var(--color-ember-400);
color: #f5f5f4; color: #f5f5f4;
border-color: #b45309; border-color: var(--color-ember-500);
} }
#event-calendar { #event-calendar {
@ -698,9 +698,9 @@ const getSeriesTypeBadgeClass = (type) => {
.month-view .vuecal__cell--today, .month-view .vuecal__cell--today,
.vuecal__cell--today { .vuecal__cell--today {
background-color: rgba(59, 130, 246, 0.15); background-color: rgba(184, 135, 58, 0.15);
color: #f5f5f4; color: #f5f5f4;
border: 2px solid #3b82f6 !important; border: 2px solid var(--color-candlelight-500) !important;
.day-of-month { .day-of-month {
display: flex; display: flex;
@ -714,7 +714,7 @@ const getSeriesTypeBadgeClass = (type) => {
font-size: 0.75rem; font-size: 0.75rem;
margin-right: 0.5rem; margin-right: 0.5rem;
display: none; display: none;
color: #3b82f6; color: var(--color-candlelight-500);
font-weight: 600; font-weight: 600;
} }
@ -775,27 +775,27 @@ const getSeriesTypeBadgeClass = (type) => {
} }
&.event-community { &.event-community {
background-color: #2563eb; background-color: var(--color-guild-400);
color: #f5f5f4; color: #f5f5f4;
border-color: #1d4ed8; border-color: var(--color-guild-500);
} }
&.event-workshop { &.event-workshop {
background-color: #059669; background-color: var(--color-candlelight-500);
color: #f5f5f4; color: #f5f5f4;
border-color: #047857; border-color: var(--color-candlelight-600);
} }
&.event-social { &.event-social {
background-color: #7c3aed; background-color: var(--color-guild-400);
color: #f5f5f4; color: #f5f5f4;
border-color: #6d28d9; border-color: var(--color-guild-500);
} }
&.event-showcase { &.event-showcase {
background-color: #d97706; background-color: var(--color-ember-400);
color: #f5f5f4; color: #f5f5f4;
border-color: #b45309; border-color: var(--color-ember-500);
} }
} }
@ -882,8 +882,8 @@ const getSeriesTypeBadgeClass = (type) => {
} }
.guild-calendar :deep(.vuecal__cell--today) { .guild-calendar :deep(.vuecal__cell--today) {
background-color: rgba(59, 130, 246, 0.1); background-color: rgba(184, 135, 58, 0.1);
border: 2px solid #3b82f6; border: 2px solid var(--color-candlelight-500);
} }
.guild-calendar :deep(.vuecal__cell--out-of-scope) { .guild-calendar :deep(.vuecal__cell--out-of-scope) {

View file

@ -1,15 +1,15 @@
<template> <template>
<div class="max-w-6xl mx-auto px-6 md:px-8"> <div class="max-w-6xl mx-auto px-6 md:px-8">
<!-- Hero Section --> <!-- Hero Section -->
<section class="py-16 md:py-24"> <section class="py-16 md:py-24 ink-grain">
<div class="max-w-2xl"> <div class="max-w-2xl">
<h1 <h1
class="text-4xl md:text-5xl font-light text-guild-100 leading-tight mb-2" class="text-display-xl font-light text-guild-100 leading-tight mb-2"
> >
Build your co-op studio Build your co-op studio
</h1> </h1>
<p <p
class="text-4xl md:text-5xl font-light text-guild-500 leading-tight mb-8" class="text-display-xl font-light text-guild-500 leading-tight mb-8"
> >
with people who get it. with people who get it.
</p> </p>
@ -54,25 +54,27 @@
</div> </div>
<div <div
v-if="submitError" v-if="submitError"
class="mt-4 p-3 bg-red-500/10 border border-red-500/30 rounded-lg" class="mt-4 p-3 bg-ember-900/20 border border-ember-500/30 rounded-lg"
> >
<p class="text-red-400 text-sm">{{ submitError }}</p> <p class="text-ember-400 text-sm">{{ submitError }}</p>
</div> </div>
</div> </div>
</section> </section>
<GuildDivider variant="woodcut" />
<!-- Value Props Section --> <!-- Value Props Section -->
<section class="py-16 border-t border-guild-800"> <section class="py-16">
<div class="grid md:grid-cols-3 gap-8 md:gap-12"> <div class="grid md:grid-cols-3 gap-8 md:gap-12">
<div> <div>
<p class="text-sm font-medium text-primary-400 mb-3">Peer Support</p> <p class="text-ui-label text-candlelight-400 mb-3">Peer Support</p>
<p class="text-guild-400 leading-relaxed"> <p class="text-guild-400 leading-relaxed">
Connect with founders at your stage and practitioners who've been Connect with founders at your stage and practitioners who've been
there. Real conversations, real help. there. Real conversations, real help.
</p> </p>
</div> </div>
<div> <div>
<p class="text-sm font-medium text-primary-400 mb-3"> <p class="text-ui-label text-candlelight-400 mb-3">
Shared Knowledge Shared Knowledge
</p> </p>
<p class="text-guild-400 leading-relaxed"> <p class="text-guild-400 leading-relaxed">
@ -81,7 +83,7 @@
</p> </p>
</div> </div>
<div> <div>
<p class="text-sm font-medium text-primary-400 mb-3"> <p class="text-ui-label text-candlelight-400 mb-3">
Solidarity Economics Solidarity Economics
</p> </p>
<p class="text-guild-400 leading-relaxed"> <p class="text-guild-400 leading-relaxed">
@ -92,9 +94,11 @@
</div> </div>
</section> </section>
<GuildDivider variant="woodcut" />
<!-- Circles Section --> <!-- Circles Section -->
<section class="py-16 border-t border-guild-800"> <section class="py-16">
<p class="text-sm text-guild-600 mb-8">Find your people</p> <p class="text-ui-label text-guild-600 mb-8">Find your people</p>
<div class="space-y-4 mb-8"> <div class="space-y-4 mb-8">
<NuxtLink <NuxtLink
@ -120,10 +124,12 @@
</p> </p>
</section> </section>
<GuildDivider variant="woodcut" />
<!-- Bottom CTA Section --> <!-- Bottom CTA Section -->
<section class="py-24 border-t border-guild-800 text-center"> <section class="py-24 text-center">
<p class="text-sm text-guild-600 mb-4">Part of the Baby Ghosts family</p> <p class="text-ui-label text-guild-600 mb-4">Part of the Baby Ghosts family</p>
<h2 class="text-3xl md:text-4xl font-light text-guild-200 mb-8"> <h2 class="text-display font-light text-guild-200 mb-8">
Ready to find your people? Ready to find your people?
</h2> </h2>
<UButton <UButton

View file

@ -5,14 +5,12 @@
v-if="!isAuthenticated" v-if="!isAuthenticated"
title="Join Ghost Guild" title="Join Ghost Guild"
subtitle="" subtitle=""
theme="gray"
size="large" size="large"
/> />
<PageHeader <PageHeader
v-else v-else
title="You're Already a Member!" title="You're Already a Member!"
:subtitle="`Welcome back, ${memberData?.name || 'member'}. You're already part of Ghost Guild in the ${memberData?.circle || 'community'} circle.`" :subtitle="`Welcome back, ${memberData?.name || 'member'}. You're already part of Ghost Guild in the ${memberData?.circle || 'community'} circle.`"
theme="gray"
size="large" size="large"
/> />
@ -20,7 +18,7 @@
<section class="py-20 bg-[--ui-bg-elevated]"> <section class="py-20 bg-[--ui-bg-elevated]">
<UContainer> <UContainer>
<div class="max-w-2xl"> <div class="max-w-2xl">
<h2 class="text-3xl font-bold text-[--ui-text] mb-6"> <h2 class="text-display font-bold text-[--ui-text] mb-6">
How Membership Works How Membership Works
</h2> </h2>
<p class="text-lg text-[--ui-text] mb-4"> <p class="text-lg text-[--ui-text] mb-4">
@ -41,7 +39,7 @@
<section v-if="!isAuthenticated" class="py-20 bg-[--ui-bg]"> <section v-if="!isAuthenticated" class="py-20 bg-[--ui-bg]">
<UContainer class="max-w-4xl"> <UContainer class="max-w-4xl">
<div class="text-center mb-12"> <div class="text-center mb-12">
<h2 class="text-3xl font-bold text-[--ui-text] mb-4"> <h2 class="text-display font-bold text-[--ui-text] mb-4">
Membership Sign Up Membership Sign Up
</h2> </h2>
</div> </div>
@ -52,10 +50,10 @@
<div class="flex items-center"> <div class="flex items-center">
<div <div
:class="[ :class="[
'w-10 h-10 rounded-full flex items-center justify-center font-semibold', 'w-10 h-10 rounded-full flex items-center justify-center text-ui-mono font-semibold',
currentStep >= 1 currentStep >= 1
? 'bg-neutral-900 text-neutral-50' ? 'bg-guild-800 text-candlelight-400'
: 'bg-neutral-200 text-neutral-500', : 'bg-guild-700 text-guild-500',
]" ]"
> >
1 1
@ -63,16 +61,16 @@
<span <span
class="ml-2 font-medium" class="ml-2 font-medium"
:class=" :class="
currentStep === 1 ? 'text-[--ui-text]' : 'text-neutral-500' currentStep === 1 ? 'text-[--ui-text]' : 'text-guild-500'
" "
> >
Information Information
</span> </span>
</div> </div>
<div v-if="needsPayment" class="w-16 h-1 bg-neutral-200"> <div v-if="needsPayment" class="w-16 h-1 bg-guild-700">
<div <div
class="h-full bg-neutral-900 transition-all" class="h-full bg-candlelight-500 transition-all"
:style="{ width: currentStep >= 2 ? '100%' : '0%' }" :style="{ width: currentStep >= 2 ? '100%' : '0%' }"
/> />
</div> </div>
@ -80,10 +78,10 @@
<div v-if="needsPayment" class="flex items-center"> <div v-if="needsPayment" class="flex items-center">
<div <div
:class="[ :class="[
'w-10 h-10 rounded-full flex items-center justify-center font-semibold', 'w-10 h-10 rounded-full flex items-center justify-center text-ui-mono font-semibold',
currentStep >= 2 currentStep >= 2
? 'bg-neutral-900 text-neutral-50' ? 'bg-guild-800 text-candlelight-400'
: 'bg-neutral-200 text-neutral-500', : 'bg-guild-700 text-guild-500',
]" ]"
> >
2 2
@ -91,16 +89,16 @@
<span <span
class="ml-2 font-medium" class="ml-2 font-medium"
:class=" :class="
currentStep === 2 ? 'text-[--ui-text]' : 'text-neutral-500' currentStep === 2 ? 'text-[--ui-text]' : 'text-guild-500'
" "
> >
Payment Payment
</span> </span>
</div> </div>
<div class="w-16 h-1 bg-neutral-200"> <div class="w-16 h-1 bg-guild-700">
<div <div
class="h-full bg-neutral-900 transition-all" class="h-full bg-candlelight-500 transition-all"
:style="{ width: currentStep >= 3 ? '100%' : '0%' }" :style="{ width: currentStep >= 3 ? '100%' : '0%' }"
/> />
</div> </div>
@ -108,10 +106,10 @@
<div class="flex items-center"> <div class="flex items-center">
<div <div
:class="[ :class="[
'w-10 h-10 rounded-full flex items-center justify-center font-semibold', 'w-10 h-10 rounded-full flex items-center justify-center text-ui-mono font-semibold',
currentStep >= 3 currentStep >= 3
? 'bg-neutral-900 text-neutral-50' ? 'bg-guild-800 text-candlelight-400'
: 'bg-neutral-200 text-neutral-500', : 'bg-guild-700 text-guild-500',
]" ]"
> >
<span v-if="needsPayment">3</span> <span v-if="needsPayment">3</span>
@ -120,7 +118,7 @@
<span <span
class="ml-2 font-medium" class="ml-2 font-medium"
:class=" :class="
currentStep === 3 ? 'text-[--ui-text]' : 'text-neutral-500' currentStep === 3 ? 'text-[--ui-text]' : 'text-guild-500'
" "
> >
Confirmation Confirmation
@ -231,7 +229,7 @@
class="bg-[--ui-bg-elevated] rounded-xl p-8" class="bg-[--ui-bg-elevated] rounded-xl p-8"
> >
<div class="mb-6"> <div class="mb-6">
<h3 class="text-2xl font-bold text-[--ui-text] mb-2"> <h3 class="text-display-sm font-bold text-[--ui-text] mb-2">
Payment Information Payment Information
</h3> </h3>
<p class="text-[--ui-text-muted]"> <p class="text-[--ui-text-muted]">
@ -273,10 +271,10 @@
> >
<div class="text-center"> <div class="text-center">
<div <div
class="w-20 h-20 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-6" class="w-20 h-20 bg-candlelight-900/20 rounded-full flex items-center justify-center mx-auto mb-6"
> >
<svg <svg
class="w-10 h-10 text-green-500" class="w-10 h-10 text-candlelight-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -290,7 +288,7 @@
</svg> </svg>
</div> </div>
<h3 class="text-2xl font-bold text-[--ui-text] mb-4"> <h3 class="text-display-sm font-bold text-[--ui-text] mb-4">
Welcome to Ghost Guild! Welcome to Ghost Guild!
</h3> </h3>
@ -353,7 +351,7 @@
<section v-if="isAuthenticated" class="py-20 bg-[--ui-bg]"> <section v-if="isAuthenticated" class="py-20 bg-[--ui-bg]">
<UContainer class="max-w-4xl"> <UContainer class="max-w-4xl">
<div class="bg-[--ui-bg-elevated] rounded-xl p-8 mb-8"> <div class="bg-[--ui-bg-elevated] rounded-xl p-8 mb-8">
<h2 class="text-2xl font-bold text-[--ui-text] mb-6"> <h2 class="text-display-sm font-bold text-[--ui-text] mb-6">
Your Membership Your Membership
</h2> </h2>
@ -387,7 +385,7 @@
</div> </div>
</div> </div>
<div class="bg-blue-50 dark:bg-blue-900/20 rounded-lg p-6"> <div class="bg-guild-800 rounded-lg p-6">
<h3 class="text-lg font-semibold text-[--ui-text] mb-3"> <h3 class="text-lg font-semibold text-[--ui-text] mb-3">
Want to change your circle or contribution? Want to change your circle or contribution?
</h3> </h3>

View file

@ -4,7 +4,6 @@
<PageHeader <PageHeader
title="Member Dashboard" title="Member Dashboard"
:subtitle="`Welcome back, ${memberData?.name || 'Member'}!`" :subtitle="`Welcome back, ${memberData?.name || 'Member'}!`"
theme="blue"
size="medium" size="medium"
/> />
@ -55,7 +54,7 @@
<template #header> <template #header>
<div class="flex items-start justify-between gap-4"> <div class="flex items-start justify-between gap-4">
<div class="flex-1"> <div class="flex-1">
<h1 class="text-2xl font-bold text-guild-100 warm-text"> <h1 class="text-display-lg text-guild-100 warm-text">
Welcome to Ghost Guild, {{ memberData?.name }}! Welcome to Ghost Guild, {{ memberData?.name }}!
</h1> </h1>
<p <p
@ -88,13 +87,13 @@
<div class="flex flex-wrap gap-4 text-sm"> <div class="flex flex-wrap gap-4 text-sm">
<div class="bg-guild-800 border border-guild-600 px-4 py-2"> <div class="bg-guild-800 border border-guild-600 px-4 py-2">
<span class="text-guild-200">Circle:</span> <span class="text-ui-label text-guild-200">Circle:</span>
<span class="font-medium text-stone-50 ml-1 capitalize">{{ <span class="font-medium text-stone-50 ml-1 capitalize">{{
memberData?.circle memberData?.circle
}}</span> }}</span>
</div> </div>
<div class="bg-guild-800 border border-guild-600 px-4 py-2"> <div class="bg-guild-800 border border-guild-600 px-4 py-2">
<span class="text-guild-200">Contribution:</span> <span class="text-ui-label text-guild-200">Contribution:</span>
<span class="font-medium text-stone-50 ml-1" <span class="font-medium text-stone-50 ml-1"
>${{ memberData?.contributionTier }} CAD/month</span >${{ memberData?.contributionTier }} CAD/month</span
> >
@ -111,7 +110,7 @@
}" }"
> >
<template #header> <template #header>
<h2 class="text-xl font-bold text-guild-100 warm-text"> <h2 class="text-display-sm text-guild-100 warm-text">
Quick Links Quick Links
</h2> </h2>
</template> </template>
@ -195,7 +194,7 @@
> >
<template #header> <template #header>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<h2 class="text-xl font-bold text-guild-100 warm-text"> <h2 class="text-display-sm text-guild-100 warm-text">
Your Upcoming Events Your Upcoming Events
</h2> </h2>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
@ -263,7 +262,7 @@
<h3 class="font-semibold text-guild-100 mb-1"> <h3 class="font-semibold text-guild-100 mb-1">
{{ evt.title }} {{ evt.title }}
</h3> </h3>
<div class="flex items-center gap-4 text-sm text-guild-400"> <div class="flex items-center gap-4 text-ui-mono text-guild-400">
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<Icon name="heroicons:calendar" class="w-4 h-4" /> <Icon name="heroicons:calendar" class="w-4 h-4" />
{{ formatEventDate(evt.startDate) }} {{ formatEventDate(evt.startDate) }}

View file

@ -3,7 +3,6 @@
<PageHeader <PageHeader
title="My Updates" title="My Updates"
subtitle="View and manage your updates" subtitle="View and manage your updates"
theme="stone"
size="medium" size="medium"
/> />

View file

@ -3,7 +3,6 @@
<PageHeader <PageHeader
title="Your Profile" title="Your Profile"
subtitle="Manage your profile information and privacy settings" subtitle="Manage your profile information and privacy settings"
theme="blue"
size="medium" size="medium"
/> />
@ -16,9 +15,9 @@
> >
<div class="text-center"> <div class="text-center">
<div <div
class="w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin mx-auto mb-4" class="w-8 h-8 border-4 border-candlelight-500 border-t-transparent rounded-full animate-spin mx-auto mb-4"
></div> ></div>
<p class="text-gray-600 dark:text-guild-400"> <p class="text-guild-400">
Loading your profile... Loading your profile...
</p> </p>
</div> </div>
@ -52,7 +51,7 @@
<!-- Basic Information --> <!-- Basic Information -->
<div> <div>
<h2 <h2
class="text-2xl font-semibold mb-8 text-gray-900 dark:text-guild-100 warm-text" class="text-display-sm mb-8 text-guild-100 warm-text"
> >
Basic Information Basic Information
</h2> </h2>
@ -123,7 +122,7 @@
class="relative aspect-square rounded-lg border-2 transition-all hover:scale-105" class="relative aspect-square rounded-lg border-2 transition-all hover:scale-105"
:class=" :class="
formData.avatar === ghost.value formData.avatar === ghost.value
? 'border-blue-400 bg-blue-500/20' ? 'border-candlelight-400 bg-candlelight-900/20'
: 'border-guild-700 bg-guild-800/50 hover:border-guild-600' : 'border-guild-700 bg-guild-800/50 hover:border-guild-600'
" "
@click="formData.avatar = ghost.value" @click="formData.avatar = ghost.value"
@ -135,7 +134,7 @@
/> />
<span <span
v-if="formData.avatar === ghost.value" v-if="formData.avatar === ghost.value"
class="absolute -top-2 -right-2 w-6 h-6 bg-blue-500 rounded-full flex items-center justify-center text-white text-xs" class="absolute -top-2 -right-2 w-6 h-6 bg-candlelight-500 rounded-full flex items-center justify-center text-white text-xs"
> >
</span> </span>
@ -153,7 +152,7 @@
<!-- Professional Info --> <!-- Professional Info -->
<div> <div>
<h2 <h2
class="text-2xl font-semibold mb-8 text-gray-900 dark:text-guild-100 warm-text" class="text-display-sm mb-8 text-guild-100 warm-text"
> >
Professional Information Professional Information
</h2> </h2>
@ -222,7 +221,7 @@
<!-- Community Connections --> <!-- Community Connections -->
<div> <div>
<h2 <h2
class="text-2xl font-semibold mb-8 text-gray-900 dark:text-guild-100 warm-text" class="text-display-sm mb-8 text-guild-100 warm-text"
> >
Community Connections Community Connections
</h2> </h2>
@ -238,7 +237,7 @@
<!-- Tags input --> <!-- Tags input -->
<div> <div>
<label <label
class="block text-sm font-medium text-gray-800 dark:text-guild-200 mb-2" class="block text-sm font-medium text-guild-200 mb-2"
> >
Skills & Topics Skills & Topics
</label> </label>
@ -256,7 +255,7 @@
<span <span
v-for="(tag, index) in formData.offering.tags" v-for="(tag, index) in formData.offering.tags"
:key="tag" :key="tag"
class="px-3 py-1 bg-blue-100 dark:bg-blue-500/20 text-blue-700 dark:text-blue-300 rounded-full text-sm border border-blue-300 dark:border-blue-500/30 flex items-center gap-2 group hover:bg-blue-200 dark:hover:bg-blue-500/30 transition-colors cursor-pointer" class="px-3 py-1 bg-guild-800 text-guild-200 rounded-full text-sm border border-guild-600 flex items-center gap-2 group hover:bg-guild-700 transition-colors cursor-pointer"
@click="removeOfferingTag(index)" @click="removeOfferingTag(index)"
> >
{{ tag }} {{ tag }}
@ -270,7 +269,7 @@
<!-- Description textarea --> <!-- Description textarea -->
<div> <div>
<label <label
class="block text-sm font-medium text-gray-800 dark:text-guild-200 mb-2" class="block text-sm font-medium text-guild-200 mb-2"
> >
Details Details
</label> </label>
@ -300,7 +299,7 @@
<!-- Tags input --> <!-- Tags input -->
<div> <div>
<label <label
class="block text-sm font-medium text-gray-800 dark:text-guild-200 mb-2" class="block text-sm font-medium text-guild-200 mb-2"
> >
Skills & Topics Skills & Topics
</label> </label>
@ -318,7 +317,7 @@
<span <span
v-for="(tag, index) in formData.lookingFor.tags" v-for="(tag, index) in formData.lookingFor.tags"
:key="tag" :key="tag"
class="px-3 py-1 bg-purple-100 dark:bg-purple-500/20 text-purple-700 dark:text-purple-300 rounded-full text-sm border border-purple-300 dark:border-purple-500/30 flex items-center gap-2 group hover:bg-purple-200 dark:hover:bg-purple-500/30 transition-colors cursor-pointer" class="px-3 py-1 bg-candlelight-900/20 text-candlelight-500 rounded-full text-sm border border-candlelight-500/30 flex items-center gap-2 group hover:bg-candlelight-900/30 transition-colors cursor-pointer"
@click="removeLookingForTag(index)" @click="removeLookingForTag(index)"
> >
{{ tag }} {{ tag }}
@ -332,7 +331,7 @@
<!-- Description textarea --> <!-- Description textarea -->
<div> <div>
<label <label
class="block text-sm font-medium text-gray-800 dark:text-guild-200 mb-2" class="block text-sm font-medium text-guild-200 mb-2"
> >
Details Details
</label> </label>
@ -357,7 +356,7 @@
<!-- Peer Support --> <!-- Peer Support -->
<div> <div>
<h2 <h2
class="text-2xl font-semibold mb-8 text-gray-900 dark:text-guild-100 warm-text" class="text-display-sm mb-8 text-guild-100 warm-text"
> >
Peer Support Peer Support
</h2> </h2>
@ -368,12 +367,12 @@
<USwitch v-model="formData.peerSupportEnabled" /> <USwitch v-model="formData.peerSupportEnabled" />
<div> <div>
<p <p
class="font-medium text-gray-800 dark:text-guild-200" class="font-medium text-guild-200"
> >
Offer Peer Support Offer Peer Support
</p> </p>
<p <p
class="text-sm text-gray-600 dark:text-guild-400 mt-1" class="text-sm text-guild-400 mt-1"
> >
Make yourself available to support other members Make yourself available to support other members
</p> </p>
@ -383,7 +382,7 @@
<!-- Conditional Fields --> <!-- Conditional Fields -->
<div <div
v-if="formData.peerSupportEnabled" v-if="formData.peerSupportEnabled"
class="space-y-6 pl-4 border-l-2 border-purple-500/30" class="space-y-6 pl-4 border-l-2 border-candlelight-500/30"
> >
<!-- Skill-Based Topics --> <!-- Skill-Based Topics -->
<UFormField <UFormField
@ -408,7 +407,7 @@
topic, index topic, index
) in formData.peerSupportSkillTopics" ) in formData.peerSupportSkillTopics"
:key="topic" :key="topic"
class="px-3 py-1 bg-blue-100 dark:bg-blue-500/20 text-blue-700 dark:text-blue-300 rounded-full text-sm border border-blue-300 dark:border-blue-500/30 flex items-center gap-2 group hover:bg-blue-200 dark:hover:bg-blue-500/30 transition-colors cursor-pointer" class="px-3 py-1 bg-guild-800 text-guild-200 rounded-full text-sm border border-guild-600 flex items-center gap-2 group hover:bg-guild-700 transition-colors cursor-pointer"
@click="removePeerSkillTopic(index)" @click="removePeerSkillTopic(index)"
> >
{{ topic }} {{ topic }}
@ -417,7 +416,7 @@
> >
</span> </span>
</div> </div>
<p class="text-xs text-stone-500 mt-2"> <p class="text-xs text-guild-500 mt-2">
Suggested from your offerings: Suggested from your offerings:
<span <span
v-for="tag in formData.offering.tags?.filter( v-for="tag in formData.offering.tags?.filter(
@ -478,7 +477,7 @@
/> />
<template #hint> <template #hint>
<span <span
class="text-xs text-gray-500 dark:text-guild-500" class="text-xs text-guild-500"
> >
{{ formData.peerSupportMessage?.length || 0 }}/200 {{ formData.peerSupportMessage?.length || 0 }}/200
characters characters
@ -506,7 +505,7 @@
<!-- Directory Settings --> <!-- Directory Settings -->
<div> <div>
<h2 <h2
class="text-2xl font-semibold mb-8 text-gray-900 dark:text-guild-100 warm-text" class="text-display-sm mb-8 text-guild-100 warm-text"
> >
Directory Visibility Directory Visibility
</h2> </h2>
@ -514,10 +513,10 @@
<div class="flex items-start gap-4"> <div class="flex items-start gap-4">
<USwitch v-model="formData.showInDirectory" /> <USwitch v-model="formData.showInDirectory" />
<div> <div>
<p class="font-medium text-gray-800 dark:text-guild-200"> <p class="font-medium text-guild-200">
Show in Member Directory Show in Member Directory
</p> </p>
<p class="text-sm text-gray-600 dark:text-guild-400 mt-1"> <p class="text-sm text-guild-400 mt-1">
Allow other members to discover and connect with you Allow other members to discover and connect with you
through the directory through the directory
</p> </p>
@ -528,16 +527,16 @@
<!-- Success/Error Messages --> <!-- Success/Error Messages -->
<div <div
v-if="saveSuccess" v-if="saveSuccess"
class="backdrop-blur-sm bg-green-500/10 border border-green-500/30 rounded-lg p-4" class="backdrop-blur-sm bg-candlelight-900/20 border border-candlelight-500/30 rounded-lg p-4"
> >
<p class="text-green-300"> Profile updated successfully!</p> <p class="text-candlelight-500"> Profile updated successfully!</p>
</div> </div>
<div <div
v-if="saveError" v-if="saveError"
class="backdrop-blur-sm bg-red-500/10 border border-red-500/30 rounded-lg p-4" class="backdrop-blur-sm bg-ember-900/20 border border-ember-400/30 rounded-lg p-4"
> >
<p class="text-red-300"> <p class="text-ember-400">
{{ saveError }} {{ saveError }}
</p> </p>
</div> </div>
@ -574,20 +573,20 @@
<!-- Current Membership --> <!-- Current Membership -->
<div> <div>
<h2 <h2
class="text-2xl font-semibold mb-6 text-gray-900 dark:text-guild-100 warm-text" class="text-display-sm mb-6 text-guild-100 warm-text"
> >
Current Membership Current Membership
</h2> </h2>
<div <div
class="backdrop-blur-sm bg-white/80 dark:bg-guild-800/50 border border-gray-200 dark:border-guild-700 rounded-lg p-6 space-y-4" class="backdrop-blur-sm bg-guild-800/50 border border-guild-700 rounded-lg p-6 space-y-4"
> >
<!-- Status Badge --> <!-- Status Badge -->
<div <div
class="flex items-center justify-between pb-4 border-b border-gray-200 dark:border-guild-700" class="flex items-center justify-between pb-4 border-b border-guild-700"
> >
<div> <div>
<p class="text-sm text-gray-600 dark:text-guild-400"> <p class="text-sm text-guild-400">
Membership Status Membership Status
</p> </p>
<div class="flex items-center gap-2 mt-1"> <div class="flex items-center gap-2 mt-1">
@ -620,21 +619,21 @@
<div class="flex items-start justify-between"> <div class="flex items-start justify-between">
<div> <div>
<p class="text-sm text-gray-600 dark:text-guild-400"> <p class="text-sm text-guild-400">
Circle Circle
</p> </p>
<p <p
class="text-lg font-medium text-gray-900 dark:text-guild-100 capitalize" class="text-lg font-medium text-guild-100 capitalize"
> >
{{ memberData.circle }} {{ memberData.circle }}
</p> </p>
</div> </div>
<div> <div>
<p class="text-sm text-gray-600 dark:text-guild-400"> <p class="text-sm text-guild-400">
Contribution Level Contribution Level
</p> </p>
<p <p
class="text-lg font-medium text-gray-900 dark:text-guild-100" class="text-lg font-medium text-guild-100"
> >
${{ contributionTierDetails?.amount }}/month ${{ contributionTierDetails?.amount }}/month
</p> </p>
@ -642,10 +641,10 @@
</div> </div>
<div v-if="memberData.subscriptionStartDate"> <div v-if="memberData.subscriptionStartDate">
<p class="text-sm text-gray-600 dark:text-guild-400"> <p class="text-sm text-guild-400">
Member Since Member Since
</p> </p>
<p class="text-gray-900 dark:text-guild-100"> <p class="text-guild-100">
{{ formatDate(memberData.subscriptionStartDate) }} {{ formatDate(memberData.subscriptionStartDate) }}
</p> </p>
</div> </div>
@ -656,10 +655,10 @@
memberData.contributionTier !== '0' memberData.contributionTier !== '0'
" "
> >
<p class="text-sm text-gray-600 dark:text-guild-400"> <p class="text-sm text-guild-400">
Next Billing Date Next Billing Date
</p> </p>
<p class="text-gray-900 dark:text-guild-100"> <p class="text-guild-100">
{{ formatDate(memberData.nextBillingDate) }} {{ formatDate(memberData.nextBillingDate) }}
</p> </p>
</div> </div>
@ -669,15 +668,15 @@
<!-- Change Contribution Level --> <!-- Change Contribution Level -->
<div> <div>
<h2 <h2
class="text-2xl font-semibold mb-6 text-gray-900 dark:text-guild-100 warm-text" class="text-display-sm mb-6 text-guild-100 warm-text"
> >
Change Contribution Level Change Contribution Level
</h2> </h2>
<div <div
class="backdrop-blur-sm bg-white/80 dark:bg-guild-800/50 border border-gray-200 dark:border-guild-700 rounded-lg p-6" class="backdrop-blur-sm bg-guild-800/50 border border-guild-700 rounded-lg p-6"
> >
<p class="text-gray-700 dark:text-guild-300 mb-6"> <p class="text-guild-300 mb-6">
Choose a new contribution level that works for you. Choose a new contribution level that works for you.
Changes will take effect on your next billing cycle. Changes will take effect on your next billing cycle.
</p> </p>
@ -690,22 +689,22 @@
:class="[ :class="[
'w-full text-left p-4 rounded-lg border-2 transition-all', 'w-full text-left p-4 rounded-lg border-2 transition-all',
selectedContributionTier === tier.value selectedContributionTier === tier.value
? 'border-blue-400 bg-blue-500/20' ? 'border-candlelight-400 bg-candlelight-900/20'
: 'border-gray-300 dark:border-guild-600 bg-gray-50 dark:bg-guild-900/30 hover:border-blue-300 dark:hover:border-guild-500', : 'border-guild-600 bg-guild-900/30 hover:border-guild-500',
]" ]"
@click="selectedContributionTier = tier.value" @click="selectedContributionTier = tier.value"
> >
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p <p
class="font-medium text-gray-900 dark:text-guild-100" class="font-medium text-guild-100"
> >
{{ tier.label }} {{ tier.label }}
</p> </p>
</div> </div>
<div <div
v-if="selectedContributionTier === tier.value" v-if="selectedContributionTier === tier.value"
class="w-6 h-6 bg-blue-500 rounded-full flex items-center justify-center text-white text-xs" class="w-6 h-6 bg-candlelight-500 rounded-full flex items-center justify-center text-white text-xs"
> >
</div> </div>
@ -715,16 +714,16 @@
<div <div
v-if="contributionChangeError" v-if="contributionChangeError"
class="mb-4 backdrop-blur-sm bg-red-500/10 border border-red-500/30 rounded-lg p-4" class="mb-4 backdrop-blur-sm bg-ember-900/20 border border-ember-400/30 rounded-lg p-4"
> >
<p class="text-red-300">{{ contributionChangeError }}</p> <p class="text-ember-400">{{ contributionChangeError }}</p>
</div> </div>
<div <div
v-if="contributionChangeSuccess" v-if="contributionChangeSuccess"
class="mb-4 backdrop-blur-sm bg-green-500/10 border border-green-500/30 rounded-lg p-4" class="mb-4 backdrop-blur-sm bg-candlelight-900/20 border border-candlelight-500/30 rounded-lg p-4"
> >
<p class="text-green-300"> <p class="text-candlelight-500">
Contribution level updated successfully! Contribution level updated successfully!
</p> </p>
</div> </div>
@ -745,20 +744,20 @@
<!-- Cancel Membership --> <!-- Cancel Membership -->
<div> <div>
<h2 <h2
class="text-2xl font-semibold mb-6 text-gray-900 dark:text-guild-100 warm-text" class="text-display-sm mb-6 text-guild-100 warm-text"
> >
Cancel Membership Cancel Membership
</h2> </h2>
<div <div
class="backdrop-blur-sm bg-white/80 dark:bg-guild-800/50 border border-gray-200 dark:border-guild-700 rounded-lg p-6" class="backdrop-blur-sm bg-guild-800/50 border border-guild-700 rounded-lg p-6"
> >
<p class="text-gray-700 dark:text-guild-300 mb-4"> <p class="text-guild-300 mb-4">
We're sorry to see you go. If you cancel, you'll lose We're sorry to see you go. If you cancel, you'll lose
access to member benefits at the end of your current access to member benefits at the end of your current
billing period. billing period.
</p> </p>
<p class="text-sm text-gray-600 dark:text-guild-400 mb-6"> <p class="text-sm text-guild-400 mb-6">
Need a break? Consider switching to the free tier instead. Need a break? Consider switching to the free tier instead.
</p> </p>

View file

@ -3,7 +3,6 @@
<PageHeader <PageHeader
title="Member Directory" title="Member Directory"
subtitle="Connect with members of the Ghost Guild community" subtitle="Connect with members of the Ghost Guild community"
theme="purple"
size="medium" size="medium"
/> />
@ -56,8 +55,8 @@
class="px-3 py-1 rounded-full text-sm transition-all border" class="px-3 py-1 rounded-full text-sm transition-all border"
:class=" :class="
selectedSkills.includes(skill) selectedSkills.includes(skill)
? 'bg-purple-100 dark:bg-purple-500/20 text-purple-700 dark:text-purple-300 border-purple-300 dark:border-purple-500/50' ? 'bg-candlelight-900/20 text-candlelight-500 border-candlelight-500/50'
: 'bg-gray-100 dark:bg-guild-800/50 text-gray-700 dark:text-guild-400 border-gray-300 dark:border-guild-700 hover:border-gray-400 dark:hover:border-guild-600' : 'bg-guild-800/50 text-guild-400 border-guild-700 hover:border-guild-600'
" "
@click="toggleSkill(skill)" @click="toggleSkill(skill)"
> >
@ -94,8 +93,8 @@
class="px-3 py-1 rounded-full text-sm transition-all border" class="px-3 py-1 rounded-full text-sm transition-all border"
:class=" :class="
selectedTopics.includes(topic) selectedTopics.includes(topic)
? 'bg-purple-100 dark:bg-purple-500/20 text-purple-700 dark:text-purple-300 border-purple-300 dark:border-purple-500/50' ? 'bg-candlelight-900/20 text-candlelight-500 border-candlelight-500/50'
: 'bg-gray-100 dark:bg-guild-800/50 text-gray-700 dark:text-guild-400 border-gray-300 dark:border-guild-700 hover:border-gray-400 dark:hover:border-guild-600' : 'bg-guild-800/50 text-guild-400 border-guild-700 hover:border-guild-600'
" "
@click="toggleTopic(topic)" @click="toggleTopic(topic)"
> >
@ -129,7 +128,7 @@
<span class="text-guild-400">Active filters:</span> <span class="text-guild-400">Active filters:</span>
<span <span
v-if="selectedCircle && selectedCircle !== 'all'" v-if="selectedCircle && selectedCircle !== 'all'"
class="px-2 py-1 bg-purple-100 dark:bg-purple-500/20 text-purple-700 dark:text-purple-300 rounded-full border border-purple-300 dark:border-purple-500/30 flex items-center gap-1" class="px-2 py-1 bg-candlelight-900/20 text-candlelight-500 rounded-full border border-candlelight-500/30 flex items-center gap-1"
> >
{{ circleLabels[selectedCircle] }} {{ circleLabels[selectedCircle] }}
<button <button
@ -142,7 +141,7 @@
</span> </span>
<span <span
v-if="peerSupportFilter && peerSupportFilter !== 'all'" v-if="peerSupportFilter && peerSupportFilter !== 'all'"
class="px-2 py-1 bg-purple-100 dark:bg-purple-500/20 text-purple-700 dark:text-purple-300 rounded-full border border-purple-300 dark:border-purple-500/30 flex items-center gap-1" class="px-2 py-1 bg-candlelight-900/20 text-candlelight-500 rounded-full border border-candlelight-500/30 flex items-center gap-1"
> >
Offering Peer Support Offering Peer Support
<button <button
@ -171,7 +170,7 @@
> >
<div class="text-center"> <div class="text-center">
<div <div
class="w-8 h-8 border-4 border-purple-500 border-t-transparent rounded-full animate-spin mx-auto mb-4" class="w-8 h-8 border-4 border-candlelight-500 border-t-transparent rounded-full animate-spin mx-auto mb-4"
></div> ></div>
<p class="text-guild-400">Loading members...</p> <p class="text-guild-400">Loading members...</p>
</div> </div>
@ -187,7 +186,7 @@
<div <div
v-for="member in members" v-for="member in members"
:key="member._id" :key="member._id"
class="relative backdrop-blur-sm bg-guild-900/50 border border-guild-700/50 rounded-lg p-6 hover:border-purple-500/50 transition-all group" class="relative backdrop-blur-sm bg-guild-900/50 border border-guild-700/50 rounded-lg p-6 hover:border-candlelight-500/50 transition-all group"
> >
<!-- Peer Support Sticker Badge --> <!-- Peer Support Sticker Badge -->
<PeerSupportBadge <PeerSupportBadge
@ -199,7 +198,7 @@
<div class="flex items-start gap-4 mb-4"> <div class="flex items-start gap-4 mb-4">
<!-- Avatar --> <!-- Avatar -->
<div <div
class="w-16 h-16 rounded-lg bg-guild-800 border border-guild-700 flex items-center justify-center flex-shrink-0 group-hover:border-purple-500/50 transition-colors" class="w-16 h-16 rounded-lg bg-guild-800 border border-guild-700 flex items-center justify-center flex-shrink-0 group-hover:border-candlelight-500/50 transition-colors"
> >
<img <img
v-if="member.avatar" v-if="member.avatar"
@ -223,7 +222,7 @@
<div class="flex items-center gap-2 flex-wrap"> <div class="flex items-center gap-2 flex-wrap">
<span <span
class="px-2 py-0.5 bg-purple-100 dark:bg-purple-500/20 text-purple-700 dark:text-purple-300 rounded text-xs border border-purple-300 dark:border-purple-500/30" :class="['px-2 py-0.5 rounded text-xs', circleBadgeClass(member.circle)]"
> >
{{ circleLabels[member.circle] }} {{ circleLabels[member.circle] }}
</span> </span>
@ -250,10 +249,10 @@
<!-- Peer Support Section --> <!-- Peer Support Section -->
<div <div
v-if="member.peerSupport?.enabled" v-if="member.peerSupport?.enabled"
class="mb-4 p-4 bg-purple-500/10 border border-purple-500/30 rounded-lg" class="mb-4 p-4 bg-candlelight-900/20 border border-candlelight-500/30 rounded-lg"
> >
<div class="mb-3"> <div class="mb-3">
<p class="text-purple-300 font-medium text-sm mb-2"> <p class="text-candlelight-500 font-medium text-sm mb-2">
{{ member.name }} offers 1:1 chats on: {{ member.name }} offers 1:1 chats on:
</p> </p>
</div> </div>
@ -270,7 +269,7 @@
<span <span
v-for="topic in member.peerSupport.topics" v-for="topic in member.peerSupport.topics"
:key="topic" :key="topic"
class="px-2 py-0.5 bg-purple-100 dark:bg-purple-500/20 text-purple-700 dark:text-purple-200 rounded text-xs border border-purple-300 dark:border-purple-500/40" class="px-2 py-0.5 bg-candlelight-900/20 text-candlelight-400 rounded text-xs border border-candlelight-500/40"
> >
{{ topic }} {{ topic }}
</span> </span>
@ -295,13 +294,13 @@
<!-- Contact Section --> <!-- Contact Section -->
<div v-if="member.peerSupport.slackUsername" class="space-y-2"> <div v-if="member.peerSupport.slackUsername" class="space-y-2">
<p class="text-sm text-purple-300 font-medium"> <p class="text-sm text-candlelight-500 font-medium">
Book a Peer Support call now: Book a Peer Support call now:
</p> </p>
<a <a
:href="`slack://user?team=T03A96LV4&id=${member.slackUserId}`" :href="`slack://user?team=T03A96LV4&id=${member.slackUserId}`"
@click.prevent="openSlackDM(member)" @click.prevent="openSlackDM(member)"
class="inline-block px-3 py-1.5 bg-purple-100 dark:bg-purple-500/20 text-purple-700 dark:text-purple-300 rounded border border-purple-300 dark:border-purple-500/30 hover:bg-purple-200 dark:hover:bg-purple-500/30 transition-colors text-sm font-medium cursor-pointer" class="inline-block px-3 py-1.5 bg-candlelight-900/20 text-candlelight-500 rounded border border-candlelight-500/30 hover:bg-candlelight-900/30 transition-colors text-sm font-medium cursor-pointer"
> >
Message {{ member.peerSupport.slackUsername }} on Slack Message {{ member.peerSupport.slackUsername }} on Slack
</a> </a>
@ -314,14 +313,14 @@
class="space-y-4" class="space-y-4"
> >
<h4 <h4
class="text-sm font-semibold text-purple-300 uppercase tracking-wide" class="text-ui-label text-candlelight-500"
> >
Skills Exchange Skills Exchange
</h4> </h4>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- Offering --> <!-- Offering -->
<div v-if="member.offering" class="space-y-2"> <div v-if="member.offering" class="space-y-2">
<h5 class="text-xs font-semibold text-purple-400 uppercase"> <h5 class="text-ui-label text-candlelight-400 text-xs">
Can share Can share
</h5> </h5>
<p <p
@ -339,7 +338,7 @@
<span <span
v-for="tag in member.offering.tags" v-for="tag in member.offering.tags"
:key="tag" :key="tag"
class="px-2 py-0.5 bg-green-100 dark:bg-green-500/20 text-green-700 dark:text-green-300 rounded text-xs border border-green-300 dark:border-green-500/30" class="px-2 py-0.5 bg-candlelight-900/20 text-candlelight-500 rounded text-xs border border-candlelight-500/30"
> >
{{ tag }} {{ tag }}
</span> </span>
@ -348,7 +347,7 @@
<!-- Looking For --> <!-- Looking For -->
<div v-if="member.lookingFor" class="space-y-2"> <div v-if="member.lookingFor" class="space-y-2">
<h5 class="text-xs font-semibold text-purple-400 uppercase"> <h5 class="text-ui-label text-candlelight-400 text-xs">
Looking to learn Looking to learn
</h5> </h5>
<p <p
@ -367,7 +366,7 @@
<span <span
v-for="tag in member.lookingFor.tags" v-for="tag in member.lookingFor.tags"
:key="tag" :key="tag"
class="px-2 py-0.5 bg-blue-100 dark:bg-blue-500/20 text-blue-700 dark:text-blue-300 rounded text-xs border border-blue-300 dark:border-blue-500/30" class="px-2 py-0.5 bg-guild-800 text-guild-200 rounded text-xs border border-guild-600"
> >
{{ tag }} {{ tag }}
</span> </span>
@ -410,9 +409,9 @@
<!-- Not Authenticated Notice --> <!-- Not Authenticated Notice -->
<div <div
v-if="!isAuthenticated && members.length > 0" v-if="!isAuthenticated && members.length > 0"
class="mt-8 backdrop-blur-sm bg-purple-500/10 border border-purple-500/30 rounded-lg p-6 text-center" class="mt-8 backdrop-blur-sm bg-candlelight-900/20 border border-candlelight-500/30 rounded-lg p-6 text-center"
> >
<p class="text-purple-200 mb-4"> <p class="text-guild-200 mb-4">
🔒 Some member information is visible to members only 🔒 Some member information is visible to members only
</p> </p>
<div class="flex gap-3 justify-center"> <div class="flex gap-3 justify-center">
@ -458,6 +457,16 @@ const circleLabels = {
practitioner: "Practitioner", practitioner: "Practitioner",
}; };
// Map circle names to badge classes
const circleBadgeClass = (circle) => {
const classes = {
community: 'circle-badge-community',
founder: 'circle-badge-founder',
practitioner: 'circle-badge-practitioner',
};
return classes[circle] || 'circle-badge-community';
};
// Peer support filter options // Peer support filter options
const peerSupportOptions = [ const peerSupportOptions = [
{ label: "All Members", value: "all" }, { label: "All Members", value: "all" },

View file

@ -28,7 +28,7 @@
<div v-else> <div v-else>
<!-- Page Header --> <!-- Page Header -->
<PageHeader :title="series.title" theme="purple" size="large" /> <PageHeader :title="series.title" size="large" />
<!-- Series Meta --> <!-- Series Meta -->
<section class="py-20 bg-[--ui-bg]"> <section class="py-20 bg-[--ui-bg]">
@ -106,9 +106,9 @@
<!-- Status Message --> <!-- Status Message -->
<div <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" class="p-4 bg-candlelight-900/20 border border-candlelight-700/30 rounded mb-8"
> >
<p class="text-green-600 dark:text-green-400 font-semibold mb-1"> <p class="text-candlelight-500 dark:text-candlelight-400 font-semibold mb-1">
This series is currently ongoing! This series is currently ongoing!
</p> </p>
<p class="text-sm text-[--ui-text-muted]"> <p class="text-sm text-[--ui-text-muted]">
@ -118,9 +118,9 @@
<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" class="p-4 bg-guild-500/10 border border-guild-500/30 rounded mb-8"
> >
<p class="text-blue-600 dark:text-blue-400 font-semibold mb-1"> <p class="text-guild-300 dark:text-guild-300 font-semibold mb-1">
This series is starting soon! This series is starting soon!
</p> </p>
<p class="text-sm text-[--ui-text-muted]"> <p class="text-sm text-[--ui-text-muted]">
@ -130,7 +130,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" class="p-4 bg-guild-500/10 border border-guild-500/30 rounded mb-8"
> >
<p class="text-[--ui-text] font-semibold mb-1"> <p class="text-[--ui-text] font-semibold mb-1">
This series has concluded. This series has concluded.
@ -148,7 +148,7 @@
<section v-if="series?.tickets?.enabled" class="py-20 bg-[--ui-bg]"> <section v-if="series?.tickets?.enabled" class="py-20 bg-[--ui-bg]">
<UContainer> <UContainer>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<h2 class="text-2xl font-bold text-[--ui-text] mb-8"> <h2 class="text-display-sm font-bold text-[--ui-text] mb-8">
Get Your Series Pass Get Your Series Pass
</h2> </h2>
<SeriesPassPurchase <SeriesPassPurchase
@ -172,7 +172,7 @@
<section class="py-20 bg-[--ui-bg-elevated]"> <section class="py-20 bg-[--ui-bg-elevated]">
<UContainer> <UContainer>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<h2 class="text-2xl font-bold text-[--ui-text] mb-8"> <h2 class="text-display-sm font-bold text-[--ui-text] mb-8">
Event Schedule Event Schedule
</h2> </h2>
@ -357,19 +357,19 @@ const formatSeriesType = (type) => {
const getSeriesTypeBadgeClass = (type) => { const getSeriesTypeBadgeClass = (type) => {
const classes = { const classes = {
workshop_series: workshop_series:
"bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/30", "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30",
recurring_meetup: recurring_meetup:
"bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/30", "bg-guild-500/10 text-guild-300 dark:text-guild-300 border border-guild-500/30",
multi_day: multi_day:
"bg-purple-500/10 text-purple-600 dark:text-purple-400 border border-purple-500/30", "bg-ember-900/20 text-ember-500 dark:text-ember-400 border border-ember-700/30",
course: course:
"bg-amber-500/10 text-amber-600 dark:text-amber-400 border border-amber-500/30", "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30",
tournament: tournament:
"bg-red-500/10 text-red-600 dark:text-red-400 border border-red-500/30", "bg-ember-900/20 text-ember-500 dark:text-ember-400 border border-ember-700/30",
}; };
return ( return (
classes[type] || classes[type] ||
"bg-gray-500/10 text-gray-600 dark:text-gray-400 border border-gray-500/30" "bg-earth-900/20 text-earth-400 dark:text-earth-400 border border-earth-700/30"
); );
}; };
@ -383,14 +383,14 @@ const getSeriesStatusText = () => {
const getSeriesStatusClass = () => { const getSeriesStatusClass = () => {
if (!series.value?.statistics) if (!series.value?.statistics)
return "bg-purple-500/10 text-purple-600 dark:text-purple-400 border border-purple-500/30"; return "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30";
if (series.value.statistics.isOngoing) if (series.value.statistics.isOngoing)
return "bg-green-500/10 text-green-600 dark:text-green-400 border border-green-500/30"; return "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30";
if (series.value.statistics.isUpcoming) if (series.value.statistics.isUpcoming)
return "bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/30"; return "bg-guild-500/10 text-guild-300 dark:text-guild-300 border border-guild-500/30";
if (series.value.statistics.isCompleted) if (series.value.statistics.isCompleted)
return "bg-gray-500/10 text-gray-600 dark:text-gray-400 border border-gray-500/30"; return "bg-guild-500/10 text-guild-400 dark:text-guild-400 border border-guild-500/30";
return "bg-purple-500/10 text-purple-600 dark:text-purple-400 border border-purple-500/30"; return "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30";
}; };
const formatEventDate = (date) => { const formatEventDate = (date) => {
@ -436,15 +436,15 @@ const getEventStatusClass = (event) => {
const status = getEventStatus(event); const status = getEventStatus(event);
const classes = { const classes = {
Upcoming: Upcoming:
"bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/30", "bg-guild-500/10 text-guild-300 dark:text-guild-300 border border-guild-500/30",
Ongoing: Ongoing:
"bg-green-500/10 text-green-600 dark:text-green-400 border border-green-500/30", "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30",
Completed: Completed:
"bg-gray-500/10 text-gray-600 dark:text-gray-400 border border-gray-500/30", "bg-guild-500/10 text-guild-400 dark:text-guild-400 border border-guild-500/30",
}; };
return ( return (
classes[status] || classes[status] ||
"bg-gray-500/10 text-gray-600 dark:text-gray-400 border border-gray-500/30" "bg-guild-500/10 text-guild-400 dark:text-guild-400 border border-guild-500/30"
); );
}; };
@ -452,15 +452,15 @@ const getEventTimelineColor = (event) => {
const status = getEventStatus(event); const status = getEventStatus(event);
const classes = { const classes = {
Upcoming: Upcoming:
"bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/30", "bg-guild-500/10 text-guild-300 dark:text-guild-300 border-guild-500/30",
Ongoing: Ongoing:
"bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/30", "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border-candlelight-700/30",
Completed: Completed:
"bg-purple-500/10 text-purple-600 dark:text-purple-400 border-purple-500/30", "bg-earth-900/20 text-earth-400 dark:text-earth-400 border-earth-700/30",
}; };
return ( return (
classes[status] || classes[status] ||
"bg-gray-500/10 text-gray-600 dark:text-gray-400 border-gray-500/30" "bg-guild-500/10 text-guild-400 dark:text-guild-400 border-guild-500/30"
); );
}; };

View file

@ -4,7 +4,6 @@
<PageHeader <PageHeader
title="Event Series" title="Event Series"
subtitle="Discover our multi-event series designed to take you on a journey of learning and growth" subtitle="Discover our multi-event series designed to take you on a journey of learning and growth"
theme="purple"
size="large" size="large"
/> />
@ -46,16 +45,16 @@
:class="[ :class="[
'inline-flex items-center px-2 py-1 rounded text-xs font-medium', 'inline-flex items-center px-2 py-1 rounded text-xs font-medium',
series.status === 'active' series.status === 'active'
? 'bg-green-500/10 text-green-600 dark:text-green-400 border border-green-500/30' ? 'bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30'
: series.status === 'upcoming' : series.status === 'upcoming'
? 'bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/30' ? 'bg-guild-500/10 text-guild-300 dark:text-guild-300 border border-guild-500/30'
: 'bg-gray-500/10 text-gray-600 dark:text-gray-400 border border-gray-500/30', : 'bg-guild-500/10 text-guild-400 dark:text-guild-400 border border-guild-500/30',
]" ]"
> >
{{ series.status }} {{ series.status }}
</span> </span>
</div> </div>
<h2 class="text-2xl font-bold text-[--ui-text] mb-2"> <h2 class="text-display-sm font-bold text-[--ui-text] mb-2">
{{ series.title }} {{ series.title }}
</h2> </h2>
<p class="text-[--ui-text-muted] leading-relaxed"> <p class="text-[--ui-text-muted] leading-relaxed">
@ -87,7 +86,7 @@
<div class="flex items-center justify-between gap-4"> <div class="flex items-center justify-between gap-4">
<div class="flex items-center gap-4 flex-1 min-w-0"> <div class="flex items-center gap-4 flex-1 min-w-0">
<div <div
class="w-8 h-8 bg-purple-500/10 text-purple-600 dark:text-purple-400 rounded-full flex items-center justify-center text-sm font-semibold flex-shrink-0 border border-purple-500/30" class="w-8 h-8 bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 rounded-full flex items-center justify-center text-sm font-semibold flex-shrink-0 border border-candlelight-700/30"
> >
{{ event.series?.position || "?" }} {{ event.series?.position || "?" }}
</div> </div>
@ -179,7 +178,7 @@
name="heroicons:squares-2x2" name="heroicons:squares-2x2"
class="w-16 h-16 text-[--ui-text-muted] mx-auto mb-4 opacity-50" class="w-16 h-16 text-[--ui-text-muted] mx-auto mb-4 opacity-50"
/> />
<h3 class="text-xl font-semibold text-[--ui-text] mb-2"> <h3 class="text-display-sm font-semibold text-[--ui-text] mb-2">
No Event Series Available No Event Series Available
</h3> </h3>
<p class="text-[--ui-text-muted] max-w-md mx-auto"> <p class="text-[--ui-text-muted] max-w-md mx-auto">
@ -233,19 +232,19 @@ const formatSeriesType = (type) => {
const getSeriesTypeBadgeClass = (type) => { const getSeriesTypeBadgeClass = (type) => {
const classes = { const classes = {
workshop_series: workshop_series:
"bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/30", "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30",
recurring_meetup: recurring_meetup:
"bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/30", "bg-guild-500/10 text-guild-300 dark:text-guild-300 border border-guild-500/30",
multi_day: multi_day:
"bg-purple-500/10 text-purple-600 dark:text-purple-400 border border-purple-500/30", "bg-ember-900/20 text-ember-500 dark:text-ember-400 border border-ember-700/30",
course: course:
"bg-amber-500/10 text-amber-600 dark:text-amber-400 border border-amber-500/30", "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30",
tournament: tournament:
"bg-red-500/10 text-red-600 dark:text-red-400 border border-red-500/30", "bg-ember-900/20 text-ember-500 dark:text-ember-400 border border-ember-700/30",
}; };
return ( return (
classes[type] || classes[type] ||
"bg-gray-500/10 text-gray-600 dark:text-gray-400 border border-gray-500/30" "bg-earth-900/20 text-earth-400 dark:text-earth-400 border border-earth-700/30"
); );
}; };
@ -292,15 +291,15 @@ const getEventStatusClass = (event) => {
const status = getEventStatus(event); const status = getEventStatus(event);
const classes = { const classes = {
Upcoming: Upcoming:
"bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/30", "bg-guild-500/10 text-guild-300 dark:text-guild-300 border border-guild-500/30",
Ongoing: Ongoing:
"bg-green-500/10 text-green-600 dark:text-green-400 border border-green-500/30", "bg-candlelight-900/20 text-candlelight-500 dark:text-candlelight-400 border border-candlelight-700/30",
Completed: Completed:
"bg-gray-500/10 text-gray-600 dark:text-gray-400 border border-gray-500/30", "bg-guild-500/10 text-guild-400 dark:text-guild-400 border border-guild-500/30",
}; };
return ( return (
classes[status] || classes[status] ||
"bg-gray-500/10 text-gray-600 dark:text-gray-400 border border-gray-500/30" "bg-guild-500/10 text-guild-400 dark:text-guild-400 border border-guild-500/30"
); );
}; };
</script> </script>

View file

@ -3,7 +3,6 @@
<PageHeader <PageHeader
title="Welcome to Ghost Guild" title="Welcome to Ghost Guild"
subtitle="You're officially part of the community!" subtitle="You're officially part of the community!"
theme="purple"
size="large" size="large"
/> />
@ -26,7 +25,7 @@
class="w-full h-full object-contain" class="w-full h-full object-contain"
/> />
</div> </div>
<h2 class="text-2xl font-bold text-guild-100 mb-4"> <h2 class="text-display font-bold text-guild-100 mb-4">
Hey {{ memberData?.name || "there" }}! Hey {{ memberData?.name || "there" }}!
</h2> </h2>
<p class="text-lg text-guild-300 max-w-2xl mx-auto"> <p class="text-lg text-guild-300 max-w-2xl mx-auto">
@ -38,15 +37,15 @@
<div class="grid grid-cols-1 md:grid-cols-3 gap-8 mb-16"> <div class="grid grid-cols-1 md:grid-cols-3 gap-8 mb-16">
<div class="p-6 bg-guild-800/50 rounded-xl border border-guild-700"> <div class="p-6 bg-guild-800/50 rounded-xl border border-guild-700">
<div <div
class="w-12 h-12 bg-purple-500/20 rounded-lg flex items-center justify-center mb-4" class="w-12 h-12 bg-candlelight-500/20 rounded-lg flex items-center justify-center mb-4"
> >
<Icon <Icon
name="heroicons:user-circle" name="heroicons:user-circle"
class="w-6 h-6 text-purple-400" class="w-6 h-6 text-candlelight-400"
/> />
</div> </div>
<h3 class="font-semibold text-guild-100 mb-2"> <h3 class="font-semibold text-guild-100 mb-2">
1. Complete Your Profile <span class="text-ui-label text-candlelight-400 mr-2">1.</span>Complete Your Profile
</h3> </h3>
<p class="text-sm text-guild-400 mb-4"> <p class="text-sm text-guild-400 mb-4">
Tell the community about yourself, your skills, and what you're Tell the community about yourself, your skills, and what you're
@ -59,15 +58,15 @@
<div class="p-6 bg-guild-800/50 rounded-xl border border-guild-700"> <div class="p-6 bg-guild-800/50 rounded-xl border border-guild-700">
<div <div
class="w-12 h-12 bg-blue-500/20 rounded-lg flex items-center justify-center mb-4" class="w-12 h-12 bg-candlelight-500/20 rounded-lg flex items-center justify-center mb-4"
> >
<Icon <Icon
name="heroicons:calendar-days" name="heroicons:calendar-days"
class="w-6 h-6 text-blue-400" class="w-6 h-6 text-candlelight-400"
/> />
</div> </div>
<h3 class="font-semibold text-guild-100 mb-2"> <h3 class="font-semibold text-guild-100 mb-2">
2. Join an Event <span class="text-ui-label text-candlelight-400 mr-2">2.</span>Join an Event
</h3> </h3>
<p class="text-sm text-guild-400 mb-4"> <p class="text-sm text-guild-400 mb-4">
From workshops to game nights, events are the heart of our From workshops to game nights, events are the heart of our
@ -80,12 +79,12 @@
<div class="p-6 bg-guild-800/50 rounded-xl border border-guild-700"> <div class="p-6 bg-guild-800/50 rounded-xl border border-guild-700">
<div <div
class="w-12 h-12 bg-green-500/20 rounded-lg flex items-center justify-center mb-4" class="w-12 h-12 bg-candlelight-500/20 rounded-lg flex items-center justify-center mb-4"
> >
<Icon name="heroicons:users" class="w-6 h-6 text-green-400" /> <Icon name="heroicons:users" class="w-6 h-6 text-candlelight-400" />
</div> </div>
<h3 class="font-semibold text-guild-100 mb-2"> <h3 class="font-semibold text-guild-100 mb-2">
3. Meet the Community <span class="text-ui-label text-candlelight-400 mr-2">3.</span>Meet the Community
</h3> </h3>
<p class="text-sm text-guild-400 mb-4"> <p class="text-sm text-guild-400 mb-4">
Connect with other members and find peers for support and Connect with other members and find peers for support and
@ -101,7 +100,7 @@
<div <div
class="p-8 bg-guild-800/30 rounded-2xl border border-guild-700 mb-16" class="p-8 bg-guild-800/30 rounded-2xl border border-guild-700 mb-16"
> >
<h3 class="text-xl font-bold text-guild-100 mb-4"> <h3 class="text-display-sm font-bold text-guild-100 mb-4">
Understanding Circles Understanding Circles
</h3> </h3>
<p class="text-guild-300 mb-6"> <p class="text-guild-300 mb-6">
@ -115,7 +114,7 @@
class="p-4 rounded-lg" class="p-4 rounded-lg"
:class=" :class="
memberData?.circle === 'community' memberData?.circle === 'community'
? 'bg-purple-500/20 border border-purple-500/50' ? 'circle-surface-community border border-[var(--color-circle-community)]/50'
: 'bg-guild-800/50' : 'bg-guild-800/50'
" "
> >
@ -123,7 +122,7 @@
Community Circle Community Circle
<span <span
v-if="memberData?.circle === 'community'" v-if="memberData?.circle === 'community'"
class="text-purple-400 text-sm ml-2" class="text-candlelight-400 text-sm ml-2"
> You're here</span > You're here</span
> >
</h4> </h4>
@ -137,7 +136,7 @@
class="p-4 rounded-lg" class="p-4 rounded-lg"
:class=" :class="
memberData?.circle === 'founder' memberData?.circle === 'founder'
? 'bg-purple-500/20 border border-purple-500/50' ? 'circle-surface-founder border border-[var(--color-circle-founder)]/50'
: 'bg-guild-800/50' : 'bg-guild-800/50'
" "
> >
@ -145,7 +144,7 @@
Founder Circle Founder Circle
<span <span
v-if="memberData?.circle === 'founder'" v-if="memberData?.circle === 'founder'"
class="text-purple-400 text-sm ml-2" class="text-candlelight-400 text-sm ml-2"
> You're here</span > You're here</span
> >
</h4> </h4>
@ -159,7 +158,7 @@
class="p-4 rounded-lg" class="p-4 rounded-lg"
:class=" :class="
memberData?.circle === 'practitioner' memberData?.circle === 'practitioner'
? 'bg-purple-500/20 border border-purple-500/50' ? 'circle-surface-practitioner border border-[var(--color-circle-practitioner)]/50'
: 'bg-guild-800/50' : 'bg-guild-800/50'
" "
> >
@ -167,7 +166,7 @@
Practitioner Circle Practitioner Circle
<span <span
v-if="memberData?.circle === 'practitioner'" v-if="memberData?.circle === 'practitioner'"
class="text-purple-400 text-sm ml-2" class="text-candlelight-400 text-sm ml-2"
> You're here</span > You're here</span
> >
</h4> </h4>
@ -183,17 +182,17 @@
<div <div
class="p-8 bg-guild-800/30 rounded-2xl border border-guild-700 mb-16" class="p-8 bg-guild-800/30 rounded-2xl border border-guild-700 mb-16"
> >
<h3 class="text-xl font-bold text-guild-100 mb-4"> <h3 class="text-display-sm font-bold text-guild-100 mb-4">
Resources & Support Resources & Support
</h3> </h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="flex items-start gap-4"> <div class="flex items-start gap-4">
<div <div
class="w-10 h-10 bg-amber-500/20 rounded-lg flex items-center justify-center flex-shrink-0" class="w-10 h-10 bg-candlelight-500/20 rounded-lg flex items-center justify-center flex-shrink-0"
> >
<Icon <Icon
name="heroicons:book-open" name="heroicons:book-open"
class="w-5 h-5 text-amber-400" class="w-5 h-5 text-candlelight-400"
/> />
</div> </div>
<div> <div>
@ -218,11 +217,11 @@
<div class="flex items-start gap-4"> <div class="flex items-start gap-4">
<div <div
class="w-10 h-10 bg-pink-500/20 rounded-lg flex items-center justify-center flex-shrink-0" class="w-10 h-10 bg-ember-500/20 rounded-lg flex items-center justify-center flex-shrink-0"
> >
<Icon <Icon
name="heroicons:chat-bubble-left-right" name="heroicons:chat-bubble-left-right"
class="w-5 h-5 text-pink-400" class="w-5 h-5 text-ember-400"
/> />
</div> </div>
<div> <div>

View file

@ -10,6 +10,13 @@ export default defineNuxtConfig({
domain: "ghostguild.org", domain: "ghostguild.org",
}, },
css: ["~/assets/css/main.css"], css: ["~/assets/css/main.css"],
vite: {
server: {
hmr: {
port: 24678,
},
},
},
runtimeConfig: { runtimeConfig: {
// Private keys (server-side only) // Private keys (server-side only)
mongodbUri: mongodbUri:

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

View file

@ -59,7 +59,7 @@ export default defineEventHandler(async (event) => {
<p style="color: #bfb3a2;">Click the button below to sign in:</p> <p style="color: #bfb3a2;">Click the button below to sign in:</p>
<div style="text-align: center; margin: 30px 0;"> <div style="text-align: center; margin: 30px 0;">
<a href="${baseUrl}/oidc/interaction/verify?token=${token}" <a href="${baseUrl}/oidc/interaction/verify?token=${token}"
style="background-color: #9a6f2c; color: #f0ebe4; padding: 12px 24px; text-decoration: none; border-radius: 6px; display: inline-block; font-weight: 600;"> style="background-color: #d09e4e; color: #1a1510; padding: 12px 24px; text-decoration: none; border-radius: 6px; display: inline-block; font-weight: 700;">
Sign In Sign In
</a> </a>
</div> </div>