diff --git a/src/components/call-desk/click-to-call-button.tsx b/src/components/call-desk/click-to-call-button.tsx index 38d932b..c3e51ff 100644 --- a/src/components/call-desk/click-to-call-button.tsx +++ b/src/components/call-desk/click-to-call-button.tsx @@ -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> = ({ 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); diff --git a/src/components/call-desk/phone-action-cell.tsx b/src/components/call-desk/phone-action-cell.tsx index 5b1da60..a5dcb32 100644 --- a/src/components/call-desk/phone-action-cell.tsx +++ b/src/components/call-desk/phone-action-cell.tsx @@ -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(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); diff --git a/src/components/layout/sidebar.tsx b/src/components/layout/sidebar.tsx index 2642158..9215117 100644 --- a/src/components/layout/sidebar.tsx +++ b/src/components/layout/sidebar.tsx @@ -143,9 +143,9 @@ export const Sidebar = ({ activeUrl = "/" }: SidebarProps) => { setLogoutOpen(true); }; - const confirmSignOut = () => { + const confirmSignOut = async () => { setLogoutOpen(false); - logout(); + await logout(); navigate("/login"); }; diff --git a/src/pages/call-desk.tsx b/src/pages/call-desk.tsx index d3dcbf2..ccd741a 100644 --- a/src/pages/call-desk.tsx +++ b/src/pages/call-desk.tsx @@ -5,10 +5,8 @@ import { Badge } from "@/components/base/badges/badges"; import { ActiveCallCard } from "@/components/call-desk/active-call-card"; import { AgentStatusToggle } from "@/components/call-desk/agent-status-toggle"; import { ContextPanel } from "@/components/call-desk/context-panel"; -import { WorklistPanel } from "@/components/call-desk/worklist-panel"; -import type { WorklistLead } from "@/components/call-desk/worklist-panel"; +import { type WorklistLead, WorklistPanel } from "@/components/call-desk/worklist-panel"; import { useWorklist } from "@/hooks/use-worklist"; -import { apiClient } from "@/lib/api-client"; import { notify } from "@/lib/toast"; import { useAuth } from "@/providers/auth-provider"; import { useData } from "@/providers/data-provider"; @@ -18,7 +16,7 @@ import { cx } from "@/utils/cx"; export const CallDeskPage = () => { const { user } = useAuth(); const { leadActivities } = useData(); - const { connectionStatus, isRegistered, callState, callerNumber, callUcid } = useSip(); + const { connectionStatus, isRegistered, callState, callerNumber, callUcid, dialOutbound } = useSip(); const { missedCalls, followUps, marketingLeads, totalPending, loading } = useWorklist(); const [selectedLead, setSelectedLead] = useState(null); const [contextOpen, setContextOpen] = useState(true); @@ -36,7 +34,7 @@ export const CallDeskPage = () => { } setDialling(true); try { - await apiClient.post("/api/ozonetel/dial", { phoneNumber: num }); + await dialOutbound(num); setDiallerOpen(false); setDialNumber(""); } catch { @@ -96,9 +94,15 @@ export const CallDeskPage = () => {
- - {dialNumber || Enter number} - + setDialNumber(e.target.value)} + onKeyDown={(e) => e.key === "Enter" && handleDial()} + placeholder="Enter number" + autoFocus + className="flex-1 bg-transparent text-center text-lg font-semibold tracking-wider text-primary outline-none placeholder:text-sm placeholder:font-normal placeholder:text-placeholder" + /> {dialNumber && (