feat(dashboard): wire Anasayfa to live data

- getDashboardData aggregates open jobs, pending-action jobs, unread
  notifications, pending finance totals, approved connection count, recent
  jobs (up to 8) and recent notifications (up to 5) — single Promise.all so
  the dashboard renders in one round-trip.
- Four stat cards, each a Link to the relevant module; tone (positive /
  negative) flips between clinic (payable) and lab (receivable).
- Clinic users with zero approved connections see a 'Bağlantı Kur' prompt
  card so they don't get stuck on /jobs/new.
- Recent jobs table is role-aware: lab sees Klinik column + 'Son Gelen
  İşler' header, clinic sees Laboratuvar column + 'Son Giden İşler' header.
- Recent notifications panel with read/unread dot, clickable header arrow
  to /notifications.
- ActiveContext now carries 'kind' (mirror of TenantSettings.kind) so we no
  longer reach into ctx.settings?.kind in callers.
This commit is contained in:
kovakmedya
2026-05-21 20:41:39 +03:00
parent 97f397d2dd
commit c980ce1d8d
3 changed files with 402 additions and 19 deletions
+3 -1
View File
@@ -3,12 +3,13 @@ import "server-only";
import { Query } from "node-appwrite";
import { createAdminClient, getCurrentUser } from "./server";
import { DATABASE_ID, TABLES, type TenantSettings } from "./schema";
import { DATABASE_ID, TABLES, type TenantKind, type TenantSettings } from "./schema";
import { getActiveTenantId, getUserTeams } from "./tenant";
export type ActiveContext = {
user: { id: string; name: string; email: string };
tenantId: string;
kind: TenantKind | null;
settings: TenantSettings | null;
};
@@ -39,6 +40,7 @@ export async function getActiveContext(): Promise<ActiveContext | null> {
return {
user: { id: user.$id, name: user.name, email: user.email },
tenantId,
kind: settings?.kind ?? null,
settings,
};
}