initial: bootstrap from BukidBountyApp base

This commit is contained in:
Jonathan Sykes
2026-06-06 18:43:00 +08:00
commit eb4a5731fb
5674 changed files with 160857 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
---
task: Fix "Similar products already exist" modal layout — match-row cards unreadable on mobile (flex row squishes info text to single characters, Import button overlaps content)
cycles: 5
context: true
private: false
started: 2026-05-28T16:30:42Z
finished: 2026-05-28T16:31:11Z
---
## files
- resources/js/Pages/CreateProductUltimate.vue [lines 534-560] — fuzzy match modal template: `.match-row` items with thumb, info, button
- resources/js/Pages/CreateProductUltimate.vue [lines 875-914] — scoped CSS: `.match-row`, `.match-thumb`, `.match-info` and dark mode overrides
## steps
1. In `CreateProductUltimate.vue` template (lines 534-560), wrap the `FileImage` + `.match-info` div in a new `<div class="match-row-top">` inner wrapper, leaving the `<button>` outside it so the layout becomes: outer `.match-row` (column) → `.match-row-top` (thumb + info, row) + button (full-width, below)
2. Add `w-100` class to the Import button so it spans the full card width on mobile
3. In the scoped CSS, change `.match-row` from `align-items: center` flex-row to a `flex-direction: column; gap: 10px` column layout. Add `.match-row-top { display: flex; align-items: center; gap: 12px; }` rule.
4. Remove `align-items: center` from `.match-row` (it now stacks vertically, not horizontally)
5. Verify `.match-info { flex: 1; min-width: 0; }` stays on `.match-info` (unchanged — still needed inside `.match-row-top`)
6. Build: `npm run build` then `docker restart bukidbountyapp`
## context
Current template structure (lines 534-560):
```html
<div v-for="m in fuzzyMatches" :key="m.hashkey" class="match-row">
<FileImage :src="..." class="match-thumb" fallback="..." />
<div class="match-info">
<div class="fw_6">{{ m.name }}</div>
<div class="text-muted small">
<span v-if="m.category">{{ m.category }}<span v-if="m.subcategory"> · {{ m.subcategory }}</span> · </span>
<span>₱{{ m.price }} / {{ m.unitname }}</span>
</div>
<div v-if="m.already_in_store" class="text-success smallest mt-1">...</div>
</div>
<button class="btn btn-sm btn-primary rounded-pill" :disabled="m.already_in_store || isImporting" @click="importExistingProduct(m)">
<span v-if="isImporting"><LoadingSpinner size="small" /></span>
<span v-else-if="m.already_in_store">In Store</span>
<span v-else>Import to Store</span>
</button>
</div>
```
Target template structure:
```html
<div v-for="m in fuzzyMatches" :key="m.hashkey" class="match-row">
<div class="match-row-top">
<FileImage :src="..." class="match-thumb" fallback="..." />
<div class="match-info">
<div class="fw_6">{{ m.name }}</div>
<div class="text-muted small">
<span v-if="m.category">{{ m.category }}<span v-if="m.subcategory"> · {{ m.subcategory }}</span> · </span>
<span>₱{{ m.price }} / {{ m.unitname }}</span>
</div>
<div v-if="m.already_in_store" class="text-success smallest mt-1">...</div>
</div>
</div>
<button class="btn btn-sm btn-primary rounded-pill w-100" :disabled="m.already_in_store || isImporting" @click="importExistingProduct(m)">
...
</button>
</div>
```
Current CSS (lines 875-890):
```css
.match-row {
display: flex;
align-items: center; /* ← causes single-column squish when button competes for width */
gap: 12px;
padding: 12px 0;
border-bottom: 1px solid #f1f5f9;
}
.match-thumb { width: 56px; height: 56px; border-radius: 10px; object-fit: cover; flex-shrink: 0; }
.match-info { flex: 1; min-width: 0; }
```
Target CSS additions/changes:
```css
.match-row {
display: flex;
flex-direction: column; /* vertical stack: top-row then button */
gap: 10px;
padding: 12px 0;
border-bottom: 1px solid #f1f5f9;
}
.match-row-top {
display: flex;
align-items: center;
gap: 12px;
}
/* .match-thumb and .match-info stay unchanged */
```
## notes
- dictionary: ai-docs/dictionary.md
- linters: none
- constraints: `.bb-modal*` styles are scoped to `CreateProductUltimate.vue` — do NOT touch global CSS. Dark mode override `:global(.dark-mode) .match-row` at line 914 only sets `border-bottom-color` — no changes needed there.
- build: `npm run build` then `docker restart bukidbountyapp` (see dictionary Build & Deployment Standards)