feat: disposition modal, persistent top bar, pagination, QA fixes

- DispositionModal: single modal for all call endings. Dismissable (agent can resume call).
  Agent clicks End → modal → select reason → hangup + dispose. Caller disconnects → same modal.
- One call screen: CallWidget stripped to ringing notification + auto-redirect to Call Desk.
- Persistent top bar in AppShell: agent status toggle + network indicator on all pages.
- Network indicator always visible (Connected/Unstable/No connection).
- Pagination: Untitled UI PaginationCardDefault on Call History + Appointments (20/page).
- Pinned table headers/footers: sticky column headers, scrollable body, pinned pagination.
  Applied to Call Desk worklist, Call History, Appointments, Call Recordings, Missed Calls.
- "Patient" → "Caller" column label in Call History.
- Offline → Ready toggle enabled.
- Profile status dot reflects Ozonetel state.
- NavAccountCard: popover placement top, View Profile + Account Settings restored.
- WIP pages for /profile and /account-settings.
- Enquiry form PHONE_INQUIRY → PHONE enum fix.
- Force Ready / View Profile / Account Settings removed then restored properly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 20:29:54 +05:30
parent daa2fbb0c2
commit e6b2208077
21 changed files with 645 additions and 816 deletions

View File

@@ -55,7 +55,7 @@ const TableContext = createContext<{ size: "sm" | "md" }>({ size: "md" });
const TableCardRoot = ({ children, className, size = "md", ...props }: HTMLAttributes<HTMLDivElement> & { size?: "sm" | "md" }) => {
return (
<TableContext.Provider value={{ size }}>
<div {...props} className={cx("overflow-hidden rounded-xl bg-primary shadow-xs ring-1 ring-secondary", className)}>
<div {...props} className={cx("flex flex-col overflow-hidden rounded-xl bg-primary shadow-xs ring-1 ring-secondary", className)}>
{children}
</div>
</TableContext.Provider>
@@ -81,7 +81,7 @@ const TableCardHeader = ({ title, badge, description, contentTrailing, className
return (
<div
className={cx(
"relative flex flex-col items-start gap-4 border-b border-secondary bg-primary px-4 md:flex-row",
"relative shrink-0 flex flex-col items-start gap-4 border-b border-secondary bg-primary px-4 md:flex-row",
size === "sm" ? "py-4 md:px-5" : "py-5 md:px-6",
className,
)}
@@ -115,8 +115,8 @@ const TableRoot = ({ className, size = "md", ...props }: TableRootProps) => {
return (
<TableContext.Provider value={{ size: context?.size ?? size }}>
<div className="overflow-x-auto">
<AriaTable className={(state) => cx("w-full overflow-x-hidden", typeof className === "function" ? className(state) : className)} {...props} />
<div className="flex-1 overflow-auto min-h-0">
<AriaTable className={(state) => cx("w-full", typeof className === "function" ? className(state) : className)} {...props} />
</div>
</TableContext.Provider>
);
@@ -138,7 +138,7 @@ const TableHeader = <T extends object>({ columns, children, bordered = true, cla
{...props}
className={(state) =>
cx(
"relative bg-secondary",
"relative bg-secondary sticky top-0 z-10",
size === "sm" ? "h-9" : "h-11",
// Row border—using an "after" pseudo-element to avoid the border taking up space.