@umituz/react-native-ai-generation-content 1.26.9 → 1.26.11

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.26.9",
3
+ "version": "1.26.11",
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",
@@ -42,3 +42,10 @@ export type {
42
42
  WizardScenarioData,
43
43
  WizardOutputType,
44
44
  } from "./presentation/hooks/useWizardGeneration";
45
+
46
+ // Presentation - Components
47
+ export { GenericWizardFlow } from "./presentation/components";
48
+ export type { GenericWizardFlowProps } from "./presentation/components";
49
+
50
+ // Presentation - Screens
51
+ export { GeneratingScreen } from "./presentation/screens";
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Generic Wizard Flow Component
3
+ * ONE wizard to rule them all!
4
+ *
5
+ * Works for:
6
+ * - Couple features (romantic-kiss, ai-hug, etc.)
7
+ * - Face swap
8
+ * - Image-to-video
9
+ * - Text-to-video
10
+ * - ANY future feature!
11
+ *
12
+ * NO feature-specific code here - everything driven by configuration!
13
+ */
14
+
15
+ import React, { useMemo, useCallback, useEffect, useRef } from "react";
16
+ import { View, StyleSheet } from "react-native";
17
+ import { useAppDesignTokens } from "@umituz/react-native-design-system";
18
+ import { useFlow } from "../../../infrastructure/flow/useFlow";
19
+ import { StepType, type StepDefinition } from "../../../../../domain/entities/flow-config.types";
20
+ import type { WizardFeatureConfig } from "../../domain/entities/wizard-config.types";
21
+ import { buildFlowStepsFromWizard } from "../../infrastructure/builders/dynamic-step-builder";
22
+ import { useWizardGeneration, type WizardScenarioData } from "../hooks/useWizardGeneration";
23
+ import type { AlertMessages } from "../../../../../presentation/hooks/generation/types";
24
+
25
+ export interface GenericWizardFlowProps {
26
+ readonly featureConfig: WizardFeatureConfig;
27
+ readonly scenario?: WizardScenarioData;
28
+ readonly userId?: string;
29
+ readonly alertMessages?: AlertMessages;
30
+ readonly onStepChange?: (stepId: string, stepType: StepType | string) => void;
31
+ readonly onGenerationStart?: (data: Record<string, unknown>, proceedToGenerating: () => void) => void;
32
+ readonly onGenerationComplete?: (result: unknown) => void;
33
+ readonly onGenerationError?: (error: string) => void;
34
+ readonly onCreditsExhausted?: () => void;
35
+ readonly onBack?: () => void;
36
+ readonly t: (key: string) => string;
37
+ readonly translations?: Record<string, string>;
38
+ readonly renderPreview?: (onContinue: () => void) => React.ReactElement | null;
39
+ readonly renderGenerating?: (progress: number) => React.ReactElement | null;
40
+ readonly renderResult?: (result: unknown) => React.ReactElement | null;
41
+ }
42
+
43
+ export const GenericWizardFlow: React.FC<GenericWizardFlowProps> = ({
44
+ featureConfig,
45
+ scenario,
46
+ userId,
47
+ alertMessages,
48
+ onStepChange,
49
+ onGenerationStart,
50
+ onGenerationComplete,
51
+ onGenerationError,
52
+ onCreditsExhausted,
53
+ onBack,
54
+ t,
55
+ translations,
56
+ renderPreview,
57
+ renderGenerating,
58
+ renderResult,
59
+ }) => {
60
+ const tokens = useAppDesignTokens();
61
+
62
+ // Build flow steps from wizard config
63
+ const flowSteps = useMemo<StepDefinition[]>(() => {
64
+ return buildFlowStepsFromWizard(featureConfig, {
65
+ includePreview: !!renderPreview,
66
+ includeGenerating: !!renderGenerating,
67
+ });
68
+ }, [featureConfig, renderPreview, renderGenerating]);
69
+
70
+ // Initialize flow and destructure to prevent infinite loops
71
+ const flow = useFlow({
72
+ steps: flowSteps,
73
+ initialStepIndex: 0,
74
+ });
75
+
76
+ // Destructure flow to get stable references for useCallback dependencies
77
+ const {
78
+ currentStep,
79
+ currentStepIndex,
80
+ customData,
81
+ generationProgress,
82
+ generationResult,
83
+ nextStep,
84
+ previousStep,
85
+ setCustomData,
86
+ updateProgress,
87
+ } = flow;
88
+
89
+ // Handle progress change - memoized to prevent infinite loops
90
+ const handleProgressChange = useCallback(
91
+ (progress: number) => {
92
+ updateProgress(progress);
93
+ },
94
+ [updateProgress],
95
+ );
96
+
97
+ // Ensure scenario has required fields - use feature config as fallback
98
+ const validatedScenario = useMemo(() => {
99
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
100
+ console.log("[GenericWizardFlow] Validating scenario", {
101
+ hasScenario: !!scenario,
102
+ scenarioId: scenario?.id,
103
+ hasAiPrompt: scenario?.aiPrompt !== undefined,
104
+ hasModel: !!scenario?.model,
105
+ scenarioModel: scenario?.model,
106
+ outputType: scenario?.outputType,
107
+ });
108
+ }
109
+
110
+ if (scenario && scenario.id && scenario.aiPrompt !== undefined) {
111
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
112
+ console.log("[GenericWizardFlow] Scenario validation passed", {
113
+ scenarioId: scenario.id,
114
+ model: scenario.model,
115
+ outputType: scenario.outputType,
116
+ });
117
+ }
118
+ return scenario;
119
+ }
120
+
121
+ // Fallback to feature config
122
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
123
+ console.warn("[GenericWizardFlow] Scenario missing required fields, using fallback", {
124
+ hasScenario: !!scenario,
125
+ scenarioId: scenario?.id,
126
+ featureConfigId: featureConfig.id,
127
+ });
128
+ }
129
+
130
+ return {
131
+ id: featureConfig.id,
132
+ aiPrompt: "",
133
+ outputType: "image" as const, // Default to image for safety
134
+ title: featureConfig.id,
135
+ };
136
+ }, [scenario, featureConfig.id]);
137
+
138
+ // Generation hook - handles AI generation automatically
139
+ // Note: Hook is used for its side effects (automatic generation)
140
+ useWizardGeneration({
141
+ scenario: validatedScenario,
142
+ wizardData: customData,
143
+ userId,
144
+ isGeneratingStep: currentStep?.type === StepType.GENERATING,
145
+ alertMessages,
146
+ onSuccess: onGenerationComplete,
147
+ onError: onGenerationError,
148
+ onProgressChange: handleProgressChange,
149
+ onCreditsExhausted,
150
+ });
151
+
152
+ // Track previous step ID to prevent infinite loops
153
+ const prevStepIdRef = useRef<string | undefined>(undefined);
154
+
155
+ // DEBUG logging
156
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
157
+ console.log("[GenericWizardFlow] Render", {
158
+ featureId: featureConfig.id,
159
+ currentStepId: currentStep?.id,
160
+ currentStepType: currentStep?.type,
161
+ stepIndex: currentStepIndex,
162
+ totalSteps: flowSteps.length,
163
+ });
164
+ }
165
+
166
+ // Notify parent when step changes
167
+ // Only call onStepChange when step ID actually changes (not on every object reference change)
168
+ useEffect(() => {
169
+ if (currentStep && onStepChange) {
170
+ const currentStepId = currentStep.id;
171
+ // Only notify if step ID changed
172
+ if (prevStepIdRef.current !== currentStepId) {
173
+ prevStepIdRef.current = currentStepId;
174
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
175
+ console.log("[GenericWizardFlow] Step changed", {
176
+ stepId: currentStep.id,
177
+ stepType: currentStep.type,
178
+ });
179
+ }
180
+ onStepChange(currentStep.id, currentStep.type);
181
+ }
182
+ }
183
+ }, [currentStep, currentStepIndex, onStepChange]);
184
+
185
+ // Handle step continue
186
+ const handleStepContinue = useCallback(
187
+ (stepData: Record<string, unknown>) => {
188
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
189
+ console.log("[GenericWizardFlow] Step continue", {
190
+ stepId: currentStep?.id,
191
+ data: stepData,
192
+ });
193
+ }
194
+
195
+ // Store step data in custom data
196
+ Object.entries(stepData).forEach(([key, value]) => {
197
+ setCustomData(key, value);
198
+ });
199
+
200
+ // Check if this is the last step before generating
201
+ if (currentStepIndex === flowSteps.length - 2) {
202
+ // Next step is GENERATING
203
+ // Notify parent and provide callback to proceed to generating
204
+ // Parent will call proceedToGenerating() after feature gate passes
205
+ if (onGenerationStart) {
206
+ onGenerationStart(customData, () => {
207
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
208
+ console.log("[GenericWizardFlow] Proceeding to GENERATING step");
209
+ }
210
+ nextStep();
211
+ });
212
+ }
213
+ // DON'T call nextStep() here - parent will call it via proceedToGenerating callback
214
+ return;
215
+ }
216
+
217
+ // Move to next step (for all non-generation steps)
218
+ nextStep();
219
+ },
220
+ [currentStep, currentStepIndex, customData, setCustomData, nextStep, flowSteps.length, onGenerationStart],
221
+ );
222
+
223
+ // Handle back
224
+ const handleBack = useCallback(() => {
225
+ if (currentStepIndex === 0) {
226
+ onBack?.();
227
+ } else {
228
+ previousStep();
229
+ }
230
+ }, [currentStepIndex, previousStep, onBack]);
231
+
232
+ // Render current step
233
+ const renderCurrentStep = useCallback(() => {
234
+ const step = currentStep;
235
+ if (!step) {
236
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
237
+ console.warn("[GenericWizardFlow] No current step!");
238
+ }
239
+ return null;
240
+ }
241
+
242
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
243
+ console.log("[GenericWizardFlow] Rendering step", {
244
+ stepId: step.id,
245
+ stepType: step.type,
246
+ });
247
+ }
248
+
249
+ // Special steps with custom renderers
250
+ switch (step.type) {
251
+ case StepType.SCENARIO_PREVIEW:
252
+ // Preview continues to next step automatically
253
+ return renderPreview?.(nextStep) || null;
254
+
255
+ case StepType.GENERATING:
256
+ return renderGenerating?.(generationProgress) || null;
257
+
258
+ case StepType.RESULT_PREVIEW:
259
+ return renderResult?.(generationResult) || null;
260
+
261
+ default:
262
+ // Other step types should be handled by custom render props
263
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
264
+ console.warn("[GenericWizardFlow] Unhandled step type", { stepType: step.type });
265
+ }
266
+ return null;
267
+ }
268
+ }, [
269
+ currentStep,
270
+ generationProgress,
271
+ generationResult,
272
+ nextStep,
273
+ renderPreview,
274
+ renderGenerating,
275
+ renderResult,
276
+ handleStepContinue,
277
+ handleBack,
278
+ t,
279
+ translations,
280
+ ]);
281
+
282
+ return (
283
+ <View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}>
284
+ {renderCurrentStep()}
285
+ </View>
286
+ );
287
+ };
288
+
289
+ const styles = StyleSheet.create({
290
+ container: {
291
+ flex: 1,
292
+ },
293
+ });
@@ -0,0 +1,2 @@
1
+ export { GenericWizardFlow } from "./GenericWizardFlow";
2
+ export type { GenericWizardFlowProps } from "./GenericWizardFlow";
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Generic Generating Screen
3
+ * Shows progress while AI generates content
4
+ * Used by ALL features - NO feature-specific code!
5
+ */
6
+
7
+ import React from "react";
8
+ import { View, StyleSheet, ActivityIndicator } from "react-native";
9
+ import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
10
+
11
+ export interface GeneratingScreenProps {
12
+ readonly progress: number;
13
+ readonly scenario?: {
14
+ readonly id: string;
15
+ readonly title?: string;
16
+ };
17
+ readonly t: (key: string) => string;
18
+ readonly onCancel?: () => void;
19
+ }
20
+
21
+ export const GeneratingScreen: React.FC<GeneratingScreenProps> = ({
22
+ progress,
23
+ scenario,
24
+ t,
25
+ onCancel: _onCancel,
26
+ }) => {
27
+ const tokens = useAppDesignTokens();
28
+
29
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
30
+ console.log("[GeneratingScreen] Rendering", {
31
+ progress,
32
+ scenarioId: scenario?.id,
33
+ });
34
+ }
35
+
36
+ return (
37
+ <View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}>
38
+ <View style={styles.content}>
39
+ <ActivityIndicator size="large" color={tokens.colors.primary} />
40
+
41
+ <AtomicText type="headlineMedium" style={styles.title}>
42
+ {t("generator.title")}
43
+ </AtomicText>
44
+
45
+ <AtomicText type="bodyMedium" style={[styles.message, { color: tokens.colors.textSecondary }]}>
46
+ {t("generator.waitMessage")}
47
+ </AtomicText>
48
+
49
+ {/* Progress Bar */}
50
+ <View style={styles.progressContainer}>
51
+ <View style={[styles.progressBar, { backgroundColor: tokens.colors.surfaceVariant }]}>
52
+ <View
53
+ style={[
54
+ styles.progressFill,
55
+ {
56
+ backgroundColor: tokens.colors.primary,
57
+ width: `${Math.min(100, Math.max(0, progress))}%`,
58
+ },
59
+ ]}
60
+ />
61
+ </View>
62
+ <AtomicText type="bodySmall" style={[styles.progressText, { color: tokens.colors.textSecondary }]}>
63
+ {Math.round(progress)}%
64
+ </AtomicText>
65
+ </View>
66
+
67
+ {/* Scenario Info */}
68
+ {scenario && (
69
+ <AtomicText type="bodySmall" style={[styles.hint, { color: tokens.colors.textSecondary }]}>
70
+ {scenario.title || scenario.id}
71
+ </AtomicText>
72
+ )}
73
+
74
+ {/* Hint */}
75
+ <AtomicText type="bodySmall" style={[styles.hint, { color: tokens.colors.textSecondary }]}>
76
+ {t("generator.hint")}
77
+ </AtomicText>
78
+ </View>
79
+ </View>
80
+ );
81
+ };
82
+
83
+ const styles = StyleSheet.create({
84
+ container: {
85
+ flex: 1,
86
+ justifyContent: "center",
87
+ alignItems: "center",
88
+ },
89
+ content: {
90
+ width: "80%",
91
+ maxWidth: 400,
92
+ alignItems: "center",
93
+ gap: 16,
94
+ },
95
+ title: {
96
+ textAlign: "center",
97
+ marginTop: 24,
98
+ },
99
+ message: {
100
+ textAlign: "center",
101
+ },
102
+ progressContainer: {
103
+ width: "100%",
104
+ marginTop: 24,
105
+ gap: 8,
106
+ },
107
+ progressBar: {
108
+ height: 8,
109
+ borderRadius: 4,
110
+ overflow: "hidden",
111
+ },
112
+ progressFill: {
113
+ height: "100%",
114
+ borderRadius: 4,
115
+ },
116
+ progressText: {
117
+ textAlign: "center",
118
+ },
119
+ hint: {
120
+ textAlign: "center",
121
+ marginTop: 8,
122
+ },
123
+ });
@@ -0,0 +1 @@
1
+ export { GeneratingScreen } from "./GeneratingScreen";
@@ -84,3 +84,42 @@ export interface ScenarioSelection {
84
84
  readonly mainCategory: MainCategory;
85
85
  readonly subCategory: SubCategory;
86
86
  }
87
+
88
+ /**
89
+ * Legacy types for presentation components (backward compatibility)
90
+ * Used by CategoryNavigationContainer and related screens
91
+ */
92
+ export interface ScenarioMainCategory {
93
+ readonly id: string;
94
+ readonly titleKey: string;
95
+ readonly descriptionKey?: string;
96
+ readonly icon?: string;
97
+ readonly emoji?: string;
98
+ readonly order: number;
99
+ readonly subCategoryIds: readonly string[];
100
+ }
101
+
102
+ export interface ScenarioSubCategory {
103
+ readonly id: string;
104
+ readonly titleKey: string;
105
+ readonly descriptionKey?: string;
106
+ readonly icon?: string;
107
+ readonly emoji?: string;
108
+ readonly mainCategoryId: string;
109
+ readonly scenarioCategories: readonly string[];
110
+ readonly order: number;
111
+ }
112
+
113
+ export interface ScenarioData {
114
+ readonly id: string;
115
+ readonly category?: string;
116
+ readonly title: string;
117
+ readonly description: string;
118
+ readonly icon: string;
119
+ readonly imageUrl?: string;
120
+ readonly previewImageUrl?: string;
121
+ readonly aiPrompt: string;
122
+ readonly storyTemplate: string;
123
+ readonly requiresPhoto?: boolean;
124
+ readonly hidden?: boolean;
125
+ }
@@ -25,3 +25,26 @@ export {
25
25
  } from "./configs/wizard-configs";
26
26
 
27
27
  export type { WizardConfigOptions } from "./configs/wizard-configs";
28
+
29
+ // Presentation - Containers
30
+ export { CategoryNavigationContainer } from "./presentation/containers";
31
+ export type { CategoryNavigationContainerProps } from "./presentation/containers";
32
+
33
+ // Presentation - Screens
34
+ export {
35
+ ScenarioPreviewScreen,
36
+ MainCategoryScreen,
37
+ SubCategoryScreen,
38
+ HierarchicalScenarioListScreen,
39
+ } from "./presentation/screens";
40
+ export type {
41
+ MainCategoryScreenProps,
42
+ SubCategoryScreenProps,
43
+ } from "./presentation/screens";
44
+
45
+ // Legacy types (backward compatibility)
46
+ export type {
47
+ ScenarioMainCategory,
48
+ ScenarioSubCategory,
49
+ ScenarioData,
50
+ } from "./domain/scenario.types";
@@ -0,0 +1,178 @@
1
+ /**
2
+ * CategoryNavigationContainer
3
+ * Orchestrates 3-step hierarchical scenario selection flow:
4
+ * Main Category → Sub Category → Scenario List
5
+ */
6
+
7
+ import React, { useState, useCallback, useEffect } from "react";
8
+ import type {
9
+ ScenarioData,
10
+ ScenarioMainCategory,
11
+ ScenarioSubCategory,
12
+ } from "../../domain/scenario.types";
13
+ import { MainCategoryScreen } from "../screens/MainCategoryScreen";
14
+ import { SubCategoryScreen } from "../screens/SubCategoryScreen";
15
+ import { HierarchicalScenarioListScreen } from "../screens/HierarchicalScenarioListScreen";
16
+
17
+ type NavigationStep = "main_category" | "sub_category" | "scenario_list";
18
+
19
+ export interface CategoryNavigationContainerProps {
20
+ readonly mainCategories: readonly ScenarioMainCategory[];
21
+ readonly subCategories: readonly ScenarioSubCategory[];
22
+ readonly scenarios: readonly ScenarioData[];
23
+ readonly onSelectScenario: (scenarioId: string) => void;
24
+ readonly onBack?: () => void;
25
+ readonly t: (key: string) => string;
26
+ readonly headerTitle?: string;
27
+ readonly headerDescription?: string;
28
+ readonly numColumns?: number;
29
+ }
30
+
31
+ export const CategoryNavigationContainer: React.FC<
32
+ CategoryNavigationContainerProps
33
+ > = ({
34
+ mainCategories,
35
+ subCategories,
36
+ scenarios,
37
+ onSelectScenario,
38
+ onBack,
39
+ t,
40
+ headerTitle,
41
+ headerDescription,
42
+ numColumns = 2,
43
+ }) => {
44
+ const [currentStep, setCurrentStep] = useState<NavigationStep>("main_category");
45
+ const [selectedMainCategoryId, setSelectedMainCategoryId] = useState<string | null>(null);
46
+ const [selectedSubCategoryId, setSelectedSubCategoryId] = useState<string | null>(null);
47
+
48
+ // Debug: Initial mount
49
+ useEffect(() => {
50
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
51
+ console.log("[CategoryNavigationContainer] Mounted", {
52
+ mainCategoriesCount: mainCategories.length,
53
+ subCategoriesCount: subCategories.length,
54
+ scenariosCount: scenarios.length,
55
+ currentStep,
56
+ });
57
+ }
58
+ }, []);
59
+
60
+ // Debug: Step changes
61
+ useEffect(() => {
62
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
63
+ console.log("[CategoryNavigationContainer] Step changed", {
64
+ currentStep,
65
+ selectedMainCategoryId,
66
+ selectedSubCategoryId,
67
+ });
68
+ }
69
+ }, [currentStep, selectedMainCategoryId, selectedSubCategoryId]);
70
+
71
+ const handleSelectMainCategory = useCallback((categoryId: string) => {
72
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
73
+ console.log("[CategoryNavigationContainer] Main category selected", {
74
+ categoryId,
75
+ });
76
+ }
77
+ setSelectedMainCategoryId(categoryId);
78
+ setCurrentStep("sub_category");
79
+ }, []);
80
+
81
+ const handleSelectSubCategory = useCallback((subCategoryId: string) => {
82
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
83
+ console.log("[CategoryNavigationContainer] Sub category selected", {
84
+ subCategoryId,
85
+ });
86
+ }
87
+ setSelectedSubCategoryId(subCategoryId);
88
+ setCurrentStep("scenario_list");
89
+ }, []);
90
+
91
+ const handleBackFromSubCategory = useCallback(() => {
92
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
93
+ console.log("[CategoryNavigationContainer] Back from sub category");
94
+ }
95
+ setSelectedMainCategoryId(null);
96
+ setCurrentStep("main_category");
97
+ }, []);
98
+
99
+ const handleBackFromScenarioList = useCallback(() => {
100
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
101
+ console.log("[CategoryNavigationContainer] Back from scenario list");
102
+ }
103
+ setSelectedSubCategoryId(null);
104
+ setCurrentStep("sub_category");
105
+ }, []);
106
+
107
+ const handleBackFromMainCategory = useCallback(() => {
108
+ if (onBack) {
109
+ onBack();
110
+ }
111
+ }, [onBack]);
112
+
113
+ if (currentStep === "main_category") {
114
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
115
+ console.log("[CategoryNavigationContainer] Rendering MainCategoryScreen", {
116
+ mainCategoriesCount: mainCategories.length,
117
+ });
118
+ }
119
+ return (
120
+ <MainCategoryScreen
121
+ mainCategories={mainCategories}
122
+ onSelectCategory={handleSelectMainCategory}
123
+ onBack={onBack ? handleBackFromMainCategory : undefined}
124
+ t={t}
125
+ headerTitle={headerTitle}
126
+ headerDescription={headerDescription}
127
+ />
128
+ );
129
+ }
130
+
131
+ if (currentStep === "sub_category" && selectedMainCategoryId) {
132
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
133
+ console.log("[CategoryNavigationContainer] Rendering SubCategoryScreen", {
134
+ selectedMainCategoryId,
135
+ subCategoriesCount: subCategories.length,
136
+ });
137
+ }
138
+ return (
139
+ <SubCategoryScreen
140
+ mainCategoryId={selectedMainCategoryId}
141
+ subCategories={subCategories}
142
+ onSelectSubCategory={handleSelectSubCategory}
143
+ onBack={handleBackFromSubCategory}
144
+ t={t}
145
+ />
146
+ );
147
+ }
148
+
149
+ if (currentStep === "scenario_list" && selectedSubCategoryId) {
150
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
151
+ console.log("[CategoryNavigationContainer] Rendering HierarchicalScenarioListScreen", {
152
+ selectedSubCategoryId,
153
+ scenariosCount: scenarios.length,
154
+ });
155
+ }
156
+ return (
157
+ <HierarchicalScenarioListScreen
158
+ subCategoryId={selectedSubCategoryId}
159
+ subCategories={subCategories}
160
+ scenarios={scenarios}
161
+ onSelectScenario={onSelectScenario}
162
+ onBack={handleBackFromScenarioList}
163
+ t={t}
164
+ numColumns={numColumns}
165
+ />
166
+ );
167
+ }
168
+
169
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
170
+ console.log("[CategoryNavigationContainer] Rendering NULL - no matching condition", {
171
+ currentStep,
172
+ selectedMainCategoryId,
173
+ selectedSubCategoryId,
174
+ });
175
+ }
176
+
177
+ return null;
178
+ };
@@ -0,0 +1,2 @@
1
+ export { CategoryNavigationContainer } from "./CategoryNavigationContainer";
2
+ export type { CategoryNavigationContainerProps } from "./CategoryNavigationContainer";