mirror of
https://github.com/prurigro/hypothetical.git
synced 2024-11-25 08:51:25 -05:00
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
This commit is contained in:
parent
83a8dede40
commit
6afe85c2d9
13 changed files with 368 additions and 104 deletions
|
@ -50,7 +50,7 @@ class Dashboard
|
||||||
*/
|
*/
|
||||||
public static $library_credits = [
|
public static $library_credits = [
|
||||||
[ 'name' => 'Bootstrap', 'url' => 'https://getbootstrap.com' ],
|
[ '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' => 'GreenSock', 'url' => 'https://greensock.com/gsap' ],
|
||||||
[ 'name' => 'jQuery', 'url' => 'https://jquery.org' ],
|
[ 'name' => 'jQuery', 'url' => 'https://jquery.org' ],
|
||||||
[ 'name' => 'List.js', 'url' => 'http://listjs.com' ],
|
[ 'name' => 'List.js', 'url' => 'http://listjs.com' ],
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
use App\Http\Requests;
|
use App\Http\Requests;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
use Auth;
|
use Auth;
|
||||||
use File;
|
use File;
|
||||||
use Image;
|
use Image;
|
||||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
||||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
||||||
use App\User;
|
use App\User;
|
||||||
use App\Dashboard;
|
use App\Dashboard;
|
||||||
|
|
||||||
|
@ -21,34 +21,14 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dashboard home
|
* Dashboard CMS
|
||||||
*/
|
*/
|
||||||
public function getIndex()
|
public function getIndex()
|
||||||
{
|
{
|
||||||
return view('dashboard.pages.home');
|
return view('dashboard.pages.home');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// View Model Data
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public function getView($model)
|
public function getView($model)
|
||||||
{
|
{
|
||||||
$model_class = Dashboard::getModel($model, 'view');
|
$model_class = Dashboard::getModel($model, 'view');
|
||||||
|
@ -66,9 +46,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Edit List of Model Rows
|
||||||
* Dashboard Edit List
|
|
||||||
*/
|
|
||||||
public function getEditList($model)
|
public function getEditList($model)
|
||||||
{
|
{
|
||||||
$model_class = Dashboard::getModel($model, 'edit');
|
$model_class = Dashboard::getModel($model, 'edit');
|
||||||
|
@ -91,9 +69,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Create and Edit Model Item
|
||||||
* Dashboard Edit Item
|
|
||||||
*/
|
|
||||||
public function getEditItem($model, $id = 'new')
|
public function getEditItem($model, $id = 'new')
|
||||||
{
|
{
|
||||||
$model_class = Dashboard::getModel($model, 'edit');
|
$model_class = Dashboard::getModel($model, 'edit');
|
||||||
|
@ -126,9 +102,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Export Spreadsheet of Model Data
|
||||||
* Dashboard Export: Export data as a spreadsheet
|
|
||||||
*/
|
|
||||||
public function getExport($model)
|
public function getExport($model)
|
||||||
{
|
{
|
||||||
$model_class = Dashboard::getModel($model);
|
$model_class = Dashboard::getModel($model);
|
||||||
|
@ -151,9 +125,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Reorder Model Rows
|
||||||
* Dashboard Reorder: Reorder rows
|
|
||||||
*/
|
|
||||||
public function postReorder(Request $request)
|
public function postReorder(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
|
@ -181,9 +153,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Create and Update Model Item Data
|
||||||
* Dashboard Update: Create and update rows
|
|
||||||
*/
|
|
||||||
public function postUpdate(Request $request)
|
public function postUpdate(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
|
@ -222,9 +192,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Upload Model Item Image
|
||||||
* Dashboard Image Upload: Upload images
|
|
||||||
*/
|
|
||||||
public function postImageUpload(Request $request)
|
public function postImageUpload(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
|
@ -257,9 +225,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Upload Model Item File
|
||||||
* Dashboard File Upload: Upload files
|
|
||||||
*/
|
|
||||||
public function postFileUpload(Request $request)
|
public function postFileUpload(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
|
@ -292,26 +258,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Delete Model Item
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public function deleteDelete(Request $request)
|
public function deleteDelete(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
|
@ -357,9 +304,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Delete Model Item Image
|
||||||
* Dashboard Image Delete: Delete images
|
|
||||||
*/
|
|
||||||
public function deleteImageDelete(Request $request)
|
public function deleteImageDelete(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
|
@ -390,9 +335,7 @@ class DashboardController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Delete Model Item File
|
||||||
* Dashboard File Delete: Delete files
|
|
||||||
*/
|
|
||||||
public function deleteFileDelete(Request $request)
|
public function deleteFileDelete(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($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');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,12 @@ namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Auth;
|
use Auth;
|
||||||
|
use App\Traits\Timestamp;
|
||||||
|
|
||||||
class DashboardModel extends Model
|
class DashboardModel extends Model
|
||||||
{
|
{
|
||||||
|
use Timestamp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The dashboard page type
|
* The dashboard page type
|
||||||
*
|
*
|
||||||
|
@ -168,13 +171,4 @@ class DashboardModel extends Model
|
||||||
|
|
||||||
return $user_check;
|
return $user_check;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Unix timestamp of the latest update
|
|
||||||
*
|
|
||||||
* @return number
|
|
||||||
*/
|
|
||||||
public function timestamp() {
|
|
||||||
return strtotime($this->updated_at);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
15
app/Traits/Timestamp.php
Normal file
15
app/Traits/Timestamp.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Traits;
|
||||||
|
|
||||||
|
trait Timestamp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the Unix timestamp of the latest update
|
||||||
|
*
|
||||||
|
* @return number
|
||||||
|
*/
|
||||||
|
public function timestamp() {
|
||||||
|
return strtotime($this->updated_at);
|
||||||
|
}
|
||||||
|
}
|
43
app/User.php
43
app/User.php
|
@ -5,10 +5,12 @@ namespace App;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Hash;
|
use Hash;
|
||||||
|
use App\Traits\Timestamp;
|
||||||
|
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
use Notifiable;
|
use Notifiable;
|
||||||
|
use Timestamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
|
@ -28,6 +30,30 @@ class User extends Authenticatable
|
||||||
'password', 'remember_token', 'api_token'
|
'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
|
* Update the user's password
|
||||||
*
|
*
|
||||||
|
@ -43,4 +69,21 @@ class User extends Authenticatable
|
||||||
|
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
1
public/img/dashboard/trash-alt.svg
Normal file
1
public/img/dashboard/trash-alt.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm416 56v324c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48V140c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12zm-272 68c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208z"/></svg>
|
After Width: | Height: | Size: 600 B |
1
public/img/dashboard/upload.svg
Normal file
1
public/img/dashboard/upload.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M296 384h-80c-13.3 0-24-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c12.6 12.6 3.7 34.1-14.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h136v8c0 30.9 25.1 56 56 56h80c30.9 0 56-25.1 56-56v-8h136c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"/></svg>
|
After Width: | Height: | Size: 533 B |
BIN
public/img/profile.png
Normal file
BIN
public/img/profile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4 KiB |
110
resources/assets/js/dashboard.js
vendored
110
resources/assets/js/dashboard.js
vendored
|
@ -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() {
|
function userPasswordInit() {
|
||||||
const $form = $("#user-password"),
|
const $form = $("#user-password"),
|
||||||
$submit = $form.find(".submit-button"),
|
$submit = $form.find(".submit-button"),
|
||||||
|
@ -691,27 +768,22 @@ function userPasswordInit() {
|
||||||
// submit the update
|
// submit the update
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: "/dashboard/user-password",
|
url: "/dashboard/user/password-update",
|
||||||
data: formData
|
data: formData
|
||||||
}).always(function(response) {
|
}).always(function(response) {
|
||||||
|
hideLoadingModal();
|
||||||
|
submitting = false;
|
||||||
|
|
||||||
if (response === "success") {
|
if (response === "success") {
|
||||||
hideLoadingModal();
|
$inputs.val("").trigger("change");
|
||||||
|
showAlert("Password updated successfully");
|
||||||
showAlert("Password updated successfully", function() {
|
} else if (response === "old-password-fail") {
|
||||||
$inputs.val("").trigger("change");
|
$oldpass.addClass("error");
|
||||||
});
|
showAlert("Old password is not correct");
|
||||||
} else {
|
} else {
|
||||||
submitting = false;
|
$newpass.addClass("error");
|
||||||
|
$newpassConfirmation.val("");
|
||||||
if (response === "old-password-fail") {
|
showAlert("New password must be at least 6 characters");
|
||||||
$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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -729,6 +801,10 @@ $(document).ready(function() {
|
||||||
editItemInit();
|
editItemInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($("#user-profile-image").length) {
|
||||||
|
userProfileImageInit();
|
||||||
|
}
|
||||||
|
|
||||||
if ($("#user-password").length) {
|
if ($("#user-password").length) {
|
||||||
userPasswordInit();
|
userPasswordInit();
|
||||||
}
|
}
|
||||||
|
|
77
resources/assets/sass/dashboard.scss
vendored
77
resources/assets/sass/dashboard.scss
vendored
|
@ -8,6 +8,9 @@
|
||||||
// Core
|
// Core
|
||||||
@import "_fonts";
|
@import "_fonts";
|
||||||
|
|
||||||
|
// Supplementary
|
||||||
|
@import "mixins/**/*.scss";
|
||||||
|
|
||||||
// Colours
|
// Colours
|
||||||
$c-text: #111; // text
|
$c-text: #111; // text
|
||||||
$c-text-inactive: fade-out($c-text, 0.25); // inactive 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 {
|
#loading-modal {
|
||||||
|
|
|
@ -16,7 +16,13 @@
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
@foreach(App\Dashboard::$library_credits as $credit)
|
@foreach(App\Dashboard::$library_credits as $credit)
|
||||||
<li><a href="{{ $credit['url'] }}" target="_blank" rel="noreferrer">{{ $credit['name'] }}</a></li>
|
<li>
|
||||||
|
<a href="{{ $credit['url'] }}" target="_blank" rel="noreferrer">{{ $credit['name'] }}</a>
|
||||||
|
|
||||||
|
@if(array_key_exists('license', $credit))
|
||||||
|
(<a href="{{ $credit['license'] }}" target="_blank" rel="noreferrer">License</a>)
|
||||||
|
@endif
|
||||||
|
</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,6 +8,19 @@
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-md-8">
|
<div class="col-12 col-md-8">
|
||||||
|
<form id="user-profile-image" class="edit-item user-profile-image">
|
||||||
|
@set('profile_image', $user->profileImage())
|
||||||
|
|
||||||
|
<div class="image-display" style="background-image: url('{{ App\User::$default_profile_image }}')">
|
||||||
|
<div class="image-display-inner" style="background-image: url('{{ $profile_image !== null ? $profile_image : App\User::$default_profile_image }}')"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="image-buttons">
|
||||||
|
<input id="profile-image-upload" name="profile-image-upload" type="file" />
|
||||||
|
<label for="profile-image-upload" class="image-upload-button">Upload Profile Image</label>
|
||||||
|
<span id="profile-image-delete" class="image-delete-button {{ $profile_image === null ? 'inactive' : '' }}">Delete Profile Image</span>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-md-4">
|
<div class="col-12 col-md-4">
|
||||||
|
|
|
@ -29,21 +29,28 @@ Route::get('/logout', 'Auth\LoginController@logout');
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::group([ 'prefix' => 'dashboard' ], function() {
|
Route::group([ 'prefix' => 'dashboard' ], function() {
|
||||||
|
// Dashboard CMS
|
||||||
Route::get('/', 'DashboardController@getIndex');
|
Route::get('/', 'DashboardController@getIndex');
|
||||||
Route::get('/credits', 'DashboardController@getCredits');
|
|
||||||
Route::get('/settings', 'DashboardController@getSettings');
|
|
||||||
Route::get('/view/{model}', 'DashboardController@getView');
|
Route::get('/view/{model}', 'DashboardController@getView');
|
||||||
Route::get('/edit/{model}', 'DashboardController@getEditList');
|
Route::get('/edit/{model}', 'DashboardController@getEditList');
|
||||||
Route::get('/edit/{model}/{id}', 'DashboardController@getEditItem');
|
Route::get('/edit/{model}/{id}', 'DashboardController@getEditItem');
|
||||||
Route::get('/export/{model}', 'DashboardController@getExport');
|
Route::get('/export/{model}', 'DashboardController@getExport');
|
||||||
|
Route::post('/reorder', 'DashboardController@postReorder');
|
||||||
|
Route::post('/update', 'DashboardController@postUpdate');
|
||||||
Route::post('/image-upload', 'DashboardController@postImageUpload');
|
Route::post('/image-upload', 'DashboardController@postImageUpload');
|
||||||
Route::post('/file-upload', 'DashboardController@postFileUpload');
|
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('/delete', 'DashboardController@deleteDelete');
|
||||||
Route::delete('/image-delete', 'DashboardController@deleteImageDelete');
|
Route::delete('/image-delete', 'DashboardController@deleteImageDelete');
|
||||||
Route::delete('/file-delete', 'DashboardController@deleteFileDelete');
|
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');
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue