Change password functionality added

This commit is contained in:
Matt Young 2024-05-27 18:00:35 -05:00
parent 6a374482ec
commit e8348252f9
12 changed files with 101 additions and 15 deletions

View File

@ -2,11 +2,14 @@
namespace App\Actions\Fortify; namespace App\Actions\Fortify;
use A6digital\Image\DefaultProfileImage;
use App\Models\User; use App\Models\User;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Laravel\Fortify\Contracts\CreatesNewUsers; use Laravel\Fortify\Contracts\CreatesNewUsers;
use function mb_substr;
class CreateNewUser implements CreatesNewUsers class CreateNewUser implements CreatesNewUsers
{ {
@ -34,12 +37,15 @@ class CreateNewUser implements CreatesNewUsers
'password' => $this->passwordRules(), 'password' => $this->passwordRules(),
])->validate(); ])->validate();
$profileImageURL = 'https://ui-avatars.com/api/?name=' . mb_substr($input['first_name'],0,1) . '+' . mb_substr($input['last_name'],0,1);
return User::create([ return User::create([
'first_name' => $input['first_name'], 'first_name' => $input['first_name'],
'last_name' => $input['last_name'], 'last_name' => $input['last_name'],
'judging_preference' => $input['judging_preference'], 'judging_preference' => $input['judging_preference'],
'cell_phone' => $input['cell_phone'], 'cell_phone' => $input['cell_phone'],
'email' => $input['email'], 'email' => $input['email'],
'profile_image_url' => $profileImageURL,
'password' => Hash::make($input['password']), 'password' => Hash::make($input['password']),
]); ]);
} }

View File

@ -23,7 +23,7 @@ class UpdateUserPassword implements UpdatesUserPasswords
'password' => $this->passwordRules(), 'password' => $this->passwordRules(),
], [ ], [
'current_password.current_password' => __('The provided password does not match your current password.'), 'current_password.current_password' => __('The provided password does not match your current password.'),
])->validateWithBag('updatePassword'); ])->validate();
$user->forceFill([ $user->forceFill([
'password' => Hash::make($input['password']), 'password' => Hash::make($input['password']),

View File

@ -30,7 +30,7 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation
'max:255', 'max:255',
Rule::unique('users')->ignore($user->id), Rule::unique('users')->ignore($user->id),
], ],
])->validateWithBag('updateProfileInformation'); ])->validate();
if ($input['email'] !== $user->email && if ($input['email'] !== $user->email &&
$user instanceof MustVerifyEmail) { $user instanceof MustVerifyEmail) {

View File

@ -24,6 +24,7 @@ class User extends Authenticatable implements MustVerifyEmail
'cell_phone', 'cell_phone',
'email', 'email',
'password', 'password',
'profile_image_url'
]; ];
/** /**

View File

@ -20,6 +20,7 @@ return new class extends Migration
$table->string('email')->unique(); $table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable(); $table->timestamp('email_verified_at')->nullable();
$table->string('password'); $table->string('password');
$table->string('profile_image_url')->nullable();
$table->rememberToken(); $table->rememberToken();
$table->timestamps(); $table->timestamps();
}); });

View File

@ -0,0 +1,6 @@
@php
$buttonClasses = "text-sm font-semibold leading-6 text-gray-900";
@endphp
<div>
<button {{ $attributes->merge(['class' => $buttonClasses, 'type'=>'submit']) }}>{{ $slot }}</button>
</div>

View File

@ -0,0 +1,29 @@
@props([
'breakpoint' => 'sm',
'cols' => '6',
'method' => 'POST',
'action' => '#',
'buttons' => false,
'submitButtonText' => 'Submit'
])
<form action="{{ $action }}" method="{{ ($method == 'GET' ? 'GET':'POST') }}">
<div class="px-4 py-6 sm:p-8">
<div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 {{ $breakpoint }}:grid-cols-{{ $cols }}">
@csrf
@if($method != 'POST' AND $method != 'GET')
@method($method)
@endif
{{ $slot }}
</div>
</div>
<div class="flex items-center justify-end gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
@if($buttons)
{{ $buttons }}
@else
<x-auth.form-button-nocolor type="button">Cancel</x-auth.form-button-nocolor>
<x-auth.form-button>{{ $submitButtonText }}</x-auth.form-button>
@endif
{{ $buttons }}
</div>
</form>

View File

@ -1,3 +1,4 @@
@php use Illuminate\Support\Facades\Auth; @endphp
<nav class="bg-indigo-600" <nav class="bg-indigo-600"
x-data="{ x-data="{
mobile_menu_open: false mobile_menu_open: false
@ -56,7 +57,8 @@
aria-haspopup="true"> aria-haspopup="true">
<span class="absolute -inset-1.5"></span> <span class="absolute -inset-1.5"></span>
<span class="sr-only">Open user menu</span> <span class="sr-only">Open user menu</span>
<p class="text-white">{{ Auth::user()->full_name() }} &nbsp; &#9660;</p> <img class="h-8 w-8 rounded-full" src="{{ Auth::user()->profile_image_url }}" alt="">
{{-- <p class="text-white">{{ Auth::user()->full_name() }} &nbsp; &#9660;</p>--}}
</button> </button>
</div> </div>
@ -89,10 +91,18 @@
<!-- Active: "bg-gray-100", Not Active: "" --> <!-- Active: "bg-gray-100", Not Active: "" -->
<a href="/profile" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1" <a href="/profile" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
id="user-menu-item-0">Your Profile</a> id="user-menu-item-0">Your Profile</a>
<a href="#" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1" {{-- <a href="#" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"--}}
id="user-menu-item-1">Settings</a> {{-- id="user-menu-item-1">Settings</a>--}}
<a href="#" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1" <form method="POST" action="/logout">
id="user-menu-item-2">Sign out</a> @csrf
<button
class="block px-4 py-2 text-sm text-gray-700"
role="menuitem"
tabindex="-1"
id="user-menu-item-2">
Sign out
</button>
</form>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,8 +1,14 @@
@props([ @props([
'section_name', 'section_name',
'section_description' 'section_description',
'first' => false
]) ])
<div class="grid grid-cols-1 gap-x-8 gap-y-8 md:grid-cols-3">
@php
$topPadding = ($first) ? '':'pt-10';
@endphp
<div class="grid grid-cols-1 gap-x-8 gap-y-8 md:grid-cols-3 {{ $topPadding }}">
<div class="px-4 sm:px-0"> <div class="px-4 sm:px-0">
<h2 class="text-base font-semibold leading-7 text-gray-900">{{ $section_name }}</h2> <h2 class="text-base font-semibold leading-7 text-gray-900">{{ $section_name }}</h2>
<p class="mt-1 text-sm leading-6 text-gray-600">{{ $section_description }}</p> <p class="mt-1 text-sm leading-6 text-gray-600">{{ $section_description }}</p>

View File

@ -0,0 +1,3 @@
<x-layout.app>
<x-slot:page_title>Dashboard</x-slot:page_title>
</x-layout.app>

View File

@ -22,9 +22,17 @@
<x-layout.page-section <x-layout.page-section
section_name="Personal Information" section_name="Personal Information"
section_description="Use a permanent address where you receive mail" section_description="Use a permanent address where you receive mail"
:first="true"
> >
@if (session('status') === 'profile-information-updated')
<div class="mt-4 px-8 font-medium text-sm text-green-600">
Profile Info has been updated.
</div>
@endif
<form> <form action="/user/profile-information" method="POST">
@csrf
@method('PUT')
<div class="px-4 py-6 sm:p-8"> <div class="px-4 py-6 sm:p-8">
<div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<x-auth.form-field name="first_name" label="First Name" value="{{ Auth::user()->first_name }}" div_classes="sm:col-span-3" /> <x-auth.form-field name="first_name" label="First Name" value="{{ Auth::user()->first_name }}" div_classes="sm:col-span-3" />
@ -32,17 +40,33 @@
<x-auth.form-field name="email" label="Email Address" value="{{ Auth::user()->email }}" div_classes="sm:col-span-3" /> <x-auth.form-field name="email" label="Email Address" value="{{ Auth::user()->email }}" div_classes="sm:col-span-3" />
<x-auth.form-field name="cell_phone" label="Cell Phone" value="{{ Auth::user()->cell_phone }}" div_classes="sm:col-span-3" /> <x-auth.form-field name="cell_phone" label="Cell Phone" value="{{ Auth::user()->cell_phone }}" div_classes="sm:col-span-3" />
<x-auth.form-field name="judging_preference" label="Judging Preference" value="{{ Auth::user()->judging_preference }}" div_classes="sm:col-span-5" /> <x-auth.form-field name="judging_preference" label="Judging Preference" value="{{ Auth::user()->judging_preference }}" div_classes="sm:col-span-5" />
</div> </div>
</div> </div>
<div class="flex items-center justify-end gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8"> <div class="flex items-center justify-end gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button> <x-auth.form-button-nocolor type="button">Cancel</x-auth.form-button-nocolor>
<button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button> <x-auth.form-button>Update Profile</x-auth.form-button>
</div> </div>
</form> </form>
</x-layout.page-section> </x-layout.page-section>
<x-layout.page-section
section_name="Change Password"
section_description="Update your user password"
>
@if (session('status') === 'password-updated')
<div class="mt-4 px-8 font-medium text-sm text-green-600">
Password has been updated.
</div>
@endif
<x-auth.form-card method="PUT" action="/user/password" cols="1" submit-button-text="Change Password">
<x-auth.form-field name="current_password" label="Current Password" type="password" autocomplete="current-password" required />
<x-auth.form-field name="password" label="New Password" type="password" autocomplete="new-password" required />
<x-auth.form-field name="password_confirmation" label="Confirm New Password" autocomplete="new-password" type="password" required />
</x-auth.form-card>
</x-layout.page-section>

View File

@ -7,8 +7,8 @@ Route::get('/', function () {
}); });
Route::view('/test','test'); Route::view('/test','test');
Route::view('/profile','profile'); Route::view('/profile','profile')->middleware('auth','verified');
Route::get('/dashboard', function () { Route::get('/dashboard', function () {
return view('welcome'); return view('dashboard');
})->middleware('auth', 'verified'); })->middleware('auth', 'verified');