Вступление
Данный рецепт демонстрирует использование MoonShine не в роли панели администратора, а в роли личного кабинета под модель User
с логином, регистрацией, восстановлением пароля и профилем (базовый набор).
Хороший пример работы с разными Layout
под разные страницы.
Routes
Начнем с маршрутизации, но для начала создадим несколько контроллеров:
AuthenticateController
ForgotController
ProfileController
RegisterController
Объявим маршруты в routes/web.php
:
use App\Http\Controllers\AuthenticateController;use App\Http\Controllers\ForgotController;use App\Http\Controllers\ProfileController;use App\Http\Controllers\RegisterController;use App\MoonShine\Pages\ResetPasswordPage;use Illuminate\Support\Facades\Route;Route::controller(AuthenticateController::class)->group(function () {Route::get('/login', 'form')->middleware('guest')->name('login');Route::post('/login', 'authenticate')->middleware('guest')->name('authenticate');Route::delete('/logout', 'logout')->middleware('auth')->name('logout');});Route::controller(ForgotController::class)->middleware('guest')->group(function () {Route::get('/forgot', 'form')->name('forgot');Route::post('/forgot', 'reset');Route::get('/reset-password/{token}', static fn (ResetPasswordPage $page) => $page)->name('password.reset');Route::post('/reset-password', 'updatePassword')->name('password.update');});Route::controller(RegisterController::class)->middleware('guest')->group(function () {Route::get('/register', 'form')->name('register');Route::post('/register', 'store')->name('register.store');});Route::controller(ProfileController::class)->middleware('auth')->prefix('profile')->group(function () {Route::get('/', 'index')->name('profile');Route::post('/', 'update')->name('profile.update');});
use App\Http\Controllers\AuthenticateController;use App\Http\Controllers\ForgotController;use App\Http\Controllers\ProfileController;use App\Http\Controllers\RegisterController;use App\MoonShine\Pages\ResetPasswordPage;use Illuminate\Support\Facades\Route;Route::controller(AuthenticateController::class)->group(function () {Route::get('/login', 'form')->middleware('guest')->name('login');Route::post('/login', 'authenticate')->middleware('guest')->name('authenticate');Route::delete('/logout', 'logout')->middleware('auth')->name('logout');});Route::controller(ForgotController::class)->middleware('guest')->group(function () {Route::get('/forgot', 'form')->name('forgot');Route::post('/forgot', 'reset');Route::get('/reset-password/{token}', static fn (ResetPasswordPage $page) => $page)->name('password.reset');Route::post('/reset-password', 'updatePassword')->name('password.update');});Route::controller(RegisterController::class)->middleware('guest')->group(function () {Route::get('/register', 'form')->name('register');Route::post('/register', 'store')->name('register.store');});Route::controller(ProfileController::class)->middleware('auth')->prefix('profile')->group(function () {Route::get('/', 'index')->name('profile');Route::post('/', 'update')->name('profile.update');});
ResetPasswordPage
мы создадим немного позже
Layouts
У нас будут страницы с формами входа, регистрации и восстановления пароля и они будут отличаться шаблоном от страницы с профилем пользователя, поэтому нам необходимо создать 2 шаблона:
AppLayout
- для профиляFormLayout
- для аутентификации
AppLayout
Начнем с выполнения команды на создание шаблона
php artisan moonshine:layout AppLayout --compact
php artisan moonshine:layout AppLayout --compact
Далее соберем конструктор из нужных нам компонентов
namespace App\MoonShine\Layouts;use App\MoonShine\Resources\PackageCategoryResource;use App\MoonShine\Resources\PackageResource;use App\MoonShine\Resources\UserResource;use MoonShine\ColorManager\ColorManager;use MoonShine\Contracts\ColorManager\ColorManagerContract;use MoonShine\Laravel\Layouts\CompactLayout;use MoonShine\MenuManager\MenuGroup;use MoonShine\MenuManager\MenuItem;use MoonShine\UI\Components\{Components,Layout\Div,Layout\Body,Layout\Content,Layout\Flash,Layout\Html,Layout\Layout,Layout\Wrapper};final class AppLayout extends CompactLayout{protected function getHomeUrl(): string{return route('home');}public function build(): Layout{return Layout::make([Html::make([$this->getHeadComponent(),Body::make([Wrapper::make([Div::make([Flash::make(),Content::make([Components::make($this->getPage()->getComponents()),]),])->class('layout-page'),]),])->class('theme-minimalistic'),])->customAttributes(['lang' => $this->getHeadLang(),])->withAlpineJs()->withThemes(),]);}}
namespace App\MoonShine\Layouts;use App\MoonShine\Resources\PackageCategoryResource;use App\MoonShine\Resources\PackageResource;use App\MoonShine\Resources\UserResource;use MoonShine\ColorManager\ColorManager;use MoonShine\Contracts\ColorManager\ColorManagerContract;use MoonShine\Laravel\Layouts\CompactLayout;use MoonShine\MenuManager\MenuGroup;use MoonShine\MenuManager\MenuItem;use MoonShine\UI\Components\{Components,Layout\Div,Layout\Body,Layout\Content,Layout\Flash,Layout\Html,Layout\Layout,Layout\Wrapper};final class AppLayout extends CompactLayout{protected function getHomeUrl(): string{return route('home');}public function build(): Layout{return Layout::make([Html::make([$this->getHeadComponent(),Body::make([Wrapper::make([Div::make([Flash::make(),Content::make([Components::make($this->getPage()->getComponents()),]),])->class('layout-page'),]),])->class('theme-minimalistic'),])->customAttributes(['lang' => $this->getHeadLang(),])->withAlpineJs()->withThemes(),]);}}
FormLayout
php artisan moonshine:layout FormLayout --compact
php artisan moonshine:layout FormLayout --compact
namespace App\MoonShine\Layouts;use MoonShine\Laravel\Layouts\CompactLayout;use MoonShine\UI\Components\{Components,FlexibleRender,Heading,Layout\Div,Layout\Body,Layout\Content,Layout\Flash,Layout\Html,Layout\Layout,Layout\Wrapper};final class FormLayout extends CompactLayout{protected function getHomeUrl(): string{return route('home');}public function build(): Layout{return Layout::make([Html::make([$this->getHeadComponent(),Body::make([Div::make([Div::make([$this->getLogoComponent(),])->class('authentication-logo'),Div::make([Flash::make(),Components::make($this->getPage()->getComponents()),])->class('authentication-content'),])->class('authentication'),]),])->customAttributes(['lang' => $this->getHeadLang(),])->withAlpineJs()->withThemes(),]);}}
namespace App\MoonShine\Layouts;use MoonShine\Laravel\Layouts\CompactLayout;use MoonShine\UI\Components\{Components,FlexibleRender,Heading,Layout\Div,Layout\Body,Layout\Content,Layout\Flash,Layout\Html,Layout\Layout,Layout\Wrapper};final class FormLayout extends CompactLayout{protected function getHomeUrl(): string{return route('home');}public function build(): Layout{return Layout::make([Html::make([$this->getHeadComponent(),Body::make([Div::make([Div::make([$this->getLogoComponent(),])->class('authentication-logo'),Div::make([Flash::make(),Components::make($this->getPage()->getComponents()),])->class('authentication-content'),])->class('authentication'),]),])->customAttributes(['lang' => $this->getHeadLang(),])->withAlpineJs()->withThemes(),]);}}
Страницы
Создадим страницы MoonShine для отображения данных:
LoginPage
Выполним команду создания страницы, а тип выберем Custom
:
php artisan moonshine:page LoginPage
php artisan moonshine:page LoginPage
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\FormLayout;use MoonShine\Laravel\Pages\Page;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\UI\Components\ActionButton;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Components\Layout\Divider;use MoonShine\UI\Components\Layout\Flex;use MoonShine\UI\Components\Layout\LineBreak;use MoonShine\UI\Components\Link;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\Switcher;use MoonShine\UI\Fields\Text;class LoginPage extends Page{protected ?string $layout = FormLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}public function getTitle(): string{return $this->title ?: 'LoginPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [FormBuilder::make()->class('authentication-form')->action(route('authenticate'))->fields([Text::make('E-mail', 'email')->required()->customAttributes(['autofocus' => true,'autocomplete' => 'username',]),Password::make(__('Password'), 'password')->required(),Switcher::make(__('Remember me'), 'remember'),])->submit(__('Log in'), ['class' => 'btn-primary btn-lg w-full',]),Divider::make(),Flex::make([ActionButton::make(__('Create account'), route('register'))->primary(),Link::make(route('forgot'), __('Forgot password'))])->justifyAlign('start')];}}
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\FormLayout;use MoonShine\Laravel\Pages\Page;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\UI\Components\ActionButton;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Components\Layout\Divider;use MoonShine\UI\Components\Layout\Flex;use MoonShine\UI\Components\Layout\LineBreak;use MoonShine\UI\Components\Link;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\Switcher;use MoonShine\UI\Fields\Text;class LoginPage extends Page{protected ?string $layout = FormLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}public function getTitle(): string{return $this->title ?: 'LoginPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [FormBuilder::make()->class('authentication-form')->action(route('authenticate'))->fields([Text::make('E-mail', 'email')->required()->customAttributes(['autofocus' => true,'autocomplete' => 'username',]),Password::make(__('Password'), 'password')->required(),Switcher::make(__('Remember me'), 'remember'),])->submit(__('Log in'), ['class' => 'btn-primary btn-lg w-full',]),Divider::make(),Flex::make([ActionButton::make(__('Create account'), route('register'))->primary(),Link::make(route('forgot'), __('Forgot password'))])->justifyAlign('start')];}}
Также обратите внимание, что у страниц мы указываем нужный шаблон
protected ?string $layout = FormLayout::class;
protected ?string $layout = FormLayout::class;
RegisterPage
php artisan moonshine:page RegisterPage
php artisan moonshine:page RegisterPage
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\FormLayout;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\ActionButton;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\PasswordRepeat;use MoonShine\UI\Fields\Switcher;use MoonShine\UI\Fields\Text;class RegisterPage extends Page{protected ?string $layout = FormLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}public function getTitle(): string{return $this->title ?: 'RegisterPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [FormBuilder::make()->class('authentication-form')->action(route('register.store'))->fields([Text::make(__('Name'), 'name')->required(),Text::make('E-mail', 'email')->required()->customAttributes(['autofocus' => true,'autocomplete' => 'off',]),Password::make(__('Password'), 'password')->required(),PasswordRepeat::make(__('Repeat password'), 'password_confirmation')->required(),])->submit(__('Create account'), ['class' => 'btn-primary btn-lg w-full',])->buttons([ActionButton::make(__('Log in'), route('login'))])];}}
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\FormLayout;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\ActionButton;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\PasswordRepeat;use MoonShine\UI\Fields\Switcher;use MoonShine\UI\Fields\Text;class RegisterPage extends Page{protected ?string $layout = FormLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}public function getTitle(): string{return $this->title ?: 'RegisterPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [FormBuilder::make()->class('authentication-form')->action(route('register.store'))->fields([Text::make(__('Name'), 'name')->required(),Text::make('E-mail', 'email')->required()->customAttributes(['autofocus' => true,'autocomplete' => 'off',]),Password::make(__('Password'), 'password')->required(),PasswordRepeat::make(__('Repeat password'), 'password_confirmation')->required(),])->submit(__('Create account'), ['class' => 'btn-primary btn-lg w-full',])->buttons([ActionButton::make(__('Log in'), route('login'))])];}}
ForgotPage
php artisan moonshine:page ForgotPage
php artisan moonshine:page ForgotPage
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\FormLayout;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\ActionButton;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Components\Layout\Divider;use MoonShine\UI\Components\Layout\Flash;use MoonShine\UI\Components\Layout\Flex;use MoonShine\UI\Components\Link;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\Switcher;use MoonShine\UI\Fields\Text;class ForgotPage extends Page{protected ?string $layout = FormLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}public function getTitle(): string{return $this->title ?: 'ForgotPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [FormBuilder::make()->class('authentication-form')->action(route('forgot'))->fields([Text::make('E-mail', 'email')->required()->customAttributes(['autofocus' => true,'autocomplete' => 'off',]),])->submit(__('Reset password'), ['class' => 'btn-primary btn-lg w-full',]),Divider::make(),Flex::make([ActionButton::make(__('Log in'), route('login'))->primary(),])->justifyAlign('start')];}}
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\FormLayout;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\ActionButton;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Components\Layout\Divider;use MoonShine\UI\Components\Layout\Flash;use MoonShine\UI\Components\Layout\Flex;use MoonShine\UI\Components\Link;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\Switcher;use MoonShine\UI\Fields\Text;class ForgotPage extends Page{protected ?string $layout = FormLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}public function getTitle(): string{return $this->title ?: 'ForgotPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [FormBuilder::make()->class('authentication-form')->action(route('forgot'))->fields([Text::make('E-mail', 'email')->required()->customAttributes(['autofocus' => true,'autocomplete' => 'off',]),])->submit(__('Reset password'), ['class' => 'btn-primary btn-lg w-full',]),Divider::make(),Flex::make([ActionButton::make(__('Log in'), route('login'))->primary(),])->justifyAlign('start')];}}
ResetPasswordPage
php artisan moonshine:page ResetPasswordPage
php artisan moonshine:page ResetPasswordPage
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\FormLayout;use Illuminate\Contracts\Routing\UrlRoutable;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\ActionButton;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Components\Layout\Divider;use MoonShine\UI\Components\Layout\Flex;use MoonShine\UI\Fields\Hidden;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\PasswordRepeat;use MoonShine\UI\Fields\Text;class ResetPasswordPage extends Page{protected ?string $layout = FormLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}public function getTitle(): string{return $this->title ?: 'ForgotPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [FormBuilder::make()->class('authentication-form')->action(route('password.update'))->fields([Hidden::make('token')->setValue(request()->route('token')),Text::make('E-mail', 'email')->setValue(request()->input('email'))->required()->readonly(),Password::make(__('Password'), 'password')->required(),PasswordRepeat::make(__('Repeat password'), 'password_confirmation')->required(),])->submit(__('Reset password'), ['class' => 'btn-primary btn-lg w-full',]),];}}
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\FormLayout;use Illuminate\Contracts\Routing\UrlRoutable;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\ActionButton;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Components\Layout\Divider;use MoonShine\UI\Components\Layout\Flex;use MoonShine\UI\Fields\Hidden;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\PasswordRepeat;use MoonShine\UI\Fields\Text;class ResetPasswordPage extends Page{protected ?string $layout = FormLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}public function getTitle(): string{return $this->title ?: 'ForgotPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [FormBuilder::make()->class('authentication-form')->action(route('password.update'))->fields([Hidden::make('token')->setValue(request()->route('token')),Text::make('E-mail', 'email')->setValue(request()->input('email'))->required()->readonly(),Password::make(__('Password'), 'password')->required(),PasswordRepeat::make(__('Repeat password'), 'password_confirmation')->required(),])->submit(__('Reset password'), ['class' => 'btn-primary btn-lg w-full',]),];}}
ProfilePage
php artisan moonshine:page ProfilePage
php artisan moonshine:page ProfilePage
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\AppLayout;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Components\Layout\Box;use MoonShine\UI\Components\Tabs;use MoonShine\UI\Components\Tabs\Tab;use MoonShine\UI\Fields\Hidden;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\PasswordRepeat;use MoonShine\UI\Fields\Text;class ProfilePage extends Page{protected ?string $layout = AppLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle(),];}public function getTitle(): string{return $this->title ?: 'LoginPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [Box::make([FormBuilder::make()->class('authentication-form')->action(route('profile.update'))->fill(auth()->user())->fields([Tabs::make([Tab::make(__('Profile'), [Text::make(__('Name'), 'name')->required(),Text::make('E-mail', 'email')->required()->customAttributes(['autofocus' => true,'autocomplete' => 'off',]),]),Tab::make(__('Password'), [Password::make(__('Password'), 'password'),PasswordRepeat::make(__('Repeat password'), 'password_confirmation'),])->active(session('errors')?->has('password') ?? false)])])->submit(__('Update profile'), ['class' => 'btn-primary btn-lg w-full',]),]),FormBuilder::make()->name('logout')->class('authentication-form')->action(route('logout'))->fields([Hidden::make('_method')->setValue('DELETE'),])->submit(__('Log out'), ['class' => 'btn-primary btn-lg w-full',]),];}}
namespace App\MoonShine\Pages;use App\MoonShine\Layouts\AppLayout;use MoonShine\Contracts\UI\ComponentContract;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\FormBuilder;use MoonShine\UI\Components\Layout\Box;use MoonShine\UI\Components\Tabs;use MoonShine\UI\Components\Tabs\Tab;use MoonShine\UI\Fields\Hidden;use MoonShine\UI\Fields\Password;use MoonShine\UI\Fields\PasswordRepeat;use MoonShine\UI\Fields\Text;class ProfilePage extends Page{protected ?string $layout = AppLayout::class;/*** @return array<string, string>*/public function getBreadcrumbs(): array{return ['#' => $this->getTitle(),];}public function getTitle(): string{return $this->title ?: 'LoginPage';}/*** @return list<ComponentContract>*/protected function components(): iterable{return [Box::make([FormBuilder::make()->class('authentication-form')->action(route('profile.update'))->fill(auth()->user())->fields([Tabs::make([Tab::make(__('Profile'), [Text::make(__('Name'), 'name')->required(),Text::make('E-mail', 'email')->required()->customAttributes(['autofocus' => true,'autocomplete' => 'off',]),]),Tab::make(__('Password'), [Password::make(__('Password'), 'password'),PasswordRepeat::make(__('Repeat password'), 'password_confirmation'),])->active(session('errors')?->has('password') ?? false)])])->submit(__('Update profile'), ['class' => 'btn-primary btn-lg w-full',]),]),FormBuilder::make()->name('logout')->class('authentication-form')->action(route('logout'))->fields([Hidden::make('_method')->setValue('DELETE'),])->submit(__('Log out'), ['class' => 'btn-primary btn-lg w-full',]),];}}
Controllers
AuthenticateController
namespace App\Http\Controllers;use App\Http\Requests\AuthenticateFormRequest;use App\Models\User;use App\MoonShine\Pages\LoginPage;use Illuminate\Container\Attributes\Auth;use Illuminate\Container\Attributes\Authenticated;use Illuminate\Container\Attributes\CurrentUser;use Illuminate\Contracts\Auth\Guard;use Illuminate\Http\RedirectResponse;use Illuminate\Http\Request;final class AuthenticateController extends Controller{public function form(LoginPage $page): LoginPage{return $page;}public function authenticate(AuthenticateFormRequest $request): RedirectResponse{if(!auth()->attempt($request->validated())) {return back()->withErrors(['email' => __('moonshine::auth.failed')]);}return redirect()->intended(route('profile'));}public function logout(#[Auth]Guard $guard,Request $request): RedirectResponse {$guard->logout();$request->session()->invalidate();$request->session()->regenerateToken();return redirect()->intended(url()->previous() ?? route('home'));}}
namespace App\Http\Controllers;use App\Http\Requests\AuthenticateFormRequest;use App\Models\User;use App\MoonShine\Pages\LoginPage;use Illuminate\Container\Attributes\Auth;use Illuminate\Container\Attributes\Authenticated;use Illuminate\Container\Attributes\CurrentUser;use Illuminate\Contracts\Auth\Guard;use Illuminate\Http\RedirectResponse;use Illuminate\Http\Request;final class AuthenticateController extends Controller{public function form(LoginPage $page): LoginPage{return $page;}public function authenticate(AuthenticateFormRequest $request): RedirectResponse{if(!auth()->attempt($request->validated())) {return back()->withErrors(['email' => __('moonshine::auth.failed')]);}return redirect()->intended(route('profile'));}public function logout(#[Auth]Guard $guard,Request $request): RedirectResponse {$guard->logout();$request->session()->invalidate();$request->session()->regenerateToken();return redirect()->intended(url()->previous() ?? route('home'));}}
Обратите внимание на то как мы рендерим страницы в контроллерах
public function form(LoginPage $page): LoginPage{return $page;}
public function form(LoginPage $page): LoginPage{return $page;}
Также буду выкладывать и FormRequest
классы, чтобы рецепт был максимально готовым
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;use Illuminate\Validation\Rules\Password;class AuthenticateFormRequest extends FormRequest{public function authorize(): bool{return auth()->guest();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['email' => ['required'],'password' => ['required', Password::default()],];}}
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;use Illuminate\Validation\Rules\Password;class AuthenticateFormRequest extends FormRequest{public function authorize(): bool{return auth()->guest();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['email' => ['required'],'password' => ['required', Password::default()],];}}
ForgotController
namespace App\Http\Controllers;use App\Http\Requests\ForgotPasswordFormRequest;use App\Http\Requests\ResetPasswordFormRequest;use App\Models\User;use App\MoonShine\Pages\ForgotPage;use Illuminate\Auth\Events\PasswordReset;use Illuminate\Http\RedirectResponse;use Illuminate\Support\Facades\Hash;use Illuminate\Support\Facades\Password;use Illuminate\Support\Str;use MoonShine\Laravel\MoonShineUI;class ForgotController extends Controller{public function form(ForgotPage $page): ForgotPage{return $page;}public function reset(ForgotPasswordFormRequest $request): RedirectResponse{$status = Password::sendResetLink($request->only('email'));if ($status === Password::RESET_LINK_SENT) {MoonShineUI::toast(__('If the account exists, then the instructions are sent to your email'));}return $status === Password::RESET_LINK_SENT? back()->with(['alert' => __($status)]): back()->withErrors(['email' => __($status)]);}public function updatePassword(ResetPasswordFormRequest $request): RedirectResponse{$status = Password::reset($request->only('email', 'password', 'password_confirmation', 'token'),static function (User $user, string $password) {$user->forceFill(['password' => Hash::make($password),])->setRememberToken(Str::random(60));$user->save();event(new PasswordReset($user));});return $status === Password::PASSWORD_RESET? redirect()->route('login')->with('alert', __($status)): back()->withErrors(['email' => [__($status)]]);}}
namespace App\Http\Controllers;use App\Http\Requests\ForgotPasswordFormRequest;use App\Http\Requests\ResetPasswordFormRequest;use App\Models\User;use App\MoonShine\Pages\ForgotPage;use Illuminate\Auth\Events\PasswordReset;use Illuminate\Http\RedirectResponse;use Illuminate\Support\Facades\Hash;use Illuminate\Support\Facades\Password;use Illuminate\Support\Str;use MoonShine\Laravel\MoonShineUI;class ForgotController extends Controller{public function form(ForgotPage $page): ForgotPage{return $page;}public function reset(ForgotPasswordFormRequest $request): RedirectResponse{$status = Password::sendResetLink($request->only('email'));if ($status === Password::RESET_LINK_SENT) {MoonShineUI::toast(__('If the account exists, then the instructions are sent to your email'));}return $status === Password::RESET_LINK_SENT? back()->with(['alert' => __($status)]): back()->withErrors(['email' => __($status)]);}public function updatePassword(ResetPasswordFormRequest $request): RedirectResponse{$status = Password::reset($request->only('email', 'password', 'password_confirmation', 'token'),static function (User $user, string $password) {$user->forceFill(['password' => Hash::make($password),])->setRememberToken(Str::random(60));$user->save();event(new PasswordReset($user));});return $status === Password::PASSWORD_RESET? redirect()->route('login')->with('alert', __($status)): back()->withErrors(['email' => [__($status)]]);}}
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;class ForgotPasswordFormRequest extends FormRequest{public function authorize(): bool{return auth()->guest();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['email' => ['required', 'email:dns'],];}}
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;class ForgotPasswordFormRequest extends FormRequest{public function authorize(): bool{return auth()->guest();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['email' => ['required', 'email:dns'],];}}
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;use Illuminate\Validation\Rule;use Illuminate\Validation\Rules\Password as PasswordRules;class ResetPasswordFormRequest extends FormRequest{public function authorize(): bool{return auth()->guest();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['token' => 'required','email' => ['required', 'email'],'password' => ['required', 'confirmed', PasswordRules::default()],];}}
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;use Illuminate\Validation\Rule;use Illuminate\Validation\Rules\Password as PasswordRules;class ResetPasswordFormRequest extends FormRequest{public function authorize(): bool{return auth()->guest();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['token' => 'required','email' => ['required', 'email'],'password' => ['required', 'confirmed', PasswordRules::default()],];}}
ProfileController
namespace App\Http\Controllers;use App\Http\Requests\ProfileFormRequest;use App\Models\User;use App\MoonShine\Pages\ProfilePage;use Illuminate\Container\Attributes\CurrentUser;use Illuminate\Support\Facades\Hash;use Symfony\Component\HttpFoundation\RedirectResponse;final class ProfileController extends Controller{public function index(ProfilePage $page): ProfilePage {return $page;}public function update(ProfileFormRequest $request,#[CurrentUser] User $user): RedirectResponse{$data = $request->only(['email', 'name']);if($request->filled('password')) {$data['password'] = Hash::make($request->input('password'));}$user->update($data);return to_route('profile');}}
namespace App\Http\Controllers;use App\Http\Requests\ProfileFormRequest;use App\Models\User;use App\MoonShine\Pages\ProfilePage;use Illuminate\Container\Attributes\CurrentUser;use Illuminate\Support\Facades\Hash;use Symfony\Component\HttpFoundation\RedirectResponse;final class ProfileController extends Controller{public function index(ProfilePage $page): ProfilePage {return $page;}public function update(ProfileFormRequest $request,#[CurrentUser] User $user): RedirectResponse{$data = $request->only(['email', 'name']);if($request->filled('password')) {$data['password'] = Hash::make($request->input('password'));}$user->update($data);return to_route('profile');}}
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;use Illuminate\Validation\Rule;class ProfileFormRequest extends FormRequest{public function authorize(): bool{return auth()->check();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['name' => ['required'],'email' => ['required', 'email:dns', Rule::unique('users')->ignore(auth()->id())],'password' => ['confirmed'],];}}
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;use Illuminate\Validation\Rule;class ProfileFormRequest extends FormRequest{public function authorize(): bool{return auth()->check();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['name' => ['required'],'email' => ['required', 'email:dns', Rule::unique('users')->ignore(auth()->id())],'password' => ['confirmed'],];}}
RegisterController
namespace App\Http\Controllers;use App\Http\Requests\RegisterFormRequest;use App\Models\User;use App\MoonShine\Pages\RegisterPage;use Illuminate\Http\RedirectResponse;final class RegisterController extends Controller{public function form(RegisterPage $page): RegisterPage{return $page;}public function store(RegisterFormRequest $request): RedirectResponse{$user = User::query()->create($request->validated());auth()->login($user);return redirect()->intended(route('home'));}}
namespace App\Http\Controllers;use App\Http\Requests\RegisterFormRequest;use App\Models\User;use App\MoonShine\Pages\RegisterPage;use Illuminate\Http\RedirectResponse;final class RegisterController extends Controller{public function form(RegisterPage $page): RegisterPage{return $page;}public function store(RegisterFormRequest $request): RedirectResponse{$user = User::query()->create($request->validated());auth()->login($user);return redirect()->intended(route('home'));}}
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;use Illuminate\Validation\Rule;class RegisterFormRequest extends FormRequest{public function authorize(): bool{return auth()->guest();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['name' => ['required'],'email' => ['required', 'email:dns', Rule::unique('users')],'password' => ['required', 'confirmed'],];}}
namespace App\Http\Requests;use Illuminate\Contracts\Validation\ValidationRule;use Illuminate\Foundation\Http\FormRequest;use Illuminate\Validation\Rule;class RegisterFormRequest extends FormRequest{public function authorize(): bool{return auth()->guest();}/*** Get the validation rules that apply to the request.** @return array<string, ValidationRule|array|string>*/public function rules(): array{return ['name' => ['required'],'email' => ['required', 'email:dns', Rule::unique('users')],'password' => ['required', 'confirmed'],];}}
Вот и все! MoonShine не ограничивает вас только панелью администратора, ведь это полноценный UI kit