feat: sous-ligne services par domaine (EsyMail, EsyMailer, Config DNS)

Sous chaque NDD dans l'onglet Noms de domaine, une ligne affiche :
- Esy-Mail : check vert si au moins 1 DomainEmail lié + nombre de boîtes
- Esy-Mailer : check vert/rouge (placeholder, false pour le moment)
- Config DNS : OK (vert) si zone Cloudflare configurée, KO (rouge) sinon

buildDomainsInfo() :
- Compte les DomainEmail par domaine
- esyMail = emailCount > 0
- esyMailerConfig = zoneIdCloudflare != null (DNS géré)
- esyMailer = false (sera branché sur l'entité service)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-04-04 20:56:44 +02:00
parent 5578d53cbd
commit d65fc102af
2 changed files with 69 additions and 8 deletions

View File

@@ -128,6 +128,31 @@ class ClientsController extends AbstractController
return $info;
}
/**
* @param list<Domain> $domains
*
* @return array<int, array{esyMail: bool, emailCount: int, esyMailer: bool, esyMailerConfig: bool}>
*/
private function buildDomainsInfo(array $domains, EntityManagerInterface $em): array
{
$emailRepo = $em->getRepository(\App\Entity\DomainEmail::class);
$info = [];
foreach ($domains as $domain) {
$emailCount = $emailRepo->count(['domain' => $domain]);
$hasCloudflare = null !== $domain->getZoneIdCloudflare();
$info[$domain->getId()] = [
'esyMail' => $emailCount > 0,
'emailCount' => $emailCount,
'esyMailer' => false,
'esyMailerConfig' => $hasCloudflare,
];
}
return $info;
}
private function ensureDefaultContact(Customer $customer, EntityManagerInterface $em): void
{
$contactRepo = $em->getRepository(\App\Entity\CustomerContact::class);
@@ -340,11 +365,13 @@ class ClientsController extends AbstractController
$this->ensureDefaultContact($customer, $em);
$contacts = $em->getRepository(\App\Entity\CustomerContact::class)->findBy(['customer' => $customer], ['createdAt' => 'DESC']);
$domains = $em->getRepository(\App\Entity\Domain::class)->findBy(['customer' => $customer]);
$domainsInfo = $this->buildDomainsInfo($domains, $em);
return $this->render('admin/clients/show.html.twig', [
'customer' => $customer,
'contacts' => $contacts,
'domains' => $domains,
'domainsInfo' => $domainsInfo,
'tab' => $tab,
]);
}

View File

@@ -318,23 +318,24 @@
</thead>
<tbody>
{% for domain in domains %}
<tr class="border-b border-white/20 hover:bg-white/50">
<td class="px-4 py-3 font-bold font-mono">{{ domain.fqdn }}</td>
<td class="px-4 py-3 text-xs">{{ domain.registrar ?? '—' }}</td>
<td class="px-4 py-3 text-center">
{% set dInfo = domainsInfo[domain.id] ?? {} %}
<tr class="hover:bg-white/50">
<td class="px-4 pt-3 pb-1 font-bold font-mono">{{ domain.fqdn }}</td>
<td class="px-4 pt-3 pb-1 text-xs">{{ domain.registrar ?? '—' }}</td>
<td class="px-4 pt-3 pb-1 text-center">
{% if domain.zoneIdCloudflare %}
<span class="px-2 py-0.5 bg-orange-500/20 text-orange-700 font-bold uppercase text-[10px] rounded">{{ domain.zoneCloudflare ?? 'Lie' }}</span>
{% else %}
<span class="text-gray-300">—</span>
{% endif %}
</td>
<td class="px-4 py-3 text-center">
<td class="px-4 pt-3 pb-1 text-center">
{% if domain.isGestion %}<span class="text-green-600 font-bold">&#10003;</span>{% else %}<span class="text-gray-300">&#10007;</span>{% endif %}
</td>
<td class="px-4 py-3 text-center">
<td class="px-4 pt-3 pb-1 text-center">
{% if domain.isBilling %}<span class="text-green-600 font-bold">&#10003;</span>{% else %}<span class="text-gray-300">&#10007;</span>{% endif %}
</td>
<td class="px-4 py-3 text-xs">
<td class="px-4 pt-3 pb-1 text-xs">
{% if domain.expiredAt %}
<span class="{{ domain.isExpired ? 'text-red-600 font-bold' : (domain.isExpiringSoon ? 'text-yellow-600 font-bold' : 'text-gray-500') }}">
{{ domain.expiredAt|date('d/m/Y') }}
@@ -343,7 +344,7 @@
<span class="text-gray-300">—</span>
{% endif %}
</td>
<td class="px-4 py-3 text-center">
<td class="px-4 pt-3 pb-1 text-center">
<form method="post" action="{{ path('app_admin_clients_show', {id: customer.id, tab: 'ndd'}) }}" data-confirm="Supprimer le domaine {{ domain.fqdn }} ?">
<input type="hidden" name="domain_action" value="delete">
<input type="hidden" name="domain_id" value="{{ domain.id }}">
@@ -351,6 +352,39 @@
</form>
</td>
</tr>
<tr class="border-b border-white/20">
<td colspan="7" class="px-4 pb-3 pt-0">
<div class="flex flex-wrap items-center gap-x-4 gap-y-1 text-[10px]">
<span class="font-bold" title="Esy-Mail (boites mail)">
Esy-Mail
{% if dInfo.esyMail ?? false %}
<span class="text-green-600">&#10003;</span>
<span class="text-gray-400">({{ dInfo.emailCount ?? 0 }})</span>
{% else %}
<span class="text-red-500">&#10007;</span>
{% endif %}
</span>
<span class="text-gray-300">|</span>
<span class="font-bold" title="Esy-Mailer (newsletter/mailing)">
Esy-Mailer
{% if dInfo.esyMailer ?? false %}
<span class="text-green-600">&#10003;</span>
{% else %}
<span class="text-red-500">&#10007;</span>
{% endif %}
</span>
<span class="text-gray-300">|</span>
<span class="font-bold" title="Configuration DNS mail (SPF, DKIM, DMARC)">
Config DNS
{% if dInfo.esyMailerConfig ?? false %}
<span class="px-1.5 py-0.5 bg-green-500/20 text-green-700 font-bold uppercase rounded">OK</span>
{% else %}
<span class="px-1.5 py-0.5 bg-red-500/20 text-red-700 font-bold uppercase rounded">KO</span>
{% endif %}
</span>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>