From 6afe85c2d9958e0467e68732818f8f705260825f Mon Sep 17 00:00:00 2001 From: Kevin MacMartin Date: Wed, 25 Apr 2018 01:22:33 -0400 Subject: [PATCH] Use a common trait to provide the timestamp function to both the DashboardModel and User classes, add an optional license key to the dashboard library_credits that adds a (license) link beside the project and add the license (as required by their license) to the fontawesome entry, and implement user profile image view, upload and deletion (with a default black question mark fallback) in the dashboard settings page --- app/Dashboard.php | 2 +- app/Http/Controllers/DashboardController.php | 173 +++++++++++------- app/Models/DashboardModel.php | 12 +- app/Traits/Timestamp.php | 15 ++ app/User.php | 43 +++++ public/img/dashboard/trash-alt.svg | 1 + public/img/dashboard/upload.svg | 1 + public/img/profile.png | Bin 0 -> 4076 bytes resources/assets/js/dashboard.js | 110 +++++++++-- resources/assets/sass/dashboard.scss | 77 ++++++++ .../views/dashboard/pages/credits.blade.php | 8 +- .../views/dashboard/pages/settings.blade.php | 13 ++ routes/web.php | 17 +- 13 files changed, 368 insertions(+), 104 deletions(-) create mode 100644 app/Traits/Timestamp.php create mode 100644 public/img/dashboard/trash-alt.svg create mode 100644 public/img/dashboard/upload.svg create mode 100644 public/img/profile.png diff --git a/app/Dashboard.php b/app/Dashboard.php index 0308252..4f69c65 100644 --- a/app/Dashboard.php +++ b/app/Dashboard.php @@ -50,7 +50,7 @@ class Dashboard */ public static $library_credits = [ [ 'name' => 'Bootstrap', 'url' => 'https://getbootstrap.com' ], - [ 'name' => 'Font Awesome', 'url' => 'https://fontawesome.com' ], + [ 'name' => 'Font Awesome', 'url' => 'https://fontawesome.com', 'license' => 'https://fontawesome.com/license' ], [ 'name' => 'GreenSock', 'url' => 'https://greensock.com/gsap' ], [ 'name' => 'jQuery', 'url' => 'https://jquery.org' ], [ 'name' => 'List.js', 'url' => 'http://listjs.com' ], diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 64a4c6c..e02dbd4 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -2,11 +2,11 @@ use App\Http\Requests; use Illuminate\Http\Request; +use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use Auth; use File; use Image; -use PhpOffice\PhpSpreadsheet\Spreadsheet; -use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use App\User; use App\Dashboard; @@ -21,34 +21,14 @@ class DashboardController extends Controller { } /** - * Dashboard home + * Dashboard CMS */ public function getIndex() { return view('dashboard.pages.home'); } - /** - * Project credits - */ - public function getCredits() - { - return view('dashboard.pages.credits'); - } - - /** - * Dashboard settings - */ - public function getSettings() - { - return view('dashboard.pages.settings', [ - 'user' => User::find(Auth::id()) - ]); - } - - /** - * Dashboard View - */ + // View Model Data public function getView($model) { $model_class = Dashboard::getModel($model, 'view'); @@ -66,9 +46,7 @@ class DashboardController extends Controller { } } - /** - * Dashboard Edit List - */ + // Edit List of Model Rows public function getEditList($model) { $model_class = Dashboard::getModel($model, 'edit'); @@ -91,9 +69,7 @@ class DashboardController extends Controller { } } - /** - * Dashboard Edit Item - */ + // Create and Edit Model Item public function getEditItem($model, $id = 'new') { $model_class = Dashboard::getModel($model, 'edit'); @@ -126,9 +102,7 @@ class DashboardController extends Controller { } } - /** - * Dashboard Export: Export data as a spreadsheet - */ + // Export Spreadsheet of Model Data public function getExport($model) { $model_class = Dashboard::getModel($model); @@ -151,9 +125,7 @@ class DashboardController extends Controller { } } - /** - * Dashboard Reorder: Reorder rows - */ + // Reorder Model Rows public function postReorder(Request $request) { $this->validate($request, [ @@ -181,9 +153,7 @@ class DashboardController extends Controller { } } - /** - * Dashboard Update: Create and update rows - */ + // Create and Update Model Item Data public function postUpdate(Request $request) { $this->validate($request, [ @@ -222,9 +192,7 @@ class DashboardController extends Controller { } } - /** - * Dashboard Image Upload: Upload images - */ + // Upload Model Item Image public function postImageUpload(Request $request) { $this->validate($request, [ @@ -257,9 +225,7 @@ class DashboardController extends Controller { } } - /** - * Dashboard File Upload: Upload files - */ + // Upload Model Item File public function postFileUpload(Request $request) { $this->validate($request, [ @@ -292,26 +258,7 @@ class DashboardController extends Controller { } } - /** - * User Password: Change the current user's password - */ - public function postUserPassword(Request $request) - { - $this->validate($request, [ - 'oldpass' => 'required|string|min:6', - 'newpass' => 'required|string|min:6|confirmed' - ]); - - if (User::find(Auth::id())->updatePassword($request['oldpass'], $request['newpass'])) { - return 'success'; - } else { - return 'old-password-fail'; - } - } - - /** - * Dashboard Delete: Delete rows - */ + // Delete Model Item public function deleteDelete(Request $request) { $this->validate($request, [ @@ -357,9 +304,7 @@ class DashboardController extends Controller { } } - /** - * Dashboard Image Delete: Delete images - */ + // Delete Model Item Image public function deleteImageDelete(Request $request) { $this->validate($request, [ @@ -390,9 +335,7 @@ class DashboardController extends Controller { } } - /** - * Dashboard File Delete: Delete files - */ + // Delete Model Item File public function deleteFileDelete(Request $request) { $this->validate($request, [ @@ -424,4 +367,92 @@ class DashboardController extends Controller { } } + /** + * Dashboard settings + */ + public function getSettings() + { + return view('dashboard.pages.settings', [ + 'user' => User::find(Auth::id()) + ]); + } + + // User Password Update + public function postUserPasswordUpdate(Request $request) + { + $this->validate($request, [ + 'oldpass' => 'required|string|min:6', + 'newpass' => 'required|string|min:6|confirmed' + ]); + + if (User::find(Auth::id())->updatePassword($request['oldpass'], $request['newpass'])) { + return 'success'; + } else { + return 'old-password-fail'; + } + } + + // User Profile Image Upload + public function postUserProfileImageUpload(Request $request) + { + if ($request->hasFile('file')) { + $user = User::find(Auth::id()); + + if ($user !== null) { + $image = Image::make($request->file('file')); + $max_width = User::$profile_image_max['width']; + $max_height = User::$profile_image_max['height']; + + if ($image->width() > $max_width || $image->height() > $max_height) { + $new_width = $max_width; + $new_height = ($new_width / $image->width()) * $image->height(); + + if ($new_height > $max_height) { + $new_height = $max_height; + $new_width = ($new_height / $image->height()) * $image->width(); + } + + $image->resize($new_width, $new_height); + } + + file::makeDirectory(base_path() . '/public' . User::$profile_image_dir, 0755, true, true); + $image->save($user->profileImage(true, true)); + $user->touch(); + return $user->profileImage() . '?version=' . $user->timestamp(); + } else { + return 'record-access-fail'; + } + } else { + return 'file-upload-fail'; + } + } + + // User Profile Image Delete + public function deleteUserProfileImageDelete(Request $request) + { + $user = User::find(Auth::id()); + + if ($user !== null) { + $profile_image = $user->profileImage(true); + + if ($profile_image === null) { + return 'image-not-exists-fail'; + } else if (!unlink($profile_image)) { + return 'image-delete-fail'; + } + + return 'success'; + } else { + return 'record-access-fail'; + } + } + + /** + * Credits Page + */ + public function getCredits() + { + return view('dashboard.pages.credits'); + } + } diff --git a/app/Models/DashboardModel.php b/app/Models/DashboardModel.php index 1338fb5..44c59fe 100644 --- a/app/Models/DashboardModel.php +++ b/app/Models/DashboardModel.php @@ -4,9 +4,12 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Auth; +use App\Traits\Timestamp; class DashboardModel extends Model { + use Timestamp; + /* * The dashboard page type * @@ -168,13 +171,4 @@ class DashboardModel extends Model return $user_check; } - - /** - * Returns the Unix timestamp of the latest update - * - * @return number - */ - public function timestamp() { - return strtotime($this->updated_at); - } } diff --git a/app/Traits/Timestamp.php b/app/Traits/Timestamp.php new file mode 100644 index 0000000..c2f41dd --- /dev/null +++ b/app/Traits/Timestamp.php @@ -0,0 +1,15 @@ +updated_at); + } +} diff --git a/app/User.php b/app/User.php index 95d5c73..c3b71ca 100644 --- a/app/User.php +++ b/app/User.php @@ -5,10 +5,12 @@ namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; use Hash; +use App\Traits\Timestamp; class User extends Authenticatable { use Notifiable; + use Timestamp; /** * The attributes that are mass assignable. @@ -28,6 +30,30 @@ class User extends Authenticatable 'password', 'remember_token', 'api_token' ]; + /** + * The default user profile image + * + * @var string + */ + public static $default_profile_image = '/img/profile.png'; + + /** + * The directory user profile uploads are stored in + * + * @var string + */ + public static $profile_image_dir = '/uploads/user/img/'; + + /** + * The maximum profile image width and height + * + * @var array + */ + public static $profile_image_max = [ + 'width' => 512, + 'height' => 512 + ]; + /** * Update the user's password * @@ -43,4 +69,21 @@ class User extends Authenticatable return false; } + + /** + * Get user profile image + * + * @var string + */ + public function profileImage($show_full_path = false, $always_return_path = false) + { + $site_path = self::$profile_image_dir . $this->id . '-profile.png'; + $file_path = base_path() . '/public' . $site_path; + + if (file_exists($file_path) || $always_return_path) { + return $show_full_path ? $file_path : $site_path; + } else { + return null; + } + } } diff --git a/public/img/dashboard/trash-alt.svg b/public/img/dashboard/trash-alt.svg new file mode 100644 index 0000000..a921fe8 --- /dev/null +++ b/public/img/dashboard/trash-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/dashboard/upload.svg b/public/img/dashboard/upload.svg new file mode 100644 index 0000000..1c880b5 --- /dev/null +++ b/public/img/dashboard/upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/profile.png b/public/img/profile.png new file mode 100644 index 0000000000000000000000000000000000000000..b5ae4adca9565e0e46790ecbe87f34d9209a73c3 GIT binary patch literal 4076 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 literal 0 HcmV?d00001 diff --git a/resources/assets/js/dashboard.js b/resources/assets/js/dashboard.js index 21c742b..9b9d2d0 100644 --- a/resources/assets/js/dashboard.js +++ b/resources/assets/js/dashboard.js @@ -625,6 +625,83 @@ function editItemInit() { }); } +function userProfileImageInit() { + const $form = $("#user-profile-image"), + $upload = $("#profile-image-upload"), + $delete = $("#profile-image-delete"), + $token = $("#token"), + $displayInner = $form.find(".image-display-inner").first(); + + let file, + submitting = false; + + $upload.on("change", function() { + if ($upload.val() !== "" && !submitting) { + submitting = true; + + askConfirmation("Update your user profile image?", function() { + // show the loading modal + showLoadingModal(); + + // add the image to the form data + file = new FormData(); + file.append("file", $upload[0].files[0]); + + // submit the form data + $.ajax({ + type: "POST", + url: "/dashboard/user/profile-image-upload", + data: file, + processData: false, + contentType: false, + beforeSend: function(xhr) { xhr.setRequestHeader("X-CSRF-TOKEN", $token.val()); } + }).always(function(response) { + hideLoadingModal(); + submitting = false; + + if (/\.png\?version=/.test(response)) { + $displayInner.css({ backgroundImage: `url(${response})` }); + $delete.removeClass("inactive"); + } else { + showAlert("Failed to upload image"); + } + }); + }, function() { + $upload.val(""); + submitting = false; + }); + } + }); + + $delete.on("click", function() { + if (!submitting) { + submitting = true; + + askConfirmation("Delete your profile image?", function() { + // delete the profile image + $.ajax({ + type: "DELETE", + url: "/dashboard/user/profile-image-delete", + data: { + _token: $token.val() + } + }).always(function(response) { + if (response === "success") { + $displayInner.css({ backgroundImage: "none" }); + $delete.addClass("inactive"); + } else { + showAlert("Failed to delete profile image"); + } + + submitting = false; + }); + }, function() { + submitting = false; + }); + } + }); +} + function userPasswordInit() { const $form = $("#user-password"), $submit = $form.find(".submit-button"), @@ -691,27 +768,22 @@ function userPasswordInit() { // submit the update $.ajax({ type: "POST", - url: "/dashboard/user-password", + url: "/dashboard/user/password-update", data: formData }).always(function(response) { + hideLoadingModal(); + submitting = false; + if (response === "success") { - hideLoadingModal(); - - showAlert("Password updated successfully", function() { - $inputs.val("").trigger("change"); - }); + $inputs.val("").trigger("change"); + showAlert("Password updated successfully"); + } else if (response === "old-password-fail") { + $oldpass.addClass("error"); + showAlert("Old password is not correct"); } else { - submitting = false; - - if (response === "old-password-fail") { - $oldpass.addClass("error"); - showAlert("Old password is not correct"); - } else { - $newpass.addClass("error"); - $newpassConfirmation.val(""); - hideLoadingModal(); - showAlert("New password must be at least 6 characters"); - } + $newpass.addClass("error"); + $newpassConfirmation.val(""); + showAlert("New password must be at least 6 characters"); } }); } @@ -729,6 +801,10 @@ $(document).ready(function() { editItemInit(); } + if ($("#user-profile-image").length) { + userProfileImageInit(); + } + if ($("#user-password").length) { userPasswordInit(); } diff --git a/resources/assets/sass/dashboard.scss b/resources/assets/sass/dashboard.scss index f11bcbb..7823e55 100644 --- a/resources/assets/sass/dashboard.scss +++ b/resources/assets/sass/dashboard.scss @@ -8,6 +8,9 @@ // Core @import "_fonts"; +// Supplementary +@import "mixins/**/*.scss"; + // Colours $c-text: #111; // text $c-text-inactive: fade-out($c-text, 0.25); // inactive text @@ -802,6 +805,80 @@ body { } } } + + &.user-profile-image { + display: block; + width: 100%; + max-width: 150px; + + .image-display { + @include aspect-ratio(1, 1); + position: relative; + width: 100%; + border: 1px solid darken($c-dashboard-light, 10%); + border-radius: 3px; + background-position: center center; + background-size: cover; + background-repeat: no-repeat; + + &-inner { + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + background-position: center center; + background-size: cover; + background-repeat: no-repeat; + } + } + + .image-buttons { + margin-top: 20px; + display: flex; + justify-content: space-around; + + input { + display: none; + } + + .image-upload-button, .image-delete-button { + @include aspect-ratio(1, 1); + display: block; + width: 40px; + min-height: 0; + border: 1px solid darken($c-dashboard-light, 14%); + border-radius: 3px; + background-color: darken($c-dashboard-light, 10%); + background-position: center center; + background-size: 50% auto; + background-repeat: no-repeat; + font-size: 0px; + line-height: 1; + cursor: pointer; + + &:hover { + background-color: darken($c-dashboard-light, 7%); + } + } + + .image-upload-button { + background-image: url("/img/dashboard/upload.svg"); + transition: background-color 150ms; + } + + .image-delete-button { + background-image: url("/img/dashboard/trash-alt.svg"); + opacity: 1; + transition: background-color 150ms, opacity 150ms; + + &.inactive { + opacity: 0.35; + pointer-events: none; + } + } + } + } } #loading-modal { diff --git a/resources/views/dashboard/pages/credits.blade.php b/resources/views/dashboard/pages/credits.blade.php index 2e61446..7b278d3 100644 --- a/resources/views/dashboard/pages/credits.blade.php +++ b/resources/views/dashboard/pages/credits.blade.php @@ -16,7 +16,13 @@ diff --git a/resources/views/dashboard/pages/settings.blade.php b/resources/views/dashboard/pages/settings.blade.php index f534252..2695b92 100644 --- a/resources/views/dashboard/pages/settings.blade.php +++ b/resources/views/dashboard/pages/settings.blade.php @@ -8,6 +8,19 @@
+
diff --git a/routes/web.php b/routes/web.php index adc9063..2e2a1f7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -29,21 +29,28 @@ Route::get('/logout', 'Auth\LoginController@logout'); */ Route::group([ 'prefix' => 'dashboard' ], function() { + // Dashboard CMS Route::get('/', 'DashboardController@getIndex'); - Route::get('/credits', 'DashboardController@getCredits'); - Route::get('/settings', 'DashboardController@getSettings'); Route::get('/view/{model}', 'DashboardController@getView'); Route::get('/edit/{model}', 'DashboardController@getEditList'); Route::get('/edit/{model}/{id}', 'DashboardController@getEditItem'); Route::get('/export/{model}', 'DashboardController@getExport'); + Route::post('/reorder', 'DashboardController@postReorder'); + Route::post('/update', 'DashboardController@postUpdate'); Route::post('/image-upload', 'DashboardController@postImageUpload'); Route::post('/file-upload', 'DashboardController@postFileUpload'); - Route::post('/update', 'DashboardController@postUpdate'); - Route::post('/reorder', 'DashboardController@postReorder'); - Route::post('/user-password', 'DashboardController@postUserPassword'); Route::delete('/delete', 'DashboardController@deleteDelete'); Route::delete('/image-delete', 'DashboardController@deleteImageDelete'); Route::delete('/file-delete', 'DashboardController@deleteFileDelete'); + + // Dashboard Settings + Route::get('/settings', 'DashboardController@getSettings'); + Route::post('/user/password-update', 'DashboardController@postUserPasswordUpdate'); + Route::post('/user/profile-image-upload', 'DashboardController@postUserProfileImageUpload'); + Route::delete('/user/profile-image-delete', 'DashboardController@deleteUserProfileImageDelete'); + + // Credits Page + Route::get('/credits', 'DashboardController@getCredits'); }); /*