@umituz/react-native-ai-generation-content 1.20.38 → 1.20.40

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.20.38",
3
+ "version": "1.20.40",
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",
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Flow Configuration Types
3
+ * Generic multi-step flow system for AI generation
4
+ */
5
+
6
+ /** Step Types */
7
+ export enum StepType {
8
+ CATEGORY_SELECTION = "category_selection",
9
+ SCENARIO_SELECTION = "scenario_selection",
10
+ SCENARIO_PREVIEW = "scenario_preview",
11
+ PARTNER_UPLOAD = "partner_upload",
12
+ TEXT_INPUT = "text_input",
13
+ FEATURE_SELECTION = "feature_selection",
14
+ GENERATING = "generating",
15
+ RESULT_PREVIEW = "result_preview",
16
+ CUSTOM = "custom",
17
+ }
18
+
19
+ /** Partner Configuration */
20
+ export interface PartnerConfig {
21
+ readonly partnerId: "A" | "B" | "single";
22
+ readonly showNameInput?: boolean;
23
+ readonly showFaceDetection?: boolean;
24
+ readonly showPhotoTips?: boolean;
25
+ readonly maxNameLength?: number;
26
+ }
27
+
28
+ /** Category Data - App provides */
29
+ export interface CategoryData {
30
+ readonly id: string;
31
+ readonly titleKey: string;
32
+ readonly descriptionKey?: string;
33
+ readonly icon: string;
34
+ readonly imageUrl?: string;
35
+ readonly subcategories?: readonly CategoryData[];
36
+ }
37
+
38
+ /** Scenario Data - App provides */
39
+ export interface ScenarioData {
40
+ readonly id: string;
41
+ readonly categoryId?: string;
42
+ readonly titleKey: string;
43
+ readonly descriptionKey: string;
44
+ readonly icon: string;
45
+ readonly imageUrl?: string;
46
+ readonly previewImageUrl?: string;
47
+ readonly aiPrompt: string;
48
+ readonly storyTemplate?: string;
49
+ }
50
+
51
+ /** Visual Style Option */
52
+ export interface VisualStyleData {
53
+ readonly id: string;
54
+ readonly icon: string;
55
+ readonly labelKey: string;
56
+ readonly promptModifier?: string;
57
+ }
58
+
59
+ /** Uploaded Image Data */
60
+ export interface UploadedImageData {
61
+ readonly uri: string;
62
+ readonly base64: string;
63
+ readonly mimeType: string;
64
+ }
65
+
66
+ /** Step Transition */
67
+ export interface StepTransition {
68
+ readonly next?: string | ((state: FlowState) => string | null);
69
+ readonly back?: string;
70
+ readonly skipIf?: (state: FlowState) => boolean;
71
+ }
72
+
73
+ /** Step Definition */
74
+ export interface StepDefinition<TConfig = unknown> {
75
+ readonly id: string;
76
+ readonly type: StepType;
77
+ readonly required?: boolean;
78
+ readonly config?: TConfig;
79
+ readonly transitions?: StepTransition;
80
+ readonly component?: React.ComponentType<StepComponentProps>;
81
+ }
82
+
83
+ /** Flow Generation Status */
84
+ export type FlowGenerationStatus = "idle" | "preparing" | "generating" | "completed" | "failed";
85
+
86
+ /** Flow State */
87
+ export interface FlowState {
88
+ readonly currentStepId: string;
89
+ readonly currentStepIndex: number;
90
+ readonly completedSteps: readonly string[];
91
+ readonly selectedCategory?: CategoryData;
92
+ readonly selectedScenario?: ScenarioData;
93
+ readonly partners: Record<string, UploadedImageData | undefined>;
94
+ readonly partnerNames: Record<string, string>;
95
+ readonly textInput?: string;
96
+ readonly visualStyle?: string;
97
+ readonly selectedFeatures: Record<string, readonly string[]>;
98
+ readonly customData: Record<string, unknown>;
99
+ readonly generationStatus: FlowGenerationStatus;
100
+ readonly generationProgress: number;
101
+ readonly generationResult?: unknown;
102
+ readonly generationError?: string;
103
+ }
104
+
105
+ /** Flow Actions */
106
+ export interface FlowActions {
107
+ goToStep: (stepId: string) => void;
108
+ nextStep: () => void;
109
+ previousStep: () => void;
110
+ setCategory: (category: CategoryData | undefined) => void;
111
+ setScenario: (scenario: ScenarioData | undefined) => void;
112
+ setPartnerImage: (partnerId: string, image: UploadedImageData | undefined) => void;
113
+ setPartnerName: (partnerId: string, name: string) => void;
114
+ setTextInput: (text: string) => void;
115
+ setVisualStyle: (styleId: string) => void;
116
+ setSelectedFeatures: (featureType: string, ids: readonly string[]) => void;
117
+ setCustomData: (key: string, value: unknown) => void;
118
+ startGeneration: () => void;
119
+ updateProgress: (progress: number) => void;
120
+ setResult: (result: unknown) => void;
121
+ setError: (error: string) => void;
122
+ reset: () => void;
123
+ completeStep: (stepId: string) => void;
124
+ }
125
+
126
+ /** Step Component Props */
127
+ export interface StepComponentProps {
128
+ readonly step: StepDefinition;
129
+ readonly state: FlowState;
130
+ readonly actions: FlowActions;
131
+ readonly onNext: () => void;
132
+ readonly onBack: () => void;
133
+ readonly isProcessing: boolean;
134
+ readonly progress: number;
135
+ readonly error: string | null;
136
+ }
137
+
138
+ /** Flow Callbacks */
139
+ export interface FlowCallbacks {
140
+ onAuthRequired?: (resume: () => void) => void;
141
+ onCreditsExhausted?: () => void;
142
+ onGenerationStart?: () => void;
143
+ onGenerationSuccess?: (result: unknown) => void;
144
+ onGenerationError?: (error: string) => void;
145
+ onStepChange?: (stepId: string, index: number) => void;
146
+ onFlowComplete?: (result: unknown) => void;
147
+ }
148
+
149
+ /** Flow Data Provider - App provides data */
150
+ export interface FlowDataProvider {
151
+ readonly categories?: readonly CategoryData[];
152
+ readonly scenarios?: readonly ScenarioData[];
153
+ readonly visualStyles?: readonly VisualStyleData[];
154
+ readonly surprisePrompts?: readonly string[];
155
+ }
156
+
157
+ /** Flow Configuration */
158
+ export interface FlowConfiguration {
159
+ readonly id: string;
160
+ readonly steps: readonly StepDefinition[];
161
+ readonly initialStepId?: string;
162
+ readonly callbacks?: FlowCallbacks;
163
+ readonly data?: FlowDataProvider;
164
+ readonly creditCost?: number;
165
+ readonly userId?: string;
166
+ }
167
+
168
+ /** Flow Features */
169
+ export interface FlowFeatures {
170
+ readonly categorySelection: boolean;
171
+ readonly partnerCount: 0 | 1 | 2;
172
+ readonly textInput: boolean;
173
+ readonly scenarioSelection: boolean;
174
+ }
@@ -10,3 +10,4 @@ export * from "./progress.types";
10
10
  export * from "./middleware.types";
11
11
  export * from "./job.types";
12
12
  export * from "./processing-modes.types";
13
+ export * from "./flow-config.types";
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { useSingleImageFeature, type BaseSingleImageHookReturn } from "../../../image-to-image";
7
- import type { HDTouchUpFeatureConfig, HDTouchUpResult } from "../../domain/types";
7
+ import type { HDTouchUpFeatureConfig } from "../../domain/types";
8
8
 
9
9
  export interface UseHDTouchUpFeatureProps {
10
10
  config: HDTouchUpFeatureConfig;
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { useSingleImageFeature, type BaseSingleImageHookReturn } from "../../../image-to-image";
7
- import type { PhotoRestoreFeatureConfig, PhotoRestoreResult } from "../../domain/types";
7
+ import type { PhotoRestoreFeatureConfig } from "../../domain/types";
8
8
 
9
9
  export interface UsePhotoRestoreFeatureProps {
10
10
  config: PhotoRestoreFeatureConfig;
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { useSingleImageFeature, type BaseSingleImageHookReturn } from "../../../image-to-image";
7
- import type { RemoveBackgroundFeatureConfig, RemoveBackgroundResult } from "../../domain/types";
7
+ import type { RemoveBackgroundFeatureConfig } from "../../domain/types";
8
8
 
9
9
  export interface UseRemoveBackgroundFeatureProps {
10
10
  config: RemoveBackgroundFeatureConfig;
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { useSingleImageFeature, type BaseSingleImageHookReturn } from "../../../image-to-image";
7
- import type { UpscaleFeatureConfig, UpscaleResult } from "../../domain/types";
7
+ import type { UpscaleFeatureConfig } from "../../domain/types";
8
8
 
9
9
  export interface UseUpscaleFeatureProps {
10
10
  config: UpscaleFeatureConfig;
package/src/index.ts CHANGED
@@ -194,3 +194,25 @@ export type {
194
194
 
195
195
  // AIGenerationWizard - Generic wizard for all AI generation flows
196
196
  export * from "./features/wizard";
197
+
198
+ // Flow System - Dynamic multi-step flow management
199
+ export { createFlowStore, useFlow, resetFlowStore } from "./infrastructure/flow";
200
+ export type { FlowStoreType } from "./infrastructure/flow";
201
+ export { StepType } from "./domain/entities/flow-config.types";
202
+ export type {
203
+ StepDefinition,
204
+ FlowState,
205
+ FlowActions,
206
+ FlowConfiguration,
207
+ FlowCallbacks,
208
+ FlowDataProvider,
209
+ FlowFeatures,
210
+ StepComponentProps,
211
+ StepTransition,
212
+ PartnerConfig,
213
+ CategoryData,
214
+ ScenarioData,
215
+ VisualStyleData,
216
+ UploadedImageData,
217
+ FlowGenerationStatus,
218
+ } from "./domain/entities/flow-config.types";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Flow Infrastructure
3
+ * Multi-step flow management system
4
+ */
5
+
6
+ export { createFlowStore, type FlowStoreType } from "./useFlowStore";
7
+ export { useFlow, resetFlowStore } from "./useFlow";
@@ -0,0 +1,87 @@
1
+ /**
2
+ * useFlow Hook
3
+ * Main hook for accessing flow state and actions
4
+ */
5
+
6
+ import { useRef, useCallback, useMemo } from "react";
7
+ import { createFlowStore, type FlowStoreType } from "./useFlowStore";
8
+ import type { FlowState, FlowActions, StepDefinition } from "../../domain/entities/flow-config.types";
9
+
10
+ interface UseFlowConfig {
11
+ steps: readonly StepDefinition[];
12
+ initialStepId?: string;
13
+ }
14
+
15
+ interface UseFlowReturn extends FlowState, FlowActions {
16
+ canGoNext: boolean;
17
+ canGoBack: boolean;
18
+ currentStep: StepDefinition | undefined;
19
+ totalSteps: number;
20
+ isFirstStep: boolean;
21
+ isLastStep: boolean;
22
+ hasPartner: (partnerId: string) => boolean;
23
+ getPartnerImage: (partnerId: string) => FlowState["partners"][string];
24
+ getPartnerName: (partnerId: string) => string;
25
+ }
26
+
27
+ let flowStoreInstance: FlowStoreType | null = null;
28
+
29
+ export const useFlow = (config: UseFlowConfig): UseFlowReturn => {
30
+ const storeRef = useRef<FlowStoreType | null>(null);
31
+
32
+ if (!storeRef.current) {
33
+ if (!flowStoreInstance) {
34
+ flowStoreInstance = createFlowStore(config);
35
+ }
36
+ storeRef.current = flowStoreInstance;
37
+ }
38
+
39
+ const store = storeRef.current;
40
+ const state = store();
41
+ const totalSteps = config.steps.length;
42
+
43
+ const canGoNext = state.currentStepIndex < totalSteps - 1;
44
+ const canGoBack = state.currentStepIndex > 0;
45
+ const isFirstStep = state.currentStepIndex === 0;
46
+ const isLastStep = state.currentStepIndex === totalSteps - 1;
47
+
48
+ const currentStep = useMemo(
49
+ () => config.steps[state.currentStepIndex],
50
+ [config.steps, state.currentStepIndex],
51
+ );
52
+
53
+ const hasPartner = useCallback(
54
+ (partnerId: string) => state.partners[partnerId] != null,
55
+ [state.partners],
56
+ );
57
+
58
+ const getPartnerImage = useCallback(
59
+ (partnerId: string) => state.partners[partnerId],
60
+ [state.partners],
61
+ );
62
+
63
+ const getPartnerName = useCallback(
64
+ (partnerId: string) => state.partnerNames[partnerId] ?? "",
65
+ [state.partnerNames],
66
+ );
67
+
68
+ return {
69
+ ...state,
70
+ canGoNext,
71
+ canGoBack,
72
+ currentStep,
73
+ totalSteps,
74
+ isFirstStep,
75
+ isLastStep,
76
+ hasPartner,
77
+ getPartnerImage,
78
+ getPartnerName,
79
+ };
80
+ };
81
+
82
+ export const resetFlowStore = () => {
83
+ if (flowStoreInstance) {
84
+ flowStoreInstance.getState().reset();
85
+ }
86
+ flowStoreInstance = null;
87
+ };
@@ -0,0 +1,145 @@
1
+ /**
2
+ * useFlowStore
3
+ * Zustand store for multi-step flow state management
4
+ */
5
+
6
+ import { createStore } from "@umituz/react-native-design-system";
7
+ import type {
8
+ FlowState,
9
+ FlowActions,
10
+ CategoryData,
11
+ ScenarioData,
12
+ UploadedImageData,
13
+ StepDefinition,
14
+ } from "../../domain/entities/flow-config.types";
15
+
16
+ interface FlowStoreState extends FlowState {
17
+ stepDefinitions: readonly StepDefinition[];
18
+ }
19
+
20
+ const createInitialState = (): FlowState => ({
21
+ currentStepId: "",
22
+ currentStepIndex: 0,
23
+ completedSteps: [],
24
+ selectedCategory: undefined,
25
+ selectedScenario: undefined,
26
+ partners: {},
27
+ partnerNames: {},
28
+ textInput: undefined,
29
+ visualStyle: undefined,
30
+ selectedFeatures: {},
31
+ customData: {},
32
+ generationStatus: "idle",
33
+ generationProgress: 0,
34
+ generationResult: undefined,
35
+ generationError: undefined,
36
+ });
37
+
38
+ interface FlowStoreConfig {
39
+ steps: readonly StepDefinition[];
40
+ initialStepId?: string;
41
+ }
42
+
43
+ export const createFlowStore = (config: FlowStoreConfig) => {
44
+ const initialStepId = config.initialStepId ?? config.steps[0]?.id ?? "";
45
+ const initialIndex = Math.max(0, config.steps.findIndex((s) => s.id === initialStepId));
46
+
47
+ const initialState: FlowStoreState = {
48
+ ...createInitialState(),
49
+ currentStepId: initialStepId,
50
+ currentStepIndex: initialIndex,
51
+ stepDefinitions: config.steps,
52
+ };
53
+
54
+ return createStore<FlowStoreState, FlowActions>({
55
+ name: "flow_store",
56
+ initialState,
57
+ persist: false,
58
+ actions: (set, get) => ({
59
+ goToStep: (stepId: string) => {
60
+ const { stepDefinitions } = get();
61
+ const index = stepDefinitions.findIndex((s) => s.id === stepId);
62
+ if (index >= 0) {
63
+ set({ currentStepId: stepId, currentStepIndex: index, generationError: undefined });
64
+ }
65
+ },
66
+
67
+ nextStep: () => {
68
+ const { stepDefinitions, currentStepIndex, completedSteps, currentStepId } = get();
69
+ const nextIndex = currentStepIndex + 1;
70
+ if (nextIndex < stepDefinitions.length) {
71
+ const nextStep = stepDefinitions[nextIndex];
72
+ const newCompleted = completedSteps.includes(currentStepId)
73
+ ? completedSteps
74
+ : [...completedSteps, currentStepId];
75
+ set({ currentStepId: nextStep.id, currentStepIndex: nextIndex, completedSteps: newCompleted });
76
+ }
77
+ },
78
+
79
+ previousStep: () => {
80
+ const { stepDefinitions, currentStepIndex } = get();
81
+ if (currentStepIndex > 0) {
82
+ const prevStep = stepDefinitions[currentStepIndex - 1];
83
+ set({ currentStepId: prevStep.id, currentStepIndex: currentStepIndex - 1 });
84
+ }
85
+ },
86
+
87
+ setCategory: (category: CategoryData | undefined) => set({ selectedCategory: category }),
88
+ setScenario: (scenario: ScenarioData | undefined) => set({ selectedScenario: scenario }),
89
+
90
+ setPartnerImage: (partnerId: string, image: UploadedImageData | undefined) => {
91
+ const { partners } = get();
92
+ set({ partners: { ...partners, [partnerId]: image } });
93
+ },
94
+
95
+ setPartnerName: (partnerId: string, name: string) => {
96
+ const { partnerNames } = get();
97
+ set({ partnerNames: { ...partnerNames, [partnerId]: name } });
98
+ },
99
+
100
+ setTextInput: (text: string) => set({ textInput: text }),
101
+ setVisualStyle: (styleId: string) => set({ visualStyle: styleId }),
102
+
103
+ setSelectedFeatures: (featureType: string, ids: readonly string[]) => {
104
+ const { selectedFeatures } = get();
105
+ set({ selectedFeatures: { ...selectedFeatures, [featureType]: ids } });
106
+ },
107
+
108
+ setCustomData: (key: string, value: unknown) => {
109
+ const { customData } = get();
110
+ set({ customData: { ...customData, [key]: value } });
111
+ },
112
+
113
+ startGeneration: () => {
114
+ set({ generationStatus: "preparing", generationProgress: 0, generationError: undefined });
115
+ },
116
+
117
+ updateProgress: (progress: number) => {
118
+ set({ generationProgress: progress, generationStatus: progress > 0 ? "generating" : "preparing" });
119
+ },
120
+
121
+ setResult: (result: unknown) => {
122
+ set({ generationResult: result, generationStatus: "completed", generationProgress: 100 });
123
+ },
124
+
125
+ setError: (error: string) => {
126
+ set({ generationError: error, generationStatus: "failed", generationProgress: 0 });
127
+ },
128
+
129
+ reset: () => {
130
+ const { stepDefinitions } = get();
131
+ const firstStepId = stepDefinitions[0]?.id ?? "";
132
+ set({ ...createInitialState(), currentStepId: firstStepId, stepDefinitions });
133
+ },
134
+
135
+ completeStep: (stepId: string) => {
136
+ const { completedSteps } = get();
137
+ if (!completedSteps.includes(stepId)) {
138
+ set({ completedSteps: [...completedSteps, stepId] });
139
+ }
140
+ },
141
+ }),
142
+ });
143
+ };
144
+
145
+ export type FlowStoreType = ReturnType<typeof createFlowStore>;
@@ -4,7 +4,6 @@ import { View, Image, StyleSheet } from "react-native";
4
4
  import { AIGenerationHero } from "./AIGenerationHero";
5
5
  import { AIGenerationForm } from "./AIGenerationForm";
6
6
  import type { AIGenerationFormProps } from "./AIGenerationForm.types";
7
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
8
7
 
9
8
  export interface AIGenerationConfigProps extends Omit<AIGenerationFormProps, "isGenerating" | "progress"> {
10
9
  readonly heroTitle: string;
@@ -24,8 +23,6 @@ export const AIGenerationConfig: React.FC<AIGenerationConfigProps> = ({
24
23
  progress = 0,
25
24
  ...formProps
26
25
  }) => {
27
- const tokens = useAppDesignTokens();
28
-
29
26
  return (
30
27
  <View style={styles.container}>
31
28
  {heroTitle && (
@@ -61,7 +61,7 @@ export const AIGenerateWizardFlow: React.FC<AIGenerateWizardFlowProps> = ({
61
61
  <PartnerStepScreen
62
62
  t={t}
63
63
  onBack={handleBack}
64
- onContinue={(img: any) => {
64
+ onContinue={(img: { uri: string; previewUrl?: string }) => {
65
65
  setStepImage(isStep2 ? 1 : 0, { uri: img.uri, previewUrl: img.previewUrl || img.uri });
66
66
  handleNext();
67
67
  }}
@@ -184,7 +184,7 @@ export const AIGenerateWizardFlow: React.FC<AIGenerateWizardFlowProps> = ({
184
184
  isGenerating={isGenerating}
185
185
  progress={progress}
186
186
  presets={presets}
187
- onPresetPress={handleGenerate as any}
187
+ onPresetPress={() => { void handleGenerate(); }}
188
188
  prompt={prompt}
189
189
  onPromptChange={setPrompt}
190
190
  styles={styleOptions}
@@ -33,11 +33,24 @@ export interface AIGenerateWizardTranslations {
33
33
  readonly maxFileSize: string;
34
34
  }
35
35
 
36
+ export interface StyleOption {
37
+ readonly id: string;
38
+ readonly label: string;
39
+ readonly icon?: string;
40
+ }
41
+
42
+ export interface PresetOption {
43
+ readonly id: string;
44
+ readonly label: string;
45
+ readonly prompt?: string;
46
+ readonly icon?: string;
47
+ }
48
+
36
49
  export interface AIGenerateWizardFlowProps {
37
50
  readonly featureType: string;
38
51
  readonly translations: AIGenerateWizardTranslations;
39
- readonly styleOptions: any[];
40
- readonly presets: any[];
52
+ readonly styleOptions: StyleOption[];
53
+ readonly presets: PresetOption[];
41
54
  readonly durationOptions: number[];
42
55
  readonly onGenerate: (data: {
43
56
  prompt: string;
@@ -3,9 +3,16 @@ import { useMemo, useCallback, useEffect } from "react";
3
3
  import { useAIGenerateState, AIGenerateStep } from "../../hooks/generation/useAIGenerateState";
4
4
  import { getAIFeatureConfig, hasAIFeature } from "../../screens/ai-feature/registry";
5
5
 
6
+ interface GenerationData {
7
+ prompt: string;
8
+ style: string;
9
+ duration: number;
10
+ images: { uri: string; previewUrl?: string }[];
11
+ }
12
+
6
13
  interface UseAIGenerateWizardFlowProps {
7
14
  featureType: string;
8
- onGenerate: (data: any) => Promise<string | null | void>;
15
+ onGenerate: (data: GenerationData) => Promise<string | null | void>;
9
16
  onBack?: () => void;
10
17
  }
11
18
 
@@ -15,15 +22,15 @@ export function useAIGenerateWizardFlow({
15
22
  onBack: onBackProp,
16
23
  }: UseAIGenerateWizardFlowProps) {
17
24
  const state = useAIGenerateState();
18
- const {
19
- currentStep, setCurrentStep, isGenerating, setIsGenerating,
20
- setProgress, setResult, images, prompt, selectedStyle,
21
- selectedDuration, setStepImage
25
+ const {
26
+ currentStep, setCurrentStep, setIsGenerating,
27
+ setProgress, setResult, images, prompt, selectedStyle,
28
+ selectedDuration
22
29
  } = state;
23
30
 
24
31
  const imageCountRequired = useMemo(() => {
25
32
  if (!featureType || !hasAIFeature(featureType)) return 0;
26
- const config = getAIFeatureConfig(featureType as any);
33
+ const config = getAIFeatureConfig(featureType as Parameters<typeof getAIFeatureConfig>[0]);
27
34
  if (config.mode === "dual" || config.mode === "dual-video") return 2;
28
35
  if (config.mode === "single" || config.mode === "single-with-prompt")
29
36
  return 1;
@@ -70,7 +70,10 @@ export const useGenerationOrchestrator = <TInput, TResult>(
70
70
 
71
71
  const offlineStore = useOfflineStore();
72
72
  const { showError, showSuccess } = useAlert();
73
- const defaultCredits = useDeductCredit({ userId, onCreditsExhausted }) as any;
73
+ const defaultCredits = useDeductCredit({ userId, onCreditsExhausted }) as {
74
+ checkCredits: (amount: number) => Promise<boolean>;
75
+ deductCredit: (amount: number) => Promise<void>;
76
+ };
74
77
 
75
78
  // Use provided credit callbacks or default to useDeductCredit hook
76
79
  const checkCredits = credits?.checkCredits ?? defaultCredits.checkCredits;
@@ -9,12 +9,25 @@ import { prepareImage } from "../../../infrastructure/utils";
9
9
  import type { AIFeatureId } from "../../screens/ai-feature/types";
10
10
  import type { ImageFeatureType, VideoFeatureType } from "../../../domain/interfaces";
11
11
 
12
+ interface AlertMessages {
13
+ success?: string;
14
+ error?: string;
15
+ network?: string;
16
+ credits?: string;
17
+ }
18
+
19
+ interface GenerationError {
20
+ type: string;
21
+ message: string;
22
+ originalError?: Error;
23
+ }
24
+
12
25
  interface FeatureGenerationConfig {
13
26
  featureType: AIFeatureId;
14
27
  userId?: string;
15
- alertMessages: any;
16
- onSuccess?: (result: any) => void;
17
- onError?: (error: any) => void;
28
+ alertMessages: AlertMessages;
29
+ onSuccess?: (result: string) => void;
30
+ onError?: (error: GenerationError) => void;
18
31
  creditCost?: number;
19
32
  onCreditsExhausted?: () => void;
20
33
  }