Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 109 additions & 32 deletions app/Http/Controllers/PostProxyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,45 +60,54 @@ public function usersTable($area): JsonResponse
return response()->json($data);
}

public function userData($extension): JsonResponse
{
$response = Http::get("http://10.57.251.181:3005/extension/info?ext={$extension}");
if (!$response->successful()) {
return response()->json(['error' => 'No se pudo obtener los datos'], 500);
}
public function userData($extension): JsonResponse
{
$response = Http::get("http://10.57.251.181:3005/extension/info?ext={$extension}");
if (!$response->successful()) {
return response()->json(['error' => 'No se pudo obtener los datos'], 500);
}

$data = $response->json();
$data = $response->json();

$texto = $data['member'] ?? $data['member2'] ?? null;
$texto = $data['member'] ?? $data['member2'] ?? null;

if ($texto) {
// Extraer nombre
$nombre = explode(' ', $texto)[0];
if ($texto) {
$nombre = explode(' ', $texto)[0];
preg_match_all('/\((.*?)\)/', $texto, $matches);
$estado = null;
$pausa = null;

// Extraer estado (Busy, In call, etc.)
preg_match_all('/\((.*?)\)/', $texto, $matches);
$estado = null;
$pausa = null;
foreach ($matches[1] as $match) {
if (str_contains($match, 'paused')) {
$pausa = $match;
}
if (in_array($match, ['Busy', 'On Hold', 'In call', 'Ringing', 'Not in use'])) {
$estado = $match;
}
}

foreach ($matches[1] as $match) {
// Si no encontramos la pausa en el primer texto, revisamos member2
if (!$pausa && isset($data['member2'])) {
preg_match_all('/\((.*?)\)/', $data['member2'], $matches2);
foreach ($matches2[1] as $match) {
if (str_contains($match, 'paused')) {
$pausa = $match; // ej: paused:ACW was 2108 secs ago
}
if (in_array($match, ['Busy', 'On Hold', 'In call', 'Ringing', 'Not in use'])) {
$estado = $match;
$pausa = $match;
break;
}
}

$data['member'] = [
'nombre' => $nombre,
'estado' => $estado,
'pausa' => $pausa,
];
}

return response()->json($data);
$data['member'] = [
'nombre' => $nombre,
'estado' => $estado,
'pausa' => $pausa,
];
}

return response()->json($data);
}





Expand Down Expand Up @@ -159,19 +168,87 @@ public function chanelHangup(Request $request)
return response()->json(['error' => 'No se pudo colgar el canal'], 500);
}

public function pausedExtension(Request $request)
public function pauseExtension(Request $request): JsonResponse
{
$extension = $request->input('extension');

$response = Http::post('http://10.57.251.181:3000/channel/hangup', [
'channel' => $extension
if (!$extension) {
return response()->json(['error' => 'Extensión no proporcionada'], 400);
}

$interface = "SIP/{$extension}";
$queues = [];
for ($i = 1; $i <= 120; $i++) {
$queues[] = 'Q' . str_pad($i, 3, '0', STR_PAD_LEFT);
}
$paused = 1;
$reason = 'ACW';

$response = Http::post('http://10.57.251.181:3000/queue/pause', [
'queues' => $queues,
'interface' => $interface,
'paused' => $paused,
'reason' => $reason,
]);

if ($response->successful()) {
return response()->json(['message' => 'Extension pausada correctamente']);
return response()->json(['message' => 'Agente pausado correctamente']);
}

return response()->json(['error' => 'No se pudo colgar el canal'], 500);
return response()->json(['error' => 'No se pudo pausar al agente'], 500);
}


public function unpauseExtension(Request $request): JsonResponse
{
$extension = $request->input('extension');

if (!$extension) {
return response()->json(['error' => 'Extensión no proporcionada'], 400);
}

$interface = "SIP/{$extension}";
$queues = [];
for ($i = 1; $i <= 120; $i++) {
$queues[] = 'Q' . str_pad($i, 3, '0', STR_PAD_LEFT);
}
$paused = 0;
$reason = 'ACW';

$response = Http::post('http://10.57.251.181:3000/queue/pause', [
'queues' => $queues,
'interface' => $interface,
'paused' => $paused,
'reason' => $reason,
]);

if ($response->successful()) {
return response()->json(['message' => 'Agente despausado correctamente']);
}

return response()->json(['error' => 'No se pudo pausar al agente'], 500);
}

public function channelTransfer(Request $request): JsonResponse
{
$channel = $request->input('channel');
$destiny = $request->input('destiny');

if (!$channel || !$destiny) {
return response()->json(['error' => 'Extensión no proporcionada'], 400);
}


$response = Http::post('http://10.57.251.181:3006/transferir', [
'canal' => $channel,
'destino' => $destiny,
]);

if ($response->successful()) {
return response()->json(['message' => 'Llamada transferida correctamente']);
}

return response()->json(['error' => 'No se pudo transferir la llamada'], 500);
}

}
8 changes: 4 additions & 4 deletions resources/js/components/actionsAgent/pausedExtension.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

export default async function pausedExtension(extension) {
export default async function PauseExtension(extension) {
try {
const response = await fetch('/api/paused-extension', {
const response = await fetch('/api/pause-extension', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Expand All @@ -18,7 +18,7 @@ export default async function pausedExtension(extension) {
return { success: false, message: data.error || 'Error desconocido' };
}
} catch (error) {
console.error('Error pausando extension:', error);
console.error('Error al pausar:', error);
return { success: false, message: 'Error de red o servidor' };
}
}
}
24 changes: 24 additions & 0 deletions resources/js/components/actionsAgent/unpauseExtension.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

export default async function UnpauseExtension(extension) {
try {
const response = await fetch('/api/unpause-extension', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({ extension }),
});

const data = await response.json();

if (response.ok) {
return { success: true, message: data.message };
} else {
return { success: false, message: data.error || 'Error desconocido' };
}
} catch (error) {
console.error('Error al pausar:', error);
return { success: false, message: 'Error de red o servidor' };
}
}
22 changes: 22 additions & 0 deletions resources/js/components/adminActionButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

export default function AdminActionButton({ icon, label, onClick, disabled, bg, border }) {
return (
<button
onClick={disabled ? null : onClick}
disabled={disabled}
className={`flex items-center gap-4 p-4
${disabled ? 'bg-gray-200 border-gray-300 cursor-not-allowed' : `bg-gray-50 dark:bg-gray-900 ${bg}`}
border ${disabled ? '' : border} rounded-xl shadow transition-all hover:shadow-md`}
>
<div className={`p-2 rounded-full shadow-sm ring-1 ring-black/5 ${disabled ? 'bg-gray-300' : 'bg-white'}`}>
{React.cloneElement(icon, {
className: disabled ? 'w-5 h-5 text-gray-400' : icon.props.className,
})}
</div>
<span className={`text-sm font-medium ${disabled ? 'text-gray-500' : 'text-gray-700 dark:text-gray-100'}`}>
{label}
</span>
</button>
);
}
Loading
Loading