1<?php use Fisharebest\Webtrees\Auth; ?> 2<?php use Fisharebest\Webtrees\Functions\FunctionsPrint; ?> 3<?php use Fisharebest\Webtrees\I18N; ?> 4<?php use Fisharebest\Webtrees\View; ?> 5 6<?php if ($individual->isPendingDeletion()) : ?> 7 <?php if (Auth::isModerator($individual->tree())) : ?> 8 <?= view('components/alert-warning-dismissible', [ 9 'alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ 10 I18N::translate('This individual has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . e($individual->xref()) . '\', \'' . e($individual->tree()->name()) . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . e($individual->xref()) . '\', \'' . e($individual->tree()->name()) . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes'), 11 ]) ?> 12 <?php elseif (Auth::isEditor($individual->tree())) : ?> 13 <?= view('components/alert-warning-dismissible', ['alert' => I18N::translate('This individual has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?> 14 <?php endif ?> 15<?php elseif ($individual->isPendingAddition()) : ?> 16 <?php if (Auth::isModerator($individual->tree())) : ?> 17 <?= view('components/alert-warning-dismissible', [ 18 'alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ 19 I18N::translate('This individual has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . e($individual->xref()) . '\', \'' . e($individual->tree()->name()) . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . e($individual->xref()) . '\', \'' . e($individual->tree()->name()) . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes'), 20 ]) ?> 21 <?php elseif (Auth::isEditor($individual->tree())) : ?> 22 <?= view('components/alert-warning-dismissible', ['alert' => I18N::translate('This individual has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?> 23 <?php endif ?> 24<?php endif ?> 25 26<div class="d-flex mb-4"> 27 <h2 class="wt-page-title mx-auto"> 28 <?= $individual->getFullName() ?><?= $user_link ?>, <?= $individual->getLifeSpan() ?> <?= $age ?> 29 </h2> 30 <?php if ($individual->canEdit() && !$individual->isPendingDeletion()) : ?> 31 <?= view('individual-page-menu', ['individual' => $individual, 'count_names' => $count_names, 'count_sex' => $count_sex]) ?> 32 <?php endif ?> 33</div> 34 35<div class="row"> 36 <div class="col-sm"> 37 <div class="row mb-4"> 38 <!-- Individual images --> 39 <div class="col-sm-3"> 40 <?php if (empty($individual_media)) : ?> 41 <i class="wt-individual-silhouette wt-individual-silhouette-<?= strtolower($individual->getSex()) ?>"></i> 42 <?php elseif (count($individual_media) === 1) : ?> 43 <?= $individual_media[0]->displayImage(200, 260, 'crop', ['class' => 'img-thumbnail img-fluid w-100']) ?> 44 <?php else : ?> 45 <div id="individual-images" class="carousel slide" data-ride="carousel" data-interval="false"> 46 <div class="carousel-inner"> 47 <?php foreach ($individual_media as $n => $media_file) : ?> 48 <div class="carousel-item <?= $n === 0 ? 'active' : '' ?>"> 49 <?= $media_file->displayImage(200, 260, 'crop', ['class' => 'img-thumbnail img-fluid w-100']) ?> 50 </div> 51 <?php endforeach ?> 52 </div> 53 <a class="carousel-control-prev" href="#individual-images" role="button" data-slide="prev"> 54 <span class="carousel-control-prev-icon" aria-hidden="true"></span> 55 <span class="sr-only"><?= I18N::translate('previous') ?></span> 56 </a> 57 <a class="carousel-control-next" href="#individual-images" role="button" data-slide="next"> 58 <span class="carousel-control-next-icon" aria-hidden="true"></span> 59 <span class="sr-only"><?= I18N::translate('next') ?></span> 60 </a> 61 </div> 62 63 <?php endif ?> 64 65 <?php if (Auth::isEditor($individual->tree())) : ?> 66 <?php if (count($individual->facts(['OBJE'])) > 1) : ?> 67 <div> 68 <a href="<?= e(route('reorder-media', ['ged' => $individual->tree()->name(), 'xref' => $individual->xref()])) ?>"> 69 <?= view('icons/reorder') ?> 70 <?= I18N::translate('Re-order media') ?> 71 </a> 72 </div> 73 <?php endif ?> 74 75 <?php if ($individual->tree()->getPreference('MEDIA_UPLOAD') >= Auth::accessLevel($individual->tree())) : ?> 76 <div> 77 <a href="<?= e(route('add-fact', ['ged' => $individual->tree()->name(), 'xref' => $individual->xref(), 'fact' => 'OBJE'])) ?>"> 78 <?= I18N::translate('Add a media object') ?> 79 </a> 80 </div> 81 <?php endif ?> 82 <?php endif ?> 83 </div> 84 85 <!-- Name accordion --> 86 <div class="col-sm-9" id="individual-names" role="tablist"> 87 <?php foreach ($name_records as $name_record) : ?> 88 <?= $name_record ?> 89 <?php endforeach ?> 90 91 <?php foreach ($sex_records as $sex_record) : ?> 92 <?= $sex_record ?> 93 <?php endforeach ?> 94 </div> 95 </div> 96 97 <div id="individual-tabs"> 98 <ul class="nav nav-tabs flex-wrap"> 99 <?php foreach ($tabs as $tab) : ?> 100 <li class="nav-item"> 101 <a class="nav-link<?= $tab->isGrayedOut($individual) ? ' text-muted' : '' ?>" data-toggle="tab" role="tab" data-href="<?= e(route('individual-tab', ['xref' => $individual->xref(), 'ged' => $individual->tree()->name(), 'module' => $tab->name()])) ?>" href="#<?= $tab->name() ?>"> 102 <?= $tab->tabTitle() ?> 103 </a> 104 </li> 105 <?php endforeach ?> 106 </ul> 107 <div class="tab-content"> 108 <?php foreach ($tabs as $tab) : ?> 109 <div id="<?= $tab->name() ?>" class="tab-pane fade wt-ajax-load" role="tabpanel"><?php if (!$tab->canLoadAjax()) : 110 ?><?= $tab->getTabContent($individual) ?><?php 111 endif ?></div> 112 <?php endforeach ?> 113 </div> 114 </div> 115 </div> 116 <?php if ($sidebars->isNotEmpty()) : ?> 117 <div class="col-sm-4" id="sidebar" role="tablist"> 118 <?php foreach ($sidebars as $sidebar) : ?> 119 <div class="card"> 120 <div class="card-header" role="tab" id="sidebar-header-<?= $sidebar->name() ?>"> 121 <div class="card-title mb-0"> 122 <a data-toggle="collapse" data-parent="#sidebar" href="#sidebar-content-<?= $sidebar->name() ?>" aria-expanded="<?= $sidebar->name() === 'family_nav' ? 'true' : 'false' ?>" aria-controls="sidebar-content-<?= $sidebar->name() ?>"> 123 <?= $sidebar->sidebarTitle() ?> 124 </a> 125 </div> 126 </div> 127 <div id="sidebar-content-<?= $sidebar->name() ?>" class="collapse<?= $sidebar->name() === 'family_nav' ? ' show' : '' ?>" role="tabpanel" aria-labelledby="sidebar-header-<?= $sidebar->name() ?>"> 128 <div class="card-body"> 129 <?= $sidebar->getSidebarContent($individual) ?></div> 130 </div> 131 </div> 132 <?php endforeach ?> 133 </div> 134 <?php endif ?> 135</div> 136 137<?php View::push('javascript') ?> 138<script> 139 "use strict"; 140 141 // Bootstrap tabs - load content dynamically using AJAX 142 $('a[data-toggle="tab"][data-href]').on('show.bs.tab', function () { 143 $(this.getAttribute('href') + ':empty').load($(this).data('href')); 144 }); 145 146 // If the URL contains a fragment, then activate the corresponding tab. 147 // Use a prefix on the fragment, to prevent scrolling to the element. 148 var target = window.location.hash.replace("tab-", ""); 149 var tab = $("#individual-tabs .nav-link[href='" + target + "']"); 150 // If not, then activate the first tab. 151 if (tab.length === 0) { 152 tab = $("#individual-tabs .nav-link:first"); 153 } 154 tab.tab("show"); 155 156 // If the user selects a tab, update the URL to reflect this 157 $('#individual-tabs a[data-toggle="tab"]').on('shown.bs.tab', function (e) { 158 window.location.hash = "tab-" + e.target.href.substring(e.target.href.indexOf('#') + 1); 159 }); 160</script> 161<?php View::endpush() ?> 162 163<?= view('modals/ajax') ?> 164