/** * TibberPrices — price curve visualization. * * - Fetches today + tomorrow price range using useEnergyPrices. * - For tibber kind: Recharts LineChart showing buy/sell prices over time. * - For manual kind: shows tariff table (buy_dal, buy_normal, sell_dal, sell_normal). * - Handles: no active contract, empty data, loading, error. * * Recharts imports are isolated to this file only. */ import { Stack, Text, Loader, Center, Alert, Table, Title, Badge, Group, Paper, } from '@mantine/core' import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, } from 'recharts' import { useEnergyPrices } from './hooks' import { formatLocalTime } from '../utils/datetime' // --------------------------------------------------------------------------- // Time range helpers // --------------------------------------------------------------------------- function getTodayStart(): string { const d = new Date() d.setUTCHours(0, 0, 0, 0) return d.toISOString() } function getTomorrowEnd(): string { const d = new Date() d.setUTCHours(0, 0, 0, 0) d.setUTCDate(d.getUTCDate() + 2) return d.toISOString() } // --------------------------------------------------------------------------- // Tibber chart // --------------------------------------------------------------------------- interface TibberChartProps { points: Array<{ starts_at: string; buy: number; sell: number; level?: string | null }> currency: string } function TibberChart({ points, currency }: TibberChartProps) { const data = points.map((p) => ({ time: formatLocalTime(p.starts_at), buy: p.buy, sell: p.sell, })) return ( Price curve ({currency}) v.toFixed(3)} /> [`${typeof val === 'number' ? val.toFixed(4) : String(val)} ${currency}`, undefined] } /> ) } // --------------------------------------------------------------------------- // Manual tariff table // --------------------------------------------------------------------------- interface ManualTariffTableProps { tariff: { buy_dal: number buy_normal: number sell_dal: number sell_normal: number } currency: string } function ManualTariffTable({ tariff, currency }: ManualTariffTableProps) { return ( Fixed tariff ({currency}/kWh) Tariff Buy Sell Normal (peak) {tariff.buy_normal.toFixed(4)} {tariff.sell_normal.toFixed(4)} Dal (off-peak) {tariff.buy_dal.toFixed(4)} {tariff.sell_dal.toFixed(4)}
) } // --------------------------------------------------------------------------- // TibberPrices — main component // --------------------------------------------------------------------------- export function TibberPrices() { const start = getTodayStart() const end = getTomorrowEnd() const { data, isLoading, isError } = useEnergyPrices(start, end) if (isLoading) { return (
) } if (isError) { return ( Failed to load energy prices. Please refresh. ) } if (!data) { return ( No pricing data available. ) } // No active contract if (!data.kind) { return ( No active contract Activate an energy contract on the Contracts tab to see pricing data. ) } const currency = data.currency return ( Energy Prices {data.kind} {currency} {data.kind === 'tibber' && data.points && data.points.length > 0 && ( )} {data.kind === 'tibber' && (!data.points || data.points.length === 0) && ( No Tibber price points available for the selected time range. Check Tibber configuration. )} {data.kind === 'manual' && data.tariff && ( )} {data.kind === 'manual' && !data.tariff && ( Manual tariff data not available. )} ) }