mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-11-16 01:21:16 +01:00
refactor(frontend): remove unused React default imports (#4529)
## Description of Changes - Removed unused `React` default imports across multiple frontend components. - Updated imports to only include required React hooks and types (e.g., `useState`, `useEffect`, `Suspense`, `createContext`). - Ensured consistency with React 17+ JSX transform, where default `React` import is no longer required. - This cleanup reduces bundle size slightly and aligns code with modern React best practices. --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
This commit is contained in:
parent
d4985f57d4
commit
02189a67bd
@ -1,4 +1,4 @@
|
|||||||
import React, { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { RainbowThemeProvider } from "./components/shared/RainbowThemeProvider";
|
import { RainbowThemeProvider } from "./components/shared/RainbowThemeProvider";
|
||||||
import { FileContextProvider } from "./contexts/FileContext";
|
import { FileContextProvider } from "./contexts/FileContext";
|
||||||
import { NavigationProvider } from "./contexts/NavigationContext";
|
import { NavigationProvider } from "./contexts/NavigationContext";
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
Modal,
|
Modal,
|
||||||
Text,
|
Text,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { FileButton, Button } from "@mantine/core";
|
import { FileButton, Button } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { Flex } from '@mantine/core';
|
import { Flex } from '@mantine/core';
|
||||||
import React from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useCookieConsent } from '../../hooks/useCookieConsent';
|
import { useCookieConsent } from '../../hooks/useCookieConsent';
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { Box, Group, Text, Button } from "@mantine/core";
|
import { Box, Group, Text, Button } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ const MultiSelectControls = ({
|
|||||||
>
|
>
|
||||||
{t("fileManager.clearSelection", "Clear Selection")}
|
{t("fileManager.clearSelection", "Clear Selection")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{onAddToUpload && (
|
{onAddToUpload && (
|
||||||
<Button
|
<Button
|
||||||
size="xs"
|
size="xs"
|
||||||
@ -47,7 +46,7 @@ const MultiSelectControls = ({
|
|||||||
{t("fileManager.addToUpload", "Add to Upload")}
|
{t("fileManager.addToUpload", "Add to Upload")}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{onOpenInFileEditor && (
|
{onOpenInFileEditor && (
|
||||||
<Button
|
<Button
|
||||||
size="xs"
|
size="xs"
|
||||||
@ -58,7 +57,7 @@ const MultiSelectControls = ({
|
|||||||
{t("fileManager.openInFileEditor", "Open in File Editor")}
|
{t("fileManager.openInFileEditor", "Open in File Editor")}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{onOpenInPageEditor && (
|
{onOpenInPageEditor && (
|
||||||
<Button
|
<Button
|
||||||
size="xs"
|
size="xs"
|
||||||
@ -69,7 +68,7 @@ const MultiSelectControls = ({
|
|||||||
{t("fileManager.openInPageEditor", "Open in Page Editor")}
|
{t("fileManager.openInPageEditor", "Open in Page Editor")}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{onDeleteAll && (
|
{onDeleteAll && (
|
||||||
<Button
|
<Button
|
||||||
size="xs"
|
size="xs"
|
||||||
@ -85,4 +84,4 @@ const MultiSelectControls = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MultiSelectControls;
|
export default MultiSelectControls;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Modal, Text, Button, Group, Stack } from '@mantine/core';
|
import { Modal, Text, Button, Group, Stack } from '@mantine/core';
|
||||||
import { useNavigationGuard } from '../../contexts/NavigationContext';
|
import { useNavigationGuard } from '../../contexts/NavigationContext';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { createContext, useContext, ReactNode } from 'react';
|
import { createContext, useContext, ReactNode } from 'react';
|
||||||
import { MantineProvider } from '@mantine/core';
|
import { MantineProvider } from '@mantine/core';
|
||||||
import { useRainbowTheme } from '../../hooks/useRainbowTheme';
|
import { useRainbowTheme } from '../../hooks/useRainbowTheme';
|
||||||
import { mantineTheme } from '../../theme/mantineTheme';
|
import { mantineTheme } from '../../theme/mantineTheme';
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { useToast } from './ToastContext';
|
import { useToast } from './ToastContext';
|
||||||
import { ToastInstance, ToastLocation } from './types';
|
import { ToastInstance, ToastLocation } from './types';
|
||||||
import { LocalIcon } from '../shared/LocalIcon';
|
import { LocalIcon } from '../shared/LocalIcon';
|
||||||
@ -66,7 +65,7 @@ export default function ToastRenderer() {
|
|||||||
<LocalIcon icon={`material-symbols:${getDefaultIconName(t)}`} width={20} height={20} />
|
<LocalIcon icon={`material-symbols:${getDefaultIconName(t)}`} width={20} height={20} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Title + count badge */}
|
{/* Title + count badge */}
|
||||||
<div className="toast-title-container">
|
<div className="toast-title-container">
|
||||||
<span>{t.title}</span>
|
<span>{t.title}</span>
|
||||||
@ -74,7 +73,7 @@ export default function ToastRenderer() {
|
|||||||
<span className="toast-count-badge">{t.count}</span>
|
<span className="toast-count-badge">{t.count}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Controls */}
|
{/* Controls */}
|
||||||
<div className="toast-controls">
|
<div className="toast-controls">
|
||||||
{t.expandable && (
|
{t.expandable && (
|
||||||
@ -101,20 +100,20 @@ export default function ToastRenderer() {
|
|||||||
{/* Progress bar - always show when present */}
|
{/* Progress bar - always show when present */}
|
||||||
{typeof t.progress === 'number' && (
|
{typeof t.progress === 'number' && (
|
||||||
<div className="toast-progress-container">
|
<div className="toast-progress-container">
|
||||||
<div
|
<div
|
||||||
className={getProgressBarClass(t)}
|
className={getProgressBarClass(t)}
|
||||||
style={{ width: `${t.progress}%` }}
|
style={{ width: `${t.progress}%` }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Body content - only show when expanded */}
|
{/* Body content - only show when expanded */}
|
||||||
{(t.isExpanded || !t.expandable) && (
|
{(t.isExpanded || !t.expandable) && (
|
||||||
<div className="toast-body">
|
<div className="toast-body">
|
||||||
{t.body}
|
{t.body}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Button - always show when present, positioned below body */}
|
{/* Button - always show when present, positioned below body */}
|
||||||
{t.buttonText && t.buttonCallback && (
|
{t.buttonText && t.buttonCallback && (
|
||||||
<div className="toast-action-container">
|
<div className="toast-action-container">
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { useToolWorkflow } from "../../contexts/ToolWorkflowContext";
|
import { useToolWorkflow } from "../../contexts/ToolWorkflowContext";
|
||||||
import { BaseToolProps } from "../../types/tool";
|
import { BaseToolProps } from "../../types/tool";
|
||||||
import ToolLoadingFallback from "./ToolLoadingFallback";
|
import ToolLoadingFallback from "./ToolLoadingFallback";
|
||||||
@ -26,7 +26,7 @@ const ToolRenderer = ({
|
|||||||
|
|
||||||
// Wrap lazy-loaded component with Suspense
|
// Wrap lazy-loaded component with Suspense
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<ToolLoadingFallback toolName={selectedTool.name} />}>
|
<Suspense fallback={<ToolLoadingFallback toolName={selectedTool.name} />}>
|
||||||
<ToolComponent
|
<ToolComponent
|
||||||
onPreviewFile={onPreviewFile}
|
onPreviewFile={onPreviewFile}
|
||||||
onComplete={onComplete}
|
onComplete={onComplete}
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* AddWatermarkSingleStepSettings - Used for automation only
|
* AddWatermarkSingleStepSettings - Used for automation only
|
||||||
*
|
*
|
||||||
* This component combines all watermark settings into a single step interface
|
* This component combines all watermark settings into a single step interface
|
||||||
* for use in the automation system. It includes type selection and all relevant
|
* for use in the automation system. It includes type selection and all relevant
|
||||||
* settings in one unified component.
|
* settings in one unified component.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { Stack } from "@mantine/core";
|
import { Stack } from "@mantine/core";
|
||||||
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
||||||
import WatermarkTypeSettings from "./WatermarkTypeSettings";
|
import WatermarkTypeSettings from "./WatermarkTypeSettings";
|
||||||
@ -67,4 +66,4 @@ const AddWatermarkSingleStepSettings = ({ parameters, onParameterChange, disable
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AddWatermarkSingleStepSettings;
|
export default AddWatermarkSingleStepSettings;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { Stack, Checkbox, Group } from "@mantine/core";
|
import { Stack, Checkbox, Group } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
||||||
@ -80,4 +79,4 @@ const WatermarkFormatting = ({ parameters, onParameterChange, disabled = false }
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default WatermarkFormatting;
|
export default WatermarkFormatting;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { Stack } from "@mantine/core";
|
import { Stack } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { Stack, Text, NumberInput } from "@mantine/core";
|
import { Stack, Text, NumberInput } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
||||||
@ -60,4 +59,4 @@ const WatermarkStyleSettings = ({ parameters, onParameterChange, disabled = fals
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default WatermarkStyleSettings;
|
export default WatermarkStyleSettings;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { Stack, Text, Select, ColorInput } from "@mantine/core";
|
import { Stack, Text, Select, ColorInput } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
|
||||||
@ -27,7 +26,7 @@ const WatermarkTextStyle = ({ parameters, onParameterChange, disabled = false }:
|
|||||||
format="hex"
|
format="hex"
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Stack gap="xs">
|
<Stack gap="xs">
|
||||||
<Text size="xs" fw={500}>
|
<Text size="xs" fw={500}>
|
||||||
{t("watermark.settings.alphabet", "Alphabet")}
|
{t("watermark.settings.alphabet", "Alphabet")}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Title, Stack, Divider } from "@mantine/core";
|
import { Title, Stack, Divider } from "@mantine/core";
|
||||||
import AddCircleOutline from "@mui/icons-material/AddCircleOutline";
|
import AddCircleOutline from "@mui/icons-material/AddCircleOutline";
|
||||||
@ -19,11 +18,11 @@ interface AutomationSelectionProps {
|
|||||||
toolRegistry: Record<string, ToolRegistryEntry>;
|
toolRegistry: Record<string, ToolRegistryEntry>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AutomationSelection({
|
export default function AutomationSelection({
|
||||||
savedAutomations,
|
savedAutomations,
|
||||||
onCreateNew,
|
onCreateNew,
|
||||||
onRun,
|
onRun,
|
||||||
onEdit,
|
onEdit,
|
||||||
onDelete,
|
onDelete,
|
||||||
onCopyFromSuggested,
|
onCopyFromSuggested,
|
||||||
toolRegistry
|
toolRegistry
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Stack, Text, Divider, Collapse, Button, NumberInput } from "@mantine/core";
|
import { Stack, Text, Divider, Collapse, Button, NumberInput } from "@mantine/core";
|
||||||
import { BookletImpositionParameters } from "../../../hooks/tools/bookletImposition/useBookletImpositionParameters";
|
import { BookletImpositionParameters } from "../../../hooks/tools/bookletImposition/useBookletImpositionParameters";
|
||||||
@ -176,4 +176,4 @@ const BookletImpositionSettings = ({ parameters, onParameterChange, disabled = f
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BookletImpositionSettings;
|
export default BookletImpositionSettings;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Stack, Text, NumberInput, Select, Divider } from "@mantine/core";
|
import { Stack, Text, NumberInput, Select, Divider } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { CompressParameters } from "../../../hooks/tools/compress/useCompressParameters";
|
import { CompressParameters } from "../../../hooks/tools/compress/useCompressParameters";
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Stack, Text, NumberInput, Checkbox } from '@mantine/core';
|
import { Stack, Text, NumberInput, Checkbox } from '@mantine/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters';
|
import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters';
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { Stack, Text, Select, Switch } from "@mantine/core";
|
import { Stack, Text, Select, Switch } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { COLOR_TYPES, FIT_OPTIONS } from "../../../constants/convertConstants";
|
import { COLOR_TYPES, FIT_OPTIONS } from "../../../constants/convertConstants";
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Stack, Text, NumberInput, Slider } from '@mantine/core';
|
import { Stack, Text, NumberInput, Slider } from '@mantine/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters';
|
import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { Stack, Text, Group, Divider, UnstyledButton, useMantineTheme, useMantineColorScheme } from "@mantine/core";
|
import { Stack, Text, Group, Divider, UnstyledButton, useMantineTheme, useMantineColorScheme } from "@mantine/core";
|
||||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { Stack, Text, Select, NumberInput, Group } from "@mantine/core";
|
import { Stack, Text, Select, NumberInput, Group } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { COLOR_TYPES, OUTPUT_OPTIONS } from "../../../constants/convertConstants";
|
import { COLOR_TYPES, OUTPUT_OPTIONS } from "../../../constants/convertConstants";
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Stack, Text, Select, Alert } from '@mantine/core';
|
import { Stack, Text, Select, Alert } from '@mantine/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters';
|
import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useMemo } from "react";
|
import { useState, useMemo } from "react";
|
||||||
import { Stack, Text, Group, Button, Box, Popover, UnstyledButton, useMantineTheme, useMantineColorScheme } from "@mantine/core";
|
import { Stack, Text, Group, Button, Box, Popover, UnstyledButton, useMantineTheme, useMantineColorScheme } from "@mantine/core";
|
||||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
||||||
|
|
||||||
@ -34,14 +34,14 @@ const GroupedFormatDropdown = ({
|
|||||||
|
|
||||||
const groupedOptions = useMemo(() => {
|
const groupedOptions = useMemo(() => {
|
||||||
const groups: Record<string, FormatOption[]> = {};
|
const groups: Record<string, FormatOption[]> = {};
|
||||||
|
|
||||||
options.forEach(option => {
|
options.forEach(option => {
|
||||||
if (!groups[option.group]) {
|
if (!groups[option.group]) {
|
||||||
groups[option.group] = [];
|
groups[option.group] = [];
|
||||||
}
|
}
|
||||||
groups[option.group].push(option);
|
groups[option.group].push(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
return groups;
|
return groups;
|
||||||
}, [options]);
|
}, [options]);
|
||||||
|
|
||||||
@ -77,14 +77,14 @@ const GroupedFormatDropdown = ({
|
|||||||
padding: '0.5rem 0.75rem',
|
padding: '0.5rem 0.75rem',
|
||||||
border: `0.0625rem solid ${theme.colors.gray[4]}`,
|
border: `0.0625rem solid ${theme.colors.gray[4]}`,
|
||||||
borderRadius: theme.radius.sm,
|
borderRadius: theme.radius.sm,
|
||||||
backgroundColor: disabled
|
backgroundColor: disabled
|
||||||
? theme.colors.gray[1]
|
? theme.colors.gray[1]
|
||||||
: colorScheme === 'dark'
|
: colorScheme === 'dark'
|
||||||
? theme.colors.dark[6]
|
? theme.colors.dark[6]
|
||||||
: theme.white,
|
: theme.white,
|
||||||
cursor: disabled ? 'not-allowed' : 'pointer',
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
color: disabled
|
color: disabled
|
||||||
? colorScheme === 'dark' ? theme.colors.dark[1] : theme.colors.dark[7]
|
? colorScheme === 'dark' ? theme.colors.dark[1] : theme.colors.dark[7]
|
||||||
: colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.dark[9]
|
: colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.dark[9]
|
||||||
}}
|
}}
|
||||||
@ -93,19 +93,19 @@ const GroupedFormatDropdown = ({
|
|||||||
<Text size="sm" c={value ? undefined : 'dimmed'}>
|
<Text size="sm" c={value ? undefined : 'dimmed'}>
|
||||||
{selectedLabel}
|
{selectedLabel}
|
||||||
</Text>
|
</Text>
|
||||||
<KeyboardArrowDownIcon
|
<KeyboardArrowDownIcon
|
||||||
style={{
|
style={{
|
||||||
fontSize: '1rem',
|
fontSize: '1rem',
|
||||||
transform: dropdownOpened ? 'rotate(180deg)' : 'rotate(0deg)',
|
transform: dropdownOpened ? 'rotate(180deg)' : 'rotate(0deg)',
|
||||||
transition: 'transform 0.2s ease',
|
transition: 'transform 0.2s ease',
|
||||||
color: colorScheme === 'dark' ? theme.colors.dark[2] : theme.colors.gray[6]
|
color: colorScheme === 'dark' ? theme.colors.dark[2] : theme.colors.gray[6]
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
</UnstyledButton>
|
</UnstyledButton>
|
||||||
</Popover.Target>
|
</Popover.Target>
|
||||||
<Popover.Dropdown
|
<Popover.Dropdown
|
||||||
style={{
|
style={{
|
||||||
minWidth: Math.min(350, parseInt(minWidth.replace('rem', '')) * 16),
|
minWidth: Math.min(350, parseInt(minWidth.replace('rem', '')) * 16),
|
||||||
maxWidth: '90vw',
|
maxWidth: '90vw',
|
||||||
maxHeight: '40vh',
|
maxHeight: '40vh',
|
||||||
@ -117,10 +117,10 @@ const GroupedFormatDropdown = ({
|
|||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
{Object.entries(groupedOptions).map(([groupName, groupOptions]) => (
|
{Object.entries(groupedOptions).map(([groupName, groupOptions]) => (
|
||||||
<Box key={groupName}>
|
<Box key={groupName}>
|
||||||
<Text
|
<Text
|
||||||
size="sm"
|
size="sm"
|
||||||
fw={600}
|
fw={600}
|
||||||
c={colorScheme === 'dark' ? 'dark.2' : 'gray.6'}
|
c={colorScheme === 'dark' ? 'dark.2' : 'gray.6'}
|
||||||
mb="xs"
|
mb="xs"
|
||||||
>
|
>
|
||||||
{groupName}
|
{groupName}
|
||||||
@ -153,4 +153,4 @@ const GroupedFormatDropdown = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GroupedFormatDropdown;
|
export default GroupedFormatDropdown;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Divider, Select, Stack, Switch } from '@mantine/core';
|
import { Divider, Select, Stack, Switch } from '@mantine/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PageLayoutParameters } from '../../../hooks/tools/pageLayout/usePageLayoutParameters';
|
import { PageLayoutParameters } from '../../../hooks/tools/pageLayout/usePageLayoutParameters';
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Divider, Select, Stack, TextInput } from '@mantine/core';
|
import { Divider, Select, Stack, TextInput } from '@mantine/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ReorganizePagesParameters } from '../../../hooks/tools/reorganizePages/useReorganizePagesParameters';
|
import { ReorganizePagesParameters } from '../../../hooks/tools/reorganizePages/useReorganizePagesParameters';
|
||||||
@ -31,7 +30,7 @@ export default function ReorganizePagesSettings({
|
|||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
{selectedMode && (
|
{selectedMode && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: 'var(--information-text-bg)',
|
backgroundColor: 'var(--information-text-bg)',
|
||||||
color: 'var(--information-text-color)',
|
color: 'var(--information-text-color)',
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { Stack, Text, Select, ColorInput } from "@mantine/core";
|
import { Stack, Text, Select, ColorInput } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { ReplaceColorParameters } from "../../../hooks/tools/replaceColor/useReplaceColorParameters";
|
import { ReplaceColorParameters } from "../../../hooks/tools/replaceColor/useReplaceColorParameters";
|
||||||
@ -105,4 +104,4 @@ const ReplaceColorSettings = ({ parameters, onParameterChange, disabled = false
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ReplaceColorSettings;
|
export default ReplaceColorSettings;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Stack, Text } from '@mantine/core';
|
import { Stack, Text } from '@mantine/core';
|
||||||
import { formatFileSize, getFileDate } from '../../../utils/fileUtils';
|
import { formatFileSize, getFileDate } from '../../../utils/fileUtils';
|
||||||
|
|
||||||
@ -24,4 +23,4 @@ const FileMetadata = ({ file }: FileMetadataProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FileMetadata;
|
export default FileMetadata;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Stack, Group, ActionIcon, Text } from '@mantine/core';
|
import { Stack, Group, ActionIcon, Text } from '@mantine/core';
|
||||||
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
|
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
|
||||||
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { Stack, Text, NumberInput } from "@mantine/core";
|
import { Stack, Text, NumberInput } from "@mantine/core";
|
||||||
|
|
||||||
interface NumberInputWithUnitProps {
|
interface NumberInputWithUnitProps {
|
||||||
@ -11,14 +11,14 @@ interface NumberInputWithUnitProps {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NumberInputWithUnit = ({
|
const NumberInputWithUnit = ({
|
||||||
label,
|
label,
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
unit,
|
unit,
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
disabled = false
|
disabled = false
|
||||||
}: NumberInputWithUnitProps) => {
|
}: NumberInputWithUnitProps) => {
|
||||||
const [localValue, setLocalValue] = useState<number | string>(value);
|
const [localValue, setLocalValue] = useState<number | string>(value);
|
||||||
|
|
||||||
@ -54,4 +54,4 @@ const NumberInputWithUnit = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NumberInputWithUnit;
|
export default NumberInputWithUnit;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Button } from '@mantine/core';
|
import { Button } from '@mantine/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Box, Text, Loader, Stack, Center, Flex } from '@mantine/core';
|
import { Box, Text, Loader, Stack, Center, Flex } from '@mantine/core';
|
||||||
import FilePreview from '../../shared/FilePreview';
|
import FilePreview from '../../shared/FilePreview';
|
||||||
import FileMetadata from './FileMetadata';
|
import FileMetadata from './FileMetadata';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Stack, Button, Text, Alert, Tabs } from '@mantine/core';
|
import { Stack, Button, Text, Alert, Tabs } from '@mantine/core';
|
||||||
import { SignParameters } from "../../../hooks/tools/sign/useSignParameters";
|
import { SignParameters } from "../../../hooks/tools/sign/useSignParameters";
|
||||||
@ -256,4 +256,4 @@ const SignSettings = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SignSettings;
|
export default SignSettings;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useRef, useEffect, useMemo } from "react";
|
import { useState, useRef, useEffect, useMemo } from "react";
|
||||||
import { Stack, Button, Text } from "@mantine/core";
|
import { Stack, Button, Text } from "@mantine/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import LocalIcon from '../../shared/LocalIcon';
|
import LocalIcon from '../../shared/LocalIcon';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useMemo } from 'react';
|
import { useState, useEffect, useMemo } from 'react';
|
||||||
import { useSearch } from '@embedpdf/plugin-search/react';
|
import { useSearch } from '@embedpdf/plugin-search/react';
|
||||||
import { useViewer } from '../../contexts/ViewerContext';
|
import { useViewer } from '../../contexts/ViewerContext';
|
||||||
import { SEARCH_CONSTANTS } from './constants/search';
|
import { SEARCH_CONSTANTS } from './constants/search';
|
||||||
@ -24,9 +24,9 @@ interface SearchResultState {
|
|||||||
activeResultIndex?: number;
|
activeResultIndex?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CustomSearchLayer({
|
export function CustomSearchLayer({
|
||||||
pageIndex,
|
pageIndex,
|
||||||
scale,
|
scale,
|
||||||
highlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.BACKGROUND,
|
highlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.BACKGROUND,
|
||||||
activeHighlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.ACTIVE_BACKGROUND,
|
activeHighlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.ACTIVE_BACKGROUND,
|
||||||
opacity = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.OPACITY,
|
opacity = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.OPACITY,
|
||||||
@ -42,17 +42,17 @@ export function CustomSearchLayer({
|
|||||||
if (!searchProvides) {
|
if (!searchProvides) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsubscribe = searchProvides.onSearchResultStateChange?.((state: SearchResultState) => {
|
const unsubscribe = searchProvides.onSearchResultStateChange?.((state: SearchResultState) => {
|
||||||
// Auto-scroll to active search result
|
// Auto-scroll to active search result
|
||||||
if (state?.results && state.activeResultIndex !== undefined && state.activeResultIndex >= 0) {
|
if (state?.results && state.activeResultIndex !== undefined && state.activeResultIndex >= 0) {
|
||||||
const activeResult = state.results[state.activeResultIndex];
|
const activeResult = state.results[state.activeResultIndex];
|
||||||
if (activeResult) {
|
if (activeResult) {
|
||||||
const pageNumber = activeResult.pageIndex + 1; // Convert to 1-based page number
|
const pageNumber = activeResult.pageIndex + 1; // Convert to 1-based page number
|
||||||
scrollActions.scrollToPage(pageNumber);
|
scrollActions.scrollToPage(pageNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setSearchResultState(state);
|
setSearchResultState(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ export function CustomSearchLayer({
|
|||||||
const filtered = searchResultState.results
|
const filtered = searchResultState.results
|
||||||
.map((result, originalIndex) => ({ result, originalIndex }))
|
.map((result, originalIndex) => ({ result, originalIndex }))
|
||||||
.filter(({ result }) => result.pageIndex === pageIndex);
|
.filter(({ result }) => result.pageIndex === pageIndex);
|
||||||
|
|
||||||
return filtered;
|
return filtered;
|
||||||
}, [searchResultState, pageIndex]);
|
}, [searchResultState, pageIndex]);
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ export function CustomSearchLayer({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
@ -117,4 +117,4 @@ export function CustomSearchLayer({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { createPluginRegistration } from '@embedpdf/core';
|
import { createPluginRegistration } from '@embedpdf/core';
|
||||||
import { EmbedPDF } from '@embedpdf/core/react';
|
import { EmbedPDF } from '@embedpdf/core/react';
|
||||||
import { usePdfiumEngine } from '@embedpdf/engines/react';
|
import { usePdfiumEngine } from '@embedpdf/engines/react';
|
||||||
@ -312,4 +312,4 @@ export function LocalEmbedPDFWithAnnotations({
|
|||||||
</EmbedPDF>
|
</EmbedPDF>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Button, Paper, Group, NumberInput } from '@mantine/core';
|
import { Button, Paper, Group, NumberInput } from '@mantine/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useViewer } from '../../contexts/ViewerContext';
|
import { useViewer } from '../../contexts/ViewerContext';
|
||||||
@ -14,11 +14,11 @@ interface PdfViewerToolbarProps {
|
|||||||
currentPage?: number;
|
currentPage?: number;
|
||||||
totalPages?: number;
|
totalPages?: number;
|
||||||
onPageChange?: (page: number) => void;
|
onPageChange?: (page: number) => void;
|
||||||
|
|
||||||
// Dual page toggle (placeholder for now)
|
// Dual page toggle (placeholder for now)
|
||||||
dualPage?: boolean;
|
dualPage?: boolean;
|
||||||
onDualPageToggle?: () => void;
|
onDualPageToggle?: () => void;
|
||||||
|
|
||||||
// Zoom controls (connected via ViewerContext)
|
// Zoom controls (connected via ViewerContext)
|
||||||
currentZoom?: number;
|
currentZoom?: number;
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ export function PdfViewerToolbar({
|
|||||||
}: PdfViewerToolbarProps) {
|
}: PdfViewerToolbarProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { getScrollState, getZoomState, scrollActions, zoomActions, registerImmediateZoomUpdate, registerImmediateScrollUpdate } = useViewer();
|
const { getScrollState, getZoomState, scrollActions, zoomActions, registerImmediateZoomUpdate, registerImmediateScrollUpdate } = useViewer();
|
||||||
|
|
||||||
const scrollState = getScrollState();
|
const scrollState = getScrollState();
|
||||||
const zoomState = getZoomState();
|
const zoomState = getZoomState();
|
||||||
const [pageInput, setPageInput] = useState(scrollState.currentPage || currentPage);
|
const [pageInput, setPageInput] = useState(scrollState.currentPage || currentPage);
|
||||||
@ -151,7 +151,7 @@ export function PdfViewerToolbar({
|
|||||||
input: { width: 48, textAlign: "center", fontWeight: 500, fontSize: 16 },
|
input: { width: 48, textAlign: "center", fontWeight: 500, fontSize: 16 },
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<span style={{ fontWeight: 500, fontSize: 16 }}>
|
<span style={{ fontWeight: 500, fontSize: 16 }}>
|
||||||
/ {scrollState.totalPages}
|
/ {scrollState.totalPages}
|
||||||
</span>
|
</span>
|
||||||
@ -229,4 +229,4 @@ export function PdfViewerToolbar({
|
|||||||
</Group>
|
</Group>
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Box, ScrollArea } from '@mantine/core';
|
import { Box, ScrollArea } from '@mantine/core';
|
||||||
import { useViewer } from '../../contexts/ViewerContext';
|
import { useViewer } from '../../contexts/ViewerContext';
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import EmbedPdfViewer from './EmbedPdfViewer';
|
import EmbedPdfViewer from './EmbedPdfViewer';
|
||||||
|
|
||||||
export interface ViewerProps {
|
export interface ViewerProps {
|
||||||
@ -13,4 +12,4 @@ const Viewer = (props: ViewerProps) => {
|
|||||||
return <EmbedPdfViewer {...props} />;
|
return <EmbedPdfViewer {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Viewer;
|
export default Viewer;
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
* Memory management handled by FileLifecycleManager (PDF.js cleanup, blob URL revocation).
|
* Memory management handled by FileLifecycleManager (PDF.js cleanup, blob URL revocation).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useReducer, useCallback, useEffect, useRef, useMemo } from 'react';
|
import { useReducer, useCallback, useEffect, useRef, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
FileContextProviderProps,
|
FileContextProviderProps,
|
||||||
FileContextSelectors,
|
FileContextSelectors,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { createContext, useContext, useState, useRef, useMemo } from 'react';
|
import { createContext, useContext, useState, useRef, useMemo } from 'react';
|
||||||
import { SidebarState, SidebarRefs, SidebarContextValue, SidebarProviderProps } from '../types/sidebar';
|
import { SidebarState, SidebarRefs, SidebarContextValue, SidebarProviderProps } from '../types/sidebar';
|
||||||
|
|
||||||
const SidebarContext = createContext<SidebarContextValue | undefined>(undefined);
|
const SidebarContext = createContext<SidebarContextValue | undefined>(undefined);
|
||||||
@ -7,7 +7,7 @@ export function SidebarProvider({ children }: SidebarProviderProps) {
|
|||||||
// All sidebar state management
|
// All sidebar state management
|
||||||
const quickAccessRef = useRef<HTMLDivElement>(null);
|
const quickAccessRef = useRef<HTMLDivElement>(null);
|
||||||
const toolPanelRef = useRef<HTMLDivElement>(null);
|
const toolPanelRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const [sidebarsVisible, setSidebarsVisible] = useState(true);
|
const [sidebarsVisible, setSidebarsVisible] = useState(true);
|
||||||
const [leftPanelView, setLeftPanelView] = useState<'toolPicker' | 'toolContent'>('toolPicker');
|
const [leftPanelView, setLeftPanelView] = useState<'toolPicker' | 'toolContent'>('toolPicker');
|
||||||
const [readerMode, setReaderMode] = useState(false);
|
const [readerMode, setReaderMode] = useState(false);
|
||||||
@ -44,4 +44,4 @@ export function useSidebarContext(): SidebarContextValue {
|
|||||||
throw new Error('useSidebarContext must be used within a SidebarProvider');
|
throw new Error('useSidebarContext must be used within a SidebarProvider');
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useEndpointEnabled } from "../hooks/useEndpointConfig";
|
import { useEndpointEnabled } from "../hooks/useEndpointConfig";
|
||||||
import { useFileSelection } from "../contexts/FileContext";
|
import { useFileSelection } from "../contexts/FileContext";
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { createToolFlow } from "../components/tools/shared/createToolFlow";
|
import { createToolFlow } from "../components/tools/shared/createToolFlow";
|
||||||
import { BaseToolProps, ToolComponent } from "../types/tool";
|
import { BaseToolProps, ToolComponent } from "../types/tool";
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { createToolFlow } from "../components/tools/shared/createToolFlow";
|
import { createToolFlow } from "../components/tools/shared/createToolFlow";
|
||||||
import { BaseToolProps, ToolComponent } from "../types/tool";
|
import { BaseToolProps, ToolComponent } from "../types/tool";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user