Fahrzeugauswahl überarbeitet

This commit is contained in:
PxlLoewe
2025-07-01 02:19:00 -07:00
parent 169a05ed8f
commit 157394767f
9 changed files with 249 additions and 157 deletions

View File

@@ -48,6 +48,7 @@ import { HPGValidationRequired } from "_helpers/hpgValidationRequired";
import { getOsmAddress } from "_querys/osm";
import { hpgStateToFMSStatus } from "_helpers/hpgStateToFmsStatus";
import { cn } from "@repo/shared-components";
import { StationsSelect } from "(app)/dispatch/_components/StationSelect";
const Einsatzdetails = ({
mission,
@@ -420,39 +421,6 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
},
});
const stationsOptions = [
...(allStations
?.filter((s) => !mission.missionStationIds.includes(s.id))
?.map((station) => ({
label: station.bosCallsign,
value: station.id,
type: "station" as const,
isOnline: !!connectedAircrafts?.find((a) => a.stationId === station.id),
})) || []),
...(!mission.hpgFireEngineState || mission.hpgFireEngineState === "NOT_REQUESTED"
? [{ label: "Feuerwehr", value: "FW", type: "vehicle" as const }]
: []),
...(!mission.hpgAmbulanceState || mission.hpgAmbulanceState === "NOT_REQUESTED"
? [{ label: "Rettungsdienst", value: "RTW", type: "vehicle" as const }]
: []),
...(!mission.hpgPoliceState || mission.hpgPoliceState === "NOT_REQUESTED"
? [{ label: "Polizei", value: "POL", type: "vehicle" as const }]
: []),
].sort((a, b) => {
// 1. Vehicles first
if (a.type === "vehicle" && b.type !== "vehicle") return -1;
if (a.type !== "vehicle" && b.type === "vehicle") return 1;
// 2. Online stations before offline stations
if (a.type === "station" && b.type === "station") {
if (a.isOnline && !b.isOnline) return -1;
if (!a.isOnline && b.isOnline) return 1;
}
// 3. Otherwise, sort alphabetically by label
return a.label.localeCompare(b.label);
});
const dispatcherConnected = useDispatchConnectionStore((s) => s.status) === "connected";
const HPGVehicle = ({ state, name }: { state: HpgState; name: string }) => (
@@ -503,70 +471,57 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
const connectedAircraft = connectedAircrafts?.find(
(aircraft) => aircraft.stationId === station.id,
);
console.log("connectedAircraft", connectedAircraft);
return (
<li key={index} className="flex items-center gap-2">
{connectedAircraft && (
<span
className="font-bold text-base"
style={{
color: FMS_STATUS_TEXT_COLORS[connectedAircraft.fmsStatus],
}}
>
{connectedAircraft.fmsStatus}
</span>
)}
<span className="text-base-content">
<div>
<span className="font-bold">{station.bosCallsign}</span>
{/* {item.min > 0 && (
<>
<br />
Ankunft in ca. {item.min} min
</>
)} */}
</div>
<span
className="font-bold text-base"
style={{
color: FMS_STATUS_TEXT_COLORS[connectedAircraft?.fmsStatus || "6"],
}}
>
{connectedAircraft?.fmsStatus || "6"}
</span>
<span className="text-base-content flex flex-col ">
<span className="font-bold">{station.bosCallsign}</span>
{!connectedAircraft && (
<span className="text-gray-400 text-xs">Kein Benutzer verbunden</span>
)}
</span>
</li>
);
})}
{mission.hpgAmbulanceState && <HPGVehicle state={mission.hpgAmbulanceState} name="RTW" />}
{mission.hpgFireEngineState && (
{mission.hpgAmbulanceState && mission.hpgAmbulanceState !== "NOT_REQUESTED" && (
<HPGVehicle state={mission.hpgAmbulanceState} name="RTW" />
)}
{mission.hpgFireEngineState && mission.hpgFireEngineState !== "NOT_REQUESTED" && (
<HPGVehicle state={mission.hpgFireEngineState} name="Feuerwehr" />
)}
{mission.hpgPoliceState && <HPGVehicle state={mission.hpgPoliceState} name="Polizei" />}
{mission.hpgPoliceState && mission.hpgPoliceState !== "NOT_REQUESTED" && (
<HPGVehicle state={mission.hpgPoliceState} name="Polizei" />
)}
</ul>
{dispatcherConnected && (
<div>
<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"
onChange={(e) => {
const value = e.target.value;
const parsedValue = !isNaN(Number(value)) ? parseInt(value, 10) : value;
setSelectedStation(parsedValue as number | "RTW" | "POL" | "FW" | null);
<StationsSelect
menuPlacement="top"
className="min-w-[320px] flex-1"
isMulti={false}
onChange={(v: any) => {
setSelectedStation(v);
}}
value={selectedStation || "default"}
>
<option disabled value={"default"}>
Rettungsmittel auswählen
</option>
{stationsOptions.map((option) => (
<option
key={option.value}
value={option.value}
className={cn(
"flex gap-2",
"isOnline" in option && option?.isOnline && "text-green-500",
)}
>
{option.label}
{"isOnline" in option && option?.isOnline && " (Online)"}
</option>
))}
</select>
selectedStations={mission.missionStationIds}
filterSelected
vehicleStates={{
hpgAmbulanceState: mission.hpgAmbulanceState || undefined,
hpgFireEngineState: mission.hpgFireEngineState || undefined,
hpgPoliceState: mission.hpgPoliceState || undefined,
}}
/>
<button
className="btn btn-sm btn-primary btn-outline"
onClick={async () => {