{"id":114,"date":"2026-03-31T05:48:09","date_gmt":"2026-03-31T05:48:09","guid":{"rendered":"https:\/\/ph-portal.zyneventures.com\/?page_id=114"},"modified":"2026-03-31T12:12:44","modified_gmt":"2026-03-31T12:12:44","slug":"account-benchmark","status":"publish","type":"page","link":"https:\/\/ph-portal.zyneventures.com\/index.php\/account-benchmark\/","title":{"rendered":"Account Benchmark"},"content":{"rendered":"<style>.kadence-column114_9d9c6e-65 > .kt-inside-inner-col,.kadence-column114_9d9c6e-65 > .kt-inside-inner-col:before{border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-right-radius:0px;border-bottom-left-radius:0px;}.kadence-column114_9d9c6e-65 > .kt-inside-inner-col{column-gap:var(--global-kb-gap-sm, 1rem);}.kadence-column114_9d9c6e-65 > .kt-inside-inner-col{flex-direction:column;}.kadence-column114_9d9c6e-65 > .kt-inside-inner-col > .aligncenter{width:100%;}.kadence-column114_9d9c6e-65 > .kt-inside-inner-col:before{opacity:0.3;}.kadence-column114_9d9c6e-65{position:relative;}@media all and (max-width: 1024px){.kadence-column114_9d9c6e-65 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}@media all and (max-width: 767px){.kadence-column114_9d9c6e-65 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}<\/style>\n<div class=\"wp-block-kadence-column kadence-column114_9d9c6e-65\"><div class=\"kt-inside-inner-col\"><style>.kb-row-layout-id114_bc4525-bc > .kt-row-column-wrap{align-content:start;}:where(.kb-row-layout-id114_bc4525-bc > .kt-row-column-wrap) > .wp-block-kadence-column{justify-content:start;}.kb-row-layout-id114_bc4525-bc > .kt-row-column-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:var(--global-kb-gap-md, 2rem);padding-top:var(--global-kb-spacing-sm, 1.5rem);padding-bottom:var(--global-kb-spacing-sm, 1.5rem);grid-template-columns:minmax(0, 1fr);}.kb-row-layout-id114_bc4525-bc > .kt-row-layout-overlay{opacity:0.30;}@media all and (max-width: 1024px){.kb-row-layout-id114_bc4525-bc > .kt-row-column-wrap{grid-template-columns:minmax(0, 1fr);}}@media all and (max-width: 767px){.kb-row-layout-id114_bc4525-bc > .kt-row-column-wrap{grid-template-columns:minmax(0, 1fr);}}<\/style><div class=\"kb-row-layout-wrap kb-row-layout-id114_bc4525-bc alignnone wp-block-kadence-rowlayout\"><div class=\"kt-row-column-wrap kt-has-1-columns kt-row-layout-equal kt-tab-layout-inherit kt-mobile-layout-row kt-row-valign-top\">\n<style>.kadence-column114_48836f-fc > .kt-inside-inner-col,.kadence-column114_48836f-fc > .kt-inside-inner-col:before{border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-right-radius:0px;border-bottom-left-radius:0px;}.kadence-column114_48836f-fc > .kt-inside-inner-col{column-gap:var(--global-kb-gap-sm, 1rem);}.kadence-column114_48836f-fc > .kt-inside-inner-col{flex-direction:column;}.kadence-column114_48836f-fc > .kt-inside-inner-col > .aligncenter{width:100%;}.kadence-column114_48836f-fc > .kt-inside-inner-col:before{opacity:0.3;}.kadence-column114_48836f-fc{position:relative;}@media all and (max-width: 1024px){.kadence-column114_48836f-fc > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}@media all and (max-width: 767px){.kadence-column114_48836f-fc > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}<\/style>\n<div class=\"wp-block-kadence-column kadence-column114_48836f-fc\"><div class=\"kt-inside-inner-col\">\n<style>\n    :root {\n        --primary-blue: #0180FF;\n        --hover-blue: #3499FF;\n        --text-dark: #212529;\n        --text-muted: #8D8C9C;\n        --border-color: #EFEFEF;\n        --success-green: #28a745;\n        --error-red: #dc3545;\n    }\n\n    body {\n        margin: 0;\n        font-family: 'Sora', sans-serif;\n        background-color: #fff;\n        color: var(--text-dark);\n    }\n\n    \/* Title Row *\/\n    .title-container {\n        margin-bottom: 20px;\n    }\n    .title-container h2 {\n        font-size: 21px;\n        font-weight: 500;\n        text-transform: uppercase;\n        margin: 0;\n        display: inline-block;\n    }\n    .title-container .count {\n        color: var(--text-muted);\n        font-size: 16px;\n        font-weight: 400;\n        margin-left: 8px;\n    }\n\n    \/* Action Row *\/\n    .action-row {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 30px;\n        gap: 15px;\n        flex-wrap: wrap;\n    }\n\n    .search-group {\n        display: flex;\n        gap: 12px;\n        align-items: center;\n        flex: 1;\n        min-width: 280px;\n    }\n\n    .search-wrapper {\n        background: #F1F3F4;\n        border-radius: 6px;\n        padding: 8px 15px;\n        display: flex;\n        align-items: center;\n        max-width: 400px;\n        flex: 1;\n        gap: 12px;\n    }\n    \n    .search-icon { \n        width: 18px; \n        height: 18px; \n        color: #8D8C9C; \n        flex-shrink: 0;\n    }\n\n    .search-wrapper input {\n        border: none;\n        background: transparent;\n        outline: none;\n        width: 100%;\n        font-size: 12px;\n        font-family: 'Sora';\n        color: var(--text-dark);\n    }\n\n    \/* Filter button \u2014 matches the screenshot icon exactly *\/\n    .btn-filter {\n        background: transparent;\n        border: 1px solid;\n        border-color: #F1F3F4;\n        color: #5f6368;\n        width: 36px;\n        height: 36px;\n        border-radius: 6px;\n        cursor: pointer;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        flex-shrink: 0;\n        padding: 0;\n    }\n    .btn-filter:hover { background: transparent; }\n\n    \/* Filter icon: 3 lines decreasing width, centered *\/\n    .filter-icon {\n        display: flex;\n        flex-direction: column;\n        gap: 4px;\n        align-items: center;\n        justify-content: center;\n    }\n    .filter-icon span {\n        display: block;\n        height: 2px;\n        background: #5f6368;\n        border-radius: 2px;\n    }\n    .filter-icon span:nth-child(1) { width: 16px; }\n    .filter-icon span:nth-child(2) { width: 11px; }\n    .filter-icon span:nth-child(3) { width: 6px; }\n\n    .button-group {\n        display: flex;\n        gap: 10px;\n        flex-wrap: wrap;\n    }\n\n    .btn {\n        padding: 8px 15px;\n        border-radius: 6px;\n        font-size: 12px;\n        font-weight: 400;\n        cursor: pointer;\n        border: none;\n        white-space: nowrap;\n        font-family: 'Sora', sans-serif;\n    }\n    .btn-primary { background: var(--primary-blue); color: white; }\n    .btn-primary:hover { background: var(--hover-blue); }\n\n    \/* Table Styling *\/\n    .table-responsive {\n        overflow-x: auto;\n        border: 1px solid var(--border-color);\n        border-radius: 8px;\n        -webkit-overflow-scrolling: touch;\n    }\n\n    table {\n        width: 100%;\n        border-collapse: collapse;\n        font-size: 12px;\n        text-align: left;\n        min-width: 1100px;\n    }\n\n    thead {\n        background-color: #F8F9FA;\n    }\n\n    th {\n        padding: 15px;\n        color: #212529;\n        font-weight: 400;\n        border-bottom: 2px solid var(--border-color);\n        text-transform: uppercase;\n    }\n\n    td {\n        padding: 15px;\n        font-size: 12px;\n        font-weight: 400;\n        border-bottom: 1px solid var(--border-color);\n        vertical-align: middle;\n        color: #8D8C9C;\n    }\n\n    \/* Status Badge *\/\n    .status-badge {\n        display: inline-flex;\n        align-items: center;\n        justify-content: center;\n        width: 80px;\n        height: 24px;\n        border-radius: 12px;\n        font-size: 12px;\n        font-weight: 400;\n    }\n    .status-active { background: #E6F4EA; color: var(--success-green); }\n    .status-active::before { content: '\u25cf'; margin-right: 4px; font-size: 8px; }\n    .status-inactive { background: #FCE8E6; color: var(--error-red); }\n    .status-inactive::before { content: '\u25cf'; margin-right: 4px; font-size: 8px; }\n\n    .category-tag {\n        background: #e6fcf5;\n        color: #8D8C9C;\n        padding: 4px 10px;\n        border-radius: 6px;\n        font-weight: 400;\n    }\n\n    .action-edit {\n        color: #8D8C9C;\n        cursor: pointer;\n        text-decoration: none;\n        display: flex;\n        align-items: center;\n        gap: 5px;\n        font-weight: 400;\n    }\n\n    \/* Pagination *\/\n    .pagination-container {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-top: 30px;\n        padding-bottom: 40px;\n        gap: 20px;\n        flex-wrap: wrap;\n    }\n\n    .pagination-controls {\n        display: flex;\n        align-items: center;\n        gap: 5px;\n        flex-wrap: nowrap;\n    }\n\n    .page-item {\n        width: 32px;\n        height: 32px;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        cursor: pointer;\n        border-radius: 50%;\n        font-size: 12px;\n        color: var(--text-muted);\n        transition: background 0.2s;\n    }\n\n    .page-item.active {\n        background-color: var(--primary-blue);\n        color: white;\n    }\n\n    .nav-link {\n        cursor: pointer;\n        color: var(--text-dark);\n        font-size: 12px;\n        padding: 5px 8px;\n        user-select: none;\n    }\n    .nav-link.disabled { color: #ccc; pointer-events: none; }\n\n    \/* Hidden file input *\/\n    #csvFileInput { display: none; }\n\n    \/* Responsive *\/\n    @media (max-width: 1024px) {\n        body { padding-left: 20px; padding-right: 20px; }\n        .button-group { gap: 8px; }\n    }\n\n    @media (max-width: 768px) {\n        body { padding-left: 15px; padding-right: 15px; }\n        .action-row { flex-direction: column; align-items: stretch; }\n        .search-group { min-width: unset; }\n        .search-wrapper { max-width: 100%; }\n        .button-group { justify-content: flex-start; flex-wrap: wrap; }\n        .btn { font-size: 11px; padding: 7px 11px; }\n        .pagination-container { justify-content: center; flex-direction: column-reverse; text-align: center; }\n        .title-container h2 { font-size: 17px; }\n    }\n\n    @media (max-width: 480px) {\n        body { padding-left: 10px; padding-right: 10px; }\n        .button-group { flex-direction: column; }\n        .btn { width: 100%; text-align: center; }\n        .pagination-controls { flex-wrap: wrap; justify-content: center; }\n    }\n<\/style>\n\n<!-- Hidden CSV import input -->\n<input type=\"file\" id=\"csvFileInput\" accept=\".csv\" onchange=\"handleCSVImport(event)\">\n\n<div class=\"title-container\">\n    <h2>View Accounts &#038; Benchmarks<\/h2>\n    <span class=\"count\" id=\"totalCount\">(0)<\/span>\n<\/div>\n\n<div class=\"action-row\">\n    <div class=\"search-group\">\n        <div class=\"search-wrapper\">\n            <svg class=\"search-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"11\" cy=\"11\" r=\"8\"><\/circle>\n                <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"><\/line>\n            <\/svg>\n            <input type=\"text\" id=\"searchInput\" placeholder=\"Search Accounts &#038; Benchmarks...\" oninput=\"handleGlobalSearch()\">\n        <\/div>\n        <button class=\"btn-filter\" title=\"Filter\">\n            <div class=\"filter-icon\">\n                <span><\/span>\n                <span><\/span>\n                <span><\/span>\n            <\/div>\n        <\/button>\n    <\/div>\n    <div class=\"button-group\">\n        <button class=\"btn btn-primary\" onclick=\"location.href='https:\/\/ph-portal.zyneventures.com\/index.php\/new-accounts-benchmarks\/'\">+ Add Account &amp; Benchmarks<\/button>\n        <button class=\"btn btn-primary\" onclick=\"document.getElementById('csvFileInput').click()\">+ CSV Import<\/button>\n        <button class=\"btn btn-primary\" onclick=\"handleCSVDownload()\">+ CSV Download<\/button>\n        <button class=\"btn btn-primary\" onclick=\"location.href='https:\/\/ph-portal.zyneventures.com\/index.php\/update-wrt\/'\">Update WorkAssignment WRT Account<\/button>\n    <\/div>\n<\/div>\n\n<div class=\"table-responsive\">\n    <table>\n        <thead>\n            <tr>\n                <th>Account ID<\/th>\n                <th>Account<\/th>\n                <th>Desc.<\/th>\n                <th>Category<\/th>\n                <th>Client<\/th>\n                <th>Project<\/th>\n                <th>Project Type<\/th>\n                <th>Operational Benchmark\/ HR<\/th>\n                <th>Quality Benchmark\/ HR<\/th>\n                <th>Threshold<\/th>\n                <th>Status<\/th>\n                <th>Action<\/th>\n            <\/tr>\n        <\/thead>\n        <tbody id=\"tableBody\">\n        <\/tbody>\n    <\/table>\n<\/div>\n\n<div class=\"pagination-container\">\n    <div class=\"pagination-controls\">\n        <span class=\"nav-link\" id=\"prevBtn\">\u00ab Previous<\/span>\n        <div id=\"pageNumbers\" style=\"display:flex; gap: 4px;\"><\/div>\n        <span class=\"nav-link\" id=\"nextBtn\">Next \u00bb<\/span>\n    <\/div>\n    <div id=\"entryInfo\" style=\"font-size: 12px; color: var(--text-muted);\">\n        Showing 0 to 0 of 0 entries\n    <\/div>\n<\/div>\n\n<script>\n    const BASE_URL = \"https:\/\/api-ph-portal.zyneventures.com\/api\/v1\";\n    const ENDPOINTS = {\n        ALL: `${BASE_URL}\/accountandbenchmark\/all`,\n        DETAIL: `${BASE_URL}\/accountandbenchmark\/detail`\n    };\n\n    \/\/ allData holds every record fetched (for global search across all pages)\n    let allData = [];\n    let masterData = [];\n    let currentPage = 1;\n    let isSearchActive = false;\n    let totalMeta = {};\n\n    const getHeaders = () => {\n        const token = localStorage.getItem(\"TOKEN\");\n        return {\n            \"Content-Type\": \"application\/json\",\n            \"Authorization\": `Bearer ${token}`\n        };\n    };\n\n    \/\/ Fetch ALL records once for search purposes\n    async function fetchAllData() {\n        try {\n            \/\/ First call to get total count\n            const res = await fetch(`${ENDPOINTS.ALL}?page=1`, { headers: getHeaders() });\n            const result = await res.json();\n            if (result.code !== 200) return;\n\n            const meta = result.data;\n            const totalPages = Math.ceil(meta.total \/ meta.perPage);\n\n            \/\/ If only one page, we already have all data\n            if (totalPages <= 1) {\n                allData = meta.data;\n                return;\n            }\n\n            \/\/ Fetch remaining pages in parallel\n            const promises = [];\n            for (let p = 2; p <= totalPages; p++) {\n                promises.push(\n                    fetch(`${ENDPOINTS.ALL}?page=${p}`, { headers: getHeaders() })\n                        .then(r => r.json())\n                        .then(r => (r.code === 200 ? r.data.data : []))\n                );\n            }\n            const rest = await Promise.all(promises);\n            allData = [...meta.data, ...rest.flat()];\n        } catch (err) {\n            console.error(\"fetchAllData Error:\", err);\n        }\n    }\n\n    async function loadData() {\n        try {\n            const response = await fetch(`${ENDPOINTS.ALL}?page=${currentPage}`, {\n                headers: getHeaders()\n            });\n            const result = await response.json();\n\n            if (result.code === 200) {\n                masterData = result.data.data;\n                totalMeta = result.data;\n\n                \/\/ Seed allData with the first page while full fetch runs in bg\n                if (allData.length === 0) allData = [...masterData];\n\n                renderTable(masterData);\n                updatePagination(result.data);\n\n                \/\/ Kick off full background fetch after first render\n                fetchAllData();\n            }\n        } catch (error) {\n            console.error(\"Load Error:\", error);\n        }\n    }\n\n    async function handleEditAction(id) {\n        try {\n            await fetch(`${ENDPOINTS.DETAIL}\/${id}`, { headers: getHeaders() });\n            window.location.href = `https:\/\/ph-portal.zyneventures.com\/index.php\/edit-accounts-benchmarks\/?id=${id}`;\n        } catch (error) {\n            console.error(\"Edit Error:\", error);\n            window.location.href = `https:\/\/ph-portal.zyneventures.com\/index.php\/edit-accounts-benchmarks\/?id=${id}`;\n        }\n    }\n\n    function renderTable(data) {\n        const tbody = document.getElementById(\"tableBody\");\n        tbody.innerHTML = \"\";\n\n        if (data.length === 0) {\n            tbody.innerHTML = `<tr><td colspan=\"12\" style=\"text-align:center; padding: 30px; color: var(--text-muted);\">No records found.<\/td><\/tr>`;\n            return;\n        }\n\n        data.forEach(item => {\n            const row = document.createElement(\"tr\");\n            row.innerHTML = `\n                <td>${item.id}<\/td>\n                <td>${item.name || '---'}<\/td>\n                <td>${item.description || '---'}<\/td>\n                <td><span class=\"category-tag\">${item.category?.category || '---'}<\/span><\/td>\n                <td>${item.client?.name || '---'}<\/td>\n                <td>${item.project?.name || '---'}<\/td>\n                <td>${item.projectType?.type || '---'}<\/td>\n                <td>${item.operational_benchmark}<\/td>\n                <td>${item.quality_benchmark}<\/td>\n                <td>${item.threshold}<\/td>\n                <td>\n                    <span class=\"status-badge ${item.is_active ? 'status-active' : 'status-inactive'}\">\n                        ${item.is_active ? 'Active' : 'Inactive'}\n                    <\/span>\n                <\/td>\n                <td>\n                    <div class=\"action-edit\" onclick=\"handleEditAction(${item.id})\">\n                        <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"><\/path><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"><\/path><\/svg>\n                        Edit\n                    <\/div>\n                <\/td>\n            `;\n            tbody.appendChild(row);\n        });\n    }\n\n    \/\/ Global search: filters across ALL data (not just current page)\n    function handleGlobalSearch() {\n        const query = document.getElementById(\"searchInput\").value.trim().toLowerCase();\n\n        if (!query) {\n            isSearchActive = false;\n            renderTable(masterData);\n            updatePagination(totalMeta);\n            return;\n        }\n\n        isSearchActive = true;\n        const source = allData.length > 0 ? allData : masterData;\n\n        const filtered = source.filter(item =>\n            item.id?.toString().includes(query) ||\n            item.name?.toLowerCase().includes(query) ||\n            item.description?.toLowerCase().includes(query) ||\n            item.client?.name?.toLowerCase().includes(query) ||\n            item.project?.name?.toLowerCase().includes(query) ||\n            item.category?.category?.toLowerCase().includes(query) ||\n            item.projectType?.type?.toLowerCase().includes(query)\n        );\n\n        renderTable(filtered);\n\n        \/\/ Show search result entry info, hide pagination\n        const total = filtered.length;\n        document.getElementById(\"totalCount\").textContent = `(${total})`;\n        document.getElementById(\"entryInfo\").textContent = `Showing ${total === 0 ? 0 : 1} to ${total} of ${total} entries (filtered)`;\n        document.getElementById(\"pageNumbers\").innerHTML = \"\";\n        document.getElementById(\"prevBtn\").className = \"nav-link disabled\";\n        document.getElementById(\"nextBtn\").className = \"nav-link disabled\";\n    }\n\n    function updatePagination(meta) {\n        if (isSearchActive) return;\n\n        document.getElementById(\"totalCount\").textContent = `(${meta.total})`;\n        const start = meta.total === 0 ? 0 : ((meta.page - 1) * meta.perPage) + 1;\n        const end = Math.min(meta.page * meta.perPage, meta.total);\n        document.getElementById(\"entryInfo\").textContent = `Showing ${start} to ${end} of ${meta.total} entries`;\n\n        const pageNumbers = document.getElementById(\"pageNumbers\");\n        pageNumbers.innerHTML = \"\";\n\n        const totalPages = Math.ceil(meta.total \/ meta.perPage);\n        const maxVisible = 5;\n\n        let startPage = Math.max(1, meta.page - Math.floor(maxVisible \/ 2));\n        let endPage = Math.min(totalPages, startPage + maxVisible - 1);\n        if (endPage - startPage + 1 < maxVisible) {\n            startPage = Math.max(1, endPage - maxVisible + 1);\n        }\n\n        \/\/ First page + ellipsis\n        if (startPage > 1) {\n            appendPageItem(pageNumbers, 1, meta.page);\n            if (startPage > 2) appendEllipsis(pageNumbers);\n        }\n\n        for (let i = startPage; i <= endPage; i++) {\n            appendPageItem(pageNumbers, i, meta.page);\n        }\n\n        \/\/ Ellipsis + last page\n        if (endPage < totalPages) {\n            if (endPage < totalPages - 1) appendEllipsis(pageNumbers);\n            appendPageItem(pageNumbers, totalPages, meta.page);\n        }\n\n        document.getElementById(\"prevBtn\").className = `nav-link ${meta.page === 1 ? 'disabled' : ''}`;\n        document.getElementById(\"nextBtn\").className = `nav-link ${meta.page === totalPages || totalPages === 0 ? 'disabled' : ''}`;\n\n        document.getElementById(\"prevBtn\").onclick = () => { if (currentPage > 1) { currentPage--; loadData(); } };\n        document.getElementById(\"nextBtn\").onclick = () => { if (currentPage < totalPages) { currentPage++; loadData(); } };\n    }\n\n    function appendPageItem(container, pageNum, activePage) {\n        const p = document.createElement(\"div\");\n        p.className = `page-item ${pageNum === activePage ? 'active' : ''}`;\n        p.textContent = pageNum;\n        p.onclick = () => { currentPage = pageNum; loadData(); };\n        container.appendChild(p);\n    }\n\n    function appendEllipsis(container) {\n        const el = document.createElement(\"div\");\n        el.className = \"page-item\";\n        el.textContent = \"...\";\n        el.style.cursor = \"default\";\n        container.appendChild(el);\n    }\n\n    \/\/ CSV Import: read file and log\/parse \u2014 extend as needed for API upload\n    function handleCSVImport(event) {\n        const file = event.target.files[0];\n        if (!file) return;\n        if (!file.name.endsWith('.csv')) {\n            alert('Please select a valid .csv file.');\n            return;\n        }\n        const reader = new FileReader();\n        reader.onload = function(e) {\n            const text = e.target.result;\n            console.log(\"CSV Import content:\", text);\n            \/\/ TODO: Parse and POST to API if endpoint is available\n            alert(`CSV file \"${file.name}\" loaded successfully. (${text.split('\\n').length - 1} rows)`);\n        };\n        reader.readAsText(file);\n        \/\/ Reset so same file can be re-selected\n        event.target.value = '';\n    }\n\n    \/\/ CSV Download: export allData (or masterData if not yet fetched) as CSV\n    function handleCSVDownload() {\n        const source = allData.length > 0 ? allData : masterData;\n        if (source.length === 0) {\n            alert('No data available to download.');\n            return;\n        }\n\n        const headers = [\n            'Account ID', 'Account', 'Description', 'Category',\n            'Client', 'Project', 'Project Type',\n            'Operational Benchmark\/HR', 'Quality Benchmark\/HR',\n            'Threshold', 'Status'\n        ];\n\n        const rows = source.map(item => [\n            item.id,\n            item.name || '',\n            item.description || '',\n            item.category?.category || '',\n            item.client?.name || '',\n            item.project?.name || '',\n            item.projectType?.type || '',\n            item.operational_benchmark,\n            item.quality_benchmark,\n            item.threshold,\n            item.is_active ? 'Active' : 'Inactive'\n        ].map(val => `\"${String(val).replace(\/\"\/g, '\"\"')}\"`).join(','));\n\n        const csvContent = [headers.join(','), ...rows].join('\\n');\n        const blob = new Blob([csvContent], { type: 'text\/csv;charset=utf-8;' });\n        const url = URL.createObjectURL(blob);\n        const a = document.createElement('a');\n        a.href = url;\n        a.download = `accounts_benchmarks_${new Date().toISOString().split('T')[0]}.csv`;\n        document.body.appendChild(a);\n        a.click();\n        document.body.removeChild(a);\n        URL.revokeObjectURL(url);\n    }\n\n    loadData();\n<\/script>\n<\/div><\/div>\n\n<\/div><\/div><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>View Accounts &#038; Benchmarks (0) + Add Account &amp; Benchmarks + CSV Import + CSV Download Update WorkAssignment WRT Account Account ID Account Desc. Category Client Project Project Type Operational Benchmark\/ HR Quality Benchmark\/ HR Threshold Status Action \u00ab Previous Next \u00bb Showing 0 to 0 of 0 entries<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"class_list":["post-114","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages\/114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/comments?post=114"}],"version-history":[{"count":6,"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages\/114\/revisions"}],"predecessor-version":[{"id":214,"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages\/114\/revisions\/214"}],"wp:attachment":[{"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/media?parent=114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}