{"id":181,"date":"2026-03-31T09:56:40","date_gmt":"2026-03-31T09:56:40","guid":{"rendered":"https:\/\/ph-portal.zyneventures.com\/?page_id=181"},"modified":"2026-03-31T09:59:35","modified_gmt":"2026-03-31T09:59:35","slug":"submitted-work-assignment","status":"publish","type":"page","link":"https:\/\/ph-portal.zyneventures.com\/index.php\/submitted-work-assignment\/","title":{"rendered":"Submitted Work Assignment"},"content":{"rendered":"<style>.kadence-column181_cb628b-32 > .kt-inside-inner-col,.kadence-column181_cb628b-32 > .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-column181_cb628b-32 > .kt-inside-inner-col{column-gap:var(--global-kb-gap-sm, 1rem);}.kadence-column181_cb628b-32 > .kt-inside-inner-col{flex-direction:column;}.kadence-column181_cb628b-32 > .kt-inside-inner-col > .aligncenter{width:100%;}.kadence-column181_cb628b-32 > .kt-inside-inner-col:before{opacity:0.3;}.kadence-column181_cb628b-32{position:relative;}@media all and (max-width: 1024px){.kadence-column181_cb628b-32 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}@media all and (max-width: 767px){.kadence-column181_cb628b-32 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}<\/style>\n<div class=\"wp-block-kadence-column kadence-column181_cb628b-32\"><div class=\"kt-inside-inner-col\"><style>.kb-row-layout-id181_987d6a-69 > .kt-row-column-wrap{align-content:start;}:where(.kb-row-layout-id181_987d6a-69 > .kt-row-column-wrap) > .wp-block-kadence-column{justify-content:start;}.kb-row-layout-id181_987d6a-69 > .kt-row-column-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:var(--global-kb-gap-md, 2rem);padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;grid-template-columns:minmax(0, 1fr);}.kb-row-layout-id181_987d6a-69 > .kt-row-layout-overlay{opacity:0.30;}@media all and (max-width: 1024px){.kb-row-layout-id181_987d6a-69 > .kt-row-column-wrap{grid-template-columns:minmax(0, 1fr);}}@media all and (max-width: 767px){.kb-row-layout-id181_987d6a-69 > .kt-row-column-wrap{grid-template-columns:minmax(0, 1fr);}}<\/style><div class=\"kb-row-layout-wrap kb-row-layout-id181_987d6a-69 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-column181_bbd020-9c > .kt-inside-inner-col,.kadence-column181_bbd020-9c > .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-column181_bbd020-9c > .kt-inside-inner-col{column-gap:var(--global-kb-gap-sm, 1rem);}.kadence-column181_bbd020-9c > .kt-inside-inner-col{flex-direction:column;}.kadence-column181_bbd020-9c > .kt-inside-inner-col > .aligncenter{width:100%;}.kadence-column181_bbd020-9c > .kt-inside-inner-col:before{opacity:0.3;}.kadence-column181_bbd020-9c{position:relative;}@media all and (max-width: 1024px){.kadence-column181_bbd020-9c > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}@media all and (max-width: 767px){.kadence-column181_bbd020-9c > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}<\/style>\n<div class=\"wp-block-kadence-column kadence-column181_bbd020-9c\"><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        --bg-light: #F7F8FA;\n        --success-green: #1E8E3E;\n        --white: #ffffff;\n    }\n\n    body {\n        font-family: 'Sora', sans-serif;\n        background-color: var(--white);\n        color: var(--text-dark);\n    }\n\n    \/* Page Header *\/\n    .dashboard-title {\n        font-size: 21px;\n        font-weight: 500;\n        text-transform: uppercase;\n        margin-bottom: 25px;\n        letter-spacing: 0.5px;\n    }\n\n    \/* Filter Grid *\/\n    .filter-grid {\n        display: grid;\n        grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n        gap: 15px;\n        margin-bottom: 20px;\n    }\n\n    .form-group { display: flex; flex-direction: column; }\n    .form-group label {\n        font-size: 12px;\n        margin-bottom: 6px;\n        color: var(--text-dark);\n    }\n\n    .form-control {\n        height: 38px;\n        padding: 0 12px;\n        border: 1px solid #ced4da;\n        border-radius: 6px;\n        font-family: 'Sora', sans-serif;\n        font-size: 12px;\n        outline: none;\n        box-sizing: border-box;\n        width: 100%;\n    }\n\n    .form-control:focus { border-color: var(--primary-blue); }\n\n    \/* Action Row \u2014 fills full width with equal flex *\/\n    .action-row {\n        display: flex;\n        flex-wrap: wrap;\n        gap: 10px;\n        margin-bottom: 25px;\n        width: 100%;\n    }\n    .action-row .btn {\n        flex: 1 1 0;\n        min-width: 90px;\n    }\n\n    .btn {\n        height: 38px;\n        padding: 0 12px;\n        border-radius: 6px;\n        font-size: 12px;\n        cursor: pointer;\n        border: none;\n        transition: 0.2s;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        white-space: nowrap;\n        box-sizing: border-box;\n    }\n    .btn-clear { background: #D0D7F3; color: #555; }\n    .btn-primary { background: var(--primary-blue); color: white; }\n    .btn:hover { opacity: 0.88; }\n\n    \/* Tab Header *\/\n    .tab-header {\n        border-bottom: 2px solid var(--primary-blue);\n        display: inline-block;\n        padding-bottom: 5px;\n        margin-bottom: 20px;\n        font-size: 16px;\n        font-weight: 500;\n        color: var(--text-dark);\n    }\n\n    \/* Table *\/\n    .table-container {\n        width: 100%;\n        overflow-x: auto;\n        border: 1px solid var(--border-color);\n        border-radius: 6px;\n    }\n\n    .data-table {\n        width: 100%;\n        border-collapse: collapse;\n        font-size: 12px;\n        white-space: nowrap;\n        min-width: 900px;\n    }\n\n    .data-table th {\n        background: var(--bg-light);\n        text-align: left;\n        padding: 12px 15px;\n        color: var(--text-dark);\n        font-weight: 500;\n        border-bottom: 1px solid var(--border-color);\n    }\n\n    .data-table td {\n        padding: 12px 15px;\n        border-bottom: 1px solid #f2f2f2;\n        color: #8D8C9C;\n        font-size: 12px;\n        font-weight: 400;\n    }\n\n    \/* Status Badge *\/\n    .status-badge {\n        background-color: #D3EFE8;\n        color: #268A76;\n        padding: 4px 12px;\n        border-radius: 999px;\n        font-size: 12px;\n        font-weight: 500;\n        display: inline-flex;\n        align-items: center;\n        gap: 4px;\n    }\n\n    \/* Pagination Footer \u2014 synced with Assigned_Assignment.html *\/\n    .pagination-footer {\n        margin-top: 20px;\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        font-size: 12px;\n        color: var(--text-muted);\n        flex-wrap: wrap;\n        gap: 15px;\n    }\n\n    .pagination-controls { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }\n\n    .page-num {\n        cursor: pointer;\n        width: 32px;\n        height: 32px;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        border-radius: 50%;\n        font-weight: 400;\n        transition: 0.2s;\n    }\n    .page-num:hover { background: #f0f0f0; }\n    .page-num.active { background: var(--primary-blue); color: white; }\n    .dots { padding: 0 5px; }\n\n    .nav-btn {\n        cursor: pointer;\n        color: var(--text-dark);\n        font-weight: 400;\n        padding: 5px 10px;\n        user-select: none;\n    }\n    .nav-btn.disabled { color: #ccc; pointer-events: none; }\n\n    \/* Hidden CSV file input *\/\n    #csvImportInput { display: none; }\n\n        \/* Custom Date Picker *\/\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            height: 38px;\n            box-sizing: border-box;\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        \/* Custom Date Picker Dropdown *\/\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        .dp-backdrop {\n            display: none;\n            position: fixed;\n            inset: 0;\n            z-index: 1999;\n        }\n        .dp-backdrop.show { display: block; }\n\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        @media (max-width: 750px) {\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            .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\n    \/* Responsive *\/\n    @media (max-width: 1100px) {\n        .filter-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }\n    }\n    @media (max-width: 768px) {\n        body { padding: 12px; }\n        .filter-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }\n        .pagination-footer { justify-content: center; }\n        .action-row { gap: 8px; }\n        .btn { font-size: 11px; }\n    }\n    @media (max-width: 480px) {\n        .filter-grid { grid-template-columns: 1fr; }\n        .action-row .btn { flex: 1 1 calc(50% - 5px); }\n    }\n<\/style>\n\n<div class=\"main-content\">\n    <h2 class=\"dashboard-title\">Submitted Work Assignments &#8211; Data Team<\/h2> <br>\n\n    <div class=\"filter-grid\" id=\"filterForm\"><\/div>\n\n    <div class=\"action-row\">\n        <button class=\"btn btn-clear\" onclick=\"clearFilters()\">Clear<\/button>\n        <button class=\"btn btn-primary\" onclick=\"handleFilter()\">Filter<\/button>\n        <button class=\"btn btn-primary\" onclick=\"handleCSVImport()\">+ CSV Import<\/button>\n        <button class=\"btn btn-primary\" onclick=\"handleDownloadCSV()\">+ Download CSV<\/button>\n    <\/div> <br>\n\n    <!-- Hidden CSV file input -->\n    <input type=\"file\" id=\"csvImportInput\" accept=\".csv\" onchange=\"processCSVImport(event)\">\n\n    <div class=\"tab-header\">Submitted Assignment<\/div> \n\n    <div class=\"table-container\">\n        <table class=\"data-table\">\n            <thead>\n                <tr>\n                    <th>Assigned Date<\/th>\n                    <th>Assigned To<\/th>\n                    <th>Client<\/th>\n                    <th>Project<\/th>\n                    <th>Entity<\/th>\n                    <th>Account<\/th>\n                    <th>Category<\/th>\n                    <th>DOS Count<\/th>\n                    <th>Amount<\/th>\n                    <th>Assigned DOS<\/th>\n                    <th>Completed DOS<\/th>\n                    <th>Pending DOS<\/th>\n                    <th>Hours<\/th>\n                    <th>Created By<\/th>\n                    <th>Approved On<\/th>\n                    <th>Remarks<\/th>\n                    <th>Status<\/th>\n                <\/tr>\n            <\/thead>\n            <tbody id=\"assignmentData\">\n                <tr>\n                    <td colspan=\"17\" style=\"text-align:center; color: var(--text-muted);\">Loading&#8230;<\/td>\n                <\/tr>\n            <\/tbody>\n        <\/table>\n    <\/div>\n\n    <div class=\"pagination-footer\">\n        <div class=\"pagination-controls\">\n            <span id=\"prevBtn\" class=\"nav-btn disabled\" onclick=\"changePage('prev')\">\u00ab Previous<\/span>\n            <div id=\"pageNumbers\" style=\"display: flex; gap: 5px; align-items: center; flex-wrap: wrap;\"><\/div>\n            <span id=\"nextBtn\" class=\"nav-btn disabled\" onclick=\"changePage('next')\">Next \u00bb<\/span>\n        <\/div>\n        <div id=\"entryInfo\">Showing 0 to 0 of 0 entries<\/div>\n    <\/div>\n<\/div>\n\n<script>\n    \/** \u2500\u2500 ENDPOINTS \u2500\u2500 **\/\n    const BASE_URL = 'https:\/\/api-ph-portal.zyneventures.com\/api\/v1';\n    const ENDPOINTS = {\n        SUBMITTED:  `${BASE_URL}\/work_assignment\/submitted`,\n        USERS:      `${BASE_URL}\/user\/table\/list`,\n        CLIENTS:    `${BASE_URL}\/client\/all`,\n        ENTITIES:   `${BASE_URL}\/entity\/all`,\n        CATEGORIES: `${BASE_URL}\/category\/table\/list`,\n        PROJECTS:   `${BASE_URL}\/project\/all`,\n        ACCOUNTS:   `${BASE_URL}\/accountandbenchmark\/tableList`\n    };\n\n    \/** \u2500\u2500 STATE \u2500\u2500 **\/\n    let currentPage    = 1;\n    let totalPages     = 1;\n    let currentPerPage = 25;\n    let currentTotal   = 0;\n    let lastFetchedRows = [];\n\n    const dropDownData = {\n        users:      [],\n        entities:   [],\n        clients:    [],\n        accounts:   [],\n        categories: [],\n        projects:   []\n    };\n\n    \/** \u2500\u2500 AUTH HEADER (matches login_form.html \u2014 token stored as \"TOKEN\") \u2500\u2500 **\/\n    const getHeaders = () => ({\n        'Content-Type':  'application\/json',\n        'Authorization': `Bearer ${localStorage.getItem('TOKEN')}`\n    });\n\n    \/** \u2500\u2500 HELPERS \u2500\u2500 **\/\n    function safeText(value) {\n        if (value === null || value === undefined || value === '') return '-';\n        return String(value)\n            .replaceAll('&',  '&amp;')\n            .replaceAll('<',  '&lt;')\n            .replaceAll('>',  '&gt;')\n            .replaceAll('\"',  '&quot;')\n            .replaceAll(\"'\",  '&#039;');\n    }\n\n    function getFilterValue(id) {\n        const el = document.getElementById(id);\n        return el ? el.value : '';\n    }\n\n    const extractListData = (payload) => {\n        if (Array.isArray(payload?.data))            return payload.data;\n        if (Array.isArray(payload?.data?.data))      return payload.data.data;\n        if (Array.isArray(payload?.data?.data?.data)) return payload.data.data.data;\n        return [];\n    };\n\n    const extractPaginationInfo = (payload, fallbackLimit) => {\n        const directPages = Number(\n            payload?.pagination?.pages       ||\n            payload?.data?.pagination?.pages ||\n            payload?.last_page               ||\n            payload?.data?.last_page         || 0\n        );\n        const limit = Number(\n            payload?.pagination?.limit       ||\n            payload?.data?.pagination?.limit ||\n            payload?.per_page                ||\n            payload?.data?.per_page          ||\n            payload?.data?.perPage           ||\n            fallbackLimit\n        );\n        if (Number.isFinite(directPages) && directPages > 0) {\n            return { pages: directPages, limit: Number.isFinite(limit) && limit > 0 ? limit : fallbackLimit };\n        }\n        const total = Number(\n            payload?.pagination?.total       ||\n            payload?.data?.pagination?.total ||\n            payload?.total                   ||\n            payload?.data?.total             || 0\n        );\n        const safeLimit   = Number.isFinite(limit) && limit > 0 ? limit : fallbackLimit;\n        const derivedPages = total > 0 ? Math.ceil(total \/ safeLimit) : 1;\n        return { pages: Math.max(1, derivedPages), limit: safeLimit };\n    };\n\n    \/** \u2500\u2500 FETCH ALL PAGES FOR DROPDOWNS \u2500\u2500 **\/\n    async function fetchAllPages(endpoint) {\n        const defaultLimit = 500;\n        const buildUrl = (page, limit = defaultLimit) => {\n            const url = new URL(endpoint);\n            url.searchParams.set('page',  String(page));\n            url.searchParams.set('limit', String(limit));\n            return url.toString();\n        };\n        const firstRes  = await fetch(buildUrl(1, defaultLimit), { headers: getHeaders() });\n        const firstJson = await firstRes.json();\n        let allItems    = extractListData(firstJson);\n        const { pages, limit } = extractPaginationInfo(firstJson, defaultLimit);\n        if (pages > 1) {\n            const pageRequests = [];\n            for (let page = 2; page <= pages; page++) {\n                pageRequests.push(\n                    fetch(buildUrl(page, limit), { headers: getHeaders() })\n                        .then(r => r.json())\n                        .catch(() => null)\n                );\n            }\n            const otherPages = await Promise.all(pageRequests);\n            otherPages.forEach(pageData => {\n                if (pageData) allItems = allItems.concat(extractListData(pageData));\n            });\n        }\n        return allItems;\n    }\n\n    \/** \u2500\u2500 FETCH DROPDOWN DATA \u2500\u2500 **\/\n    async function fetchDropdownData() {\n        try {\n            const [u, e, c, a, cat, p] = await Promise.all([\n                fetchAllPages(ENDPOINTS.USERS),\n                fetchAllPages(ENDPOINTS.ENTITIES),\n                fetchAllPages(ENDPOINTS.CLIENTS),\n                fetch(ENDPOINTS.ACCOUNTS, { headers: getHeaders() }).then(r => r.json()),\n                fetchAllPages(ENDPOINTS.CATEGORIES),\n                fetchAllPages(ENDPOINTS.PROJECTS)\n            ]);\n            dropDownData.users      = Array.isArray(u)   ? u   : [];\n            dropDownData.entities   = Array.isArray(e)   ? e   : [];\n            dropDownData.clients    = Array.isArray(c)   ? c   : [];\n            dropDownData.accounts   = Array.isArray(a)   ? a   : extractListData(a);\n            dropDownData.categories = Array.isArray(cat) ? cat : [];\n            dropDownData.projects   = Array.isArray(p)   ? p   : [];\n        } catch (err) {\n            console.error('Dropdown fetch error', err);\n        }\n    }\n\n    \/** \u2500\u2500 RENDER DROPDOWNS \u2500\u2500 **\/\n    function renderSelect(label, selectId, data, labelKey, valueKey = 'id') {\n        return `\n            <div class=\"form-group\">\n                <label>${label}<\/label>\n                <select id=\"${selectId}\" class=\"form-control\">\n                    <option value=\"\">Select ${label}<\/option>\n                    ${data.map(item => `<option value=\"${item[valueKey] ?? ''}\">${item[labelKey] ?? ''}<\/option>`).join('')}\n                <\/select>\n            <\/div>\n        `;\n    }\n\n    function renderFilters() {\n        document.getElementById('filterForm').innerHTML = `\n            ${renderSelect('Assigned to', 'filterAssignedTo', dropDownData.users,      'name',     'id')}\n            ${renderSelect('Entity',      'filterEntity',     dropDownData.entities,   'entity',   'id')}\n            ${renderSelect('Client',      'filterClient',     dropDownData.clients,    'name',     'id')}\n            ${renderSelect('Account',     'filterAccount',    dropDownData.accounts,   'name',     'id')}\n            ${renderSelect('Project',     'filterProject',    dropDownData.projects,   'name',     'id')}\n            ${renderSelect('Category',    'filterCategory',   dropDownData.categories, 'category', 'id')}\n            <div class=\"form-group\"><label>Select Date<\/label>\n                <div class=\"date-wrapper\" id=\"dpWrapperDate\">\n                    <input type=\"text\" id=\"filterDate\" placeholder=\"Select Date\" readonly onclick=\"toggleDatePicker(event,'date')\">\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=\"dpBackdropDate\" onclick=\"closeDatePicker('date')\"><\/div>\n                    <div class=\"dp-dropdown\" id=\"dpDropdownDate\">\n                        <div class=\"dp-presets\">\n                            <div class=\"dp-preset-item active\" data-preset=\"today\"     onclick=\"selectPreset(event,'today','date')\">Today<\/div>\n                            <div class=\"dp-preset-item\"       data-preset=\"yesterday\"  onclick=\"selectPreset(event,'yesterday','date')\">Yesterday<\/div>\n                            <div class=\"dp-preset-item\"       data-preset=\"last7\"      onclick=\"selectPreset(event,'last7','date')\">Last 7 Days<\/div>\n                            <div class=\"dp-preset-item\"       data-preset=\"last30\"     onclick=\"selectPreset(event,'last30','date')\">Last 30 Days<\/div>\n                            <div class=\"dp-preset-item\"       data-preset=\"thisMonth\"  onclick=\"selectPreset(event,'thisMonth','date')\">This Month<\/div>\n                            <div class=\"dp-preset-item\"       data-preset=\"lastMonth\"  onclick=\"selectPreset(event,'lastMonth','date')\">Last Month<\/div>\n                        <\/div>\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,'date')\">&#8249;<\/button>\n                                        <span class=\"dp-cal-title\" id=\"dpCalTitleDate\"><\/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=\"dpDaysDate\"><\/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=\"dpCalTitleDate2\"><\/span>\n                                        <button class=\"dp-nav-btn\" onclick=\"dpChangeMonth(event,1,'date')\">&#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=\"dpDaysDate2\"><\/div>\n                                <\/div>\n                            <\/div>\n                            <div class=\"dp-footer\">\n                                <button class=\"dp-btn-clear\" onclick=\"dpClear(event,'date')\">Clear<\/button>\n                                <button class=\"dp-btn-apply\" onclick=\"dpApply(event,'date')\">Apply<\/button>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n            <div class=\"form-group\">\n                <label>Per Page<\/label>\n                <select id=\"filterPerPage\" class=\"form-control\" onchange=\"fetchTableData(1)\">\n                    <option value=\"25\">25<\/option>\n                    <option value=\"50\">50<\/option>\n                    <option value=\"100\">100<\/option>\n                <\/select>\n            <\/div>\n        `;\n    }\n\n    \/** \u2500\u2500 BUILD URL \u2500\u2500 **\/\n    function buildSubmittedUrl(page = 1) {\n        const url = new URL(ENDPOINTS.SUBMITTED);\n        const perPage = getFilterValue('filterPerPage') || '25';\n        url.searchParams.set('page',    String(page));\n        url.searchParams.set('perPage', String(perPage));\n\n        const filters = {\n            assigned_to:  getFilterValue('filterAssignedTo'),\n            entity_id:    getFilterValue('filterEntity'),\n            client_id:    getFilterValue('filterClient'),\n            account_id:   getFilterValue('filterAccount'),\n            project_id:   getFilterValue('filterProject'),\n            category_id:  getFilterValue('filterCategory'),\n            assigned_date: getFilterValue('filterDate')\n        };\n        Object.entries(filters).forEach(([key, value]) => {\n            if (value !== '') url.searchParams.set(key, value);\n        });\n        return url;\n    }\n\n    \/** \u2500\u2500 FETCH TABLE DATA \u2500\u2500 **\/\n    async function fetchTableData(page = 1) {\n        const url  = buildSubmittedUrl(page);\n        const tbody = document.getElementById('assignmentData');\n        tbody.innerHTML = '<tr><td colspan=\"17\" style=\"text-align:center; color: var(--text-muted);\">Loading...<\/td><\/tr>';\n\n        try {\n            const res  = await fetch(url.toString(), { headers: getHeaders() });\n            const json = await res.json();\n            const rows = Array.isArray(json?.data?.data) ? json.data.data : [];\n            lastFetchedRows = rows;\n\n            if (!rows.length) {\n                tbody.innerHTML = '<tr><td colspan=\"17\" style=\"text-align:center; color: var(--text-muted);\">No data found<\/td><\/tr>';\n                renderPagination({ total: 0, pages: 1, perPage: 25 }, 1);\n                return;\n            }\n\n            tbody.innerHTML = rows.map(row => `\n                <tr>\n                    <td>${safeText(row.assigned_date)}<\/td>\n                    <td>${safeText(row.assigned_to_name)}<\/td>\n                    <td>${safeText(row.client_name)}<\/td>\n                    <td>${safeText(row.project_name)}<\/td>\n                    <td>${safeText(row.entity_name)}<\/td>\n                    <td>${safeText(row.account_name)}<\/td>\n                    <td>${safeText(row.category_name)}<\/td>\n                    <td>${safeText(row.dos_count)}<\/td>\n                    <td>${safeText(row.amount)}<\/td>\n                    <td>${safeText(row.assigned_dos)}<\/td>\n                    <td>${safeText(row.completed_dos)}<\/td>\n                    <td>${safeText(row.pending_dos)}<\/td>\n                    <td>${safeText(row.hours)}<\/td>\n                    <td>${safeText(row.created_by_name || row.created_by)}<\/td>\n                    <td>${safeText(row.approved_on || row.approved_at)}<\/td>\n                    <td>${safeText(row.remarks)}<\/td>\n                    <td><span class=\"status-badge\">${safeText(row.status || 'Submitted')}<\/span><\/td>\n                <\/tr>\n            `).join('');\n\n            const meta = {\n                total:   json?.data?.total    || json?.data?.pagination?.total    || rows.length,\n                pages:   json?.data?.pages    || json?.data?.pagination?.pages    || json?.data?.last_page || 1,\n                perPage: json?.data?.perPage  || json?.data?.pagination?.limit    || json?.data?.per_page  || 25\n            };\n            renderPagination(meta, page);\n\n        } catch (error) {\n            console.error('Submitted fetch error', error);\n            tbody.innerHTML = '<tr><td colspan=\"17\" style=\"text-align:center; color: var(--text-muted);\">Failed to load data<\/td><\/tr>';\n        }\n    }\n\n    \/** \u2500\u2500 PAGINATION (synced with Assigned_Assignment.html) \u2500\u2500 **\/\n    function renderPagination(meta, page) {\n        currentPage    = page;\n        currentTotal   = Number(meta.total)                                          || 0;\n        currentPerPage = Number(meta.perPage || meta.limit || meta.per_page)         || 25;\n        totalPages     = Number(meta.pages) || Math.ceil(currentTotal \/ currentPerPage) || 1;\n\n        const prevBtn   = document.getElementById('prevBtn');\n        const nextBtn   = document.getElementById('nextBtn');\n        const container = document.getElementById('pageNumbers');\n        container.innerHTML = '';\n\n        prevBtn.className = currentPage === 1 ? 'nav-btn disabled' : 'nav-btn';\n        nextBtn.className = currentPage === totalPages ? 'nav-btn disabled' : 'nav-btn';\n\n        let pages = [];\n        if (totalPages <= 5) {\n            for (let i = 1; i <= totalPages; i++) pages.push(i);\n        } else {\n            pages.push(1);\n            if (currentPage > 3) pages.push('...');\n            let start = Math.max(2, currentPage - 1);\n            let end   = Math.min(totalPages - 1, currentPage + 1);\n            if (currentPage <= 2) end = 4;\n            if (currentPage >= totalPages - 1) start = totalPages - 3;\n            for (let i = start; i <= end; i++) {\n                if (!pages.includes(i)) pages.push(i);\n            }\n            if (currentPage < totalPages - 2) pages.push('...');\n            if (!pages.includes(totalPages)) pages.push(totalPages);\n        }\n\n        pages.forEach(p => {\n            if (p === '...') {\n                const span = document.createElement('span');\n                span.className   = 'dots';\n                span.textContent = '...';\n                container.appendChild(span);\n            } else {\n                const span = document.createElement('span');\n                span.className   = p === currentPage ? 'page-num active' : 'page-num';\n                span.textContent = p;\n                span.onclick     = () => fetchTableData(p);\n                container.appendChild(span);\n            }\n        });\n\n        const startEntry = currentTotal === 0 ? 0 : ((currentPage - 1) * currentPerPage) + 1;\n        const endEntry   = Math.min(currentPage * currentPerPage, currentTotal);\n        document.getElementById('entryInfo').textContent =\n            `Showing ${startEntry} to ${endEntry} of ${currentTotal} entries`;\n    }\n\n    function changePage(direction) {\n        if (direction === 'prev' && currentPage > 1)          fetchTableData(currentPage - 1);\n        if (direction === 'next' && currentPage < totalPages) fetchTableData(currentPage + 1);\n    }\n\n    \/** \u2500\u2500 FILTER \/ CLEAR \u2500\u2500 **\/\n    function handleFilter() {\n        fetchTableData(1);\n    }\n\n    function clearFilters() {\n        ['filterAssignedTo', 'filterEntity', 'filterClient', 'filterAccount',\n         'filterProject', 'filterCategory', 'filterDate'].forEach(id => {\n            const el = document.getElementById(id);\n            if (el) el.value = '';\n        });\n        \/\/ Also clear the datepicker state\n        dpState.date.selectedDate = null;\n        dpState.date.activePreset = null;\n        const pp = document.getElementById('filterPerPage');\n        if (pp) pp.value = '25';\n        fetchTableData(1);\n    }\n\n    \/** \u2500\u2500 CSV IMPORT \u2500\u2500 **\/\n    function handleCSVImport() {\n        document.getElementById('csvImportInput').value = '';\n        document.getElementById('csvImportInput').click();\n    }\n\n    function processCSVImport(event) {\n        const file = event.target.files[0];\n        if (!file) return;\n        if (!file.name.toLowerCase().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            const lines = text.trim().split('\\n');\n            if (lines.length < 2) {\n                alert('CSV file is empty or has no data rows.');\n                return;\n            }\n            const headerRow = lines[0].split(',').map(h => h.trim().replace(\/^\"|\"$\/g, ''));\n            const dataRows  = lines.slice(1)\n                .map(line => line.split(',').map(cell => cell.trim().replace(\/^\"|\"$\/g, '')))\n                .filter(row => row.some(cell => cell !== ''));\n\n            if (!dataRows.length) {\n                alert('No data rows found in CSV.');\n                return;\n            }\n\n            \/\/ Re-render table with CSV data\n            const thead = document.querySelector('.data-table thead');\n            const tbody = document.getElementById('assignmentData');\n            thead.innerHTML = `<tr>${headerRow.map(h => `<th>${h}<\/th>`).join('')}<\/tr>`;\n            tbody.innerHTML = dataRows.map(row =>\n                `<tr>${row.map(cell => `<td>${cell || '-'}<\/td>`).join('')}<\/tr>`\n            ).join('');\n\n            renderPagination({ total: dataRows.length, pages: 1, perPage: dataRows.length }, 1);\n            alert(`CSV imported successfully: ${dataRows.length} row(s) loaded.`);\n        };\n        reader.onerror = () => alert('Failed to read the CSV file.');\n        reader.readAsText(file);\n    }\n\n    \/** \u2500\u2500 CSV DOWNLOAD \u2500\u2500 **\/\n    function handleDownloadCSV() {\n        if (!lastFetchedRows || !lastFetchedRows.length) {\n            alert('No data available to download. Please load the table first.');\n            return;\n        }\n\n        const colHeaders = [\n            'Assigned Date', 'Assigned To', 'Client', 'Project', 'Entity', 'Account',\n            'Category', 'DOS Count', 'Amount', 'Assigned DOS', 'Completed DOS',\n            'Pending DOS', 'Hours', 'Created By', 'Approved On', 'Remarks', 'Status'\n        ];\n        const keyMap = {\n            'Assigned Date':  'assigned_date',\n            'Assigned To':    'assigned_to_name',\n            'Client':         'client_name',\n            'Project':        'project_name',\n            'Entity':         'entity_name',\n            'Account':        'account_name',\n            'Category':       'category_name',\n            'DOS Count':      'dos_count',\n            'Amount':         'amount',\n            'Assigned DOS':   'assigned_dos',\n            'Completed DOS':  'completed_dos',\n            'Pending DOS':    'pending_dos',\n            'Hours':          'hours',\n            'Created By':     'created_by_name',\n            'Approved On':    'approved_on',\n            'Remarks':        'remarks',\n            'Status':         'status'\n        };\n\n        const csvLines = [colHeaders.join(',')];\n        lastFetchedRows.forEach(row => {\n            const values = colHeaders.map(h => {\n                const val = row[keyMap[h]] !== undefined && row[keyMap[h]] !== null\n                    ? String(row[keyMap[h]])\n                    : '';\n                return `\"${val.replace(\/\"\/g, '\"\"')}\"`;\n            });\n            csvLines.push(values.join(','));\n        });\n\n        const blob = new Blob([csvLines.join('\\n')], { type: 'text\/csv;charset=utf-8;' });\n        const url  = URL.createObjectURL(blob);\n        const link = document.createElement('a');\n        link.href     = url;\n        link.download = `submitted_assignments_page${currentPage}.csv`;\n        document.body.appendChild(link);\n        link.click();\n        document.body.removeChild(link);\n        URL.revokeObjectURL(url);\n    }\n\n    \/** \u2500\u2500 CUSTOM DATE PICKER (exact match \u2014 Adhoc_Assignment.html) \u2500\u2500 **\/\n    const dpState = {\n        date: { viewYear: null, viewMonth: null, selectedDate: null, activePreset: 'today' }\n    };\n\n    const DP_IDS = {\n        date: { dropdown: 'dpDropdownDate', backdrop: 'dpBackdropDate', title: 'dpCalTitleDate', days: 'dpDaysDate', title2: 'dpCalTitleDate2', days2: 'dpDaysDate2', display: 'filterDate' }\n    };\n\n    const DP_MONTHS = ['January','February','March','April','May','June',\n                       'July','August','September','October','November','December'];\n\n    function dpToday() { 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\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\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(inst) {\n        const s = dpState[inst];\n        const ids = DP_IDS[inst];\n\n        \/\/ Second month = first month + 1\n        let y2 = s.viewYear, m2 = s.viewMonth + 1;\n        if (m2 > 11) { m2 = 0; y2++; }\n\n        document.getElementById(ids.title).textContent  = `${DP_MONTHS[s.viewMonth]} ${s.viewYear}`;\n        document.getElementById(ids.title2).textContent = `${DP_MONTHS[m2]} ${y2}`;\n\n        document.getElementById(ids.days).innerHTML  = dpBuildDays(s.viewYear, s.viewMonth, s, inst);\n        document.getElementById(ids.days2).innerHTML = dpBuildDays(y2, m2, s, inst);\n    }\n\n    function dpBuildDays(year, month, s, inst) {\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()},'${inst}')\">${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, s.selectedDate)) cls += ' selected';\n            html += `<div class=\"${cls}\" onclick=\"dpPickDay(event,${year},${month},${d},'${inst}')\">${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},'${inst}')\">${d}<\/div>`;\n        }\n        return html;\n    }\n\n    function dpPickDay(e, y, m, d, inst) {\n        e.stopPropagation();\n        const s = dpState[inst];\n        s.selectedDate = new Date(y, m, d);\n        s.activePreset = null;\n        document.querySelectorAll(`#${DP_IDS[inst].dropdown} .dp-preset-item`).forEach(el => el.classList.remove('active'));\n        s.viewYear = y; s.viewMonth = m;\n        dpRenderCalendar(inst);\n    }\n\n    function dpChangeMonth(e, dir, inst) {\n        e.stopPropagation();\n        const s = dpState[inst];\n        s.viewMonth += dir;\n        if (s.viewMonth > 11) { s.viewMonth = 0; s.viewYear++; }\n        if (s.viewMonth < 0)  { s.viewMonth = 11; s.viewYear--; }\n        dpRenderCalendar(inst);\n    }\n\n    function selectPreset(e, preset, inst) {\n        e.stopPropagation();\n        const s = dpState[inst];\n        const today = dpToday();\n        s.activePreset = preset;\n        const dropId = DP_IDS[inst].dropdown;\n        document.querySelectorAll(`#${dropId} .dp-preset-item`).forEach(el =>\n            el.classList.toggle('active', el.dataset.preset === preset));\n\n        switch (preset) {\n            case 'today':     s.selectedDate = new Date(today); break;\n            case 'yesterday': { const y = new Date(today); y.setDate(y.getDate()-1); s.selectedDate = y; break; }\n            case 'last7':     { const y = new Date(today); y.setDate(y.getDate()-6); s.selectedDate = y; break; }\n            case 'last30':    { const y = new Date(today); y.setDate(y.getDate()-29); s.selectedDate = y; break; }\n            case 'thisMonth': s.selectedDate = new Date(today.getFullYear(), today.getMonth(), 1); break;\n            case 'lastMonth': s.selectedDate = new Date(today.getFullYear(), today.getMonth()-1, 1); break;\n        }\n        s.viewYear  = s.selectedDate.getFullYear();\n        s.viewMonth = s.selectedDate.getMonth();\n        dpRenderCalendar(inst);\n    }\n\n    function dpApply(e, inst) {\n        e.stopPropagation();\n        const s = dpState[inst];\n        document.getElementById(DP_IDS[inst].display).value = s.selectedDate ? dpFmtISO(s.selectedDate) : '';\n        closeDatePicker(inst);\n    }\n\n    function dpClear(e, inst) {\n        e.stopPropagation();\n        const s = dpState[inst];\n        s.selectedDate = null;\n        s.activePreset = null;\n        document.getElementById(DP_IDS[inst].display).value = '';\n        const dropId = DP_IDS[inst].dropdown;\n        document.querySelectorAll(`#${dropId} .dp-preset-item`).forEach(el => el.classList.remove('active'));\n        dpRenderCalendar(inst);\n        closeDatePicker(inst);\n    }\n\n    function toggleDatePicker(e, inst) {\n        e.stopPropagation();\n        const ids = DP_IDS[inst];\n        const dd = document.getElementById(ids.dropdown);\n        if (dd.classList.contains('open')) {\n            closeDatePicker(inst);\n        } else {\n            const s = dpState[inst];\n            const ref = s.selectedDate || dpToday();\n            s.viewYear  = ref.getFullYear();\n            s.viewMonth = ref.getMonth();\n            if (!s.selectedDate) {\n                s.activePreset = 'today';\n                document.querySelectorAll(`#${ids.dropdown} .dp-preset-item`).forEach(el =>\n                    el.classList.toggle('active', el.dataset.preset === 'today'));\n            }\n            dpRenderCalendar(inst);\n            dd.classList.add('open');\n            document.getElementById(ids.backdrop).classList.add('show');\n\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(inst) {\n        const ids = DP_IDS[inst];\n        document.getElementById(ids.dropdown).classList.remove('open');\n        document.getElementById(ids.backdrop).classList.remove('show');\n    }\n\n    \/\/ Close pickers when clicking outside\n    document.addEventListener('click', function(e) {\n        const wrapEl = document.getElementById('dpWrapperDate');\n        if (wrapEl && !wrapEl.contains(e.target)) {\n            closeDatePicker('date');\n        }\n    });\n\n    \/** \u2500\u2500 INIT \u2500\u2500 **\/\n    async function init() {\n        await fetchDropdownData();\n        renderFilters();\n        fetchTableData(1);\n    }\n\n    window.onload = init;\n<\/script>\n<\/div><\/div>\n\n<\/div><\/div><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Submitted Work Assignments &#8211; Data Team Clear Filter + CSV Import + Download CSV Submitted Assignment Assigned Date Assigned To Client Project Entity Account Category DOS Count Amount Assigned DOS Completed DOS Pending DOS Hours Created By Approved On Remarks Status Loading&#8230; \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-181","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages\/181","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=181"}],"version-history":[{"count":2,"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages\/181\/revisions"}],"predecessor-version":[{"id":183,"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/pages\/181\/revisions\/183"}],"wp:attachment":[{"href":"https:\/\/ph-portal.zyneventures.com\/index.php\/wp-json\/wp\/v2\/media?parent=181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}