templates/business_contacts/index.html.twig line 1
{# templates/business_contacts/index.html.twig #}{% extends 'base.html.twig' %}{% block title %}Business Contacts{% endblock %}{% block body %}<div class="row">{% include 'business_contacts/parts/business_type_selection_buttons.html.twig' %}</div><br>{% include 'business_contacts/parts/import_and_export.html.twig' %}<div class="table-responsive"><table class="table custom-table fixed-cols"><thead><tr><th class="desktop">Photo</th><th style="width: 150px; text-align: left">Company</th>{% if list_or_map == 'map' %}<th></th>{% endif %}<th style="width: 70px; text-align: left"><i class="fa fa-user"></i></th><th title="Website" style="width: 10px; text-align: center"><i class="fa fa-link"></i></th><th title="Email" style="width: 10px; text-align: center"><i class="fa fa-envelope"></i></th><th title="Mobile" style="width: 10px; text-align: center; border-left: 1px dotted;"><i class="fab fa-whatsapp"></i></th>{# Mobile analyser header columns (keep as-is) #}{% for type in ['mobile'] %}{% include 'business_contacts/parts/5 telephone_numbers_analyser_header.html.twig' %}{% endfor %}<th title="Phone" style="width: 10px; text-align: center"><i class="fa fa-phone"></i></th>{# Landline analyser header columns (keep as-is) #}{% for type in ['landline'] %}{% include 'business_contacts/parts/5 telephone_numbers_analyser_header.html.twig' %}{% endfor %}<th title="Address" style="border-left: 1px dotted; width: 400px; text-align: left"><i class="fa fa-building"></i></th><th class="desktop" title="Notes" style="width: 100px; text-align: left"><i class="fa fa-pen"></i></th><th class="desktop" style="width: 10px; text-align: center" title="Business card"><i class="fa fa-address-card"></i></th><th class="desktop" title="Files" style="width: 10px; text-align: center"><i class="fa fa-file-pdf"></i></th><th><i style="color: darkblue" class="fab fa-waze"></i></th>{% include 'business_contacts/parts/7 access_count_headers.html.twig' %}</tr></thead><tbody>{# One pass over business types; render a group header row, then that group's contacts #}{% for business_type in business_types %}{% set business_contacts_count = CountBusinessContactsService.count(business_type) %}{% set business_contacts_count_with_map_locations = CountBusinessContactsService.countWithMapLocations(business_type) %}{% if business_type.mapicon is not null %}{% set file = asset('administration/ATSSharedFiles/BusinessContactsMapIcons/' ~ business_type.mapIcon.iconFile) %}{% endif %}{% if business_contacts_count > 0 %}{# Group header row for this business type #}<tr class="group-header" data-type="{{ business_type.businessType }}"><td colspan="100"><h2 style="color: red; margin: 0;">{% if business_contacts_count_with_map_locations > 0 %}<a class="btn btn-danger btn-sm"href="{{ path('business_contacts_map', {subset: business_type.businessType}) }}"><i class="fa fa-map-marker"></i></a>{% endif %}{% if business_type.mapIcon is not empty %}<img height="40" width="40" src="{{ file }}" alt="">{% endif %}{% if is_granted('ROLE_ADMIN') %}<a target="_blank" href="{{ path('business_types_edit', {id: business_type.id}) }}">{{ business_type.businessType }}</a>{% else %}{{ business_type.businessType }}{% endif %}{% if app.user %}<a href="{{ path('business_contacts_new', {business_type: business_type.id}) }}">+</a>{% endif %}</h2></td></tr>{# Rows for contacts in this group — use the grouped array, not business_contacts #}{% set contacts = contacts_by_type[business_type.id] ?? [] %}{% for business_contact in contacts %}<tr class="contact-row" data-type="{{ business_type.businessType }}">{% include 'business_contacts/parts/1 photo.html.twig' %}{% include 'business_contacts/parts/2 company_and_user_body.html.twig' %}{% include 'business_contacts/parts/4 website_email_tels_body.html.twig' %}{% include 'business_contacts/parts/3 map marker_body.html.twig' %}{% include 'business_contacts/parts/6 notes_buttons_files_body.html.twig' %}{# Waze column construction #}{% set hasCoords = business_contact.locationLatitude is not null and business_contact.locationLongitude is not null %}{% set lat = hasCoords ? (business_contact.locationLatitude|number_format(6, '.', '')) : null %}{% set lng = hasCoords ? (business_contact.locationLongitude|number_format(6, '.', '')) : null %}{% set fullAddress = '35 Lillian Road, Barnes, SW13 9LH, UK' %}{% set wazeUrl = hasCoords? ('https://waze.com/ul?ll=' ~ lat ~ ',' ~ lng ~ '&navigate=yes'): ('https://waze.com/ul?q=' ~ (fullAddress|url_encode) ~ '&navigate=yes') %}<td><a href="{{ wazeUrl }}" target="_blank" rel="noopener"><i class="fab fa-waze"></i></a></td>{% include 'business_contacts/parts/7 access_count_body.html.twig' %}</tr>{% endfor %}{% endif %}{% endfor %}</tbody></table></div>{% endblock %}{% block datatable %}<style>/* Keep columns aligned and content tidy */.fixed-cols { table-layout: fixed; width: 100%; }.fixed-cols th, .fixed-cols td {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;vertical-align: middle;}.group-header td {background: #f7f7f7;font-weight: bold;border-top: 2px solid #ddd;border-bottom: 2px solid #eee;}.fixed-cols img { max-width: 100%; height: auto; }</style><script>$(document).ready(function () {$('.table').DataTable({autoWidth: false,paging: false,searching: false,bInfo: false,ordering: false // important: keep group headers in place});});</script>{% endblock datatable %}{% block additionaljs %}<script>(function () {function applyFilter(type) {const rows = document.querySelectorAll('tr.contact-row');const headers = document.querySelectorAll('tr.group-header');const wanted = (type || '').toString().trim();rows.forEach(tr => {const t = tr.getAttribute('data-type') || '';tr.style.display = (!wanted || t === wanted) ? '' : 'none';});// Show header if it has at least one visible contact beneath itheaders.forEach(h => {const t = h.getAttribute('data-type') || '';if (!wanted) {h.style.display = ''; // All} else {// Find the next sibling contact rows until next headerlet hasVisible = false;let el = h.nextElementSibling;while (el && !el.classList.contains('group-header')) {if (el.classList.contains('contact-row') && el.style.display !== 'none') {hasVisible = true; break;}el = el.nextElementSibling;}h.style.display = hasVisible ? '' : 'none';}});// Toggle active classes on buttons and dropdown itemsdocument.querySelectorAll('.js-type').forEach(a => {const f = (a.getAttribute('data-filter') || '').trim();if (f === wanted) a.classList.add('active'); else a.classList.remove('active');});// Update dropdown button label on mobileconst ddBtn = document.getElementById('businessTypeDropdown');if (ddBtn) {ddBtn.textContent = wanted ? wanted : `All (${rows.length})`;}// Push state to the URL (no reload)const url = new URL(window.location.href);if (wanted) url.searchParams.set('business_type', wanted);else url.searchParams.delete('business_type');window.history.replaceState({}, '', url);}// Hook up clicksdocument.addEventListener('click', function (e) {const a = e.target.closest('a.js-type');if (!a) return;e.preventDefault();applyFilter(a.getAttribute('data-filter') || '');});// Apply initial filter from query string on load (so reload/links keep state)document.addEventListener('DOMContentLoaded', function () {const url = new URL(window.location.href);applyFilter(url.searchParams.get('business_type') || '');});})();</script><script>var businessContactId = '';function getLocation(id) {businessContactId = id;if (navigator.geolocation) {navigator.geolocation.getCurrentPosition(showLocation);} else {$('#location').html('Geolocation is not supported by this browser.');}}function showLocation(position) {var latitude = position.coords.latitude;var longitude = position.coords.longitude;$.ajax({type: 'POST',url: 'update/location',data: 'latitude=' + latitude + '&longitude=' + longitude + '&id=' + businessContactId,success: function () {location.reload();}});}$('.action').click(function (e) {e.preventDefault();let elem = $(this);let id = $(this).attr('data-id');let action = $(this).attr('data-action');let url = '/referrals/new_from_businesscontacts/' + id + '/' + action;$.ajax({type: 'GET',url: url,success: function () {let goTo = elem.attr('href');window.open(goTo, '_blank');}});});</script>{% endblock %}