- Documente tab: link to a new /app/work-orders/{id}/pdf route that
streams the invoice PDF via WorkOrderPdfService; also lists any
files uploaded to the 'signed_documents' media collection.
- Chat client card: only show the input form when telegram_bot or
whatsapp_business is enabled AND credentialed in the tenant's
Integrations page. Otherwise render an empty state with a shortcut
to /app/integrations.
RU + EN translations added for the new strings (RO source).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Right column now shows:
- Timeline card: synthesised events from WO lifecycle fields (created,
opened, approved, closed) + payments + activity_log entries (spatie/
activitylog). Sorted newest first, scrollable.
- Chat client card: outbound notifications history (ClientNotificationLog)
+ inline send form. Prefers Telegram if client has telegram_chat_id,
else falls back to SMS/WhatsApp. Logged either way for UI history.
New bottom action bar (fixed, above footer):
- Previous / Next WO links (adjacent by id) with number preview
- Repeat order: pre-fills create form with same client/vehicle
- Close order (danger button): sets status='done' + closed_at=now, with
wire:confirm guard. Hidden when already closed.
+14 translations. Fixed ready_at reference (not in schema, removed).
All 306 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Custom Filament Page at /app/work-orders/{id}/dashboard renders a
Mitchell1-inspired 3-column layout:
- Top bar: WO#, status badge, actions (Edit / Tracking link)
- Meta header row: creation / opened / ETA / responsible / urgency /
paid amount (6 cells)
- Left sidebar (300px): Client card (avatar, phone, email, status
tag, 3-stat grid: visits/total/debt) + Vehicle card (photo, plate,
VIN, mileage, engine, gearbox) + Repair history (latest 5 for this
vehicle, links to dashboards)
- Middle: tab bar (Lucrări/Piese/Diagnostic/Foto/Documente/Note)
with Alpine-driven switching. Works & Parts show the tables read-
only; add/edit still goes through existing EditWorkOrder Filament
resource. Photos tab shows gallery from spatie/media-library.
- Right (300px): Finance summary card (works cost, parts cost,
discount, total, paid, balance) + placeholder for Timeline+Chat
(Phase 2)
- Responsive: right column collapses <1280px, left <900px.
'Vizualizare dashboard' button added on top of the existing
EditWorkOrder page so users can switch between edit form and info-
dense dashboard.
Fixed getSlug() signature (must match parent with ?Panel $panel).
+14 translations. All 306 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prior commit only landed the RO entry; the RU + EN Edits were silently
skipped (file-not-read guard). Now all 3 langs have the label.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous sed insert-after-'Programări' silently failed because that key
didn't exist. Now placed alphabetically after 'Procentaj' in all 3
lang/nav.php files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prior version used Cyrillic strings as __() keys — RO users saw
Cyrillic text because fallback = key. Now all PDF labels use RO as
the source-language key (e.g. 'Automobil', 'Nr. înmatriculare',
'Nr. protocol:', 'INJECTOARE'). ru.json + en.json provide translations.
+24 keys covering title, all field labels, table headers, measurement
column headers, before/after subheadings, footer note, conclusion
section, signature block, unit suffixes (km, ml).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- WorksRelationManager Name column: getStateUsing(labor?->label()) so
the row shows the labor's localized name (not the raw snapshot);
fallback to stored snapshot when labor is missing.
- 4 explicit empty states with helper description + icon on Works,
Parts, SubcontractJobs, Payments — replaces Filament's auto-generated
'Не найдено X / Создать X для старта.'
- 4 CreateAction titles / modal headings for all four relation managers.
- Notification 'Piesa returnată în stoc' / 'Nimic de restituit' wrapped.
- +11 translation keys.
All 306 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Migration: add nullable `labors.name_en` alongside existing name_ro/
name_ru.
- Labor model: label(?locale) accessor returns name_{locale} with
name_ro fallback.
- LaborResource form: expose 3rd 'Nume (EN)' field.
- Table + Select displays now go through label() so options show the
locale-appropriate name:
/app/labors table column,
WorkOrderResource works Select ('[category] name (Nh)'),
ServiceTemplate items Select,
ServiceComposer WorkOrderWork snapshot on create.
- Snapshot name saved on wo_works.name at creation reflects the
current locale; existing rows keep their stored snapshot untouched.
All 306 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Labor Select options now build '[__(category)] name_ro (hours __(h))'
so category chip and hour suffix translate on RU/EN. Labor name stays
as name_ro (user data — separate long-term concern).
- CreateAction gets explicit label + modalHeading (was 'Create Work
Order Work' auto-generated).
- Notification 'Piese implicite adăugate (N)' rewritten with __(':n')
placeholder.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sections Mesaj client / Sursă & Atribuire / Marketing (UTM), the full
empty-state description, plus previously-missing Lead::SOURCES enum
values (Manual, Apel, Site, Google Maps, SEO, Recomandare) and
STATUSES (Contactat, Convertit, Pierdut).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
OnlineOrder::DELIVERY values (Ridicare din service / Curier / Poștă)
weren't translated; now go through I18n::opts and have RU/EN entries.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Currency Select ->options() had 4 raw entries (MDL/EUR/USD/UAH)
and 2 wrapped (RON/RUB); consolidated all 6 under I18n::opts()
- Push notification title 'Trimis pe N dispozitiv(e)' rebuilt with
__(':n')-placeholder; empty state + helper now go through __()
- Added 4 long helper description keys with the closing „…"
Romanian quotation marks (the previous keys were missing the
trailing quote and dot; now match Settings.php byte-for-byte)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Full coverage across Logo & favicon / AI providers / Telegram bot /
Notifications (client reminders) / Shop / Currencies / Internal
margin. Includes long helper paragraphs and 'Setări salvate' /
'Tenant not resolved' notification titles.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Filament default rendered 'Не найдено user permission overrides /
Создать user permission override для старта.' from the model class
name. Overridden with translated heading + explanatory description
+ shield-exclamation icon.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add Permissions::permissionLabels() mapping every slug to a
human-readable RO label (e.g. 'clients.view_all' → 'Vezi toți
clienții').
- RoleResource permission checkboxes now show translated labels
as titles + technical slug as description (so admins see both
the meaning and the key).
- PermissionOverridesRelationManager Select 'permission_id' now
shows 'Human label (technical.slug)' format, plus helper text
explaining GRANT/DENY. Same format on the display column.
- +57 translations (50 permission labels in RU/EN + role page
supporting keys + module labels).
All 306 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 'DENY — interzice dreptul' select option was missing __() wrap
- CreateAction/EditAction now have explicit label/modalHeading so
the modal shows 'Добавить исключение прав' instead of
'Создать User Permission Override' (auto-generated from class name)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Status column showed raw DB enum values (active/inactive/blocked) with
no formatStateUsing → readers saw 'active' instead of the translated
'Активный / Активно' visible in the Select. Added formatStateUsing with
a match() that returns the appropriate __() key.
Locale header re-translated to 'Язык' (RU) / 'Language' (EN) since
'Локаль' is unusual for end users.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Both role selects (primary + additional roles multi) passed the raw
roleLabels() array without translation; wrap with I18n::opts() so
Proprietar/Administrator/… now render translated in RU/EN.
- 2FA status text ('✓ Activat (TOTP)' / '✗ Dezactivat') split so
the checkmark stays and label runs through __().
- +3 translations (Activat (TOTP), Dezactivat, Locale) — Locale is
Filament's auto-generated headline from the `locale` field.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Covers Identitate/Acces/2FA sections, all helper texts on user
edit page (2FA reset, role sync, additional roles, margin helper,
salary formula), placeholder examples, RBAC role labels (Proprietar,
Vizitator, Recepție), 'Română' language option, and Permission
Overrides RelationManager helpers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fixes 'Posturi De Lucru' title (was RO fallback) and translates the
create form placeholder + default-mechanic helper text + no-default
option label.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- +6 subcontract-jobs translations (Lucrare, Termene, Returnat, ETA,
helper 'Setat manual dacă markup = 0.', empty-state description)
- Add lang/vendor/filament-forms/{ru,en}/components.php with select
no_options_message + max_items_message. Filament ships RO copy with
no RU override, so 'Nu sunt disponibile opțiuni.' bled through into
RU/EN locales.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fills in the untranslated Subcontractor::SPECIALTIES options (Turbo,
Variator, Casetă direcție, PDR, Electronică, Injectoare) plus
Specialitate label, empty-state heading and full description.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wraps the free-text token/requests counter suffix and adds the last 6
identity-fallback keys used on the page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Reports.php periods() had 'this_year' hardcoded; now wrapped in __()
- masters tab specialization cell: split by '/' and __()-translate each
token so 'Motor / Cutie viteze' auto-renders as «Двигатель / КПП»
on RU (and 'Engine / Gearbox' on EN). Users can enter any free-text
specialisation; the common keywords now have RU/EN translations.
- +12 specialisation vocabulary entries (Motor, Frâne, Suspensie,
Anvelope, Cutie viteze, Electrică, Diagnosticare, Vopsitorie,
Tinichigerie, Aer condiționat, Roți, Ambreiaj).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Covers 3 report tabs (Clienți/Finanțe/Încărcare), 6 subsection titles
(Cheltuieli pe categorie, Încasări pe metodă, Top piese vândute,
Tranz., Pe status, Ore total) and 4 empty-state messages.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 4 stepper labels (Upload / Mapare coloane / Previzualizare / Confirmare)
now split so the number stays and only the text runs through __()
- Step 3 heading rewritten with __(':n poziții') placeholder
- 'Selectat: filename.xlsx' hint wrapped
- Row status badges (Găsit/Nou/Nu găsit) split so emoji stays and label
translates
- 'Articole noi (se vor crea)' summary line wrapped
+8 translations.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Full page translation across all 4 steps (upload / map columns / preview /
done), including form labels, buttons, helper text, empty state, and
final result summary. Notification 'N poziții importate' now built via
__(':n')-placeholder so it translates on RU/EN.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Complete coverage for /app/tire-sets + create + storage history tab.
Includes Specificații/TPMS/Uzură sections, all field labels
(Sezon/Stare/Cu jante/Tip jante/Senzori TPMS/Dimensiune/Diametru R),
Check-in depozit action + result notifications, empty state (heading
+ description), placeholder examples, storage history relation
manager, and remaining CONDITIONS enum values (Bun/Critic/All-season).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Descriptions for Telegram/SMS/Message-templates/Webhook integration
cards + the placeholder-note info banner + Status: label.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds RU/EN for Call::DIRECTIONS (Primit/Efectuat/Pierdut),
Call::STATUSES (Răspuns/Ocupat/Fără răspuns), the 'Pierdute'
missed-calls quick filter, and Filament's auto-generated
'Direction' label from the direction field.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds RU/EN for feminine STATUSES enum values used by online-orders
(Nouă/Confirmată/Pregătită/Expediată/Livrată/Anulată), lowercase
model labels for plural/create titles, Livrare (delivery method
column), and the confirm-order helper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Model labels (ajustare, bonusuri/avansuri) drive the plural title
'Bonusuri/avansuri' and 'Create Ajustare' text; TYPES enum
(Bonus/Penalizare/Avans) drives the type select; column 'Aplicat'
and auto-generated 'Period' for the period field.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Notification 'Calculat salariul YYYY-MM pentru N utilizatori' was
built via string interpolation → couldn't translate. Now uses __()
with :period / :count placeholders. Adds 7 more translations for
section titles and column labels.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Section titles (Profil, Salariu & comisioane), commission column
headers (% Manopere / % marja piese), plural model label, hire date
label, and both commission helper texts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>