{"id":3436,"date":"2025-07-29T10:27:20","date_gmt":"2025-07-29T08:27:20","guid":{"rendered":"https:\/\/j-cred.co.za\/?page_id=3436"},"modified":"2025-07-29T10:30:51","modified_gmt":"2025-07-29T08:30:51","slug":"bidashboard","status":"publish","type":"page","link":"https:\/\/j-cred.co.za\/zh\/bidashboard\/","title":{"rendered":"bidashboard"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>J-Cred BI Portal<\/title>\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/PapaParse\/5.3.2\/papaparse.min.js\"><\/script>\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js\"><\/script>\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/flatpickr\"><\/script>\n    <link rel=\"stylesheet\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/flatpickr\/dist\/flatpickr.min.css\">\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;display=swap\" rel=\"stylesheet\">\n    <style>\n        body {\n            font-family: 'Inter', sans-serif;\n            background-color: #f3f4f6;\n        }\n        .chart-container {\n            position: relative;\n            margin: auto;\n            height: 350px;\n            width: 100%;\n        }\n        .table-container {\n            max-height: 500px;\n            overflow-y: auto;\n        }\n        .flatpickr-calendar {\n            background-color: #fff;\n            border-radius: 0.5rem;\n            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n        }\n        .flatpickr-day.selected {\n            background: #4f46e5;\n            border-color: #4f46e5;\n        }\n        .sidebar-link.active {\n            background-color: #4f46e5;\n            color: white;\n            font-weight: 600;\n        }\n        .page-content {\n            display: none;\n        }\n        .page-content.active {\n            display: block;\n        }\n        \/* Tooltip styles *\/\n        .tooltip-container {\n            position: relative;\n        }\n        .tooltip {\n            visibility: hidden;\n            opacity: 0;\n            transition: opacity 0.3s;\n        }\n        .tooltip-container:hover .tooltip {\n            visibility: visible;\n            opacity: 1;\n        }\n\n        @media print {\n            body * {\n                visibility: hidden;\n            }\n            #print-area, #print-area * {\n                visibility: visible;\n            }\n            #print-area {\n                position: absolute;\n                left: 0;\n                top: 0;\n                width: 100%;\n            }\n            .no-print {\n                display: none;\n            }\n        }\n    <\/style>\n<\/head>\n<body class=\"text-gray-800\">\n\n    <!-- Login Page -->\n    <div id=\"login-page\" class=\"flex items-center justify-center min-h-screen bg-gray-50\">\n        <div class=\"w-full max-w-md p-8 space-y-8 bg-white rounded-xl shadow-lg\">\n            <div class=\"text-center\">\n                <img decoding=\"async\" src=\"https:\/\/j-cred.co.za\/wp-content\/uploads\/2024\/12\/Group-1285.svg\" alt=\"J-Cred BI Portal Logo\" class=\"mx-auto h-12 w-auto\">\n                <p id=\"login-prompt\" class=\"mt-4 text-gray-600\">Sign in to access your dashboard<\/p>\n            <\/div>\n            \n            <!-- Username\/Password Form -->\n            <form id=\"login-form\" class=\"mt-8 space-y-6\">\n                <div id=\"credentials-section\">\n                    <div class=\"relative\">\n                        <label for=\"username\" class=\"sr-only\">Username<\/label>\n                        <input id=\"username\" name=\"username\" type=\"text\" required class=\"relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\" placeholder=\"Username\">\n                    <\/div>\n                    <div class=\"relative mt-4\">\n                        <label for=\"password\" class=\"sr-only\">Password<\/label>\n                        <input id=\"password\" name=\"password\" type=\"password\" required class=\"relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\" placeholder=\"Password\">\n                    <\/div>\n                <\/div>\n                <div>\n                    <button id=\"login-submit-btn\" type=\"submit\" class=\"group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\">\n                        Sign in\n                    <\/button>\n                <\/div>\n                <p id=\"login-error\" class=\"text-center text-red-500 text-sm mt-2\"><\/p>\n            <\/form>\n        <\/div>\n    <\/div>\n\n    <!-- Main Portal -->\n    <div id=\"portal-app\" class=\"hidden\">\n        <div class=\"flex h-screen bg-gray-100\">\n            <!-- Sidebar -->\n            <div id=\"sidebar\" class=\"w-64 bg-gray-800 text-white flex flex-col no-print\">\n                <div class=\"h-16 flex items-center justify-center px-4\">\n                     <img decoding=\"async\" src=\"https:\/\/j-cred.co.za\/wp-content\/uploads\/2024\/12\/Group-1285.svg\" alt=\"J-Cred BI Portal Logo\" class=\"h-10 w-auto\" style=\"filter: brightness(0) invert(1);\">\n                <\/div>\n                <nav id=\"sidebar-nav\" class=\"flex-1 px-2 py-4 space-y-2\">\n                    <a href=\"#\" class=\"sidebar-link flex items-center px-4 py-2 rounded-md text-sm\" data-page=\"descriptive\"><svg class=\"w-5 h-5 mr-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z\"><\/path><\/svg>Descriptive<\/a>\n                    <a href=\"#\" class=\"sidebar-link flex items-center px-4 py-2 rounded-md text-sm\" data-page=\"diagnostic\"><svg class=\"w-5 h-5 mr-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16l2.879-2.879a1 1 0 011.414 0L15 15m-3-3l-2.879 2.879a1 1 0 01-1.414 0L5 12m5 6a7 7 0 110-14 7 7 0 010 14z\"><\/path><\/svg>Diagnostic<\/a>\n                    <a href=\"#\" class=\"sidebar-link flex items-center px-4 py-2 rounded-md text-sm\" data-page=\"predictive\"><svg class=\"w-5 h-5 mr-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 7h8m0 0v8m0-8l-8 8-4-4-6 6\"><\/path><\/svg>Predictive<\/a>\n                    <a href=\"#\" class=\"sidebar-link flex items-center px-4 py-2 rounded-md text-sm\" data-page=\"prescriptive\"><svg class=\"w-5 h-5 mr-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z\"><\/path><\/svg>Prescriptive<\/a>\n                    <a href=\"#\" class=\"sidebar-link flex items-center px-4 py-2 rounded-md text-sm\" data-page=\"data\"><svg class=\"w-5 h-5 mr-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 10h16M4 14h16M4 18h16\"><\/path><\/svg>Data Explorer<\/a>\n                <\/nav>\n                <div class=\"p-4\">\n                    <button id=\"logout-btn\" class=\"w-full flex items-center justify-center px-4 py-2 rounded-md text-sm bg-red-500 hover:bg-red-600\">\n                        <svg class=\"w-5 h-5 mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1\"><\/path><\/svg>\n                        Logout\n                    <\/button>\n                <\/div>\n            <\/div>\n\n            <!-- Main content -->\n            <div class=\"flex-1 flex flex-col overflow-hidden\">\n                <header class=\"flex justify-between items-center p-4 bg-white border-b no-print\">\n                    <h2 id=\"page-title\" class=\"text-2xl font-semibold text-gray-800\">Descriptive<\/h2>\n                    <button id=\"print-btn-main\" class=\"inline-flex items-center gap-2 rounded-md border border-gray-300 bg-white py-2 px-4 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50\">\n                        <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\"><path d=\"M2.5 8a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1z\"\/><path d=\"M5 1a2 2 0 0 0-2 2v2H2a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h1v1a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-1h1a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-1V3a2 2 0 0 0-2-2H5zM4 3a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2H4V3zm1 5a2 2 0 0 0-2 2v1H2a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v-1a2 2 0 0 0-2-2H5zm7 2v3a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-3h8z\"\/><\/svg>\n                        Print Report\n                    <\/button>\n                <\/header>\n                <main id=\"main-content\" class=\"flex-1 overflow-x-hidden overflow-y-auto bg-gray-100 p-8\">\n                    <div id=\"upload-container\" class=\"text-center\">\n                        <div class=\"max-w-2xl mx-auto bg-white p-8 rounded-xl shadow-lg transition-all\">\n                             <h3 class=\"text-xl font-semibold text-gray-800 mb-4\">Upload Your Data File<\/h3>\n                             <p class=\"text-gray-600 mb-6\">Please upload the daily CSV spreadsheet to populate the portal.<\/p>\n                            <div class=\"flex items-center justify-center w-full\">\n                                <label for=\"csv-file-input\" class=\"flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100\">\n                                    <div class=\"flex flex-col items-center justify-center pt-5 pb-6\">\n                                        <svg class=\"w-10 h-10 mb-4 text-gray-500\" aria-hidden=\"true\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" fill=\"none\" viewBox=\"0 0 20 16\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2\"\/><\/svg>\n                                        <p class=\"mb-2 text-sm text-gray-500\"><span class=\"font-semibold\">Click to upload<\/span> or drag and drop<\/p>\n                                        <p class=\"text-xs text-gray-500\">CSV, XLSX (exported as CSV)<\/p>\n                                    <\/div>\n                                    <input id=\"csv-file-input\" type=\"file\" class=\"hidden\" accept=\".csv\" \/>\n                                <\/label>\n                            <\/div>\n                            <div id=\"file-info\" class=\"text-center mt-4 text-gray-600\"><\/div>\n                            <div id=\"error-message\" class=\"text-center mt-4 text-red-500\"><\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div id=\"data-display-area\" class=\"hidden\">\n                        <div id=\"print-area\">\n                            <!-- Advanced Filters -->\n                            <div class=\"bg-white p-6 rounded-xl shadow mb-8 no-print\">\n                                <h3 class=\"text-lg font-semibold mb-4 text-gray-800\">Filter Your Data<\/h3>\n                                <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4\">\n                                    <div><label for=\"start-date\" class=\"block text-sm font-medium text-gray-700\">Start Date<\/label><input type=\"text\" id=\"start-date\" placeholder=\"Select start date\" class=\"mt-1 block w-full rounded-md border-gray-300 shadow-sm\"><\/div>\n                                    <div><label for=\"end-date\" class=\"block text-sm font-medium text-gray-700\">End Date<\/label><input type=\"text\" id=\"end-date\" placeholder=\"Select end date\" class=\"mt-1 block w-full rounded-md border-gray-300 shadow-sm\"><\/div>\n                                    <div><label for=\"filter-column\" class=\"block text-sm font-medium text-gray-700\">Filter By Column<\/label><select id=\"filter-column\" class=\"mt-1 block w-full rounded-md border-gray-300 shadow-sm\"><option value=\"\">&#8212; Select Column &#8212;<\/option><\/select><\/div>\n                                    <div><label for=\"filter-value\" class=\"block text-sm font-medium text-gray-700\">Value<\/label><select id=\"filter-value\" class=\"mt-1 block w-full rounded-md border-gray-300 shadow-sm\" disabled><option value=\"\">&#8212; Select Value &#8212;<\/option><\/select><\/div>\n                                <\/div>\n                                <div class=\"mt-6 flex flex-col sm:flex-row gap-3\">\n                                    <button id=\"apply-filters-btn\" class=\"w-full sm:w-auto inline-flex justify-center rounded-md border border-transparent bg-indigo-600 py-2 px-4 text-sm font-medium text-white shadow-sm hover:bg-indigo-700\">Apply Filters<\/button>\n                                    <button id=\"clear-filters-btn\" class=\"w-full sm:w-auto inline-flex justify-center rounded-md border border-gray-300 bg-white py-2 px-4 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50\">Clear Filters<\/button>\n                                <\/div>\n                            <\/div>\n                            \n                            <!-- Page Content -->\n                            <div id=\"descriptive\" class=\"page-content\">\n                                <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8\">\n                                    <div class=\"bg-white p-6 rounded-xl shadow tooltip-container\"><div class=\"flex items-center\"><h3 class=\"text-gray-500 text-sm font-medium\">Total Requests<\/h3><svg class=\"w-4 h-4 ml-2 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"><\/path><\/svg><\/div><p id=\"summary-total-requests\" class=\"text-3xl font-bold text-indigo-600\">0<\/p><div class=\"tooltip absolute bottom-full mb-2 w-64 bg-gray-800 text-white text-xs rounded py-2 px-3 pointer-events-none z-10\"><p>The total number of requests that match the current filter criteria.<\/p><svg class=\"absolute text-gray-800 h-2 w-full left-0 top-full\" x=\"0px\" y=\"0px\" viewBox=\"0 0 255 255\" xml:space=\"preserve\"><polygon class=\"fill-current\" points=\"0,0 127.5,127.5 255,0\"\/><\/svg><\/div><\/div>\n                                    <div class=\"bg-white p-6 rounded-xl shadow tooltip-container\"><div class=\"flex items-center\"><h3 class=\"text-gray-500 text-sm font-medium\">Avg. Turnaround (Hrs)<\/h3><svg class=\"w-4 h-4 ml-2 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"><\/path><\/svg><\/div><p id=\"summary-avg-tat\" class=\"text-3xl font-bold text-indigo-600\">0<\/p><div class=\"tooltip absolute bottom-full mb-2 w-64 bg-gray-800 text-white text-xs rounded py-2 px-3 pointer-events-none z-10\"><p>The average time taken, in hours, from request creation to completion for all completed requests in this period.<\/p><svg class=\"absolute text-gray-800 h-2 w-full left-0 top-full\" x=\"0px\" y=\"0px\" viewBox=\"0 0 255 255\" xml:space=\"preserve\"><polygon class=\"fill-current\" points=\"0,0 127.5,127.5 255,0\"\/><\/svg><\/div><\/div>\n                                    <div class=\"bg-white p-6 rounded-xl shadow tooltip-container\"><div class=\"flex items-center\"><h3 class=\"text-gray-500 text-sm font-medium\">SLA Compliance<\/h3><svg class=\"w-4 h-4 ml-2 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"><\/path><\/svg><\/div><p id=\"summary-sla-compliance\" class=\"text-3xl font-bold text-green-600\">0%<\/p><div class=\"tooltip absolute bottom-full mb-2 w-64 bg-gray-800 text-white text-xs rounded py-2 px-3 pointer-events-none z-10\"><p>The percentage of completed requests that were finished within their defined Service Level Agreement (SLA) time.<\/p><svg class=\"absolute text-gray-800 h-2 w-full left-0 top-full\" x=\"0px\" y=\"0px\" viewBox=\"0 0 255 255\" xml:space=\"preserve\"><polygon class=\"fill-current\" points=\"0,0 127.5,127.5 255,0\"\/><\/svg><\/div><\/div>\n                                    <div class=\"bg-white p-6 rounded-xl shadow tooltip-container\"><div class=\"flex items-center\"><h3 class=\"text-gray-500 text-sm font-medium\">Open Requests<\/h3><svg class=\"w-4 h-4 ml-2 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"><\/path><\/svg><\/div><p id=\"summary-open-requests\" class=\"text-3xl font-bold text-yellow-500\">0<\/p><div class=\"tooltip absolute bottom-full mb-2 w-64 bg-gray-800 text-white text-xs rounded py-2 px-3 pointer-events-none z-10\"><p>The number of requests that are currently in &#8216;Open&#8217; or &#8216;InProgress&#8217; status.<\/p><svg class=\"absolute text-gray-800 h-2 w-full left-0 top-full\" x=\"0px\" y=\"0px\" viewBox=\"0 0 255 255\" xml:space=\"preserve\"><polygon class=\"fill-current\" points=\"0,0 127.5,127.5 255,0\"\/><\/svg><\/div><\/div>\n                                <\/div>\n                                <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-8 mb-8\">\n                                    <div class=\"bg-white p-6 rounded-xl shadow\"><div class=\"tooltip-container inline-block\"><h3 class=\"text-lg font-semibold mb-4 text-center\">Request Volume Trend <svg class=\"w-4 h-4 inline text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"><\/path><\/svg><\/h3><div class=\"tooltip absolute bottom-full mb-2 w-64 bg-gray-800 text-white text-xs rounded py-2 px-3 pointer-events-none z-10 left-1\/2 -translate-x-1\/2\"><p>This chart shows the number of new requests created each day over the selected period.<\/p><svg class=\"absolute text-gray-800 h-2 w-full left-0 top-full\" x=\"0px\" y=\"0px\" viewBox=\"0 0 255 255\" xml:space=\"preserve\"><polygon class=\"fill-current\" points=\"0,0 127.5,127.5 255,0\"\/><\/svg><\/div><\/div><div class=\"chart-container\"><canvas id=\"summary-volume-trend-chart\"><\/canvas><\/div><\/div>\n                                    <div class=\"bg-white p-6 rounded-xl shadow\"><div class=\"tooltip-container inline-block\"><h3 class=\"text-lg font-semibold mb-4 text-center\">Requests by Status <svg class=\"w-4 h-4 inline text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"><\/path><\/svg><\/h3><div class=\"tooltip absolute bottom-full mb-2 w-64 bg-gray-800 text-white text-xs rounded py-2 px-3 pointer-events-none z-10 left-1\/2 -translate-x-1\/2\"><p>A breakdown of all requests by their current status (e.g., Open, InProgress, Completed).<\/p><svg class=\"absolute text-gray-800 h-2 w-full left-0 top-full\" x=\"0px\" y=\"0px\" viewBox=\"0 0 255 255\" xml:space=\"preserve\"><polygon class=\"fill-current\" points=\"0,0 127.5,127.5 255,0\"\/><\/svg><\/div><\/div><div class=\"chart-container\"><canvas id=\"summary-status-chart\"><\/canvas><\/div><\/div>\n                                <\/div>\n                            <\/div>\n                            <div id=\"diagnostic\" class=\"page-content\">\n                                <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-8 mb-8\">\n                                    <div class=\"bg-white p-6 rounded-xl shadow\"><div class=\"tooltip-container inline-block\"><h3 class=\"text-lg font-semibold mb-4 text-center\">Requests per Client <svg class=\"w-4 h-4 inline text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"><\/path><\/svg><\/h3><div class=\"tooltip absolute bottom-full mb-2 w-64 bg-gray-800 text-white text-xs rounded py-2 px-3 pointer-events-none z-10 left-1\/2 -translate-x-1\/2\"><p>The total number of requests logged by each company or client.<\/p><svg class=\"absolute text-gray-800 h-2 w-full left-0 top-full\" x=\"0px\" y=\"0px\" viewBox=\"0 0 255 255\" xml:space=\"preserve\"><polygon class=\"fill-current\" points=\"0,0 127.5,127.5 255,0\"\/><\/svg><\/div><\/div><div class=\"chart-container\"><canvas id=\"client-requests-chart\"><\/canvas><\/div><\/div>\n                                    <div class=\"bg-white p-6 rounded-xl shadow\"><div class=\"tooltip-container inline-block\"><h3 class=\"text-lg font-semibold mb-4 text-center\">Avg. Turnaround Time per Client (Hrs) <svg class=\"w-4 h-4 inline text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"><\/path><\/svg><\/h3><div class=\"tooltip absolute bottom-full mb-2 w-64 bg-gray-800 text-white text-xs rounded py-2 px-3 pointer-events-none z-10 left-1\/2 -translate-x-1\/2\"><p>The average time it takes to complete requests for each specific client, helping to identify efficiency per account.<\/p><svg class=\"absolute text-gray-800 h-2 w-full left-0 top-full\" x=\"0px\" y=\"0px\" viewBox=\"0 0 255 255\" xml:space=\"preserve\"><polygon class=\"fill-current\" points=\"0,0 127.5,127.5 255,0\"\/><\/svg><\/div><\/div><div class=\"chart-container\"><canvas id=\"client-tat-chart\"><\/canvas><\/div><\/div>\n                                <\/div>\n                                <div class=\"bg-white p-6 rounded-xl shadow\"><div class=\"tooltip-container inline-block\"><h3 class=\"text-lg font-semibold mb-4\">Monthly Billing Report <svg class=\"w-4 h-4 inline text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"><\/path><\/svg><\/h3><div class=\"tooltip absolute bottom-full mb-2 w-64 bg-gray-800 text-white text-xs rounded py-2 px-3 pointer-events-none z-10\"><p>A summary of the total number of requests per client, useful for monthly billing and client reviews.<\/p><svg class=\"absolute text-gray-800 h-2 w-full left-0 top-full\" x=\"0px\" y=\"0px\" viewBox=\"0 0 255 255\" xml:space=\"preserve\"><polygon class=\"fill-current\" points=\"0,0 127.5,127.5 255,0\"\/><\/svg><\/div><\/div><p class=\"text-sm text-gray-500 mb-4\">Summary of billable requests. Use filters for specific date ranges.<\/p><div class=\"table-container\"><table id=\"billing-table\" class=\"min-w-full divide-y divide-gray-200\"><thead class=\"bg-gray-50\"><\/thead><tbody class=\"bg-white divide-y divide-gray-200\"><\/tbody><\/table><\/div><\/div>\n                            <\/div>\n                            <div id=\"predictive\" class=\"page-content\">\n                                <!-- Predictive Analytics Content -->\n                            <\/div>\n                            <div id=\"prescriptive\" class=\"page-content\">\n                                <!-- Prescriptive Analytics Content -->\n                            <\/div>\n                            <div id=\"data\" class=\"page-content\">\n                                <div class=\"bg-white p-6 rounded-xl shadow\"><h3 class=\"text-lg font-semibold mb-4\">Raw Data Explorer<\/h3><div class=\"table-container\"><table id=\"data-table\" class=\"min-w-full divide-y divide-gray-200\"><thead class=\"bg-gray-50\"><\/thead><tbody class=\"bg-white divide-y divide-gray-200\"><\/tbody><\/table><\/div><div id=\"pagination-controls\" class=\"flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6 mt-4\"><\/div><\/div>\n                            <\/div>\n                            <div id=\"no-data-message\" class=\"hidden text-center bg-white p-8 rounded-xl shadow\"><h3 class=\"text-xl font-semibold text-gray-700\">No Data Found<\/h3><p class=\"text-gray-500 mt-2\">There is no data matching your filter criteria.<\/p><\/div>\n                        <\/div>\n                    <\/div>\n                <\/main>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <script type=\"module\">\n        function parseCustomDate(dateString) {\n            if (!dateString || typeof dateString !== 'string') return null;\n            const parts = dateString.match(\/(\\d{2})\\\/(\\d{2})\\\/(\\d{4}), (\\d{2}):(\\d{2}):(\\d{2})\/);\n            if (!parts) {\n                const isoDate = new Date(dateString);\n                return isNaN(isoDate) ? null : isoDate;\n            }\n            return new Date(parts[3], parts[2] - 1, parts[1], parts[4], parts[5], parts[6]);\n        }\n\n        document.addEventListener('DOMContentLoaded', () => {\n            \/\/ Page Elements\n            const loginPage = document.getElementById('login-page');\n            const portalApp = document.getElementById('portal-app');\n            const loginForm = document.getElementById('login-form');\n            const loginError = document.getElementById('login-error');\n            const logoutBtn = document.getElementById('logout-btn');\n            const sidebarNav = document.getElementById('sidebar-nav');\n            const pageTitle = document.getElementById('page-title');\n            const uploadContainer = document.getElementById('upload-container');\n            const dataDisplayArea = document.getElementById('data-display-area');\n\n            \/\/ Data Elements\n            const fileInput = document.getElementById('csv-file-input');\n            const fileInfo = document.getElementById('file-info');\n            const errorMessage = document.getElementById('error-message');\n            const applyFiltersBtn = document.getElementById('apply-filters-btn');\n            const clearFiltersBtn = document.getElementById('clear-filters-btn');\n            const filterColumnSelect = document.getElementById('filter-column');\n            const filterValueSelect = document.getElementById('filter-value');\n            const noDataMessage = document.getElementById('no-data-message');\n            const printBtnMain = document.getElementById('print-btn-main');\n\n            let chartInstances = {};\n            let fullData = [];\n            let currentHeaders = [];\n            const ROWS_PER_PAGE = 10;\n            let currentPage = 1;\n            let startDatePicker, endDatePicker;\n\n            \/\/ --- Initial Setup & Event Listeners ---\n            \n            \/\/ Login\/Logout Logic\n            loginForm.addEventListener('submit', (e) => {\n                e.preventDefault();\n                const username = e.target.username.value;\n                const password = e.target.password.value;\n                \/\/ Simple validation for simulation\n                if (username === 'admin' && password === 'password') {\n                    loginPage.classList.add('hidden');\n                    portalApp.classList.remove('hidden');\n                    setActivePage('descriptive');\n                } else {\n                    loginError.textContent = 'Invalid username or password.';\n                }\n            });\n\n            logoutBtn.addEventListener('click', () => {\n                portalApp.classList.add('hidden');\n                loginPage.classList.remove('hidden');\n                loginError.textContent = '';\n                loginForm.reset();\n            });\n\n            \/\/ Sidebar Navigation\n            sidebarNav.addEventListener('click', (e) => {\n                e.preventDefault();\n                const link = e.target.closest('.sidebar-link');\n                if (link) {\n                    setActivePage(link.dataset.page);\n                }\n            });\n\n            \/\/ File Upload & Data Processing\n            fileInput.addEventListener('change', handleFileSelect);\n            const dropZone = document.querySelector('[for=\"csv-file-input\"]');\n            dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.classList.add('bg-gray-200'); });\n            dropZone.addEventListener('dragleave', (e) => { e.preventDefault(); dropZone.classList.remove('bg-gray-200'); });\n            dropZone.addEventListener('drop', (e) => {\n                e.preventDefault();\n                dropZone.classList.remove('bg-gray-200');\n                const files = e.dataTransfer.files;\n                if (files.length) { fileInput.files = files; handleFileSelect({ target: fileInput }); }\n            });\n            \n            \/\/ Filters and Print\n            applyFiltersBtn.addEventListener('click', applyFilters);\n            clearFiltersBtn.addEventListener('click', clearFilters);\n            filterColumnSelect.addEventListener('change', handleColumnFilterChange);\n            printBtnMain.addEventListener('click', () => window.print());\n\n            \/\/ --- Functions ---\n            \n            function setActivePage(pageId) {\n                \/\/ Update sidebar links\n                sidebarNav.querySelectorAll('.sidebar-link').forEach(link => {\n                    link.classList.toggle('active', link.dataset.page === pageId);\n                });\n                \/\/ Update page title\n                const activeLink = sidebarNav.querySelector(`.sidebar-link[data-page=\"${pageId}\"]`);\n                pageTitle.textContent = activeLink ? activeLink.textContent : 'Descriptive';\n                \n                \/\/ Show\/hide page content\n                document.querySelectorAll('.page-content').forEach(page => {\n                    page.classList.toggle('active', page.id === pageId);\n                });\n            }\n\n            function handleFileSelect(event) {\n                const file = event.target.files[0];\n                if (!file) return;\n                if (file.type !== 'text\/csv' && !file.name.endsWith('.csv')) {\n                    errorMessage.textContent = 'Error: Please upload a valid .csv file.'; return;\n                }\n                fileInfo.textContent = `Processing file: ${file.name}`;\n                errorMessage.textContent = '';\n\n                Papa.parse(file, {\n                    header: true, skipEmptyLines: true,\n                    complete: (results) => {\n                        if (results.errors.length) {\n                            errorMessage.textContent = 'Error parsing CSV. Check format.'; console.error('Parsing errors:', results.errors); return;\n                        }\n                        fullData = results.data.map(row => ({\n                            ...row,\n                            _dateCreated: parseCustomDate(row['Date Created']),\n                            _tatHours: parseFloat(row['SLA Time Elapsed']?.replace(' Hrs', '')) || 0\n                        }));\n                        currentHeaders = results.meta.fields;\n                        \n                        uploadContainer.classList.add('hidden');\n                        dataDisplayArea.classList.remove('hidden');\n                        \n                        startDatePicker = flatpickr(\"#start-date\", { dateFormat: \"Y-m-d\" });\n                        endDatePicker = flatpickr(\"#end-date\", { dateFormat: \"Y-m-d\" });\n\n                        setupFilterControls(currentHeaders);\n                        renderDashboard(fullData, currentHeaders);\n                    },\n                    error: (error) => { errorMessage.textContent = 'An unexpected error occurred.'; console.error('PapaParse error:', error); }\n                });\n            }\n\n            function setupFilterControls(headers) {\n                filterColumnSelect.innerHTML = '<option value=\"\">-- Select Column --<\/option>';\n                headers.forEach(header => {\n                    const option = document.createElement('option');\n                    option.value = header;\n                    option.textContent = header;\n                    filterColumnSelect.appendChild(option);\n                });\n            }\n\n            function handleColumnFilterChange() {\n                const selectedColumn = filterColumnSelect.value;\n                filterValueSelect.innerHTML = '<option value=\"\">-- Select Value --<\/option>';\n                if (!selectedColumn) { filterValueSelect.disabled = true; return; }\n                const uniqueValues = [...new Set(fullData.map(row => row[selectedColumn]).filter(Boolean))].sort();\n                uniqueValues.forEach(value => {\n                    const option = document.createElement('option');\n                    option.value = value;\n                    option.textContent = value;\n                    filterValueSelect.appendChild(option);\n                });\n                filterValueSelect.disabled = false;\n            }\n\n            function applyFilters() {\n                let filteredData = [...fullData];\n                const startDate = startDatePicker.selectedDates[0];\n                const endDate = endDatePicker.selectedDates[0];\n                const filterColumn = filterColumnSelect.value;\n                const filterValue = filterValueSelect.value;\n\n                if (startDate && endDate) {\n                    const inclusiveEndDate = new Date(endDate);\n                    inclusiveEndDate.setHours(23, 59, 59, 999);\n                    filteredData = filteredData.filter(row => row._dateCreated && row._dateCreated >= startDate && row._dateCreated <= inclusiveEndDate);\n                }\n                if (filterColumn &#038;&#038; filterValue) {\n                    filteredData = filteredData.filter(row => row[filterColumn] === filterValue);\n                }\n                currentPage = 1;\n                renderDashboard(filteredData, currentHeaders);\n            }\n\n            function clearFilters() {\n                if(startDatePicker) startDatePicker.clear();\n                if(endDatePicker) endDatePicker.clear();\n                filterColumnSelect.value = '';\n                filterValueSelect.innerHTML = '<option value=\"\">-- Select Value --<\/option>';\n                filterValueSelect.disabled = true;\n                currentPage = 1;\n                renderDashboard(fullData, currentHeaders);\n            }\n\n            function renderDashboard(data, headers) {\n                const hasData = data && data.length > 0;\n                noDataMessage.classList.toggle('hidden', !hasData);\n                \n                 document.querySelectorAll('.page-content').forEach(el => {\n                    if (!el.classList.contains('active')) {\n                        el.style.display = 'none';\n                    } else {\n                         el.style.display = hasData ? 'block' : 'none';\n                    }\n                });\n\n                if (!hasData) {\n                    Object.values(chartInstances).forEach(chart => chart.destroy());\n                    chartInstances = {};\n                    return;\n                }\n\n                Object.values(chartInstances).forEach(chart => chart.destroy());\n                chartInstances = {};\n\n                \/\/ --- Descriptive Analytics ---\n                const totalRequests = data.length;\n                const totalTAT = data.reduce((sum, row) => sum + row._tatHours, 0);\n                const avgTAT = totalRequests > 0 ? (totalTAT \/ totalRequests).toFixed(1) : 0;\n                const slaMetCount = data.filter(row => row['SLA Status'] === 'Within SLA').length;\n                const slaCompliance = totalRequests > 0 ? ((slaMetCount \/ totalRequests) * 100).toFixed(0) : 0;\n                const openRequests = data.filter(row => ['Open', 'InProgress'].includes(row['Status'])).length;\n\n                document.getElementById('summary-total-requests').textContent = totalRequests;\n                document.getElementById('summary-avg-tat').textContent = avgTAT;\n                document.getElementById('summary-sla-compliance').textContent = `${slaCompliance}%`;\n                document.getElementById('summary-open-requests').textContent = openRequests;\n                \n                const volumeByDate = groupBy(data, row => row._dateCreated ? new Date(row._dateCreated).toISOString().split('T')[0] : 'Unknown');\n                const trendLabels = Object.keys(volumeByDate).sort();\n                const trendData = trendLabels.map(label => volumeByDate[label].length);\n                createChart('summary-volume-trend-chart', 'line', {labels: trendLabels, data: trendData}, 'Request Volume');\n                \n                const statusCounts = countOccurrences(data, 'Status');\n                createChart('summary-status-chart', 'pie', statusCounts, 'Status');\n\n                \/\/ --- Diagnostic Analytics ---\n                const requestsByClient = countOccurrences(data, 'Company', 'No Company');\n                createChart('client-requests-chart', 'bar', requestsByClient, 'Requests');\n                \n                const clientTat = calculateAverage(data, 'Company', '_tatHours', 'No Company');\n                createChart('client-tat-chart', 'bar', clientTat, 'Avg. TAT (Hrs)');\n                \n                renderBillingTable(data);\n\n                \/\/ --- Predictive & Prescriptive (placeholder) ---\n                \/\/ In a real app, you'd have more complex logic here.\n                document.getElementById('predictive').innerHTML = `<div class=\"bg-white p-6 rounded-xl shadow\"><h3 class=\"text-lg font-semibold mb-4 text-center\">Predictive Analytics<\/h3><p class=\"text-center text-gray-500\">Predictive analytics features are under development.<\/p><\/div>`;\n                document.getElementById('prescriptive').innerHTML = `<div class=\"bg-white p-6 rounded-xl shadow\"><h3 class=\"text-lg font-semibold mb-4 text-center\">Prescriptive Analytics<\/h3><p class=\"text-center text-gray-500\">Prescriptive analytics features are under development.<\/p><\/div>`;\n\n\n                \/\/ --- Data Explorer ---\n                populateTable(data, headers);\n            }\n            \n            function renderBillingTable(data) {\n                const table = document.getElementById('billing-table');\n                const thead = table.querySelector('thead');\n                const tbody = table.querySelector('tbody');\n                thead.innerHTML = `<tr><th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase\">Company<\/th><th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase\">Request Count<\/th><\/tr>`;\n                const billingData = countOccurrences(data, 'Company', 'No Company');\n                tbody.innerHTML = Object.entries(billingData)\n                    .sort((a, b) => b[1] - a[1])\n                    .map(([company, count]) => `<tr><td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-700\">${company}<\/td><td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-700\">${count}<\/td><\/tr>`)\n                    .join('');\n            }\n\n            function countOccurrences(data, col, def = 'N\/A') {\n                return data.reduce((acc, row) => {\n                    const key = row[col] ? row[col].trim() : def;\n                    acc[key] = (acc[key] || 0) + 1;\n                    return acc;\n                }, {});\n            }\n            \n            function groupBy(array, keyGetter) {\n                const map = new Map();\n                array.forEach((item) => {\n                     const key = keyGetter(item);\n                     const collection = map.get(key);\n                     if (!collection) { map.set(key, [item]); } else { collection.push(item); }\n                });\n                return Object.fromEntries(map);\n            }\n            \n            function calculateAverage(data, groupCol, valueCol, defGroup = 'N\/A') {\n                const groups = groupBy(data, row => row[groupCol] || defGroup);\n                const averages = {};\n                for (const groupName in groups) {\n                    const groupData = groups[groupName];\n                    const total = groupData.reduce((sum, row) => sum + row[valueCol], 0);\n                    averages[groupName] = groupData.length > 0 ? (total \/ groupData.length).toFixed(1) : 0;\n                }\n                return averages;\n            }\n\n            function createChart(id, type, dataObj, label) {\n                const ctx = document.getElementById(id)?.getContext('2d');\n                if (!ctx) return;\n                const labels = dataObj.labels || Object.keys(dataObj);\n                const data = dataObj.data || Object.values(dataObj);\n                const bgColors = type === 'bar' || type === 'line' ? 'rgba(79, 70, 229, 0.8)' : generateColors(labels.length);\n                const borderColors = type === 'bar' || type === 'line' ? 'rgba(79, 70, 229, 1)' : '#fff';\n                \n                chartInstances[id] = new Chart(ctx, {\n                    type: type,\n                    data: { labels, datasets: [{ label, data, backgroundColor: bgColors, borderColor: borderColors, borderWidth: type === 'line' ? 2 : 1 }] },\n                    options: {\n                        responsive: true, maintainAspectRatio: false,\n                        plugins: { legend: { display: type === 'pie' || type === 'doughnut' } },\n                        scales: type.includes('bar') || type.includes('line') ? { y: { beginAtZero: true } } : {}\n                    }\n                });\n            }\n            \n            function generateColors(num) {\n                const base = [[79, 70, 229], [34, 197, 94], [234, 179, 8], [239, 68, 68], [217, 70, 239], [20, 184, 166], [249, 115, 22], [99, 102, 241]];\n                return Array.from({ length: num }, (_, i) => `rgba(${base[i % base.length].join(',')}, 0.8)`);\n            }\n\n            function populateTable(data, headers) {\n                const table = document.getElementById('data-table');\n                table.querySelector('thead').innerHTML = `<tr>${headers.map(h => `<th class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase\">${h}<\/th>`).join('')}<\/tr>`;\n                renderTablePage(data, headers);\n                renderPaginationControls(data.length, data, headers);\n            }\n\n            function renderTablePage(data, headers) {\n                const tbody = document.getElementById('data-table').querySelector('tbody');\n                const start = (currentPage - 1) * ROWS_PER_PAGE;\n                const paginatedData = data.slice(start, start + ROWS_PER_PAGE);\n                tbody.innerHTML = paginatedData.map(rowData => `<tr>${headers.map(h => `<td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-700\">${rowData[h] || ''}<\/td>`).join('')}<\/tr>`).join('');\n            }\n\n            function renderPaginationControls(totalRows, data, headers) {\n                const container = document.getElementById('pagination-controls');\n                const totalPages = Math.ceil(totalRows \/ ROWS_PER_PAGE);\n                if (totalPages <= 1) { container.innerHTML = ''; return; }\n                const startItem = (currentPage - 1) * ROWS_PER_PAGE + 1;\n                const endItem = Math.min(currentPage * ROWS_PER_PAGE, totalRows);\n                container.innerHTML = `<div class=\"hidden sm:flex-1 sm:flex sm:items-center sm:justify-between\"><p class=\"text-sm text-gray-700\">Showing <span class=\"font-medium\">${startItem}<\/span> to <span class=\"font-medium\">${endItem}<\/span> of <span class=\"font-medium\">${totalRows}<\/span> results<\/p><\/div><div class=\"flex-1 flex justify-between sm:justify-end\"><button id=\"prev-page-btn\" class=\"relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50\" ${currentPage === 1 ? 'disabled' : ''}>Previous<\/button><button id=\"next-page-btn\" class=\"ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50\" ${currentPage === totalPages ? 'disabled' : ''}>Next<\/button><\/div>`;\n                document.getElementById('prev-page-btn').addEventListener('click', () => { if (currentPage > 1) { currentPage--; renderTablePage(data, headers); renderPaginationControls(totalRows, data, headers); } });\n                document.getElementById('next-page-btn').addEventListener('click', () => { if (currentPage < totalPages) { currentPage++; renderTablePage(data, headers); renderPaginationControls(totalRows, data, headers); } });\n            }\n        });\n    <\/script>\n<\/body>\n<\/html>\n\n","protected":false},"excerpt":{"rendered":"<p>J-Cred BI Portal Sign in to access your dashboard Username Password Sign in Descriptive Diagnostic Predictive Prescriptive Data Explorer Logout Descriptive Print Report Upload Your Data File Please upload the daily CSV spreadsheet to populate the portal. Click to upload or drag and drop CSV, XLSX (exported as CSV) Filter Your Data Start Date End Date Filter By Column&#8212; Select Column &#8212; Value&#8212; Select Value &#8212; Apply Filters Clear Filters Total Requests 0 The total number of requests that match the current filter criteria. Avg. Turnaround (Hrs) 0 The average time taken, in hours, from request creation to completion for all completed requests in this period. SLA Compliance 0% The percentage of completed requests that were finished within their defined Service Level Agreement (SLA) time. Open Requests 0 The number of requests that are currently in &#8216;Open&#8217; or &#8216;InProgress&#8217; status. Request Volume Trend This chart shows the number of new requests created each day over the selected period. Requests by Status A breakdown of all requests by their current status (e.g., Open, InProgress, Completed). Requests per Client The total number of requests logged by each company or client. Avg. Turnaround Time per Client (Hrs) The average time it takes to complete requests for each specific client, helping to identify efficiency per account. Monthly Billing Report A summary of the total number of requests per client, useful for monthly billing and client reviews. Summary of billable requests. Use filters for specific date ranges. Raw Data Explorer No Data Found There is no data matching your filter criteria.<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"essential-blocks-fullwidth-template.php","meta":{"_eb_attr":"","footnotes":""},"class_list":["post-3436","page","type-page","status-publish","hentry"],"blocksy_meta":{"disable_header":"yes","disable_footer":"yes","disable_share_box":"yes","disable_featured_image":"yes","styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":6}},"_links":{"self":[{"href":"https:\/\/j-cred.co.za\/zh\/wp-json\/wp\/v2\/pages\/3436","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/j-cred.co.za\/zh\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/j-cred.co.za\/zh\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/j-cred.co.za\/zh\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/j-cred.co.za\/zh\/wp-json\/wp\/v2\/comments?post=3436"}],"version-history":[{"count":3,"href":"https:\/\/j-cred.co.za\/zh\/wp-json\/wp\/v2\/pages\/3436\/revisions"}],"predecessor-version":[{"id":3439,"href":"https:\/\/j-cred.co.za\/zh\/wp-json\/wp\/v2\/pages\/3436\/revisions\/3439"}],"wp:attachment":[{"href":"https:\/\/j-cred.co.za\/zh\/wp-json\/wp\/v2\/media?parent=3436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}