"use client"; import { useState } from "react"; import { Pencil } from "lucide-react"; type Asset = { id: string; code: string; qr_code?: string }; /** * The text on a vehicle's QR sticker. Double-click (or tap the pencil) to type it in; Enter * or leaving the box saves, Escape cancels, and an empty box clears it. Saves on its own — * it does not wait for the table's Edit mode, because it is one value, not a batch. */ export function QrTextCell({ asset, onSaved }: { asset: Asset; onSaved: (qr: string) => void }) { const [editing, setEditing] = useState(false); const [value, setValue] = useState(""); const [saving, setSaving] = useState(false); const [error, setError] = useState(""); function begin() { setValue(asset.qr_code || ""); setError(""); setEditing(true); } async function save() { if (saving) return; const next = value.trim(); if (next === (asset.qr_code || "")) { setEditing(false); return; } setSaving(true); setError(""); try { const res = await fetch(`/api/assets/${asset.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ qr_code: next }), }); const j = await res.json().catch(() => ({})); if (!res.ok || !j.ok) throw new Error(j.error || "Could not save"); onSaved(next); setEditing(false); } catch (e: any) { setError(e.message); } finally { setSaving(false); } } if (editing) { return (
setValue(e.target.value)} onBlur={save} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); save(); } if (e.key === "Escape") setEditing(false); }} className="w-full sm:w-44 min-h-[44px] px-2 rounded-md text-sm font-mono border border-[#30638E] bg-white dark:bg-white/10 focus:outline-none" /> {error &&

{error}

}
); } return (
{asset.qr_code || "—"}
); }