diff --git a/packages/api/src/controllers/leo/LeoController.ts b/packages/api/src/controllers/leo/LeoController.ts index 82dff8686..0453a5b3d 100644 --- a/packages/api/src/controllers/leo/LeoController.ts +++ b/packages/api/src/controllers/leo/LeoController.ts @@ -12,7 +12,7 @@ import { CREATE_OFFICER_SCHEMA, UPDATE_OFFICER_STATUS_SCHEMA, validate } from "@ import { BodyParams, Context, PathParams } from "@tsed/platform-params"; import { BadRequest, NotFound } from "@tsed/exceptions"; import { prisma } from "../../lib/prisma"; -import { cad, ShouldDoType, MiscCadSettings, User, Citizen } from ".prisma/client"; +import { Officer, cad, ShouldDoType, MiscCadSettings, User, Citizen } from ".prisma/client"; import { setCookie } from "../../utils/setCookie"; import { AllowedFileExtension, allowedFileExtensions, Cookie } from "@snailycad/config"; import { IsAuth } from "../../middlewares"; @@ -462,6 +462,24 @@ export class LeoController { return data; } + + @Post("/panic-button") + @Use(ActiveOfficer) + async panicButton(@Context("activeOfficer") officer: Officer) { + const fullOfficer = await prisma.officer.findUnique({ + where: { + id: officer.id, + }, + include: { + department: { include: { value: true } }, + rank: true, + division: { include: { value: true } }, + status: { include: { value: true } }, + }, + }); + + this.socket.emitPanicButtonLeo(fullOfficer); + } } export function createWebhookData(webhook: APIWebhook, officer: any) { diff --git a/packages/api/src/services/SocketService.ts b/packages/api/src/services/SocketService.ts index 4dfdb3dfb..e70512590 100644 --- a/packages/api/src/services/SocketService.ts +++ b/packages/api/src/services/SocketService.ts @@ -95,4 +95,8 @@ export class Socket { emitSignal100(value: boolean) { this.io.sockets.emit(SocketEvents.Signal100, value); } + + emitPanicButtonLeo(officer: any) { + this.io.sockets.emit(SocketEvents.PANIC_BUTTON, officer); + } } diff --git a/packages/client/locales/en/leo.json b/packages/client/locales/en/leo.json index 8a2f4b1e0..1d9e6d426 100644 --- a/packages/client/locales/en/leo.json +++ b/packages/client/locales/en/leo.json @@ -68,6 +68,8 @@ "suspendLicense": "Suspend License", "deleteRecord": "Delete Record", "image": "Image", + "panicButton": "Panic Button", + "panicButtonLeo": "{officer} has pressed the panic button.", "alert_deleteRecord": "Are you sure you want to delete this record? This action cannot be undone.", "alert_deleteOfficer": "Are you sure you want to delete {officer}? This action cannot be undone." } diff --git a/packages/client/src/components/ems-fd/ModalButtons.tsx b/packages/client/src/components/ems-fd/ModalButtons.tsx index 7e4319343..4bf88719f 100644 --- a/packages/client/src/components/ems-fd/ModalButtons.tsx +++ b/packages/client/src/components/ems-fd/ModalButtons.tsx @@ -32,8 +32,6 @@ export const ModalButtons = () => { const t = useTranslations(); const generateCallsign = useGenerateCallsign(); - console.log({ activeDeputy }); - const isButtonDisabled = !activeDeputy || activeDeputy.status?.shouldDo === ShouldDoType.SET_OFF_DUTY || diff --git a/packages/client/src/components/leo/ModalButtons.tsx b/packages/client/src/components/leo/ModalButtons.tsx index 11834aa1b..e15d3b896 100644 --- a/packages/client/src/components/leo/ModalButtons.tsx +++ b/packages/client/src/components/leo/ModalButtons.tsx @@ -5,6 +5,7 @@ import { ShouldDoType } from "types/prisma"; import { useModal } from "context/ModalContext"; import { useTranslations } from "use-intl"; import { useGenerateCallsign } from "hooks/useGenerateCallsign"; +import useFetch from "lib/useFetch"; interface MButton { nameKey: [string, string]; @@ -56,6 +57,16 @@ export const ModalButtons = () => { const t = useTranslations(); const generateCallsign = useGenerateCallsign(); + const { execute } = useFetch(); + + async function handlePanic() { + if (!activeOfficer) return; + + await execute("/leo/panic-button", { + method: "POST", + }); + } + const isButtonDisabled = !activeOfficer || activeOfficer.status?.shouldDo === ShouldDoType.SET_OFF_DUTY || @@ -82,6 +93,15 @@ export const ModalButtons = () => { {t(button.nameKey.join("."))} ))} + + ); diff --git a/packages/client/src/components/modals/Manage911CallModal.tsx b/packages/client/src/components/modals/Manage911CallModal.tsx index eadf419cd..e1f5765c8 100644 --- a/packages/client/src/components/modals/Manage911CallModal.tsx +++ b/packages/client/src/components/modals/Manage911CallModal.tsx @@ -104,8 +104,6 @@ export const Manage911CallModal = ({ setCall, call, onClose }: Props) => { (event) => { if (!call) return; - console.log({ event }); - setCall?.((p) => ({ ...(p ?? call), events: (p ?? call).events.filter((v) => v.id !== event.id), diff --git a/packages/client/src/hooks/usePanicButton.tsx b/packages/client/src/hooks/usePanicButton.tsx new file mode 100644 index 000000000..cb5d8b0be --- /dev/null +++ b/packages/client/src/hooks/usePanicButton.tsx @@ -0,0 +1,31 @@ +import * as React from "react"; +import { useListener } from "@casper124578/use-socket.io"; +import { SocketEvents } from "@snailycad/config"; +import { useTranslations } from "use-intl"; +import { FullDeputy, FullOfficer } from "state/dispatchState"; +import { useGenerateCallsign } from "./useGenerateCallsign"; + +export function usePanicButton() { + const [unit, setUnit] = React.useState(null); + + useListener(SocketEvents.PANIC_BUTTON, (officer: FullOfficer) => { + setUnit(officer); + }); + + return { unit, PanicButton: Component }; +} + +const Component = ({ unit }: { unit: FullOfficer | FullDeputy }) => { + const t = useTranslations("Leo"); + const generateCallsign = useGenerateCallsign(); + + return ( +
+

+ {t.rich("panicButtonLeo", { + officer: `${generateCallsign(unit)} ${unit.name}`, + })} +

+
+ ); +}; diff --git a/packages/client/src/pages/citizen/index.tsx b/packages/client/src/pages/citizen/index.tsx index 34bbaa79a..3e51a7201 100644 --- a/packages/client/src/pages/citizen/index.tsx +++ b/packages/client/src/pages/citizen/index.tsx @@ -53,7 +53,7 @@ export default function CitizenPage({ citizens }: Props) {