select box
This commit is contained in:
@@ -15,5 +15,6 @@
|
||||
<button type="submit" class="inline-flex items-center justify-center bg-red-600 hover:bg-red-700 text-white font-bold py-2.5 px-6 rounded-xl text-sm transition-colors shadow-md shadow-red-500/10 min-w-[120px] h-[45px]">Nghỉ việc</button>
|
||||
@elseif($mode === 'self')
|
||||
<a href="{{ route('user.dashboard') }}" class="inline-flex items-center justify-center bg-white border border-[#d9dfe7] hover:bg-gray-50 text-[#1a2b49] font-bold py-2.5 px-6 rounded-xl text-sm transition-colors shadow-sm min-w-[120px] h-[45px]">Quay lại</a>
|
||||
<button type="submit" class="inline-flex items-center justify-center bg-[#3462f7] hover:bg-blue-700 text-white font-bold py-2.5 px-6 rounded-xl text-sm transition-colors shadow-md shadow-blue-500/10 min-w-[120px] h-[45px]">Lưu Thay Đổi</button>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
@props(['mode', 'user' => null])
|
||||
|
||||
@if($mode === 'create' || $mode === 'edit')
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<!-- Quyền hạn -->
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2">Quyền hạn <span class="text-red-500">*</span></label>
|
||||
<div class="grid grid-cols-2 gap-2 mt-2 bg-gray-100/80 p-1 rounded-xl">
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="role" value="{{ config('constants.ROLE_MEMBER') }}" class="sr-only" {{ old('role', $user?->role) == config('constants.ROLE_MEMBER') || (is_null($user) && old('role') != config('constants.ROLE_ADMIN')) ? 'checked' : '' }}>
|
||||
<span>Member</span>
|
||||
</label>
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="role" value="{{ config('constants.ROLE_ADMIN') }}" class="sr-only" {{ old('role', $user?->role) == config('constants.ROLE_ADMIN') ? 'checked' : '' }}>
|
||||
<span>Admin</span>
|
||||
</label>
|
||||
</div>
|
||||
@error('role')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
@if($mode === 'edit')
|
||||
<!-- Trạng thái -->
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2">Trạng thái <span class="text-red-500">*</span></label>
|
||||
<div class="grid grid-cols-2 gap-2 mt-2 bg-gray-100/80 p-1 rounded-xl">
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="status" value="{{ config('constants.STATUS_ACTIVE') }}" class="sr-only" {{ old('status', $user?->status) == config('constants.STATUS_ACTIVE') ? 'checked' : '' }}>
|
||||
<span>Đang làm việc</span>
|
||||
</label>
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="status" value="{{ config('constants.STATUS_INACTIVE') }}" class="sr-only" {{ old('status', $user?->status) == config('constants.STATUS_INACTIVE') ? 'checked' : '' }}>
|
||||
<span>Đã nghỉ việc</span>
|
||||
</label>
|
||||
</div>
|
||||
@error('status')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<!-- Quyền gửi thẻ -->
|
||||
<div class="relative col-span-1">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2">Quyền gửi thẻ <span class="text-red-500">*</span></label>
|
||||
<div class="grid grid-cols-2 gap-2 mt-2 bg-gray-100/80 p-1 rounded-xl">
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="flag_send" value="{{ config('constants.FLAG_SEND_ENABLED') }}" class="sr-only" {{ old('flag_send', $user?->flag_send) == config('constants.FLAG_SEND_ENABLED') ? 'checked' : '' }}>
|
||||
<span>Được phép gửi</span>
|
||||
</label>
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="flag_send" value="{{ config('constants.FLAG_SEND_DISABLED') }}" class="sr-only" {{ old('flag_send', $user?->flag_send) == config('constants.FLAG_SEND_DISABLED') ? 'checked' : '' }}>
|
||||
<span>Không cho phép</span>
|
||||
</label>
|
||||
</div>
|
||||
@error('flag_send')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@@ -0,0 +1,29 @@
|
||||
@props(['mode', 'user' => null])
|
||||
|
||||
<div class="flex items-center gap-4 mb-6">
|
||||
<div class="w-16 h-16 rounded-full overflow-hidden border border-gray-200 shrink-0">
|
||||
<img src="{{ ($user && $user->avatar) ? asset($user->avatar) : asset('images/avatar.png') }}" alt="Avatar" class="w-full h-full object-cover" id="avatar-preview" onerror="this.onerror=null; this.src='{{ asset('images/avatar.png') }}';">
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="block text-[13px] font-bold text-gray-700 mb-1" for="avatar">Thay đổi ảnh đại diện</label>
|
||||
<input type="file" name="avatar" id="avatar" accept="image/*" class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-3 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-[#3462f7] file:text-white hover:file:bg-[#254edb]" onchange="previewAvatar(event)">
|
||||
@error('avatar')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@once
|
||||
@push('scripts')
|
||||
<script>
|
||||
function previewAvatar(event) {
|
||||
const input = event.target;
|
||||
if (input.files && input.files[0]) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
document.getElementById('avatar-preview').src = e.target.result;
|
||||
};
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@endpush
|
||||
@endonce
|
||||
@@ -0,0 +1,95 @@
|
||||
@props(['mode', 'user' => null])
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
|
||||
<!-- MSNV -->
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="msnv">Mã nhân viên (MSNV) <span class="text-red-500">*</span></label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 9h3.75M15 12h3.75M15 15h3.75M4.5 19.5h15a2.25 2.25 0 002.25-2.25V6.75A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25v10.5A2.25 2.25 0 004.5 19.5zm6-10.125a1.875 1.875 0 11-3.75 0 1.875 1.875 0 013.75 0zm1.294 6.336a6.721 6.721 0 01-3.17.789 6.721 6.721 0 01-3.168-.789 3.376 3.376 0 016.338 0z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="number" name="msnv" id="msnv"
|
||||
class="form-input form-input-with-icon !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20 {{ $mode !== 'create' ? '!bg-gray-50 !text-gray-500 cursor-not-allowed' : '' }}"
|
||||
style="padding-left: 48px;"
|
||||
{{ $mode !== 'create' ? 'readonly' : 'required' }}
|
||||
value="{{ old('msnv', $user?->msnv) }}"
|
||||
placeholder="VD: 1001">
|
||||
</div>
|
||||
@error('msnv')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<!-- Name -->
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="name">Họ và tên <span class="text-red-500">*</span></label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="text" name="name" id="name"
|
||||
class="form-input form-input-with-icon !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20"
|
||||
style="padding-left: 48px;"
|
||||
required
|
||||
value="{{ old('name', $user?->name) }}"
|
||||
placeholder="VD: Nguyễn Văn A">
|
||||
</div>
|
||||
@error('name')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="mail">Email <span class="text-red-500">*</span></label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="email" name="mail" id="mail"
|
||||
class="form-input form-input-with-icon !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20 {{ $mode === 'self' ? '!bg-gray-50 !text-gray-500 cursor-not-allowed' : '' }}"
|
||||
style="padding-left: 48px;"
|
||||
{{ $mode === 'self' ? 'readonly' : 'required' }}
|
||||
value="{{ old('mail', $user?->mail) }}"
|
||||
placeholder="VD: nguyenvana@runsystem.net">
|
||||
</div>
|
||||
@error('mail')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<!-- Department -->
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="departments">Phòng ban <span class="text-red-500">*</span></label>
|
||||
@if($mode === 'self')
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 14.15v4.25c0 .621-.504 1.125-1.125 1.125H4.875c-.621 0-1.125-.504-1.125-1.125v-4.25m16.5 0a2.18 2.18 0 0 0 .75-1.661V8.706c0-1.081-.768-2.015-1.837-2.175a48.114 48.114 0 0 0-3.413-.387m4.5 8.006c-.194.165-.453.254-.718.254H4.875a1.03 1.03 0 0 1-.718-.254m16.5 0c-.417-.38-.953-.59-1.517-.59H4.875A2.25 2.25 0 0 0 2.25 14.15v-4.25c0-1.081.768-2.015 1.837-2.175a48.067 48.067 0 0 1 16.076 0c1.069.16 1.837 1.094 1.837 2.175v4.25Z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="text"
|
||||
class="form-input form-input-with-icon !rounded-xl !bg-gray-50 !text-gray-500 cursor-not-allowed w-full"
|
||||
style="padding-left: 48px;"
|
||||
readonly
|
||||
title="{{ $user?->departments }}"
|
||||
value="{{ $user?->departments }}">
|
||||
</div>
|
||||
@else
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center z-10">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 14.15v4.25c0 .621-.504 1.125-1.125 1.125H4.875c-.621 0-1.125-.504-1.125-1.125v-4.25m16.5 0a2.18 2.18 0 0 0 .75-1.661V8.706c0-1.081-.768-2.015-1.837-2.175a48.114 48.114 0 0 0-3.413-.387m4.5 8.006c-.194.165-.453.254-.718.254H4.875a1.03 1.03 0 0 1-.718-.254m16.5 0c-.417-.38-.953-.59-1.517-.59H4.875A2.25 2.25 0 0 0 2.25 14.15v-4.25c0-1.081.768-2.015 1.837-2.175a48.067 48.067 0 0 1 16.076 0c1.069.16 1.837 1.094 1.837 2.175v4.25Z" />
|
||||
</svg>
|
||||
</span>
|
||||
<select name="departments" id="departments" class="form-input form-input-with-icon !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20 w-full" style="padding-left: 48px;" required>
|
||||
<option value="">-- Chọn phòng ban --</option>
|
||||
@foreach(config('constants.DEPARTMENTS') as $dept)
|
||||
<option value="{{ $dept }}" {{ old('departments', $user?->departments) == $dept ? 'selected' : '' }}>{{ $dept }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
@endif
|
||||
@error('departments')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
</div>
|
||||
@@ -68,8 +68,6 @@
|
||||
width: 220px !important;
|
||||
}
|
||||
}
|
||||
.ts-control { border-radius: 0.75rem; border-color: #d9dfe7; padding: 0.45rem 1rem; }
|
||||
.ts-wrapper.form-input { padding: 0; border: none; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@@ -84,6 +82,9 @@
|
||||
},
|
||||
placeholder: "🔍 Tìm phòng ban...",
|
||||
render: {
|
||||
item: function(data, escape) {
|
||||
return '<div class="item" title="' + escape(data.text) + '">' + escape(data.text) + '</div>';
|
||||
},
|
||||
no_results: function(data, escape) {
|
||||
return '<div class="no-results p-3 text-gray-500">Không tìm thấy phòng ban nào</div>';
|
||||
}
|
||||
|
||||
@@ -22,18 +22,19 @@
|
||||
@endphp
|
||||
|
||||
<div class="bg-white rounded-[24px] shadow-[0_10px_30px_rgba(15,23,42,0.05)] border border-white overflow-hidden flex flex-col justify-between">
|
||||
<div class="bg-gradient-to-r from-blue-50/70 via-indigo-50/50 to-purple-50/30 px-6 py-6 sm:px-8 border-b border-gray-100">
|
||||
<h3 class="text-[17px] font-extrabold text-[#1a2b49] leading-tight flex items-center gap-2">
|
||||
<span>{{ match($mode) {
|
||||
'create' => '👥 Thêm User Mới',
|
||||
'edit' => '⚙️ Quản Lý Thẻ: ' . ($user?->msnv),
|
||||
'delete' => '⚠️ Xác nhận nghỉ việc: ' . ($user?->msnv),
|
||||
'self' => '👤 Thông tin cá nhân: ' . ($user?->msnv),
|
||||
} }}</span>
|
||||
</h3>
|
||||
</div>
|
||||
@if($mode !== 'edit')
|
||||
<div class="bg-gradient-to-r from-blue-50/70 via-indigo-50/50 to-purple-50/30 px-6 py-6 sm:px-8 border-b border-gray-100">
|
||||
<h3 class="text-[17px] font-extrabold text-[#1a2b49] leading-tight flex items-center gap-2">
|
||||
<span>{{ match($mode) {
|
||||
'create' => '👥 Thêm User Mới',
|
||||
'delete' => '⚠️ Xác nhận nghỉ việc: ' . ($user?->msnv),
|
||||
'self' => '👤 Thông tin cá nhân: ' . ($user?->msnv),
|
||||
} }}</span>
|
||||
</h3>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(!$isCreate && $user && !$isEdit)
|
||||
@if(!$isCreate && $user && !$isEdit && !$isSelf)
|
||||
<div class="p-6 sm:p-8 pb-0">
|
||||
<div class="mb-2 p-5 rounded-2xl bg-gradient-to-br from-slate-50 to-gray-50 border border-gray-100 flex items-center gap-4 shadow-sm">
|
||||
<div class="w-12 h-12 rounded-full bg-blue-50 text-[#3462f7] flex items-center justify-center font-extrabold text-lg shadow-inner flex-shrink-0">
|
||||
@@ -55,168 +56,32 @@
|
||||
@endif
|
||||
|
||||
@if($actionUrl)
|
||||
<form action="{{ $actionUrl }}" method="POST" class="flex flex-col flex-1 justify-between">
|
||||
<form action="{{ $actionUrl }}" method="POST" enctype="multipart/form-data" class="flex flex-col flex-1 justify-between">
|
||||
@csrf
|
||||
@if($method !== 'POST')
|
||||
@method($method)
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<div class="p-6 sm:p-8 {{ !$isCreate && !$isEdit ? 'pt-0' : '' }} space-y-5">
|
||||
@if($isCreate)
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="msnv">Mã nhân viên (MSNV) <span class="text-red-500">*</span></label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 9h3.75M15 12h3.75M15 15h3.75M4.5 19.5h15a2.25 2.25 0 002.25-2.25V6.75A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25v10.5A2.25 2.25 0 004.5 19.5zm6-10.125a1.875 1.875 0 11-3.75 0 1.875 1.875 0 013.75 0zm1.294 6.336a6.721 6.721 0 01-3.17.789 6.721 6.721 0 01-3.168-.789 3.376 3.376 0 016.338 0z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="number" name="msnv" id="msnv" class="form-input form-input-with-icon !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20" style="padding-left: 48px;" required value="{{ old('msnv') }}" placeholder="VD: 1001">
|
||||
</div>
|
||||
@error('msnv')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="name">Họ và tên <span class="text-red-500">*</span></label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="text" name="name" id="name" class="form-input form-input-with-icon !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20" style="padding-left: 48px;" required value="{{ old('name') }}" placeholder="VD: Nguyễn Văn A">
|
||||
</div>
|
||||
@error('name')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="mail">Email <span class="text-red-500">*</span></label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="email" name="mail" id="mail" class="form-input form-input-with-icon !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20" style="padding-left: 48px;" required value="{{ old('mail') }}" placeholder="VD: nguyenvana@runsystem.net">
|
||||
</div>
|
||||
@error('mail')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="departments">Phòng ban <span class="text-red-500">*</span></label>
|
||||
<select name="departments" id="departments" class="form-input !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20" required>
|
||||
<option value="">-- Chọn phòng ban --</option>
|
||||
@foreach(config('constants.DEPARTMENTS') as $dept)
|
||||
<option value="{{ $dept }}" {{ old('departments') == $dept ? 'selected' : '' }}>{{ $dept }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('departments')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="password">Mật khẩu khởi tạo <span class="text-red-500">*</span></label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0V10.5m-2.812 10.5h14.625c.621 0 1.125-.504 1.125-1.125V11.25c0-.621-.504-1.125-1.125-1.125H3.75c-.621 0-1.125.504-1.125 1.125v7.875c0 .621.504 1.125 1.125 1.125z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="text" name="password" id="password" class="form-input form-input-with-icon !rounded-xl !bg-gray-50 !text-gray-500 cursor-not-allowed" style="padding-left: 48px;" readonly required value="1234@Dcba">
|
||||
</div>
|
||||
<span class="text-[13px] text-gray-400 mt-2 block">Mật khẩu mặc định cho tất cả user mới tạo.</span>
|
||||
@error('password')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="role">Quyền hạn <span class="text-red-500">*</span></label>
|
||||
<select name="role" id="role" class="form-input !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20" required>
|
||||
<option value="{{ config('constants.ROLE_MEMBER') }}" {{ old('role') == config('constants.ROLE_MEMBER') ? 'selected' : '' }}>Member</option>
|
||||
<option value="{{ config('constants.ROLE_ADMIN') }}" {{ old('role') == config('constants.ROLE_ADMIN') ? 'selected' : '' }}>Admin</option>
|
||||
</select>
|
||||
@error('role')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($isEdit && $user)
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="mail">Email (Chỉ xem)</label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="email" name="mail" id="mail" class="form-input form-input-with-icon !rounded-xl !bg-gray-50 !text-gray-500 cursor-not-allowed w-full" style="padding-left: 48px;" readonly value="{{ $user->mail }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="password">Mật khẩu (Chỉ xem)</label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0V10.5m-2.812 10.5h14.625c.621 0 1.125-.504 1.125-1.125V11.25c0-.621-.504-1.125-1.125-1.125H3.75c-.621 0-1.125.504-1.125 1.125v7.875c0 .621.504 1.125 1.125 1.125z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="password" name="password" id="password" class="form-input form-input-with-icon !rounded-xl !bg-gray-50 !text-gray-500 cursor-not-allowed w-full" style="padding-left: 48px;" readonly value="********">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2">Quyền hạn</label>
|
||||
<div class="grid grid-cols-2 gap-2 mt-2 bg-gray-100/80 p-1 rounded-xl">
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="role" value="{{ config('constants.ROLE_MEMBER') }}" class="sr-only" {{ old('role', $user->role) == config('constants.ROLE_MEMBER') ? 'checked' : '' }}>
|
||||
<span>Member</span>
|
||||
</label>
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="role" value="{{ config('constants.ROLE_ADMIN') }}" class="sr-only" {{ old('role', $user->role) == config('constants.ROLE_ADMIN') ? 'checked' : '' }}>
|
||||
<span>Admin</span>
|
||||
</label>
|
||||
</div>
|
||||
@error('role')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2">Trạng thái</label>
|
||||
<div class="grid grid-cols-2 gap-2 mt-2 bg-gray-100/80 p-1 rounded-xl">
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="status" value="{{ config('constants.STATUS_ACTIVE') }}" class="sr-only" {{ old('status', $user->status) == config('constants.STATUS_ACTIVE') ? 'checked' : '' }}>
|
||||
<span>Đang làm việc</span>
|
||||
</label>
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="status" value="{{ config('constants.STATUS_INACTIVE') }}" class="sr-only" {{ old('status', $user->status) == config('constants.STATUS_INACTIVE') ? 'checked' : '' }}>
|
||||
<span>Đã nghỉ việc</span>
|
||||
</label>
|
||||
</div>
|
||||
@error('status')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2">Quyền gửi thẻ</label>
|
||||
<div class="grid grid-cols-2 gap-2 mt-2 bg-gray-100/80 p-1 rounded-xl">
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="flag_send" value="{{ config('constants.FLAG_SEND_ENABLED') }}" class="sr-only" {{ old('flag_send', $user->flag_send) == config('constants.FLAG_SEND_ENABLED') ? 'checked' : '' }}>
|
||||
<span>Được phép gửi</span>
|
||||
</label>
|
||||
<label class="flex items-center justify-center gap-2 cursor-pointer py-2 rounded-lg transition-all text-center has-[:checked]:bg-white has-[:checked]:text-[#3462f7] has-[:checked]:shadow-sm text-gray-500 font-bold text-sm hover:bg-white/50">
|
||||
<input type="radio" name="flag_send" value="{{ config('constants.FLAG_SEND_DISABLED') }}" class="sr-only" {{ old('flag_send', $user->flag_send) == config('constants.FLAG_SEND_DISABLED') ? 'checked' : '' }}>
|
||||
<span>Không cho phép</span>
|
||||
</label>
|
||||
</div>
|
||||
@error('flag_send')<span class="text-red-500 text-[13px] font-semibold mt-1.5 block">{{ $message }}</span>@enderror
|
||||
</div>
|
||||
|
||||
<div class="hidden md:block"></div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="p-6 sm:p-8 {{ !$isCreate && !$isEdit && !$isSelf ? 'pt-0' : '' }} space-y-5">
|
||||
@if($isDelete && $user)
|
||||
<p class="text-sm text-red-600 leading-relaxed font-semibold">
|
||||
Bạn có chắc chắn muốn cho nhân viên {{ $user->msnv }} nghỉ việc không? Tài khoản này sẽ không thể đăng nhập hoặc thực hiện các giao dịch thẻ sau khi xác nhận.
|
||||
</p>
|
||||
@else
|
||||
<!-- 1. User Avatar Section -->
|
||||
@if($isSelf || $isEdit)
|
||||
<x-user-avatar-section :mode="$mode" :user="$user" />
|
||||
@endif
|
||||
|
||||
<!-- 2. User Basic Information Section -->
|
||||
<x-user-basic-info :mode="$mode" :user="$user" />
|
||||
|
||||
<!-- 3. User Security Section -->
|
||||
<x-user-security-section :mode="$mode" :user="$user" />
|
||||
|
||||
<!-- 4. User Administration Fields Section -->
|
||||
<x-user-admin-section :mode="$mode" :user="$user" />
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -227,30 +92,28 @@
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if($isCreate)
|
||||
@push('styles')
|
||||
<style>
|
||||
.ts-control { border-radius: 0.75rem; border-color: #d9dfe7; padding: 0.65rem 1rem; }
|
||||
.ts-wrapper.form-input { padding: 0; border: none; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@if($isCreate || $isEdit)
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
new TomSelect("#departments", {
|
||||
create: false,
|
||||
sortField: {
|
||||
field: "text",
|
||||
direction: "asc"
|
||||
},
|
||||
placeholder: "🔍 Tìm phòng ban...",
|
||||
render: {
|
||||
no_results: function(data, escape) {
|
||||
return '<div class="no-results p-3 text-gray-500">Không tìm thấy phòng ban nào</div>';
|
||||
if (document.getElementById('departments') && typeof TomSelect === 'function') {
|
||||
new TomSelect("#departments", {
|
||||
create: false,
|
||||
sortField: {
|
||||
field: "text",
|
||||
direction: "asc"
|
||||
},
|
||||
placeholder: "Tìm phòng ban...",
|
||||
render: {
|
||||
item: function(data, escape) {
|
||||
return '<div class="item" title="' + escape(data.text) + '">' + escape(data.text) + '</div>';
|
||||
},
|
||||
no_results: function(data, escape) {
|
||||
return '<div class="no-results p-3 text-gray-500">Không tìm thấy phòng ban nào</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4 bg-slate-50 border border-slate-100 rounded-2xl p-4 relative z-10 min-w-[200px] shadow-sm">
|
||||
<div class="flex items-center gap-4 bg-slate-50 border border-slate-100 rounded-2xl p-4 relative z-10 min-w-[220px] shadow-sm">
|
||||
<div class="w-11 h-11 bg-white rounded-xl shadow-sm flex items-center justify-center text-xl">
|
||||
🎫
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex-1">
|
||||
<span class="text-[10px] font-bold text-gray-500 uppercase tracking-wider block">Số thẻ hiện có</span>
|
||||
<span id="user-card-balance" class="text-xl font-black text-[#1a2b49]">{{ $user->card }}</span>
|
||||
</div>
|
||||
@@ -82,10 +82,10 @@
|
||||
<table class="min-w-full divide-y divide-gray-100 text-sm">
|
||||
<thead class="bg-gray-50/50 sticky top-0 z-10">
|
||||
<tr>
|
||||
<th class="px-6 py-4 text-center text-xs font-bold text-text-light uppercase tracking-wider w-24">Hành động</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-text-light uppercase tracking-wider">Ngày cấp</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-text-light uppercase tracking-wider">Người cấp (Admin)</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-text-light uppercase tracking-wider">Số lượng thẻ</th>
|
||||
<th class="px-6 py-4 text-center text-xs font-bold text-text-light uppercase tracking-wider w-24">Hành động</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
@@ -94,6 +94,16 @@
|
||||
$isCurrentMonth = Carbon\Carbon::parse($addCard->date)->format('Y-m') === Carbon\Carbon::now()->format('Y-m');
|
||||
@endphp
|
||||
<tr class="hover:bg-slate-50/60 transition-colors">
|
||||
<td class="px-6 py-3.5 whitespace-nowrap text-center">
|
||||
@if($isCurrentMonth)
|
||||
<div class="flex items-center justify-center gap-3">
|
||||
<button type="button" onclick="openEditAddCardModal({{ json_encode($addCard) }})" class="text-blue-600 hover:text-blue-900 font-bold transition-colors">Sửa</button>
|
||||
<button type="button" onclick="confirmDeleteAddCard({{ $addCard->id }})" class="text-red-600 hover:text-red-900 font-bold transition-colors">Xóa</button>
|
||||
</div>
|
||||
@else
|
||||
<span class="text-gray-400 font-semibold text-xs cursor-not-allowed" title="Không thể chỉnh sửa giao dịch tháng trước">Tháng trước</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-3.5 whitespace-nowrap text-text-medium font-medium">{{ Carbon\Carbon::parse($addCard->date)->format('d/m/Y') }}</td>
|
||||
<td class="px-6 py-3.5 whitespace-nowrap font-bold text-[#1a2b49]">
|
||||
@if($addCard->sellerUser)
|
||||
@@ -106,13 +116,6 @@
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-3.5 whitespace-nowrap font-extrabold text-base text-green-600">+{{ $addCard->num_card }}</td>
|
||||
<td class="px-6 py-3.5 whitespace-nowrap text-center">
|
||||
@if($isCurrentMonth)
|
||||
<button type="button" onclick="openEditAddCardModal({{ json_encode($addCard) }})" class="text-blue-600 hover:text-blue-900 font-bold transition-colors">Sửa</button>
|
||||
@else
|
||||
<span class="text-gray-400 font-semibold text-xs cursor-not-allowed" title="Không thể chỉnh sửa giao dịch tháng trước">Tháng trước</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
@@ -124,9 +127,12 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@php
|
||||
$isCurrentMonthFilter = $selectedMonth === Carbon\Carbon::now()->format('Y-m');
|
||||
@endphp
|
||||
<div class="px-6 py-4 bg-slate-50 border-t border-gray-100 flex justify-end">
|
||||
<button type="button" onclick="openAddCardModal()" class="inline-flex items-center gap-2 bg-[#3462f7] hover:bg-blue-700 text-white font-bold text-sm px-5 py-2.5 rounded-xl shadow-md shadow-blue-500/10 transition-all">
|
||||
➕ Thêm thẻ
|
||||
<button type="button" onclick="openAddCardModal()" {{ !$isCurrentMonthFilter ? 'disabled' : '' }} class="inline-flex items-center justify-center bg-[#3462f7] hover:bg-blue-700 disabled:bg-gray-300 disabled:text-gray-500 disabled:cursor-not-allowed disabled:shadow-none text-white font-bold text-sm px-5 py-2.5 rounded-xl shadow-md shadow-blue-500/10 transition-all">
|
||||
Thêm thẻ
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -171,10 +177,10 @@
|
||||
<table class="min-w-full divide-y divide-gray-100 text-sm">
|
||||
<thead class="bg-gray-50/50 sticky top-0">
|
||||
<tr>
|
||||
<th class="px-6 py-4 text-center text-xs font-bold text-text-light uppercase tracking-wider w-24">Hành động</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-text-light uppercase tracking-wider">Ngày cấp</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-text-light uppercase tracking-wider">Người cấp (Admin)</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-bold text-text-light uppercase tracking-wider">Số lượng thẻ</th>
|
||||
<th class="px-6 py-4 text-center text-xs font-bold text-text-light uppercase tracking-wider w-24">Hành động</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
@@ -183,6 +189,16 @@
|
||||
$isCurrentMonth = Carbon\Carbon::parse($addCard->date)->format('Y-m') === Carbon\Carbon::now()->format('Y-m');
|
||||
@endphp
|
||||
<tr class="hover:bg-slate-50/60 transition-colors">
|
||||
<td class="px-6 py-3.5 whitespace-nowrap text-center">
|
||||
@if($isCurrentMonth)
|
||||
<div class="flex items-center justify-center gap-3">
|
||||
<button type="button" onclick="openEditAddCardModal({{ json_encode($addCard) }})" class="text-blue-600 hover:text-blue-900 font-bold transition-colors">Sửa</button>
|
||||
<button type="button" onclick="confirmDeleteAddCard({{ $addCard->id }})" class="text-red-600 hover:text-red-900 font-bold transition-colors">Xóa</button>
|
||||
</div>
|
||||
@else
|
||||
<span class="text-gray-400 font-semibold text-xs cursor-not-allowed" title="Không thể chỉnh sửa giao dịch tháng trước">Tháng trước</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-3.5 whitespace-nowrap text-text-medium font-medium">{{ Carbon\Carbon::parse($addCard->date)->format('d/m/Y') }}</td>
|
||||
<td class="px-6 py-3.5 whitespace-nowrap font-bold text-[#1a2b49]">
|
||||
@if($addCard->sellerUser)
|
||||
@@ -195,13 +211,6 @@
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-3.5 whitespace-nowrap font-extrabold text-base text-green-600">+{{ $addCard->num_card }}</td>
|
||||
<td class="px-6 py-3.5 whitespace-nowrap text-center">
|
||||
@if($isCurrentMonth)
|
||||
<button type="button" onclick="openEditAddCardModal({{ json_encode($addCard) }})" class="text-blue-600 hover:text-blue-900 font-bold transition-colors">Sửa</button>
|
||||
@else
|
||||
<span class="text-gray-400 font-semibold text-xs cursor-not-allowed" title="Không thể chỉnh sửa giao dịch tháng trước">Tháng trước</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
@@ -213,9 +222,12 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@php
|
||||
$isCurrentMonthFilter = $selectedMonth === Carbon\Carbon::now()->format('Y-m');
|
||||
@endphp
|
||||
<div class="px-6 py-4 bg-slate-50 border-t border-gray-100 flex justify-end">
|
||||
<button type="button" onclick="openAddCardModal()" class="inline-flex items-center gap-2 bg-[#3462f7] hover:bg-blue-700 text-white font-bold text-sm px-5 py-2.5 rounded-xl shadow-md shadow-blue-500/10 transition-all">
|
||||
➕ Thêm thẻ
|
||||
<button type="button" onclick="openAddCardModal()" {{ !$isCurrentMonthFilter ? 'disabled' : '' }} class="inline-flex items-center justify-center bg-[#3462f7] hover:bg-blue-700 disabled:bg-gray-300 disabled:text-gray-500 disabled:cursor-not-allowed disabled:shadow-none text-white font-bold text-sm px-5 py-2.5 rounded-xl shadow-md shadow-blue-500/10 transition-all">
|
||||
Thêm thẻ
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -275,6 +287,8 @@
|
||||
</form>
|
||||
</x-modal>
|
||||
|
||||
<x-confirm-modal id="deleteAddCardModal" title="Xác nhận xóa giao dịch" confirmText="Xác nhận xóa" />
|
||||
|
||||
<script>
|
||||
function openEditAddCardModal(record) {
|
||||
const form = document.getElementById('editAddCardForm');
|
||||
@@ -340,6 +354,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
function confirmDeleteAddCard(id) {
|
||||
const messageEl = document.getElementById('deleteAddCardModal-message');
|
||||
if (messageEl) {
|
||||
messageEl.innerHTML = 'Bạn có chắc chắn muốn xóa giao dịch cấp phát thẻ này không? Thao tác này sẽ trừ số thẻ tương ứng của user.';
|
||||
}
|
||||
|
||||
const formEl = document.getElementById('deleteAddCardModal-form');
|
||||
if (formEl) {
|
||||
formEl.action = `/admin/add-cards/${id}`;
|
||||
}
|
||||
|
||||
openModal('deleteAddCardModal');
|
||||
}
|
||||
|
||||
async function reloadListsSection() {
|
||||
try {
|
||||
const response = await fetch(window.location.href, {
|
||||
@@ -379,6 +407,11 @@
|
||||
if (editForm) {
|
||||
editForm.addEventListener('submit', (e) => submitModalForm(e, 'editAddCardForm', 'editAddCardModal'));
|
||||
}
|
||||
|
||||
const deleteForm = document.getElementById('deleteAddCardModal-form');
|
||||
if (deleteForm) {
|
||||
deleteForm.addEventListener('submit', (e) => submitModalForm(e, 'deleteAddCardModal-form', 'deleteAddCardModal'));
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState !== 'loading') {
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
@props(['mode', 'user' => null])
|
||||
|
||||
@if($mode === 'create')
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="password">Mật khẩu khởi tạo <span class="text-red-500">*</span></label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0V10.5m-2.812 10.5h14.625c.621 0 1.125-.504 1.125-1.125V11.25c0-.621-.504-1.125-1.125-1.125H3.75c-.621 0-1.125.504-1.125 1.125v7.875c0 .621.504 1.125 1.125 1.125z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="text" name="password" id="password" class="form-input form-input-with-icon !rounded-xl !bg-gray-50 !text-gray-500 cursor-not-allowed" style="padding-left: 48px;" readonly required value="1234@Dcba">
|
||||
</div>
|
||||
<span class="text-[13px] text-gray-400 mt-2 block">Mật khẩu mặc định cho tất cả user mới tạo.</span>
|
||||
</div>
|
||||
@elseif($mode === 'edit')
|
||||
<div class="relative">
|
||||
<label class="block text-[14px] font-bold text-[#1a2b49] mb-2" for="password">Mật khẩu (Chỉ xem)</label>
|
||||
<div class="relative flex items-center w-full">
|
||||
<span class="absolute left-4 text-gray-400 pointer-events-none w-5 h-5 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0V10.5m-2.812 10.5h14.625c.621 0 1.125-.504 1.125-1.125V11.25c0-.621-.504-1.125-1.125-1.125H3.75c-.621 0-1.125.504-1.125 1.125v7.875c0 .621.504 1.125 1.125 1.125z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="password" name="password" id="password" class="form-input form-input-with-icon !rounded-xl !bg-gray-50 !text-gray-500 cursor-not-allowed w-full" style="padding-left: 48px;" readonly value="********">
|
||||
</div>
|
||||
</div>
|
||||
@elseif($mode === 'self')
|
||||
<div class="border-t border-gray-100 pt-5 mt-5">
|
||||
<h4 class="text-sm font-bold text-[#1a2b49] mb-4 flex items-center gap-2">
|
||||
🔑 Bảo mật & Đổi mật khẩu
|
||||
</h4>
|
||||
<div class="space-y-4">
|
||||
<!-- Current Password -->
|
||||
<div class="flex flex-col">
|
||||
<label class="text-[13px] font-bold text-gray-700 mb-1.5" for="current_password">Mật khẩu hiện tại</label>
|
||||
<div class="relative">
|
||||
<span class="absolute left-3.5 top-1/2 -translate-y-1/2 text-gray-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0V10.5m-2.812 10.5h14.625c.621 0 1.125-.504 1.125-1.125V11.25c0-.621-.504-1.125-1.125-1.125H3.75c-.621 0-1.125.504-1.125 1.125v7.875c0 .621.504 1.125 1.125 1.125z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<input type="password" name="current_password" id="current_password"
|
||||
class="w-full h-[46px] pl-[42px] pr-12 bg-white border @error('current_password') border-red-500 focus:border-red-500 focus:ring-red-500/20 @else border-gray-200 focus:border-[#3462f7] focus:ring-[#3462f7]/20 @enderror rounded-xl text-sm text-gray-800 outline-none transition-all shadow-sm placeholder:text-gray-400"
|
||||
placeholder="Nhập mật khẩu hiện tại (chỉ cần khi đổi mật khẩu)">
|
||||
<button type="button" onclick="togglePasswordVisibility('current_password', this)" class="absolute right-3.5 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer" aria-label="Show password">
|
||||
<svg class="w-5 h-5 eye-icon-closed" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 001.934 12c1.292 4.338 5.31 7.5 10.066 7.5.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"/></svg>
|
||||
<svg class="w-5 h-5 eye-icon-open hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@error('current_password')
|
||||
<span class="text-red-500 text-[12px] font-semibold mt-1.5 block">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<!-- New Password -->
|
||||
<div class="flex flex-col">
|
||||
<label class="text-[13px] font-bold text-gray-700 mb-1.5" for="new_password">Mật khẩu mới</label>
|
||||
<div class="relative">
|
||||
<span class="absolute left-3.5 top-1/2 -translate-y-1/2 text-gray-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0V10.5m-2.812 10.5h14.625c.621 0 1.125-.504 1.125-1.125V11.25c0-.621-.504-1.125-1.125-1.125H3.75c-.621 0-1.125.504-1.125 1.125v7.875c0 .621.504 1.125 1.125 1.125z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<input type="password" name="new_password" id="new_password"
|
||||
class="w-full h-[46px] pl-[42px] pr-12 bg-white border @error('new_password') border-red-500 focus:border-red-500 focus:ring-red-500/20 @else border-gray-200 focus:border-[#3462f7] focus:ring-[#3462f7]/20 @enderror rounded-xl text-sm text-gray-800 outline-none transition-all shadow-sm placeholder:text-gray-400"
|
||||
placeholder="Nhập mật khẩu mới">
|
||||
<button type="button" onclick="togglePasswordVisibility('new_password', this)" class="absolute right-3.5 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer" aria-label="Show password">
|
||||
<svg class="w-5 h-5 eye-icon-closed" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 001.934 12c1.292 4.338 5.31 7.5 10.066 7.5.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"/></svg>
|
||||
<svg class="w-5 h-5 eye-icon-open hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@error('new_password')
|
||||
<span class="text-red-500 text-[12px] font-semibold mt-1.5 block">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Confirm Password -->
|
||||
<div class="flex flex-col">
|
||||
<label class="text-[13px] font-bold text-gray-700 mb-1.5" for="new_password_confirmation">Xác nhận mật khẩu mới</label>
|
||||
<div class="relative">
|
||||
<span class="absolute left-3.5 top-1/2 -translate-y-1/2 text-gray-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<input type="password" name="new_password_confirmation" id="new_password_confirmation"
|
||||
class="w-full h-[46px] pl-[42px] pr-12 bg-white border @error('new_password_confirmation') border-red-500 focus:border-red-500 focus:ring-red-500/20 @else border-gray-200 focus:border-[#3462f7] focus:ring-[#3462f7]/20 @enderror rounded-xl text-sm text-gray-800 outline-none transition-all shadow-sm placeholder:text-gray-400"
|
||||
placeholder="Nhập lại mật khẩu mới">
|
||||
<button type="button" onclick="togglePasswordVisibility('new_password_confirmation', this)" class="absolute right-3.5 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer" aria-label="Show password">
|
||||
<svg class="w-5 h-5 eye-icon-closed" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 001.934 12c1.292 4.338 5.31 7.5 10.066 7.5.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"/></svg>
|
||||
<svg class="w-5 h-5 eye-icon-open hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@error('new_password_confirmation')
|
||||
<span class="text-red-500 text-[12px] font-semibold mt-1.5 block">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@@ -3,76 +3,14 @@
|
||||
@section('title', 'Cài đặt tài khoản')
|
||||
|
||||
@section('content')
|
||||
<div class="max-w-[480px] mx-auto bg-white rounded-[24px] shadow-[0_10px_30px_rgba(15,23,42,0.05)] p-8 mt-6">
|
||||
<h3 class="text-[20px] font-extrabold text-[#1a2b49] mb-4 text-center">Cài đặt tài khoản</h3>
|
||||
|
||||
<div class="max-w-2xl mx-auto w-full mt-6">
|
||||
@if(session('success'))
|
||||
<div class="mb-4 p-3 bg-green-100 text-green-800 rounded-xl">{{ session('success') }}</div>
|
||||
<div class="mb-4 p-4 bg-green-50 border border-green-200 text-green-800 rounded-2xl font-semibold flex items-center gap-2 shadow-sm">
|
||||
<span>✅</span>
|
||||
<span>{{ session('success') }}</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('user.update_profile') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<!-- Avatar preview and upload -->
|
||||
<div class="flex items-center gap-4 mb-6">
|
||||
<div class="w-16 h-16 rounded-full overflow-hidden border border-gray-200">
|
||||
<img src="{{ Auth::user()->avatar ?? asset('images/avatar.png') }}" alt="Avatar" class="w-full h-full object-cover" id="avatar-preview" onerror="this.onerror=null; this.src='{{ asset('images/avatar.png') }}';">
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="block text-[13px] font-bold text-gray-700 mb-1" for="avatar">Thay đổi ảnh đại diện</label>
|
||||
<input type="file" name="avatar" id="avatar" accept="image/*" class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-3 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-[#3462f7] file:text-white hover:file:bg-[#254edb]" onchange="previewAvatar(event)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- New password -->
|
||||
<div class="space-y-6 mb-4">
|
||||
<div class="flex flex-col">
|
||||
<label class="text-[13px] font-bold text-gray-700 mb-1.5" for="new_password">Mật khẩu mới <span class="text-red-500">*</span></label>
|
||||
<div class="relative">
|
||||
<span class="absolute left-3.5 top-1/2 -translate-y-1/2 text-gray-400"><svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" class=\"w-5 h-5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 10.5V6.75a4.5 4.5 0 10-9 0V10.5m-2.812 10.5h14.625c.621 0 1.125-.504 1.125-1.125V11.25c0-.621-.504-1.125-1.125-1.125H3.75c-.621 0-1.125.504-1.125 1.125v7.875c0 .621.504 1.125 1.125 1.125z\"/></svg></span>
|
||||
<input type="password" name="new_password" id="new_password" class="w-full h-[46px] pl-[42px] pr-12 bg-white border @error('new_password') border-red-500 focus:border-red-500 focus:ring-red-500/20 @else border-gray-200 focus:border-[#2563eb] focus:ring-[#2563eb]/20 @enderror rounded-lg text-sm text-gray-800 outline-none transition-all shadow-sm placeholder:text-gray-400" placeholder="Nhập mật khẩu mới">
|
||||
<button type="button" onclick="togglePasswordVisibility('new_password', this)" class="absolute right-3.5 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer" aria-label="Show password">
|
||||
<svg class="w-5 h-5 eye-icon-closed" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 001.934 12c1.292 4.338 5.31 7.5 10.066 7.5.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"/></svg>
|
||||
<svg class="w-5 h-5 eye-icon-open hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@error('new_password')
|
||||
<span class="text-red-500 text-[12px] font-semibold mt-1.5 block">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<label class="text-[13px] font-bold text-gray-700 mb-1.5" for="new_password_confirmation">Xác nhận mật khẩu mới <span class="text-red-500">*</span></label>
|
||||
<div class="relative">
|
||||
<span class="absolute left-3.5 top-1/2 -translate-y-1/2 text-gray-400"><svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" class=\"w-5 h-5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/></svg></span>
|
||||
<input type="password" name="new_password_confirmation" id="new_password_confirmation" class="w-full h-[46px] pl-[42px] pr-12 bg-white border @error('new_password_confirmation') border-red-500 focus:border-red-500 focus:ring-red-500/20 @else border-gray-200 focus:border-[#2563eb] focus:ring-[#2563eb]/20 @enderror rounded-lg text-sm text-gray-800 outline-none transition-all shadow-sm placeholder:text-gray-400" placeholder="Nhập lại mật khẩu mới">
|
||||
<button type="button" onclick="togglePasswordVisibility('new_password_confirmation', this)" class="absolute right-3.5 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer" aria-label="Show password">
|
||||
<svg class="w-5 h-5 eye-icon-closed" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 001.934 12c1.292 4.338 5.31 7.5 10.066 7.5.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"/></svg>
|
||||
<svg class="w-5 h-5 eye-icon-open hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@error('new_password_confirmation')
|
||||
<span class="text-red-500 text-[12px] font-semibold mt-1.5 block">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3 pt-4">
|
||||
<a href="{{ route('user.dashboard') }}" class="flex-1 text-center py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-xl font-medium">Hủy bỏ</a>
|
||||
<button type="submit" class="flex-1 py-2 bg-[#3462f7] hover:bg-[#254edb] text-white rounded-xl font-bold">Lưu thay đổi</button>
|
||||
</div>
|
||||
</form>
|
||||
<x-user-form mode="self" :user="Auth::user()" />
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function previewAvatar(event) {
|
||||
const input = event.target;
|
||||
if (input.files && input.files[0]) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
document.getElementById('avatar-preview').src = e.target.result;
|
||||
};
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Gửi Thank Card')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.ts-control { border-radius: 0.75rem; border-color: #d9dfe7; padding: 0.65rem 1rem; }
|
||||
.ts-wrapper.form-input { padding: 0; border: none; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="max-w-[640px] mx-auto w-full pb-10">
|
||||
<div class="bg-white rounded-[24px] shadow-[0_10px_30px_rgba(15,23,42,0.05)] border border-white overflow-hidden">
|
||||
|
||||
Reference in New Issue
Block a user