feat(loyalty): multi-select categories on transactions
Some checks failed
Some checks failed
Switch from single category_id to category_ids JSON array on transactions. Sellers can now select multiple categories (e.g., Men + Accessories) when entering stamp/points transactions. - Migration loyalty_009: drop category_id FK, add category_ids JSON - Schemas: category_id → category_ids (list[int] | None) - Services: stamp_service + points_service accept category_ids - Terminal UI: pills are now multi-select (toggle on/off) - Transaction response: category_names (list[str]) resolved from IDs - Recent transactions table: new Category column showing comma- separated names Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -286,13 +286,14 @@
|
||||
<th class="px-4 py-3">{{ _('loyalty.store.terminal.col_customer') }}</th>
|
||||
<th class="px-4 py-3">{{ _('loyalty.store.terminal.col_type') }}</th>
|
||||
<th class="px-4 py-3 text-right">{{ _('loyalty.store.terminal.col_points') }}</th>
|
||||
<th class="px-4 py-3">{{ _('loyalty.store.terminal.select_category') }}</th>
|
||||
<th class="px-4 py-3">{{ _('loyalty.store.terminal.col_notes') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800">
|
||||
<template x-if="recentTransactions.length === 0">
|
||||
<tr>
|
||||
<td colspan="5" class="px-4 py-6 text-center text-gray-500 dark:text-gray-400">
|
||||
<td colspan="6" class="px-4 py-6 text-center text-gray-500 dark:text-gray-400">
|
||||
{{ _('loyalty.store.terminal.no_recent_transactions') }}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -309,6 +310,7 @@
|
||||
<td class="px-4 py-3 text-sm text-right font-medium"
|
||||
:class="tx.points_delta > 0 ? 'text-green-600' : 'text-orange-600'"
|
||||
x-text="(tx.points_delta > 0 ? '+' : '') + formatNumber(tx.points_delta)"></td>
|
||||
<td class="px-4 py-3 text-sm text-gray-500" x-text="tx.category_names?.join(', ') || '-'"></td>
|
||||
<td class="px-4 py-3 text-sm text-gray-500" x-text="tx.notes || '-'"></td>
|
||||
</tr>
|
||||
</template>
|
||||
@@ -331,9 +333,9 @@
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<template x-for="cat in categories" :key="cat.id">
|
||||
<button type="button"
|
||||
@click="selectedCategory = (selectedCategory === cat.id) ? null : cat.id"
|
||||
@click="selectedCategories.includes(cat.id) ? selectedCategories = selectedCategories.filter(id => id !== cat.id) : selectedCategories.push(cat.id)"
|
||||
class="px-3 py-1.5 text-sm font-medium rounded-full border transition-colors"
|
||||
:class="selectedCategory === cat.id
|
||||
:class="selectedCategories.includes(cat.id)
|
||||
? 'bg-purple-600 text-white border-purple-600'
|
||||
: 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-600'"
|
||||
x-text="cat.name">
|
||||
|
||||
Reference in New Issue
Block a user