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>
{roleId === 3 && userLevelId === 216 ? (
<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")}
</Button>
) : null}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -49,6 +49,7 @@ import { error } from "@/lib/swal";
import { getCsrfToken } from "@/service/auth";
import { Upload } from "tus-js-client";
import { useTranslations } from "next-intl";
import dynamic from "next/dynamic";
const audioSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
@ -88,6 +89,13 @@ type Option = {
name: string;
};
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function FormAudioUpdate() {
const MySwal = withReactContent(Swal);
const router = useRouter();
@ -646,11 +654,9 @@ export default function FormAudioUpdate() {
control={control}
name="description"
render={({ field: { onChange, value } }) => (
<JoditEditor
ref={editor}
value={detail?.description}
<CustomEditor
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>
</div>
{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">
<Checkbox
id="all-content"
@ -971,7 +971,7 @@ export default function FormConvertSPIT() {
<Input
size="md"
type="text"
defaultValue={detail?.contentCreator}
value={detail?.contentCreator}
onChange={field.onChange}
placeholder="Enter Title"
/>

View File

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

View File

@ -33,7 +33,7 @@ import {
PopoverTrigger,
} from "@/components/ui/popover";
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 { Calendar } from "@/components/ui/calendar";
import { DateRange } from "react-day-picker";
@ -898,10 +898,10 @@ export default function FormContestDetail() {
{isRecording && <p>Recording... {timer} seconds remaining</p>}{" "}
{/* Display remaining time */}
<div className="mt-4">
<h2 className="text-lg font-bold">Link Berita</h2>
<Label className="">Link Berita</Label>
{links.map((link, index) => (
<div key={index} className="flex items-center gap-2 mt-2">
<input
<Input
type="url"
className="border rounded p-2 w-full"
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"
onClick={() => handleRemoveRow(index)}
>
Hapus
<Trash2 className="h-4 w-4" />
</button>
)}
</div>
))}
<button
<Button
type="button"
size="md"
className="mt-2 bg-blue-500 text-white px-4 py-2 rounded"
onClick={handleAddRow}
>
Tambah Link
</button>
</Button>
</div>
</div>
</div>

View File

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

View File

@ -34,6 +34,7 @@ import {
DialogTrigger,
} from "@/components/ui/dialog";
import { useTranslations } from "next-intl";
import dynamic from "next/dynamic";
const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
@ -56,6 +57,13 @@ export type medsosDetail = {
is_active: string;
};
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function PublishMedsos() {
const MySwal = withReactContent(Swal);
const router = useRouter();
@ -496,11 +504,9 @@ export default function PublishMedsos() {
control={control}
name="description"
render={({ field: { onChange, value } }) => (
<JoditEditor
ref={editor}
value={detail?.description}
<CustomEditor
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">
<div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label>
<Popover>
<PopoverTrigger asChild>
@ -245,11 +245,11 @@ export default function FormEventDetail() {
id="date"
variant={"outline"}
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"
)}
>
<CalendarIcon />
<CalendarIcon size={15} className="mr-3" />
{date?.from ? (
date.to ? (
<>
@ -276,7 +276,7 @@ export default function FormEventDetail() {
</PopoverContent>
</Popover>
</div>
<div>
<div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label>
<div>
<div className="flex flex-row items-center">
@ -326,7 +326,7 @@ export default function FormEventDetail() {
DI SAMPAIKAN OLEH
</p>
<div className="flex flex-col ">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label>
<Controller
control={control}
@ -349,7 +349,7 @@ export default function FormEventDetail() {
</div>
</div>
<div className="flex flex-col my-3">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label>
<Controller
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 ">
<div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label>
<Popover>
<PopoverTrigger asChild>
@ -242,11 +242,11 @@ export default function FormEvent() {
id="date"
variant={"outline"}
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"
)}
>
<CalendarIcon />
<CalendarIcon size={15} className="mr-3" />
{date?.from ? (
date.to ? (
<>
@ -273,7 +273,7 @@ export default function FormEvent() {
</PopoverContent>
</Popover>
</div>
<div>
<div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label>
<div className="">
<div className="flex flex-row items-center">
@ -321,7 +321,7 @@ export default function FormEvent() {
</div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col ">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label>
<Controller
control={control}
@ -344,7 +344,7 @@ export default function FormEvent() {
</div>
</div>
<div className="flex flex-col my-3">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label>
<Controller
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">
<div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label>
<Popover>
<PopoverTrigger asChild>
@ -258,11 +258,11 @@ export default function FormEventUpdate() {
id="date"
variant={"outline"}
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"
)}
>
<CalendarIcon />
<CalendarIcon size={15} className="mr-3" />
{date?.from ? (
date.to ? (
<>
@ -289,7 +289,7 @@ export default function FormEventUpdate() {
</PopoverContent>
</Popover>
</div>
<div>
<div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label>
<div>
<div className="flex flex-row items-center">
@ -337,7 +337,7 @@ export default function FormEventUpdate() {
</div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col ">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label>
<Controller
control={control}
@ -360,7 +360,7 @@ export default function FormEventUpdate() {
</div>
</div>
<div className="flex flex-col my-3">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label>
<Controller
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">
<div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label>
<Popover>
<PopoverTrigger asChild>
@ -255,11 +255,11 @@ export default function FormDetailPressRillis() {
id="date"
variant={"outline"}
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"
)}
>
<CalendarIcon />
<CalendarIcon size={15} className="mr-3" />
{date?.from ? (
date.to ? (
<>
@ -286,7 +286,7 @@ export default function FormDetailPressRillis() {
</PopoverContent>
</Popover>
</div>
<div>
<div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label>
<div>
<div className="flex flex-row items-center">
@ -332,7 +332,7 @@ export default function FormDetailPressRillis() {
{errors.location?.message}
</div>
</div>
<div className="mt-6">
<div className="mt-6 space-y-2">
<Label>Invitation</Label>
<Select onValueChange={setSelectedTarget}>
<SelectTrigger size="md">
@ -353,7 +353,7 @@ export default function FormDetailPressRillis() {
DI SAMPAIKAN OLEH
</p>
<div className="flex flex-col ">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label>
<Controller
control={control}
@ -376,7 +376,7 @@ export default function FormDetailPressRillis() {
</div>
</div>
<div className="flex flex-col my-3">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label>
<Controller
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">
<div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label>
<Popover>
<PopoverTrigger asChild>
@ -265,11 +265,11 @@ export default function FormUpdatePressRelease() {
id="date"
variant={"outline"}
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"
)}
>
<CalendarIcon />
<CalendarIcon size={15} className="mr-3" />
{date?.from ? (
date.to ? (
<>
@ -296,7 +296,7 @@ export default function FormUpdatePressRelease() {
</PopoverContent>
</Popover>
</div>
<div>
<div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label>
<div>
<div className="flex flex-row items-center">
@ -342,7 +342,7 @@ export default function FormUpdatePressRelease() {
{errors.location?.message}
</div>
</div>
<div className="mt-5">
<div className="mt-5 space-y-2">
<Label>Invitation</Label>
<Select onValueChange={setSelectedTarget}>
<SelectTrigger size="md">
@ -361,7 +361,7 @@ export default function FormUpdatePressRelease() {
</div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col ">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label>
<Controller
control={control}
@ -384,7 +384,7 @@ export default function FormUpdatePressRelease() {
</div>
</div>
<div className="flex flex-col my-3">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label>
<Controller
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 ">
<div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label>
<Popover>
<PopoverTrigger asChild>
@ -242,11 +242,11 @@ export default function FormPressRelease() {
id="date"
variant={"outline"}
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"
)}
>
<CalendarIcon />
<CalendarIcon size={15} className="mr-3" />
{date?.from ? (
date.to ? (
<>
@ -273,7 +273,7 @@ export default function FormPressRelease() {
</PopoverContent>
</Popover>
</div>
<div>
<div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label>
<div className="">
<div className="flex flex-row items-center">
@ -319,7 +319,7 @@ export default function FormPressRelease() {
{errors.location?.message}
</div>
</div>
<div className="mt-5">
<div className="mt-5 space-y-2">
<Label>Invitation</Label>
<Select onValueChange={setSelectedTarget}>
<SelectTrigger size="md">
@ -338,7 +338,7 @@ export default function FormPressRelease() {
</div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col ">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label>
<Controller
control={control}
@ -361,7 +361,7 @@ export default function FormPressRelease() {
</div>
</div>
<div className="flex flex-col my-3">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label>
<Controller
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">
<div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label>
<Popover>
<PopoverTrigger asChild>
@ -202,11 +202,11 @@ export default function FormDetailPressConference() {
id="date"
variant={"outline"}
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"
)}
>
<CalendarIcon />
<CalendarIcon size={15} className="mr-3" />
{date?.from ? (
date.to ? (
<>
@ -233,7 +233,7 @@ export default function FormDetailPressConference() {
</PopoverContent>
</Popover>
</div>
<div>
<div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label>
<div>
<div className="flex flex-row items-center">
@ -283,7 +283,7 @@ export default function FormDetailPressConference() {
DI SAMPAIKAN OLEH
</p>
<div className="flex flex-col ">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label>
<Controller
control={control}
@ -306,7 +306,7 @@ export default function FormDetailPressConference() {
</div>
</div>
<div className="flex flex-col my-3">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label>
<Controller
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 ">
<div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label>
<Popover>
<PopoverTrigger asChild>
<PopoverTrigger asChild className="px-0">
<Button
size="md"
id="date"
variant={"outline"}
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"
)}
>
<CalendarIcon />
<CalendarIcon size={15} className="mr-3" />
{date?.from ? (
date.to ? (
<>
@ -247,7 +247,7 @@ export default function FormPressConference() {
</PopoverContent>
</Popover>
</div>
<div>
<div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label>
<div className="">
<div className="flex flex-row items-center">
@ -295,7 +295,7 @@ export default function FormPressConference() {
</div>
<p className="text-sm mt-4 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col ">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label>
<Controller
control={control}
@ -318,7 +318,7 @@ export default function FormPressConference() {
</div>
</div>
<div className="flex flex-col my-3">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label>
<Controller
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">
<div className="flex flex-col space-y-2">
<Label className="mr-3 mb-1">Tanggal</Label>
<Popover>
<PopoverTrigger asChild>
@ -262,11 +262,11 @@ export default function FormUpdatePressConference() {
id="date"
variant={"outline"}
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"
)}
>
<CalendarIcon />
<CalendarIcon size={15} className="mr-3" />
{date?.from ? (
date.to ? (
<>
@ -293,7 +293,7 @@ export default function FormUpdatePressConference() {
</PopoverContent>
</Popover>
</div>
<div>
<div className="space-y-2">
<Label htmlFor="title">Rentang Waktu</Label>
<div>
<div className="flex flex-row items-center">
@ -343,7 +343,7 @@ export default function FormUpdatePressConference() {
</div>
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
<div className="flex flex-col ">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Pangkat</Label>
<Controller
control={control}
@ -366,7 +366,7 @@ export default function FormUpdatePressConference() {
</div>
</div>
<div className="flex flex-col my-3">
<div className="mt-1">
<div className="mt-1 space-y-2">
<Label>Nama Lengkap</Label>
<Controller
control={control}

View File

@ -1108,7 +1108,7 @@ export default function FormTaskDetail() {
</p>
)} */}
</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>
<div className="space-y-3">
<div>

View File

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

View File

@ -32,7 +32,7 @@ import {
DialogTitle,
DialogTrigger,
} 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 FileUploader from "@/components/form/shared/file-uploader";
import { Upload } from "tus-js-client";
@ -40,6 +40,7 @@ import { error } from "@/config/swal";
import { getCsrfToken } from "@/service/auth";
import { loading } from "@/lib/swal";
import { useTranslations } from "next-intl";
import dynamic from "next/dynamic";
const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
@ -74,6 +75,13 @@ export type taskDetail = {
is_active: string;
};
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false }
);
export default function FormTask() {
const MySwal = withReactContent(Swal);
const router = useRouter();
@ -188,6 +196,63 @@ export default function FormTask() {
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 fileTypeMapping = {
all: "1",
@ -518,14 +583,17 @@ export default function FormTask() {
</SelectContent>
</Select>
</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) => (
<div className="flex items-center gap-2" key={key}>
<Checkbox
id={key}
checked={unitSelection[key as keyof typeof unitSelection]}
onCheckedChange={(value) =>
setUnitSelection({ ...unitSelection, [key]: value })
handleUnitChange(
key as keyof typeof unitSelection,
value as boolean
)
}
/>
<Label htmlFor={key}>
@ -534,7 +602,7 @@ export default function FormTask() {
</div>
))}
</div>
<div className="mt-6 lg:pt-5 lg:pl-3">
<div className="mt-6 lg:pt-6 lg:pl-3">
<Dialog>
<DialogTrigger asChild>
<Button variant="soft" size="sm" color="primary">
@ -668,14 +736,17 @@ export default function FormTask() {
</div>
<div className="mt-5 space-y-2">
<Label>{t("output-task")}</Label>
<div className="flex flex-wrap gap-3">
<div className="flex flex-wrap gap-4">
{Object.keys(taskOutput).map((key) => (
<div className="flex items-center gap-2" key={key}>
<Checkbox
id={key}
checked={taskOutput[key as keyof typeof taskOutput]}
onCheckedChange={(value) =>
setTaskOutput({ ...taskOutput, [key]: value })
handleTaskOutputChange(
key as keyof typeof taskOutput,
value as boolean
)
}
/>
<Label htmlFor={key}>
@ -712,12 +783,7 @@ export default function FormTask() {
control={control}
name="naration"
render={({ field: { onChange, value } }) => (
<JoditEditor
ref={editor}
value={value}
onChange={onChange}
className="dark:text-black"
/>
<CustomEditor onChange={onChange} initialData={value} />
)}
/>
{errors.naration?.message && (
@ -809,7 +875,7 @@ export default function FormTask() {
<Label className="">{t("news-links")}</Label>
{links.map((link, index) => (
<div key={index} className="flex items-center gap-2 mt-2">
<input
<Input
type="url"
className="border rounded p-2 w-full"
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"
onClick={() => handleRemoveRow(index)}
>
{t("remove")}
<Trash2 className="h-4 w-4" />
</button>
)}
</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 router = useRouter();
@ -388,12 +388,13 @@ const Hero: React.FC = () => {
useEffect(() => {
const roleId = Cookies.get("urie");
const lastShown = Cookies.get("surveyLastShown");
const now = new Date().getTime();
if (roleId && (!lastShown || now - parseInt(lastShown) > FIVE_MINUTES)) {
setShowSurveyModal(true);
Cookies.set("surveyLastShown", now.toString(), { expires: 1 });
if (roleId && roleId !== "2") {
if (!lastShown || now - parseInt(lastShown) > ONE_MONTH) {
setShowSurveyModal(true);
Cookies.set("surveyLastShown", now.toString(), { expires: 30 });
}
}
initFetch();

View File

@ -10,7 +10,7 @@ import { useForm, SubmitHandler } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { cn, setCookiesEncrypt } from "@/lib/utils";
import { Loader2 } from "lucide-react";
import { Eye, EyeOff, Loader2 } from "lucide-react";
import {
getProfile,
login,
@ -66,6 +66,7 @@ const LoginForm = () => {
const [newEmail, setNewEmail] = useState("");
const [newEmailValidate, setNewEmailValidate] = useState("");
const [otpValidate, setOtpValidate] = useState("");
const [showPassword, setShowPassword] = useState(false);
const [otp1, setOtp1] = useState();
const [otp2, setOtp2] = useState();
@ -222,7 +223,7 @@ const LoginForm = () => {
profile?.data?.data?.userLevel?.id == 761 ||
profile?.data?.data?.userLevel?.parentLevelId == 761
) {
window.location.href = "/in/welcome";
window.location.href = "/in/dashboard/executive";
Cookies.set("status", "login", {
expires: 1,
});
@ -384,9 +385,17 @@ const LoginForm = () => {
disabled={isPending}
{...register("password")}
id="password"
type="password"
className="peer"
type={showPassword ? "text" : "password"}
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>
{errors.password?.message && (
<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",
children: [],
},
{
href: "/admin/settings/feedback",
label: "Feedback",
active: pathname === "/admin/settings/feedback",
icon: "heroicons:arrow-trending-up",
children: [],
},
{
href: "/admin/settings/faq",
label: "FAQ",
active: pathname === "/admin/settings/faq",
icon: "heroicons:arrow-trending-up",
children: [],
},
{
href: "https://nat-mediahub.polri.go.id/",
label: "Mediahub 2022",
active: pathname === "/admin/settings/mediahub-2022",
icon: "heroicons:arrow-trending-up",
children: [],
},
{
href: "/admin/settings/privacy",
label: t("privacy"),
active: pathname === "/admin/settings/privacy",
icon: "heroicons:arrow-trending-up",
children: [],
},
// {
// href: "/admin/settings/feedback",
// label: "Feedback",
// active: pathname === "/admin/settings/feedback",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// {
// href: "/admin/settings/faq",
// label: "FAQ",
// active: pathname === "/admin/settings/faq",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// {
// href: "https://nat-mediahub.polri.go.id/",
// label: "Mediahub 2022",
// active: pathname === "/admin/settings/mediahub-2022",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// {
// href: "/admin/settings/privacy",
// label: t("privacy"),
// active: pathname === "/admin/settings/privacy",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
],
},
],