Files
itflow/agent/includes/client_details.php
johnnyq 234afd25fb Contacts overhaul: rebuilt contacts list with role tabs and counts, avatars, flag pills, hover copy on phone/mobile/email, inline location picker, linked asset/credential/license/ticket chips and tag filter; contact page rebuilt to match the asset page with header actions, Reach/Details/Quick notes cards and tabbed Assets, Credentials, Tickets, Recurring, Licenses, Documents, Files, Services and Notes; add and edit contact share one tabbed form (Details, Roles, Access, Notes) with field icons, role switches, password generator, duplicate email check and photo removal; contact quick look redone to match the asset quick look; contact avatars now used everywhere a contact appears - contact pickers, ticket header, contact card, client replies, ticket list, kanban, assets, clients list, client header, overview key contacts, credentials, documents, services, invoice/quote/statement recipients, license users and global search - with each contact keeping the same colour throughout; ticket contact pickers show the name with title and role underneath; fixes: permission checks on the add contact modal and contact page/list actions, contact location limited to the contact's own client on add/edit/bulk assign, contacts list no longer selects user account columns, archived assets and credentials left off the contact page and quick look, saving a contact with the client portal disabled no longer clears their portal login method, replacing a photo no longer tries to delete a directory, sort column whitelisted, list counts and tags batched instead of per row, recurring ticket menu markup, undefined index notices, contacts list no longer scrolls sideways on phones, Edit Service shows avatars on unselected contacts and assets, license user labels toggle their checkbox; new functions/contact.php helpers (contactAvatar, contactLink, contactFlagPills, contactPhoneLink, contactAvatarData, contactOptionDescription), shared contact_form.php, contact_location quick pick, removed unused assetContactAvatar and clientOverviewPersonInitials
2026-10-14 18:33:18 -04:00

77 lines
5.2 KiB
PHP

<?php
/*
* The primary contact, primary location and details columns under the
* client's name. Shared by the client overview's header and the client header
* on every other client page (inc_client_top_head.php), so both show the same.
* Expects the client variables from inc_all_client.php; the caller supplies
* the surrounding .row.
*/
$client_details_edit = lookupUserPermission('module_client') >= 2;
$client_since = $client_created_at ? date('M Y', strtotime($client_created_at)) : '';
$client_website_url = $client_website ? (preg_match('#^https?://#i', $client_website) ? $client_website : "https://$client_website") : '';
$client_website_label = preg_replace('#^https?://#i', '', rtrim($client_website, '/'));
$location_map_query = rawurlencode(html_entity_decode(trim("$location_address $location_city $location_state $location_zip"), ENT_QUOTES));
?>
<div class="col-md-4">
<div class="itflow-ov-label">Primary contact</div>
<?php if ($contact_id) { ?>
<?= contactLink($client_id, $contact_id, $contact_name, $contact_photo, ['class' => 'fw-semibold']) ?>
<?php if ($contact_title) { ?><span class="text-body-secondary small ms-1"><?= $contact_title ?></span><?php } ?>
<div class="small mt-1 d-flex flex-column gap-1">
<?php if ($contact_phone) { ?>
<a class="text-reset text-decoration-none" href="tel:<?= escapeHtml(preg_replace('/[^0-9+]/', '', html_entity_decode($contact_phone))) ?>"><i class="fas fa-fw fa-phone text-body-secondary me-2" aria-hidden="true"></i><?= $contact_phone ?><?= $contact_extension ? " x$contact_extension" : '' ?></a>
<?php } ?>
<?php if ($contact_mobile) { ?>
<a class="text-reset text-decoration-none" href="tel:<?= escapeHtml(preg_replace('/[^0-9+]/', '', html_entity_decode($contact_mobile))) ?>"><i class="fas fa-fw fa-mobile-alt text-body-secondary me-2" aria-hidden="true"></i><?= $contact_mobile ?></a>
<?php } ?>
<?php if ($contact_email) { ?>
<span class="d-flex align-items-center">
<a class="text-reset text-decoration-none text-truncate" href="mailto:<?= $contact_email ?>"><i class="far fa-fw fa-envelope text-body-secondary me-2" aria-hidden="true"></i><?= $contact_email ?></a>
<button type="button" class="itflow-copy clipboardjs" title="Copy email" data-clipboard-text="<?= $contact_email ?>"><i class="far fa-copy"></i></button>
</span>
<?php } ?>
</div>
<?php } elseif ($client_details_edit) { ?>
<a class="ajax-modal small" href="#" data-modal-size="lg" data-modal-url="modals/contact/contact_add.php?client_id=<?= $client_id ?>&primary=1"><i class="fas fa-fw fa-plus me-1"></i>Add primary contact</a>
<?php } else { ?>
<span class="text-body-tertiary">None</span>
<?php } ?>
</div>
<div class="col-md-4">
<div class="itflow-ov-label">Primary location</div>
<?php if ($location_id) { ?>
<?php if ($location_address || $location_city) { ?>
<a class="text-reset text-decoration-none" href="//maps.<?= $session_map_source ?>.com/?q=<?= $location_map_query ?>" target="_blank" rel="noopener" title="Open in maps">
<?php if ($location_address) { ?><div><?= $location_address ?></div><?php } ?>
<div class="<?= $location_address ? 'small text-body-secondary' : '' ?>"><?= formatAddress('', $location_city, $location_state, $location_zip, $location_country, ', ') ?></div>
</a>
<?php } else { ?>
<div><?= $location_name ?></div>
<?php } ?>
<?php if ($location_phone) { ?>
<a class="small text-reset text-decoration-none d-block mt-1" href="tel:<?= escapeHtml(preg_replace('/[^0-9+]/', '', html_entity_decode($location_phone))) ?>"><i class="fas fa-fw fa-phone text-body-secondary me-2" aria-hidden="true"></i><?= $location_phone ?></a>
<?php } ?>
<?php } elseif ($client_details_edit) { ?>
<a class="ajax-modal small" href="#" data-modal-url="modals/location/location_add.php?client_id=<?= $client_id ?>&primary=1"><i class="fas fa-fw fa-plus me-1"></i>Add primary location</a>
<?php } else { ?>
<span class="text-body-tertiary">None</span>
<?php } ?>
</div>
<div class="col-md-4">
<div class="itflow-ov-label">Details</div>
<div class="small d-flex flex-column gap-1">
<?php if ($client_website) { ?>
<a class="text-truncate" href="<?= $client_website_url ?>" target="_blank" rel="noopener"><i class="fas fa-fw fa-globe text-body-secondary me-2" aria-hidden="true"></i><?= $client_website_label ?></a>
<?php } ?>
<?php if ($client_since) { ?>
<span><i class="far fa-fw fa-calendar text-body-secondary me-2" aria-hidden="true"></i><?= $client_is_lead ? 'Lead' : 'Client' ?> since <?= $client_since ?></span>
<?php } ?>
<?php if ($client_referral) { ?>
<span><i class="fas fa-fw fa-handshake text-body-secondary me-2" aria-hidden="true"></i>Referred by <?= $client_referral ?></span>
<?php } ?>
<span class="text-body-secondary"><i class="fas fa-fw fa-hashtag me-2" aria-hidden="true"></i>Client ID <?= $client_id ?></span>
</div>
</div>