mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-05-07 17:40:57 +00:00
My Account: Built out profile page & endpoints
Text currently hard-coded, needs finalising and extracting.
This commit is contained in:
parent
a868012048
commit
c1b01639c1
4 changed files with 157 additions and 1 deletions
app/Users/Controllers
lang/en
resources/views/users/account
routes
|
@ -7,6 +7,7 @@ use BookStack\Http\Controller;
|
||||||
use BookStack\Permissions\PermissionApplicator;
|
use BookStack\Permissions\PermissionApplicator;
|
||||||
use BookStack\Settings\UserNotificationPreferences;
|
use BookStack\Settings\UserNotificationPreferences;
|
||||||
use BookStack\Settings\UserShortcutMap;
|
use BookStack\Settings\UserShortcutMap;
|
||||||
|
use BookStack\Uploads\ImageRepo;
|
||||||
use BookStack\Users\UserRepo;
|
use BookStack\Users\UserRepo;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
@ -19,6 +20,7 @@ class UserAccountController extends Controller
|
||||||
) {
|
) {
|
||||||
$this->middleware(function (Request $request, Closure $next) {
|
$this->middleware(function (Request $request, Closure $next) {
|
||||||
$this->preventGuestAccess();
|
$this->preventGuestAccess();
|
||||||
|
$this->preventAccessInDemoMode();
|
||||||
return $next($request);
|
return $next($request);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -35,6 +37,51 @@ class UserAccountController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the profile form interface.
|
||||||
|
*/
|
||||||
|
public function showProfile()
|
||||||
|
{
|
||||||
|
return view('users.account.profile', [
|
||||||
|
'model' => user(),
|
||||||
|
'category' => 'profile',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the submission of the user profile form.
|
||||||
|
*/
|
||||||
|
public function updateProfile(Request $request, ImageRepo $imageRepo)
|
||||||
|
{
|
||||||
|
$user = user();
|
||||||
|
$validated = $this->validate($request, [
|
||||||
|
'name' => ['min:2', 'max:100'],
|
||||||
|
'email' => ['min:2', 'email', 'unique:users,email,' . $user->id],
|
||||||
|
'language' => ['string', 'max:15', 'alpha_dash'],
|
||||||
|
'profile_image' => array_merge(['nullable'], $this->getImageValidationRules()),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->userRepo->update($user, $validated, userCan('users-manage'));
|
||||||
|
|
||||||
|
// Save profile image if in request
|
||||||
|
if ($request->hasFile('profile_image')) {
|
||||||
|
$imageUpload = $request->file('profile_image');
|
||||||
|
$imageRepo->destroyImage($user->avatar);
|
||||||
|
$image = $imageRepo->saveNew($imageUpload, 'user', $user->id);
|
||||||
|
$user->image_id = $image->id;
|
||||||
|
$user->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the profile image if reset option is in request
|
||||||
|
if ($request->has('profile_image_reset')) {
|
||||||
|
$imageRepo->destroyImage($user->avatar);
|
||||||
|
$user->image_id = 0;
|
||||||
|
$user->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect('/my-account/profile');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the user-specific interface shortcuts.
|
* Show the user-specific interface shortcuts.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,5 +35,5 @@ return [
|
||||||
'auth_change_password_success' => 'Password has been updated!',
|
'auth_change_password_success' => 'Password has been updated!',
|
||||||
|
|
||||||
'profile' => 'Profile Details',
|
'profile' => 'Profile Details',
|
||||||
'profile_overview_desc' => ' Manage your user profile details including preferred language and authentication options.',
|
'profile_overview_desc' => 'Manage your user profile details including preferred language and authentication options.',
|
||||||
];
|
];
|
||||||
|
|
107
resources/views/users/account/profile.blade.php
Normal file
107
resources/views/users/account/profile.blade.php
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
@extends('users.account.layout')
|
||||||
|
|
||||||
|
@section('main')
|
||||||
|
|
||||||
|
<section class="card content-wrap auto-height">
|
||||||
|
<form action="{{ url('/my-account/profile') }}" method="post" enctype="multipart/form-data">
|
||||||
|
{{ method_field('put') }}
|
||||||
|
{{ csrf_field() }}
|
||||||
|
|
||||||
|
<div class="flex-container-row gap-l items-center wrap justify-space-between">
|
||||||
|
<h1 class="list-heading">{{ trans('preferences.profile') }}</h1>
|
||||||
|
<div>
|
||||||
|
<a href="{{ user()->getProfileUrl() }}" class="button outline">View Public Profile</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="text-muted text-small mb-none">
|
||||||
|
Manage the details of your account that represent you to other users, in addition to
|
||||||
|
details that are used for communication and system personalisation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="setting-list">
|
||||||
|
|
||||||
|
<div class="flex-container-row gap-l items-center wrap">
|
||||||
|
<div class="flex">
|
||||||
|
<label class="setting-list-label" for="name">{{ trans('auth.name') }}</label>
|
||||||
|
<p class="text-small mb-none">
|
||||||
|
Configure your display name which will be visible to other users in the system
|
||||||
|
within the activity you perform, and content you own.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex stretch-inputs">
|
||||||
|
@include('form.text', ['name' => 'name'])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="flex-container-row gap-l items-center wrap">
|
||||||
|
<div class="flex">
|
||||||
|
<label class="setting-list-label" for="email">{{ trans('auth.email') }}</label>
|
||||||
|
<p class="text-small mb-none">
|
||||||
|
This email will be used for notifications and, depending on active system authentication, system access.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex stretch-inputs">
|
||||||
|
@include('form.text', ['name' => 'email', 'disabled' => !userCan('users-manage')])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if(!userCan('users-manage'))
|
||||||
|
<p class="text-small text-muted">
|
||||||
|
Unfortunately you don't have permission to change your email address.
|
||||||
|
If you want to change this, you'd need to ask an administrator to change this for you.
|
||||||
|
</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid half gap-xl">
|
||||||
|
<div>
|
||||||
|
<label for="user-avatar"
|
||||||
|
class="setting-list-label">{{ trans('settings.users_avatar') }}</label>
|
||||||
|
<p class="text-small">
|
||||||
|
Select an image which will be used to represent yourself to others
|
||||||
|
in the system. Ideally this image should be square and about 256px in width and height.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@include('form.image-picker', [
|
||||||
|
'resizeHeight' => '512',
|
||||||
|
'resizeWidth' => '512',
|
||||||
|
'showRemove' => false,
|
||||||
|
'defaultImage' => url('/user_avatar.png'),
|
||||||
|
'currentImage' => user()->getAvatar(80),
|
||||||
|
'currentId' => user()->image_id,
|
||||||
|
'name' => 'profile_image',
|
||||||
|
'imageClass' => 'avatar large'
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@include('users.parts.language-option-row', ['value' => old('language') ?? user()->getLocale()->appLocale()])
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group text-right">
|
||||||
|
<button class="button">{{ trans('common.save') }}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
@if(userCan('users-manage'))
|
||||||
|
<section class="card content-wrap auto-height">
|
||||||
|
<div class="flex-container-row gap-l items-center wrap">
|
||||||
|
<div class="flex">
|
||||||
|
<h2 class="list-heading">Administrator Options</h2>
|
||||||
|
<p class="text-small">
|
||||||
|
Additional administrator-level options, like role options, can be found for your user account in the
|
||||||
|
<nobr>"Settings > Users"</nobr> area of the application.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="text-m-right">
|
||||||
|
<a class="button outline" href="{{ user()->getEditUrl() }}">Open</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endif
|
||||||
|
@stop
|
|
@ -234,6 +234,8 @@ Route::middleware('auth')->group(function () {
|
||||||
|
|
||||||
// User Account
|
// User Account
|
||||||
Route::get('/my-account', [UserControllers\UserAccountController::class, 'index']);
|
Route::get('/my-account', [UserControllers\UserAccountController::class, 'index']);
|
||||||
|
Route::get('/my-account/profile', [UserControllers\UserAccountController::class, 'showProfile']);
|
||||||
|
Route::put('/my-account/profile', [UserControllers\UserAccountController::class, 'updateProfile']);
|
||||||
Route::get('/my-account/shortcuts', [UserControllers\UserAccountController::class, 'showShortcuts']);
|
Route::get('/my-account/shortcuts', [UserControllers\UserAccountController::class, 'showShortcuts']);
|
||||||
Route::put('/my-account/shortcuts', [UserControllers\UserAccountController::class, 'updateShortcuts']);
|
Route::put('/my-account/shortcuts', [UserControllers\UserAccountController::class, 'updateShortcuts']);
|
||||||
Route::get('/my-account/notifications', [UserControllers\UserAccountController::class, 'showNotifications']);
|
Route::get('/my-account/notifications', [UserControllers\UserAccountController::class, 'showNotifications']);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue