2026-06-23 10:04:23 +00:00
{% extends "base.html" %}
{% block title %}Wereldexport · Foodlinkk B2B{% endblock %}
{% block extra_head %}
2026-07-19 18:36:02 +00:00
< link rel = "stylesheet" href = "/static/vendor/leaflet/leaflet.css?v=1" />
< link rel = "stylesheet" href = "/static/vendor/leaflet.markercluster/MarkerCluster.css?v=1" />
< link rel = "stylesheet" href = "/static/vendor/leaflet.markercluster/MarkerCluster.Default.css?v=1" />
2026-07-30 09:33:03 +00:00
< link rel = "stylesheet" href = "/static/css/export-intel.css?v=32" />
< link rel = "stylesheet" href = "/static/css/export-intel-tabs.css?v=20" />
2026-07-19 18:36:02 +00:00
< script src = "/static/vendor/leaflet/leaflet.js?v=1" ></ script >
< script src = "/static/vendor/leaflet.markercluster/leaflet.markercluster.js?v=1" ></ script >
2026-07-30 09:33:03 +00:00
< script src = "/static/js/export-intel-map.js?v=21" ></ script >
< script src = "/static/js/export-intel.js?v=32" ></ script >
< script src = "/static/js/export-intel-profile.js?v=7" ></ script >
2026-06-23 10:04:23 +00:00
{% endblock %}
{% block content %}
< div class = "ei-page" x-data = "exportIntelApp()" x-init = "init()" >
2026-07-19 18:47:12 +00:00
< div class = "ei-progress-overlay" x-show = "isWorking()" x-cloak >
< div class = "ei-progress-card" >
< div class = "ei-progress-spinner" ></ div >
< p x-text = "progressLabel()" ></ p >
2026-07-30 09:33:03 +00:00
< div class = "ei-progress-bar" >< div class = "ei-progress-bar-fill" :style = "'width:' + (syncMonitorPercent() || 100) + '%'" ></ div ></ div >
2026-07-19 18:47:12 +00:00
</ div >
</ div >
2026-06-23 10:04:23 +00:00
< header class = "ei-header page-header" >
< div >
< h1 > Wereldexport < span class = "live-badge" > Live</ span ></ h1 >
< p class = "ei-subtitle" > Foodlinkk B2B · wereldwijde markten · halal vlees · cateraars · distributeurs</ p >
</ div >
< div class = "retail-actions" >
< button class = "btn btn-sm btn-pulse-green" @ click = "syncKind('world')" :disabled = "busy" title = "Europa · MENA · Afrika · Amerika" > 🌍 Sync wereld</ button >
< button class = "btn btn-sm btn-pulse" @ click = "syncKind('region')" :disabled = "busy || !region" title = "Sync huidige regio-filter" > Sync regio</ button >
< button class = "btn btn-sm btn-pulse-green" @ click = "syncKind('all')" :disabled = "busy" > ⚡ Sync alles</ button >
< button class = "btn btn-sm btn-pulse" @ click = "syncKind('distributors')" :disabled = "busy" > Distributeurs</ button >
< button class = "btn btn-sm btn-pulse" @ click = "syncKind('caterers')" :disabled = "busy" > Cateraars</ button >
< button class = "btn btn-sm btn-pulse-green" @ click = "syncKind('contacts')" :disabled = "busy" > Contacten</ button >
< button class = "btn btn-sm btn-pulse-purple" @ click = "syncKind('tenders')" :disabled = "busy" > TED</ button >
< a class = "btn btn-sm" :href = "contactsExportUrl()" target = "_blank" > CSV export</ a >
</ div >
</ header >
2026-07-30 09:33:03 +00:00
< div class = "ei-sync-monitor" :class = "{ 'ei-sync-monitor-open': syncMonitorOpen, 'ei-sync-monitor-active': syncMonitor && syncMonitor.any_running }" >
< button type = "button" class = "ei-sync-monitor-toggle" @ click = "toggleSyncMonitor()" >
< span x-show = "syncMonitor && syncMonitor.any_running" > ⏳ Sync bezig</ span >
< span x-show = "!(syncMonitor && syncMonitor.any_running)" > 📡 Sync monitor</ span >
< span class = "ei-sync-monitor-badge" x-show = "syncMonitor && syncMonitor.coverage" x-text = "(syncMonitor.coverage.countries_with_data||0) + '/' + (syncMonitor.coverage.territories_total||0) + ' landen'" ></ span >
</ button >
< div class = "ei-sync-monitor-panel" x-show = "syncMonitorOpen" x-cloak >
< div class = "ei-sync-monitor-head" >
< strong > Sync voortgang</ strong >
< span x-show = "syncMonitor && syncMonitor.any_running" class = "ei-sync-live" > ● Live</ span >
</ div >
< template x-if = "syncMonitor && syncMonitor.active_jobs && syncMonitor.active_jobs.length" >
< div class = "ei-sync-jobs" >
< template x-for = "j in syncMonitor.active_jobs" :key = "j.id" >
< div class = "ei-sync-job" >
< div class = "ei-sync-job-title" x-text = "j.label" ></ div >
< div class = "ei-sync-job-msg" x-text = "j.message || j.step || 'Bezig…'" ></ div >
< div class = "ei-sync-job-bar" >< div class = "ei-sync-job-bar-fill" :style = "'width:' + (j.percent||0) + '%'" ></ div ></ div >
< div class = "ei-sync-job-meta" x-show = "j.total" x-text = "(j.current||0) + ' / ' + j.total + (j.country ? ' · ' + territoryName(j.country) : '')" ></ div >
</ div >
</ template >
</ div >
</ template >
< div class = "ei-sync-coverage" x-show = "syncMonitor && syncMonitor.coverage" >
< div >< span > Entiteiten</ span >< strong x-text = "syncMonitor.coverage.entities_total||0" ></ strong ></ div >
< div >< span > Landen met data</ span >< strong x-text = "(syncMonitor.coverage.countries_with_data||0) + ' / ' + (syncMonitor.coverage.territories_total||0)" ></ strong ></ div >
< div >< span > Lege landen</ span >< strong x-text = "syncMonitor.coverage.countries_empty||0" ></ strong ></ div >
</ div >
< div class = "ei-sync-events" x-show = "syncMonitor && syncMonitor.events && syncMonitor.events.length" >
< div class = "ei-sync-events-title" > Laatste stappen</ div >
< template x-for = "(ev, idx) in (syncMonitor.events || []).slice().reverse().slice(0,12)" :key = "idx" >
< div class = "ei-sync-event" >
< span class = "ei-sync-event-time" x-text = "formatSyncTime(ev.ts)" ></ span >
< span class = "ei-sync-event-text" x-text = "syncEventLabel(ev)" ></ span >
</ div >
</ template >
</ div >
</ div >
</ div >
2026-06-23 10:04:23 +00:00
< p class = "ei-sync-msg" x-show = "syncMsg" x-text = "syncMsg" ></ p >
2026-07-19 18:25:01 +00:00
< div class = "ei-selection-bar" x-show = "showSelectionBar()" x-cloak >
2026-06-23 10:04:23 +00:00
< div class = "ei-selection-left" >
< span class = "ei-selection-count" x-show = "selectedIds.length" x-text = "selectedIds.length + ' geselecteerd'" ></ span >
2026-07-19 18:25:01 +00:00
< span class = "ei-selection-hint" x-show = "!selectedIds.length" x-text = "tab === 'contacts' ? 'Selecteer contacten met ☑ — organisatie gaat naar CRM' : 'Selecteer rijen met ☑ voor bulk-acties'" ></ span >
2026-06-23 10:04:23 +00:00
</ div >
< div class = "ei-selection-actions" >
< button type = "button" class = "btn btn-sm" @ click = "toggleSelectAllVisible()" title = "Alles op lijst" > ☑ Alles</ button >
< button type = "button" class = "btn btn-sm" x-show = "selectedIds.length" @ click = "clearSelection()" > Wis selectie</ button >
< button type = "button" class = "btn btn-sm btn-pulse" :disabled = "!selectedIds.length || busy" @ click = "favoriteSelection()" > ★ Favoriet</ button >
< button type = "button" class = "btn btn-sm" :disabled = "!selectedIds.length || busy" @ click = "unfavoriteSelection()" > ☆ Verwijder favoriet</ button >
< button type = "button" class = "btn btn-sm btn-pulse-green" :disabled = "!selectedIds.length || crmPushBusy" @ click = "openCrmModal()" > ➕ Naar CRM</ button >
</ div >
</ div >
< div class = "ei-neo-kpi-row" >
< div class = "ei-neo-kpi" >
< div class = "ei-neo-kpi-top" >
< div class = "ei-neo-ring" style = "--ring-color:#0ea5e9;--ring-pct:85" >< div class = "ei-neo-ring-inner" > 🌍</ div ></ div >
< div >< div class = "ei-neo-kpi-label" > Landen</ div ></ div >
</ div >
< div class = "ei-neo-kpi-value" x-text = "stats.territories||0" ></ div >
</ div >
< div class = "ei-neo-kpi" >
< div class = "ei-neo-kpi-top" >
< div class = "ei-neo-ring" style = "--ring-color:#38bdf8;--ring-pct:70" >< div class = "ei-neo-ring-inner" > 📊</ div ></ div >
< div >< div class = "ei-neo-kpi-label" > Entities</ div ></ div >
</ div >
< div class = "ei-neo-kpi-value" x-text = "stats.entities||0" ></ div >
</ div >
< div class = "ei-neo-kpi" >
< div class = "ei-neo-kpi-top" >
< div class = "ei-neo-ring" style = "--ring-color:#fbbf24;--ring-pct:75" >< div class = "ei-neo-ring-inner" > 📦</ div ></ div >
< div >< div class = "ei-neo-kpi-label" > Distributeurs</ div ></ div >
</ div >
< div class = "ei-neo-kpi-value" x-text = "stats.distributors||0" ></ div >
</ div >
< div class = "ei-neo-kpi" >
< div class = "ei-neo-kpi-top" >
< div class = "ei-neo-ring" style = "--ring-color:#a78bfa;--ring-pct:65" >< div class = "ei-neo-ring-inner" > 🏢</ div ></ div >
< div >< div class = "ei-neo-kpi-label" > Cateraars</ div ></ div >
</ div >
< div class = "ei-neo-kpi-value" x-text = "stats.caterers||0" ></ div >
</ div >
< div class = "ei-neo-kpi" >
< div class = "ei-neo-kpi-top" >
< div class = "ei-neo-ring" style = "--ring-color:#34d399;--ring-pct:60" >< div class = "ei-neo-ring-inner" > 📇</ div ></ div >
< div >< div class = "ei-neo-kpi-label" > Contacten</ div ></ div >
</ div >
< div class = "ei-neo-kpi-value" x-text = "stats.contacts||0" ></ div >
</ div >
< div class = "ei-neo-kpi" >
< div class = "ei-neo-kpi-top" >
< div class = "ei-neo-ring" style = "--ring-color:#c084fc;--ring-pct:50" >< div class = "ei-neo-ring-inner" > 📋</ div ></ div >
< div >< div class = "ei-neo-kpi-label" > Tenders open</ div ></ div >
</ div >
< div class = "ei-neo-kpi-value" x-text = "stats.tenders_open||0" ></ div >
</ div >
</ div >
< div class = "ei-filter-bar" >
2026-07-30 09:33:03 +00:00
< div class = "ei-filter-grid" >
< label class = "ei-filter-label ei-filter-cell ei-fa-regio" > Regio
2026-06-23 10:04:23 +00:00
< select x-model = "region" @ change = "country=''; refresh()" >
< option value = "" > Alle regio's</ option >
< template x-for = "r in regions" :key = "r.code" >
< option :value = "r.code" x-text = "r.name_nl" ></ option >
</ template >
</ select >
</ label >
2026-07-30 09:33:03 +00:00
< label class = "ei-filter-label ei-filter-cell ei-fa-land" > Land
2026-06-23 10:04:23 +00:00
< select x-model = "country" @ change = "onCountryChange()" >
< option value = "" > Alle landen</ option >
2026-07-30 09:33:03 +00:00
< template x-for = "t in filteredTerritories()" :key = "t.country_iso2" >
< option :value = "t.country_iso2" x-text = "countryOptionLabel(t)" ></ option >
2026-06-23 10:04:23 +00:00
</ template >
</ select >
</ label >
2026-07-30 09:33:03 +00:00
< label class = "ei-filter-label ei-filter-cell ei-filter-cell-search ei-fa-zoek" >
< span > Zoeken</ span >
< input type = "search" placeholder = "Organisatie, e-mail…" x-model = "q" @ input = "onSearchInput()" />
</ label >
< label class = "ei-filter-label ei-filter-cell ei-fa-type" x-show = "showEntityTypeFilter()" > Type
< select x-model = "entityTypeFilter" @ change = "applyEntityFilters()" >
< template x-for = "o in entityTypeOptions()" :key = "o.v" >
< option :value = "o.v" x-text = "o.l" ></ option >
</ template >
</ select >
</ label >
< label class = "ei-filter-label ei-filter-cell ei-fa-contact" x-show = "showEmailFilter()" > Contact
< select x-model = "filterHasEmail" @ change = "applyEntityFilters()" >
< option value = "" > Alle</ option >
< option value = "yes" > Met e-mail/tel</ option >
< option value = "no" > Zonder contact</ option >
</ select >
</ label >
< label class = "ei-filter-label ei-filter-cell ei-fa-conf" x-show = "showConfidenceFilter()" > Confidence
< select x-model = "filterConfidenceMin" @ change = "applyEntityFilters()" >
< option value = "" > Alle</ option >
< option value = "50" > 50%+</ option >
< option value = "70" > 70%+</ option >
< option value = "85" > 85%+</ option >
</ select >
2026-06-23 10:04:23 +00:00
</ label >
2026-07-30 09:33:03 +00:00
< label class = "ei-filter-label ei-filter-cell ei-fa-stad" x-show = "showCityFilter()" > Stad
< input type = "text" placeholder = "bv. Rotterdam" x-model = "filterCity" @ input = "onCityFilterInput()" />
</ label >
< label class = "ei-filter-label ei-filter-cell ei-fa-extra" x-show = "tab==='tenders'" > Status
< select x-model = "filterTenderStatus" @ change = "loadTabData()" >
< option value = "" > Alle</ option >
< option value = "open" > Open</ option >
< option value = "closed" > Gesloten</ option >
</ select >
</ label >
< label class = "ei-filter-label ei-filter-cell ei-fa-extra" x-show = "tab==='gov'" > Categorie
< select x-model = "filterGovCategory" @ change = "applyGovFilters()" >
< option value = "" > Alle</ option >
< option value = "statistics" > Statistiek</ option >
< option value = "trade" > Handel</ option >
< option value = "regulation" > Regelgeving</ option >
< option value = "demographics" > Demografie</ option >
</ select >
</ label >
< label class = "ei-filter-label ei-filter-cell ei-fa-crm" x-show = "showCollectionFilters()" > CRM
< select x-model = "filterCrmStatus" @ change = "onFilterCollectionChange()" >
< option value = "" > Alle</ option >
< option value = "not_linked" > Nog niet in CRM</ option >
< option value = "linked" > In CRM</ option >
</ select >
</ label >
< label class = "ei-filter-check ei-filter-cell ei-filter-cell-check ei-fa-fav" x-show = "showFavoritesFilter()" >
< input type = "checkbox" x-model = "filterFavoritesOnly" @ change = "onFilterCollectionChange()" />
< span > ★ Favorieten</ span >
</ label >
< div class = "ei-filter-meta ei-filter-cell ei-filter-cell-meta ei-fa-meta" >
< span class = "ei-filter-count" x-show = "resultCount > 0" x-text = "resultCount + ' resultaten'" ></ span >
< span class = "ei-filter-count ei-filter-fav" x-show = "stats.favorites > 0" x-text = "(stats.favorites||0) + ' ★'" ></ span >
< button type = "button" class = "btn btn-sm ei-filter-clear" x-show = "hasActiveFilters()" @ click = "clearFilters()" > Wis filters</ button >
</ div >
2026-06-23 10:04:23 +00:00
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-filter-map-row" x-show = "showMapTypeFilter()" x-cloak >
< span class = "ei-filter-label ei-filter-map-label" > Kaart toont</ span >
2026-06-23 10:04:23 +00:00
< div class = "ei-type-chips" role = "group" aria-label = "Types op kaart" >
< button type = "button" class = "ei-type-chip" :class = "{ active: !mapTypesSelected.length }" @ click = "clearMapTypes()" > Alle</ button >
< template x-for = "chip in mapTypeChips" :key = "chip.v" >
< button type = "button" class = "ei-type-chip" :class = "{ active: isMapTypeActive(chip.v) }" @ click = "toggleMapType(chip.v)" >
2026-07-30 09:33:03 +00:00
< span x-text = "chip.icon" ></ span > < span x-text = "chip.l" ></ span > < span class = "ei-chip-count" x-show = "mapTypeCount(chip.v)" x-text = "mapTypeCount(chip.v)" ></ span >
2026-06-23 10:04:23 +00:00
</ button >
</ template >
</ div >
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-filter-map-row ei-filter-map-row-halal" x-show = "showMapTypeFilter()" x-cloak >
2026-06-23 10:04:23 +00:00
< label class = "ei-filter-check" >
< input type = "checkbox" x-model = "mapHalalMode" @ change = "applyMapFilters()" />
< span > 🥩 Halal-kansen modus</ span >
</ label >
< label class = "ei-filter-label ei-halal-min" x-show = "mapHalalMode" >
Min. score
< input type = "range" min = "30" max = "90" step = "5" x-model . number = "mapHalalMin" @ change = "applyMapFilters()" />
< strong x-text = "mapHalalMin" ></ strong >
</ label >
</ div >
</ div >
2026-07-30 09:33:03 +00:00
< div class = "vtabs-layout wereldexport-workspace" style = "--vt-color:#0ea5e9" x-ref = "vtabsWrap" >
2026-06-23 10:04:23 +00:00
< nav class = "vtabs-nav" x-ref = "vtabsNav" :style = "'--vt-indicator-top:'+tabIndicatorTop+'px;--vt-indicator-h:'+tabIndicatorH+'px'" >
< div class = "vtabs-nav-header" >< strong > Modules</ strong ></ div >
< template x-for = "t in tabs" :key = "t.id" >
< button type = "button" class = "vtab-btn vtab-btn-rich" :class = "{active: tab===t.id}" :data-tab = "t.id"
:style = "'--tab-accent:'+t.color"
@ click = "setTab(t.id, $el)" >
< span class = "ei-vtab-icon-wrap" x-text = "t.icon" ></ span >
< span class = "ei-vtab-text" >
< span class = "ei-vtab-label" x-text = "t.label" ></ span >
< span class = "ei-vtab-sub" x-show = "tabSub(t.id)" x-text = "tabSub(t.id)" ></ span >
</ span >
< span class = "ei-vtab-meta" >
< span class = "ei-vtab-key" x-text = "t.key" ></ span >
< span class = "ei-vtab-badge" x-show = "tabCount(t.id) > 0" x-text = "tabCount(t.id)" ></ span >
</ span >
</ button >
</ template >
</ nav >
< div class = "vtabs-content" >
<!-- Kaart -->
< section x-show = "tab==='map'" x-cloak >
< div class = "ei-tab-panel" >
< div class = "ei-tab-panel-head" >
< div >
< h2 > Wereldkaart</ h2 >
< p > Klik pin voor preview · dubbelklik of “Volledig profiel” voor alle gegevens</ p >
</ div >
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-tab-panel-body ei-workspace-body ei-workspace-body-map" >
2026-06-23 10:04:23 +00:00
< div class = "ei-map-legend" >
< template x-if = "!mapHalalMode" >
< div class = "ei-legend-row" >
< span class = "ei-legend-item" >< i class = "ei-leg-pin" style = "--c:#f59e0b" > 📦</ i > Distributeur</ span >
< span class = "ei-legend-item" >< i class = "ei-leg-pin" style = "--c:#eab308" > 🏪</ i > Groothandel</ span >
< span class = "ei-legend-item" >< i class = "ei-leg-pin" style = "--c:#a78bfa" > 🏢</ i > Cateraar</ span >
< span class = "ei-legend-item" >< i class = "ei-leg-pin" style = "--c:#34d399" > 🍽️</ i > Horeca</ span >
< span class = "ei-legend-item" >< i class = "ei-leg-pin" style = "--c:#0ea5e9" > 📍</ i > Overig</ span >
</ div >
</ template >
< template x-if = "mapHalalMode" >
< div class = "ei-legend-row ei-legend-halal" >
< span class = "ei-legend-item" >< i class = "ei-leg-pin" style = "--c:#22c55e" > ●</ i > Hoge kans (75+)</ span >
< span class = "ei-legend-item" >< i class = "ei-leg-pin" style = "--c:#eab308" > ●</ i > Gemiddeld (55+)</ span >
< span class = "ei-legend-item" >< i class = "ei-leg-pin" style = "--c:#f97316" > ●</ i > Matig (40+)</ span >
< span class = "ei-legend-item" >< i class = "ei-leg-pin" style = "--c:#64748b" > ●</ i > Laag</ span >
</ div >
</ template >
</ div >
< div class = "ei-map-empty" x-show = "tab==='map' && !entities.length && !busy" x-cloak >
< div class = "ei-map-empty-inner" >
< strong x-show = "region || country" > Nog geen data op de kaart voor deze selectie</ strong >
< strong x-show = "!region && !country" > Zoom in of filter op regio</ strong >
< p > Landen staan in het systeem, maar entities + contacten komen pas na een < em > OSM sync</ em > (OpenStreetMap).</ p >
< p x-show = "region==='africa'" > Afrika: 51 landen toegevoegd — sync nog niet gedraaid voor dit continent.</ p >
< div class = "ei-map-empty-actions" >
< button type = "button" class = "btn btn-sm btn-pulse-green" x-show = "region" @ click = "syncKind('region')" :disabled = "busy" > ↻ Sync regio</ button >
< button type = "button" class = "btn btn-sm btn-pulse" @ click = "syncKind('world')" :disabled = "busy" > 🌍 Sync wereld</ button >
</ div >
</ div >
</ div >
2026-07-19 18:47:12 +00:00
< div class = "ei-map-error" x-show = "mapError" x-cloak x-text = "mapError" ></ div >
2026-07-30 09:33:03 +00:00
< p class = "ei-map-truncated" x-show = "mapTruncated && !mapLoading" x-cloak > Filter actief: max. 8.000 pins op de kaart. Zoom in op regio/land voor alles.</ p >
< p class = "ei-map-truncated ei-map-filter-hint" x-show = "resultCount === 0 && !mapLoading && (mapTypesSelected.length || entityTypeFilter)" x-cloak > Geen entities op de kaart voor dit filter — probeer B2B/groothandel of wis filters.</ p >
< div class = "ei-split ei-split-side" >
2026-07-19 18:42:47 +00:00
< div class = "ei-map-wrap" >< div class = "ei-map-loading" x-show = "mapLoading" x-cloak >< span class = "ei-map-spinner" ></ span > Kaart laden…</ div >< div id = "ei-map" ></ div ></ div >
2026-07-30 09:33:03 +00:00
< aside class = "ei-side-panel" >
< div class = "ei-side-panel-head" >
< h3 x-text = "mapHalalMode ? 'Top halal-kansen' : 'Entities op kaart'" ></ h3 >
< p x-show = "!mapHalalMode" > Klik een rij of kaart-pin om het volledige profiel te openen.</ p >
< p x-show = "mapHalalMode" > Klik een rij voor contact & context · kaart zoomt mee.</ p >
2026-06-23 10:04:23 +00:00
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-side-panel-body" >
2026-06-23 10:04:23 +00:00
< div class = "ei-halal-markets" x-show = "mapHalalMode && halalTopMarkets.length" >
< h4 > Landen met meeste kans</ h4 >
< template x-for = "m in halalTopMarkets.slice(0,8)" :key = "m.country_iso2" >
< div class = "ei-halal-market-row" @ click = "country=m.country_iso2; refresh()" style = "cursor:pointer" >
< span class = "ei-halal-flag" x-text = "m.country_iso2" ></ span >
2026-07-30 09:33:03 +00:00
< span class = "ei-halal-market-name" x-text = "territoryName(m.country_iso2)" ></ span >
2026-06-23 10:04:23 +00:00
< strong class = "ei-halal-score" x-text = "Math.round(m.combined_score||0)" ></ strong >
</ div >
</ template >
</ div >
< div class = "ei-table-wrap" >
2026-07-30 09:33:03 +00:00
< table class = "ei-table ei-table-compact" >
2026-06-23 10:04:23 +00:00
< thead >
< tr >
< th class = "ei-th-check" >< input type = "checkbox" @ change = "toggleSelectAllVisible()" title = "Alles selecteren" /></ th >
< th class = "ei-th-fav" > ★</ th >
2026-07-30 09:33:03 +00:00
< th class = "ei-th-name" > Naam</ th >
< th class = "ei-th-type" > Type</ th >
< th class = "ei-th-city" > Stad</ th >
< th class = "ei-th-contact ei-col-hide-side" > Contact</ th >
< th class = "ei-th-score" x-show = "mapHalalMode" > Score</ th >
< th class = "ei-th-country" > Land</ th >
< th class = "ei-th-open ei-col-hide-side" ></ th >
2026-06-23 10:04:23 +00:00
</ tr >
</ thead >
< tbody >
2026-07-30 09:33:03 +00:00
< template x-for = "e in (mapHalalMode && halalTopEntities.length ? halalTopEntities : displayEntities())" :key = "e.id" >
2026-06-23 10:04:23 +00:00
< tr
2026-07-30 09:33:03 +00:00
:data-entity-id = "e.id"
:class = "{ 'ei-row-active': selected && selected.id === e.id && drawerOpen, 'ei-row-selected': isSelected(e.id), 'ei-row-crm': e.client_id }"
2026-06-23 10:04:23 +00:00
style = "cursor:pointer"
2026-07-30 09:33:03 +00:00
title = "Klik voor profiel"
2026-06-23 10:04:23 +00:00
>
< td class = "ei-td-check" @ click . stop >
< input type = "checkbox" :checked = "isSelected(e.id)" @ change = "toggleSelect(e.id, $event)" />
</ td >
< td class = "ei-td-fav" @ click . stop >
< button type = "button" class = "ei-fav-btn" :class = "{ active: e.is_favorite }" @ click = "toggleFavorite(e.id, e.is_favorite, $event)" x-text = "e.is_favorite ? '★' : '☆'" ></ button >
</ td >
2026-07-30 09:33:03 +00:00
< td class = "ei-td-name" >
< div class = "ei-name-cell" >
< button type = "button" class = "ei-row-open-btn" x-text = "e.name" :title = "e.name" ></ button >
2026-06-23 10:04:23 +00:00
< span class = "ei-crm-badge" x-show = "e.client_id" title = "In CRM" > CRM</ span >
2026-07-30 09:33:03 +00:00
</ div >
</ td >
< td class = "ei-td-type" >< span class = "ei-type-pill ei-type-pill-sm" :class = "'ei-type-'+e.entity_type" x-text = "typeLabel(e.entity_type)" ></ span ></ td >
< td class = "ei-td-city" x-text = "e.city ? (e.city + (e.country_iso2 ? ' · ' + e.country_iso2 : '')) : (e.country_iso2 || '—')" ></ td >
< td class = "ei-td-contact ei-contact-cell" x-text = "contactPreview(e)" ></ td >
< td class = "ei-td-score" x-show = "mapHalalMode" >< span class = "ei-halal-pill" :class = "'ei-halal-'+(e.halal_score>=75?'hot':e.halal_score>=55?'warm':'mild')" x-text = "Math.round(e.halal_score||0)" ></ span ></ td >
< td class = "ei-td-country" x-text = "territoryName(e.country_iso2) || e.country_iso2" ></ td >
< td class = "ei-td-open" >< span class = "ei-open-chevron" > Profiel →</ span ></ td >
2026-06-23 10:04:23 +00:00
</ tr >
</ template >
</ tbody >
</ table >
</ div >
< div class = "ei-empty" x-show = "!entities.length" >
< p > Geen entities met geo in selectie.</ p >
< button class = "btn btn-sm btn-pulse ei-empty-cta" @ click = "syncKind('distributors')" > Start sync — fase B vult data</ button >
</ div >
2026-07-30 09:33:03 +00:00
</ div >
</ aside >
2026-06-23 10:04:23 +00:00
</ div >
</ div >
</ div >
</ section >
<!-- Distributeurs -->
2026-07-30 09:33:03 +00:00
< section x-show = "tab==='distributors'" x-cloak >
2026-06-23 10:04:23 +00:00
< div class = "ei-tab-panel" >
< div class = "ei-tab-panel-head" >
2026-07-30 09:33:03 +00:00
< div >< h2 > Distributeurs & groothandels</ h2 >< p > OSM · website-scrape · handmatig (gratis)</ p ></ div >
2026-06-23 10:04:23 +00:00
< button class = "btn btn-sm btn-pulse" @ click = "syncKind('distributors')" :disabled = "busy" > ↻ Sync</ button >
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-tab-panel-body ei-workspace-body" >
< div class = "ei-split ei-split-side" >
< div class = "ei-map-wrap" >
< div class = "ei-map-loading" x-show = "tabMapLoading" x-cloak >< span class = "ei-map-spinner" ></ span > Kaart laden…</ div >
< div id = "ei-map-distributors" ></ div >
</ div >
< aside class = "ei-side-panel" >
< div class = "ei-side-panel-head" >
< h3 > Distributeurs op kaart</ h3 >
< p > Klik een pin of tabelrij voor het volledige profiel.</ p >
</ div >
< div class = "ei-side-panel-body" >
2026-06-23 10:04:23 +00:00
< div class = "ei-table-wrap" >
2026-07-30 09:33:03 +00:00
< table class = "ei-table ei-table-compact" >
2026-07-19 18:47:12 +00:00
< thead >< tr >
< th class = "ei-th-check" >< input type = "checkbox" @ change = "toggleSelectAllVisible()" title = "Alles" /></ th >
2026-07-30 09:33:03 +00:00
< th class = "ei-th-name" > Naam</ th >< th class = "ei-th-type" > Type</ th >< th class = "ei-th-country" > Land</ th >< th class = "ei-th-city" > Stad</ th >< th class = "ei-th-contact ei-col-hide-side" > Contact</ th >< th class = "ei-th-conf ei-col-hide-side" > Conf.</ th >< th class = "ei-th-open ei-col-hide-side" ></ th >
2026-07-19 18:47:12 +00:00
</ tr ></ thead >
2026-06-23 10:04:23 +00:00
< tbody >
2026-07-30 09:33:03 +00:00
< template x-for = "e in displayEntities()" :key = "e.id" >
< tr :data-entity-id = "e.id" :class = "{ 'ei-row-selected': isSelected(e.id), 'ei-row-crm': e.client_id, 'ei-row-active': selected && selected.id === e.id && drawerOpen }" style = "cursor:pointer" title = "Klik voor profiel" >
2026-07-19 18:47:12 +00:00
< td class = "ei-td-check" @ click . stop >
< input type = "checkbox" :checked = "isSelected(e.id)" @ change = "toggleSelect(e.id, $event)" />
</ td >
2026-07-30 09:33:03 +00:00
< td class = "ei-td-name" >
< div class = "ei-name-cell" >
< button type = "button" class = "ei-row-open-btn" x-text = "e.name" :title = "e.name" ></ button >
2026-07-19 18:47:12 +00:00
< span class = "ei-crm-badge" x-show = "e.client_id" > CRM</ span >
2026-07-30 09:33:03 +00:00
</ div >
2026-07-19 18:47:12 +00:00
</ td >
2026-07-30 09:33:03 +00:00
< td class = "ei-td-type" >< span class = "ei-type-pill ei-type-pill-sm" :class = "'ei-type-'+e.entity_type" x-text = "typeLabel(e.entity_type)" ></ span ></ td >
< td class = "ei-td-country" x-text = "territoryName(e.country_iso2) || e.country_iso2" ></ td >
< td class = "ei-td-city" x-text = "e.city ? (e.city + (e.country_iso2 ? ' · ' + e.country_iso2 : '')) : (e.country_iso2 || '—')" ></ td >
< td class = "ei-td-contact ei-contact-cell" x-text = "contactPreview(e)" ></ td >
< td class = "ei-td-conf ei-confidence" x-text = "(e.confidence||0)+'%'" ></ td >
< td class = "ei-td-open" >< span class = "ei-open-chevron" > Profiel →</ span ></ td >
2026-06-23 10:04:23 +00:00
</ tr >
</ template >
</ tbody >
</ table >
</ div >
< div class = "ei-empty" x-show = "!entities.length" >
< p > Nog geen distributeurs in deze selectie.</ p >
< button class = "btn btn-sm btn-pulse" @ click = "syncKind('distributors')" > Sync distributeurs (fase B)</ button >
</ div >
2026-07-30 09:33:03 +00:00
</ div >
</ aside >
2026-06-23 10:04:23 +00:00
</ div >
</ div >
</ div >
</ section >
<!-- Eindklanten -->
< section x-show = "tab==='customers'" x-cloak >
< div class = "ei-tab-panel" >
< div class = "ei-tab-panel-head" >
< div >< h2 > Eindklanten</ h2 >< p > Restaurants · döner · slagers · horeca</ p ></ div >
< button class = "btn btn-sm btn-pulse" @ click = "syncKind('customers')" :disabled = "busy || !country" > ↻ Sync horeca</ button >
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-tab-panel-body ei-workspace-body" >
< div class = "ei-split ei-split-side" >
< div class = "ei-map-wrap" >
< div class = "ei-map-loading" x-show = "tabMapLoading" x-cloak >< span class = "ei-map-spinner" ></ span > Kaart laden…</ div >
< div id = "ei-map-customers" ></ div >
</ div >
< aside class = "ei-side-panel" >
< div class = "ei-side-panel-head" >
< h3 > Eindklanten op kaart</ h3 >
< p > Klik een pin of tabelrij voor het volledige profiel.</ p >
</ div >
< div class = "ei-side-panel-body" >
2026-06-23 10:04:23 +00:00
< div class = "ei-table-wrap" >
2026-07-30 09:33:03 +00:00
< table class = "ei-table ei-table-compact" >
< thead >< tr >
< th class = "ei-th-check" >< input type = "checkbox" @ change = "toggleSelectAllVisible()" title = "Alles" /></ th >
< th class = "ei-th-name" > Naam</ th >< th class = "ei-th-type" > Type</ th >< th class = "ei-th-country" > Land</ th >< th class = "ei-th-city" > Stad</ th >< th class = "ei-th-contact ei-col-hide-side" > Contact</ th >< th class = "ei-th-open ei-col-hide-side" ></ th >
</ tr ></ thead >
2026-06-23 10:04:23 +00:00
< tbody >
2026-07-30 09:33:03 +00:00
< template x-for = "e in displayEntities()" :key = "e.id" >
< tr :data-entity-id = "e.id" :class = "{ 'ei-row-selected': isSelected(e.id), 'ei-row-crm': e.client_id, 'ei-row-active': selected && selected.id === e.id && drawerOpen }" style = "cursor:pointer" title = "Klik voor profiel" >
< td class = "ei-td-check" @ click . stop >
< input type = "checkbox" :checked = "isSelected(e.id)" @ change = "toggleSelect(e.id, $event)" />
</ td >
< td class = "ei-td-name" >
< div class = "ei-name-cell" >
< button type = "button" class = "ei-row-open-btn" x-text = "e.name" :title = "e.name" ></ button >
< span class = "ei-crm-badge" x-show = "e.client_id" > CRM</ span >
</ div >
</ td >
< td class = "ei-td-type" >< span class = "ei-type-pill ei-type-pill-sm" :class = "'ei-type-'+e.entity_type" x-text = "typeLabel(e.entity_type)" ></ span ></ td >
< td class = "ei-td-country" x-text = "territoryName(e.country_iso2) || e.country_iso2" ></ td >
< td class = "ei-td-city" x-text = "e.city ? (e.city + (e.country_iso2 ? ' · ' + e.country_iso2 : '')) : (e.country_iso2 || '—')" ></ td >
< td class = "ei-td-contact ei-contact-cell" x-text = "contactPreview(e)" ></ td >
< td class = "ei-td-open" >< span class = "ei-open-chevron" > Profiel →</ span ></ td >
2026-06-23 10:04:23 +00:00
</ tr >
</ template >
</ tbody >
</ table >
</ div >
< div class = "ei-empty" x-show = "!entities.length" >
< p > Selecteer een land en sync horeca via OSM.</ p >
</ div >
2026-07-30 09:33:03 +00:00
</ div >
</ aside >
2026-06-23 10:04:23 +00:00
</ div >
</ div >
</ div >
</ section >
<!-- Cateraars -->
< section x-show = "tab==='caterers'" x-cloak >
< div class = "ei-tab-panel" >
< div class = "ei-tab-panel-head" >
< div >< h2 > Facilitaire cateraars</ h2 >< p > Albron · Sodexo · Compass · presence per land</ p ></ div >
< button class = "btn btn-sm btn-pulse" @ click = "syncKind('caterers')" :disabled = "busy" > ↻ Sync</ button >
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-tab-panel-body ei-workspace-body" >
< div class = "ei-split ei-split-side" >
< div class = "ei-map-wrap" >
< div class = "ei-map-loading" x-show = "tabMapLoading" x-cloak >< span class = "ei-map-spinner" ></ span > Kaart laden…</ div >
< div id = "ei-map-caterers" ></ div >
</ div >
< aside class = "ei-side-panel" >
< div class = "ei-side-panel-head" >
< h3 > Cateraars op kaart</ h3 >
< p > Klik een pin of tabelrij voor het volledige profiel.</ p >
</ div >
< div class = "ei-side-panel-body" >
< div class = "ei-side-section" >
< h4 > Brand presence</ h4 >
2026-06-23 10:04:23 +00:00
< div class = "ei-table-wrap" >
2026-07-30 09:33:03 +00:00
< table class = "ei-table ei-table-compact ei-table-brand" >
< thead >< tr >< th class = "ei-th-name" > Brand</ th >< th class = "ei-th-country" > Land</ th >< th > Lokale naam</ th >< th > Takken</ th ></ tr ></ thead >
2026-06-23 10:04:23 +00:00
< tbody >
< template x-for = "p in catererPresence" :key = "p.id" >
2026-07-30 09:33:03 +00:00
< tr
:data-entity-id = "p.entity_id || null"
:class = "{ 'ei-row-active': p.entity_id && selected && selected.id === p.entity_id && drawerOpen, 'ei-row-crm': p.client_id }"
:style = "p.entity_id ? 'cursor:pointer' : ''"
:title = "p.entity_id ? 'Klik voor profiel' : ''"
>
< td class = "ei-td-name" >
< div class = "ei-name-cell" >
< button type = "button" class = "ei-row-open-btn" x-show = "p.entity_id" x-text = "p.brand_name" ></ button >
< span x-show = "!p.entity_id" x-text = "p.brand_name" ></ span >
</ div >
</ td >
< td class = "ei-td-country" x-text = "territoryName(p.country_iso2) || p.country_iso2" ></ td >
2026-06-23 10:04:23 +00:00
< td x-text = "p.local_legal_name||'—'" ></ td >
< td x-text = "(p.service_lines||[]).join(', ')" ></ td >
</ tr >
</ template >
</ tbody >
</ table >
</ div >
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-side-section" >
< h4 > Cateraar entities</ h4 >
2026-06-23 10:04:23 +00:00
< div class = "ei-table-wrap" >
2026-07-30 09:33:03 +00:00
< table class = "ei-table ei-table-compact" >
< thead >< tr >
< th class = "ei-th-name" > Naam</ th >< th class = "ei-th-type" > Type</ th >< th class = "ei-th-country" > Land</ th >< th class = "ei-th-city" > Stad</ th >< th class = "ei-th-contact ei-col-hide-side" > Contact</ th >< th class = "ei-th-conf ei-col-hide-side" > Conf.</ th >< th class = "ei-th-open ei-col-hide-side" ></ th >
</ tr ></ thead >
2026-06-23 10:04:23 +00:00
< tbody >
2026-07-30 09:33:03 +00:00
< template x-for = "e in displayEntities()" :key = "e.id" >
< tr :data-entity-id = "e.id" :class = "{ 'ei-row-active': selected && selected.id === e.id && drawerOpen, 'ei-row-crm': e.client_id }" style = "cursor:pointer" title = "Klik voor profiel" >
< td class = "ei-td-name" >
< div class = "ei-name-cell" >
< button type = "button" class = "ei-row-open-btn" x-text = "e.name" :title = "e.name" ></ button >
< span class = "ei-crm-badge" x-show = "e.client_id" > CRM</ span >
</ div >
</ td >
< td class = "ei-td-type" >< span class = "ei-type-pill ei-type-pill-sm" :class = "'ei-type-'+e.entity_type" x-text = "typeLabel(e.entity_type)" ></ span ></ td >
< td class = "ei-td-country" x-text = "territoryName(e.country_iso2) || e.country_iso2" ></ td >
< td class = "ei-td-city" x-text = "e.city ? (e.city + (e.country_iso2 ? ' · ' + e.country_iso2 : '')) : (e.country_iso2 || '—')" ></ td >
< td class = "ei-td-contact ei-contact-cell" x-text = "contactPreview(e)" ></ td >
< td class = "ei-td-conf ei-confidence" x-text = "(e.confidence||0)+'%'" ></ td >
< td class = "ei-td-open" >< span class = "ei-open-chevron" > Profiel →</ span ></ td >
2026-06-23 10:04:23 +00:00
</ tr >
</ template >
</ tbody >
</ table >
</ div >
2026-07-30 09:33:03 +00:00
</ div >
</ aside >
2026-06-23 10:04:23 +00:00
</ div >
</ div >
</ div >
</ section >
<!-- Contacten -->
< section x-show = "tab==='contacts'" x-cloak >
< div class = "ei-tab-panel" >
< div class = "ei-tab-panel-head" >
2026-07-19 18:25:01 +00:00
< div >< h2 > Contactregistry</ h2 >< p > E-mail · telefoon · outreach-ready · direct naar CRM</ p ></ div >
< div class = "ei-tab-panel-actions" >
< button type = "button" class = "btn btn-sm btn-pulse-green" :disabled = "!selectedIds.length || crmPushBusy" @ click = "openCrmModal()" > ➕ Geselecteerde naar CRM</ button >
< a class = "btn btn-sm" :href = "contactsExportUrl()" target = "_blank" > CSV export</ a >
</ div >
2026-06-23 10:04:23 +00:00
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-tab-panel-body ei-workspace-body" >
< div class = "ei-split ei-split-side" >
< div class = "ei-map-wrap" >
< div class = "ei-map-loading" x-show = "tabMapLoading" x-cloak >< span class = "ei-map-spinner" ></ span > Kaart laden…</ div >
< div id = "ei-map-contacts" ></ div >
</ div >
< aside class = "ei-side-panel" >
< div class = "ei-side-panel-head" >
< h3 > Contacten op kaart</ h3 >
< p > Klik een pin of tabelrij voor het volledige profiel.</ p >
</ div >
< div class = "ei-side-panel-body" >
2026-06-23 10:04:23 +00:00
< div class = "ei-table-wrap" >
2026-07-30 09:33:03 +00:00
< table class = "ei-table ei-table-compact ei-table-contacts" >
2026-07-19 18:25:01 +00:00
< thead >
< tr >
< th class = "ei-th-check" >< input type = "checkbox" @ change = "toggleSelectAllVisible()" title = "Alles selecteren" /></ th >
2026-07-30 09:33:03 +00:00
< th class = "ei-th-name" > Organisatie</ th >
< th class = "ei-th-city" > Stad</ th >
< th class = "ei-th-type" > Type</ th >
< th class = "ei-th-country" > Land</ th >
< th class = "ei-col-hide-side" > Rol</ th >
< th class = "ei-col-hide-side ei-th-name" > Naam</ th >
< th class = "ei-col-hide-side" > E-mail</ th >
< th class = "ei-col-hide-side" > Telefoon</ th >
< th class = "ei-col-hide-side" > CRM</ th >
< th class = "ei-th-open ei-col-hide-side" ></ th >
2026-07-19 18:25:01 +00:00
< th ></ th >
</ tr >
</ thead >
2026-06-23 10:04:23 +00:00
< tbody >
< template x-for = "c in contacts" :key = "c.id" >
2026-07-30 09:33:03 +00:00
< tr :data-entity-id = "c.entity_id" :class = "{ 'ei-row-selected': isSelected(c.entity_id), 'ei-row-crm': c.client_id, 'ei-row-active': selected && selected.id === c.entity_id && drawerOpen }" style = "cursor:pointer" title = "Klik voor profiel" >
2026-07-19 18:25:01 +00:00
< td class = "ei-td-check" @ click . stop >
< input type = "checkbox" :checked = "isSelected(c.entity_id)" @ change = "toggleSelect(c.entity_id, $event)" />
</ td >
2026-07-30 09:33:03 +00:00
< td class = "ei-td-name" >
< div class = "ei-name-cell" >
< button type = "button" class = "ei-row-open-btn" x-text = "c.entity_name" :title = "c.entity_name" ></ button >
< span class = "ei-crm-badge" x-show = "c.client_id" > CRM</ span >
</ div >
2026-07-19 18:25:01 +00:00
</ td >
2026-07-30 09:33:03 +00:00
< td class = "ei-td-city" x-text = "c.entity_city ? (c.entity_city + (c.country_iso2 ? ' · ' + c.country_iso2 : '')) : (c.country_iso2 || '—')" ></ td >
< td class = "ei-td-type" >< span class = "ei-type-pill ei-type-pill-sm" :class = "'ei-type-'+c.entity_type" x-text = "typeLabel(c.entity_type)" ></ span ></ td >
< td class = "ei-td-country" x-text = "territoryName(c.country_iso2) || c.country_iso2" ></ td >
< td class = "ei-col-hide-side" x-text = "c.role || '—'" ></ td >
< td class = "ei-col-hide-side" x-text = "c.name||'—'" ></ td >
< td class = "ei-col-hide-side" x-text = "c.email||'—'" ></ td >
< td class = "ei-col-hide-side" x-text = "c.phone||c.mobile||'—'" ></ td >
< td class = "ei-col-hide-side" >
2026-07-19 18:25:01 +00:00
< span class = "ei-crm-badge" x-show = "c.client_id" :title = "c.crm_client_name || 'In CRM'" > CRM</ span >
< span class = "muted" x-show = "!c.client_id" > —</ span >
</ td >
2026-07-30 09:33:03 +00:00
< td class = "ei-td-open" >< span class = "ei-open-chevron" > Profiel →</ span ></ td >
2026-07-19 18:25:01 +00:00
< td class = "ei-td-actions" @ click . stop >
< button type = "button" class = "btn btn-sm btn-pulse-green" x-show = "!c.client_id" @ click = "pushEntityToCrm(c.entity_id)" :disabled = "crmPushBusy" > ➕ CRM</ button >
< a class = "btn btn-sm" x-show = "c.client_id" :href = "'/clients'" title = "Bekijk in CRM" > Open</ a >
</ td >
2026-06-23 10:04:23 +00:00
</ tr >
</ template >
</ tbody >
</ table >
</ div >
2026-07-19 18:25:01 +00:00
< div class = "ei-load-more" x-show = "contactsHasMore" >
< button type = "button" class = "btn btn-sm" @ click = "loadMoreContacts()" :disabled = "contactsLoadingMore || busy" >
< span x-text = "contactsLoadingMore ? 'Laden…' : ('Meer laden (' + contacts.length + ' / ' + resultCount + ')')" ></ span >
</ button >
</ div >
< div class = "ei-empty" x-show = "!contacts.length && !busy" >
< p > Geen contacten voor deze filters — pas land, type of zoekterm aan.</ p >
2026-06-23 10:04:23 +00:00
< button class = "btn btn-sm btn-pulse-green" @ click = "syncKind('contacts')" > Sync contacten</ button >
</ div >
2026-07-30 09:33:03 +00:00
</ div >
</ aside >
2026-06-23 10:04:23 +00:00
</ div >
</ div >
</ div >
</ section >
<!-- Tenders -->
< section x-show = "tab==='tenders'" x-cloak >
< div class = "ei-tab-panel" >
< div class = "ei-tab-panel-head" >
< div >< h2 > Tenders</ h2 >< p > TED API · food · catering · meat</ p ></ div >
< button class = "btn btn-sm btn-pulse-purple" @ click = "syncKind('tenders')" :disabled = "busy" > ↻ TED sync</ button >
</ div >
2026-07-30 09:33:03 +00:00
2026-06-23 10:04:23 +00:00
< div class = "ei-tab-panel-body" >
< div class = "ei-panel" style = "border:none;background:transparent;padding:0" >
< div class = "ei-table-wrap" >
2026-07-30 09:33:03 +00:00
< table class = "ei-table ei-table-compact" >
< thead >< tr >< th > Titel</ th >< th class = "ei-th-country" > Land</ th >< th > Status</ th >< th > Link</ th ></ tr ></ thead >
2026-06-23 10:04:23 +00:00
< tbody >
< template x-for = "t in tenders" :key = "t.id" >
< tr >
< td x-text = "t.title" ></ td >
2026-07-30 09:33:03 +00:00
< td x-text = "territoryName(t.country_iso2) || t.country_iso2||'—'" ></ td >
2026-06-23 10:04:23 +00:00
< td x-text = "t.status" ></ td >
< td >< a :href = "t.url" target = "_blank" rel = "noopener" > Open</ a ></ td >
</ tr >
</ template >
</ tbody >
</ table >
</ div >
< div class = "ei-empty" x-show = "!tenders.length" >
< p > Geen tenders — klik TED sync.</ p >
</ div >
</ div >
</ div >
</ div >
</ section >
<!-- Overheid -->
< section x-show = "tab==='gov'" x-cloak >
< div class = "ei-tab-panel" >
< div class = "ei-tab-panel-head" >
< div >< h2 > Overheid & data</ h2 >< p > Statistiek · tender portals per land</ p ></ div >
</ div >
2026-07-30 09:33:03 +00:00
2026-06-23 10:04:23 +00:00
< div class = "ei-tab-panel-body" >
< div class = "ei-panel" style = "border:none;background:transparent;padding:0" >
< div class = "ei-table-wrap" >
2026-07-30 09:33:03 +00:00
< table class = "ei-table ei-table-compact" >
< thead >< tr >< th class = "ei-th-country" > Land</ th >< th class = "ei-th-name" > Naam</ th >< th > Categorie</ th >< th > Link</ th ></ tr ></ thead >
2026-06-23 10:04:23 +00:00
< tbody >
< template x-for = "g in govSources" :key = "g.id" >
< tr >
2026-07-30 09:33:03 +00:00
< td x-text = "territoryName(g.country_iso2) || g.country_iso2" ></ td >
2026-06-23 10:04:23 +00:00
< td x-text = "g.name" ></ td >
< td x-text = "g.category" ></ td >
< td >< a :href = "g.url" target = "_blank" rel = "noopener" > Open</ a ></ td >
</ tr >
</ template >
</ tbody >
</ table >
</ div >
</ div >
</ div >
</ div >
</ section >
<!-- Pipeline -->
< section x-show = "tab==='pipeline'" x-cloak >
< div class = "ei-tab-panel" >
< div class = "ei-tab-panel-head" >
< div >< h2 > CRM Pipeline</ h2 >< p > Van Wereldexport naar klanten & deals</ p ></ div >
< div class = "retail-actions" >
< button type = "button" class = "btn btn-sm btn-pulse-green" :disabled = "!selectedIds.length" @ click = "openCrmModal()" > ➕ Geselecteerde naar CRM</ button >
< a class = "btn btn-sm btn-pulse" href = "/clients" > Klanten</ a >
< a class = "btn btn-sm btn-pulse" href = "/deals" > Deals</ a >
</ div >
</ div >
2026-07-30 09:33:03 +00:00
< div class = "ei-tab-panel-body ei-workspace-body" >
< div class = "ei-split ei-split-side" >
< div class = "ei-map-wrap" >
< div class = "ei-map-loading" x-show = "tabMapLoading" x-cloak >< span class = "ei-map-spinner" ></ span > Kaart laden…</ div >
< div id = "ei-map-pipeline" ></ div >
</ div >
< aside class = "ei-side-panel" >
< div class = "ei-side-panel-head" >
< h3 > CRM pipeline op kaart</ h3 >
< p > Klik een pin of tabelrij voor het volledige profiel.</ p >
</ div >
< div class = "ei-side-panel-body" >
< p class = "ei-side-hint ei-pipeline-hint" > Entities via < strong > Naar CRM</ strong > — koppeling naar klant + deal.</ p >
2026-06-23 10:04:23 +00:00
< div class = "ei-table-wrap" x-show = "crmPipeline.length" >
2026-07-30 09:33:03 +00:00
< table class = "ei-table ei-table-compact ei-table-pipeline" >
2026-06-23 10:04:23 +00:00
< thead >
< tr >
2026-07-30 09:33:03 +00:00
< th class = "ei-th-name" > Organisatie</ th >
< th class = "ei-th-type" > Type</ th >
< th class = "ei-th-country" > Land</ th >
< th class = "ei-th-pipe-meta" > CRM klant</ th >
< th class = "ei-th-pipe-meta" > Deal</ th >
< th class = "ei-th-pipe-meta" > Datum</ th >
< th class = "ei-th-open ei-col-hide-side" ></ th >
2026-06-23 10:04:23 +00:00
</ tr >
</ thead >
< tbody >
2026-07-30 09:33:03 +00:00
< template x-for = "p in displayPipeline()" :key = "p.id" >
< tr :data-entity-id = "p.id" :class = "{ 'ei-row-active': selected && selected.id === p.id && drawerOpen, 'ei-row-crm': p.client_id }" style = "cursor:pointer" title = "Klik voor profiel" >
< td class = "ei-td-name" >
< div class = "ei-name-cell" >
< button type = "button" class = "ei-row-open-btn" x-text = "p.name" :title = "p.name" ></ button >
< span class = "ei-crm-badge" x-show = "p.client_id" > CRM</ span >
</ div >
</ td >
< td class = "ei-td-type" >< span class = "ei-type-pill ei-type-pill-sm" :class = "'ei-type-'+p.entity_type" x-text = "typeLabel(p.entity_type)" ></ span ></ td >
< td class = "ei-td-country" x-text = "territoryName(p.country_iso2) || p.country_iso2" ></ td >
< td class = "ei-td-pipe-meta" >
2026-06-23 10:04:23 +00:00
< a x-show = "p.client_id" :href = "'/clients'" @ click . stop x-text = "p.crm_client_name || ('#'+p.client_id)" ></ a >
</ td >
2026-07-30 09:33:03 +00:00
< td class = "ei-td-pipe-meta" x-text = "p.crm_deal_title || '—'" ></ td >
< td class = "ei-td-pipe-meta" x-text = "p.crm_pushed_at ? new Date(p.crm_pushed_at).toLocaleDateString('nl-NL') : '—'" ></ td >
< td class = "ei-td-open" >< span class = "ei-open-chevron" > Profiel →</ span ></ td >
2026-06-23 10:04:23 +00:00
</ tr >
</ template >
</ tbody >
</ table >
</ div >
< div class = "ei-empty" x-show = "!crmPipeline.length" >
< p > Nog geen entities in CRM vanuit Wereldexport.</ p >
< p > Selecteer leads op de kaart en klik < strong > ➕ Naar CRM</ strong > .</ p >
2026-07-30 09:33:03 +00:00
</ div >
</ aside >
</ div >
2026-06-23 10:04:23 +00:00
</ div >
</ div >
</ section >
</ div >
</ div >
2026-07-30 09:33:03 +00:00
<!-- Profiel popup (modal) — content rendered by ExportIntelProfile JS -->
< div id = "ei-profile-modal" class = "ei-profile-modal-root" aria-hidden = "true" >
< div class = "ei-profile-backdrop" data-ei-action = "close" ></ div >
< div class = "ei-profile-panel" role = "dialog" aria-modal = "true" aria-labelledby = "ei-profile-title" >
< div id = "ei-profile-mount" ></ div >
</ div >
2026-06-23 10:04:23 +00:00
</ div >
<!-- CRM bevestiging -->
< div class = "ei-modal-root" x-show = "crmModalOpen" x-cloak >
< div class = "ei-drawer-backdrop" @ click = "crmModalOpen=false" ></ div >
< div class = "ei-modal-card" >
< h3 > Toevoegen aan CRM</ h3 >
< p >< strong x-text = "selectedIds.length" ></ strong > organisatie(s) worden klant in CRM.</ p >
< label class = "ei-filter-check" >
< input type = "checkbox" x-model = "crmCreateDeals" />
< span > Maak ook een deal per klant (aanbevolen)</ span >
</ label >
< p class = "ei-modal-note" > Bestaande klanten met hetzelfde e-mailadres worden gekoppeld i.p.v. dubbel aangemaakt.</ p >
< div class = "ei-modal-actions" >
< button type = "button" class = "btn btn-sm" @ click = "crmModalOpen=false" > Annuleren</ button >
< button type = "button" class = "btn btn-sm btn-pulse-green" @ click = "pushToCrm()" :disabled = "crmPushBusy" >
< span x-text = "crmPushBusy ? 'Bezig…' : 'Bevestig → CRM'" ></ span >
</ button >
</ div >
</ div >
</ div >
</ div >
{% endblock %}
2026-07-30 09:33:03 +00:00
{% block scripts %}{% endblock %}