Merge pull request #77 from VAR-Virtual-Air-Rescue/staging

Final Bugfixes
This commit was merged in pull request #77.
This commit is contained in:
PxlLoewe
2025-07-22 11:16:44 -07:00
committed by GitHub
10 changed files with 81 additions and 47 deletions

View File

@@ -38,7 +38,7 @@ jobs:
- name: Build and start containers - name: Build and start containers
uses: appleboy/ssh-action@v1 uses: appleboy/ssh-action@v1
with: with:
host: ${{ vars.STAGING_HOST }} host: ${{ vars.PRODUCTION_HOST }}
username: ${{ secrets.SSH_USERNAME }} username: ${{ secrets.SSH_USERNAME }}
password: ${{ secrets.SSH_PASSWORD }} password: ${{ secrets.SSH_PASSWORD }}
port: 22 port: 22
@@ -46,4 +46,4 @@ jobs:
export NVM_DIR="$HOME/.nvm" export NVM_DIR="$HOME/.nvm"
source "$NVM_DIR/nvm.sh" source "$NVM_DIR/nvm.sh"
cd ~/docker/var-monorepo cd ~/docker/var-monorepo
pnpm staging-start pnpm prod-start

View File

@@ -45,16 +45,9 @@ export function StationsSelect({
queryFn: () => getStationsAPI(), queryFn: () => getStationsAPI(),
}); });
const [value, setValue] = useState<string[]>(selectedStations?.map((id) => String(id)) || []); const [value, setValue] = useState<string[] | string | null>(
selectedStations?.map((id) => String(id)) || [],
useEffect(() => { );
setValue([
...(selectedStations || []).map((id) => String(id)),
...(vehicleStates.hpgAmbulanceState !== HpgState.NOT_REQUESTED || undefined ? ["RTW"] : []),
...(vehicleStates.hpgFireEngineState !== HpgState.NOT_REQUESTED || undefined ? ["FW"] : []),
...(vehicleStates.hpgPoliceState !== HpgState.NOT_REQUESTED || undefined ? ["POL"] : []),
]);
}, [selectedStations, vehicleStates]);
// Helper to check if a station is a vehicle and its state is NOT_REQUESTED // Helper to check if a station is a vehicle and its state is NOT_REQUESTED
const stationsOptions = [ const stationsOptions = [
@@ -101,6 +94,20 @@ export function StationsSelect({
return true; return true;
}); });
useEffect(() => {
if (isMulti) {
setValue([
...(selectedStations || []).map((id) => String(id)),
...(vehicleStates.hpgAmbulanceState !== HpgState.NOT_REQUESTED || undefined ? ["RTW"] : []),
...(vehicleStates.hpgFireEngineState !== HpgState.NOT_REQUESTED || undefined ? ["FW"] : []),
...(vehicleStates.hpgPoliceState !== HpgState.NOT_REQUESTED || undefined ? ["POL"] : []),
]);
} else {
console.log("clear selected stations");
setValue(null);
}
}, [selectedStations, vehicleStates, isMulti]);
return ( return (
<Select <Select
className={className} className={className}

View File

@@ -135,7 +135,7 @@ export const ConnectionBtn = () => {
/> />
</div> </div>
)} )}
<fieldset className="fieldset mt-2 w-full"> <fieldset className="fieldset mt-4 w-full">
<label className="floating-label w-full text-base"> <label className="floating-label w-full text-base">
<span>Logoff Zeit (LCL)</span> <span>Logoff Zeit (LCL)</span>
<input <input

View File

@@ -7,9 +7,11 @@ import { getMissionsAPI } from "_querys/missions";
import { HPGValidationRequired } from "_helpers/hpgValidationRequired"; import { HPGValidationRequired } from "_helpers/hpgValidationRequired";
import { getConnectedAircraftsAPI } from "_querys/aircrafts"; import { getConnectedAircraftsAPI } from "_querys/aircrafts";
import { useMapStore } from "_store/mapStore"; import { useMapStore } from "_store/mapStore";
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
export const MapAdditionals = () => { export const MapAdditionals = () => {
const { isOpen, missionFormValues } = usePannelStore((state) => state); const { isOpen, missionFormValues } = usePannelStore((state) => state);
const dispatcherConnectionState = useDispatchConnectionStore((state) => state.status);
const { data: missions = [] } = useQuery({ const { data: missions = [] } = useQuery({
queryKey: ["missions"], queryKey: ["missions"],
queryFn: () => queryFn: () =>
@@ -32,6 +34,7 @@ export const MapAdditionals = () => {
m.hpgValidationState === "POSITION_AMANDED" && m.hpgValidationState === "POSITION_AMANDED" &&
m.state === "draft" && m.state === "draft" &&
m.hpgLocationLat && m.hpgLocationLat &&
dispatcherConnectionState === "connected" &&
m.hpgLocationLng, m.hpgLocationLng,
); );

View File

@@ -82,7 +82,7 @@ const MissionPopupContent = ({
return ( return (
<> <>
<div <div
className="absolute p-1 z-99 top-0 right-0 transform -translate-y-full bg-base-100 cursor-pointer" className="z-99 bg-base-100 absolute right-0 top-0 -translate-y-full transform cursor-pointer p-1"
onClick={() => { onClick={() => {
setOpenMissionMarker({ setOpenMissionMarker({
open: [], open: [],
@@ -95,7 +95,7 @@ const MissionPopupContent = ({
<div <div
className={cn( className={cn(
"absolute w-[calc(100%+2px)] h-4 z-99", "z-99 absolute h-4 w-[calc(100%+2px)]",
anchor.includes("left") ? "-left-[2px]" : "-right-[2px]", anchor.includes("left") ? "-left-[2px]" : "-right-[2px]",
anchor.includes("top") ? "-top-[2px]" : "-bottom-[2px]", anchor.includes("top") ? "-top-[2px]" : "-bottom-[2px]",
)} )}
@@ -116,13 +116,13 @@ const MissionPopupContent = ({
/> />
<div> <div>
<div <div
className="flex gap-[2px] text-white pb-0.5" className="flex gap-[2px] pb-0.5 text-white"
style={{ style={{
backgroundColor: `${MISSION_STATUS_TEXT_COLORS[mission.state]}`, backgroundColor: `${MISSION_STATUS_TEXT_COLORS[mission.state]}`,
}} }}
> >
<div <div
className="p-2 px-3 flex justify-center items-center cursor-pointer" className="flex cursor-pointer items-center justify-center p-2 px-3"
style={{ style={{
backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`, backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`,
borderBottom: borderBottom:
@@ -135,7 +135,7 @@ const MissionPopupContent = ({
<House className="text-sm" /> <House className="text-sm" />
</div> </div>
<div <div
className="p-2 px-4 flex justify-center items-center cursor-pointer" className="flex cursor-pointer items-center justify-center p-2 px-4"
style={{ style={{
backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`, backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`,
borderBottom: borderBottom:
@@ -148,7 +148,7 @@ const MissionPopupContent = ({
<Cross className="text-sm" /> <Cross className="text-sm" />
</div> </div>
<div <div
className="p-2 px-4 flex justify-center items-center cursor-pointer" className="flex cursor-pointer items-center justify-center p-2 px-4"
style={{ style={{
backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`, backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`,
borderBottom: borderBottom:
@@ -162,7 +162,7 @@ const MissionPopupContent = ({
</div> </div>
{mission.state === "draft" && ( {mission.state === "draft" && (
<div <div
className="p-2 px-4 flex justify-center items-center cursor-pointer ml-auto" className="ml-auto flex cursor-pointer items-center justify-center p-2 px-4"
style={{ style={{
backgroundColor: `${MISSION_STATUS_COLORS["attention"]}`, backgroundColor: `${MISSION_STATUS_COLORS["attention"]}`,
borderBottom: "5px solid transparent", borderBottom: "5px solid transparent",
@@ -173,9 +173,9 @@ const MissionPopupContent = ({
addressMissionDestination: mission.addressMissionDestination ?? undefined, addressMissionDestination: mission.addressMissionDestination ?? undefined,
addressAdditionalInfo: mission.addressAdditionalInfo ?? undefined, addressAdditionalInfo: mission.addressAdditionalInfo ?? undefined,
state: "draft", state: "draft",
hpgAmbulanceState: "NOT_REQUESTED", hpgAmbulanceState: mission.hpgAmbulanceState ?? "NOT_REQUESTED",
hpgFireEngineState: "NOT_REQUESTED", hpgFireEngineState: mission.hpgFireEngineState ?? "NOT_REQUESTED",
hpgPoliceState: "NOT_REQUESTED", hpgPoliceState: mission.hpgPoliceState ?? "NOT_REQUESTED",
hpgLocationLat: mission.hpgLocationLat ?? undefined, hpgLocationLat: mission.hpgLocationLat ?? undefined,
hpgLocationLng: mission.hpgLocationLng ?? undefined, hpgLocationLng: mission.hpgLocationLng ?? undefined,
}); });
@@ -188,7 +188,7 @@ const MissionPopupContent = ({
)} )}
<div <div
className={cn( className={cn(
"p-2 px-4 flex justify-center items-center cursor-pointer", "flex cursor-pointer items-center justify-center p-2 px-4",
mission.state !== "draft" && "ml-auto", mission.state !== "draft" && "ml-auto",
)} )}
style={{ style={{

View File

@@ -530,11 +530,15 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
className="min-w-[320px] flex-1" className="min-w-[320px] flex-1"
isMulti={false} isMulti={false}
onChange={(v) => { onChange={(v) => {
console.log("Selected Station:", v);
setSelectedStation({ setSelectedStation({
selectedStationId: v?.selectedStationIds[0], selectedStationId: v?.selectedStationIds[0],
hpgAmbulanceState: mission.hpgAmbulanceState || HpgState.NOT_REQUESTED, hpgAmbulanceState:
hpgFireEngineState: mission.hpgFireEngineState || HpgState.NOT_REQUESTED, v.hpgAmbulanceState || mission.hpgAmbulanceState || HpgState.NOT_REQUESTED,
hpgPoliceState: mission.hpgPoliceState || HpgState.NOT_REQUESTED, hpgFireEngineState:
v.hpgFireEngineState || mission.hpgFireEngineState || HpgState.NOT_REQUESTED,
hpgPoliceState:
v.hpgPoliceState || mission.hpgPoliceState || HpgState.NOT_REQUESTED,
}); });
}} }}
selectedStations={mission.missionStationIds} selectedStations={mission.missionStationIds}
@@ -548,6 +552,7 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => {
<button <button
className="btn btn-sm btn-primary btn-outline" className="btn btn-sm btn-primary btn-outline"
onClick={async () => { onClick={async () => {
console.log("Selected Station:", selectedStation);
if ( if (
selectedStation.hpgAmbulanceState !== "NOT_REQUESTED" || selectedStation.hpgAmbulanceState !== "NOT_REQUESTED" ||
selectedStation.hpgFireEngineState !== "NOT_REQUESTED" || selectedStation.hpgFireEngineState !== "NOT_REQUESTED" ||

View File

@@ -149,8 +149,7 @@ export const useDmeStore = create<MrtStore>(
{ {
textLeft: pageData.mission.addressAdditionalInfo || "keine Daten", textLeft: pageData.mission.addressAdditionalInfo || "keine Daten",
}, },
...(pageData.mission.addressMissionDestination && ...(pageData.mission.type === "sekundär"
pageData.mission.addressMissionDestination.length > 0
? [ ? [
{ {
textMid: "Zielort:", textMid: "Zielort:",
@@ -161,20 +160,30 @@ export const useDmeStore = create<MrtStore>(
}, },
] ]
: []), : []),
{ ...(pageData.mission.missionPatientInfo &&
textMid: "Patienteninfos:", pageData.mission.missionPatientInfo.length > 0
style: { fontWeight: "bold" }, ? [
}, {
{ textMid: "Patienteninfos:",
textLeft: pageData.mission.missionPatientInfo || "keine Daten", style: { fontWeight: "bold" },
}, },
{ {
textMid: "Weitere Infos:", textLeft: pageData.mission.missionPatientInfo,
style: { fontWeight: "bold" }, },
}, ]
{ : []),
textLeft: pageData.mission.missionAdditionalInfo || "keine Daten", ...(pageData.mission.missionAdditionalInfo &&
}, pageData.mission.missionAdditionalInfo.length > 0
? [
{
textMid: "Weitere Infos:",
style: { fontWeight: "bold" },
},
{
textLeft: pageData.mission.missionAdditionalInfo,
},
]
: []),
], ],
}); });
break; break;

View File

@@ -10,6 +10,9 @@ const page = async () => {
if (!user) return null; if (!user) return null;
const events = await prisma.event.findMany({ const events = await prisma.event.findMany({
where: {
hidden: false,
},
include: { include: {
Appointments: { Appointments: {
where: { where: {
@@ -65,8 +68,8 @@ const page = async () => {
return ( return (
<div className="grid grid-cols-6 gap-4"> <div className="grid grid-cols-6 gap-4">
<div className="col-span-full"> <div className="col-span-full">
<p className="text-2xl font-semibold text-left flex items-center gap-2"> <p className="flex items-center gap-2 text-left text-2xl font-semibold">
<RocketIcon className="w-5 h-5" /> Events & Kurse <RocketIcon className="h-5 w-5" /> Events & Kurse
</p> </p>
</div> </div>

View File

@@ -28,6 +28,13 @@ services:
- "traefik.http.routers.hub.entrypoints=websecure" - "traefik.http.routers.hub.entrypoints=websecure"
- "traefik.http.routers.hub.tls.certresolver=le" - "traefik.http.routers.hub.tls.certresolver=le"
- "traefik.http.services.hub.loadbalancer.server.port=3000" - "traefik.http.services.hub.loadbalancer.server.port=3000"
- "traefik.http.routers.lst-redirect.rule=Host(`lst.virtualairrescue.com`)"
- "traefik.http.routers.lst-redirect.entrypoints=websecure"
- "traefik.http.routers.lst-redirect.tls.certresolver=le"
- "traefik.http.middlewares.lst-to-hub-redirect.redirectregex.regex=^https://lst.virtualairrescue.com/(.*)"
- "traefik.http.middlewares.lst-to-hub-redirect.redirectregex.replacement=https://hub.virtualairrescue.com/"
- "traefik.http.middlewares.lst-to-hub-redirect.redirectregex.permanent=true"
- "traefik.http.routers.lst-redirect.middlewares=lst-to-hub-redirect"
environment: environment:
- NEXTAUTH_URL=${AUTH_HUB_URL} - NEXTAUTH_URL=${AUTH_HUB_URL}
- NEXTAUTH_SECRET=${AUTH_HUB_SECRET} - NEXTAUTH_SECRET=${AUTH_HUB_SECRET}

View File

@@ -9,8 +9,8 @@ export interface PublicUser {
} }
export const DISCORD_ROLES = { export const DISCORD_ROLES = {
ONLINE_DISPATCHER: "1287399540390891571", // Replace with actual role ID ONLINE_DISPATCHER: "1287399540390891571",
ONLINE_PILOT: "1287399540390891571", // Replace with actual role ID ONLINE_PILOT: "1287399540390891571",
DISPATCHER: "1081247459994501222", DISPATCHER: "1081247459994501222",
PILOT: "1081247405304975390", PILOT: "1081247405304975390",
}; };