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

View File

@ -22,7 +22,7 @@ public function index()
public function dashboard() public function dashboard()
{ {
$user = auth()->user(); $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) $recentTransactions = Transaction::where('user_id', $user->id)
->latest() ->latest()
->take(3) ->take(3)

View File

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

View File

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

View File

@ -3,7 +3,7 @@
@section('title', 'Checkout') @section('title', 'Checkout')
<!-- Halaman Checkout --> <!-- Halaman Checkout -->
@section('content') @section('content')
<div class="max-w-5xl mx-auto"> <div class="max-w-5xl mx-auto">
<h2 class="text-2xl font-bold text-gray-900 tracking-tight mb-6">Checkout</h2> <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"> <form method="POST" action="{{ route('checkout.process') }}" class="grid grid-cols-1 lg:grid-cols-2 gap-8">
@ -24,20 +24,46 @@
</div> </div>
</div> </div>
<div> <div>
<label for="phone" class="block text-sm font-medium text-gray-700 mb-1.5">No. telepon pembeli *</label> <label for="phone" class="block text-sm font-medium text-gray-700 mb-1.5">No. telepon pembeli
<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"> *</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>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4"> <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div> <div>
<label for="pickup_date" class="block text-sm font-medium text-gray-700 mb-1.5">Tanggal ambil *</label> <label for="pickup_date" class="block text-sm font-medium text-gray-700 mb-1.5">Tanggal ambil
<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"> *</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>
<div> <div>
<label for="pickup_time" class="block text-sm font-medium text-gray-700 mb-1.5">Jam ambil *</label> <label for="pickup_time" class="block text-sm font-medium text-gray-700 mb-1.5">
<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"> 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>
</div> </div>
<p class="text-xs text-gray-500">Jam operasional pengambilan: {{ $pickupStart }} - {{ $pickupEnd }}. Pesanan otomatis dibatalkan jika melewati jam pengambilan.</p> <p class="text-xs text-gray-500">Jam operasional pengambilan: {{ $pickupStart }} - {{ $pickupEnd }}.
Pesanan otomatis dibatalkan jika melewati jam pengambilan.</p>
</div> </div>
</x-card> </x-card>
<div class="space-y-6"> <div class="space-y-6">
@ -47,14 +73,17 @@
@foreach($items as $item) @foreach($items as $item)
<li class="flex justify-between text-sm"> <li class="flex justify-between text-sm">
<span class="text-gray-700">{{ $item->product->name }} × {{ $item->quantity }}</span> <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> <span class="font-medium text-gray-900">Rp
{{ number_format($item->quantity * $item->product->price, 0, ',', '.') }}</span>
</li> </li>
@endforeach @endforeach
</ul> </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> <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-card>
<x-button type="submit" variant="primary" size="lg" class="w-full">Buat pesanan</x-button> <x-button type="submit" variant="primary" size="lg" class="w-full">Buat pesanan</x-button>
</div> </div>
</form> </form>
</div> </div>
@endsection @endsection

View File

@ -81,7 +81,7 @@
<tr class="hover:bg-gray-50/50"> <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 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-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> </tr>
@endforeach @endforeach
</tbody> </tbody>

View File

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

View File

@ -13,7 +13,7 @@
Rekomendasi Mainan Anak dengan Metode SAW Rekomendasi Mainan Anak dengan Metode SAW
</h1> </h1>
<p class="text-base lg:text-lg text-gray-600 max-w-xl leading-relaxed"> <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> </p>
<div class="flex flex-wrap gap-4"> <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"> <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">