Situation Board WIP #28
This commit is contained in:
45
apps/dispatch/app/_components/left/SituationBoard.tsx
Normal file
45
apps/dispatch/app/_components/left/SituationBoard.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
"use client";
|
||||||
|
import { useLeftMenuStore } from "_store/leftMenuStore";
|
||||||
|
import { useSession } from "next-auth/react";
|
||||||
|
import { cn } from "_helpers/cn";
|
||||||
|
import { ListCollapse, Plane } from "lucide-react";
|
||||||
|
|
||||||
|
export const SituationBoard = () => {
|
||||||
|
const { setSituationTabOpen, situationTabOpen } = useLeftMenuStore();
|
||||||
|
const session = useSession();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cn("dropdown dropdown-top", situationTabOpen && "dropdown-open")}>
|
||||||
|
<div className="indicator">
|
||||||
|
<button
|
||||||
|
className="btn btn-soft btn-sm btn-info"
|
||||||
|
onClick={() => {
|
||||||
|
setSituationTabOpen(!situationTabOpen);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ListCollapse className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{situationTabOpen && (
|
||||||
|
<div
|
||||||
|
tabIndex={0}
|
||||||
|
className="dropdown-content card bg-base-200 w-150 shadow-md z-[1100] ml-2 border-1 border-info"
|
||||||
|
>
|
||||||
|
<div className="card-body flex flex-row gap-4">
|
||||||
|
<div className="flex-1">
|
||||||
|
<h2 className="inline-flex items-center gap-2 text-lg font-bold mb-2">
|
||||||
|
<ListCollapse /> Einsatzliste
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="w-px bg-gray-400 mx-2" />
|
||||||
|
<div className="flex-1">
|
||||||
|
<h2 className="inline-flex items-center gap-2 text-lg font-bold mb-2">
|
||||||
|
<Plane /> Stations
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -4,6 +4,8 @@ import { dispatchSocket } from "dispatch/socket";
|
|||||||
import { pilotSocket } from "pilot/socket";
|
import { pilotSocket } from "pilot/socket";
|
||||||
|
|
||||||
interface ChatStore {
|
interface ChatStore {
|
||||||
|
situationTabOpen: boolean;
|
||||||
|
setSituationTabOpen: (open: boolean) => void;
|
||||||
reportTabOpen: boolean;
|
reportTabOpen: boolean;
|
||||||
setReportTabOpen: (open: boolean) => void;
|
setReportTabOpen: (open: boolean) => void;
|
||||||
ownId: null | string;
|
ownId: null | string;
|
||||||
@@ -12,10 +14,7 @@ interface ChatStore {
|
|||||||
setChatOpen: (open: boolean) => void;
|
setChatOpen: (open: boolean) => void;
|
||||||
setSelectedChat: (chatId: string | null) => void;
|
setSelectedChat: (chatId: string | null) => void;
|
||||||
setOwnId: (id: string) => void;
|
setOwnId: (id: string) => void;
|
||||||
chats: Record<
|
chats: Record<string, { name: string; notification: boolean; messages: ChatMessage[] }>;
|
||||||
string,
|
|
||||||
{ name: string; notification: boolean; messages: ChatMessage[] }
|
|
||||||
>;
|
|
||||||
setChatNotification: (userId: string, notification: boolean) => void;
|
setChatNotification: (userId: string, notification: boolean) => void;
|
||||||
sendMessage: (userId: string, message: string) => Promise<void>;
|
sendMessage: (userId: string, message: string) => Promise<void>;
|
||||||
addChat: (userId: string, name: string) => void;
|
addChat: (userId: string, name: string) => void;
|
||||||
@@ -23,6 +22,8 @@ interface ChatStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const useLeftMenuStore = create<ChatStore>((set, get) => ({
|
export const useLeftMenuStore = create<ChatStore>((set, get) => ({
|
||||||
|
situationTabOpen: false,
|
||||||
|
setSituationTabOpen: (open: boolean) => set({ situationTabOpen: open }),
|
||||||
reportTabOpen: false,
|
reportTabOpen: false,
|
||||||
setReportTabOpen: (open: boolean) => set({ reportTabOpen: open }),
|
setReportTabOpen: (open: boolean) => set({ reportTabOpen: open }),
|
||||||
ownId: null,
|
ownId: null,
|
||||||
@@ -34,17 +35,13 @@ export const useLeftMenuStore = create<ChatStore>((set, get) => ({
|
|||||||
chats: {},
|
chats: {},
|
||||||
sendMessage: (userId: string, message: string) => {
|
sendMessage: (userId: string, message: string) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
dispatchSocket.emit(
|
dispatchSocket.emit("send-message", { userId, message }, ({ error }: { error?: string }) => {
|
||||||
"send-message",
|
|
||||||
{ userId, message },
|
|
||||||
({ error }: { error?: string }) => {
|
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
addChat: (userId, name) => {
|
addChat: (userId, name) => {
|
||||||
@@ -87,8 +84,7 @@ export const useLeftMenuStore = create<ChatStore>((set, get) => ({
|
|||||||
[userId]: {
|
[userId]: {
|
||||||
...user,
|
...user,
|
||||||
name: isSender ? message.receiverName : message.senderName,
|
name: isSender ? message.receiverName : message.senderName,
|
||||||
notification:
|
notification: !isSender && (state.selectedChat !== userId || !state.chatOpen),
|
||||||
!isSender && (state.selectedChat !== userId || !state.chatOpen),
|
|
||||||
messages: [...user.messages, message], // Neuen Zustand erzeugen
|
messages: [...user.messages, message], // Neuen Zustand erzeugen
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -106,12 +102,9 @@ dispatchSocket.on(
|
|||||||
store.addMessage(userId, message);
|
store.addMessage(userId, message);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
pilotSocket.on(
|
pilotSocket.on("chat-message", ({ userId, message }: { userId: string; message: ChatMessage }) => {
|
||||||
"chat-message",
|
|
||||||
({ userId, message }: { userId: string; message: ChatMessage }) => {
|
|
||||||
const store = useLeftMenuStore.getState();
|
const store = useLeftMenuStore.getState();
|
||||||
console.log("chat-message", userId, message);
|
console.log("chat-message", userId, message);
|
||||||
// Update the chat store with the new message
|
// Update the chat store with the new message
|
||||||
store.addMessage(userId, message);
|
store.addMessage(userId, message);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { cn } from "_helpers/cn";
|
|||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { Chat } from "../_components/left/Chat";
|
import { Chat } from "../_components/left/Chat";
|
||||||
import { Report } from "../_components/left/Report";
|
import { Report } from "../_components/left/Report";
|
||||||
|
import { SituationBoard } from "_components/left/SituationBoard";
|
||||||
const Map = dynamic(() => import("../_components/map/Map"), { ssr: false });
|
const Map = dynamic(() => import("../_components/map/Map"), { ssr: false });
|
||||||
|
|
||||||
const DispatchPage = () => {
|
const DispatchPage = () => {
|
||||||
@@ -20,6 +21,11 @@ const DispatchPage = () => {
|
|||||||
<Report />
|
<Report />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<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">
|
||||||
|
<SituationBoard />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Map />
|
<Map />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user