This commit is contained in:
antv
2026-07-17 13:42:00 +07:00
parent e81a285aa9
commit 91a598a5f9
5 changed files with 154 additions and 14 deletions
+46 -2
View File
@@ -236,7 +236,8 @@ class UserService implements UserServiceInterface
{
$start = Carbon::parse($selectedMonth)->startOfMonth();
$end = Carbon::parse($selectedMonth)->endOfMonth();
$cards = Administration::where('msnv', $user->msnv)
$cards = Administration::with('senderUser')
->where('msnv', $user->msnv)
->whereBetween('date', [$start, $end])
->where('received', '>', 0)
->orderBy('date', 'desc')
@@ -249,7 +250,8 @@ class UserService implements UserServiceInterface
{
$start = Carbon::parse($selectedMonth)->startOfMonth();
$end = Carbon::parse($selectedMonth)->endOfMonth();
$cards = Administration::where('msnv', $user->msnv)
$cards = Administration::with('receiverUser')
->where('msnv', $user->msnv)
->whereBetween('date', [$start, $end])
->where('sent', '>', 0)
->orderBy('date', 'desc')
@@ -257,6 +259,48 @@ class UserService implements UserServiceInterface
return ['cards' => $cards];
}
// Retrieve limited feed of received ThankCards for activity feed
public function getReceivedFeed(User $user, string $selectedMonth, int $limit = 12, int $offset = 0): array
{
$start = Carbon::parse($selectedMonth)->startOfMonth();
$end = Carbon::parse($selectedMonth)->endOfMonth();
$cards = Administration::with('senderUser')
->where('msnv', $user->msnv)
->whereBetween('date', [$start, $end])
->where('received', '>', 0)
->orderBy('date', 'desc')
->skip($offset)
->take($limit)
->get();
$hasMore = Administration::where('msnv', $user->msnv)
->whereBetween('date', [$start, $end])
->where('received', '>', 0)
->skip($offset + $limit)
->exists();
return ['cards' => $cards, 'hasMore' => $hasMore];
}
// Retrieve limited feed of sent ThankCards for activity feed
public function getSentFeed(User $user, string $selectedMonth, int $limit = 12, int $offset = 0): array
{
$start = Carbon::parse($selectedMonth)->startOfMonth();
$end = Carbon::parse($selectedMonth)->endOfMonth();
$cards = Administration::with('receiverUser')
->where('msnv', $user->msnv)
->whereBetween('date', [$start, $end])
->where('sent', '>', 0)
->orderBy('date', 'desc')
->skip($offset)
->take($limit)
->get();
$hasMore = Administration::where('msnv', $user->msnv)
->whereBetween('date', [$start, $end])
->where('sent', '>', 0)
->skip($offset + $limit)
->exists();
return ['cards' => $cards, 'hasMore' => $hasMore];
}
public function updateProfile(User $user, array $data, ?\Illuminate\Http\UploadedFile $avatarFile = null): void
{
if (isset($data['name'])) {
+55
View File
@@ -93,5 +93,60 @@ class MockDataSeeder extends Seeder
'flag_send' => config('constants.FLAG_SEND_DISABLED'),
'first_login' => config('constants.FIRST_LOGIN_FALSE'),
]);
// 2. CREATE MOCK TRANSACTIONS
// Nguyễn Văn A (1001) receives 3 cards from Trần Thị Ngọc (1002)
Administration::create([
'msnv' => '1001',
'received' => 3,
'sender' => '1002',
'sent' => 0,
'receiver' => null,
'date' => Carbon::now()->format('Y-m-d'),
]);
Administration::create([
'msnv' => '1002',
'received' => 0,
'sender' => null,
'sent' => 3,
'receiver' => '1001',
'date' => Carbon::now()->format('Y-m-d'),
]);
// Nguyễn Văn A (1001) receives 2 cards from Bản Giang (1005)
Administration::create([
'msnv' => '1001',
'received' => 2,
'sender' => '1005',
'sent' => 0,
'receiver' => null,
'date' => Carbon::now()->subDays(2)->format('Y-m-d'),
]);
Administration::create([
'msnv' => '1005',
'received' => 0,
'sender' => null,
'sent' => 2,
'receiver' => '1001',
'date' => Carbon::now()->subDays(2)->format('Y-m-d'),
]);
// Nguyễn Văn A (1001) sends 4 cards to Trần Thị Ngọc (1002)
Administration::create([
'msnv' => '1001',
'sent' => 4,
'receiver' => '1002',
'received' => 0,
'sender' => null,
'date' => Carbon::now()->subDays(1)->format('Y-m-d'),
]);
Administration::create([
'msnv' => '1002',
'sent' => 0,
'receiver' => null,
'received' => 4,
'sender' => '1001',
'date' => Carbon::now()->subDays(1)->format('Y-m-d'),
]);
}
}
@@ -66,6 +66,9 @@
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
<!-- 1. User Avatar Section -->
<x-user-avatar-section :mode="$mode" :user="$user" />
<!-- 2. User Basic Information Section -->
<x-user-basic-info :mode="$mode" :user="$user" />
+25 -6
View File
@@ -32,14 +32,33 @@
@if (!empty($cards) && $cards->count())
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
@foreach ($cards as $c)
<div class="bg-white rounded-[24px] shadow-[0_4px_12px_rgba(0,0,0,0.05)] p-5">
<div class="flex justify-between items-center mb-2">
<span class="font-semibold text-[#1a2b49]">Từ: {{ $c->sender ?? '---' }}</span>
<span class="text-gray-500 text-sm">{{ \Carbon\Carbon::parse($c->date)->format('d/m/Y') }}</span>
<div class="bg-white rounded-[24px] shadow-[0_10px_30px_rgba(15,23,42,0.05)] border border-gray-100/50 p-6 flex flex-col justify-between hover:shadow-lg transition-all duration-300 hover:-translate-y-0.5">
<div class="flex items-start gap-4">
@if($c->senderUser)
<x-avatar :user="$c->senderUser" class="w-12 h-12 rounded-full object-cover border-2 border-purple-100 flex-shrink-0" />
<div class="flex-1 min-w-0">
<h4 class="font-bold text-[#1a2b49] text-base truncate" title="{{ $c->senderUser->name }}">{{ $c->senderUser->name }}</h4>
<p class="text-xs font-semibold text-gray-400 mt-0.5">MSNV: {{ $c->senderUser->msnv }}</p>
<p class="text-xs text-gray-500 mt-1 truncate" title="{{ $c->senderUser->mail }}">{{ $c->senderUser->mail }}</p>
</div>
@else
<div class="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center text-gray-500 font-bold flex-shrink-0">
{{ strtoupper(substr($c->sender ?? 'S', 0, 1)) }}
</div>
<div class="flex-1 min-w-0">
<h4 class="font-bold text-[#1a2b49] text-base truncate">Từ: {{ $c->sender ?? '---' }}</h4>
<p class="text-xs font-semibold text-gray-400 mt-0.5">MSNV: {{ $c->sender ?? '---' }}</p>
</div>
@endif
</div>
<div class="flex justify-between items-center mt-6 pt-4 border-t border-gray-50">
<span class="text-gray-400 text-xs font-medium">{{ \Carbon\Carbon::parse($c->date)->format('d/m/Y') }}</span>
<span class="px-3 py-1 inline-flex text-xs font-extrabold rounded-full bg-purple-50 text-purple-700 border border-purple-100/80">
+{{ $c->received }} thẻ
</span>
</div>
<p class="text-gray-700">{{ $c->received }} thẻ</p>
</div>
@endforeach
</div>
+25 -6
View File
@@ -31,14 +31,33 @@
@if (!empty($cards) && $cards->count())
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
@foreach ($cards as $c)
<div class="bg-white rounded-[24px] shadow-[0_4px_12px_rgba(0,0,0,0.05)] p-5">
<div class="flex justify-between items-center mb-2">
<span class="font-semibold text-[#1a2b49]">Gửi tới: {{ $c->receiver ?? '---' }}</span>
<span class="text-gray-500 text-sm">{{ \Carbon\Carbon::parse($c->date)->format('d/m/Y') }}</span>
<div class="bg-white rounded-[24px] shadow-[0_10px_30px_rgba(15,23,42,0.05)] border border-gray-100/50 p-6 flex flex-col justify-between hover:shadow-lg transition-all duration-300 hover:-translate-y-0.5">
<div class="flex items-start gap-4">
@if($c->receiverUser)
<x-avatar :user="$c->receiverUser" class="w-12 h-12 rounded-full object-cover border-2 border-blue-100 flex-shrink-0" />
<div class="flex-1 min-w-0">
<h4 class="font-bold text-[#1a2b49] text-base truncate" title="{{ $c->receiverUser->name }}">{{ $c->receiverUser->name }}</h4>
<p class="text-xs font-semibold text-gray-400 mt-0.5">MSNV: {{ $c->receiverUser->msnv }}</p>
<p class="text-xs text-gray-500 mt-1 truncate" title="{{ $c->receiverUser->mail }}">{{ $c->receiverUser->mail }}</p>
</div>
@else
<div class="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center text-gray-500 font-bold flex-shrink-0">
{{ strtoupper(substr($c->receiver ?? 'R', 0, 1)) }}
</div>
<div class="flex-1 min-w-0">
<h4 class="font-bold text-[#1a2b49] text-base truncate">Tới: {{ $c->receiver ?? '---' }}</h4>
<p class="text-xs font-semibold text-gray-400 mt-0.5">MSNV: {{ $c->receiver ?? '---' }}</p>
</div>
@endif
</div>
<div class="flex justify-between items-center mt-6 pt-4 border-t border-gray-50">
<span class="text-gray-400 text-xs font-medium">{{ \Carbon\Carbon::parse($c->date)->format('d/m/Y') }}</span>
<span class="px-3 py-1 inline-flex text-xs font-extrabold rounded-full bg-blue-50 text-blue-700 border border-blue-100/80">
-{{ $c->sent }} thẻ
</span>
</div>
<p class="text-gray-700">{{ $c->sent }} thẻ</p>
</div>
@endforeach
</div>