xref: /webtrees/resources/views/admin/control-panel.phtml (revision b43e8d2bb2c20432b6d427f0f5d9a32679a9aa4f)
1<?php
2
3use Fisharebest\Webtrees\Http\RequestHandlers\BroadcastPage;
4use Fisharebest\Webtrees\Http\RequestHandlers\CleanDataFolder;
5use Fisharebest\Webtrees\Http\RequestHandlers\ControlPanel;
6use Fisharebest\Webtrees\Http\RequestHandlers\CreateTreePage;
7use Fisharebest\Webtrees\Http\RequestHandlers\EmailPreferencesPage;
8use Fisharebest\Webtrees\Http\RequestHandlers\ManageMediaPage;
9use Fisharebest\Webtrees\Http\RequestHandlers\ManageTrees;
10use Fisharebest\Webtrees\Http\RequestHandlers\MapDataList;
11use Fisharebest\Webtrees\Http\RequestHandlers\MergeTreesPage;
12use Fisharebest\Webtrees\Http\RequestHandlers\ModulesAllPage;
13use Fisharebest\Webtrees\Http\RequestHandlers\ModulesAnalyticsPage;
14use Fisharebest\Webtrees\Http\RequestHandlers\ModulesBlocksPage;
15use Fisharebest\Webtrees\Http\RequestHandlers\ModulesChartsPage;
16use Fisharebest\Webtrees\Http\RequestHandlers\ModulesDataFixesPage;
17use Fisharebest\Webtrees\Http\RequestHandlers\ModulesFootersPage;
18use Fisharebest\Webtrees\Http\RequestHandlers\ModulesHistoricEventsPage;
19use Fisharebest\Webtrees\Http\RequestHandlers\ModulesLanguagesPage;
20use Fisharebest\Webtrees\Http\RequestHandlers\ModulesListsPage;
21use Fisharebest\Webtrees\Http\RequestHandlers\ModulesMenusPage;
22use Fisharebest\Webtrees\Http\RequestHandlers\ModulesReportsPage;
23use Fisharebest\Webtrees\Http\RequestHandlers\ModulesSidebarsPage;
24use Fisharebest\Webtrees\Http\RequestHandlers\ModulesTabsPage;
25use Fisharebest\Webtrees\Http\RequestHandlers\ModulesThemesPage;
26use Fisharebest\Webtrees\Http\RequestHandlers\PendingChanges;
27use Fisharebest\Webtrees\Http\RequestHandlers\PhpInformation;
28use Fisharebest\Webtrees\Http\RequestHandlers\SiteLogsPage;
29use Fisharebest\Webtrees\Http\RequestHandlers\SitePreferencesPage;
30use Fisharebest\Webtrees\Http\RequestHandlers\SiteRegistrationPage;
31use Fisharebest\Webtrees\Http\RequestHandlers\TreePageDefaultEdit;
32use Fisharebest\Webtrees\Http\RequestHandlers\UploadMediaPage;
33use Fisharebest\Webtrees\Http\RequestHandlers\UserPageDefaultEdit;
34use Fisharebest\Webtrees\Http\RequestHandlers\UsersCleanupPage;
35use Fisharebest\Webtrees\I18N;
36use Fisharebest\Webtrees\Module\FamilyListModule;
37use Fisharebest\Webtrees\Module\IndividualListModule;
38use Fisharebest\Webtrees\Module\MediaListModule;
39use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface;
40use Fisharebest\Webtrees\Module\ModuleBlockInterface;
41use Fisharebest\Webtrees\Module\ModuleChartInterface;
42use Fisharebest\Webtrees\Module\ModuleConfigInterface;
43use Fisharebest\Webtrees\Module\ModuleCustomInterface;
44use Fisharebest\Webtrees\Module\ModuleDataFixInterface;
45use Fisharebest\Webtrees\Module\ModuleFooterInterface;
46use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface;
47use Fisharebest\Webtrees\Module\ModuleInterface;
48use Fisharebest\Webtrees\Module\ModuleLanguageInterface;
49use Fisharebest\Webtrees\Module\ModuleListInterface;
50use Fisharebest\Webtrees\Module\ModuleMenuInterface;
51use Fisharebest\Webtrees\Module\ModuleReportInterface;
52use Fisharebest\Webtrees\Module\ModuleSidebarInterface;
53use Fisharebest\Webtrees\Module\ModuleTabInterface;
54use Fisharebest\Webtrees\Module\ModuleThemeInterface;
55use Fisharebest\Webtrees\Module\NoteListModule;
56use Fisharebest\Webtrees\Module\RepositoryListModule;
57use Fisharebest\Webtrees\Module\SourceListModule;
58use Fisharebest\Webtrees\Module\SubmitterListModule;
59use Fisharebest\Webtrees\Tree;
60use Fisharebest\Webtrees\User;
61use Fisharebest\Webtrees\Webtrees;
62use Illuminate\Support\Collection;
63
64/**
65 * @var Collection<User>                          $administrators
66 * @var Collection<ModuleInterface>               $all_modules_disabled
67 * @var Collection<ModuleInterface>               $all_modules_enabled
68 * @var Collection<Tree>                          $all_trees
69 * @var Collection<User>                          $all_users
70 * @var Collection<ModuleAnalyticsInterface>      $analytics_modules_disabled
71 * @var Collection<ModuleAnalyticsInterface>      $analytics_modules_enabled
72 * @var Collection<ModuleBlockInterface>          $block_modules_disabled
73 * @var Collection<ModuleBlockInterface>          $block_modules_enabled
74 * @var array<string,int>                         $changes
75 * @var Collection<ModuleChartInterface>          $chart_modules_disabled
76 * @var Collection<ModuleChartInterface>          $chart_modules_enabled
77 * @var Collection<ModuleCustomInterface>         $custom_updates
78 * @var Collection<ModuleDataFixInterface>        $data_fix_modules_disabled
79 * @var Collection<ModuleDataFixInterface>        $data_fix_modules_enabled
80 * @var Collection<string,int>                    $families
81 * @var FamilyListModule|null                     $family_list_module
82 * @var Collection<ModuleFooterInterface>         $footer_modules_disabled
83 * @var Collection<ModuleFooterInterface>         $footer_modules_enabled
84 * @var Collection<ModuleHistoricEventsInterface> $history_modules_disabled
85 * @var Collection<ModuleHistoricEventsInterface> $history_modules_enabled
86 * @var Collection<string,int>                    $individuals
87 * @var IndividualListModule|null                 $individual_list_module
88 * @var Collection<ModuleLanguageInterface>       $language_modules_disabled
89 * @var Collection<ModuleLanguageInterface>       $language_modules_enabled
90 * @var string                                    $latest_version
91 * @var Collection<ModuleListInterface>           $list_modules_disabled
92 * @var Collection<ModuleListInterface>           $list_modules_enabled
93 * @var Collection<User>                          $managers
94 * @var Collection<string,int>                    $media
95 * @var MediaListModule|null                      $media_list_module
96 * @var Collection<ModuleMenuInterface>           $menu_modules_disabled
97 * @var Collection<ModuleMenuInterface>           $menu_modules_enabled
98 * @var Collection<User>                          $moderators
99 * @var Collection<string,int>                    $notes
100 * @var NoteListModule|null                       $note_list_module
101 * @var Collection<ModuleInterface>               $other_modules
102 * @var Collection<ModuleReportInterface>         $report_modules_disabled
103 * @var Collection<ModuleReportInterface>         $report_modules_enabled
104 * @var Collection<string,int>                    $repositories
105 * @var RepositoryListModule|null                 $repository_list_module
106 * @var Collection<string>                        $server_errors
107 * @var Collection<string>                        $server_warnings
108 * @var bool                                      $show_synchronize
109 * @var Collection<ModuleSidebarInterface>        $sidebar_modules_disabled
110 * @var Collection<ModuleSidebarInterface>        $sidebar_modules_enabled
111 * @var Collection<string,int>                    $sources
112 * @var SourceListModule|null                     $source_list_module
113 * @var Collection<string,int>                    $submitters
114 * @var SubmitterListModule|null                  $submitter_list_module
115 * @var Collection<ModuleTabInterface>            $tab_modules_disabled
116 * @var Collection<ModuleTabInterface>            $tab_modules_enabled
117 * @var Collection<ModuleThemeInterface>          $theme_modules_disabled
118 * @var Collection<ModuleThemeInterface>          $theme_modules_enabled
119 * @var string                                    $title
120 * @var Collection<User>                          $unapproved
121 * @var Collection<User>                          $unverified
122 */
123
124?>
125
126<h1><?= $title ?></h1>
127
128<!-- WEBSITE / WEBTREES -->
129<div class="card mb-4">
130    <div class="card-header">
131        <h2 class="mb-0">
132            <?= I18N::translate('Website') ?>
133            <span class="badge badge-secondary" dir="ltr">
134                <?= e(Webtrees::VERSION) ?>
135            </span>
136        </h2>
137    </div>
138    <div class="card-body">
139        <?php foreach ($server_errors as $server_error) : ?>
140            <p class="alert alert-danger"><?= $server_error ?></p>
141        <?php endforeach ?>
142
143        <?php foreach ($server_warnings as $server_warning) : ?>
144            <p class="alert alert-warning"><?= $server_warning ?></p>
145        <?php endforeach ?>
146
147        <p class="card-text">
148            <?= /* I18N: %s is a URL/link to the project website */
149            I18N::translate('Support and documentation can be found at %s.', '<a href="https://webtrees.net/">webtrees.net</a>') ?>
150        </p>
151        <p class="card-text">
152            <?php if ($latest_version === '') : ?>
153                <?= I18N::translate('No upgrade information is available.') ?>
154            <?php elseif (version_compare(Webtrees::VERSION, $latest_version) < 0) : ?>
155                <div class="alert alert-info">
156                    <?= I18N::translate('A new version of webtrees is available.') ?>
157                    <a href="<?= e(route('upgrade')) ?>" class="alert-link">
158                        <?= /* I18N: %s is a version number */
159                        I18N::translate('Upgrade to webtrees %s.', e($latest_version)) ?>
160                    </a>
161                </div>
162            <?php else : ?>
163                <?= I18N::translate('This is the latest version of webtrees. No upgrade is available.') ?>
164            <?php endif ?>
165        </p>
166
167        <?php foreach ($custom_updates as $module) : ?>
168        <div class="alert alert-info">
169            <?= view('icons/information') ?>
170            <?= I18N::translate('An upgrade is available.') ?>
171            <br>
172            <?= $module->title() ?><?= e($module->customModuleVersion()) ?><?= e($module->customModuleLatestVersion()) ?>
173        </div>
174        <?php endforeach ?>
175
176        <div class="row">
177            <div class="col-sm-6">
178                <ul class="fa-ul">
179                    <li>
180                        <span class="fa-li"><?= view('icons/preferences') ?></span>
181                        <a href="<?= e(route(SitePreferencesPage::class)) ?>">
182                            <?= I18N::translate('Website preferences') ?>
183                        </a>
184                    </li>
185                    <li>
186                        <span class="fa-li"><?= view('icons/email') ?></span>
187                        <a href="<?= e(route(EmailPreferencesPage::class)) ?>">
188                            <?= I18N::translate('Sending email') ?>
189                        </a>
190                    </li>
191                    <li>
192                        <span class="fa-li"><?= view('icons/user') ?></span>
193                        <a href="<?= e(route(SiteRegistrationPage::class)) ?>">
194                            <?= I18N::translate('Sign-in and registration') ?>
195                        </a>
196                    </li>
197                </ul>
198            </div>
199            <div class="col-sm-6">
200                <ul class="fa-ul">
201                    <li>
202                        <span class="fa-li"><?= view('icons/list') ?></span>
203                        <a href="<?= e(route(SiteLogsPage::class)) ?>">
204                            <?= I18N::translate('Website logs') ?>
205                        </a>
206                    </li>
207                    <li>
208                        <span class="fa-li"><?= view('icons/delete') ?></span>
209                        <a href="<?= e(route(CleanDataFolder::class)) ?>">
210                            <?= I18N::translate('Clean up data folder') ?>
211                        </a>
212                    </li>
213                    <li>
214                        <span class="fa-li"><?= view('icons/help') ?></span>
215                        <a href="<?= e(route(PhpInformation::class)) ?>">
216                            <?= I18N::translate('Server information') ?>
217                        </a>
218                    </li>
219                </ul>
220            </div>
221        </div>
222    </div>
223</div>
224
225<!-- FAMILY TREES -->
226<div class="card mb-4 <?= array_sum($changes) ? 'card-outline-danger' : '' ?>">
227    <div class="card-header">
228        <h2 class="mb-0">
229            <?= I18N::translate('Family trees') ?>
230            <span class="badge badge-secondary">
231                    <?= I18N::number($all_trees->count()) ?>
232                </span>
233        </h2>
234    </div>
235
236    <div class="card-body">
237        <?php if ($all_trees->isEmpty()) : ?>
238            <p class="alert alert-info">
239                <?= I18N::translate('You need to create a family tree.') ?>
240            </p>
241        <?php endif ?>
242
243        <ul class="fa-ul">
244            <li>
245                <span class="fa-li"><?= view('icons/add') ?></span>
246                <a href="<?= e(route(CreateTreePage::class)) ?>">
247                    <?= I18N::translate('Create a family tree') ?>
248                </a>
249            </li>
250            <li>
251                <span class="fa-li"><?= view('icons/block') ?></span>
252                <a href="<?= e(route(TreePageDefaultEdit::class)) ?>">
253                    <?= I18N::translate('Set the default blocks for new family trees') ?>
254                </a>
255            </li>
256            <?php if (count($all_trees) > 1) : ?>
257                <li>
258                    <span class="fa-li"><?= view('icons/merge') ?></span>
259                    <a href="<?= e(route(MergeTreesPage::class)) ?>">
260                        <?= I18N::translate('Merge family trees') ?>
261                    </a>
262                </li>
263            <?php endif ?>
264        </ul>
265
266        <table class="table table-sm">
267            <caption class="sr-only">
268                <?= I18N::translate('Family trees') ?>
269            </caption>
270
271            <thead>
272                <tr>
273                    <th><?= I18N::translate('Family tree') ?></th>
274                    <th class="align-digits"><?= I18N::translate('Pending changes') ?></th>
275                    <th class="d-none d-sm-table-cell align-digits"><?= I18N::translate('Individuals') ?></th>
276                    <th class="d-none d-lg-table-cell align-digits"><?= I18N::translate('Families') ?></th>
277                    <th class="d-none d-sm-table-cell align-digits"><?= I18N::translate('Sources') ?></th>
278                    <th class="d-none d-lg-table-cell align-digits"><?= I18N::translate('Repositories') ?></th>
279                    <th class="d-none d-sm-table-cell align-digits"><?= I18N::translate('Media') ?></th>
280                    <th class="d-none d-lg-table-cell align-digits"><?= I18N::translate('Notes') ?></th>
281                    <th class="d-none d-lg-table-cell align-digits"><?= I18N::translate('Submitters') ?></th>
282                </tr>
283            </thead>
284
285            <tbody>
286                <?php foreach ($all_trees as $tree) : ?>
287                    <tr class="<?= $changes[$tree->id()] ? 'danger' : '' ?>">
288                        <th scope="row">
289                            <?= view('icons/preferences') ?>
290                            <a href="<?= e(route(ManageTrees::class, ['tree' => $tree->name()])) ?>">
291                                <?= e($tree->name()) ?>
292                                -
293                                <?= e($tree->title()) ?>
294                            </a>
295                        </th>
296                        <td style="text-align: right;">
297                            <?php if ($changes[$tree->id()]) : ?>
298                                <a href="<?= e(route(PendingChanges::class, ['tree' => $tree->name(), 'url' => route(ControlPanel::class)])) ?>">
299                                    <?= I18N::number($changes[$tree->id()]) ?>
300                                    <span class="sr-only"><?= I18N::translate('Pending changes') ?> <?= e($tree->title()) ?></span>
301                                </a>
302                            <?php else : ?>
303                                -
304                            <?php endif ?>
305                        </td>
306                        <td class="d-none d-sm-table-cell align-digits">
307                            <?php if ($individuals[$tree->id()] > 0) : ?>
308                                <?php if ($individual_list_module instanceof IndividualListModule) : ?>
309                                    <a href="<?= e($individual_list_module->listUrl($tree)) ?>"><?= I18N::number($individuals[$tree->id()]) ?></a>
310                                <?php else : ?>
311                                    <?= I18N::number($individuals[$tree->id()]) ?>
312                                <?php endif ?>
313                            <?php else : ?>
314                                -
315                            <?php endif ?>
316                        </td>
317                        <td class="d-none d-lg-table-cell align-digits">
318                            <?php if ($families[$tree->id()] > 0) : ?>
319                                <?php if ($family_list_module instanceof FamilyListModule) : ?>
320                                    <a href="<?= e($family_list_module->listUrl($tree)) ?>"><?= I18N::number($families[$tree->id()]) ?></a>
321                                <?php else : ?>
322                                    <?= I18N::number($families[$tree->id()]) ?>
323                                <?php endif ?>
324                            <?php else : ?>
325                                -
326                            <?php endif ?>
327                        </td>
328                        <td class="d-none d-sm-table-cell align-digits">
329                            <?php if ($sources[$tree->id()] > 0) : ?>
330                                <?php if ($source_list_module instanceof SourceListModule) : ?>
331                                    <a href="<?= e($source_list_module->listUrl($tree)) ?>"><?= I18N::number($sources[$tree->id()]) ?></a>
332                                <?php else : ?>
333                                    <?= I18N::number($sources[$tree->id()]) ?>
334                                <?php endif ?>
335                            <?php else : ?>
336                                -
337                            <?php endif ?>
338                        </td>
339                        <td class="d-none d-lg-table-cell align-digits">
340                            <?php if ($repositories[$tree->id()] > 0) : ?>
341                                <?php if ($repository_list_module instanceof RepositoryListModule) : ?>
342                                    <a href="<?= e($repository_list_module->listUrl($tree)) ?>"><?= I18N::number($repositories[$tree->id()]) ?></a>
343                                <?php else : ?>
344                                    <?= I18N::number($repositories[$tree->id()]) ?>
345                                <?php endif ?>
346                            <?php else : ?>
347                                -
348                            <?php endif ?>
349                        </td>
350                        <td class="d-none d-sm-table-cell align-digits">
351                            <?php if ($media[$tree->id()] > 0) : ?>
352                                <?php if ($media_list_module instanceof MediaListModule) : ?>
353                                    <a href="<?= e($media_list_module->listUrl($tree)) ?>"><?= I18N::number($media[$tree->id()]) ?></a>
354                                <?php else : ?>
355                                    <?= I18N::number($media[$tree->id()]) ?>
356                                <?php endif ?>
357                            <?php else : ?>
358                                -
359                            <?php endif ?>
360                        </td>
361                        <td class="d-none d-lg-table-cell align-digits">
362                            <?php if ($notes[$tree->id()] > 0) : ?>
363                                <?php if ($note_list_module instanceof NoteListModule) : ?>
364                                    <a href="<?= e($note_list_module->listUrl($tree)) ?>"><?= I18N::number($notes[$tree->id()]) ?></a>
365                                <?php else : ?>
366                                    <?= I18N::number($notes[$tree->id()]) ?>
367                                <?php endif ?>
368                            <?php else : ?>
369                                -
370                            <?php endif ?>
371                        </td>
372                         <td class="d-none d-lg-table-cell align-digits">
373                            <?php if ($submitters[$tree->id()] > 0) : ?>
374                                <?php if ($submitter_list_module instanceof SubmitterListModule) : ?>
375                                    <a href="<?= e($submitter_list_module->listUrl($tree)) ?>"><?= I18N::number($submitters[$tree->id()]) ?></a>
376                                <?php else : ?>
377                                    <?= I18N::number($submitters[$tree->id()]) ?>
378                                <?php endif ?>
379                            <?php else : ?>
380                                -
381                            <?php endif ?>
382                        </td>
383                    </tr>
384                <?php endforeach ?>
385            </tbody>
386
387            <tfoot>
388                <tr>
389                    <th scope="row">
390                        <?= I18N::translate('Total') ?>
391                    </th>
392                    <td class="align-digits">
393                        <?= I18N::number(array_sum($changes)) ?>
394                    </td>
395                    <td class="d-none d-sm-table-cell align-digits">
396                        <?= I18N::number($individuals->sum()) ?>
397                    </td>
398                    <td class="d-none d-lg-table-cell align-digits">
399                        <?= I18N::number($families->sum()) ?>
400                    </td>
401                    <td class="d-none d-sm-table-cell align-digits">
402                        <?= I18N::number($sources->sum()) ?>
403                    </td>
404                    <td class="d-none d-lg-table-cell align-digits">
405                        <?= I18N::number($repositories->sum()) ?>
406                    </td>
407                    <td class="d-none d-sm-table-cell align-digits">
408                        <?= I18N::number($media->sum()) ?>
409                    </td>
410                    <td class="d-none d-lg-table-cell align-digits">
411                        <?= I18N::number($notes->sum()) ?>
412                    </td>
413                </tr>
414            </tfoot>
415        </table>
416    </div>
417</div>
418
419<?php if ($show_synchronize): ?>
420    <?= view('admin/synchronize-trees') ?>
421<?php endif ?>
422
423<!-- USERS -->
424<div class="card mb-4 <?= $unapproved || $unverified ? 'card-outline-danger' : '' ?>">
425    <div class="card-header">
426        <h2 class="mb-0">
427            <?= I18N::translate('Users') ?>
428            <span class="badge badge-secondary">
429                    <?= I18N::number(count($all_users)) ?>
430                </span>
431        </h2>
432    </div>
433    <div class="card-body">
434        <dl class="row">
435            <?php foreach ([I18N::translate('Administrators') => $administrators, I18N::translate('Managers') => $managers, I18N::translate('Moderators') => $moderators, I18N::translate('Not verified by the user') => $unverified, I18N::translate('Not approved by an administrator') => $unapproved] as $label => $list) : ?>
436                <?php if (!empty($list)) : ?>
437                    <dt class="col-sm-6">
438                        <?= $label ?>
439                    </dt>
440                    <dd class="col-sm-6">
441                        <?php foreach ($list as $n => $user) : ?>
442                            <?= $n ? I18N::$list_separator : '' ?>
443                            <a href="<?= e(route('admin-users-edit', ['user_id' => $user->id()])) ?>" dir="auto">
444                                <?= e($user->realName()) ?>
445                            </a>
446                        <?php endforeach ?>
447                        <?php if ($list->isEmpty()) : ?>
448449                        <?php endif ?>
450                    </dd>
451                <?php endif ?>
452            <?php endforeach ?>
453        </dl>
454
455        <div class="row">
456            <div class="col-sm-6">
457                <ul class="fa-ul">
458                    <li>
459                        <span class="fa-li"><?= view('icons/preferences') ?></span>
460                        <a href="<?= e(route('admin-users')) ?>">
461                            <?= I18N::translate('User administration') ?>
462                        </a>
463                    </li>
464                    <li>
465                        <span class="fa-li"><?= view('icons/add') ?></span>
466                        <a href="<?= e(route('admin-users-create')) ?>">
467                            <?= I18N::translate('Add a user') ?>
468                        </a>
469                    </li>
470                    <li>
471                        <span class="fa-li"><?= view('icons/delete') ?></span>
472                        <a href="<?= e(route(UsersCleanupPage::class)) ?>">
473                            <?= I18N::translate('Delete inactive users') ?>
474                        </a>
475                    </li>
476                    <li>
477                        <span class="fa-li"><?= view('icons/block') ?></span>
478                        <a href="<?= e(route(UserPageDefaultEdit::class)) ?>">
479                            <?= I18N::translate('Set the default blocks for new users') ?>
480                        </a>
481                    </li>
482                </ul>
483            </div>
484            <div class="col-sm-6">
485                <ul class="fa-ul">
486                    <li>
487                        <span class="fa-li"><?= view('icons/email') ?></span>
488                        <a href="<?= e(route(BroadcastPage::class, ['to' => 'all'])) ?>">
489                            <?= I18N::translate('Send a message to all users') ?>
490                        </a>
491                    </li>
492                    <li>
493                        <span class="fa-li"><?= view('icons/email') ?></span>
494                        <a href="<?= e(route(BroadcastPage::class, ['to' => 'never_logged'])) ?>">
495                            <?= I18N::translate('Send a message to users who have never signed in') ?>
496                        </a>
497                    </li>
498                    <li>
499                        <span class="fa-li"><?= view('icons/email') ?></span>
500                        <a href="<?= e(route(BroadcastPage::class, ['to' => 'last_6mo'])) ?>">
501                            <?= I18N::translate('Send a message to users who have not signed in for 6 months') ?>
502                        </a>
503                    </li>
504                </ul>
505            </div>
506        </div>
507    </div>
508</div>
509
510<!-- MODULES -->
511<div class="card mb-4">
512    <div class="card-header">
513        <h2 class="mb-0">
514            <?= I18N::translate('Modules') ?>
515            <?= view('components/badge', ['count' => $all_modules_enabled->count(), 'total' => $all_modules_disabled->count(), 'context' => 'secondary']) ?>
516        </h2>
517    </div>
518
519    <div class="card-body">
520        <ul class="fa-ul">
521            <li>
522                <span class="fa-li"><?= view('icons/module') ?></span>
523                <a href="<?= e(route(ModulesAllPage::class)) ?>">
524                    <?= I18N::translate('All modules') ?>
525                </a>
526                <?= view('components/badge', ['count' => $all_modules_enabled->count(), 'total' => $all_modules_disabled->count(), 'context' => 'primary']) ?>
527            </li>
528        </ul>
529
530        <div class="row">
531            <div class="col-sm-4">
532                <h3>
533                    <?= I18N::translate('Genealogy') ?>
534                </h3>
535
536                <ul class="fa-ul">
537                    <li>
538                        <span class="fa-li"><?= view('icons/menu') ?></span>
539                        <a href="<?= e(route(ModulesMenusPage::class)) ?>">
540                            <?= I18N::translate('Menus') ?>
541                        </a>
542                        <?= view('components/badge', ['count' => $menu_modules_enabled->count(), 'total' => $menu_modules_disabled->count(), 'context' => 'primary']) ?>
543                    </li>
544                    <li>
545                        <span class="fa-li"><?= view('icons/chart') ?></span>
546                        <a href="<?= e(route(ModulesChartsPage::class)) ?>">
547                            <?= I18N::translate('Charts') ?>
548                        </a>
549                        <?= view('components/badge', ['count' => $chart_modules_enabled->count(), 'total' => $chart_modules_disabled->count(), 'context' => 'primary']) ?>
550                    </li>
551                    <li>
552                        <span class="fa-li"><?= view('icons/list') ?></span>
553                        <a href="<?= e(route(ModulesListsPage::class)) ?>">
554                            <?= I18N::translate('Lists') ?>
555                        </a>
556                        <?= view('components/badge', ['count' => $list_modules_enabled->count(), 'total' => $list_modules_disabled->count(), 'context' => 'primary']) ?>
557                    </li>
558                    <li>
559                        <span class="fa-li"><?= view('icons/report') ?></span>
560                        <a href="<?= e(route(ModulesReportsPage::class)) ?>">
561                            <?= I18N::translate('Reports') ?>
562                        </a>
563                        <?= view('components/badge', ['count' => $report_modules_enabled->count(), 'total' => $report_modules_disabled->count(), 'context' => 'primary']) ?>
564                    </li>
565                    <li>
566                        <span class="fa-li"><?= view('icons/data-fix') ?></span>
567                        <a href="<?= e(route(ModulesDataFixesPage::class)) ?>">
568                            <?= I18N::translate('Data fixes') ?>
569                        </a>
570                        <?= view('components/badge', ['count' => $data_fix_modules_enabled->count(), 'total' => $data_fix_modules_disabled->count(), 'context' => 'primary']) ?>
571                    </li>
572                </ul>
573
574                <h3>
575                    <?= I18N::translate('Website') ?>
576                </h3>
577
578                <ul class="fa-ul">
579                    <li>
580                        <span class="fa-li"><?= view('icons/footer') ?></span>
581                        <a href="<?= e(route(ModulesFootersPage::class)) ?>">
582                            <?= I18N::translate('Footers') ?>
583                        </a>
584                        <?= view('components/badge', ['count' => $footer_modules_enabled->count(), 'total' => $footer_modules_disabled->count(), 'context' => 'primary']) ?>
585                    </li>
586                    <li>
587                        <span class="fa-li"><?= view('icons/analytics') ?></span>
588                        <a href="<?= e(route(ModulesAnalyticsPage::class)) ?>">
589                            <?= I18N::translate('Tracking and analytics') ?>
590                        </a>
591                        <?= view('components/badge', ['count' => $analytics_modules_enabled->count(), 'total' => $analytics_modules_disabled->count(), 'context' => 'primary']) ?>
592                    </li>
593                    <li>
594                        <span class="fa-li"><?= view('icons/theme') ?></span>
595                        <a href="<?= e(route(ModulesThemesPage::class)) ?>">
596                            <?= I18N::translate('Themes') ?>
597                        </a>
598                        <?= view('components/badge', ['count' => $theme_modules_enabled->count(), 'total' => $theme_modules_disabled->count(), 'context' => 'primary']) ?>
599                    </li>
600                    <li>
601                        <span class="fa-li"><?= view('icons/language') ?></span>
602                        <a href="<?= e(route(ModulesLanguagesPage::class)) ?>">
603                            <?= I18N::translate('Languages') ?>
604                        </a>
605                        <?= view('components/badge', ['count' => $language_modules_enabled->count(), 'total' => $language_modules_disabled->count(), 'context' => 'primary']) ?>
606                    </li>
607                </ul>
608
609            </div>
610
611            <div class="col-sm-4">
612
613                <h3>
614                    <?= I18N::translate('Home page') ?>
615                </h3>
616
617                <ul class="fa-ul">
618                    <li>
619                        <span class="fa-li"><?= view('icons/block') ?></span>
620                        <a href="<?= e(route(ModulesBlocksPage::class)) ?>">
621                            <?= I18N::translate('Blocks') ?>
622                        </a>
623                        <?= view('components/badge', ['count' => $block_modules_enabled->count(), 'total' => $block_modules_disabled->count(), 'context' => 'primary']) ?>
624                    </li>
625                </ul>
626
627                <h3>
628                    <?= I18N::translate('Individual page') ?>
629                </h3>
630
631                <ul class="fa-ul">
632                    <li>
633                        <span class="fa-li"><?= view('icons/tab') ?></span>
634                        <a href="<?= e(route(ModulesTabsPage::class)) ?>">
635                            <?= I18N::translate('Tabs') ?>
636                            <?= view('components/badge', ['count' => $tab_modules_enabled->count(), 'total' => $tab_modules_disabled->count(), 'context' => 'primary']) ?>
637                        </a>
638                    </li>
639                    <li>
640                        <span class="fa-li"><?= view('icons/sidebar') ?></span>
641                        <a href="<?= e(route(ModulesSidebarsPage::class)) ?>">
642                            <?= I18N::translate('Sidebars') ?>
643                        </a>
644                        <?= view('components/badge', ['count' => $sidebar_modules_enabled->count(), 'total' => $sidebar_modules_disabled->count(), 'context' => 'primary']) ?>
645                    </li>
646                    <li>
647                        <span class="fa-li"><?= view('icons/history') ?></span>
648                        <a href="<?= e(route(ModulesHistoricEventsPage::class)) ?>">
649                            <?= I18N::translate('Historic events') ?>
650                        </a>
651                        <?= view('components/badge', ['count' => $history_modules_enabled->count(), 'total' => $history_modules_disabled->count(), 'context' => 'primary']) ?>
652                    </li>
653                </ul>
654
655            </div>
656
657            <div class="col-sm-4">
658
659                <h3>
660                    <?= I18N::translate('Other') ?>
661                </h3>
662
663                <ul class="fa-ul">
664                    <?php foreach ($other_modules as $module) : ?>
665                        <li>
666                            <span class="fa-li"><?= view('icons/module') ?></span>
667
668                            <?php if ($module->isEnabled()) : ?>
669                                <?php if ($module instanceof ModuleConfigInterface) : ?>
670                                    <a href="<?= e($module->getConfigLink()) ?>">
671                                    <?= $module->title() ?>
672                                    <?= view('icons/preferences') ?>
673                                    </a>
674                                <?php else : ?>
675                                    <?= $module->title() ?>
676                                <?php endif ?>
677                            <?php else : ?>
678                                <span class="text-muted">
679                                    <span class="fa-li"><?= view('icons/module') ?></span>
680                                     <?= $module->title() ?>
681                                    <?php if ($module instanceof ModuleConfigInterface) : ?>
682                                        <?= view('icons/preferences') ?>
683                                    <?php endif ?>
684                                    </span>
685                                </span>
686                            <?php endif ?>
687
688                            <?php if ($module instanceof ModuleCustomInterface) : ?>
689                                <?= view('admin/custom-module-info', ['module' => $module]) ?>
690                            <?php endif ?>
691                        </li>
692                    <?php endforeach ?>
693                </ul>
694            </div>
695        </div>
696    </div>
697</div>
698
699<!-- MEDIA -->
700<div class="card mb-4">
701    <div class="card-header">
702        <h2 class="mb-0">
703            <?= I18N::translate('Media') ?>
704        </h2>
705    </div>
706    <div class="card-body">
707        <ul class="fa-ul">
708            <li>
709                <span class="fa-li"><?= view('icons/preferences') ?></span>
710                <a href="<?= e(route(ManageMediaPage::class)) ?>">
711                    <?= I18N::translate('Manage media') ?>
712                </a>
713            </li>
714            <li>
715                <span class="fa-li"><?= view('icons/upload') ?></span>
716                <a href="<?= e(route(UploadMediaPage::class)) ?>">
717                    <?= I18N::translate('Upload media files') ?>
718                </a>
719            </li>
720            <li>
721                <span class="fa-li"><?= view('icons/link') ?></span>
722                <a href="<?= e(route('admin-fix-level-0-media')) ?>">
723                    <?= I18N::translate('Link media objects to facts and events') ?>
724                </a>
725            </li>
726            <li>
727                <span class="fa-li"><?= view('icons/upload') ?></span>
728                <a href="<?= e(route('admin-webtrees1-thumbs')) ?>">
729                    <?= I18N::translate('Import custom thumbnails from webtrees version 1') ?>
730                </a>
731            </li>
732        </ul>
733    </div>
734</div>
735
736<!-- MAPS -->
737<div class="card mb-4">
738    <div class="card-header">
739        <h2 class="mb-0">
740            <?= I18N::translate('Map') ?>
741        </h2>
742    </div>
743    <div class="card-body">
744        <div class="row">
745            <div class="col-sm-6">
746                <ul class="fa-ul">
747                    <li>
748                        <span class="fa-li"><?= view('icons/location') ?></span>
749                        <a href="<?= e(route(MapDataList::class)) ?>">
750                            <?= I18N::translate('Geographic data') ?>
751                        </a>
752                    </li>
753                </ul>
754            </div>
755            <div class="col-sm-6">
756                <ul class="fa-ul">
757                    <li>
758                        <span class="fa-li"><?= view('icons/map') ?></span>
759                        <a href="<?= e(route('map-provider')) ?>">
760                            <?= I18N::translate('Map provider') ?>
761                        </a>
762                    </li>
763                </ul>
764            </div>
765        </div>
766    </div>
767</div>
768
769<!-- OLD FILES -->
770<?php if (!empty($files_to_delete)) : ?>
771    <div class="card mb-4 card-outline-danger">
772        <div class="card-header">
773            <h2 class="mb-0">
774                <?= I18N::translate('Old files found') ?>
775            </h2>
776        </div>
777        <div class="card-body">
778            <p>
779                <?= I18N::translate('Files have been found from a previous version of webtrees. Old files can sometimes be a security risk. You should delete them.') ?>
780            </p>
781            <ul class="list-unstyled">
782                <?php foreach ($files_to_delete as $file_to_delete) : ?>
783                    <li dir="ltr">
784                        <code><?= e($file_to_delete) ?></code>
785                    </li>
786                <?php endforeach ?>
787            </ul>
788        </div>
789    </div>
790<?php endif ?>
791