feat: add member order history page with detailed order summaries and navigation.
This commit is contained in:
parent
ca92fc9089
commit
bebc5be5a2
@ -14,7 +14,7 @@ class MyVouchers extends Component
|
||||
{
|
||||
public array $myVouchers = [];
|
||||
|
||||
public function mount()
|
||||
public function mount(): void
|
||||
{
|
||||
$this->myVouchers = auth()->user()->vouchers()
|
||||
->withPivot('quantity', 'created_at')
|
||||
|
||||
49
app/Livewire/Member/OrderHistory.php
Normal file
49
app/Livewire/Member/OrderHistory.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Member;
|
||||
|
||||
use App\Models\Order;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Title;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Title('Riwayat Pesanan')]
|
||||
#[Layout('components.layouts.member')]
|
||||
class OrderHistory extends Component
|
||||
{
|
||||
public array $orders = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->orders = Order::where('customer_id', auth()->user()->customer->id)
|
||||
->with(['items.orderable'])
|
||||
->latest()
|
||||
->get()
|
||||
->map(function ($order) {
|
||||
$order->status_color = $order->status->color();
|
||||
$order->status_label = $order->status->label();
|
||||
$order->formatted_created_at = formatDateLocalized($order->created_at);
|
||||
$order->formatted_total = formatCurrencyNumber($order->total, 'Rp');
|
||||
$order->total_items_count = $order->items->count();
|
||||
$order->preview_items = $order->items->take(2)->map(function ($item) {
|
||||
return [
|
||||
'name' => $item->orderable->name ?? 'Unknown Item',
|
||||
'quantity_label' => ! empty($item->quality) ? $item->quality : 'x'.$item->quantity,
|
||||
];
|
||||
});
|
||||
$order->remaining_items_count = max(0, $order->items->count() - 2);
|
||||
|
||||
return $order;
|
||||
})
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.member.order-histories', [
|
||||
'pageTitle' => 'Riwayat Pesanan',
|
||||
'pageDescription' => 'Lihat riwayat pesanan dan status pembayaran Anda.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,9 @@ class="bg-zinc-50 dark:bg-zinc-900 border-r rtl:border-r-0 rtl:border-l border-z
|
||||
<flux:navlist.item icon="ticket" href="{{ route('member.my_vouchers') }}"
|
||||
:current="request()->routeIs('member.my_vouchers')" wire:navigate>
|
||||
Voucher Saya</flux:navlist.item>
|
||||
<flux:navlist.item icon="shopping-bag" href="{{ route('member.order_history') }}"
|
||||
:current="request()->routeIs('member.order_history')" wire:navigate>
|
||||
Riwayat Pesanan</flux:navlist.item>
|
||||
<flux:navlist.item icon="check-badge" href="{{ route('member.redeem_point') }}"
|
||||
:current="request()->routeIs('member.redeem_point')" wire:navigate>
|
||||
Penukaran Poin</flux:navlist.item>
|
||||
|
||||
79
resources/views/livewire/member/order-histories.blade.php
Normal file
79
resources/views/livewire/member/order-histories.blade.php
Normal file
@ -0,0 +1,79 @@
|
||||
<flux:main>
|
||||
<flux:heading size="xl" level="1">{{ $pageTitle }}</flux:heading>
|
||||
<flux:text class="mb-6 mt-2 text-base">{{ $pageDescription }}</flux:text>
|
||||
|
||||
@if (empty($orders))
|
||||
<flux:card class="text-center py-12">
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<flux:icon.shopping-bag variant="outline" class="size-16 text-zinc-400 mb-4" />
|
||||
<flux:heading size="lg" class="mb-2">Belum Ada Pesanan</flux:heading>
|
||||
<flux:text class="text-zinc-500 mb-6">
|
||||
Anda belum melakukan pemesanan apapun. Mulai belanja sekarang!
|
||||
</flux:text>
|
||||
</div>
|
||||
</flux:card>
|
||||
@else
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
@foreach ($orders as $order)
|
||||
<flux:card class="relative overflow-hidden flex flex-col h-full">
|
||||
{{-- Badge Status --}}
|
||||
<div class="absolute top-4 right-4">
|
||||
<flux:badge color="{{ $order['status_color'] }}" size="sm">
|
||||
{{ $order['status_label'] }}
|
||||
</flux:badge>
|
||||
</div>
|
||||
|
||||
{{-- Order Header --}}
|
||||
<div class="mb-4 flex-1">
|
||||
<flux:heading size="lg" class="mb-1">Order #{{ $order['invoice_number'] }}
|
||||
</flux:heading>
|
||||
|
||||
{{-- Date --}}
|
||||
<div class="flex items-center gap-2 mb-4 text-zinc-500 dark:text-zinc-400">
|
||||
<flux:icon.calendar class="size-4" />
|
||||
<flux:text class="text-sm">
|
||||
{{ $order['formatted_created_at'] }}
|
||||
</flux:text>
|
||||
</div>
|
||||
|
||||
{{-- Items Count --}}
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<flux:icon.shopping-bag class="size-4 text-zinc-500" />
|
||||
<flux:text class="text-sm">
|
||||
{{ $order['total_items_count'] }} Produk
|
||||
</flux:text>
|
||||
</div>
|
||||
|
||||
{{-- Total Amount --}}
|
||||
<div class="flex items-center gap-2">
|
||||
<flux:icon.credit-card class="size-4 text-zinc-500" />
|
||||
<flux:text class="text-lg font-semibold text-zinc-900 dark:text-white">
|
||||
{{ $order['formatted_total'] }}
|
||||
</flux:text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<flux:separator class="my-3" />
|
||||
|
||||
{{-- Items Preview --}}
|
||||
<div class="space-y-2">
|
||||
<flux:text class="text-xs font-medium uppercase tracking-wider text-zinc-500">Ringkasan Pesanan
|
||||
</flux:text>
|
||||
@foreach ($order['preview_items'] as $item)
|
||||
<div class="flex justify-between items-start text-sm">
|
||||
<span class="truncate pr-2 text-zinc-700 dark:text-zinc-300">{{ $item['name'] }}</span>
|
||||
<span
|
||||
class="text-xs text-zinc-500 whitespace-nowrap">{{ $item['quantity_label'] }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
@if ($order['remaining_items_count'] > 0)
|
||||
<flux:text class="text-xs text-zinc-400 italic">
|
||||
+{{ $order['remaining_items_count'] }} item lainnya
|
||||
</flux:text>
|
||||
@endif
|
||||
</div>
|
||||
</flux:card>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</flux:main>
|
||||
@ -299,7 +299,7 @@
|
||||
<flux:input.group>
|
||||
<flux:input.group.prefix>Rp</flux:input.group.prefix>
|
||||
<flux:input placeholder="10.000" x-mask:dynamic="$money($input, ',')"
|
||||
wire:model="form.discount" autocomplete="off" />
|
||||
wire:model.live="form.discount" autocomplete="off" />
|
||||
</flux:input.group>
|
||||
</flux:field>
|
||||
</div>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
use App\Livewire\Member\Membership;
|
||||
use App\Livewire\Member\MyVouchers;
|
||||
use App\Livewire\Member\OrderHistory;
|
||||
use App\Livewire\Member\Overview;
|
||||
use App\Livewire\Member\RedeemPoint;
|
||||
use App\Livewire\Member\Referral;
|
||||
@ -16,6 +17,7 @@
|
||||
|
||||
Route::get('memberships', Membership::class)->name('membership');
|
||||
Route::get('my-vouchers', MyVouchers::class)->name('my_vouchers');
|
||||
Route::get('order-histories', OrderHistory::class)->name('order_history');
|
||||
Route::get('redeem-points', RedeemPoint::class)->name('redeem_point');
|
||||
Route::get('referrals', Referral::class)->name('referral');
|
||||
Route::get('settings', Account::class)->name('setting');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user