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:
@@ -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`
|
||||
|
||||
Reference in New Issue
Block a user