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