Subversion Repositories SmartDukaan

Rev

Rev 37468 | Rev 37487 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37468 Rev 37469
Line 1580... Line 1580...
1580
    .xtable .cnt-pill.good {
1580
    .xtable .cnt-pill.good {
1581
      background: #e5f7ee;
1581
      background: #e5f7ee;
1582
      color: #177a3a
1582
      color: #177a3a
1583
    }
1583
    }
1584
 
1584
 
-
 
1585
    /* call-target drawer content (Called Partners / OOS Calls) */
-
 
1586
    #rdrrCallDrawerBody {
-
 
1587
      overflow-x: auto
-
 
1588
    }
-
 
1589
 
-
 
1590
    #rdrrCallDrawerBody table {
-
 
1591
      width: 100%;
-
 
1592
      border-collapse: separate;
-
 
1593
      border-spacing: 0;
-
 
1594
      font-size: 12.5px;
-
 
1595
      background: #fff;
-
 
1596
      margin: 0
-
 
1597
    }
-
 
1598
 
-
 
1599
    #rdrrCallDrawerBody table th {
-
 
1600
      font-size: 10.5px;
-
 
1601
      text-transform: uppercase;
-
 
1602
      letter-spacing: .04em;
-
 
1603
      color: var(--soft);
-
 
1604
      font-weight: 700;
-
 
1605
      padding: 9px 10px;
-
 
1606
      background: #fafbfe;
-
 
1607
      border-bottom: 1px solid var(--line);
-
 
1608
      text-align: left;
-
 
1609
      white-space: nowrap
-
 
1610
    }
-
 
1611
 
-
 
1612
    #rdrrCallDrawerBody table td {
-
 
1613
      padding: 9px 10px;
-
 
1614
      border-bottom: 1px solid var(--line2);
-
 
1615
      color: var(--ink);
-
 
1616
      font-weight: 500;
-
 
1617
      vertical-align: middle
-
 
1618
    }
-
 
1619
 
-
 
1620
    #rdrrCallDrawerBody table tr:hover {
-
 
1621
      background: #f6f8fd
-
 
1622
    }
-
 
1623
 
-
 
1624
    #rdrrCallDrawerBody audio {
-
 
1625
      max-width: 170px;
-
 
1626
      height: 26px
-
 
1627
    }
-
 
1628
 
1585
    /* rbm performance dashboard (extracted from today_po_rbm) */
1629
    /* rbm performance dashboard (extracted from today_po_rbm) */
1586
    #rdrrPerfWrap {
1630
    #rdrrPerfWrap {
1587
      overflow-x: auto
1631
      overflow-x: auto
1588
    }
1632
    }
1589
 
1633
 
Line 2013... Line 2057...
2013
        Loading…
2057
        Loading…
2014
      </div>
2058
      </div>
2015
    </div>
2059
    </div>
2016
  </div>
2060
  </div>
2017
 
2061
 
2018
  <!-- RBM Call Target Summary — full interactive page embedded via iframe (no backend change) -->
-
 
2019
  <div class="sectionlabel">RBM Call Target Summary</div>
-
 
2020
  <div class="card">
-
 
2021
    <div class="card-hd">
-
 
2022
      <div>
-
 
2023
        <h2>Today's Call Coverage per RBM</h2>
-
 
2024
        <p class="desc">Full interactive view — all popups, drill-downs and downloads work exactly like the standalone
-
 
2025
          page.</p>
-
 
2026
      </div>
-
 
2027
      <a class="badge-period" href="/indent/rbm_call_target" target="_blank" style="text-decoration:none">Open in new
-
 
2028
        tab &rsaquo;</a>
-
 
2029
    </div>
-
 
2030
    <iframe id="rdrrCallFrame" src="/indent/rbm_call_target" title="RBM Call Target Summary"
-
 
2031
            style="width:100%;min-height:800px;border:0;border-radius:10px;background:#fff;display:block"></iframe>
-
 
2032
  </div>
-
 
2033
 
-
 
2034
  <!-- Today PO & Billed — Brand × RBM matrix (reuses /indent/today_po_table_fragment) -->
2062
  <!-- Today PO & Billed — Brand × RBM matrix (reuses /indent/today_po_table_fragment) -->
2035
  <div class="sectionlabel">Today PO &amp; Billed — Brand &times; RBM</div>
2063
  <div class="sectionlabel">Today PO &amp; Billed — Brand &times; RBM</div>
2036
  <div class="card">
2064
  <div class="card">
2037
    <div class="card-hd">
2065
    <div class="card-hd">
2038
      <div>
2066
      <div>
Line 2055... Line 2083...
2055
        <div class="spinner"></div>
2083
        <div class="spinner"></div>
2056
        Loading&hellip;
2084
        Loading&hellip;
2057
      </div>
2085
      </div>
2058
    </div>
2086
    </div>
2059
  </div>
2087
  </div>
-
 
2088
 
-
 
2089
  <!-- RBM Call Target Summary — full interactive page injected via iframe srcdoc (no backend change) -->
-
 
2090
  <div class="sectionlabel">RBM Call Target Summary</div>
-
 
2091
  <div class="card">
-
 
2092
    <div class="card-hd">
-
 
2093
      <div>
-
 
2094
        <h2>Today's Call Coverage per RBM</h2>
-
 
2095
        <p class="desc">Full interactive view — all popups, drill-downs and downloads work exactly like the standalone
-
 
2096
          page.</p>
-
 
2097
      </div>
-
 
2098
      <a class="badge-period" href="/indent/rbm_call_target" target="_blank" style="text-decoration:none">Open in new
-
 
2099
        tab &rsaquo;</a>
-
 
2100
    </div>
-
 
2101
    <iframe id="rdrrCallFrame" title="RBM Call Target Summary"
-
 
2102
            style="width:100%;min-height:800px;border:0;border-radius:10px;background:#fff;display:block"></iframe>
-
 
2103
  </div>
2060
</div>
2104
</div>
2061
 
2105
 
2062
<!-- achieved-vs-pending modal (opens from the RBMs ≥ 100% Target KPI card) -->
2106
<!-- achieved-vs-pending modal (opens from the RBMs ≥ 100% Target KPI card) -->
2063
<div class="status-back" id="rdrrStatusBack">
2107
<div class="status-back" id="rdrrStatusBack">
2064
  <div class="status-modal">
2108
  <div class="status-modal">
Line 2076... Line 2120...
2076
      </div>
2120
      </div>
2077
    </div>
2121
    </div>
2078
  </div>
2122
  </div>
2079
</div>
2123
</div>
2080
 
2124
 
-
 
2125
<!-- call-target drill-down drawer (Called Partners / OOS Calls) -->
-
 
2126
<div class="rdrr-back" id="rdrrCallDrawerBack">
-
 
2127
  <div class="rdrr-panel">
-
 
2128
    <button class="x" id="rdrrCallDrawerClose" aria-label="Close">&times;</button>
-
 
2129
    <h3 id="rdrrCallDrawerTitle">&mdash;</h3>
-
 
2130
    <p class="desc" id="rdrrCallDrawerDesc">&mdash;</p>
-
 
2131
    <div id="rdrrCallDrawerBody">
-
 
2132
      <div class="loading">
-
 
2133
        <div class="spinner"></div>
-
 
2134
        Loading&hellip;
-
 
2135
      </div>
-
 
2136
    </div>
-
 
2137
  </div>
-
 
2138
</div>
-
 
2139
 
2081
<!-- drill-down panel -->
2140
<!-- drill-down panel -->
2082
<div class="rdrr-back" id="rdrrBack">
2141
<div class="rdrr-back" id="rdrrBack">
2083
  <div class="rdrr-panel">
2142
  <div class="rdrr-panel">
2084
    <button class="x" id="rdrrClose" aria-label="Close">&times;</button>
2143
    <button class="x" id="rdrrClose" aria-label="Close">&times;</button>
2085
    <h3 id="rdrrDdTitle">&mdash;</h3>
2144
    <h3 id="rdrrDdTitle">&mdash;</h3>
Line 2708... Line 2767...
2708
          $("#rdrrPerfWrap").html('<div class="empty">Failed to load performance dashboard.</div>');
2767
          $("#rdrrPerfWrap").html('<div class="empty">Failed to load performance dashboard.</div>');
2709
        }
2768
        }
2710
      });
2769
      });
2711
    }
2770
    }
2712
 
2771
 
-
 
2772
    // ------------------------- RBM Call Target iframe -------------------------
-
 
2773
    // The /indent/rbm_call_target endpoint returns a Velocity FRAGMENT (no <html>,
-
 
2774
    // no Bootstrap/jQuery). When loaded directly in an iframe, Bootstrap modals
-
 
2775
    // collapse and their inner Loading… contents render inline. Fix: fetch the
-
 
2776
    // fragment, wrap it in a self-contained document that loads jQuery + Popper +
-
 
2777
    // Bootstrap, then hand it to the iframe via srcdoc. Zero backend change.
-
 
2778
    function loadCallTargetIframe() {
-
 
2779
      $.ajax({
-
 
2780
        url: "/indent/rbm_call_target",
-
 
2781
        type: "GET",
-
 
2782
        dataType: "html",
-
 
2783
        success: function (fragment) {
-
 
2784
          var doc = [
-
 
2785
            '<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">',
-
 
2786
            '<meta name="viewport" content="width=device-width,initial-scale=1">',
-
 
2787
            '<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">',
-
 
2788
            '<style>body{margin:0;padding:16px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;background:#fff}</style>',
-
 
2789
            '</head><body>',
-
 
2790
            fragment,
-
 
2791
            '<script src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></' + 'script>',
-
 
2792
            '<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></' + 'script>',
-
 
2793
            '<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></' + 'script>',
-
 
2794
            '</body></html>'
-
 
2795
          ].join("");
-
 
2796
          var frame = document.getElementById("rdrrCallFrame");
-
 
2797
          frame.onload = function () {
-
 
2798
            hookCallTargetDrawer(frame);
-
 
2799
          };
-
 
2800
          frame.srcdoc = doc;
-
 
2801
        },
-
 
2802
        error: function () {
-
 
2803
          document.getElementById("rdrrCallFrame").srcdoc =
-
 
2804
                  '<div style="padding:24px;font-family:system-ui;color:#97a1b5">Failed to load call-target view.</div>';
-
 
2805
        }
-
 
2806
      });
-
 
2807
    }
-
 
2808
 
-
 
2809
    // Redirect the iframe's Bootstrap-modal drill-downs into a slide-in parent drawer
-
 
2810
    // that matches the dashboard style. srcdoc iframes inherit the parent origin so
-
 
2811
    // we can freely reach into the iframe's window and override its functions.
-
 
2812
    function hookCallTargetDrawer(frame) {
-
 
2813
      var iw = frame.contentWindow;
-
 
2814
      if (!iw) return;
-
 
2815
      // Give the source's own <script> a moment to run and define the functions.
-
 
2816
      setTimeout(function () {
-
 
2817
        try {
-
 
2818
          iw.showCalledPartnerDetails = function (authId, rbmName) {
-
 
2819
            openCallTargetDrawer("called", authId, rbmName, iw.pageQueryDate);
-
 
2820
          };
-
 
2821
          iw.showOutOfSequenceDetails = function (authId, rbmName) {
-
 
2822
            openCallTargetDrawer("oos", authId, rbmName, iw.pageQueryDate);
-
 
2823
          };
-
 
2824
        } catch (e) {
-
 
2825
          // If cross-origin ever kicks in (shouldn't with srcdoc same-origin),
-
 
2826
          // fall back to the iframe's native Bootstrap modal — no crash.
-
 
2827
        }
-
 
2828
      }, 50);
-
 
2829
    }
-
 
2830
 
-
 
2831
    function openCallTargetDrawer(kind, authId, rbmName, dateStr) {
-
 
2832
      var titleWho = rbmName + (dateStr ? " (" + dateStr + ")" : "");
-
 
2833
      var title = (kind === "oos" ? "Out of Sequence Calls — " : "Called Partners — ") + titleWho;
-
 
2834
      $("#rdrrCallDrawerTitle").text(title);
-
 
2835
      $("#rdrrCallDrawerDesc").text(kind === "oos"
-
 
2836
              ? "Calls placed outside the recommended sequence."
-
 
2837
              : "All calls made by this RBM today, with recordings.");
-
 
2838
      $("#rdrrCallDrawerBody").html('<div class="loading"><div class="spinner"></div>Loading&hellip;</div>');
-
 
2839
      $("#rdrrCallDrawerBack").addClass("show");
-
 
2840
 
-
 
2841
      var url;
-
 
2842
      if (kind === "oos") {
-
 
2843
        url = "/indent/rbm_call_target/oos_details?authId=" + encodeURIComponent(authId);
-
 
2844
      } else {
-
 
2845
        var dp = dateStr ? "&date=" + encodeURIComponent(dateStr) : "";
-
 
2846
        url = "/indent/rbm_call_target/called_details?authId=" + encodeURIComponent(authId)
-
 
2847
                + "&agentName=" + encodeURIComponent(rbmName) + dp;
-
 
2848
      }
-
 
2849
      $.ajax({
-
 
2850
        url: url, type: "GET", dataType: "json",
-
 
2851
        success: function (data) {
-
 
2852
          if (!data || data.length === 0) {
-
 
2853
            $("#rdrrCallDrawerBody").html('<div class="empty"><div class="ei">📭</div>No entries.</div>');
-
 
2854
            return;
-
 
2855
          }
-
 
2856
          $("#rdrrCallDrawerBody").html(kind === "oos" ? renderOosTable(data) : renderCalledTable(data));
-
 
2857
        },
-
 
2858
        error: function () {
-
 
2859
          $("#rdrrCallDrawerBody").html('<div class="empty">Failed to load details.</div>');
-
 
2860
        }
-
 
2861
      });
-
 
2862
    }
-
 
2863
 
-
 
2864
    function renderOosTable(data) {
-
 
2865
      var html = '<table><thead><tr><th>S.No</th><th>Party Name</th><th>Code</th><th>Time</th></tr></thead><tbody>';
-
 
2866
      data.forEach(function (r, i) {
-
 
2867
        html += '<tr><td>' + (i + 1) + '</td><td>' + escapeHtml(r.partyName || "-") +
-
 
2868
                '</td><td>' + escapeHtml(r.code || "-") + '</td><td>' + escapeHtml(r.time || "-") + '</td></tr>';
-
 
2869
      });
-
 
2870
      return html + '</tbody></table>';
-
 
2871
    }
-
 
2872
 
-
 
2873
    function renderCalledTable(data) {
-
 
2874
      var html = '<table><thead><tr>' +
-
 
2875
              '<th>S.No</th><th>Party Name</th><th>Code</th><th>Remark</th>' +
-
 
2876
              '<th>Call Status</th><th>Duration</th><th>Date/Time</th><th>Recording</th>' +
-
 
2877
              '</tr></thead><tbody>';
-
 
2878
      data.forEach(function (r, i) {
-
 
2879
        var rowStyle = "";
-
 
2880
        var recording = "-";
-
 
2881
        if (r.breakLog) {
-
 
2882
          var status = (r.breakStatus || "").toLowerCase();
-
 
2883
          if (status.indexOf("available") >= 0) rowStyle = 'style="background:#fdecec;color:#721c24"';
-
 
2884
          else if (status.indexOf("trying") >= 0) rowStyle = 'style="background:#fff5d6;color:#856404"';
-
 
2885
          else if (status.indexOf("logged out") >= 0 || status.indexOf("logout") >= 0) rowStyle = 'style="background:#eef0f4;color:#383d41"';
-
 
2886
          else if (status.indexOf("break") >= 0) rowStyle = 'style="background:#ffe5cc;color:#c45200"';
-
 
2887
        }
-
 
2888
        if (r.recordingUrl) {
-
 
2889
          recording = '<audio controls preload="none" src="' + escapeHtml(r.recordingUrl) + '"></audio>';
-
 
2890
        }
-
 
2891
        html += '<tr ' + rowStyle + '>' +
-
 
2892
                '<td>' + (i + 1) + '</td>' +
-
 
2893
                '<td>' + escapeHtml(r.partyName || (r.breakLog ? (r.breakStatus || "-") : "-")) + '</td>' +
-
 
2894
                '<td>' + escapeHtml(r.code || "-") + '</td>' +
-
 
2895
                '<td>' + escapeHtml(r.remark || "-") + '</td>' +
-
 
2896
                '<td>' + escapeHtml(r.callStatus || "-") + '</td>' +
-
 
2897
                '<td>' + escapeHtml(r.callDuration || "-") + '</td>' +
-
 
2898
                '<td>' + escapeHtml(r.callDateTime || "-") + '</td>' +
-
 
2899
                '<td>' + recording + '</td>' +
-
 
2900
                '</tr>';
-
 
2901
      });
-
 
2902
      return html + '</tbody></table>';
-
 
2903
    }
-
 
2904
 
-
 
2905
    $("#rdrrCallDrawerClose").on("click", function () {
-
 
2906
      $("#rdrrCallDrawerBack").removeClass("show");
-
 
2907
    });
-
 
2908
    $("#rdrrCallDrawerBack").on("click", function (e) {
-
 
2909
      if (e.target === this) $(this).removeClass("show");
-
 
2910
    });
-
 
2911
 
2713
    // initial load
2912
    // initial load
2714
    load();
2913
    load();
2715
    loadPurchaseMilestones();
2914
    loadPurchaseMilestones();
2716
    loadPerformanceDashboard();
2915
    loadPerformanceDashboard();
-
 
2916
    loadCallTargetIframe();
2717
  })();
2917
  })();
2718
</script>
2918
</script>
2719
</body>
2919
</body>
2720
</html>
2920
</html>