mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 18:28:15 +00:00
77 lines
3.5 KiB
TypeScript
77 lines
3.5 KiB
TypeScript
import { useMemo } from "react";
|
|
import { faPhoneMissed } from "@fortawesome/pro-duotone-svg-icons";
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
import { Badge } from "@/components/base/badges/badges";
|
|
import { ClickToCallButton } from "@/components/call-desk/click-to-call-button";
|
|
import type { Call } from "@/types/entities";
|
|
|
|
const getTimeSince = (dateStr: string | null): string => {
|
|
if (!dateStr) return "—";
|
|
const mins = Math.floor((Date.now() - new Date(dateStr).getTime()) / 60000);
|
|
if (mins < 1) return "Just now";
|
|
if (mins < 60) return `${mins}m ago`;
|
|
const hours = Math.floor(mins / 60);
|
|
if (hours < 24) return `${hours}h ago`;
|
|
return `${Math.floor(hours / 24)}d ago`;
|
|
};
|
|
|
|
interface MissedQueueProps {
|
|
calls: Call[];
|
|
}
|
|
|
|
export const MissedQueue = ({ calls }: MissedQueueProps) => {
|
|
const missedCalls = useMemo(() => {
|
|
return calls
|
|
.filter((c) => c.callStatus === "MISSED")
|
|
.sort((a, b) => {
|
|
const dateA = a.startedAt ? new Date(a.startedAt).getTime() : 0;
|
|
const dateB = b.startedAt ? new Date(b.startedAt).getTime() : 0;
|
|
return dateB - dateA;
|
|
})
|
|
.slice(0, 15);
|
|
}, [calls]);
|
|
|
|
return (
|
|
<div className="rounded-xl border border-secondary bg-primary shadow-xs">
|
|
<div className="flex items-center justify-between border-b border-secondary px-4 py-3">
|
|
<div className="flex items-center gap-2">
|
|
<FontAwesomeIcon icon={faPhoneMissed} className="size-3.5 text-fg-error-primary" />
|
|
<h3 className="text-sm font-semibold text-primary">Missed Call Queue</h3>
|
|
</div>
|
|
{missedCalls.length > 0 && (
|
|
<Badge size="sm" color="error">
|
|
{missedCalls.length}
|
|
</Badge>
|
|
)}
|
|
</div>
|
|
<div className="max-h-[500px] overflow-y-auto">
|
|
{missedCalls.length === 0 ? (
|
|
<div className="flex flex-col items-center justify-center gap-2 py-10">
|
|
<FontAwesomeIcon icon={faPhoneMissed} className="size-6 text-fg-quaternary" />
|
|
<p className="text-sm text-tertiary">No missed calls</p>
|
|
</div>
|
|
) : (
|
|
<ul className="divide-y divide-secondary">
|
|
{missedCalls.map((call) => {
|
|
const phone = call.callerNumber?.[0]?.number ?? "";
|
|
const display = phone ? `+91 ${phone}` : "Unknown";
|
|
return (
|
|
<li
|
|
key={call.id}
|
|
className="flex items-center justify-between px-4 py-2.5 transition duration-100 ease-linear hover:bg-primary_hover"
|
|
>
|
|
<div className="flex flex-col">
|
|
<span className="text-sm font-medium text-primary">{display}</span>
|
|
<span className="text-xs text-tertiary">{getTimeSince(call.startedAt)}</span>
|
|
</div>
|
|
{phone && <ClickToCallButton phoneNumber={phone} size="sm" />}
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|