feat(mobile-fixes-phase3): Complete US-302 - Footer Nav pe toate Paginile de Setări

Implemented by Ralph autonomous loop.
Iteration: 4

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-12 16:42:59 +00:00
parent 216475ee87
commit f272d55ba4
4 changed files with 104 additions and 14 deletions

View File

@@ -127,8 +127,8 @@
"SettingsHubView.vue include MobileBottomNav cu Setări activ", "SettingsHubView.vue include MobileBottomNav cu Setări activ",
"npm run build passes" "npm run build passes"
], ],
"passes": false, "passes": true,
"notes": "" "notes": "Completed in iteration 4"
}, },
{ {
"id": "US-303", "id": "US-303",

View File

@@ -1038,3 +1038,9 @@ User Stories: 11 (US-301 to US-311)
[2026-01-12 16:39:02] Working on story: US-301 [2026-01-12 16:39:02] Working on story: US-301
[2026-01-12 16:39:02] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_3_US-301.log) [2026-01-12 16:39:02] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_3_US-301.log)
[2026-01-12 16:40:01] SUCCESS: Story US-301 passed! [2026-01-12 16:40:01] SUCCESS: Story US-301 passed!
[2026-01-12 16:40:01] Changes committed
[2026-01-12 16:40:01] Progress: 5/11 stories completed
[2026-01-12 16:40:03] === Iteration 4/100 ===
[2026-01-12 16:40:03] Working on story: US-302
[2026-01-12 16:40:03] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_4_US-302.log)
[2026-01-12 16:42:59] SUCCESS: Story US-302 passed!

View File

@@ -1,6 +1,17 @@
<template> <template>
<div class="ocr-metrics-view"> <div class="ocr-metrics-view" :class="{ 'mobile-layout': isMobile }">
<div class="page-header"> <!-- US-302: Mobile Material Design Top Bar -->
<MobileTopBar
v-if="isMobile"
title="Metrici OCR"
:show-back="true"
:actions="mobileTopBarActions"
@back-click="router.push('/settings')"
@action-click="handleTopBarAction"
/>
<!-- Desktop Header -->
<div class="page-header" v-if="!isMobile">
<h1>Metrici OCR</h1> <h1>Metrici OCR</h1>
</div> </div>
@@ -365,6 +376,9 @@
</div> </div>
</div> </div>
</div> </div>
<!-- US-302: Mobile Bottom Navigation -->
<MobileBottomNav v-if="isMobile" />
</div> </div>
</template> </template>
@@ -390,6 +404,10 @@ import {
} from 'chart.js' } from 'chart.js'
import { useOCRSettingsStore } from '@data-entry/stores/ocrSettingsStore' import { useOCRSettingsStore } from '@data-entry/stores/ocrSettingsStore'
import { exportToExcel, exportToPDF } from '@reports/utils/exportUtils' import { exportToExcel, exportToPDF } from '@reports/utils/exportUtils'
import { useRouter } from 'vue-router'
// US-302: Mobile Material Design components
import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue'
import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue'
// Register Chart.js components // Register Chart.js components
Chart.register( Chart.register(
@@ -404,6 +422,23 @@ Chart.register(
const ocrStore = useOCRSettingsStore() const ocrStore = useOCRSettingsStore()
const toast = useToast() const toast = useToast()
const router = useRouter()
// US-302: Mobile TopBar actions
const mobileTopBarActions = computed(() => [
{
icon: 'pi pi-refresh',
label: 'Actualizează',
tooltip: 'Actualizează metricile'
}
])
// US-302: Handle top bar action clicks
const handleTopBarAction = (action) => {
if (action.icon === 'pi pi-refresh') {
loadAllMetrics()
}
}
// State // State
const selectedDays = ref(30) const selectedDays = ref(30)
@@ -811,6 +846,13 @@ onBeforeUnmount(() => {
margin: 0 auto; margin: 0 auto;
} }
/* US-302: Mobile Layout - Padding for fixed top/bottom bars */
.ocr-metrics-view.mobile-layout {
padding: var(--space-sm);
padding-top: 56px; /* MobileTopBar height */
padding-bottom: 56px; /* MobileBottomNav height */
}
.page-header { .page-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@@ -1,13 +1,22 @@
<template> <template>
<main class="main-content"> <div class="telegram-view" :class="{ 'mobile-layout': isMobile }">
<div class="app-container"> <!-- US-302: Mobile Material Design Top Bar -->
<!-- Page Header --> <MobileTopBar
<div class="page-header"> v-if="isMobile"
<h1 class="page-title">Telegram Bot</h1> title="Telegram"
<p class="page-subtitle"> :show-back="true"
Conectează-ți contul pentru acces rapid din Telegram @back-click="router.push('/settings')"
</p> />
</div>
<main class="main-content">
<div class="app-container">
<!-- Page Header - Desktop only -->
<div v-if="!isMobile" class="page-header">
<h1 class="page-title">Telegram Bot</h1>
<p class="page-subtitle">
Conectează-ți contul pentru acces rapid din Telegram
</p>
</div>
<!-- Loading State --> <!-- Loading State -->
<div v-if="loading" class="loading-state"> <div v-if="loading" class="loading-state">
@@ -71,15 +80,23 @@
</div> </div>
</div> </div>
</main> </main>
<!-- US-302: Mobile Bottom Navigation -->
<MobileBottomNav v-if="isMobile" />
</div>
</template> </template>
<script setup> <script setup>
import { ref, computed, onUnmounted } from "vue"; import { ref, computed, onMounted, onUnmounted } from "vue";
import { useRouter } from "vue-router";
import { useToast } from "primevue/usetoast"; import { useToast } from "primevue/usetoast";
import Button from "primevue/button"; import Button from "primevue/button";
import Toast from "primevue/toast"; import Toast from "primevue/toast";
import QRCodeVue from "qrcode.vue"; import QRCodeVue from "qrcode.vue";
import axios from "axios"; import axios from "axios";
// US-302: Mobile Material Design components
import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue';
import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue';
// Telegram API uses /api/telegram (separate from reports) // Telegram API uses /api/telegram (separate from reports)
const telegramApi = axios.create({ const telegramApi = axios.create({
@@ -97,6 +114,15 @@ telegramApi.interceptors.request.use((config) => {
}); });
const toast = useToast(); const toast = useToast();
const router = useRouter();
// US-302: Mobile state
const isMobile = ref(window.innerWidth < 768);
// Handle window resize
const handleResize = () => {
isMobile.value = window.innerWidth < 768;
};
// State // State
const linkingCode = ref(""); const linkingCode = ref("");
@@ -196,12 +222,28 @@ const copyCode = async () => {
} }
}; };
// US-302: Lifecycle
onMounted(() => {
window.addEventListener('resize', handleResize);
});
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('resize', handleResize);
if (countdownInterval) clearInterval(countdownInterval); if (countdownInterval) clearInterval(countdownInterval);
}); });
</script> </script>
<style scoped> <style scoped>
/* US-302: Mobile Layout - Padding for fixed top/bottom bars */
.telegram-view.mobile-layout {
padding-top: 56px; /* MobileTopBar height */
padding-bottom: 56px; /* MobileBottomNav height */
}
.telegram-view.mobile-layout .main-content {
padding: var(--space-sm);
}
/* Page Header - Uses global .page-header pattern */ /* Page Header - Uses global .page-header pattern */
/* Loading - Uses global .loading-spinner pattern */ /* Loading - Uses global .loading-spinner pattern */
/* Card - Uses global .card pattern */ /* Card - Uses global .card pattern */