--- task: Create HomeStoreManager.vue — a dedicated Store Manager home dashboard — and wire it into Home.vue cycles: 5 context: true private: false started: 2026-05-16T00:00:00Z finished: 2026-05-16T00:02:00Z --- ## files - `resources/js/Pages/Home.vue` [lines 67-69] — STORE_MANAGER currently mapped to `HomeShared`; change to new `HomeStoreManager` - `resources/js/Pages/Fragments/Home/HomeStoreManager.vue` — NEW FILE to create - `resources/js/Pages/Fragments/Home/HomeStoreOwner.vue` — primary reference pattern to follow (BalanceBox + ServiceButtonGrid + openPos logic) - `resources/js/Pages/Fragments/Home/HomeShared.vue` [lines 56-93] — has `openPos()` store-select logic; copy this exact pattern - `resources/js/Components/Core/Stats/BalanceBox.vue` — props: `stats[]`, `footerItems[]`, `boxStyle` - `resources/js/Components/Core/Services/ServiceButtonGrid.vue` — prop: `items[]` with `icon`, `title`, `pagename|action` - `resources/js/Components/Core/Services/SideTextButtonList.vue` — quick text actions - `resources/js/Components/Core/Skeleton/HomeSkeleton.vue` — loading skeleton - `resources/js/composables/usePageData.js` — `fetchPageData(url, payload)` - `routes/web.php` [lines 76-135] — `/home-data` — already returns `transactions_today_no`, `cash_flow_today_php`; also returns `my_stores_no` scoped to store_managers pivot - `app/Http/Controllers/Support/VueRouteMap.php` — must confirm `ManageStoresAdmin`, `PosMain`, `PosHistory`, `PosAccessKeys`, `ManageProductsAdmin` allow `store manager` ## steps 1. **`routes/web.php` @ `/home-data`** — The existing `$myStoresCount` for non-Big3 only counts `owner_id` stores (line ~113). Update to also count stores where the user is in the `store_managers` pivot, so STORE_MANAGER sees the correct count: ```php $myStoresCount = !$isBig3 && $user ? \App\Models\Market\Store::where('owner_id', $user->id) ->orWhereHas('managers', fn($q) => $q->where('user_id', $user->id)) ->count() : $storeCount; ``` This change is backward-compatible (STORE_OWNER still works, now STORE_MANAGER also gets a nonzero count). 2. **Create `resources/js/Pages/Fragments/Home/HomeStoreManager.vue`** with this structure: **Script (setup):** - Imports: `ref, onMounted, h`, `usePageData`, `useNavigate`, `useAuth`, `useModal`, `BalanceBox`, `ServiceButtonGrid`, `SideTextButtonList`, `HomeSkeleton`, `axios` - `stats` ref: ```js [ { title: 'Transactions', number: 0, unit: 'Today', align: 'left', numberId: 'transactions_today_no' }, { title: 'Cash Flow', number: '0.00', unit: 'PHP Today', align: 'left', numberId: 'cash_flow_today_php' }, { title: 'My Stores', number: 0, unit: 'Assigned', align: 'right', numberId: 'my_stores_no' }, ] ``` - `balanceFooterItems` ref: ```js [ { title: 'Open POS', icon: '', action: 'openPos' }, { title: 'My Stores', icon: '', pagename: 'ManageStoresAdmin' }, ] ``` - `services` array (8 tiles): 1. `{ icon:'', title:'Open POS', action:'openPos' }` 2. `{ icon:'', title:'Inventory', pagename:'ManageProductsAdmin' }` 3. `{ icon:'', title:'POS History', action:'openPosHistory' }` 4. `{ icon:'', title:'Manage Stores', pagename:'ManageStoresAdmin' }` 5. `{ icon:'', title:'Add Product', pagename:'CreateProductStoreOwner' }` 6. `{ icon:'', title:'POS Keys', pagename:'PosAccessKeys' }` 7. `{ icon:'', title:'Customers', action:'viewCustomers' }` 8. `{ icon:'', title:'Reports', pagename:'ListReports' }` - `quickActions` array (SideTextButtonList items): - `{ text:'Onboard New User', pagename:'CreateUser', icon:'...' }` - `{ text:'My Personal Profile', pagename:'UserInfoEdit', icon:'...' }` - `{ text:'Add Transaction', pagename:'AddTransaction', icon:'...' }` - `openPos()` — identical copy of the logic in `HomeShared.vue` lines 77-92: - POST to `/ListStores/MyStores/data` - If 0 stores → modal warn - If 1 store → navigate to `PosMain` with `target: stores[0].hashkey` - If >1 → `showStoreSelectModal(stores)` with per-store buttons - `openPosHistory()` — same store-picker logic but navigates to `PosHistory` with the store's hashkey - `viewCustomers()` — navigate to `ManageStoresAdmin` (customers are visible per-store there) - `applyStats()` — standard pattern from HomeStoreOwner - `onMounted` → `fetchPageData('/home-data', {})` then `applyStats()` **Template:** ```html
``` **Style:** No `bg-white`/`bg-light`/`text-dark`. Theme-aware only. 3. **`resources/js/Pages/Home.vue`** — Add import line: `import HomeStoreManager from './Fragments/Home/HomeStoreManager.vue';` — Change lines 67-69 from `` to ``. 4. **`app/Http/Controllers/Support/VueRouteMap.php`** — Confirm all pages used by this dashboard have `'store manager'` in their `allowedUserTypes`. Required pages: `ManageStoresAdmin`, `ManageProductsAdmin`, `CreateProductStoreOwner`, `PosAccessKeys`, `PosHistory`, `ListReports`, `AddTransaction`, `CreateUser`, `UserInfoEdit`. Add `'store manager'` to any that are missing it. 5. **`app/Http/Controllers/Helpers/Permissions/UserPermissions.php`** — Confirm `STORE_MANAGER` has these actions in `roles()`: - `ViewTransactions` (for Reports) - `ViewAccountingReports` (for ListReports) - `CreatePosAccessKey`, `DeletePosAccessKey`, `TogglePosAccessKey` - `CreateProductForOwnStore`, `AddProducttoOwnStore` Add any that are missing. ## context ``` // HomeShared.vue openPos() pattern (lines 77-92): const openPos = async () => { try { const { data: stores } = await axios.post('/ListStores/MyStores/data', {}); if (!stores || stores.length === 0) { modal.quickDismiss({ title: 'No Store Found', body: 'You have no active stores assigned to your account.' }); return; } if (stores.length === 1) { navigate({ page: 'PosMain', props: { target: stores[0].hashkey } }); return; } showStoreSelectModal(stores); } catch (e) { modal.quickDismiss({ title: 'Error', body: 'Could not load your stores. Please try again.' }); } }; // Home.vue lines 67-69 currently: // // /home-data stats keys available: transactions_today_no, cash_flow_today_php, my_stores_no // CDN icon URLs in use (from HomeStoreOwner.vue): // POS key: https://cdn.jsdelivr.net/gh/.../a/5b5ef88c0ad1.svg // Store: https://cdn.jsdelivr.net/gh/.../a/85605eacd4c8.bin // Product: https://cdn.jsdelivr.net/gh/.../a/f0a0193d728e.bin // Import: https://cdn.jsdelivr.net/gh/.../a/ef1a9a079a2d.svg // Reports: https://cdn.jsdelivr.net/gh/.../a/f87407046b18.bin // Profile: https://cdn.jsdelivr.net/gh/.../a/ac7a1cebe580.bin // AddTxn: https://cdn.jsdelivr.net/gh/.../a/c9fd442fe676.bin // Users: https://cdn.jsdelivr.net/gh/.../a/516ed2aaaa4c.bin ``` ## notes - dictionary: `ai-docs/dictionary.md` - linters: none detected - constraints: Do NOT give store manager access to global product editing or user-type creation beyond their hierarchy. The `openPos` logic must re-use the exact same store-picker modal pattern from HomeShared. Use CDN icon URLs already in the project — do not introduce new external URLs. No `bg-white` or hardcoded colors.