diff --git a/src/lib/components/BlogCard.svelte b/src/lib/components/BlogCard.svelte
index dd02d40..25bf97d 100644
--- a/src/lib/components/BlogCard.svelte
+++ b/src/lib/components/BlogCard.svelte
@@ -10,7 +10,9 @@
import {
BLOG_POST_FRESHNESS_MILLIS,
blogPostTypeToIcon,
- blogPostTypeToString
+ blogPostTypeToString,
+ EventStatus,
+ postEventStatus
} from '$lib/util/Blogs';
import DateWidget from '$lib/components/DateWidget.svelte';
import Icon from '@iconify/svelte';
@@ -26,15 +28,20 @@
let isPostNew = $state(false);
let isPostUpdated = $state(false);
let isPostFresh = $derived(isPostNew || isPostUpdated);
- // TODO: rndtrash: события и их актуальность
+ let eventStatus: EventStatus | undefined = $state(undefined);
+ let isPostEventOfInterest = $derived(
+ type === 'event' &&
+ (eventStatus === EventStatus.NotStarted || eventStatus === EventStatus.InProgress)
+ );
+ let eventHasStarted = $derived(eventStatus === EventStatus.InProgress);
onMount(() => {
- // rndtrash: Выполняем проверки на клиенте, чтобы плашка не скомпилировалась и потом не потеряла актуальность
const dateNow = new Date().valueOf();
isPostNew = dateNow - new Date(post.date!).valueOf() <= BLOG_POST_FRESHNESS_MILLIS;
isPostUpdated =
post.dateChanged != null &&
dateNow - new Date(post.dateChanged).valueOf() <= BLOG_POST_FRESHNESS_MILLIS;
+ eventStatus = postEventStatus(post);
});
/**
@@ -71,7 +78,15 @@
href="/blog/{post.slug}"
class="blog-card
{fullHeight ? 'min-h-full' : ''}
- {isPostUpdated ? 'updated' : isPostNew ? 'new' : ''}
+ {isPostEventOfInterest
+ ? eventHasStarted
+ ? 'eventOngoing'
+ : 'eventPreStart'
+ : isPostUpdated
+ ? 'updated'
+ : isPostNew
+ ? 'new'
+ : ''}
{shortClass('flex-col justify-baseline')}
{fullClass('flex-row justify-stretch', 'sm:flex-row sm:justify-stretch')}"
>
@@ -87,7 +102,15 @@
alt={post.thumbnailAlt ?? 'Миниатюра поста'}
/>
{/if}
- {#if isPostFresh}
+ {#if isPostEventOfInterest}
+
+ {#if eventStatus === EventStatus.NotStarted}
+ СКОРО НАЧАЛО
+ {:else}
+ СОБЫТИЕ
+ {/if}
+
+ {:else if isPostFresh}
{#if isPostUpdated}
ОБНОВЛЕНО
@@ -99,25 +122,40 @@
-
- {#if post.dateChanged}
+ {#if isPostEventOfInterest}
+
+ {:else}
+
+ {#if post.dateChanged}
+
+ {/if}
+
+
+
+ {blogPostTypeToString(type)}
+
+
{/if}
-
-
-
- {blogPostTypeToString(type)}
-
-
{post.title}
@@ -139,7 +177,7 @@
}
&.updated {
- box-shadow: 0 0 0 4px var(--color-purple-600);
+ box-shadow: 0 0 0 calc(var(--spacing) * 1) var(--color-purple-600);
.toast {
@apply bg-purple-600;
@@ -147,13 +185,29 @@
}
&.new {
- box-shadow: 0 0 0 4px var(--color-amber-600);
+ box-shadow: 0 0 0 calc(var(--spacing) * 1) var(--color-amber-600);
.toast {
@apply bg-amber-600;
}
}
+ &.eventPreStart {
+ box-shadow: 0 0 0 calc(var(--spacing) * 1) var(--color-rose-600);
+
+ .toast {
+ @apply bg-rose-600;
+ }
+ }
+
+ &.eventOngoing {
+ box-shadow: 0 0 0 calc(var(--spacing) * 1) var(--color-teal-600);
+
+ .toast {
+ @apply bg-teal-600;
+ }
+ }
+
img.thumbnail {
@apply absolute h-full w-full object-cover transition-transform;
diff --git a/src/lib/components/DateWidget.svelte b/src/lib/components/DateWidget.svelte
index fd52c69..90065a3 100644
--- a/src/lib/components/DateWidget.svelte
+++ b/src/lib/components/DateWidget.svelte
@@ -10,7 +10,7 @@
class: className = ''
}: {
dateString?: string;
- type?: 'published' | 'updated';
+ type?: 'published' | 'updated' | 'eventStart' | 'eventFinish';
highlight?: boolean;
showTime?: boolean;
class?: string;
@@ -18,7 +18,9 @@
const typeToIcon = {
published: 'material-symbols:calendar-today',
- updated: 'material-symbols:update'
+ updated: 'material-symbols:update',
+ eventStart: 'material-symbols:rocket-launch',
+ eventFinish: 'material-symbols:sports-score'
};
const icon = type ? typeToIcon[type] : undefined;
@@ -28,7 +30,12 @@
{#if icon}
diff --git a/src/lib/util/Blogs.ts b/src/lib/util/Blogs.ts
index e10d18d..3b193dc 100644
--- a/src/lib/util/Blogs.ts
+++ b/src/lib/util/Blogs.ts
@@ -8,6 +8,11 @@ export enum EventStatus {
IsOver
}
+export function postIsEventOfInterest(post: App.BlogPost): boolean {
+ const status = postEventStatus(post);
+ return status === EventStatus.NotStarted || status === EventStatus.InProgress;
+}
+
export function postEventStatus(post: App.BlogPost): EventStatus {
if (post.type !== 'event' || post.dateEventFrom === undefined || post.dateEventTo === undefined) {
return EventStatus.NotEvent;
@@ -27,12 +32,17 @@ export type PostComparer = (a: App.BlogPost, b: App.BlogPost) => number;
export const sortPostsByPostDate: PostComparer = (a, b) => new Date(b.date!).valueOf() - new Date(a.date!).valueOf();
-function laterDate(a: string, b?: string): number {
+function laterDate(a: string, ...dates: (string | undefined)[]): number {
const dateA = new Date(a).valueOf();
- if (!b) return dateA;
+ if (dates.length <= 0) return dateA;
- const dateB = new Date(b).valueOf();
- return Math.max(dateA, dateB);
+ let max = dateA;
+ for (const d of dates) {
+ if (!d) continue;
+ const date = new Date(d).valueOf();
+ max = Math.max(max, date);
+ };
+ return max;
}
export const sortPostsByPostAndUpdateDate: PostComparer = (a, b) => laterDate(b.date!, b.dateChanged) - laterDate(a.date!, a.dateChanged);