Compare commits

..

2 Commits

Author SHA1 Message Date
c9aeca0ed9 feat(wsClient): implement WebSocket client with reconnecting functionality 2026-01-27 12:16:09 +07:00
Tran Anh Tuan
fea9cca865 chore(iconfont): update iconfont url 2026-01-27 10:48:31 +07:00
5 changed files with 32 additions and 10 deletions

View File

@@ -86,7 +86,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
contentWidth: 'Fluid', contentWidth: 'Fluid',
navTheme: isDark ? 'realDark' : 'light', navTheme: isDark ? 'realDark' : 'light',
splitMenus: true, splitMenus: true,
iconfontUrl: '//at.alicdn.com/t/c/font_5096559_84vdbef39dp.js', iconfontUrl: '//at.alicdn.com/t/c/font_5096559_pwy498d2aw.js',
contentStyle: { contentStyle: {
padding: 0, padding: 0,
margin: 0, margin: 0,

View File

@@ -1,7 +1,7 @@
import { createFromIconfontCN } from '@ant-design/icons'; import { createFromIconfontCN } from '@ant-design/icons';
const IconFont = createFromIconfontCN({ const IconFont = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/c/font_5096559_84vdbef39dp.js', scriptUrl: '//at.alicdn.com/t/c/font_5096559_pwy498d2aw.js',
}); });
export default IconFont; export default IconFont;

View File

@@ -1,5 +1,5 @@
import { SHIP_SOS_WS_URL } from '@/constants/slave/sgw/websocket'; import { SHIP_SOS_WS_URL } from '@/constants/slave/sgw/websocket';
import { wsClient } from '@/utils/slave/sgw/wsClient'; import { wsClient } from '@/utils/wsClient';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
export default function useGetShipSos() { export default function useGetShipSos() {

View File

@@ -1,4 +1,5 @@
import { apiSearchThings } from '@/services/master/ThingController'; import { apiSearchThings } from '@/services/master/ThingController';
import { wsClient } from '@/utils/wsClient';
import { import {
ArrowLeftOutlined, ArrowLeftOutlined,
DeleteOutlined, DeleteOutlined,
@@ -23,6 +24,7 @@ import {
Space, Space,
Spin, Spin,
Table, Table,
theme,
Typography, Typography,
} from 'antd'; } from 'antd';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
@@ -95,6 +97,7 @@ interface CameraFormValues {
const CameraConfigPage = () => { const CameraConfigPage = () => {
const { thingId } = useParams<{ thingId: string }>(); const { thingId } = useParams<{ thingId: string }>();
const { token } = theme.useToken();
const [form] = Form.useForm<CameraFormValues>(); const [form] = Form.useForm<CameraFormValues>();
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [cameras, setCameras] = useState<Camera[]>([]); const [cameras, setCameras] = useState<Camera[]>([]);
@@ -107,6 +110,16 @@ const CameraConfigPage = () => {
const [thingName, setThingName] = useState<string>(''); const [thingName, setThingName] = useState<string>('');
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
useEffect(() => {
wsClient.connect('wss://gms.smatec.com.vn/mqtt', false);
const unsubscribe = wsClient.subscribe((data: any) => {
console.log('Received WS data:', data);
});
return () => {
unsubscribe();
};
}, []);
// Fetch thing info on mount // Fetch thing info on mount
useEffect(() => { useEffect(() => {
const fetchThingInfo = async () => { const fetchThingInfo = async () => {
@@ -202,7 +215,9 @@ const CameraConfigPage = () => {
title: 'Tên', title: 'Tên',
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
render: (text: string) => <a style={{ color: '#1890ff' }}>{text}</a>, render: (text: string) => (
<a style={{ color: token.colorPrimary }}>{text}</a>
),
}, },
{ {
title: 'Loại', title: 'Loại',
@@ -298,8 +313,9 @@ const CameraConfigPage = () => {
alignItems: 'center', alignItems: 'center',
marginBottom: 16, marginBottom: 16,
padding: '8px 12px', padding: '8px 12px',
background: '#f5f5f5', background: token.colorBgContainer,
borderRadius: 4, borderRadius: token.borderRadius,
border: `1px solid ${token.colorBorder}`,
}} }}
> >
<Text type="secondary"> <Text type="secondary">
@@ -322,9 +338,13 @@ const CameraConfigPage = () => {
onClick={() => handleAlertToggle(alert.id)} onClick={() => handleAlertToggle(alert.id)}
style={{ style={{
cursor: 'pointer', cursor: 'pointer',
borderColor: isSelected ? '#1890ff' : '#d9d9d9', borderColor: isSelected
? token.colorPrimary
: token.colorBorder,
borderWidth: isSelected ? 2 : 1, borderWidth: isSelected ? 2 : 1,
background: isSelected ? '#e6f7ff' : '#fff', background: isSelected
? token.colorPrimaryBg
: token.colorBgContainer,
height: 80, height: 80,
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
@@ -339,7 +359,9 @@ const CameraConfigPage = () => {
<Text <Text
style={{ style={{
fontSize: 12, fontSize: 12,
color: isSelected ? '#1890ff' : 'inherit', color: isSelected
? token.colorPrimary
: token.colorText,
wordBreak: 'break-word', wordBreak: 'break-word',
}} }}
> >

View File

@@ -1,5 +1,5 @@
import ReconnectingWebSocket from 'reconnecting-websocket'; import ReconnectingWebSocket from 'reconnecting-websocket';
import { getToken } from '../../storage'; import { getToken } from './storage';
type MessageHandler = (data: any) => void; type MessageHandler = (data: any) => void;