import React from "react"; import Link from "next/link"; import { useRouter } from "next/router"; import { Modal, Text, Divider, ScrollArea, ModalProps, Table, ActionIcon, Badge, Paper, Flex, DefaultMantineColor, Input, Button, Group, Stack, RingProgress, UnstyledButton, Drawer, LoadingOverlay, } from "@mantine/core"; import { useQuery } from "@tanstack/react-query"; import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; import toast from "react-hot-toast"; import { AiOutlineLink } from "react-icons/ai"; import { FaTrash } from "react-icons/fa"; import { MdFileOpen } from "react-icons/md"; import { VscAdd, VscEdit, VscLock, VscUnlock } from "react-icons/vsc"; import { FileFormat } from "src/enums/file.enum"; import { documentSvc } from "src/services/document.service"; import useFile, { File } from "src/store/useFile"; import useUser from "src/store/useUser"; dayjs.extend(relativeTime); const colorByFormat: Record = { json: "orange", yaml: "blue", xml: "red", toml: "dark", csv: "grape", }; const UpdateNameModal: React.FC<{ file: File | null; onClose: () => void; refetch: () => void; }> = ({ file, onClose, refetch }) => { const [name, setName] = React.useState(""); const onSubmit = () => { if (!file) return; toast .promise(documentSvc.update(file.id, { name }), { loading: "Updating document...", error: "Error occurred while updating document!", success: `Renamed document to ${name}`, }) .then(() => { refetch(); setName(""); }); onClose(); }; return ( setName(e.currentTarget.value)} /> ); }; export const CloudModal: React.FC = ({ opened, onClose }) => { const totalQuota = useUser(state => (state.premium ? 200 : 25)); const isPremium = useUser(state => state.premium); const getContents = useFile(state => state.getContents); const setHasChanges = useFile(state => state.setHasChanges); const getFormat = useFile(state => state.getFormat); const [currentFile, setCurrentFile] = React.useState(null); const { isReady, query, replace } = useRouter(); const { data, isLoading, refetch } = useQuery(["allJson", query], () => documentSvc.getAll(), { enabled: isReady && opened, }); const isCreateDisabled = React.useMemo(() => { if (!data?.length) return false; return isPremium ? data.length >= 200 : data.length >= 25; }, [isPremium, data?.length]); const onCreate = async () => { try { toast.loading("Saving document...", { id: "fileSave" }); const { data, error } = await documentSvc.upsert({ contents: getContents(), format: getFormat(), }); if (error) throw error; toast.success("Document saved to cloud", { id: "fileSave" }); setHasChanges(false); replace({ query: { json: data } }); onClose(); } catch (error: any) { toast.error("Failed to save document!", { id: "fileSave" }); console.error(error); } }; const onDeleteClick = React.useCallback( (file: File) => { toast .promise(documentSvc.delete(file.id), { loading: "Deleting file...", error: "An error occurred while deleting the file!", success: `Deleted ${file.name}!`, }) .then(() => refetch()); }, [refetch] ); const copyShareLink = React.useCallback((fileId: string) => { const shareLink = `${window.location.origin}/editor?json=${fileId}`; navigator.clipboard.writeText(shareLink); toast.success("Copied share link to clipboard!"); }, []); const rows = React.useMemo( () => data?.map(element => ( {element.private ? : } {element.id} {element.name} setCurrentFile(element)} > {dayjs(element.created_at).format("DD.MM.YYYY")} {element.format.toUpperCase()} {element.views.toLocaleString("en-US")} onDeleteClick(element)} > copyShareLink(element.id)} > )), [data, copyShareLink, onClose, onDeleteClick] ); return ( {data && ( totalQuota / 1.5 ? "red" : "blue", }, ]} />
Total Quota {data.length} / {totalQuota}
Create New Document
)} The Cloud Save feature is primarily designed for convenient access and is not advisable for storing sensitive data. ID Name Create Date Format Views Actions {rows}
setCurrentFile(null)} refetch={refetch} />
); };