153 lines
7.6 KiB
PHP
153 lines
7.6 KiB
PHP
@extends('frontend.user.layout')
|
|
|
|
@section("section-account")
|
|
<div x-data="{
|
|
currentPassword: '',
|
|
newPassword: '',
|
|
confirmPassword: '',
|
|
showCurrentPassword: false,
|
|
showNewPassword: false,
|
|
showConfirmPassword: false,
|
|
passwordStrength: 0,
|
|
passwordMatch: null
|
|
}" class="col-span-12 lg:col-span-9 animate__animated animate__fadeInUp">
|
|
<form action="{{ route('user.password.store') }}" method="post"
|
|
class="grid grid-cols-1 md:grid-cols-2 gap-6 bg-white rounded-xl shadow-md mt-5 p-5">
|
|
@csrf
|
|
@method('put')
|
|
|
|
<!-- Ảnh minh hoạ -->
|
|
<div>
|
|
<img src="{{ asset('images/password-reset.jpg') }}" alt="{{ $title }}" class="w-full h-auto rounded">
|
|
</div>
|
|
|
|
<!-- Form nhập mật khẩu -->
|
|
<div class="space-y-5 self-center">
|
|
<!-- Mật khẩu cũ -->
|
|
<flux:field>
|
|
<flux:label>Nhập mật khẩu cũ</flux:label>
|
|
<flux:input
|
|
x-bind:type="showCurrentPassword ? 'text' : 'password'"
|
|
icon="lock-closed"
|
|
placeholder="*******"
|
|
name="password"
|
|
x-model="currentPassword"
|
|
autocomplete="current-password"
|
|
value="{{ old('password') }}">
|
|
<x-slot name="iconTrailing">
|
|
<flux:button size="sm" variant="subtle" class="-mr-1"
|
|
@click="showCurrentPassword = !showCurrentPassword" type="button">
|
|
<flux:icon.eye x-show="!showCurrentPassword" class="w-4 h-4" />
|
|
<flux:icon.eye-slash x-show="showCurrentPassword" class="w-4 h-4" />
|
|
</flux:button>
|
|
</x-slot>
|
|
</flux:input>
|
|
</flux:field>
|
|
|
|
<!-- Mật khẩu mới -->
|
|
<flux:field>
|
|
<flux:label>Mật khẩu mới</flux:label>
|
|
<flux:input
|
|
x-bind:type="showNewPassword ? 'text' : 'password'"
|
|
icon="lock-closed"
|
|
placeholder="*******"
|
|
name="new_password"
|
|
x-model="newPassword"
|
|
autocomplete="new-password"
|
|
value="{{ old('new_password') }}"
|
|
@input="
|
|
passwordStrength = 0;
|
|
if (newPassword.length >= 8) passwordStrength++;
|
|
if (/[0-9]/.test(newPassword)) passwordStrength++;
|
|
if (/[A-Z]/.test(newPassword) && /[a-z]/.test(newPassword)) passwordStrength++;
|
|
if (/[^A-Za-z0-9]/.test(newPassword)) passwordStrength++;
|
|
passwordMatch = confirmPassword === newPassword ? true : (confirmPassword === '' ? null : false);
|
|
">
|
|
<x-slot name="iconTrailing">
|
|
<flux:button size="sm" variant="subtle" class="-mr-1"
|
|
@click="showNewPassword = !showNewPassword" type="button">
|
|
<flux:icon.eye x-show="!showNewPassword" class="w-4 h-4" />
|
|
<flux:icon.eye-slash x-show="showNewPassword" class="w-4 h-4" />
|
|
</flux:button>
|
|
</x-slot>
|
|
</flux:input>
|
|
|
|
<!-- Password Strength Indicator -->
|
|
<div class="mt-2">
|
|
<div class="flex gap-1 mb-1">
|
|
<template x-for="i in 4" :key="i">
|
|
<div class="h-1 flex-1 rounded-full transition-colors"
|
|
:class="{
|
|
'bg-gray-200': passwordStrength < i,
|
|
'bg-red-500': passwordStrength === 1 && i === 1,
|
|
'bg-yellow-500': passwordStrength === 2 && i <= 2,
|
|
'bg-emerald-500': passwordStrength === 3 && i <= 3,
|
|
'bg-green-500': passwordStrength === 4 && i <= 4
|
|
}">
|
|
</div>
|
|
</template>
|
|
</div>
|
|
<p class="text-xs font-medium"
|
|
:class="{
|
|
'text-red-500': passwordStrength === 1,
|
|
'text-yellow-500': passwordStrength === 2,
|
|
'text-emerald-500': passwordStrength === 3,
|
|
'text-green-500': passwordStrength === 4,
|
|
'text-gray-500': passwordStrength === 0
|
|
}"
|
|
x-text="[
|
|
'Độ bảo mật mật khẩu sẽ được hiển thị ở đây',
|
|
'Yếu',
|
|
'Trung bình',
|
|
'Tốt',
|
|
'Rất mạnh'
|
|
][passwordStrength]">
|
|
</p>
|
|
</div>
|
|
</flux:field>
|
|
|
|
<!-- Nhập lại mật khẩu mới -->
|
|
<flux:field>
|
|
<flux:label>Nhập lại mật khẩu mới</flux:label>
|
|
<flux:input
|
|
x-bind:type="showConfirmPassword ? 'text' : 'password'"
|
|
icon="shield-check"
|
|
placeholder="*******"
|
|
name="confirm_password"
|
|
x-model="confirmPassword"
|
|
autocomplete="new-password"
|
|
value="{{ old('confirm_password') }}"
|
|
@input="passwordMatch = (confirmPassword === newPassword) ? true : false">
|
|
<x-slot name="iconTrailing">
|
|
<flux:button size="sm" variant="subtle" class="-mr-1"
|
|
@click="showConfirmPassword = !showConfirmPassword" type="button">
|
|
<flux:icon.eye x-show="!showConfirmPassword" class="w-4 h-4" />
|
|
<flux:icon.eye-slash x-show="showConfirmPassword" class="w-4 h-4" />
|
|
</flux:button>
|
|
</x-slot>
|
|
</flux:input>
|
|
|
|
<!-- Password Match Indicator -->
|
|
<flux:error x-show="passwordMatch === false" class="text-red-500">
|
|
Mật khẩu không khớp
|
|
</flux:error>
|
|
<flux:description x-show="passwordMatch === true" class="text-green-500">
|
|
Mật khẩu trùng khớp
|
|
</flux:description>
|
|
<flux:description x-show="passwordMatch === null" class="text-gray-500">
|
|
Vui lòng xác nhận mật khẩu
|
|
</flux:description>
|
|
</flux:field>
|
|
</div>
|
|
|
|
<!-- Nút submit -->
|
|
<div class="col-span-1 md:col-span-2 text-end pt-4">
|
|
<flux:button type="submit" icon:trailing="arrow-right" variant="primary" color="orange">
|
|
Lưu thông tin
|
|
</flux:button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
@endsection
|