/**
* 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.
)}
)
}