@umituz/react-native-ai-generation-content 1.17.266 → 1.17.267

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.17.266",
3
+ "version": "1.17.267",
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,196 @@
1
+ /**
2
+ * GenerationErrorScreen
3
+ * Generic error screen for AI generation failures
4
+ */
5
+
6
+ import React, { useMemo } from "react";
7
+ import { View, StyleSheet, StyleProp, ViewStyle } from "react-native";
8
+ import {
9
+ ScreenLayout,
10
+ AtomicText,
11
+ AtomicIcon,
12
+ useAppDesignTokens,
13
+ AtomicButton,
14
+ type DesignTokens,
15
+ } from "@umituz/react-native-design-system";
16
+
17
+ /**
18
+ * Error screen translations
19
+ */
20
+ export interface GenerationErrorTranslations {
21
+ /** Error title */
22
+ readonly title: string;
23
+ /** Try again button */
24
+ readonly tryAgain: string;
25
+ /** Choose another button */
26
+ readonly chooseAnother: string;
27
+ /** Credit info message */
28
+ readonly noCreditCharged: string;
29
+ }
30
+
31
+ /**
32
+ * Error screen config
33
+ */
34
+ export interface GenerationErrorConfig {
35
+ /** Show credit info message */
36
+ readonly showCreditInfo?: boolean;
37
+ /** Icon name */
38
+ readonly iconName?: string;
39
+ /** Icon size */
40
+ readonly iconSize?: number;
41
+ }
42
+
43
+ /**
44
+ * Error screen props
45
+ */
46
+ export interface GenerationErrorScreenProps {
47
+ /** Error message to display */
48
+ readonly errorMessage?: string;
49
+ /** Translations */
50
+ readonly translations: GenerationErrorTranslations;
51
+ /** Configuration */
52
+ readonly config?: GenerationErrorConfig;
53
+ /** Try again callback */
54
+ readonly onTryAgain: () => void;
55
+ /** Choose another scenario callback */
56
+ readonly onChooseAnother: () => void;
57
+ /** Optional custom style */
58
+ readonly style?: StyleProp<ViewStyle>;
59
+ }
60
+
61
+ const DEFAULT_CONFIG: GenerationErrorConfig = {
62
+ showCreditInfo: true,
63
+ iconName: "alert-circle",
64
+ iconSize: 56,
65
+ };
66
+
67
+ export const GenerationErrorScreen: React.FC<GenerationErrorScreenProps> = ({
68
+ errorMessage,
69
+ translations,
70
+ config = DEFAULT_CONFIG,
71
+ onTryAgain,
72
+ onChooseAnother,
73
+ style,
74
+ }) => {
75
+ const tokens = useAppDesignTokens();
76
+ const styles = useMemo(() => createStyles(tokens), [tokens]);
77
+ const mergedConfig = { ...DEFAULT_CONFIG, ...config };
78
+
79
+ return (
80
+ <View
81
+ style={[
82
+ styles.container,
83
+ { backgroundColor: tokens.colors.backgroundPrimary },
84
+ style,
85
+ ]}
86
+ >
87
+ <ScreenLayout
88
+ scrollable={false}
89
+ edges={["top", "bottom"]}
90
+ backgroundColor="transparent"
91
+ >
92
+ <View style={styles.content}>
93
+ <View style={styles.iconContainer}>
94
+ <AtomicIcon
95
+ name={mergedConfig.iconName || "alert-circle"}
96
+ size={mergedConfig.iconSize || 56}
97
+ customColor={tokens.colors.error}
98
+ />
99
+ </View>
100
+
101
+ <AtomicText style={styles.title}>{translations.title}</AtomicText>
102
+
103
+ <AtomicText style={styles.message}>
104
+ {errorMessage || translations.title}
105
+ </AtomicText>
106
+
107
+ {mergedConfig.showCreditInfo && (
108
+ <View style={styles.infoContainer}>
109
+ <AtomicIcon
110
+ name="information-circle-outline"
111
+ size={16}
112
+ customColor={tokens.colors.textSecondary}
113
+ />
114
+ <AtomicText style={styles.infoText}>
115
+ {translations.noCreditCharged}
116
+ </AtomicText>
117
+ </View>
118
+ )}
119
+
120
+ <View style={styles.spacer} />
121
+
122
+ <View style={styles.actionsContainer}>
123
+ <AtomicButton
124
+ title={translations.tryAgain}
125
+ onPress={onTryAgain}
126
+ variant="primary"
127
+ size="lg"
128
+ fullWidth
129
+ />
130
+
131
+ <View style={styles.secondaryButtonContainer}>
132
+ <AtomicButton
133
+ title={translations.chooseAnother}
134
+ onPress={onChooseAnother}
135
+ variant="text"
136
+ size="md"
137
+ fullWidth
138
+ />
139
+ </View>
140
+ </View>
141
+ </View>
142
+ </ScreenLayout>
143
+ </View>
144
+ );
145
+ };
146
+
147
+ const createStyles = (tokens: DesignTokens) =>
148
+ StyleSheet.create({
149
+ container: {
150
+ flex: 1,
151
+ },
152
+ content: {
153
+ flex: 1,
154
+ alignItems: "center",
155
+ paddingHorizontal: 32,
156
+ paddingTop: 80,
157
+ paddingBottom: 40,
158
+ },
159
+ iconContainer: {
160
+ marginBottom: 24,
161
+ },
162
+ title: {
163
+ ...tokens.typography.headingMedium,
164
+ color: tokens.colors.textPrimary,
165
+ fontWeight: "700",
166
+ marginBottom: 12,
167
+ textAlign: "center",
168
+ },
169
+ message: {
170
+ ...tokens.typography.bodyMedium,
171
+ color: tokens.colors.textSecondary,
172
+ textAlign: "center",
173
+ lineHeight: 22,
174
+ marginBottom: 24,
175
+ },
176
+ infoContainer: {
177
+ flexDirection: "row",
178
+ alignItems: "center",
179
+ gap: 6,
180
+ opacity: 0.7,
181
+ },
182
+ infoText: {
183
+ ...tokens.typography.bodySmall,
184
+ color: tokens.colors.textSecondary,
185
+ },
186
+ spacer: {
187
+ flex: 1,
188
+ },
189
+ actionsContainer: {
190
+ width: "100%",
191
+ gap: 16,
192
+ },
193
+ secondaryButtonContainer: {
194
+ marginTop: 4,
195
+ },
196
+ });
@@ -6,3 +6,9 @@ export { ResultPreviewScreen } from "./ResultPreviewScreen";
6
6
  export { ResultImageCard } from "./ResultImageCard";
7
7
  export { ResultActionBar } from "./ResultActionBar";
8
8
  export { RecentCreationsSection } from "./RecentCreationsSection";
9
+ export { GenerationErrorScreen } from "./GenerationErrorScreen";
10
+ export type {
11
+ GenerationErrorTranslations,
12
+ GenerationErrorConfig,
13
+ GenerationErrorScreenProps,
14
+ } from "./GenerationErrorScreen";