import { Button } from "@mui/joy"; import { useEffect, useMemo, useState } from "react"; import { toast } from "react-hot-toast"; import { useTranslation } from "react-i18next"; import useLoading from "../hooks/useLoading"; import { useResourceStore } from "../store/module"; import Icon from "../components/Icon"; import ResourceCard from "../components/ResourceCard"; import ResourceSearchBar from "../components/ResourceSearchBar"; import MobileHeader from "../components/MobileHeader"; import Dropdown from "../components/base/Dropdown"; import ResourceItem from "../components/ResourceItem"; import { showCommonDialog } from "../components/Dialog/CommonDialog"; import showChangeResourceFilenameDialog from "../components/ChangeResourceFilenameDialog"; import copy from "copy-to-clipboard"; import { getResourceUrl } from "../utils/resource"; import showPreviewImageDialog from "../components/PreviewImageDialog"; import showCreateResourceDialog from "../components/CreateResourceDialog"; import useListStyle from "../hooks/useListStyle"; const ResourcesDashboard = () => { const { t } = useTranslation(); const loadingState = useLoading(); const resourceStore = useResourceStore(); const resources = resourceStore.state.resources; const [selectedList, setSelectedList] = useState>([]); const [isVisible, setIsVisible] = useState(false); const [queryText, setQueryText] = useState(""); const { listStyle, setToTableStyle, setToGridStyle } = useListStyle(); const [dragActive, setDragActive] = useState(false); useEffect(() => { resourceStore .fetchResourceList() .catch((error) => { console.error(error); toast.error(error.response.data.message); }) .finally(() => { loadingState.setFinish(); }); }, []); useEffect(() => { if (selectedList.length === 0) { setIsVisible(false); } else { setIsVisible(true); } }, [selectedList]); const handleCheckBtnClick = (resourceId: ResourceId) => { setSelectedList([...selectedList, resourceId]); }; const handleUncheckBtnClick = (resourceId: ResourceId) => { setSelectedList(selectedList.filter((resId) => resId !== resourceId)); }; const handleDeleteUnusedResourcesBtnClick = () => { let warningText = t("resources.warning-text-unused"); const unusedResources = resources.filter((resource) => { if (resource.linkedMemoAmount === 0) { warningText = warningText + `\n- ${resource.filename}`; return true; } return false; }); if (unusedResources.length === 0) { toast.success(t("resources.no-unused-resources")); return; } showCommonDialog({ title: t("resources.delete-resource"), content: warningText, style: "warning", dialogName: "delete-unused-resources", onConfirm: async () => { for (const resource of unusedResources) { await resourceStore.deleteResourceById(resource.id); } }, }); }; const handleDeleteSelectedBtnClick = () => { if (selectedList.length == 0) { toast.error(t("resources.no-files-selected")); } else { const warningText = t("resources.warning-text"); showCommonDialog({ title: t("resources.delete-resource"), content: warningText, style: "warning", dialogName: "delete-resource-dialog", onConfirm: async () => { selectedList.map(async (resourceId: ResourceId) => { await resourceStore.deleteResourceById(resourceId); }); }, }); } }; const handleStyleChangeBtnClick = (listStyleValue: boolean) => { if (listStyleValue) { setToTableStyle(); } else { setToGridStyle(); } setSelectedList([]); }; const handleRenameBtnClick = (resource: Resource) => { showChangeResourceFilenameDialog(resource.id, resource.filename); }; const handleDeleteResourceBtnClick = (resource: Resource) => { let warningText = t("resources.warning-text"); if (resource.linkedMemoAmount > 0) { warningText = warningText + `\n${t("resources.linked-amount")}: ${resource.linkedMemoAmount}`; } showCommonDialog({ title: t("resources.delete-resource"), content: warningText, style: "warning", dialogName: "delete-resource-dialog", onConfirm: async () => { await resourceStore.deleteResourceById(resource.id); }, }); }; const handlePreviewBtnClick = (resource: Resource) => { const resourceUrl = getResourceUrl(resource); if (resource.type.startsWith("image")) { showPreviewImageDialog( resources.filter((r) => r.type.startsWith("image")).map((r) => getResourceUrl(r)), resources.findIndex((r) => r.id === resource.id) ); } else { window.open(resourceUrl); } }; const handleCopyResourceLinkBtnClick = (resource: Resource) => { const url = getResourceUrl(resource); copy(url); toast.success(t("message.succeed-copy-resource-link")); }; const handleSearchResourceInputChange = (query: string) => { setQueryText(query); setSelectedList([]); }; const resourceList = useMemo( () => resources .filter((res: Resource) => (queryText === "" ? true : res.filename.toLowerCase().includes(queryText.toLowerCase()))) .map((resource) => listStyle ? ( handleCheckBtnClick(resource.id)} handleUncheckClick={() => handleUncheckBtnClick(resource.id)} handleRenameBtnClick={handleRenameBtnClick} handleDeleteResourceBtnClick={handleDeleteResourceBtnClick} handlePreviewBtnClick={handlePreviewBtnClick} handleCopyResourceLinkBtnClick={handleCopyResourceLinkBtnClick} > ) : ( handleCheckBtnClick(resource.id)} handleUncheckClick={() => handleUncheckBtnClick(resource.id)} handleRenameBtnClick={handleRenameBtnClick} handleDeleteResourceBtnClick={handleDeleteResourceBtnClick} handlePreviewBtnClick={handlePreviewBtnClick} handleCopyResourceLinkBtnClick={handleCopyResourceLinkBtnClick} > ) ), [resources, queryText, listStyle] ); const handleDrag = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); if (e.type === "dragenter" || e.type === "dragover") { setDragActive(true); } else if (e.type === "dragleave") { setDragActive(false); } }; const handleDrop = async (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); setDragActive(false); if (e.dataTransfer.files && e.dataTransfer.files[0]) { await resourceStore.createResourcesWithBlob(e.dataTransfer.files).then( (res) => { for (const resource of res) { toast.success(`${resource.filename} ${t("resources.upload-successfully")}`); } }, (reason) => { toast.error(reason); } ); } }; return (
{dragActive && (

{t("resources.file-drag-drop-prompt")}

)}

{t("common.resources")}

{isVisible && ( )} } actions={ <> } />
handleStyleChangeBtnClick(false)} >
handleStyleChangeBtnClick(true)} >
{loadingState.isLoading ? (

{t("resources.fetching-data")}

) : (
{listStyle && (
{t("resources.select")} ID {t("resources.name")}
)} {resourceList.length === 0 ? (

{t("resources.no-resources")}

) : ( resourceList )}
)}
); }; export default ResourcesDashboard;