[QUDO-18,QUDO-24] feat:check Ckeditor,Check Form Rencana Penugasan Koor kurator
This commit is contained in:
parent
e97cbcddcb
commit
4007a57ba3
|
|
@ -61,6 +61,7 @@ import {
|
|||
import { getOnlyDate } from "@/utils/globals";
|
||||
import { useParams } from "next/navigation";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
date: z.date({
|
||||
|
|
@ -118,7 +119,19 @@ const units = [
|
|||
id: "3",
|
||||
label: "Polres",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: "Satker",
|
||||
},
|
||||
];
|
||||
|
||||
const ViewEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/view-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function DetailDaily() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
|
@ -725,16 +738,10 @@ export default function DetailDaily() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
config={{ readonly: true }}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<ViewEditor initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ import {
|
|||
import { getOnlyDate } from "@/utils/globals";
|
||||
import { useParams } from "next/navigation";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
date: z.date({
|
||||
|
|
@ -118,7 +119,18 @@ const units = [
|
|||
id: "3",
|
||||
label: "Polres",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: "Satker",
|
||||
},
|
||||
];
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function EditDaily() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
|
@ -728,15 +740,10 @@ export default function EditDaily() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ import {
|
|||
savePlanning,
|
||||
} from "@/service/agenda-setting/agenda-setting";
|
||||
import { getOnlyDate } from "@/utils/globals";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
date: z.date({
|
||||
|
|
@ -116,7 +117,18 @@ const units = [
|
|||
id: "3",
|
||||
label: "Polres",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: "Satker",
|
||||
},
|
||||
];
|
||||
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
export default function CreateDaily() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [listDest, setListDest] = useState<any>([]);
|
||||
|
|
@ -694,15 +706,10 @@ export default function CreateDaily() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import { close, error, loading } from "@/config/swal";
|
|||
import { savePlanning } from "@/service/agenda-setting/agenda-setting";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import { useParams } from "next/navigation";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
month: z.date({
|
||||
|
|
@ -44,6 +45,13 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
|
||||
const ViewEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/view-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
export default function DetailMonthly() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
|
@ -215,16 +223,10 @@ export default function DetailMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
config={{ readonly: true }}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<ViewEditor initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import { close, error, loading } from "@/config/swal";
|
|||
import { savePlanning } from "@/service/agenda-setting/agenda-setting";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import { useParams } from "next/navigation";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
month: z.date({
|
||||
|
|
@ -44,6 +45,14 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function EditMonthly() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
|
@ -108,6 +117,8 @@ export default function EditMonthly() {
|
|||
};
|
||||
|
||||
const save = async (data: z.infer<typeof FormSchema>) => {
|
||||
const month = new Date(data.month).getMonth() + 1;
|
||||
const year = new Date(data.month).getFullYear();
|
||||
const reqData = {
|
||||
id: id,
|
||||
planningTypeId: 1,
|
||||
|
|
@ -115,9 +126,7 @@ export default function EditMonthly() {
|
|||
time: "3",
|
||||
description: data.detail,
|
||||
username: "",
|
||||
date: `${new Date(data.month).getMonth() + 1}/${new Date(
|
||||
data.month
|
||||
).getFullYear()}`,
|
||||
date: `${month.toString().padStart(2, "0")}/${year}`,
|
||||
status: "Open",
|
||||
};
|
||||
console.log("req", reqData, data.month);
|
||||
|
|
@ -214,15 +223,10 @@ export default function EditMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ import Swal from "sweetalert2";
|
|||
import withReactContent from "sweetalert2-react-content";
|
||||
import { error } from "@/config/swal";
|
||||
import { savePlanning } from "@/service/agenda-setting/agenda-setting";
|
||||
import month from "react-datepicker/dist/month";
|
||||
import year from "react-datepicker/dist/year";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
month: z.date({
|
||||
|
|
@ -42,6 +45,12 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
export default function CreateMonthly() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
|
|
@ -77,15 +86,15 @@ export default function CreateMonthly() {
|
|||
};
|
||||
|
||||
const save = async (data: z.infer<typeof FormSchema>) => {
|
||||
const month = new Date(data.month).getMonth() + 1;
|
||||
const year = new Date(data.month).getFullYear();
|
||||
const reqData = {
|
||||
planningTypeId: 1,
|
||||
title: data.title,
|
||||
time: "3",
|
||||
description: data.detail,
|
||||
username: "",
|
||||
date: `${new Date(data.month).getMonth() + 1}/${new Date(
|
||||
data.month
|
||||
).getFullYear()}`,
|
||||
// username: "",
|
||||
date: `${month.toString().padStart(2, "0")}/${year}`,
|
||||
status: "Open",
|
||||
};
|
||||
console.log("req", reqData, data.month);
|
||||
|
|
@ -110,6 +119,7 @@ export default function CreateMonthly() {
|
|||
|
||||
const handleMonthSelect = (selectedDate: Date | undefined) => {
|
||||
if (!selectedDate) return;
|
||||
// Set ke tanggal 1 agar tidak ada hari yang diambil
|
||||
const newDate = new Date(
|
||||
selectedDate.getFullYear(),
|
||||
selectedDate.getMonth(),
|
||||
|
|
@ -198,15 +208,10 @@ export default function CreateMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import {
|
|||
import dayjs from "dayjs";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import { useParams } from "next/navigation";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
week: z.object({
|
||||
|
|
@ -61,7 +62,15 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
export default function DetailMonthly() {
|
||||
|
||||
const ViewEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/view-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function DetailWeekly() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
|
|
@ -227,16 +236,10 @@ export default function DetailMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
config={{ readonly: true }}
|
||||
/>
|
||||
<ViewEditor initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import {
|
|||
import dayjs from "dayjs";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import { useParams } from "next/navigation";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
week: z.object({
|
||||
|
|
@ -61,7 +62,14 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
export default function EditMonthly() {
|
||||
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
export default function EditWeekly() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
|
|
@ -225,15 +233,10 @@ export default function EditMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -42,6 +42,14 @@ import {
|
|||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import dayjs from "dayjs";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
const FormSchema = z.object({
|
||||
week: z.object({
|
||||
|
|
@ -260,15 +268,10 @@ export default function CreateMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -65,6 +65,16 @@ const columns: ColumnDef<any>[] = [
|
|||
Detail
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||
<Link
|
||||
href={`/curator/task-plan/medsos-mediahub/create-daily/edit/${row.original.id}`}
|
||||
>
|
||||
Edit
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||
<a className="text-red-600">Delete</a>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,766 @@
|
|||
"use client";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Calendar } from "@/components/ui/calendar";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { Link, useRouter } from "@/i18n/routing";
|
||||
import { CalendarIcon } from "lucide-react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { format } from "date-fns";
|
||||
import JoditEditor from "jodit-react";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { z } from "zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import { getUserLevelForAssignments } from "@/service/task";
|
||||
import { list } from "postcss";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import { id } from "date-fns/locale";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import {
|
||||
getWeeklyPlanList,
|
||||
savePlanning,
|
||||
} from "@/service/agenda-setting/agenda-setting";
|
||||
import { getOnlyDate } from "@/utils/globals";
|
||||
import { useParams } from "next/navigation";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
date: z.date({
|
||||
required_error: "Required",
|
||||
}),
|
||||
title: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
detail: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
output: z.array(z.string()).refine((value) => value.some((item) => item), {
|
||||
message: "Required",
|
||||
}),
|
||||
unit: z.array(z.string()).refine((value) => value.some((item) => item), {
|
||||
message: "Required",
|
||||
}),
|
||||
type: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
parentId: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
|
||||
const items = [
|
||||
{
|
||||
id: "2",
|
||||
label: "Audio Visual",
|
||||
},
|
||||
{
|
||||
id: "1",
|
||||
label: "Foto",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: "Audio",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
label: "Text",
|
||||
},
|
||||
];
|
||||
|
||||
const units = [
|
||||
{
|
||||
id: "1",
|
||||
label: "Mabes Polri",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
label: "Polda",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
label: "Polres",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: "Satker",
|
||||
},
|
||||
];
|
||||
|
||||
const ViewEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/view-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function DetailDaily() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [listDest, setListDest] = useState<any>([]);
|
||||
const router = useRouter();
|
||||
const [weeklyList, setWeeklyList] = useState<any>();
|
||||
const [selected, setSelected] = useState<{ [key: string]: boolean }>({});
|
||||
const [selectAll, setSelectAll] = useState<{ [key: string]: boolean }>({});
|
||||
|
||||
useEffect(() => {
|
||||
initFetch();
|
||||
}, [id]);
|
||||
|
||||
async function initFetch() {
|
||||
if (id != undefined) {
|
||||
loading();
|
||||
const res = await getPlanningById(id);
|
||||
close();
|
||||
|
||||
if (res?.data?.data != undefined) {
|
||||
const data = res?.data?.data;
|
||||
console.log("data");
|
||||
console.log("Data :", data);
|
||||
form.setValue("title", data.title);
|
||||
form.setValue("detail", data.description);
|
||||
form.setValue("date", new Date(data.date));
|
||||
form.setValue(
|
||||
"output",
|
||||
data.fileTypeOutput.split(",")?.length > 1
|
||||
? data.fileTypeOutput.split(",")
|
||||
: [data.fileTypeOutput]
|
||||
);
|
||||
form.setValue(
|
||||
"unit",
|
||||
data.assignedToLevel.split(",")?.length > 1
|
||||
? data.assignedToLevel.split(",")
|
||||
: [data.assignedToLevel]
|
||||
);
|
||||
form.setValue("type", String(data?.assignmentTypeId));
|
||||
form.setValue("parentId", String(data?.parentId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getWeeklyPlanning();
|
||||
}, []);
|
||||
|
||||
async function getWeeklyPlanning() {
|
||||
const res = await getWeeklyPlanList(new Date().getDate(), 2);
|
||||
|
||||
if (res?.data !== null) {
|
||||
const rawUser = res?.data?.data;
|
||||
const optionArr = rawUser.map((option: any) => ({
|
||||
id: option.id,
|
||||
label: option.title,
|
||||
value: String(option.id),
|
||||
}));
|
||||
setWeeklyList(optionArr);
|
||||
}
|
||||
}
|
||||
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
unit: [],
|
||||
output: [],
|
||||
detail: "",
|
||||
},
|
||||
});
|
||||
const editor = useRef(null);
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof FormSchema>) => {
|
||||
console.log("data", data);
|
||||
if (form.getValues("detail") == "") {
|
||||
form.setError("detail", {
|
||||
type: "manual",
|
||||
message: "Required",
|
||||
});
|
||||
} else {
|
||||
MySwal.fire({
|
||||
title: "Simpan Data",
|
||||
text: "Apakah Anda yakin ingin menyimpan data ini?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Simpan",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const save = async (data: z.infer<typeof FormSchema>) => {
|
||||
const getSelectedString = () => {
|
||||
return Object.keys(selected)
|
||||
.filter((key) => selected[key])
|
||||
.join(", ");
|
||||
};
|
||||
console.log("data", data, selected);
|
||||
loading();
|
||||
|
||||
const reqData = {
|
||||
planningTypeId: 2,
|
||||
time: "1",
|
||||
title: data.title,
|
||||
assignmentTypeId: data.type, //string
|
||||
description: data.detail,
|
||||
assignedToLevel: unit?.join(","), //string
|
||||
assignmentPurpose: getSelectedString(), //string
|
||||
fileTypeOutput: data.output?.join(","), //string
|
||||
status: "Open",
|
||||
date: getOnlyDate(data.date),
|
||||
// date:
|
||||
// isPublish || isUpdate
|
||||
// ? selectedDate?.length > 10
|
||||
// ? data.date?.toISOString().slice(0, 10)
|
||||
// : selectedDate
|
||||
// : data.date?.toISOString().slice(0, 10),
|
||||
parentId: Number(data.parentId), //number
|
||||
assignmentMainTypeId: 1,
|
||||
};
|
||||
|
||||
console.log("req =>", reqData);
|
||||
const response = await savePlanning(reqData);
|
||||
|
||||
if (response?.error) {
|
||||
error(response?.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
close();
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
router.push("/curator/task-plan/mediahub");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const output = form.watch("output");
|
||||
|
||||
const isAllChecked = items.every((item) => output?.includes(item.id));
|
||||
|
||||
const unit = form.watch("unit");
|
||||
|
||||
const isAllUnitChecked = units.every((item) => unit?.includes(item.id));
|
||||
|
||||
const handleAllCheckedChange = (checked: boolean | string) => {
|
||||
if (checked) {
|
||||
form.setValue(
|
||||
"output",
|
||||
items.map((item) => item.id)
|
||||
);
|
||||
} else {
|
||||
form.setValue("output", []);
|
||||
}
|
||||
};
|
||||
|
||||
const handleItemCheckedChange = (id: string, checked: boolean | string) => {
|
||||
form.setValue(
|
||||
"output",
|
||||
checked ? [...output, id] : output.filter((value) => value !== id)
|
||||
);
|
||||
};
|
||||
|
||||
const handleAllUnitCheckedChange = (checked: boolean | string) => {
|
||||
if (checked) {
|
||||
form.setValue(
|
||||
"unit",
|
||||
units.map((item) => item.id)
|
||||
);
|
||||
} else {
|
||||
form.setValue("unit", []);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUnitCheckedChange = (id: string, checked: boolean | string) => {
|
||||
if (checked) {
|
||||
form.setValue("unit", [...unit, id]);
|
||||
} else {
|
||||
if (id == "2") {
|
||||
const temp = [];
|
||||
for (const element of unit) {
|
||||
if (element == "1") {
|
||||
temp.push("1");
|
||||
}
|
||||
}
|
||||
form.setValue("unit", temp);
|
||||
} else {
|
||||
form.setValue(
|
||||
"unit",
|
||||
unit.filter((value) => value !== id)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
async function initState() {
|
||||
const response = await getUserLevelForAssignments();
|
||||
setListDest(response?.data?.data.list);
|
||||
}
|
||||
|
||||
initState();
|
||||
}, []);
|
||||
|
||||
const handleParentChange = (listId: string) => {
|
||||
setSelected((prev) => ({
|
||||
...prev,
|
||||
[listId]: !prev[listId],
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSelectAllPolres = (listId: string, isChecked: boolean) => {
|
||||
setSelectAll((prev) => ({
|
||||
...prev,
|
||||
[listId]: isChecked,
|
||||
}));
|
||||
|
||||
setSelected((prev) => {
|
||||
const updatedState = { ...prev };
|
||||
listDest
|
||||
.find((list: any) => list.id === listId)
|
||||
?.subDestination.forEach((subDes: any) => {
|
||||
updatedState[`${listId}${subDes.id}`] = isChecked;
|
||||
});
|
||||
return updatedState;
|
||||
});
|
||||
};
|
||||
|
||||
const handleChildChange = (childId: string) => {
|
||||
setSelected((prev) => ({
|
||||
...prev,
|
||||
[childId]: !prev[childId],
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-col bg-white gap-2 p-6">
|
||||
<p className="text-lg">Perencanaan MediaHub</p>
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Judul Perencanaan</FormLabel>
|
||||
<Input
|
||||
value={field.value}
|
||||
placeholder="Masukkan Judul Perencanaan"
|
||||
onChange={field.onChange}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="output"
|
||||
render={() => (
|
||||
<FormItem>
|
||||
<div className="mb-4">
|
||||
<FormLabel className="text-sm">Output Tugas</FormLabel>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 items-center ">
|
||||
<div className="flex items-center gap-3">
|
||||
<Checkbox
|
||||
id="all"
|
||||
checked={isAllChecked}
|
||||
onCheckedChange={(checked) =>
|
||||
handleAllCheckedChange(checked)
|
||||
}
|
||||
disabled
|
||||
/>
|
||||
<label htmlFor="all" className="text-sm">
|
||||
Semua
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{items.map((item) => (
|
||||
<FormField
|
||||
key={item.id}
|
||||
control={form.control}
|
||||
name="output"
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormItem
|
||||
key={item.id}
|
||||
className="flex flex-row items-start space-x-3 space-y-0"
|
||||
>
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={output?.includes(item.id)}
|
||||
onCheckedChange={(checked) =>
|
||||
handleItemCheckedChange(item.id, checked)
|
||||
}
|
||||
disabled
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
{item.label}
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="unit"
|
||||
render={() => (
|
||||
<FormItem>
|
||||
<div className="mb-4">
|
||||
<FormLabel className="text-sm">Pelaksana Tugas</FormLabel>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 items-center ">
|
||||
<div className="flex items-center gap-3">
|
||||
<Checkbox
|
||||
id="all"
|
||||
checked={isAllUnitChecked}
|
||||
onCheckedChange={(checked) =>
|
||||
handleAllUnitCheckedChange(checked)
|
||||
}
|
||||
disabled
|
||||
/>
|
||||
<label htmlFor="all" className="text-sm">
|
||||
Semua
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{units.map((item) => (
|
||||
<FormField
|
||||
key={item.id}
|
||||
control={form.control}
|
||||
name="unit"
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormItem
|
||||
key={item.id}
|
||||
className="flex flex-row items-start space-x-3 space-y-0"
|
||||
>
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={unit?.includes(item.id)}
|
||||
// disabled={
|
||||
// item.id === "3" && !unit.includes("2")
|
||||
// }
|
||||
onCheckedChange={(checked) =>
|
||||
handleUnitCheckedChange(item.id, checked)
|
||||
}
|
||||
disabled
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
{item.label}
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<Dialog>
|
||||
<DialogTrigger disabled>
|
||||
<a className="text-primary cursor-pointer text-sm">
|
||||
{`[Kustom]`}
|
||||
</a>
|
||||
</DialogTrigger>
|
||||
<DialogContent size="md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Daftar Wilayah Polda dan Polres
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="grid grid-cols-2 gap-4 py-4 px-2 max-h-[600px] overflow-y-auto custom-scrollbar-table">
|
||||
{listDest?.map((list: any) => (
|
||||
<div key={list.id}>
|
||||
<Accordion
|
||||
type="single"
|
||||
collapsible
|
||||
className="h-fit border-none"
|
||||
>
|
||||
<AccordionItem
|
||||
value={list.name}
|
||||
className="border-none"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id={list.id}
|
||||
name={`all${list.id}`}
|
||||
checked={
|
||||
unit.includes("2")
|
||||
? true
|
||||
: !!selected[list.id]
|
||||
}
|
||||
onCheckedChange={() =>
|
||||
handleParentChange(list.id)
|
||||
}
|
||||
disabled={unit.includes("2")}
|
||||
/>
|
||||
<label
|
||||
htmlFor={list.name}
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
{list.name}
|
||||
</label>
|
||||
<AccordionTrigger className="w-fit bg-transparent"></AccordionTrigger>
|
||||
</div>
|
||||
<AccordionContent>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
checked={
|
||||
unit.includes("3")
|
||||
? true
|
||||
: !!selectAll[list.id]
|
||||
}
|
||||
onCheckedChange={(e) =>
|
||||
handleSelectAllPolres(
|
||||
list.id,
|
||||
Boolean(e)
|
||||
)
|
||||
}
|
||||
disabled={unit.includes("3")}
|
||||
/>
|
||||
<label
|
||||
htmlFor="all-polres"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
Pilih Semua Polres
|
||||
</label>
|
||||
</div>
|
||||
{list.subDestination.map(
|
||||
(subDes: any) => (
|
||||
<div
|
||||
key={subDes.id}
|
||||
className="flex items-center space-x-2"
|
||||
>
|
||||
<Checkbox
|
||||
id={`${list.id}${subDes.id}`}
|
||||
checked={
|
||||
unit.includes("3")
|
||||
? true
|
||||
: !!selected[
|
||||
`${list.id}${subDes.id}`
|
||||
]
|
||||
}
|
||||
onCheckedChange={() =>
|
||||
handleChildChange(
|
||||
`${list.id}${subDes.id}`
|
||||
)
|
||||
}
|
||||
disabled={unit.includes("3")}
|
||||
/>
|
||||
<label
|
||||
htmlFor={`${list.id}${subDes.id}`}
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
{subDes.name}
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="type"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Jenis Penugasan</FormLabel>
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
className="flex flex-row gap-3"
|
||||
disabled
|
||||
>
|
||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<RadioGroupItem value="1" />
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
Publikasi
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<RadioGroupItem value="2" />
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
Amplifikasi
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<RadioGroupItem value="3" />
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">Kontra</FormLabel>
|
||||
</FormItem>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="date"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-col">
|
||||
<FormLabel>Pilih Tanggal</FormLabel>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant={"outline"}
|
||||
className={cn(
|
||||
"w-[280px] justify-start text-left font-normal",
|
||||
!field.value && "text-muted-foreground"
|
||||
)}
|
||||
disabled
|
||||
>
|
||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||
{field.value ? (
|
||||
format(field.value, "PPP")
|
||||
) : (
|
||||
<span>Masukkan Tanggal</span>
|
||||
)}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={field.value}
|
||||
onSelect={field.onChange}
|
||||
initialFocus
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="parentId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Perencanaan Mingguan</FormLabel>
|
||||
<Select
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
disabled
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{weeklyList?.map((list: any) => (
|
||||
<SelectItem key={list.id} value={list.value}>
|
||||
{list.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<ViewEditor initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<div className="flex flex-row gap-2 justify-end mt-4 pt-4">
|
||||
<Button
|
||||
onClick={() => router.back()}
|
||||
variant="outline"
|
||||
color="destructive"
|
||||
type="button"
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,771 @@
|
|||
"use client";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Calendar } from "@/components/ui/calendar";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { Link, useRouter } from "@/i18n/routing";
|
||||
import { CalendarIcon } from "lucide-react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { format } from "date-fns";
|
||||
import JoditEditor from "jodit-react";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { z } from "zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import { getUserLevelForAssignments } from "@/service/task";
|
||||
import { list } from "postcss";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import { id, te } from "date-fns/locale";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import {
|
||||
getWeeklyPlanList,
|
||||
savePlanning,
|
||||
} from "@/service/agenda-setting/agenda-setting";
|
||||
import { getOnlyDate } from "@/utils/globals";
|
||||
import { useParams } from "next/navigation";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
date: z.date({
|
||||
required_error: "Required",
|
||||
}),
|
||||
title: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
detail: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
output: z.array(z.string()).refine((value) => value.some((item) => item), {
|
||||
message: "Required",
|
||||
}),
|
||||
unit: z.array(z.string()).refine((value) => value.some((item) => item), {
|
||||
message: "Required",
|
||||
}),
|
||||
type: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
parentId: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
|
||||
const items = [
|
||||
{
|
||||
id: "2",
|
||||
label: "Audio Visual",
|
||||
},
|
||||
{
|
||||
id: "1",
|
||||
label: "Foto",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: "Audio",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
label: "Text",
|
||||
},
|
||||
];
|
||||
|
||||
const units = [
|
||||
{
|
||||
id: "1",
|
||||
label: "Mabes Polri",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
label: "Polda",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
label: "Polres",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: "Satker",
|
||||
},
|
||||
];
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function EditDaily() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [listDest, setListDest] = useState<any>([]);
|
||||
const router = useRouter();
|
||||
const [weeklyList, setWeeklyList] = useState<any>();
|
||||
const [selected, setSelected] = useState<{ [key: string]: boolean }>({});
|
||||
const [selectAll, setSelectAll] = useState<{ [key: string]: boolean }>({});
|
||||
|
||||
useEffect(() => {
|
||||
initFetch();
|
||||
}, [id]);
|
||||
|
||||
async function initFetch() {
|
||||
if (id != undefined) {
|
||||
loading();
|
||||
const res = await getPlanningById(id);
|
||||
close();
|
||||
|
||||
if (res?.data?.data != undefined) {
|
||||
const data = res?.data?.data;
|
||||
console.log("data");
|
||||
console.log("Data :", data);
|
||||
form.setValue("title", data.title);
|
||||
form.setValue("detail", data.description);
|
||||
form.setValue("date", new Date(data.date));
|
||||
form.setValue(
|
||||
"output",
|
||||
data.fileTypeOutput.split(",")?.length > 1
|
||||
? data.fileTypeOutput.split(",")
|
||||
: [data.fileTypeOutput]
|
||||
);
|
||||
form.setValue("type", String(data?.assignmentTypeId));
|
||||
form.setValue("parentId", String(data?.parentId));
|
||||
mapTopDestination(data?.assignedToLevel);
|
||||
mapDestination(data?.assignedToTopLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mapTopDestination = (data: string) => {
|
||||
const temp: string[] = [];
|
||||
data.split(",").map((list) => {
|
||||
if (list.length < 2) {
|
||||
temp.push(list);
|
||||
}
|
||||
});
|
||||
form.setValue("unit", temp);
|
||||
};
|
||||
|
||||
const mapDestination = (data: string) => {
|
||||
const temp: { [key: number]: boolean } = {};
|
||||
data.split(",").forEach((list) => {
|
||||
temp[Number(list)] = true;
|
||||
});
|
||||
setSelected(temp);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getWeeklyPlanning();
|
||||
}, []);
|
||||
|
||||
async function getWeeklyPlanning() {
|
||||
const res = await getWeeklyPlanList(new Date().getDate(), 2);
|
||||
|
||||
if (res?.data !== null) {
|
||||
const rawUser = res?.data?.data;
|
||||
const optionArr = rawUser.map((option: any) => ({
|
||||
id: option.id,
|
||||
label: option.title,
|
||||
value: String(option.id),
|
||||
}));
|
||||
setWeeklyList(optionArr);
|
||||
}
|
||||
}
|
||||
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
unit: [],
|
||||
output: [],
|
||||
detail: "",
|
||||
},
|
||||
});
|
||||
const editor = useRef(null);
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof FormSchema>) => {
|
||||
console.log("data", data);
|
||||
if (form.getValues("detail") == "") {
|
||||
form.setError("detail", {
|
||||
type: "manual",
|
||||
message: "Required",
|
||||
});
|
||||
} else {
|
||||
MySwal.fire({
|
||||
title: "Simpan Data",
|
||||
text: "Apakah Anda yakin ingin menyimpan data ini?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Simpan",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const save = async (data: z.infer<typeof FormSchema>) => {
|
||||
const getSelectedString = () => {
|
||||
return Object.keys(selected)
|
||||
.filter((key) => selected[key])
|
||||
.join(", ");
|
||||
};
|
||||
console.log("data", data, selected);
|
||||
loading();
|
||||
|
||||
const reqData = {
|
||||
id: id,
|
||||
planningTypeId: 2,
|
||||
time: "1",
|
||||
title: data.title,
|
||||
assignmentTypeId: data.type, //string
|
||||
description: data.detail,
|
||||
assignedToLevel: unit?.join(","), //string
|
||||
assignmentPurpose: getSelectedString(), //string
|
||||
fileTypeOutput: data.output?.join(","), //string
|
||||
status: "Open",
|
||||
date: getOnlyDate(data.date),
|
||||
// date:
|
||||
// isPublish || isUpdate
|
||||
// ? selectedDate?.length > 10
|
||||
// ? data.date?.toISOString().slice(0, 10)
|
||||
// : selectedDate
|
||||
// : data.date?.toISOString().slice(0, 10),
|
||||
parentId: Number(data.parentId), //number
|
||||
assignmentMainTypeId: 1,
|
||||
};
|
||||
|
||||
const response = await savePlanning(reqData);
|
||||
|
||||
if (response?.error) {
|
||||
error(response?.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
close();
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
router.push("/curator/task-plan/mediahub");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const output = form.watch("output");
|
||||
|
||||
const isAllChecked = items.every((item) => output?.includes(item.id));
|
||||
|
||||
const unit = form.watch("unit");
|
||||
|
||||
const isAllUnitChecked = units.every((item) => unit?.includes(item.id));
|
||||
|
||||
const handleAllCheckedChange = (checked: boolean | string) => {
|
||||
if (checked) {
|
||||
form.setValue(
|
||||
"output",
|
||||
items.map((item) => item.id)
|
||||
);
|
||||
} else {
|
||||
form.setValue("output", []);
|
||||
}
|
||||
};
|
||||
|
||||
const handleItemCheckedChange = (id: string, checked: boolean | string) => {
|
||||
form.setValue(
|
||||
"output",
|
||||
checked ? [...output, id] : output.filter((value) => value !== id)
|
||||
);
|
||||
};
|
||||
|
||||
const handleAllUnitCheckedChange = (checked: boolean | string) => {
|
||||
if (checked) {
|
||||
form.setValue(
|
||||
"unit",
|
||||
units.map((item) => item.id)
|
||||
);
|
||||
} else {
|
||||
form.setValue("unit", []);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUnitCheckedChange = (id: string, checked: boolean | string) => {
|
||||
if (checked) {
|
||||
form.setValue("unit", [...unit, id]);
|
||||
} else {
|
||||
if (id == "2") {
|
||||
const temp = [];
|
||||
for (const element of unit) {
|
||||
if (element == "1") {
|
||||
temp.push("1");
|
||||
}
|
||||
}
|
||||
form.setValue("unit", temp);
|
||||
} else {
|
||||
form.setValue(
|
||||
"unit",
|
||||
unit.filter((value) => value !== id)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
async function initState() {
|
||||
const response = await getUserLevelForAssignments();
|
||||
setListDest(response?.data?.data.list);
|
||||
}
|
||||
|
||||
initState();
|
||||
}, []);
|
||||
|
||||
const handleParentChange = (listId: string) => {
|
||||
setSelected((prev) => ({
|
||||
...prev,
|
||||
[listId]: !prev[listId],
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSelectAllPolres = (listId: string, isChecked: boolean) => {
|
||||
setSelectAll((prev) => ({
|
||||
...prev,
|
||||
[listId]: isChecked,
|
||||
}));
|
||||
|
||||
setSelected((prev) => {
|
||||
const updatedState = { ...prev };
|
||||
listDest
|
||||
.find((list: any) => list.id === listId)
|
||||
?.subDestination.forEach((subDes: any) => {
|
||||
updatedState[`${listId}${subDes.id}`] = isChecked;
|
||||
});
|
||||
return updatedState;
|
||||
});
|
||||
};
|
||||
|
||||
const handleChildChange = (childId: string) => {
|
||||
setSelected((prev) => ({
|
||||
...prev,
|
||||
[childId]: !prev[childId],
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-col bg-white gap-2 p-6">
|
||||
<p className="text-lg">Perencanaan MediaHub</p>
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Judul Perencanaan</FormLabel>
|
||||
<Input
|
||||
value={field.value}
|
||||
placeholder="Masukkan Judul Perencanaan"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="output"
|
||||
render={() => (
|
||||
<FormItem>
|
||||
<div className="mb-4">
|
||||
<FormLabel className="text-sm">Output Tugas</FormLabel>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 items-center ">
|
||||
<div className="flex items-center gap-3">
|
||||
<Checkbox
|
||||
id="all"
|
||||
checked={isAllChecked}
|
||||
onCheckedChange={(checked) =>
|
||||
handleAllCheckedChange(checked)
|
||||
}
|
||||
/>
|
||||
<label htmlFor="all" className="text-sm">
|
||||
Semua
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{items.map((item) => (
|
||||
<FormField
|
||||
key={item.id}
|
||||
control={form.control}
|
||||
name="output"
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormItem
|
||||
key={item.id}
|
||||
className="flex flex-row items-start space-x-3 space-y-0"
|
||||
>
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={output?.includes(item.id)}
|
||||
onCheckedChange={(checked) =>
|
||||
handleItemCheckedChange(item.id, checked)
|
||||
}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
{item.label}
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="unit"
|
||||
render={() => (
|
||||
<FormItem>
|
||||
<div className="mb-4">
|
||||
<FormLabel className="text-sm">Pelaksana Tugas</FormLabel>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 items-center ">
|
||||
<div className="flex items-center gap-3">
|
||||
<Checkbox
|
||||
id="all"
|
||||
checked={isAllUnitChecked}
|
||||
onCheckedChange={(checked) =>
|
||||
handleAllUnitCheckedChange(checked)
|
||||
}
|
||||
/>
|
||||
<label htmlFor="all" className="text-sm">
|
||||
Semua
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{units.map((item) => (
|
||||
<FormField
|
||||
key={item.id}
|
||||
control={form.control}
|
||||
name="unit"
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormItem
|
||||
key={item.id}
|
||||
className="flex flex-row items-start space-x-3 space-y-0"
|
||||
>
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={unit?.includes(item.id)}
|
||||
disabled={
|
||||
item.id === "3" && !unit.includes("2")
|
||||
}
|
||||
onCheckedChange={(checked) =>
|
||||
handleUnitCheckedChange(item.id, checked)
|
||||
}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
{item.label}
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<Dialog>
|
||||
<DialogTrigger>
|
||||
<a className="text-primary cursor-pointer text-sm">
|
||||
{`[Kustom]`}
|
||||
</a>
|
||||
</DialogTrigger>
|
||||
<DialogContent size="md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Daftar Wilayah Polda dan Polres
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="grid grid-cols-2 gap-4 py-4 px-2 max-h-[600px] overflow-y-auto custom-scrollbar-table">
|
||||
{listDest?.map((list: any) => (
|
||||
<div key={list.id}>
|
||||
<Accordion
|
||||
type="single"
|
||||
collapsible
|
||||
className="h-fit border-none"
|
||||
>
|
||||
<AccordionItem
|
||||
value={list.name}
|
||||
className="border-none"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id={list.id}
|
||||
name={`all${list.id}`}
|
||||
checked={
|
||||
unit.includes("2")
|
||||
? true
|
||||
: !!selected[list.id]
|
||||
}
|
||||
onCheckedChange={() =>
|
||||
handleParentChange(list.id)
|
||||
}
|
||||
disabled={unit.includes("2")}
|
||||
/>
|
||||
<label
|
||||
htmlFor={list.name}
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
{list.name}
|
||||
</label>
|
||||
<AccordionTrigger className="w-fit bg-transparent"></AccordionTrigger>
|
||||
</div>
|
||||
<AccordionContent>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
checked={
|
||||
unit.includes("3")
|
||||
? true
|
||||
: !!selectAll[list.id]
|
||||
}
|
||||
onCheckedChange={(e) =>
|
||||
handleSelectAllPolres(
|
||||
list.id,
|
||||
Boolean(e)
|
||||
)
|
||||
}
|
||||
disabled={unit.includes("3")}
|
||||
/>
|
||||
<label
|
||||
htmlFor="all-polres"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
Pilih Semua Polres
|
||||
</label>
|
||||
</div>
|
||||
{list.subDestination.map(
|
||||
(subDes: any) => (
|
||||
<div
|
||||
key={subDes.id}
|
||||
className="flex items-center space-x-2"
|
||||
>
|
||||
<Checkbox
|
||||
id={`${list.id}${subDes.id}`}
|
||||
checked={
|
||||
unit.includes("3")
|
||||
? true
|
||||
: !!selected[
|
||||
`${list.id}${subDes.id}`
|
||||
]
|
||||
}
|
||||
onCheckedChange={() =>
|
||||
handleChildChange(
|
||||
`${list.id}${subDes.id}`
|
||||
)
|
||||
}
|
||||
disabled={unit.includes("3")}
|
||||
/>
|
||||
<label
|
||||
htmlFor={`${list.id}${subDes.id}`}
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
{subDes.name}
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="type"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Jenis Penugasan</FormLabel>
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
className="flex flex-row gap-3"
|
||||
>
|
||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<RadioGroupItem value="1" />
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
Publikasi
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<RadioGroupItem value="2" />
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
Amplifikasi
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<RadioGroupItem value="3" />
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">Kontra</FormLabel>
|
||||
</FormItem>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="date"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-col">
|
||||
<FormLabel>Pilih Tanggal</FormLabel>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant={"outline"}
|
||||
className={cn(
|
||||
"w-[280px] justify-start text-left font-normal",
|
||||
!field.value && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||
{field.value ? (
|
||||
format(field.value, "PPP")
|
||||
) : (
|
||||
<span>Masukkan Tanggal</span>
|
||||
)}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={field.value}
|
||||
onSelect={field.onChange}
|
||||
initialFocus
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="parentId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Perencanaan Mingguan</FormLabel>
|
||||
<Select value={field.value} onValueChange={field.onChange}>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{weeklyList?.map((list: any) => (
|
||||
<SelectItem key={list.id} value={list.value}>
|
||||
{list.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<div className="flex flex-row gap-2 justify-end mt-4 pt-4">
|
||||
<Button
|
||||
onClick={() => router.back()}
|
||||
variant="outline"
|
||||
color="destructive"
|
||||
type="button"
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
<Button type="submit" color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -58,6 +58,7 @@ import {
|
|||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import { getUserLevelForAssignments } from "@/service/task";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
date: z.date({
|
||||
|
|
@ -141,8 +142,20 @@ const units = [
|
|||
id: "3",
|
||||
label: "Polres",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: "Satker",
|
||||
},
|
||||
];
|
||||
export default function CreateMonthly() {
|
||||
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function CreateDaily() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [weeklyList, setWeeklyList] = useState<any>();
|
||||
const router = useRouter();
|
||||
|
|
@ -760,15 +773,10 @@ export default function CreateMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import { close, error, loading } from "@/config/swal";
|
|||
import { savePlanning } from "@/service/agenda-setting/agenda-setting";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import { useParams } from "next/navigation";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
month: z.date({
|
||||
|
|
@ -44,6 +45,13 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
|
||||
const ViewEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/view-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
export default function DetailMonthly() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
|
@ -108,15 +116,15 @@ export default function DetailMonthly() {
|
|||
};
|
||||
|
||||
const save = async (data: z.infer<typeof FormSchema>) => {
|
||||
const month = new Date(data.month).getMonth() + 1;
|
||||
const year = new Date(data.month).getFullYear();
|
||||
const reqData = {
|
||||
planningTypeId: 1,
|
||||
title: data.title,
|
||||
time: "3",
|
||||
description: data.detail,
|
||||
username: "",
|
||||
date: `${new Date(data.month).getMonth() + 1}/${new Date(
|
||||
data.month
|
||||
).getFullYear()}`,
|
||||
date: `${month.toString().padStart(2, "0")}/${year}`,
|
||||
status: "Open",
|
||||
};
|
||||
console.log("req", reqData, data.month);
|
||||
|
|
@ -215,16 +223,10 @@ export default function DetailMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
config={{ readonly: true }}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<ViewEditor initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import { close, error, loading } from "@/config/swal";
|
|||
import { savePlanning } from "@/service/agenda-setting/agenda-setting";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import { useParams } from "next/navigation";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
month: z.date({
|
||||
|
|
@ -44,6 +45,13 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
export default function EditMonthly() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
|
@ -108,6 +116,8 @@ export default function EditMonthly() {
|
|||
};
|
||||
|
||||
const save = async (data: z.infer<typeof FormSchema>) => {
|
||||
const month = new Date(data.month).getMonth() + 1;
|
||||
const year = new Date(data.month).getFullYear();
|
||||
const reqData = {
|
||||
id: id,
|
||||
planningTypeId: 1,
|
||||
|
|
@ -115,9 +125,7 @@ export default function EditMonthly() {
|
|||
time: "3",
|
||||
description: data.detail,
|
||||
username: "",
|
||||
date: `${new Date(data.month).getMonth() + 1}/${new Date(
|
||||
data.month
|
||||
).getFullYear()}`,
|
||||
date: `${month.toString().padStart(2, "0")}/${year}`,
|
||||
status: "Open",
|
||||
};
|
||||
console.log("req", reqData, data.month);
|
||||
|
|
@ -214,15 +222,10 @@ export default function EditMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import Swal from "sweetalert2";
|
|||
import withReactContent from "sweetalert2-react-content";
|
||||
import { error } from "@/config/swal";
|
||||
import { savePlanning } from "@/service/agenda-setting/agenda-setting";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
month: z.date({
|
||||
|
|
@ -42,6 +43,12 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
export default function CreateMonthly() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
|
|
@ -77,15 +84,15 @@ export default function CreateMonthly() {
|
|||
};
|
||||
|
||||
const save = async (data: z.infer<typeof FormSchema>) => {
|
||||
const month = new Date(data.month).getMonth() + 1;
|
||||
const year = new Date(data.month).getFullYear();
|
||||
const reqData = {
|
||||
planningTypeId: 2,
|
||||
title: data.title,
|
||||
time: "3",
|
||||
description: data.detail,
|
||||
username: "",
|
||||
date: `${new Date(data.month).getMonth() + 1}/${new Date(
|
||||
data.month
|
||||
).getFullYear()}`,
|
||||
date: `${month.toString().padStart(2, "0")}/${year}`,
|
||||
status: "Open",
|
||||
};
|
||||
console.log("req", reqData, data.month);
|
||||
|
|
@ -198,15 +205,10 @@ export default function CreateMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import {
|
|||
import dayjs from "dayjs";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import { useParams } from "next/navigation";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
week: z.object({
|
||||
|
|
@ -61,7 +62,15 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
export default function DetailMonthly() {
|
||||
|
||||
const ViewEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/view-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function DetailWeekly() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
|
|
@ -227,16 +236,10 @@ export default function DetailMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
config={{ readonly: true }}
|
||||
/>
|
||||
<ViewEditor initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import {
|
|||
import dayjs from "dayjs";
|
||||
import { getPlanningById } from "@/service/planning/planning";
|
||||
import { useParams } from "next/navigation";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
week: z.object({
|
||||
|
|
@ -61,7 +62,13 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
export default function EditMonthly() {
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
export default function EditWeekly() {
|
||||
const id = useParams()?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
|
|
@ -225,15 +232,10 @@ export default function EditMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import {
|
|||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const FormSchema = z.object({
|
||||
week: z.object({
|
||||
|
|
@ -61,6 +62,12 @@ const FormSchema = z.object({
|
|||
required_error: "Required",
|
||||
}),
|
||||
});
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
return import("@/components/editor/custom-editor");
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
export default function CreateMonthly() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
|
|
@ -261,15 +268,10 @@ export default function CreateMonthly() {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="detail"
|
||||
render={({ field }) => (
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Detail Perencanaan</FormLabel>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={field.value}
|
||||
className="dark:text-black"
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<CustomEditor onChange={onChange} initialData={value} />
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const Home = ({ params: { locale } }: { params: { locale: string } }) => {
|
|||
<NewContent group="mabes" type="latest" />
|
||||
<NewContent group="mabes" type="popular" />
|
||||
{/* <PopularContent /> */}
|
||||
<ContentCategory group="mabes" />
|
||||
<ContentCategory group="mabes" type="popular" />
|
||||
{/* <Coverage /> */}
|
||||
{/* <Division /> */}
|
||||
<AreaCoverageWorkUnits />
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ const AreaCoverageWorkUnits = () => {
|
|||
</h2>
|
||||
<div className="h-1 w-[250px] bg-[#bb3523] mx-auto mb-6 rounded"></div>
|
||||
<div className="flex flex-col justify-center lg:flex-row gap-8">
|
||||
<div>
|
||||
{/* POLDA */}
|
||||
<Dialog open={openPolda} onOpenChange={setOpenPolda}>
|
||||
<DialogTrigger className="flex flex-col gap-2 justify-center items-center shadow-lg group rounded-xl py-5 px-24 border-2 border-transparent hover:border-[#bb3523] transition-all duration-300">
|
||||
|
|
@ -67,7 +68,7 @@ const AreaCoverageWorkUnits = () => {
|
|||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
</div>
|
||||
{/* SATKER */}
|
||||
<Dialog open={openSatker} onOpenChange={setOpenSatker}>
|
||||
<DialogTrigger className="flex flex-col gap-2 justify-center items-center shadow-lg group rounded-xl py-5 px-24 border-2 border-transparent hover:border-[#bb3523] transition-all duration-300">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
import { getCategoryData, getPublicCategoryData } from "@/service/landing/landing";
|
||||
import {
|
||||
getCategoryData,
|
||||
getPublicCategoryData,
|
||||
} from "@/service/landing/landing";
|
||||
import Link from "next/link";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Button } from "../ui/button";
|
||||
|
|
@ -7,26 +10,45 @@ import { useTranslations } from "next-intl";
|
|||
import { usePathname } from "next/navigation";
|
||||
import { useParams } from "next/navigation";
|
||||
import Image from "next/image";
|
||||
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "../ui/carousel";
|
||||
import {
|
||||
Carousel,
|
||||
CarouselContent,
|
||||
CarouselItem,
|
||||
CarouselNext,
|
||||
CarouselPrevious,
|
||||
} from "../ui/carousel";
|
||||
import { useRouter } from "@/i18n/routing";
|
||||
|
||||
const ContentCategory = (props: { group?: string }) => {
|
||||
const ContentCategory = (props: { group?: string; type: string }) => {
|
||||
const [categories, setCategories] = useState<any>();
|
||||
const t = useTranslations("LandingPage");
|
||||
const params = useParams();
|
||||
const locale = params?.locale;
|
||||
const [selectedTab, setSelectedTab] = useState("image");
|
||||
const poldaName = params?.polda_name;
|
||||
const satkerName = params?.satker_name;
|
||||
const router = useRouter();
|
||||
|
||||
let prefixPath = poldaName ? `/polda/${poldaName}` : satkerName ? `/satker/${satkerName}` : "/";
|
||||
let prefixPath = poldaName
|
||||
? `/polda/${poldaName}`
|
||||
: satkerName
|
||||
? `/satker/${satkerName}`
|
||||
: "/";
|
||||
|
||||
useEffect(() => {
|
||||
initFetch();
|
||||
}, []);
|
||||
const initFetch = async () => {
|
||||
const response = await getPublicCategoryData(
|
||||
props.group == "mabes" ? "" : props.group == "polda" && poldaName && String(poldaName)?.length > 1 ? poldaName : props.group == "satker" && satkerName && String(satkerName)?.length > 1 ? "satker-" + satkerName : "",
|
||||
props.group == "mabes"
|
||||
? ""
|
||||
: props.group == "polda" && poldaName && String(poldaName)?.length > 1
|
||||
? poldaName
|
||||
: props.group == "satker" &&
|
||||
satkerName &&
|
||||
String(satkerName)?.length > 1
|
||||
? "satker-" + satkerName
|
||||
: "",
|
||||
"",
|
||||
locale == "en" ? true : false
|
||||
);
|
||||
|
|
@ -52,7 +74,10 @@ const ContentCategory = (props: { group?: string }) => {
|
|||
<animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite" />
|
||||
</svg>`;
|
||||
|
||||
const toBase64 = (str: string) => (typeof window === "undefined" ? Buffer.from(str).toString("base64") : window.btoa(str));
|
||||
const toBase64 = (str: string) =>
|
||||
typeof window === "undefined"
|
||||
? Buffer.from(str).toString("base64")
|
||||
: window.btoa(str);
|
||||
|
||||
return (
|
||||
<div className="px-4 lg:px-24 py-10">
|
||||
|
|
@ -60,12 +85,16 @@ const ContentCategory = (props: { group?: string }) => {
|
|||
<h2 className="text-center text-xl lg:text-3xl font-bold text-[#bb3523] mb-4">
|
||||
{pathname?.split("/")[1] == "in" ? (
|
||||
<>
|
||||
<span className="text-black dark:text-white">{t("category")} </span>
|
||||
<span className="text-black dark:text-white">
|
||||
{t("category")}
|
||||
</span>
|
||||
{t("content")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-black dark:text-white">{t("content")} </span>
|
||||
<span className="text-black dark:text-white">
|
||||
{t("content")}
|
||||
</span>
|
||||
{t("category")}
|
||||
</>
|
||||
)}
|
||||
|
|
@ -76,11 +105,19 @@ const ContentCategory = (props: { group?: string }) => {
|
|||
<Carousel className="w-full max-w-full">
|
||||
<CarouselContent>
|
||||
{categories?.map((category: any) => (
|
||||
<CarouselItem key={category?.id} className="md:basis-1/2 lg:basis-1/3">
|
||||
<Link href={`all/filter?category=${category?.id}`} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg block">
|
||||
<CarouselItem
|
||||
key={category?.id}
|
||||
className="md:basis-1/2 lg:basis-1/3"
|
||||
>
|
||||
<Link
|
||||
href={`all/filter?category=${category?.id}`}
|
||||
className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg block"
|
||||
>
|
||||
{/* Gambar */}
|
||||
<Image
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||
shimmer(700, 475)
|
||||
)}`}
|
||||
alt="category"
|
||||
width={2560}
|
||||
height={1440}
|
||||
|
|
@ -93,7 +130,9 @@ const ContentCategory = (props: { group?: string }) => {
|
|||
|
||||
{/* Judul */}
|
||||
<div className="absolute bottom-5 left-0 right-16 bg-transparent backdrop-blur-md text-white p-4 border-l-2 border-[#bb3523] z-10 group-hover:scale-x-150 origin-left">
|
||||
<h3 className="text-sm font-semibold truncate">{category?.name}</h3>
|
||||
<h3 className="text-sm font-semibold truncate">
|
||||
{category?.name}
|
||||
</h3>
|
||||
</div>
|
||||
</Link>
|
||||
</CarouselItem>
|
||||
|
|
@ -110,7 +149,11 @@ const ContentCategory = (props: { group?: string }) => {
|
|||
</div> */}
|
||||
<div className="flex items-center flex-row justify-center mt-7">
|
||||
<div
|
||||
// onClick={() => router.push(prefixPath + `/${selectedTab}/filter?sortBy=${props.type}`)}
|
||||
onClick={() =>
|
||||
router.push(
|
||||
prefixPath + `/${selectedTab}/filter?sortBy=${props.type}`
|
||||
)
|
||||
}
|
||||
className="cursor-pointer border text-[#bb3523] rounded-lg text-sm lg:text-md px-4 py-1 border-[#bb3523]"
|
||||
>
|
||||
{t("seeAll")}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
export const locales = ['en', 'in', 'ar'];
|
||||
export const locales = ["in", "en", "ar"];
|
||||
|
||||
export const baseURL = process.env.NEXT_PUBLIC_SITE_URL + "/api";
|
||||
|
|
@ -1,32 +1,25 @@
|
|||
import createMiddleware from 'next-intl/middleware';
|
||||
import {NextRequest, NextResponse} from 'next/server';
|
||||
import {locales} from '@/config';
|
||||
import createMiddleware from "next-intl/middleware";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { locales } from "@/config";
|
||||
|
||||
export default async function middleware(request: NextRequest) {
|
||||
|
||||
|
||||
|
||||
|
||||
// Step 1: Use the incoming request (example)
|
||||
const defaultLocale = request.headers.get('dashcode-locale') || 'en';
|
||||
const defaultLocale = request.headers.get("dashcode-locale") || "in";
|
||||
|
||||
// Step 2: Create and call the next-intl middleware (example)
|
||||
const handleI18nRouting = createMiddleware({
|
||||
locales,
|
||||
defaultLocale
|
||||
|
||||
defaultLocale,
|
||||
});
|
||||
const response = handleI18nRouting(request);
|
||||
|
||||
// Step 3: Alter the response (example)
|
||||
response.headers.set('dashcode-locale', defaultLocale);
|
||||
|
||||
|
||||
response.headers.set("dashcode-locale", defaultLocale);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const config = {
|
||||
// Match only internationalized pathnames
|
||||
matcher: ['/', '/(ar|en|in)/:path*']
|
||||
matcher: ["/", "/(ar|in|en)/:path*"],
|
||||
};
|
||||
|
|
@ -16,6 +16,10 @@ const bundleAnalyzer = withBundleAnalyzer({
|
|||
});
|
||||
|
||||
const nextConfig = {
|
||||
// i18n: {
|
||||
// locales: ["en", "in"],
|
||||
// defaultLocale: "in",
|
||||
// },
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue