Improved the admin section - added breadcrumb navigation and a nice looking dashboard

This commit is contained in:
Andy Heathershaw 2016-09-09 15:06:34 +01:00
parent 504134caa7
commit 3af7708933
21 changed files with 277 additions and 55 deletions

View File

@ -32,7 +32,10 @@ class LocalFilesystemSource implements IAlbumSource
public function deleteAlbumContents() public function deleteAlbumContents()
{ {
$this->recursiveDelete($this->getPathToAlbum()); if (file_exists($this->getPathToAlbum()) && is_dir($this->getPathToAlbum()))
{
$this->recursiveDelete($this->getPathToAlbum());
}
} }
public function deleteThumbnail(Photo $photo, $thumbnail = null) public function deleteThumbnail(Photo $photo, $thumbnail = null)

View File

@ -146,7 +146,7 @@ class AlbumController extends Controller
$album->generateAlias(); $album->generateAlias();
$album->save(); $album->save();
return redirect(route('albums.index')); return redirect(route('albums.show', ['id' => $album->id]));
} }
/** /**

View File

@ -11,6 +11,7 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\SaveSettingsRequest; use App\Http\Requests\SaveSettingsRequest;
use App\Mail\TestMailConfig; use App\Mail\TestMailConfig;
use App\Photo; use App\Photo;
use App\User;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@ -25,10 +26,19 @@ class DefaultController extends Controller
$albumCount = Album::all()->count(); $albumCount = Album::all()->count();
$photoCount = Photo::all()->count(); $photoCount = Photo::all()->count();
$userCount = User::where('is_activated', true)->count();
return Theme::render('admin.index', [ return Theme::render('admin.index', [
'album_count' => $albumCount, 'album_count' => $albumCount,
'photo_count' => $photoCount 'app_version' => config('app.version'),
'memory_limit' => ini_get('memory_limit'),
'photo_count' => $photoCount,
'php_version' => phpversion(),
'os_version' => exec('lsb_release -ds 2>/dev/null || cat /etc/*release 2>/dev/null | head -n1 || uname -om'),
'server_name' => gethostname(),
'upload_file_size' => ini_get('upload_max_filesize'),
'upload_max_limit' => ini_get('post_max_size'),
'user_count' => $userCount
]); ]);
} }

View File

@ -4,12 +4,12 @@
font-family: Raleway, sans-serif; font-family: Raleway, sans-serif;
} }
body { .album-container .photo {
padding-bottom: 40px; margin-bottom: 20px;
} }
.album-index img { body {
max-width: 100%; padding-bottom: 40px;
} }
div.breadcrumb { div.breadcrumb {
@ -31,6 +31,10 @@ ol.breadcrumb {
margin-right: 5px; margin-right: 5px;
} }
.page-title {
margin-top: 0;
}
.panel .progress { .panel .progress {
margin-top: 20px; margin-top: 20px;
margin-bottom: 0; margin-bottom: 0;
@ -62,6 +66,16 @@ ol.breadcrumb {
font-weight: bold; font-weight: bold;
} }
#system-info .meta-label
{
width: 30%;
}
#system-info .meta-value
{
font-weight: bold;
}
.tab-content { .tab-content {
border: solid 1px #ddd; border: solid 1px #ddd;
border-top: 0; border-top: 0;

View File

@ -1,6 +1,9 @@
<?php <?php
return [ return [
'actions_panel' => 'Actions', 'actions_widget' => [
'create_album_link' => 'Create album',
'panel_header' => 'Actions',
],
'album_no_photos_p1' => 'No photos in this album', 'album_no_photos_p1' => 'No photos in this album',
'album_no_photos_p2' => 'Click the "Upload photos" button below to get started.', 'album_no_photos_p2' => 'Click the "Upload photos" button below to get started.',
'album_no_photos_button' => 'Upload photos', 'album_no_photos_button' => 'Upload photos',
@ -10,19 +13,40 @@ return [
'create_album' => 'Create a photo album', 'create_album' => 'Create a photo album',
'create_album_intro' => 'Photo albums contain individual photographs together in the same way as a physical photo album or memory book.', 'create_album_intro' => 'Photo albums contain individual photographs together in the same way as a physical photo album or memory book.',
'create_album_intro2' => 'Complete the form below to create a photo album.', 'create_album_intro2' => 'Complete the form below to create a photo album.',
'create_album_link' => 'Create album',
'delete_album' => 'Delete album :name', 'delete_album' => 'Delete album :name',
'delete_album_confirm' => 'Are you sure you want to permanently delete this album and all its contents?', 'delete_album_confirm' => 'Are you sure you want to permanently delete this album and all its contents?',
'delete_album_warning' => 'This is a permanent action that cannot be undone!', 'delete_album_warning' => 'This is a permanent action that cannot be undone!',
'edit_album' => 'Edit photo album: :album_name',
'edit_album_intro' => 'Photo albums contain individual photographs together in the same way as a physical photo album or memory book.',
'edit_album_intro2' => 'Complete the form below to edit the properties of the album: :album_name.',
'list_albums_name_column' => 'Album name', 'list_albums_name_column' => 'Album name',
'manage_widget' => [
'panel_header' => 'Manage'
],
'no_albums_text' => 'You have no photo albums yet. Click the button below to create one.', 'no_albums_text' => 'You have no photo albums yet. Click the button below to create one.',
'no_albums_title' => 'No Photo Albums', 'no_albums_title' => 'No Photo Albums',
'open_album' => 'Open album',
'settings_link' => 'Settings', 'settings_link' => 'Settings',
'settings_save_action' => 'Update Settings', 'settings_save_action' => 'Update Settings',
'settings_saved_message' => 'The settings were updated successfully.', 'settings_saved_message' => 'The settings were updated successfully.',
'settings_test_email_action' => 'Send a test e-mail', 'settings_test_email_action' => 'Send a test e-mail',
'settings_title' => 'Settings', 'settings_title' => 'Settings',
'stats_albums' => 'album|albums', 'stats_widget' => [
'stats_panel' => 'Statistics', 'albums' => 'album|albums',
'stats_photos' => 'photo|photos' 'panel_header' => 'Statistics',
'photos' => 'photo|photos',
'users' => 'user|users',
],
'sysinfo_panel' => 'System information',
'sysinfo_widget' => [
'app_version' => 'Blue Twilight version:',
'hostname' => 'Server name:',
'memory_limit' => 'Memory limit:',
'os' => 'Operating system:',
'php_version' => 'PHP version:',
'theme' => 'Visual theme:',
'upload_file_size' => 'Upload limit (each file):',
'upload_max_limit' => 'Upload limit (maximum size):'
],
'title' => 'Gallery Admin'
]; ];

View File

@ -1,7 +1,4 @@
<?php <?php
return [ return [
'app_name' => 'Blue Twilight', 'app_name' => 'Blue Twilight'
'nav_admin' => 'Manage',
'nav_admin_control' => 'Control Panel',
'nav_admin_albums' => 'Albums'
]; ];

View File

@ -0,0 +1,20 @@
<?php
return [
'breadcrumb' => [
'admin' => 'Admin',
'albums' => 'Albums',
'create_album' => 'Create album',
'delete_album' => 'Delete album',
'edit_album' => 'Edit album',
'home' => 'Gallery',
'settings' => 'Settings',
'users' => 'Users'
],
'navbar' => [
'admin' => 'Manage',
'albums' => 'Albums',
'login' => 'Login',
'logout' => 'Logout',
'register' => 'Register'
]
];

View File

@ -1,6 +1,19 @@
@extends('themes.base.layout') @extends('themes.base.layout')
@section('title', 'Gallery Admin') @section('title', 'Gallery Admin')
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}">@lang('navigation.breadcrumb.home')</a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
<li class="active">@lang('navigation.breadcrumb.create_album')</li>
</ol>
</div>
</div>
@endsection
@section('content') @section('content')
<div class="container"> <div class="container">
<div class="row"> <div class="row">

View File

@ -1,6 +1,20 @@
@extends('themes.base.layout') @extends('themes.base.layout')
@section('title', trans('admin.delete_album', ['name' => $album->name])) @section('title', trans('admin.delete_album', ['name' => $album->name]))
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}">@lang('navigation.breadcrumb.home')</a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
<li><a href="{{ route('albums.show', ['id' => $album->id]) }}">{{ $album->name }}</a></li>
<li class="active">@lang('navigation.breadcrumb.delete_album')</li>
</ol>
</div>
</div>
@endsection
@section('content') @section('content')
<div class="container"> <div class="container">
<div class="row"> <div class="row">

View File

@ -1,13 +1,27 @@
@extends('themes.base.layout') @extends('themes.base.layout')
@section('title', 'Gallery Admin') @section('title', 'Gallery Admin')
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}">@lang('navigation.breadcrumb.home')</a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
<li><a href="{{ route('albums.show', ['id' => $album->id]) }}">{{ $album->name }}</a></li>
<li class="active">@lang('navigation.breadcrumb.edit_album')</li>
</ol>
</div>
</div>
@endsection
@section('content') @section('content')
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<h1>@lang('admin.create_album')</h1> <h1>@lang('admin.edit_album', ['album_name' => $album->name])</h1>
<p>@lang('admin.create_album_intro')</p> <p>@lang('admin.edit_album_intro')</p>
<p>@lang('admin.create_album_intro2')</p> <p>@lang('admin.edit_album_intro2', ['album_name' => $album->name])</p>
<hr/> <hr/>
@if (count($errors) > 0) @if (count($errors) > 0)

View File

@ -1,31 +1,28 @@
@extends('themes.base.layout') @extends('themes.base.layout')
@section('title', 'Gallery Admin') @section('title', 'Gallery Admin')
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}">@lang('navigation.breadcrumb.home')</a></li>
<li class="active">@lang('navigation.breadcrumb.admin')</li>
</ol>
</div>
</div>
@endsection
@section('content') @section('content')
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-4"> <div class="col-xs-12 col-sm-8">
<div class="panel panel-default"> @include (Theme::viewName('partials.admin_sysinfo_widget'))
<div class="panel-heading">@lang('admin.stats_panel')</div>
<div class="panel-body">
<p>
<a href="{{ route('albums.index') }}">
<b>{{ $album_count }}</b> {{ trans_choice('admin.stats_albums', $album_count) }}
</a><br/>
<b>{{ $photo_count }}</b> {{ trans_choice('admin.stats_photos', $photo_count) }}
</p>
</div>
</div>
</div> </div>
<div class="col-xs-12 col-sm-4"> <div class="col-xs-12 col-sm-4">
<div class="panel panel-default"> @include (Theme::viewName('partials.admin_actions_widget'))
<div class="panel-heading">@lang('admin.actions_panel')</div> @include (Theme::viewName('partials.admin_manage_widget'))
<div class="panel-body"> @include (Theme::viewName('partials.admin_stats_widget'))
<a href="{{ route('albums.create') }}" class="btn btn-default"><i class="fa fa-fw fa-plus"></i> @lang('admin.create_album_link')</a>
<a href="{{ route('admin.settings') }}" class="btn btn-default"><i class="fa fa-fw fa-cog"></i> @lang('admin.settings_link')</a>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,18 @@
@extends('themes.base.layout') @extends('themes.base.layout')
@section('title', 'Gallery Admin') @section('title', 'Gallery Admin')
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}">@lang('navigation.breadcrumb.home')</a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li class="active">@lang('navigation.breadcrumb.albums')</li>
</ol>
</div>
</div>
@endsection
@section('content') @section('content')
<div class="container"> <div class="container">
<div class="row"> <div class="row">

View File

@ -1,6 +1,18 @@
@extends('themes.base.layout') @extends('themes.base.layout')
@section('title', trans('admin.settings_title')) @section('title', trans('admin.settings_title'))
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}">@lang('navigation.breadcrumb.home')</a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li class="active">@lang('navigation.breadcrumb.settings')</li>
</ol>
</div>
</div>
@endsection
@section('content') @section('content')
<div class="container"> <div class="container">
<div class="row"> <div class="row">

View File

@ -1,11 +1,26 @@
@extends('themes.base.layout') @extends('themes.base.layout')
@section('title', $album->name) @section('title', $album->name)
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}">@lang('navigation.breadcrumb.home')</a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
<li class="active">{{ $album->name }}</li>
</ol>
</div>
</div>
@endsection
@section('content') @section('content')
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<h1>{{ $album->name }}</h1> <a class="pull-right btn btn-default" href="{{ $album->url() }}" target="_blank"><i class="fa fa-fw fa-eye"></i> @lang('admin.open_album')</a>
<h1 class="page-title">{{ $album->name }}</h1>
<p>{{ $album->description }}</p> <p>{{ $album->description }}</p>
<hr/> <hr/>

View File

@ -1,5 +1,5 @@
@extends('themes.base.layout') @extends('themes.base.layout')
@section('title', 'Welcome') @section('title', $album->name)
@section('breadcrumb') @section('breadcrumb')
<div class="breadcrumb"> <div class="breadcrumb">
@ -13,11 +13,24 @@
@endsection @endsection
@section('content') @section('content')
<div class="container"> <div class="container album-container">
<div class="row">
<div class="col-xs-12">
<h1 class="page-title">{{ $album->name }}</h1>
<p>{{ $album->description }}</p>
<hr/>
</div>
</div>
<div class="row"> <div class="row">
@foreach ($photos as $photo) @foreach ($photos as $photo)
<div class="col-xs-12 col-sm-4"> <div class="col-xs-6 col-sm-4 photo">
<a href="{{ $photo->url() }}"><img src="{{ $photo->thumbnailUrl('preview') }}" alt="" class="img-thumbnail"/></a> <div class="panel panel-default">
<div class="panel-body" style="padding: 0;">
<a href="{{ $photo->url() }}"><img src="{{ $photo->thumbnailUrl('preview') }}" alt="" class="img-responsive"/></a>
</div>
<div class="panel-footer"><b><a href="{{ $photo->url() }}">{{ $photo->name }}</a></b></div>
</div>
</div> </div>
@endforeach @endforeach
</div> </div>

View File

@ -5,8 +5,8 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
@foreach ($albums as $album) @foreach ($albums as $album)
<div class="col-xs-12 col-sm-4"> <div class="col-xs-6 col-sm-4">
<div class="panel panel-default album-index"> <div class="panel panel-default">
<div class="panel-heading"><a href="{{ $album->url() }}">{{ $album->name }}</a></div> <div class="panel-heading"><a href="{{ $album->url() }}">{{ $album->name }}</a></div>
<div class="panel-body"> <div class="panel-body">
<p class="text-center"> <p class="text-center">

View File

@ -0,0 +1,6 @@
<div class="panel panel-default">
<div class="panel-heading">@lang('admin.actions_widget.panel_header')</div>
<div class="panel-body">
<a href="{{ route('albums.create') }}"><i class="fa fa-fw fa-plus"></i> @lang('admin.actions_widget.create_album_link')</a>
</div>
</div>

View File

@ -0,0 +1,10 @@
<div class="panel panel-default">
<div class="panel-heading">@lang('admin.manage_widget.panel_header')</div>
<div class="panel-body">
<ul class="nav nav-pills">
<li role="presentation"><a href="{{ route('albums.index') }}"><i class="fa fa-fw fa-picture-o"></i> @lang('navigation.breadcrumb.albums')</a></li>
<li role="presentation"><a href="#"><i class="fa fa-fw fa-user"></i> @lang('navigation.breadcrumb.users')</a></li>
<li role="presentation"><a href="{{ route('admin.settings') }}"><i class="fa fa-fw fa-cog"></i> @lang('admin.settings_link')</a></li>
</ul>
</div>
</div>

View File

@ -0,0 +1,10 @@
<div class="panel panel-default">
<div class="panel-heading">@lang('admin.stats_widget.panel_header')</div>
<div class="panel-body">
<p>
<b>{{ $album_count }}</b> {{ trans_choice('admin.stats_widget.albums', $album_count) }}<br/>
<b>{{ $photo_count }}</b> {{ trans_choice('admin.stats_widget.photos', $photo_count) }}<br/>
<b>{{ $user_count }}</b> {{ trans_choice('admin.stats_widget.users', $user_count) }}
</p>
</div>
</div>

View File

@ -0,0 +1,41 @@
<div class="panel panel-default">
<div class="panel-heading">@lang('admin.sysinfo_panel')</div>
<div class="panel-body" style="padding: 0;">
<table id="system-info" class="table table-striped" style="margin-bottom: 0;">
<tbody>
<tr>
<td class="meta-label">@lang('admin.sysinfo_widget.app_version')</td>
<td class="meta-value">{{ $app_version }}</td>
</tr>
<tr>
<td class="meta-label">@lang('admin.sysinfo_widget.hostname')</td>
<td class="meta-value">{{ $server_name }}</td>
</tr>
<tr>
<td class="meta-label">@lang('admin.sysinfo_widget.os')</td>
<td class="meta-value">{{ $os_version }}</td>
</tr>
<tr>
<td class="meta-label">@lang('admin.sysinfo_widget.php_version')</td>
<td class="meta-value">{{ $php_version }}</td>
</tr>
<tr>
<td class="meta-label">@lang('admin.sysinfo_widget.theme')</td>
<td class="meta-value">{{ Theme::info()['name'] }}</td>
</tr>
<tr>
<td class="meta-label">@lang('admin.sysinfo_widget.memory_limit')</td>
<td class="meta-value">{{ $memory_limit }}</td>
</tr>
<tr>
<td class="meta-label">@lang('admin.sysinfo_widget.upload_file_size')</td>
<td class="meta-value">{{ $upload_file_size }}</td>
</tr>
<tr>
<td class="meta-label">@lang('admin.sysinfo_widget.upload_max_limit')</td>
<td class="meta-value">{{ $upload_max_limit }}</td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@ -14,23 +14,20 @@
<!-- Collect the nav links, forms, and other content for toggling --> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
@if (count($albums) > 0)
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Albums <span class="caret"></span></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">@lang('navigation.navbar.albums') <span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
@foreach ($albums as $album) @foreach ($albums as $album)
<li><a href="{{ $album->url() }}">{{ $album->name }}</a></li> <li><a href="{{ $album->url() }}">{{ $album->name }}</a></li>
@endforeach @endforeach
</ul> </ul>
</li> </li>
@endif
@can('admin-access') @can('admin-access')
<li class="dropdown"> <li class="dropdown">
<a href="{{ route('admin') }}" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">@lang('global.nav_admin') <span class="caret"></span></a> <li><a href="{{ route('admin') }}"><i class="fa fa-fw fa-cog"></i> @lang('navigation.navbar.admin')</a></li>
<ul class="dropdown-menu">
<li><a href="{{ route('admin') }}">@lang('global.nav_admin_control')</a></li>
<li role="separator" class="divider"></li>
<li><a href="{{ route('albums.index') }}">@lang('global.nav_admin_albums')</a></li>
</ul>
</li> </li>
@endcan @endcan
</ul> </ul>
@ -38,10 +35,10 @@
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
{{-- Authentication Links --}} {{-- Authentication Links --}}
@if (Auth::guest()) @if (Auth::guest())
<li><a href="{{ url('/login') }}">Login</a></li> <li><a href="{{ url('/login') }}">@lang('navigation.navbar.login')</a></li>
@if (UserConfig::get('allow_self_registration') == 1) @if (UserConfig::get('allow_self_registration') == 1)
<li><a href="{{ url('/register') }}">Register</a></li> <li><a href="{{ url('/register') }}">@lang('navigation.navbar.register')</a></li>
@endif @endif
@else @else
<li class="dropdown"> <li class="dropdown">
@ -53,7 +50,7 @@
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li> <li>
<a href="{{ url('/logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">Logout</a> <a href="{{ url('/logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">@lang('navigation.navbar.logout')</a>
<form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display: none;"> <form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display: none;">
{{ csrf_field() }} {{ csrf_field() }}