feat:update task,content,blog,curated content,contest,communication

This commit is contained in:
Anang Yusman 2025-04-09 20:19:36 +08:00
parent aff407f3ce
commit 26b13b0129
37 changed files with 385 additions and 202 deletions

View File

@ -594,7 +594,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => {
<DialogTrigger asChild> <DialogTrigger asChild>
{roleId === 3 && userLevelId === 216 ? ( {roleId === 3 && userLevelId === 216 ? (
<Button className="dark:bg-background dark:text-foreground w-full"> <Button className="dark:bg-background dark:text-foreground w-full">
<Book className="w-4 h-4" /> <Book size={15} className="w-4 h-4 mr-3" />
{t("bag-pa-monitoring-results")} {t("bag-pa-monitoring-results")}
</Button> </Button>
) : null} ) : null}

View File

@ -186,7 +186,7 @@ const BlogTable = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/contributor/blog/create"}> <Link href={"/contributor/blog/create"}>
<Button fullWidth color="primary"> <Button fullWidth color="primary">
<Plus className="w-6 h-6 me-1.5" /> <Plus size={18} className=" me-1.5" />
{t("create-indeks")} {t("create-indeks")}
</Button> </Button>
</Link> </Link>

View File

@ -63,7 +63,7 @@ const ReactTableAudioPage = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/contributor/content/audio/create"}> <Link href={"/contributor/content/audio/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon /> <UploadIcon size={18} className="mr-2" />
{t("create-audio")} {t("create-audio")}
</Button> </Button>
</Link> </Link>

View File

@ -63,7 +63,7 @@ const ReactTableImagePage = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/contributor/content/image/create"}> <Link href={"/contributor/content/image/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon /> <UploadIcon size={18} className="mr-2" />
{t("create-image")} {t("create-image")}
</Button> </Button>
</Link> </Link>

View File

@ -66,7 +66,7 @@ const ReactTableTeksPage = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/contributor/content/teks/create"}> <Link href={"/contributor/content/teks/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon /> <UploadIcon size={18} className="mr-2" />
{t("create-text")} {t("create-text")}
</Button> </Button>
</Link> </Link>

View File

@ -64,7 +64,7 @@ const ReactTableVideoPage = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/contributor/content/video/create"}> <Link href={"/contributor/content/video/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon /> <UploadIcon size={18} className="mr-2" />
{t("create-video")} {t("create-video")}
</Button> </Button>
</Link> </Link>

View File

@ -132,7 +132,7 @@ const EventTable = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/contributor/schedule/event/create"}> <Link href={"/contributor/schedule/event/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon /> <UploadIcon size={18} className="mr-2" />
{t("create-schedule")} {t("create-schedule")}
</Button> </Button>
</Link> </Link>

View File

@ -145,7 +145,7 @@ const PressConferenceTable = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/contributor/schedule/press-conference/create"}> <Link href={"/contributor/schedule/press-conference/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon /> <UploadIcon size={18} className="mr-2" />
{t("create-schedule")} {t("create-schedule")}
</Button> </Button>
</Link> </Link>

View File

@ -146,7 +146,7 @@ const PressReleaseTable = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/contributor/schedule/press-release/create"}> <Link href={"/contributor/schedule/press-release/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon /> <UploadIcon size={18} className="mr-2" />
{t("create-schedule")} {t("create-schedule")}
</Button> </Button>
</Link> </Link>

View File

@ -34,7 +34,7 @@ const TaskPage = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/contributor/task/create"}> <Link href={"/contributor/task/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon /> <UploadIcon size={18} className="mr-2" />
{t("create-task")} {t("create-task")}
</Button> </Button>
</Link> </Link>

View File

@ -24,7 +24,7 @@ const CommunicationPage = () => {
{tab === "Pertanyaan Internal" && ( {tab === "Pertanyaan Internal" && (
<Link href="/shared/communication/internal/create"> <Link href="/shared/communication/internal/create">
<Button color="primary" size="md"> <Button color="primary" size="md">
<PlusIcon /> <PlusIcon size={18} className="mr-2" />
{t("new-question")} {t("new-question")}
</Button> </Button>
</Link> </Link>
@ -32,7 +32,7 @@ const CommunicationPage = () => {
{tab === "Kolaborasi" && ( {tab === "Kolaborasi" && (
<Link href="/shared/communication/collaboration/create"> <Link href="/shared/communication/collaboration/create">
<Button color="primary" size="md"> <Button color="primary" size="md">
<PlusIcon /> <PlusIcon size={18} className="mr-2" />
{t("new-collaboration")} {t("new-collaboration")}
</Button> </Button>
</Link> </Link>

View File

@ -31,7 +31,7 @@ const ContestPage = () => {
<div className="flex-none"> <div className="flex-none">
<Link href={"/shared/contest/create"}> <Link href={"/shared/contest/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon /> <UploadIcon size={18} className="mr-2" />
{t("create-contest")} {t("create-contest")}
</Button> </Button>
</Link> </Link>

View File

@ -113,19 +113,18 @@ const CuratedContentPage = () => {
</div> </div>
</div> </div>
<div className="ml-5 pb-3"> <div className="ml-5 pb-3">
<Label>Audio Visual</Label>
<div className="px-5 my-5"> <div className="px-5 my-5">
<VideoSliderPage /> <VideoSliderPage />
</div> </div>
<Label>Audio</Label>
<div className="px-5 my-5"> <div className="px-5 my-5">
<AudioSliderPage /> <AudioSliderPage />
</div> </div>
<Label>Foto</Label>
<div className="px-5 my-5"> <div className="px-5 my-5">
<ImageSliderPage /> <ImageSliderPage />
</div> </div>
<Label>Teks</Label>
<div className="px-5 my-5"> <div className="px-5 my-5">
<TeksSliderPage /> <TeksSliderPage />
</div> </div>

View File

@ -26,6 +26,7 @@ import {
SelectItem, SelectItem,
} from "@radix-ui/react-select"; } from "@radix-ui/react-select";
import { SelectGroup } from "@/components/ui/select"; import { SelectGroup } from "@/components/ui/select";
import dynamic from "next/dynamic";
const taskSchema = z.object({ const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -43,6 +44,13 @@ interface Option {
userLevelId: string; userLevelId: string;
} }
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function FormCollaboration() { export default function FormCollaboration() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
@ -257,12 +265,7 @@ export default function FormCollaboration() {
control={control} control={control}
name="naration" name="naration"
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<JoditEditor <CustomEditor onChange={onChange} initialData={value} />
ref={editor}
value={value}
onChange={onChange}
className="dark:text-black"
/>
)} )}
/> />
{errors.naration?.message && ( {errors.naration?.message && (

View File

@ -26,6 +26,7 @@ import {
SelectItem, SelectItem,
} from "@radix-ui/react-select"; } from "@radix-ui/react-select";
import { SelectGroup } from "@/components/ui/select"; import { SelectGroup } from "@/components/ui/select";
import dynamic from "next/dynamic";
const taskSchema = z.object({ const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -43,6 +44,13 @@ interface Option {
userLevelId: string; userLevelId: string;
} }
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function FormInternal() { export default function FormInternal() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
@ -253,12 +261,7 @@ export default function FormInternal() {
control={control} control={control}
name="naration" name="naration"
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<JoditEditor <CustomEditor onChange={onChange} initialData={value} />
ref={editor}
value={value}
onChange={onChange}
className="dark:text-black"
/>
)} )}
/> />
{errors.naration?.message && ( {errors.naration?.message && (

View File

@ -49,6 +49,7 @@ import { error } from "@/lib/swal";
import { getCsrfToken } from "@/service/auth"; import { getCsrfToken } from "@/service/auth";
import { Upload } from "tus-js-client"; import { Upload } from "tus-js-client";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import dynamic from "next/dynamic";
const audioSchema = z.object({ const audioSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -88,6 +89,13 @@ type Option = {
name: string; name: string;
}; };
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function FormAudioUpdate() { export default function FormAudioUpdate() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
@ -646,11 +654,9 @@ export default function FormAudioUpdate() {
control={control} control={control}
name="description" name="description"
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<JoditEditor <CustomEditor
ref={editor}
value={detail?.description}
onChange={onChange} onChange={onChange}
className="dark:text-black" initialData={detail?.description || value}
/> />
)} )}
/> />

View File

@ -815,7 +815,7 @@ export default function FormConvertSPIT() {
<Label className="text-xl">{t("file-placement")}</Label> <Label className="text-xl">{t("file-placement")}</Label>
</div> </div>
{files?.length > 1 && ( {files?.length > 1 && (
<div className="flex flex-wrap gap-2 mt-2 justify-center"> <div className="flex flex-wrap gap-2 mt-2 justify-end mr-24 pr-2">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Checkbox <Checkbox
id="all-content" id="all-content"
@ -971,7 +971,7 @@ export default function FormConvertSPIT() {
<Input <Input
size="md" size="md"
type="text" type="text"
defaultValue={detail?.contentCreator} value={detail?.contentCreator}
onChange={field.onChange} onChange={field.onChange}
placeholder="Enter Title" placeholder="Enter Title"
/> />

View File

@ -45,6 +45,7 @@ import { error, loading } from "@/lib/swal";
import { Upload } from "tus-js-client"; import { Upload } from "tus-js-client";
import { getCsrfToken } from "@/service/auth"; import { getCsrfToken } from "@/service/auth";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import dynamic from "next/dynamic";
const teksSchema = z.object({ const teksSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -88,6 +89,13 @@ type Option = {
label: string; label: string;
}; };
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function FormTeksUpdate() { export default function FormTeksUpdate() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
@ -610,11 +618,9 @@ export default function FormTeksUpdate() {
control={control} control={control}
name="description" name="description"
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<JoditEditor <CustomEditor
ref={editor}
value={detail?.description}
onChange={onChange} onChange={onChange}
className="dark:text-black" initialData={detail?.description || value}
/> />
)} )}
/> />

View File

@ -56,6 +56,7 @@ import { Upload } from "tus-js-client";
import { getCsrfToken } from "@/service/auth"; import { getCsrfToken } from "@/service/auth";
import { error, loading } from "@/lib/swal"; import { error, loading } from "@/lib/swal";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import dynamic from "next/dynamic";
const videoSchema = z.object({ const videoSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -95,6 +96,13 @@ type Option = {
name: string; name: string;
}; };
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function FormVideoUpdate() { export default function FormVideoUpdate() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
@ -665,11 +673,9 @@ export default function FormVideoUpdate() {
control={control} control={control}
name="description" name="description"
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<JoditEditor <CustomEditor
ref={editor}
value={detail?.description}
onChange={onChange} onChange={onChange}
className="dark:text-black" initialData={detail?.description || value}
/> />
)} )}
/> />

View File

@ -33,7 +33,7 @@ import {
PopoverTrigger, PopoverTrigger,
} from "@/components/ui/popover"; } from "@/components/ui/popover";
import { cn, getCookiesDecrypt } from "@/lib/utils"; import { cn, getCookiesDecrypt } from "@/lib/utils";
import { CalendarIcon, ChevronDown, ChevronUp } from "lucide-react"; import { CalendarIcon, ChevronDown, ChevronUp, Trash2 } from "lucide-react";
import { format, parseISO } from "date-fns"; import { format, parseISO } from "date-fns";
import { Calendar } from "@/components/ui/calendar"; import { Calendar } from "@/components/ui/calendar";
import { DateRange } from "react-day-picker"; import { DateRange } from "react-day-picker";
@ -898,10 +898,10 @@ export default function FormContestDetail() {
{isRecording && <p>Recording... {timer} seconds remaining</p>}{" "} {isRecording && <p>Recording... {timer} seconds remaining</p>}{" "}
{/* Display remaining time */} {/* Display remaining time */}
<div className="mt-4"> <div className="mt-4">
<h2 className="text-lg font-bold">Link Berita</h2> <Label className="">Link Berita</Label>
{links.map((link, index) => ( {links.map((link, index) => (
<div key={index} className="flex items-center gap-2 mt-2"> <div key={index} className="flex items-center gap-2 mt-2">
<input <Input
type="url" type="url"
className="border rounded p-2 w-full" className="border rounded p-2 w-full"
placeholder={`Masukkan link berita ${index + 1}`} placeholder={`Masukkan link berita ${index + 1}`}
@ -916,18 +916,19 @@ export default function FormContestDetail() {
className="bg-red-500 text-white px-3 py-1 rounded" className="bg-red-500 text-white px-3 py-1 rounded"
onClick={() => handleRemoveRow(index)} onClick={() => handleRemoveRow(index)}
> >
Hapus <Trash2 className="h-4 w-4" />
</button> </button>
)} )}
</div> </div>
))} ))}
<button <Button
type="button" type="button"
size="md"
className="mt-2 bg-blue-500 text-white px-4 py-2 rounded" className="mt-2 bg-blue-500 text-white px-4 py-2 rounded"
onClick={handleAddRow} onClick={handleAddRow}
> >
Tambah Link Tambah Link
</button> </Button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -38,6 +38,7 @@ import {
import { AlertDialogHeader } from "@/components/ui/alert-dialog"; import { AlertDialogHeader } from "@/components/ui/alert-dialog";
import { Description } from "@radix-ui/react-toast"; import { Description } from "@radix-ui/react-toast";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import dynamic from "next/dynamic";
const taskSchema = z.object({ const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -62,6 +63,13 @@ export type mediahubDetail = {
is_active: string; is_active: string;
}; };
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function PublishMediahub() { export default function PublishMediahub() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
@ -503,11 +511,9 @@ export default function PublishMediahub() {
control={control} control={control}
name="description" name="description"
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<JoditEditor <CustomEditor
ref={editor}
value={detail?.description}
onChange={onChange} onChange={onChange}
className="dark:text-black" initialData={detail?.description || value}
/> />
)} )}
/> />

View File

@ -34,6 +34,7 @@ import {
DialogTrigger, DialogTrigger,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import dynamic from "next/dynamic";
const taskSchema = z.object({ const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -56,6 +57,13 @@ export type medsosDetail = {
is_active: string; is_active: string;
}; };
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function PublishMedsos() { export default function PublishMedsos() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
@ -496,11 +504,9 @@ export default function PublishMedsos() {
control={control} control={control}
name="description" name="description"
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<JoditEditor <CustomEditor
ref={editor}
value={detail?.description}
onChange={onChange} onChange={onChange}
className="dark:text-black" initialData={detail?.description || value}
/> />
)} )}
/> />

View File

@ -237,7 +237,7 @@ export default function FormEventDetail() {
)} )}
<div className="flex flex-col lg:flex-row mt-6 items-start lg:items-center justify-between"> <div className="flex flex-col lg:flex-row mt-6 items-start lg:items-center justify-between">
<div className="flex flex-col"> <div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label> <Label className="mr-3 mb-1">Tanggal</Label>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
@ -245,11 +245,11 @@ export default function FormEventDetail() {
id="date" id="date"
variant={"outline"} variant={"outline"}
className={cn( className={cn(
"w-[280px] lg:w-[300px] justify-start text-left font-normal", "w-[280px] lg:w-[250px] justify-start text-left font-normal px-0 md:px-0 lg:px-4",
!date && "text-muted-foreground" !date && "text-muted-foreground"
)} )}
> >
<CalendarIcon /> <CalendarIcon size={15} className="mr-3" />
{date?.from ? ( {date?.from ? (
date.to ? ( date.to ? (
<> <>
@ -276,7 +276,7 @@ export default function FormEventDetail() {
</PopoverContent> </PopoverContent>
</Popover> </Popover>
</div> </div>
<div> <div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label> <Label htmlFor="title">Rentang Waktu</Label>
<div> <div>
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
@ -326,7 +326,7 @@ export default function FormEventDetail() {
DI SAMPAIKAN OLEH DI SAMPAIKAN OLEH
</p> </p>
<div className="flex flex-col "> <div className="flex flex-col ">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label> <Label>Nama Pangkat</Label>
<Controller <Controller
control={control} control={control}
@ -349,7 +349,7 @@ export default function FormEventDetail() {
</div> </div>
</div> </div>
<div className="flex flex-col my-3"> <div className="flex flex-col my-3">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label> <Label>Nama Lengkap</Label>
<Controller <Controller
control={control} control={control}

View File

@ -234,7 +234,7 @@ export default function FormEvent() {
)} )}
<div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between"> <div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between">
<div className="flex flex-col "> <div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label> <Label className="mr-3 mb-1">Tanggal</Label>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
@ -242,11 +242,11 @@ export default function FormEvent() {
id="date" id="date"
variant={"outline"} variant={"outline"}
className={cn( className={cn(
"w-[280px] lg:w-[300px] justify-start text-left font-normal", "w-[280px] lg:w-[250px] justify-start text-left font-normal px-0 md:px-0 lg:px-4",
!date && "text-muted-foreground" !date && "text-muted-foreground"
)} )}
> >
<CalendarIcon /> <CalendarIcon size={15} className="mr-3" />
{date?.from ? ( {date?.from ? (
date.to ? ( date.to ? (
<> <>
@ -273,7 +273,7 @@ export default function FormEvent() {
</PopoverContent> </PopoverContent>
</Popover> </Popover>
</div> </div>
<div> <div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label> <Label htmlFor="title">Rentang Waktu</Label>
<div className=""> <div className="">
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
@ -321,7 +321,7 @@ export default function FormEvent() {
</div> </div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p> <p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col "> <div className="flex flex-col ">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label> <Label>Nama Pangkat</Label>
<Controller <Controller
control={control} control={control}
@ -344,7 +344,7 @@ export default function FormEvent() {
</div> </div>
</div> </div>
<div className="flex flex-col my-3"> <div className="flex flex-col my-3">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label> <Label>Nama Lengkap</Label>
<Controller <Controller
control={control} control={control}

View File

@ -250,7 +250,7 @@ export default function FormEventUpdate() {
)} )}
<div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between"> <div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between">
<div className="flex flex-col"> <div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label> <Label className="mr-3 mb-1">Tanggal</Label>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
@ -258,11 +258,11 @@ export default function FormEventUpdate() {
id="date" id="date"
variant={"outline"} variant={"outline"}
className={cn( className={cn(
"w-[280px] lg:w-[300px] justify-start text-left font-normal", "w-[280px] lg:w-[250px] justify-start text-left font-normal px-0 md:px-0 lg:px-4",
!date && "text-muted-foreground" !date && "text-muted-foreground"
)} )}
> >
<CalendarIcon /> <CalendarIcon size={15} className="mr-3" />
{date?.from ? ( {date?.from ? (
date.to ? ( date.to ? (
<> <>
@ -289,7 +289,7 @@ export default function FormEventUpdate() {
</PopoverContent> </PopoverContent>
</Popover> </Popover>
</div> </div>
<div> <div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label> <Label htmlFor="title">Rentang Waktu</Label>
<div> <div>
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
@ -337,7 +337,7 @@ export default function FormEventUpdate() {
</div> </div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p> <p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col "> <div className="flex flex-col ">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label> <Label>Nama Pangkat</Label>
<Controller <Controller
control={control} control={control}
@ -360,7 +360,7 @@ export default function FormEventUpdate() {
</div> </div>
</div> </div>
<div className="flex flex-col my-3"> <div className="flex flex-col my-3">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label> <Label>Nama Lengkap</Label>
<Controller <Controller
control={control} control={control}

View File

@ -247,7 +247,7 @@ export default function FormDetailPressRillis() {
)} )}
<div className="flex flex-col lg:flex-row mt-6 items-start lg:items-center justify-between"> <div className="flex flex-col lg:flex-row mt-6 items-start lg:items-center justify-between">
<div className="flex flex-col"> <div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label> <Label className="mr-3 mb-1">Tanggal</Label>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
@ -255,11 +255,11 @@ export default function FormDetailPressRillis() {
id="date" id="date"
variant={"outline"} variant={"outline"}
className={cn( className={cn(
"w-[280px] lg:w-[300px] justify-start text-left font-normal", "w-[280px] lg:w-[250px] justify-start text-left font-normal px-0 md:px-0 lg:px-4",
!date && "text-muted-foreground" !date && "text-muted-foreground"
)} )}
> >
<CalendarIcon /> <CalendarIcon size={15} className="mr-3" />
{date?.from ? ( {date?.from ? (
date.to ? ( date.to ? (
<> <>
@ -286,7 +286,7 @@ export default function FormDetailPressRillis() {
</PopoverContent> </PopoverContent>
</Popover> </Popover>
</div> </div>
<div> <div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label> <Label htmlFor="title">Rentang Waktu</Label>
<div> <div>
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
@ -332,7 +332,7 @@ export default function FormDetailPressRillis() {
{errors.location?.message} {errors.location?.message}
</div> </div>
</div> </div>
<div className="mt-6"> <div className="mt-6 space-y-2">
<Label>Invitation</Label> <Label>Invitation</Label>
<Select onValueChange={setSelectedTarget}> <Select onValueChange={setSelectedTarget}>
<SelectTrigger size="md"> <SelectTrigger size="md">
@ -353,7 +353,7 @@ export default function FormDetailPressRillis() {
DI SAMPAIKAN OLEH DI SAMPAIKAN OLEH
</p> </p>
<div className="flex flex-col "> <div className="flex flex-col ">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label> <Label>Nama Pangkat</Label>
<Controller <Controller
control={control} control={control}
@ -376,7 +376,7 @@ export default function FormDetailPressRillis() {
</div> </div>
</div> </div>
<div className="flex flex-col my-3"> <div className="flex flex-col my-3">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label> <Label>Nama Lengkap</Label>
<Controller <Controller
control={control} control={control}

View File

@ -257,7 +257,7 @@ export default function FormUpdatePressRelease() {
)} )}
<div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between"> <div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between">
<div className="flex flex-col"> <div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label> <Label className="mr-3 mb-1">Tanggal</Label>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
@ -265,11 +265,11 @@ export default function FormUpdatePressRelease() {
id="date" id="date"
variant={"outline"} variant={"outline"}
className={cn( className={cn(
"w-[280px] lg:w-[300px] justify-start text-left font-normal", "w-[280px] lg:w-[250px] justify-start text-left font-normal px-0 md:px-0 lg:px-4",
!date && "text-muted-foreground" !date && "text-muted-foreground"
)} )}
> >
<CalendarIcon /> <CalendarIcon size={15} className="mr-3" />
{date?.from ? ( {date?.from ? (
date.to ? ( date.to ? (
<> <>
@ -296,7 +296,7 @@ export default function FormUpdatePressRelease() {
</PopoverContent> </PopoverContent>
</Popover> </Popover>
</div> </div>
<div> <div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label> <Label htmlFor="title">Rentang Waktu</Label>
<div> <div>
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
@ -342,7 +342,7 @@ export default function FormUpdatePressRelease() {
{errors.location?.message} {errors.location?.message}
</div> </div>
</div> </div>
<div className="mt-5"> <div className="mt-5 space-y-2">
<Label>Invitation</Label> <Label>Invitation</Label>
<Select onValueChange={setSelectedTarget}> <Select onValueChange={setSelectedTarget}>
<SelectTrigger size="md"> <SelectTrigger size="md">
@ -361,7 +361,7 @@ export default function FormUpdatePressRelease() {
</div> </div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p> <p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col "> <div className="flex flex-col ">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label> <Label>Nama Pangkat</Label>
<Controller <Controller
control={control} control={control}
@ -384,7 +384,7 @@ export default function FormUpdatePressRelease() {
</div> </div>
</div> </div>
<div className="flex flex-col my-3"> <div className="flex flex-col my-3">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label> <Label>Nama Lengkap</Label>
<Controller <Controller
control={control} control={control}

View File

@ -234,7 +234,7 @@ export default function FormPressRelease() {
)} )}
<div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between"> <div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between">
<div className="flex flex-col "> <div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label> <Label className="mr-3 mb-1">Tanggal</Label>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
@ -242,11 +242,11 @@ export default function FormPressRelease() {
id="date" id="date"
variant={"outline"} variant={"outline"}
className={cn( className={cn(
"w-[280px] lg:w-[300px] justify-start text-left font-normal", "w-[280px] lg:w-[250px] justify-start text-left font-normal px-0 md:px-0 lg:px-4",
!date && "text-muted-foreground" !date && "text-muted-foreground"
)} )}
> >
<CalendarIcon /> <CalendarIcon size={15} className="mr-3" />
{date?.from ? ( {date?.from ? (
date.to ? ( date.to ? (
<> <>
@ -273,7 +273,7 @@ export default function FormPressRelease() {
</PopoverContent> </PopoverContent>
</Popover> </Popover>
</div> </div>
<div> <div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label> <Label htmlFor="title">Rentang Waktu</Label>
<div className=""> <div className="">
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
@ -319,7 +319,7 @@ export default function FormPressRelease() {
{errors.location?.message} {errors.location?.message}
</div> </div>
</div> </div>
<div className="mt-5"> <div className="mt-5 space-y-2">
<Label>Invitation</Label> <Label>Invitation</Label>
<Select onValueChange={setSelectedTarget}> <Select onValueChange={setSelectedTarget}>
<SelectTrigger size="md"> <SelectTrigger size="md">
@ -338,7 +338,7 @@ export default function FormPressRelease() {
</div> </div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p> <p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col "> <div className="flex flex-col ">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label> <Label>Nama Pangkat</Label>
<Controller <Controller
control={control} control={control}
@ -361,7 +361,7 @@ export default function FormPressRelease() {
</div> </div>
</div> </div>
<div className="flex flex-col my-3"> <div className="flex flex-col my-3">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label> <Label>Nama Lengkap</Label>
<Controller <Controller
control={control} control={control}

View File

@ -194,7 +194,7 @@ export default function FormDetailPressConference() {
)} )}
<div className="flex flex-col lg:flex-row items-start lg:items-center justify-between mt-6"> <div className="flex flex-col lg:flex-row items-start lg:items-center justify-between mt-6">
<div className="flex flex-col"> <div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label> <Label className="mr-3 mb-1">Tanggal</Label>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
@ -202,11 +202,11 @@ export default function FormDetailPressConference() {
id="date" id="date"
variant={"outline"} variant={"outline"}
className={cn( className={cn(
"w-[280px] lg:w-[300px] justify-start text-left font-normal", "w-[280px] lg:w-[250px] justify-start text-left font-normal px-0 md:px-0 lg:px-4",
!date && "text-muted-foreground" !date && "text-muted-foreground"
)} )}
> >
<CalendarIcon /> <CalendarIcon size={15} className="mr-3" />
{date?.from ? ( {date?.from ? (
date.to ? ( date.to ? (
<> <>
@ -233,7 +233,7 @@ export default function FormDetailPressConference() {
</PopoverContent> </PopoverContent>
</Popover> </Popover>
</div> </div>
<div> <div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label> <Label htmlFor="title">Rentang Waktu</Label>
<div> <div>
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
@ -283,7 +283,7 @@ export default function FormDetailPressConference() {
DI SAMPAIKAN OLEH DI SAMPAIKAN OLEH
</p> </p>
<div className="flex flex-col "> <div className="flex flex-col ">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label> <Label>Nama Pangkat</Label>
<Controller <Controller
control={control} control={control}
@ -306,7 +306,7 @@ export default function FormDetailPressConference() {
</div> </div>
</div> </div>
<div className="flex flex-col my-3"> <div className="flex flex-col my-3">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label> <Label>Nama Lengkap</Label>
<Controller <Controller
control={control} control={control}

View File

@ -207,20 +207,20 @@ export default function FormPressConference() {
)} )}
<div className="flex flex-col lg:flex-row mb-4 mt-2 items-start lg:items-center justify-between"> <div className="flex flex-col lg:flex-row mb-4 mt-2 items-start lg:items-center justify-between">
<div className="flex flex-col "> <div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label> <Label className="mr-3 mb-1">Tanggal</Label>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild className="px-0">
<Button <Button
size="md" size="md"
id="date" id="date"
variant={"outline"} variant={"outline"}
className={cn( className={cn(
"w-[280px] lg:w-[250px] justify-start text-left font-normal border border-slate-300", "w-[280px] lg:w-[250px] justify-start text-left font-normal border border-slate-300 px-0 md:px-0 lg:px-4",
!date && "text-muted-foreground" !date && "text-muted-foreground"
)} )}
> >
<CalendarIcon /> <CalendarIcon size={15} className="mr-3" />
{date?.from ? ( {date?.from ? (
date.to ? ( date.to ? (
<> <>
@ -247,7 +247,7 @@ export default function FormPressConference() {
</PopoverContent> </PopoverContent>
</Popover> </Popover>
</div> </div>
<div> <div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label> <Label htmlFor="title">Rentang Waktu</Label>
<div className=""> <div className="">
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
@ -295,7 +295,7 @@ export default function FormPressConference() {
</div> </div>
<p className="text-sm mt-4 font-semibold">DI SAMPAIKAN OLEH</p> <p className="text-sm mt-4 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col "> <div className="flex flex-col ">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label> <Label>Nama Pangkat</Label>
<Controller <Controller
control={control} control={control}
@ -318,7 +318,7 @@ export default function FormPressConference() {
</div> </div>
</div> </div>
<div className="flex flex-col my-3"> <div className="flex flex-col my-3">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label> <Label>Nama Lengkap</Label>
<Controller <Controller
control={control} control={control}

View File

@ -254,7 +254,7 @@ export default function FormUpdatePressConference() {
)} )}
<div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between"> <div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between">
<div className="flex flex-col"> <div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label> <Label className="mr-3 mb-1">Tanggal</Label>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
@ -262,11 +262,11 @@ export default function FormUpdatePressConference() {
id="date" id="date"
variant={"outline"} variant={"outline"}
className={cn( className={cn(
"w-[280px] lg:w-[300px] justify-start text-left font-normal", "w-[280px] lg:w-[250px] justify-start text-left font-normal px-0 md:px-0 lg:px-4",
!date && "text-muted-foreground" !date && "text-muted-foreground"
)} )}
> >
<CalendarIcon /> <CalendarIcon size={15} className="mr-3" />
{date?.from ? ( {date?.from ? (
date.to ? ( date.to ? (
<> <>
@ -293,7 +293,7 @@ export default function FormUpdatePressConference() {
</PopoverContent> </PopoverContent>
</Popover> </Popover>
</div> </div>
<div> <div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label> <Label htmlFor="title">Rentang Waktu</Label>
<div> <div>
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
@ -343,7 +343,7 @@ export default function FormUpdatePressConference() {
</div> </div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p> <p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col "> <div className="flex flex-col ">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label> <Label>Nama Pangkat</Label>
<Controller <Controller
control={control} control={control}
@ -366,7 +366,7 @@ export default function FormUpdatePressConference() {
</div> </div>
</div> </div>
<div className="flex flex-col my-3"> <div className="flex flex-col my-3">
<div className="mt-1"> <div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label> <Label>Nama Lengkap</Label>
<Controller <Controller
control={control} control={control}

View File

@ -1108,7 +1108,7 @@ export default function FormTaskDetail() {
</p> </p>
)} */} )} */}
</div> </div>
<div className="space-y-1.5 mt-5 space-y-2"> <div className=" mt-5 space-y-2">
<Label htmlFor="attachment">{t("attachment")}</Label> <Label htmlFor="attachment">{t("attachment")}</Label>
<div className="space-y-3"> <div className="space-y-3">
<div> <div>

View File

@ -48,6 +48,8 @@ import WavesurferPlayer from "@wavesurfer/react";
import { getCsrfToken } from "@/service/auth"; import { getCsrfToken } from "@/service/auth";
import { Upload } from "tus-js-client"; import { Upload } from "tus-js-client";
import { error, loading } from "@/lib/swal"; import { error, loading } from "@/lib/swal";
import dynamic from "next/dynamic";
import { useTranslations } from "next-intl";
const taskSchema = z.object({ const taskSchema = z.object({
// uniqueCode: z.string().min(1, { message: "Judul diperlukan" }), // uniqueCode: z.string().min(1, { message: "Judul diperlukan" }),
@ -93,6 +95,13 @@ type Url = {
attachmentUrl: string; attachmentUrl: string;
}; };
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function FormTaskEdit() { export default function FormTaskEdit() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
@ -110,6 +119,7 @@ export default function FormTaskEdit() {
text: false, text: false,
}); });
const t = useTranslations("Form");
const [imageFiles, setImageFiles] = useState<FileWithPreview[]>([]); const [imageFiles, setImageFiles] = useState<FileWithPreview[]>([]);
const [videoFiles, setVideoFiles] = useState<FileWithPreview[]>([]); const [videoFiles, setVideoFiles] = useState<FileWithPreview[]>([]);
const [textFiles, setTextFiles] = useState<FileWithPreview[]>([]); const [textFiles, setTextFiles] = useState<FileWithPreview[]>([]);
@ -294,6 +304,63 @@ export default function FormTaskEdit() {
return Array.from(checkedLevels).join(","); // Mengonversi Set ke string return Array.from(checkedLevels).join(","); // Mengonversi Set ke string
}; };
const handleUnitChange = (
key: keyof typeof unitSelection,
value: boolean
) => {
if (key === "allUnit") {
const newState = {
allUnit: value,
mabes: value,
polda: value,
polres: value,
satker: value,
};
setUnitSelection(newState);
} else {
const updatedSelection = {
...unitSelection,
[key]: value,
};
const allChecked = ["mabes", "polda", "polres", "satker"].every(
(k) => updatedSelection[k as keyof typeof unitSelection]
);
updatedSelection.allUnit = allChecked;
setUnitSelection(updatedSelection);
}
};
const handleTaskOutputChange = (
key: keyof typeof taskOutput,
value: boolean
) => {
if (key === "all") {
const newState = {
all: value,
video: value,
audio: value,
image: value,
text: value,
};
setTaskOutput(newState);
} else {
const updated = {
...taskOutput,
[key]: value,
};
const allChecked = ["video", "audio", "image", "text"].every(
(k) => updated[k as keyof typeof taskOutput]
);
updated.all = allChecked;
setTaskOutput(updated);
}
};
const save = async (data: TaskSchema) => { const save = async (data: TaskSchema) => {
const fileTypeMapping = { const fileTypeMapping = {
all: "1", all: "1",
@ -624,7 +691,7 @@ export default function FormTaskEdit() {
{detail !== undefined ? ( {detail !== undefined ? (
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<div className="gap-5 mb-5"> <div className="gap-5 mb-5">
<div className="space-y-2 mt-6"> <div className="space-y-2">
<Label>Judul</Label> <Label>Judul</Label>
<Controller <Controller
control={control} control={control}
@ -644,7 +711,7 @@ export default function FormTaskEdit() {
)} )}
</div> </div>
<div className="flex flex-col sm:flex-row lg:flex-row sm:items-center lg:items-center"> <div className="flex flex-col sm:flex-row lg:flex-row sm:items-center lg:items-center">
<div className="mt-6"> <div className="mt-5 space-y-2">
<Label>Tujuan Pemilihan Tugas</Label> <Label>Tujuan Pemilihan Tugas</Label>
<Select <Select
onValueChange={setSelectedTarget} onValueChange={setSelectedTarget}
@ -660,7 +727,7 @@ export default function FormTaskEdit() {
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
<div className="flex flex-wrap gap-3 mt-6 lg:pt-5 lg:ml-3"> <div className="flex flex-wrap gap-3 mt-6 lg:pt-7 lg:ml-3">
{Object.keys(unitSelection).map((key) => ( {Object.keys(unitSelection).map((key) => (
<div className="flex items-center gap-2" key={key}> <div className="flex items-center gap-2" key={key}>
<Checkbox <Checkbox
@ -669,7 +736,10 @@ export default function FormTaskEdit() {
unitSelection[key as keyof typeof unitSelection] unitSelection[key as keyof typeof unitSelection]
} }
onCheckedChange={(value) => onCheckedChange={(value) =>
setUnitSelection({ ...unitSelection, [key]: value }) handleUnitChange(
key as keyof typeof unitSelection,
value as boolean
)
} }
/> />
<Label htmlFor={key}> <Label htmlFor={key}>
@ -678,7 +748,7 @@ export default function FormTaskEdit() {
</div> </div>
))} ))}
</div> </div>
<div className="mt-6 lg:pt-5 lg:pl-3"> <div className="mt-6 lg:pt-6 lg:pl-3">
<Dialog> <Dialog>
<DialogTrigger asChild> <DialogTrigger asChild>
<Button variant="soft" size="sm" color="primary"> <Button variant="soft" size="sm" color="primary">
@ -762,8 +832,8 @@ export default function FormTaskEdit() {
</Dialog> </Dialog>
</div> </div>
</div> </div>
<div className="mt-6"> <div className="mt-5 space-y-2">
<Label>Tipe Penugasan</Label> <Label>{t("type-task")}</Label>
<RadioGroup <RadioGroup
defaultValue={detail.assignmentMainType.id.toString()} // State yang dipetakan ke value RadioGroup defaultValue={detail.assignmentMainType.id.toString()} // State yang dipetakan ke value RadioGroup
onValueChange={(value) => setMainType(value)} onValueChange={(value) => setMainType(value)}
@ -777,8 +847,8 @@ export default function FormTaskEdit() {
<Label htmlFor="medsos-mediahub">Medsos Mediahub</Label> <Label htmlFor="medsos-mediahub">Medsos Mediahub</Label>
</RadioGroup> </RadioGroup>
</div> </div>
<div className="mt-6"> <div className="mt-5 space-y-2">
<Label>Jenis Tugas </Label> <Label>{t("assigment-type")} </Label>
<RadioGroup <RadioGroup
defaultValue={detail.taskType.toString()} defaultValue={detail.taskType.toString()}
onValueChange={(value) => setTaskType(String(value))} onValueChange={(value) => setTaskType(String(value))}
@ -791,8 +861,8 @@ export default function FormTaskEdit() {
</RadioGroup> </RadioGroup>
</div> </div>
{/* RadioGroup Assignment Category */} {/* RadioGroup Assignment Category */}
<div className="mt-6"> <div className="mt-5 space-y-2">
<Label>Jenis Penugasan</Label> <Label>{t("type-of-task")}</Label>
<RadioGroup <RadioGroup
defaultValue={detail.assignmentType.id.toString()} // State yang dipetakan ke value RadioGroup defaultValue={detail.assignmentType.id.toString()} // State yang dipetakan ke value RadioGroup
onValueChange={(value) => setType(value)} // Mengubah nilai state ketika pilihan berubah onValueChange={(value) => setType(value)} // Mengubah nilai state ketika pilihan berubah
@ -812,16 +882,19 @@ export default function FormTaskEdit() {
</div> </div>
</RadioGroup> </RadioGroup>
</div> </div>
<div className="mt-6"> <div className="mt-5 space-y-2">
<Label>Output Tugas</Label> <Label>{t("output-task")}</Label>
<div className="flex flex-wrap gap-3"> <div className="flex flex-wrap gap-4">
{Object.keys(taskOutput).map((key) => ( {Object.keys(taskOutput).map((key) => (
<div className="flex items-center gap-2" key={key}> <div className="flex items-center gap-2" key={key}>
<Checkbox <Checkbox
id={key} id={key}
checked={taskOutput[key as keyof typeof taskOutput]} checked={taskOutput[key as keyof typeof taskOutput]}
onCheckedChange={(value) => onCheckedChange={(value) =>
setTaskOutput({ ...taskOutput, [key]: value }) handleTaskOutputChange(
key as keyof typeof taskOutput,
value as boolean
)
} }
/> />
<Label htmlFor={key}> <Label htmlFor={key}>
@ -831,17 +904,15 @@ export default function FormTaskEdit() {
))} ))}
</div> </div>
</div> </div>
<div className="mt-6"> <div className="mt-5 space-y-2">
<Label>Narasi Penugasan</Label> <Label>{t("description")}</Label>
<Controller <Controller
control={control} control={control}
name="naration" name="naration"
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<JoditEditor <CustomEditor
ref={editor}
value={detail?.narration}
onChange={onChange} onChange={onChange}
className="dark:text-black" initialData={detail?.narration || value}
/> />
)} )}
/> />
@ -851,11 +922,11 @@ export default function FormTaskEdit() {
</p> </p>
)} )}
</div> </div>
<div className="space-y-1.5 mt-5"> <div className="space-y-2.5 mt-5">
<Label htmlFor="attachments">Lampiran</Label> <Label htmlFor="attachments">{t("attachment")}</Label>
<div className="space-y-3"> <div className="space-y-3">
<div> <div className="space-y-2">
<Label>Video</Label> <Label>{t("audio-visual")}</Label>
<FileUploader <FileUploader
accept={{ accept={{
"mp4/*": [], "mp4/*": [],
@ -895,8 +966,8 @@ export default function FormTaskEdit() {
</div> </div>
))} ))}
</div> </div>
<div> <div className="space-y-2">
<Label>Foto</Label> <Label>{t("image")}</Label>
<FileUploader <FileUploader
accept={{ accept={{
"image/*": [], "image/*": [],
@ -935,8 +1006,8 @@ export default function FormTaskEdit() {
</div> </div>
))} ))}
</div> </div>
<div> <div className="space-y-2">
<Label>Teks</Label> <Label>{t("text")}</Label>
<FileUploader <FileUploader
accept={{ accept={{
"pdf/*": [], "pdf/*": [],
@ -975,8 +1046,8 @@ export default function FormTaskEdit() {
</div> </div>
))} ))}
</div> </div>
<div> <div className="space-y-2">
<Label>Audio</Label> <Label>{t("audio")}</Label>
<AudioRecorder <AudioRecorder
onRecordingComplete={addAudioElement} onRecordingComplete={addAudioElement}
audioTrackConstraints={{ audioTrackConstraints={{
@ -1030,7 +1101,7 @@ export default function FormTaskEdit() {
</div> </div>
{audioFile && ( {audioFile && (
<div className="flex flex-row justify-between items-center"> <div className="flex flex-row justify-between items-center">
<p>Voice Note</p> <p>{t("voice-note")}</p>
<Button <Button
type="button" type="button"
onClick={handleDeleteAudio} onClick={handleDeleteAudio}
@ -1043,8 +1114,8 @@ export default function FormTaskEdit() {
)} )}
{isRecording && <p>Recording... {timer} seconds remaining</p>}{" "} {isRecording && <p>Recording... {timer} seconds remaining</p>}{" "}
{/* Display remaining time */} {/* Display remaining time */}
<div className="mt-4"> <div className="mt-4 space-y-2">
<h2 className="text-lg font-bold">Link Berita</h2> <h2 className="text-lg font-bold">{t("news-links")}</h2>
{urlInputs.map((url: any, index: any) => ( {urlInputs.map((url: any, index: any) => (
<div <div
key={url.id} key={url.id}
@ -1066,7 +1137,7 @@ export default function FormTaskEdit() {
className="mt-4 bg-green-500 text-white px-4 py-2 rounded" className="mt-4 bg-green-500 text-white px-4 py-2 rounded"
onClick={handleAddLink} onClick={handleAddLink}
> >
Tambah Link {t("add-links")}
</button> </button>
</div> </div>
</div> </div>

View File

@ -32,7 +32,7 @@ import {
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { ChevronDown, ChevronUp } from "lucide-react"; import { ChevronDown, ChevronUp, Trash2 } from "lucide-react";
import { AudioRecorder } from "react-audio-voice-recorder"; import { AudioRecorder } from "react-audio-voice-recorder";
import FileUploader from "@/components/form/shared/file-uploader"; import FileUploader from "@/components/form/shared/file-uploader";
import { Upload } from "tus-js-client"; import { Upload } from "tus-js-client";
@ -40,6 +40,7 @@ import { error } from "@/config/swal";
import { getCsrfToken } from "@/service/auth"; import { getCsrfToken } from "@/service/auth";
import { loading } from "@/lib/swal"; import { loading } from "@/lib/swal";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import dynamic from "next/dynamic";
const taskSchema = z.object({ const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -74,6 +75,13 @@ export type taskDetail = {
is_active: string; is_active: string;
}; };
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function FormTask() { export default function FormTask() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
@ -188,6 +196,63 @@ export default function FormTask() {
return Array.from(checkedLevels).join(","); // Mengonversi Set ke string return Array.from(checkedLevels).join(","); // Mengonversi Set ke string
}; };
const handleUnitChange = (
key: keyof typeof unitSelection,
value: boolean
) => {
if (key === "allUnit") {
const newState = {
allUnit: value,
mabes: value,
polda: value,
polres: value,
satker: value,
};
setUnitSelection(newState);
} else {
const updatedSelection = {
...unitSelection,
[key]: value,
};
const allChecked = ["mabes", "polda", "polres", "satker"].every(
(k) => updatedSelection[k as keyof typeof unitSelection]
);
updatedSelection.allUnit = allChecked;
setUnitSelection(updatedSelection);
}
};
const handleTaskOutputChange = (
key: keyof typeof taskOutput,
value: boolean
) => {
if (key === "all") {
const newState = {
all: value,
video: value,
audio: value,
image: value,
text: value,
};
setTaskOutput(newState);
} else {
const updated = {
...taskOutput,
[key]: value,
};
const allChecked = ["video", "audio", "image", "text"].every(
(k) => updated[k as keyof typeof taskOutput]
);
updated.all = allChecked;
setTaskOutput(updated);
}
};
const save = async (data: TaskSchema) => { const save = async (data: TaskSchema) => {
const fileTypeMapping = { const fileTypeMapping = {
all: "1", all: "1",
@ -518,14 +583,17 @@ export default function FormTask() {
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
<div className="flex flex-wrap gap-3 mt-5 lg:pt-5 lg:ml-3"> <div className="flex flex-wrap gap-3 mt-5 lg:pt-7 lg:ml-3 ">
{Object.keys(unitSelection).map((key) => ( {Object.keys(unitSelection).map((key) => (
<div className="flex items-center gap-2" key={key}> <div className="flex items-center gap-2" key={key}>
<Checkbox <Checkbox
id={key} id={key}
checked={unitSelection[key as keyof typeof unitSelection]} checked={unitSelection[key as keyof typeof unitSelection]}
onCheckedChange={(value) => onCheckedChange={(value) =>
setUnitSelection({ ...unitSelection, [key]: value }) handleUnitChange(
key as keyof typeof unitSelection,
value as boolean
)
} }
/> />
<Label htmlFor={key}> <Label htmlFor={key}>
@ -534,7 +602,7 @@ export default function FormTask() {
</div> </div>
))} ))}
</div> </div>
<div className="mt-6 lg:pt-5 lg:pl-3"> <div className="mt-6 lg:pt-6 lg:pl-3">
<Dialog> <Dialog>
<DialogTrigger asChild> <DialogTrigger asChild>
<Button variant="soft" size="sm" color="primary"> <Button variant="soft" size="sm" color="primary">
@ -668,14 +736,17 @@ export default function FormTask() {
</div> </div>
<div className="mt-5 space-y-2"> <div className="mt-5 space-y-2">
<Label>{t("output-task")}</Label> <Label>{t("output-task")}</Label>
<div className="flex flex-wrap gap-3"> <div className="flex flex-wrap gap-4">
{Object.keys(taskOutput).map((key) => ( {Object.keys(taskOutput).map((key) => (
<div className="flex items-center gap-2" key={key}> <div className="flex items-center gap-2" key={key}>
<Checkbox <Checkbox
id={key} id={key}
checked={taskOutput[key as keyof typeof taskOutput]} checked={taskOutput[key as keyof typeof taskOutput]}
onCheckedChange={(value) => onCheckedChange={(value) =>
setTaskOutput({ ...taskOutput, [key]: value }) handleTaskOutputChange(
key as keyof typeof taskOutput,
value as boolean
)
} }
/> />
<Label htmlFor={key}> <Label htmlFor={key}>
@ -712,12 +783,7 @@ export default function FormTask() {
control={control} control={control}
name="naration" name="naration"
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<JoditEditor <CustomEditor onChange={onChange} initialData={value} />
ref={editor}
value={value}
onChange={onChange}
className="dark:text-black"
/>
)} )}
/> />
{errors.naration?.message && ( {errors.naration?.message && (
@ -809,7 +875,7 @@ export default function FormTask() {
<Label className="">{t("news-links")}</Label> <Label className="">{t("news-links")}</Label>
{links.map((link, index) => ( {links.map((link, index) => (
<div key={index} className="flex items-center gap-2 mt-2"> <div key={index} className="flex items-center gap-2 mt-2">
<input <Input
type="url" type="url"
className="border rounded p-2 w-full" className="border rounded p-2 w-full"
placeholder={`Masukkan link berita ${index + 1}`} placeholder={`Masukkan link berita ${index + 1}`}
@ -824,7 +890,7 @@ export default function FormTask() {
className="bg-red-500 text-white px-3 py-1 rounded" className="bg-red-500 text-white px-3 py-1 rounded"
onClick={() => handleRemoveRow(index)} onClick={() => handleRemoveRow(index)}
> >
{t("remove")} <Trash2 className="h-4 w-4" />
</button> </button>
)} )}
</div> </div>

View File

@ -356,7 +356,7 @@ const SurveyFormModal = ({ onClose }: { onClose: () => void }) => {
); );
}; };
const FIVE_MINUTES = 5 * 60 * 1000; const ONE_MONTH = 30 * 24 * 60 * 60 * 1000;
const Hero: React.FC = () => { const Hero: React.FC = () => {
const router = useRouter(); const router = useRouter();
@ -388,12 +388,13 @@ const Hero: React.FC = () => {
useEffect(() => { useEffect(() => {
const roleId = Cookies.get("urie"); const roleId = Cookies.get("urie");
const lastShown = Cookies.get("surveyLastShown"); const lastShown = Cookies.get("surveyLastShown");
const now = new Date().getTime(); const now = new Date().getTime();
if (roleId && (!lastShown || now - parseInt(lastShown) > FIVE_MINUTES)) { if (roleId && roleId !== "2") {
setShowSurveyModal(true); if (!lastShown || now - parseInt(lastShown) > ONE_MONTH) {
Cookies.set("surveyLastShown", now.toString(), { expires: 1 }); setShowSurveyModal(true);
Cookies.set("surveyLastShown", now.toString(), { expires: 30 });
}
} }
initFetch(); initFetch();

View File

@ -10,7 +10,7 @@ import { useForm, SubmitHandler } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod"; import { z } from "zod";
import { cn, setCookiesEncrypt } from "@/lib/utils"; import { cn, setCookiesEncrypt } from "@/lib/utils";
import { Loader2 } from "lucide-react"; import { Eye, EyeOff, Loader2 } from "lucide-react";
import { import {
getProfile, getProfile,
login, login,
@ -66,6 +66,7 @@ const LoginForm = () => {
const [newEmail, setNewEmail] = useState(""); const [newEmail, setNewEmail] = useState("");
const [newEmailValidate, setNewEmailValidate] = useState(""); const [newEmailValidate, setNewEmailValidate] = useState("");
const [otpValidate, setOtpValidate] = useState(""); const [otpValidate, setOtpValidate] = useState("");
const [showPassword, setShowPassword] = useState(false);
const [otp1, setOtp1] = useState(); const [otp1, setOtp1] = useState();
const [otp2, setOtp2] = useState(); const [otp2, setOtp2] = useState();
@ -222,7 +223,7 @@ const LoginForm = () => {
profile?.data?.data?.userLevel?.id == 761 || profile?.data?.data?.userLevel?.id == 761 ||
profile?.data?.data?.userLevel?.parentLevelId == 761 profile?.data?.data?.userLevel?.parentLevelId == 761
) { ) {
window.location.href = "/in/welcome"; window.location.href = "/in/dashboard/executive";
Cookies.set("status", "login", { Cookies.set("status", "login", {
expires: 1, expires: 1,
}); });
@ -384,9 +385,17 @@ const LoginForm = () => {
disabled={isPending} disabled={isPending}
{...register("password")} {...register("password")}
id="password" id="password"
type="password" type={showPassword ? "text" : "password"}
className="peer" className="peer pr-10"
/> />
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2 text-default-500 hover:text-default-700"
tabIndex={-1}
>
{showPassword ? <EyeOff size={18} /> : <Eye size={18} />}
</button>
</div> </div>
{errors.password?.message && ( {errors.password?.message && (
<div className="text-destructive mt-2 text-sm"> <div className="text-destructive mt-2 text-sm">

View File

@ -3679,34 +3679,34 @@ export function getMenuList(pathname: string, t: any): Group[] {
icon: "heroicons:arrow-trending-up", icon: "heroicons:arrow-trending-up",
children: [], children: [],
}, },
{ // {
href: "/admin/settings/feedback", // href: "/admin/settings/feedback",
label: "Feedback", // label: "Feedback",
active: pathname === "/admin/settings/feedback", // active: pathname === "/admin/settings/feedback",
icon: "heroicons:arrow-trending-up", // icon: "heroicons:arrow-trending-up",
children: [], // children: [],
}, // },
{ // {
href: "/admin/settings/faq", // href: "/admin/settings/faq",
label: "FAQ", // label: "FAQ",
active: pathname === "/admin/settings/faq", // active: pathname === "/admin/settings/faq",
icon: "heroicons:arrow-trending-up", // icon: "heroicons:arrow-trending-up",
children: [], // children: [],
}, // },
{ // {
href: "https://nat-mediahub.polri.go.id/", // href: "https://nat-mediahub.polri.go.id/",
label: "Mediahub 2022", // label: "Mediahub 2022",
active: pathname === "/admin/settings/mediahub-2022", // active: pathname === "/admin/settings/mediahub-2022",
icon: "heroicons:arrow-trending-up", // icon: "heroicons:arrow-trending-up",
children: [], // children: [],
}, // },
{ // {
href: "/admin/settings/privacy", // href: "/admin/settings/privacy",
label: t("privacy"), // label: t("privacy"),
active: pathname === "/admin/settings/privacy", // active: pathname === "/admin/settings/privacy",
icon: "heroicons:arrow-trending-up", // icon: "heroicons:arrow-trending-up",
children: [], // children: [],
}, // },
], ],
}, },
], ],