feat(work-order-dashboard): PDF download in Docs tab + gate chat by config
- 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>
This commit is contained in:
+2694
-2689
File diff suppressed because it is too large
Load Diff
+2694
-2689
File diff suppressed because it is too large
Load Diff
@@ -681,7 +681,22 @@
|
|||||||
|
|
||||||
{{-- ── DOCUMENTS TAB ── --}}
|
{{-- ── DOCUMENTS TAB ── --}}
|
||||||
<div x-show="tab === 'docs'" x-cloak>
|
<div x-show="tab === 'docs'" x-cloak>
|
||||||
<div class="wd-empty">{{ __('Nicio factură emisă încă') }}</div>
|
<div style="display:flex;flex-direction:column;gap:8px;">
|
||||||
|
<a class="wd-btn" href="{{ url('/app/work-orders/' . $wo->id . '/pdf') }}" target="_blank">
|
||||||
|
📄 {{ __('Descarcă factură (PDF)') }}
|
||||||
|
</a>
|
||||||
|
@php $signed = $wo->getMedia('signed_documents'); @endphp
|
||||||
|
@if ($signed->isNotEmpty())
|
||||||
|
<div style="font-size:11px;color:var(--wd-text-3);text-transform:uppercase;margin-top:12px;">{{ __('Documente semnate') }}</div>
|
||||||
|
@foreach ($signed as $doc)
|
||||||
|
<a class="wd-btn" href="{{ $doc->getFullUrl() }}" target="_blank">
|
||||||
|
📎 {{ $doc->name }} <span style="color:var(--wd-text-3);">({{ round($doc->size / 1024) }} KB)</span>
|
||||||
|
</a>
|
||||||
|
@endforeach
|
||||||
|
@else
|
||||||
|
<div class="wd-empty" style="padding:12px 0;font-size:11px;">{{ __('Niciun document semnat încă. Poți încărca documente din formularul de editare al fișei.') }}</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- ── NOTES TAB ── --}}
|
{{-- ── NOTES TAB ── --}}
|
||||||
@@ -754,16 +769,34 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- CHAT CLIENT --}}
|
{{-- CHAT CLIENT --}}
|
||||||
|
@php
|
||||||
|
$tenantSettings = (array) (app(\App\Tenancy\TenantManager::class)->current()?->settings ?? []);
|
||||||
|
$integrations = (array) ($tenantSettings['integrations'] ?? []);
|
||||||
|
$telegramEnabled = (bool) data_get($integrations, 'telegram_bot.enabled')
|
||||||
|
&& filled(data_get($integrations, 'telegram_bot.fields.bot_token'));
|
||||||
|
$whatsappEnabled = (bool) data_get($integrations, 'whatsapp_business.enabled')
|
||||||
|
&& filled(data_get($integrations, 'whatsapp_business.fields.token'));
|
||||||
|
$messagingConfigured = $telegramEnabled || $whatsappEnabled;
|
||||||
|
@endphp
|
||||||
<div class="wd-card">
|
<div class="wd-card">
|
||||||
<div class="wd-card-hd">
|
<div class="wd-card-hd">
|
||||||
<h3>{{ __('Chat client') }}</h3>
|
<h3>{{ __('Chat client') }}</h3>
|
||||||
@if ($wo->client?->telegram_chat_id)
|
@if ($telegramEnabled && $wo->client?->telegram_chat_id)
|
||||||
<span style="font-size:10px;color:var(--wd-blue);">✓ Telegram</span>
|
<span style="font-size:10px;color:var(--wd-blue);">✓ Telegram</span>
|
||||||
@elseif ($wo->client?->phone)
|
@elseif ($whatsappEnabled && $wo->client?->phone)
|
||||||
<span style="font-size:10px;color:var(--wd-text-3);">SMS/WhatsApp</span>
|
<span style="font-size:10px;color:var(--wd-text-3);">✓ WhatsApp</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@if ($wo->client)
|
@if (! $messagingConfigured)
|
||||||
|
<div class="wd-empty" style="padding:16px 0;">
|
||||||
|
{{ __('Mesageria nu este configurată.') }}
|
||||||
|
<div class="wd-empty-add" style="margin-top:8px;">
|
||||||
|
<a class="wd-btn" href="{{ url('/app/integrations') }}">⚙️ {{ __('Configurează integrări') }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@elseif (! $wo->client)
|
||||||
|
<div class="wd-empty" style="padding:16px 0;">{{ __('Fișa nu are client asociat.') }}</div>
|
||||||
|
@else
|
||||||
<div class="wd-chat">
|
<div class="wd-chat">
|
||||||
<div class="wd-chat-list">
|
<div class="wd-chat-list">
|
||||||
@forelse ($messages as $m)
|
@forelse ($messages as $m)
|
||||||
@@ -784,8 +817,6 @@
|
|||||||
<button type="submit" class="wd-btn wd-btn-primary">➤</button>
|
<button type="submit" class="wd-btn wd-btn-primary">➤</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@else
|
|
||||||
<div class="wd-empty" style="padding:16px 0;">{{ __('Fără client — nu se poate trimite mesaj.') }}</div>
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -47,6 +47,15 @@ Route::post('/payments/paypal/webhook', [\App\Http\Controllers\PaymentController
|
|||||||
Route::post('/payments/paynet/webhook', [\App\Http\Controllers\PaymentController::class, 'paynetWebhook'])
|
Route::post('/payments/paynet/webhook', [\App\Http\Controllers\PaymentController::class, 'paynetWebhook'])
|
||||||
->withoutMiddleware([\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class]);
|
->withoutMiddleware([\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class]);
|
||||||
|
|
||||||
|
// PDF download for a work order (used from dashboard's Documents tab).
|
||||||
|
Route::get('/app/work-orders/{workOrder}/pdf', function (int $workOrder) {
|
||||||
|
abort_unless(auth('web')->check(), 403);
|
||||||
|
$wo = \App\Models\Tenant\WorkOrder::findOrFail($workOrder);
|
||||||
|
$svc = app(\App\Services\WorkOrderPdfService::class);
|
||||||
|
$pdf = $svc->generate($wo);
|
||||||
|
return response()->streamDownload(fn () => print($pdf->output()), $svc->filename($wo));
|
||||||
|
})->name('work-orders.pdf');
|
||||||
|
|
||||||
// User invitation accept flow (no auth required — token is the credential).
|
// User invitation accept flow (no auth required — token is the credential).
|
||||||
Route::get('/invitations/{token}', [\App\Http\Controllers\InvitationController::class, 'show'])
|
Route::get('/invitations/{token}', [\App\Http\Controllers\InvitationController::class, 'show'])
|
||||||
->name('invitation.show');
|
->name('invitation.show');
|
||||||
|
|||||||
Reference in New Issue
Block a user