diff --git a/src/app/alert-settings/page.tsx b/src/app/alert-settings/page.tsx index 003bc5c..d848aab 100644 --- a/src/app/alert-settings/page.tsx +++ b/src/app/alert-settings/page.tsx @@ -1,5 +1,5 @@ "use client" -import { useEffect, useState, useCallback } from 'react' +import React, { useEffect, useState, useCallback, Suspense } from 'react' import { useSearchParams } from 'next/navigation' import { api, @@ -23,11 +23,11 @@ import { Check, Phone, MessageSquare, - Clock, Moon, Zap, Maximize2, - ArrowLeftRight + ArrowLeftRight, + LucideIcon } from 'lucide-react' import Loading from '@/components/Loading' @@ -36,7 +36,7 @@ type ComparisonType = 0 | 1 | 2 | 3 type NotificationType = 0 | 1 type TimeType = 0 | 1 | 2 -const SENSOR_TYPES: { value: SensorType; label: string; icon: any; unit: string }[] = [ +const SENSOR_TYPES: { value: SensorType; label: string; icon: LucideIcon; unit: string }[] = [ { value: 0, label: 'دما', icon: Thermometer, unit: '°C' }, { value: 1, label: 'رطوبت هوا', icon: Droplets, unit: '%' }, { value: 2, label: 'رطوبت خاک', icon: Leaf, unit: '%' }, @@ -44,25 +44,25 @@ const SENSOR_TYPES: { value: SensorType; label: string; icon: any; unit: string { value: 4, label: 'نور', icon: Sun, unit: 'Lux' } ] -const COMPARISON_TYPES: { value: ComparisonType; label: string; icon: any; needsMax: boolean }[] = [ +const COMPARISON_TYPES: { value: ComparisonType; label: string; icon: LucideIcon | (() => React.JSX.Element); needsMax: boolean }[] = [ { value: 0, label: 'بزرگتر از', icon: () => >, needsMax: false }, { value: 1, label: 'کوچکتر از', icon: () => <, needsMax: false }, { value: 2, label: 'بین', icon: ArrowLeftRight, needsMax: true }, { value: 3, label: 'خارج از محدوده', icon: Maximize2, needsMax: true } ] -const NOTIFICATION_TYPES: { value: NotificationType; label: string; icon: any }[] = [ +const NOTIFICATION_TYPES: { value: NotificationType; label: string; icon: LucideIcon }[] = [ { value: 0, label: 'تماس تلفنی', icon: Phone }, { value: 1, label: 'پیامک', icon: MessageSquare } ] -const TIME_TYPES: { value: TimeType; label: string; icon: any; description: string }[] = [ +const TIME_TYPES: { value: TimeType; label: string; icon: LucideIcon; description: string }[] = [ { value: 0, label: 'روز', icon: Sun, description: 'فقط در روز بررسی شود' }, { value: 1, label: 'شب', icon: Moon, description: 'فقط در شب بررسی شود' }, { value: 2, label: 'همیشه', icon: Zap, description: 'در هر زمان بررسی شود' } ] -export default function AlertSettingsPage() { +function AlertSettingsContent() { const searchParams = useSearchParams() const deviceId = Number(searchParams.get('deviceId') ?? '1') @@ -134,7 +134,7 @@ export default function AlertSettingsPage() { e.preventDefault() if (formData.rules.length === 0) { - alert('لطفاً حداقل یک قانون اضافه کنید') + window.alert('لطفاً حداقل یک قانون اضافه کنید') return } @@ -157,14 +157,14 @@ export default function AlertSettingsPage() { closeModal() } catch (error) { console.error('Error saving alert:', error) - alert('خطا در ذخیره هشدار. لطفاً دوباره تلاش کنید.') + window.alert('خطا در ذخیره هشدار. لطفاً دوباره تلاش کنید.') } finally { setSaving(false) } } const handleDelete = async (id: number) => { - if (!confirm('آیا از حذف این هشدار اطمینان دارید؟')) { + if (!window.confirm('آیا از حذف این هشدار اطمینان دارید؟')) { return } @@ -173,7 +173,7 @@ export default function AlertSettingsPage() { await loadAlerts() } catch (error) { console.error('Error deleting alert:', error) - alert('خطا در حذف هشدار. لطفاً دوباره تلاش کنید.') + window.alert('خطا در حذف هشدار. لطفاً دوباره تلاش کنید.') } } @@ -191,7 +191,7 @@ export default function AlertSettingsPage() { await loadAlerts() } catch (error) { console.error('Error toggling alert:', error) - alert('خطا در تغییر وضعیت هشدار.') + window.alert('خطا در تغییر وضعیت هشدار.') } } @@ -222,7 +222,7 @@ export default function AlertSettingsPage() { setFormData({ ...formData, rules: newRules }) } - const getSensorIcon = (type: SensorType) => { + const getSensorIcon = (type: SensorType): LucideIcon => { const sensor = SENSOR_TYPES.find(s => s.value === type) return sensor ? sensor.icon : AlertTriangle } @@ -724,3 +724,18 @@ export default function AlertSettingsPage() { ) } + +export default function AlertSettingsPage() { + return ( + +
+
+

در حال بارگذاری...

+
+ + }> + +
+ ) +} diff --git a/src/app/daily-report/page.tsx b/src/app/daily-report/page.tsx index 0583534..d607c51 100644 --- a/src/app/daily-report/page.tsx +++ b/src/app/daily-report/page.tsx @@ -1,5 +1,5 @@ "use client" -import { useEffect, useMemo, useState, useCallback } from 'react' +import { useEffect, useMemo, useState, useCallback, Suspense } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import { api, TelemetryDto, DailyReportDto } from '@/lib/api' import { persianToGregorian, getCurrentPersianDay, getCurrentPersianYear, getCurrentPersianMonth, getPreviousPersianDay, getNextPersianDay } from '@/lib/persian-date' @@ -22,7 +22,7 @@ import { DataGap } from '@/components/daily-report' -export default function DailyReportPage() { +function DailyReportContent() { const router = useRouter() const searchParams = useSearchParams() const [telemetry, setTelemetry] = useState([]) @@ -269,23 +269,23 @@ export default function DailyReportPage() { const gas = useMemo(() => sortedTelemetry.map(t => Number(t.gasPPM ?? 0)), [sortedTelemetry]) const lux = useMemo(() => sortedTelemetry.map(t => Number(t.lux ?? 0)), [sortedTelemetry]) - // Min/Max calculations - const tempMinMax = useMemo(() => { - const min = Math.min(...temp) - const max = Math.max(...temp) - return { - min: min < 0 ? Math.floor(min / 10) * 10 : 0, - max: max > 40 ? Math.floor(max / 10) * 10 : 40 - } - }, [temp]) + // Min/Max calculations (not currently used but kept for potential future use) + // const tempMinMax = useMemo(() => { + // const min = Math.min(...temp) + // const max = Math.max(...temp) + // return { + // min: min < 0 ? Math.floor(min / 10) * 10 : 0, + // max: max > 40 ? Math.floor(max / 10) * 10 : 40 + // } + // }, [temp]) - const luxMinMax = useMemo(() => { - const max = Math.max(...lux) - return { - min: 0, - max: max > 2000 ? Math.floor(max / 1000) * 1000 : 2000 - } - }, [lux]) + // const luxMinMax = useMemo(() => { + // const max = Math.max(...lux) + // return { + // min: 0, + // max: max > 2000 ? Math.floor(max / 1000) * 1000 : 2000 + // } + // }, [lux]) // Detect data gaps in the full day data const dataGaps = useMemo(() => { @@ -591,3 +591,18 @@ export default function DailyReportPage() { ) } + +export default function DailyReportPage() { + return ( + +
+
+

در حال بارگذاری گزارش...

+
+ + }> + +
+ ) +} diff --git a/src/app/day-details/page.tsx b/src/app/day-details/page.tsx index b755983..210b1c1 100644 --- a/src/app/day-details/page.tsx +++ b/src/app/day-details/page.tsx @@ -1,5 +1,5 @@ "use client" -import { useEffect, useState, useMemo } from 'react' +import { useEffect, useState, useMemo, Suspense } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import { api } from '@/lib/api' import { getCurrentPersianYear, getCurrentPersianMonth, getPersianMonthStartWeekday, getPersianMonthDays } from '@/lib/persian-date' @@ -9,7 +9,7 @@ import Loading from '@/components/Loading' const monthNames = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'] -export default function DayDetailsPage() { +function DayDetailsContent() { const router = useRouter() const searchParams = useSearchParams() const [items, setItems] = useState<{ persianDate: string; count: number }[]>([]) @@ -164,3 +164,18 @@ export default function DayDetailsPage() { ) } +export default function DayDetailsPage() { + return ( + +
+
+

در حال بارگذاری...

+
+ + }> + +
+ ) +} + diff --git a/src/components/Charts.tsx b/src/components/Charts.tsx index af1a074..a1c379b 100644 --- a/src/components/Charts.tsx +++ b/src/components/Charts.tsx @@ -50,10 +50,19 @@ export function Panel({ title, children }: { title: string; children: React.Reac ) } -export function LineChart({ labels, series, yAxisMin, yAxisMax, dataGaps = [] }: Props) { +export function LineChart({ labels, series, yAxisMin, yAxisMax }: Props) { // Find gap annotations based on null values in data const gapAnnotations = React.useMemo(() => { - const annotations: any = {} + const annotations: Record = {} let gapCount = 0 // Find nulls in the first series data @@ -84,7 +93,8 @@ export function LineChart({ labels, series, yAxisMin, yAxisMax, dataGaps = [] }: return annotations }, [series]) - // Calculate hour range and determine which hours to show + // Calculate hour range and determine which hours to show (not currently used but kept for potential future use) + // eslint-disable-next-line @typescript-eslint/no-unused-vars const hourConfig = React.useMemo(() => { const validLabels = labels.filter(l => l) if (validLabels.length === 0) { diff --git a/src/components/daily-report/TimeRangeSelector.tsx b/src/components/daily-report/TimeRangeSelector.tsx index 49661c2..442ab3d 100644 --- a/src/components/daily-report/TimeRangeSelector.tsx +++ b/src/components/daily-report/TimeRangeSelector.tsx @@ -1,4 +1,4 @@ -import { BarChart3, AlertTriangle } from 'lucide-react' +import { AlertTriangle } from 'lucide-react' import { toPersianDigits, DataGap } from './utils' type TimeRangeSelectorProps = { diff --git a/src/components/daily-report/WeatherTab.tsx b/src/components/daily-report/WeatherTab.tsx index 274495b..ffb45d9 100644 --- a/src/components/daily-report/WeatherTab.tsx +++ b/src/components/daily-report/WeatherTab.tsx @@ -337,7 +337,7 @@ export function WeatherTab({
- {weatherData.hourly.map((hour, index) => { + {weatherData.hourly.map((hour) => { const hourNum = new Date(hour.time).getHours() const isNow = hourNum === new Date().getHours() const IconComponent = getWeatherInfo(hour.weatherCode).icon diff --git a/src/components/daily-report/weather-helpers.ts b/src/components/daily-report/weather-helpers.ts index 1697cdd..1978938 100644 --- a/src/components/daily-report/weather-helpers.ts +++ b/src/components/daily-report/weather-helpers.ts @@ -1,4 +1,4 @@ -import { Thermometer, Sun, Droplets, Wind, Leaf, AlertTriangle } from 'lucide-react' +import { Thermometer, Sun, Droplets, Wind, Leaf } from 'lucide-react' import { WeatherData, GreenhouseAlert } from './types' import { toPersianDigits } from './utils'