260 lines
9.4 KiB
PHP
260 lines
9.4 KiB
PHP
@extends('admin.layout')
|
|
|
|
@section('title', 'Input Transaksi')
|
|
|
|
@section('content')
|
|
@php
|
|
$selectedCategory = $categories->firstWhere('id', old('category_id'));
|
|
$categoryOptions = $categories->map(function ($category) {
|
|
return [
|
|
'id' => $category->id,
|
|
'label' => $category->name . ' - Rp ' . number_format($category->price, 0, ',', '.'),
|
|
'name' => $category->name,
|
|
'price' => (float) $category->price,
|
|
];
|
|
})->values();
|
|
@endphp
|
|
|
|
<style>
|
|
.transaction-form {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.transaction-form .form-group--full,
|
|
.transaction-form .transaction-items,
|
|
.transaction-form .form-actions {
|
|
grid-column: 1 / -1;
|
|
}
|
|
|
|
.category-search-meta {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
margin-top: 8px;
|
|
color: #64748b;
|
|
font-size: 12px;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.transaction-form {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<div class="page-header">
|
|
<div>
|
|
<p style="margin:0; color:#6b7280; font-weight:600; letter-spacing:0.15em; text-transform:uppercase;">Input Transaksi</p>
|
|
<h2>Tambah transaksi baru</h2>
|
|
<p>Masukkan data customer, pilih produk, dan simpan transaksi dengan mudah.</p>
|
|
</div>
|
|
<div class="badge">Input</div>
|
|
</div>
|
|
|
|
<div class="panel">
|
|
<div class="panel-header">
|
|
<h3>Informasi Transaksi</h3>
|
|
<a href="{{ route('riwayat') }}" class="button-secondary">Kembali ke Daftar Transaksi</a>
|
|
</div>
|
|
|
|
@if($errors->any())
|
|
<div class="alert alert-danger" style="margin-bottom:16px; padding:12px; border-radius:8px; background:#ffe6e6; color:#9b1c1c;">
|
|
<ul style="margin:0; padding-left:18px;">
|
|
@foreach($errors->all() as $error)
|
|
<li>{{ $error }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
|
|
<form action="{{ route('input.store') }}" method="POST" enctype="multipart/form-data" class="form-grid transaction-form">
|
|
@csrf
|
|
<div class="form-group">
|
|
<label>Kode Transaksi</label>
|
|
<input type="text" name="transaction_code" value="{{ old('transaction_code', $transactionCode ?? 'TRX' . now()->format('YmdHis')) }}" readonly />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Tanggal Transaksi</label>
|
|
<input type="text" value="{{ now()->format('d/m/Y') }}" readonly />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Nama Customer</label>
|
|
<input type="text" name="customer_name" value="{{ old('customer_name') }}" placeholder="Nama Customer*" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>No. Telepon</label>
|
|
<input type="text" name="customer_phone" value="{{ old('customer_phone') }}" placeholder="No. Telepon" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Email</label>
|
|
<input type="email" name="customer_email" value="{{ old('customer_email') }}" placeholder="Email" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Cari Kategori / Produk</label>
|
|
<input
|
|
type="text"
|
|
id="category_search"
|
|
list="category_options"
|
|
value="{{ $selectedCategory ? $selectedCategory->name . ' - Rp ' . number_format($selectedCategory->price, 0, ',', '.') : '' }}"
|
|
placeholder="Ketik nama mobil atau harga"
|
|
autocomplete="off"
|
|
/>
|
|
<input type="hidden" name="category_id" id="category_id" value="{{ old('category_id') }}" />
|
|
<datalist id="category_options">
|
|
@foreach($categories as $category)
|
|
<option value="{{ $category->name }} - Rp {{ number_format($category->price, 0, ',', '.') }}"></option>
|
|
@endforeach
|
|
</datalist>
|
|
<div class="category-search-meta">
|
|
<span>Ketik untuk mencari, lalu pilih mobil dari saran.</span>
|
|
<span>{{ $categories->count() }} mobil</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Jumlah</label>
|
|
<input type="number" name="quantity" id="quantity" min="1" value="{{ old('quantity', 1) }}" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Total Bayar</label>
|
|
<input type="text" id="total_bayar" value="Rp 0" readonly />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Metode Pembayaran</label>
|
|
<select name="payment_method">
|
|
<option value="">-- Pilih Metode Pembayaran --</option>
|
|
<option value="cash" {{ old('payment_method') === 'cash' ? 'selected' : '' }}>Tunai</option>
|
|
<option value="transfer" {{ old('payment_method') === 'transfer' ? 'selected' : '' }}>Transfer Bank</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Status Pembayaran</label>
|
|
<select name="payment_status">
|
|
<option value="pending" {{ old('payment_status') === 'pending' ? 'selected' : '' }}>Pending</option>
|
|
<option value="paid" {{ old('payment_status') === 'paid' ? 'selected' : '' }}>Lunas</option>
|
|
<option value="cancelled" {{ old('payment_status') === 'cancelled' ? 'selected' : '' }}>Dibatalkan</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group form-group--full">
|
|
<label>Bukti Pembayaran</label>
|
|
<input type="file" name="payment_proof" accept=".jpg,.jpeg,.png,.pdf" />
|
|
<small style="color:#64748b;">Format JPG, PNG, atau PDF. Maksimal 2 MB.</small>
|
|
</div>
|
|
|
|
<div class="form-group form-group--full">
|
|
<label>Catatan</label>
|
|
<textarea name="note" placeholder="Catatan tambahan">{{ old('note') }}</textarea>
|
|
</div>
|
|
|
|
<div class="panel transaction-items" style="padding:18px;">
|
|
<h3 style="margin-top:0;">Item yang Dipilih</h3>
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Produk</th>
|
|
<th>Harga</th>
|
|
<th>Qty</th>
|
|
<th>Subtotal</th>
|
|
<th>Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="selected_item_body">
|
|
<tr id="empty_item_row">
|
|
<td colspan="5" style="text-align:center; color:#64748b; padding:18px 0;">Pilih kategori terlebih dahulu untuk menambahkan item.</td>
|
|
</tr>
|
|
<tr id="selected_item_row" style="display:none;">
|
|
<td id="item_name">-</td>
|
|
<td id="item_price">Rp 0</td>
|
|
<td id="item_quantity">1</td>
|
|
<td id="item_subtotal">Rp 0</td>
|
|
<td>
|
|
<button type="button" class="button-secondary" id="clear_item" style="background:#f87171; color:#fff;">Hapus</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-actions" style="display:flex; gap:12px; justify-content:flex-end;">
|
|
<button type="submit" class="button-primary">Simpan Transaksi</button>
|
|
<a href="{{ route('riwayat') }}" class="button-secondary">Batal</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<script>
|
|
const categorySearch = document.getElementById('category_search');
|
|
const categoryInput = document.getElementById('category_id');
|
|
const quantityInput = document.getElementById('quantity');
|
|
const totalInput = document.getElementById('total_bayar');
|
|
const emptyItemRow = document.getElementById('empty_item_row');
|
|
const selectedItemRow = document.getElementById('selected_item_row');
|
|
const itemName = document.getElementById('item_name');
|
|
const itemPrice = document.getElementById('item_price');
|
|
const itemQuantity = document.getElementById('item_quantity');
|
|
const itemSubtotal = document.getElementById('item_subtotal');
|
|
const clearItemButton = document.getElementById('clear_item');
|
|
const categories = @json($categoryOptions);
|
|
|
|
function formatRupiah(value) {
|
|
return new Intl.NumberFormat('id-ID', {
|
|
style: 'currency',
|
|
currency: 'IDR',
|
|
maximumFractionDigits: 0
|
|
}).format(value);
|
|
}
|
|
|
|
function getSelectedCategory() {
|
|
return categories.find(category => String(category.id) === String(categoryInput.value));
|
|
}
|
|
|
|
function syncSelectedCategory() {
|
|
const selected = categories.find(category => category.label === categorySearch.value);
|
|
categoryInput.value = selected ? selected.id : '';
|
|
updateTotal();
|
|
}
|
|
|
|
function updateTotal() {
|
|
const selected = getSelectedCategory();
|
|
const price = Number(selected ? selected.price : 0);
|
|
const quantity = Number(quantityInput.value || 1);
|
|
const subtotal = price * quantity;
|
|
|
|
totalInput.value = formatRupiah(subtotal);
|
|
itemQuantity.textContent = quantity;
|
|
itemSubtotal.textContent = formatRupiah(subtotal);
|
|
|
|
if (selected) {
|
|
itemName.textContent = selected.name;
|
|
itemPrice.textContent = formatRupiah(price);
|
|
emptyItemRow.style.display = 'none';
|
|
selectedItemRow.style.display = '';
|
|
} else {
|
|
emptyItemRow.style.display = '';
|
|
selectedItemRow.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
categorySearch.addEventListener('input', syncSelectedCategory);
|
|
categorySearch.addEventListener('change', syncSelectedCategory);
|
|
quantityInput.addEventListener('input', updateTotal);
|
|
clearItemButton.addEventListener('click', () => {
|
|
categorySearch.value = '';
|
|
categoryInput.value = '';
|
|
updateTotal();
|
|
});
|
|
updateTotal();
|
|
</script>
|
|
@endsection
|