mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-12 02:38:15 +00:00
Merge branch 'dev-main' into dev-kartik
This commit is contained in:
@@ -1,14 +1,9 @@
|
||||
import type { FC } from "react";
|
||||
import { useState } from "react";
|
||||
import { type FC, useState } from "react";
|
||||
import { faPhone } from "@fortawesome/pro-duotone-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useSetAtom } from "jotai";
|
||||
import { Button } from "@/components/base/buttons/button";
|
||||
import { apiClient } from "@/lib/api-client";
|
||||
import { notify } from "@/lib/toast";
|
||||
import { useSip } from "@/providers/sip-provider";
|
||||
import { setOutboundPending } from "@/state/sip-manager";
|
||||
import { sipCallStateAtom, sipCallUcidAtom, sipCallerNumberAtom } from "@/state/sip-state";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const Phone01: FC<{ className?: string } & Record<string, any>> = ({ className, ...rest }) => (
|
||||
@@ -23,33 +18,14 @@ interface ClickToCallButtonProps {
|
||||
}
|
||||
|
||||
export const ClickToCallButton = ({ phoneNumber, label, size = "sm" }: ClickToCallButtonProps) => {
|
||||
const { isRegistered, isInCall } = useSip();
|
||||
const { isRegistered, isInCall, dialOutbound } = useSip();
|
||||
const [dialing, setDialing] = useState(false);
|
||||
const setCallState = useSetAtom(sipCallStateAtom);
|
||||
const setCallerNumber = useSetAtom(sipCallerNumberAtom);
|
||||
const setCallUcid = useSetAtom(sipCallUcidAtom);
|
||||
|
||||
const handleDial = async () => {
|
||||
setDialing(true);
|
||||
|
||||
// Show call UI immediately
|
||||
setCallState("ringing-out");
|
||||
setCallerNumber(phoneNumber);
|
||||
setOutboundPending(true);
|
||||
// Safety: reset flag if SIP INVITE doesn't arrive within 30s
|
||||
const safetyTimer = setTimeout(() => setOutboundPending(false), 30000);
|
||||
|
||||
try {
|
||||
const result = await apiClient.post<{ ucid?: string; status?: string }>("/api/ozonetel/dial", { phoneNumber });
|
||||
if (result?.ucid) {
|
||||
setCallUcid(result.ucid);
|
||||
}
|
||||
await dialOutbound(phoneNumber);
|
||||
} catch {
|
||||
clearTimeout(safetyTimer);
|
||||
setCallState("idle");
|
||||
setCallerNumber(null);
|
||||
setOutboundPending(false);
|
||||
setCallUcid(null);
|
||||
notify.error("Dial Failed", "Could not place the call");
|
||||
} finally {
|
||||
setDialing(false);
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { faCommentDots, faEllipsisVertical, faMessageDots, faPhone } from "@fortawesome/pro-duotone-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useSetAtom } from "jotai";
|
||||
import { apiClient } from "@/lib/api-client";
|
||||
import { notify } from "@/lib/toast";
|
||||
import { useSip } from "@/providers/sip-provider";
|
||||
import { setOutboundPending } from "@/state/sip-manager";
|
||||
import { sipCallStateAtom, sipCallUcidAtom, sipCallerNumberAtom } from "@/state/sip-state";
|
||||
import { cx } from "@/utils/cx";
|
||||
|
||||
type PhoneActionCellProps = {
|
||||
@@ -16,10 +12,7 @@ type PhoneActionCellProps = {
|
||||
};
|
||||
|
||||
export const PhoneActionCell = ({ phoneNumber, displayNumber, leadId: _leadId }: PhoneActionCellProps) => {
|
||||
const { isRegistered, isInCall } = useSip();
|
||||
const setCallState = useSetAtom(sipCallStateAtom);
|
||||
const setCallerNumber = useSetAtom(sipCallerNumberAtom);
|
||||
const setCallUcid = useSetAtom(sipCallUcidAtom);
|
||||
const { isRegistered, isInCall, dialOutbound } = useSip();
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [dialing, setDialing] = useState(false);
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
@@ -41,20 +34,9 @@ export const PhoneActionCell = ({ phoneNumber, displayNumber, leadId: _leadId }:
|
||||
if (!isRegistered || isInCall || dialing) return;
|
||||
setMenuOpen(false);
|
||||
setDialing(true);
|
||||
setCallState("ringing-out");
|
||||
setCallerNumber(phoneNumber);
|
||||
setOutboundPending(true);
|
||||
const safetyTimer = setTimeout(() => setOutboundPending(false), 30000);
|
||||
|
||||
try {
|
||||
const result = await apiClient.post<{ ucid?: string }>("/api/ozonetel/dial", { phoneNumber });
|
||||
if (result?.ucid) setCallUcid(result.ucid);
|
||||
await dialOutbound(phoneNumber);
|
||||
} catch {
|
||||
clearTimeout(safetyTimer);
|
||||
setCallState("idle");
|
||||
setCallerNumber(null);
|
||||
setOutboundPending(false);
|
||||
setCallUcid(null);
|
||||
notify.error("Dial Failed", "Could not place the call");
|
||||
} finally {
|
||||
setDialing(false);
|
||||
|
||||
@@ -143,9 +143,9 @@ export const Sidebar = ({ activeUrl = "/" }: SidebarProps) => {
|
||||
setLogoutOpen(true);
|
||||
};
|
||||
|
||||
const confirmSignOut = () => {
|
||||
const confirmSignOut = async () => {
|
||||
setLogoutOpen(false);
|
||||
logout();
|
||||
await logout();
|
||||
navigate("/login");
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user