m
This commit is contained in:
@@ -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'])) {
|
||||
|
||||
@@ -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 có 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" />
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user