step it out

This commit is contained in:
EthanHealy01 2025-09-29 16:48:12 +01:00
parent beb54c748f
commit bf1f6c1f91
5 changed files with 121 additions and 11 deletions

View File

@ -0,0 +1,44 @@
import React from 'react';
import { Stack, Slider, Text, Group, NumberInput } from '@mantine/core';
import { useTranslation } from 'react-i18next';
import { AdjustContrastParameters } from '../../../hooks/tools/adjustContrast/useAdjustContrastParameters';
interface Props {
parameters: AdjustContrastParameters;
onParameterChange: <K extends keyof AdjustContrastParameters>(key: K, value: AdjustContrastParameters[K]) => void;
disabled?: boolean;
}
export default function AdjustContrastBasicSettings({ parameters, onParameterChange, disabled }: Props) {
const { t } = useTranslation();
const renderSlider = (label: string, value: number, onChange: (v: number) => void) => (
<div>
<Text size="sm" fw={600} mb={4}>{label}: {Math.round(value)}%</Text>
<Group gap="sm" align="center">
<div style={{ flex: 1 }}>
<Slider min={0} max={200} step={1} value={value} onChange={onChange} disabled={disabled} />
</div>
<NumberInput
value={value}
onChange={(v) => onChange(Number(v) || 0)}
min={0}
max={200}
step={1}
disabled={disabled}
style={{ width: 90 }}
/>
</Group>
</div>
);
return (
<Stack gap="md">
{renderSlider(t('adjustContrast.contrast', 'Contrast'), parameters.contrast, (v) => onParameterChange('contrast', v as any))}
{renderSlider(t('adjustContrast.brightness', 'Brightness'), parameters.brightness, (v) => onParameterChange('brightness', v as any))}
{renderSlider(t('adjustContrast.saturation', 'Saturation'), parameters.saturation, (v) => onParameterChange('saturation', v as any))}
</Stack>
);
}

View File

@ -0,0 +1,44 @@
import React from 'react';
import { Stack, Slider, Text, Group, NumberInput } from '@mantine/core';
import { useTranslation } from 'react-i18next';
import { AdjustContrastParameters } from '../../../hooks/tools/adjustContrast/useAdjustContrastParameters';
interface Props {
parameters: AdjustContrastParameters;
onParameterChange: <K extends keyof AdjustContrastParameters>(key: K, value: AdjustContrastParameters[K]) => void;
disabled?: boolean;
}
export default function AdjustContrastColorSettings({ parameters, onParameterChange, disabled }: Props) {
const { t } = useTranslation();
const renderSlider = (label: string, value: number, onChange: (v: number) => void) => (
<div>
<Text size="sm" fw={600} mb={4}>{label}: {Math.round(value)}%</Text>
<Group gap="sm" align="center">
<div style={{ flex: 1 }}>
<Slider min={0} max={200} step={1} value={value} onChange={onChange} disabled={disabled} />
</div>
<NumberInput
value={value}
onChange={(v) => onChange(Number(v) || 0)}
min={0}
max={200}
step={1}
disabled={disabled}
style={{ width: 90 }}
/>
</Group>
</div>
);
return (
<Stack gap="md">
{renderSlider(t('adjustContrast.red', 'Red'), parameters.red, (v) => onParameterChange('red', v as any))}
{renderSlider(t('adjustContrast.green', 'Green'), parameters.green, (v) => onParameterChange('green', v as any))}
{renderSlider(t('adjustContrast.blue', 'Blue'), parameters.blue, (v) => onParameterChange('blue', v as any))}
</Stack>
);
}

View File

@ -1,6 +1,5 @@
import React from 'react';
import { Stack, Slider, Text, Group, NumberInput, Divider } from '@mantine/core';
import AdjustContrastPreview from './AdjustContrastPreview';
import { useTranslation } from 'react-i18next';
import { AdjustContrastParameters } from '../../../hooks/tools/adjustContrast/useAdjustContrastParameters';
@ -11,7 +10,7 @@ interface Props {
file?: File | null;
}
export default function AdjustContrastSettings({ parameters, onParameterChange, disabled, file }: Props) {
export default function AdjustContrastSettings({ parameters, onParameterChange, disabled }: Props) {
const { t } = useTranslation();
const renderSlider = (label: string, value: number, onChange: (v: number) => void) => (
@ -45,8 +44,6 @@ export default function AdjustContrastSettings({ parameters, onParameterChange,
{renderSlider(t('adjustContrast.red', 'Red'), parameters.red, (v) => onParameterChange('red', v as any))}
{renderSlider(t('adjustContrast.green', 'Green'), parameters.green, (v) => onParameterChange('green', v as any))}
{renderSlider(t('adjustContrast.blue', 'Blue'), parameters.blue, (v) => onParameterChange('blue', v as any))}
{/* Inline accurate preview */}
<AdjustContrastPreview file={file || null} parameters={parameters} />
</Stack>
);
}

View File

@ -54,6 +54,8 @@ export interface ToolFlowConfig {
title?: TitleConfig;
files: FilesStepConfig;
steps: MiddleStepConfig[];
// Optional preview content rendered between steps and the execute button
preview?: React.ReactNode;
executeButton?: ExecuteButtonConfig;
review: ReviewStepConfig;
forceStepNumbers?: boolean;
@ -90,6 +92,9 @@ export function createToolFlow(config: ToolFlowConfig) {
}, stepConfig.content)
)}
{/* Preview (outside steps, above execute button). Hide when review is visible. */}
{!config.review.isVisible && config.preview}
{/* Execute Button */}
{config.executeButton && config.executeButton.isVisible !== false && (
<OperationButton

View File

@ -5,6 +5,9 @@ import { useBaseTool } from '../hooks/tools/shared/useBaseTool';
import { useAdjustContrastParameters } from '../hooks/tools/adjustContrast/useAdjustContrastParameters';
import { useAdjustContrastOperation } from '../hooks/tools/adjustContrast/useAdjustContrastOperation';
import AdjustContrastSettings from '../components/tools/adjustContrast/AdjustContrastSettings';
import AdjustContrastBasicSettings from '../components/tools/adjustContrast/AdjustContrastBasicSettings';
import AdjustContrastColorSettings from '../components/tools/adjustContrast/AdjustContrastColorSettings';
import AdjustContrastPreview from '../components/tools/adjustContrast/AdjustContrastPreview';
import { useAccordionSteps } from '../hooks/tools/shared/useAccordionSteps';
const AdjustContrast = (props: BaseToolProps) => {
@ -17,10 +20,10 @@ const AdjustContrast = (props: BaseToolProps) => {
props
);
enum Step { NONE='none', SETTINGS='settings' }
enum Step { NONE='none', BASIC='basic', COLORS='colors' }
const accordion = useAccordionSteps<Step>({
noneValue: Step.NONE,
initialStep: Step.SETTINGS,
initialStep: Step.BASIC,
stateConditions: { hasFiles: base.hasFiles, hasResults: base.hasResults },
afterResults: base.handleSettingsReset
});
@ -32,19 +35,36 @@ const AdjustContrast = (props: BaseToolProps) => {
},
steps: [
{
title: t('adjustContrast.title', 'Adjust Colors/Contrast'),
isCollapsed: accordion.getCollapsedState(Step.SETTINGS),
onCollapsedClick: () => accordion.handleStepToggle(Step.SETTINGS),
title: t('adjustContrast.basic', 'Basic Adjustments'),
isCollapsed: accordion.getCollapsedState(Step.BASIC),
onCollapsedClick: () => accordion.handleStepToggle(Step.BASIC),
content: (
<AdjustContrastSettings
<AdjustContrastBasicSettings
parameters={base.params.parameters}
onParameterChange={base.params.updateParameter}
disabled={base.endpointLoading}
/>
),
},
{
title: t('adjustContrast.adjustColors', 'Adjust Colors'),
isCollapsed: accordion.getCollapsedState(Step.COLORS),
onCollapsedClick: () => accordion.handleStepToggle(Step.COLORS),
content: (
<AdjustContrastColorSettings
parameters={base.params.parameters}
onParameterChange={base.params.updateParameter}
disabled={base.endpointLoading}
file={base.selectedFiles[0] || null}
/>
),
},
],
preview: (
<AdjustContrastPreview
file={base.selectedFiles[0] || null}
parameters={base.params.parameters}
/>
),
executeButton: {
text: t('adjustContrast.confirm', 'Confirm'),
isVisible: !base.hasResults,