Accessibility fixes.
This commit is contained in:
parent
4aacb26c4b
commit
88c94aaaf4
12 changed files with 276 additions and 260 deletions
|
|
@ -3,7 +3,7 @@
|
|||
<div class="page-header">
|
||||
<div class="header-row">
|
||||
<NuxtLink to="/admin/events" class="back-link">← Events</NuxtLink>
|
||||
<h1>{{ editingEvent ? 'Edit Event' : 'Create Event' }}</h1>
|
||||
<h1>{{ editingEvent ? "Edit Event" : "Create Event" }}</h1>
|
||||
<p>Fill out the form below to create or update an event</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -32,9 +32,7 @@
|
|||
<h2 class="section-heading">Basic Information</h2>
|
||||
|
||||
<div class="field">
|
||||
<label>
|
||||
Event Title <span class="required">*</span>
|
||||
</label>
|
||||
<label> Event Title <span class="required">*</span> </label>
|
||||
<UInput
|
||||
v-model="eventForm.title"
|
||||
placeholder="Enter a clear, descriptive event title"
|
||||
|
|
@ -51,15 +49,13 @@
|
|||
<label>Feature Image</label>
|
||||
<ImageUpload v-model="eventForm.featureImage" />
|
||||
<p class="help-text">
|
||||
Upload a high-quality image (1200x630px recommended) to
|
||||
represent your event
|
||||
Upload a high-quality image (1200x630px recommended) to represent
|
||||
your event
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>
|
||||
Event Description <span class="required">*</span>
|
||||
</label>
|
||||
<label> Event Description <span class="required">*</span> </label>
|
||||
<UTextarea
|
||||
v-model="eventForm.description"
|
||||
placeholder="Provide a clear description of what attendees can expect from this event"
|
||||
|
|
@ -97,11 +93,10 @@
|
|||
|
||||
<div class="form-grid">
|
||||
<div class="field">
|
||||
<label>
|
||||
Event Type <span class="required">*</span>
|
||||
</label>
|
||||
<label> Event Type <span class="required">*</span> </label>
|
||||
<USelect
|
||||
v-model="eventForm.eventType"
|
||||
aria-label="Event Type"
|
||||
:items="[
|
||||
{ label: 'Community Meetup', value: 'community' },
|
||||
{ label: 'Workshop', value: 'workshop' },
|
||||
|
|
@ -116,9 +111,7 @@
|
|||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>
|
||||
Location <span class="required">*</span>
|
||||
</label>
|
||||
<label> Location <span class="required">*</span> </label>
|
||||
<UInput
|
||||
v-model="eventForm.location"
|
||||
placeholder="e.g., https://zoom.us/j/123... or #channel-name"
|
||||
|
|
@ -135,9 +128,7 @@
|
|||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>
|
||||
Start Date & Time <span class="required">*</span>
|
||||
</label>
|
||||
<label> Start Date & Time <span class="required">*</span> </label>
|
||||
<NaturalDateInput
|
||||
v-model="eventForm.startDate"
|
||||
placeholder="e.g., 'tomorrow at 3pm', 'next Friday at 9am'"
|
||||
|
|
@ -149,9 +140,7 @@
|
|||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>
|
||||
End Date & Time <span class="required">*</span>
|
||||
</label>
|
||||
<label> End Date & Time <span class="required">*</span> </label>
|
||||
<NaturalDateInput
|
||||
v-model="eventForm.endDate"
|
||||
placeholder="e.g., 'tomorrow at 5pm', 'next Friday at 11am'"
|
||||
|
|
@ -248,22 +237,14 @@
|
|||
<h2 class="section-heading">Ticketing</h2>
|
||||
|
||||
<label class="check-label">
|
||||
<input
|
||||
v-model="eventForm.tickets.enabled"
|
||||
type="checkbox"
|
||||
/>
|
||||
<input v-model="eventForm.tickets.enabled" type="checkbox" />
|
||||
<div>
|
||||
<strong>Enable Ticketing</strong>
|
||||
<span class="help-text">
|
||||
Allow ticket sales for this event
|
||||
</span>
|
||||
<span class="help-text"> Allow ticket sales for this event </span>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<div
|
||||
v-if="eventForm.tickets.enabled"
|
||||
class="nested-section"
|
||||
>
|
||||
<div v-if="eventForm.tickets.enabled" class="nested-section">
|
||||
<label class="check-label">
|
||||
<input
|
||||
v-model="eventForm.tickets.public.available"
|
||||
|
|
@ -298,9 +279,7 @@
|
|||
placeholder="0.00"
|
||||
class="w-full"
|
||||
/>
|
||||
<p class="help-text">
|
||||
Set to 0 for free public events
|
||||
</p>
|
||||
<p class="help-text">Set to 0 for free public events</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -339,7 +318,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="eventForm.tickets.public.earlyBirdPrice > 0" class="field">
|
||||
<div
|
||||
v-if="eventForm.tickets.public.earlyBirdPrice > 0"
|
||||
class="field"
|
||||
>
|
||||
<label>Early Bird Deadline</label>
|
||||
<NaturalDateInput
|
||||
v-model="eventForm.tickets.public.earlyBirdDeadline"
|
||||
|
|
@ -353,8 +335,8 @@
|
|||
</div>
|
||||
|
||||
<div class="note-box">
|
||||
<strong>Note:</strong> Members always get free access to all
|
||||
events regardless of ticket settings.
|
||||
<strong>Note:</strong> Members always get free access to all events
|
||||
regardless of ticket settings.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -363,10 +345,7 @@
|
|||
<h2 class="section-heading">Series Management</h2>
|
||||
|
||||
<label class="check-label">
|
||||
<input
|
||||
v-model="eventForm.series.isSeriesEvent"
|
||||
type="checkbox"
|
||||
/>
|
||||
<input v-model="eventForm.series.isSeriesEvent" type="checkbox" />
|
||||
<div>
|
||||
<strong>Part of Event Series</strong>
|
||||
<span class="help-text">
|
||||
|
|
@ -375,17 +354,13 @@
|
|||
</div>
|
||||
</label>
|
||||
|
||||
<div
|
||||
v-if="eventForm.series.isSeriesEvent"
|
||||
class="nested-section"
|
||||
>
|
||||
<div v-if="eventForm.series.isSeriesEvent" class="nested-section">
|
||||
<div class="field">
|
||||
<label>
|
||||
Select Series <span class="required">*</span>
|
||||
</label>
|
||||
<label> Select Series <span class="required">*</span> </label>
|
||||
<div class="series-select-row">
|
||||
<USelect
|
||||
v-model="selectedSeriesId"
|
||||
aria-label="Select Series"
|
||||
@update:model-value="onSeriesSelect"
|
||||
:items="
|
||||
availableSeries.map((series) => ({
|
||||
|
|
@ -397,10 +372,7 @@
|
|||
value-key="value"
|
||||
class="w-full"
|
||||
/>
|
||||
<NuxtLink
|
||||
to="/admin/series/create"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
<NuxtLink to="/admin/series/create" class="btn btn-primary">
|
||||
New Series
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
|
@ -409,13 +381,9 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="selectedSeriesId || eventForm.series.id"
|
||||
>
|
||||
<div v-if="selectedSeriesId || eventForm.series.id">
|
||||
<div class="field">
|
||||
<label>
|
||||
Series Title <span class="required">*</span>
|
||||
</label>
|
||||
<label> Series Title <span class="required">*</span> </label>
|
||||
<UInput
|
||||
v-model="eventForm.series.title"
|
||||
placeholder="e.g., Cooperative Game Development Fundamentals"
|
||||
|
|
@ -454,8 +422,8 @@
|
|||
</div>
|
||||
|
||||
<div v-if="selectedSeriesId" class="note-box">
|
||||
<strong>Note:</strong> This event will be added to the
|
||||
existing "{{ eventForm.series.title }}" series.
|
||||
<strong>Note:</strong> This event will be added to the existing
|
||||
"{{ eventForm.series.title }}" series.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -507,10 +475,7 @@
|
|||
<div class="form-grid">
|
||||
<div class="check-group">
|
||||
<label class="check-label">
|
||||
<input
|
||||
v-model="eventForm.isOnline"
|
||||
type="checkbox"
|
||||
/>
|
||||
<input v-model="eventForm.isOnline" type="checkbox" />
|
||||
<div>
|
||||
<strong>Online Event</strong>
|
||||
<span class="help-text">
|
||||
|
|
@ -535,10 +500,7 @@
|
|||
|
||||
<div class="check-group">
|
||||
<label class="check-label">
|
||||
<input
|
||||
v-model="eventForm.isVisible"
|
||||
type="checkbox"
|
||||
/>
|
||||
<input v-model="eventForm.isVisible" type="checkbox" />
|
||||
<div>
|
||||
<strong>Visible on Public Calendar</strong>
|
||||
<span class="help-text">
|
||||
|
|
@ -548,15 +510,10 @@
|
|||
</label>
|
||||
|
||||
<label class="check-label">
|
||||
<input
|
||||
v-model="eventForm.isCancelled"
|
||||
type="checkbox"
|
||||
/>
|
||||
<input v-model="eventForm.isCancelled" type="checkbox" />
|
||||
<div>
|
||||
<strong>Event Cancelled</strong>
|
||||
<span class="help-text">
|
||||
Mark this event as cancelled
|
||||
</span>
|
||||
<span class="help-text"> Mark this event as cancelled </span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
|
@ -582,9 +539,7 @@
|
|||
|
||||
<!-- Form Actions -->
|
||||
<div class="form-actions">
|
||||
<NuxtLink to="/admin/events" class="btn">
|
||||
Cancel
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/events" class="btn"> Cancel </NuxtLink>
|
||||
|
||||
<div class="form-actions-right">
|
||||
<button
|
||||
|
|
@ -597,11 +552,7 @@
|
|||
{{ creating ? "Saving..." : "Save & Create Another" }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="creating"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
<button type="submit" :disabled="creating" class="btn btn-primary">
|
||||
{{
|
||||
creating
|
||||
? "Saving..."
|
||||
|
|
@ -1007,7 +958,7 @@ const saveAndCreateAnother = async () => {
|
|||
}
|
||||
|
||||
.page-header h1 {
|
||||
font-family: 'Brygada 1918', serif;
|
||||
font-family: "Brygada 1918", serif;
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
color: var(--text-bright);
|
||||
|
|
@ -1037,7 +988,7 @@ const saveAndCreateAnother = async () => {
|
|||
}
|
||||
|
||||
.section-heading {
|
||||
font-family: 'Brygada 1918', serif;
|
||||
font-family: "Brygada 1918", serif;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--text-bright);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
<input v-model="searchQuery" placeholder="Search members..." />
|
||||
</div>
|
||||
<div class="field" style="margin-bottom: 0">
|
||||
<select v-model="circleFilter">
|
||||
<select v-model="circleFilter" aria-label="Filter by circle">
|
||||
<option value="">All Circles</option>
|
||||
<option value="community">Community</option>
|
||||
<option value="founder">Founder</option>
|
||||
|
|
@ -56,6 +56,8 @@
|
|||
<tr>
|
||||
<th class="col-check">
|
||||
<UCheckbox
|
||||
label="Select all members"
|
||||
:ui="{ label: 'sr-only' }"
|
||||
:model-value="
|
||||
allVisibleSelected
|
||||
? true
|
||||
|
|
@ -80,6 +82,8 @@
|
|||
<tr v-for="member in filteredMembers" :key="member._id">
|
||||
<td class="col-check">
|
||||
<UCheckbox
|
||||
:label="`Select ${member.name}`"
|
||||
:ui="{ label: 'sr-only' }"
|
||||
:model-value="selectedMemberIds.includes(member._id)"
|
||||
@update:model-value="toggleSelect(member._id)"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -403,13 +403,12 @@ const isAlmostFull = (event) => {
|
|||
color: var(--candle);
|
||||
}
|
||||
.cta-soon {
|
||||
color: var(--text-faint);
|
||||
color: var(--text-dim);
|
||||
cursor: default;
|
||||
}
|
||||
.cta-soon em {
|
||||
font-style: normal;
|
||||
font-size: 10px;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
.filter-toggle {
|
||||
|
|
|
|||
|
|
@ -256,22 +256,21 @@ const copyCalendarLink = async () => {
|
|||
const { openLoginModal } = useLoginModal();
|
||||
|
||||
// Handle authentication check on page load
|
||||
// server: false ensures this always runs on the client, even on a hard page load.
|
||||
// The auth middleware only fires for client-side navigations in Nuxt 4, so we
|
||||
// can't rely on it to open the modal when the user lands directly on this URL.
|
||||
const { pending: authPending } = await useLazyAsyncData(
|
||||
"dashboard-auth",
|
||||
async () => {
|
||||
// Only check authentication on client side
|
||||
if (process.server) return null;
|
||||
|
||||
// If no member data, try to authenticate
|
||||
if (!memberData.value) {
|
||||
const isAuthenticated = await checkMemberStatus();
|
||||
|
||||
if (!isAuthenticated) {
|
||||
// Show login modal instead of redirecting
|
||||
openLoginModal({
|
||||
title: "Sign in to your dashboard",
|
||||
description: "Enter your email to access your member dashboard",
|
||||
title: "Sign in to continue",
|
||||
description: "You need to be signed in to access this page",
|
||||
dismissible: true,
|
||||
redirectTo: "/member/dashboard",
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
|
@ -279,6 +278,7 @@ const { pending: authPending } = await useLazyAsyncData(
|
|||
|
||||
return memberData.value;
|
||||
},
|
||||
{ server: false },
|
||||
);
|
||||
|
||||
// Load registered events
|
||||
|
|
|
|||
|
|
@ -188,7 +188,10 @@
|
|||
<div class="section-label">Visibility</div>
|
||||
|
||||
<div class="toggle-field">
|
||||
<USwitch v-model="formData.showInDirectory" />
|
||||
<USwitch
|
||||
v-model="formData.showInDirectory"
|
||||
aria-label="Show in Member Directory"
|
||||
/>
|
||||
<div class="toggle-label">
|
||||
Show in Member Directory
|
||||
<span class="toggle-sub"
|
||||
|
|
@ -206,7 +209,10 @@
|
|||
<div class="section-label">Peer Support</div>
|
||||
|
||||
<div class="toggle-field">
|
||||
<USwitch v-model="formData.peerSupportEnabled" />
|
||||
<USwitch
|
||||
v-model="formData.peerSupportEnabled"
|
||||
aria-label="Offer Peer Support"
|
||||
/>
|
||||
<div class="toggle-label">
|
||||
Offer Peer Support
|
||||
<span class="toggle-sub"
|
||||
|
|
@ -291,7 +297,10 @@
|
|||
<div class="section-label">Notifications</div>
|
||||
|
||||
<div class="toggle-field">
|
||||
<USwitch v-model="formData.notifyEvents" />
|
||||
<USwitch
|
||||
v-model="formData.notifyEvents"
|
||||
aria-label="Event reminders"
|
||||
/>
|
||||
<div class="toggle-label">
|
||||
Event reminders
|
||||
<span class="toggle-sub"
|
||||
|
|
@ -301,7 +310,10 @@
|
|||
</div>
|
||||
|
||||
<div class="toggle-field">
|
||||
<USwitch v-model="formData.notifyUpdates" />
|
||||
<USwitch
|
||||
v-model="formData.notifyUpdates"
|
||||
aria-label="Community updates"
|
||||
/>
|
||||
<div class="toggle-label">
|
||||
Community updates
|
||||
<span class="toggle-sub"
|
||||
|
|
@ -311,7 +323,10 @@
|
|||
</div>
|
||||
|
||||
<div class="toggle-field">
|
||||
<USwitch v-model="formData.notifyPeerRequests" />
|
||||
<USwitch
|
||||
v-model="formData.notifyPeerRequests"
|
||||
aria-label="Peer support requests"
|
||||
/>
|
||||
<div class="toggle-label">
|
||||
Peer support requests
|
||||
<span class="toggle-sub"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue