/** * Dashboard Domain Utilities * Business logic for dashboard activities and task generation */ import type { Activity, ActivityFilter, ActivityFilterConfig, ActivityType } from "./contract.js"; /** * Activity filter configurations * Defines which activity types belong to each filter category */ export const ACTIVITY_FILTERS: ActivityFilterConfig[] = [ { key: "all", label: "All" }, { key: "billing", label: "Billing", types: ["invoice_created", "invoice_paid"], }, { key: "orders", label: "Orders", types: ["service_activated"], }, { key: "support", label: "Support", types: ["case_created", "case_closed"], }, ]; /** * Filter activities by type category */ export function filterActivities(activities: Activity[], filter: ActivityFilter): Activity[] { if (filter === "all") { return activities; } const filterConfig = ACTIVITY_FILTERS.find(f => f.key === filter); if (!filterConfig?.types) { return activities; } return activities.filter(activity => filterConfig.types!.includes(activity.type)); } /** * Activity types that support navigation to detail views */ const CLICKABLE_ACTIVITY_TYPES: ActivityType[] = ["invoice_created", "invoice_paid"]; /** * Check if an activity is clickable (has a navigable detail view) */ export function isActivityClickable(activity: Activity): boolean { return CLICKABLE_ACTIVITY_TYPES.includes(activity.type) && !!activity.relatedId; } /** * Quick action task definition for dashboard */ export interface QuickActionTask { label: string; href: string; } /** * Dashboard summary input for task generation */ export interface DashboardTaskSummary { nextInvoice?: { id: number } | null; stats?: { unpaidInvoices?: number; openCases?: number }; } /** * Generate dashboard quick action suggestions based on summary data */ export function generateQuickActions(summary: DashboardTaskSummary): QuickActionTask[] { const tasks: QuickActionTask[] = []; if (summary.nextInvoice) { tasks.push({ label: "Pay upcoming invoice", href: "#attention", }); } if (summary.stats?.unpaidInvoices && summary.stats.unpaidInvoices > 0) { tasks.push({ label: "Review unpaid invoices", href: "/billing/invoices", }); } if (summary.stats?.openCases && summary.stats.openCases > 0) { tasks.push({ label: "Check support cases", href: "/support/cases", }); } return tasks; }