feature: make style like main page

This commit is contained in:
antv
2026-07-07 11:21:21 +07:00
parent af529a4e81
commit 63764d0718
15 changed files with 385 additions and 185 deletions
+12 -1
View File
@@ -2,5 +2,16 @@
@section('title', 'Thêm User Mới')
@section('content')
<x-user-page mode="create" />
<div class="mb-6 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 pl-1">
<div>
<h1 class="text-[28px] font-extrabold text-[#1a2b49] flex items-center gap-2 mb-1.5 tracking-tight">
Thêm User Mới
</h1>
<p class="text-gray-500 font-medium text-[14px]">
Tạo tài khoản nhân viên mới thiết lập các thông tin bản.
</p>
</div>
</div>
<x-user-page mode="create" />
@endsection
+12 -1
View File
@@ -2,5 +2,16 @@
@section('title', 'Chi tiết User')
@section('content')
<x-user-page mode="edit" :user="$user" :administrations="$administrations" :selectedMonth="$selectedMonth" />
<div class="mb-6 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 pl-1">
<div>
<h1 class="text-[28px] font-extrabold text-[#1a2b49] flex items-center gap-2 mb-1.5 tracking-tight">
Chi tiết User
</h1>
<p class="text-gray-500 font-medium text-[14px]">
Quản thông tin thẻ theo dõi lịch sử nhận gửi của nhân viên.
</p>
</div>
</div>
<x-user-page mode="edit" :user="$user" :administrations="$administrations" :selectedMonth="$selectedMonth" />
@endsection
+47 -10
View File
@@ -2,25 +2,62 @@
@section('title', 'Quản lý Users')
@section('content')
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4 border-b border-border-light pb-4 mb-4">
<h2 id="pageTitle" class="text-xl font-bold text-text-dark flex items-center gap-2">
@include('admin.users.partials.title')
</h2>
<form action="{{ route('admin.reset_cards') }}" method="POST" class="w-full sm:w-auto" onsubmit="return confirm('Bạn có chắc chắn muốn reset toàn bộ số card hiện tại của các user về 0? Hành động này thường chỉ thực hiện vào cuối tháng.');">
@csrf
<button type="submit" class="border border-red-200 hover:bg-red-50 text-red-600 font-semibold py-1.5 px-4 rounded text-sm transition-colors shadow-sm w-full sm:w-auto">Reset Card Tháng</button>
</form>
<div class="mb-6 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 pl-1">
<div>
<h1 class="text-[28px] font-extrabold text-[#1a2b49] flex items-center gap-2 mb-1.5 tracking-tight">
<span id="pageTitle" class="inline-flex items-center gap-2">
@include('admin.users.partials.title')
</span>
</h1>
<p class="text-gray-500 font-medium text-[14px]">
Xem danh sách nhân viên, cấp phát thẻ cập nhật trạng thái làm việc.
</p>
</div>
<div class="flex flex-col sm:flex-row items-center gap-3 shrink-0 w-full sm:w-auto">
<a href="{{ route('admin.users.create') }}" class="inline-flex items-center justify-center bg-[#3462f7] hover:bg-blue-700 text-white font-bold py-2.5 px-5 rounded-xl text-sm transition-colors shadow-md shadow-blue-500/10 w-full sm:w-auto">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="w-4 h-4 mr-2">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
Thêm user mới
</a>
<button type="button" onclick="openModal('resetModal')" class="cursor-pointer border border-red-200 bg-red-50/50 hover:bg-red-50 text-red-600 font-bold py-2.5 px-5 rounded-xl text-sm transition-colors shadow-sm w-full sm:w-auto">Reset Card Tháng</button>
</div>
</div>
<div id="statsGrid" class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<div id="statsGrid" class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
@include('admin.users.partials.stats')
</div>
<x-user-filter-form :action="route('admin.users.index')" :search="$search" :flag-send="$flagSend" :selected-month="$selectedMonth" />
<div id="userTableContainer" class="bg-white shadow-sm rounded-xl overflow-hidden border border-border-light mt-2">
<div id="userTableContainer" class="bg-white rounded-[24px] shadow-[0_10px_30px_rgba(15,23,42,0.05)] border border-white overflow-hidden mt-4">
@include('admin.users.partials.table')
</div>
<x-confirm-modal id="deleteModal" title="Xác nhận nghỉ việc" confirmText="Xác nhận Nghỉ việc" />
<x-modal id="resetModal" title="Xác nhận reset card" maxWidth="md" hideHeader="true">
<div class="flex items-start gap-4">
<div class="flex-shrink-0 flex items-center justify-center w-12 h-12 bg-red-100 rounded-full">
<svg class="w-6 h-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
</div>
<div class="flex-1 mt-1">
<h3 class="text-lg font-bold text-gray-900">Xác nhận reset card tháng</h3>
<p class="text-sm text-gray-600 mt-2 leading-relaxed">
Bạn chắc chắn muốn reset toàn bộ số card hiện tại của các user về 0?<br><br>Hành động này thường chỉ thực hiện vào cuối tháng không thể hoàn tác.
</p>
</div>
</div>
<x-slot name="footer">
<form action="{{ route('admin.reset_cards') }}" method="POST" class="w-full sm:w-auto">
@csrf
<button type="submit" class="w-full btn-primary !px-6 shadow-sm bg-red-600 hover:bg-red-700">Đồng ý Reset</button>
</form>
<button type="button" onclick="closeModal('resetModal')" class="w-full sm:w-auto btn-secondary !px-6 shadow-sm">Hủy bỏ</button>
</x-slot>
</x-modal>
@endsection
@@ -1,2 +1,45 @@
<x-stat-card title="User nhận nhiều nhất" :user="$topReceivedUser?->msnv" :value="$topReceivedUser?->total_received ?? 0" bgClass="!bg-[#0f4c81]" valueLabel="Tổng thẻ đã nhận" />
<x-stat-card title="User gửi nhiều nhất" :user="$topSentUser?->msnv" :value="$topSentUser?->total_sent ?? 0" bgClass="!bg-[#ef222e]" valueLabel="Tổng thẻ đã gửi" />
<div class="bg-white rounded-[24px] shadow-[0_10px_30px_rgba(15,23,42,0.05)] p-6 border border-white hover:shadow-md transition-all flex items-center justify-between">
<div class="flex items-center gap-4">
<div class="w-14 h-14 rounded-2xl bg-purple-50 flex items-center justify-center text-purple-500 shrink-0">
<svg class="w-7 h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
</svg>
</div>
<div class="flex flex-col">
<span class="text-[13px] font-bold text-gray-400 uppercase tracking-wider mb-1">User nhận nhiều nhất</span>
@if($topReceivedUser)
<span class="text-[16px] font-extrabold text-[#1a2b49] leading-tight">{{ $topReceivedUser->name }}</span>
<span class="text-[12px] text-gray-500 font-semibold mt-0.5">MSNV: {{ $topReceivedUser->msnv }}</span>
@else
<span class="text-[15px] font-semibold text-gray-400">Không dữ liệu</span>
@endif
</div>
</div>
<div class="text-right">
<span class="text-[36px] font-extrabold text-purple-600 leading-none">{{ $topReceivedUser?->total_received ?? 0 }}</span>
<span class="block text-[11px] text-gray-400 font-bold uppercase mt-1">Thẻ Nhận</span>
</div>
</div>
<div class="bg-white rounded-[24px] shadow-[0_10px_30px_rgba(15,23,42,0.05)] p-6 border border-white hover:shadow-md transition-all flex items-center justify-between">
<div class="flex items-center gap-4">
<div class="w-14 h-14 rounded-2xl bg-blue-50 flex items-center justify-center text-blue-500 shrink-0">
<svg class="w-7 h-7 transform -rotate-45" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
</svg>
</div>
<div class="flex flex-col">
<span class="text-[13px] font-bold text-gray-400 uppercase tracking-wider mb-1">User gửi nhiều nhất</span>
@if($topSentUser)
<span class="text-[16px] font-extrabold text-[#1a2b49] leading-tight">{{ $topSentUser->name }}</span>
<span class="text-[12px] text-gray-500 font-semibold mt-0.5">MSNV: {{ $topSentUser->msnv }}</span>
@else
<span class="text-[15px] font-semibold text-gray-400">Không dữ liệu</span>
@endif
</div>
</div>
<div class="text-right">
<span class="text-[36px] font-extrabold text-blue-600 leading-none">{{ $topSentUser?->total_sent ?? 0 }}</span>
<span class="block text-[11px] text-gray-400 font-bold uppercase mt-1">Thẻ Gửi</span>
</div>
</div>
@@ -1,18 +1,18 @@
<div class="px-6 py-4 border-b border-border-light flex justify-between items-center bg-gray-50/50">
<span class="text-sm font-medium text-text-medium" id="paginationStats">
<div class="px-6 py-4 border-b border-gray-100 flex justify-between items-center bg-white">
<span class="text-sm font-semibold text-gray-500" id="paginationStats">
@if($users->total() > 0)
Showing {{ $users->firstItem() }}-{{ $users->lastItem() }} of {{ $users->total() }} users
Hiển thị {{ $users->firstItem() }}-{{ $users->lastItem() }} trên {{ $users->total() }} nhân viên
@else
Showing 0 users
Hiển thị 0 nhân viên
@endif
</span>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-border-light text-sm">
<thead class="bg-gray-50/80">
<table class="min-w-full divide-y divide-gray-100 text-sm">
<thead class="bg-gray-50/50">
<tr>
<th class="table-header-cell">MSNV</th>
<th class="table-header-cell">Email</th>
<th class="table-header-cell">Nhân viên</th>
<th class="table-header-cell">Đã Nhận</th>
<th class="table-header-cell">Đã Gửi</th>
<th class="table-header-cell">Số thẻ</th>
@@ -20,24 +20,29 @@
<th class="table-header-cell text-right">Thao tác</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-border-light">
<tbody class="bg-white divide-y divide-gray-100">
@forelse($users as $u)
<tr class="hover:bg-slate-50 transition-colors">
<tr class="hover:bg-slate-50/60 transition-colors">
<td class="table-body-cell font-bold text-text-dark">{{ $u->msnv }}</td>
<td class="table-body-cell text-text-medium">{{ $u->mail }}</td>
<td class="table-body-cell">
<div class="flex flex-col">
<span class="font-bold text-text-dark">{{ $u->name }}</span>
<span class="text-xs text-gray-400 mt-0.5">{{ $u->mail }}</span>
</div>
</td>
<td class="table-body-cell font-extrabold text-green-600">+{{ $u->total_received }}</td>
<td class="table-body-cell font-extrabold text-blue-600">{{ $u->total_sent }}</td>
<td class="table-body-cell font-extrabold text-orange-500">{{ $u->card }}</td>
<td class="table-body-cell">
@if($u->flag_send)
<span class="px-2 py-1 inline-flex text-[10px] leading-5 font-semibold rounded-full bg-green-100 text-green-800">Được gửi</span>
<span class="px-2.5 py-1 inline-flex text-[10px] leading-5 font-bold rounded-full bg-green-50 text-green-700 border border-green-100">Được gửi</span>
@else
<span class="px-2 py-1 inline-flex text-[10px] leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">Không</span>
<span class="px-2.5 py-1 inline-flex text-[10px] leading-5 font-bold rounded-full bg-gray-50 text-gray-500 border border-gray-100">Không</span>
@endif
</td>
<td class="table-body-cell text-right font-medium space-x-3">
<a href="{{ route('admin.users.edit', $u->msnv) }}" class="table-action-link text-primary">Quản </a>
<button type="button" onclick="openDeleteModal('{{ $u->msnv }}', '{{ route('admin.users.destroy', $u->msnv) }}')" class="table-action-link text-red-500">Nghỉ việc</button>
<a href="{{ route('admin.users.edit', $u->msnv) }}" class="table-action-link !text-[#3462f7] hover:!text-blue-800">Quản </a>
<button type="button" onclick="openDeleteModal('{{ $u->msnv }}', '{{ route('admin.users.destroy', $u->msnv) }}')" class="table-action-link !text-red-500 hover:!text-red-700">Nghỉ việc</button>
</td>
</tr>
@empty
@@ -49,7 +54,7 @@
</table>
</div>
@if($users->hasPages())
<div class="px-6 py-4 border-t border-border-light bg-gray-50/30">
<div class="px-6 py-4 border-t border-gray-100 bg-white">
{{ $users->links() }}
</div>
@endif
@@ -1,4 +1,4 @@
Danh sách User
<div id="loadingSpinner" class="hidden animate-spin rounded-full h-5 w-5 border-2 border-indigo-600 border-t-transparent" role="status">
<div id="loadingSpinner" class="hidden animate-spin rounded-full h-5 w-5 border-2 border-[#3462f7] border-t-transparent" role="status">
<span class="sr-only">Loading...</span>
</div>