Skip to content

Commit

Permalink
Fastest registrations
Browse files Browse the repository at this point in the history
  • Loading branch information
omfj committed Jan 18, 2025
1 parent 172c4d5 commit ef2786e
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { cn } from "@/utils/cn";

export const Box = ({ children, className }: { children: React.ReactNode; className?: string }) => (
<div className={cn("space-y-4 rounded-lg border bg-muted px-3 py-8", className)}>{children}</div>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { type getFullHappening } from "@/data/happenings/queries";
import { type RegistrationWithUser } from "../_lib/types";
import { Box } from "./box";

type FastestRegistrationsProps = {
happening: Exclude<Awaited<ReturnType<typeof getFullHappening>>, undefined>;
registrations: Array<RegistrationWithUser>;
};

export const FastestRegistrations = ({ happening, registrations }: FastestRegistrationsProps) => {
const fastestRegistrations = registrations
.filter((registration) => registration.status === "registered")
.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());

const topThree = fastestRegistrations.slice(0, 3);

return (
<Box>
<ul className="mt-2 px-4">
<li>
Påmelding for grupper åpnet:{" "}
<span className="text-muted-foreground">
{happening.registrationStartGroups?.toLocaleString() ?? "Ingen påmelding for grupper"}
</span>
</li>
<li>
Påmelding for alle åpnet:{" "}
<span className="text-muted-foreground">
{happening.registrationStart?.toLocaleString()}
</span>
</li>
</ul>

<ul className="space-y-2 px-4">
{topThree.map((registration, i) => {
const createdAtMs = registration.createdAt.getTime();
const normalStartMs = happening.registrationStart!.getTime();
const groupStartMs = happening.registrationStartGroups?.getTime();

let ms = createdAtMs - normalStartMs;
if (ms < 0 && groupStartMs) {
ms = createdAtMs - groupStartMs;
}

return (
<li className="flex flex-col justify-between sm:flex-row" key={registration.user.id}>
<p>
<span className="text-muted-foreground">{i + 1}.</span> {registration.user.name}
</p>
<p className="text-sm text-muted-foreground">{(ms / 1000).toFixed(2)} sekunder</p>
</li>
);
})}
</ul>

<p className="mt-2 px-4 text-sm text-muted-foreground">
Om det er negativt tall, så har brukeren meldt seg på før påmeldingen åpnet. Dette kan
skyldes at de har blitt lagt til manuelt, eller at påmeldingsdatoen har blitt endret etter
at de meldte seg på.
</p>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const Heading = ({ children }: { children: React.ReactNode }) => (
<h2 className="text-2xl font-medium">{children}</h2>
);
26 changes: 15 additions & 11 deletions apps/web/src/app/(default)/dashbord/[slug]/_tabs/statistics.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
import { getAllDegrees } from "@/data/degrees/queries";
import { getStudentGroups } from "@/data/groups/queries";
import { type getFullHappening } from "@/data/happenings/queries";
import { Box } from "../_components/box";
import { AreaChartRegistrationsOverTime } from "../_components/charts/area-chart-registrations-over-time";
import { BarChartYear } from "../_components/charts/bar-chart-year-registrations";
import { PieChartDegrees } from "../_components/charts/pie-chart-degree-registrations";
import { PieChartGroups } from "../_components/charts/pie-chart-group-registrations";
import { FastestRegistrations } from "../_components/fastest-registrations";
import { Heading } from "../_components/heading";
import { type RegistrationWithUser } from "../_lib/types";

const Heading = ({ children }: { children: React.ReactNode }) => (
<h2 className="text-2xl font-medium">{children}</h2>
);

const Box = ({ children }: { children: React.ReactNode }) => (
<div className="rounded-lg border bg-muted px-3 py-8 text-center">{children}</div>
);

const Stat = ({ title, value }: { title: string; value: string }) => (
<Box>
<Box className="text-center">
<p className="mb-2 text-muted-foreground">{title}</p>
<p className="text-7xl font-medium">{value}</p>
</Box>
);

type DetailsTabProps = {
type StatisticsTabProps = {
happening: Exclude<Awaited<ReturnType<typeof getFullHappening>>, undefined>;
registrations: Array<RegistrationWithUser>;
};

export const StatisticsTab = async ({ registrations }: DetailsTabProps) => {
export const StatisticsTab = async ({ happening, registrations }: StatisticsTabProps) => {
const [groups, degrees] = await Promise.all([getStudentGroups(), getAllDegrees()]);

const registered = registrations.filter((registration) => registration.status === "registered");
Expand All @@ -46,6 +43,13 @@ export const StatisticsTab = async ({ registrations }: DetailsTabProps) => {
<Stat title="Antall fjernet" value={removed.length.toString()} />
</div>

{happening.registrationStart && (
<>
<Heading>Raskeste påmeldinger</Heading>
<FastestRegistrations happening={happening} registrations={registrations} />
</>
)}

<Heading>Grafer</Heading>

<div className="grid grid-cols-1 gap-5 md:grid-cols-2">
Expand Down
10 changes: 2 additions & 8 deletions apps/web/src/app/(default)/dashbord/[slug]/_tabs/utilities.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { type getFullHappening } from "@/data/happenings/queries";
import { Box } from "../_components/box";
import { DownloadCsvButton } from "../_components/download-csv-button";
import { Heading } from "../_components/heading";
import { RandomPersonButton } from "../_components/random-person-button";
import { RemoveAllRegistrationsButton } from "../_components/remove-all-registrations-button";
import { type RegistrationWithUser } from "../_lib/types";

const Box = ({ children }: { children: React.ReactNode }) => (
<div className="space-y-4 rounded-lg border bg-muted p-4">{children}</div>
);

const Text = ({ children }: { children: React.ReactNode }) => (
<p className="text-muted-foreground">{children}</p>
);

const Heading = ({ children }: { children: React.ReactNode }) => (
<h2 className="text-2xl font-medium">{children}</h2>
);

type UtilitiesTabProps = {
happening: Exclude<Awaited<ReturnType<typeof getFullHappening>>, undefined>;
registrations: Array<RegistrationWithUser>;
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/(default)/dashbord/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default async function EventDashboard({ params }: Props) {
<RegistrationsTab happening={happening} registrations={registrations} />
</TabsContent>
<TabsContent value="statistics">
<StatisticsTab registrations={registrations} />
<StatisticsTab happening={happening} registrations={registrations} />
</TabsContent>
<TabsContent value="utilities">
<UtilitiesTab happening={happening} registrations={registrations} />
Expand Down

0 comments on commit ef2786e

Please sign in to comment.