analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
1 lines • 7.6 kB
Source Map (JSON)
{"version":3,"sources":["../src/components/DownloadModal/DownloadModal.tsx","../src/enums/DownloadFormat.ts"],"sourcesContent":["import { useState, useCallback, useEffect, useRef } from 'react';\nimport {\n FilePdfIcon,\n FileXlsIcon,\n DownloadSimpleIcon,\n} from '@phosphor-icons/react';\nimport Modal from '../Modal/Modal';\nimport Button from '../Button/Button';\nimport Text from '../Text/Text';\nimport { Skeleton } from '../Skeleton/Skeleton';\nimport { DOWNLOAD_FORMAT } from '../../enums/DownloadFormat';\n\n/**\n * Download format type alias\n */\nexport type DownloadFormat = DOWNLOAD_FORMAT;\n\n/**\n * Props for the DownloadModal component\n */\nexport interface DownloadModalProps {\n readonly isOpen: boolean;\n readonly onClose: () => void;\n readonly isDownloading: boolean;\n readonly error: string | null;\n readonly onDownloadPdf: () => void;\n readonly onDownloadExcel: () => void;\n}\n\n/**\n * Modal with two selectable format cards (PDF and Excel) and action buttons.\n * Shows skeleton placeholders while generating files.\n */\nconst DownloadModal = ({\n isOpen,\n onClose,\n isDownloading,\n error,\n onDownloadPdf,\n onDownloadExcel,\n}: DownloadModalProps) => {\n const [selectedFormat, setSelectedFormat] = useState<DownloadFormat | null>(\n null\n );\n\n const handleClose = useCallback(() => {\n setSelectedFormat(null);\n onClose();\n }, [onClose]);\n\n // Auto-close the modal when an async download transitions from loading\n // to idle without an error. Consumers only need to toggle `isDownloading`\n // in their download hook — no extra parent-side logic required.\n const wasDownloadingRef = useRef(false);\n useEffect(() => {\n if (!isOpen) {\n wasDownloadingRef.current = isDownloading;\n return;\n }\n if (wasDownloadingRef.current && !isDownloading && !error) {\n handleClose();\n }\n wasDownloadingRef.current = isDownloading;\n }, [isOpen, isDownloading, error, handleClose]);\n\n const handleDownload = useCallback(() => {\n if (selectedFormat === DOWNLOAD_FORMAT.PDF) {\n onDownloadPdf();\n handleClose();\n } else if (selectedFormat === DOWNLOAD_FORMAT.EXCEL) {\n // Excel generation is async. The useEffect above auto-closes the modal\n // once `isDownloading` transitions back to false and there is no error.\n onDownloadExcel();\n }\n }, [selectedFormat, onDownloadPdf, onDownloadExcel, handleClose]);\n\n const cardBase =\n 'flex flex-1 items-center justify-center h-20 rounded-xl border bg-background shadow-soft-shadow-1 cursor-pointer transition-colors';\n const cardDefault = 'border-border-100 hover:border-primary-300';\n const cardSelected = 'border-primary-300 bg-primary-50';\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title=\"Como deseja baixar o relatório?\"\n size=\"lg\"\n footer={\n <div className=\"flex justify-end gap-2\">\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"small\"\n onClick={handleClose}\n data-testid=\"download-cancel-btn\"\n >\n Cancelar\n </Button>\n <Button\n variant=\"solid\"\n action=\"primary\"\n size=\"small\"\n disabled={!selectedFormat || isDownloading}\n iconLeft={<DownloadSimpleIcon size={16} />}\n onClick={handleDownload}\n data-testid=\"download-confirm-btn\"\n >\n Baixar\n </Button>\n </div>\n }\n >\n <div className=\"flex flex-col gap-3\">\n {error && (\n <Text size=\"sm\" className=\"text-indicator-error\">\n {error}\n </Text>\n )}\n\n {isDownloading ? (\n <div className=\"flex flex-row gap-4\" data-testid=\"download-skeleton\">\n <Skeleton variant=\"rounded\" width=\"100%\" height={80} />\n <Skeleton variant=\"rounded\" width=\"100%\" height={80} />\n </div>\n ) : (\n <div className=\"flex flex-row gap-4\">\n <Button\n data-testid=\"download-pdf-option\"\n aria-label=\"PDF\"\n aria-pressed={selectedFormat === DOWNLOAD_FORMAT.PDF}\n variant=\"outline\"\n action=\"secondary\"\n className={`${cardBase} ${selectedFormat === DOWNLOAD_FORMAT.PDF ? cardSelected : cardDefault}`}\n onClick={() => setSelectedFormat(DOWNLOAD_FORMAT.PDF)}\n >\n <FilePdfIcon size={24} className=\"text-text-700\" />\n </Button>\n\n <Button\n data-testid=\"download-excel-option\"\n aria-label=\"Excel\"\n aria-pressed={selectedFormat === DOWNLOAD_FORMAT.EXCEL}\n variant=\"outline\"\n action=\"secondary\"\n className={`${cardBase} ${selectedFormat === DOWNLOAD_FORMAT.EXCEL ? cardSelected : cardDefault}`}\n onClick={() => setSelectedFormat(DOWNLOAD_FORMAT.EXCEL)}\n >\n <FileXlsIcon size={24} className=\"text-text-700\" />\n </Button>\n </div>\n )}\n </div>\n </Modal>\n );\n};\n\nexport default DownloadModal;\n","/**\n * Supported download format options\n */\nexport enum DOWNLOAD_FORMAT {\n PDF = 'pdf',\n EXCEL = 'excel',\n}\n"],"mappings":"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","names":["DOWNLOAD_FORMAT"]}