From 170290857d6f15533b14fdb34e2cb0aab1c70358 Mon Sep 17 00:00:00 2001 From: Gobot1234 Date: Tue, 16 Apr 2024 00:11:21 +0100 Subject: [PATCH 1/2] fix: sign in chart --- apps/anvil/src/users/users.service.ts | 13 +- .../dashboard/components/SignInsChart.tsx | 111 +++++++++--------- 2 files changed, 64 insertions(+), 60 deletions(-) diff --git a/apps/anvil/src/users/users.service.ts b/apps/anvil/src/users/users.service.ts index 5bc206c..6e8f121 100644 --- a/apps/anvil/src/users/users.service.ts +++ b/apps/anvil/src/users/users.service.ts @@ -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_), })), }; }); diff --git a/apps/forge/src/components/signin/dashboard/components/SignInsChart.tsx b/apps/forge/src/components/signin/dashboard/components/SignInsChart.tsx index 12ffeda..051a41e 100644 --- a/apps/forge/src/components/signin/dashboard/components/SignInsChart.tsx +++ b/apps/forge/src/components/signin/dashboard/components/SignInsChart.tsx @@ -1,24 +1,23 @@ -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 & { data: Datum["data"] & SignInStat }; -type SignInDatum = Omit & {data: Datum["data"] & SignInStat} - -function SignInTable({datum}: {datum: SignInDatum | null}) { +function SignInTable({ datum }: { datum: SignInDatum | null }) { const navigate = useNavigate(); return ( - + Location Entered Left @@ -26,36 +25,38 @@ function SignInTable({datum}: {datum: SignInDatum | null}) { - {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 ( - navigate({to: `/sign-ins/${sign_in.id}` as string})}> - - - - {sign_in.created_at.toLocaleTimeString()} - {sign_in.ends_at?.toLocaleTimeString() || "-"} - { - hours && minutes - ? `${hours_string} and ${minutes_string}` - : hours ? hours_string : minutes_string - } - - ) - } - )} + return ( + navigate({ to: `/sign-ins/${sign_in.id}` as string })} + > + + + + {sign_in.created_at.toLocaleTimeString()} + {sign_in.ends_at?.toLocaleTimeString() || "-"} + + {hours && minutes ? `${hours_string} and ${minutes_string}` : hours ? hours_string : minutes_string} + + + ); + })}
- ) + ); } +const Entry = ({ day }: { day: string }) => { + return
{new Date(day).toLocaleDateString()}
; +}; -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? @@ -65,14 +66,13 @@ export default function SignInsChart({data}: {data: SignInStat[]}) { return ( <> -
+
<>} + tooltip={(props) => (props.value ? : <>)} 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); }} />
{(matches) => { - const title = `Visits on ${datum?.date.toLocaleDateString()}` - return matches ? + const title = `Visits on ${datum?.date.toLocaleDateString()}`; + return matches ? ( - - - {title} - - - - - : + + + {title} + + + + + ) : ( {title} - + @@ -127,6 +127,7 @@ export default function SignInsChart({data}: {data: SignInStat[]}) { + ); }} From a4e431ea70a94239298572bae82a66ef5a4270ac Mon Sep 17 00:00:00 2001 From: Gobot1234 Date: Tue, 16 Apr 2024 00:17:26 +0100 Subject: [PATCH 2/2] fix: more rep sign in for not shift reasons --- apps/anvil/src/sign-in/sign-in.service.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/anvil/src/sign-in/sign-in.service.ts b/apps/anvil/src/sign-in/sign-in.service.ts index 54221d7..14653f7 100644 --- a/apps/anvil/src/sign-in/sign-in.service.ts +++ b/apps/anvil/src/sign-in/sign-in.service.ts @@ -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)) {