"use client";
import { useQuery } from "@tanstack/react-query";
import { Spinner } from "@heroui/react";
import { TagDollar, ChartLine } from "@gravity-ui/icons";
import { api, type PriceTier, type TariffConfig, type TariffSlot } from "@/lib/api";
// ── Tier meta (matches admin pricing editor colors) ───────────────────────────
const TIER_META: Record<
PriceTier,
{ label: string; sublabel: string; cellBg: string; text: string; border: string; dot: string }
> = {
peak: {
label: "峰时",
sublabel: "高峰时段",
cellBg: "bg-orange-500/70",
text: "text-orange-500",
border: "border-orange-500/40",
dot: "bg-orange-500",
},
flat: {
label: "平时",
sublabel: "肩峰时段",
cellBg: "bg-neutral-400/45",
text: "text-neutral-400",
border: "border-neutral-400/40",
dot: "bg-neutral-400",
},
valley: {
label: "谷时",
sublabel: "低谷时段",
cellBg: "bg-blue-500/65",
text: "text-blue-500",
border: "border-blue-500/40",
dot: "bg-blue-500",
},
};
// ── Slot cards ────────────────────────────────────────────────────────────────
function SlotCards({ tariff }: { tariff: TariffConfig }) {
const sorted = [...tariff.slots].sort((a, b) => a.start - b.start);
return (
{sorted.map((slot: TariffSlot, i) => {
const meta = TIER_META[slot.tier];
const p = tariff.prices[slot.tier];
const total = p.electricityPrice + p.serviceFee;
return (
{/* Header */}
{meta.label}
{meta.sublabel}
{String(slot.start).padStart(2, "0")}:00 – {String(slot.end).padStart(2, "0")}:00
{/* Prices */}
电费
¥{p.electricityPrice.toFixed(4)}
/kWh
服务费
¥{p.serviceFee.toFixed(4)}
/kWh
单价
¥{total.toFixed(4)}
/kWh
);
})}
);
}
// ── Page ─────────────────────────────────────────────────────────────────────
export default function PricingPage() {
const {
data: tariff,
isLoading,
isError,
} = useQuery({
queryKey: ["tariff"],
queryFn: () => api.tariff.get(),
});
return (
{/* Header */}
{isLoading && (
)}
{isError && (
电价信息加载失败,请刷新页面重试。
)}
{!isLoading && !isError && !tariff && (
尚未配置峰谷电价
各充电桩使用独立固定电价,请查看充电桩详情页了解具体费率。
)}
{tariff && (
<>
{/* Timeline + legend */}
24 小时时段分布
实际扣费以交易完成时系统计算为准
{/* Tick labels */}
{[0, 6, 12, 18, 24].map((h) => (
0 ? "translateX(-50%)" : undefined,
}}
>
{String(h).padStart(2, "0")}:00
))}
{/* Colored bar */}
{(() => {
const hourTier: PriceTier[] = Array(24).fill("flat" as PriceTier);
for (const slot of tariff.slots) {
for (let h = slot.start; h < slot.end; h++) hourTier[h] = slot.tier;
}
return hourTier.map((tier, h) => (
{String(h).padStart(2, "0")}
));
})()}
{/* Legend */}
{(["peak", "flat", "valley"] as PriceTier[]).map((tier) => {
const meta = TIER_META[tier];
const hours = tariff.slots
.filter((s) => s.tier === tier)
.reduce((acc, s) => acc + (s.end - s.start), 0);
const total =
tariff.prices[tier].electricityPrice + tariff.prices[tier].serviceFee;
return (
{meta.label}
{hours}h · ¥{total.toFixed(4)}/kWh
);
})}
{/* Slot cards */}
各时段费率
合计费率 = 电费 + 服务费。实际扣费以交易完成时系统计算为准。
>
)}
);
}