This commit is contained in:
nocnico
2025-07-19 01:11:33 +02:00
8 changed files with 62 additions and 18 deletions

View File

@@ -18,14 +18,10 @@ const DispatchPage = () => {
<div className="relative flex-1 flex transition-all duration-500 ease w-full"> <div className="relative flex-1 flex transition-all duration-500 ease w-full">
{/* <MapToastCard2 /> */} {/* <MapToastCard2 /> */}
<div className="flex flex-1 relative"> <div className="flex flex-1 relative">
<div className="absolute left-0 top-1/2 transform -translate-y-1/2 pl-4 z-999999"> <div className="absolute left-0 top-1/2 transform -translate-y-1/2 pl-4 z-999999 space-y-2">
<Chat /> <Chat />
<div className="mt-2"> <Report />
<Report /> <BugReport />
</div>
<div className="mt-2">
<BugReport />
</div>
</div> </div>
<div className="absolute left-0 top-19/20 transform -translate-y-1/2 pl-4 z-999999"> <div className="absolute left-0 top-19/20 transform -translate-y-1/2 pl-4 z-999999">
<div className="flex items-center justify-between gap-4"> <div className="flex items-center justify-between gap-4">

View File

@@ -33,14 +33,10 @@ const PilotPage = () => {
<div className="relative flex-1 flex transition-all duration-500 ease w-full h-screen overflow-hidden"> <div className="relative flex-1 flex transition-all duration-500 ease w-full h-screen overflow-hidden">
{/* <MapToastCard2 /> */} {/* <MapToastCard2 /> */}
<div className="flex flex-1 relative w-full h-full"> <div className="flex flex-1 relative w-full h-full">
<div className="absolute left-0 top-1/2 transform -translate-y-1/2 pl-4 z-999999"> <div className="absolute left-0 top-1/2 transform -translate-y-1/2 pl-4 z-999999 space-y-2">
<Chat /> <Chat />
<div className="mt-2"> <Report />
<Report /> <BugReport />
</div>
<div className="mt-2">
<BugReport />
</div>
</div> </div>
<div className="flex w-2/3 h-full"> <div className="flex w-2/3 h-full">
<div className="relative flex flex-1 h-full"> <div className="relative flex flex-1 h-full">

View File

@@ -9,6 +9,7 @@ import { useQuery } from "@tanstack/react-query";
import { getConnectedDispatcherAPI } from "_querys/dispatcher"; import { getConnectedDispatcherAPI } from "_querys/dispatcher";
import { getConnectedAircraftsAPI } from "_querys/aircrafts"; import { getConnectedAircraftsAPI } from "_querys/aircrafts";
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore"; import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
import { usePilotConnectionStore } from "_store/pilot/connectionStore";
export const Chat = () => { export const Chat = () => {
const { const {
@@ -28,6 +29,7 @@ export const Chat = () => {
const [addTabValue, setAddTabValue] = useState<string>("default"); const [addTabValue, setAddTabValue] = useState<string>("default");
const [message, setMessage] = useState<string>(""); const [message, setMessage] = useState<string>("");
const dispatcherConnected = useDispatchConnectionStore((state) => state.status === "connected"); const dispatcherConnected = useDispatchConnectionStore((state) => state.status === "connected");
const pilotConnected = usePilotConnectionStore((state) => state.status === "connected");
const { data: dispatcher } = useQuery({ const { data: dispatcher } = useQuery({
queryKey: ["dispatcher"], queryKey: ["dispatcher"],
@@ -51,6 +53,14 @@ export const Chat = () => {
(a) => a.userId !== session.data?.user.id && dispatcherConnected, (a) => a.userId !== session.data?.user.id && dispatcherConnected,
); );
const btnActive = pilotConnected || dispatcherConnected;
useEffect(() => {
if (!btnActive) {
setChatOpen(false);
}
}, [btnActive, setChatOpen]);
return ( return (
<div className={cn("dropdown dropdown-right dropdown-center", chatOpen && "dropdown-open")}> <div className={cn("dropdown dropdown-right dropdown-center", chatOpen && "dropdown-open")}>
<div className="indicator"> <div className="indicator">
@@ -58,8 +68,12 @@ export const Chat = () => {
<span className="indicator-item status status-info animate-ping"></span> <span className="indicator-item status status-info animate-ping"></span>
)} )}
<button <button
className="btn btn-soft btn-sm btn-primary" className={cn(
"btn btn-soft btn-sm cursor-default",
btnActive && "btn-primary cursor-pointer",
)}
onClick={() => { onClick={() => {
if (!btnActive) return;
setReportTabOpen(false); setReportTabOpen(false);
setChatOpen(!chatOpen); setChatOpen(!chatOpen);
if (selectedChat) { if (selectedChat) {

View File

@@ -10,6 +10,8 @@ import { useQuery } from "@tanstack/react-query";
import { getConnectedDispatcherAPI } from "_querys/dispatcher"; import { getConnectedDispatcherAPI } from "_querys/dispatcher";
import { sendReportAPI } from "_querys/report"; import { sendReportAPI } from "_querys/report";
import { getConnectedAircraftsAPI } from "_querys/aircrafts"; import { getConnectedAircraftsAPI } from "_querys/aircrafts";
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
import { usePilotConnectionStore } from "_store/pilot/connectionStore";
export const Report = () => { export const Report = () => {
const { setChatOpen, setReportTabOpen, reportTabOpen, setOwnId } = useLeftMenuStore(); const { setChatOpen, setReportTabOpen, reportTabOpen, setOwnId } = useLeftMenuStore();
@@ -18,6 +20,9 @@ export const Report = () => {
const [selectedPlayer, setSelectedPlayer] = useState<string>("default"); const [selectedPlayer, setSelectedPlayer] = useState<string>("default");
const [message, setMessage] = useState<string>(""); const [message, setMessage] = useState<string>("");
const dispatcherConnected = useDispatchConnectionStore((state) => state.status === "connected");
const pilotConnected = usePilotConnectionStore((state) => state.status === "connected");
useEffect(() => { useEffect(() => {
if (!session.data?.user.id) return; if (!session.data?.user.id) return;
setOwnId(session.data.user.id); setOwnId(session.data.user.id);
@@ -36,6 +41,13 @@ export const Report = () => {
const filteredDispatcher = dispatcher?.filter((d) => d.userId !== session.data?.user.id); const filteredDispatcher = dispatcher?.filter((d) => d.userId !== session.data?.user.id);
const filteredAircrafts = aircrafts?.filter((a) => a.userId !== session.data?.user.id); const filteredAircrafts = aircrafts?.filter((a) => a.userId !== session.data?.user.id);
const btnActive = pilotConnected || dispatcherConnected;
useEffect(() => {
if (!btnActive) {
setReportTabOpen(false);
}
}, [btnActive, setReportTabOpen]);
return ( return (
<div <div
@@ -43,8 +55,12 @@ export const Report = () => {
> >
<div className="indicator"> <div className="indicator">
<button <button
className="btn btn-soft btn-sm btn-error" className={cn(
"btn btn-soft btn-sm cursor-default",
btnActive && "cursor-pointer btn-error",
)}
onClick={() => { onClick={() => {
if (!btnActive) return;
setChatOpen(false); setChatOpen(false);
setReportTabOpen(!reportTabOpen); setReportTabOpen(!reportTabOpen);
}} }}

View File

@@ -53,7 +53,7 @@ export const ContextMenu = () => {
if (!contextMenu || !dispatcherConnected) return null; if (!contextMenu || !dispatcherConnected) return null;
const einsatzBtnText = missionFormValues && isOpen ? "Position übernehmen" : "Einsatz erstellen"; const missionBtnText = missionFormValues && isOpen ? "Position übernehmen" : "Einsatz erstellen";
const addOSMobjects = async (ignorePreviosSelected?: boolean) => { const addOSMobjects = async (ignorePreviosSelected?: boolean) => {
const res = await fetch( const res = await fetch(
@@ -108,7 +108,7 @@ export const ContextMenu = () => {
{/* Top Button */} {/* Top Button */}
<button <button
className="btn btn-circle bg-rescuetrack w-10 h-10 absolute left-1/2 top-0 pointer-events-auto opacity-80 tooltip tooltip-top tooltip-accent" className="btn btn-circle bg-rescuetrack w-10 h-10 absolute left-1/2 top-0 pointer-events-auto opacity-80 tooltip tooltip-top tooltip-accent"
data-tip={einsatzBtnText} data-tip={missionBtnText}
style={{ transform: "translateX(-50%)" }} style={{ transform: "translateX(-50%)" }}
onClick={async () => { onClick={async () => {
const { parsed } = await getOsmAddress(contextMenu.lat, contextMenu.lng); const { parsed } = await getOsmAddress(contextMenu.lat, contextMenu.lng);

View File

@@ -12,6 +12,7 @@ import { MarkerCluster } from "_components/map/_components/MarkerCluster";
import { useEffect, useRef } from "react"; import { useEffect, useRef } from "react";
import { Map as TMap } from "leaflet"; import { Map as TMap } from "leaflet";
import { DistanceLayer } from "_components/map/Measurement"; import { DistanceLayer } from "_components/map/Measurement";
import { MapAdditionals } from "_components/map/MapAdditionals";
const Map = () => { const Map = () => {
const ref = useRef<TMap | null>(null); const ref = useRef<TMap | null>(null);
@@ -48,6 +49,7 @@ const Map = () => {
<MissionLayer /> <MissionLayer />
<AircraftLayer /> <AircraftLayer />
<DistanceLayer /> <DistanceLayer />
<MapAdditionals />
</MapContainer> </MapContainer>
); );
}; };

View File

@@ -0,0 +1,20 @@
"use client";
import { usePannelStore } from "_store/pannelStore";
import { Marker } from "react-leaflet";
import L from "leaflet";
export const MapAdditionals = () => {
const missionForm = usePannelStore((state) => state.missionFormValues);
if (!missionForm?.addressLat || !missionForm?.addressLng) return null;
return (
<>
<Marker
position={[missionForm.addressLat, missionForm.addressLng]}
icon={L.icon({ iconUrl: "/icons/mapMarker.png", iconSize: [40, 40], iconAnchor: [20, 35] })}
interactive={false}
/>
</>
);
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB