feat(unified-mobile-material-design): Complete US-119 - Actualizare claude-learn-frontend.md cu pattern-uri noi

Implemented by Ralph autonomous loop.
Iteration: 7

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-12 11:21:35 +00:00
parent 7b3491b7b6
commit 9ea8dd22ac
3 changed files with 120 additions and 2 deletions

View File

@@ -157,3 +157,115 @@ const onFilesSelected = async (event) => {
}
```
**Applied in**: `src/modules/data-entry/components/bulk/BulkUploadZone.vue`
## P: Mobile Material Design Component Architecture
@2026-01-12 #mobile #material-design #vue #architecture | explicit:high
Unified mobile UI using shared MD3-inspired components. All mobile pages MUST use MobileTopBar for header and MobileBottomNav for persistent navigation. Components are in `src/shared/components/mobile/`.
```vue
<template>
<div class="mobile-page">
<MobileTopBar
:title="pageTitle"
:show-back="hasBackNavigation"
:show-menu="!hasBackNavigation"
:actions="headerActions"
@back-click="goBack"
@action-click="handleAction"
/>
<main class="mobile-content">
<!-- Page content with padding for fixed bars -->
</main>
<MobileBottomNav :items="navItems" />
</div>
</template>
<script setup>
import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue'
import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue'
</script>
<style scoped>
.mobile-content {
padding-top: 56px; /* MobileTopBar height */
padding-bottom: 56px; /* MobileBottomNav height */
}
</style>
```
## P: Bottom Sheet Filter Pattern
@2026-01-12 #mobile #material-design #filters #bottom-sheet | explicit:high
On mobile, filters MUST be placed in a BottomSheet component instead of inline. BottomSheet slides up from bottom with drag-to-close gesture. Use a filter icon in MobileTopBar actions to toggle.
```vue
<template>
<MobileTopBar
title="Lista"
:actions="[{ icon: 'pi pi-filter', label: 'Filtre', active: hasActiveFilters }]"
@action-click="handleAction"
/>
<BottomSheet v-model="isFilterOpen">
<div class="filter-content">
<h3>Filtre</h3>
<Dropdown v-model="selectedStatus" :options="statusOptions" />
<Calendar v-model="dateRange" selectionMode="range" />
<div class="filter-actions">
<Button label="Resetează" severity="secondary" @click="resetFilters" />
<Button label="Aplică" @click="applyFilters" />
</div>
</div>
</BottomSheet>
</template>
<script setup>
import BottomSheet from '@shared/components/mobile/BottomSheet.vue'
</script>
```
## P: Mobile Selection Mode Flow
@2026-01-12 #mobile #material-design #selection #batch-actions | explicit:high
When items are selected on mobile, batch actions appear in MobileSelectionFooter (bottom), NOT in the header. The footer slides up when `selectedItems.length > 0`. Actions array defines available operations per context.
```vue
<template>
<!-- List with selection -->
<div v-for="item in items" :key="item.id" @click="toggleSelection(item)">
<Checkbox v-model="selectedItems" :value="item.id" />
{{ item.name }}
</div>
<!-- Selection footer - appears when items selected -->
<MobileSelectionFooter
:visible="selectedItems.length > 0 && isMobile"
:actions="selectionActions"
/>
</template>
<script setup>
import MobileSelectionFooter from '@shared/components/mobile/MobileSelectionFooter.vue'
const selectionActions = [
{ label: 'Șterge', icon: 'pi pi-trash', severity: 'danger', handler: handleDelete },
{ label: 'Export', icon: 'pi pi-download', severity: 'secondary', handler: handleExport }
]
</script>
```
## G: Nu duplica delete button în header și footer pe mobil
@2026-01-12 #mobile #material-design #ux #selection | explicit:high
**P**: Butonul de ștergere apărea în două locuri pe mobil: în bulk-actions-bar (header tabel) ȘI în mobile-selection-bottom-bar (footer), creând confuzie UX.
**C**: Desktop și mobile foloseau același cod pentru bulk actions, dar pe mobil acțiunile trebuie să fie DOAR în footer pentru ergonomie touch.
**S**: Afișează bulk-actions-bar DOAR când `!isMobile`. Pe mobil, toate acțiunile de selecție apar exclusiv în MobileSelectionFooter:
```vue
<!-- Desktop: header actions -->
<div v-if="selectedItems.length > 0 && !isMobile" class="bulk-actions-bar">
<Button icon="pi pi-trash" label="Șterge" @click="handleDelete" />
</div>
<!-- Mobile: footer actions (MobileSelectionFooter handles visibility) -->
<MobileSelectionFooter
:visible="selectedItems.length > 0 && isMobile"
:actions="mobileSelectionActions"
/>
```
**Applied in**: `src/modules/data-entry/views/ReceiptsListView.vue`