diff --git a/app/[locale]/(protected)/dashboard/routine-task/components/content-table.tsx b/app/[locale]/(protected)/dashboard/routine-task/components/content-table.tsx index 6bfc7860..52d893b7 100644 --- a/app/[locale]/(protected)/dashboard/routine-task/components/content-table.tsx +++ b/app/[locale]/(protected)/dashboard/routine-task/components/content-table.tsx @@ -60,13 +60,13 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { useTranslations } from "next-intl"; type StatusFilter = string[]; const ContentTable = () => { const router = useRouter(); const searchParams = useSearchParams(); - const [dataTable, setDataTable] = React.useState([]); const [totalData, setTotalData] = React.useState(1); const [sorting, setSorting] = React.useState([]); @@ -85,7 +85,6 @@ const ContentTable = () => { const [limit, setLimit] = React.useState(10); const userId = getCookiesDecrypt("uie"); const userLevelId = getCookiesDecrypt("ulie"); - const [categories, setCategories] = React.useState(); const [categoryFilter, setCategoryFilter] = React.useState([]); const [statusFilter, setStatusFilter] = React.useState([]); @@ -95,8 +94,8 @@ const ContentTable = () => { const [fileTypeFilter, setFileTypeFilter] = React.useState([]); const [filterBySource, setFilterBySource] = React.useState(""); const [search, setSearch] = React.useState(""); - const roleId = getCookiesDecrypt("urie"); + const t = useTranslations("Form"); const table = useReactTable({ data: dataTable, @@ -165,8 +164,8 @@ const ContentTable = () => { } const handleSearch = (e: React.ChangeEvent) => { - setSearch(e.target.value); - table.getColumn("judul")?.setFilterValue(e.target.value); + setSearch(e.target.value); + table.getColumn("judul")?.setFilterValue(e.target.value); }; return ( @@ -179,7 +178,7 @@ const ContentTable = () => { { }} > - + Filter - Foto - Audio Visual - Teks + {t("image")} + {t("audio-visual")} + {t("text")} Audio diff --git a/components/form/content/image-form.tsx b/components/form/content/image-form.tsx index 60813be1..c54595f7 100644 --- a/components/form/content/image-form.tsx +++ b/components/form/content/image-form.tsx @@ -48,7 +48,7 @@ import { import { getCookiesDecrypt } from "@/lib/utils"; import { useDropzone } from "react-dropzone"; import { Icon } from "@iconify/react"; -import { CloudUpload } from "lucide-react"; +import { CloudUpload, X } from "lucide-react"; import Image from "next/image"; import { error, loading } from "@/config/swal"; import { Item } from "@radix-ui/react-dropdown-menu"; @@ -95,14 +95,12 @@ export default function FormImage() { const scheduleType = Cookies.get("scheduleType"); const roleId = getCookiesDecrypt("urie"); const [selectedFileType, setSelectedFileType] = useState("original"); - const [categories, setCategories] = useState([]); const [selectedCategory, setSelectedCategory] = useState(); const [tags, setTags] = useState([]); const [thumbnail, setThumbnail] = useState(null); const [preview, setPreview] = useState(null); const [selectedLanguage, setSelectedLanguage] = useState(""); - const [selectedSEO, setSelectedSEO] = useState(""); const [title, setTitle] = useState(""); const [selectedAdvConfig, setSelectedAdvConfig] = useState(""); @@ -119,18 +117,14 @@ export default function FormImage() { const [selectedMainKeyword, setSelectedMainKeyword] = useState(""); const [selectedWritingStyle, setSelectedWritingStyle] = useState("professional"); - const [editorContent, setEditorContent] = useState(""); // Untuk original editor + const [editorContent, setEditorContent] = useState(""); const [rewriteEditorContent, setRewriteEditorContent] = useState(""); const [selectedSize, setSelectedSize] = useState(""); const [detailData, setDetailData] = useState(null); const [articleImages, setArticleImages] = useState([]); const [isSwitchOn, setIsSwitchOn] = useState(false); const inputRef = useRef(null); - - const [content, setContent] = useState(""); - const [isContentRewriteClicked, setIsContentRewriteClicked] = useState(false); - const [selectedTarget, setSelectedTarget] = useState(""); const [unitSelection, setUnitSelection] = useState({ allUnit: false, @@ -147,7 +141,6 @@ export default function FormImage() { const [isStartUpload, setIsStartUpload] = useState(false); const [counterProgress, setCounterProgress] = useState(0); const [showRewriteEditor, setShowRewriteEditor] = useState(false); - const [files, setFiles] = useState([]); const [filesTemp, setFilesTemp] = useState([]); const [publishedFor, setPublishedFor] = useState([]); @@ -1246,6 +1239,7 @@ export default function FormImage() { name="files" render={({ field }) => { const maxSize = 100 * 1024 * 1024; + const [previews, setPreviews] = useState([]); const { getRootProps, getInputProps, fileRejections } = useDropzone({ @@ -1254,12 +1248,40 @@ export default function FormImage() { "image/png": [".png"], }, maxSize, - multiple: false, + multiple: true, // <- Set true jika ingin lebih dari satu onDrop: (acceptedFiles) => { - field.onChange(acceptedFiles); + const currentFiles = [ + ...(field.value || []), + ...acceptedFiles, + ]; + field.onChange(currentFiles); + + const newPreviews = acceptedFiles.map((file) => + URL.createObjectURL(file) + ); + setPreviews((prev) => [...prev, ...newPreviews]); }, }); + // Clean up URL on unmount + useEffect(() => { + return () => { + previews.forEach((url) => URL.revokeObjectURL(url)); + }; + }, [previews]); + + const handleRemoveFile = (indexToRemove: number) => { + const updatedFiles = [...field.value]; + updatedFiles.splice(indexToRemove, 1); + + const updatedPreviews = [...previews]; + URL.revokeObjectURL(updatedPreviews[indexToRemove]); // Clean up + updatedPreviews.splice(indexToRemove, 1); + + field.onChange(updatedFiles); + setPreviews(updatedPreviews); + }; + return (
+ {field.value && field.value.length > 0 && ( - <> -
    - {field.value.map((file, idx) => ( -
  • - {file.name} ( - {(file.size / (1024 * 1024)).toFixed(2)} MB) -
  • - ))} -
-
+
+ {field.value.map((file: File, idx: number) => ( +
+ {`preview-${idx}`} +
+
{file.name}
+
+ {(file.size / (1024 * 1024)).toFixed(2)} MB +
+
+ +
+ ))} +
- +
)} {errors.files?.message && ( diff --git a/messages/en.json b/messages/en.json index 89386689..f5ab23e1 100644 --- a/messages/en.json +++ b/messages/en.json @@ -836,7 +836,7 @@ "output-task": "Task Output", "attachment": "Attachment", "image": "Image", - "audio-visual": "Audio Visual", + "audio-visual": "Video", "text": "Text", "audio": "Audio", "voice-note": "Voice Note", @@ -855,7 +855,9 @@ "coverage-area": "Coverage Area", "only": "Only .jpg, .jpeg, .png files are allowed", "size": "File too large. Max 100MB", - "onlyVd": "Upload files with mp4 or mov Maximum size 100mb." - + "onlyVd": "Upload files with mp4 or mov Maximum size 100mb.", + "searchTitle": "Find Title...", + "selectFilter": "Select a Filter", + "noResult": "No results." } } diff --git a/messages/in.json b/messages/in.json index abacab6b..3739e0a7 100644 --- a/messages/in.json +++ b/messages/in.json @@ -856,6 +856,9 @@ "coverage-area": "Cakupan Wilayah", "only": "Hanya file .jpg, .jpeg, .png yang diizinkan", "size": "File terlalu besar. Maksimal 100MB", - "onlyVd": "Upload file dengan mp4 atau mov Ukuran maksimal 100mb." + "onlyVd": "Upload file dengan mp4 atau mov Ukuran maksimal 100mb.", + "searchTitle": "Cari Judul...", + "selectFilter": "Pilih Filter", + "noResult": "Tidak ada hasil" } }