feat(mobile-fixes-phase4): Complete US-406 - Fix UI Bonuri cu Eroare - Afișare Corectă pe Mobil

Implemented by Ralph autonomous loop.
Iteration: 5

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-12 19:36:45 +00:00
parent 043797edaa
commit f66164f763
3 changed files with 106 additions and 7 deletions

View File

@@ -120,8 +120,8 @@
"npm run build passes",
"Verify in browser (375x667): Bon cu eroare arată 'Eroare' nu 'În procesare'"
],
"passes": false,
"notes": "Depinde de US-405 - bonurile failed trebuie să fie în listă mai întâi"
"passes": true,
"notes": "Completed in iteration 5"
},
{
"id": "US-407",

View File

@@ -27,3 +27,9 @@ Stories: 8 (US-401 to US-408)
[2026-01-12 19:27:07] Working on story: US-405
[2026-01-12 19:27:07] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_4_US-405.log)
[2026-01-12 19:31:08] SUCCESS: Story US-405 passed!
[2026-01-12 19:31:09] Changes committed
[2026-01-12 19:31:09] Progress: 5/8 stories completed
[2026-01-12 19:31:11] === Iteration 5/50 ===
[2026-01-12 19:31:11] Working on story: US-406
[2026-01-12 19:31:11] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_5_US-406.log)
[2026-01-12 19:36:45] SUCCESS: Story US-406 passed!

View File

@@ -387,29 +387,57 @@
>
<!-- US-017: Job card layout -->
<template v-if="isJobItem(item)">
<!-- Row 1: Filename + Processing indicator -->
<!-- Row 1: Filename + Status indicator -->
<div class="card-row-1">
<div class="partner-info">
<span class="partner job-filename-mobile">
<i class="pi pi-file"></i>
{{ item.filename }}
</span>
<span class="cui text-muted">Se procesează...</span>
<!-- US-406: Different subtitle for failed vs processing jobs -->
<span v-if="item.processing_status === 'failed'" class="cui text-error">
Eroare OCR
</span>
<span v-else class="cui text-muted">Se procesează...</span>
</div>
<div class="amount-block">
<span class="amount text-muted">-</span>
</div>
<span class="job-processing-indicator-mobile">
<!-- US-406: Show error icon for failed, spinner for processing -->
<span v-if="item.processing_status === 'failed'" class="job-failed-indicator-mobile">
<i class="pi pi-exclamation-triangle"></i>
</span>
<span v-else class="job-processing-indicator-mobile">
<i class="pi pi-spin pi-spinner"></i>
</span>
</div>
<!-- Row 2: Job info -->
<div class="card-row-2">
<span class="text-muted">În procesare</span>
<!-- US-406: Show truncated error message for failed jobs -->
<span
v-if="item.processing_status === 'failed' && item.processing_error"
class="text-error job-error-message"
v-tooltip.top="item.processing_error"
>
{{ truncateErrorMessage(item.processing_error) }}
</span>
<span v-else-if="item.processing_status === 'failed'" class="text-error">
Procesare eșuată
</span>
<span v-else class="text-muted">În procesare</span>
</div>
<!-- Row 3: Processing status -->
<div class="card-row-3">
<span class="processing-badge processing-active">
<!-- US-406: Show error badge for failed, processing badge for others -->
<span
v-if="item.processing_status === 'failed'"
class="processing-badge processing-failed"
v-tooltip.top="item.processing_error || 'Eroare la procesare'"
>
<i class="pi pi-exclamation-triangle"></i>
Eroare
</span>
<span v-else class="processing-badge processing-active">
<i class="pi pi-spin pi-spinner"></i>
{{ item.processing_status === 'pending' ? 'În așteptare' : 'Procesare' }}
</span>
@@ -1880,6 +1908,21 @@ const truncateFilename = (filename) => {
return filename.substring(0, maxLength) + '...'
}
/**
* US-406: Truncate error message for display on mobile card row 2.
* Shows first 40 characters with ellipsis if longer.
* Full error available via tooltip on hover/click.
*
* @param {string} error - Error message from OCR processing
* @returns {string} Truncated error message
*/
const truncateErrorMessage = (error) => {
if (!error) return 'Eroare necunoscută'
const maxLength = 40
if (error.length <= maxLength) return error
return error.substring(0, maxLength) + '...'
}
/**
* US-036: Get original filename from a receipt's attachments.
* For receipts, the original_filename is stored in attachments[0].filename.
@@ -4078,6 +4121,56 @@ const cleanupCompletedBatches = (storedBatchIds) => {
color: var(--blue-400);
}
/* ============ US-406: Mobile Failed Job Styles ============ */
/* Failed job indicator icon in mobile cards (replaces spinner) */
.job-failed-indicator-mobile {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
color: var(--red-500);
}
.job-failed-indicator-mobile .pi-exclamation-triangle {
font-size: var(--text-lg);
}
/* Error text color utility class */
.text-error {
color: var(--red-600);
}
/* Truncated error message in job card row 2 */
.job-error-message {
font-size: var(--text-xs);
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: help;
}
/* Dark mode adjustments for mobile failed jobs */
[data-theme="dark"] .job-failed-indicator-mobile {
color: var(--red-400);
}
[data-theme="dark"] .text-error {
color: var(--red-400);
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) .job-failed-indicator-mobile {
color: var(--red-400);
}
:root:not([data-theme]) .text-error {
color: var(--red-400);
}
}
/* ============ US-018: Failed Job Row Styles ============ */
/* Failed job indicator in Actions column */