refactor(tier): menyesuaikan tampilan card nya, menambahkan beberapa counting data dan merubah relasi dari has one ke membership menjadi has many

This commit is contained in:
Yoga Pangestu 2025-10-28 21:15:59 +07:00
parent f4a4a30d70
commit 53923bd6fc
3 changed files with 80 additions and 13 deletions

View File

@ -29,14 +29,42 @@ class Tier extends Component
public function mount()
{
$this->tiers = TierModel::orderBy('min_points', 'asc')
$this->tiers = TierModel::with(['memberships.user.customer.orders.orderItems', 'memberships.user.customer.orders.payments'])
->withCount('memberships')
->orderBy('min_points', 'asc')
->get()
->map(fn ($tier) => [
'hash' => $tier->hash,
'name' => $tier->name,
'min_points' => currency($tier->min_points, ''),
'max_points' => currency($tier->max_points, ''),
])
->map(function ($tier) {
$topMembership = $tier->memberships()
->with(['user.customer.orders.orderItems', 'user.customer.orders.payments'])
->orderByDesc('total_points')
->first();
$topMemberStats = null;
if ($topMembership && $topMembership->user && $topMembership->user->customer) {
$orders = $topMembership->user->customer->orders;
$totalOrders = $orders->count();
$totalItems = $orders->flatMap(fn ($order) => $order->orderItems)->sum('quantity');
$totalAmount = $orders->flatMap(fn ($order) => $order->payments)->sum('amount');
$topMemberStats = [
'name' => $topMembership->user->customer->name,
'points' => currency($topMembership->total_points),
'total_orders' => currency($totalOrders),
'total_items' => currency($totalItems),
'total_amount' => currency($totalAmount),
];
}
return [
'hash' => $tier->hash,
'name' => $tier->name,
'min_points' => currency($tier->min_points),
'max_points' => currency($tier->max_points),
'total_members' => currency($tier->memberships_count),
'top_member' => $topMemberStats,
];
})
->toArray();
}
@ -66,6 +94,8 @@ public function create()
'name' => $tier->name,
'min_points' => currency($tier->min_points, ''),
'max_points' => currency($tier->max_points, ''),
'total_members' => 0,
'top_member' => null,
];
usort($tiers, fn ($a, $b) => replaceCurrency($a['min_points']) <=> replaceCurrency($b['min_points']));

View File

@ -5,7 +5,7 @@
use Dyrynda\Database\Support\CascadeSoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Veelasky\LaravelHashId\Eloquent\HashableId;
@ -15,7 +15,7 @@ class Tier extends Model
protected $guarded = ['id'];
protected $cascadeDeletes = ['membership'];
protected $cascadeDeletes = ['memberships'];
protected function casts(): array
{
@ -25,8 +25,8 @@ protected function casts(): array
];
}
public function membership(): HasOne
public function memberships(): HasMany
{
return $this->hasOne(Membership::class);
return $this->hasMany(Membership::class);
}
}

View File

@ -25,7 +25,7 @@ class="hover:shadow-lg transition-shadow duration-200 bg-white dark:bg-gray-900
</flux:heading>
</div>
<div class="space-y-1">
<div class="space-y-2">
<div class="flex justify-between text-sm">
<span class="text-gray-500 dark:text-gray-400">Min. Poin:</span>
<span class="font-medium">{{ $tier['min_points'] }}</span>
@ -34,9 +34,46 @@ class="hover:shadow-lg transition-shadow duration-200 bg-white dark:bg-gray-900
<span class="text-gray-500 dark:text-gray-400">Maks. Poin:</span>
<span class="font-medium">{{ $tier['max_points'] }}</span>
</div>
<flux:separator />
<div class="flex justify-between text-sm">
<span class="text-gray-500 dark:text-gray-400">Total Member:</span>
<span class="font-medium">{{ $tier['total_members'] }}</span>
</div>
@if ($tier['top_member'])
<div class="text-sm">
<span class="text-gray-500 dark:text-gray-400 font-semibold">Member Dengan Poin
Tertinggi:</span>
<div
class="mt-1 flex items-center justify-between bg-gradient-to-r from-emerald-400 to-emerald-600 text-white rounded px-3 py-3 text-sm font-medium shadow-lg">
<span>{{ $tier['top_member']['name'] }}</span>
<span>{{ $tier['top_member']['points'] }} Poin</span>
</div>
<div
class="mt-2 bg-white dark:bg-gray-800 rounded-lg shadow p-4 text-gray-700 dark:text-gray-300">
<h4 class="font-semibold mb-2">Statistik Order</h4>
<div class="flex justify-between text-sm">
<span>Total Order:</span>
<span>{{ $tier['top_member']['total_orders'] }}x</span>
</div>
<div class="flex justify-between text-sm mt-1">
<span>Total Item Yang Dibeli:</span>
<span>{{ $tier['top_member']['total_items'] }}</span>
</div>
<div class="flex justify-between text-sm mt-1">
<span>Total Pembayaran:</span>
<span>{{ $tier['top_member']['total_amount'] }}</span>
</div>
</div>
</div>
@endif
</div>
<div class="flex gap-2 pt-2 border-t border-gray-200 dark:border-gray-700">
<div class="flex gap-2 pt-2 border-gray-200 dark:border-gray-700">
@can('update tier')
<flux:modal.trigger name="form-modal">
<flux:tooltip content="Ubah">