import {PageParams} from "@/types/next"; import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page"; import {Card, CardContent, CardHeader, CardTitle} from "@/components/ui/card"; import {EvolutionLineChart} from "@/components/wrappers/dashboard/statistics/charts/evolution-line-chart"; import {PercentageLineChart} from "@/components/wrappers/dashboard/statistics/charts/percentage-line-chart"; import {notFound} from "next/navigation"; import {db} from "@/db"; import {and, asc, count, eq, inArray} from "drizzle-orm"; import * as drizzleDb from "@/db"; import {getOrganization} from "@/lib/auth/auth"; import {Building2, DatabaseBackup, Folder, RefreshCcw} from "lucide-react"; import {Metadata} from "next"; export const metadata: Metadata = { title: "Statistics", }; export default async function RoutePage(props: PageParams<{}>) { const organization = await getOrganization({}); if (!organization) { notFound(); } const org = await db.query.organization.findFirst({ where: eq(drizzleDb.schemas.organization.slug, organization.slug), }); if (!org) notFound(); const projects = await db.query.project.findMany({ where: eq(drizzleDb.schemas.project.organizationId, org.id), }); const projectIds = projects.map(project => project.id); const databasesOfAllProjects = await db.query.database.findMany({ where: inArray(drizzleDb.schemas.database.projectId, projectIds), }) const databaseIds = databasesOfAllProjects.map((database) => database.id); const backupsEvolution = await db.query.backup.findMany({ columns: { id: true, createdAt: true, }, orderBy: [asc(drizzleDb.schemas.backup.id)], where: inArray(drizzleDb.schemas.backup.databaseId, databaseIds), }); const backupsRate = await db .select({ createdAt: drizzleDb.schemas.backup.createdAt, status: drizzleDb.schemas.backup.status, _count: count(), }) .from(drizzleDb.schemas.backup) .where(and(inArray(drizzleDb.schemas.backup.status, ["success", "failed"]), inArray(drizzleDb.schemas.backup.databaseId, databaseIds))) .groupBy(drizzleDb.schemas.backup.createdAt, drizzleDb.schemas.backup.status) .orderBy(drizzleDb.schemas.backup.createdAt); const restorationsCountResult = await db .select({ count: count(), }) .from(drizzleDb.schemas.restoration) .where(inArray(drizzleDb.schemas.restoration.databaseId, databaseIds)); const restorationsCount = restorationsCountResult[0]?.count ?? 0; const projectsCount = projects.length; const backupsEvolutionCount = backupsEvolution.length; const sortedBackupsEvolution = backupsEvolution.sort( (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime() ); const Placeholder = ({text}: { text: string }) => (
{text}
); return ( Statistics Overview
Projects
{projectsCount}

Active projects in this organization

Backups
{backupsEvolutionCount}

Total backups executed across all databases

Restorations
{restorationsCount}

Total restoration operations performed

Evolution of the number of backups {sortedBackupsEvolution.length > 0 ? ( ) : ( )} Success rate of backups {backupsRate.length > 0 ? ( ) : ( )}
); }