Files
jp dddb8c3663 frontend: prevent contacts content overflowing the viewport + sync UI repo
- ContactsPage: drop whiteSpace:nowrap on the action cell; wrap the
  Edit/History/Delete/⋮ buttons in a flex container with flex-wrap so they
  reflow instead of forcing the table wider than the viewport; allow the
  name/number/email cell to break long strings.
- index.css: td word-break:break-word + table max-width:100% as a guard.
- Sync the UI repo (ContactsPage/ContactHistory/MessagesPage implicit-any
  annotations that unblock npm run build) into the frontend/ mirror.
2026-08-13 20:42:29 +01:00

30 lines
1.3 KiB
TypeScript

import { useQuery } from "@tanstack/react-query";
import { useParams } from "react-router-dom";
import { api } from "../lib/api";
export default function ContactHistory() {
const { num } = useParams();
const { data, isLoading, error } = useQuery({ queryKey: ["history", num], queryFn: () => api.contactHistory(num || ""), enabled: !!num });
return (
<div className="wrap">
<div className="card" style={{ padding: "12px 16px" }}>
<div className="meta">
<a href="/contacts">&larr; Back to contacts</a>
{data && <> · {data.messages?.length ?? 0} message(s) from <b>{data.contact}</b></>}
</div>
</div>
{isLoading && <div className="card empty">Loading...</div>}
{error && <div className="card err">{(error as Error).message}</div>}
{data?.messages?.map((m: any) => (
<div key={m.id} className={"card" + (m.is_read ? "" : " unread")}>
<div className="who">{data.contact}</div>
<div className="meta">{m.time}{m.duration_fmt ? ` · ${m.duration_fmt}` : ""}</div>
<div className="sum">{m.summary || "(no speech detected)"}</div>
{m.has_audio && <audio controls preload="none" src={`/audio/${m.id}`} />}
</div>
))}
{data?.messages?.length === 0 && <div className="card empty">No voicemails from this caller yet.</div>}
</div>
);
}