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