dstpabuaran.com/resources/js/pages/admin/master/product/reject-dialog.tsx
Yoga Pangestu 85556f8779 feat: enhance product management with approval and rejection workflows
- Added approval and rejection functionality for products, including new routes and methods in the ProductController.
- Implemented UI changes to display product status (pending, rejected) with appropriate badges and actions.
- Introduced a RejectDialog component for providing rejection reasons.
- Updated product columns to handle new actions for approving and rejecting products.
- Enhanced variant management to restrict actions based on product status.
- Refactored various components to improve code organization and readability.
2026-08-07 11:23:41 +07:00

87 lines
2.7 KiB
TypeScript

import { useState } from 'react';
import { router } from '@inertiajs/react';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Textarea } from '@/components/ui/textarea';
import type { Product } from './columns';
type RejectDialogProps = {
product: Product | null;
onOpenChange: (open: boolean) => void;
rejectUrl: (id: number) => string;
};
export function RejectDialog({ product, onOpenChange, rejectUrl }: RejectDialogProps) {
const [reason, setReason] = useState('');
const [processing, setProcessing] = useState(false);
function handleReject() {
if (!product) return;
setProcessing(true);
router.post(
rejectUrl(product.id),
{ rejection_reason: reason },
{
preserveScroll: true,
onSuccess: () => {
setReason('');
onOpenChange(false);
},
onFinish: () => setProcessing(false),
},
);
}
return (
<Dialog open={product !== null} onOpenChange={onOpenChange}>
<DialogContent>
<DialogHeader>
<DialogTitle>Tolak Produk</DialogTitle>
<DialogDescription>
Berikan alasan penolakan untuk produk "{product?.name}".
Alasan ini akan terlihat oleh pembuat produk.
</DialogDescription>
</DialogHeader>
<div className="space-y-2">
<label className="text-sm font-medium">
Alasan Penolakan <span className="text-destructive">*</span>
</label>
<Textarea
value={reason}
onChange={(e) => setReason(e.target.value)}
placeholder="Masukkan alasan penolakan..."
rows={3}
/>
</div>
<DialogFooter>
<Button
variant="outline"
onClick={() => onOpenChange(false)}
disabled={processing}
>
Batal
</Button>
<Button
variant="destructive"
onClick={handleReject}
disabled={processing || !reason.trim()}
>
Tolak
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}