diff --git a/app/Http/Controllers/Admin/FeedbackController.php b/app/Http/Controllers/Admin/FeedbackController.php index dd300fe..a6e4832 100644 --- a/app/Http/Controllers/Admin/FeedbackController.php +++ b/app/Http/Controllers/Admin/FeedbackController.php @@ -36,6 +36,13 @@ public function index(PaginatedRequest $request): Response ]); } + public function create(): Response + { + return Inertia::render('admin/feedback/create', [ + 'types' => FeedbackType::options(), + ]); + } + public function store(FeedbackRequest $request): RedirectResponse { $this->service->create($request->user(), $request->validated()); @@ -45,6 +52,16 @@ public function store(FeedbackRequest $request): RedirectResponse return to_route('admin.feedback.index'); } + public function edit(Request $request, Feedback $feedback): Response + { + abort_unless($feedback->user_id === $request->user()->id, 403); + + return Inertia::render('admin/feedback/edit', [ + 'feedback' => $feedback, + 'types' => FeedbackType::options(), + ]); + } + public function update(FeedbackRequest $request, Feedback $feedback): RedirectResponse { abort_unless($feedback->user_id === $request->user()->id, 403); diff --git a/resources/js/pages/admin/feedback/create.tsx b/resources/js/pages/admin/feedback/create.tsx new file mode 100644 index 0000000..423017a --- /dev/null +++ b/resources/js/pages/admin/feedback/create.tsx @@ -0,0 +1,126 @@ +import { Form, Head, Link } from '@inertiajs/react'; +import { ArrowLeft, Save } from 'lucide-react'; +import { useState } from 'react'; +import InputError from '@/components/input-error'; +import { PageHeader } from '@/components/page-header'; +import TiptapEditor from '@/components/rich-text-editor'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; +import { index, store } from '@/routes/admin/feedback'; + +type FeedbackTypeOption = { value: string; label: string }; + +type Props = { + types: FeedbackTypeOption[]; +}; + +export default function FeedbackCreate({ types }: Props) { + const [message, setMessage] = useState(''); + + return ( + <> + + +
+ + + + Kembali + + + } + /> + +
+ {({ errors, processing }) => ( + <> + + + Detail Masukan + + +
+ + + + +
+
+ + + +
+
+ + +
+
+
+ +
+ +
+ + )} +
+
+ + ); +} diff --git a/resources/js/pages/admin/feedback/edit.tsx b/resources/js/pages/admin/feedback/edit.tsx new file mode 100644 index 0000000..2ca550b --- /dev/null +++ b/resources/js/pages/admin/feedback/edit.tsx @@ -0,0 +1,128 @@ +import { Form, Head, Link } from '@inertiajs/react'; +import { ArrowLeft, Save } from 'lucide-react'; +import { useState } from 'react'; +import InputError from '@/components/input-error'; +import { PageHeader } from '@/components/page-header'; +import TiptapEditor from '@/components/rich-text-editor'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; +import { index, update } from '@/routes/admin/feedback'; +import type { Feedback } from '@/types/feedback'; + +type FeedbackTypeOption = { value: string; label: string }; + +type Props = { + feedback: Feedback; + types: FeedbackTypeOption[]; +}; + +export default function FeedbackEdit({ feedback, types }: Props) { + const [message, setMessage] = useState(feedback.message); + + return ( + <> + + +
+ + + + Kembali + + + } + /> + +
+ {({ errors, processing }) => ( + <> + + + Detail Masukan + + +
+ + + +
+
+ + + +
+
+ + +
+
+
+ +
+ +
+ + )} +
+
+ + ); +} diff --git a/resources/js/pages/admin/feedback/index.tsx b/resources/js/pages/admin/feedback/index.tsx index 8afb087..7e7bbfa 100644 --- a/resources/js/pages/admin/feedback/index.tsx +++ b/resources/js/pages/admin/feedback/index.tsx @@ -1,16 +1,10 @@ -import { Head, router } from '@inertiajs/react'; -import { format } from 'date-fns'; -import { Plus } from 'lucide-react'; -import { useState } from 'react'; 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 { FormDialog } from '@/components/form-dialog'; -import InputError from '@/components/input-error'; import { PageHeader } from '@/components/page-header'; -import TiptapEditor from '@/components/rich-text-editor'; +import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { @@ -19,28 +13,24 @@ import { DialogHeader, DialogTitle, } from '@/components/ui/dialog'; -import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; 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 { - index as feedbackIndex, + create, destroy, - store, - update, + 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 }; @@ -67,8 +57,6 @@ export default function FeedbackIndex({ statuses, filters, }: Props) { - const [createOpen, setCreateOpen] = useState(false); - const [editing, setEditing] = useState(null); const [deleting, setDeleting] = useState(null); const [viewing, setViewing] = useState(null); const { hasPermission } = usePermissions(); @@ -129,7 +117,7 @@ export default function FeedbackIndex({ const columns = createFeedbackColumns({ handleView: (feedback) => setViewing(feedback), - handleEdit: (feedback) => setEditing(feedback), + handleEdit: (feedback) => router.get(edit.url(feedback.id)), handleDeleteClick: (feedback) => setDeleting(feedback), handleStatusChange, statuses, @@ -148,36 +136,15 @@ export default function FeedbackIndex({ actions={ canCreate && ( + ) } /> - - - { - if (!open) { - setEditing(null); - } - }} - editing={editing} - types={types} - /> - { @@ -188,6 +155,15 @@ export default function FeedbackIndex({ feedback={viewing} /> + + + Ubah status Kritik dan Saran + + Klik badge Status pada tabel untuk mengubah status Kritik dan Saran + secara langsung. + + + ; - editing?: Feedback; - types: FeedbackTypeOption[]; -}) { - const [message, setMessage] = useState(editing?.message ?? ''); - - return ( - <> -
- - {!editing && } - - -
-
- - - -
-
- - -
- - ); -} - -function CreateForm({ - open, - onOpenChange, - types, -}: { - open: boolean; - onOpenChange: (open: boolean) => void; - types: FeedbackTypeOption[]; -}) { - return ( - onOpenChange(false)} - contentClassName="sm:max-w-4xl" - > - {({ errors }) => ( -
- -
- )} -
- ); -} - -function EditForm({ - open, - onOpenChange, - editing, - types, -}: { - open: boolean; - onOpenChange: (open: boolean) => void; - editing: Feedback | null; - types: FeedbackTypeOption[]; -}) { - return ( - onOpenChange(false)} - contentClassName="sm:max-w-2xl" - > - {({ errors }) => - editing && ( -
- -
- ) - } -
- ); -} - function ViewDetailDialog({ open, onOpenChange, diff --git a/routes/admin.php b/routes/admin.php index f2799fa..bd88d19 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -201,11 +201,11 @@ }); Route::resource('admin/feedback', FeedbackController::class) - ->except(['create', 'edit', 'show']) + ->except(['show']) ->names('admin.feedback') ->middlewareFor(['index'], 'permission:view-feedback') - ->middlewareFor(['store'], 'permission:create-feedback') - ->middlewareFor(['update'], 'permission:update-feedback') + ->middlewareFor(['create', 'store'], 'permission:create-feedback') + ->middlewareFor(['edit', 'update'], 'permission:update-feedback') ->middlewareFor(['destroy'], 'permission:delete-feedback'); Route::patch('admin/feedback/{feedback}/status', [FeedbackController::class, 'updateStatus'])->name('admin.feedback.update_status')->middleware('permission:update-feedback-status');