diff --git a/apps/anvil/src/sign-in/sign-in.service.ts b/apps/anvil/src/sign-in/sign-in.service.ts index 75f3a6c..aabcc87 100644 --- a/apps/anvil/src/sign-in/sign-in.service.ts +++ b/apps/anvil/src/sign-in/sign-in.service.ts @@ -64,6 +64,7 @@ export class SignInService implements OnModuleInit { this.maxCount(location), this.canSignIn(location), this.countInQueue(location), + this.outOfHours(), ]); return { @@ -71,6 +72,7 @@ export class SignInService implements OnModuleInit { open: on_shift_count > 0, count, max, + out_of_hours: this.outOfHours(), needs_queue: !can_sign_in, count_in_queue, }; diff --git a/apps/forge/src/components/signin/actions/ActiveLocationSelector/index.tsx b/apps/forge/src/components/signin/actions/ActiveLocationSelector/index.tsx index ce21cc6..7768c39 100644 --- a/apps/forge/src/components/signin/actions/ActiveLocationSelector/index.tsx +++ b/apps/forge/src/components/signin/actions/ActiveLocationSelector/index.tsx @@ -1,5 +1,3 @@ -// @ts-ignore - import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons"; import { cn } from "@/lib/utils"; import { Button } from "@ui/components/ui/button"; @@ -13,6 +11,8 @@ import { locationStatus } from "@/services/signin/locationService.ts"; import { useQuery } from "@tanstack/react-query"; import { Separator } from "@ui/components/ui/separator.tsx"; import { PulseLoader } from "react-spinners"; +import { Location } from "@ignis/types/sign_in.ts"; +import { Moon } from "lucide-react"; const ActiveLocationSelector = () => { const [open, setOpen] = useState(false); @@ -28,6 +28,7 @@ const ActiveLocationSelector = () => { } = useQuery({ queryKey: ["locationStatus"], queryFn: locationStatus, + staleTime: 4_000, refetchInterval: value ? refetchInterval : false, // Only refetch if a location is selected }); @@ -44,16 +45,14 @@ const ActiveLocationSelector = () => { dispatch(signinActions.setError(error.message)); } - if (activeLocation != "") { - setValue(activeLocation); - } + setValue(activeLocation); }, [locationStatuses, dispatch, isError, activeLocation, error]); const capitalizeFirstLetter = (string: string) => { return string.charAt(0).toUpperCase() + string.slice(1); }; - const handleLocationSelect = (selectedLocationName: string) => { + const handleLocationSelect = (selectedLocationName: Location) => { dispatch(signinActions.setActiveLocation(selectedLocationName)); }; @@ -88,14 +87,14 @@ const ActiveLocationSelector = () => { ) : ( <> {locationStatuses && - locationStatuses!.map((location, index) => ( + locationStatuses!.map((location, _) => ( { setValue(currentValue); setOpen(false); - handleLocationSelect(currentValue); + handleLocationSelect(currentValue as Location); }} > {capitalizeFirstLetter(location.locationName)} @@ -124,6 +123,12 @@ const ActiveLocationSelector = () => { ) : ( CLOSED )} + {activeLocationStatus.out_of_hours ? ( + <> + + Out of Hours + + ) : undefined} {/* Count and Max Count Status */} diff --git a/apps/forge/src/components/signin/actions/QueueDispatcher/index.tsx b/apps/forge/src/components/signin/actions/QueueDispatcher/index.tsx index caff0b5..043ec6d 100644 --- a/apps/forge/src/components/signin/actions/QueueDispatcher/index.tsx +++ b/apps/forge/src/components/signin/actions/QueueDispatcher/index.tsx @@ -41,8 +41,9 @@ const QueueDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { console.log("Success"); setCanContinue(true); abortController.abort(); - redirectToActions(timeout); + dispatch(signinActions.resetSignInSession()); toast.success("User added to queue successfully"); + navigate({ to: "/signin/actions" }); }, }); @@ -70,13 +71,6 @@ const QueueDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { ); }; - const redirectToActions = (timeoutInMs: number) => { - setTimeout(() => { - dispatch(signinActions.resetSignInSession()); - navigate({ to: "/signin/actions" }); - }, timeoutInMs); - }; - const successDisplay = ( <>
diff --git a/apps/forge/src/components/signin/actions/RegisterDispatcher/index.tsx b/apps/forge/src/components/signin/actions/RegisterDispatcher/index.tsx index 22287e2..ab53009 100644 --- a/apps/forge/src/components/signin/actions/RegisterDispatcher/index.tsx +++ b/apps/forge/src/components/signin/actions/RegisterDispatcher/index.tsx @@ -48,8 +48,9 @@ const RegisterDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { console.log("Success"); setCanContinue(true); abortController.abort(); - redirectToActions(timeout); + dispatch(signinActions.resetSignInSession()); toast.success("User registered successfully"); + navigate({ to: "/signin/actions" }); }, }); @@ -66,13 +67,6 @@ const RegisterDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { ); - const redirectToActions = (timeoutInMs: number) => { - setTimeout(() => { - dispatch(signinActions.resetSignInSession()); - navigate({ to: "/signin/actions" }); - }, timeoutInMs); - }; - const successDisplay = ( <>
diff --git a/apps/forge/src/components/signin/actions/SignInDispatcher/index.tsx b/apps/forge/src/components/signin/actions/SignInDispatcher/index.tsx index 5335e98..0c73831 100644 --- a/apps/forge/src/components/signin/actions/SignInDispatcher/index.tsx +++ b/apps/forge/src/components/signin/actions/SignInDispatcher/index.tsx @@ -12,6 +12,7 @@ import { useEffect, useState } from "react"; import { signinActions } from "@/redux/signin.slice.ts"; import { FlowStepComponent } from "@/components/signin/actions/SignInManager/types.ts"; import { useNavigate } from "@tanstack/react-router"; +import { toast } from "sonner"; const SignInDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { const queryClient = useQueryClient(); @@ -47,8 +48,10 @@ const SignInDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { console.log("Success"); setCanContinue(true); abortController.abort(); - redirectToActions(timeout); + dispatch(signinActions.resetSignInSession()); queryClient.invalidateQueries({ queryKey: ["locationStatus"] }); + toast.success("User signed in!"); + navigate({ to: "/signin/actions" }); }, }); @@ -65,13 +68,6 @@ const SignInDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { ); - const redirectToActions = (timeoutInMs: number) => { - setTimeout(() => { - dispatch(signinActions.resetSignInSession()); - navigate({ to: "/signin/actions" }); - }, timeoutInMs); - }; - const successDisplay = ( <>
diff --git a/apps/forge/src/components/signin/actions/SignOutDispatcher/index.tsx b/apps/forge/src/components/signin/actions/SignOutDispatcher/index.tsx index e3a7970..be42ff6 100644 --- a/apps/forge/src/components/signin/actions/SignOutDispatcher/index.tsx +++ b/apps/forge/src/components/signin/actions/SignOutDispatcher/index.tsx @@ -12,6 +12,7 @@ import { useEffect, useState } from "react"; import { signinActions } from "@/redux/signin.slice.ts"; import { FlowStepComponent } from "@/components/signin/actions/SignInManager/types.ts"; import { useNavigate } from "@tanstack/react-router"; +import { toast } from "sonner"; const SignOutDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { const queryClient = useQueryClient(); @@ -41,8 +42,10 @@ const SignOutDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { onSuccess: () => { setCanContinue(true); abortController.abort(); - redirectToActions(timeout); + dispatch(signinActions.resetSignInSession()); queryClient.invalidateQueries({ queryKey: ["locationStatus"] }); + toast.success("User signed out successfully!"); + navigate({ to: "/signin/actions" }); }, }); @@ -59,13 +62,6 @@ const SignOutDispatcher: FlowStepComponent = ({ onSecondary, onPrimary }) => { ); - const redirectToActions = (timeoutInMs: number) => { - setTimeout(() => { - dispatch(signinActions.resetSignInSession()); - navigate({ to: "/signin/actions" }); - }, timeoutInMs); - }; - const successDisplay = ( <>
diff --git a/apps/forge/src/components/signin/dashboard/components/SignInDrawer.tsx b/apps/forge/src/components/signin/dashboard/components/SignInDrawer.tsx index 506768c..831c4b1 100644 --- a/apps/forge/src/components/signin/dashboard/components/SignInDrawer.tsx +++ b/apps/forge/src/components/signin/dashboard/components/SignInDrawer.tsx @@ -5,7 +5,7 @@ import { InfoCircledIcon } from "@radix-ui/react-icons"; import { Alert, AlertDescription, AlertTitle } from "@ui/components/ui/alert.tsx"; import { Button } from "@ui/components/ui/button.tsx"; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@ui/components/ui/collapsible.tsx"; -import { ArrowDownIcon, ArrowRightIcon } from "lucide-react"; +import { ArrowDownIcon, ArrowRightIcon, Ban } from "lucide-react"; import { FC, useState } from "react"; // SignInDrawer Props @@ -40,9 +40,15 @@ export const SignInDrawer: FC = ({ title, entries, startExpan onClick={toggleOpen} disabled={entries.length === 0} > - {isOpen ? : } - Toggle - Toggle + {entries.length === 0 ? ( + + ) : ( + <> + {isOpen ? "Hide" : "Show"} + {isOpen ? : } + {isOpen ? "Hide" : "Show"} + + )}
diff --git a/apps/forge/src/components/signin/dashboard/components/SignedInUserCard.tsx b/apps/forge/src/components/signin/dashboard/components/SignedInUserCard.tsx index bca8509..7a5f237 100644 --- a/apps/forge/src/components/signin/dashboard/components/SignedInUserCard.tsx +++ b/apps/forge/src/components/signin/dashboard/components/SignedInUserCard.tsx @@ -10,7 +10,7 @@ import { getUserTrainingRemaining } from "@/services/users/getUserTrainingRemain import revokeTraining from "@/services/users/revokeTraining"; import type { Location, PartialReason, SignInEntry } from "@ignis/types/sign_in"; import type { InfractionType, PartialUser } from "@ignis/types/users"; -import { useMutation, useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { Link } from "@tanstack/react-router"; import DatePickerWithRange from "@ui/components/date-picker-with-range"; import { Badge } from "@ui/components/ui/badge.tsx"; @@ -329,6 +329,7 @@ interface SignInUserCardProps { export const SignedInUserCard: React.FC = ({ user, tools, reason, onSignOut, onShiftReps }) => { const activeLocation = useSelector((state: AppRootState) => state.signin.active_location); const abortController = new AbortController(); + const queryClient = useQueryClient(); const onShift = reason?.name === REP_ON_SHIFT; const signOutProps: PostSignOutProps = { @@ -349,6 +350,7 @@ export const SignedInUserCard: React.FC = ({ user, tools, r abortController.abort(); toast.success(`Successfully signed out ${user.display_name}`); onSignOut?.(); + queryClient.invalidateQueries({ queryKey: ["locationStatus", "locationList", { activeLocation }] }); }, }); diff --git a/apps/forge/src/components/signin/dashboard/index.tsx b/apps/forge/src/components/signin/dashboard/index.tsx index 79d1e46..d9333bb 100644 --- a/apps/forge/src/components/signin/dashboard/index.tsx +++ b/apps/forge/src/components/signin/dashboard/index.tsx @@ -32,6 +32,11 @@ export default function SignInDashboard() { queryClient.invalidateQueries({ queryKey: ["locationStatus", "locationList", { activeLocation }] }); }; + const handleRemoveSignedInOffShiftRep = (userId: string) => { + setSignInOffShiftReps((currentOffShiftReps) => currentOffShiftReps.filter((rep) => rep.user.id !== userId)); + queryClient.invalidateQueries({ queryKey: ["locationStatus", "locationList", { activeLocation }] }); + }; + const { data: locationList, isLoading, @@ -91,7 +96,7 @@ export default function SignInDashboard() {