feat: complete AI analytics experience
This commit is contained in:
57
src/lib/components/GrowthEventImpactChart.svelte
Normal file
57
src/lib/components/GrowthEventImpactChart.svelte
Normal file
@@ -0,0 +1,57 @@
|
||||
<script lang="ts">
|
||||
import type { components } from '$lib/api/schema';
|
||||
import { formatDateOnly } from '$lib/format';
|
||||
|
||||
type UpcomingEvent = components['schemas']['GrowthUpcomingEvent'];
|
||||
type EventRecommendation = components['schemas']['GrowthEventRecommendation'];
|
||||
|
||||
let {
|
||||
events = [],
|
||||
recommendations = [],
|
||||
now = new Date(),
|
||||
}: {
|
||||
events?: UpcomingEvent[];
|
||||
recommendations?: EventRecommendation[];
|
||||
now?: Date;
|
||||
} = $props();
|
||||
|
||||
const visibleEvents = $derived.by(() => {
|
||||
const byEvidenceId = new Map(events.map((event) => [event.evidenceId, event]));
|
||||
const ranked = recommendations
|
||||
.map((recommendation) => ({
|
||||
...byEvidenceId.get(recommendation.evidenceId),
|
||||
relevanceReason: recommendation.relevanceReason,
|
||||
}))
|
||||
.filter(
|
||||
(event): event is UpcomingEvent & { relevanceReason: string } =>
|
||||
Boolean(event.evidenceId) && new Date(event.date) >= now,
|
||||
);
|
||||
if (ranked.length) return ranked.slice(0, 3);
|
||||
return events
|
||||
.filter((event) => new Date(event.date) >= now)
|
||||
.toSorted((a, b) => Date.parse(a.date) - Date.parse(b.date))
|
||||
.slice(0, 3)
|
||||
.map((event) => ({
|
||||
...event,
|
||||
relevanceReason: 'این مناسبت در تقویم بررسیشده بهعنوان رویدادی مرتبط با کسبوکار ثبت شده است.',
|
||||
}));
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if visibleEvents.length}
|
||||
<div class="grid gap-3 sm:grid-cols-3" role="list" aria-label="رویدادهای پیش رو">
|
||||
{#each visibleEvents as event (event.evidenceId)}
|
||||
<article class="bg-muted/35 rounded-lg border p-4 text-right" role="listitem">
|
||||
<p class="text-muted-foreground text-xs">رویداد پیش رو</p>
|
||||
<h3 class="mt-2 text-sm font-bold">{event.eventTitleFa}</h3>
|
||||
<p class="text-muted-foreground mt-2 text-xs">{formatDateOnly(event.date)}</p>
|
||||
<p class="text-muted-foreground mt-3 text-xs leading-5">{event.relevanceReason}</p>
|
||||
</article>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="py-10 text-center" role="status">
|
||||
<p class="font-bold">رویداد مرتبطی در تقویم بررسیشده پیدا نشد</p>
|
||||
<p class="text-muted-foreground mt-1 text-sm">با بهروزرسانی تقویم، این بخش دوباره بررسی میشود.</p>
|
||||
</div>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user