xref: /webtrees/resources/views/individual-page.phtml (revision 853f2b8ab920254b02a6cbbe9d6bf1f5c4486e2f)
12c3dad18SGreg Roach<?php
2852ede8cSGreg Roach
32c3dad18SGreg Roachuse Fisharebest\Webtrees\Auth;
4dc270d8cSGreg Roachuse Fisharebest\Webtrees\Fact;
52917771cSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\AddNewFact;
622e73debSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\PendingChangesAcceptRecord;
722e73debSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\PendingChangesRejectRecord;
82c3dad18SGreg Roachuse Fisharebest\Webtrees\I18N;
92c3dad18SGreg Roachuse Fisharebest\Webtrees\Individual;
10dc270d8cSGreg Roachuse Fisharebest\Webtrees\Media;
11dc270d8cSGreg Roachuse Fisharebest\Webtrees\Module\ModuleSidebarInterface;
12dc270d8cSGreg Roachuse Fisharebest\Webtrees\Module\ModuleTabInterface;
13054771e9SGreg Roachuse Fisharebest\Webtrees\Tree;
142c3dad18SGreg Roachuse Fisharebest\Webtrees\View;
152c3dad18SGreg Roachuse Illuminate\Support\Collection;
162c3dad18SGreg Roach
172c3dad18SGreg Roach/**
18054771e9SGreg Roach * @var string                             $age
192c3dad18SGreg Roach * @var Individual                         $individual
202c3dad18SGreg Roach * @var string                             $user_link
21dc270d8cSGreg Roach * @var Collection<ModuleSidebarInterface> $sidebars
22dc270d8cSGreg Roach * @var Collection<Media>                  $individual_media
23dc270d8cSGreg Roach * @var Collection<Fact>                   $name_records
24dc270d8cSGreg Roach * @var Collection<Fact>                   $sex_records
25*853f2b8aSGreg Roach * @var Collection<string>                 $shares
267c2c99faSGreg Roach * @var Collection<ModuleTabInterface>     $tabs
27054771e9SGreg Roach * @var Tree                               $tree
282c3dad18SGreg Roach */
292c3dad18SGreg Roach?>
30dd6b2bfcSGreg Roach
31dd6b2bfcSGreg Roach<?php if ($individual->isPendingDeletion()) : ?>
32f4afa648SGreg Roach    <?php if (Auth::isModerator($individual->tree())) : ?>
33dd6b2bfcSGreg Roach        <?= view('components/alert-warning-dismissible', [
34dd6b2bfcSGreg Roach            'alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */
350973b4d2SGreg Roach                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>') . ' ' . view('help/link', ['topic' => 'pending_changes']),
36dd6b2bfcSGreg Roach        ]) ?>
37f4afa648SGreg Roach    <?php elseif (Auth::isEditor($individual->tree())) : ?>
380973b4d2SGreg Roach        <?= view('components/alert-warning-dismissible', ['alert' => I18N::translate('This individual has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . view('help/link', ['topic' => 'pending_changes'])]) ?>
39dd6b2bfcSGreg Roach    <?php endif ?>
40dd6b2bfcSGreg Roach<?php elseif ($individual->isPendingAddition()) : ?>
41f4afa648SGreg Roach    <?php if (Auth::isModerator($individual->tree())) : ?>
42dd6b2bfcSGreg Roach        <?= view('components/alert-warning-dismissible', [
43dd6b2bfcSGreg Roach            'alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */
440973b4d2SGreg Roach                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>') . ' ' . view('help/link', ['topic' => 'pending_changes']),
45dd6b2bfcSGreg Roach        ]) ?>
46f4afa648SGreg Roach    <?php elseif (Auth::isEditor($individual->tree())) : ?>
470973b4d2SGreg Roach        <?= view('components/alert-warning-dismissible', ['alert' => I18N::translate('This individual has been edited. The changes need to be reviewed by a moderator.') . ' ' . view('help/link', ['topic' => 'pending_changes'])]) ?>
48dd6b2bfcSGreg Roach    <?php endif ?>
49dd6b2bfcSGreg Roach<?php endif ?>
50dd6b2bfcSGreg Roach
51dd6b2bfcSGreg Roach<div class="d-flex mb-4">
52dd6b2bfcSGreg Roach    <h2 class="wt-page-title mx-auto">
535e6816beSGreg Roach        <?= $individual->fullName() ?><?= $user_link ?>, <?= $individual->lifespan() ?> <?= $age ?>
54dd6b2bfcSGreg Roach    </h2>
551450f098SGreg Roach    <?php if ($individual->canEdit()) : ?>
56*853f2b8aSGreg Roach        <?= view('individual-page-menu', ['record' => $individual, 'shares' => $shares]) ?>
57dd6b2bfcSGreg Roach    <?php endif ?>
58dd6b2bfcSGreg Roach</div>
59dd6b2bfcSGreg Roach
60dd6b2bfcSGreg Roach<div class="row">
618d38dd5aSGreg Roach    <div class="<?= $sidebars->isEmpty() ? 'col-sm-12' : 'col-sm-8' ?>">
62dd6b2bfcSGreg Roach        <div class="row mb-4">
63dd6b2bfcSGreg Roach            <!-- Individual images -->
648e64ca84SGreg Roach            <?php if ($individual_media->isNotEmpty() || $tree->getPreference('USE_SILHOUETTE') === '1') : ?>
65dd6b2bfcSGreg Roach                <div class="col-sm-3">
668e64ca84SGreg Roach                    <?php if ($individual_media->isEmpty()) : ?>
678e64ca84SGreg Roach                        <div class="img-thumbnail">
6839ca88baSGreg Roach                            <i class="wt-individual-silhouette wt-individual-silhouette-<?= strtolower($individual->sex()) ?>"></i>
698e64ca84SGreg Roach                        </div>
708e64ca84SGreg Roach                    <?php elseif ($individual_media->count() === 1) : ?>
718e64ca84SGreg Roach                        <?= $individual_media->first()->displayImage(200, 260, 'crop', ['class' => 'img-thumbnail img-fluid w-100']) ?>
72dd6b2bfcSGreg Roach                    <?php else : ?>
73dd6b2bfcSGreg Roach                        <div id="individual-images" class="carousel slide" data-ride="carousel" data-interval="false">
74dd6b2bfcSGreg Roach                            <div class="carousel-inner">
75dd6b2bfcSGreg Roach                                <?php foreach ($individual_media as $n => $media_file) : ?>
76dd6b2bfcSGreg Roach                                    <div class="carousel-item <?= $n === 0 ? 'active' : '' ?>">
77dd6b2bfcSGreg Roach                                        <?= $media_file->displayImage(200, 260, 'crop', ['class' => 'img-thumbnail img-fluid w-100']) ?>
78dd6b2bfcSGreg Roach                                    </div>
79dd6b2bfcSGreg Roach                                <?php endforeach ?>
80dd6b2bfcSGreg Roach                            </div>
81dd6b2bfcSGreg Roach                            <a class="carousel-control-prev" href="#individual-images" role="button" data-slide="prev">
82dd6b2bfcSGreg Roach                                <span class="carousel-control-prev-icon" aria-hidden="true"></span>
83dd6b2bfcSGreg Roach                                <span class="sr-only"><?= I18N::translate('previous') ?></span>
84dd6b2bfcSGreg Roach                            </a>
85dd6b2bfcSGreg Roach                            <a class="carousel-control-next" href="#individual-images" role="button" data-slide="next">
86dd6b2bfcSGreg Roach                                <span class="carousel-control-next-icon" aria-hidden="true"></span>
87dd6b2bfcSGreg Roach                                <span class="sr-only"><?= I18N::translate('next') ?></span>
88dd6b2bfcSGreg Roach                            </a>
89dd6b2bfcSGreg Roach                        </div>
90dd6b2bfcSGreg Roach                    <?php endif ?>
91dd6b2bfcSGreg Roach
92f4afa648SGreg Roach                    <?php if (Auth::isEditor($individual->tree())) : ?>
938e64ca84SGreg Roach                        <div class="text-center">
942917771cSGreg Roach                            <a href="<?= e(route(AddNewFact::class, ['tree' => $individual->tree()->name(), 'xref' => $individual->xref(), 'fact' => 'OBJE'])) ?>">
95dd6b2bfcSGreg Roach                                <?= I18N::translate('Add a media object') ?>
96dd6b2bfcSGreg Roach                            </a>
97dd6b2bfcSGreg Roach                        </div>
98dd6b2bfcSGreg Roach                    <?php endif ?>
99dd6b2bfcSGreg Roach                </div>
1008e64ca84SGreg Roach            <?php endif ?>
101dd6b2bfcSGreg Roach
102dd6b2bfcSGreg Roach            <!-- Name accordion -->
103c15fb5e7SGreg Roach            <div class="col-sm accordion" id="individual-names">
104dd6b2bfcSGreg Roach                <?php foreach ($name_records as $name_record) : ?>
105dd6b2bfcSGreg Roach                    <?= $name_record ?>
106dd6b2bfcSGreg Roach                <?php endforeach ?>
107dd6b2bfcSGreg Roach
108dd6b2bfcSGreg Roach                <?php foreach ($sex_records as $sex_record) : ?>
109dd6b2bfcSGreg Roach                    <?= $sex_record ?>
110dd6b2bfcSGreg Roach                <?php endforeach ?>
111dd6b2bfcSGreg Roach            </div>
112dd6b2bfcSGreg Roach        </div>
113dd6b2bfcSGreg Roach
1144a2590a5SGreg Roach        <div class="wt-tabs-individual" id="individual-tabs">
1156a4003b9SGreg Roach            <ul class="nav nav-tabs flex-wrap" role="tablist">
116dd6b2bfcSGreg Roach                <?php foreach ($tabs as $tab) : ?>
1176a4003b9SGreg Roach                    <li class="nav-item" role="presentation">
118852ede8cSGreg Roach                        <a class="nav-link<?= $tab->isGrayedOut($individual) ? ' text-muted' : '' ?>" data-toggle="tab" role="tab" data-href="<?= e(route('module', ['module' => $tab->name(), 'action' => 'Tab', 'tree' => $individual->tree()->name(), 'xref' => $individual->xref()])) ?>" href="#<?= $tab->name() ?>">
119defb8071SRichard Cissée                            <?= $tab->tabTitle() ?>
120dd6b2bfcSGreg Roach                        </a>
121dd6b2bfcSGreg Roach                    </li>
122dd6b2bfcSGreg Roach                <?php endforeach ?>
123dd6b2bfcSGreg Roach            </ul>
1246a4003b9SGreg Roach
125dd6b2bfcSGreg Roach            <div class="tab-content">
126dd6b2bfcSGreg Roach                <?php foreach ($tabs as $tab) : ?>
127677aaceaSGreg Roach                    <div id="<?= $tab->name() ?>" class="tab-pane fade wt-ajax-load" role="tabpanel"><?php if (!$tab->canLoadAjax()) :
128d70512abSGreg Roach                        ?><?= $tab->getTabContent($individual) ?><?php
129d70512abSGreg Roach                             endif ?></div>
130dd6b2bfcSGreg Roach                <?php endforeach ?>
131dd6b2bfcSGreg Roach            </div>
132dd6b2bfcSGreg Roach        </div>
133dd6b2bfcSGreg Roach    </div>
134c72fc94cSGreg Roach    <?php if ($sidebars->isNotEmpty()) : ?>
135336be01cSGreg Roach    <div class="col-sm-4 accordion" id="sidebar">
136dd6b2bfcSGreg Roach        <?php foreach ($sidebars as $sidebar) : ?>
137dd6b2bfcSGreg Roach            <div class="card">
138677aaceaSGreg Roach                <div class="card-header" role="tab" id="sidebar-header-<?= $sidebar->name() ?>">
139dd6b2bfcSGreg Roach                    <div class="card-title mb-0">
140336be01cSGreg Roach                        <a data-toggle="collapse" href="#sidebar-content-<?= $sidebar->name() ?>" aria-expanded="<?= $sidebar->name() === 'family_nav' ? 'true' : 'false' ?>" aria-controls="sidebar-content-<?= $sidebar->name() ?>">
141c15fb5e7SGreg Roach                            <?= view('icons/expand') ?>
142c15fb5e7SGreg Roach                            <?= view('icons/collapse') ?>
143defb8071SRichard Cissée                            <?= $sidebar->sidebarTitle() ?>
144dd6b2bfcSGreg Roach                        </a>
145dd6b2bfcSGreg Roach                    </div>
146dd6b2bfcSGreg Roach                </div>
1476a4003b9SGreg Roach
148336be01cSGreg Roach                <div id="sidebar-content-<?= $sidebar->name() ?>" class="collapse<?= $sidebar->name() === 'family_nav' ? ' show' : '' ?>" data-parent="#sidebar" aria-labelledby="sidebar-header-<?= $sidebar->name() ?>">
149dd6b2bfcSGreg Roach                    <div class="card-body">
1507d70e4a7SGreg Roach                        <?= $sidebar->getSidebarContent($individual) ?>
1517d70e4a7SGreg Roach                    </div>
152dd6b2bfcSGreg Roach                </div>
153dd6b2bfcSGreg Roach            </div>
154dd6b2bfcSGreg Roach        <?php endforeach ?>
155dd6b2bfcSGreg Roach    </div>
156c72fc94cSGreg Roach    <?php endif ?>
157dd6b2bfcSGreg Roach</div>
158dd6b2bfcSGreg Roach
159dd6b2bfcSGreg Roach<?php View::push('javascript') ?>
160dd6b2bfcSGreg Roach<script>
161dd6b2bfcSGreg Roach  "use strict";
162dd6b2bfcSGreg Roach
163dd6b2bfcSGreg Roach  // Bootstrap tabs - load content dynamically using AJAX
164dd6b2bfcSGreg Roach  $('a[data-toggle="tab"][data-href]').on('show.bs.tab', function () {
1655675e46eSmiqrogroove      let target = $(this.hash + ':empty');
16606b58f1dSGreg Roach      if (target.length > 0) {
1675675e46eSmiqrogroove          // Start the download immediately...
1685675e46eSmiqrogroove          let download = fetch(this.dataset.href);
1695675e46eSmiqrogroove
1705675e46eSmiqrogroove          // ...but don't insert it until the tab is ready.
1715675e46eSmiqrogroove          $(this).one('shown.bs.tab', () => {
1725675e46eSmiqrogroove              download
1735675e46eSmiqrogroove                  .then(data => data.text())
1745675e46eSmiqrogroove                  .then(data => target.html(data));
1755675e46eSmiqrogroove          });
1765675e46eSmiqrogroove      }
177dd6b2bfcSGreg Roach  });
178dd6b2bfcSGreg Roach
179dd6b2bfcSGreg Roach  // If the URL contains a fragment, then activate the corresponding tab.
180dd6b2bfcSGreg Roach  // Use a prefix on the fragment, to prevent scrolling to the element.
181054771e9SGreg Roach  let target = window.location.hash.replace("tab-", "");
182054771e9SGreg Roach  let tab = $("#individual-tabs .nav-link[href='" + target + "']");
183dd6b2bfcSGreg Roach  // If not, then activate the first tab.
184dd6b2bfcSGreg Roach  if (tab.length === 0) {
185dd6b2bfcSGreg Roach    tab = $("#individual-tabs .nav-link:first");
186dd6b2bfcSGreg Roach  }
187dd6b2bfcSGreg Roach  tab.tab("show");
188dd6b2bfcSGreg Roach
189dd6b2bfcSGreg Roach  // If the user selects a tab, update the URL to reflect this
190dd6b2bfcSGreg Roach  $('#individual-tabs a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
191dd6b2bfcSGreg Roach    window.location.hash = "tab-" + e.target.href.substring(e.target.href.indexOf('#') + 1);
192dd6b2bfcSGreg Roach  });
193dd6b2bfcSGreg Roach</script>
194dd6b2bfcSGreg Roach<?php View::endpush() ?>
195dd6b2bfcSGreg Roach
196dd6b2bfcSGreg Roach<?= view('modals/ajax') ?>
197*853f2b8aSGreg Roach<?= view('modals/shares', ['shares' => $shares, 'title' => I18N::translate('Share')]) ?>
198