Some more UI changes. Also added device issue indicator

This commit is contained in:
2026-02-19 06:59:26 +02:00
parent f09979c653
commit 88bf06df35
5 changed files with 36 additions and 15 deletions

View File

@@ -367,6 +367,8 @@ export default function DeviceDetail() {
const [savingNotes, setSavingNotes] = useState(false);
const notesRef = useRef(null);
const [usersLoading, setUsersLoading] = useState(false);
const [unresolvedIssues, setUnresolvedIssues] = useState(0);
const notesPanelRef = useRef(null);
useEffect(() => {
loadData();
@@ -396,6 +398,14 @@ export default function DeviceDetail() {
setDeviceUsers([]);
}).finally(() => setUsersLoading(false));
// Load unresolved issues count
api.get(`/equipment/notes?device_id=${id}`).then((data) => {
const issues = (data.notes || []).filter(
(n) => (n.category === "issue" || n.category === "action_item") && n.status !== "completed"
);
setUnresolvedIssues(issues.length);
}).catch(() => setUnresolvedIssues(0));
// Reverse geocode
const coords = parseCoordinates(d.device_location_coordinates);
if (coords) {
@@ -944,7 +954,7 @@ export default function DeviceDetail() {
</SectionCard>
);
const notesSection = <NotesPanel deviceId={id} />;
const notesSection = <div ref={notesPanelRef}><NotesPanel deviceId={id} /></div>;
const logsSection = <DeviceLogsPanel deviceSerial={device.device_id} />;
// ===== Layout rendering =====
@@ -1021,10 +1031,11 @@ export default function DeviceDetail() {
<button onClick={() => navigate("/devices")} className="text-sm hover:underline mb-2 inline-block" style={{ color: "var(--accent)" }}>
&larr; Back to Devices
</button>
<div className="flex items-center gap-3">
<div className="flex items-center gap-4">
<h1 className="text-2xl font-bold" style={{ color: "var(--text-heading)" }}>
{device.device_name || "Unnamed Device"}
</h1>
<div style={{ width: 1, height: 24, backgroundColor: "var(--border-primary)" }} />
<div style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}>
<span
className="w-3 h-3 rounded-full inline-block"
@@ -1039,6 +1050,19 @@ export default function DeviceDetail() {
)}
</span>
</div>
{unresolvedIssues > 0 && (
<>
<div style={{ width: 1, height: 24, backgroundColor: "var(--border-primary)" }} />
<button
onClick={() => notesPanelRef.current?.scrollIntoView({ behavior: "smooth", block: "start" })}
className="flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-md cursor-pointer hover:opacity-80 transition-opacity"
style={{ backgroundColor: "var(--danger-bg)", color: "var(--danger-text)", border: "none" }}
>
<span style={{ fontSize: "0.85rem", lineHeight: 1 }}></span>
{unresolvedIssues} Issue{unresolvedIssues !== 1 ? "s" : ""} Unresolved
</button>
</>
)}
</div>
</div>
{canEdit && (

View File

@@ -201,7 +201,7 @@ export default function NotesPanel({ deviceId, userId }) {
{note.title}
</span>
</div>
<p className="text-xs truncate" style={{ color: "var(--text-muted)" }}>{note.content}</p>
<p className="text-xs" style={{ color: "var(--text-muted)", display: "-webkit-box", WebkitLineClamp: 3, WebkitBoxOrient: "vertical", overflow: "hidden" }}>{note.content}</p>
<p className="text-xs mt-1" style={{ color: "var(--text-muted)" }}>
{note.created_by && `${note.created_by} · `}{note.created_at}
</p>
@@ -256,7 +256,7 @@ export default function NotesPanel({ deviceId, userId }) {
{msg.subject || "No subject"}
</span>
</div>
<p className="text-xs truncate" style={{ color: "var(--text-muted)" }}>{msg.message}</p>
<p className="text-xs" style={{ color: "var(--text-muted)", display: "-webkit-box", WebkitLineClamp: 3, WebkitBoxOrient: "vertical", overflow: "hidden" }}>{msg.message}</p>
<p className="text-xs mt-1" style={{ color: "var(--text-muted)" }}>
{msg.sender_name && `${msg.sender_name} · `}{msg.phone && `${msg.phone} · `}{msg.date_sent}
</p>
@@ -269,7 +269,7 @@ export default function NotesPanel({ deviceId, userId }) {
return (
<section
className="rounded-lg border p-6"
style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)" }}
style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)", minWidth: 0, overflow: "hidden" }}
>
<div className="flex items-center justify-between mb-3">
<h2 className="text-lg font-semibold" style={{ color: "var(--text-heading)" }}>

View File

@@ -12,7 +12,7 @@ export default function Header() {
}}
>
<h2 className="text-lg font-semibold" style={{ color: "var(--text-heading)" }}>
Admin Panel
BellSystems - Control Panel
</h2>
<div className="flex items-center gap-4">

View File

@@ -225,8 +225,8 @@ export default function MelodyDetail() {
<Field label="Tone">
<span className="capitalize">{info.melodyTone}</span>
</Field>
<Field label="Total Active Notes (bells)">{info.totalNotes}</Field>
<Field label="Steps">{info.steps}</Field>
<Field label="Total Active Notes (bells)">{info.totalNotes}</Field>
<Field label="Min Speed">{info.minSpeed}</Field>
<Field label="Max Speed">{info.maxSpeed}</Field>
<Field label="Color">

View File

@@ -309,14 +309,14 @@ export default function UserDetail() {
</div>
{/* Fields */}
<dl className="grid grid-cols-2 md:grid-cols-3 gap-4 flex-1">
<Field label="Document ID">
<Field label="Title">{user.userTitle}</Field>
<Field label="Phone">{user.phone_number}</Field>
<Field label="UID">
<span className="font-mono text-xs" style={{ color: "var(--text-muted)" }}>
{user.id}
{user.uid || user.id}
</span>
</Field>
<Field label="UID">
<span className="font-mono text-xs">{user.uid}</span>
</Field>
<Field label="Email">{user.email}</Field>
<Field label="Status">
<span
className="px-2 py-0.5 text-xs rounded-full"
@@ -331,9 +331,6 @@ export default function UserDetail() {
{user.status || "unknown"}
</span>
</Field>
<Field label="Email">{user.email}</Field>
<Field label="Phone">{user.phone_number}</Field>
<Field label="Title">{user.userTitle}</Field>
</dl>
</div>
</section>