diff --git a/src/components/call-desk/click-to-call-button.tsx b/src/components/call-desk/click-to-call-button.tsx index 3c8904d..37721e1 100644 --- a/src/components/call-desk/click-to-call-button.tsx +++ b/src/components/call-desk/click-to-call-button.tsx @@ -2,14 +2,10 @@ import type { FC } from 'react'; import { useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faPhone } from '@fortawesome/pro-duotone-svg-icons'; -import { useSetAtom } from 'jotai'; const Phone01: FC<{ className?: string } & Record> = ({ className, ...rest }) => ; import { Button } from '@/components/base/buttons/button'; import { useSip } from '@/providers/sip-provider'; -import { sipCallStateAtom, sipCallerNumberAtom, sipCallUcidAtom } from '@/state/sip-state'; -import { setOutboundPending } from '@/state/sip-manager'; -import { apiClient } from '@/lib/api-client'; import { notify } from '@/lib/toast'; interface ClickToCallButtonProps { @@ -20,33 +16,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 a1464b7..07ceb2e 100644 --- a/src/components/call-desk/phone-action-cell.tsx +++ b/src/components/call-desk/phone-action-cell.tsx @@ -1,11 +1,7 @@ import { useState, useRef, useEffect } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faPhone, faCommentDots, faEllipsisVertical, faMessageDots } from '@fortawesome/pro-duotone-svg-icons'; -import { useSetAtom } from 'jotai'; import { useSip } from '@/providers/sip-provider'; -import { sipCallStateAtom, sipCallerNumberAtom, sipCallUcidAtom } from '@/state/sip-state'; -import { setOutboundPending } from '@/state/sip-manager'; -import { apiClient } from '@/lib/api-client'; import { notify } from '@/lib/toast'; import { cx } from '@/utils/cx'; @@ -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/pages/call-desk.tsx b/src/pages/call-desk.tsx index 41b2cd8..14e75d9 100644 --- a/src/pages/call-desk.tsx +++ b/src/pages/call-desk.tsx @@ -12,14 +12,13 @@ import { ActiveCallCard } from '@/components/call-desk/active-call-card'; import { Badge } from '@/components/base/badges/badges'; import { AgentStatusToggle } from '@/components/call-desk/agent-status-toggle'; -import { apiClient } from '@/lib/api-client'; import { notify } from '@/lib/toast'; 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); @@ -34,7 +33,7 @@ export const CallDeskPage = () => { if (num.length < 10) { notify.error('Enter a valid phone number'); return; } setDialling(true); try { - await apiClient.post('/api/ozonetel/dial', { phoneNumber: num }); + await dialOutbound(num); setDiallerOpen(false); setDialNumber(''); } catch { @@ -95,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-lg font-semibold text-primary tracking-wider text-center placeholder:text-placeholder placeholder:font-normal placeholder:text-sm outline-none" + /> {dialNumber && (