From 63c5d0a11f9d318a66c7f187d3a67ad6f6181081 Mon Sep 17 00:00:00 2001 From: Mhanif26 Date: Wed, 3 Jun 2026 10:50:30 +0700 Subject: [PATCH] pembatasan akses delete dari pengelola rumah ibadah dan fitur upload bukti penyerahan bantuan --- api/distributionRouter.ts | 2 ++ api/recipientRouter.ts | 11 +++---- db/schema.ts | 1 + src/pages/PlacesOfWorshipPage.tsx | 49 +++++++++++++++++++++++++++++-- src/pages/RecipientsPage.tsx | 26 ++++++++-------- 5 files changed, 68 insertions(+), 21 deletions(-) diff --git a/api/distributionRouter.ts b/api/distributionRouter.ts index 9743631..885dce0 100644 --- a/api/distributionRouter.ts +++ b/api/distributionRouter.ts @@ -59,6 +59,7 @@ export const distributionRouter = createRouter({ quantity: z.number().min(1).default(1), unit: z.string().default("package"), notes: z.string().optional(), + handoverPhoto: z.string().min(1), }) ) .mutation(async ({ input, ctx }) => { @@ -77,6 +78,7 @@ export const distributionRouter = createRouter({ amount: input.amount.toString(), distributedBy: input.distributedBy ?? null, notes: input.notes ?? null, + handoverPhoto: input.handoverPhoto, }); if (created) { diff --git a/api/recipientRouter.ts b/api/recipientRouter.ts index ef38ba5..c84d9a7 100644 --- a/api/recipientRouter.ts +++ b/api/recipientRouter.ts @@ -250,13 +250,10 @@ export const recipientRouter = createRouter({ } if (ctx.user.role === "manager") { - const placeIds = await findPlaceIdsByManagerId(ctx.user.id); - if (!placeIds.includes(target.placeOfWorshipId)) { - throw new TRPCError({ - code: "FORBIDDEN", - message: "Anda tidak berwenang menghapus data penerima ini.", - }); - } + throw new TRPCError({ + code: "FORBIDDEN", + message: "Pengelola rumah ibadah tidak berwenang menghapus data penerima.", + }); } await deleteRecipient(input.id); diff --git a/db/schema.ts b/db/schema.ts index 96ff6d6..ac68888 100644 --- a/db/schema.ts +++ b/db/schema.ts @@ -108,6 +108,7 @@ export const distributions = mysqlTable( quantity: int("quantity").default(1), unit: varchar("unit", { length: 50 }).default("package"), distributionDate: timestamp("distribution_date").defaultNow().notNull(), + handoverPhoto: longtext("handover_photo"), notes: text("notes"), createdAt: timestamp("created_at").defaultNow().notNull(), }, diff --git a/src/pages/PlacesOfWorshipPage.tsx b/src/pages/PlacesOfWorshipPage.tsx index 9090a87..a3f9856 100644 --- a/src/pages/PlacesOfWorshipPage.tsx +++ b/src/pages/PlacesOfWorshipPage.tsx @@ -2,6 +2,8 @@ import { useMemo, useState } from "react"; import { trpc } from "@/providers/trpc"; import { useAuth } from "@/hooks/useAuth"; import { LocationPicker } from "@/components/LocationPicker"; +import { DocumentUploadField } from "@/components/DocumentUploadField"; +import { toast } from "sonner"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -80,6 +82,7 @@ export default function PlacesOfWorshipPage() { quantity: 1, unit: "paket", notes: "", + handoverPhoto: "", }); const [formData, setFormData] = useState({ name: "", @@ -142,6 +145,7 @@ export default function PlacesOfWorshipPage() { quantity: 1, unit: "paket", notes: "", + handoverPhoto: "", }); }, }); @@ -232,6 +236,10 @@ export default function PlacesOfWorshipPage() { const handleAidSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!selectedPlace || !aidForm.recipientId) return; + if (!aidForm.handoverPhoto) { + toast.error("Foto penyerahan wajib diunggah."); + return; + } createAidMutation.mutate({ placeOfWorshipId: selectedPlace, recipientId: aidForm.recipientId, @@ -240,6 +248,7 @@ export default function PlacesOfWorshipPage() { quantity: aidForm.quantity, unit: aidForm.unit, notes: aidForm.notes || undefined, + handoverPhoto: aidForm.handoverPhoto, }); }; @@ -507,7 +516,7 @@ export default function PlacesOfWorshipPage() { /> -
+
- @@ -536,6 +555,7 @@ export default function PlacesOfWorshipPage() { Jenis Jumlah Catatan + Foto Bukti @@ -554,6 +574,31 @@ export default function PlacesOfWorshipPage() { {distribution.aidType} {formatRupiah(Number.parseFloat(String(distribution.amount ?? 0)))} {distribution.notes ?? "-"} + + {distribution.handoverPhoto ? ( + + + Bukti Penyerahan + + + + Foto Penyerahan Bantuan + + Bukti Penyerahan + + + ) : ( + - + )} + ); })} diff --git a/src/pages/RecipientsPage.tsx b/src/pages/RecipientsPage.tsx index 3439947..30609c8 100644 --- a/src/pages/RecipientsPage.tsx +++ b/src/pages/RecipientsPage.tsx @@ -576,18 +576,20 @@ export default function RecipientsPage() { > - + {isAdmin && ( + + )} )}