{"id":167,"date":"2026-03-31T07:33:47","date_gmt":"2026-03-31T07:33:47","guid":{"rendered":"https:\/\/ph-portal.zyneventures.com\/?page_id=167"},"modified":"2026-03-31T09:30:59","modified_gmt":"2026-03-31T09:30:59","slug":"general-errors","status":"publish","type":"page","link":"https:\/\/ph-portal.zyneventures.com\/index.php\/general-errors\/","title":{"rendered":"General Errors"},"content":{"rendered":"<style>.kadence-column167_b9c467-e8 > .kt-inside-inner-col,.kadence-column167_b9c467-e8 > .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-column167_b9c467-e8 > .kt-inside-inner-col{column-gap:var(--global-kb-gap-sm, 1rem);}.kadence-column167_b9c467-e8 > .kt-inside-inner-col{flex-direction:column;}.kadence-column167_b9c467-e8 > .kt-inside-inner-col > .aligncenter{width:100%;}.kadence-column167_b9c467-e8 > .kt-inside-inner-col:before{opacity:0.3;}.kadence-column167_b9c467-e8{position:relative;}@media all and (max-width: 1024px){.kadence-column167_b9c467-e8 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}@media all and (max-width: 767px){.kadence-column167_b9c467-e8 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}<\/style>\n<div class=\"wp-block-kadence-column kadence-column167_b9c467-e8\"><div class=\"kt-inside-inner-col\"><style>.kb-row-layout-id167_7132a0-38 > .kt-row-column-wrap{align-content:start;}:where(.kb-row-layout-id167_7132a0-38 > .kt-row-column-wrap) > .wp-block-kadence-column{justify-content:start;}.kb-row-layout-id167_7132a0-38 > .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-id167_7132a0-38 > .kt-row-layout-overlay{opacity:0.30;}@media all and (max-width: 1024px){.kb-row-layout-id167_7132a0-38 > .kt-row-column-wrap{grid-template-columns:minmax(0, 1fr);}}@media all and (max-width: 767px){.kb-row-layout-id167_7132a0-38 > .kt-row-column-wrap{grid-template-columns:minmax(0, 1fr);}}<\/style><div class=\"kb-row-layout-wrap kb-row-layout-id167_7132a0-38 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-column167_3a8b4d-67 > .kt-inside-inner-col,.kadence-column167_3a8b4d-67 > .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-column167_3a8b4d-67 > .kt-inside-inner-col{column-gap:var(--global-kb-gap-sm, 1rem);}.kadence-column167_3a8b4d-67 > .kt-inside-inner-col{flex-direction:column;}.kadence-column167_3a8b4d-67 > .kt-inside-inner-col > .aligncenter{width:100%;}.kadence-column167_3a8b4d-67 > .kt-inside-inner-col:before{opacity:0.3;}.kadence-column167_3a8b4d-67{position:relative;}@media all and (max-width: 1024px){.kadence-column167_3a8b4d-67 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}@media all and (max-width: 767px){.kadence-column167_3a8b4d-67 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}<\/style>\n<div class=\"wp-block-kadence-column kadence-column167_3a8b4d-67\"><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: #1E8E3E;\n            --error-red: #D93025;\n            --bg-light: #F8F9FA;\n        }\n\n        * { box-sizing: border-box; }\n\n        body {\n            font-family: 'Sora', sans-serif;\n            color: var(--text-dark);\n            background: #fff;\n        }\n\n        \/* \u2500\u2500 Header \u2500\u2500 *\/\n        .header-container {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 28px;\n        }\n        .title-group { display: flex; align-items: center; gap: 10px; }\n        .title-group h2 {\n            margin: 0;\n            font-size: 21px;\n            font-weight: 500;\n            text-transform: uppercase;\n            letter-spacing: 0.5px;\n        }\n        .count { color: var(--text-muted); font-size: 16px; font-weight: 400; }\n\n        \/* \u2500\u2500 Filter Section \u2500\u2500 *\/\n        .filter-section {\n            display: grid;\n            grid-template-columns: 1fr 1fr 1fr auto;\n            gap: 16px;\n            align-items: flex-end;\n            margin-bottom: 20px;\n        }\n        .filter-group { display: flex; flex-direction: column; gap: 6px; }\n        .filter-group label {\n            font-size: 12px;\n            font-weight: 500;\n            color: var(--text-dark);\n        }\n        .filter-group label span { color: var(--error-red); }\n\n        \/* Custom Select *\/\n        .select-wrapper {\n            position: relative;\n        }\n        .select-wrapper select {\n            width: 100%;\n            padding: 10px 36px 10px 14px;\n            border: 1px solid #E0E0E0;\n            border-radius: 6px;\n            background: #fff;\n            font-family: 'Sora', sans-serif;\n            font-size: 12px;\n            color: var(--text-muted);\n            appearance: none;\n            cursor: pointer;\n            outline: none;\n            transition: border-color 0.2s;\n        }\n        .select-wrapper select:focus { border-color: var(--primary-blue); }\n        .select-wrapper::after {\n            content: '';\n            position: absolute;\n            right: 14px;\n            top: 50%;\n            transform: translateY(-50%);\n            width: 0;\n            height: 0;\n            border-left: 5px solid transparent;\n            border-right: 5px solid transparent;\n            border-top: 5px solid #8D8C9C;\n            pointer-events: none;\n        }\n\n        \/* Date Input *\/\n        .date-wrapper {\n            position: relative;\n        }\n        .date-wrapper input[type=\"text\"] {\n            width: 100%;\n            padding: 10px 36px 10px 14px;\n            border: 1px solid #E0E0E0;\n            border-radius: 6px;\n            font-family: 'Sora', sans-serif;\n            font-size: 12px;\n            color: var(--text-dark);\n            outline: none;\n            cursor: pointer;\n            background: #fff;\n            transition: border-color 0.2s;\n            user-select: none;\n        }\n        .date-wrapper input[type=\"text\"]:focus { border-color: var(--primary-blue); }\n        .date-wrapper input[type=\"text\"]::placeholder { color: #aaa; }\n        .date-wrapper .cal-icon {\n            position: absolute;\n            right: 12px;\n            top: 50%;\n            transform: translateY(-50%);\n            pointer-events: none;\n            color: #8D8C9C;\n        }\n\n        \/* \u2500\u2500 Custom Date Picker Dropdown \u2500\u2500 *\/\n        .dp-dropdown {\n            display: none;\n            position: absolute;\n            top: calc(100% + 6px);\n            left: 0;\n            z-index: 2000;\n            background: #fff;\n            border: 1px solid #E0E0E0;\n            border-radius: 10px;\n            box-shadow: 0 8px 28px rgba(0,0,0,0.13);\n            flex-direction: row;\n            width: 680px;\n            max-width: calc(100vw - 24px);\n            overflow: hidden;\n        }\n        .dp-dropdown.open { display: flex; }\n        .dp-dropdown.align-right { left: auto; right: 0; }\n\n        \/* Mobile backdrop *\/\n        .dp-backdrop {\n            display: none;\n            position: fixed;\n            inset: 0;\n            z-index: 1999;\n        }\n        .dp-backdrop.show { display: block; }\n\n        \/* Left quick-select panel *\/\n        .dp-presets {\n            width: 100px;\n            background: #fff;\n            border-right: 1px solid #EFEFEF;\n            padding: 3px 0;\n            flex-shrink: 0;\n        }\n        .dp-preset-item {\n            padding: 8px 12px;\n            font-size: 12px;\n            color: var(--text-dark);\n            cursor: pointer;\n            transition: background 0.15s, color 0.15s;\n            white-space: nowrap;\n        }\n        .dp-preset-item:hover { background: #f4f6fb; }\n        .dp-preset-item.active {\n            background: var(--primary-blue);\n            color: #fff;\n            font-weight: 500;\n        }\n\n        \/* Two-month panel container *\/\n        .dp-calendars-wrap {\n            flex: 1;\n            display: flex;\n            flex-direction: column;\n            padding: 8px 10px 8px;\n            min-width: 0;\n        }\n        .dp-months-row {\n            display: flex;\n            gap: 0;\n            flex: 1;\n        }\n        .dp-calendar {\n            flex: 1;\n            padding: 0 6px;\n            min-width: 0;\n        }\n        .dp-calendar + .dp-calendar {\n            border-left: 1px solid #EFEFEF;\n        }\n        .dp-cal-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 6px;\n        }\n        .dp-cal-title {\n            font-size: 13px;\n            font-weight: 500;\n            color: var(--text-dark);\n        }\n        .dp-nav-btn {\n            background: none;\n            border: none;\n            cursor: pointer;\n            color: #8D8C9C;\n            padding: 3px 7px;\n            border-radius: 4px;\n            font-size: 16px;\n            line-height: 1;\n            transition: background 0.15s, color 0.15s;\n        }\n        .dp-nav-btn:hover { background: #f0f4ff; color: var(--primary-blue); }\n        .dp-nav-btn.dp-nav-hidden { visibility: hidden; pointer-events: none; }\n        .dp-weekdays {\n            display: grid;\n            grid-template-columns: repeat(7, 1fr);\n            margin-bottom: 2px;\n        }\n        .dp-weekday {\n            text-align: center;\n            font-size: 11px;\n            font-weight: 500;\n            color: #8D8C9C;\n            padding: 2px 0;\n        }\n        .dp-days {\n            display: grid;\n            grid-template-columns: repeat(7, 1fr);\n            gap: 1px;\n        }\n        .dp-day {\n            text-align: center;\n            padding: 2px 0;\n            font-size: 11px;\n            border-radius: 50%;\n            cursor: pointer;\n            color: var(--text-dark);\n            transition: background 0.15s, color 0.15s;\n            aspect-ratio: 1;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n        }\n        .dp-day:hover { background: #e8f1ff; color: var(--primary-blue); }\n        .dp-day.today { font-weight: 700; color: var(--primary-blue); }\n        .dp-day.selected {\n            background: var(--primary-blue);\n            color: #fff !important;\n            font-weight: 600;\n        }\n        .dp-day.other-month { color: #ccc; }\n        .dp-day.other-month:hover { background: #f5f5f5; color: #aaa; }\n        .dp-footer {\n            display: flex;\n            justify-content: flex-end;\n            gap: 8px;\n            margin-top: 8px;\n            padding-top: 8px;\n            border-top: 1px solid #EFEFEF;\n        }\n        .dp-btn-clear {\n            padding: 6px 14px;\n            border-radius: 6px;\n            font-size: 12px;\n            font-family: 'Sora', sans-serif;\n            background: #F1F3F4;\n            color: #555;\n            border: none;\n            cursor: pointer;\n            font-weight: 400;\n        }\n        .dp-btn-clear:hover { background: #e2e4e7; }\n        .dp-btn-apply {\n            padding: 6px 14px;\n            border-radius: 6px;\n            font-size: 12px;\n            font-family: 'Sora', sans-serif;\n            background: var(--primary-blue);\n            color: #fff;\n            border: none;\n            cursor: pointer;\n            font-weight: 400;\n        }\n        .dp-btn-apply:hover { background: var(--hover-blue); }\n\n        \/* Search Button *\/\n        .btn {\n            padding: 10px 20px;\n            border-radius: 6px;\n            font-size: 12px;\n            font-weight: 400;\n            cursor: pointer;\n            border: none;\n            transition: background 0.2s;\n            font-family: 'Sora', sans-serif;\n            white-space: nowrap;\n            display: inline-flex;\n            align-items: center;\n            gap: 6px;\n        }\n        .btn-primary { background: var(--primary-blue); color: #fff; }\n        .btn-primary:hover { background: var(--hover-blue); }\n        .btn-success { background: #0180FF; color: #fff; }\n        .btn-success:hover { background: #3499FF; }\n        .btn-csv { background: #0180FF; color: #fff; }\n        .btn-csv:hover { background: #3499FF; }\n\n        \/* \u2500\u2500 Action Row \u2500\u2500 *\/\n        .action-row {\n            display: flex;\n            gap: 12px;\n            margin-bottom: 24px;\n        }\n\n        \/* \u2500\u2500 Table \u2500\u2500 *\/\n        .table-wrapper {\n            width: 100%;\n            overflow-x: auto;\n            border: 1px solid var(--border-color);\n            border-radius: 10px;\n        }\n        table {\n            width: 100%;\n            border-collapse: collapse;\n            min-width: 750px;\n        }\n        thead tr {\n            background: #F8F9FA;\n        }\n        thead th {\n            padding: 14px 16px;\n            font-size: 12px;\n            font-weight: 500;\n            color: var(--text-dark);\n            text-align: left;\n            border-bottom: 1px solid var(--border-color);\n            white-space: nowrap;\n        }\n        tbody tr {\n            border-bottom: 1px solid var(--border-color);\n            transition: background 0.15s;\n        }\n        tbody tr:last-child { border-bottom: none; }\n        tbody tr:hover { background: #fafbff; }\n        tbody td {\n            padding: 14px 16px;\n            font-size: 12px;\n            color: var(--text-muted);\n            vertical-align: middle;\n        }\n\n        \/* Type Badge *\/\n        .type-badge {\n            display: inline-block;\n            padding: 3px 10px;\n            border-radius: 20px;\n            font-size: 12px;\n            font-weight: 400;\n            white-space: nowrap;\n        }\n        .type-zero { background: transparent; color: var(--text-muted); }\n        .type-minor { background: transparent; color: var(--text-muted); }\n        .type-critical { background: transparent; color: var(--text-muted); }\n\n        \/* View Icon *\/\n        .view-btn {\n            background: none;\n            border: none;\n            cursor: pointer;\n            padding: 6px;\n            color: #aaa;\n            border-radius: 4px;\n            transition: color 0.15s, background 0.15s;\n            display: inline-flex;\n            align-items: center;\n        }\n        .view-btn:hover { color: var(--primary-blue); background: #e8f1ff; }\n\n        \/* \u2500\u2500 Pagination \u2500\u2500 *\/\n        .pagination-footer {\n            margin-top: 50px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            color: var(--text-muted);\n            font-size: 12px;\n        }\n        .pagination-controls { display: flex; align-items: center; gap: 15px; }\n        .page-num {\n            cursor: pointer;\n            width: 35px;\n            height: 35px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            border-radius: 50%;\n            font-weight: 500;\n        }\n        .page-num:hover { background: transparent; }\n        .page-num.active { background: var(--primary-blue); color: #fff; }\n        .dots { padding: 0 4px; color: var(--text-muted); }\n        .nav-btn {\n            cursor: pointer;\n            color: var(--text-dark);\n            font-weight: 500;\n            text-decoration: none;\n        }\n        .nav-btn.disabled { color: #ccc; pointer-events: none; }\n\n        \/* Loading \/ Empty *\/\n        .loading-row td, .empty-row td {\n            text-align: center;\n            padding: 40px;\n            color: var(--text-muted);\n            font-size: 13px;\n        }\n\n        \/* Spinner *\/\n        .spinner {\n            display: inline-block;\n            width: 18px; height: 18px;\n            border: 2px solid #e0e0e0;\n            border-top-color: var(--primary-blue);\n            border-radius: 50%;\n            animation: spin 0.7s linear infinite;\n            vertical-align: middle;\n            margin-right: 6px;\n        }\n        @keyframes spin { to { transform: rotate(360deg); } }\n\n        \/* Toast *\/\n        .toast {\n            position: fixed;\n            bottom: 28px;\n            right: 28px;\n            padding: 12px 20px;\n            border-radius: 8px;\n            font-size: 13px;\n            font-family: 'Sora', sans-serif;\n            z-index: 9999;\n            opacity: 0;\n            transform: translateY(16px);\n            transition: opacity 0.3s, transform 0.3s;\n            pointer-events: none;\n        }\n        .toast.show { opacity: 1; transform: translateY(0); }\n        .toast-success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }\n        .toast-error   { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }\n\n\n\n        \/* \u2500\u2500 Responsive \u2500\u2500 *\/\n        @media (max-width: 1100px) {\n            .filter-section { grid-template-columns: 1fr 1fr 1fr; }\n            .filter-section .filter-group:last-child { grid-column: 1 \/ -1; justify-items: start; }\n            .filter-section .btn { width: auto; }\n        }\n        @media (max-width: 750px) {\n            body { padding: 16px; }\n            .filter-section { grid-template-columns: 1fr 1fr; }\n            .header-container { flex-direction: column; align-items: flex-start; gap: 10px; }\n            .action-row { flex-wrap: wrap; }\n            .pagination-footer {\n                flex-direction: column;\n                align-items: center;\n                gap: 12px;\n            }\n            #entryInfo {\n                order: 2;\n                width: 100%;\n                text-align: center;\n            }\n            .pagination-controls {\n                order: 1;\n                width: 100%;\n                justify-content: center;\n            }\n\n            \/* Calendar: stack presets above calendar *\/\n            .dp-dropdown {\n                flex-direction: column;\n                min-width: 0;\n                width: calc(100vw - 32px);\n                left: 50%;\n                transform: translateX(-50%);\n                max-height: 85vh;\n                overflow-y: auto;\n            }\n            .dp-presets {\n                width: 100%;\n                border-right: none;\n                border-bottom: 1px solid #EFEFEF;\n                padding: 4px 0;\n                display: flex;\n                flex-wrap: wrap;\n            }\n            .dp-preset-item {\n                padding: 6px 10px;\n                font-size: 11px;\n                flex: 1 1 auto;\n                text-align: center;\n                min-width: 80px;\n            }\n            .dp-months-row { flex-direction: column; gap: 10px; }\n            .dp-calendar + .dp-calendar { border-left: none; border-top: 1px solid #EFEFEF; padding-top: 8px; }\n            .dp-calendars-wrap { padding: 6px 8px 8px; }\n            .dp-cal-header { margin-bottom: 6px; }\n            .dp-day { padding: 5px 0; font-size: 11px; }\n            .dp-footer { margin-top: 8px; padding-top: 8px; }\n        }\n        @media (max-width: 480px) {\n            .filter-section { grid-template-columns: 1fr; }\n\n            \/* Calendar: fixed overlay on very small screens *\/\n            .dp-dropdown {\n                position: fixed;\n                top: 50%;\n                left: 50% !important;\n                transform: translate(-50%, -50%) !important;\n                width: calc(100vw - 24px);\n                max-width: 400px;\n                max-height: 92vh;\n                overflow-y: auto;\n                z-index: 3000;\n            }\n            .dp-calendars-wrap { padding: 6px 6px 6px; }\n            .dp-day { font-size: 11px; padding: 4px 0; }\n            .dp-cal-title { font-size: 12px; }\n            .dp-footer { margin-top: 6px; padding-top: 6px; }\n            .dp-btn-clear, .dp-btn-apply { padding: 5px 10px; font-size: 11px; }\n        }\n    <\/style>\n\n\n<!-- Header -->\n<div class=\"header-container\">\n    <div class=\"title-group\">\n        <h2>General Errors<\/h2>\n        <span class=\"count\" id=\"totalCount\">(0)<\/span>\n    <\/div>\n<\/div>\n\n<!-- Filters -->\n<div class=\"filter-section\">\n    <!-- Assign To -->\n    <div class=\"filter-group\">\n        <label>Assign To <span>*<\/span><\/label>\n        <div class=\"select-wrapper\">\n            <select id=\"filterAssignTo\">\n                <option value=\"\">Select<\/option>\n            <\/select>\n        <\/div>\n    <\/div>\n\n    <!-- Department -->\n    <div class=\"filter-group\">\n        <label>Department <span>*<\/span><\/label>\n        <div class=\"select-wrapper\">\n            <select id=\"filterDepartment\">\n                <option value=\"\">Select Department<\/option>\n            <\/select>\n        <\/div>\n    <\/div>\n\n    <!-- Select Date -->\n    <div class=\"filter-group\">\n        <label>Select Date<\/label>\n        <div class=\"date-wrapper\" id=\"dpWrapper\">\n            <input type=\"text\" id=\"dateDisplay\" placeholder=\"Select Date\" readonly onclick=\"toggleDatePicker(event)\">\n            <svg class=\"cal-icon\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\">\n                <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"\/>\n                <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"\/>\n                <line x1=\"8\"  y1=\"2\" x2=\"8\"  y2=\"6\"\/>\n                <line x1=\"3\"  y1=\"10\" x2=\"21\" y2=\"10\"\/>\n            <\/svg>\n            <div class=\"dp-backdrop\" id=\"dpBackdrop\" onclick=\"closeDatePicker()\"><\/div>\n            <div class=\"dp-dropdown\" id=\"dpDropdown\">\n                <!-- Left: Presets -->\n                <div class=\"dp-presets\">\n                    <div class=\"dp-preset-item active\" data-preset=\"today\"      onclick=\"selectPreset(event,'today')\">Today<\/div>\n                    <div class=\"dp-preset-item\"        data-preset=\"yesterday\"  onclick=\"selectPreset(event,'yesterday')\">Yesterday<\/div>\n                    <div class=\"dp-preset-item\"        data-preset=\"last7\"      onclick=\"selectPreset(event,'last7')\">Last 7 Days<\/div>\n                    <div class=\"dp-preset-item\"        data-preset=\"last30\"     onclick=\"selectPreset(event,'last30')\">Last 30 Days<\/div>\n                    <div class=\"dp-preset-item\"        data-preset=\"thisMonth\"  onclick=\"selectPreset(event,'thisMonth')\">This Month<\/div>\n                    <div class=\"dp-preset-item\"        data-preset=\"lastMonth\"  onclick=\"selectPreset(event,'lastMonth')\">Last Month<\/div>\n                <\/div>\n                <!-- Right: Two-month calendars -->\n                <div class=\"dp-calendars-wrap\">\n                    <div class=\"dp-months-row\">\n                        <div class=\"dp-calendar\">\n                            <div class=\"dp-cal-header\">\n                                <button class=\"dp-nav-btn\" onclick=\"dpChangeMonth(event,-1)\">&#8249;<\/button>\n                                <span class=\"dp-cal-title\" id=\"dpCalTitle\"><\/span>\n                                <button class=\"dp-nav-btn dp-nav-hidden\">&#8250;<\/button>\n                            <\/div>\n                            <div class=\"dp-weekdays\">\n                                <div class=\"dp-weekday\">Su<\/div><div class=\"dp-weekday\">Mo<\/div>\n                                <div class=\"dp-weekday\">Tu<\/div><div class=\"dp-weekday\">We<\/div>\n                                <div class=\"dp-weekday\">Th<\/div><div class=\"dp-weekday\">Fr<\/div>\n                                <div class=\"dp-weekday\">Sa<\/div>\n                            <\/div>\n                            <div class=\"dp-days\" id=\"dpDays\"><\/div>\n                        <\/div>\n                        <div class=\"dp-calendar\">\n                            <div class=\"dp-cal-header\">\n                                <button class=\"dp-nav-btn dp-nav-hidden\">&#8249;<\/button>\n                                <span class=\"dp-cal-title\" id=\"dpCalTitle2\"><\/span>\n                                <button class=\"dp-nav-btn\" onclick=\"dpChangeMonth(event,1)\">&#8250;<\/button>\n                            <\/div>\n                            <div class=\"dp-weekdays\">\n                                <div class=\"dp-weekday\">Su<\/div><div class=\"dp-weekday\">Mo<\/div>\n                                <div class=\"dp-weekday\">Tu<\/div><div class=\"dp-weekday\">We<\/div>\n                                <div class=\"dp-weekday\">Th<\/div><div class=\"dp-weekday\">Fr<\/div>\n                                <div class=\"dp-weekday\">Sa<\/div>\n                            <\/div>\n                            <div class=\"dp-days\" id=\"dpDays2\"><\/div>\n                        <\/div>\n                    <\/div>\n                    <div class=\"dp-footer\">\n                        <button class=\"dp-btn-clear\" onclick=\"dpClear(event)\">Clear<\/button>\n                        <button class=\"dp-btn-apply\" onclick=\"dpApply(event)\">Apply<\/button>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <!-- Search -->\n    <div class=\"filter-group\" style=\"justify-content:flex-end;\">\n        <button class=\"btn btn-primary\" onclick=\"doSearch()\">Search<\/button>\n    <\/div>\n<\/div>\n\n<!-- Action buttons -->\n<div class=\"action-row\">\n    <button class=\"btn btn-success\" onclick=\"openAddModal()\">+ Add New General Error<\/button>\n    <button class=\"btn btn-csv\"     onclick=\"downloadCSV()\">+ Download CSV<\/button>\n<\/div>\n<br>\n<!-- Table -->\n<div class=\"table-wrapper\">\n    <table>\n        <thead>\n            <tr>\n                <th>Assign To<\/th>\n                <th>Type<\/th>\n                <th>Error Count<\/th>\n                <th>Error WTG<\/th>\n                <th>Description<\/th>\n                <th>Created By<\/th>\n                <th>Date<\/th>\n                <th>Action<\/th>\n            <\/tr>\n        <\/thead>\n        <tbody id=\"tableBody\">\n            <tr class=\"loading-row\">\n                <td colspan=\"8\"><span class=\"spinner\"><\/span> Loading\u2026<\/td>\n            <\/tr>\n        <\/tbody>\n    <\/table>\n<\/div>\n\n<!-- Pagination -->\n<div class=\"pagination-footer\">\n    <div class=\"pagination-controls\">\n        <span id=\"prevBtn\" class=\"nav-btn disabled\">\u00ab Previous<\/span>\n        <div id=\"pageNumbers\" style=\"display:flex; gap:8px;\"><\/div>\n        <span id=\"nextBtn\" class=\"nav-btn disabled\">Next \u00bb<\/span>\n    <\/div>\n    <div id=\"entryInfo\">Showing 0 to 0 of 0 entries<\/div>\n<\/div>\n\n<!-- Toast -->\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<script>\n    \/\/ ENDPOINTS \n    const BASE_URL = 'https:\/\/api-ph-portal.zyneventures.com\/api\/v1';\n    const ENDPOINTS = {\n        QC_LIST:      `${BASE_URL}\/user\/qc-list`,\n        DEPARTMENTS:  `${BASE_URL}\/department\/all`,\n        ERRORS_ALL:   `${BASE_URL}\/gernal_error\/all`,\n    };\n\n    \/\/ STATE\n    let currentPage  = 1;\n    let totalPages   = 1;\n    let allData      = [];   \/\/ full dataset for client-side pagination\n    let filteredData = [];\n    const PER_PAGE   = 15;\n\n    \/\/ AUTH HELPERS  (mirrors login_form.html)\n    function getToken() {\n        return localStorage.getItem('TOKEN') ||\n               (document.cookie.match(\/(?:^|;\\s*)TOKEN=([^;]*)\/) || [])[1] || '';\n    }\n\n    function getHeaders() {\n        const token = getToken();\n        return {\n            'Content-Type': 'application\/json',\n            ...(token ? { 'Authorization': `Bearer ${token}` } : {})\n        };\n    }\n\n    \/\/TOAST\n    function showToast(msg, type = 'success') {\n        const t = document.getElementById('toast');\n        t.textContent = msg;\n        t.className = `toast toast-${type} show`;\n        setTimeout(() => { t.className = 'toast'; }, 3200);\n    }\n\n    \/\/ LOAD DROPDOWNS\n    async function loadDropdowns() {\n        try {\n            const [usersRes, deptRes] = await Promise.all([\n                fetch(ENDPOINTS.QC_LIST,    { headers: getHeaders() }),\n                fetch(ENDPOINTS.DEPARTMENTS,{ headers: getHeaders() }),\n            ]);\n\n            const usersJson = await usersRes.json();\n            const deptJson  = await deptRes.json();\n\n            \/\/ QC \/ Assign-to users\n            const users = usersJson?.data?.data || usersJson?.data || usersJson?.response || [];\n            fillSelect('filterAssignTo', Array.isArray(users) ? users : [], 'name', 'id', 'Select');\n\n            \/\/ Departments\n            const depts = deptJson?.data?.data || deptJson?.data || deptJson?.response || [];\n            fillSelect('filterDepartment', Array.isArray(depts) ? depts : [], 'name', 'id', 'Select Department');\n\n        } catch (err) {\n            console.error('Dropdown load error:', err);\n        }\n    }\n\n    function fillSelect(selectId, data, labelKey, valueKey, placeholder) {\n        const el = document.getElementById(selectId);\n        if (!el) return;\n        el.innerHTML = `<option value=\"\">${placeholder}<\/option>`;\n        if (!Array.isArray(data)) return;\n        data.forEach(item => {\n            const opt = document.createElement('option');\n            opt.value = item[valueKey] ?? item.id ?? '';\n            opt.textContent = item[labelKey] ?? item.name ?? '';\n            el.appendChild(opt);\n        });\n    }\n\n    \/\/ FETCH ERRORS\n    async function fetchErrors() {\n        showLoading();\n        try {\n            const params = new URLSearchParams();\n            const deptId   = document.getElementById('filterDepartment').value;\n            const assignTo = document.getElementById('filterAssignTo').value;\n            const date     = dpSelectedDate ? dpFmtISO(dpSelectedDate) : '';\n\n            if (deptId)   params.set('department_id', deptId);\n            if (assignTo) params.set('assign_to',     assignTo);\n            if (date)     params.set('date',           date);\n\n            const res    = await fetch(`${ENDPOINTS.ERRORS_ALL}?${params}`, { headers: getHeaders() });\n            const result = await res.json();\n\n            allData = result?.data?.data\n                   || result?.data\n                   || result?.response\n                   || result?.errors\n                   || [];\n\n            if (!Array.isArray(allData)) allData = [];\n\n            filteredData = [...allData];\n            currentPage  = 1;\n            renderTable();\n\n        } catch (err) {\n            console.error('Fetch errors:', err);\n            showEmpty('Failed to load data. Please try again.');\n        }\n    }\n\n    function doSearch() { fetchErrors(); }\n\n    \/\/ RENDER TABLE\n    function renderTable() {\n        const tbody = document.getElementById('tableBody');\n        const total = filteredData.length;\n\n        if (total === 0) { showEmpty('No records found.'); renderPagination(0); return; }\n\n        const start = (currentPage - 1) * PER_PAGE;\n        const end   = Math.min(start + PER_PAGE, total);\n        const slice = filteredData.slice(start, end);\n\n        tbody.innerHTML = slice.map(row => {\n            const type = (row.type || row.error_type || '').toLowerCase();\n            let badgeClass = 'type-zero';\n            if (type.includes('minor'))    badgeClass = 'type-minor';\n            if (type.includes('critical')) badgeClass = 'type-critical';\n\n            const displayType = row.type || row.error_type || '\u2014';\n            const assignTo    = row.assign_to_name || '\u2014';\n            const createdBy   = row.action_by_name || '\u2014';\n            const date        = formatDate(row.created_at || row.date || '');\n            const desc        = row.description || '\u2013';\n            const errCount    = row.error_count ?? row.count ?? '\u2014';\n            const errWtg      = row.error_wtg ?? row.wtg ?? '\u2014';\n            const id          = row.id || row._id || '';\n\n            return `\n            <tr>\n                <td>${escHtml(String(assignTo))}<\/td>\n                <td><span class=\"type-badge ${badgeClass}\">${escHtml(displayType)}<\/span><\/td>\n                <td>${errCount}<\/td>\n                <td>${errWtg}<\/td>\n                <td style=\"max-width:320px;\">${escHtml(desc)}<\/td>\n                <td>${escHtml(String(createdBy))}<\/td>\n                <td style=\"white-space:nowrap;\">${date}<\/td>\n                <td>\n                    <button class=\"view-btn\" onclick=\"window.location.href='https:\/\/ph-portal.zyneventures.com\/index.php\/general-errors\/'\" title=\"View\">\n                        <svg width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\">\n                            <ellipse cx=\"12\" cy=\"12\" rx=\"10\" ry=\"10\" stroke=\"none\"\/>\n                            <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"\/>\n                            <circle cx=\"12\" cy=\"12\" r=\"3\"\/>\n                        <\/svg>\n                    <\/button>\n                <\/td>\n            <\/tr>`;\n        }).join('');\n\n        renderPagination(total);\n    }\n\n    function showLoading() {\n        document.getElementById('tableBody').innerHTML =\n            `<tr class=\"loading-row\"><td colspan=\"8\"><span class=\"spinner\"><\/span> Loading\u2026<\/td><\/tr>`;\n        document.getElementById('totalCount').textContent = '(0)';\n    }\n\n    function showEmpty(msg) {\n        document.getElementById('tableBody').innerHTML =\n            `<tr class=\"empty-row\"><td colspan=\"8\">${msg}<\/td><\/tr>`;\n    }\n\n    \/\/ PAGINATION\n    function renderPagination(total) {\n        const pages = Math.max(1, Math.ceil(total \/ PER_PAGE));\n        totalPages  = pages;\n\n        document.getElementById('totalCount').textContent = `(${total})`;\n        const start = total === 0 ? 0 : (currentPage - 1) * PER_PAGE + 1;\n        const end   = Math.min(currentPage * PER_PAGE, total);\n        document.getElementById('entryInfo').textContent =\n            `Showing ${start} to ${end} of ${total} entries`;\n\n        const prevBtn = document.getElementById('prevBtn');\n        const nextBtn = document.getElementById('nextBtn');\n        prevBtn.className = currentPage === 1      ? 'nav-btn disabled' : 'nav-btn';\n        nextBtn.className = currentPage === pages  ? 'nav-btn disabled' : 'nav-btn';\n        prevBtn.onclick = () => { if (currentPage > 1)      goPage(currentPage - 1); };\n        nextBtn.onclick = () => { if (currentPage < pages)  goPage(currentPage + 1); };\n\n        const container = document.getElementById('pageNumbers');\n        container.innerHTML = '';\n\n        let pagesToShow = [];\n        if (pages <= 7) {\n            for (let i = 1; i <= pages; i++) pagesToShow.push(i);\n        } else {\n            pagesToShow.push(1);\n            if (currentPage > 3) pagesToShow.push('...');\n            let s = Math.max(2, currentPage - 1);\n            let e = Math.min(pages - 1, currentPage + 1);\n            if (currentPage <= 3)       e = Math.min(5, pages - 1);\n            if (currentPage >= pages-2) s = Math.max(2, pages - 4);\n            for (let i = s; i <= e; i++) pagesToShow.push(i);\n            if (currentPage < pages - 2) pagesToShow.push('...');\n            if (!pagesToShow.includes(pages)) pagesToShow.push(pages);\n        }\n\n        pagesToShow.forEach(p => {\n            if (p === '...') {\n                const span = document.createElement('span');\n                span.className = 'dots';\n                span.textContent = '\u2026';\n                container.appendChild(span);\n            } else {\n                const span = document.createElement('span');\n                span.className = 'page-num' + (p === currentPage ? ' active' : '');\n                span.textContent = p;\n                span.onclick = () => goPage(p);\n                container.appendChild(span);\n            }\n        });\n    }\n\n    function goPage(p) {\n        currentPage = p;\n        renderTable();\n    }\n\n    \/\/ \u2500\u2500 CUSTOM DATE PICKER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    let dpViewYear, dpViewMonth;          \/\/ calendar view state\n    let dpSelectedDate  = null;           \/\/ JS Date \u2013 the chosen single date\n    let dpActivePreset  = 'today';        \/\/ which preset is highlighted\n\n    const MONTHS = ['January','February','March','April','May','June',\n                    'July','August','September','October','November','December'];\n\n    function dpToday() {\n        const d = new Date(); d.setHours(0,0,0,0); return d;\n    }\n    function dpFmt(d) {\n        if (!d) return '';\n        const dd = String(d.getDate()).padStart(2,'0');\n        const mm = String(d.getMonth()+1).padStart(2,'0');\n        return `${dd}-${mm}-${d.getFullYear()}`;\n    }\n    function dpFmtISO(d) {\n        if (!d) return '';\n        const dd = String(d.getDate()).padStart(2,'0');\n        const mm = String(d.getMonth()+1).padStart(2,'0');\n        return `${d.getFullYear()}-${mm}-${dd}`;\n    }\n    function dpSameDay(a, b) {\n        return a && b && a.getFullYear()===b.getFullYear() &&\n               a.getMonth()===b.getMonth() && a.getDate()===b.getDate();\n    }\n\n    function dpRenderCalendar() {\n        \/\/ Second month = first month + 1\n        let y2 = dpViewYear, m2 = dpViewMonth + 1;\n        if (m2 > 11) { m2 = 0; y2++; }\n\n        document.getElementById('dpCalTitle').textContent  = `${MONTHS[dpViewMonth]} ${dpViewYear}`;\n        document.getElementById('dpCalTitle2').textContent = `${MONTHS[m2]} ${y2}`;\n\n        document.getElementById('dpDays').innerHTML  = dpBuildDays(dpViewYear, dpViewMonth);\n        document.getElementById('dpDays2').innerHTML = dpBuildDays(y2, m2);\n    }\n\n    function dpBuildDays(year, month) {\n        const today = dpToday();\n        const first = new Date(year, month, 1);\n        const startDay = first.getDay();\n        const daysInMonth = new Date(year, month + 1, 0).getDate();\n\n        let html = '';\n        for (let i = 0; i < startDay; i++) {\n            const prevDate = new Date(year, month, 0 - (startDay - i - 2));\n            html += `<div class=\"dp-day other-month\" onclick=\"dpPickDay(event,${prevDate.getFullYear()},${prevDate.getMonth()},${prevDate.getDate()})\">${prevDate.getDate()}<\/div>`;\n        }\n        for (let d = 1; d <= daysInMonth; d++) {\n            const cur = new Date(year, month, d);\n            let cls = 'dp-day';\n            if (dpSameDay(cur, today))          cls += ' today';\n            if (dpSameDay(cur, dpSelectedDate)) cls += ' selected';\n            html += `<div class=\"${cls}\" onclick=\"dpPickDay(event,${year},${month},${d})\">${d}<\/div>`;\n        }\n        const filled = startDay + daysInMonth;\n        const rem = filled % 7 === 0 ? 0 : 7 - (filled % 7);\n        for (let d = 1; d <= rem; d++) {\n            html += `<div class=\"dp-day other-month\" onclick=\"dpPickDay(event,${year},${month + 1},${d})\">${d}<\/div>`;\n        }\n        return html;\n    }\n\n    function dpPickDay(e, y, m, d) {\n        e.stopPropagation();\n        dpSelectedDate = new Date(y, m, d);\n        dpActivePreset = null;\n        document.querySelectorAll('.dp-preset-item').forEach(el => el.classList.remove('active'));\n        dpViewYear = y; dpViewMonth = m;\n        dpRenderCalendar();\n    }\n\n    function dpChangeMonth(e, dir) {\n        e.stopPropagation();\n        dpViewMonth += dir;\n        if (dpViewMonth > 11) { dpViewMonth = 0; dpViewYear++; }\n        if (dpViewMonth < 0)  { dpViewMonth = 11; dpViewYear--; }\n        dpRenderCalendar();\n    }\n\n    function selectPreset(e, preset) {\n        e.stopPropagation();\n        const today = dpToday();\n        dpActivePreset = preset;\n        document.querySelectorAll('.dp-preset-item').forEach(el =>\n            el.classList.toggle('active', el.dataset.preset === preset));\n\n        switch (preset) {\n            case 'today':\n                dpSelectedDate = new Date(today); break;\n            case 'yesterday': {\n                const y = new Date(today); y.setDate(y.getDate()-1);\n                dpSelectedDate = y; break;\n            }\n            case 'last7': {\n                const y = new Date(today); y.setDate(y.getDate()-6);\n                dpSelectedDate = y; break;\n            }\n            case 'last30': {\n                const y = new Date(today); y.setDate(y.getDate()-29);\n                dpSelectedDate = y; break;\n            }\n            case 'thisMonth':\n                dpSelectedDate = new Date(today.getFullYear(), today.getMonth(), 1); break;\n            case 'lastMonth':\n                dpSelectedDate = new Date(today.getFullYear(), today.getMonth()-1, 1); break;\n        }\n        dpViewYear  = dpSelectedDate.getFullYear();\n        dpViewMonth = dpSelectedDate.getMonth();\n        dpRenderCalendar();\n    }\n\n    function dpApply(e) {\n        e.stopPropagation();\n        document.getElementById('dateDisplay').value = dpSelectedDate ? dpFmtISO(dpSelectedDate) : '';\n        closeDatePicker();\n    }\n\n    function dpClear(e) {\n        e.stopPropagation();\n        dpSelectedDate = null;\n        dpActivePreset = null;\n        document.getElementById('dateDisplay').value = '';\n        document.querySelectorAll('.dp-preset-item').forEach(el => el.classList.remove('active'));\n        dpRenderCalendar();\n        closeDatePicker();\n    }\n\n    function toggleDatePicker(e) {\n        e.stopPropagation();\n        const dd = document.getElementById('dpDropdown');\n        if (dd.classList.contains('open')) {\n            closeDatePicker();\n        } else {\n            const ref = dpSelectedDate || dpToday();\n            dpViewYear  = ref.getFullYear();\n            dpViewMonth = ref.getMonth();\n            if (!dpSelectedDate) {\n                dpActivePreset = 'today';\n                document.querySelectorAll('.dp-preset-item').forEach(el =>\n                    el.classList.toggle('active', el.dataset.preset === 'today'));\n            }\n            dpRenderCalendar();\n            dd.classList.add('open');\n            document.getElementById('dpBackdrop').classList.add('show');\n\n            \/\/ Smart alignment: if dropdown overflows right edge, align right\n            requestAnimationFrame(() => {\n                const rect = dd.getBoundingClientRect();\n                if (rect.right > window.innerWidth - 8) {\n                    dd.classList.add('align-right');\n                } else {\n                    dd.classList.remove('align-right');\n                }\n            });\n        }\n    }\n\n    function closeDatePicker() {\n        document.getElementById('dpDropdown').classList.remove('open');\n        document.getElementById('dpBackdrop').classList.remove('show');\n    }\n\n    \/\/ Close when clicking outside (desktop fallback)\n    document.addEventListener('click', function(e) {\n        if (!document.getElementById('dpWrapper').contains(e.target)) {\n            closeDatePicker();\n        }\n    });\n\n    \/\/ ADD \u2014 redirect to add page\n    function openAddModal() {\n        window.location.href = 'https:\/\/ph-portal.zyneventures.com\/index.php\/add-general-errors\/';\n    }\n\n    \/\/ CSV DOWNLOAD\n    function downloadCSV() {\n        if (!filteredData.length) { showToast('No data to export.', 'error'); return; }\n        const headers = ['Assign To','Type','Error Count','Error WTG','Description','Created By','Date'];\n        const rows = filteredData.map(r => [\n            r.assign_to_name || '',\n            r.type || r.error_type || '',\n            r.error_count ?? r.count ?? '',\n            r.error_wtg ?? r.wtg ?? '',\n            (r.description || '').replace(\/,\/g, ';'),\n            r.action_by_name || '',\n            formatDate(r.created_at || r.date || ''),\n        ]);\n        const csv = [headers.join(','), ...rows.map(r => r.join(','))].join('\\n');\n        const a   = document.createElement('a');\n        a.href    = 'data:text\/csv;charset=utf-8,' + encodeURIComponent(csv);\n        a.download = 'general_errors.csv';\n        a.click();\n    }\n\n    \/\/ UTILS\n    function formatDate(str) {\n        if (!str) return '\u2014';\n        const d = new Date(str);\n        if (isNaN(d)) return str;\n        const day   = String(d.getDate()).padStart(2, '0');\n        const month = d.toLocaleString('en-US', { month: 'short' });\n        const year  = d.getFullYear();\n        return `${day}-${month}-${year}`;\n    }\n\n    function escHtml(str) {\n        return str.replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;').replace(\/\"\/g,'&quot;');\n    }\n\n    \/\/ INIT\n    (async function init() {\n        await loadDropdowns();\n        await fetchErrors();\n    })();\n<\/script>\n<\/div><\/div>\n\n<\/div><\/div><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>General Errors (0) Assign To * Select Department * Select Department Select Date Today Yesterday Last 7 Days Last 30 Days This Month Last Month &#8249; &#8250; Su Mo Tu We Th Fr Sa &#8249; &#8250; Su Mo Tu We Th Fr Sa Clear Apply Search + Add New General Error + Download CSV Assign&#8230;<\/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-167","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages\/167","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=167"}],"version-history":[{"count":3,"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages\/167\/revisions"}],"predecessor-version":[{"id":178,"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages\/167\/revisions\/178"}],"wp:attachment":[{"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/media?parent=167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}