Skip to content

Commit f876b0d

Browse files
authored
Merge pull request #21 from chechojgb/responsive
add: agregar funcion detalles operacion
2 parents e3b8246 + 22b98a3 commit f876b0d

File tree

9 files changed

+245
-74
lines changed

9 files changed

+245
-74
lines changed

app/Http/Controllers/PostProxyController.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,18 @@ public function operationState($area): JsonResponse
388388
$data = $response->json();
389389
return response()->json($data);
390390
}
391-
public function operationQueueState($area): JsonResponse
391+
public function operationPromState($area): JsonResponse
392392
{
393-
$response = Http::get("http://10.57.251.181:3014/operacion/{$area}");
393+
$response = Http::get("http://10.57.251.181:3015/tiempo-respuesta/{$area}");
394+
if (!$response->successful()) {
395+
return response()->json(['error' => 'No se pudo obtener los datos'], 500);
396+
}
397+
$data = $response->json();
398+
return response()->json($data);
399+
}
400+
public function operationAgentSatus($area): JsonResponse
401+
{
402+
$response = Http::get("http://10.57.251.181:3016/operacion/{$area}");
394403
if (!$response->successful()) {
395404
return response()->json(['error' => 'No se pudo obtener los datos'], 500);
396405
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// ModalColasAgent.jsx
2+
import React from 'react';
3+
import {
4+
Glasses,
5+
} from 'lucide-react';
6+
function ModalColasAgent({ titulo = "Agentes", usuarios = [], tipo }) {
7+
const estadoColorMap = {
8+
disponibles: 'bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300',
9+
ocupados: 'bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-300',
10+
en_pausa: 'bg-yellow-100 dark:bg-yellow-900 text-yellow-700 dark:text-yellow-300',
11+
};
12+
13+
const badgeClass = `text-xs font-semibold px-3 py-1 rounded-full ${estadoColorMap[tipo] ?? ''}`;
14+
return (
15+
<div className="p-6 max-h-[70vh] overflow-y-auto">
16+
<h2 className="text-lg font-semibold mb-4 text-gray-800 dark:text-white flex items-center gap-2">
17+
<Glasses/> {titulo} ({usuarios.length})
18+
</h2>
19+
20+
{usuarios.length === 0 ? (
21+
<p className="text-sm text-gray-500 dark:text-gray-400">
22+
No hay agentes en este estado.
23+
</p>
24+
) : (
25+
<ul className="divide-y divide-gray-200 dark:divide-gray-700">
26+
{usuarios.map((agente, idx) => (
27+
<li key={idx} className="py-3">
28+
<div className="flex justify-between items-start">
29+
<div>
30+
<p className="text-sm font-medium text-gray-900 dark:text-white">
31+
👤 {agente.usuario}
32+
</p>
33+
<p className="text-xs text-gray-500 dark:text-gray-400">
34+
Extensión: <strong>{agente.extension}</strong>
35+
</p>
36+
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
37+
Colas asignadas:{" "}
38+
<span className="font-semibold">{agente.colas.join(", ")}</span>
39+
</p>
40+
</div>
41+
<span className={badgeClass}>
42+
{agente.estado}
43+
</span>
44+
</div>
45+
</li>
46+
))}
47+
</ul>
48+
)}
49+
</div>
50+
);
51+
}
52+
53+
export default ModalColasAgent;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export default function TiempoFormateado({ tiempo }) {
2+
if (tiempo === undefined || tiempo === null || tiempo === '') {
3+
return <span className=""></span>;
4+
}
5+
6+
let horas = 0;
7+
let minutos = 0;
8+
let segundos = 0;
9+
10+
if (typeof tiempo === 'string' && tiempo.includes(':')) {
11+
const partes = tiempo.split(':');
12+
horas = parseInt(partes[0], 10);
13+
minutos = parseInt(partes[1], 10);
14+
segundos = parseFloat(partes[2]);
15+
} else if (!isNaN(tiempo)) {
16+
const totalSegundos = parseFloat(tiempo);
17+
horas = Math.floor(totalSegundos / 3600);
18+
minutos = Math.floor((totalSegundos % 3600) / 60);
19+
segundos = Math.floor(totalSegundos % 60);
20+
} else {
21+
return <span className=""></span>;
22+
}
23+
24+
let resultado = '';
25+
if (horas > 0) {
26+
resultado = `${horas}:${String(minutos).padStart(2, '0')}:${String(segundos).padStart(2, '0')}`;
27+
} else {
28+
resultado = `${minutos}:${String(segundos).padStart(2, '0')}`;
29+
}
30+
31+
return <span className="">{resultado}</span>;
32+
}

resources/js/components/welcome/agentRankingWidget.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import DiscordLoader from '@/components/discordloader';
44
import { useLoadStatus } from "../context/loadContext";
55
import { Link, usePage } from "@inertiajs/react";
66
import { themeByProject } from '../utils/theme';
7-
7+
import TiempoFormateado from '@/components/utils/formatTime';
88

99
const getMedal = (rank) => {
1010
switch (rank) {
@@ -34,6 +34,8 @@ export default function AgentRankingWidget() {
3434
.map((agente, index) => ({ ...agente, rank: index + 1 }));
3535

3636
setAgentes(ordenados);
37+
console.log(ordenados);
38+
3739
} else {
3840
console.warn("La respuesta no contiene un array de datos:", res.data);
3941
}
@@ -49,7 +51,7 @@ export default function AgentRankingWidget() {
4951
}, []);
5052

5153
return (
52-
<div className="p-6 flex flex-col justify-between">
54+
<div className="p-0 sm:p-6 flex flex-col justify-between">
5355
{loading || !allLoaded ? ( // ⛳ doble condición: hasta que TODOS estén listos
5456
<DiscordLoader />
5557
) : (
@@ -72,7 +74,7 @@ export default function AgentRankingWidget() {
7274
<div>
7375
<p className="font-medium text-gray-900 dark:text-white">{agente.agente}</p>
7476
<p className="text-xs text-gray-500 dark:text-gray-400">
75-
Directas: {agente.directas}, Transferidas: {agente.transferidas}
77+
promedio: <TiempoFormateado tiempo={agente?.promedio_duracion}/>,<br/> Total en llamadas: <TiempoFormateado tiempo={agente?.total_duracion}/>
7678
</p>
7779
</div>
7880
</div>

resources/js/components/welcome/callPerOperationChart.jsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { useEffect, useState } from 'react';
1313
import DiscordLoader from '@/components/discordloader';
1414
import axios from "axios";
1515
import { useLoadStatus } from "../context/loadContext";
16-
import { themeByProject } from "../utils/theme";
16+
import { themeByProject, getChartColors } from '../utils/theme';
1717
ChartJS.register(
1818
CategoryScale,
1919
LinearScale,
@@ -63,6 +63,8 @@ export default function CallsPerOperationChart() {
6363
const theme = themeByProject[proyecto];
6464
const [loading, setLoading] = useState(true);
6565
const { allLoaded, markLoaded } = useLoadStatus();
66+
const chartColors = getChartColors(proyecto);
67+
6668
const [callData, setCallData] = useState({
6769
Soporte: 0,
6870
Tramites: 0,
@@ -111,16 +113,16 @@ export default function CallsPerOperationChart() {
111113
callData.Movil,
112114
callData.Pruebas
113115
],
114-
backgroundColor: 'rgba(168, 85, 247, 0.6)',
115-
borderColor: 'rgba(147, 51, 234, 1)',
116+
backgroundColor: chartColors.fill,
117+
borderColor: chartColors.border,
116118
borderWidth: 1,
117119
borderRadius: 10,
118120
},
119121
],
120122
};
121123

122124
return (
123-
<div className="absolute inset-0 p-6 flex flex-col justify-between ">
125+
<div className="px-4 py-3 sm:px-6 sm:py-4 flex flex-col justify-between h-full">
124126
{!allLoaded ? (
125127
<DiscordLoader />
126128
) : (
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { useState } from 'react';
2+
3+
export default function useOperationModal() {
4+
const [modal, setModal] = useState({ show: false, tipo: null });
5+
6+
const showModal = (tipo) => {
7+
setModal({ show: true, tipo });
8+
};
9+
10+
const hideModal = () => {
11+
setModal({ show: false, tipo: null });
12+
};
13+
14+
return { modal, showModal, hideModal };
15+
}

resources/js/pages/agentState.jsx

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,31 +37,33 @@ export default function TableAgents() {
3737
<div className="xl:col-span-2 rounded-2xl shadow-lg border border-gray-100 dark:border-gray-800 p-6 flex flex-col">
3838
<h2 className="text-xl font-semibold text-indigo-700 dark:text-indigo-300 mb-4">Tabla de Ranking</h2>
3939
<div className="flex-1">
40-
{/* <LoadProvider total={1}>
40+
<LoadProvider total={1}>
4141
<AgentRankingWidget />
42-
</LoadProvider> */}
43-
</div>
44-
</div>
45-
<div className=" from-purple-100 via-white to-indigo-100 dark:from-gray-900 dark:via-gray-800 dark:to-gray-900 rounded-2xl shadow-lg border border-gray-100 dark:border-gray-800 p-6 flex flex-col justify-between">
46-
<h3 className="text-lg font-bold text-purple-700 dark:text-purple-300 mb-2">Resumen del Día</h3>
47-
<ul className="space-y-3 text-base text-gray-700 dark:text-gray-200">
48-
<li>
49-
<span className="font-bold text-indigo-600">124</span> llamadas atendidas
50-
<span className="block text-xs text-gray-500 dark:text-gray-400">Excelente desempeño general.</span>
51-
</li>
52-
<li>
53-
<span className="font-bold text-green-600">32</span> llamadas en espera
54-
<span className="block text-xs text-gray-500 dark:text-gray-400">Revisar horarios de mayor demanda.</span>
55-
</li>
56-
<li>
57-
<span className="font-bold text-red-600">18</span> llamadas perdidas
58-
<span className="block text-xs text-gray-500 dark:text-gray-400">Oportunidad de mejora en atención.</span>
59-
</li>
60-
</ul>
61-
<div className="mt-6 text-xs text-gray-400 dark:text-gray-500">
62-
Última actualización: hace 5 minutos.
42+
</LoadProvider>
6343
</div>
6444
</div>
45+
<div className="from-purple-100 via-white to-indigo-100 dark:from-gray-900 dark:via-gray-800 dark:to-gray-900 rounded-2xl shadow-lg border border-gray-100 dark:border-gray-800 p-6 flex flex-col justify-between">
46+
<h3 className="text-lg font-bold text-purple-700 dark:text-purple-300 mb-2">Estadísticas Curiosas</h3>
47+
48+
<ul className="space-y-3 text-base text-gray-700 dark:text-gray-200">
49+
<li>
50+
🏆 <span className="font-bold text-indigo-600">luisa611</span> fue el agente más rápido
51+
<span className="block text-xs text-gray-500 dark:text-gray-400">Promedio de duración: 2:31</span>
52+
</li>
53+
<li>
54+
🧱 <span className="font-bold text-green-600">baguirre39</span> trabajó sin pausas por 3h 10m
55+
<span className="block text-xs text-gray-500 dark:text-gray-400">Resistencia comprobada 💪</span>
56+
</li>
57+
<li>
58+
🎯 <span className="font-bold text-pink-600">sramoss1</span> recibió 12 transferencias
59+
<span className="block text-xs text-gray-500 dark:text-gray-400">¡Más apoyo recibido!</span>
60+
</li>
61+
</ul>
62+
63+
<div className="mt-6 text-xs text-gray-400 dark:text-gray-500">
64+
Última actualización: hace 5 minutos.
65+
</div>
66+
</div>
6567
</div>
6668

6769
<div className=" rounded-2xl shadow-lg border border-gray-100 dark:border-gray-800 p-8 mt-8">

0 commit comments

Comments
 (0)