From d38bb005a1f70deddb16ec7c88edb7036dcd5734 Mon Sep 17 00:00:00 2001 From: Anang Yusman Date: Tue, 10 Jun 2025 12:55:36 +0800 Subject: [PATCH] feat:emergency issue --- .../setting-tracking/component/column.tsx | 20 +- .../setting-tracking/component/create.tsx | 260 +++++++++--------- .../setting-tracking/component/table.tsx | 12 +- .../settings/setting-tracking/create/page.tsx | 15 + .../setting-tracking/detail/[id]/page.tsx | 15 + .../setting-tracking/update/[id]/page.tsx | 15 + .../communication/questions-reply-form.tsx | 9 +- .../setting-tracking-detail-form.tsx | 110 ++++++++ .../media-tracking/setting-tracking-form.tsx | 110 ++++++++ .../setting-tracking-update-form.tsx | 110 ++++++++ .../form/ticketing/info-lainnya-types.ts | 7 +- components/form/ticketing/info-lainnya.tsx | 78 +++++- 12 files changed, 608 insertions(+), 153 deletions(-) create mode 100644 app/[locale]/(protected)/admin/settings/setting-tracking/create/page.tsx create mode 100644 app/[locale]/(protected)/admin/settings/setting-tracking/detail/[id]/page.tsx create mode 100644 app/[locale]/(protected)/admin/settings/setting-tracking/update/[id]/page.tsx create mode 100644 components/form/media-tracking/setting-tracking-detail-form.tsx create mode 100644 components/form/media-tracking/setting-tracking-form.tsx create mode 100644 components/form/media-tracking/setting-tracking-update-form.tsx diff --git a/app/[locale]/(protected)/admin/settings/setting-tracking/component/column.tsx b/app/[locale]/(protected)/admin/settings/setting-tracking/component/column.tsx index 09ef5cd2..9fd2e03b 100644 --- a/app/[locale]/(protected)/admin/settings/setting-tracking/component/column.tsx +++ b/app/[locale]/(protected)/admin/settings/setting-tracking/component/column.tsx @@ -122,10 +122,22 @@ const useTableColumns = () => { - - - - + + + + View + + + + + + Edit + + handleDeleteMedia(row.original.id)} className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none" diff --git a/app/[locale]/(protected)/admin/settings/setting-tracking/component/create.tsx b/app/[locale]/(protected)/admin/settings/setting-tracking/component/create.tsx index a378f474..90544ee2 100644 --- a/app/[locale]/(protected)/admin/settings/setting-tracking/component/create.tsx +++ b/app/[locale]/(protected)/admin/settings/setting-tracking/component/create.tsx @@ -1,141 +1,141 @@ -"use client"; +// "use client"; -import { Button } from "@/components/ui/button"; -import { - Dialog, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; -import { z } from "zod"; -import { useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { - Form, - FormControl, - FormDescription, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form"; -import { useRouter } from "@/i18n/routing"; -import { Input } from "@/components/ui/input"; -import { Checkbox } from "@/components/ui/checkbox"; -import { getUserRoles, postCategory } from "@/service/settings/settings"; -import { Fragment, useEffect, useState } from "react"; -import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; -import { Icon } from "@iconify/react/dist/iconify.js"; -import { Textarea } from "@/components/ui/textarea"; -import { close, error, loading } from "@/config/swal"; -import { useToast } from "@/components/ui/use-toast"; -import { stringify } from "querystring"; -import { useDropzone } from "react-dropzone"; -import { CloudUpload } from "lucide-react"; -import Image from "next/image"; -import { Upload } from "tus-js-client"; -import { getCookiesDecrypt } from "@/lib/utils"; -import Cookies from "js-cookie"; -import { useTranslations } from "next-intl"; +// import { Button } from "@/components/ui/button"; +// import { +// Dialog, +// DialogContent, +// DialogFooter, +// DialogHeader, +// DialogTitle, +// DialogTrigger, +// } from "@/components/ui/dialog"; +// import { z } from "zod"; +// import { useForm } from "react-hook-form"; +// import { zodResolver } from "@hookform/resolvers/zod"; +// import { +// Form, +// FormControl, +// FormDescription, +// FormField, +// FormItem, +// FormLabel, +// FormMessage, +// } from "@/components/ui/form"; +// import { useRouter } from "@/i18n/routing"; +// import { Input } from "@/components/ui/input"; +// import { Checkbox } from "@/components/ui/checkbox"; +// import { getUserRoles, postCategory } from "@/service/settings/settings"; +// import { Fragment, useEffect, useState } from "react"; +// import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; +// import { Icon } from "@iconify/react/dist/iconify.js"; +// import { Textarea } from "@/components/ui/textarea"; +// import { close, error, loading } from "@/config/swal"; +// import { useToast } from "@/components/ui/use-toast"; +// import { stringify } from "querystring"; +// import { useDropzone } from "react-dropzone"; +// import { CloudUpload } from "lucide-react"; +// import Image from "next/image"; +// import { Upload } from "tus-js-client"; +// import { getCookiesDecrypt } from "@/lib/utils"; +// import Cookies from "js-cookie"; +// import { useTranslations } from "next-intl"; -const wilayahList = [ - { id: "mabes", label: "Mabes" }, - { id: "polda", label: "Polda" }, - { id: "satker", label: "Satker" }, -]; +// const wilayahList = [ +// { id: "mabes", label: "Mabes" }, +// { id: "polda", label: "Polda" }, +// { id: "satker", label: "Satker" }, +// ]; -const jumlahList = [5, 10, 15, 20, 25, 30]; +// const jumlahList = [5, 10, 15, 20, 25, 30]; -export default function CreateSettingTracking() { - const t = useTranslations("Menu"); - const [isOpen, setIsOpen] = useState(false); +// export default function CreateSettingTracking() { +// const t = useTranslations("Menu"); +// const [isOpen, setIsOpen] = useState(false); - const form = useForm({ - defaultValues: { - wilayah: [] as string[], - jumlah: [] as number[], - }, - }); +// const form = useForm({ +// defaultValues: { +// wilayah: [] as string[], +// jumlah: [] as number[], +// }, +// }); - const onSubmit = (values: any) => { - console.log("Submitted values:", values); - setIsOpen(false); - }; +// const onSubmit = (values: any) => { +// console.log("Submitted values:", values); +// setIsOpen(false); +// }; - return ( - - - - +// return ( +// +// +// +// - - - Add Setting Tracking Berita Harian - +// +// +// Add Setting Tracking Berita Harian +// -
- - {/* Wilayah */} - ( - - Wilayah -
- {wilayahList.map((item) => ( -
- { - const updated = checked - ? [...field.value, item.id] - : field.value.filter((val) => val !== item.id); - field.onChange(updated); - }} - /> - -
- ))} -
-
- )} - /> +// +// +// {/* Wilayah */} +// ( +// +// Wilayah +//
+// {wilayahList.map((item) => ( +//
+// { +// const updated = checked +// ? [...field.value, item.id] +// : field.value.filter((val) => val !== item.id); +// field.onChange(updated); +// }} +// /> +// +//
+// ))} +//
+//
+// )} +// /> - ( - - Jumlah Tracking Berita Harian -
- {jumlahList.map((num) => ( -
- { - const updated = checked - ? [...field.value, num] - : field.value.filter((val) => val !== num); - field.onChange(updated); - }} - /> - -
- ))} -
-
- )} - /> +// ( +// +// Jumlah Tracking Berita Harian +//
+// {jumlahList.map((num) => ( +//
+// { +// const updated = checked +// ? [...field.value, num] +// : field.value.filter((val) => val !== num); +// field.onChange(updated); +// }} +// /> +// +//
+// ))} +//
+//
+// )} +// /> - - - - - -
-
- ); -} +// +// +// +// +// +// +//
+// ); +// } diff --git a/app/[locale]/(protected)/admin/settings/setting-tracking/component/table.tsx b/app/[locale]/(protected)/admin/settings/setting-tracking/component/table.tsx index 82e8f34f..b6978627 100644 --- a/app/[locale]/(protected)/admin/settings/setting-tracking/component/table.tsx +++ b/app/[locale]/(protected)/admin/settings/setting-tracking/component/table.tsx @@ -49,8 +49,8 @@ import { PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; -import CreateSettingTracking from "./create"; import useTableColumns from "./column"; +import { UploadIcon } from "lucide-react"; const AdminSettingTrackingTable = () => { const router = useRouter(); @@ -190,7 +190,15 @@ const AdminSettingTrackingTable = () => { return (
- + {/* */} +
+ + + +
+
+ + + + + ); +} diff --git a/components/form/media-tracking/setting-tracking-form.tsx b/components/form/media-tracking/setting-tracking-form.tsx new file mode 100644 index 00000000..5ec57285 --- /dev/null +++ b/components/form/media-tracking/setting-tracking-form.tsx @@ -0,0 +1,110 @@ +"use client"; + +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { z } from "zod"; +import { Controller, useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { Checkbox } from "@/components/ui/checkbox"; +import { Fragment, useEffect, useState } from "react"; +import { useTranslations } from "next-intl"; +import { Card } from "@/components/ui/card"; + +const wilayahList = [ + { id: "mabes", label: "Mabes" }, + { id: "polda", label: "Polda" }, + { id: "satker", label: "Satker" }, +]; + +const jumlahList = [5, 10, 15, 20, 25, 30]; + +export default function CreateSettingTracking() { + const t = useTranslations("Menu"); + const [isOpen, setIsOpen] = useState(false); + + const form = useForm({ + defaultValues: { + wilayah: [] as string[], + jumlah: [] as number[], + }, + }); + + const onSubmit = (values: any) => { + console.log("Submitted values:", values); + setIsOpen(false); + }; + + return ( + <> + +
+ + {/* Wilayah */} + ( + + Wilayah +
+ {wilayahList.map((item) => ( +
+ { + const updated = checked + ? [...field.value, item.id] + : field.value.filter((val) => val !== item.id); + field.onChange(updated); + }} + /> + +
+ ))} +
+
+ )} + /> + + ( + + Jumlah Tracking Berita Harian +
+ +
+
+ )} + /> +
+ +
+ + +
+ + ); +} diff --git a/components/form/media-tracking/setting-tracking-update-form.tsx b/components/form/media-tracking/setting-tracking-update-form.tsx new file mode 100644 index 00000000..621bf378 --- /dev/null +++ b/components/form/media-tracking/setting-tracking-update-form.tsx @@ -0,0 +1,110 @@ +"use client"; + +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { z } from "zod"; +import { Controller, useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { Checkbox } from "@/components/ui/checkbox"; +import { Fragment, useEffect, useState } from "react"; +import { useTranslations } from "next-intl"; +import { Card } from "@/components/ui/card"; + +const wilayahList = [ + { id: "mabes", label: "Mabes" }, + { id: "polda", label: "Polda" }, + { id: "satker", label: "Satker" }, +]; + +const jumlahList = [5, 10, 15, 20, 25, 30]; + +export default function UpdateSettingTracking() { + const t = useTranslations("Menu"); + const [isOpen, setIsOpen] = useState(false); + + const form = useForm({ + defaultValues: { + wilayah: [] as string[], + jumlah: [] as number[], + }, + }); + + const onSubmit = (values: any) => { + console.log("Submitted values:", values); + setIsOpen(false); + }; + + return ( + <> + +
+ + {/* Wilayah */} + ( + + Wilayah +
+ {wilayahList.map((item) => ( +
+ { + const updated = checked + ? [...field.value, item.id] + : field.value.filter((val) => val !== item.id); + field.onChange(updated); + }} + /> + +
+ ))} +
+
+ )} + /> + + ( + + Jumlah Tracking Berita Harian +
+ +
+
+ )} + /> +
+ +
+ + +
+ + ); +} diff --git a/components/form/ticketing/info-lainnya-types.ts b/components/form/ticketing/info-lainnya-types.ts index 51ff1472..108d6d6c 100644 --- a/components/form/ticketing/info-lainnya-types.ts +++ b/components/form/ticketing/info-lainnya-types.ts @@ -1,4 +1,6 @@ export type DetailTicket = { + title: string; + description: string; commentFromUserId: string; assignedTeams: string; message: string; @@ -19,7 +21,10 @@ export type DetailTicket = { feedUrl: string; recommendationName: string; link: string; - uploadFiles?: string; + uploadFiles?: { + fileUrl: string; + fileName: string; + }[]; description: string; }; }; diff --git a/components/form/ticketing/info-lainnya.tsx b/components/form/ticketing/info-lainnya.tsx index 9fcf5e79..0af6a1f8 100644 --- a/components/form/ticketing/info-lainnya.tsx +++ b/components/form/ticketing/info-lainnya.tsx @@ -1,4 +1,3 @@ -// InfoLainnyaModal.tsx import { Dialog, DialogContent, @@ -6,6 +5,7 @@ import { DialogTitle, } from "@/components/ui/dialog"; import { DetailTicket } from "./info-lainnya-types"; +import { useState } from "react"; interface InfoLainnyaModalProps { open: boolean; @@ -18,6 +18,34 @@ export default function InfoLainnyaModal({ onClose, data, }: InfoLainnyaModalProps) { + const files = data?.uploadFiles || []; + const [currentIndex, setCurrentIndex] = useState(0); + + const handlePrev = () => { + setCurrentIndex((prev) => (prev > 0 ? prev - 1 : prev)); + }; + + const handleNext = () => { + setCurrentIndex((prev) => (prev < files.length - 1 ? prev + 1 : prev)); + }; + + const currentFile = files[currentIndex]; + const isImage = (fileUrl: string) => + /\.(jpeg|jpg|png|gif|bmp|webp)$/i.test(fileUrl.toLowerCase()); + + const getIframeUrl = (fileUrl: string): string => { + const lower = fileUrl.toLowerCase(); + + // Dokumen ditampilkan melalui Google Docs Viewer + if (/\.(pdf|doc|docx|xls|xlsx|ppt|pptx)$/i.test(lower)) { + return `https://docs.google.com/viewer?url=${encodeURIComponent( + fileUrl + )}&embedded=true`; + } + + return fileUrl; + }; + return ( @@ -41,11 +69,11 @@ export default function InfoLainnyaModal({
:{data?.recommendationName}
Link Pendukung
-
+ - {data?.uploadFiles && ( + {files.length > 0 && ( <> -
Lampiran
-
- Lampiran +
Lampiran
+
+ {isImage(currentFile?.fileUrl || "") ? ( + {`Lampiran + ) : ( +