# DataTable Audit and Standardization Report

## Scope Snapshot

- Scan date: 2026-07-01
- DataTable initializations found: 46 (across 25 source files)
- Files with `<table` based listing UI: 42
- Library variants found:
  - DataTables 1.13.8 (lookup tracking)
  - DataTables 1.13.7 (majority of admin pages)
  - DataTables 1.13.6 (campaign segment/global search)
  - DataTables 1.10.7 (report-libs vendor bundle used by reports + coupon conversion)
  - Buttons extension 2.4.2 (global search / campaign segment)

---

## 1) DataTable Inventory Report

### A. DataTables / DataTable-powered table implementations

| Page / Section | Module | Route / URL | File Path | Library + Version | Data Source | Custom Styling | Loader / Processing | Pagination | Search / Filter | Sorting | Export | Responsive | Row Actions | Custom callbacks / handlers |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Invoice Templates table (`#invoice-templates-table`) | Invoice | `admin/invoice` | `resources/views/filament/resources/invoice-resource/pages/invoice-admin.blade.php` + `public/js/invoice-template-list.js` | DataTables CDN 1.13.7 | Ajax (`indexUrl`), client-side table processing | Page CSS (`invoice-admin.blade.php`) + global framework | DataTables processing text; no custom overlay | Default DataTables paging, `pageLength: 10` | Built-in search with custom Search/Reset buttons in `initComplete` | Enabled | No DT buttons; actions include preview/edit/delete | Not explicitly enabled | Preview/Edit/Delete | `initComplete` rewires search UX, modal preview handlers |
| Segment detail subscribers table | Business Analytics | `admin/analytics-admin/business-analytics` | `public/js/business-analytics.js` | DataTables CDN 1.13.7 (dynamic load) | Static array (`data: customers`) from API response | Business analytics page CSS + global framework | No explicit processing state | `paging: true`, `pageLength: 10`, `lengthChange: false` | Built-in search enabled | Enabled | CSV export implemented outside DataTables | `responsive: true` | None in-table | Segment export flows (graph/table), custom screenshot/csv logic |
| Campaign Segment results (`#segmentTable`) | Campaign Segment | `admin/campaign-segment` | `resources/views/filament/pages/campaign-segment.blade.php` | DataTables CDN 1.13.6 (+ Buttons CSS included) | Ajax server-side (`segmentDataEndpoint`) | Strong page-scoped CSS + global framework | `processing: true` | Server-side, no length change | Built-in search disabled; external filter row controls | Default ordering (column-level orderable flags) | No DT export buttons for table; campaign modal CSV handled separately | Default | Send action + row selection checkbox | Draw handler syncs select-all behavior |
| Global Search results (`#resultTable`) | Global Search | `admin/global-search` | `resources/views/filament/pages/global-search.blade.php` | DataTables CDN 1.13.6 + Buttons 2.4.2 | Ajax server-side (`global.search.data`) | Page-scoped `#resultTable_wrapper` styles + global framework | `processing: true` | `lengthChange: true`, `pageLength: 10`, `lengthMenu` configured | Built-in search disabled; custom filter form inputs + tabs | Enabled (column definition based) | DT Buttons: Excel/CSV/PDF | `scrollX: true` | Transaction invoice action column | Custom dynamic columns by search type |
| SMS Weightage provider table (`$table`) | Operations | `admin/sms-weightage` | `resources/views/filament/pages/operations/sms-weightage.blade.php` | DataTables CDN 1.13.7 | In-memory data/table render (non-server-side) | Page-scoped DataTable control styles + global framework | Uses DataTables language processing text | `pageLength: 10`, `lengthMenu` set | Built-in search true | Enabled; default `order: [[0,'asc']]` | None | `responsive: false` | Inline row actions from render | Custom language/length label |
| Country Restrictions table (`#country-restrictions-table`) | Operations | `admin/country-wise-restrictions` | `resources/views/filament/pages/operations/country-wise-restrictions.blade.php` | DataTables CDN 1.13.7 | Ajax server-side (custom async callback) | Page-scoped wrapper/pagination styling + global framework | `processing: true`, custom message | `pageLength: 10`, `lengthMenu` | Built-in search true + external filters | Enabled, ordered by updated date | None | Default (`scrollX` not forced) | Edit/Delete style actions | Async ajax callback transforms API payload |
| Parental Master table (`#pm-table`) | Operations | `admin/parental-master` | `resources/views/filament/pages/operations/parental-master.blade.php` | DataTables CDN 1.13.7 | Ajax server-side (custom async callback) | Page-scoped styling + global framework | `processing: true`, custom message | `pageLength: 10`, `lengthMenu` | Built-in search false; external filters | Enabled (`order: [[6,'desc']]`) | None | Default | Edit/Delete style actions | Async callback and custom language |
| Lookup Tracking event tables (`#lf-events-table`, `#lf-packages-events-table`, `#lf-global-events-table`, `#lf-signup-events-table`, `#lf-create-order-events-table`, `#lf-complete-order-events-table`) | Logs | `admin/logs/lookup` | `resources/views/filament/pages/logs/lookup-tracking.blade.php` | DataTables CDN 1.13.8 | Ajax server-side async callbacks | Heavy page-scoped DT pagination/control styling + global framework | `processing: true`, custom `language.processing`, draw + row callbacks | `pageLength: DATA_TABLE_PAGE_SIZE`, `lengthMenu` configured | Built-in search false; external filters/control bar | Ordering disabled | None | Default | Mostly details/log context (no CRUD actions) | `createdRow`, `drawCallback`, custom DOM layout (`<"lf-dt-top"l>t<"lf-dt-bottom"ip>`) |
| Back Office Email Templates table (`#email-templates-table`) | Back Office | `admin/back-office-admin` | `resources/views/filament/resources/back-office-admin-resource/pages/back-office-admin.blade.php` | DataTables CDN 1.13.7 | Ajax server-side | Extensive table-specific CSS + global framework | `processing: true`, custom processing overlay hooks | `pageLength: 10`, `lengthMenu` | Built-in search true + custom search controls | Enabled | No DT export button on table | Default | Edit/view style actions | Custom processing events and wrapper manipulations |
| Back Office SMS Templates table (`#sms-templates-table`) | Back Office | `admin/back-office-admin` | Same as above | DataTables CDN 1.13.7 | Ajax server-side | Same | `processing: true`, custom processing text | `pageLength: 10`, `lengthMenu` | Built-in search true + custom controls | Enabled (`order: [[4,'desc']]`) | None | Default | Edit/view style actions | Custom language, dom `lfrtip` |
| Back Office Coupons table (`#coupons-table`) | Back Office | `admin/back-office-admin` | Same as above | DataTables CDN 1.13.7 | Ajax server-side | Same | `processing: true`, custom processing text | `pageLength: 10`, `lengthMenu` | Built-in search true + custom controls | Enabled (`order: [[0,'asc']]`) | None | Default | Edit/performance-style actions | Custom language, dom `lfrtip` |
| Billing Invoices table (`#invoices-table`) | Billing | `admin/billing-admin` | `resources/views/filament/resources/billing-admin-resource/pages/billing-admin.blade.php` | DataTables CDN 1.13.7 | Ajax server-side | Page-scoped table/pagination styles + global framework | `processing: true`, custom text | `pageLength: 10`, `lengthMenu` | Built-in search disabled; external filters | Enabled (`order` by created date) | CSV/PDF exports handled outside DT | Default | Invoice preview/download actions | Custom dom `lfrtip`, custom renderers |
| Billing Gateways table (`#gateways-table`) | Billing | `admin/billing-admin` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | `processing: true`, custom text | `pageLength: 10`, `lengthMenu` | Built-in search disabled; external filters | `ordering: false` in config | None | Default | Row action context driven | dom `frtip` |
| Billing Pending Subscriptions table (`#psubscriptions-table`) | Billing | `admin/billing-admin` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | `processing: true` | `pageLength: 10`, no length change | Built-in search disabled; external filters | `ordering: false` | None | Default | Action buttons | dom `frtip` |
| Dunning campaigns table (`#campaigns-table`) | Billing / Dunning | `admin/billing-admin/dunning-management` | `resources/views/filament/resources/billing-admin-resource/pages/dunning-management.blade.php` | DataTables CDN 1.13.7 | Ajax server-side | Page styles + global framework | `processing: true` | Standard pagination | Built-in search disabled; custom filters | Column-level | No DT export buttons | Default | Campaign actions | Page-level callback handling |
| Gateway lifecycle table (`#gateway-lifecycle-table`) | Billing / Gateway Lifecycle | `admin/billing-admin/gateway-lifecycle` | `resources/views/filament/resources/billing-admin-resource/pages/gateway-lifecycle.blade.php` | DataTables CDN 1.13.7 | Ajax server-side | Page styles + global framework | `processing: true`, custom text | `pageLength: 10`, `lengthChange: true` | Built-in search disabled; external filters | Enabled (`order: [[7,'desc']]`) | None | Default | Row actions in action column | custom language |
| Gateway incidents table (`#gateway-incidents-table`) | Billing / Gateway Lifecycle | `admin/billing-admin/gateway-lifecycle` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | `processing: true`, custom text | `pageLength: 10`, `lengthChange: true` | Built-in search disabled; external filters | Enabled (`order: [[3,'desc']]`) | None | Default | Row actions | custom language |
| Coupon Conversion customers table (`#ccp-customers-table`) | Coupon Conversion Performance | `admin/coupon-conversion-performance` | `resources/views/filament/resources/coupon-conversion-performance-resource/pages/coupon-conversion-performance.blade.php` | `vendor/report-libs` DataTables 1.10.7 | Ajax server-side | CCP table-specific CSS + global framework | `processing: true` + custom text | `pageLength: 10`, length change enabled | Built-in search disabled; filter panel controls | Enabled (`order: [[6,'desc']]`) | No DT export buttons | `scrollX: true` | Detail/action column render | `initComplete`, `drawCallback` hooks |
| Ticket list (`#tickets-table`) | Support Desk / Ticket Admin | `admin/ticket-admin` | `resources/views/filament/resources/ticket-admin-resource/pages/ticket-admin.blade.php` | DataTables CDN 1.13.7 | Ajax server-side | Strong ticket page styling + global framework | `processing: true`, custom overlay hooks | `pageLength: 10`, `lengthMenu` | Built-in search true + custom search controls | Enabled (hidden created sort column) | Export handled outside main table | Default | Update / escalate / read-only action states | `drawCallback`, custom language by tab |
| Support Categories table (`#support-categories-table`) | Support Desk / Ticket Admin | `admin/ticket-admin` | Same file | DataTables CDN 1.13.7 | Static `data: rows` loaded from API first | Same | `processing: true` (client-side table) | `pageLength: 10`, `lengthMenu` | Built-in search true + custom controls | Enabled | None | Default | Edit category action | Language customizations |
| Products table (`#products-table`) | Product Admin | `admin/products` | `resources/views/filament/resources/product-admin-resource/pages/product-admin-products.blade.php` | DataTables CDN 1.13.7 | Ajax server-side | Product page table CSS + global framework | `processing: true`, custom text | `pageLength: 25`, `lengthMenu` | Built-in search disabled; custom global search UI | Enabled (`order` by created_at desc) | No DT export buttons | Default | Edit/delete style actions | `initComplete`, dom `lfrtip` |
| Packages table (`#packages-table`) | Package Admin | `admin/packages` | `resources/views/filament/resources/product-admin-resource/pages/product-admin-packages.blade.php` | DataTables CDN 1.13.7 | Ajax server-side | Package page table CSS + global framework | `processing: true`, custom processing handlers | Server-side pagination | Built-in search disabled; external filters/search | Enabled | Export outside DT | Default | Edit/delete/action buttons | processing event hooks |
| Regions table (`#regions-table`) | Tax Administration | `admin/tax-administration` | `resources/views/filament/resources/tax-administration-resource/pages/tax-administration.blade.php` | DataTables CDN 1.13.7 | Ajax server-side | Table-specific tax styles + global framework | `processing: true`, custom text | `pageLength: 10`, `lengthMenu` | Built-in search true | Enabled (`order` asc) | None | Default | Edit/delete | dom `lfrtip` |
| Tax Groups table (`#tax-groups-table`) | Tax Administration | `admin/tax-administration` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | `processing: true` | `pageLength: 10`, `lengthMenu` | Built-in search true | Enabled (`order` asc) | None | Default | Edit/delete | dom `lfrtip` |
| BU Mapping table (`#bu-mapping-table`) | Tax Administration | `admin/tax-administration` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | `processing: true` | `pageLength: 10`, `lengthMenu` | Built-in search true | Enabled | None | Default | Edit/delete | dom `lfrtip` |
| Compliance Reports table (`#compliance-reports-table`) | Tax Administration | `admin/tax-administration` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | `processing: true` | `pageLength: 10`, `lengthMenu` | Built-in search true | Enabled | Download/report actions (non-DT export buttons) | Default | View/download/delete style actions | dom `lfrtip` |
| Customers table (primary init path) (`#customers-table`) | Subscriber 360 / Customers | `admin/customers` | `resources/views/filament/resources/customer-resource/pages/list-customers.blade.php` | DataTables CDN 1.13.7 | Ajax server-side (custom `ajax` fn + token) | Customers page styles + global framework | `processing: false` + external page loader hooks | `pageLength: 10`, no length change | Built-in search customized to button-driven flow + external filters | Enabled | No DT export button | Default | View action | `initComplete`, `preXhr`, `xhr` handlers |
| Customers table (fallback init path) (`#customers-table`) | Subscriber 360 / Customers | `admin/customers` | Same file | DataTables CDN 1.13.7 | Ajax server-side (`ajax` object) | Same | `processing: true` | Standard pagination | Built-in search true/customized | Enabled | None | Default | View action | alternate initialization/retry flow |
| Customer detail Orders table (`#ordersTable`) | Subscriber 360 / Customer Detail | `admin/customers/{record}` | `resources/views/filament/resources/customer-resource/pages/view-customer.blade.php` | DataTables CDN 1.13.7 | Ajax server-side | Customer detail table styles + global framework | Custom processing markup (`dt-s360-processing`) | `pageLength: 10`, `lengthChange: false`, dom `rtip` | Built-in search true + page filters | `ordering: false` | None | Default | Row detail/action render | Custom columnDefs |
| Customer detail Invoices table (`#invoicesTable`) | Subscriber 360 / Customer Detail | `admin/customers/{record}` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | Custom processing markup | `pageLength: 10`, dom `rtip` | Built-in search true | `ordering: false` | Invoice preview/download links | `scrollX: false` | View/download invoice actions | custom renderers |
| Customer detail Payments table (`#paymentsTable`) | Subscriber 360 / Customer Detail | `admin/customers/{record}` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | Custom processing markup | `pageLength: 10`, dom `rtip` | Built-in search true | `ordering: false` | None | Default | context actions | custom columnDefs |
| Customer detail Coupon Consumption table (`#couponConsumptionTable`) | Subscriber 360 / Customer Detail | `admin/customers/{record}` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | Custom processing markup | `pageLength: 10`, dom `rtip` | Built-in search true | `ordering: false` | None | Default | context actions | custom columnDefs |
| Customer detail Tickets table (`#ticketsTable`) | Subscriber 360 / Customer Detail | `admin/customers/{record}` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | Custom processing markup | `pageLength: 10`, dom `rtip` | Built-in search true | `ordering: false` | None | Default | ticket actions | custom renderers |
| Customer detail Devices table (`#devicesTable`) | Subscriber 360 / Customer Detail | `admin/customers/{record}` | Same file | DataTables CDN 1.13.7 | Ajax server-side | Same | Custom processing markup | `pageLength: 10`, dom `rtip` | Built-in search true | `ordering: false` | None | Default | device actions | custom columnDefs |
| Coupon Usage report table (`#report-table`) | Reports | `admin/reports/coupon-usage-report` | `resources/views/filament/pages/reports/coupon-usage-report.blade.php` + `public/js/reports/coupon-usage-report.js` | `vendor/report-libs` DataTables 1.10.7 | Static data (`data: rows`) after API fetch | Shared report CSS (`report-datatable.css`) + global framework | Page-level loader (`showLoader`) not DT processing | `pageLength: 10`, `lengthMenu` | Built-in search true + custom filter panel | Ordering true | CSV export via report endpoint (outside DT Buttons) | `responsive: false` | None | dynamic columns, date formatting render |
| Order Conversion report table | Reports | `admin/reports/order-conversion-report` | `resources/views/filament/pages/reports/order-conversion-report.blade.php` + `public/js/reports/order-conversion-report.js` | `vendor/report-libs` DataTables 1.10.7 | Static data after API fetch | Shared report CSS + global framework | Page-level loader | `pageLength: 10`, `lengthMenu` | Built-in search true + filters | Ordering true (`order: [[0,'desc']]`) | CSV export outside DT Buttons | `responsive: false` | None | dynamic columns |
| Refund Operation report table | Reports | `admin/reports/refund-operation-report` | `resources/views/filament/pages/reports/refund-operation-report.blade.php` + `public/js/reports/refund-operation-report.js` | `vendor/report-libs` DataTables 1.10.7 | Static data after API fetch | Shared report CSS + global framework | Page-level loader | `pageLength: 10`, `lengthMenu` | Built-in search true + filters | Ordering true | CSV export outside DT Buttons | `responsive: false` | None | dynamic columns |
| Lifecycle Audience report table (primary + fallback init path) | Reports | `admin/reports/lifecycle-audience-reports` | `resources/views/filament/pages/reports/lifecycle-audience-reports.blade.php` + `public/js/reports/lifecycle-audience-reports.js` | `vendor/report-libs` DataTables 1.10.7 | Static data after API fetch | Shared report CSS + global framework | Page-level loader | `pageLength: 10`, `lengthMenu` | Built-in search true + advanced filters | Ordering true (`order: []`) | CSV export outside DT Buttons | Responsive attempted (`responsive: { details: false }`) with fallback `responsive: false` | None | destroy/re-init fallback logic |
| Subscription Export report table | Reports | `admin/reports/subscription-export-report` | `resources/views/filament/pages/reports/subscription-report.blade.php` + `public/js/reports/subscription-report.js` | `vendor/report-libs` DataTables 1.10.7 | Static data after API fetch | Shared report CSS + global framework | Page-level loader | `pageLength: 10`, `lengthMenu` | Built-in search true + filter panel | Ordering true | CSV export outside DT Buttons | `responsive: false` | None | dynamic columns |
| Subscription Product Export report table | Reports | `admin/reports/subscription-product-export-report` | `resources/views/filament/pages/reports/export-subscription-product-report.blade.php` + `public/js/reports/export-subscription-product-report.js` | `vendor/report-libs` DataTables 1.10.7 | Static data after API fetch | Shared report CSS + global framework | Page-level loader | `pageLength: 10`, `lengthMenu` | Built-in search true + filter panel | Ordering true | CSV export outside DT Buttons | `responsive: false` | None | dynamic columns |

### B. Other table-listing UI locations (non-DataTables runtime in these files)

| Page / Component | Module | Route / URL | File Path | Table UI Type | Data Source / Behavior |
|---|---|---|---|---|---|
| Account | Account | `admin/account` | `resources/views/filament/pages/account.blade.php` | Blade/Livewire styled table sections | Livewire state-driven tabular layouts |
| APIs Integrations | Analytics & Admin | `admin/apis-integrations` | `resources/views/filament/pages/apis-integrations.blade.php` | Custom table/list cards | JS fetch + custom rendering |
| Business Analytics APIs partial | Business Analytics | `admin/analytics-admin/business-analytics` | `resources/views/filament/pages/business-analytics/partials/apis.blade.php` | Static/custom table markup | JS-driven widgets |
| Business Analytics Segments partial | Business Analytics | `admin/analytics-admin/business-analytics` | `resources/views/filament/pages/business-analytics/partials/segments.blade.php` | Segment tables/cards | Data fed by `public/js/business-analytics.js` |
| Email Logs | Logs | `admin/logs/email-logs` | `resources/views/filament/pages/logs/email-logs.blade.php` | Custom listing blocks | API/log query based custom rendering |
| Login Frequency | Logs | `admin/logs/login-frequency` | `resources/views/filament/pages/logs/login-frequency.blade.php` | Custom listing blocks | API/log query based custom rendering |
| OTP Tracking | Logs | `admin/logs/otp-tracking` | `resources/views/filament/pages/logs/otp-tracking.blade.php` | Custom listing blocks | API/log query based custom rendering |
| Push Notifications | Operations | `admin/push-notifications` | `resources/views/filament/pages/operations/push-notifications.blade.php` | Custom HTML table (`.push-table`) | Custom JS form + API |
| Churn Waterfall Chart | Retention Trends | `admin/retention-trends/churn-waterfall-chart` | `resources/views/filament/pages/retention-trends/churn-waterfall-chart.blade.php` | Custom table/cards/widgets | API widgets |
| Risk Management | Risk Management | `admin/risk-management` | `resources/views/filament/pages/risk-management.blade.php` | Custom cards/sections with table-like blocks | API widgets |
| Saved Dashboard Preview | Dashboard | `admin/saved-dashboard/{id}/preview` | `resources/views/filament/pages/saved-dashboard-preview.blade.php` | Static data table style (`.data-table`) | Saved snapshot payload |
| Upgrade Subscription | Packages | `admin/packages/upgrade-subscription` | `resources/views/filament/resources/product-admin-resource/pages/upgrade-subscription.blade.php` | Form/list table-like sections | Server-rendered options + AJAX submit |
| Livewire Coupons Table | Back Office | Embedded in `admin/back-office-admin` | `resources/views/livewire/back-office/coupons-table.blade.php` | Livewire table (`boa-admin-table`) | Livewire pagination/filter state |
| Livewire Email Notification Settings | Back Office | Embedded in `admin/back-office-admin` | `resources/views/livewire/back-office/email-notification-settings.blade.php` | Livewire table | Livewire data |
| Livewire Email Templates Table | Back Office | Embedded in `admin/back-office-admin` | `resources/views/livewire/back-office/email-templates-table.blade.php` | Livewire table | Livewire data |
| Livewire SMS Templates Table | Back Office | Embedded in `admin/back-office-admin` | `resources/views/livewire/back-office/sms-templates-table.blade.php` | Livewire table | Livewire data |
| Livewire Send Bulk SMS Form | Back Office | Embedded in `admin/back-office-admin/sms/send` | `resources/views/livewire/back-office/send-bulk-sms-form.blade.php` | Form list selection table-like layout | Livewire state |
| Invoice PDF Preview | Invoice | Public/internal invoice preview rendering | `resources/views/livewire/invoice/invoice-pdf-preview.blade.php` | Static HTML invoice tables | Server-rendered invoice data |

---

## 2) Consistency Review Report

### UI inconsistencies identified

1. Multiple DataTables core versions are in use (`1.10.7`, `1.13.6`, `1.13.7`, `1.13.8`).
2. Buttons extension is loaded only on selected pages (global search/campaign), while other pages use custom export logic.
3. Pagination styles are implemented repeatedly and differently per page (`#*_wrapper .paginate_button` blocks).
4. Search controls vary widely:
   - native DataTables search,
   - native search disabled + external filters,
   - custom Search/Reset button wrappers in `initComplete`.
5. Loader behavior varies:
   - built-in `processing: true`,
   - custom processing text,
   - custom overlay classes (`processing-visible`),
   - external full-page loaders (`showLoader`, `showMainContentAjaxLoader`).
6. Empty-state messages vary (`No data loaded yet`, `No matching ...`, `No records ...`).
7. Responsive behavior differs (`responsive: true`, `responsive: false`, `scrollX: true`, fallback init paths).
8. DOM layout configurations differ (`lfrtip`, `frtip`, `rtip`, custom `<"lf-dt-top"...>` layouts).
9. Row action UI patterns differ significantly (icon buttons, text buttons, pill styles, mixed hover states).
10. Initialization style differs (inline blade scripts, external JS modules, async re-init patterns).

### Different initialization patterns

- Direct one-time init on page load.
- Destroy + re-init on every search/filter action.
- Multiple alternate init paths in the same file (e.g., customers table fallback path, lifecycle report fallback path).
- Manual processing event bindings in many modules (`processing.dt`).

---

## 3) Code Duplication Analysis

### Major duplicated areas

1. **DataTable initialization boilerplate**
   - Repeated blocks with `processing`, `serverSide`, `pageLength`, `lengthMenu`, `language`, `dom`.
2. **Pagination styling duplication**
   - Repeated per-table/per-page CSS selectors for `.dataTables_paginate .paginate_button`.
3. **Loader handling duplication**
   - Repeated `processing.dt` event hooks and wrapper class toggles.
4. **Search control duplication**
   - Repeated Search/Reset button injection + custom keydown handling in multiple pages.
5. **Error handling duplication**
   - Repeated Ajax error callbacks (401 retry, network fallback, default empty response).
6. **Empty state handling duplication**
   - Similar `emptyTable/zeroRecords` text overrides and manual empty-state toggles.
7. **Action rendering duplication**
   - Repeated HTML renderer patterns for view/edit/delete/escalate actions.
8. **Report table duplication**
   - Near-identical DataTable setup in 6 report JS files.

### Representative duplicate locations

- `resources/views/filament/resources/back-office-admin-resource/pages/back-office-admin.blade.php`
- `resources/views/filament/resources/billing-admin-resource/pages/billing-admin.blade.php`
- `resources/views/filament/resources/tax-administration-resource/pages/tax-administration.blade.php`
- `resources/views/filament/resources/customer-resource/pages/view-customer.blade.php`
- `resources/views/filament/pages/logs/lookup-tracking.blade.php`
- `public/js/reports/*.js`

---

## 4) Common Framework Files (Created)

| File | Purpose |
|---|---|
| `public/js/datatable-framework.js` | Global DataTable framework. Adds common defaults, normalizes language defaults, applies shared wrapper classes, binds processing state styling, and patches `$.fn.DataTable` non-destructively so existing page inits continue to work. |
| `public/css/datatable-framework.css` | Shared DataTable UI layer for table typography, row spacing/hover, filter controls, pagination buttons, processing overlay, empty-state visual style, and export button baseline style. |

Framework injection point:

- `resources/views/filament/layouts/app.blade.php` now globally loads both files.

---

## 5) Modified Files

### Global framework wiring

- `resources/views/filament/layouts/app.blade.php`

### New framework files

- `public/js/datatable-framework.js`
- `public/css/datatable-framework.css`

### Runtime compatibility fix applied after validation

- All page-level table initializers continue using native `DataTable(...)` calls.
- Shared framework is applied centrally by patching `$.fn.DataTable` at runtime.
- This avoids timing-related alias issues while preserving backward compatibility.

---

## 6) Architecture Summary

### How the global DataTable framework works

1. `datatable-framework.js` patches jQuery DataTables runtime (`$.fn.DataTable`) once available.
2. It deep-merges common defaults (non-business logic defaults + language baseline) with page-provided options.
3. It decorates DataTable wrappers (`.sms-dt-wrapper`) and controls for shared CSS application.
4. It binds a unified processing class (`.sms-dt-processing`) for consistent loader behavior styling.
5. It keeps existing `DataTable(...)` usage intact and applies the framework without requiring page-level rewrites.

### How pages inherit common config

- Existing tables initialize with native `DataTable(...)` as before.
- Existing page-level options still pass through unchanged.
- Global defaults apply only where page config does not override them.

### How page-specific behavior remains intact

- Existing columns, renderers, ajax callbacks, filters, permissions, and custom event handlers were not removed.
- `initComplete`/`drawCallback` in each table remain preserved and still run.
- Existing page CSS still works; global CSS adds a shared baseline.

### How to implement future DataTables

1. Load table-specific assets as needed.
2. Initialize with `$(selector).DataTable({...})`.
3. Keep business logic in page/module-level `ajax`, `columns`, and callbacks.
4. Avoid duplicating pagination/search/processing UI CSS unless truly page-specific.

---

## 7) Validation Report

Validated against requested constraints:

- Business logic: **unchanged**
- API behavior/integrations: **unchanged**
- Permissions/RBAC: **unchanged**
- Filters/query semantics: **unchanged**
- Workflows/data flow: **unchanged**
- Response structures: **unchanged**
- Table functionality: **preserved**
- Change type: **UI framework centralization + initialization standardization**

Implementation notes:

- No backend/controller/model/query refactors were introduced.
- Refactor is intentionally front-end scoped:
  - global CSS/JS framework,
  - global runtime patching of DataTables UI behavior,
  - layout-level framework inclusion.

---

## 8) Loader Standardization Pass (Subscriber Profile Parity) — 2026-07-01

### Target reference

- Reference loader UX: `Subscriber Profile` page (`view-customer.blade.php`) DataTables processing pill/spinner behavior.

### Pages/sections identified with loader differences vs reference

- Billing (`billing-admin`)
- Tax Management (`tax-administration`)
- Global Search
- Invoice Templates
- Back Office tables (email templates, SMS templates, coupons)
- Support Desk / Ticket Admin tables
- Product Admin tables (products, packages)
- Subscriber 360 customers listing
- Coupon Conversion Performance table
- Reports DataTables (`coupon-usage`, `order-conversion`, `refund-operation`, `lifecycle-audience`, `subscription`, `export-subscription-product`)

Notes:
- `Push Notifications` page uses custom table UI (not DataTables runtime), so DataTables loader standardization is not applicable there.
- `Country Restrictions` and `Parental Master` already used DataTables processing and now inherit centralized loader styling.

### Inconsistencies addressed

- Page-level `.dataTables_processing` CSS overriding global loader visual.
- Page-level `processing-visible` class toggles and manual positioning (`top`, `transform`) overriding shared overlay behavior.
- Missing `processing: true` on some Ajax-backed tables (e.g. Invoice Templates).
- Reports DataTables missing processing mode configuration.
- Legacy `.SMSDataTable()` compatibility gaps.

### Common/global loader framework enhancements

- `public/js/datatable-framework.js`
  - Unified `language.processing` default.
  - Strong normalization of `.dataTables_processing` node style/position.
  - Centralized visibility control (`syncProcessingNodeVisibility`) for processing state.
  - Removal/neutralization of legacy `processing-visible` class conflicts.
  - Added compatibility alias: `$.fn.SMSDataTable`.
  - Ensures already-initialized DataTables are decorated and processing-bound.

- `public/css/datatable-framework.css`
  - Wrapper-level relative positioning for stable overlay anchoring.
  - Unified processing overlay transitions and visibility states.
  - Explicit non-processing override for stale `processing-visible` class.

### Files updated to consume centralized loader behavior

- `resources/views/filament/resources/billing-admin-resource/pages/billing-admin.blade.php`
- `resources/views/filament/resources/tax-administration-resource/pages/tax-administration.blade.php`
- `resources/views/filament/pages/global-search.blade.php`
- `public/js/invoice-template-list.js`
- `resources/views/filament/resources/back-office-admin-resource/pages/back-office-admin.blade.php`
- `resources/views/filament/resources/ticket-admin-resource/pages/ticket-admin.blade.php`
- `resources/views/filament/resources/product-admin-resource/pages/product-admin-packages.blade.php`
- `resources/views/filament/resources/product-admin-resource/pages/product-admin-products.blade.php`
- `resources/views/filament/resources/customer-resource/pages/list-customers.blade.php`
- `resources/views/filament/resources/coupon-conversion-performance-resource/pages/coupon-conversion-performance.blade.php`
- `public/js/reports/coupon-usage-report.js`
- `public/js/reports/order-conversion-report.js`
- `public/js/reports/refund-operation-report.js`
- `public/js/reports/lifecycle-audience-reports.js`
- `public/js/reports/subscription-report.js`
- `public/js/reports/export-subscription-product-report.js`
- `public/js/datatable-framework.js`
- `public/css/datatable-framework.css`

### Validation confirmation

- No business logic changed.
- No API contracts/endpoints changed.
- No permissions/RBAC behavior changed.
- No filter/query logic changed.
- No table functional behavior changed (columns/actions/callbacks preserved).
- Loader UI/UX behavior was centralized into the shared DataTable framework and page-level conflicting presentation overrides were removed or neutralized.
