templates/reports/working-hours.html.twig line 1

Open in your IDE?
  1. {% extends "@UVDeskCoreFramework//Templates//layout.html.twig" %}
  2. {% block title %} 
  3.     {{ 'Horarios Laborales'|trans }}
  4. {% endblock %}
  5. {% block pageContent %}
  6.     <style>
  7.         .uv-action-bar {
  8.             border-bottom: 2px solid #e9ecef;
  9.             padding-bottom: 20px;
  10.             margin-bottom: 30px;
  11.             background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  12.             margin: -20px -20px 30px -20px;
  13.             padding: 30px 20px 20px 20px;
  14.             border-radius: 0 0 15px 15px;
  15.             box-shadow: 0 4px 20px rgba(0,0,0,0.1);
  16.         }
  17.         
  18.         .uv-action-bar h1 {
  19.             color: white;
  20.             margin: 0;
  21.             font-size: 28px;
  22.             font-weight: 600;
  23.             text-shadow: 0 2px 4px rgba(0,0,0,0.2);
  24.         }
  25.         
  26.         .uv-working-hours-container {
  27.             padding: 20px;
  28.             background: #f8f9fa;
  29.             min-height: calc(100vh - 200px);
  30.         }
  31.         
  32.         /* Nuevo layout con dashboard y sidebar */
  33.         .uv-countries-dashboard {
  34.             display: grid;
  35.             grid-template-columns: 2fr 1fr;
  36.             gap: 30px;
  37.             margin-bottom: 30px;
  38.         }
  39.         
  40.         .uv-countries-grid {
  41.             display: grid;
  42.             grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  43.             gap: 20px;
  44.         }
  45.         
  46.         .uv-country-card-expanded {
  47.             background: white;
  48.             border-radius: 15px;
  49.             padding: 20px;
  50.             box-shadow: 0 6px 20px rgba(0,0,0,0.08);
  51.             border-top: 4px solid #28a745;
  52.             position: relative;
  53.             transition: all 0.3s ease;
  54.         }
  55.         
  56.         .uv-country-card-expanded.closed {
  57.             border-top-color: #dc3545;
  58.         }
  59.         
  60.         .uv-country-card-expanded:hover {
  61.             transform: translateY(-2px);
  62.             box-shadow: 0 8px 25px rgba(0,0,0,0.12);
  63.         }
  64.         
  65.         /* Sidebar de estadísticas */
  66.         .uv-sidebar-stats {
  67.             background: white;
  68.             border-radius: 15px;
  69.             padding: 20px;
  70.             box-shadow: 0 4px 15px rgba(0,0,0,0.08);
  71.             height: fit-content;
  72.             position: sticky;
  73.             top: 20px;
  74.         }
  75.         
  76.         .uv-sidebar-title {
  77.             font-size: 18px;
  78.             font-weight: 700;
  79.             color: #2c3e50;
  80.             margin-bottom: 20px;
  81.             padding-bottom: 10px;
  82.             border-bottom: 2px solid #e9ecef;
  83.             display: flex;
  84.             align-items: center;
  85.             gap: 8px;
  86.         }
  87.         
  88.         .uv-stat-item {
  89.             display: flex;
  90.             align-items: center;
  91.             justify-content: space-between;
  92.             padding: 12px 0;
  93.             border-bottom: 1px solid #f1f3f4;
  94.         }
  95.         
  96.         .uv-stat-item:last-child {
  97.             border-bottom: none;
  98.         }
  99.         
  100.         .uv-stat-label {
  101.             font-size: 13px;
  102.             color: #6c757d;
  103.             font-weight: 500;
  104.             display: flex;
  105.             align-items: center;
  106.             gap: 6px;
  107.         }
  108.         
  109.         .uv-stat-value {
  110.             font-size: 16px;
  111.             font-weight: 700;
  112.             color: #2c3e50;
  113.         }
  114.         
  115.         .uv-stat-icon {
  116.             font-size: 16px;
  117.         }
  118.         
  119.         /* Información principal del país */
  120.         .uv-country-main-info {
  121.             display: flex;
  122.             align-items: center;
  123.             justify-content: space-between;
  124.             margin-bottom: 15px;
  125.             padding-bottom: 10px;
  126.             border-bottom: 1px solid #e9ecef;
  127.         }
  128.         
  129.         .uv-country-name {
  130.             font-size: 18px;
  131.             font-weight: 700;
  132.             color: #2c3e50;
  133.             display: flex;
  134.             align-items: center;
  135.             gap: 10px;
  136.         }
  137.         
  138.         .uv-country-flag {
  139.             font-size: 24px;
  140.         }
  141.         
  142.         .uv-country-status {
  143.             padding: 6px 12px;
  144.             border-radius: 15px;
  145.             font-size: 11px;
  146.             font-weight: 600;
  147.             text-transform: uppercase;
  148.             letter-spacing: 0.5px;
  149.         }
  150.         
  151.         .uv-country-status.open {
  152.             background: rgba(40, 167, 69, 0.1);
  153.             color: #28a745;
  154.             border: 1px solid rgba(40, 167, 69, 0.3);
  155.         }
  156.         
  157.         .uv-country-status.closed {
  158.             background: rgba(220, 53, 69, 0.1);
  159.             color: #dc3545;
  160.             border: 1px solid rgba(220, 53, 69, 0.3);
  161.         }
  162.         
  163.         /* Detalles del país */
  164.         .uv-country-details {
  165.             display: grid;
  166.             grid-template-columns: 1fr 1fr;
  167.             gap: 15px;
  168.             margin-bottom: 15px;
  169.         }
  170.         
  171.         .uv-detail-section {
  172.             background: #f8f9fa;
  173.             padding: 12px;
  174.             border-radius: 8px;
  175.             border-left: 3px solid #667eea;
  176.         }
  177.         
  178.         .uv-detail-title {
  179.             font-size: 11px;
  180.             font-weight: 600;
  181.             color: #495057;
  182.             text-transform: uppercase;
  183.             letter-spacing: 0.5px;
  184.             margin-bottom: 6px;
  185.         }
  186.         
  187.         .uv-detail-content {
  188.             font-size: 13px;
  189.             color: #2c3e50;
  190.             font-weight: 500;
  191.         }
  192.         
  193.         .uv-time-display {
  194.             font-family: 'Courier New', monospace;
  195.             font-size: 14px;
  196.             font-weight: 700;
  197.             color: #667eea;
  198.         }
  199.         
  200.         /* Agentes del país */
  201.         .uv-agents-section {
  202.             background: linear-gradient(135deg, #fff3e0, #ffe0b2);
  203.             padding: 12px;
  204.             border-radius: 8px;
  205.             border: 1px solid #ffcc02;
  206.             margin-top: 10px;
  207.         }
  208.         
  209.         .uv-agents-title {
  210.             font-size: 12px;
  211.             font-weight: 600;
  212.             color: #e65100;
  213.             text-transform: uppercase;
  214.             letter-spacing: 0.5px;
  215.             margin-bottom: 8px;
  216.             display: flex;
  217.             align-items: center;
  218.             gap: 6px;
  219.         }
  220.         
  221.         .uv-agents-preview {
  222.             display: flex;
  223.             flex-wrap: wrap;
  224.             gap: 8px;
  225.             align-items: flex-start;
  226.         }
  227.         
  228.         .uv-agent-chip {
  229.             display: flex;
  230.             align-items: center;
  231.             gap: 6px;
  232.             background: rgba(255, 255, 255, 0.9);
  233.             padding: 6px 10px;
  234.             border-radius: 15px;
  235.             font-size: 11px;
  236.             color: #2c3e50;
  237.             font-weight: 500;
  238.             border: 1px solid rgba(102, 126, 234, 0.2);
  239.             box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  240.             min-width: fit-content;
  241.             max-width: 200px;
  242.         }
  243.         
  244.         .uv-agent-avatar-small {
  245.             width: 18px;
  246.             height: 18px;
  247.             background: linear-gradient(135deg, #667eea, #764ba2);
  248.             border-radius: 50%;
  249.             display: flex;
  250.             align-items: center;
  251.             justify-content: center;
  252.             color: white;
  253.             font-size: 9px;
  254.             font-weight: bold;
  255.             flex-shrink: 0;
  256.         }
  257.         
  258.         .uv-no-agents {
  259.             text-align: center;
  260.             padding: 10px;
  261.             color: #6c757d;
  262.             font-size: 11px;
  263.             font-style: italic;
  264.             background: rgba(255, 255, 255, 0.5);
  265.             border-radius: 6px;
  266.         }
  267.         
  268.         /* Botón de edición */
  269.         .uv-edit-hours-btn {
  270.             background: linear-gradient(135deg, #ffc107, #ff9800);
  271.             color: #212529;
  272.             border: none;
  273.             padding: 8px 12px;
  274.             border-radius: 8px;
  275.             font-size: 11px;
  276.             font-weight: 600;
  277.             cursor: pointer;
  278.             transition: all 0.3s ease;
  279.             text-transform: uppercase;
  280.             letter-spacing: 0.5px;
  281.             display: flex;
  282.             align-items: center;
  283.             gap: 4px;
  284.         }
  285.         
  286.         .uv-edit-hours-btn:hover {
  287.             background: linear-gradient(135deg, #e0a800, #f57c00);
  288.             transform: translateY(-1px);
  289.             box-shadow: 0 4px 8px rgba(255, 193, 7, 0.3);
  290.         }
  291.         
  292.         /* Estilos para el switch de asignación automática */
  293.         .uv-auto-assignment-section {
  294.             background: linear-gradient(135deg, #e8f5e8, #f0f8f0);
  295.             padding: 12px;
  296.             border-radius: 8px;
  297.             border: 1px solid #28a745;
  298.             margin-bottom: 15px;
  299.             display: flex;
  300.             align-items: center;
  301.             justify-content: space-between;
  302.         }
  303.         
  304.         .uv-auto-assignment-label {
  305.             display: flex;
  306.             align-items: center;
  307.             gap: 8px;
  308.             font-size: 12px;
  309.             font-weight: 600;
  310.             color: #28a745;
  311.         }
  312.         
  313.         .uv-switch {
  314.             position: relative;
  315.             display: inline-block;
  316.             width: 50px;
  317.             height: 24px;
  318.         }
  319.         
  320.         .uv-switch input {
  321.             opacity: 0;
  322.             width: 0;
  323.             height: 0;
  324.         }
  325.         
  326.         .uv-slider {
  327.             position: absolute;
  328.             cursor: pointer;
  329.             top: 0;
  330.             left: 0;
  331.             right: 0;
  332.             bottom: 0;
  333.             background-color: #ccc;
  334.             transition: .4s;
  335.             border-radius: 24px;
  336.         }
  337.         
  338.         .uv-slider:before {
  339.             position: absolute;
  340.             content: "";
  341.             height: 18px;
  342.             width: 18px;
  343.             left: 3px;
  344.             bottom: 3px;
  345.             background-color: white;
  346.             transition: .4s;
  347.             border-radius: 50%;
  348.         }
  349.         
  350.         input:checked + .uv-slider {
  351.             background-color: #28a745;
  352.         }
  353.         
  354.         input:checked + .uv-slider:before {
  355.             transform: translateX(26px);
  356.         }
  357.         
  358.         .uv-switch:hover .uv-slider {
  359.             box-shadow: 0 0 8px rgba(40, 167, 69, 0.3);
  360.         }
  361.         
  362.         /* Responsive para el nuevo layout */
  363.         @media (max-width: 768px) {
  364.             .uv-countries-dashboard {
  365.                 grid-template-columns: 1fr;
  366.                 gap: 20px;
  367.             }
  368.             
  369.             .uv-countries-grid {
  370.                 grid-template-columns: 1fr;
  371.                 gap: 15px;
  372.             }
  373.             
  374.             .uv-country-details {
  375.                 grid-template-columns: 1fr;
  376.                 gap: 10px;
  377.             }
  378.             
  379.             .uv-sidebar-stats {
  380.                 position: static;
  381.                 order: -1;
  382.             }
  383.         }
  384.         
  385.         /* Estilos eliminados - ya no necesarios con el nuevo diseño */
  386.         
  387.         @keyframes pulse-green {
  388.             0% { box-shadow: 0 0 12px rgba(40, 167, 69, 0.4); }
  389.             50% { box-shadow: 0 0 20px rgba(40, 167, 69, 0.6); }
  390.             100% { box-shadow: 0 0 12px rgba(40, 167, 69, 0.4); }
  391.         }
  392.         
  393.         @keyframes pulse-red {
  394.             0% { box-shadow: 0 0 12px rgba(220, 53, 69, 0.4); }
  395.             50% { box-shadow: 0 0 20px rgba(220, 53, 69, 0.6); }
  396.             100% { box-shadow: 0 0 12px rgba(220, 53, 69, 0.4); }
  397.         }
  398.         
  399.         .uv-refresh-button {
  400.             background: linear-gradient(135deg, #007bff, #0056b3);
  401.             color: white;
  402.             border: none;
  403.             padding: 12px 24px;
  404.             border-radius: 25px;
  405.             cursor: pointer;
  406.             margin-left: 15px;
  407.             font-weight: 600;
  408.             font-size: 14px;
  409.             transition: all 0.3s ease;
  410.             box-shadow: 0 4px 15px rgba(0, 123, 255, 0.3);
  411.         }
  412.         
  413.         .uv-refresh-button:hover {
  414.             background: linear-gradient(135deg, #0056b3, #004085);
  415.             transform: translateY(-2px);
  416.             box-shadow: 0 6px 20px rgba(0, 123, 255, 0.4);
  417.         }
  418.         
  419.         .uv-refresh-button i {
  420.             margin-right: 8px;
  421.         }
  422.         
  423.         .uv-loading {
  424.             text-align: center;
  425.             padding: 40px 20px;
  426.             color: #6c757d;
  427.             font-size: 16px;
  428.         }
  429.         
  430.         .uv-loading i {
  431.             font-size: 24px;
  432.             margin-bottom: 15px;
  433.             display: block;
  434.             color: #667eea;
  435.         }
  436.         
  437.         .uv-error {
  438.             background: linear-gradient(135deg, #f8d7da, #f5c6cb);
  439.             color: #721c24;
  440.             padding: 20px;
  441.             border-radius: 15px;
  442.             margin: 20px 0;
  443.             border: 1px solid #f5c6cb;
  444.             text-align: center;
  445.             font-weight: 500;
  446.         }
  447.         
  448.         .uv-status-badge {
  449.             display: inline-block;
  450.             padding: 2px 5px;
  451.             border-radius: 10px;
  452.             font-size: 8px;
  453.             font-weight: 600;
  454.             text-transform: uppercase;
  455.             letter-spacing: 0.5px;
  456.             margin-left: 5px;
  457.         }
  458.         
  459.         .uv-status-badge.open {
  460.             background: rgba(40, 167, 69, 0.1);
  461.             color: #28a745;
  462.             border: 1px solid rgba(40, 167, 69, 0.3);
  463.         }
  464.         
  465.         .uv-status-badge.closed {
  466.             background: rgba(220, 53, 69, 0.1);
  467.             color: #dc3545;
  468.             border: 1px solid rgba(220, 53, 69, 0.3);
  469.         }
  470.         
  471.         /* Estilos para la sección de tickets */
  472.         .uv-tickets-section {
  473.             background: white;
  474.             border-radius: 20px;
  475.             padding: 20px;
  476.             box-shadow: 0 10px 30px rgba(0,0,0,0.08);
  477.             margin-bottom: 30px;
  478.         }
  479.         
  480.         .uv-tickets-section h2 {
  481.             color: #2c3e50;
  482.             font-size: 20px;
  483.             font-weight: 700;
  484.             margin-bottom: 15px;
  485.             padding-bottom: 10px;
  486.             border-bottom: 2px solid #e9ecef;
  487.             display: flex;
  488.             align-items: center;
  489.             gap: 8px;
  490.         }
  491.         
  492.         .uv-tickets-table {
  493.             width: 100%;
  494.             border-collapse: collapse;
  495.             margin-top: 15px;
  496.         }
  497.         
  498.         .uv-tickets-table th {
  499.             background: linear-gradient(135deg, #f8f9fa, #e9ecef);
  500.             color: #495057;
  501.             font-weight: 600;
  502.             padding: 10px 8px;
  503.             text-align: left;
  504.             border-bottom: 2px solid #dee2e6;
  505.             font-size: 12px;
  506.             text-transform: uppercase;
  507.             letter-spacing: 0.5px;
  508.         }
  509.         
  510.         .uv-tickets-table td {
  511.             padding: 10px 8px;
  512.             border-bottom: 1px solid #f1f3f4;
  513.             color: #6c757d;
  514.             font-size: 12px;
  515.         }
  516.         
  517.         .uv-tickets-table tr:hover {
  518.             background-color: #f8f9fa;
  519.         }
  520.         
  521.         .uv-ticket-id {
  522.             font-weight: 600;
  523.             color: #667eea;
  524.             font-family: 'Courier New', monospace;
  525.             font-size: 11px;
  526.         }
  527.         
  528.         .uv-ticket-id-link {
  529.             color: #667eea;
  530.             text-decoration: none;
  531.             font-weight: 600;
  532.             font-family: 'Courier New', monospace;
  533.             font-size: 11px;
  534.             transition: all 0.3s ease;
  535.             padding: 2px 6px;
  536.             border-radius: 4px;
  537.             background: rgba(102, 126, 234, 0.1);
  538.             border: 1px solid rgba(102, 126, 234, 0.2);
  539.         }
  540.         
  541.         .uv-ticket-id-link:hover {
  542.             text-decoration: none;
  543.             background: rgba(102, 126, 234, 0.2);
  544.             border-color: rgba(102, 126, 234, 0.4);
  545.             transform: translateY(-1px);
  546.             box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
  547.         }
  548.         
  549.         .uv-ticket-id-link:active {
  550.             transform: translateY(0);
  551.         }
  552.         
  553.         .uv-ticket-subject {
  554.             font-weight: 500;
  555.             color: #2c3e50;
  556.             max-width: 180px;
  557.             overflow: hidden;
  558.             text-overflow: ellipsis;
  559.             white-space: nowrap;
  560.             font-size: 11px;
  561.         }
  562.         
  563.         .uv-customer-info {
  564.             display: flex;
  565.             flex-direction: column;
  566.             gap: 2px;
  567.         }
  568.         
  569.         .uv-customer-name {
  570.             font-weight: 600;
  571.             color: #2c3e50;
  572.             font-size: 11px;
  573.         }
  574.         
  575.         .uv-customer-email {
  576.             font-size: 10px;
  577.             color: #6c757d;
  578.         }
  579.         
  580.         .uv-region-info {
  581.             display: flex;
  582.             flex-direction: column;
  583.             gap: 2px;
  584.         }
  585.         
  586.         .uv-region-name {
  587.             font-weight: 600;
  588.             color: #28a745;
  589.             font-size: 11px;
  590.         }
  591.         
  592.         .uv-region-description {
  593.             font-size: 9px;
  594.             color: #6c757d;
  595.             font-style: italic;
  596.         }
  597.         
  598.         .uv-agent-assigned {
  599.             display: flex;
  600.             flex-direction: column;
  601.             gap: 2px;
  602.         }
  603.         
  604.         .uv-agent-assigned-name {
  605.             font-weight: 600;
  606.             color: #667eea;
  607.             font-size: 11px;
  608.         }
  609.         
  610.         .uv-agent-assigned-email {
  611.             font-size: 9px;
  612.             color: #6c757d;
  613.         }
  614.         
  615.         .uv-agent-assigned-none {
  616.             color: #6c757d;
  617.             font-style: italic;
  618.             font-size: 10px;
  619.         }
  620.         
  621.         .uv-priority-badge {
  622.             padding: 2px 5px;
  623.             border-radius: 8px;
  624.             font-size: 9px;
  625.             font-weight: 600;
  626.             text-transform: uppercase;
  627.             letter-spacing: 0.5px;
  628.         }
  629.         
  630.         .uv-priority-badge.low {
  631.             background: rgba(40, 167, 69, 0.1);
  632.             color: #28a745;
  633.             border: 1px solid rgba(40, 167, 69, 0.3);
  634.         }
  635.         
  636.         .uv-priority-badge.medium {
  637.             background: rgba(255, 193, 7, 0.1);
  638.             color: #ffc107;
  639.             border: 1px solid rgba(255, 193, 7, 0.3);
  640.         }
  641.         
  642.         .uv-priority-badge.high {
  643.             background: rgba(220, 53, 69, 0.1);
  644.             color: #dc3545;
  645.             border: 1px solid rgba(220, 53, 69, 0.3);
  646.         }
  647.         
  648.         .uv-status-badge-ticket {
  649.             padding: 2px 5px;
  650.             border-radius: 8px;
  651.             font-size: 9px;
  652.             font-weight: 600;
  653.             text-transform: uppercase;
  654.             letter-spacing: 0.5px;
  655.         }
  656.         
  657.         .uv-status-badge-ticket.open {
  658.             background: rgba(40, 167, 69, 0.1);
  659.             color: #28a745;
  660.             border: 1px solid rgba(40, 167, 69, 0.3);
  661.         }
  662.         
  663.         .uv-status-badge-ticket.pending {
  664.             background: rgba(255, 193, 7, 0.1);
  665.             color: #ffc107;
  666.             border: 1px solid rgba(255, 193, 7, 0.3);
  667.         }
  668.         
  669.         .uv-status-badge-ticket.closed {
  670.             background: rgba(108, 117, 125, 0.1);
  671.             color: #6c757d;
  672.             border: 1px solid rgba(108, 117, 125, 0.3);
  673.         }
  674.         
  675.         .uv-card-header-icon {
  676.             width: 25px;
  677.             height: 25px;
  678.             background: linear-gradient(135deg, #667eea, #764ba2);
  679.             border-radius: 50%;
  680.             display: flex;
  681.             align-items: center;
  682.             justify-content: center;
  683.             color: white;
  684.             font-size: 12px;
  685.             font-weight: bold;
  686.         }
  687.         
  688.         /* Estilos para la sección de agentes */
  689.         .uv-agents-section {
  690.             background: white;
  691.             border-radius: 20px;
  692.             padding: 20px;
  693.             box-shadow: 0 10px 30px rgba(0,0,0,0.08);
  694.         }
  695.         
  696.         .uv-agents-section h2 {
  697.             color: #2c3e50;
  698.             font-size: 20px;
  699.             font-weight: 700;
  700.             margin-bottom: 15px;
  701.             padding-bottom: 10px;
  702.             border-bottom: 2px solid #e9ecef;
  703.             display: flex;
  704.             align-items: center;
  705.             gap: 8px;
  706.         }
  707.         
  708.         .uv-agents-table {
  709.             width: 100%;
  710.             border-collapse: collapse;
  711.             margin-top: 15px;
  712.         }
  713.         
  714.         .uv-agents-table th {
  715.             background: linear-gradient(135deg, #f8f9fa, #e9ecef);
  716.             color: #495057;
  717.             font-weight: 600;
  718.             padding: 10px 8px;
  719.             text-align: left;
  720.             border-bottom: 2px solid #dee2e6;
  721.             font-size: 12px;
  722.             text-transform: uppercase;
  723.             letter-spacing: 0.5px;
  724.         }
  725.         
  726.         .uv-agents-table td {
  727.             padding: 10px 8px;
  728.             border-bottom: 1px solid #f1f3f4;
  729.             color: #6c757d;
  730.             font-size: 12px;
  731.         }
  732.         
  733.         .uv-agents-table tr:hover {
  734.             background-color: #f8f9fa;
  735.         }
  736.         
  737.         .uv-agent-id {
  738.             font-weight: 600;
  739.             color: #667eea;
  740.             font-family: 'Courier New', monospace;
  741.             font-size: 11px;
  742.         }
  743.         
  744.         .uv-agent-name {
  745.             font-weight: 600;
  746.             color: #2c3e50;
  747.             font-size: 12px;
  748.         }
  749.         
  750.         .uv-agent-email {
  751.             font-size: 10px;
  752.             color: #6c757d;
  753.         }
  754.         
  755.         .uv-agent-idor {
  756.             font-size: 10px;
  757.             color: #6c757d;
  758.             font-family: 'Courier New', monospace;
  759.         }
  760.         
  761.         .uv-agent-role {
  762.             font-size: 10px;
  763.             color: #6c757d;
  764.             font-weight: 600;
  765.             text-transform: uppercase;
  766.             letter-spacing: 0.5px;
  767.         }
  768.         
  769.         .uv-agent-region {
  770.             font-weight: 600;
  771.             color: #28a745;
  772.             font-size: 11px;
  773.         }
  774.         
  775.         .uv-agent-region-description {
  776.             font-size: 9px;
  777.             color: #6c757d;
  778.             font-style: italic;
  779.         }
  780.         
  781.         .uv-agent-status {
  782.             padding: 3px 6px;
  783.             border-radius: 10px;
  784.             font-size: 9px;
  785.             font-weight: 600;
  786.             text-transform: uppercase;
  787.             letter-spacing: 0.5px;
  788.         }
  789.         
  790.         .uv-agent-status.active {
  791.             background: rgba(40, 167, 69, 0.1);
  792.             color: #28a745;
  793.             border: 1px solid rgba(40, 167, 69, 0.3);
  794.         }
  795.         
  796.         .uv-agent-status.inactive {
  797.             background: rgba(108, 117, 125, 0.1);
  798.             color: #6c757d;
  799.             border: 1px solid rgba(108, 117, 125, 0.3);
  800.         }
  801.         
  802.         .uv-agent-last-activity {
  803.             font-size: 10px;
  804.             color: #6c757d;
  805.             font-style: italic;
  806.             font-family: 'Courier New', monospace;
  807.         }
  808.         
  809.         /* Estilos para el modal de asignación de agentes */
  810.         .uv-modal-overlay {
  811.             position: fixed;
  812.             top: 0;
  813.             left: 0;
  814.             width: 100%;
  815.             height: 100%;
  816.             background: rgba(0, 0, 0, 0.5);
  817.             z-index: 10000;
  818.             display: none;
  819.             align-items: center;
  820.             justify-content: center;
  821.         }
  822.         
  823.         .uv-modal-overlay.show {
  824.             display: flex;
  825.         }
  826.         
  827.         .uv-modal {
  828.             background: white;
  829.             border-radius: 20px;
  830.             padding: 30px;
  831.             max-width: 700px;
  832.             width: 90%;
  833.             max-height: 80vh;
  834.             overflow-y: auto;
  835.             box-shadow: 0 25px 80px rgba(0, 0, 0, 0.3);
  836.             position: relative;
  837.             border: 1px solid rgba(255, 255, 255, 0.2);
  838.         }
  839.         
  840.         .uv-modal-header {
  841.             display: flex;
  842.             justify-content: space-between;
  843.             align-items: center;
  844.             margin-bottom: 25px;
  845.             padding-bottom: 20px;
  846.             border-bottom: 3px solid #e9ecef;
  847.             background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  848.             margin: -30px -30px 25px -30px;
  849.             padding: 25px 30px 20px 30px;
  850.             border-radius: 20px 20px 0 0;
  851.         }
  852.         
  853.         .uv-modal-title {
  854.             font-size: 20px;
  855.             font-weight: 700;
  856.             color: #2c3e50;
  857.             margin: 0;
  858.         }
  859.         
  860.         .uv-modal-close {
  861.             background: none;
  862.             border: none;
  863.             font-size: 24px;
  864.             color: #6c757d;
  865.             cursor: pointer;
  866.             padding: 0;
  867.             width: 30px;
  868.             height: 30px;
  869.             display: flex;
  870.             align-items: center;
  871.             justify-content: center;
  872.             border-radius: 50%;
  873.             transition: all 0.3s ease;
  874.         }
  875.         
  876.         .uv-modal-close:hover {
  877.             background: #f8f9fa;
  878.             color: #495057;
  879.         }
  880.         
  881.         .uv-modal-content {
  882.             margin-bottom: 20px;
  883.         }
  884.         
  885.         .uv-modal-description {
  886.             color: #6c757d;
  887.             margin-bottom: 20px;
  888.             line-height: 1.5;
  889.         }
  890.         
  891.         .uv-agents-grid {
  892.             display: grid;
  893.             grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  894.             gap: 12px;
  895.             margin-bottom: 20px;
  896.         }
  897.         
  898.         .uv-agent-option {
  899.             background: #f8f9fa;
  900.             border: 2px solid #e9ecef;
  901.             border-radius: 10px;
  902.             padding: 15px;
  903.             cursor: pointer;
  904.             transition: all 0.3s ease;
  905.             text-align: center;
  906.         }
  907.         
  908.         .uv-agent-option:hover {
  909.             border-color: #667eea;
  910.             background: #f0f2ff;
  911.             transform: translateY(-2px);
  912.         }
  913.         
  914.         .uv-agent-option.selected {
  915.             border-color: #28a745;
  916.             background: #f8fff9;
  917.         }
  918.         
  919.         .uv-agent-option-avatar {
  920.             width: 50px;
  921.             height: 50px;
  922.             background: linear-gradient(135deg, #667eea, #764ba2);
  923.             border-radius: 50%;
  924.             display: flex;
  925.             align-items: center;
  926.             justify-content: center;
  927.             color: white;
  928.             font-size: 18px;
  929.             font-weight: bold;
  930.             margin: 0 auto 10px auto;
  931.         }
  932.         
  933.         .uv-agent-option-name {
  934.             font-weight: 600;
  935.             color: #2c3e50;
  936.             margin-bottom: 5px;
  937.             font-size: 14px;
  938.         }
  939.         
  940.         .uv-agent-option-email {
  941.             color: #6c757d;
  942.             font-size: 12px;
  943.             margin-bottom: 8px;
  944.         }
  945.         
  946.         .uv-agent-option-status {
  947.             display: inline-block;
  948.             padding: 4px 8px;
  949.             border-radius: 15px;
  950.             font-size: 10px;
  951.             font-weight: 600;
  952.             text-transform: uppercase;
  953.             background: rgba(40, 167, 69, 0.1);
  954.             color: #28a745;
  955.             border: 1px solid rgba(40, 167, 69, 0.3);
  956.         }
  957.         
  958.         .uv-modal-footer {
  959.             display: flex;
  960.             gap: 10px;
  961.             justify-content: flex-end;
  962.         }
  963.         
  964.         .uv-btn {
  965.             padding: 10px 20px;
  966.             border: none;
  967.             border-radius: 8px;
  968.             font-weight: 600;
  969.             cursor: pointer;
  970.             transition: all 0.3s ease;
  971.             font-size: 14px;
  972.         }
  973.         
  974.         .uv-btn-secondary {
  975.             background: #6c757d;
  976.             color: white;
  977.             border: 2px solid #6c757d;
  978.         }
  979.         
  980.         .uv-btn-secondary:hover {
  981.             background: #5a6268;
  982.             border-color: #5a6268;
  983.             transform: translateY(-2px);
  984.             box-shadow: 0 4px 12px rgba(108, 117, 125, 0.3);
  985.         }
  986.         
  987.         .uv-btn-primary {
  988.             background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  989.             color: white;
  990.             border: 2px solid transparent;
  991.         }
  992.         
  993.         .uv-btn-primary:hover {
  994.             background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
  995.             transform: translateY(-2px);
  996.             box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
  997.         }
  998.         
  999.         .uv-btn:disabled {
  1000.             opacity: 0.6;
  1001.             cursor: not-allowed;
  1002.         }
  1003.         
  1004.         .uv-confirmation-message {
  1005.             background: linear-gradient(135deg, #fff3cd, #ffeaa7);
  1006.             border: 1px solid #ffc107;
  1007.             border-radius: 10px;
  1008.             padding: 15px;
  1009.             margin-bottom: 20px;
  1010.             text-align: center;
  1011.             color: #856404;
  1012.             font-weight: 500;
  1013.         }
  1014.         
  1015.         .uv-ticket-assign-btn {
  1016.             background: linear-gradient(135deg, #007bff, #0056b3);
  1017.             color: white;
  1018.             border: none;
  1019.             padding: 6px 12px;
  1020.             border-radius: 6px;
  1021.             font-size: 10px;
  1022.             font-weight: 600;
  1023.             cursor: pointer;
  1024.             transition: all 0.3s ease;
  1025.             text-transform: uppercase;
  1026.             letter-spacing: 0.5px;
  1027.         }
  1028.         
  1029.         .uv-ticket-assign-btn:hover {
  1030.             background: linear-gradient(135deg, #0056b3, #004085);
  1031.             transform: translateY(-1px);
  1032.         }
  1033.         
  1034.         .uv-ticket-assign-btn:disabled {
  1035.             opacity: 0.6;
  1036.             cursor: not-allowed;
  1037.             background: #6c757d;
  1038.         }
  1039.         
  1040.         @media (max-width: 768px) {
  1041.             .uv-working-hours-grid {
  1042.                 grid-template-columns: 1fr;
  1043.                 gap: 15px;
  1044.             }
  1045.             
  1046.             .uv-action-bar {
  1047.                 padding: 20px 15px 15px 15px;
  1048.                 margin: -20px -15px 20px -15px;
  1049.             }
  1050.             
  1051.             .uv-action-bar h1 {
  1052.                 font-size: 24px;
  1053.             }
  1054.             
  1055.             .uv-working-hours-container {
  1056.                 padding: 15px;
  1057.             }
  1058.             
  1059.             .uv-card-content {
  1060.                 left: -15px;
  1061.                 right: -15px;
  1062.                 border-radius: 8px;
  1063.             }
  1064.             
  1065.             .uv-card-content.expanded {
  1066.                 padding: 12px;
  1067.             }
  1068.             
  1069.             .uv-card-content.expanded::before,
  1070.             .uv-card-content.expanded::after {
  1071.                 left: 35px;
  1072.             }
  1073.             
  1074.             .uv-modal {
  1075.                 margin: 20px;
  1076.                 padding: 20px;
  1077.                 max-height: 90vh;
  1078.             }
  1079.             
  1080.             .uv-agents-grid {
  1081.                 grid-template-columns: 1fr;
  1082.                 gap: 10px;
  1083.             }
  1084.             
  1085.             .uv-agent-option {
  1086.                 padding: 12px;
  1087.             }
  1088.             
  1089.             .uv-modal-footer {
  1090.                 flex-direction: column;
  1091.             }
  1092.             
  1093.             .uv-btn {
  1094.                 width: 100%;
  1095.                 text-align: center;
  1096.             }
  1097.             
  1098.             .uv-time-info {
  1099.                 flex-direction: column;
  1100.                 align-items: flex-start;
  1101.             }
  1102.             
  1103.             .uv-time-label {
  1104.                 margin-bottom: 3px;
  1105.                 min-width: auto;
  1106.             }
  1107.             
  1108.             .uv-agents-count {
  1109.                 padding: 3px 6px;
  1110.                 gap: 3px;
  1111.             }
  1112.             
  1113.             .uv-agents-count-number {
  1114.                 font-size: 11px;
  1115.                 min-width: 14px;
  1116.             }
  1117.             
  1118.             .uv-agents-count-total {
  1119.                 font-size: 9px;
  1120.             }
  1121.             
  1122.             .uv-agents-section-card {
  1123.                 padding: 8px;
  1124.             }
  1125.             
  1126.             .uv-agent-item {
  1127.                 padding: 5px;
  1128.                 gap: 6px;
  1129.             }
  1130.             
  1131.             .uv-agent-avatar {
  1132.                 width: 20px;
  1133.                 height: 20px;
  1134.                 font-size: 8px;
  1135.             }
  1136.             
  1137.             .uv-tickets-table {
  1138.                 font-size: 11px;
  1139.             }
  1140.             
  1141.             .uv-tickets-table th,
  1142.             .uv-tickets-table td {
  1143.                 padding: 8px 6px;
  1144.             }
  1145.             
  1146.             .uv-agent-assigned {
  1147.                 gap: 1px;
  1148.             }
  1149.             
  1150.             .uv-agent-assigned-name {
  1151.                 font-size: 10px;
  1152.             }
  1153.             
  1154.             .uv-agent-assigned-email {
  1155.                 font-size: 8px;
  1156.             }
  1157.             
  1158.             .uv-agent-assigned-none {
  1159.                 font-size: 9px;
  1160.             }
  1161.             
  1162.             .uv-agents-table {
  1163.                 font-size: 11px;
  1164.             }
  1165.             
  1166.             .uv-agents-table th,
  1167.             .uv-agents-table td {
  1168.                 padding: 8px 6px;
  1169.             }
  1170.             .uv-ticket-id-link {
  1171.                 font-size: 10px;
  1172.                 padding: 1px 4px;
  1173.             }
  1174.             
  1175.             .uv-ticket-id-link:hover {
  1176.                 transform: none;
  1177.                 box-shadow: 0 1px 4px rgba(102, 126, 234, 0.3);
  1178.             }
  1179.             
  1180.             /* Estilos para el botón de edición de horarios */
  1181.             .uv-edit-hours-btn {
  1182.                 background: linear-gradient(135deg, #ffc107, #ff9800);
  1183.                 color: #212529;
  1184.                 border: none;
  1185.                 padding: 6px 8px;
  1186.                 border-radius: 6px;
  1187.                 font-size: 10px;
  1188.                 font-weight: 600;
  1189.                 cursor: pointer;
  1190.                 transition: all 0.3s ease;
  1191.                 text-transform: uppercase;
  1192.                 letter-spacing: 0.5px;
  1193.                 margin-left: 8px;
  1194.                 display: flex;
  1195.                 align-items: center;
  1196.                 justify-content: center;
  1197.                 min-width: 28px;
  1198.                 height: 28px;
  1199.             }
  1200.             
  1201.             .uv-edit-hours-btn:hover {
  1202.                 background: linear-gradient(135deg, #e0a800, #f57c00);
  1203.                 transform: translateY(-1px);
  1204.                 box-shadow: 0 4px 8px rgba(255, 193, 7, 0.3);
  1205.             }
  1206.             
  1207.             .uv-edit-icon {
  1208.                 font-size: 12px;
  1209.             }
  1210.             
  1211.             /* Estilos para el modal de edición de horarios */
  1212.             .uv-modal-large {
  1213.                 max-width: 800px;
  1214.                 width: 95%;
  1215.                 padding: 35px;
  1216.             }
  1217.             
  1218.             .uv-edit-hours-form {
  1219.                 background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  1220.                 border-radius: 15px;
  1221.                 padding: 25px;
  1222.                 margin-top: 20px;
  1223.                 border: 1px solid #dee2e6;
  1224.                 box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
  1225.             }
  1226.             
  1227.             .uv-form-group {
  1228.                 margin-bottom: 25px;
  1229.             }
  1230.             
  1231.             .uv-form-group label {
  1232.                 display: block;
  1233.                 font-weight: 600;
  1234.                 color: #2c3e50;
  1235.                 margin-bottom: 8px;
  1236.                 font-size: 14px;
  1237.             }
  1238.             
  1239.             .uv-form-group label {
  1240.                 display: block;
  1241.                 margin-bottom: 8px;
  1242.                 font-weight: 600;
  1243.                 color: #2c3e50;
  1244.                 font-size: 14px;
  1245.             }
  1246.             
  1247.             .uv-form-control {
  1248.                 width: 100%;
  1249.                 padding: 12px 16px;
  1250.                 border: 2px solid #e9ecef;
  1251.                 border-radius: 10px;
  1252.                 font-size: 14px;
  1253.                 transition: all 0.3s ease;
  1254.                 background: white;
  1255.                 font-weight: 500;
  1256.             }
  1257.             
  1258.             .uv-form-control:focus {
  1259.                 outline: none;
  1260.                 border-color: #667eea;
  1261.                 box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
  1262.                 transform: translateY(-1px);
  1263.             }
  1264.             
  1265.             .uv-form-control:hover {
  1266.                 border-color: #ced4da;
  1267.             }
  1268.             
  1269.             .uv-form-row {
  1270.                 display: grid;
  1271.                 grid-template-columns: 1fr 1fr;
  1272.                 gap: 15px;
  1273.             }
  1274.             
  1275.             .uv-working-days-grid {
  1276.                 display: grid;
  1277.                 grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  1278.                 gap: 12px;
  1279.                 margin-top: 12px;
  1280.             }
  1281.             
  1282.             .uv-day-checkbox {
  1283.                 display: flex;
  1284.                 align-items: center;
  1285.                 gap: 10px;
  1286.                 padding: 12px 16px;
  1287.                 background: white;
  1288.                 border: 2px solid #e9ecef;
  1289.                 border-radius: 10px;
  1290.                 cursor: pointer;
  1291.                 transition: all 0.3s ease;
  1292.                 font-size: 14px;
  1293.                 font-weight: 500;
  1294.                 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  1295.             }
  1296.             
  1297.             .uv-day-checkbox:hover {
  1298.                 border-color: #667eea;
  1299.                 background: #f8f9fa;
  1300.                 transform: translateY(-2px);
  1301.                 box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  1302.             }
  1303.             
  1304.             .uv-day-checkbox input[type="checkbox"] {
  1305.                 margin: 0;
  1306.                 width: 18px;
  1307.                 height: 18px;
  1308.                 accent-color: #667eea;
  1309.                 cursor: pointer;
  1310.             }
  1311.             
  1312.             .uv-day-checkbox input[type="checkbox"]:checked + span {
  1313.                 color: #667eea;
  1314.                 font-weight: 700;
  1315.             }
  1316.             
  1317.             .uv-day-checkbox:has(input[type="checkbox"]:checked) {
  1318.                 border-color: #667eea;
  1319.                 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  1320.                 color: white;
  1321.             }
  1322.             
  1323.             .uv-day-checkbox:has(input[type="checkbox"]:checked) span {
  1324.                 color: white;
  1325.             }
  1326.             
  1327.             /* Responsive para el modal de edición */
  1328.             @media (max-width: 768px) {
  1329.                 .uv-form-row {
  1330.                     grid-template-columns: 1fr;
  1331.                     gap: 10px;
  1332.                 }
  1333.                 
  1334.                 .uv-working-days-grid {
  1335.                     grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
  1336.                     gap: 8px;
  1337.                 }
  1338.                 
  1339.                 .uv-day-checkbox {
  1340.                     padding: 6px 8px;
  1341.                     font-size: 12px;
  1342.                 }
  1343.                 
  1344.                 .uv-edit-hours-btn {
  1345.                     margin-left: 4px;
  1346.                     padding: 4px 6px;
  1347.                     min-width: 24px;
  1348.                     height: 24px;
  1349.                 }
  1350.                 
  1351.                 .uv-edit-icon {
  1352.                     font-size: 10px;
  1353.                 }
  1354.             }
  1355.         }
  1356.     </style>
  1357.     <div class="uv-working-hours-container">
  1358.         <div class="uv-action-bar">
  1359.             <h1>{{ 'Horarios Laborales'|trans }}</h1>
  1360.             <button class="uv-refresh-button" onclick="refreshAll()">
  1361.                 <i class="fa fa-refresh"></i> Actualizar Todo
  1362.             </button>
  1363.         </div>
  1364.         <!-- Sección de Horarios Laborales -->
  1365.         <div id="working-hours-content">
  1366.             <div class="uv-loading">
  1367.                 <i class="fa fa-spinner fa-spin"></i>
  1368.                 Cargando horarios laborales...
  1369.             </div>
  1370.         </div>
  1371.         <!-- Sección de Tickets Recientes -->
  1372.         <div class="uv-tickets-section">
  1373.             <h2>📋 Últimos 5 Tickets Ingresados</h2>
  1374.             <div id="tickets-content">
  1375.                 <div class="uv-loading">
  1376.                     <i class="fa fa-spinner fa-spin"></i>
  1377.                     Cargando tickets recientes...
  1378.                 </div>
  1379.             </div>
  1380.         </div>
  1381.         <!-- Sección de Agentes -->
  1382.         <div class="uv-agents-section">
  1383.             <h2>👥 Agentes </h2>
  1384.             <div id="agents-content">
  1385.                 <div class="uv-loading">
  1386.                     <i class="fa fa-spinner fa-spin"></i>
  1387.                     Cargando agentes...
  1388.                 </div>
  1389.             </div>
  1390.         </div>
  1391.     </div>
  1392.     <!-- Modal para asignar agentes -->
  1393.     <div id="assignAgentModal" class="uv-modal-overlay">
  1394.         <div class="uv-modal">
  1395.             <div class="uv-modal-header">
  1396.                 <h3 class="uv-modal-title">🔄 Asignar Agente al Ticket</h3>
  1397.                 <button class="uv-modal-close" onclick="closeAssignAgentModal()">&times;</button>
  1398.             </div>
  1399.             
  1400.             <div class="uv-modal-content">
  1401.                 <div class="uv-modal-description">
  1402.                     Selecciona un agente de una oficina abierta para asignar al ticket <strong id="modalTicketId"></strong>
  1403.                     <div style="margin-top: 8px; padding: 8px; background: rgba(102, 126, 234, 0.1); border-radius: 6px; font-size: 12px; color: #667eea;">
  1404.                         <strong>ℹ️ Solo se muestran agentes de oficinas que están abiertas actualmente</strong>
  1405.                     </div>
  1406.                 </div>
  1407.                 
  1408.                 <div id="confirmationMessage" class="uv-confirmation-message" style="display: none;">
  1409.                     Se le va a asignar el ticket actual a este agente, ¿desea continuar?
  1410.                 </div>
  1411.                 
  1412.                 <div id="agentsGrid" class="uv-agents-grid">
  1413.                     <!-- Los agentes se cargarán dinámicamente aquí -->
  1414.                 </div>
  1415.             </div>
  1416.             
  1417.             <div class="uv-modal-footer">
  1418.                 <button class="uv-btn uv-btn-secondary" onclick="closeAssignAgentModal()">Cancelar</button>
  1419.                 <button id="confirmAssignBtn" class="uv-btn uv-btn-primary" onclick="confirmAssignAgent()" disabled>
  1420.                     Confirmar Asignación
  1421.                 </button>
  1422.             </div>
  1423.         </div>
  1424.     </div>
  1425.     <!-- Modal para editar horarios laborales -->
  1426.     <div id="editHoursModal" class="uv-modal-overlay">
  1427.         <div class="uv-modal uv-modal-large">
  1428.             <div class="uv-modal-header">
  1429.                 <h3 class="uv-modal-title">🕐 Editar Horarios Laborales</h3>
  1430.                 <button class="uv-modal-close" onclick="closeEditHoursModal()">&times;</button>
  1431.             </div>
  1432.             
  1433.             <div class="uv-modal-content">
  1434.                 <div class="uv-modal-description">
  1435.                     Configura los horarios laborales para <strong id="editCountryName"></strong>
  1436.                 </div>
  1437.                 
  1438.                 <div class="uv-edit-hours-form">
  1439.                     <div class="uv-form-group">
  1440.                         <label for="editTimezone">🌍 Zona Horaria:</label>
  1441.                         <select id="editTimezone" class="uv-form-control">
  1442.                             <option value="America/Argentina/Buenos_Aires">Argentina (Buenos Aires)</option>
  1443.                             <option value="America/Bogota">Colombia (Bogotá)</option>
  1444.                             <option value="America/Mexico_City">México (Ciudad de México)</option>
  1445.                             <option value="America/Sao_Paulo">Brasil (São Paulo)</option>
  1446.                             <option value="Europe/Madrid">España (Madrid)</option>
  1447.                             <option value="America/Lima">Perú (Lima)</option>
  1448.                             <option value="America/Santiago">Chile (Santiago)</option>
  1449.                             <option value="America/Caracas">Venezuela (Caracas)</option>
  1450.                             <option value="America/Costa_Rica">Costa Rica (San José)</option>
  1451.                             <option value="America/New_York">Estados Unidos (Nueva York)</option>
  1452.                             <option value="Europe/London">Reino Unido (Londres)</option>
  1453.                             <option value="Asia/Tokyo">Japón (Tokio)</option>
  1454.                             <option value="Australia/Sydney">Australia (Sídney)</option>
  1455.                         </select>
  1456.                     </div>
  1457.                     
  1458.                     <div class="uv-form-row">
  1459.                         <div class="uv-form-group">
  1460.                             <label for="editStartTime">🕐 Hora de Inicio:</label>
  1461.                             <input type="time" id="editStartTime" class="uv-form-control" value="09:00">
  1462.                         </div>
  1463.                         
  1464.                         <div class="uv-form-group">
  1465.                             <label for="editEndTime">🕐 Hora de Fin:</label>
  1466.                             <input type="time" id="editEndTime" class="uv-form-control" value="18:00">
  1467.                         </div>
  1468.                     </div>
  1469.                     
  1470.                     <div class="uv-form-group">
  1471.                         <label>📅 Días Laborales:</label>
  1472.                         <div class="uv-working-days-grid">
  1473.                             <label class="uv-day-checkbox">
  1474.                                 <input type="checkbox" id="editMonday" checked>
  1475.                                 <span>Lunes</span>
  1476.                             </label>
  1477.                             <label class="uv-day-checkbox">
  1478.                                 <input type="checkbox" id="editTuesday" checked>
  1479.                                 <span>Martes</span>
  1480.                             </label>
  1481.                             <label class="uv-day-checkbox">
  1482.                                 <input type="checkbox" id="editWednesday" checked>
  1483.                                 <span>Miércoles</span>
  1484.                             </label>
  1485.                             <label class="uv-day-checkbox">
  1486.                                 <input type="checkbox" id="editThursday" checked>
  1487.                                 <span>Jueves</span>
  1488.                             </label>
  1489.                             <label class="uv-day-checkbox">
  1490.                                 <input type="checkbox" id="editFriday" checked>
  1491.                                 <span>Viernes</span>
  1492.                             </label>
  1493.                             <label class="uv-day-checkbox">
  1494.                                 <input type="checkbox" id="editSaturday">
  1495.                                 <span>Sábado</span>
  1496.                             </label>
  1497.                             <label class="uv-day-checkbox">
  1498.                                 <input type="checkbox" id="editSunday">
  1499.                                 <span>Domingo</span>
  1500.                             </label>
  1501.                         </div>
  1502.                     </div>
  1503.                 </div>
  1504.             </div>
  1505.             
  1506.             <div class="uv-modal-footer">
  1507.                 <button class="uv-btn uv-btn-secondary" onclick="closeEditHoursModal()">Cancelar</button>
  1508.                 <button id="saveWorkingHoursBtn" class="uv-btn uv-btn-primary" onclick="saveWorkingHours()">
  1509.                     Guardar Cambios
  1510.                 </button>
  1511.             </div>
  1512.         </div>
  1513.     </div>
  1514.     <script>
  1515.         function loadWorkingHours() {
  1516.             fetch('{{ path("helpdesk_report_working_hours_status") }}')
  1517.                 .then(response => response.json())
  1518.                 .then(data => {
  1519.                     displayWorkingHours(data);
  1520.                 })
  1521.                 .catch(error => {
  1522.                     console.error('Error loading working hours:', error);
  1523.                     document.getElementById('working-hours-content').innerHTML = 
  1524.                         '<div class="uv-error">Error al cargar los horarios laborales. Por favor, intente nuevamente.</div>';
  1525.                 });
  1526.         }
  1527.         function loadRecentTickets() {
  1528.             fetch('{{ path("helpdesk_report_working_hours_tickets") }}')
  1529.                 .then(response => response.json())
  1530.                 .then(data => {
  1531.                     // Limitar a solo los últimos 5 tickets
  1532.                     const limitedTickets = data.slice(0, 5);
  1533.                     displayRecentTickets(limitedTickets);
  1534.                 })
  1535.                 .catch(error => {
  1536.                     console.error('Error loading recent tickets:', error);
  1537.                     document.getElementById('tickets-content').innerHTML = 
  1538.                         '<div class="uv-error">Error al cargar los tickets recientes. Por favor, intente nuevamente.</div>';
  1539.                 });
  1540.         }
  1541.         function loadAgents() {
  1542.             fetch('{{ path("helpdesk_report_working_hours_agents") }}')
  1543.                 .then(response => response.json())
  1544.                 .then(data => {
  1545.                     displayAgents(data);
  1546.                 })
  1547.                 .catch(error => {
  1548.                     console.error('Error loading agents:', error);
  1549.                     document.getElementById('agents-content').innerHTML = 
  1550.                         '<div class="uv-error">Error al cargar los agentes. Por favor, intente nuevamente.</div>';
  1551.                 });
  1552.         }
  1553.         function displayWorkingHours(data) {
  1554.             const container = document.getElementById('working-hours-content');
  1555.             
  1556.             // Calcular estadísticas globales
  1557.             const countries = Object.values(data);
  1558.             const totalCountries = countries.length;
  1559.             const openCountries = countries.filter(c => c.status === 'open').length;
  1560.             const totalAgents = countries.reduce((sum, c) => sum + (c.agents ? c.agents.length : 0), 0);
  1561.             const activeAgents = countries.reduce((sum, c) => sum + (c.agents ? c.agents.filter(a => a.isEnabled).length : 0), 0);
  1562.             
  1563.             let html = `
  1564.                 <div class="uv-countries-dashboard">
  1565.                     <div class="uv-countries-grid">
  1566.             `;
  1567.             // Mostrar cada país con información expandida
  1568.             countries.forEach(country => {
  1569.                 const statusClass = country.status === 'open' ? 'open' : 'closed';
  1570.                 const statusText = country.status === 'open' ? 'Abierto' : 'Cerrado';
  1571.                 const countryFlag = getCountryFlag(country.country);
  1572.                 
  1573.                 // Contar agentes activos
  1574.                 const activeAgentsCount = country.agents ? country.agents.filter(agent => agent.isEnabled).length : 0;
  1575.                 const totalAgentsCount = country.agents ? country.agents.length : 0;
  1576.                 
  1577.                 html += `
  1578.                     <div class="uv-country-card-expanded ${statusClass}">
  1579.                         <div class="uv-country-main-info">
  1580.                             <div class="uv-country-name">
  1581.                                 <span class="uv-country-flag">${countryFlag}</span>
  1582.                                 ${country.country}
  1583.                             </div>
  1584.                             <div class="uv-country-status ${statusClass}">${statusText}</div>
  1585.                         </div>
  1586.                         
  1587.                         <div class="uv-country-details">
  1588.                             <div class="uv-detail-section">
  1589.                                 <div class="uv-detail-title">🕐 Hora Local</div>
  1590.                                 <div class="uv-detail-content">
  1591.                                     <div class="uv-time-display">${country.localTime}</div>
  1592.                                     <div style="font-size: 11px; color: #6c757d; margin-top: 2px;">${country.dayOfWeek}</div>
  1593.                             </div>
  1594.                             </div>
  1595.                             
  1596.                             <div class="uv-detail-section">
  1597.                                 <div class="uv-detail-title">📅 Horario Laboral</div>
  1598.                                 <div class="uv-detail-content">
  1599.                                     <div style="font-weight: 600;">${country.workingHours}</div>
  1600.                                     <div style="font-size: 11px; color: #6c757d; margin-top: 2px;">${country.workingDaysText}</div>
  1601.                             </div>
  1602.                             </div>
  1603.                             
  1604.                             <div class="uv-detail-section">
  1605.                                 <div class="uv-detail-title">🌍 Zona Horaria</div>
  1606.                                 <div class="uv-detail-content">${country.timezone}</div>
  1607.                             </div>
  1608.                             
  1609.                             <div class="uv-detail-section">
  1610.                                 <div class="uv-detail-title">👥 Agentes</div>
  1611.                                 <div class="uv-detail-content">
  1612.                                     <div style="font-weight: 600; color: #28a745;">${activeAgentsCount}/${totalAgentsCount} Activos</div>
  1613.                 </div>
  1614.                                                 </div>
  1615.                         </div>
  1616.                         
  1617.                         <div class="uv-agents-section">
  1618.                             <div class="uv-agents-title">
  1619.                                 👥 Agentes Asignados (${totalAgentsCount})
  1620.                             </div>
  1621.                             ${country.agents && country.agents.length > 0 ? 
  1622.                                 `<div class="uv-agents-preview">
  1623.                                     ${country.agents.slice(0, 4).map(agent => `
  1624.                                         <div class="uv-agent-chip">
  1625.                                             <div class="uv-agent-avatar-small">${getInitials(agent.name)}</div>
  1626.                                             <span>${agent.name}</span>
  1627.                                             <span style="color: ${agent.isEnabled ? '#28a745' : '#dc3545'};">${agent.isEnabled ? '🟢' : '🔴'}</span>
  1628.                                             </div>
  1629.                                         `).join('')}
  1630.                                     ${country.agents.length > 4 ? `<div class="uv-agent-chip" style="background: rgba(102, 126, 234, 0.1); color: #667eea;">+${country.agents.length - 4} más</div>` : ''}
  1631.                                     </div>` : 
  1632.                                     `<div class="uv-no-agents">No hay agentes asignados a esta región</div>`
  1633.                                 }
  1634.                             </div>
  1635.                         
  1636.                         ${country.country === 'Casa Central' ? `
  1637.                             <div class="uv-auto-assignment-section">
  1638.                                 <div class="uv-auto-assignment-label">
  1639.                                     <span>🤖</span>
  1640.                                     <span>Asignación Automática de Agentes</span>
  1641.                                 </div>
  1642.                                 <label class="uv-switch">
  1643.                                     <input type="checkbox" ${country.autoAssignmentEnabled == 1 ? 'checked' : ''} 
  1644.                                            onchange="toggleAutoAssignment(${country.supportGroupId}, this.checked)">
  1645.                                     <span class="uv-slider"></span>
  1646.                                 </label>
  1647.                             </div>
  1648.                         ` : ''}
  1649.                         
  1650.                         <div style="margin-top: 15px; text-align: right;">
  1651.                             <button class="uv-edit-hours-btn" onclick="openEditHoursModal('${country.country}', ${JSON.stringify(country).replace(/"/g, '&quot;')})" title="Editar horarios">
  1652.                                 <span>✏️</span> Editar Horarios
  1653.                             </button>
  1654.                         </div>
  1655.                     </div>
  1656.                 `;
  1657.             });
  1658.             html += `
  1659.                     </div>
  1660.                     
  1661.                     <div class="uv-sidebar-stats">
  1662.                         <div class="uv-sidebar-title">
  1663.                             📊 Estadísticas Globales
  1664.                         </div>
  1665.                         
  1666.                         <div class="uv-stat-item">
  1667.                             <div class="uv-stat-label">
  1668.                                 <span class="uv-stat-icon">🌍</span>
  1669.                                 Países Totales
  1670.                             </div>
  1671.                             <div class="uv-stat-value">${totalCountries}</div>
  1672.                         </div>
  1673.                         
  1674.                         <div class="uv-stat-item">
  1675.                             <div class="uv-stat-label">
  1676.                                 <span class="uv-stat-icon">🟢</span>
  1677.                                 Oficinas Abiertas
  1678.                             </div>
  1679.                             <div class="uv-stat-value" style="color: #28a745;">${openCountries}</div>
  1680.                         </div>
  1681.                         
  1682.                         <div class="uv-stat-item">
  1683.                             <div class="uv-stat-label">
  1684.                                 <span class="uv-stat-icon">🔴</span>
  1685.                                 Oficinas Cerradas
  1686.                             </div>
  1687.                             <div class="uv-stat-value" style="color: #dc3545;">${totalCountries - openCountries}</div>
  1688.                         </div>
  1689.                         
  1690.                         <div class="uv-stat-item">
  1691.                             <div class="uv-stat-label">
  1692.                                 <span class="uv-stat-icon">👥</span>
  1693.                                 Agentes Totales
  1694.                             </div>
  1695.                             <div class="uv-stat-value">${totalAgents}</div>
  1696.                         </div>
  1697.                         
  1698.                         <div class="uv-stat-item">
  1699.                             <div class="uv-stat-label">
  1700.                                 <span class="uv-stat-icon">✅</span>
  1701.                                 Agentes Activos
  1702.                             </div>
  1703.                             <div class="uv-stat-value" style="color: #28a745;">${activeAgents}</div>
  1704.                         </div>
  1705.                         
  1706.                         <div class="uv-stat-item">
  1707.                             <div class="uv-stat-label">
  1708.                                 <span class="uv-stat-icon">⏰</span>
  1709.                                 Zonas Horarias
  1710.                             </div>
  1711.                             <div class="uv-stat-value">${new Set(countries.map(c => c.timezone)).size}</div>
  1712.                         </div>
  1713.                     </div>
  1714.                 </div>
  1715.             `;
  1716.             
  1717.             container.innerHTML = html;
  1718.         }
  1719.         function displayRecentTickets(tickets) {
  1720.             const container = document.getElementById('tickets-content');
  1721.             
  1722.             if (!tickets || tickets.length === 0) {
  1723.                 container.innerHTML = '<div class="uv-error">No se encontraron tickets recientes.</div>';
  1724.                 return;
  1725.             }
  1726.             let html = `
  1727.                 <table class="uv-tickets-table">
  1728.                     <thead>
  1729.                         <tr>
  1730.                             <th>Ticket ID</th>
  1731.                             <th>Asunto</th>
  1732.                             <th>Cliente</th>
  1733.                             <th>Región</th>
  1734.                             <th>Estado</th>
  1735.                             <th>Prioridad</th>
  1736.                             <th>Agente Asignado</th>
  1737.                             <th>Fecha Creación</th>
  1738.                             <th>Acciones</th>
  1739.                         </tr>
  1740.                     </thead>
  1741.                     <tbody>
  1742.             `;
  1743.             tickets.forEach(ticket => {
  1744.                 const priorityClass = getPriorityClass(ticket.priority);
  1745.                 const statusClass = getStatusClass(ticket.status);
  1746.                 
  1747.                 html += `
  1748.                     <tr>
  1749.                         <td><a href="/en/member/ticket/view/${ticket.ticketId}" class="uv-ticket-id-link" target="_blank">#${ticket.ticketId}</a></td>
  1750.                         <td><div class="uv-ticket-subject" title="${ticket.subject}">${ticket.subject}</div></td>
  1751.                         <td>
  1752.                             <div class="uv-customer-info">
  1753.                                 <div class="uv-customer-name">${ticket.customer.name}</div>
  1754.                                 <div class="uv-customer-email">${ticket.customer.email}</div>
  1755.                                 <small>IDOR: ${ticket.customer.idor || 'N/A'}</small>
  1756.                             </div>
  1757.                         </td>
  1758.                         <td>
  1759.                             <div class="uv-region-info">
  1760.                                 <div class="uv-region-name">${ticket.region.name}</div>
  1761.                                 <div class="uv-region-description">${ticket.region.description}</div>
  1762.                             </div>
  1763.                         </td>
  1764.                         <td><span class="uv-status-badge-ticket ${statusClass}">${ticket.status}</span></td>
  1765.                         <td><span class="uv-priority-badge ${priorityClass}">${ticket.priority}</span></td>
  1766.                         <td>
  1767.                             ${ticket.agent ? 
  1768.                                 `<div class="uv-agent-assigned">
  1769.                                     <div class="uv-agent-assigned-name">${ticket.agent.name}</div>
  1770.                                     <div class="uv-agent-assigned-email">${ticket.agent.email}</div>
  1771.                                 </div>` : 
  1772.                                 `<div class="uv-agent-assigned-none">Sin asignar</div>`
  1773.                             }
  1774.                         </td>
  1775.                         <td>${formatDate(ticket.createdAt)}</td>
  1776.                         <td>
  1777.                             <button class="uv-ticket-assign-btn" onclick="openAssignAgentModal(${ticket.ticketId})">
  1778.                                 Asignar Agente
  1779.                             </button>
  1780.                         </td>
  1781.                     </tr>
  1782.                 `;
  1783.             });
  1784.             html += '</tbody></table>';
  1785.             container.innerHTML = html;
  1786.         }
  1787.         function displayAgents(agents) {
  1788.             const container = document.getElementById('agents-content');
  1789.             let html = '<table class="uv-agents-table">';
  1790.             if (!agents || agents.length === 0) {
  1791.                 html += '<tr><td colspan="9" class="uv-error">No se encontraron agentes disponibles.</td></tr>';
  1792.             } else {
  1793.                 html += `
  1794.                     <thead>
  1795.                         <tr>
  1796.                             <th>ID</th>
  1797.                             <th>Nombre</th>
  1798.                             <th>Email</th>
  1799.                             <th>IDOR</th>
  1800.                             <th>Rol</th>
  1801.                             <th>Región</th>
  1802.                             <th>Estado</th>
  1803.                             <th>Última Actividad</th>
  1804.                         </tr>
  1805.                     </thead>
  1806.                     <tbody>
  1807.                 `;
  1808.                 agents.forEach(agent => {
  1809.                     html += `
  1810.                         <tr>
  1811.                             <td><span class="uv-agent-id">#${agent.id}</span></td>
  1812.                             <td><span class="uv-agent-name">${agent.name}</span></td>
  1813.                             <td><span class="uv-agent-email">${agent.email}</span></td>
  1814.                             <td><span class="uv-agent-idor">${agent.idor || 'N/A'}</span></td>
  1815.                             <td><span class="uv-agent-role">${agent.role}</span></td>
  1816.                             <td>
  1817.                                 <div class="uv-agent-region-info">
  1818.                                     <div class="uv-agent-region">${agent.region.name}</div>
  1819.                                     <div class="uv-agent-region-description">${agent.region.description}</div>
  1820.                                 </div>
  1821.                             </td>
  1822.                             <td><span class="uv-agent-status ${agent.isEnabled ? 'active' : 'inactive'}">${agent.isEnabled ? 'Activo' : 'Inactivo'}</span></td>
  1823.                             <td><span class="uv-agent-last-activity">${agent.lastActivity}</span></td>
  1824.                         </tr>
  1825.                     `;
  1826.                 });
  1827.             }
  1828.             html += '</tbody></table>';
  1829.             container.innerHTML = html;
  1830.         }
  1831.         function getPriorityClass(priority) {
  1832.             const priorityMap = {
  1833.                 'low': 'low',
  1834.                 'medium': 'medium',
  1835.                 'high': 'high'
  1836.             };
  1837.             return priorityMap[priority.toLowerCase()] || 'low';
  1838.         }
  1839.         function getStatusClass(status) {
  1840.             const statusMap = {
  1841.                 'open': 'open',
  1842.                 'pending': 'pending',
  1843.                 'closed': 'closed'
  1844.             };
  1845.             return statusMap[status.toLowerCase()] || 'open';
  1846.         }
  1847.         function formatDate(dateString) {
  1848.             const date = new Date(dateString);
  1849.             return date.toLocaleDateString('es-ES', {
  1850.                 year: 'numeric',
  1851.                 month: 'short',
  1852.                 day: 'numeric',
  1853.                 hour: '2-digit',
  1854.                 minute: '2-digit'
  1855.             });
  1856.         }
  1857.         function getCountryFlag(country) {
  1858.             const flags = {
  1859.                 'Casa Central': '🏢',
  1860.                 'Colombia': '🇨🇴',
  1861.                 'Mexico': '🇲🇽',
  1862.                 'Brasil': '🇧🇷',
  1863.                 'España': '🇪🇸',
  1864.                 'Peru': '🇵🇪',
  1865.                 'Chile': '🇨🇱',
  1866.                 'Venezuela': '🇻🇪',
  1867.                 'Costa Rica': '🇨🇷'
  1868.             };
  1869.             return flags[country] || '🌍';
  1870.         }
  1871.         
  1872.         function getInitials(name) {
  1873.             return name.split(' ').map(word => word.charAt(0)).join('').toUpperCase().substring(0, 2);
  1874.         }
  1875.         
  1876.         // Función eliminada - ya no necesaria con el nuevo diseño expandido
  1877.         function refreshAll() {
  1878.             // Actualizar horarios laborales
  1879.             document.getElementById('working-hours-content').innerHTML = 
  1880.                 '<div class="uv-loading"><i class="fa fa-spinner fa-spin"></i> Actualizando horarios...</div>';
  1881.             
  1882.             // Actualizar tickets
  1883.             document.getElementById('tickets-content').innerHTML = 
  1884.                 '<div class="uv-loading"><i class="fa fa-spinner fa-spin"></i> Actualizando tickets...</div>';
  1885.             
  1886.             // Actualizar agentes
  1887.             document.getElementById('agents-content').innerHTML = 
  1888.                 '<div class="uv-loading"><i class="fa fa-spinner fa-spin"></i> Actualizando agentes...</div>';
  1889.             
  1890.             loadWorkingHours();
  1891.             loadRecentTickets();
  1892.             loadAgents();
  1893.         }
  1894.         // Load all data when page loads
  1895.         document.addEventListener('DOMContentLoaded', function() {
  1896.             loadWorkingHours();
  1897.             loadRecentTickets();
  1898.             loadAgents();
  1899.             
  1900.             // Auto-refresh every 5 minutes
  1901.             setInterval(function() {
  1902.                 loadWorkingHours();
  1903.                 loadRecentTickets();
  1904.                 loadAgents();
  1905.             }, 5 * 60 * 1000);
  1906.         });
  1907.         
  1908.         // Variables globales para el modal
  1909.         let currentTicketId = null;
  1910.         let selectedAgentId = null;
  1911.         let allAgents = [];
  1912.         
  1913.         // Función para abrir el modal de asignación de agentes
  1914.         function openAssignAgentModal(ticketId) {
  1915.             currentTicketId = ticketId;
  1916.             selectedAgentId = null;
  1917.             
  1918.             // Mostrar el modal
  1919.             document.getElementById('assignAgentModal').classList.add('show');
  1920.             document.getElementById('modalTicketId').textContent = '#' + ticketId;
  1921.             
  1922.             // Ocultar mensaje de confirmación
  1923.             document.getElementById('confirmationMessage').style.display = 'none';
  1924.             
  1925.             // Deshabilitar botón de confirmación
  1926.             document.getElementById('confirmAssignBtn').disabled = true;
  1927.             
  1928.             // Cargar agentes activos
  1929.             loadActiveAgentsForModal();
  1930.         }
  1931.         
  1932.         // Función para cerrar el modal
  1933.         function closeAssignAgentModal() {
  1934.             document.getElementById('assignAgentModal').classList.remove('show');
  1935.             currentTicketId = null;
  1936.             selectedAgentId = null;
  1937.         }
  1938.         
  1939.         // Función para cargar agentes activos en el modal (solo de oficinas abiertas)
  1940.         function loadActiveAgentsForModal() {
  1941.             // Siempre cargar agentes de oficinas abiertas en tiempo real
  1942.             fetch('{{ path("helpdesk_report_working_hours_active_office_agents") }}')
  1943.                     .then(response => response.json())
  1944.                     .then(data => {
  1945.                         allAgents = data;
  1946.                         displayAgentsInModal();
  1947.                     })
  1948.                     .catch(error => {
  1949.                     console.error('Error loading active office agents for modal:', error);
  1950.                         document.getElementById('agentsGrid').innerHTML = 
  1951.                         '<div class="uv-error">Error al cargar los agentes de oficinas abiertas. Por favor, intente nuevamente.</div>';
  1952.                     });
  1953.         }
  1954.         
  1955.         // Función para mostrar agentes en el modal
  1956.         function displayAgentsInModal() {
  1957.             const agentsGrid = document.getElementById('agentsGrid');
  1958.             const activeAgents = allAgents.filter(agent => agent.isEnabled);
  1959.             
  1960.             if (allAgents.length === 0) {
  1961.                 agentsGrid.innerHTML = `
  1962.                     <div class="uv-error">
  1963.                         <div style="text-align: center; padding: 20px;">
  1964.                             <div style="font-size: 24px; margin-bottom: 10px;">🏢</div>
  1965.                             <div style="font-weight: 600; margin-bottom: 5px;">No hay oficinas abiertas</div>
  1966.                             <div style="font-size: 12px; color: #6c757d;">
  1967.                                 Todas las oficinas están cerradas en este momento.<br>
  1968.                                 Los agentes estarán disponibles cuando sus oficinas abran.
  1969.                             </div>
  1970.                         </div>
  1971.                     </div>
  1972.                 `;
  1973.                 return;
  1974.             }
  1975.             
  1976.             if (activeAgents.length === 0) {
  1977.                 agentsGrid.innerHTML = '<div class="uv-error">No hay agentes activos disponibles en las oficinas abiertas.</div>';
  1978.                 return;
  1979.             }
  1980.             
  1981.             let html = '';
  1982.             activeAgents.forEach(agent => {
  1983.                 const regionName = agent.region.name || 'Sin región';
  1984.                 const regionFlag = getCountryFlag(regionName.replace('OR ', ''));
  1985.                 
  1986.                 html += `
  1987.                     <div class="uv-agent-option" onclick="selectAgent(${agent.id})" data-agent-id="${agent.id}">
  1988.                         <div class="uv-agent-option-avatar">${getInitials(agent.name)}</div>
  1989.                         <div class="uv-agent-option-name">${agent.name}</div>
  1990.                         <div class="uv-agent-option-email">${agent.email}</div>
  1991.                         <div class="uv-agent-option-region" style="display: flex; align-items: center; gap: 4px; margin: 4px 0; font-size: 10px; color: #667eea;">
  1992.                             <span>${regionFlag}</span>
  1993.                             <span>${regionName}</span>
  1994.                         </div>
  1995.                         <div class="uv-agent-option-status">🟢 Activo</div>
  1996.                     </div>
  1997.                 `;
  1998.             });
  1999.             
  2000.             agentsGrid.innerHTML = html;
  2001.         }
  2002.         
  2003.         // Función para seleccionar un agente
  2004.         function selectAgent(agentId) {
  2005.             // Remover selección anterior
  2006.             document.querySelectorAll('.uv-agent-option').forEach(option => {
  2007.                 option.classList.remove('selected');
  2008.             });
  2009.             
  2010.             // Seleccionar el nuevo agente
  2011.             const selectedOption = document.querySelector(`[data-agent-id="${agentId}"]`);
  2012.             if (selectedOption) {
  2013.                 selectedOption.classList.add('selected');
  2014.             }
  2015.             
  2016.             selectedAgentId = agentId;
  2017.             
  2018.             // Mostrar mensaje de confirmación
  2019.             document.getElementById('confirmationMessage').style.display = 'block';
  2020.             
  2021.             // Habilitar botón de confirmación
  2022.             document.getElementById('confirmAssignBtn').disabled = false;
  2023.         }
  2024.         
  2025.         // Función para confirmar la asignación
  2026.         function confirmAssignAgent() {
  2027.             if (!currentTicketId || !selectedAgentId) {
  2028.                 alert('Por favor, selecciona un agente primero.');
  2029.                 return;
  2030.             }
  2031.             
  2032.             // Deshabilitar botón durante la operación
  2033.             document.getElementById('confirmAssignBtn').disabled = true;
  2034.             document.getElementById('confirmAssignBtn').textContent = 'Asignando...';
  2035.             
  2036.             // Realizar la asignación
  2037.             assignTicketToAgent(currentTicketId, selectedAgentId);
  2038.         }
  2039.         
  2040.         // Función para asignar el ticket al agente
  2041.         function assignTicketToAgent(ticketId, agentId) {
  2042.             fetch('{{ path("helpdesk_report_working_hours_assign_agent") }}', {
  2043.                 method: 'POST',
  2044.                 headers: {
  2045.                     'Content-Type': 'application/json',
  2046.                 },
  2047.                 body: JSON.stringify({
  2048.                     ticketId: ticketId,
  2049.                     agentId: agentId
  2050.                 })
  2051.             })
  2052.             .then(response => response.json())
  2053.             .then(data => {
  2054.                 if (data.success) {
  2055.                     // Mostrar mensaje de éxito
  2056.                     alert('✅ Ticket asignado exitosamente al agente.');
  2057.                     
  2058.                     // Cerrar modal
  2059.                     closeAssignAgentModal();
  2060.                     
  2061.                     // Actualizar la lista de tickets
  2062.                     loadRecentTickets();
  2063.                 } else {
  2064.                     alert('❌ Error al asignar el ticket: ' + (data.message || 'Error desconocido'));
  2065.                 }
  2066.             })
  2067.             .catch(error => {
  2068.                 console.error('Error assigning ticket:', error);
  2069.                 alert('❌ Error al asignar el ticket. Por favor, intente nuevamente.');
  2070.             })
  2071.             .finally(() => {
  2072.                 // Restaurar botón
  2073.                 document.getElementById('confirmAssignBtn').disabled = false;
  2074.                 document.getElementById('confirmAssignBtn').textContent = 'Confirmar Asignación';
  2075.             });
  2076.         }
  2077.         
  2078.         // Cerrar modal al hacer clic fuera de él
  2079.         document.addEventListener('click', function(event) {
  2080.             const modal = document.getElementById('assignAgentModal');
  2081.             if (event.target === modal) {
  2082.                 closeAssignAgentModal();
  2083.             }
  2084.         });
  2085.         
  2086.         // Cerrar modal con tecla Escape
  2087.         document.addEventListener('keydown', function(event) {
  2088.             if (event.key === 'Escape') {
  2089.                 closeAssignAgentModal();
  2090.             }
  2091.         });
  2092.         
  2093.         // ===== FUNCIONES PARA EDITAR HORARIOS =====
  2094.         
  2095.         let currentEditingCountry = null;
  2096.         
  2097.         // Función para abrir el modal de edición de horarios
  2098.         function openEditHoursModal(countryName, countryData) {
  2099.             currentEditingCountry = countryData;
  2100.             
  2101.             // Llenar el formulario con los datos actuales
  2102.             document.getElementById('editCountryName').textContent = countryName;
  2103.             document.getElementById('editTimezone').value = countryData.timezone;
  2104.             document.getElementById('editStartTime').value = countryData.workingHours.split(' - ')[0];
  2105.             document.getElementById('editEndTime').value = countryData.workingHours.split(' - ')[1];
  2106.             
  2107.             // Configurar días laborales
  2108.             const workingDays = countryData.workingDays;
  2109.             document.getElementById('editMonday').checked = workingDays.includes('Lunes');
  2110.             document.getElementById('editTuesday').checked = workingDays.includes('Martes');
  2111.             document.getElementById('editWednesday').checked = workingDays.includes('Miércoles');
  2112.             document.getElementById('editThursday').checked = workingDays.includes('Jueves');
  2113.             document.getElementById('editFriday').checked = workingDays.includes('Viernes');
  2114.             document.getElementById('editSaturday').checked = workingDays.includes('Sábado');
  2115.             document.getElementById('editSunday').checked = workingDays.includes('Domingo');
  2116.             
  2117.             // Mostrar el modal
  2118.             document.getElementById('editHoursModal').style.display = 'flex';
  2119.         }
  2120.         
  2121.         // Función para cerrar el modal de edición
  2122.         function closeEditHoursModal() {
  2123.             document.getElementById('editHoursModal').style.display = 'none';
  2124.             currentEditingCountry = null;
  2125.         }
  2126.         
  2127.         // Función para guardar los cambios de horarios
  2128.         function saveWorkingHours() {
  2129.             if (!currentEditingCountry) {
  2130.                 alert('No hay país seleccionado para editar.');
  2131.                 return;
  2132.             }
  2133.             
  2134.             // Recopilar datos del formulario
  2135.             const formData = {
  2136.                 countryName: currentEditingCountry.country,
  2137.                 supportGroupId: currentEditingCountry.supportGroupId,
  2138.                 timezone: document.getElementById('editTimezone').value,
  2139.                 startTime: document.getElementById('editStartTime').value,
  2140.                 endTime: document.getElementById('editEndTime').value,
  2141.                 monday: document.getElementById('editMonday').checked ? 1 : 0,
  2142.                 tuesday: document.getElementById('editTuesday').checked ? 1 : 0,
  2143.                 wednesday: document.getElementById('editWednesday').checked ? 1 : 0,
  2144.                 thursday: document.getElementById('editThursday').checked ? 1 : 0,
  2145.                 friday: document.getElementById('editFriday').checked ? 1 : 0,
  2146.                 saturday: document.getElementById('editSaturday').checked ? 1 : 0,
  2147.                 sunday: document.getElementById('editSunday').checked ? 1 : 0
  2148.             };
  2149.             
  2150.             // Validar datos
  2151.             if (!formData.timezone || !formData.startTime || !formData.endTime) {
  2152.                 alert('Por favor, complete todos los campos obligatorios.');
  2153.                 return;
  2154.             }
  2155.             
  2156.             // Deshabilitar botón durante la operación
  2157.             const saveBtn = document.getElementById('saveWorkingHoursBtn');
  2158.             saveBtn.disabled = true;
  2159.             saveBtn.textContent = 'Guardando...';
  2160.             
  2161.             // Enviar datos al servidor
  2162.             fetch('{{ path("helpdesk_report_working_hours_update_hours") }}', {
  2163.                 method: 'POST',
  2164.                 headers: {
  2165.                     'Content-Type': 'application/json',
  2166.                 },
  2167.                 body: JSON.stringify(formData)
  2168.             })
  2169.             .then(response => response.json())
  2170.             .then(data => {
  2171.                 if (data.success) {
  2172.                     alert('✅ Horarios actualizados exitosamente.');
  2173.                     closeEditHoursModal();
  2174.                     
  2175.                     // Actualizar la vista
  2176.                     loadWorkingHours();
  2177.                 } else {
  2178.                     alert('❌ Error al actualizar horarios: ' + (data.message || 'Error desconocido'));
  2179.                 }
  2180.             })
  2181.             .catch(error => {
  2182.                 console.error('Error updating working hours:', error);
  2183.                 alert('❌ Error al actualizar horarios. Por favor, intente nuevamente.');
  2184.             })
  2185.             .finally(() => {
  2186.                 // Restaurar botón
  2187.                 saveBtn.disabled = false;
  2188.                 saveBtn.textContent = 'Guardar Cambios';
  2189.             });
  2190.         }
  2191.         
  2192.         // Cerrar modal de edición al hacer clic fuera de él
  2193.         document.addEventListener('click', function(event) {
  2194.             const modal = document.getElementById('editHoursModal');
  2195.             if (event.target === modal) {
  2196.                 closeEditHoursModal();
  2197.             }
  2198.         });
  2199.         
  2200.         // Función para toggle de asignación automática
  2201.         function toggleAutoAssignment(supportGroupId, enabled) {
  2202.             fetch('{{ path("helpdesk_report_working_hours_toggle_auto_assignment") }}', {
  2203.                 method: 'POST',
  2204.                 headers: {
  2205.                     'Content-Type': 'application/json',
  2206.                 },
  2207.                 body: JSON.stringify({
  2208.                     supportGroupId: supportGroupId,
  2209.                     enabled: enabled
  2210.                 })
  2211.             })
  2212.             .then(response => response.json())
  2213.             .then(data => {
  2214.                 if (data.success) {
  2215.                     // Mostrar mensaje de éxito
  2216.                     const message = enabled ? 
  2217.                         '✅ Asignación automática de agentes activada para Casa Central' : 
  2218.                         '❌ Asignación automática de agentes desactivada para Casa Central';
  2219.                     alert(message);
  2220.                     
  2221.                     // Actualizar la vista para reflejar los cambios
  2222.                     loadWorkingHours();
  2223.                 } else {
  2224.                     alert('❌ Error al actualizar el estado: ' + (data.message || 'Error desconocido'));
  2225.                 }
  2226.             })
  2227.             .catch(error => {
  2228.                 console.error('Error toggling auto assignment:', error);
  2229.                 alert('❌ Error al actualizar el estado. Por favor, intente nuevamente.');
  2230.             });
  2231.         }
  2232.     </script>
  2233. {% endblock %}