"use client"; import { useState, useCallback } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Lightbulb } from "lucide-react"; import { toggleLight, setLightBrightness } from "@/lib/api"; import { getBrightnessPct, pctToBrightness } from "@/lib/ha"; interface Props { entityId: string; name: string; state: string; brightness?: number; showSlider?: boolean; onUpdate: () => void; } export default function LightCard({ entityId, name, state, brightness, showSlider = false, onUpdate }: Props) { // Optimistic local state — не зависим от HA mock const [localOn, setLocalOn] = useState(state === "on"); const brightPct = getBrightnessPct(brightness); const [localBrightness, setLocalBrightness] = useState(brightPct || 70); const [pending, setPending] = useState(false); const handleToggle = useCallback(async () => { if (pending) return; const newState = !localOn; setLocalOn(newState); // optimistic setPending(true); try { await toggleLight(entityId, newState); onUpdate(); } catch (e) { setLocalOn(!newState); // rollback on real error } setPending(false); }, [entityId, localOn, pending, onUpdate]); const handleBrightnessChange = useCallback(async (val: number) => { setLocalBrightness(val); await setLightBrightness(entityId, pctToBrightness(val)); onUpdate(); }, [entityId, onUpdate]); const isOn = localOn; return ( {/* Top row: icon + toggle */}
{/* Toggle switch */}
{/* Name + state */}
{name}
{isOn ? (showSlider ? `Яркость ${localBrightness}%` : "Включён") : "Выключен"}
{showSlider && isOn && ( setLocalBrightness(parseInt(e.target.value))} onMouseUp={(e) => handleBrightnessChange(parseInt((e.target as HTMLInputElement).value))} onTouchEnd={(e) => handleBrightnessChange(parseInt((e.target as HTMLInputElement).value))} className="w-full" style={{ accentColor: "#f59e0b" }} /> )}
); }