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