import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { useFileSelection } from "@app/contexts/FileContext"; import { createToolFlow } from "@app/components/tools/shared/createToolFlow"; import { BaseToolProps, ToolComponent } from "@app/types/tool"; import { useEndpointEnabled } from "@app/hooks/useEndpointConfig"; import { useAddStampParameters } from "@app/components/tools/addStamp/useAddStampParameters"; import { useAddStampOperation } from "@app/components/tools/addStamp/useAddStampOperation"; import { Stack, Text } from "@mantine/core"; import StampPreview from "@app/components/tools/addStamp/StampPreview"; import styles from "@app/components/tools/addStamp/StampPreview.module.css"; import ButtonSelector from "@app/components/shared/ButtonSelector"; import { useAccordionSteps } from "@app/hooks/tools/shared/useAccordionSteps"; import ObscuredOverlay from "@app/components/shared/ObscuredOverlay"; import StampSetupSettings from "@app/components/tools/addStamp/StampSetupSettings"; import StampPositionFormattingSettings from "@app/components/tools/addStamp/StampPositionFormattingSettings"; const AddStamp = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => { const { t } = useTranslation(); const { selectedFiles } = useFileSelection(); const [quickPositionModeSelected, setQuickPositionModeSelected] = useState(false); const [customPositionModeSelected, setCustomPositionModeSelected] = useState(true); const params = useAddStampParameters(); const operation = useAddStampOperation(); const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled("add-stamp"); useEffect(() => { operation.resetResults(); onPreviewFile?.(null); }, [params.parameters]); const handleExecute = async () => { try { await operation.executeOperation(params.parameters, selectedFiles); if (operation.files && onComplete) { onComplete(operation.files); } } catch (error: any) { onError?.(error?.message || t("AddStampRequest.error.failed", "Add stamp operation failed")); } }; const hasFiles = selectedFiles.length > 0; const hasResults = operation.files.length > 0 || operation.downloadUrl !== null; enum AddStampStep { NONE = 'none', STAMP_SETUP = 'stampSetup', POSITION_FORMATTING = 'positionFormatting' } const accordion = useAccordionSteps({ noneValue: AddStampStep.NONE, initialStep: AddStampStep.STAMP_SETUP, stateConditions: { hasFiles, hasResults }, afterResults: () => { operation.resetResults(); onPreviewFile?.(null); } }); const getSteps = () => { const steps: any[] = []; // Step 1: Stamp Setup steps.push({ title: t("AddStampRequest.stampSetup", "Stamp Setup"), isCollapsed: accordion.getCollapsedState(AddStampStep.STAMP_SETUP), onCollapsedClick: () => accordion.handleStepToggle(AddStampStep.STAMP_SETUP), isVisible: hasFiles || hasResults, content: ( ), }); // Step 2: Formatting & Position steps.push({ title: t("AddStampRequest.positionAndFormatting", "Position & Formatting"), isCollapsed: accordion.getCollapsedState(AddStampStep.POSITION_FORMATTING), onCollapsedClick: () => accordion.handleStepToggle(AddStampStep.POSITION_FORMATTING), isVisible: hasFiles || hasResults, content: ( {/* Mode toggle: Quick grid vs Custom drag - only show for image stamps */} {params.parameters.stampType === 'image' && ( { const isQuick = v === 'quick'; setQuickPositionModeSelected(isQuick); setCustomPositionModeSelected(!isQuick); }} options={[ { value: 'quick', label: t('quickPosition', 'Quick Position') }, { value: 'custom', label: t('customPosition', 'Custom Position') }, ]} disabled={endpointLoading} buttonClassName={styles.modeToggleButton} textClassName={styles.modeToggleButtonText} /> )} {params.parameters.stampType === 'image' && customPositionModeSelected && (
{t('AddStampRequest.customPosition', 'Drag the stamp to the desired location in the preview window.')}
)} {params.parameters.stampType === 'image' && !customPositionModeSelected && (
{t('AddStampRequest.quickPosition', 'Select a position on the page to place the stamp.')}
)} {/* Unified preview wrapped with obscured overlay if no stamp selected */} {t('AddStampRequest.noStampSelected', 'No stamp selected. Return to Step 1.')} } >
), }); return steps; }; return createToolFlow({ files: { selectedFiles, isCollapsed: hasResults, }, steps: getSteps(), executeButton: { text: t('AddStampRequest.submit', 'Add Stamp'), isVisible: !hasResults, loadingText: t('loading'), onClick: handleExecute, disabled: !params.validateParameters() || !hasFiles || !endpointEnabled, }, review: { isVisible: hasResults, operation: operation, title: t('AddStampRequest.results.title', 'Stamp Results'), onFileClick: (file) => onPreviewFile?.(file), onUndo: async () => { await operation.undoOperation(); onPreviewFile?.(null); }, }, }); }; AddStamp.tool = () => useAddStampOperation; export default AddStamp as ToolComponent;