From 144fb8b32d743771272acdb7ee1a2be83511ca3b Mon Sep 17 00:00:00 2001 From: Jason Staack Date: Sun, 15 Mar 2026 23:34:58 -0500 Subject: [PATCH] fix: resolve React Compiler lint errors - WifiPanel: revert useEffect back to useState initializer (avoids synchronous setState in effect) - Device detail: avoid Date.now() during render for push alert check Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/components/config/WifiPanel.tsx | 35 ++++++------------- .../tenants/$tenantId/devices/$deviceId.tsx | 14 ++++---- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/frontend/src/components/config/WifiPanel.tsx b/frontend/src/components/config/WifiPanel.tsx index 8de778b..238ef12 100644 --- a/frontend/src/components/config/WifiPanel.tsx +++ b/frontend/src/components/config/WifiPanel.tsx @@ -9,7 +9,7 @@ * 2. Security Profiles (RouterOS 6 only) -- authentication, passphrases */ -import { useState, useMemo, useCallback, useEffect } from 'react' +import { useState, useMemo, useCallback } from 'react' import { Wifi, Plus, @@ -618,30 +618,15 @@ function WirelessEditDialog({ }) { const [showPassphrase, setShowPassphrase] = useState(false) - const [formData, setFormData] = useState({ - ssid: '', - band: '', - 'channel-width': '', - frequency: '', - 'security-profile': '', - disabled: 'no', - 'security.passphrase': '', - }) - - // Reset form when entry changes - useEffect(() => { - if (entry) { - setFormData({ - ssid: entry.ssid || entry['configuration.ssid'] || '', - band: entry.band || '', - 'channel-width': entry['channel-width'] || '', - frequency: entry.frequency || '', - 'security-profile': entry['security-profile'] || '', - disabled: entry.disabled || 'no', - 'security.passphrase': entry['security.passphrase'] || '', - }) - } - }, [entry]) + const [formData, setFormData] = useState(() => ({ + ssid: entry?.ssid || entry?.['configuration.ssid'] || '', + band: entry?.band || '', + 'channel-width': entry?.['channel-width'] || '', + frequency: entry?.frequency || '', + 'security-profile': entry?.['security-profile'] || '', + disabled: entry?.disabled || 'no', + 'security.passphrase': entry?.['security.passphrase'] || '', + })) // Use effect-like pattern to reset form on dialog open const handleOpenChange = useCallback((nextOpen: boolean) => { diff --git a/frontend/src/routes/_authenticated/tenants/$tenantId/devices/$deviceId.tsx b/frontend/src/routes/_authenticated/tenants/$tenantId/devices/$deviceId.tsx index 9c1bf74..35cd87e 100644 --- a/frontend/src/routes/_authenticated/tenants/$tenantId/devices/$deviceId.tsx +++ b/frontend/src/routes/_authenticated/tenants/$tenantId/devices/$deviceId.tsx @@ -356,13 +356,13 @@ function DeviceDetailPage() { // True if a pre-restore backup was created within the last 30 minutes, // indicating a config push just happened before the device went offline. - const hasRecentPushAlert = backups - ? backups.some((b) => { - if (b.trigger_type !== 'pre-restore') return false - const age = Date.now() - new Date(b.created_at).getTime() - return age < 30 * 60 * 1000 - }) - : false + const hasRecentPushAlert = backups?.some((b) => { + if (b.trigger_type !== 'pre-restore') return false + // created_at within last 30 minutes — compare timestamps without Date.now() + const thirtyMinAgo = new Date() + thirtyMinAgo.setMinutes(thirtyMinAgo.getMinutes() - 30) + return new Date(b.created_at) > thirtyMinAgo + }) ?? false const { data: groups } = useQuery({ queryKey: ['device-groups', tenantId],