feat: switch outbound to direct SIP call from browser

Instead of Kookoo outbound → IVR → dial back to SIP (broken bridge),
make the call directly from JsSIP in the browser. The SIP INVITE goes
through Ozonetel's SIP server to the PSTN. No intermediary needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-20 06:52:24 +05:30
parent d25207e49e
commit e7c5c13e83

View File

@@ -4,8 +4,6 @@ import { useSetAtom } from 'jotai';
import { Button } from '@/components/base/buttons/button';
import { useSip } from '@/providers/sip-provider';
import { sipCallStateAtom, sipCallerNumberAtom } from '@/state/sip-state';
import { setOutboundPending } from '@/state/sip-manager';
import { apiClient } from '@/lib/api-client';
import { notify } from '@/lib/toast';
interface ClickToCallButtonProps {
@@ -15,8 +13,8 @@ interface ClickToCallButtonProps {
size?: 'sm' | 'md';
}
export const ClickToCallButton = ({ phoneNumber, leadId, label, size = 'sm' }: ClickToCallButtonProps) => {
const { isRegistered, isInCall } = useSip();
export const ClickToCallButton = ({ phoneNumber, label, size = 'sm' }: ClickToCallButtonProps) => {
const { isRegistered, isInCall, makeCall } = useSip();
const [dialing, setDialing] = useState(false);
const setCallState = useSetAtom(sipCallStateAtom);
const setCallerNumber = useSetAtom(sipCallerNumberAtom);
@@ -24,18 +22,16 @@ export const ClickToCallButton = ({ phoneNumber, leadId, label, size = 'sm' }: C
const handleDial = async () => {
setDialing(true);
// Immediately show the call UI and mark outbound pending for auto-answer
// Show call UI immediately
setCallState('ringing-out');
setCallerNumber(phoneNumber);
setOutboundPending(true);
try {
await apiClient.post('/api/ozonetel/dial', { phoneNumber, leadId });
// Direct SIP call from browser
makeCall(phoneNumber);
} catch {
// API error — reset call state
setCallState('idle');
setCallerNumber(null);
setOutboundPending(false);
notify.error('Dial Failed', 'Could not place the call');
} finally {
setDialing(false);