From 9392e1bec3fd1fa967e1c59dc23890631aaa997d Mon Sep 17 00:00:00 2001 From: Toby Zerner <toby.zerner@gmail.com> Date: Wed, 29 Nov 2017 12:52:49 +1030 Subject: [PATCH] New design for reset password view --- .../Controller/ResetPasswordController.php | 14 +-- .../Controller/SavePasswordController.php | 3 +- src/Forum/ForumServiceProvider.php | 7 ++ .../Middleware/ShareErrorsFromSession.php | 62 ++++++++++ views/layouts/basic.blade.php | 106 ++++++++++++++++++ views/reset-password.blade.php | 33 ++++++ views/reset.blade.php | 37 ------ 7 files changed, 213 insertions(+), 49 deletions(-) create mode 100644 src/Http/Middleware/ShareErrorsFromSession.php create mode 100644 views/layouts/basic.blade.php create mode 100644 views/reset-password.blade.php delete mode 100644 views/reset.blade.php diff --git a/src/Forum/Controller/ResetPasswordController.php b/src/Forum/Controller/ResetPasswordController.php index 42a47b288..1e87fdf0c 100644 --- a/src/Forum/Controller/ResetPasswordController.php +++ b/src/Forum/Controller/ResetPasswordController.php @@ -26,18 +26,12 @@ class ResetPasswordController extends AbstractHtmlController */ protected $view; - /** - * @var TranslatorInterface - */ - protected $translator; - /** * @param Factory $view */ - public function __construct(Factory $view, TranslatorInterface $translator) + public function __construct(Factory $view) { $this->view = $view; - $this->translator = $translator; } /** @@ -55,10 +49,8 @@ class ResetPasswordController extends AbstractHtmlController throw new InvalidConfirmationTokenException; } - return $this->view->make('flarum::reset') - ->with('translator', $this->translator) + return $this->view->make('flarum.forum::reset-password') ->with('passwordToken', $token->id) - ->with('csrfToken', $request->getAttribute('session')->get('csrf_token')) - ->with('error', $request->getAttribute('session')->get('error')); + ->with('csrfToken', $request->getAttribute('session')->get('csrf_token')); } } diff --git a/src/Forum/Controller/SavePasswordController.php b/src/Forum/Controller/SavePasswordController.php index 0b36f9779..3a9fc4605 100644 --- a/src/Forum/Controller/SavePasswordController.php +++ b/src/Forum/Controller/SavePasswordController.php @@ -75,11 +75,12 @@ class SavePasswordController implements ControllerInterface $this->validator->assertValid(compact('password')); $validator = $this->validatorFactory->make($input, ['password' => 'required|confirmed']); + if ($validator->fails()) { throw new ValidationException($validator); } } catch (ValidationException $e) { - $request->getAttribute('session')->set('error', $e->errors()->first()); + $request->getAttribute('session')->set('errors', $e->errors()); return new RedirectResponse($this->url->toRoute('resetPassword', ['token' => $token->id])); } diff --git a/src/Forum/ForumServiceProvider.php b/src/Forum/ForumServiceProvider.php index 43f4c2bed..766cdc618 100644 --- a/src/Forum/ForumServiceProvider.php +++ b/src/Forum/ForumServiceProvider.php @@ -18,6 +18,8 @@ use Flarum\Event\SettingWasSet; use Flarum\Foundation\AbstractServiceProvider; use Flarum\Http\Handler\RouteHandlerFactory; use Flarum\Http\RouteCollection; +use Flarum\Settings\SettingsRepositoryInterface; +use Symfony\Component\Translation\TranslatorInterface; class ForumServiceProvider extends AbstractServiceProvider { @@ -44,6 +46,11 @@ class ForumServiceProvider extends AbstractServiceProvider $this->loadViewsFrom(__DIR__.'/../../views', 'flarum.forum'); + $this->app->make('view')->share([ + 'translator' => $this->app->make(TranslatorInterface::class), + 'settings' => $this->app->make(SettingsRepositoryInterface::class) + ]); + $this->flushWebAppAssetsWhenThemeChanged(); $this->flushWebAppAssetsWhenExtensionsChanged(); diff --git a/src/Http/Middleware/ShareErrorsFromSession.php b/src/Http/Middleware/ShareErrorsFromSession.php new file mode 100644 index 000000000..4ab83d2f8 --- /dev/null +++ b/src/Http/Middleware/ShareErrorsFromSession.php @@ -0,0 +1,62 @@ +<?php +/* + * This file is part of Flarum. + * + * (c) Toby Zerner <toby.zerner@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Http\Middleware; + +use Illuminate\Support\ViewErrorBag; +use Illuminate\Contracts\View\Factory as ViewFactory; +use Psr\Http\Message\ResponseInterface as Response; +use Psr\Http\Message\ServerRequestInterface as Request; +use Zend\Stratigility\MiddlewareInterface; + +/** + * Inspired by Illuminate\View\Middleware\ShareErrorsFromSession + * + * @author Taylor Otwell + */ +class ShareErrorsFromSession implements MiddlewareInterface +{ + /** + * @var ViewFactory + */ + protected $view; + + /** + * @param ViewFactory $view + */ + public function __construct(ViewFactory $view) + { + $this->view = $view; + } + + /** + * {@inheritdoc} + */ + public function __invoke(Request $request, Response $response, callable $out = null) + { + $session = $request->getAttribute('session'); + + // If the current session has an "errors" variable bound to it, we will share + // its value with all view instances so the views can easily access errors + // without having to bind. An empty bag is set when there aren't errors. + $this->view->share( + 'errors', $session->get('errors', new ViewErrorBag) + ); + + // Putting the errors in the view for every view allows the developer to just + // assume that some errors are always available, which is convenient since + // they don't have to continually run checks for the presence of errors. + + $session->remove('errors'); + + return $out ? $out($request, $response) : $response; + } +} + diff --git a/views/layouts/basic.blade.php b/views/layouts/basic.blade.php new file mode 100644 index 000000000..7143e24c9 --- /dev/null +++ b/views/layouts/basic.blade.php @@ -0,0 +1,106 @@ +{{-- TODO: Change below to @php when Laravel is upgraded --}} +<?php + $primaryColor = $settings->get('theme_primary_color', '#000'); +?> + +<!doctype html> +<html> + <head> + <meta charset="utf-8"> + {{-- TODO: Change below to @hasSection when Laravel is upgraded --}} + <title>@if ($__env->hasSection('title')) @yield('title') - @endif{{ $settings->get('forum_title') }}</title> + <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1"> + + <style> + * { + box-sizing: border-box; + } + body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 18px; + text-align: center; + line-height: 1.5; + color: #333; + } + input, + button, + select, + textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; + } + a { + cursor: pointer; + color: {{ $primaryColor }}; + text-decoration: none; + } + a:hover { + text-decoration: underline; + } + .container { + margin: 100px auto; + max-width: 450px; + padding: 0 15px; + } + .button { + display: inline-block; + padding: 15px 25px; + background: {{ $primaryColor }}; + color: #fff; + text-decoration: none; + text-align: center; + vertical-align: middle; + border-radius: 4px; + cursor: pointer; + white-space: nowrap; + font-weight: bold; + border: 0; + } + .button:hover { + text-decoration: none; + } + .button:active, + .button.active { + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + } + .form { + max-width: 300px; + margin: 0 auto; + } + .form .button { + display: block; + width: 100%; + } + .form-control { + display: block; + width: 100%; + text-align: center; + padding: 15px 20px; + background-color: #fff; + border: 2px solid #eee; + border-radius: 4px; + transition: border-color .15s; + } + .form-control:focus, + .form-control.focus { + border-color: {{ $primaryColor }}; + outline: none; + } + .errors { + color: #d83e3e; + } + .errors ul { + list-style-type: none; + margin: 0; + padding: 0; + } + </style> + </head> + + <body> + <div class="container"> + @yield('content') + </div> + </body> +</html> diff --git a/views/reset-password.blade.php b/views/reset-password.blade.php new file mode 100644 index 000000000..11ac7020e --- /dev/null +++ b/views/reset-password.blade.php @@ -0,0 +1,33 @@ +@extends('flarum.forum::layouts.basic') +@inject('url', 'Flarum\Forum\UrlGenerator') + +@section('title', $translator->trans('core.views.reset_password.title')) + +@section('content') + @if ($errors->any()) + <div class="errors"> + <ul> + @foreach ($errors->all() as $error) + <li>{{ $error }}</li> + @endforeach + </ul> + </div> + @endif + + <form class="form" method="POST" action="{{ $url->toRoute('savePassword') }}"> + <input type="hidden" name="csrfToken" value="{{ $csrfToken }}"> + <input type="hidden" name="passwordToken" value="{{ $passwordToken }}"> + + <p class="form-group"> + <input type="password" class="form-control" name="password" placeholder="{{ $translator->trans('core.views.reset_password.new_password_label') }}"> + </p> + + <p class="form-group"> + <input type="password" class="form-control" name="password_confirmation" placeholder="{{ $translator->trans('core.views.reset_password.confirm_password_label') }}"> + </p> + + <p class="form-group"> + <button type="submit" class="button">{{ $translator->trans('core.views.reset_password.submit_button') }}</button> + </p> + </form> +@endsection diff --git a/views/reset.blade.php b/views/reset.blade.php deleted file mode 100644 index 671157b38..000000000 --- a/views/reset.blade.php +++ /dev/null @@ -1,37 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <title>Reset Your Password</title> - <meta name="description" content=""> - <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1"> - </head> - - <body> - <h2>{{ $translator->trans('core.views.reset.title') }}</h2> - - @if (! empty($error)) - <p style="color:red">{{ $error }}</p> - @endif - - <form class="form-horizontal" role="form" method="POST" action="{{ app('Flarum\Forum\UrlGenerator')->toRoute('savePassword') }}"> - <input type="hidden" name="csrfToken" value="{{ $csrfToken }}"> - <input type="hidden" name="passwordToken" value="{{ $passwordToken }}"> - - <p class="form-group"> - <label class="control-label">{{ $translator->trans('core.views.reset.password_label') }}</label><br> - <input type="password" class="form-control" name="password"> - </p> - - <p class="form-group"> - <label class="control-label">{{ $translator->trans('core.views.reset.confirm_password_label') }}</label><br> - <input type="password" class="form-control" name="password_confirmation"> - </p> - - <p class="form-group"> - <button type="submit" class="btn btn-primary">{{ $translator->trans('core.views.reset.submit_button') }}</button> - </p> - </form> - </body> -</html>