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