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