|
@@ -1,5 +1,9 @@
|
|
import { useState } from "react";
|
|
import { useState } from "react";
|
|
|
|
+import { Bell, Expand, Minus, Square, X } from "lucide-react";
|
|
import "./index.scss";
|
|
import "./index.scss";
|
|
|
|
+import MessageModal from "@/components/MessageModal/MessageModal";
|
|
|
|
+import { useNotificationStore } from "@/store/NotificationStore";
|
|
|
|
+import useWebSocket from "@/hooks/useWebSocket";
|
|
|
|
|
|
interface optType {
|
|
interface optType {
|
|
maxStatus?: string; // 最大化
|
|
maxStatus?: string; // 最大化
|
|
@@ -7,7 +11,10 @@ interface optType {
|
|
|
|
|
|
// 顶部栏
|
|
// 顶部栏
|
|
const LayoutHeader = (props) => {
|
|
const LayoutHeader = (props) => {
|
|
|
|
+ const { socket } = useWebSocket("ws://localhost:8080");
|
|
const [opt, setOpt] = useState<optType>({});
|
|
const [opt, setOpt] = useState<optType>({});
|
|
|
|
+ const [messageModalVisible, setMessageModalVisible] = useState(false);
|
|
|
|
+ const { notifications } = useNotificationStore();
|
|
|
|
|
|
// 操作点击
|
|
// 操作点击
|
|
const handleTitleClick = async (event, type: string) => {
|
|
const handleTitleClick = async (event, type: string) => {
|
|
@@ -30,23 +37,49 @@ const LayoutHeader = (props) => {
|
|
<header className="header bg-[#ffffff]">
|
|
<header className="header bg-[#ffffff]">
|
|
<div className="content flex">
|
|
<div className="content flex">
|
|
<div className="header-menu flex-1 h-full"></div>
|
|
<div className="header-menu flex-1 h-full"></div>
|
|
- <div className="opt flex items-center">
|
|
|
|
- <i
|
|
|
|
- className="iconfont icon-jianhao icon"
|
|
|
|
|
|
+ <div className="opt flex items-center py-2 px-6">
|
|
|
|
+ <div
|
|
|
|
+ onClick={() => setMessageModalVisible(true)}
|
|
|
|
+ className="relative cursor-pointer p-2 hover:bg-gray-100 rounded-lg"
|
|
|
|
+ >
|
|
|
|
+ <Bell className="text-gray-600 hover:bg-gray-5002" size={16} />
|
|
|
|
+ {!!notifications.length && (
|
|
|
|
+ <span className="absolute top-0 right-0 w-4 h-4 flex justify-center items-center text-xs bg-red-500 text-white rounded-full">
|
|
|
|
+ {notifications.length}
|
|
|
|
+ </span>
|
|
|
|
+ )}
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ className="cursor-pointer p-2 hover:bg-gray-100 rounded-lg"
|
|
|
|
+ onClick={(event) => handleTitleClick(event, "middle")}
|
|
|
|
+ >
|
|
|
|
+ <Expand className="text-gray-600 hover:bg-gray-5002" size={16} />
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ className="cursor-pointer p-2 hover:bg-gray-100 rounded-lg"
|
|
onClick={(event) => handleTitleClick(event, "min")}
|
|
onClick={(event) => handleTitleClick(event, "min")}
|
|
- ></i>
|
|
|
|
- <i
|
|
|
|
- className={`iconfont ${
|
|
|
|
- opt.maxStatus == "max" ? "icon-suoxiao" : "icon-24gl-square"
|
|
|
|
- } icon-24gl-square icon`}
|
|
|
|
|
|
+ >
|
|
|
|
+ <Minus className="cursor-pointer text-gray-600" size={16} />
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ className="cursor-pointer p-2 hover:bg-gray-100 rounded-lg"
|
|
onClick={(event) => handleTitleClick(event, "max")}
|
|
onClick={(event) => handleTitleClick(event, "max")}
|
|
- ></i>
|
|
|
|
- <i
|
|
|
|
- className="iconfont icon-chacha icon"
|
|
|
|
|
|
+ >
|
|
|
|
+ <Square className="cursor-pointer text-gray-600" size={16} />
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ className="cursor-pointer p-2 hover:bg-gray-100 rounded-lg"
|
|
onClick={(event) => handleTitleClick(event, "close")}
|
|
onClick={(event) => handleTitleClick(event, "close")}
|
|
- ></i>
|
|
|
|
|
|
+ >
|
|
|
|
+ <X className="cursor-pointer text-gray-600 " size={16} />
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
+ <MessageModal
|
|
|
|
+ visible={messageModalVisible}
|
|
|
|
+ onClose={() => setMessageModalVisible(false)}
|
|
|
|
+ socket={socket}
|
|
|
|
+ />
|
|
</header>
|
|
</header>
|
|
);
|
|
);
|
|
};
|
|
};
|