fix: fixing point 1 -4
This commit is contained in:
parent
6c5bb50661
commit
b03da630ba
|
|
@ -74,7 +74,7 @@ const TaskTable = () => {
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
React.useState<VisibilityState>({});
|
React.useState<VisibilityState>({});
|
||||||
const [rowSelection, setRowSelection] = React.useState({});
|
const [rowSelection, setRowSelection] = React.useState({});
|
||||||
const [showData, setShowData] = React.useState("50");
|
const [showData, setShowData] = React.useState("10");
|
||||||
const [pagination, setPagination] = React.useState<PaginationState>({
|
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||||
pageIndex: 0,
|
pageIndex: 0,
|
||||||
pageSize: Number(showData),
|
pageSize: Number(showData),
|
||||||
|
|
@ -206,7 +206,7 @@ const TaskTable = () => {
|
||||||
<span
|
<span
|
||||||
className={` ${
|
className={` ${
|
||||||
isSpecificAttention
|
isSpecificAttention
|
||||||
? "bg-default-900 text-white"
|
? "bg-default-900 text-white dark:text-black"
|
||||||
: "dark:text-default-700 border-2"
|
: "dark:text-default-700 border-2"
|
||||||
}
|
}
|
||||||
px-[18px] py-1 transition duration-100 rounded`}
|
px-[18px] py-1 transition duration-100 rounded`}
|
||||||
|
|
@ -217,7 +217,7 @@ const TaskTable = () => {
|
||||||
className={`
|
className={`
|
||||||
${
|
${
|
||||||
!isSpecificAttention
|
!isSpecificAttention
|
||||||
? "bg-default-900 text-white"
|
? "bg-default-900 text-white dark:text-black"
|
||||||
: " dark:text-default-700 border-2"
|
: " dark:text-default-700 border-2"
|
||||||
}
|
}
|
||||||
px-[18px] py-1 transition duration-100 rounded
|
px-[18px] py-1 transition duration-100 rounded
|
||||||
|
|
|
||||||
|
|
@ -105,12 +105,10 @@ interface FileWithPreview extends File {
|
||||||
export default function FormImageUpdate() {
|
export default function FormImageUpdate() {
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const { id } = useParams() as { id: string };
|
const { id } = useParams() as { id: string };
|
||||||
console.log(id);
|
console.log(id);
|
||||||
const editor = useRef(null);
|
const editor = useRef(null);
|
||||||
type ImageSchema = z.infer<typeof imageSchema>;
|
type ImageSchema = z.infer<typeof imageSchema>;
|
||||||
|
|
||||||
let progressInfo: any = [];
|
let progressInfo: any = [];
|
||||||
let counterUpdateProgress = 0;
|
let counterUpdateProgress = 0;
|
||||||
const [progressList, setProgressList] = useState<any>([]);
|
const [progressList, setProgressList] = useState<any>([]);
|
||||||
|
|
@ -122,7 +120,6 @@ export default function FormImageUpdate() {
|
||||||
const taskId = Cookies.get("taskId");
|
const taskId = Cookies.get("taskId");
|
||||||
const scheduleId = Cookies.get("scheduleId");
|
const scheduleId = Cookies.get("scheduleId");
|
||||||
const scheduleType = Cookies.get("scheduleType");
|
const scheduleType = Cookies.get("scheduleType");
|
||||||
|
|
||||||
const [categories, setCategories] = useState<Category[]>([]);
|
const [categories, setCategories] = useState<Category[]>([]);
|
||||||
const [selectedCategory, setSelectedCategory] = useState<any>();
|
const [selectedCategory, setSelectedCategory] = useState<any>();
|
||||||
const [tags, setTags] = useState<any[]>([]);
|
const [tags, setTags] = useState<any[]>([]);
|
||||||
|
|
@ -133,11 +130,19 @@ export default function FormImageUpdate() {
|
||||||
const [files, setFiles] = useState<FileWithPreview[]>([]);
|
const [files, setFiles] = useState<FileWithPreview[]>([]);
|
||||||
const [filesTemp, setFilesTemp] = useState<File[]>([]);
|
const [filesTemp, setFilesTemp] = useState<File[]>([]);
|
||||||
const [publishedFor, setPublishedFor] = useState<string[]>([]);
|
const [publishedFor, setPublishedFor] = useState<string[]>([]);
|
||||||
|
const [thumbnailFile, setThumbnailFile] = useState<File | null>(null);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const [selectedOptions, setSelectedOptions] = useState<{
|
const [selectedOptions, setSelectedOptions] = useState<{
|
||||||
[fileId: number]: string[];
|
[fileId: number]: string[];
|
||||||
}>({});
|
}>({});
|
||||||
|
|
||||||
|
const handleThumbnailChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const file = e.target.files?.[0];
|
||||||
|
if (file) {
|
||||||
|
setThumbnailFile(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const options: Option[] = [
|
const options: Option[] = [
|
||||||
{ id: "all", name: "SEMUA" },
|
{ id: "all", name: "SEMUA" },
|
||||||
{ id: "5", name: "UMUM" },
|
{ id: "5", name: "UMUM" },
|
||||||
|
|
@ -176,35 +181,6 @@ export default function FormImageUpdate() {
|
||||||
resolver: zodResolver(imageSchema),
|
resolver: zodResolver(imageSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
// const handleKeyDown = (e: any) => {
|
|
||||||
// const newTag = e.target.value.trim(); // Ambil nilai input
|
|
||||||
// if (e.key === "Enter" && newTag) {
|
|
||||||
// e.preventDefault(); // Hentikan submit form
|
|
||||||
// if (!tags.includes(newTag)) {
|
|
||||||
// setTags((prevTags) => [...prevTags, newTag]); // Tambah tag baru
|
|
||||||
// setValue("tags", ""); // Kosongkan input
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
if (event.target.files) {
|
|
||||||
const files = Array.from(event.target.files);
|
|
||||||
setSelectedFiles((prevImages: any) => [...prevImages, ...files]);
|
|
||||||
console.log("DATAFILE::", selectedFiles);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRemoveImage = (index: number) => {
|
|
||||||
setSelectedFiles((prevImages) => prevImages.filter((_, i) => i !== index));
|
|
||||||
};
|
|
||||||
|
|
||||||
// const handleCheckboxChange = (id: number) => {
|
|
||||||
// setSelectedPublishers((prev) =>
|
|
||||||
// prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
getCategories();
|
getCategories();
|
||||||
|
|
@ -218,9 +194,9 @@ export default function FormImageUpdate() {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const newTag = e.currentTarget.value.trim();
|
const newTag = e.currentTarget.value.trim();
|
||||||
if (!tags.includes(newTag)) {
|
if (!tags.includes(newTag)) {
|
||||||
setTags((prevTags) => [...prevTags, newTag]); // Tambahkan tag baru
|
setTags((prevTags) => [...prevTags, newTag]);
|
||||||
if (inputRef.current) {
|
if (inputRef.current) {
|
||||||
inputRef.current.value = ""; // Kosongkan input
|
inputRef.current.value = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +227,7 @@ export default function FormImageUpdate() {
|
||||||
|
|
||||||
if (findCategory) {
|
if (findCategory) {
|
||||||
// setValue("categoryId", findCategory.id);
|
// setValue("categoryId", findCategory.id);
|
||||||
setSelectedCategory(findCategory.id); // Set the selected category
|
setSelectedCategory(findCategory.id);
|
||||||
const response = await getTagsBySubCategoryId(findCategory.id);
|
const response = await getTagsBySubCategoryId(findCategory.id);
|
||||||
setTags(response?.data?.data);
|
setTags(response?.data?.data);
|
||||||
}
|
}
|
||||||
|
|
@ -268,16 +244,13 @@ export default function FormImageUpdate() {
|
||||||
const details = response?.data?.data;
|
const details = response?.data?.data;
|
||||||
|
|
||||||
setDetail(details);
|
setDetail(details);
|
||||||
|
|
||||||
// Set the selected target to the category ID from details
|
|
||||||
setSelectedTarget(String(details.category.id));
|
setSelectedTarget(String(details.category.id));
|
||||||
|
|
||||||
// Set form values immediately and then again after a delay to ensure editor is ready
|
|
||||||
setValue("title", details.title);
|
setValue("title", details.title);
|
||||||
setValue("description", details.htmlDescription);
|
setValue("description", details.htmlDescription);
|
||||||
setValue("creatorName", details.creatorName);
|
setValue("creatorName", details.creatorName);
|
||||||
|
|
||||||
// Set again after delay to ensure editor has loaded
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setValue("title", details.title);
|
setValue("title", details.title);
|
||||||
setValue("description", details.htmlDescription);
|
setValue("description", details.htmlDescription);
|
||||||
|
|
@ -307,7 +280,7 @@ export default function FormImageUpdate() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
initState();
|
initState();
|
||||||
}, [id, setValue]); // Remove refresh dependency and add id
|
}, [id, setValue]);
|
||||||
|
|
||||||
const mapPlacementsToOptions = (placements: string): string[] => {
|
const mapPlacementsToOptions = (placements: string): string[] => {
|
||||||
const mapping: Record<string, string> = {
|
const mapping: Record<string, string> = {
|
||||||
|
|
@ -317,7 +290,6 @@ export default function FormImageUpdate() {
|
||||||
polres: "internasional",
|
polres: "internasional",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Jika placements hanya "all", langsung aktifkan semua checkbox
|
|
||||||
if (placements.trim() === "all") {
|
if (placements.trim() === "all") {
|
||||||
return ["all", "nasional", "wilayah", "internasional"];
|
return ["all", "nasional", "wilayah", "internasional"];
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +308,6 @@ export default function FormImageUpdate() {
|
||||||
|
|
||||||
const handleCheckboxChange = (id: string) => {
|
const handleCheckboxChange = (id: string) => {
|
||||||
if (id === "all") {
|
if (id === "all") {
|
||||||
// Select all options except "all"
|
|
||||||
const allOptions = options
|
const allOptions = options
|
||||||
.filter((opt) => opt.id !== "all")
|
.filter((opt) => opt.id !== "all")
|
||||||
.map((opt) => opt.id);
|
.map((opt) => opt.id);
|
||||||
|
|
@ -344,7 +315,6 @@ export default function FormImageUpdate() {
|
||||||
publishedFor.length === allOptions.length ? [] : allOptions
|
publishedFor.length === allOptions.length ? [] : allOptions
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Toggle individual option
|
|
||||||
setPublishedFor((prev) =>
|
setPublishedFor((prev) =>
|
||||||
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
|
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
|
||||||
);
|
);
|
||||||
|
|
@ -380,9 +350,11 @@ export default function FormImageUpdate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const formMedia = new FormData();
|
const formMedia = new FormData();
|
||||||
const thumbnail = files[0];
|
const thumbnail = thumbnailFile || files[0];
|
||||||
formMedia.append("file", thumbnail);
|
formMedia.append("file", thumbnail);
|
||||||
|
|
||||||
const responseThumbnail = await uploadThumbnail(id, formMedia);
|
const responseThumbnail = await uploadThumbnail(id, formMedia);
|
||||||
|
|
||||||
if (responseThumbnail?.error == true) {
|
if (responseThumbnail?.error == true) {
|
||||||
error(responseThumbnail?.message);
|
error(responseThumbnail?.message);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -448,7 +420,7 @@ export default function FormImageUpdate() {
|
||||||
filename: file.name,
|
filename: file.name,
|
||||||
filetype: file.type,
|
filetype: file.type,
|
||||||
duration,
|
duration,
|
||||||
isWatermark: "true", // hardcode
|
isWatermark: "true",
|
||||||
},
|
},
|
||||||
onBeforeRequest: function (req) {
|
onBeforeRequest: function (req) {
|
||||||
var xhr = req.getUnderlyingObject();
|
var xhr = req.getUnderlyingObject();
|
||||||
|
|
@ -554,7 +526,7 @@ export default function FormImageUpdate() {
|
||||||
|
|
||||||
const fileList = files.map((file: any) => (
|
const fileList = files.map((file: any) => (
|
||||||
<div
|
<div
|
||||||
key={file.id} // Gunakan ID file sebagai key
|
key={file.id}
|
||||||
className="flex justify-between border px-3.5 py-3 my-6 rounded-md"
|
className="flex justify-between border px-3.5 py-3 my-6 rounded-md"
|
||||||
>
|
>
|
||||||
<div className="flex gap-3 items-center">
|
<div className="flex gap-3 items-center">
|
||||||
|
|
@ -579,7 +551,7 @@ export default function FormImageUpdate() {
|
||||||
color="destructive"
|
color="destructive"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="border-none rounded-full"
|
className="border-none rounded-full"
|
||||||
onClick={() => handleDeleteFile(file.id)} // Kirim ID spesifik
|
onClick={() => handleDeleteFile(file.id)}
|
||||||
>
|
>
|
||||||
<Icon icon="tabler:x" className="h-5 w-5" />
|
<Icon icon="tabler:x" className="h-5 w-5" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -590,21 +562,18 @@ export default function FormImageUpdate() {
|
||||||
setSelectedOptions((prev: any) => {
|
setSelectedOptions((prev: any) => {
|
||||||
const currentSelections = prev[fileId] || [];
|
const currentSelections = prev[fileId] || [];
|
||||||
if (value === "all") {
|
if (value === "all") {
|
||||||
// If "all" is clicked, toggle all options
|
|
||||||
if (currentSelections.includes("all")) {
|
if (currentSelections.includes("all")) {
|
||||||
return { ...prev, [fileId]: [] }; // Deselect all
|
return { ...prev, [fileId]: [] };
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
[fileId]: ["all", "nasional", "wilayah", "internasional"],
|
[fileId]: ["all", "nasional", "wilayah", "internasional"],
|
||||||
}; // Select all
|
};
|
||||||
} else {
|
} else {
|
||||||
// If any other checkbox is clicked, toggle that checkbox
|
|
||||||
const updatedSelections = currentSelections.includes(value)
|
const updatedSelections = currentSelections.includes(value)
|
||||||
? currentSelections.filter((option: any) => option !== value)
|
? currentSelections.filter((option: any) => option !== value)
|
||||||
: [...currentSelections, value];
|
: [...currentSelections, value];
|
||||||
|
|
||||||
// If all individual options are selected, include "all" automatically
|
|
||||||
const isAllSelected = ["nasional", "wilayah", "internasional"].every(
|
const isAllSelected = ["nasional", "wilayah", "internasional"].every(
|
||||||
(opt) => updatedSelections.includes(opt)
|
(opt) => updatedSelections.includes(opt)
|
||||||
);
|
);
|
||||||
|
|
@ -671,7 +640,9 @@ export default function FormImageUpdate() {
|
||||||
<div className="flex flex-col lg:flex-row gap-10">
|
<div className="flex flex-col lg:flex-row gap-10">
|
||||||
<Card className="w-full lg:w-8/12">
|
<Card className="w-full lg:w-8/12">
|
||||||
<div className="px-6 py-6">
|
<div className="px-6 py-6">
|
||||||
<p className="text-lg font-semibold mb-3">{t("form-image", { defaultValue: "Form Image" })}</p>
|
<p className="text-lg font-semibold mb-3">
|
||||||
|
{t("form-image", { defaultValue: "Form Image" })}
|
||||||
|
</p>
|
||||||
<div className="gap-5 mb-5">
|
<div className="gap-5 mb-5">
|
||||||
{/* Input Title */}
|
{/* Input Title */}
|
||||||
<div className="space-y-2 py-3">
|
<div className="space-y-2 py-3">
|
||||||
|
|
@ -710,14 +681,18 @@ export default function FormImageUpdate() {
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{/* Show the category from details if it doesn't exist in categories list */}
|
{/* Show the category from details if it doesn't exist in categories list */}
|
||||||
{detail && !categories.find(cat => String(cat.id) === String(detail.category.id)) && (
|
{detail &&
|
||||||
<SelectItem
|
!categories.find(
|
||||||
key={String(detail.category.id)}
|
(cat) =>
|
||||||
value={String(detail.category.id)}
|
String(cat.id) === String(detail.category.id)
|
||||||
>
|
) && (
|
||||||
{detail.category.name}
|
<SelectItem
|
||||||
</SelectItem>
|
key={String(detail.category.id)}
|
||||||
)}
|
value={String(detail.category.id)}
|
||||||
|
>
|
||||||
|
{detail.category.name}
|
||||||
|
</SelectItem>
|
||||||
|
)}
|
||||||
{categories.map((category) => (
|
{categories.map((category) => (
|
||||||
<SelectItem
|
<SelectItem
|
||||||
key={String(category.id)}
|
key={String(category.id)}
|
||||||
|
|
@ -732,12 +707,17 @@ export default function FormImageUpdate() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="py-3 space-y-2">
|
<div className="py-3 space-y-2">
|
||||||
<Label>{t("description", { defaultValue: "Description" })}</Label>
|
<Label>
|
||||||
|
{t("description", { defaultValue: "Description" })}
|
||||||
|
</Label>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="description"
|
name="description"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<CustomEditor onChange={field.onChange} initialData={field.value} />
|
<CustomEditor
|
||||||
|
onChange={field.onChange}
|
||||||
|
initialData={field.value}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{errors.description?.message && (
|
{errors.description?.message && (
|
||||||
|
|
@ -747,7 +727,9 @@ export default function FormImageUpdate() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="py-3 space-y-2">
|
<div className="py-3 space-y-2">
|
||||||
<Label>{t("select-file", { defaultValue: "Select File" })}</Label>
|
<Label>
|
||||||
|
{t("select-file", { defaultValue: "Select File" })}
|
||||||
|
</Label>
|
||||||
{/* <Input
|
{/* <Input
|
||||||
id="fileInput"
|
id="fileInput"
|
||||||
type="file"
|
type="file"
|
||||||
|
|
@ -763,7 +745,9 @@ export default function FormImageUpdate() {
|
||||||
{t("drag-file", { defaultValue: "Drag File" })}
|
{t("drag-file", { defaultValue: "Drag File" })}
|
||||||
</h4>
|
</h4>
|
||||||
<div className=" text-xs text-muted-foreground">
|
<div className=" text-xs text-muted-foreground">
|
||||||
{t("upload-file-max", { defaultValue: "Upload File Max" })}
|
{t("upload-file-max", {
|
||||||
|
defaultValue: "Upload File Max",
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -772,7 +756,9 @@ export default function FormImageUpdate() {
|
||||||
<div>{fileList}</div>
|
<div>{fileList}</div>
|
||||||
<div className=" flex justify-between gap-2">
|
<div className=" flex justify-between gap-2">
|
||||||
<div className="flex flex-row items-center gap-3 py-3">
|
<div className="flex flex-row items-center gap-3 py-3">
|
||||||
<Label>{t("watermark", { defaultValue: "Watermark" })}</Label>
|
<Label>
|
||||||
|
{t("watermark", { defaultValue: "Watermark" })}
|
||||||
|
</Label>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Switch defaultChecked color="primary" id="c2" />
|
<Switch defaultChecked color="primary" id="c2" />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -812,7 +798,9 @@ export default function FormImageUpdate() {
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="text-blue-500 text-sm"
|
className="text-blue-500 text-sm"
|
||||||
>
|
>
|
||||||
{t("view-file", { defaultValue: "View File" })}
|
{t("view-file", {
|
||||||
|
defaultValue: "View File",
|
||||||
|
})}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -830,7 +818,9 @@ export default function FormImageUpdate() {
|
||||||
}
|
}
|
||||||
className="form-checkbox"
|
className="form-checkbox"
|
||||||
/>
|
/>
|
||||||
<span>{t("all", { defaultValue: "All" })}</span>
|
<span>
|
||||||
|
{t("all", { defaultValue: "All" })}
|
||||||
|
</span>
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -899,7 +889,7 @@ export default function FormImageUpdate() {
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
<div className="w-full lg:w-4/12">
|
<div className="w-full lg:w-4/12">
|
||||||
<Card className="h-[900px] md:h-[1100px] lg:h-[800px]">
|
<Card className="h-[900px] md:h-[1100px] lg:h-fit">
|
||||||
<div className="px-3 py-3">
|
<div className="px-3 py-3">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>{t("creator", { defaultValue: "Creator" })}</Label>
|
<Label>{t("creator", { defaultValue: "Creator" })}</Label>
|
||||||
|
|
@ -923,7 +913,7 @@ export default function FormImageUpdate() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3 px-3 space-y-2">
|
{/* <div className="mt-3 px-3 space-y-2">
|
||||||
<Label>{t("preview", { defaultValue: "Preview" })}</Label>
|
<Label>{t("preview", { defaultValue: "Preview" })}</Label>
|
||||||
<Card className="mt-2">
|
<Card className="mt-2">
|
||||||
<img
|
<img
|
||||||
|
|
@ -932,7 +922,37 @@ export default function FormImageUpdate() {
|
||||||
className="w-full h-auto rounded"
|
className="w-full h-auto rounded"
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
</div> */}
|
||||||
|
<div className="mt-3 px-3 space-y-2">
|
||||||
|
<Label>{t("preview", { defaultValue: "Preview" })}</Label>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
onChange={(e) => {
|
||||||
|
const file = e.target.files?.[0];
|
||||||
|
if (file) {
|
||||||
|
setThumbnailFile(file);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="dark:border dark:border-gray-500 dark:rounded-lg"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Card className="mt-2">
|
||||||
|
<img
|
||||||
|
src={
|
||||||
|
thumbnailFile
|
||||||
|
? URL.createObjectURL(thumbnailFile)
|
||||||
|
: detail?.thumbnailLink
|
||||||
|
? `${detail.thumbnailLink}?v=${Date.now()}`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
alt="Thumbnail Preview"
|
||||||
|
className="w-full h-auto rounded"
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="px-3 py-3">
|
<div className="px-3 py-3">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>{t("tags", { defaultValue: "Tags" })}</Label>
|
<Label>{t("tags", { defaultValue: "Tags" })}</Label>
|
||||||
|
|
@ -980,7 +1000,9 @@ export default function FormImageUpdate() {
|
||||||
</div>
|
</div>
|
||||||
<div className="px-3 py-3">
|
<div className="px-3 py-3">
|
||||||
<div className="flex flex-col gap-6 space-y-2">
|
<div className="flex flex-col gap-6 space-y-2">
|
||||||
<Label>{t("publish-target", { defaultValue: "Publish Target" })}</Label>
|
<Label>
|
||||||
|
{t("publish-target", { defaultValue: "Publish Target" })}
|
||||||
|
</Label>
|
||||||
{options.map((option: Option) => (
|
{options.map((option: Option) => (
|
||||||
<div key={option.id} className="flex gap-2 items-center">
|
<div key={option.id} className="flex gap-2 items-center">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|
@ -1000,7 +1022,9 @@ export default function FormImageUpdate() {
|
||||||
</div>
|
</div>
|
||||||
<div className="px-3 py-3 flex flex-row items-center text-blue-500 gap-2 text-sm">
|
<div className="px-3 py-3 flex flex-row items-center text-blue-500 gap-2 text-sm">
|
||||||
<MailIcon />
|
<MailIcon />
|
||||||
<p className="">{t("suggestion-box", { defaultValue: "Suggestion Box" })} (0)</p>
|
<p className="">
|
||||||
|
{t("suggestion-box", { defaultValue: "Suggestion Box" })} (0)
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="px-3 py-3">
|
<div className="px-3 py-3">
|
||||||
<p>{t("information", { defaultValue: "Information" })}:</p>
|
<p>{t("information", { defaultValue: "Information" })}:</p>
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,17 @@ interface FileUploaded {
|
||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Destination {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
subDestination?: SubDestination[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SubDestination {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
type Url = {
|
type Url = {
|
||||||
id: number;
|
id: number;
|
||||||
attachmentUrl: string;
|
attachmentUrl: string;
|
||||||
|
|
@ -137,7 +148,7 @@ export default function FormTaskEdit() {
|
||||||
const [detail, setDetail] = useState<taskDetail>();
|
const [detail, setDetail] = useState<taskDetail>();
|
||||||
const [urlInputs, setUrlInputs] = useState<Url[]>([]);
|
const [urlInputs, setUrlInputs] = useState<Url[]>([]);
|
||||||
const [refresh] = useState(false);
|
const [refresh] = useState(false);
|
||||||
const [listDest, setListDest] = useState([]);
|
const [listDest, setListDest] = useState<Destination[]>([]);
|
||||||
const [checkedLevels, setCheckedLevels] = useState(new Set());
|
const [checkedLevels, setCheckedLevels] = useState(new Set());
|
||||||
const [expandedPolda, setExpandedPolda] = useState([{}]);
|
const [expandedPolda, setExpandedPolda] = useState([{}]);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
@ -177,6 +188,12 @@ export default function FormTaskEdit() {
|
||||||
resolver: zodResolver(taskSchema),
|
resolver: zodResolver(taskSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (detail?.taskType) {
|
||||||
|
setTaskType(detail.taskType.toString());
|
||||||
|
}
|
||||||
|
}, [detail]);
|
||||||
|
|
||||||
// const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
// const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
// const selectedValue = Number(event.target.value);
|
// const selectedValue = Number(event.target.value);
|
||||||
// setMainType(selectedValue);
|
// setMainType(selectedValue);
|
||||||
|
|
@ -425,7 +442,7 @@ export default function FormTaskEdit() {
|
||||||
console.log("Form Data Submitted:", requestData);
|
console.log("Form Data Submitted:", requestData);
|
||||||
console.log("response", response);
|
console.log("response", response);
|
||||||
const id = response?.data?.data.id;
|
const id = response?.data?.data.id;
|
||||||
loading();
|
// loading();
|
||||||
if (imageFiles?.length == 0) {
|
if (imageFiles?.length == 0) {
|
||||||
setIsImageUploadFinish(true);
|
setIsImageUploadFinish(true);
|
||||||
}
|
}
|
||||||
|
|
@ -471,6 +488,26 @@ export default function FormTaskEdit() {
|
||||||
// });
|
// });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const updated = new Set(checkedLevels);
|
||||||
|
|
||||||
|
if (unitSelection.polda) {
|
||||||
|
listDest.forEach((polda) => {
|
||||||
|
updated.add(polda.id); // hanya id polda
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unitSelection.polres) {
|
||||||
|
listDest.forEach((polda) => {
|
||||||
|
polda?.subDestination?.forEach((polres: any) => {
|
||||||
|
updated.add(polres.id); // hanya id polres
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setCheckedLevels(updated);
|
||||||
|
}, [unitSelection.polda, unitSelection.polres, listDest]);
|
||||||
|
|
||||||
const onSubmit = (data: TaskSchema) => {
|
const onSubmit = (data: TaskSchema) => {
|
||||||
MySwal.fire({
|
MySwal.fire({
|
||||||
title: "Simpan Data",
|
title: "Simpan Data",
|
||||||
|
|
@ -732,25 +769,29 @@ export default function FormTaskEdit() {
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap gap-3 mt-6 lg:pt-7 lg:ml-3">
|
<div className="flex flex-wrap gap-3 mt-6 lg:pt-7 lg:ml-3">
|
||||||
{Object.keys(unitSelection).map((key) => (
|
{Object.keys(unitSelection).map((key) => {
|
||||||
<div className="flex items-center gap-2" key={key}>
|
const isDisabled = key === "polres" && !unitSelection.polda;
|
||||||
<Checkbox
|
return (
|
||||||
id={key}
|
<div className="flex items-center gap-2" key={key}>
|
||||||
checked={
|
<Checkbox
|
||||||
unitSelection[key as keyof typeof unitSelection]
|
id={key}
|
||||||
}
|
checked={
|
||||||
onCheckedChange={(value) =>
|
unitSelection[key as keyof typeof unitSelection]
|
||||||
handleUnitChange(
|
}
|
||||||
key as keyof typeof unitSelection,
|
disabled={isDisabled}
|
||||||
value as boolean
|
onCheckedChange={(value) =>
|
||||||
)
|
handleUnitChange(
|
||||||
}
|
key as keyof typeof unitSelection,
|
||||||
/>
|
value as boolean
|
||||||
<Label htmlFor={key}>
|
)
|
||||||
{key.charAt(0).toUpperCase() + key.slice(1)}
|
}
|
||||||
</Label>
|
/>
|
||||||
</div>
|
<Label htmlFor={key}>
|
||||||
))}
|
{key.charAt(0).toUpperCase() + key.slice(1)}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-6 lg:pt-6 lg:pl-3">
|
<div className="mt-6 lg:pt-6 lg:pl-3">
|
||||||
<Dialog>
|
<Dialog>
|
||||||
|
|
@ -766,71 +807,67 @@ export default function FormTaskEdit() {
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="grid grid-cols-2 gap-2 max-h-[400px] overflow-y-auto">
|
<div className="grid grid-cols-2 gap-2 max-h-[400px] overflow-y-auto">
|
||||||
{listDest.map((polda: any) => (
|
{listDest.map((polda: any) => {
|
||||||
<div key={polda.id} className="border p-2">
|
const poldaChecked = unitSelection.polda; // kontrol polda luar
|
||||||
<Label className="flex items-center">
|
const polresChecked = unitSelection.polres; // kontrol polres luar
|
||||||
<Checkbox
|
|
||||||
checked={checkedLevels.has(polda.id)}
|
const isPoldaDisabled = poldaChecked; // lock checkbox polda dialog jika polda luar dicentang
|
||||||
onCheckedChange={() =>
|
const isPolresDisabled = polresChecked; // lock checkbox polres dialog jika polres luar dicentang
|
||||||
handleCheckboxChange(polda.id)
|
|
||||||
}
|
return (
|
||||||
className="mr-3"
|
<div key={polda.id} className="border p-2">
|
||||||
/>
|
<Label className="flex items-center">
|
||||||
{polda.name}
|
<Checkbox
|
||||||
<button
|
checked={
|
||||||
onClick={() => toggleExpand(polda.id)}
|
poldaChecked || checkedLevels.has(polda.id)
|
||||||
className="ml-2 focus:outline-none"
|
} // auto-centang jika polda luar dicentang
|
||||||
>
|
disabled={isPoldaDisabled}
|
||||||
{expandedPolda[polda.id] ? (
|
onCheckedChange={() => {
|
||||||
<ChevronUp size={16} />
|
if (isPoldaDisabled) return;
|
||||||
) : (
|
handleCheckboxChange(polda.id);
|
||||||
<ChevronDown size={16} />
|
}}
|
||||||
)}
|
className="mr-3"
|
||||||
</button>
|
/>
|
||||||
</Label>
|
{polda.name}
|
||||||
{expandedPolda[polda.id] && (
|
<button
|
||||||
<div className="ml-6 mt-2">
|
onClick={() => toggleExpand(polda.id)}
|
||||||
<Label className="block">
|
className="ml-2 focus:outline-none"
|
||||||
<Checkbox
|
>
|
||||||
checked={polda?.subDestination?.every(
|
{expandedPolda[polda.id] ? (
|
||||||
(polres: any) =>
|
<ChevronUp size={16} />
|
||||||
checkedLevels.has(polres.id)
|
) : (
|
||||||
)}
|
<ChevronDown size={16} />
|
||||||
onCheckedChange={(isChecked) => {
|
)}
|
||||||
const updatedLevels = new Set(
|
</button>
|
||||||
checkedLevels
|
</Label>
|
||||||
);
|
|
||||||
polda?.subDestination?.forEach(
|
{expandedPolda[polda.id] && (
|
||||||
(polres: any) => {
|
<div className="ml-6 mt-2">
|
||||||
if (isChecked) {
|
{polda?.subDestination?.map((polres: any) => (
|
||||||
updatedLevels.add(polres.id);
|
<Label
|
||||||
} else {
|
key={polres.id}
|
||||||
updatedLevels.delete(polres.id);
|
className="block mt-1"
|
||||||
}
|
>
|
||||||
}
|
<Checkbox
|
||||||
);
|
checked={
|
||||||
setCheckedLevels(updatedLevels);
|
polresChecked ||
|
||||||
}}
|
checkedLevels.has(polres.id)
|
||||||
className="mr-2"
|
} // auto-centang jika polres luar dicentang
|
||||||
/>
|
disabled={isPolresDisabled}
|
||||||
Pilih Semua Polres
|
onCheckedChange={() => {
|
||||||
</Label>
|
if (isPolresDisabled) return;
|
||||||
{polda?.subDestination?.map((polres: any) => (
|
handleCheckboxChange(polres.id);
|
||||||
<Label key={polres.id} className="block mt-1">
|
}}
|
||||||
<Checkbox
|
className="mr-2"
|
||||||
checked={checkedLevels.has(polres.id)}
|
/>
|
||||||
onCheckedChange={() =>
|
{polres.name}
|
||||||
handleCheckboxChange(polres.id)
|
</Label>
|
||||||
}
|
))}
|
||||||
className="mr-2"
|
</div>
|
||||||
/>
|
)}
|
||||||
{polres.name}
|
</div>
|
||||||
</Label>
|
);
|
||||||
))}
|
})}
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
@ -856,14 +893,15 @@ export default function FormTaskEdit() {
|
||||||
{t("assigment-type", { defaultValue: "Assigment Type" })}{" "}
|
{t("assigment-type", { defaultValue: "Assigment Type" })}{" "}
|
||||||
</Label>
|
</Label>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
defaultValue={detail.taskType.toString()}
|
value={taskType} // ✅ controlled
|
||||||
onValueChange={(value) => setTaskType(String(value))}
|
onValueChange={(value) => setTaskType(value)}
|
||||||
className="flex flex-wrap gap-3"
|
className="flex flex-wrap gap-3"
|
||||||
>
|
>
|
||||||
<RadioGroupItem value="atensi-khusus" id="khusus" />
|
<RadioGroupItem value="atensi-khusus" id="khusus" />
|
||||||
<Label htmlFor="atensi-khusus">Atensi Khusus</Label>
|
<Label htmlFor="khusus">Atensi Khusus</Label>
|
||||||
|
|
||||||
<RadioGroupItem value="tugas-harian" id="harian" />
|
<RadioGroupItem value="tugas-harian" id="harian" />
|
||||||
<Label htmlFor="tugas-harian">Tugas Harian</Label>
|
<Label htmlFor="harian">Tugas Harian</Label>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
{/* RadioGroup Assignment Category */}
|
{/* RadioGroup Assignment Category */}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue