# Formipay — Migration Strategy **Date:** April 18, 2026 (Updated) **Context:** Phase 2 — React Admin Foundation --- ## Overview This document explains how to approach migrating existing Formipay admin interfaces to React while **ensuring zero feature loss**. **Key Principle:** **Coexistence until Feature Parity** — New React versions must match or exceed old functionality before deprecating old code. No "delete and replace" without validation. --- ## Existing Technology Inventory | Technology | Location | Purpose | Feature Count | Migration Priority | |-------------|----------|---------|---------------|-------------------| | **WPCFTO Framework** | `vendor/` | Settings form builder | N/A | Low (replaced by React settings) | | **Grid.js** | `admin/assets/js/page-*.js` | All admin tables | ~20 features per page | **HIGH** (current gap) | | **SweetAlert2** | `vendor/SweetAlert2/` | Modal dialogs | N/A | None (keep using) | | **Custom Vue 2 App** | `admin/assets/js/admin-product-editor.js` | Product variation pricing | ~7 features | Medium | | **jQuery** | Core WP dependency | DOM manipulation | N/A | Phase out gradually | --- ## Critical: Grid.js Migration Strategy ### Current Grid.js Features (Must Preserve) **Every admin page with Grid.js has these features:** | Feature | Forms | Coupons | Access | Orders | Products | |---------|-------|--------|-------|--------|----------| | Checkbox column + "Select All" | ✅ | ✅ | ✅ | ✅ | ✅ | | Bulk delete button | ✅ | ✅ | ✅ | ✅ | ✅ | | Inline row actions (hover) | ✅ | ✅ | ✅ | ✅ | ✅ | | Status filter tabs (All/Published/Draft) | ✅ | ✅ | ✅ | ❌ | ✅ | | Search input | ✅ | ✅ | ✅ | ✅ | ✅ | | Sort dropdown | ✅ | ✅ | ✅ | ❌ | ✅ | | Order (ASC/DESC) | ✅ | ✅ | ✅ | ❌ | ✅ | | Server-side pagination | ✅ | ✅ | ✅ | ✅ | ✅ | | "Add New" modal (SweetAlert2) | ✅ | ✅ | ✅ | ❌ | ✅ | | Inline delete action | ✅ | ✅ | ✅ | ✅ | ✅ | | Inline duplicate action | ✅ | ✅ | ✅ | ❌ | ✅ | | Shortcode copy button | ✅ | ❌ | ❌ | ❌ | ❌ | | Multi-currency display | ❌ | ✅ | ❌ | ❌ | ✅ | **Total: ~20 table features per page** ### Migration Approach: Coexistence **DO NOT:** Delete old Grid.js code until React replacement is feature-complete **DO:** Use query param or feature flag to run both versions side-by-side ``` Phase 1: Coexistence (Required) ┌─────────────────────────────────────────────────────────┐ │ Formipay Admin │ ├─────────────────────────────────────────────────────────┤ │ Old: Grid.js Tables → Fully functional │ │ New: React Tables → Under development, feature-incomplete │ │ │ │ Access: ?old=1 → Grid.js | ?old=0 → React (default when ready) │ └─────────────────────────────────────────────────────────┘ ``` ### Implementation Steps **Step 1: Feature Parity Checklist** Create `MIGRATION_CHECKLIST.md` with per-page feature requirements (see template below). **Step 2: Dual-Mode Rendering** In PHP page callback, check for query param: ```php public function formipay_form() { $use_react = isset($_GET['react']) || get_option('formipay_use_react_admin', false); if ($use_react) { \Formipay\Admin\ReactAdmin::render_mount_point('forms'); } else { include_once FORMIPAY_PATH . 'admin/page-forms.php'; } } ``` **Step 3: Feature Flag for Default** ```php // In settings or option public function use_react_admin() { return get_option('formipay_use_react_admin', false); } ``` **Step 4: Toggle Link in Admin** ```php // Add to admin footer or menu bar Try React Admin (Beta) Use Classic Admin ``` ### Testing Protocol Before setting `use_react_admin` to true as default: 1. **Manual Feature Testing**: Go through checklist item by item 2. **Regression Testing**: Old Grid.js version still works 3. **Data Compatibility**: Both versions read/write same data format 4. **Performance**: React version not significantly slower 5. **Browser Testing**: Test in Chrome, Firefox, Safari **Only when ALL checkboxes pass → Enable React by default** --- ## React Component Library Strategy ### Approved Libraries | Library | Purpose | Why | |---------|---------|-----| | **@wordpress/components** | UI primitives (Button, Modal, SelectControl, TextControl) | Native WP styling, already bundled | | **@tanstack/react-table** (v8) | Headless table engine | Flexible, performant, React 18 compatible | | **SweetAlert2** (existing) | Modals, confirmations, toasts | Already in use, keep as-is | | **@wordpress/icons** | Icons | Already bundled, correct WP styling | ### Libraries to AVOID | Library | Reason to Avoid | |---------|-----------------| | **shadcn/ui** | Wrong styling (Tailwind vs WP), requires Tailwind setup | | **Material UI (@mui/x-data-grid)** | Wrong styling, 100KB+ bundle, overkill | | **react-table** (v7) | Deprecated, use @tanstack/react-table | | **react-data-table** | Heavy bundle, opinionated styling | ### Building the Table Component ```jsx // Use @tanstack/react-table for the engine import { useReactTable } from '@tanstack/react-table'; // Use @wordpress/components for UI import { Modal, Button, CheckboxControl } from '@wordpress/components'; // Style with WordPress classes ``` --- ## Data Compatibility Requirements ### AJAX Endpoints (Must Preserve) | Endpoint | Request | Response Format | |----------|---------|------------------| | `formipay-tabledata-forms` | GET + params | `{results, total, posts_report}` | | `formipay-create-form-post` | POST + title | `{success, data: {edit_post_url}}` | | `formipay-delete-form` | POST + id | `{success, data: {title, message, icon}}` | | `formipay-duplicate-form` | POST + id | `{success, data: {title, message, icon}}` | | `formipay-bulk-delete-form` | POST + ids[] | `{success, data: {title, message, icon}}` | | `get_product_variables` | GET + post_id | Variation data object | | `formipay-tabledata-coupons` | GET + params | `{results, total, posts_report}` | | `formipay-tabledata-access-items` | GET + params | `{results, total, posts_report}` | | `formipay-tabledata-orders` | GET + params | `{results, total, posts_report}` | | `formipay-tabledata-customers` | GET + params | `{results, total, posts_report}` | **Critical:** Response formats must remain identical for compatibility! --- ## Rollback Plan If React version has issues: 1. **Immediate:** Set `formipay_use_react_admin` to false 2. **Users see:** Classic Grid.js version (fully functional) 3. **Fix React:** Debug and fix in development 4. **Retest:** Go through checklist again 5. **Re-enable:** Set flag back to true **Critical:** Never deploy without working fallback! --- ## Migration Checklist Template Copy this template for each page migration: ### [Page Name] Migration Checklist #### Table Core Features - [ ] Data loads and displays correctly - [ ] Loading spinner shown during fetch - [ ] Empty state shown when no data - [ ] Error state handled gracefully #### Selection Features - [ ] Checkbox column renders - [ ] "Select All" checkbox works - [ ] Individual row checkboxes work - [ ] Checkboxes persist across page changes - [ ] Bulk delete button appears when rows selected - [ ] Bulk delete confirmation modal - [ ] Bulk delete refreshes table #### Row Actions - [ ] Hover shows action links - [ ] Edit action navigates correctly - [ ] Delete action shows confirmation - [ ] Delete action removes row and refreshes - [ ] Duplicate action shows confirmation - [ ] Duplicate action adds new row and refreshes #### Filtering & Sorting - [ ] Status filter tabs work - [ ] Status counts display correctly - [ ] Active filter highlighted - [ ] Search input filters results - [ ] Search debounce (don't spam server) - [ ] Sort dropdown works - [ ] Order toggle works - [ ] Combined filters work (search + status + sort) #### Pagination - [ ] Pagination controls display - [ ] Page numbers correct - [ ] Next/Previous buttons work - [ ] Limit per page respected - [ ] Total count accurate #### Create Features - [ ] "Add New" button visible - [ ] Modal/dialog opens on click - [ ] Modal has required fields - [ ] Modal validation works - [ ] Create action succeeds - [ ] Post creation redirects to edit - [ ] Error handling in modal #### UX Details - [ ] Row hover effects work - [ ] Selected row highlighting - [ ] Toast notifications for actions - [ ] Confirmation dialogs for destructive actions - [ ] Keyboard accessibility (Enter, Escape) - [ ] Loading states during actions #### Data Compatibility - [ ] Same AJAX endpoints as old version - [ ] Same request format - [ ] Same response format handling - [ ] Hidden inputs updated (if applicable) - [ ] WordPress nonces handled correctly --- ## Notes - **Grid.js Library:** ~20KB, well-tested, handles server-side pagination well - **@tanstack/react-table:** ~9KB, headless, requires more setup but more flexible - **jQuery:** Still used by WordPress core, will remain for now - **SweetAlert2:** Keep using, integrates well with React - **Migration is NOT a race:** Take time to get it right --- *End of Migration Strategy.*