import type { PaginationState } from '@/components/data-table'; import { DataTable } from '@/components/data-table'; import { DeleteConfirmDialog } from '@/components/delete-confirm-dialog'; import type { FilterField } from '@/components/filter-dialog'; import { FilterDialog } from '@/components/filter-dialog'; import { PageHeader } from '@/components/page-header'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Label } from '@/components/ui/label'; import { usePermissions } from '@/hooks/use-permissions'; import { useServerTable } from '@/hooks/use-server-table'; import { richTextContentClass } from '@/lib/rich-text-content'; import { cn } from '@/lib/utils'; import { create, destroy, edit, index as feedbackIndex, update_status, } from '@/routes/admin/feedback'; import type { Feedback } from '@/types/feedback'; import { FeedbackStatusLabels, FeedbackTypeLabels } from '@/types/feedback'; import { Head, Link, router } from '@inertiajs/react'; import { format } from 'date-fns'; import { Info, Plus } from 'lucide-react'; import { useState } from 'react'; import { createFeedbackColumns, FeedbackStatusVariants } from './columns'; type FeedbackTypeOption = { value: string; label: string }; type Props = { feedbacks: { data: Feedback[]; current_page: number; last_page: number; per_page: number; total: number; }; types: FeedbackTypeOption[]; statuses: FeedbackTypeOption[]; filters: { type?: string; status?: string; }; }; export default function FeedbackIndex({ feedbacks, types, statuses, filters, }: Props) { const [deleting, setDeleting] = useState(null); const [viewing, setViewing] = useState(null); const { hasPermission } = usePermissions(); const canCreate = hasPermission('create-feedback'); const canUpdate = hasPermission('update-feedback'); const canDelete = hasPermission('delete-feedback'); const canUpdateStatus = hasPermission('update-feedback-status'); const filterFields: FilterField[] = [ { key: 'type', label: 'Jenis', options: types, }, { key: 'status', label: 'Status', options: statuses, }, ]; const pagination: PaginationState = { current_page: feedbacks.current_page, last_page: feedbacks.last_page, per_page: feedbacks.per_page, total: feedbacks.total, }; const { search, handlePageChange, handlePerPageChange, handleSearchChange, applyFilters, } = useServerTable({ route: () => feedbackIndex.url(), pagination, filters, }); function handleDelete() { if (!deleting) { return; } router.delete(destroy(deleting.id), { onSuccess: () => setDeleting(null), }); } function handleStatusChange(feedback: Feedback, status: string) { router.patch( update_status.url(feedback.id), { status }, { preserveScroll: true }, ); } const columns = createFeedbackColumns({ handleView: (feedback) => setViewing(feedback), handleEdit: (feedback) => router.get(edit.url(feedback.id)), handleDeleteClick: (feedback) => setDeleting(feedback), handleStatusChange, statuses, canUpdateStatus, canUpdate, canDelete, }); return ( <>
Tambah ) } /> { if (!open) { setViewing(null); } }} feedback={viewing} /> {canUpdateStatus && ( Ubah status Kritik dan Saran Klik badge Status pada tabel untuk mengubah status Kritik dan Saran secara langsung. )} } /> { if (!open) { setDeleting(null); } }} title="Hapus Masukan" description={(feedback) => `Apakah Anda yakin ingin menghapus "${feedback.subject}"? Tindakan ini tidak dapat dibatalkan.` } onConfirm={handleDelete} />
); } function ViewDetailDialog({ open, onOpenChange, feedback, }: { open: boolean; onOpenChange: (open: boolean) => void; feedback: Feedback | null; }) { return ( Detail Kritik dan Saran {feedback && (
{FeedbackTypeLabels[feedback.type]} {FeedbackStatusLabels[feedback.status]} Dikirim{' '} {format( new Date(feedback.created_at), 'd MMM yyyy, HH:mm', )}

{feedback.subject}

{feedback.user?.profile?.full_name ?? '-'}

{feedback.handler?.profile?.full_name ?? 'Belum ditindaklanjuti'}

{feedback.admin_notes && (

{feedback.admin_notes}

)}
)}
); }