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 year = date.getFullYear();
|
||||
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) => {
|
||||
const { id } = req.params;
|
||||
const { stationId } = req.body as { stationId?: number };
|
||||
try {
|
||||
const mission = await prisma.mission.findUnique({
|
||||
where: { id: Number(id) },
|
||||
@@ -136,6 +135,7 @@ router.post("/:id/send-alert", async (req, res) => {
|
||||
});
|
||||
|
||||
for (const aircraft of connectedAircrafts) {
|
||||
if (stationId && stationId !== aircraft.stationId) continue;
|
||||
console.log(`Sending mission to: station:${aircraft.stationId}`);
|
||||
io.to(`station:${aircraft.stationId}`).emit("mission-alert", {
|
||||
...mission,
|
||||
|
||||
@@ -46,7 +46,6 @@ export const SearchElements = () => {
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
ref.current.on("click", () => {
|
||||
console.log("click");
|
||||
const center = ref.current?.getBounds().getCenter();
|
||||
if (center && searchPopup?.elementId !== element.wayID) {
|
||||
setSearchPopup({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use client";
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { FMS_STATUS_TEXT_COLORS } from "../AircraftMarker";
|
||||
import { toast } from "react-hot-toast";
|
||||
import {
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
User,
|
||||
SmartphoneNfc,
|
||||
CheckCheck,
|
||||
ArrowRight,
|
||||
Cross,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
@@ -52,7 +51,7 @@ const Einsatzdetails = ({ mission }: { mission: Mission }) => {
|
||||
});
|
||||
const sendAlertMutation = useMutation({
|
||||
mutationKey: ["missions"],
|
||||
mutationFn: sendMissionAPI,
|
||||
mutationFn: (id: number) => sendMissionAPI(id, {}),
|
||||
onError: (error) => {
|
||||
console.error(error);
|
||||
toast.error("Fehler beim Alarmieren");
|
||||
@@ -225,23 +224,71 @@ const Patientdetails = ({ 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({
|
||||
queryKey: ["aircrafts"],
|
||||
queryFn: getConnectedAircraftsAPI,
|
||||
});
|
||||
const { data: stations } = useQuery({
|
||||
queryKey: ["mission", "stations-mission", mission.id],
|
||||
queryFn: () =>
|
||||
getStationsAPI({
|
||||
id: {
|
||||
in: mission.missionStationIds,
|
||||
},
|
||||
}),
|
||||
const updateMissionMutation = useMutation({
|
||||
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: () =>
|
||||
getStationsAPI({
|
||||
id: {
|
||||
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({
|
||||
mutationKey: ["missions"],
|
||||
mutationFn: sendMissionAPI,
|
||||
mutationFn: ({ id, stationId }: { id: number; stationId?: number }) =>
|
||||
sendMissionAPI(id, { stationId }),
|
||||
onError: (error) => {
|
||||
console.error(error);
|
||||
toast.error("Fehler beim Alarmieren");
|
||||
@@ -264,7 +311,7 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
|
||||
<button
|
||||
className="btn btn-xs btn-primary btn-outline"
|
||||
onClick={() => {
|
||||
sendAlertMutation.mutate(mission.id);
|
||||
sendAlertMutation.mutate({ id: mission.id });
|
||||
}}
|
||||
>
|
||||
<BellRing size={16} />
|
||||
@@ -272,7 +319,7 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
|
||||
</div>
|
||||
</div>
|
||||
<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(
|
||||
(aircraft) => aircraft.stationId === station.id,
|
||||
);
|
||||
@@ -307,12 +354,66 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
|
||||
<div className="divider mt-0 mb-0" />
|
||||
<div className="flex items-center gap-2">
|
||||
{/* TODO: make it a small multiselect */}
|
||||
<select className="select select-sm select-primary select-bordered flex-1">
|
||||
<option value="1">Feuerwehr</option>
|
||||
<option value="2">RTW</option>
|
||||
<option value="3">Polizei</option>
|
||||
<select
|
||||
className="select select-sm select-primary select-bordered flex-1"
|
||||
onChange={(e) => {
|
||||
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>
|
||||
<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">
|
||||
<BellRing size={16} /> Nachalarmieren
|
||||
</span>
|
||||
|
||||
@@ -13,7 +13,11 @@ import { usePannelStore } from "_store/pannelStore";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { toast } from "react-hot-toast";
|
||||
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 { getStationsAPI } from "querys/stations";
|
||||
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({
|
||||
mutationFn: ({
|
||||
@@ -347,9 +362,9 @@ export const MissionForm = () => {
|
||||
await createMissionMutation.mutateAsync(
|
||||
mission as unknown as Prisma.MissionCreateInput,
|
||||
);
|
||||
await sendAlertMutation.mutateAsync(newMission.id);
|
||||
setSeachOSMElements([]); // Reset search elements
|
||||
toast.success(`Einsatz ${newMission.id} erstellt`);
|
||||
// TODO: Einsatz alarmieren
|
||||
|
||||
setOpen(false);
|
||||
} catch (error) {
|
||||
toast.error(
|
||||
|
||||
@@ -27,10 +27,19 @@ export const editMissionAPI = async (
|
||||
return respone.data;
|
||||
};
|
||||
|
||||
export const sendMissionAPI = async (id: number) => {
|
||||
export const sendMissionAPI = async (
|
||||
id: number,
|
||||
{
|
||||
stationId,
|
||||
}: {
|
||||
stationId?: number;
|
||||
},
|
||||
) => {
|
||||
const respone = await serverApi.post<{
|
||||
message: string;
|
||||
}>(`/mission/${id}/send-alert`);
|
||||
}>(`/mission/${id}/send-alert`, {
|
||||
stationId,
|
||||
});
|
||||
return respone.data;
|
||||
};
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user