import React, { useEffect, useMemo, useState } from "react"; import { Button, Stack, Text } from "@mantine/core"; import { useTranslation } from "react-i18next"; import DownloadIcon from "@mui/icons-material/Download"; import { useEndpointEnabled } from "../hooks/useEndpointConfig"; import { useFileContext } from "../contexts/FileContext"; import { useToolFileSelection } from "../contexts/FileSelectionContext"; import ToolStep, { ToolStepContainer } from "../components/tools/shared/ToolStep"; import OperationButton from "../components/tools/shared/OperationButton"; import ErrorNotification from "../components/tools/shared/ErrorNotification"; import FileStatusIndicator from "../components/tools/shared/FileStatusIndicator"; import ResultsPreview from "../components/tools/shared/ResultsPreview"; import WatermarkTypeSettings from "../components/tools/addWatermark/WatermarkTypeSettings"; import WatermarkContentSettings from "../components/tools/addWatermark/WatermarkContentSettings"; import WatermarkStyleSettings from "../components/tools/addWatermark/WatermarkStyleSettings"; import { useAddWatermarkParameters } from "../hooks/tools/addWatermark/useAddWatermarkParameters"; import { useAddWatermarkOperation } from "../hooks/tools/addWatermark/useAddWatermarkOperation"; import { BaseToolProps } from "../types/tool"; const AddWatermark = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => { const { t } = useTranslation(); const { setCurrentMode } = useFileContext(); const { selectedFiles } = useToolFileSelection(); const watermarkParams = useAddWatermarkParameters(); const watermarkOperation = useAddWatermarkOperation(); // Endpoint validation const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled("add-watermark"); useEffect(() => { watermarkOperation.resetResults(); onPreviewFile?.(null); }, [watermarkParams.parameters, selectedFiles]); const handleAddWatermark = async () => { try { await watermarkOperation.executeOperation( watermarkParams.parameters, selectedFiles ); if (watermarkOperation.files && onComplete) { onComplete(watermarkOperation.files); } } catch (error) { if (onError) { onError(error instanceof Error ? error.message : 'Add watermark operation failed'); } } }; const handleThumbnailClick = (file: File) => { onPreviewFile?.(file); sessionStorage.setItem('previousMode', 'watermark'); setCurrentMode('viewer'); }; const handleSettingsReset = () => { watermarkOperation.resetResults(); onPreviewFile?.(null); setCurrentMode('watermark'); }; const hasFiles = selectedFiles.length > 0; const hasResults = watermarkOperation.files.length > 0 || watermarkOperation.downloadUrl !== null; const filesCollapsed = hasFiles; // Step completion logic const typeStepCompleted = hasFiles && !!watermarkParams.parameters.watermarkType; const contentStepCompleted = typeStepCompleted && ( (watermarkParams.parameters.watermarkType === 'text' && watermarkParams.parameters.watermarkText.trim().length > 0) || (watermarkParams.parameters.watermarkType === 'image' && watermarkParams.parameters.watermarkImage !== undefined) ); const styleStepCompleted = contentStepCompleted; // Style step has defaults, so completed when content is done // Track which steps have been manually opened const [manuallyOpenedSteps, setManuallyOpenedSteps] = useState>(new Set()); // Auto-collapse logic with manual override const typeStepCollapsed = typeStepCompleted && !hasResults && !manuallyOpenedSteps.has('type'); const contentStepCollapsed = contentStepCompleted && !hasResults && !manuallyOpenedSteps.has('content'); const styleStepCollapsed = !manuallyOpenedSteps.has('style'); // Style starts collapsed, only opens when clicked // Click handlers to manage step visibility and reset results const handleTypeStepClick = () => { setManuallyOpenedSteps(prev => { const newSet = new Set(prev); if (newSet.has('type')) { newSet.delete('type'); // Close if already open } else { newSet.add('type'); // Open if closed } return newSet; }); watermarkOperation.resetResults(); onPreviewFile?.(null); }; const handleContentStepClick = () => { setManuallyOpenedSteps(prev => { const newSet = new Set(prev); if (newSet.has('content')) { newSet.delete('content'); // Close if already open } else { newSet.add('content'); // Open if closed } return newSet; }); watermarkOperation.resetResults(); onPreviewFile?.(null); }; const handleStyleStepClick = () => { setManuallyOpenedSteps(prev => { const newSet = new Set(prev); if (newSet.has('style')) { newSet.delete('style'); // Close if already open } else { newSet.add('style'); // Open if closed } return newSet; }); watermarkOperation.resetResults(); onPreviewFile?.(null); }; const previewResults = useMemo(() => watermarkOperation.files?.map((file, index) => ({ file, thumbnail: watermarkOperation.thumbnails[index] })) || [], [watermarkOperation.files, watermarkOperation.thumbnails] ); return ( {/* Files Step */} {/* Watermark Type Step */} watermarkParams.updateParameter('watermarkType', type)} disabled={endpointLoading} /> {/* Content Step */} {/* Style Step */} {/* Apply Button - Outside of settings steps */} {styleStepCompleted && !hasResults && ( )} {/* Results Step */} {watermarkOperation.status && ( {watermarkOperation.status} )} {watermarkOperation.downloadUrl && ( )} ); } export default AddWatermark;