{{-- v4.2.0 §C1 — La fiche d'un espace client : huit onglets, la disposition de la maquette. Le cockpit ne compte que les EXCEPTIONS : quatre repères, « Aujourd'hui », « Échéances ». --}} @php use App\Enums\EspaceClient\ModeAcces; use App\Enums\EspaceClient\ModeLettre; use App\Enums\EspaceClient\CanalDecision; use App\Enums\EspaceClient\CanalDemande; use App\Enums\EspaceClient\FamilleDocument; use App\Enums\EspaceClient\RoleAcces; use App\Enums\EspaceClient\TypeDecision; use App\Models\EspaceClient\DocumentClient; $espace = $this->espace(); $gere = $this->peutGerer(); $etiquette = 'block text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400'; $nombre = fn ($v) => rtrim(rtrim(number_format((float) $v, 2, ',', ' '), '0'), ','); @endphp {{-- v4.4.2 §4a — Sans compte client actif, chaque envoi de l'espace part à personne : le journal l'écrit en « échec », l'écran disait succès. Le bandeau le dit avant le geste. --}} @if ($this->sansAccesClientActif())
Aucun compte client actif. Les e-mails de cet espace ne partiront à personne — invitez un référent depuis l'onglet Paramètres.
@endif {{-- ═══ Les onglets ════════════════════════════════════════════════════════════════════ --}}
@foreach (\App\Filament\Admin\Resources\EspacesClients\Pages\ViewEspaceClient::ONGLETS as $cle => $libelle) @endforeach
{{-- ═══ COCKPIT ═══════════════════════════════════════════════════════════════════════ --}} @if ($onglet === 'cockpit') @php $t = $this->tuiles(); @endphp

En attente du client

{{ $t['en_attente_du_client'] }}

{{ $t['a_valider'] }} livrable(s) à valider

Échéances sous 10 jours

{{ $t['echeances_10_jours'] }}

en jours ouvrés

Pièces manquantes

{{ $t['pieces_manquantes'] }}

{{ $t['pieces_cote_client'] }} côté client · {{ $t['pieces_cote_nous'] }} de notre côté

Commandé

{{ number_format($t['montant_commande'], 2, ',', ' ') }} DH

{{ $t['part_du_marche'] }} % du marché

@if ($gere)
Nouveau livrable Saisir une demande reçue Message de la semaine
@endif
@forelse ($this->alertes() as $alerte) {{ ['danger' => 'urgent', 'warning' => 'à traiter', 'info' => 'à suivre'][$alerte['niveau']] ?? '—' }} @empty Rien ne va mal aujourd'hui. @endforelse @forelse ($this->echeances() as $ligne) @php $l = $ligne['livrable']; @endphp {{ $ligne['jours_ouvres'] < 0 ? 'en retard de '.abs($ligne['jours_ouvres']).' j' : $ligne['jours_ouvres'].' j ouvrés' }} @empty Aucune échéance sous dix jours ouvrés. @endforelse
@endif {{-- ═══ LIVRABLES ═════════════════════════════════════════════════════════════════════ --}} @if ($onglet === 'livrables') @if ($gere)
Nouveau livrable
@endif @forelse ($this->livrables() as $livrable) {{ $livrable->statut->label() }} @if ($gere) Remettre @if ($livrable->version_courante > 0) Décision reçue @endif @if ($livrable->statut->estValide()) Réceptionner Diffuser @endif @endif @empty Aucun livrable — créez le premier. @endforelse @endif {{-- ═══ REPORTING ═════════════════════════════════════════════════════════════════════ --}} @if ($onglet === 'reporting') @php $ligne = $this->indicateurs(); $c = $ligne->calcules ?? []; $m = $c['mois'] ?? []; $cum = $c['cumul'] ?? []; $cibles = $espace->ciblesConfigurees(); $pct = fn ($v) => $v === null ? '—' : number_format((float) $v, 1, ',', ' ').' %'; /** L'état d'un indicateur face à sa cible. Trois mots, pas un code couleur muet. */ $etat = function ($valeur, $cible, bool $plusHaut = true): array { if ($valeur === null || $cible === null) { return ['pas encore mesuré', 'gray']; } return ($plusHaut ? $valeur >= $cible : $valeur <= $cible) ? ['atteint', 'success'] : ['à surveiller', 'warning']; }; @endphp
@foreach ($this->moisDisponibles() as $cle => $libelle) @endforeach @if ($gere) Saisir les indicateurs digitaux du mois Générer le rapport mensuel Recalculer @endif @if ($ligne->verrouille) Mois clôturé @endif
@php $dt = $m['delais_tenus'] ?? []; $dtc = $cum['delais_tenus'] ?? []; $vp = $m['valides_premier_passage'] ?? []; $vpc = $cum['valides_premier_passage'] ?? []; $dr = $m['delai_retour'] ?? []; $drc = $cum['delai_retour'] ?? []; $pn = $m['penalites_theoriques'] ?? []; $pnc = $cum['penalites_theoriques'] ?? []; [$dtLib, $dtTon] = $etat($dtc['ratio'] ?? null, $cibles['delais_tenus_pct']); [$vpLib, $vpTon] = $etat($vpc['ratio'] ?? null, $cibles['valides_premier_passage_pct']); [$drLib, $drTon] = $etat($drc['moyenne'] ?? null, $cibles['delai_retour_max_jours'], false); @endphp {{ $dtLib }} {{ $vpLib }} {{ $drLib }} {{ ((float) ($pnc['montant'] ?? 0)) > 0 ? 'à surveiller' : 'atteint' }} @php $cv = $m['couverture'] ?? []; $cvc = $cum['couverture'] ?? []; $pr = $m['promesse_tenue'] ?? []; $prc = $cum['promesse_tenue'] ?? []; $pj = $m['planning_j5'] ?? []; $pjc = $cum['planning_j5'] ?? []; @endphp @forelse ($espace->reseauxConfigures() as $reseau) @php $s = ($ligne->saisis['reseaux'][$reseau['cle']] ?? []); @endphp @empty Aucun réseau configuré — voyez « Paramètres » pour en ajouter. @endforelse @forelse ($this->rapportsGeneres() as $rapport) @if ($gere) Partager avec le client @endif @empty Aucun rapport généré pour cet espace. @endforelse @endif {{-- ═══ PUBLICATIONS ══════════════════════════════════════════════════════════════════ --}} @if ($onglet === 'publications') @if ($gere)
Nouvelle publication
@endif
@foreach (\App\Filament\Admin\Resources\EspacesClients\Pages\ViewEspaceClient::VUES_PUBLICATIONS as $cle => $libelle) @endforeach
@forelse ($this->publications() as $publication) @php $contenu = $publication->contenu(); @endphp {{ $publication->statut->label() }} @if ($gere) Ouvrir @if ($publication->statut->estModifiable()) Envoyer au client @endif @if ($publication->statut->attendLeClient()) Relancer Décision reçue @endif @if ($publication->statut === \App\Enums\EspaceClient\StatutPublication::Validee) Programmer @endif @if (in_array($publication->statut, [\App\Enums\EspaceClient\StatutPublication::Validee, \App\Enums\EspaceClient\StatutPublication::Programmee], true)) Marquer publiée @endif @if ($publication->statut !== \App\Enums\EspaceClient\StatutPublication::Annulee) Annuler @endif @endif @empty Aucune publication dans cette vue. @endforelse @endif {{-- ═══ ÉVÉNEMENTS ════════════════════════════════════════════════════════════════════ --}} @if ($onglet === 'evenements') @if ($gere)
Planifier un événement
@endif @forelse ($this->evenements() as $evenement) {{ $evenement->statut->label() }} @if ($evenement->promesse_tenue !== null) {{ $evenement->promesse_tenue ? 'promesse tenue' : 'promesse non tenue' }} @endif @if ($gere) {{ $evenement->statut === \App\Enums\EspaceClient\StatutEvenement::Signale ? 'Qualifier' : 'Modifier' }} Galerie @endif {{-- La chronologie, étape par étape : c'est la promesse du jour même, pas une décoration. --}} @if ($evenement->etapes())
@foreach ($evenement->etapes() as $etape) @php $fait = filled($etape['fait_le'] ?? null); $enRetard = ! $fait && filled($etape['echeance_le'] ?? null) && \Illuminate\Support\Carbon::parse($etape['echeance_le'])->isPast(); @endphp
$fait, 'border-red-200 bg-red-50 text-red-800 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300' => $enRetard, 'border-gray-200 bg-white text-gray-600 dark:border-white/10 dark:bg-gray-900 dark:text-gray-300' => ! $fait && ! $enRetard, ])> {{ $etape['libelle'] }} {{ $etape['decalage_h'] < 0 ? 'H'.$etape['decalage_h'] : 'H+'.$etape['decalage_h'] }} @if ($fait) · fait à {{ \Illuminate\Support\Carbon::parse($etape['fait_le'])->format('H:i') }} @endif @if ($etape['cle_promesse']) · promesse @endif @if (! $fait && $gere) @endif
@endforeach
@if ($evenement->galerie_lien)

Galerie : {{ $evenement->galerie_lien }}

@endif
@endif @empty Aucun événement — planifiez la première couverture. @endforelse
@endif {{-- ═══ DEMANDES ══════════════════════════════════════════════════════════════════════ --}} @if ($onglet === 'demandes') @if ($gere)
Saisir une demande reçue
@endif @forelse ($this->demandes() as $demande) {{ $demande->statut->label() }} @if ($gere) @if ($demande->statut->value === 'recue') Qualifier @endif @if ($demande->lettre_commande_id === null) Préparer la lettre @endif @endif @empty Aucune demande reçue. @endforelse @endif {{-- ═══ COMMANDES ═════════════════════════════════════════════════════════════════════ --}} @php $vuesCommandes = \App\Filament\Admin\Resources\EspacesClients\Pages\ViewEspaceClient::VUES_COMMANDES; @endphp @if ($onglet === 'commandes') @php $vueCmd = $this->vueCourante($vuesCommandes); @endphp
@foreach ($vuesCommandes as $cle => $libelle) @endforeach
@endif {{-- ─── Commandes › Réceptions (v4.3.0 §C1) ──────────────────────────────────────────── --}} @if ($onglet === 'commandes' && $vueCmd === 'receptions') @php $receptions = $this->receptions(); $reperes = $this->postes(); $commande = round((float) $reperes->sum('montant_commande'), 2); $facture = round((float) $receptions->sum(fn ($r) => $r->invoice_id !== null ? (float) $r->montant_ttc : 0), 2); $valide = round((float) $receptions->sum('montant_ht'), 2); @endphp
@foreach ([ ['Commandé', number_format($commande, 2, ',', ' ').' DH', 'HT, lettres engagées'], ['Livré', $reperes->sum('livre').' ligne(s)', 'remis au moins une fois'], ['Validé', number_format($valide, 2, ',', ' ').' DH', 'HT, base des décomptes'], ['Facturé', number_format($facture, 2, ',', ' ').' DH', 'TTC, décomptes facturés'], ] as [$libelle, $valeur, $detail])

{{ $libelle }}

{{ $valeur }}

{{ $detail }}

@endforeach
@if ($gere)
Générer les périodes
@endif @forelse ($receptions as $reception) {{ $reception->statut->label() }} @if ($gere) Préparer le décompte @if (in_array($reception->statut->value, ['decompte_prepare', 'en_cours'], true)) PV signé @endif @if ($reception->invoice_id === null && $reception->lignes->isNotEmpty()) Créer la facture @endif @endif @if ($reception->lignes->isNotEmpty())
@foreach ($reception->lignes as $l) {{ $l->poste?->numero ?? '?' }} · {{ $nombre($l->quantite) }} × {{ number_format((float) $l->pu_ht, 2, ',', ' ') }} = {{ number_format((float) $l->montant_ht, 2, ',', ' ') }} DH @endforeach
@endif @empty Générez les périodes de réception depuis les dates d'exécution du marché. @endforelse
@endif {{-- ─── Commandes › Pénalités (v4.3.0 §C1) ───────────────────────────────────────────── --}} @if ($onglet === 'commandes' && $vueCmd === 'penalites') @php $simulation = $this->simulationDePenalites(); $theoriques = $this->penalitesTheoriques(); @endphp
{{ number_format($simulation['total'], 2, ',', ' ') }} DH @if ($simulation['plafond_atteint']) plafond atteint @endif
@forelse ($theoriques['lignes'] as $ligne) {{ $ligne['jours'] }} jour(s) @empty Aucun livrable n'a été remis en retard. @endforelse @endif {{-- ─── Commandes › Lettres de commande ──────────────────────────────────────────────── --}} @if ($onglet === 'commandes' && $vueCmd === 'lettres') @forelse ($this->lettres() as $lettre) {{ $lettre->statut->label() }} {{ number_format($lettre->montantHt(), 2, ',', ' ') }} DH @if ($gere && $lettre->statut->value === 'preparee') Envoyer à signer @endif @empty Aucune lettre de commande. @endforelse @forelse ($this->piecesManquantes() as $piece) {{ $piece->debiteur === 'client' ? 'côté client' : 'de notre côté' }} @empty Tous les dossiers sont complets. @endforelse @endif {{-- ─── Commandes › Bordereau ────────────────────────────────────────────────────────── --}} @if ($onglet === 'commandes' && $vueCmd === 'bordereau') @if ($gere)
Poste
@endif @forelse ($this->postes() as $ligne) {{ number_format($ligne['montant_commande'], 2, ',', ' ') }} DH @if ($gere) Modifier Supprimer @endif @empty Aucun poste — ajoutez le premier avec + Poste. @endforelse @endif {{-- ═══ DOCUMENTS ═════════════════════════════════════════════════════════════════════ --}} @if ($onglet === 'documents') @if ($gere)
Ajouter un document
@endif @forelse ($this->documents() as $document) {{ $document->estPartage() ? 'partagé' : 'interne' }} @empty Aucun document. @endforelse @endif {{-- ═══ RÉUNIONS ══════════════════════════════════════════════════════════════════════ --}} @if ($onglet === 'reunions') @if ($gere)
Proposer un créneau
@endif @forelse ($this->reunions() as $reunion) @if ($gere) Compte rendu @endif @empty Aucune réunion — proposez le premier créneau. @endforelse @endif {{-- ═══ JOURNAL E-MAILS ═══════════════════════════════════════════════════════════════ --}} @if ($onglet === 'journal') @forelse ($this->journal() as $ligne) {{ $ligne->statut === 'envoye' ? 'envoyé' : 'échec' }} @empty Aucun e-mail envoyé pour cet espace. @endforelse @endif {{-- ═══ PARAMÈTRES ════════════════════════════════════════════════════════════════════ --}} @if ($onglet === 'parametres') @if ($gere) Modifier @endif @if ($espace->lienPublic())

{{ $espace->lienPublic() }}

@if ($gere)
Renouveler le jeton Voir comme le client
@endif
{!! $this->qrCode() !!}
@else Le mode d'accès de cet espace n'ouvre pas de lien de lecture. @endif
@foreach ($this->modules() as $module) {{ $module['actif'] ? 'actif' : 'éteint' }} @if ($gere) ↑ ↓ {{ $module['actif'] ? 'Éteindre' : 'Allumer' }} @endif @endforeach {{-- ─── v4.3.0 §C1 — Les paramètres du lot 2 ─────────────────────────────────── --}} @if ($gere) Modifier @endif @if ($gere) Régénérer les périodes @endif @foreach ([\App\Enums\EspaceClient\ModuleClient::Avancement, \App\Enums\EspaceClient\ModuleClient::Quantites] as $moduleAVues) @php $actives = array_keys(app(\App\Services\EspaceClient\VueClient::class)->vuesActives($espace, $moduleAVues)); @endphp @if ($gere) @foreach ($moduleAVues->vuesPossibles() as $cle => $libelle) {{ $libelle }} @endforeach @endif @endforeach @if ($gere) {{ $espace->optionDuModule(\App\Enums\EspaceClient\ModuleClient::AFaire, 'publications', true) ? 'Retirer' : 'Autoriser' }} @endif @if ($gere) {{ $espace->optionDuModule(\App\Enums\EspaceClient\ModuleClient::Avancement, 'evenements_signalement_client', true) ? 'Retirer' : 'Autoriser' }} @endif @if ($gere)
Inviter une personne
@endif @forelse ($this->acces() as $acces) {{ $acces->actif ? 'actif' : 'désactivé' }} @if ($gere) Renvoyer {{ $acces->actif ? 'Désactiver' : 'Rétablir' }} @endif @empty Aucun compte client — invitez le référent du marché. @endforelse
@endif {{-- ═══ LES PANNEAUX DE SAISIE, EN LIGNE ══════════════════════════════════════════════ --}} @include('filament.admin.espace-client.panneaux', ['espace' => $espace, 'etiquette' => $etiquette])