Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
Sampiiiii committed Apr 15, 2024
2 parents 5a4ff95 + a4e431e commit 6be2fdf
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 67 deletions.
11 changes: 4 additions & 7 deletions apps/anvil/src/sign-in/sign-in.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,17 +416,14 @@ export class SignInService implements OnModuleInit {
e.select(e.sign_in.SignInReason, () => ({
name: true,
agreement: true,
category: true,
filter_single: { id: reason_id },
})),
);
const { name, agreement } = await this.dbService.query(query);
const { name, agreement, category } = await this.dbService.query(query);

if ([REP_ON_SHIFT, REP_OFF_SHIFT].includes(name)) {
if (!is_rep) {
throw new BadRequestException("User has somehow passed a rep reason");
}
} else if (is_rep) {
throw new BadRequestException(`Invalid sign in reason passed ${name}`);
if (category === "REP_SIGN_IN" && !is_rep) {
throw new BadRequestException("User has somehow passed a rep reason");
}

if (agreement && !agreements_signed.some((agreement_) => agreement_.id === agreement.id)) {
Expand Down
13 changes: 8 additions & 5 deletions apps/anvil/src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,21 +310,24 @@ export class UsersService {
location: true,
ends_at: true,
created_at: true,
duration: true,
duration_: e.select(e.duration_to_seconds(sign_in.duration)),
by: { created_at: e.datetime_truncate(sign_in.created_at, "days") },
}),
),
);
return groupings.map((group) => {
const key = group.key.created_at!;
const day = `${key.getFullYear()}-${key.getMonth()}-${key.getDay()}`;
const year = key.getFullYear();
const month = (key.getMonth() + 1).toString().padStart(2, "0"); // getMonth() is zero-based
const day = key.getDate().toString().padStart(2, "0"); // getDate() returns the day of the month

return {
day,
value: group.elements.reduce((previous_duration, visit) => previous_duration + visit.duration.seconds, 0),
day: `${year}-${month}-${day}`,
value: group.elements.reduce((previous_duration, visit) => previous_duration + parseInt(visit.duration_), 0),
sign_ins: group.elements.map((sign_in) => ({
...sign_in,
location: sign_in.location.toLowerCase() as unknown as Location,
duration: sign_in.duration.seconds,
duration: parseInt(sign_in.duration_),
})),
};
});
Expand Down
111 changes: 56 additions & 55 deletions apps/forge/src/components/signin/dashboard/components/SignInsChart.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,62 @@
import * as React from 'react';
import { Datum, ResponsiveCalendar } from '@nivo/calendar';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@ui/components/ui/dialog';
import { LocationIcon } from "@/components/icons";
import { SignInStat } from "@ignis/types/users";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@ui/components/ui/table';
import MediaQuery from 'react-responsive'
import {Drawer, DrawerClose, DrawerContent, DrawerFooter, DrawerHeader, DrawerTitle} from "@ui/components/ui/drawer";
import { Button } from '@ui/components/ui/button';
import { useNavigate } from '@tanstack/react-router';
import { LocationIcon } from '@/components/icons';
import { Datum, ResponsiveCalendar } from "@nivo/calendar";
import { useNavigate } from "@tanstack/react-router";
import { Button } from "@ui/components/ui/button";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@ui/components/ui/dialog";
import { Drawer, DrawerClose, DrawerContent, DrawerFooter, DrawerHeader, DrawerTitle } from "@ui/components/ui/drawer";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@ui/components/ui/table";
import * as React from "react";
import MediaQuery from "react-responsive";

type SignInDatum = Omit<Datum, "data"> & { data: Datum["data"] & SignInStat };

type SignInDatum = Omit<Datum, "data"> & {data: Datum["data"] & SignInStat}

function SignInTable({datum}: {datum: SignInDatum | null}) {
function SignInTable({ datum }: { datum: SignInDatum | null }) {
const navigate = useNavigate();

return (
<Table>
<TableHeader>
<TableRow className='bg-accent rounded'>
<TableRow className="bg-accent rounded">
<TableHead>Location</TableHead>
<TableHead>Entered</TableHead>
<TableHead>Left</TableHead>
<TableHead>Duration</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{datum?.data.sign_ins.map(
(sign_in) => {
let hours = Math.floor(sign_in.duration! / 60 / 60);
let hours_string = `${hours} hour${hours !== 0 ? 's' : ''}`;
let minutes = Math.floor((sign_in.duration! % 3600) / 60);
let minutes_string = `${minutes} minute${minutes !== 0 ? 's' : ''}`;
{datum?.data.sign_ins.map((sign_in) => {
const hours = Math.floor(sign_in.duration! / 60 / 60);
const hours_string = `${hours} hour${hours !== 1 ? "s" : ""}`;
const minutes = Math.floor((sign_in.duration! % 3600) / 60);
const minutes_string = `${minutes} minute${minutes !== 1 ? "s" : ""}`;

return (
<TableRow className='hover:bg-accent hover:cursor-pointer' onClick={() => navigate({to: `/sign-ins/${sign_in.id}` as string})}>
<TableCell className='flex justify-center'>
<LocationIcon location={sign_in.location}/>
</TableCell>
<TableCell>{sign_in.created_at.toLocaleTimeString()}</TableCell>
<TableCell>{sign_in.ends_at?.toLocaleTimeString() || "-"}</TableCell>
<TableCell>{
hours && minutes
? `${hours_string} and ${minutes_string}`
: hours ? hours_string : minutes_string
}</TableCell>
</TableRow>
)
}
)}
return (
<TableRow
className="hover:bg-accent hover:cursor-pointer"
onClick={() => navigate({ to: `/sign-ins/${sign_in.id}` as string })}
>
<TableCell className="flex justify-center">
<LocationIcon location={sign_in.location} />
</TableCell>
<TableCell>{sign_in.created_at.toLocaleTimeString()}</TableCell>
<TableCell>{sign_in.ends_at?.toLocaleTimeString() || "-"}</TableCell>
<TableCell>
{hours && minutes ? `${hours_string} and ${minutes_string}` : hours ? hours_string : minutes_string}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
)
);
}

const Entry = ({ day }: { day: string }) => {
return <div className="bg-inherit p-4 rounded-md">{new Date(day).toLocaleDateString()}</div>;
};

export default function SignInsChart({data}: {data: SignInStat[]}) {
export default function SignInsChart({ data }: { data: SignInStat[] }) {
// Theming for this component is handled in index.css using selectors,
// I'm sorry :(
// TODO rewrite this to use nivo's theming engine and get the colours from the index.css dynamically?
Expand All @@ -65,14 +66,13 @@ export default function SignInsChart({data}: {data: SignInStat[]}) {

return (
<>
<div style={{ height: 250 }} id="sign-in-chart">
<div className="h-60" id="sign-in-chart">
<ResponsiveCalendar
data={data}
from={`${new Date().getFullYear()}-01-01`}
to={`${new Date().getFullYear()}-12-31`}
colors={["#E7B0A9", "#DF948B", "#D6776C", "#CE5B4D"]}
emptyColor="#f8e9e7"
firstWeekday="monday"
margin={{ top: 40, right: 40, bottom: 40, left: 40 }}
yearSpacing={40}
dayBorderWidth={2}
Expand All @@ -88,45 +88,46 @@ export default function SignInsChart({data}: {data: SignInStat[]}) {
itemDirection: "right-to-left",
},
]}
tooltip={() => <></>}
tooltip={(props) => (props.value ? <Entry day={props.day} /> : <></>)}
onMouseEnter={(_, event) => {
event.currentTarget.style.cursor = "pointer"; // plouc/nivo#2276
event.currentTarget.style.cursor = "pointer"; // plouc/nivo#2276
}}
// @ts-expect-error: TS2322 the types here are wrong in the source
onClick={(datum: SignInsDatum) => {
if (!datum.data?.sign_ins) return
setOpen(true)
setDatum(datum)
if (!datum.data?.sign_ins) return;
setOpen(true);
setDatum(datum);
}}
/>
</div>

<MediaQuery minWidth={768}>
{(matches) => {
const title = `Visits on ${datum?.date.toLocaleDateString()}`
return matches ?
const title = `Visits on ${datum?.date.toLocaleDateString()}`;
return matches ? (
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle className="text-center">{title}</DialogTitle>
</DialogHeader>
<SignInTable datum={datum}/>
</DialogContent>
</Dialog>
:
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle className="text-center">{title}</DialogTitle>
</DialogHeader>
<SignInTable datum={datum} />
</DialogContent>
</Dialog>
) : (
<Drawer open={open} onOpenChange={setOpen}>
<DrawerContent>
<DrawerHeader className="text-left">
<DrawerTitle>{title}</DrawerTitle>
</DrawerHeader>
<SignInTable datum={datum}/>
<SignInTable datum={datum} />
<DrawerFooter className="pt-2">
<DrawerClose asChild>
<Button variant="outline">Close</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
);
}}
</MediaQuery>
</>
Expand Down

0 comments on commit 6be2fdf

Please sign in to comment.