2025-06-05 01:34:10 +02:00

72 lines
2.0 KiB
TypeScript

import { DataCard } from "@/components/data-card";
import { validateRequest } from "@/server/auth";
import { db } from "@/server/db";
import { eq } from "drizzle-orm";
export default async function PersonalizedCards() {
const { user } = await validateRequest();
if (!user) {
return null;
}
const allPrintJobs = await db.query.printJobs.findMany({
with: {
printer: true,
},
where: (printJobs) => eq(printJobs.userId, user.id),
});
const totalPrintingMinutes = allPrintJobs
.filter((job) => !job.aborted)
.reduce((acc, curr) => acc + curr.durationInMinutes, 0);
const averagePrintingHoursPerWeek = totalPrintingMinutes / 60 / 52;
const mostUsedPrinters = allPrintJobs
.map((job) => job.printer.name)
.reduce((acc, curr) => {
acc[curr] = (acc[curr] || 0) + 1;
return acc;
}, {});
const mostUsedPrinter = Object.keys(mostUsedPrinters).reduce((a, b) =>
mostUsedPrinters[a] > mostUsedPrinters[b] ? a : b,
);
const printerSuccessRate = (allPrintJobs.filter((job) => job.aborted).length / allPrintJobs.length) * 100;
const mostUsedWeekday = allPrintJobs
.map((job) => job.startAt.getDay())
.reduce((acc, curr) => {
acc[curr] = (acc[curr] || 0) + 1;
return acc;
}, {});
const mostUsedWeekdayIndex = Object.keys(mostUsedWeekday).reduce((a, b) =>
mostUsedWeekday[a] > mostUsedWeekday[b] ? a : b,
);
const mostUsedWeekdayName = new Intl.DateTimeFormat("de-DE", {
weekday: "long",
}).format(new Date(0, 0, Number.parseInt(mostUsedWeekdayIndex)));
return (
<div className="flex flex-col lg:flex-row gap-4">
<DataCard
icon="Clock10"
title="Druckstunden"
description="insgesamt"
value={`${(totalPrintingMinutes / 60).toFixed(2)}h`}
/>
<DataCard
icon="Calendar"
title="Aktivster Tag"
description="(nach Anzahl der Aufträgen)"
value={mostUsedWeekdayName}
/>
<DataCard icon="Heart" title="Lieblingsdrucker" description="" value={mostUsedPrinter} />
<DataCard icon="Check" title="Druckerfolgsquote" description="" value={`${printerSuccessRate.toFixed(2)}%`} />
</div>
);
}