@umituz/react-native-ai-generation-content 1.26.7 → 1.26.9
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/generation/application/generation-strategy.factory.ts +1 -3
- package/src/domains/generation/infrastructure/executors/executor-factory.ts +1 -1
- package/src/domains/generation/infrastructure/flow/step-builder.ts +2 -11
- package/src/domains/generation/infrastructure/flow/useFlow.ts +1 -1
- package/src/domains/generation/infrastructure/flow/useFlowStore.ts +1 -1
- package/src/domains/generation/presentation/useAIGeneration.hook.ts +9 -3
- package/src/domains/generation/wizard/domain/entities/wizard-config.types.ts +1 -1
- package/src/domains/generation/wizard/index.ts +0 -29
- package/src/domains/generation/wizard/infrastructure/builders/dynamic-step-builder.ts +2 -3
- package/src/domains/generation/wizard/infrastructure/strategies/wizard-strategy.factory.ts +13 -15
- package/src/domains/generation/wizard/presentation/hooks/usePhotoUploadState.ts +2 -2
- package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +2 -2
- package/src/domains/scenarios/configs/wizard-configs.ts +1 -1
- package/src/index.ts +1 -1
- package/src/infrastructure/wrappers/synchronous-generation.wrapper.ts +3 -2
- package/src/presentation/hooks/generation/index.ts +0 -1
- package/src/presentation/hooks/generation/orchestrator.ts +8 -3
- package/src/presentation/hooks/generation/useAIGenerateState.ts +3 -0
- package/src/presentation/hooks/index.ts +0 -1
- package/src/presentation/layouts/types/layout-props.ts +30 -4
- package/src/domains/generation/wizard/infrastructure/renderers/step-renderer.tsx +0 -107
- package/src/domains/generation/wizard/presentation/components/GenericWizardFlow.tsx +0 -297
- package/src/domains/generation/wizard/presentation/screens/GeneratingScreen.tsx +0 -123
- package/src/domains/generation/wizard/presentation/screens/GenericPhotoUploadScreen.tsx +0 -222
- package/src/domains/generation/wizard/presentation/steps/PhotoUploadStep.tsx +0 -66
- package/src/domains/generation/wizard/presentation/steps/SelectionStep.tsx +0 -244
- package/src/domains/generation/wizard/presentation/steps/TextInputStep.tsx +0 -199
- package/src/presentation/hooks/generation/useAIFeatureGeneration.ts +0 -180
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.9",
|
|
4
4
|
"description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -3,11 +3,9 @@
|
|
|
3
3
|
* Creates generation strategies from feature configs
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { GenerationStrategy } from "../../../presentation/hooks/generation/
|
|
6
|
+
import type { GenerationStrategy } from "../../../presentation/hooks/generation/types";
|
|
7
7
|
import type { FeatureConfig } from "../domain/feature-config.types";
|
|
8
8
|
import type {
|
|
9
|
-
ImageGenerationInput,
|
|
10
|
-
VideoGenerationInput,
|
|
11
9
|
ImageGenerationOutput,
|
|
12
10
|
VideoGenerationOutput,
|
|
13
11
|
} from "../domain/generation.types";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Creates appropriate executor based on generation type
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { GenerationExecutor } from "../../
|
|
6
|
+
import type { GenerationExecutor } from "../../domain/generation.types";
|
|
7
7
|
import { ImageExecutor } from "./image-executor";
|
|
8
8
|
import { VideoExecutor } from "./video-executor";
|
|
9
9
|
|
|
@@ -3,13 +3,12 @@
|
|
|
3
3
|
* Builds step definitions from configuration
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { StepType } from "
|
|
6
|
+
import { StepType } from "../../../../domain/entities/flow-config.types";
|
|
7
7
|
import type {
|
|
8
8
|
ScenarioStepConfig,
|
|
9
9
|
DynamicStepDefinition,
|
|
10
|
-
BuiltStep,
|
|
11
10
|
PhotoUploadStepConfig,
|
|
12
|
-
} from "
|
|
11
|
+
} from "../../../../domain/entities/step-config.types";
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
14
|
* Build steps from scenario configuration
|
|
@@ -121,14 +120,6 @@ export const resolveNextStep = (
|
|
|
121
120
|
const currentStep = steps.find((s) => s.id === currentStepId);
|
|
122
121
|
if (!currentStep) return null;
|
|
123
122
|
|
|
124
|
-
// Check if should skip based on skipIf condition
|
|
125
|
-
const nextStepCandidates = steps.filter((s) => {
|
|
126
|
-
if (s.skipIf && s.skipIf({ values: context.values })) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
return true;
|
|
130
|
-
});
|
|
131
|
-
|
|
132
123
|
// If nextStep is a function, call it
|
|
133
124
|
if (typeof currentStep.nextStep === "function") {
|
|
134
125
|
return currentStep.nextStep({
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { useRef, useCallback, useMemo } from "react";
|
|
7
7
|
import { createFlowStore, type FlowStoreType } from "./useFlowStore";
|
|
8
|
-
import type { FlowState, FlowActions, StepDefinition, FlowUploadedImageData } from "
|
|
8
|
+
import type { FlowState, FlowActions, StepDefinition, FlowUploadedImageData } from "../../../../domain/entities/flow-config.types";
|
|
9
9
|
|
|
10
10
|
interface UseFlowConfig {
|
|
11
11
|
steps: readonly StepDefinition[];
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
FlowActions,
|
|
10
10
|
FlowUploadedImageData,
|
|
11
11
|
StepDefinition,
|
|
12
|
-
} from "
|
|
12
|
+
} from "../../../../domain/entities/flow-config.types";
|
|
13
13
|
|
|
14
14
|
interface FlowStoreState extends FlowState {
|
|
15
15
|
stepDefinitions: readonly StepDefinition[];
|
|
@@ -48,7 +48,7 @@ export interface UseAIGenerationProps {
|
|
|
48
48
|
|
|
49
49
|
export interface UseAIGenerationReturn {
|
|
50
50
|
/** Trigger generation */
|
|
51
|
-
generate: (input: unknown) => Promise<
|
|
51
|
+
generate: (input: unknown) => Promise<unknown>;
|
|
52
52
|
|
|
53
53
|
/** Whether generation is in progress */
|
|
54
54
|
isGenerating: boolean;
|
|
@@ -92,9 +92,15 @@ export function useAIGeneration(
|
|
|
92
92
|
// Use orchestrator for lifecycle management
|
|
93
93
|
const orchestrator = useGenerationOrchestrator(strategy, {
|
|
94
94
|
userId,
|
|
95
|
-
alertMessages
|
|
95
|
+
alertMessages: alertMessages || {
|
|
96
|
+
networkError: "No internet connection",
|
|
97
|
+
policyViolation: "Content policy violation",
|
|
98
|
+
saveFailed: "Failed to save",
|
|
99
|
+
creditFailed: "Failed to deduct credits",
|
|
100
|
+
unknown: "An error occurred",
|
|
101
|
+
},
|
|
96
102
|
onSuccess,
|
|
97
|
-
onError,
|
|
103
|
+
onError: onError ? (error) => onError(error.message) : undefined,
|
|
98
104
|
onCreditsExhausted,
|
|
99
105
|
});
|
|
100
106
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* All features use these same types - NO feature-specific wizards!
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { StepType } from "
|
|
8
|
+
import type { StepType } from "../../../../../domain/entities/flow-config.types";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Generic Step Configuration
|
|
@@ -26,35 +26,6 @@ export {
|
|
|
26
26
|
quickBuildWizard,
|
|
27
27
|
} from "./infrastructure/builders/dynamic-step-builder";
|
|
28
28
|
|
|
29
|
-
// Infrastructure - Renderers
|
|
30
|
-
export { renderStep } from "./infrastructure/renderers/step-renderer";
|
|
31
|
-
export type { StepRendererProps } from "./infrastructure/renderers/step-renderer";
|
|
32
|
-
|
|
33
|
-
// Presentation - Components
|
|
34
|
-
export { GenericWizardFlow } from "./presentation/components/GenericWizardFlow";
|
|
35
|
-
export type { GenericWizardFlowProps } from "./presentation/components/GenericWizardFlow";
|
|
36
|
-
|
|
37
|
-
// Presentation - Steps
|
|
38
|
-
export { PhotoUploadStep } from "./presentation/steps/PhotoUploadStep";
|
|
39
|
-
export type { PhotoUploadStepProps } from "./presentation/steps/PhotoUploadStep";
|
|
40
|
-
|
|
41
|
-
export { TextInputStep } from "./presentation/steps/TextInputStep";
|
|
42
|
-
export type { TextInputStepProps } from "./presentation/steps/TextInputStep";
|
|
43
|
-
|
|
44
|
-
export { SelectionStep } from "./presentation/steps/SelectionStep";
|
|
45
|
-
export type { SelectionStepProps } from "./presentation/steps/SelectionStep";
|
|
46
|
-
|
|
47
|
-
// Presentation - Screens
|
|
48
|
-
export { GenericPhotoUploadScreen } from "./presentation/screens/GenericPhotoUploadScreen";
|
|
49
|
-
export type {
|
|
50
|
-
PhotoUploadScreenProps,
|
|
51
|
-
PhotoUploadScreenConfig,
|
|
52
|
-
PhotoUploadScreenTranslations,
|
|
53
|
-
} from "./presentation/screens/GenericPhotoUploadScreen";
|
|
54
|
-
|
|
55
|
-
export { GeneratingScreen } from "./presentation/screens/GeneratingScreen";
|
|
56
|
-
export type { GeneratingScreenProps } from "./presentation/screens/GeneratingScreen";
|
|
57
|
-
|
|
58
29
|
// Presentation - Hooks
|
|
59
30
|
export { usePhotoUploadState } from "./presentation/hooks/usePhotoUploadState";
|
|
60
31
|
export type {
|
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
* Works with ANY feature - completely generic!
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { StepType } from "
|
|
8
|
-
import type { StepDefinition } from "
|
|
7
|
+
import { StepType } from "../../../../../domain/entities/flow-config.types";
|
|
8
|
+
import type { StepDefinition } from "../../../../../domain/entities/flow-config.types";
|
|
9
9
|
import type {
|
|
10
10
|
WizardFeatureConfig,
|
|
11
11
|
WizardStepConfig,
|
|
12
12
|
ScenarioBasedConfig,
|
|
13
|
-
buildWizardConfigFromScenario,
|
|
14
13
|
} from "../../domain/entities/wizard-config.types";
|
|
15
14
|
|
|
16
15
|
/**
|
|
@@ -5,13 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { readFileAsBase64 } from "@umituz/react-native-design-system";
|
|
8
|
-
import type { GenerationStrategy } from "
|
|
9
|
-
import type { VideoFeatureType } from "
|
|
10
|
-
import { executeVideoFeature } from "
|
|
11
|
-
import { createCreationsRepository } from "
|
|
12
|
-
import {
|
|
13
|
-
import type { CoupleFeatureSelection } from "../../../../features/couple-future/domain/types";
|
|
14
|
-
import type { WizardOutputType, WizardScenarioData } from "../../presentation/hooks/useWizardGeneration";
|
|
8
|
+
import type { GenerationStrategy } from "../../../../../presentation/hooks/generation/types";
|
|
9
|
+
import type { VideoFeatureType } from "../../../../../domain/interfaces";
|
|
10
|
+
import { executeVideoFeature } from "../../../../../infrastructure/services/video-feature-executor.service";
|
|
11
|
+
import { createCreationsRepository } from "../../../../creations/infrastructure/adapters";
|
|
12
|
+
import type { WizardScenarioData } from "../../presentation/hooks/useWizardGeneration";
|
|
15
13
|
|
|
16
14
|
declare const __DEV__: boolean;
|
|
17
15
|
|
|
@@ -52,7 +50,7 @@ async function executeImageGeneration(
|
|
|
52
50
|
});
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
const { providerRegistry } = await import("
|
|
53
|
+
const { providerRegistry } = await import("../../../../../infrastructure/services/provider-registry.service");
|
|
56
54
|
|
|
57
55
|
const provider = providerRegistry.getActiveProvider();
|
|
58
56
|
if (!provider || !provider.isInitialized()) {
|
|
@@ -179,29 +177,29 @@ async function buildGenerationInput(
|
|
|
179
177
|
|
|
180
178
|
// For image generation, enhance prompt with style selections
|
|
181
179
|
if (outputType === "image") {
|
|
182
|
-
const
|
|
180
|
+
const styleEnhancements: string[] = [];
|
|
183
181
|
|
|
184
182
|
// Romantic mood (multi-select array)
|
|
185
183
|
const romanticMoods = wizardData.selection_romantic_mood as string[] | undefined;
|
|
186
184
|
if (romanticMoods && romanticMoods.length > 0) {
|
|
187
|
-
|
|
185
|
+
styleEnhancements.push(`Mood: ${romanticMoods.join(", ")}`);
|
|
188
186
|
}
|
|
189
187
|
|
|
190
188
|
// Art style (single select)
|
|
191
189
|
const artStyle = wizardData.selection_art_style as string | undefined;
|
|
192
190
|
if (artStyle && artStyle !== "original") {
|
|
193
|
-
|
|
191
|
+
styleEnhancements.push(`Art style: ${artStyle}`);
|
|
194
192
|
}
|
|
195
193
|
|
|
196
194
|
// Artist style (single select)
|
|
197
195
|
const artist = wizardData.selection_artist_style as string | undefined;
|
|
198
196
|
if (artist && artist !== "original") {
|
|
199
|
-
|
|
197
|
+
styleEnhancements.push(`Artist style: ${artist}`);
|
|
200
198
|
}
|
|
201
199
|
|
|
202
200
|
// Enhance prompt with selected styles
|
|
203
|
-
if (
|
|
204
|
-
prompt =
|
|
201
|
+
if (styleEnhancements.length > 0) {
|
|
202
|
+
prompt = `${prompt}. ${styleEnhancements.join(", ")}`;
|
|
205
203
|
}
|
|
206
204
|
|
|
207
205
|
return {
|
|
@@ -247,7 +245,7 @@ export interface CreateWizardStrategyOptions {
|
|
|
247
245
|
export const createWizardStrategy = (
|
|
248
246
|
options: CreateWizardStrategyOptions,
|
|
249
247
|
): GenerationStrategy<WizardGenerationInput, WizardGenerationResult> => {
|
|
250
|
-
const { scenario,
|
|
248
|
+
const { scenario, collectionName = "creations" } = options;
|
|
251
249
|
const repository = createCreationsRepository(collectionName);
|
|
252
250
|
const outputType = scenario.outputType || "video";
|
|
253
251
|
const videoFeatureType = getVideoFeatureType(scenario.id);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { useState, useCallback } from "react";
|
|
8
8
|
import * as ImagePicker from "expo-image-picker";
|
|
9
9
|
import { Alert } from "react-native";
|
|
10
|
-
import type { UploadedImage } from "
|
|
10
|
+
import type { UploadedImage } from "../../../../../presentation/hooks/generation/useAIGenerateState";
|
|
11
11
|
|
|
12
12
|
export interface PhotoUploadConfig {
|
|
13
13
|
readonly maxFileSizeMB?: number;
|
|
@@ -52,7 +52,7 @@ export const usePhotoUploadState = ({
|
|
|
52
52
|
|
|
53
53
|
// Pick image
|
|
54
54
|
const result = await ImagePicker.launchImageLibraryAsync({
|
|
55
|
-
mediaTypes:
|
|
55
|
+
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
|
56
56
|
allowsEditing: true,
|
|
57
57
|
aspect: [1, 1],
|
|
58
58
|
quality: 0.8,
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { useEffect, useRef, useMemo } from "react";
|
|
7
|
-
import { useGenerationOrchestrator } from "
|
|
8
|
-
import type { AlertMessages } from "
|
|
7
|
+
import { useGenerationOrchestrator } from "../../../../../presentation/hooks/generation";
|
|
8
|
+
import type { AlertMessages } from "../../../../../presentation/hooks/generation/types";
|
|
9
9
|
import { createWizardStrategy, buildWizardInput } from "../../infrastructure/strategies";
|
|
10
10
|
|
|
11
11
|
declare const __DEV__: boolean;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Supports overrides for customization
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { WizardFeatureConfig } from "../../wizard/domain/entities/wizard-config.types";
|
|
7
|
+
import type { WizardFeatureConfig } from "../../generation/wizard/domain/entities/wizard-config.types";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Feature Type Classification
|
package/src/index.ts
CHANGED
|
@@ -72,7 +72,7 @@ export {
|
|
|
72
72
|
useGeneration, usePendingJobs, useBackgroundGeneration,
|
|
73
73
|
useGenerationFlow, useAIFeatureCallbacks,
|
|
74
74
|
useAIGenerateState, AIGenerateStep,
|
|
75
|
-
useGenerationOrchestrator, useImageGeneration, useVideoGeneration,
|
|
75
|
+
useGenerationOrchestrator, useImageGeneration, useVideoGeneration,
|
|
76
76
|
createGenerationError, getAlertMessage, parseError,
|
|
77
77
|
} from "./presentation/hooks";
|
|
78
78
|
|
|
@@ -30,7 +30,7 @@ export async function generateSynchronously<T = string>(
|
|
|
30
30
|
): Promise<GenerationResult<T>> {
|
|
31
31
|
// Check user ID if required
|
|
32
32
|
if (config.checkCredits && !input.userId) {
|
|
33
|
-
return createErrorResult("user_id_required");
|
|
33
|
+
return createErrorResult("user_id_required", config.model || "unknown");
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
// Check credits if configured
|
|
@@ -40,7 +40,7 @@ export async function generateSynchronously<T = string>(
|
|
|
40
40
|
input.type || "generation",
|
|
41
41
|
);
|
|
42
42
|
if (!hasCredits) {
|
|
43
|
-
return createErrorResult("insufficient_credits");
|
|
43
|
+
return createErrorResult("insufficient_credits", config.model || "unknown");
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -50,6 +50,7 @@ export async function generateSynchronously<T = string>(
|
|
|
50
50
|
if (!moderationResult.allowed) {
|
|
51
51
|
return createErrorResult(
|
|
52
52
|
moderationResult.error || "content_policy_violation",
|
|
53
|
+
config.model || "unknown",
|
|
53
54
|
);
|
|
54
55
|
}
|
|
55
56
|
}
|
|
@@ -9,7 +9,6 @@ export { useGenerationOrchestrator } from "./orchestrator";
|
|
|
9
9
|
// Generic feature hooks
|
|
10
10
|
export { useImageGeneration } from "./useImageGeneration";
|
|
11
11
|
export { useVideoGeneration } from "./useVideoGeneration";
|
|
12
|
-
export { useAIFeatureGeneration } from "./useAIFeatureGeneration";
|
|
13
12
|
|
|
14
13
|
// Types
|
|
15
14
|
export type {
|
|
@@ -70,9 +70,14 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
70
70
|
|
|
71
71
|
const offlineStore = useOfflineStore();
|
|
72
72
|
const { showError, showSuccess } = useAlert();
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
const creditHook = useDeductCredit({ userId, onCreditsExhausted });
|
|
74
|
+
|
|
75
|
+
// Wrap credit hook to match expected interface
|
|
76
|
+
const defaultCredits = {
|
|
77
|
+
checkCredits: creditHook.checkCredits,
|
|
78
|
+
deductCredit: async (amount: number) => {
|
|
79
|
+
await creditHook.deductCredit(amount);
|
|
80
|
+
}
|
|
76
81
|
};
|
|
77
82
|
|
|
78
83
|
// Use provided credit callbacks or default to useDeductCredit hook
|
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { ReactNode } from "react";
|
|
7
|
-
import type {
|
|
8
|
-
BaseSingleImageHookReturn,
|
|
9
|
-
BaseDualImageHookReturn,
|
|
10
|
-
} from "../../../features/image-to-image/domain/types";
|
|
11
7
|
import type {
|
|
12
8
|
ModalTranslations,
|
|
13
9
|
BaseLayoutTranslations,
|
|
@@ -24,6 +20,36 @@ import type {
|
|
|
24
20
|
SingleImageWithPromptFeatureState,
|
|
25
21
|
} from "./feature-states";
|
|
26
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Base hook return for single image features
|
|
25
|
+
*/
|
|
26
|
+
export interface BaseSingleImageHookReturn {
|
|
27
|
+
readonly imageUri: string | null;
|
|
28
|
+
readonly processedUrl: string | null;
|
|
29
|
+
readonly isProcessing: boolean;
|
|
30
|
+
readonly progress: number;
|
|
31
|
+
selectImage(): Promise<void>;
|
|
32
|
+
process(): Promise<void>;
|
|
33
|
+
save(): Promise<void>;
|
|
34
|
+
reset(): void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Base hook return for dual image features
|
|
39
|
+
*/
|
|
40
|
+
export interface BaseDualImageHookReturn {
|
|
41
|
+
readonly sourceImageUri: string | null;
|
|
42
|
+
readonly targetImageUri: string | null;
|
|
43
|
+
readonly processedUrl: string | null;
|
|
44
|
+
readonly isProcessing: boolean;
|
|
45
|
+
readonly progress: number;
|
|
46
|
+
selectSourceImage(): Promise<void>;
|
|
47
|
+
selectTargetImage(): Promise<void>;
|
|
48
|
+
process(): Promise<void>;
|
|
49
|
+
save(): Promise<void>;
|
|
50
|
+
reset(): void;
|
|
51
|
+
}
|
|
52
|
+
|
|
27
53
|
/**
|
|
28
54
|
* Single image feature layout props
|
|
29
55
|
* Note: No modal - shows fullscreen progress when processing (FutureUS pattern)
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic Step Renderer
|
|
3
|
-
* Renders any step type based on configuration
|
|
4
|
-
* NO feature-specific code! Works for ALL features!
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React from "react";
|
|
8
|
-
import { StepType } from "../../../../domain/entities/flow-config.types";
|
|
9
|
-
import type { StepDefinition } from "../../../../domain/entities/flow-config.types";
|
|
10
|
-
import type {
|
|
11
|
-
WizardStepConfig,
|
|
12
|
-
PhotoUploadStepConfig,
|
|
13
|
-
TextInputStepConfig,
|
|
14
|
-
SelectionStepConfig,
|
|
15
|
-
} from "../../domain/entities/wizard-config.types";
|
|
16
|
-
|
|
17
|
-
// Import generic step components (will create these)
|
|
18
|
-
import { PhotoUploadStep } from "../../presentation/steps/PhotoUploadStep";
|
|
19
|
-
import { TextInputStep } from "../../presentation/steps/TextInputStep";
|
|
20
|
-
import { SelectionStep } from "../../presentation/steps/SelectionStep";
|
|
21
|
-
|
|
22
|
-
export interface StepRendererProps {
|
|
23
|
-
readonly step: StepDefinition;
|
|
24
|
-
readonly onContinue: (data: Record<string, unknown>) => void;
|
|
25
|
-
readonly onBack: () => void;
|
|
26
|
-
readonly t: (key: string) => string;
|
|
27
|
-
readonly translations?: Record<string, string>;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Render a step based on its type and configuration
|
|
32
|
-
* This is the ONLY renderer needed for ALL features!
|
|
33
|
-
*/
|
|
34
|
-
export const renderStep = (props: StepRendererProps): React.ReactElement | null => {
|
|
35
|
-
const { step, onContinue, onBack, t, translations } = props;
|
|
36
|
-
|
|
37
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
38
|
-
console.log("[StepRenderer] Rendering step", {
|
|
39
|
-
stepId: step.id,
|
|
40
|
-
stepType: step.type,
|
|
41
|
-
hasConfig: !!step.config,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const wizardConfig = step.config as WizardStepConfig | undefined;
|
|
46
|
-
|
|
47
|
-
switch (step.type) {
|
|
48
|
-
case StepType.PARTNER_UPLOAD: {
|
|
49
|
-
// This handles ALL photo uploads (couple, face-swap, image-to-video, etc.)
|
|
50
|
-
const photoConfig = wizardConfig as PhotoUploadStepConfig;
|
|
51
|
-
return (
|
|
52
|
-
<PhotoUploadStep
|
|
53
|
-
key={step.id}
|
|
54
|
-
config={photoConfig}
|
|
55
|
-
onContinue={(imageData) => {
|
|
56
|
-
onContinue({ [`photo_${step.id}`]: imageData });
|
|
57
|
-
}}
|
|
58
|
-
onBack={onBack}
|
|
59
|
-
t={t}
|
|
60
|
-
translations={translations}
|
|
61
|
-
/>
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
case StepType.TEXT_INPUT: {
|
|
66
|
-
const textConfig = wizardConfig as TextInputStepConfig;
|
|
67
|
-
return (
|
|
68
|
-
<TextInputStep
|
|
69
|
-
config={textConfig}
|
|
70
|
-
onContinue={(text) => {
|
|
71
|
-
onContinue({ text });
|
|
72
|
-
}}
|
|
73
|
-
onBack={onBack}
|
|
74
|
-
t={t}
|
|
75
|
-
translations={translations}
|
|
76
|
-
/>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
case StepType.FEATURE_SELECTION: {
|
|
81
|
-
const selectionConfig = wizardConfig as SelectionStepConfig;
|
|
82
|
-
return (
|
|
83
|
-
<SelectionStep
|
|
84
|
-
config={selectionConfig}
|
|
85
|
-
onContinue={(selected) => {
|
|
86
|
-
onContinue({ [`selection_${step.id}`]: selected });
|
|
87
|
-
}}
|
|
88
|
-
onBack={onBack}
|
|
89
|
-
t={t}
|
|
90
|
-
translations={translations}
|
|
91
|
-
/>
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
case StepType.SCENARIO_PREVIEW:
|
|
96
|
-
case StepType.GENERATING:
|
|
97
|
-
case StepType.RESULT_PREVIEW:
|
|
98
|
-
// These are handled by parent wizard component
|
|
99
|
-
return null;
|
|
100
|
-
|
|
101
|
-
default:
|
|
102
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
103
|
-
console.warn("[StepRenderer] Unknown step type", step.type);
|
|
104
|
-
}
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
};
|