feat(unified-mobile-desktop-ui): Complete US-503 - BottomSheet Filtre pentru Lista Bonuri (Mobil)

Implemented by Ralph autonomous loop.
Iteration: 3

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-12 22:23:51 +00:00
parent c74fe4b221
commit af012a7a11
3 changed files with 131 additions and 15 deletions

View File

@@ -101,8 +101,8 @@
"npm run build passes", "npm run build passes",
"Verify in browser mobil (375x667): filtrele apar în BottomSheet" "Verify in browser mobil (375x667): filtrele apar în BottomSheet"
], ],
"passes": false, "passes": true,
"notes": "" "notes": "Completed in iteration 3"
}, },
{ {
"id": "US-504", "id": "US-504",

View File

@@ -82,3 +82,9 @@ Design Reference: src/modules/reports/views/InvoicesView.vue
[2026-01-12 22:16:55] Working on story: US-502 [2026-01-12 22:16:55] Working on story: US-502
[2026-01-12 22:16:55] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_2_US-502.log) [2026-01-12 22:16:55] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_2_US-502.log)
[2026-01-12 22:20:46] SUCCESS: Story US-502 passed! [2026-01-12 22:20:46] SUCCESS: Story US-502 passed!
[2026-01-12 22:20:46] Changes committed
[2026-01-12 22:20:47] Progress: 2/19 stories completed
[2026-01-12 22:20:49] === Iteration 3/100 ===
[2026-01-12 22:20:49] Working on story: US-503
[2026-01-12 22:20:49] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_3_US-503.log)
[2026-01-12 22:23:51] SUCCESS: Story US-503 passed!

View File

@@ -135,6 +135,87 @@
@logout="handleLogout" @logout="handleLogout"
/> />
<!-- US-503: Filter BottomSheet for mobile -->
<BottomSheet v-model="showFilters">
<h3 class="bottom-sheet-title">Filtre</h3>
<div class="bottom-sheet-filters">
<!-- Status Filter -->
<div class="form-group">
<label class="form-label">Status</label>
<Dropdown
v-model="filters.status"
:options="statusOptions"
optionLabel="label"
optionValue="value"
placeholder="Toate statusurile"
class="w-full"
/>
</div>
<!-- Search -->
<div class="form-group">
<label class="form-label">Căutare</label>
<InputText
v-model="filters.search"
placeholder="Caută furnizor, CUI, nr. bon..."
class="w-full"
/>
</div>
<!-- Direction Filter -->
<div class="form-group">
<label class="form-label">Tip</label>
<Dropdown
v-model="filters.direction"
:options="directionOptions"
optionLabel="label"
optionValue="value"
placeholder="Toate tipurile"
class="w-full"
/>
</div>
<!-- Date From -->
<div class="form-group">
<label class="form-label">De la data</label>
<Calendar
v-model="filters.dateFrom"
dateFormat="dd.mm.yy"
placeholder="Selectează data"
showIcon
class="w-full"
/>
</div>
<!-- Date To -->
<div class="form-group">
<label class="form-label">Până la data</label>
<Calendar
v-model="filters.dateTo"
dateFormat="dd.mm.yy"
placeholder="Selectează data"
showIcon
class="w-full"
/>
</div>
<!-- Bottom sheet actions -->
<div class="bottom-sheet-actions">
<Button
icon="pi pi-filter-slash"
label="Resetează"
class="p-button-outlined p-button-secondary"
@click="clearFiltersAndClose"
/>
<Button
icon="pi pi-check"
label="Aplică"
@click="applyFiltersAndClose"
/>
</div>
</div>
</BottomSheet>
<!-- Main Card --> <!-- Main Card -->
<!-- Page Header (centered, no icon) - Desktop only --> <!-- Page Header (centered, no icon) - Desktop only -->
<div class="page-header" v-if="!isMobile"> <div class="page-header" v-if="!isMobile">
@@ -264,19 +345,8 @@
</div> </div>
</div> </div>
<!-- Search and Filters Row --> <!-- Search and Filters Row (desktop only - mobile uses BottomSheet US-503) -->
<div v-if="!isMobile || showFilters" class="filters-row"> <div v-if="!isMobile" class="filters-row">
<!-- Mobile: Status Dropdown (instead of chips) -->
<Dropdown
v-if="isMobile"
v-model="filters.status"
:options="statusOptions"
optionLabel="label"
optionValue="value"
placeholder="Status"
class="filter-status"
@change="onFilterChange"
/>
<InputText <InputText
v-model="filters.search" v-model="filters.search"
@@ -1017,6 +1087,7 @@ import Textarea from 'primevue/textarea'
import Dropdown from 'primevue/dropdown' import Dropdown from 'primevue/dropdown'
import Checkbox from 'primevue/checkbox' import Checkbox from 'primevue/checkbox'
import MobileDrawerMenu from '@shared/components/mobile/MobileDrawerMenu.vue' import MobileDrawerMenu from '@shared/components/mobile/MobileDrawerMenu.vue'
import BottomSheet from '@shared/components/mobile/BottomSheet.vue'
import DragDropOverlay from '@data-entry/components/bulk/DragDropOverlay.vue' import DragDropOverlay from '@data-entry/components/bulk/DragDropOverlay.vue'
// US-103: Mobile Material Design common components // US-103: Mobile Material Design common components
import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue' import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue'
@@ -2090,6 +2161,18 @@ const clearFilters = async () => {
await store.fetchReceipts() await store.fetchReceipts()
} }
// US-503: Clear filters and close BottomSheet (for mobile)
const clearFiltersAndClose = async () => {
await clearFilters()
showFilters.value = false
}
// US-503: Apply filters and close BottomSheet (for mobile)
const applyFiltersAndClose = async () => {
await onFilterChange()
showFilters.value = false
}
// Refresh data (for mobile toolbar) // Refresh data (for mobile toolbar)
const refreshData = async () => { const refreshData = async () => {
await store.fetchReceipts() await store.fetchReceipts()
@@ -4984,4 +5067,31 @@ const cleanupCompletedBatches = (storedBatchIds) => {
.receipts-list-view.mobile-android-layout:has(.mobile-filter-chips-container) { .receipts-list-view.mobile-android-layout:has(.mobile-filter-chips-container) {
padding-top: calc(56px + 48px + var(--space-sm)); /* Top bar + filter chips + spacing */ padding-top: calc(56px + 48px + var(--space-sm)); /* Top bar + filter chips + spacing */
} }
/* ================================================
US-503: BottomSheet Filters Styles
Pattern from InvoicesView.vue
================================================ */
.bottom-sheet-title {
font-size: var(--text-lg);
font-weight: var(--font-semibold);
color: var(--text-color);
margin: 0 0 var(--space-md) 0;
}
.bottom-sheet-filters {
display: flex;
flex-direction: column;
gap: var(--space-md);
}
.bottom-sheet-actions {
display: flex;
gap: var(--space-sm);
justify-content: flex-end;
margin-top: var(--space-md);
padding-top: var(--space-md);
border-top: 1px solid var(--surface-border);
}
</style> </style>