Files
GreenHomeUI/src/components/daily-report/SummaryTab.tsx
alireza 3644d57206
Some checks failed
Deploy MyApp on Same Server / build-and-deploy (push) Failing after 1s
optimize
2025-12-20 01:50:14 +03:30

158 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useMemo, useState } from 'react'
import { SummaryCard } from './SummaryCard'
import { WeatherData } from '@/features/weather'
import { GreenhouseForecastAlerts, getForecastAlertsCount } from './GreenhouseForecastAlerts'
import { Dialog } from '@/components/common/Dialog'
import { WeatherAlertBanner } from '@/components/alerts'
import { Loader2 } from 'lucide-react'
type SummaryTabProps = {
temperature: number[]
humidity: number[]
soil: number[]
gas: number[]
lux: number[]
forecastWeather?: WeatherData | null
forecastWeatherLoading?: boolean
onCardClick?: (param: string) => void
}
export function SummaryTab({ temperature, humidity, soil, gas, lux, forecastWeather, forecastWeatherLoading = false, onCardClick }: SummaryTabProps) {
const [isAlertsDialogOpen, setIsAlertsDialogOpen] = useState(false)
const alertsCount = useMemo(() => {
return getForecastAlertsCount(forecastWeather ?? null)
}, [forecastWeather])
// Memoized summary statistics for each parameter
const temperatureSummary = useMemo(() => {
if (temperature.length === 0) return { current: 0, min: 0, max: 0 }
return {
current: temperature.at(-1) ?? 0,
min: Math.min(...temperature),
max: Math.max(...temperature),
}
}, [temperature])
const humiditySummary = useMemo(() => {
if (humidity.length === 0) return { current: 0, min: 0, max: 0 }
return {
current: humidity.at(-1) ?? 0,
min: Math.min(...humidity),
max: Math.max(...humidity),
}
}, [humidity])
const soilSummary = useMemo(() => {
if (soil.length === 0) return { current: 0, min: 0, max: 0 }
return {
current: soil.at(-1) ?? 0,
min: Math.min(...soil),
max: Math.max(...soil),
}
}, [soil])
const gasSummary = useMemo(() => {
if (gas.length === 0) return { current: 0, min: 0, max: 0 }
return {
current: gas.at(-1) ?? 0,
min: Math.min(...gas),
max: Math.max(...gas),
}
}, [gas])
const luxSummary = useMemo(() => {
if (lux.length === 0) return { current: 0, min: 0, max: 0 }
return {
current: lux.at(-1) ?? 0,
min: Math.min(...lux),
max: Math.max(...lux),
}
}, [lux])
return (
<>
{/* Greenhouse Forecast Alerts Section */}
{forecastWeatherLoading ? (
<div className="mb-6">
<div className="w-full p-4 bg-gradient-to-r from-amber-50 to-orange-50 border-2 border-amber-200 rounded-xl text-right flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-amber-500 rounded-lg flex items-center justify-center">
<Loader2 className="w-6 h-6 text-white animate-spin" />
</div>
<div>
<p className="font-semibold text-gray-800">
در حال بارگذاری هشدارهای آب و هوایی...
</p>
<p className="text-sm text-gray-600 mt-1">
لطفاً صبر کنید
</p>
</div>
</div>
</div>
</div>
) : alertsCount > 0 && forecastWeather ? (
<WeatherAlertBanner
alertsCount={alertsCount}
onClick={() => setIsAlertsDialogOpen(true)}
/>
) : null}
{/* Summary Cards Grid */}
<div className="grid gap-6 grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
<SummaryCard
param="temperature"
currentValue={temperatureSummary.current}
minValue={temperatureSummary.min}
maxValue={temperatureSummary.max}
data={temperature}
onClick={() => onCardClick?.('temperature')}
/>
<SummaryCard
param="humidity"
currentValue={humiditySummary.current}
minValue={humiditySummary.min}
maxValue={humiditySummary.max}
data={humidity}
onClick={() => onCardClick?.('humidity')}
/>
<SummaryCard
param="gas"
currentValue={gasSummary.current}
minValue={gasSummary.min}
maxValue={gasSummary.max}
data={gas}
onClick={() => onCardClick?.('gas')}
/>
<SummaryCard
param="soil"
currentValue={soilSummary.current}
minValue={soilSummary.min}
maxValue={soilSummary.max}
data={soil}
onClick={() => onCardClick?.('soil')}
/>
<SummaryCard
param="lux"
currentValue={luxSummary.current}
minValue={luxSummary.min}
maxValue={luxSummary.max}
data={lux}
onClick={() => onCardClick?.('lux')}
/>
</div>
{/* Alerts Dialog */}
{forecastWeather && (
<Dialog
isOpen={isAlertsDialogOpen}
onClose={() => setIsAlertsDialogOpen(false)}
title="هشدارهای پیش‌بینی آب و هوا"
>
<GreenhouseForecastAlerts weatherData={forecastWeather} />
</Dialog>
)}
</>
)
}