Files
lmtlab/app/jsonparser/ExportModal.tsx
T

128 lines
4.8 KiB
TypeScript

'use client';
import React, { useEffect, useState } from 'react';
import {
Button,
Checkbox,
CheckboxGroup,
Modal,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
Textarea
} from '@nextui-org/react';
import { toast } from 'react-toastify';
import { HiOutlineDownload, HiOutlineDuplicate } from 'react-icons/hi';
const workflows = new Map<string, (json: string) => string>([
[ 'minify', (json) => {
try {
const value = JSON.parse(json);
return JSON.stringify(value);
} catch (e) {
toast.error(`Operation Failed: ${ e }`, { autoClose: 5000 });
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return e.toString();
}
} ]
]);
type Props = { isOpen: boolean, onOpenChange: () => void, value: string };
const ExportModal = ({ isOpen, onOpenChange, value }: Props) => {
const [ workflow, setWorkflow ] = useState<string[]>([]);
const [ editorValue, setEditorValue ] = useState(value);
useEffect(() => {
setEditorValue(value);
}, [ value ]);
const [ exportValue, setExportValue ] = useState(editorValue);
useEffect(() => {
let value = editorValue;
for (const fn of workflow) {
const func = workflows.get(fn);
value = func ? func(value) : value;
}
setExportValue(value);
}, [ workflow, editorValue ]);
return (
<Modal
isOpen={ isOpen }
onOpenChange={ onOpenChange }
size={ '4xl' }
hideCloseButton
>
<ModalContent>
{ (onClose) => (
<>
<ModalHeader className="gap-1">Export</ModalHeader>
<ModalBody>
<CheckboxGroup
label={ 'Config' }
color={ 'primary' }
value={ workflow }
onChange={ setWorkflow }
>
<Checkbox value={ 'minify' }>Minify</Checkbox>
</CheckboxGroup>
<Textarea
label={ 'Value' }
variant={ 'flat' }
value={ exportValue }
readOnly
/>
<div
className={ 'mt-3 flex flex-col md:flex-row gap-1 justify-center' }
>
<Button
color={ 'primary' }
aria-label={ 'Download' }
startContent={ <HiOutlineDownload size={ 20 } /> }
onClick={ () => {
const blob = new Blob([ exportValue ], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'value.json';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
toast.success('File Downloaded');
} }
>
Download
</Button>
<Button
color={ 'success' }
aria-label={ 'Copy' }
startContent={ <HiOutlineDuplicate size={ 20 } /> }
onClick={ () => {
navigator.clipboard.writeText(exportValue);
toast.success('Copied to Clipboard');
} }
>
Copy
</Button>
</div>
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={ onClose }>
Close
</Button>
</ModalFooter>
</>
) }
</ModalContent>
</Modal>
);
};
export default ExportModal;