Batch 3: Integrări placeholder + Backup tenant

═══ Integrări (Marketing → Integrări) ═══
- /app/integrations Page cu 6 carduri (Telegram/WhatsApp/Google Ads/FB/SMS/Webhook)
- Toggle on/off per integrare; salvare în settings.integrations JSON
- Câmpuri specifice per integrare (token/key/id/secret)
- Banner explicativ: 'placeholder UI — implementare separată'

═══ Backup tenant ═══
- TenantBackupService::export($company) → ZIP cu:
  • data/ (1 JSON per tabel: clients/vehicles/leads/deals/work_orders cu sub-relații/...)
  • media/ (logo + favicon)
  • manifest.json (metadata + counts)
- /app/backup Page cu buton 'Descarcă backup acum'
- Streaming download cu deleteFileAfterSend
- Util pentru: backup local, migrare, audit, GDPR right-to-erasure

Total tenant routes: 104.
Toate cele ~26 module din prototip implementate (sau echivalent funcțional).
This commit is contained in:
2026-05-07 17:36:00 +00:00
parent 4b3201ca1c
commit 6c72fc7db1
5 changed files with 380 additions and 0 deletions
@@ -0,0 +1,78 @@
<x-filament-panels::page>
<style>
.ig-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); }
.ig-card {
background: #fff; border: 1px solid #e5e7eb; border-radius: 12px;
padding: 20px; position: relative;
}
.dark .ig-card { background: #1f2937; border-color: #374151; }
.ig-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.ig-icon {
width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
border-radius: 8px; font-size: 22px; color: #fff;
}
.ig-name { font-size: 15px; font-weight: 600; flex: 1; }
.ig-desc { font-size: 12px; color: #6b7280; margin-bottom: 16px; line-height: 1.5; }
.ig-toggle { display: flex; align-items: center; gap: 8px; }
.ig-toggle input[type=checkbox] { transform: scale(1.2); cursor: pointer; }
.ig-status { font-size: 11px; color: #6b7280; }
.ig-status.on { color: #059669; font-weight: 600; }
.ig-fields { margin-top: 12px; }
.ig-fld { margin-bottom: 10px; }
.ig-lbl { font-size: 11px; color: #6b7280; display: block; margin-bottom: 4px; }
.ig-input {
width: 100%; padding: 8px 10px; border: 1px solid #e5e7eb; border-radius: 6px;
font-size: 12px; font-family: inherit;
}
.dark .ig-input { background: #111827; border-color: #374151; color: #f9fafb; }
.ig-save {
margin-top: 8px; padding: 6px 16px; font-size: 12px;
background: #3b82f6; color: #fff; border: none; border-radius: 6px; cursor: pointer;
}
</style>
<div style="background: #fef3c7; border-left: 4px solid #f59e0b; padding: 12px 16px; border-radius: 6px; margin-bottom: 16px; font-size: 13px;">
<b>Status:</b> aceste integrări sunt placeholder UI le configurezi aici, dar implementarea actuală a fiecărui canal e proiect separat.
Pentru moment, valorile salvate sunt accesibile în cod via <code>$tenant->settings['integrations']</code>.
</div>
<div class="ig-grid">
@foreach ($this->integrations() as $key => $meta)
@php
$cfg = $config[$key] ?? [];
$enabled = $cfg['enabled'] ?? false;
@endphp
<div class="ig-card">
<div class="ig-head">
<div class="ig-icon" style="background:{{ $meta['color'] }};">{{ $meta['icon'] }}</div>
<div class="ig-name">{{ $meta['name'] }}</div>
<label class="ig-toggle">
<input type="checkbox" {{ $enabled ? 'checked' : '' }}
wire:click="setStatus('{{ $key }}', {{ $enabled ? 'false' : 'true' }})">
<span class="ig-status {{ $enabled ? 'on' : '' }}">{{ $enabled ? 'Activ' : 'Inactiv' }}</span>
</label>
</div>
<div class="ig-desc">{{ $meta['description'] }}</div>
<div class="ig-fields">
@foreach ($meta['fields'] as $fkey => $fmeta)
<div class="ig-fld">
<label class="ig-lbl">{{ $fmeta['label'] }}</label>
<input
type="{{ $fmeta['type'] }}"
class="ig-input"
placeholder="{{ $fmeta['placeholder'] ?? '' }}"
wire:change="updateField('{{ $key }}', '{{ $fkey }}', $event.target.value)"
value="{{ $cfg[$fkey] ?? '' }}"
>
</div>
@endforeach
</div>
<button type="button" class="ig-save" wire:click="save">Salvează</button>
</div>
@endforeach
</div>
</x-filament-panels::page>