feat: pages services NDD/Esy-Web + index Meilisearch + sync + recherche
Pages services : - /admin/services/ndd : liste tous les NDD avec client, registrar, Cloudflare, gestion, facturation, expiration + barre recherche - /admin/services/esyweb : liste tous les sites avec client, UUID, type, statut + barre recherche - Liens sidebar mis à jour (Esy-Web → esyweb, Nom de domaine → ndd) MeilisearchService : - Index customer_ndd : searchable fqdn/registrar/customerName/customerEmail, filterable customerId/isGestion/isBilling - Index customer_website : searchable name/uuid/customerName/customerEmail, filterable customerId/type/state - CRUD : indexDomain/removeDomain/searchDomains, indexWebsite/removeWebsite/searchWebsites - Serializers avec infos client intégrées (customerName, customerEmail, customerId) SyncController : - Route POST /admin/sync/domains : sync tous les Domain dans Meilisearch - Route POST /admin/sync/websites : sync tous les Website dans Meilisearch - Compteurs totalDomains et totalWebsites dans index Template admin/sync : - Bloc "Noms de domaine" (slate) avec bouton sync - Bloc "Sites Internet" (blue) avec bouton sync Recherche (app.js) : - renderHit adapté : affiche fqdn/name pour NDD/sites, customerName en sous-texte - Lien vers la fiche client (customerId) pour les résultats NDD/Website - setupSearch configuré pour search-ndd et search-websites Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -142,12 +142,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
|
||||
// Search (customers & revendeurs)
|
||||
const renderHit = (h, linkPrefix) =>
|
||||
`<a href="${linkPrefix}${h.id}" class="block px-4 py-2 hover:bg-gray-50 border-b border-gray-100 text-xs">
|
||||
<span class="font-bold">${h.fullName || h.raisonSociale || (h.firstName + ' ' + h.lastName)}</span>
|
||||
${h.email ? `<span class="text-gray-400 ml-2">${h.email}</span>` : ''}
|
||||
const renderHit = (h, linkPrefix) => {
|
||||
const id = h.customerId || h.id;
|
||||
const name = h.fqdn || h.name || h.fullName || h.raisonSociale || (h.firstName + ' ' + h.lastName);
|
||||
const sub = h.customerName ? `<span class="text-gray-400 ml-2">${h.customerName}</span>` : (h.email ? `<span class="text-gray-400 ml-2">${h.email}</span>` : '');
|
||||
return `<a href="${linkPrefix}${id}" class="block px-4 py-2 hover:bg-gray-50 border-b border-gray-100 text-xs">
|
||||
<span class="font-bold">${name}</span>
|
||||
${sub}
|
||||
${h.codeRevendeur ? `<span class="ml-2 px-1 py-0.5 bg-gray-900 text-[#fabf04] text-[9px] font-bold">${h.codeRevendeur}</span>` : ''}
|
||||
</a>`;
|
||||
};
|
||||
|
||||
const performSearch = async (searchUrl, linkPrefix, results, q) => {
|
||||
const resp = await fetch(`${searchUrl}?q=${encodeURIComponent(q)}`);
|
||||
@@ -184,6 +188,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
setupSearch('search-customers', 'search-results', '/admin/clients/search', '/admin/clients/');
|
||||
setupSearch('search-revendeurs', 'search-results-revendeurs', '/admin/revendeurs/search', '/admin/revendeurs/');
|
||||
setupSearch('search-ndd', 'search-ndd-results', '/admin/services/ndd/search', '/admin/clients/');
|
||||
setupSearch('search-websites', 'search-websites-results', '/admin/services/esyweb/search', '/admin/clients/');
|
||||
|
||||
// Tarif tabs
|
||||
const tarifTabs = document.getElementById('tarif-tabs');
|
||||
|
||||
Reference in New Issue
Block a user