perbaiki tampilan

This commit is contained in:
iFannJR 2026-06-22 00:02:58 +07:00
parent c638d2240c
commit 6fb2ab0d57
8 changed files with 102 additions and 73 deletions

View File

@ -17,7 +17,7 @@ public function show()
return redirect()->route('cart.index')->with('error', 'Keranjang kosong.');
}
$total = $items->sum(fn ($item) => $item->quantity * $item->product->price);
$pickupStart = config('store.pickup_start', '19:00');
$pickupStart = config('store.pickup_start', '07:00');
$pickupEnd = config('store.pickup_end', '21:00');
return view('user.checkout', compact('items', 'total', 'pickupStart', 'pickupEnd'));
@ -42,7 +42,7 @@ public function process(CheckoutRequest $request)
$code = 'TRX-' . strtoupper(Str::random(8));
$pickupDateTime = Carbon::parse($request->pickup_date . ' ' . $request->pickup_time);
$pickupStartDateTime = Carbon::parse($request->pickup_date . ' ' . config('store.pickup_start', '19:00'));
$pickupStartDateTime = Carbon::parse($request->pickup_date . ' ' . config('store.pickup_start', '07:00'));
$pickupEndDateTime = Carbon::parse($request->pickup_date . ' ' . config('store.pickup_end', '21:00'));
if ($pickupDateTime->lt(now())) {

View File

@ -22,7 +22,7 @@ public function index()
public function dashboard()
{
$user = auth()->user();
$totalTransactions = Transaction::where('user_id', $user->id)->count();
$totalTransactions = Transaction::where('user_id', $user->id)->count();//
$recentTransactions = Transaction::where('user_id', $user->id)
->latest()
->take(3)

View File

@ -18,6 +18,7 @@ class Transaction extends Model
'stock_restored_at' => 'datetime',
];
//status: pending, paid, cancelled
public static function cancelOverduePendingPickup(): void
{
static::query()

View File

@ -250,13 +250,12 @@ public function getRecommendationsWithMatrix(array $input): array
}
protected function getFilteredProducts(
int $ageMin,
int $ageMax,
float $budgetMin,
float $budgetMax,
?string $category = null
): Collection
{
int $ageMin,
int $ageMax,
float $budgetMin,
float $budgetMax,
?string $category = null
): Collection {
$query = Product::with('criterias')
->where('stock', '>', 0)
->whereBetween('price', [$budgetMin, $budgetMax]);
@ -386,10 +385,10 @@ protected function normalizeMatrix(array $matrix, Collection $criterias): array
foreach ($criterias as $criteria) {
$key = $criteria->name;
$values = array_column($matrix, $key);
$max = max($values);
$min = min($values);
$isCost = $criteria->type === 'cost';
$values = array_column($matrix, $key); //Mengambil seluruh nilai dari suatu kriteria.
$max = max($values); //Mencari nilai terbesar.
$min = min($values); //Mencari nilai terkecil
$isCost = $criteria->type === 'cost';//Mengecek apakah kriteria termasuk Cost atau Benefit.
if ($isCost) {
foreach ($matrix as $pid => $row) {

View File

@ -3,58 +3,87 @@
@section('title', 'Checkout')
<!-- Halaman Checkout -->
@section('content')
<div class="max-w-5xl mx-auto">
<h2 class="text-2xl font-bold text-gray-900 tracking-tight mb-6">Checkout</h2>
<div class="max-w-5xl mx-auto">
<h2 class="text-2xl font-bold text-gray-900 tracking-tight mb-6">Checkout</h2>
<form method="POST" action="{{ route('checkout.process') }}" class="grid grid-cols-1 lg:grid-cols-2 gap-8">
@csrf
<x-card>
<h3 class="text-xl font-semibold text-gray-900 mb-4">Pengambilan di Toko</h3>
<div class="space-y-6">
<div>
<p class="block text-sm font-medium text-gray-700 mb-1.5">Alamat toko</p>
<div class="rounded-xl border border-gray-200 bg-gray-50 px-4 py-3 text-sm text-gray-800">
{{ config('store.address') }}
</div>
</div>
<div>
<p class="block text-sm font-medium text-gray-700 mb-1.5">No. telepon toko</p>
<div class="rounded-xl border border-gray-200 bg-gray-50 px-4 py-3 text-sm text-gray-800">
{{ config('store.phone') }}
</div>
</div>
<div>
<label for="phone" class="block text-sm font-medium text-gray-700 mb-1.5">No. telepon pembeli *</label>
<input type="tel" id="phone" name="phone" value="{{ old('phone', auth()->user()->phone) }}" required placeholder="08..." autocomplete="tel" class="w-full rounded-xl border border-gray-200 bg-white px-4 py-2.5 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20">
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label for="pickup_date" class="block text-sm font-medium text-gray-700 mb-1.5">Tanggal ambil *</label>
<input type="date" id="pickup_date" name="pickup_date" value="{{ old('pickup_date', now()->toDateString()) }}" min="{{ now()->toDateString() }}" required class="w-full rounded-xl border border-gray-200 bg-white px-4 py-2.5 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20">
</div>
<div>
<label for="pickup_time" class="block text-sm font-medium text-gray-700 mb-1.5">Jam ambil *</label>
<input type="time" id="pickup_time" name="pickup_time" value="{{ old('pickup_time', $pickupStart) }}" min="{{ $pickupStart }}" max="{{ $pickupEnd }}" step="1800" required class="w-full rounded-xl border border-gray-200 bg-white px-4 py-2.5 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20">
</div>
</div>
<p class="text-xs text-gray-500">Jam operasional pengambilan: {{ $pickupStart }} - {{ $pickupEnd }}. Pesanan otomatis dibatalkan jika melewati jam pengambilan.</p>
</div>
</x-card>
<div class="space-y-6">
<form method="POST" action="{{ route('checkout.process') }}" class="grid grid-cols-1 lg:grid-cols-2 gap-8">
@csrf
<x-card>
<h3 class="font-semibold text-gray-900 mb-4">Ringkasan pesanan</h3>
<ul class="space-y-3">
@foreach($items as $item)
<li class="flex justify-between text-sm">
<span class="text-gray-700">{{ $item->product->name }} × {{ $item->quantity }}</span>
<span class="font-medium text-gray-900">Rp {{ number_format($item->quantity * $item->product->price, 0, ',', '.') }}</span>
</li>
@endforeach
</ul>
<p class="mt-4 pt-4 border-t border-gray-100 font-bold text-gray-900 text-lg">Total: Rp {{ number_format($total, 0, ',', '.') }}</p>
<h3 class="text-xl font-semibold text-gray-900 mb-4">Pengambilan di Toko</h3>
<div class="space-y-6">
<div>
<p class="block text-sm font-medium text-gray-700 mb-1.5">Alamat toko</p>
<div class="rounded-xl border border-gray-200 bg-gray-50 px-4 py-3 text-sm text-gray-800">
{{ config('store.address') }}
</div>
</div>
<div>
<p class="block text-sm font-medium text-gray-700 mb-1.5">No. telepon toko</p>
<div class="rounded-xl border border-gray-200 bg-gray-50 px-4 py-3 text-sm text-gray-800">
{{ config('store.phone') }}
</div>
</div>
<div>
<label for="phone" class="block text-sm font-medium text-gray-700 mb-1.5">No. telepon pembeli
*</label>
<input type="tel" id="phone" name="phone" value="{{ old('phone', auth()->user()->phone) }}" required
placeholder="08..." autocomplete="tel"
class="w-full rounded-xl border border-gray-200 bg-white px-4 py-2.5 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20">
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label for="pickup_date" class="block text-sm font-medium text-gray-700 mb-1.5">Tanggal ambil
*</label>
<input type="date" id="pickup_date" name="pickup_date"
value="{{ old('pickup_date', now()->toDateString()) }}" min="{{ now()->toDateString() }}"
required
class="w-full rounded-xl border border-gray-200 bg-white px-4 py-2.5 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20">
</div>
<div>
<label for="pickup_time" class="block text-sm font-medium text-gray-700 mb-1.5">
Jam ambil *
</label>
<select id="pickup_time" name="pickup_time" required
class="w-full rounded-xl border border-gray-200 bg-white px-4 py-2.5 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20">
@for ($hour = 7; $hour <= 21; $hour++)
<option value="{{ sprintf('%02d:00', $hour) }}">
{{ sprintf('%02d:00', $hour) }}
</option>
@if ($hour < 21)
<option value="{{ sprintf('%02d:30', $hour) }}">
{{ sprintf('%02d:30', $hour) }}
</option>
@endif
@endfor
</select>
</div>
</div>
<p class="text-xs text-gray-500">Jam operasional pengambilan: {{ $pickupStart }} - {{ $pickupEnd }}.
Pesanan otomatis dibatalkan jika melewati jam pengambilan.</p>
</div>
</x-card>
<x-button type="submit" variant="primary" size="lg" class="w-full">Buat pesanan</x-button>
</div>
</form>
</div>
@endsection
<div class="space-y-6">
<x-card>
<h3 class="font-semibold text-gray-900 mb-4">Ringkasan pesanan</h3>
<ul class="space-y-3">
@foreach($items as $item)
<li class="flex justify-between text-sm">
<span class="text-gray-700">{{ $item->product->name }} × {{ $item->quantity }}</span>
<span class="font-medium text-gray-900">Rp
{{ number_format($item->quantity * $item->product->price, 0, ',', '.') }}</span>
</li>
@endforeach
</ul>
<p class="mt-4 pt-4 border-t border-gray-100 font-bold text-gray-900 text-lg">Total: Rp
{{ number_format($total, 0, ',', '.') }}
</p>
</x-card>
<x-button type="submit" variant="primary" size="lg" class="w-full">Buat pesanan</x-button>
</div>
</form>
</div>
@endsection

View File

@ -81,7 +81,7 @@
<tr class="hover:bg-gray-50/50">
<td class="px-4 py-3 font-medium text-gray-900">{{ $c['name'] }}</td>
<td class="px-4 py-3 text-gray-600">{{ $c['type'] === 'cost' ? 'Cost' : 'Benefit' }}</td>
<td class="px-4 py-3 text-right font-mono">{{ number_format($c['weight'], 4) }}</td>
<td class="px-4 py-3 text-right font-mono">{{ number_format($c['weight'], 9) }}</td>
</tr>
@endforeach
</tbody>

View File

@ -20,15 +20,15 @@
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
<x-input label="Usia minimal (tahun)" name="age_min" type="number" value="{{ old('age_min', 3) }}"
min="0" max="18" required />
<x-input label="Usia maksimal (tahun)" name="age_max" type="number" value="{{ old('age_max', 8) }}"
<x-input label="Usia maksimal (tahun)" name="age_max" type="number" value="{{ old('age_max', 6) }}"
min="0" max="18" required />
<x-input label="Budget minimal (Rp)" name="budget_min" type="number"
value="{{ old('budget_min', 5000) }}" min="0" required />
value="{{ old('budget_min', 50000) }}" min="0" required />
<x-input label="Budget maksimal (Rp)" name="budget_max" type="number"
value="{{ old('budget_max', 300000) }}" min="0" required />
<div class="col-span-1 sm:col-span-2">
<x-select label="Kategori (opsional)" name="category" id="category">
<option value="">Pilih Kategori</option>
<option value="">Kategoti Umum</option>
@foreach($categories as $category)
<option value="{{ $category }}" {{ old('category') === $category ? 'selected' : '' }}>
{{ $category }}
@ -48,8 +48,8 @@
@forelse(($criterias ?? collect()) as $c)
@php
$hint = $c->type === 'cost'
? 'Cost semakin kecil semakin baik'
: 'Benefit semakin besar semakin baik';
? 'Semakin kecil, semakin penting ' //cost
: 'Semakin besar, semakin penting'; // benefit
$val = old('priorities.' . $c->id, 3);
@endphp
<div>

View File

@ -13,7 +13,7 @@
Rekomendasi Mainan Anak dengan Metode SAW
</h1>
<p class="text-base lg:text-lg text-gray-600 max-w-xl leading-relaxed">
Dapatkan rekomendasi mainan yang sesuai usia, budget, dan prioritas Anda. Sistem cerdas berbasis Simple Additive Weighting (SAW).
Dapatkan rekomendasi mainan yang sesuai usia, budget, dan prioritas Anda. Sistem cerdas berbasis Metode Simple Additive Weighting (SAW).
</p>
<div class="flex flex-wrap gap-4">
<a href="{{ route('register') }}" class="inline-flex items-center justify-center gap-2 px-8 py-3.5 rounded-2xl font-semibold text-white bg-primary-500 shadow-md hover:bg-primary-600 hover:shadow-lg hover:-translate-y-0.5 transition-all duration-300">