import type { DB } from '../db/client.js'; export interface CardContext { db: DB; env: Record; query: Record; } export interface Card { id: string; refreshSeconds?: number; render: (ctx: CardContext) => string | Promise; } export interface DashboardOptions { title?: string; cards?: Card[]; auth?: { username: string; password: string; } | null; theme?: string | null; } /** * Minimal subset of Hono we touch. Avoids a hard import. */ export interface HonoLike { use(path: string, mw: (c: unknown, next: () => Promise) => Promise): unknown; get(path: string, handler: (c: HonoContextLike) => unknown): unknown; } export interface HonoContextLike { html(body: string): unknown; env: { DB: D1Database; [k: string]: unknown; }; req: { query(): Record; }; } export declare class Dashboard { readonly title: string; readonly cards: Card[]; readonly auth: { username: string; password: string; } | null; readonly theme: string; constructor({ title, cards, auth, theme }: DashboardOptions); mount(app: HonoLike, base?: string): Promise; renderShell(base: string): string; } export declare function summaryCard({ id, title, refreshSeconds }?: { id?: string | undefined; title?: string | undefined; refreshSeconds?: number | undefined; }): Card; export declare function queueCard({ id, title, refreshSeconds }?: { id?: string | undefined; title?: string | undefined; refreshSeconds?: number | undefined; }): Card; export declare function funnelCard({ id, title, refreshSeconds }?: { id?: string | undefined; title?: string | undefined; refreshSeconds?: number | undefined; }): Card; export declare function messagesChartCard({ id, title, refreshSeconds, days }?: { id?: string | undefined; title?: string | undefined; refreshSeconds?: number | undefined; days?: number | undefined; }): Card; /** * Daily-active-users line chart with overlay of new users per day. * Reads `messages` for DAU and `leads.created_at` for new-user counts. */ export declare function dauCard({ id, title, refreshSeconds, days }?: { id?: string | undefined; title?: string | undefined; refreshSeconds?: number | undefined; days?: number | undefined; }): Card; /** * Re-engagement response rate over the last `days`. Reads `engagement_answers` * (yes/no) and `broadcast_log` (sent count) for the given `topicId`. */ export declare function engagementCard({ id, title, refreshSeconds, days, topicId, channel, }?: { id?: string | undefined; title?: string | undefined; refreshSeconds?: number | undefined; days?: number | undefined; topicId?: number | undefined; channel?: string | undefined; }): Card; /** * Free→paid conversion funnel for any gated feature. * * Pairs with `UsageCounter`: every time `gate.check()` returns * `{ allowed: false }`, the consumer logs `usage.record(whatsapp, feature)`. * This card aggregates those events: * - users blocked (distinct count) * - users converted (blocked + later moved to `convertedFunnelState`) * - conversion rate (converted / blocked) * - total hits * - daily blocked-users series for the last `days` * * Defaults to feature='ai_gate_blocked' and convertedFunnelState='SUBSCRIBE' * but both are configurable. */ export declare function gateConversionCard({ id, title, refreshSeconds, feature, convertedFunnelState, days, }?: { id?: string | undefined; title?: string | undefined; refreshSeconds?: number | undefined; feature?: string | undefined; convertedFunnelState?: string | undefined; days?: number | undefined; }): Card; /** * Sequential-plan enrollment table with completion rate per plan. * Reads `plans` + `user_plans`. */ export declare function plansCard({ id, title, refreshSeconds }?: { id?: string | undefined; title?: string | undefined; refreshSeconds?: number | undefined; }): Card; /** * Churn — opt-in users with no open message window. Useful early-warning * indicator: when this number trends up, your re-engagement isn't keeping * users inside the 24h window. */ export declare function churnCard({ id, title, refreshSeconds }?: { id?: string | undefined; title?: string | undefined; refreshSeconds?: number | undefined; }): Card; export declare const defaultCards: { all: () => Card[]; summary: () => Card[]; core: () => Card[]; }; //# sourceMappingURL=index.d.ts.map