@umituz/react-native-ai-generation-content 1.13.1 → 1.15.0
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 +2 -2
- package/src/domains/creations/presentation/components/CreationCard.tsx +1 -2
- package/src/domains/creations/presentation/components/CreationsGrid.tsx +0 -1
- package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +17 -22
- package/src/index.ts +32 -0
- package/src/presentation/components/index.ts +1 -0
- package/src/presentation/components/photo-step/PhotoStep.tsx +96 -0
- package/src/presentation/components/photo-step/index.ts +2 -0
- package/src/presentation/components/result/GenerationResultContent.tsx +60 -23
- package/src/presentation/components/result/ResultActions.tsx +171 -84
- package/src/presentation/components/result/ResultHeader.tsx +69 -38
- package/src/presentation/components/result/ResultImageCard.tsx +118 -39
- package/src/presentation/components/result/ResultStoryCard.tsx +94 -44
- package/src/presentation/components/result/index.ts +14 -0
- package/src/presentation/hooks/index.ts +6 -0
- package/src/presentation/hooks/useGenerationFlow.ts +315 -0
- package/src/presentation/types/flow-config.types.ts +246 -0
- package/src/presentation/types/result-config.types.ts +194 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ResultStoryCard Component
|
|
3
|
-
* Displays story text with quote styling
|
|
3
|
+
* Displays story text with quote styling - fully configurable
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import * as React from "react";
|
|
@@ -11,63 +11,113 @@ import {
|
|
|
11
11
|
useAppDesignTokens,
|
|
12
12
|
} from "@umituz/react-native-design-system";
|
|
13
13
|
import { LinearGradient } from "expo-linear-gradient";
|
|
14
|
+
import type { ResultStoryConfig } from "../../types/result-config.types";
|
|
15
|
+
import { DEFAULT_RESULT_CONFIG } from "../../types/result-config.types";
|
|
14
16
|
|
|
15
17
|
export interface ResultStoryCardProps {
|
|
16
18
|
story: string;
|
|
19
|
+
config?: ResultStoryConfig;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
export const ResultStoryCard: React.FC<ResultStoryCardProps> = ({
|
|
22
|
+
export const ResultStoryCard: React.FC<ResultStoryCardProps> = ({
|
|
23
|
+
story,
|
|
24
|
+
config = DEFAULT_RESULT_CONFIG.story,
|
|
25
|
+
}) => {
|
|
20
26
|
const tokens = useAppDesignTokens();
|
|
27
|
+
const cfg = { ...DEFAULT_RESULT_CONFIG.story, ...config };
|
|
21
28
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
marginBottom: 20,
|
|
26
|
-
},
|
|
27
|
-
container: {
|
|
28
|
-
padding: 20,
|
|
29
|
+
const containerStyle = useMemo(() => {
|
|
30
|
+
const base = {
|
|
31
|
+
padding: cfg.spacing?.padding ?? 20,
|
|
29
32
|
borderRadius: 16,
|
|
30
|
-
|
|
31
|
-
borderColor: tokens.colors.primaryContainer,
|
|
32
|
-
},
|
|
33
|
-
quoteIcon: {
|
|
34
|
-
fontSize: 40,
|
|
35
|
-
lineHeight: 40,
|
|
36
|
-
color: tokens.colors.primary,
|
|
37
|
-
opacity: 0.4,
|
|
38
|
-
marginBottom: -12,
|
|
39
|
-
},
|
|
40
|
-
quoteEnd: {
|
|
41
|
-
alignItems: "flex-end",
|
|
42
|
-
marginTop: -12,
|
|
43
|
-
},
|
|
44
|
-
quoteIconEnd: {
|
|
45
|
-
marginBottom: 0,
|
|
46
|
-
},
|
|
47
|
-
text: {
|
|
48
|
-
fontSize: 14,
|
|
49
|
-
color: tokens.colors.textPrimary,
|
|
50
|
-
textAlign: "center",
|
|
51
|
-
lineHeight: 22,
|
|
52
|
-
fontStyle: "italic",
|
|
53
|
-
fontWeight: "500",
|
|
54
|
-
},
|
|
55
|
-
}), [tokens]);
|
|
33
|
+
};
|
|
56
34
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
35
|
+
if (cfg.borderStyle === "outline") {
|
|
36
|
+
return {
|
|
37
|
+
...base,
|
|
38
|
+
borderWidth: 1,
|
|
39
|
+
borderColor: tokens.colors.primaryContainer,
|
|
40
|
+
backgroundColor: "transparent",
|
|
41
|
+
};
|
|
42
|
+
} else if (cfg.borderStyle === "filled") {
|
|
43
|
+
return {
|
|
44
|
+
...base,
|
|
45
|
+
backgroundColor: tokens.colors.primaryContainer,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return base;
|
|
50
|
+
}, [cfg.borderStyle, cfg.spacing, tokens]);
|
|
51
|
+
|
|
52
|
+
const styles = useMemo(
|
|
53
|
+
() =>
|
|
54
|
+
StyleSheet.create({
|
|
55
|
+
outer: {
|
|
56
|
+
paddingHorizontal: cfg.spacing?.paddingHorizontal ?? 20,
|
|
57
|
+
marginBottom: cfg.spacing?.marginBottom ?? 20,
|
|
58
|
+
},
|
|
59
|
+
container: containerStyle,
|
|
60
|
+
quoteIcon: {
|
|
61
|
+
fontSize: 40,
|
|
62
|
+
lineHeight: 40,
|
|
63
|
+
color: tokens.colors.primary,
|
|
64
|
+
opacity: 0.4,
|
|
65
|
+
marginBottom: -12,
|
|
66
|
+
},
|
|
67
|
+
quoteEnd: {
|
|
68
|
+
alignItems:
|
|
69
|
+
cfg.textAlignment === "left"
|
|
70
|
+
? "flex-start"
|
|
71
|
+
: cfg.textAlignment === "right"
|
|
72
|
+
? "flex-end"
|
|
73
|
+
: "flex-end",
|
|
74
|
+
marginTop: -12,
|
|
75
|
+
},
|
|
76
|
+
quoteIconEnd: {
|
|
77
|
+
marginBottom: 0,
|
|
78
|
+
},
|
|
79
|
+
text: {
|
|
80
|
+
fontSize: cfg.fontSize ?? 14,
|
|
81
|
+
color: tokens.colors.textPrimary,
|
|
82
|
+
textAlign: cfg.textAlignment ?? "center",
|
|
83
|
+
lineHeight: (cfg.fontSize ?? 14) * 1.57,
|
|
84
|
+
fontStyle: cfg.fontStyle ?? "italic",
|
|
85
|
+
fontWeight: cfg.fontWeight ?? "500",
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
88
|
+
[tokens, cfg, containerStyle],
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const renderContent = () => (
|
|
92
|
+
<>
|
|
93
|
+
{cfg.showQuotes && <AtomicText style={styles.quoteIcon}>"</AtomicText>}
|
|
94
|
+
<AtomicText style={styles.text}>{story}</AtomicText>
|
|
95
|
+
{cfg.showQuotes && (
|
|
65
96
|
<View style={styles.quoteEnd}>
|
|
66
97
|
<AtomicText style={[styles.quoteIcon, styles.quoteIconEnd]}>
|
|
67
98
|
"
|
|
68
99
|
</AtomicText>
|
|
69
100
|
</View>
|
|
70
|
-
|
|
101
|
+
)}
|
|
102
|
+
</>
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
if (cfg.borderStyle === "gradient") {
|
|
106
|
+
return (
|
|
107
|
+
<View style={styles.outer}>
|
|
108
|
+
<LinearGradient
|
|
109
|
+
colors={[tokens.colors.primaryContainer, tokens.colors.surface]}
|
|
110
|
+
style={styles.container}
|
|
111
|
+
>
|
|
112
|
+
{renderContent()}
|
|
113
|
+
</LinearGradient>
|
|
114
|
+
</View>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<View style={styles.outer}>
|
|
120
|
+
<View style={styles.container}>{renderContent()}</View>
|
|
71
121
|
</View>
|
|
72
122
|
);
|
|
73
123
|
};
|
|
@@ -19,3 +19,17 @@ export type { ResultStoryCardProps } from "./ResultStoryCard";
|
|
|
19
19
|
|
|
20
20
|
export { ResultActions } from "./ResultActions";
|
|
21
21
|
export type { ResultActionsProps } from "./ResultActions";
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
DEFAULT_RESULT_CONFIG,
|
|
25
|
+
} from "../../types/result-config.types";
|
|
26
|
+
|
|
27
|
+
export type {
|
|
28
|
+
ResultConfig,
|
|
29
|
+
ResultHeaderConfig,
|
|
30
|
+
ResultImageConfig,
|
|
31
|
+
ResultStoryConfig,
|
|
32
|
+
ResultActionsConfig,
|
|
33
|
+
ResultLayoutConfig,
|
|
34
|
+
ResultActionButton,
|
|
35
|
+
} from "../../types/result-config.types";
|
|
@@ -34,3 +34,9 @@ export type {
|
|
|
34
34
|
PhotoGenerationState,
|
|
35
35
|
PhotoGenerationStatus,
|
|
36
36
|
} from "./photo-generation.types";
|
|
37
|
+
|
|
38
|
+
export { useGenerationFlow } from "./useGenerationFlow";
|
|
39
|
+
export type {
|
|
40
|
+
UseGenerationFlowOptions,
|
|
41
|
+
UseGenerationFlowReturn,
|
|
42
|
+
} from "./useGenerationFlow";
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useGenerationFlow Hook
|
|
3
|
+
* Manages step-by-step generation flow state and navigation
|
|
4
|
+
*
|
|
5
|
+
* @package @umituz/react-native-ai-generation-content
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useState, useCallback, useMemo } from "react";
|
|
9
|
+
import type {
|
|
10
|
+
GenerationFlowConfig,
|
|
11
|
+
GenerationFlowState,
|
|
12
|
+
PhotoStepData,
|
|
13
|
+
PhotoStepConfig,
|
|
14
|
+
} from "../types/flow-config.types";
|
|
15
|
+
|
|
16
|
+
export interface UseGenerationFlowOptions {
|
|
17
|
+
/** Flow configuration */
|
|
18
|
+
config: GenerationFlowConfig;
|
|
19
|
+
/** Callback when flow is complete */
|
|
20
|
+
onComplete?: (state: GenerationFlowState) => void;
|
|
21
|
+
/** Callback when step changes */
|
|
22
|
+
onStepChange?: (stepIndex: number, stepConfig: PhotoStepConfig) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface UseGenerationFlowReturn {
|
|
26
|
+
/** Current flow state */
|
|
27
|
+
state: GenerationFlowState;
|
|
28
|
+
/** Current step configuration */
|
|
29
|
+
currentStepConfig: PhotoStepConfig | null;
|
|
30
|
+
/** Current step data */
|
|
31
|
+
currentStepData: PhotoStepData | null;
|
|
32
|
+
/** Whether can go to next step */
|
|
33
|
+
canGoNext: boolean;
|
|
34
|
+
/** Whether can go to previous step */
|
|
35
|
+
canGoBack: boolean;
|
|
36
|
+
/** Go to next step */
|
|
37
|
+
goNext: () => void;
|
|
38
|
+
/** Go to previous step */
|
|
39
|
+
goBack: () => void;
|
|
40
|
+
/** Update current step photo */
|
|
41
|
+
updatePhoto: (imageUri: string, previewUrl?: string) => void;
|
|
42
|
+
/** Update current step name */
|
|
43
|
+
updateName: (name: string) => void;
|
|
44
|
+
/** Update current step validation */
|
|
45
|
+
updateValidation: (isValid: boolean) => void;
|
|
46
|
+
/** Update text input */
|
|
47
|
+
updateTextInput: (text: string) => void;
|
|
48
|
+
/** Reset flow */
|
|
49
|
+
reset: () => void;
|
|
50
|
+
/** Complete flow */
|
|
51
|
+
complete: () => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Hook to manage generation flow state
|
|
56
|
+
*/
|
|
57
|
+
export const useGenerationFlow = ({
|
|
58
|
+
config,
|
|
59
|
+
onComplete,
|
|
60
|
+
onStepChange,
|
|
61
|
+
}: UseGenerationFlowOptions): UseGenerationFlowReturn => {
|
|
62
|
+
// Initialize state
|
|
63
|
+
const [state, setState] = useState<GenerationFlowState>(() => ({
|
|
64
|
+
currentStepIndex: 0,
|
|
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
|
+
}));
|
|
83
|
+
|
|
84
|
+
// Get current step configuration
|
|
85
|
+
const currentStepConfig = useMemo(() => {
|
|
86
|
+
if (state.currentStepIndex >= config.photoSteps.length) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return config.photoSteps[state.currentStepIndex];
|
|
90
|
+
}, [state.currentStepIndex, config.photoSteps]);
|
|
91
|
+
|
|
92
|
+
// Get current step data
|
|
93
|
+
const currentStepData = useMemo(() => {
|
|
94
|
+
if (state.currentStepIndex >= state.photoSteps.length) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return state.photoSteps[state.currentStepIndex];
|
|
98
|
+
}, [state.currentStepIndex, state.photoSteps]);
|
|
99
|
+
|
|
100
|
+
// Check if current step is valid
|
|
101
|
+
const isCurrentStepValid = useMemo(() => {
|
|
102
|
+
if (!currentStepData || !currentStepConfig) {
|
|
103
|
+
return false;
|
|
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]);
|
|
123
|
+
|
|
124
|
+
// Can go to next step
|
|
125
|
+
const canGoNext = useMemo(() => {
|
|
126
|
+
return isCurrentStepValid && !state.isProcessing;
|
|
127
|
+
}, [isCurrentStepValid, state.isProcessing]);
|
|
128
|
+
|
|
129
|
+
// Can go back
|
|
130
|
+
const canGoBack = useMemo(() => {
|
|
131
|
+
return (
|
|
132
|
+
state.currentStepIndex > 0 &&
|
|
133
|
+
config.behavior?.allowBack !== false &&
|
|
134
|
+
!state.isProcessing
|
|
135
|
+
);
|
|
136
|
+
}, [state.currentStepIndex, config.behavior?.allowBack, state.isProcessing]);
|
|
137
|
+
|
|
138
|
+
// Go to next step
|
|
139
|
+
const goNext = useCallback(() => {
|
|
140
|
+
if (!canGoNext) return;
|
|
141
|
+
|
|
142
|
+
setState((prev) => {
|
|
143
|
+
const nextIndex = prev.currentStepIndex + 1;
|
|
144
|
+
|
|
145
|
+
// If we've completed all photo steps, mark as complete
|
|
146
|
+
if (nextIndex >= config.photoSteps.length) {
|
|
147
|
+
const newState = {
|
|
148
|
+
...prev,
|
|
149
|
+
isComplete: true,
|
|
150
|
+
};
|
|
151
|
+
onComplete?.(newState);
|
|
152
|
+
return newState;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Move to next step
|
|
156
|
+
const newState = {
|
|
157
|
+
...prev,
|
|
158
|
+
currentStepIndex: nextIndex,
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// Notify step change
|
|
162
|
+
onStepChange?.(nextIndex, config.photoSteps[nextIndex]);
|
|
163
|
+
|
|
164
|
+
return newState;
|
|
165
|
+
});
|
|
166
|
+
}, [canGoNext, config.photoSteps, onComplete, onStepChange]);
|
|
167
|
+
|
|
168
|
+
// Go to previous step
|
|
169
|
+
const goBack = useCallback(() => {
|
|
170
|
+
if (!canGoBack) return;
|
|
171
|
+
|
|
172
|
+
setState((prev) => {
|
|
173
|
+
const prevIndex = prev.currentStepIndex - 1;
|
|
174
|
+
const newState = {
|
|
175
|
+
...prev,
|
|
176
|
+
currentStepIndex: prevIndex,
|
|
177
|
+
isComplete: false,
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Notify step change
|
|
181
|
+
onStepChange?.(prevIndex, config.photoSteps[prevIndex]);
|
|
182
|
+
|
|
183
|
+
return newState;
|
|
184
|
+
});
|
|
185
|
+
}, [canGoBack, config.photoSteps, onStepChange]);
|
|
186
|
+
|
|
187
|
+
// Update photo
|
|
188
|
+
const updatePhoto = useCallback(
|
|
189
|
+
(imageUri: string, previewUrl?: string) => {
|
|
190
|
+
setState((prev) => {
|
|
191
|
+
const newPhotoSteps = [...prev.photoSteps];
|
|
192
|
+
newPhotoSteps[prev.currentStepIndex] = {
|
|
193
|
+
...newPhotoSteps[prev.currentStepIndex],
|
|
194
|
+
imageUri,
|
|
195
|
+
previewUrl,
|
|
196
|
+
validationStatus: "pending",
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
...prev,
|
|
201
|
+
photoSteps: newPhotoSteps,
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
},
|
|
205
|
+
[],
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
// Update name
|
|
209
|
+
const updateName = useCallback((name: string) => {
|
|
210
|
+
setState((prev) => {
|
|
211
|
+
const newPhotoSteps = [...prev.photoSteps];
|
|
212
|
+
newPhotoSteps[prev.currentStepIndex] = {
|
|
213
|
+
...newPhotoSteps[prev.currentStepIndex],
|
|
214
|
+
name,
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
...prev,
|
|
219
|
+
photoSteps: newPhotoSteps,
|
|
220
|
+
};
|
|
221
|
+
});
|
|
222
|
+
}, []);
|
|
223
|
+
|
|
224
|
+
// Update validation
|
|
225
|
+
const updateValidation = useCallback((isValid: boolean) => {
|
|
226
|
+
setState((prev) => {
|
|
227
|
+
const newPhotoSteps = [...prev.photoSteps];
|
|
228
|
+
newPhotoSteps[prev.currentStepIndex] = {
|
|
229
|
+
...newPhotoSteps[prev.currentStepIndex],
|
|
230
|
+
isValid,
|
|
231
|
+
validationStatus: isValid ? "valid" : "invalid",
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
...prev,
|
|
236
|
+
photoSteps: newPhotoSteps,
|
|
237
|
+
};
|
|
238
|
+
});
|
|
239
|
+
}, []);
|
|
240
|
+
|
|
241
|
+
// Update text input
|
|
242
|
+
const updateTextInput = useCallback(
|
|
243
|
+
(text: string) => {
|
|
244
|
+
setState((prev) => {
|
|
245
|
+
if (!prev.textInput) return prev;
|
|
246
|
+
|
|
247
|
+
const minLength = config.textInputStep?.minLength ?? 0;
|
|
248
|
+
const maxLength = config.textInputStep?.maxLength ?? Infinity;
|
|
249
|
+
const isValid = text.length >= minLength && text.length <= maxLength;
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
...prev,
|
|
253
|
+
textInput: {
|
|
254
|
+
...prev.textInput,
|
|
255
|
+
text,
|
|
256
|
+
isValid,
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
});
|
|
260
|
+
},
|
|
261
|
+
[config.textInputStep],
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
// Reset flow
|
|
265
|
+
const reset = useCallback(() => {
|
|
266
|
+
setState({
|
|
267
|
+
currentStepIndex: 0,
|
|
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]);
|
|
287
|
+
|
|
288
|
+
// Complete flow
|
|
289
|
+
const complete = useCallback(() => {
|
|
290
|
+
setState((prev) => {
|
|
291
|
+
const newState = {
|
|
292
|
+
...prev,
|
|
293
|
+
isComplete: true,
|
|
294
|
+
};
|
|
295
|
+
onComplete?.(newState);
|
|
296
|
+
return newState;
|
|
297
|
+
});
|
|
298
|
+
}, [onComplete]);
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
state,
|
|
302
|
+
currentStepConfig,
|
|
303
|
+
currentStepData,
|
|
304
|
+
canGoNext,
|
|
305
|
+
canGoBack,
|
|
306
|
+
goNext,
|
|
307
|
+
goBack,
|
|
308
|
+
updatePhoto,
|
|
309
|
+
updateName,
|
|
310
|
+
updateValidation,
|
|
311
|
+
updateTextInput,
|
|
312
|
+
reset,
|
|
313
|
+
complete,
|
|
314
|
+
};
|
|
315
|
+
};
|