Files
SMATEC-FRONTEND/src/pages/Manager/Device/Detail/components/BinarySensors.tsx

167 lines
4.6 KiB
TypeScript

import IconFont from '@/components/IconFont';
import { StatisticCard } from '@ant-design/pro-components';
import {
Divider,
Flex,
GlobalToken,
Grid,
theme,
Tooltip,
Typography,
} from 'antd';
const { Text } = Typography;
type BinarySensorsProps = {
nodeConfigs: MasterModel.NodeConfig[];
};
export const getBinaryEntities = (
nodeConfigs: MasterModel.NodeConfig[] = [],
): MasterModel.Entity[] =>
nodeConfigs.flatMap((nodeConfig) =>
nodeConfig.type === 'din'
? nodeConfig.entities.filter(
(entity) => entity.type === 'bin' && entity.active === 1,
)
: [],
);
interface IconTypeResult {
iconType: string;
color: string;
name?: string;
}
const getIconTypeByEntity = (
entity: MasterModel.Entity,
token: GlobalToken,
): IconTypeResult => {
if (!entity.config || entity.config.length === 0) {
return {
iconType: 'icon-not-found',
color: token.colorPrimary,
};
}
switch (entity.config[0].subType) {
case 'smoke':
return {
iconType: 'icon-smoke1',
color: entity.value === 0 ? token.colorSuccess : token.colorWarning,
name: entity.value === 0 ? 'Bình thường' : 'Phát hiện',
};
case 'heat':
return {
iconType: 'icon-fire',
color: entity.value === 0 ? token.colorSuccess : token.colorWarning,
name: entity.value === 0 ? 'Bình thường' : 'Phát hiện',
};
case 'motion':
return {
iconType: 'icon-motion',
color: entity.value === 0 ? token.colorTextBase : token.colorInfoActive,
name: entity.value === 0 ? 'Không' : 'Phát hiện',
};
case 'flood':
return {
iconType: 'icon-water-ingress',
color: entity.value === 0 ? token.colorSuccess : token.colorWarning,
name: entity.value === 0 ? 'Không' : 'Phát hiện',
};
case 'door':
return {
iconType: entity.value === 0 ? 'icon-door' : 'icon-door-open1',
color: entity.value === 0 ? token.colorText : token.colorWarning,
name: entity.value === 0 ? 'Đóng' : 'Mở',
};
case 'button':
return {
iconType: 'icon-alarm-button',
color: entity.value === 0 ? token.colorText : token.colorSuccess,
name: entity.value === 0 ? 'Tắt' : 'Bật',
};
default:
return {
iconType: 'icon-not-found',
color: token.colorPrimary,
};
}
};
const StatisticCardItem = (entity: MasterModel.Entity, token: GlobalToken) => {
const { iconType, color, name } = getIconTypeByEntity(entity, token);
return (
<StatisticCard
bordered={false}
key={entity.entityId}
style={{
borderRadius: 8,
background: token.colorBgContainer,
border: `1px solid ${token.colorBorder}`,
transition: 'all 0.3s ease',
}}
onMouseEnter={(e) => {
const el = e.currentTarget as HTMLElement;
el.style.boxShadow = `0 4px 12px ${token.colorPrimary}20`;
el.style.transform = 'translateY(-2px)';
}}
onMouseLeave={(e) => {
const el = e.currentTarget as HTMLElement;
el.style.boxShadow = 'none';
el.style.transform = 'translateY(0)';
}}
statistic={{
icon: (
<Tooltip title={entity.name}>
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: 56,
marginBottom: 8,
}}
>
<IconFont type={iconType} style={{ color, fontSize: 32 }} />
</div>
</Tooltip>
),
title: (
<Text
ellipsis={{ tooltip: entity.name }}
style={{ fontSize: 13, fontWeight: 500 }}
>
{entity.name}
</Text>
),
value: name,
valueStyle: { fontSize: 12, color, fontWeight: 600, marginTop: 8 },
}}
/>
);
};
const BinarySensors = ({ nodeConfigs }: BinarySensorsProps) => {
const binarySensors = getBinaryEntities(nodeConfigs);
console.log('BinarySensor: ', binarySensors);
const { token } = theme.useToken();
const { useBreakpoint } = Grid;
const screens = useBreakpoint();
return (
<Flex wrap="wrap" gap="middle">
<Divider orientation="left">Cảm biến</Divider>
{binarySensors.map((entity) => (
<div
key={entity.entityId}
style={{
width: 'fit-content',
}}
>
{StatisticCardItem(entity, token)}
</div>
))}
</Flex>
);
};
export default BinarySensors;