- Miuix day/night dual theme CSS variables - themeStore: light default, follows prefers-color-scheme - Header: sun/moon toggle button - All components migrated to CSS variables - Cyrene avatar image replaces 'C' logo everywhere - Favicon added
60 lines
3.0 KiB
TypeScript
60 lines
3.0 KiB
TypeScript
import { useEffect, useState } from 'react'
|
|
import type { IotDevice } from '../../types/chat'
|
|
|
|
const mockDevices: IotDevice[] = [
|
|
{ id: 'light-livingroom', name: '客厅灯', type: 'light', state: { power: false, brightness: 80 }, online: true },
|
|
{ id: 'light-bedroom', name: '卧室灯', type: 'light', state: { power: false, brightness: 60 }, online: true },
|
|
{ id: 'ac-livingroom', name: '客厅空调', type: 'ac', state: { power: false, temperature: 26, mode: 'cool' }, online: true },
|
|
{ id: 'ac-bedroom', name: '卧室空调', type: 'ac', state: { power: false, temperature: 25, mode: 'heat' }, online: true },
|
|
{ id: 'curtain-livingroom', name: '客厅窗帘', type: 'curtain', state: { power: false, position: 0 }, online: true },
|
|
{ id: 'sensor-temperature', name: '温度传感器', type: 'sensor', state: { temperature: 25.0 }, online: true },
|
|
{ id: 'sensor-humidity', name: '湿度传感器', type: 'sensor', state: { humidity: 55.0 }, online: true },
|
|
{ id: 'lock-door', name: '智能门锁', type: 'lock', state: { locked: true, battery: 85 }, online: true },
|
|
]
|
|
|
|
export default function IoTManagementPage() {
|
|
const [devices, setDevices] = useState<IotDevice[]>(mockDevices)
|
|
|
|
const toggle = (id: string) => {
|
|
setDevices(prev => prev.map(d => {
|
|
if (d.id !== id) return d
|
|
const newState = { ...d.state, power: !(d.state.power as boolean) }
|
|
return { ...d, state: newState }
|
|
}))
|
|
}
|
|
|
|
return (
|
|
<div className="p-6 space-y-4">
|
|
<h2 className="text-lg font-semibold">IoT 设备管理</h2>
|
|
<p className="text-xs text-[var(--mx-text-dim)]">8 个模拟智能家居设备(测试环境)</p>
|
|
|
|
<div className="space-y-2">
|
|
{devices.map(d => {
|
|
const isOn = d.type !== 'sensor' && d.state.power === true
|
|
return (
|
|
<div key={d.id} className="bg-[var(--mx-surface)] border border-[var(--mx-outline)] rounded-[18px] px-4 py-3 flex items-center justify-between">
|
|
<div>
|
|
<p className="text-sm text-[var(--mx-text)]">{d.name}</p>
|
|
<p className="text-xs text-[var(--mx-text-dim)]">
|
|
{d.type === 'light' && `亮度: ${d.state.brightness}%`}
|
|
{d.type === 'ac' && `${d.state.temperature}°C ${d.state.mode}`}
|
|
{d.type === 'curtain' && `位置: ${d.state.position}%`}
|
|
{d.type === 'sensor' && `${JSON.stringify(d.state)}`}
|
|
{d.type === 'lock' && `电量: ${d.state.battery}%`}
|
|
</p>
|
|
</div>
|
|
{d.type !== 'sensor' && (
|
|
<button onClick={() => toggle(d.id)}
|
|
className={`w-12 h-7 rounded-full relative transition-colors ${isOn ? 'bg-[var(--mx-primary)]' : 'bg-[#404040]'}`}
|
|
>
|
|
<div className={`absolute top-0.5 w-6 h-6 rounded-full bg-white transition-transform ${isOn ? 'translate-x-6' : 'translate-x-0.5'}`} />
|
|
</button>
|
|
)}
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|