nachalarmieren tab complete
This commit is contained in:
@@ -51,8 +51,6 @@ router.put("/", async (req, res) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("missionsTodayCount", missionsTodayCount);
|
|
||||||
|
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
const month = String(date.getMonth() + 1).padStart(2, "0"); // Months are zero-based
|
const month = String(date.getMonth() + 1).padStart(2, "0"); // Months are zero-based
|
||||||
@@ -107,6 +105,7 @@ router.delete("/:id", async (req, res) => {
|
|||||||
|
|
||||||
router.post("/:id/send-alert", async (req, res) => {
|
router.post("/:id/send-alert", async (req, res) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
const { stationId } = req.body as { stationId?: number };
|
||||||
try {
|
try {
|
||||||
const mission = await prisma.mission.findUnique({
|
const mission = await prisma.mission.findUnique({
|
||||||
where: { id: Number(id) },
|
where: { id: Number(id) },
|
||||||
@@ -136,6 +135,7 @@ router.post("/:id/send-alert", async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const aircraft of connectedAircrafts) {
|
for (const aircraft of connectedAircrafts) {
|
||||||
|
if (stationId && stationId !== aircraft.stationId) continue;
|
||||||
console.log(`Sending mission to: station:${aircraft.stationId}`);
|
console.log(`Sending mission to: station:${aircraft.stationId}`);
|
||||||
io.to(`station:${aircraft.stationId}`).emit("mission-alert", {
|
io.to(`station:${aircraft.stationId}`).emit("mission-alert", {
|
||||||
...mission,
|
...mission,
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ export const SearchElements = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ref.current) {
|
if (ref.current) {
|
||||||
ref.current.on("click", () => {
|
ref.current.on("click", () => {
|
||||||
console.log("click");
|
|
||||||
const center = ref.current?.getBounds().getCenter();
|
const center = ref.current?.getBounds().getCenter();
|
||||||
if (center && searchPopup?.elementId !== element.wayID) {
|
if (center && searchPopup?.elementId !== element.wayID) {
|
||||||
setSearchPopup({
|
setSearchPopup({
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { FMS_STATUS_TEXT_COLORS } from "../AircraftMarker";
|
import { FMS_STATUS_TEXT_COLORS } from "../AircraftMarker";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import {
|
import {
|
||||||
@@ -17,7 +17,6 @@ import {
|
|||||||
User,
|
User,
|
||||||
SmartphoneNfc,
|
SmartphoneNfc,
|
||||||
CheckCheck,
|
CheckCheck,
|
||||||
ArrowRight,
|
|
||||||
Cross,
|
Cross,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import {
|
import {
|
||||||
@@ -52,7 +51,7 @@ const Einsatzdetails = ({ mission }: { mission: Mission }) => {
|
|||||||
});
|
});
|
||||||
const sendAlertMutation = useMutation({
|
const sendAlertMutation = useMutation({
|
||||||
mutationKey: ["missions"],
|
mutationKey: ["missions"],
|
||||||
mutationFn: sendMissionAPI,
|
mutationFn: (id: number) => sendMissionAPI(id, {}),
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
toast.error("Fehler beim Alarmieren");
|
toast.error("Fehler beim Alarmieren");
|
||||||
@@ -225,23 +224,71 @@ const Patientdetails = ({ mission }: { mission: Mission }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Rettungsmittel = ({ mission }: { mission: Mission }) => {
|
const Rettungsmittel = ({ mission }: { mission: Mission }) => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const [selectedStation, setSelectedStation] = useState<
|
||||||
|
Station | "ambulance" | "police" | "firebrigade" | null
|
||||||
|
>(null);
|
||||||
const { data: conenctedAircrafts } = useQuery({
|
const { data: conenctedAircrafts } = useQuery({
|
||||||
queryKey: ["aircrafts"],
|
queryKey: ["aircrafts"],
|
||||||
queryFn: getConnectedAircraftsAPI,
|
queryFn: getConnectedAircraftsAPI,
|
||||||
});
|
});
|
||||||
const { data: stations } = useQuery({
|
const updateMissionMutation = useMutation({
|
||||||
queryKey: ["mission", "stations-mission", mission.id],
|
mutationKey: ["missions", "stations-mission", mission.id],
|
||||||
|
mutationFn: ({
|
||||||
|
id,
|
||||||
|
missionEdit,
|
||||||
|
}: {
|
||||||
|
id: number;
|
||||||
|
missionEdit: Prisma.MissionUpdateInput;
|
||||||
|
}) => editMissionAPI(id, missionEdit),
|
||||||
|
|
||||||
|
onError: (error) => {
|
||||||
|
console.error(error);
|
||||||
|
toast.error("Fehler beim Speichern");
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
// Cache invalidieren → Query wird neu ausgeführt
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["missions"],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { data: missionStations, refetch: refetchMissionStationIds } = useQuery(
|
||||||
|
{
|
||||||
|
queryKey: ["stations-mission", mission.id],
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
getStationsAPI({
|
getStationsAPI({
|
||||||
id: {
|
id: {
|
||||||
in: mission.missionStationIds,
|
in: mission.missionStationIds,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
refetchMissionStationIds();
|
||||||
|
}, [mission.missionStationIds, refetchMissionStationIds]);
|
||||||
|
|
||||||
|
const { data: allStations } = useQuery({
|
||||||
|
queryKey: ["stations"],
|
||||||
|
queryFn: () => getStationsAPI(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (allStations) {
|
||||||
|
const stationsNotItMission = allStations.filter(
|
||||||
|
(s) => !mission.missionStationIds.includes(s.id),
|
||||||
|
);
|
||||||
|
if (stationsNotItMission[0]) {
|
||||||
|
setSelectedStation(stationsNotItMission[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [allStations, mission.missionStationIds]);
|
||||||
|
|
||||||
const sendAlertMutation = useMutation({
|
const sendAlertMutation = useMutation({
|
||||||
mutationKey: ["missions"],
|
mutationKey: ["missions"],
|
||||||
mutationFn: sendMissionAPI,
|
mutationFn: ({ id, stationId }: { id: number; stationId?: number }) =>
|
||||||
|
sendMissionAPI(id, { stationId }),
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
toast.error("Fehler beim Alarmieren");
|
toast.error("Fehler beim Alarmieren");
|
||||||
@@ -264,7 +311,7 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
|
|||||||
<button
|
<button
|
||||||
className="btn btn-xs btn-primary btn-outline"
|
className="btn btn-xs btn-primary btn-outline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
sendAlertMutation.mutate(mission.id);
|
sendAlertMutation.mutate({ id: mission.id });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BellRing size={16} />
|
<BellRing size={16} />
|
||||||
@@ -272,7 +319,7 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul className="space-y-2 max-h-[300px] overflow-y-auto overflow-x-auto">
|
<ul className="space-y-2 max-h-[300px] overflow-y-auto overflow-x-auto">
|
||||||
{stations?.map((station, index) => {
|
{missionStations?.map((station, index) => {
|
||||||
const connectedAircraft = conenctedAircrafts?.find(
|
const connectedAircraft = conenctedAircrafts?.find(
|
||||||
(aircraft) => aircraft.stationId === station.id,
|
(aircraft) => aircraft.stationId === station.id,
|
||||||
);
|
);
|
||||||
@@ -307,12 +354,66 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
|
|||||||
<div className="divider mt-0 mb-0" />
|
<div className="divider mt-0 mb-0" />
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{/* TODO: make it a small multiselect */}
|
{/* TODO: make it a small multiselect */}
|
||||||
<select className="select select-sm select-primary select-bordered flex-1">
|
<select
|
||||||
<option value="1">Feuerwehr</option>
|
className="select select-sm select-primary select-bordered flex-1"
|
||||||
<option value="2">RTW</option>
|
onChange={(e) => {
|
||||||
<option value="3">Polizei</option>
|
const selected = allStations?.find(
|
||||||
|
(s) => s.id.toString() === e.target.value,
|
||||||
|
);
|
||||||
|
if (selected) {
|
||||||
|
setSelectedStation(selected);
|
||||||
|
} else {
|
||||||
|
setSelectedStation(
|
||||||
|
e.target.value as "ambulance" | "police" | "firebrigade",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
value={
|
||||||
|
typeof selectedStation === "string"
|
||||||
|
? selectedStation
|
||||||
|
: selectedStation?.id
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{allStations
|
||||||
|
?.filter((s) => !mission.missionStationIds.includes(s.id))
|
||||||
|
?.map((station) => (
|
||||||
|
<option
|
||||||
|
key={station.id}
|
||||||
|
value={station.id}
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedStation(station);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{station.bosCallsign}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
<option disabled>Fahrzeuge:</option>
|
||||||
|
<option value="firebrigade">Feuerwehr</option>
|
||||||
|
<option value="ambulance">RTW</option>
|
||||||
|
<option value="police">Polizei</option>
|
||||||
</select>
|
</select>
|
||||||
<button className="btn btn-sm btn-primary btn-outline">
|
<button
|
||||||
|
className="btn btn-sm btn-primary btn-outline"
|
||||||
|
onClick={async () => {
|
||||||
|
if (typeof selectedStation === "string") {
|
||||||
|
toast.error("Fahrzeuge werden aktuell nicht unterstützt");
|
||||||
|
} else {
|
||||||
|
if (!selectedStation?.id) return;
|
||||||
|
await updateMissionMutation.mutateAsync({
|
||||||
|
id: mission.id,
|
||||||
|
missionEdit: {
|
||||||
|
missionStationIds: {
|
||||||
|
push: selectedStation?.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await sendAlertMutation.mutate({
|
||||||
|
id: mission.id,
|
||||||
|
stationId: selectedStation?.id ?? 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<span className="text-base-content flex items-center gap-2">
|
<span className="text-base-content flex items-center gap-2">
|
||||||
<BellRing size={16} /> Nachalarmieren
|
<BellRing size={16} /> Nachalarmieren
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ import { usePannelStore } from "_store/pannelStore";
|
|||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { createMissionAPI, editMissionAPI } from "querys/missions";
|
import {
|
||||||
|
createMissionAPI,
|
||||||
|
editMissionAPI,
|
||||||
|
sendMissionAPI,
|
||||||
|
} from "querys/missions";
|
||||||
import { getKeywordsAPI } from "querys/keywords";
|
import { getKeywordsAPI } from "querys/keywords";
|
||||||
import { getStationsAPI } from "querys/stations";
|
import { getStationsAPI } from "querys/stations";
|
||||||
import { useMapStore } from "_store/mapStore";
|
import { useMapStore } from "_store/mapStore";
|
||||||
@@ -43,6 +47,17 @@ export const MissionForm = () => {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const sendAlertMutation = useMutation({
|
||||||
|
mutationKey: ["missions"],
|
||||||
|
mutationFn: (id: number) => sendMissionAPI(id, {}),
|
||||||
|
onError: (error) => {
|
||||||
|
console.error(error);
|
||||||
|
toast.error("Fehler beim Alarmieren");
|
||||||
|
},
|
||||||
|
onSuccess: (data) => {
|
||||||
|
toast.success(data.message);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const editMissionMutation = useMutation({
|
const editMissionMutation = useMutation({
|
||||||
mutationFn: ({
|
mutationFn: ({
|
||||||
@@ -347,9 +362,9 @@ export const MissionForm = () => {
|
|||||||
await createMissionMutation.mutateAsync(
|
await createMissionMutation.mutateAsync(
|
||||||
mission as unknown as Prisma.MissionCreateInput,
|
mission as unknown as Prisma.MissionCreateInput,
|
||||||
);
|
);
|
||||||
|
await sendAlertMutation.mutateAsync(newMission.id);
|
||||||
setSeachOSMElements([]); // Reset search elements
|
setSeachOSMElements([]); // Reset search elements
|
||||||
toast.success(`Einsatz ${newMission.id} erstellt`);
|
|
||||||
// TODO: Einsatz alarmieren
|
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(
|
toast.error(
|
||||||
|
|||||||
@@ -27,10 +27,19 @@ export const editMissionAPI = async (
|
|||||||
return respone.data;
|
return respone.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sendMissionAPI = async (id: number) => {
|
export const sendMissionAPI = async (
|
||||||
|
id: number,
|
||||||
|
{
|
||||||
|
stationId,
|
||||||
|
}: {
|
||||||
|
stationId?: number;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
const respone = await serverApi.post<{
|
const respone = await serverApi.post<{
|
||||||
message: string;
|
message: string;
|
||||||
}>(`/mission/${id}/send-alert`);
|
}>(`/mission/${id}/send-alert`, {
|
||||||
|
stationId,
|
||||||
|
});
|
||||||
return respone.data;
|
return respone.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user