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