feature: send thankscard page

This commit is contained in:
antv
2026-07-14 16:23:04 +07:00
parent 3aa9e04bd7
commit 05605ed1eb
28 changed files with 536 additions and 297 deletions
+1 -7
View File
@@ -23,13 +23,7 @@
<div class="w-10 h-10 rounded-full overflow-hidden shrink-0 border border-gray-200">
@php
$avatarUrl = Auth::user()->avatar ? Auth::user()->avatar : asset('images/avatar.png');
$deptVal = Auth::user()->departments;
if (is_numeric($deptVal)) {
$idx = ((int)$deptVal) - 1;
$deptName = config('constants.DEPARTMENTS')[$idx] ?? 'Team';
} else {
$deptName = $deptVal ?? 'Team';
}
$deptName = Auth::user()->department_name ?? 'Team';
@endphp
<img src="{{ $avatarUrl }}" alt="Avatar" class="w-full h-full object-cover" onerror="this.onerror=null; this.src='{{ asset('images/avatar.png') }}';">
</div>
@@ -61,6 +61,9 @@
<!-- 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>
@php
$deptVal = old('departments', $user?->department_name);
@endphp
@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">
@@ -72,8 +75,8 @@
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 }}">
title="{{ $deptVal }}"
value="{{ $deptVal }}">
</div>
@else
<div class="relative flex items-center w-full">
@@ -85,7 +88,7 @@
<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>
<option value="{{ $dept }}" {{ $deptVal == $dept ? 'selected' : '' }}>{{ $dept }}</option>
@endforeach
</select>
</div>
@@ -11,7 +11,7 @@
<form id="filterForm" action="{{ $action }}" method="GET" class="flex flex-col md:flex-row md:flex-wrap items-stretch md:items-center gap-3.5 w-full mb-6 bg-white p-5 rounded-[24px] border border-white shadow-[0_10px_30px_rgba(15,23,42,0.05)]">
<div class="search-wrapper flex-1 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 class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</span>
@@ -19,7 +19,7 @@
class="form-input form-input-with-icon !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20 w-full"
style="padding-left: 44px; padding-right: 40px;" />
<button type="button" id="btnClearSearch" class="{{ empty($search) ? 'hidden' : '' }} absolute right-3.5 text-gray-400 hover:text-gray-600 focus:outline-none">
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
@@ -84,7 +84,7 @@
field: "text",
direction: "asc"
},
placeholder: "🔍 Tìm phòng ban...",
placeholder: "Tìm phòng ban...",
render: {
item: function(data, escape) {
return '<div class="item" title="' + escape(data.text) + '">' + escape(data.text) + '</div>';
+12 -15
View File
@@ -26,9 +26,9 @@
<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),
'create' => 'Thêm User Mới',
'delete' => 'Xác nhận nghỉ việc: ' . ($user?->name),
'self' => 'Thông tin cá nhân',
} }}</span>
</h3>
</div>
@@ -40,23 +40,20 @@
<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">
{{ strtoupper(substr($user->name ?? $user->msnv, 0, 2)) }}
</div>
<div class="flex-1 min-w-0">
<h4 class="font-extrabold text-[#1a2b49] text-base truncate">{{ $user->name }}</h4>
<p class="text-xs text-gray-500 font-medium truncate mb-1">{{ $user->mail }}</p>
<div class="flex items-center gap-2">
<span class="px-2 py-0.5 text-[10px] font-bold rounded-full bg-blue-50 text-blue-700 border border-blue-100">
{{ $user->role == config('constants.ROLE_ADMIN') ? 'Admin' : 'Member' }}
</span>
<span class="text-xs text-gray-300 font-semibold"></span>
<span class="text-xs font-bold text-gray-600">Thẻ: <span class="text-orange-500 font-extrabold text-sm">{{ $user->card }}</span></span>
</div>
<div class="flex-1">
<h4 class="text-base font-extrabold text-[#1a2b49]">{{ $user->name }}</h4>
<p class="text-xs text-gray-500 font-semibold mt-1 flex items-center gap-2">
<span>MSNV: {{ $user->msnv }}</span>
<span class="w-1 h-1 bg-gray-300 rounded-full"></span>
<span>{{ $user->mail }}</span>
</p>
</div>
</div>
</div>
@endif
@if($actionUrl)
<form action="{{ $actionUrl }}" method="POST" enctype="multipart/form-data" class="flex flex-col flex-1 justify-between">
<form action="{{ $actionUrl }}" method="POST" id="userForm" enctype="multipart/form-data" class="flex-1 flex flex-col justify-between">
@csrf
@if($method !== 'POST')
@method($method)
@@ -66,7 +63,7 @@
<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 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.
Bạn chắc chắn muốn cho nhân viên {{ $user->name }} (MSNV: {{ $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
<!-- 2. User Basic Information Section -->
@@ -344,11 +344,15 @@
await reloadListsSection();
} else {
alert(result.message || 'Đã xảy ra lỗi. Vui lòng thử lại.');
if (window.showToast) {
window.showToast(result.message || 'Đã xảy ra lỗi. Vui lòng thử lại.', 'error');
}
}
} catch (err) {
console.error(err);
alert('Đã xảy ra lỗi kết nối.');
if (window.showToast) {
window.showToast('Đã xảy ra lỗi kết nối.', 'error');
}
} finally {
if (submitBtn) submitBtn.disabled = false;
}
@@ -9,9 +9,10 @@
<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">
<input type="text" name="password" id="password" class="form-input form-input-with-icon !rounded-xl !focus:border-[#3462f7] !focus:ring-[#3462f7]/20" style="padding-left: 48px;" required value="{{ old('password', '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
<span class="text-[13px] text-gray-400 mt-2 block">Thiết lập mật khẩu khởi tạo cho user (mặc định 1234@Dcba).</span>
</div>
@elseif($mode === 'edit')
<div class="relative">
@@ -28,7 +29,7 @@
@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
Bảo mật & Đổi mật khẩu
</h4>
<div class="space-y-4">
<!-- Current Password -->