# Supplier Select Modal — Two-Step Wizard Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Replace the mutually-exclusive tab bar in the supplier select modal with a two-step wizard: Step 1 picks the supply method (Full Order / By Item), Step 2 shows the appropriate supplier selection UI with a "← Change method" back link that clears all selections. **Architecture:** Single Blade component file change only — no controller, route, or migration work. The HTML is restructured into `#sup-step1` (method cards) and `#sup-step2` (existing form), both children of the modal shell. Two new JS functions (`showStep` / `goBack`) drive transitions; the existing form, panes, and submission logic are untouched. **Tech Stack:** Laravel Blade, vanilla JS, inline CSS (Tailwind JIT not used — inline styles only per project convention) **Spec:** `docs/superpowers/specs/2026-05-25-supplier-modal-wizard-design.md` --- ### Task 1: Replace the header tab bar with the mode badge row **Files:** - Modify: `resources/views/components/purchase/supplier-select-modal.blade.php` The current header has a tab bar (`stab-global`, `stab-item`). Remove it. Replace with a hidden `#sup-mode-badge-row` div (shown only in Step 2). Also add `id="sup-modal-subtitle"` to the subtitle element so JS can update it dynamically. Change the initial title to "Request for Quotation" and subtitle to "How do you want to assign suppliers?". Change `padding:20px 24px 0` → `padding:20px 24px 16px` (the `0` bottom padding was a tab-flush hack no longer needed). - [ ] **Step 1: Replace the header block** In `resources/views/components/purchase/supplier-select-modal.blade.php`, find and replace this exact block: ```blade {{-- Header --}}
Select Suppliers
Choose who receives the quote request
{{-- Tab bar --}}
``` Replace with: ```blade {{-- Header --}}
Request for Quotation
How do you want to assign suppliers?
{{-- Mode badge row: hidden in Step 1, shown in Step 2 --}}
``` - [ ] **Step 2: Verify the file saved correctly** Open `resources/views/components/purchase/supplier-select-modal.blade.php` and confirm: - No `stab-global` or `stab-item` buttons exist - `sup-mode-badge-row` div is present with `display:none` - Title reads "Request for Quotation" - Subtitle element has `id="sup-modal-subtitle"` --- ### Task 2: Add Step 1 method-selection cards and wrap Step 2 **Files:** - Modify: `resources/views/components/purchase/supplier-select-modal.blade.php` Insert `#sup-step1` (method cards + Step 1 Cancel footer) immediately after the header closing ``. Then wrap the existing `
` and the existing footer `
` inside a new `#sup-step2` div. Step 1 is `display:flex` on load; Step 2 is `display:none`. - [ ] **Step 1: Insert Step 1 cards immediately after the header** Find this exact line (the comment that opens the form section): ```blade {{-- Single form wrapping both panes --}} ``` Replace with: ```blade {{-- Step 1: Method selection --}}
{{-- Step 2: Supplier selection --}}
``` Replace with: ```blade {{-- Footer --}}
{{-- /sup-step2 --}} ``` - [ ] **Step 4: Verify structure** Confirm the file now has this nesting order: 1. `#supplier-modal` → modal shell 2. Header (`#sup-mode-badge-row` inside) 3. `#sup-step1` with two card buttons + Cancel footer 4. `#sup-step2` containing `#sup-form` + the Step 2 footer 5. `#sup-step2` closing tag 6. Modal shell closing tags --- ### Task 3: Update JavaScript — add showStep/goBack, update openSupplierModal, remove switchSupTab **Files:** - Modify: `resources/views/components/purchase/supplier-select-modal.blade.php` (script block) - [ ] **Step 1: Replace `openSupplierModal` and remove `switchSupTab`** Find this exact block: ```javascript function openSupplierModal() { document.getElementById('supplier-modal').classList.add('open'); switchSupTab('global'); document.getElementById('sup-search').focus(); } function closeSupplierModal() { closeAllItemDd(); document.getElementById('supplier-modal').classList.remove('open'); } ``` Replace with: ```javascript function openSupplierModal() { document.getElementById('supplier-modal').classList.add('open'); goBack(); } function closeSupplierModal() { closeAllItemDd(); document.getElementById('supplier-modal').classList.remove('open'); } function showStep(method) { _supTab = method; document.getElementById('sup-mode').value = method === 'item' ? 'by_item' : 'global'; var badge = document.getElementById('sup-mode-badge'); if (method === 'global') { badge.textContent = '📦 Full Order'; badge.style.background = '#eff6ff'; badge.style.color = '#2563eb'; } else { badge.textContent = '🔀 By Item'; badge.style.background = '#f0fdf4'; badge.style.color = '#15803d'; } document.getElementById('sup-modal-title').textContent = 'Select Suppliers'; document.getElementById('sup-modal-subtitle').textContent = 'Choose who receives the quote request'; document.getElementById('sup-mode-badge-row').style.display = 'flex'; document.getElementById('sup-step1').style.display = 'none'; document.getElementById('sup-step2').style.display = 'flex'; if (method === 'global') { setTimeout(function(){ document.getElementById('sup-search').focus(); }, 50); } updateFooter(); } function goBack() { document.querySelectorAll('#sup-form input[type="checkbox"]:not([disabled])').forEach(function(cb) { cb.checked = false; }); document.querySelectorAll('[id^="gchan-"]').forEach(function(el) { el.style.display = 'none'; }); var searchEl = document.getElementById('sup-search'); if (searchEl) { searchEl.value = ''; filterGlobalSups(''); } document.querySelectorAll('[id^="idd-label-"]').forEach(function(el) { el.textContent = 'Select suppliers…'; el.style.color = '#94a3b8'; }); var ics = document.getElementById('item-chan-section'); if (ics) ics.style.display = 'none'; document.querySelectorAll('[id^="ic-"]').forEach(function(el) { el.style.display = 'none'; }); document.getElementById('sup-mode').value = ''; document.getElementById('sup-modal-title').textContent = 'Request for Quotation'; document.getElementById('sup-modal-subtitle').textContent = 'How do you want to assign suppliers?'; document.getElementById('sup-mode-badge-row').style.display = 'none'; document.getElementById('sup-step1').style.display = 'flex'; document.getElementById('sup-step2').style.display = 'none'; closeAllItemDd(); } ``` - [ ] **Step 2: Delete the now-dead `switchSupTab` function** Find and delete this entire block: ```javascript function switchSupTab(tab) { _supTab = tab; document.getElementById('sup-mode').value = tab === 'item' ? 'by_item' : 'global'; document.getElementById('sup-global-pane').style.display = tab === 'global' ? 'flex' : 'none'; document.getElementById('sup-item-pane').style.display = tab === 'item' ? 'flex' : 'none'; var gBtn = document.getElementById('stab-global'); var iBtn = document.getElementById('stab-item'); if (tab === 'global') { gBtn.style.color = '#2563eb'; gBtn.style.borderBottomColor = '#2563eb'; iBtn.style.color = '#94a3b8'; iBtn.style.borderBottomColor = 'transparent'; } else { iBtn.style.color = '#2563eb'; iBtn.style.borderBottomColor = '#2563eb'; gBtn.style.color = '#94a3b8'; gBtn.style.borderBottomColor = 'transparent'; } updateFooter(); } ``` (Replace with nothing — delete the block entirely.) - [ ] **Step 3: Verify the script block** Confirm: - `openSupplierModal` calls `goBack()` only - `showStep` and `goBack` are both defined - `switchSupTab` does not appear anywhere in the file - `stab-global` and `stab-item` do not appear anywhere in the file --- ### Task 4: Manual verification **Prerequisites:** Laravel dev server running (`php artisan serve`) and Vite running (`npm run dev`). - [ ] **Step 1: Open a purchase request that has the supplier modal** Navigate to `http://localhost:8000/purchase/requests`, open any request that has an "Assign Suppliers" or "Send RFQ" button, and click it. **Expected:** Modal opens showing Step 1 — two cards ("Full Order", "By Item") and a Cancel button. No tabs visible. - [ ] **Step 2: Test Full Order flow** Click the "Full Order" card. **Expected:** - Modal transitions to Step 2 - Header shows "← Change method · 📦 Full Order" badge row - Title changes to "Select Suppliers", subtitle to "Choose who receives the quote request" - Global supplier list is visible with search input - Search input is auto-focused Select one or more suppliers via checkboxes. Confirm channel toggles appear per supplier selected. - [ ] **Step 3: Test back navigation clears state** Click "← Change method". **Expected:** - Returns to Step 1 (method cards) - Title resets to "Request for Quotation" - Mode badge row hidden Click "Full Order" again. **Expected:** All checkboxes unchecked, search cleared — fresh state. - [ ] **Step 4: Test By Item flow** Click "By Item" card. **Expected:** - Step 2 shows the per-item dropdown UI - Mode badge shows "🔀 By Item" in green Assign a supplier to one item. Click "← Change method". Click "By Item" again. **Expected:** Item dropdown labels reset to "Select suppliers…", channel section hidden. - [ ] **Step 5: Test submission still works** Go to Full Order, select one supplier, click "Save & Continue →". **Expected:** Form submits to `purchase.requests.rfq.select` with `mode=global` and the selected `supplier_ids[]`. No JS errors in the browser console. - [ ] **Step 6: Test Escape key and backdrop click** Open modal, press Escape. **Expected:** Modal closes regardless of which step is active. Open modal, click outside the modal card. **Expected:** Modal closes. --- ### Task 5: Commit - [ ] **Step 1: Stage the file** ```bash git add resources/views/components/purchase/supplier-select-modal.blade.php ``` - [ ] **Step 2: Commit** ```bash git commit -m "feat: replace supplier modal tabs with two-step wizard" ```