feat: add update status functionality for transactions with corresponding UI actions

This commit is contained in:
Yoga Pangestu 2026-08-06 14:59:48 +07:00
parent 508a0e3fa8
commit 6ebcbc24c0
4 changed files with 57 additions and 1 deletions

View File

@ -76,4 +76,13 @@ public function destroy(Order $transaction): RedirectResponse
'admin.manage.transactions.index' 'admin.manage.transactions.index'
); );
} }
public function updateStatus(Order $transaction): RedirectResponse
{
return $this->handleAction(
fn () => $this->service->updateStatus($transaction, request('status')),
'Status transaksi berhasil diperbarui.',
'admin.manage.transactions.index'
);
}
} }

View File

@ -358,6 +358,13 @@ public function delete(Order $order): bool
}); });
} }
public function updateStatus(Order $order, string $status): Order
{
$order->update(['status' => $status]);
return $order;
}
private function buildItemRows(array $items, string $stockType, string $priceType, $now, int &$subtotal, int &$totalCost): array private function buildItemRows(array $items, string $stockType, string $priceType, $now, int &$subtotal, int &$totalCost): array
{ {
$resolvedPriceType = $stockType === ProductStockQuality::REJECT->value $resolvedPriceType = $stockType === ProductStockQuality::REJECT->value

View File

@ -31,6 +31,7 @@ import {
create as transactionCreate, create as transactionCreate,
index as transactionIndex, index as transactionIndex,
edit as transactionEdit, edit as transactionEdit,
updateStatus as transactionUpdateStatus,
} from '@/routes/admin/manage/transactions'; } from '@/routes/admin/manage/transactions';
import type { Transaction } from './columns'; import type { Transaction } from './columns';
import { TransactionCardRow } from './transaction-card'; import { TransactionCardRow } from './transaction-card';
@ -147,6 +148,10 @@ export default function TransactionIndex({
}); });
} }
function handleUpdateStatus(transaction: Transaction, status: string) {
router.patch(transactionUpdateStatus.url(transaction.id), { status });
}
const filterToolbar = ( const filterToolbar = (
<FilterPopover <FilterPopover
open={filterOpen} open={filterOpen}
@ -398,6 +403,7 @@ export default function TransactionIndex({
router.visit(transactionEdit.url(t.id)); router.visit(transactionEdit.url(t.id));
}} }}
onDelete={(t) => setDeleting(t)} onDelete={(t) => setDeleting(t)}
onUpdateStatus={(t, status) => handleUpdateStatus(t, status)}
/> />
)} )}
renderSubContent={(transaction) => ( renderSubContent={(transaction) => (

View File

@ -5,7 +5,7 @@ import { Card, CardContent } from '@/components/ui/card';
import { useCan } from '@/hooks/use-can'; import { useCan } from '@/hooks/use-can';
import { formatDateTime, formatNumber } from '@/lib/format'; import { formatDateTime, formatNumber } from '@/lib/format';
import { formatCurrency } from '@/lib/utils'; import { formatCurrency } from '@/lib/utils';
import { ChevronDown, Pencil, Trash2 } from 'lucide-react'; import { CheckCircle, ChevronDown, Pencil, Send, Trash2, XCircle } from 'lucide-react';
import type { Transaction } from './columns'; import type { Transaction } from './columns';
const STATUS_BADGE_CLASSES: Record<string, string> = { const STATUS_BADGE_CLASSES: Record<string, string> = {
@ -23,6 +23,7 @@ export type TransactionCardRowParams = {
onToggleExpand: () => void; onToggleExpand: () => void;
onEdit: (transaction: Transaction) => void; onEdit: (transaction: Transaction) => void;
onDelete: (transaction: Transaction) => void; onDelete: (transaction: Transaction) => void;
onUpdateStatus: (transaction: Transaction, status: string) => void;
}; };
export function TransactionCardRow({ export function TransactionCardRow({
@ -32,6 +33,7 @@ export function TransactionCardRow({
onToggleExpand, onToggleExpand,
onEdit, onEdit,
onDelete, onDelete,
onUpdateStatus,
}: TransactionCardRowParams) { }: TransactionCardRowParams) {
const { can } = useCan(); const { can } = useCan();
const items = transaction.order_items ?? []; const items = transaction.order_items ?? [];
@ -183,6 +185,38 @@ export function TransactionCardRow({
<RowActions <RowActions
actions={[ actions={[
...(transaction.status === 'pending' && can('orders.update')
? [
{
label: 'Kirim',
icon: <Send className="h-4 w-4" />,
onClick: () => onUpdateStatus(transaction, 'processing'),
},
]
: []),
...((transaction.status === 'pending' || transaction.status === 'processing') && can('orders.update')
? [
{
label: 'Selesai',
icon: <CheckCircle className="h-4 w-4" />,
onClick: () => onUpdateStatus(transaction, 'completed'),
},
{
label: 'Dibatalkan',
icon: <XCircle className="h-4 w-4 text-destructive" />,
onClick: () => onUpdateStatus(transaction, 'cancelled'),
},
]
: []),
...(transaction.status === 'completed' && can('orders.update')
? [
{
label: 'Refund',
icon: <XCircle className="h-4 w-4 text-destructive" />,
onClick: () => onUpdateStatus(transaction, 'refunded'),
},
]
: []),
{ {
label: 'Edit', label: 'Edit',
icon: <Pencil className="h-4 w-4" />, icon: <Pencil className="h-4 w-4" />,