@umituz/react-native-ai-generation-content 1.17.143 → 1.17.145
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/domains/creations/presentation/hooks/index.ts +2 -2
- package/src/domains/creations/presentation/hooks/{useMediaFilter.ts → useFilter.ts} +12 -7
- package/src/domains/creations/presentation/hooks/useGalleryFilters.ts +5 -6
- package/src/features/ai-hug/presentation/hooks/useAIHugFeature.ts +9 -113
- package/src/features/ai-kiss/presentation/hooks/useAIKissFeature.ts +9 -113
- package/src/features/image-to-video/infrastructure/services/image-to-video-executor.ts +5 -9
- package/src/features/image-to-video/presentation/hooks/useImageToVideoForm.ts +5 -0
- package/src/features/replace-background/index.ts +5 -50
- package/src/features/replace-background/presentation/components/index.ts +0 -12
- package/src/features/replace-background/presentation/hooks/index.ts +0 -3
- package/src/features/shared/dual-image-video/domain/types/dual-image-video.types.ts +67 -0
- package/src/features/shared/dual-image-video/domain/types/index.ts +13 -0
- package/src/features/shared/dual-image-video/index.ts +16 -0
- package/src/features/shared/dual-image-video/presentation/hooks/index.ts +5 -0
- package/src/features/shared/dual-image-video/presentation/hooks/useDualImageVideoFeature.ts +124 -0
- package/src/features/shared/index.ts +6 -0
- package/src/infrastructure/utils/index.ts +1 -0
- package/src/infrastructure/utils/progress-calculator.util.ts +31 -0
- package/src/infrastructure/utils/result-validator.util.ts +0 -214
- package/src/infrastructure/utils/url-extractor.util.ts +209 -0
- package/src/presentation/hooks/flow-state.utils.ts +101 -0
- package/src/presentation/hooks/useGenerationFlow.ts +47 -178
- package/src/presentation/types/flow-config.types.ts +5 -99
- package/src/presentation/types/flow-default-configs.ts +106 -0
- package/src/domains/creations/presentation/hooks/useStatusFilter.ts +0 -54
- package/src/features/replace-background/domain/entities/background.types.ts +0 -77
- package/src/features/replace-background/domain/entities/component.types.ts +0 -87
- package/src/features/replace-background/domain/entities/config.types.ts +0 -41
- package/src/features/replace-background/domain/entities/index.ts +0 -30
- package/src/features/replace-background/infrastructure/constants/index.ts +0 -5
- package/src/features/replace-background/infrastructure/constants/prompts.constants.ts +0 -15
- package/src/features/replace-background/infrastructure/index.ts +0 -5
- package/src/features/replace-background/presentation/components/BackgroundFeature.tsx +0 -143
- package/src/features/replace-background/presentation/components/ComparisonSlider.tsx +0 -187
- package/src/features/replace-background/presentation/components/ErrorDisplay.tsx +0 -60
- package/src/features/replace-background/presentation/components/FeatureHeader.tsx +0 -80
- package/src/features/replace-background/presentation/components/GenerateButton.tsx +0 -85
- package/src/features/replace-background/presentation/components/ImagePicker.tsx +0 -136
- package/src/features/replace-background/presentation/components/ModeSelector.tsx +0 -78
- package/src/features/replace-background/presentation/components/PromptInput.tsx +0 -142
- package/src/features/replace-background/presentation/components/ResultDisplay.tsx +0 -122
- package/src/features/replace-background/presentation/hooks/useBackgroundFeature.ts +0 -119
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flow State Utilities
|
|
3
|
+
* State initialization and update helpers for generation flow
|
|
4
|
+
*
|
|
5
|
+
* @package @umituz/react-native-ai-generation-content
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
GenerationFlowConfig,
|
|
10
|
+
GenerationFlowState,
|
|
11
|
+
PhotoStepData,
|
|
12
|
+
PhotoStepConfig,
|
|
13
|
+
} from "../types/flow-config.types";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create initial flow state from config
|
|
17
|
+
*/
|
|
18
|
+
export function createInitialFlowState(
|
|
19
|
+
config: GenerationFlowConfig,
|
|
20
|
+
): GenerationFlowState {
|
|
21
|
+
return {
|
|
22
|
+
currentStepIndex: 0,
|
|
23
|
+
photoSteps: config.photoSteps.map((step) => ({
|
|
24
|
+
id: step.id,
|
|
25
|
+
imageUri: null,
|
|
26
|
+
previewUrl: undefined,
|
|
27
|
+
name: undefined,
|
|
28
|
+
isValid: undefined,
|
|
29
|
+
validationStatus: "pending" as const,
|
|
30
|
+
})),
|
|
31
|
+
textInput: config.textInputStep
|
|
32
|
+
? {
|
|
33
|
+
id: config.textInputStep.id,
|
|
34
|
+
text: "",
|
|
35
|
+
isValid: false,
|
|
36
|
+
}
|
|
37
|
+
: undefined,
|
|
38
|
+
isComplete: false,
|
|
39
|
+
isProcessing: false,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Update photo step in state
|
|
45
|
+
*/
|
|
46
|
+
export function updatePhotoStep(
|
|
47
|
+
state: GenerationFlowState,
|
|
48
|
+
stepIndex: number,
|
|
49
|
+
updates: Partial<PhotoStepData>,
|
|
50
|
+
): GenerationFlowState {
|
|
51
|
+
const newPhotoSteps = [...state.photoSteps];
|
|
52
|
+
newPhotoSteps[stepIndex] = {
|
|
53
|
+
...newPhotoSteps[stepIndex],
|
|
54
|
+
...updates,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
...state,
|
|
59
|
+
photoSteps: newPhotoSteps,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Check if current step is valid
|
|
65
|
+
*/
|
|
66
|
+
export function isStepValid(
|
|
67
|
+
stepData: PhotoStepData | null,
|
|
68
|
+
stepConfig: PhotoStepConfig | null,
|
|
69
|
+
): boolean {
|
|
70
|
+
if (!stepData || !stepConfig) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Check photo
|
|
75
|
+
if (!stepData.imageUri) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Check name if required
|
|
80
|
+
if (stepConfig.requireNameInput && !stepData.name) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Check validation if enabled
|
|
85
|
+
if (stepConfig.enableValidation && !stepData.isValid) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Check if text input is valid
|
|
94
|
+
*/
|
|
95
|
+
export function isTextInputValid(
|
|
96
|
+
text: string,
|
|
97
|
+
minLength: number,
|
|
98
|
+
maxLength: number,
|
|
99
|
+
): boolean {
|
|
100
|
+
return text.length >= minLength && text.length <= maxLength;
|
|
101
|
+
}
|
|
@@ -12,42 +12,32 @@ import type {
|
|
|
12
12
|
PhotoStepData,
|
|
13
13
|
PhotoStepConfig,
|
|
14
14
|
} from "../types/flow-config.types";
|
|
15
|
+
import {
|
|
16
|
+
createInitialFlowState,
|
|
17
|
+
updatePhotoStep,
|
|
18
|
+
isStepValid,
|
|
19
|
+
isTextInputValid,
|
|
20
|
+
} from "./flow-state.utils";
|
|
15
21
|
|
|
16
22
|
export interface UseGenerationFlowOptions {
|
|
17
|
-
/** Flow configuration */
|
|
18
23
|
config: GenerationFlowConfig;
|
|
19
|
-
/** Callback when flow is complete */
|
|
20
24
|
onComplete?: (state: GenerationFlowState) => void;
|
|
21
|
-
/** Callback when step changes */
|
|
22
25
|
onStepChange?: (stepIndex: number, stepConfig: PhotoStepConfig) => void;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
export interface UseGenerationFlowReturn {
|
|
26
|
-
/** Current flow state */
|
|
27
29
|
state: GenerationFlowState;
|
|
28
|
-
/** Current step configuration */
|
|
29
30
|
currentStepConfig: PhotoStepConfig | null;
|
|
30
|
-
/** Current step data */
|
|
31
31
|
currentStepData: PhotoStepData | null;
|
|
32
|
-
/** Whether can go to next step */
|
|
33
32
|
canGoNext: boolean;
|
|
34
|
-
/** Whether can go to previous step */
|
|
35
33
|
canGoBack: boolean;
|
|
36
|
-
/** Go to next step */
|
|
37
34
|
goNext: () => void;
|
|
38
|
-
/** Go to previous step */
|
|
39
35
|
goBack: () => void;
|
|
40
|
-
/** Update current step photo */
|
|
41
36
|
updatePhoto: (imageUri: string, previewUrl?: string) => void;
|
|
42
|
-
/** Update current step name */
|
|
43
37
|
updateName: (name: string) => void;
|
|
44
|
-
/** Update current step validation */
|
|
45
38
|
updateValidation: (isValid: boolean) => void;
|
|
46
|
-
/** Update text input */
|
|
47
39
|
updateTextInput: (text: string) => void;
|
|
48
|
-
/** Reset flow */
|
|
49
40
|
reset: () => void;
|
|
50
|
-
/** Complete flow */
|
|
51
41
|
complete: () => void;
|
|
52
42
|
}
|
|
53
43
|
|
|
@@ -59,186 +49,90 @@ export const useGenerationFlow = ({
|
|
|
59
49
|
onComplete,
|
|
60
50
|
onStepChange,
|
|
61
51
|
}: UseGenerationFlowOptions): UseGenerationFlowReturn => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
photoSteps: config.photoSteps.map((step) => ({
|
|
66
|
-
id: step.id,
|
|
67
|
-
imageUri: null,
|
|
68
|
-
previewUrl: undefined,
|
|
69
|
-
name: undefined,
|
|
70
|
-
isValid: undefined,
|
|
71
|
-
validationStatus: "pending",
|
|
72
|
-
})),
|
|
73
|
-
textInput: config.textInputStep
|
|
74
|
-
? {
|
|
75
|
-
id: config.textInputStep.id,
|
|
76
|
-
text: "",
|
|
77
|
-
isValid: false,
|
|
78
|
-
}
|
|
79
|
-
: undefined,
|
|
80
|
-
isComplete: false,
|
|
81
|
-
isProcessing: false,
|
|
82
|
-
}));
|
|
52
|
+
const [state, setState] = useState<GenerationFlowState>(() =>
|
|
53
|
+
createInitialFlowState(config),
|
|
54
|
+
);
|
|
83
55
|
|
|
84
|
-
// Get current step configuration
|
|
85
56
|
const currentStepConfig = useMemo(() => {
|
|
86
|
-
if (state.currentStepIndex >= config.photoSteps.length)
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
57
|
+
if (state.currentStepIndex >= config.photoSteps.length) return null;
|
|
89
58
|
return config.photoSteps[state.currentStepIndex];
|
|
90
59
|
}, [state.currentStepIndex, config.photoSteps]);
|
|
91
60
|
|
|
92
|
-
// Get current step data
|
|
93
61
|
const currentStepData = useMemo(() => {
|
|
94
|
-
if (state.currentStepIndex >= state.photoSteps.length)
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
62
|
+
if (state.currentStepIndex >= state.photoSteps.length) return null;
|
|
97
63
|
return state.photoSteps[state.currentStepIndex];
|
|
98
64
|
}, [state.currentStepIndex, state.photoSteps]);
|
|
99
65
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Check photo
|
|
107
|
-
if (!currentStepData.imageUri) {
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Check name if required
|
|
112
|
-
if (currentStepConfig.requireNameInput && !currentStepData.name) {
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Check validation if enabled
|
|
117
|
-
if (currentStepConfig.enableValidation && !currentStepData.isValid) {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return true;
|
|
122
|
-
}, [currentStepData, currentStepConfig]);
|
|
66
|
+
const isCurrentStepValid = useMemo(
|
|
67
|
+
() => isStepValid(currentStepData, currentStepConfig),
|
|
68
|
+
[currentStepData, currentStepConfig],
|
|
69
|
+
);
|
|
123
70
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
71
|
+
const canGoNext = useMemo(
|
|
72
|
+
() => isCurrentStepValid && !state.isProcessing,
|
|
73
|
+
[isCurrentStepValid, state.isProcessing],
|
|
74
|
+
);
|
|
128
75
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return (
|
|
76
|
+
const canGoBack = useMemo(
|
|
77
|
+
() =>
|
|
132
78
|
state.currentStepIndex > 0 &&
|
|
133
79
|
config.behavior?.allowBack !== false &&
|
|
134
|
-
!state.isProcessing
|
|
135
|
-
|
|
136
|
-
|
|
80
|
+
!state.isProcessing,
|
|
81
|
+
[state.currentStepIndex, config.behavior?.allowBack, state.isProcessing],
|
|
82
|
+
);
|
|
137
83
|
|
|
138
|
-
// Go to next step
|
|
139
84
|
const goNext = useCallback(() => {
|
|
140
85
|
if (!canGoNext) return;
|
|
141
86
|
|
|
142
87
|
setState((prev) => {
|
|
143
88
|
const nextIndex = prev.currentStepIndex + 1;
|
|
144
89
|
|
|
145
|
-
// If we've completed all photo steps, mark as complete
|
|
146
90
|
if (nextIndex >= config.photoSteps.length) {
|
|
147
|
-
const newState = {
|
|
148
|
-
...prev,
|
|
149
|
-
isComplete: true,
|
|
150
|
-
};
|
|
91
|
+
const newState = { ...prev, isComplete: true };
|
|
151
92
|
onComplete?.(newState);
|
|
152
93
|
return newState;
|
|
153
94
|
}
|
|
154
95
|
|
|
155
|
-
// Move to next step
|
|
156
|
-
const newState = {
|
|
157
|
-
...prev,
|
|
158
|
-
currentStepIndex: nextIndex,
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
// Notify step change
|
|
162
96
|
onStepChange?.(nextIndex, config.photoSteps[nextIndex]);
|
|
163
|
-
|
|
164
|
-
return newState;
|
|
97
|
+
return { ...prev, currentStepIndex: nextIndex };
|
|
165
98
|
});
|
|
166
99
|
}, [canGoNext, config.photoSteps, onComplete, onStepChange]);
|
|
167
100
|
|
|
168
|
-
// Go to previous step
|
|
169
101
|
const goBack = useCallback(() => {
|
|
170
102
|
if (!canGoBack) return;
|
|
171
103
|
|
|
172
104
|
setState((prev) => {
|
|
173
105
|
const prevIndex = prev.currentStepIndex - 1;
|
|
174
|
-
const newState = {
|
|
175
|
-
...prev,
|
|
176
|
-
currentStepIndex: prevIndex,
|
|
177
|
-
isComplete: false,
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
// Notify step change
|
|
181
106
|
onStepChange?.(prevIndex, config.photoSteps[prevIndex]);
|
|
182
|
-
|
|
183
|
-
return newState;
|
|
107
|
+
return { ...prev, currentStepIndex: prevIndex, isComplete: false };
|
|
184
108
|
});
|
|
185
109
|
}, [canGoBack, config.photoSteps, onStepChange]);
|
|
186
110
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
validationStatus: "pending",
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
return {
|
|
200
|
-
...prev,
|
|
201
|
-
photoSteps: newPhotoSteps,
|
|
202
|
-
};
|
|
203
|
-
});
|
|
204
|
-
},
|
|
205
|
-
[],
|
|
206
|
-
);
|
|
111
|
+
const updatePhoto = useCallback((imageUri: string, previewUrl?: string) => {
|
|
112
|
+
setState((prev) =>
|
|
113
|
+
updatePhotoStep(prev, prev.currentStepIndex, {
|
|
114
|
+
imageUri,
|
|
115
|
+
previewUrl,
|
|
116
|
+
validationStatus: "pending",
|
|
117
|
+
}),
|
|
118
|
+
);
|
|
119
|
+
}, []);
|
|
207
120
|
|
|
208
|
-
// Update name
|
|
209
121
|
const updateName = useCallback((name: string) => {
|
|
210
|
-
setState((prev) =>
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
...newPhotoSteps[prev.currentStepIndex],
|
|
214
|
-
name,
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
...prev,
|
|
219
|
-
photoSteps: newPhotoSteps,
|
|
220
|
-
};
|
|
221
|
-
});
|
|
122
|
+
setState((prev) =>
|
|
123
|
+
updatePhotoStep(prev, prev.currentStepIndex, { name }),
|
|
124
|
+
);
|
|
222
125
|
}, []);
|
|
223
126
|
|
|
224
|
-
// Update validation
|
|
225
127
|
const updateValidation = useCallback((isValid: boolean) => {
|
|
226
|
-
setState((prev) =>
|
|
227
|
-
|
|
228
|
-
newPhotoSteps[prev.currentStepIndex] = {
|
|
229
|
-
...newPhotoSteps[prev.currentStepIndex],
|
|
128
|
+
setState((prev) =>
|
|
129
|
+
updatePhotoStep(prev, prev.currentStepIndex, {
|
|
230
130
|
isValid,
|
|
231
131
|
validationStatus: isValid ? "valid" : "invalid",
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return {
|
|
235
|
-
...prev,
|
|
236
|
-
photoSteps: newPhotoSteps,
|
|
237
|
-
};
|
|
238
|
-
});
|
|
132
|
+
}),
|
|
133
|
+
);
|
|
239
134
|
}, []);
|
|
240
135
|
|
|
241
|
-
// Update text input
|
|
242
136
|
const updateTextInput = useCallback(
|
|
243
137
|
(text: string) => {
|
|
244
138
|
setState((prev) => {
|
|
@@ -246,14 +140,13 @@ export const useGenerationFlow = ({
|
|
|
246
140
|
|
|
247
141
|
const minLength = config.textInputStep?.minLength ?? 0;
|
|
248
142
|
const maxLength = config.textInputStep?.maxLength ?? Infinity;
|
|
249
|
-
const isValid = text.length >= minLength && text.length <= maxLength;
|
|
250
143
|
|
|
251
144
|
return {
|
|
252
145
|
...prev,
|
|
253
146
|
textInput: {
|
|
254
147
|
...prev.textInput,
|
|
255
148
|
text,
|
|
256
|
-
isValid,
|
|
149
|
+
isValid: isTextInputValid(text, minLength, maxLength),
|
|
257
150
|
},
|
|
258
151
|
};
|
|
259
152
|
});
|
|
@@ -261,37 +154,13 @@ export const useGenerationFlow = ({
|
|
|
261
154
|
[config.textInputStep],
|
|
262
155
|
);
|
|
263
156
|
|
|
264
|
-
// Reset flow
|
|
265
157
|
const reset = useCallback(() => {
|
|
266
|
-
setState(
|
|
267
|
-
|
|
268
|
-
photoSteps: config.photoSteps.map((step) => ({
|
|
269
|
-
id: step.id,
|
|
270
|
-
imageUri: null,
|
|
271
|
-
previewUrl: undefined,
|
|
272
|
-
name: undefined,
|
|
273
|
-
isValid: undefined,
|
|
274
|
-
validationStatus: "pending",
|
|
275
|
-
})),
|
|
276
|
-
textInput: config.textInputStep
|
|
277
|
-
? {
|
|
278
|
-
id: config.textInputStep.id,
|
|
279
|
-
text: "",
|
|
280
|
-
isValid: false,
|
|
281
|
-
}
|
|
282
|
-
: undefined,
|
|
283
|
-
isComplete: false,
|
|
284
|
-
isProcessing: false,
|
|
285
|
-
});
|
|
286
|
-
}, [config.photoSteps, config.textInputStep]);
|
|
158
|
+
setState(createInitialFlowState(config));
|
|
159
|
+
}, [config]);
|
|
287
160
|
|
|
288
|
-
// Complete flow
|
|
289
161
|
const complete = useCallback(() => {
|
|
290
162
|
setState((prev) => {
|
|
291
|
-
const newState = {
|
|
292
|
-
...prev,
|
|
293
|
-
isComplete: true,
|
|
294
|
-
};
|
|
163
|
+
const newState = { ...prev, isComplete: true };
|
|
295
164
|
onComplete?.(newState);
|
|
296
165
|
return newState;
|
|
297
166
|
});
|
|
@@ -99,105 +99,11 @@ export interface GenerationFlowConfig {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
{
|
|
108
|
-
enabled: true,
|
|
109
|
-
order: 1,
|
|
110
|
-
id: "photo-1",
|
|
111
|
-
header: {
|
|
112
|
-
showStepIndicator: false,
|
|
113
|
-
titleAlignment: "center",
|
|
114
|
-
titleFontSize: 28,
|
|
115
|
-
subtitleFontSize: 16,
|
|
116
|
-
},
|
|
117
|
-
photoCard: {
|
|
118
|
-
aspectRatio: 1,
|
|
119
|
-
borderRadius: 28,
|
|
120
|
-
showValidationStatus: true,
|
|
121
|
-
allowChange: true,
|
|
122
|
-
borderStyle: "dashed",
|
|
123
|
-
},
|
|
124
|
-
requireNameInput: true,
|
|
125
|
-
enableValidation: false,
|
|
126
|
-
validationType: "none",
|
|
127
|
-
showPhotoTips: true,
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
behavior: {
|
|
131
|
-
allowBack: false,
|
|
132
|
-
showProgress: false,
|
|
133
|
-
autoAdvance: false,
|
|
134
|
-
requireAuth: false,
|
|
135
|
-
checkFeatureGate: true,
|
|
136
|
-
},
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Default dual photo flow configuration
|
|
141
|
-
*/
|
|
142
|
-
export const DEFAULT_DUAL_PHOTO_FLOW: GenerationFlowConfig = {
|
|
143
|
-
photoSteps: [
|
|
144
|
-
{
|
|
145
|
-
enabled: true,
|
|
146
|
-
order: 1,
|
|
147
|
-
id: "partner-a",
|
|
148
|
-
header: {
|
|
149
|
-
showStepIndicator: true,
|
|
150
|
-
currentStep: 1,
|
|
151
|
-
totalSteps: 2,
|
|
152
|
-
titleAlignment: "center",
|
|
153
|
-
titleFontSize: 28,
|
|
154
|
-
subtitleFontSize: 16,
|
|
155
|
-
},
|
|
156
|
-
photoCard: {
|
|
157
|
-
aspectRatio: 1,
|
|
158
|
-
borderRadius: 28,
|
|
159
|
-
showValidationStatus: true,
|
|
160
|
-
allowChange: true,
|
|
161
|
-
borderStyle: "dashed",
|
|
162
|
-
},
|
|
163
|
-
requireNameInput: true,
|
|
164
|
-
enableValidation: false,
|
|
165
|
-
validationType: "none",
|
|
166
|
-
showPhotoTips: true,
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
enabled: true,
|
|
170
|
-
order: 2,
|
|
171
|
-
id: "partner-b",
|
|
172
|
-
header: {
|
|
173
|
-
showStepIndicator: true,
|
|
174
|
-
currentStep: 2,
|
|
175
|
-
totalSteps: 2,
|
|
176
|
-
titleAlignment: "center",
|
|
177
|
-
titleFontSize: 28,
|
|
178
|
-
subtitleFontSize: 16,
|
|
179
|
-
},
|
|
180
|
-
photoCard: {
|
|
181
|
-
aspectRatio: 1,
|
|
182
|
-
borderRadius: 28,
|
|
183
|
-
showValidationStatus: true,
|
|
184
|
-
allowChange: true,
|
|
185
|
-
borderStyle: "dashed",
|
|
186
|
-
},
|
|
187
|
-
requireNameInput: true,
|
|
188
|
-
enableValidation: false,
|
|
189
|
-
validationType: "none",
|
|
190
|
-
showPhotoTips: false,
|
|
191
|
-
},
|
|
192
|
-
],
|
|
193
|
-
behavior: {
|
|
194
|
-
allowBack: true,
|
|
195
|
-
showProgress: true,
|
|
196
|
-
autoAdvance: false,
|
|
197
|
-
requireAuth: false,
|
|
198
|
-
checkFeatureGate: true,
|
|
199
|
-
},
|
|
200
|
-
};
|
|
102
|
+
// Re-export default configs from separate file
|
|
103
|
+
export {
|
|
104
|
+
DEFAULT_SINGLE_PHOTO_FLOW,
|
|
105
|
+
DEFAULT_DUAL_PHOTO_FLOW,
|
|
106
|
+
} from "./flow-default-configs";
|
|
201
107
|
|
|
202
108
|
/**
|
|
203
109
|
* Step data structure
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flow Default Configurations
|
|
3
|
+
* Default configurations for generation flows
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { GenerationFlowConfig } from "./flow-config.types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Default single photo flow configuration
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_SINGLE_PHOTO_FLOW: GenerationFlowConfig = {
|
|
12
|
+
photoSteps: [
|
|
13
|
+
{
|
|
14
|
+
enabled: true,
|
|
15
|
+
order: 1,
|
|
16
|
+
id: "photo-1",
|
|
17
|
+
header: {
|
|
18
|
+
showStepIndicator: false,
|
|
19
|
+
titleAlignment: "center",
|
|
20
|
+
titleFontSize: 28,
|
|
21
|
+
subtitleFontSize: 16,
|
|
22
|
+
},
|
|
23
|
+
photoCard: {
|
|
24
|
+
aspectRatio: 1,
|
|
25
|
+
borderRadius: 28,
|
|
26
|
+
showValidationStatus: true,
|
|
27
|
+
allowChange: true,
|
|
28
|
+
borderStyle: "dashed",
|
|
29
|
+
},
|
|
30
|
+
requireNameInput: true,
|
|
31
|
+
enableValidation: false,
|
|
32
|
+
validationType: "none",
|
|
33
|
+
showPhotoTips: true,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
behavior: {
|
|
37
|
+
allowBack: false,
|
|
38
|
+
showProgress: false,
|
|
39
|
+
autoAdvance: false,
|
|
40
|
+
requireAuth: false,
|
|
41
|
+
checkFeatureGate: true,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Default dual photo flow configuration
|
|
47
|
+
*/
|
|
48
|
+
export const DEFAULT_DUAL_PHOTO_FLOW: GenerationFlowConfig = {
|
|
49
|
+
photoSteps: [
|
|
50
|
+
{
|
|
51
|
+
enabled: true,
|
|
52
|
+
order: 1,
|
|
53
|
+
id: "partner-a",
|
|
54
|
+
header: {
|
|
55
|
+
showStepIndicator: true,
|
|
56
|
+
currentStep: 1,
|
|
57
|
+
totalSteps: 2,
|
|
58
|
+
titleAlignment: "center",
|
|
59
|
+
titleFontSize: 28,
|
|
60
|
+
subtitleFontSize: 16,
|
|
61
|
+
},
|
|
62
|
+
photoCard: {
|
|
63
|
+
aspectRatio: 1,
|
|
64
|
+
borderRadius: 28,
|
|
65
|
+
showValidationStatus: true,
|
|
66
|
+
allowChange: true,
|
|
67
|
+
borderStyle: "dashed",
|
|
68
|
+
},
|
|
69
|
+
requireNameInput: true,
|
|
70
|
+
enableValidation: false,
|
|
71
|
+
validationType: "none",
|
|
72
|
+
showPhotoTips: true,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
enabled: true,
|
|
76
|
+
order: 2,
|
|
77
|
+
id: "partner-b",
|
|
78
|
+
header: {
|
|
79
|
+
showStepIndicator: true,
|
|
80
|
+
currentStep: 2,
|
|
81
|
+
totalSteps: 2,
|
|
82
|
+
titleAlignment: "center",
|
|
83
|
+
titleFontSize: 28,
|
|
84
|
+
subtitleFontSize: 16,
|
|
85
|
+
},
|
|
86
|
+
photoCard: {
|
|
87
|
+
aspectRatio: 1,
|
|
88
|
+
borderRadius: 28,
|
|
89
|
+
showValidationStatus: true,
|
|
90
|
+
allowChange: true,
|
|
91
|
+
borderStyle: "dashed",
|
|
92
|
+
},
|
|
93
|
+
requireNameInput: true,
|
|
94
|
+
enableValidation: false,
|
|
95
|
+
validationType: "none",
|
|
96
|
+
showPhotoTips: false,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
behavior: {
|
|
100
|
+
allowBack: true,
|
|
101
|
+
showProgress: true,
|
|
102
|
+
autoAdvance: false,
|
|
103
|
+
requireAuth: false,
|
|
104
|
+
checkFeatureGate: true,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useStatusFilter Hook
|
|
3
|
-
* Handles status filtering (completed, pending, processing, failed)
|
|
4
|
-
* SOLID: Single Responsibility - Only handles status filter state
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { useState, useCallback, useMemo } from "react";
|
|
8
|
-
import type { FilterOption } from "../../domain/types/creation-filter";
|
|
9
|
-
|
|
10
|
-
interface UseStatusFilterProps {
|
|
11
|
-
readonly options: FilterOption[];
|
|
12
|
-
readonly t: (key: string) => string;
|
|
13
|
-
readonly defaultId?: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface UseStatusFilterReturn {
|
|
17
|
-
readonly selectedId: string;
|
|
18
|
-
readonly filterOptions: FilterOption[];
|
|
19
|
-
readonly hasActiveFilter: boolean;
|
|
20
|
-
readonly selectFilter: (id: string) => void;
|
|
21
|
-
readonly clearFilter: () => void;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function useStatusFilter({
|
|
25
|
-
options,
|
|
26
|
-
t,
|
|
27
|
-
defaultId = "all"
|
|
28
|
-
}: UseStatusFilterProps): UseStatusFilterReturn {
|
|
29
|
-
const [selectedId, setSelectedId] = useState(defaultId);
|
|
30
|
-
|
|
31
|
-
const filterOptions = useMemo(() =>
|
|
32
|
-
options.map(opt => ({
|
|
33
|
-
...opt,
|
|
34
|
-
label: opt.labelKey ? t(opt.labelKey) : opt.label
|
|
35
|
-
})),
|
|
36
|
-
[options, t]
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
const selectFilter = useCallback((id: string) => {
|
|
40
|
-
setSelectedId(id);
|
|
41
|
-
}, []);
|
|
42
|
-
|
|
43
|
-
const clearFilter = useCallback(() => {
|
|
44
|
-
setSelectedId(defaultId);
|
|
45
|
-
}, [defaultId]);
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
selectedId,
|
|
49
|
-
filterOptions,
|
|
50
|
-
hasActiveFilter: selectedId !== defaultId,
|
|
51
|
-
selectFilter,
|
|
52
|
-
clearFilter
|
|
53
|
-
};
|
|
54
|
-
}
|