Many an update!
This commit is contained in:
parent
85195d6c7a
commit
d588c49946
35 changed files with 3528 additions and 1142 deletions
|
|
@ -13,13 +13,115 @@
|
|||
<UTabs
|
||||
v-model="activeTab"
|
||||
:items="[
|
||||
{ label: 'Upcoming Events', value: 'upcoming', slot: 'upcoming' },
|
||||
{ label: 'What\'s On', value: 'upcoming', slot: 'upcoming' },
|
||||
{ label: 'Calendar', value: 'calendar', slot: 'calendar' },
|
||||
]"
|
||||
class="max-w-6xl mx-auto"
|
||||
>
|
||||
<template #upcoming>
|
||||
<div class="max-w-4xl mx-auto space-y-6 pt-8">
|
||||
<!-- Search and Filter Controls -->
|
||||
<div class="pt-8">
|
||||
<div class="max-w-4xl mx-auto mb-8">
|
||||
<div class="flex flex-col gap-4">
|
||||
<!-- Search Input -->
|
||||
<div
|
||||
class="flex flex-row flex-wrap gap-4 items-center justify-center"
|
||||
>
|
||||
<UInput
|
||||
v-model="searchQuery"
|
||||
placeholder="Search events..."
|
||||
autocomplete="off"
|
||||
size="xl"
|
||||
class="rounded-md shadow-sm text-lg w-full md:w-2/3"
|
||||
:ui="{ icon: { trailing: { pointer: '' } } }"
|
||||
>
|
||||
<template #trailing>
|
||||
<UButton
|
||||
v-show="searchQuery"
|
||||
icon="i-heroicons-x-mark-20-solid"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
@click="searchQuery = ''"
|
||||
class="mr-1"
|
||||
/>
|
||||
</template>
|
||||
</UInput>
|
||||
|
||||
<!-- Past Events Toggle -->
|
||||
<div
|
||||
class="flex flex-col items-center md:items-start gap-2"
|
||||
>
|
||||
<label class="text-sm font-medium text-ghost-200">
|
||||
Show past events?
|
||||
</label>
|
||||
<USwitch v-model="includePastEvents" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Category Filter -->
|
||||
<div class="flex justify-center">
|
||||
<UPopover
|
||||
:ui="{ base: 'overflow-visible' }"
|
||||
:popper="{
|
||||
placement: 'bottom-end',
|
||||
strategy: 'absolute',
|
||||
}"
|
||||
>
|
||||
<UButton
|
||||
icon="i-heroicons-adjustments-vertical-20-solid"
|
||||
variant="outline"
|
||||
color="primary"
|
||||
size="sm"
|
||||
class="rounded-md shadow-sm"
|
||||
>
|
||||
Filter Events
|
||||
</UButton>
|
||||
|
||||
<template #panel="{ close }">
|
||||
<div
|
||||
class="bg-ghost-800 dark:bg-ghost-900 p-6 rounded-md shadow-lg w-80 space-y-4"
|
||||
>
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-medium text-ghost-200">
|
||||
Filter by category
|
||||
</label>
|
||||
<USelectMenu
|
||||
v-model="selectedCategories"
|
||||
:options="eventCategories"
|
||||
option-attribute="name"
|
||||
multiple
|
||||
value-attribute="id"
|
||||
placeholder="Select categories..."
|
||||
:ui="{
|
||||
base: 'overflow-visible',
|
||||
menu: { maxHeight: '200px', overflowY: 'auto' },
|
||||
popper: { strategy: 'absolute' },
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</UPopover>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search Status Message -->
|
||||
<div v-if="isSearching" class="mt-6 text-center">
|
||||
<p class="text-ghost-300 text-sm">
|
||||
{{
|
||||
filteredEvents.length > 0
|
||||
? `Found ${filteredEvents.length} event${
|
||||
filteredEvents.length !== 1 ? "s" : ""
|
||||
}`
|
||||
: "No events found matching your search"
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Events List -->
|
||||
<div class="max-w-4xl mx-auto space-y-6 pb-8">
|
||||
<NuxtLink
|
||||
v-for="event in upcomingEvents"
|
||||
:key="event.id"
|
||||
|
|
@ -76,48 +178,49 @@
|
|||
</template>
|
||||
|
||||
<template #calendar>
|
||||
<div class="pt-8">
|
||||
<ClientOnly>
|
||||
<div
|
||||
v-if="pending"
|
||||
class="min-h-[400px] bg-ghost-700 rounded-xl flex items-center justify-center"
|
||||
>
|
||||
<div class="text-center">
|
||||
<p class="text-ghost-200">Loading events...</p>
|
||||
</div>
|
||||
</div>
|
||||
<VueCal
|
||||
v-else
|
||||
:events="events"
|
||||
:time="false"
|
||||
active-view="month"
|
||||
class="custom-calendar"
|
||||
:disable-views="['years', 'year']"
|
||||
:hide-weekends="false"
|
||||
today-button
|
||||
events-on-month-view="short"
|
||||
:editable-events="{
|
||||
title: false,
|
||||
drag: false,
|
||||
resize: false,
|
||||
delete: false,
|
||||
create: false,
|
||||
}"
|
||||
@event-click="onEventClick"
|
||||
/>
|
||||
<template #fallback>
|
||||
<div class="pt-8 pb-8">
|
||||
<div class="max-w-6xl mx-auto" id="event-calendar">
|
||||
<ClientOnly>
|
||||
<div
|
||||
class="min-h-[400px] bg-ghost-700 rounded-xl flex items-center justify-center"
|
||||
v-if="pending"
|
||||
class="min-h-[400px] bg-ghost-800 rounded-xl flex items-center justify-center"
|
||||
>
|
||||
<div class="text-center">
|
||||
<div
|
||||
class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-4"
|
||||
class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"
|
||||
></div>
|
||||
<p class="text-ghost-200">Loading calendar...</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ClientOnly>
|
||||
<div v-else style="min-height: 600px">
|
||||
<VueCal
|
||||
ref="vuecal"
|
||||
:events="calendarEvents"
|
||||
:time="false"
|
||||
active-view="month"
|
||||
class="ghost-calendar"
|
||||
:disable-views="['years', 'year']"
|
||||
:hide-view-selector="false"
|
||||
events-on-month-view="short"
|
||||
today-button
|
||||
@event-click="onEventClick"
|
||||
>
|
||||
</VueCal>
|
||||
</div>
|
||||
<template #fallback>
|
||||
<div
|
||||
class="min-h-[400px] bg-ghost-800 rounded-xl flex items-center justify-center"
|
||||
>
|
||||
<div class="text-center">
|
||||
<div
|
||||
class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"
|
||||
></div>
|
||||
<p class="text-ghost-200">Loading calendar...</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
|
|
@ -183,7 +286,7 @@
|
|||
<div class="series-list-item__events space-y-2 mb-4">
|
||||
<div
|
||||
v-for="(event, index) in series.events.slice(0, 3)"
|
||||
:key="event.id"
|
||||
:key="index"
|
||||
class="series-list-item__event flex items-center justify-between text-xs"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
|
|
@ -234,28 +337,16 @@
|
|||
>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p class="text-lg leading-relaxed text-ghost-200 mb-6">
|
||||
Our events are ,Lorem ipsum, dolor sit amet consectetur
|
||||
adipisicing elit. Quibusdam exercitationem delectus ab
|
||||
voluptates aspernatur, quia deleniti aut maxime, veniam
|
||||
accusantium non dolores saepe error, ipsam laudantium asperiores
|
||||
dolorum alias nulla!
|
||||
Our events bring together game developers, founders, and practitioners
|
||||
who are building more equitable workplaces. From hands-on workshops
|
||||
about governance and finance to casual co-working sessions and game nights,
|
||||
there's something for every stage of your journey.
|
||||
</p>
|
||||
|
||||
<p class="text-lg leading-relaxed text-ghost-200 mb-6">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
|
||||
in reprehenderit in voluptate velit esse cillum dolore eu fugiat
|
||||
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
|
||||
sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
|
||||
in reprehenderit in voluptate velit esse cillum dolore eu fugiat
|
||||
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
|
||||
sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
All events are designed to be accessible, with most offered free to members
|
||||
and sliding-scale pricing for non-members. Can't make it live?
|
||||
Many sessions are recorded and shared in our resource library.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -301,19 +392,64 @@
|
|||
import { VueCal } from "vue-cal";
|
||||
import "vue-cal/style.css";
|
||||
|
||||
// Composables
|
||||
const { formatDateRange, formatDate, isPastDate } = useEventDateUtils();
|
||||
const {
|
||||
searchQuery,
|
||||
includePastEvents,
|
||||
searchResults,
|
||||
selectedCategories,
|
||||
isSearching,
|
||||
saveSearchState,
|
||||
loadSearchState,
|
||||
clearSearch: clearSearchFilters,
|
||||
} = useCalendarSearch();
|
||||
|
||||
// Active tab state
|
||||
const activeTab = ref("upcoming");
|
||||
|
||||
// Hover state for calendar cells
|
||||
const hoveredCells = ref({});
|
||||
|
||||
const handleMouseEnter = (date) => {
|
||||
hoveredCells.value[date] = true;
|
||||
};
|
||||
|
||||
const handleMouseLeave = (date) => {
|
||||
hoveredCells.value[date] = false;
|
||||
};
|
||||
|
||||
const isHovered = (date) => {
|
||||
return hoveredCells.value[date] || false;
|
||||
};
|
||||
|
||||
// Fetch events from API
|
||||
const { data: eventsData, pending, error } = await useFetch("/api/events");
|
||||
// Fetch series from API
|
||||
const { data: seriesData } = await useFetch("/api/series");
|
||||
|
||||
// Event categories for filtering
|
||||
const eventCategories = computed(() => {
|
||||
if (!eventsData.value) return [];
|
||||
const categories = new Set();
|
||||
eventsData.value.forEach((event) => {
|
||||
if (event.eventType) {
|
||||
categories.add(event.eventType);
|
||||
}
|
||||
});
|
||||
return Array.from(categories).map((type) => ({
|
||||
id: type,
|
||||
name: type.charAt(0).toUpperCase() + type.slice(1),
|
||||
}));
|
||||
});
|
||||
|
||||
// Transform events for calendar display
|
||||
const events = computed(() => {
|
||||
if (!eventsData.value) return [];
|
||||
if (!eventsData.value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return eventsData.value.map((event) => ({
|
||||
const transformed = eventsData.value.map((event) => ({
|
||||
id: event.id || event._id,
|
||||
slug: event.slug,
|
||||
start: new Date(event.startDate),
|
||||
|
|
@ -329,6 +465,71 @@ const events = computed(() => {
|
|||
featureImage: event.featureImage,
|
||||
series: event.series,
|
||||
}));
|
||||
return transformed;
|
||||
});
|
||||
|
||||
// Helper function to format date for VueCal
|
||||
// When time is disabled, VueCal expects just 'YYYY-MM-DD' format
|
||||
const formatDateForVueCal = (date) => {
|
||||
const d = date instanceof Date ? date : new Date(date);
|
||||
const year = d.getFullYear();
|
||||
const month = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(d.getDate()).padStart(2, "0");
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
|
||||
// Transform events for calendar view
|
||||
const calendarEvents = computed(() => {
|
||||
const filtered = events.value
|
||||
.filter((event) => {
|
||||
// Filter by past events setting
|
||||
if (!includePastEvents.value && isPastDate(event.start)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((event) => {
|
||||
// VueCal expects Date objects when time is disabled
|
||||
// Only pass title (no content/description) for clean display
|
||||
return {
|
||||
start: event.start, // Use Date object directly
|
||||
end: event.end, // Use Date object directly
|
||||
title: event.title, // Only title, no description
|
||||
class: event.class,
|
||||
};
|
||||
});
|
||||
|
||||
return filtered;
|
||||
});
|
||||
|
||||
// Filter events based on search query and selected categories
|
||||
const filteredEvents = computed(() => {
|
||||
return events.value.filter((event) => {
|
||||
// Filter by past events setting
|
||||
if (!includePastEvents.value && isPastDate(event.start)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Filter by search query
|
||||
if (searchQuery.value) {
|
||||
const query = searchQuery.value.toLowerCase();
|
||||
const matchesTitle = event.title.toLowerCase().includes(query);
|
||||
const matchesDescription =
|
||||
event.content?.toLowerCase().includes(query) || false;
|
||||
if (!matchesTitle && !matchesDescription) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter by selected categories
|
||||
if (selectedCategories.value.length > 0) {
|
||||
if (!selectedCategories.value.includes(event.eventType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
// Get active event series
|
||||
|
|
@ -340,13 +541,13 @@ const activeSeries = computed(() => {
|
|||
);
|
||||
});
|
||||
|
||||
// Get upcoming events (future events)
|
||||
// Get upcoming events (future events, respecting filters)
|
||||
const upcomingEvents = computed(() => {
|
||||
const now = new Date();
|
||||
return events.value
|
||||
return filteredEvents.value
|
||||
.filter((event) => event.start > now)
|
||||
.sort((a, b) => a.start - b.start)
|
||||
.slice(0, 6); // Show max 6 upcoming events
|
||||
.slice(0, 10); // Show max 10 upcoming events
|
||||
});
|
||||
|
||||
// Format event date for display
|
||||
|
|
@ -426,30 +627,6 @@ const getSeriesTypeBadgeClass = (type) => {
|
|||
"bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400"
|
||||
);
|
||||
};
|
||||
|
||||
const formatDateRange = (startDate, endDate) => {
|
||||
if (!startDate || !endDate) return "No dates";
|
||||
|
||||
const start = new Date(startDate);
|
||||
const end = new Date(endDate);
|
||||
|
||||
const startMonth = start.toLocaleDateString("en-US", { month: "short" });
|
||||
const endMonth = end.toLocaleDateString("en-US", { month: "short" });
|
||||
const startDay = start.getDate();
|
||||
const endDay = end.getDate();
|
||||
const year = end.getFullYear();
|
||||
|
||||
if (
|
||||
start.getMonth() === end.getMonth() &&
|
||||
start.getFullYear() === end.getFullYear()
|
||||
) {
|
||||
return `${startMonth} ${startDay}-${endDay}, ${year}`;
|
||||
} else if (start.getFullYear() === end.getFullYear()) {
|
||||
return `${startMonth} ${startDay} - ${endMonth} ${endDay}, ${year}`;
|
||||
} else {
|
||||
return `${formatEventDate(startDate)} - ${formatEventDate(endDate)}`;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
@ -460,8 +637,199 @@ const formatDateRange = (startDate, endDate) => {
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Custom calendar styling to match the site theme */
|
||||
.custom-calendar {
|
||||
/* Calendar styling based on tranzac design principles */
|
||||
.ghost-calendar :deep(.vuecal__event) {
|
||||
border-radius: 0.5rem;
|
||||
border: 2px solid #292524;
|
||||
transform: translateZ(0);
|
||||
transition: transform 300ms;
|
||||
}
|
||||
|
||||
.ghost-calendar :deep(.vuecal__event:hover) {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.ghost-calendar :deep(.vuecal__event-title) {
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ghost-calendar :deep(.vuecal__event-time) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ghost-calendar :deep(.vuecal__event.event-community) {
|
||||
background-color: #2563eb;
|
||||
color: #f5f5f4;
|
||||
border-color: #1d4ed8;
|
||||
}
|
||||
|
||||
.ghost-calendar :deep(.vuecal__event.event-workshop) {
|
||||
background-color: #059669;
|
||||
color: #f5f5f4;
|
||||
border-color: #047857;
|
||||
}
|
||||
|
||||
.ghost-calendar :deep(.vuecal__event.event-social) {
|
||||
background-color: #7c3aed;
|
||||
color: #f5f5f4;
|
||||
border-color: #6d28d9;
|
||||
}
|
||||
|
||||
.ghost-calendar :deep(.vuecal__event.event-showcase) {
|
||||
background-color: #d97706;
|
||||
color: #f5f5f4;
|
||||
border-color: #b45309;
|
||||
}
|
||||
|
||||
#event-calendar {
|
||||
.vuecal__cell-events-count {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.25rem;
|
||||
left: auto;
|
||||
background-color: transparent;
|
||||
color: #f5f5f4;
|
||||
font-weight: 700;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.month-view .vuecal__cell--today,
|
||||
.vuecal__cell--today {
|
||||
background-color: rgba(59, 130, 246, 0.15);
|
||||
color: #f5f5f4;
|
||||
border: 2px solid #3b82f6 !important;
|
||||
|
||||
.day-of-month {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.day-of-month::before {
|
||||
content: "Today";
|
||||
text-transform: uppercase;
|
||||
font-size: 0.75rem;
|
||||
margin-right: 0.5rem;
|
||||
display: none;
|
||||
color: #3b82f6;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.day-of-month::before {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vuecal__cell--selected {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.past-date {
|
||||
background-color: rgba(120, 113, 108, 0.1);
|
||||
color: #78716c;
|
||||
}
|
||||
|
||||
.vuecal__cell--has-events {
|
||||
}
|
||||
|
||||
.vuecal__cell--disabled {
|
||||
}
|
||||
|
||||
.vuecal__cell-events {
|
||||
}
|
||||
|
||||
.vuecal__event {
|
||||
border-radius: 0.5rem;
|
||||
border: 2px solid #3a3a3a;
|
||||
transform: translateZ(0);
|
||||
transition: transform 300ms;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
&.vuecal__event--selected {
|
||||
background-color: #2a2a2a;
|
||||
}
|
||||
|
||||
.vuecal__cell--today {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.vuecal__event-title {
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: #f5f5f4;
|
||||
}
|
||||
|
||||
.vuecal__event-time {
|
||||
font-weight: 400;
|
||||
color: #a8a29e;
|
||||
}
|
||||
|
||||
&.event-community {
|
||||
background-color: #2563eb;
|
||||
color: #f5f5f4;
|
||||
border-color: #1d4ed8;
|
||||
}
|
||||
|
||||
&.event-workshop {
|
||||
background-color: #059669;
|
||||
color: #f5f5f4;
|
||||
border-color: #047857;
|
||||
}
|
||||
|
||||
&.event-social {
|
||||
background-color: #7c3aed;
|
||||
color: #f5f5f4;
|
||||
border-color: #6d28d9;
|
||||
}
|
||||
|
||||
&.event-showcase {
|
||||
background-color: #d97706;
|
||||
color: #f5f5f4;
|
||||
border-color: #b45309;
|
||||
}
|
||||
}
|
||||
|
||||
.vuecal__cell.vuecal__cell--out-of-scope {
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.outOfScope {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
:not(.vuecal__cell--out-of-scope) .vuecal__cell {
|
||||
border: 1px solid #3a3a3a;
|
||||
}
|
||||
|
||||
.vuecal__cell:before {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.vuecal__title-bar {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ghost calendar theme */
|
||||
.ghost-calendar {
|
||||
--vuecal-primary-color: #fff;
|
||||
--vuecal-text-color: #e7e5e4;
|
||||
--vuecal-border-color: #57534e;
|
||||
|
|
@ -470,142 +838,124 @@ const formatDateRange = (startDate, endDate) => {
|
|||
background-color: #292524;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__bg) {
|
||||
.ghost-calendar :deep(.vuecal__bg) {
|
||||
background-color: #292524;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__header) {
|
||||
.ghost-calendar :deep(.vuecal__header) {
|
||||
background-color: #1c1917;
|
||||
border-bottom: 1px solid #57534e;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__title-bar) {
|
||||
.ghost-calendar :deep(.vuecal__title-bar) {
|
||||
background-color: #1c1917;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__title) {
|
||||
.ghost-calendar :deep(.vuecal__title) {
|
||||
color: #e7e5e4;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__weekdays-headings) {
|
||||
.ghost-calendar :deep(.vuecal__weekdays-headings) {
|
||||
background-color: #1c1917;
|
||||
border-bottom: 1px solid #57534e;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__heading) {
|
||||
.ghost-calendar :deep(.vuecal__heading) {
|
||||
color: #a8a29e;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__cell) {
|
||||
.ghost-calendar :deep(.vuecal__cell) {
|
||||
background-color: #292524;
|
||||
border-color: #57534e;
|
||||
color: #e7e5e4;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__cell:hover) {
|
||||
.ghost-calendar :deep(.vuecal__cell:hover) {
|
||||
background-color: #44403c;
|
||||
border-color: #78716c;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__cell-content) {
|
||||
.ghost-calendar :deep(.vuecal__cell-content) {
|
||||
color: #e7e5e4;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__cell--today) {
|
||||
background-color: #44403c;
|
||||
.ghost-calendar :deep(.vuecal__cell--today) {
|
||||
background-color: rgba(59, 130, 246, 0.1);
|
||||
border: 2px solid #3b82f6;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__cell--out-of-scope) {
|
||||
.ghost-calendar :deep(.vuecal__cell--out-of-scope) {
|
||||
background-color: #1c1917;
|
||||
color: #78716c;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__arrow) {
|
||||
.ghost-calendar :deep(.vuecal__arrow) {
|
||||
color: #a8a29e;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__arrow:hover) {
|
||||
.ghost-calendar :deep(.vuecal__arrow:hover) {
|
||||
background-color: #44403c;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__today-btn) {
|
||||
.ghost-calendar :deep(.vuecal__today-btn) {
|
||||
background-color: #44403c;
|
||||
color: white;
|
||||
color: #fff;
|
||||
border: 1px solid #78716c;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__today-btn:hover) {
|
||||
.ghost-calendar :deep(.vuecal__today-btn:hover) {
|
||||
background-color: #57534e;
|
||||
border-color: #a8a29e;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__view-btn),
|
||||
.custom-calendar :deep(button[class*="view"]) {
|
||||
.ghost-calendar :deep(.vuecal__view-btn),
|
||||
.ghost-calendar :deep(button[class*="view"]) {
|
||||
background-color: #44403c !important;
|
||||
color: #ffffff !important;
|
||||
border: 1px solid #78716c !important;
|
||||
font-weight: 600 !important;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__view-btn:hover),
|
||||
.custom-calendar :deep(button[class*="view"]:hover) {
|
||||
.ghost-calendar :deep(.vuecal__view-btn:hover),
|
||||
.ghost-calendar :deep(button[class*="view"]:hover) {
|
||||
background-color: #57534e !important;
|
||||
border-color: #a8a29e !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__view-btn--active),
|
||||
.custom-calendar :deep(button[class*="view"][class*="active"]) {
|
||||
.ghost-calendar :deep(.vuecal__view-btn--active),
|
||||
.ghost-calendar :deep(button[class*="view"][class*="active"]) {
|
||||
background-color: #0c0a09 !important;
|
||||
color: #ffffff !important;
|
||||
border-color: #a8a29e !important;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__view-btn--active:hover),
|
||||
.custom-calendar :deep(button[class*="view"][class*="active"]:hover) {
|
||||
.ghost-calendar :deep(.vuecal__view-btn--active:hover),
|
||||
.ghost-calendar :deep(button[class*="view"][class*="active"]:hover) {
|
||||
background-color: #1c1917 !important;
|
||||
border-color: #d6d3d1 !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__title-bar button) {
|
||||
.ghost-calendar :deep(.vuecal__title-bar button) {
|
||||
color: #ffffff !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__title-bar .default-view-btn) {
|
||||
.ghost-calendar :deep(.vuecal__title-bar .default-view-btn) {
|
||||
background-color: #44403c !important;
|
||||
color: #ffffff !important;
|
||||
border: 1px solid #78716c !important;
|
||||
}
|
||||
|
||||
.custom-calendar :deep(.vuecal__title-bar .default-view-btn.active) {
|
||||
.ghost-calendar :deep(.vuecal__title-bar .default-view-btn.active) {
|
||||
background-color: #0c0a09 !important;
|
||||
border-color: #a8a29e !important;
|
||||
}
|
||||
|
||||
/* Event type styling */
|
||||
.vuecal__event.event-community {
|
||||
background-color: #3b82f6;
|
||||
border-color: #2563eb;
|
||||
}
|
||||
|
||||
.vuecal__event.event-workshop {
|
||||
background-color: #10b981;
|
||||
border-color: #059669;
|
||||
}
|
||||
|
||||
.vuecal__event.event-social {
|
||||
background-color: #8b5cf6;
|
||||
border-color: #7c3aed;
|
||||
}
|
||||
|
||||
.vuecal__event.event-showcase {
|
||||
background-color: #f59e0b;
|
||||
border-color: #d97706;
|
||||
}
|
||||
|
||||
/* Responsive calendar */
|
||||
.vuecal {
|
||||
border-radius: 0.75rem;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue