@umituz/react-native-ai-generation-content 1.12.21 → 1.12.24

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.
Files changed (132) hide show
  1. package/package.json +33 -15
  2. package/src/domains/content-moderation/infrastructure/services/content-moderation.service.ts +4 -32
  3. package/src/domains/content-moderation/infrastructure/services/moderators/base.moderator.ts +1 -1
  4. package/src/domains/face-detection/infrastructure/validators/faceValidator.ts +1 -1
  5. package/src/domains/face-detection/presentation/components/FaceValidationStatus.tsx +3 -3
  6. package/src/domains/prompts/domain/entities/FuturePredictionConfig.ts +2 -1
  7. package/src/domains/prompts/domain/entities/GeneratedPrompt.ts +0 -1
  8. package/src/domains/prompts/domain/repositories/IAIPromptServices.ts +6 -12
  9. package/src/domains/prompts/infrastructure/repositories/PromptHistoryRepository.ts +42 -42
  10. package/src/domains/prompts/infrastructure/repositories/TemplateRepository.ts +42 -42
  11. package/src/domains/prompts/infrastructure/services/BackgroundRemovalService.ts +7 -7
  12. package/src/domains/prompts/infrastructure/services/ColorizationService.ts +7 -7
  13. package/src/domains/prompts/infrastructure/services/FaceSwapService.ts +19 -20
  14. package/src/domains/prompts/infrastructure/services/FuturePredictionService.ts +11 -31
  15. package/src/domains/prompts/infrastructure/services/ImageEnhancementService.ts +7 -7
  16. package/src/domains/prompts/infrastructure/services/PhotoRestorationService.ts +7 -7
  17. package/src/domains/prompts/infrastructure/services/PromptGenerationService.ts +13 -13
  18. package/src/domains/prompts/infrastructure/services/StyleTransferService.ts +8 -8
  19. package/src/domains/prompts/infrastructure/services/TextGenerationService.ts +7 -7
  20. package/src/domains/prompts/presentation/hooks/useAIServices.ts +30 -28
  21. package/src/domains/prompts/presentation/hooks/useFaceSwap.ts +1 -2
  22. package/src/domains/prompts/presentation/hooks/usePromptGeneration.ts +4 -5
  23. package/src/domains/prompts/presentation/hooks/useStyleTransfer.ts +1 -1
  24. package/src/domains/prompts/presentation/hooks/useTemplateRepository.ts +3 -3
  25. package/src/domains/prompts/presentation/theme/utils.ts +1 -1
  26. package/src/features/audio-generation/domain/entities.ts +39 -0
  27. package/src/features/audio-generation/index.ts +2 -0
  28. package/src/features/audio-generation/presentation/hooks.ts +39 -0
  29. package/src/{domains/feature-background → features/background}/presentation/components/BackgroundFeature.tsx +5 -4
  30. package/src/{domains/feature-background → features/background}/presentation/components/ComparisonSlider.tsx +45 -51
  31. package/src/{domains/feature-background → features/background}/presentation/components/ErrorDisplay.tsx +5 -3
  32. package/src/{domains/feature-background → features/background}/presentation/components/ModeSelector.tsx +2 -2
  33. package/src/{domains/feature-background → features/background}/presentation/hooks/useBackgroundFeature.ts +3 -2
  34. package/src/features/colorization/domain/entities.ts +46 -0
  35. package/src/features/colorization/index.ts +2 -0
  36. package/src/features/colorization/presentation/hooks.ts +39 -0
  37. package/src/features/face-swap/domain/entities.ts +48 -0
  38. package/src/features/face-swap/index.ts +2 -0
  39. package/src/features/face-swap/presentation/hooks.ts +41 -0
  40. package/src/features/future-prediction/domain/entities.ts +45 -0
  41. package/src/features/future-prediction/index.ts +2 -0
  42. package/src/features/future-prediction/presentation/hooks.ts +39 -0
  43. package/src/features/image-captioning/domain/entities.ts +47 -0
  44. package/src/features/image-captioning/index.ts +2 -0
  45. package/src/features/image-captioning/presentation/hooks.ts +39 -0
  46. package/src/features/inpainting/domain/entities.ts +58 -0
  47. package/src/features/inpainting/index.ts +2 -0
  48. package/src/features/inpainting/presentation/hooks.ts +39 -0
  49. package/src/features/photo-restoration/domain/entities.ts +48 -0
  50. package/src/features/photo-restoration/index.ts +2 -0
  51. package/src/features/photo-restoration/presentation/hooks.ts +39 -0
  52. package/src/features/sketch-to-image/domain/entities.ts +47 -0
  53. package/src/features/sketch-to-image/index.ts +2 -0
  54. package/src/features/sketch-to-image/presentation/hooks.ts +39 -0
  55. package/src/features/style-transfer/domain/entities.ts +52 -0
  56. package/src/features/style-transfer/index.ts +2 -0
  57. package/src/features/style-transfer/presentation/hooks.ts +39 -0
  58. package/src/features/text-to-image/domain/entities.ts +58 -0
  59. package/src/features/text-to-image/index.ts +2 -0
  60. package/src/features/text-to-image/presentation/hooks.ts +39 -0
  61. package/src/features/text-to-video/domain/entities.ts +52 -0
  62. package/src/features/text-to-video/index.ts +2 -0
  63. package/src/features/text-to-video/presentation/hooks.ts +39 -0
  64. package/src/features/upscaling/domain/entities.ts +42 -0
  65. package/src/features/upscaling/index.ts +2 -0
  66. package/src/features/upscaling/presentation/hooks.ts +39 -0
  67. package/src/index.ts +3 -6
  68. package/src/infrastructure/utils/status-checker.util.ts +4 -4
  69. package/src/infrastructure/wrappers/synchronous-generation.wrapper.ts +3 -3
  70. package/src/presentation/components/result/GenerationResultContent.tsx +21 -22
  71. package/src/presentation/components/result/ResultActions.tsx +51 -52
  72. package/src/presentation/components/result/ResultHeader.tsx +24 -25
  73. package/src/presentation/components/result/ResultImageCard.tsx +19 -20
  74. package/src/presentation/components/result/ResultStoryCard.tsx +23 -24
  75. package/src/presentation/hooks/photo-generation.types.ts +13 -4
  76. package/src/presentation/hooks/usePhotoGeneration.ts +30 -13
  77. package/src/domains/creations/application/services/CreationsService.ts +0 -72
  78. package/src/domains/creations/domain/entities/Creation.ts +0 -54
  79. package/src/domains/creations/domain/entities/index.ts +0 -6
  80. package/src/domains/creations/domain/repositories/ICreationsRepository.ts +0 -25
  81. package/src/domains/creations/domain/repositories/index.ts +0 -5
  82. package/src/domains/creations/domain/services/ICreationsStorageService.ts +0 -13
  83. package/src/domains/creations/domain/value-objects/CreationsConfig.ts +0 -77
  84. package/src/domains/creations/domain/value-objects/index.ts +0 -12
  85. package/src/domains/creations/index.ts +0 -84
  86. package/src/domains/creations/infrastructure/adapters/createRepository.ts +0 -54
  87. package/src/domains/creations/infrastructure/adapters/index.ts +0 -5
  88. package/src/domains/creations/infrastructure/repositories/CreationsRepository.ts +0 -263
  89. package/src/domains/creations/infrastructure/repositories/index.ts +0 -8
  90. package/src/domains/creations/infrastructure/services/CreationsStorageService.ts +0 -48
  91. package/src/domains/creations/presentation/components/CreationCard.tsx +0 -196
  92. package/src/domains/creations/presentation/components/CreationDetail/DetailActions.tsx +0 -76
  93. package/src/domains/creations/presentation/components/CreationDetail/DetailHeader.tsx +0 -81
  94. package/src/domains/creations/presentation/components/CreationDetail/DetailImage.tsx +0 -41
  95. package/src/domains/creations/presentation/components/CreationDetail/DetailStory.tsx +0 -67
  96. package/src/domains/creations/presentation/components/CreationDetail/index.ts +0 -4
  97. package/src/domains/creations/presentation/components/CreationImageViewer.tsx +0 -101
  98. package/src/domains/creations/presentation/components/CreationThumbnail.tsx +0 -63
  99. package/src/domains/creations/presentation/components/CreationsGalleryEmptyState.tsx +0 -77
  100. package/src/domains/creations/presentation/components/CreationsGrid.tsx +0 -87
  101. package/src/domains/creations/presentation/components/CreationsHomeCard.tsx +0 -176
  102. package/src/domains/creations/presentation/components/EmptyState.tsx +0 -75
  103. package/src/domains/creations/presentation/components/FilterBottomSheet.tsx +0 -157
  104. package/src/domains/creations/presentation/components/FilterChips.tsx +0 -105
  105. package/src/domains/creations/presentation/components/GalleryHeader.tsx +0 -157
  106. package/src/domains/creations/presentation/components/index.ts +0 -20
  107. package/src/domains/creations/presentation/hooks/index.ts +0 -9
  108. package/src/domains/creations/presentation/hooks/useCreations.ts +0 -33
  109. package/src/domains/creations/presentation/hooks/useCreationsFilter.ts +0 -90
  110. package/src/domains/creations/presentation/hooks/useDeleteCreation.ts +0 -51
  111. package/src/domains/creations/presentation/hooks/useDeleteMultipleCreations.ts +0 -57
  112. package/src/domains/creations/presentation/hooks/useToggleFavorite.ts +0 -59
  113. package/src/domains/creations/presentation/screens/CreationDetailScreen.tsx +0 -71
  114. package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +0 -264
  115. package/src/domains/creations/presentation/screens/index.ts +0 -5
  116. package/src/domains/creations/presentation/utils/filterUtils.ts +0 -52
  117. package/src/domains/creations/types.d.ts +0 -107
  118. /package/src/{domains/feature-background → features/background}/domain/entities/background.types.ts +0 -0
  119. /package/src/{domains/feature-background → features/background}/domain/entities/component.types.ts +0 -0
  120. /package/src/{domains/feature-background → features/background}/domain/entities/config.types.ts +0 -0
  121. /package/src/{domains/feature-background → features/background}/domain/entities/index.ts +0 -0
  122. /package/src/{domains/feature-background → features/background}/index.ts +0 -0
  123. /package/src/{domains/feature-background → features/background}/infrastructure/constants/index.ts +0 -0
  124. /package/src/{domains/feature-background → features/background}/infrastructure/constants/prompts.constants.ts +0 -0
  125. /package/src/{domains/feature-background → features/background}/presentation/components/FeatureHeader.tsx +0 -0
  126. /package/src/{domains/feature-background → features/background}/presentation/components/GenerateButton.tsx +0 -0
  127. /package/src/{domains/feature-background → features/background}/presentation/components/ImagePicker.tsx +0 -0
  128. /package/src/{domains/feature-background → features/background}/presentation/components/ProcessingModal.tsx +0 -0
  129. /package/src/{domains/feature-background → features/background}/presentation/components/PromptInput.tsx +0 -0
  130. /package/src/{domains/feature-background → features/background}/presentation/components/ResultDisplay.tsx +0 -0
  131. /package/src/{domains/feature-background → features/background}/presentation/components/index.ts +0 -0
  132. /package/src/{domains/feature-background → features/background}/presentation/hooks/index.ts +0 -0
@@ -1,77 +0,0 @@
1
- import React, { useMemo } from "react";
2
- import { View, StyleSheet, ActivityIndicator } from "react-native";
3
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
4
- import { EmptyState } from "./EmptyState";
5
- import type { CreationsConfig } from "../../domain/value-objects/CreationsConfig";
6
-
7
- interface CreationsGalleryEmptyStateProps {
8
- readonly isLoading: boolean;
9
- readonly hasCreations: boolean;
10
- readonly config: CreationsConfig;
11
- readonly t: (key: string) => string;
12
- readonly emptyActionLabel?: string;
13
- readonly onEmptyAction?: () => void;
14
- readonly clearFilters: () => void;
15
- }
16
-
17
- export const CreationsGalleryEmptyState: React.FC<CreationsGalleryEmptyStateProps> = ({
18
- isLoading,
19
- hasCreations,
20
- config,
21
- t,
22
- emptyActionLabel,
23
- onEmptyAction,
24
- clearFilters,
25
- }) => {
26
- const tokens = useAppDesignTokens();
27
- const styles = useStyles(tokens);
28
-
29
- return useMemo(() => {
30
- // 1. Loading State
31
- if (isLoading && !hasCreations) {
32
- return (
33
- <View style={styles.centerContainer}>
34
- <ActivityIndicator size="large" color={tokens.colors.primary} />
35
- </View>
36
- );
37
- }
38
-
39
- // 2. System Empty State (User has NO creations at all)
40
- // We check 'hasCreations' which represents the full list presence
41
- if (!hasCreations) {
42
- return (
43
- <View style={styles.centerContainer}>
44
- <EmptyState
45
- title={t(config.translations.empty)}
46
- description={t(config.translations.emptyDescription)}
47
- actionLabel={emptyActionLabel}
48
- onAction={onEmptyAction}
49
- />
50
- </View>
51
- );
52
- }
53
-
54
- // 3. Filter Empty State (User has creations, but filter returns none)
55
- // This component is rendered when the list is empty, but hasCreations is true.
56
- return (
57
- <View style={styles.centerContainer}>
58
- <EmptyState
59
- title={t("common.no_results") || "No results"}
60
- description={t("common.no_results_description") || "Try changing your filters"}
61
- actionLabel={t("common.clear_all") || "Clear All"}
62
- onAction={clearFilters}
63
- />
64
- </View>
65
- );
66
- }, [isLoading, hasCreations, config, t, emptyActionLabel, onEmptyAction, clearFilters, styles.centerContainer, tokens.colors.primary]);
67
- };
68
-
69
- const useStyles = (tokens: any) => StyleSheet.create({
70
- centerContainer: {
71
- flex: 1,
72
- justifyContent: 'center',
73
- alignItems: 'center',
74
- minHeight: 400,
75
- paddingHorizontal: tokens.spacing.xl
76
- },
77
- });
@@ -1,87 +0,0 @@
1
- import React from 'react';
2
- import { FlatList, RefreshControl, StyleSheet } from 'react-native';
3
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
4
- import type { Creation } from "../../domain/entities/Creation";
5
- import type { CreationType } from "../../domain/value-objects/CreationsConfig";
6
- import { CreationCard } from "./CreationCard";
7
-
8
- interface CreationsGridProps {
9
- readonly creations: Creation[];
10
- readonly types: readonly CreationType[];
11
- readonly isLoading: boolean;
12
- readonly onRefresh: () => void;
13
- readonly onView: (creation: Creation) => void;
14
- readonly onShare: (creation: Creation) => void;
15
- readonly onDelete: (creation: Creation) => void;
16
- readonly onToggleFavorite?: (creation: Creation) => void;
17
- readonly selectedIds?: string[];
18
- readonly onSelect?: (creation: Creation) => void;
19
- readonly isSelectionMode?: boolean;
20
- readonly contentContainerStyle?: any;
21
- readonly ListEmptyComponent?: React.ReactElement | null;
22
- readonly ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null;
23
- }
24
-
25
- export const CreationsGrid: React.FC<CreationsGridProps> = ({
26
- creations,
27
- types,
28
- isLoading,
29
- onRefresh,
30
- onView,
31
- onShare,
32
- onDelete,
33
- onToggleFavorite,
34
- selectedIds = [],
35
- onSelect,
36
- isSelectionMode = false,
37
- contentContainerStyle,
38
- ListEmptyComponent,
39
- ListHeaderComponent,
40
- }) => {
41
- const tokens = useAppDesignTokens();
42
- const styles = useStyles(tokens);
43
-
44
- const renderItem = ({ item }: { item: Creation }) => (
45
- <CreationCard
46
- creation={item}
47
- types={types as CreationType[]}
48
- onView={() => onView(item)}
49
- onShare={() => onShare(item)}
50
- onDelete={() => onDelete(item)}
51
- onToggleFavorite={onToggleFavorite}
52
- isSelected={selectedIds.includes(item.id)}
53
- onSelect={onSelect}
54
- isSelectionMode={isSelectionMode}
55
- />
56
- );
57
-
58
- return (
59
- <FlatList
60
- data={creations}
61
- renderItem={renderItem}
62
- keyExtractor={(item) => item.id}
63
- ListHeaderComponent={ListHeaderComponent}
64
- ListEmptyComponent={ListEmptyComponent}
65
- contentContainerStyle={[
66
- styles.list,
67
- contentContainerStyle,
68
- (!creations || creations.length === 0) && { flexGrow: 1 }
69
- ]}
70
- showsVerticalScrollIndicator={false}
71
- refreshControl={
72
- <RefreshControl
73
- refreshing={isLoading}
74
- onRefresh={onRefresh}
75
- tintColor={tokens.colors.primary}
76
- />
77
- }
78
- />
79
- );
80
- };
81
-
82
- const useStyles = (tokens: any) => StyleSheet.create({
83
- list: {
84
- padding: tokens.spacing.md,
85
- paddingBottom: 100, // Space for fab or bottom tab
86
- },
87
- });
@@ -1,176 +0,0 @@
1
- /**
2
- * CreationsHomeCard Component
3
- * Shows user's creations preview on home screen
4
- */
5
-
6
- declare const __DEV__: boolean;
7
-
8
- import React, { useMemo, useCallback } from "react";
9
- import { View, TouchableOpacity, FlatList, StyleSheet } from "react-native";
10
- import {
11
- AtomicText,
12
- AtomicIcon,
13
- useAppDesignTokens,
14
- } from "@umituz/react-native-design-system";
15
- import type { Creation } from "../../domain/entities/Creation";
16
- import { CreationThumbnail } from "./CreationThumbnail";
17
-
18
- interface CreationsHomeCardProps {
19
- readonly creations: Creation[] | undefined;
20
- readonly isLoading: boolean;
21
- readonly title: string;
22
- readonly countLabel: string;
23
- readonly loadingLabel: string;
24
- readonly maxThumbnails?: number;
25
- readonly onPress: () => void;
26
- }
27
-
28
- export function CreationsHomeCard({
29
- creations,
30
- isLoading,
31
- title,
32
- countLabel,
33
- loadingLabel,
34
- maxThumbnails = 4,
35
- onPress,
36
- }: CreationsHomeCardProps) {
37
- const tokens = useAppDesignTokens();
38
-
39
- if (__DEV__) {
40
- console.log("[CreationsHomeCard] Render:", {
41
- isLoading,
42
- count: creations?.length ?? 0,
43
- });
44
- }
45
-
46
- const styles = useMemo(
47
- () =>
48
- StyleSheet.create({
49
- container: {
50
- backgroundColor: tokens.colors.surface,
51
- borderRadius: tokens.spacing.md,
52
- padding: tokens.spacing.md,
53
- },
54
- header: {
55
- flexDirection: "row",
56
- justifyContent: "space-between",
57
- alignItems: "center",
58
- marginBottom: tokens.spacing.md,
59
- },
60
- headerLeft: {
61
- flexDirection: "row",
62
- alignItems: "center",
63
- gap: tokens.spacing.sm,
64
- },
65
- icon: {
66
- fontSize: 20,
67
- },
68
- title: {
69
- ...tokens.typography.bodyLarge,
70
- fontWeight: "600",
71
- color: tokens.colors.textPrimary,
72
- },
73
- viewAll: {
74
- flexDirection: "row",
75
- alignItems: "center",
76
- gap: tokens.spacing.xs,
77
- },
78
- count: {
79
- ...tokens.typography.bodySmall,
80
- color: tokens.colors.textSecondary,
81
- },
82
- thumbnailList: {
83
- gap: tokens.spacing.sm,
84
- },
85
- loadingText: {
86
- ...tokens.typography.bodySmall,
87
- color: tokens.colors.textSecondary,
88
- textAlign: "center",
89
- padding: tokens.spacing.md,
90
- },
91
- moreBadge: {
92
- width: 72,
93
- height: 72,
94
- borderRadius: tokens.spacing.sm,
95
- backgroundColor: tokens.colors.backgroundSecondary,
96
- justifyContent: "center",
97
- alignItems: "center",
98
- },
99
- moreText: {
100
- ...tokens.typography.bodySmall,
101
- fontWeight: "600",
102
- color: tokens.colors.primary,
103
- },
104
- }),
105
- [tokens],
106
- );
107
-
108
- const displayItems = useMemo(() => {
109
- if (!creations) return [];
110
- return creations.slice(0, maxThumbnails);
111
- }, [creations, maxThumbnails]);
112
-
113
- const renderItem = useCallback(
114
- ({ item, index }: { item: Creation; index: number }) => {
115
- const isLast = index === maxThumbnails - 1;
116
- const hasMore = creations && creations.length > maxThumbnails;
117
-
118
- if (isLast && hasMore) {
119
- return (
120
- <TouchableOpacity style={styles.moreBadge} onPress={onPress}>
121
- <AtomicText style={styles.moreText}>
122
- +{creations.length - maxThumbnails + 1}
123
- </AtomicText>
124
- </TouchableOpacity>
125
- );
126
- }
127
-
128
- return <CreationThumbnail uri={item.uri} onPress={onPress} />;
129
- },
130
- [styles, creations, maxThumbnails, onPress],
131
- );
132
-
133
- if (isLoading) {
134
- return (
135
- <View style={styles.container}>
136
- <AtomicText style={styles.loadingText}>{loadingLabel}</AtomicText>
137
- </View>
138
- );
139
- }
140
-
141
- if (!creations || creations.length === 0) {
142
- return null;
143
- }
144
-
145
- const count = creations.length;
146
-
147
- return (
148
- <TouchableOpacity
149
- style={styles.container}
150
- onPress={onPress}
151
- activeOpacity={0.8}
152
- >
153
- <View style={styles.header}>
154
- <View style={styles.headerLeft}>
155
- <AtomicText style={styles.icon}>🎨</AtomicText>
156
- <AtomicText style={styles.title}>{title}</AtomicText>
157
- </View>
158
- <TouchableOpacity style={styles.viewAll} onPress={onPress}>
159
- <AtomicText style={styles.count}>
160
- {countLabel.replace("{{count}}", String(count))}
161
- </AtomicText>
162
- <AtomicIcon name="chevron-forward" size="sm" color="primary" />
163
- </TouchableOpacity>
164
- </View>
165
- <FlatList
166
- data={displayItems}
167
- renderItem={renderItem}
168
- keyExtractor={(item) => item.id}
169
- horizontal
170
- showsHorizontalScrollIndicator={false}
171
- contentContainerStyle={styles.thumbnailList}
172
- scrollEnabled={false}
173
- />
174
- </TouchableOpacity>
175
- );
176
- }
@@ -1,75 +0,0 @@
1
- /**
2
- * EmptyState Component
3
- * Displays when no creations exist
4
- */
5
-
6
- import React, { useMemo } from "react";
7
- import { View, StyleSheet } from "react-native";
8
- import { AtomicText, AtomicButton, AtomicIcon, useAppDesignTokens } from "@umituz/react-native-design-system";
9
-
10
- interface EmptyStateProps {
11
- readonly title: string;
12
- readonly description: string;
13
- readonly iconName?: string;
14
- readonly actionLabel?: string;
15
- readonly onAction?: () => void;
16
- }
17
-
18
- export function EmptyState({
19
- title,
20
- description,
21
- iconName = "images-outline",
22
- actionLabel,
23
- onAction,
24
- }: EmptyStateProps) {
25
- const tokens = useAppDesignTokens();
26
-
27
- const styles = useMemo(
28
- () =>
29
- StyleSheet.create({
30
- container: {
31
- flex: 1,
32
- justifyContent: "center",
33
- alignItems: "center",
34
- padding: tokens.spacing.xl,
35
- },
36
- iconContainer: {
37
- marginBottom: tokens.spacing.lg,
38
- },
39
- title: {
40
- ...tokens.typography.headingSmall,
41
- color: tokens.colors.textPrimary,
42
- textAlign: "center",
43
- marginBottom: tokens.spacing.sm,
44
- },
45
- description: {
46
- ...tokens.typography.bodyMedium,
47
- color: tokens.colors.textSecondary,
48
- textAlign: "center",
49
- marginBottom: onAction ? tokens.spacing.xl : 0,
50
- },
51
- button: {
52
- minWidth: 160,
53
- },
54
- }),
55
- [tokens, onAction],
56
- );
57
-
58
- return (
59
- <View style={styles.container}>
60
- <View style={styles.iconContainer}>
61
- <AtomicIcon name={iconName} size={64} color="secondary" />
62
- </View>
63
- <AtomicText style={styles.title}>{title}</AtomicText>
64
- <AtomicText style={styles.description}>{description}</AtomicText>
65
- {onAction && actionLabel && (
66
- <AtomicButton
67
- title={actionLabel}
68
- onPress={onAction}
69
- variant="primary"
70
- style={styles.button}
71
- />
72
- )}
73
- </View>
74
- );
75
- }
@@ -1,157 +0,0 @@
1
- import React, { forwardRef, useCallback, useMemo } from 'react';
2
- import { View, StyleSheet, TouchableOpacity, ScrollView } from 'react-native';
3
- import { BottomSheetModal, type BottomSheetModalRef, useAppDesignTokens, AtomicText, AtomicIcon } from '@umituz/react-native-design-system';
4
-
5
- export interface FilterOption {
6
- id: string;
7
- label: string;
8
- icon?: string;
9
- }
10
-
11
- export interface FilterCategory {
12
- id: string;
13
- title: string;
14
- multiSelect?: boolean;
15
- options: FilterOption[];
16
- }
17
-
18
- interface FilterBottomSheetProps {
19
- categories: FilterCategory[];
20
- selectedIds: string[];
21
- onFilterPress: (id: string, categoryId: string) => void;
22
- onClearFilters: () => void;
23
- title: string;
24
- snapPoints?: string[];
25
- }
26
-
27
- export const FilterBottomSheet = forwardRef<BottomSheetModalRef, FilterBottomSheetProps>((props, ref) => {
28
- const { categories, selectedIds, onFilterPress, onClearFilters, title, snapPoints: propSnapPoints } = props;
29
- const tokens = useAppDesignTokens();
30
- const styles = useStyles(tokens);
31
-
32
- const snapPoints = useMemo(() => propSnapPoints || ['50%', '75%'], [propSnapPoints]);
33
-
34
- const renderOption = useCallback((option: FilterOption, category: FilterCategory) => {
35
- const isSelected = selectedIds.includes(option.id);
36
-
37
- return (
38
- <TouchableOpacity
39
- key={option.id}
40
- style={[styles.option, isSelected && styles.optionSelected]}
41
- onPress={() => onFilterPress(option.id, category.id)}
42
- >
43
- <View style={styles.optionContent}>
44
- {option.icon && (
45
- <View style={styles.optionIcon}>
46
- <AtomicIcon
47
- name={option.icon as any}
48
- size="sm"
49
- color={isSelected ? "primary" : "onSurface"}
50
- />
51
- </View>
52
- )}
53
- <AtomicText
54
- style={[styles.optionLabel, isSelected && styles.optionLabelSelected]}
55
- >
56
- {option.label}
57
- </AtomicText>
58
- </View>
59
- {isSelected && (
60
- <AtomicIcon name="check" size="sm" color="primary" />
61
- )}
62
- </TouchableOpacity>
63
- );
64
- }, [onFilterPress, selectedIds, styles]);
65
-
66
- return (
67
- <BottomSheetModal
68
- ref={ref}
69
- snapPoints={snapPoints}
70
- >
71
- <View style={styles.header}>
72
- <AtomicText style={styles.headerTitle}>{title}</AtomicText>
73
- <TouchableOpacity onPress={onClearFilters}>
74
- <AtomicText style={styles.clearButton}>Clear</AtomicText>
75
- </TouchableOpacity>
76
- </View>
77
-
78
- <ScrollView contentContainerStyle={styles.content}>
79
- {categories.map(category => (
80
- <View key={category.id} style={styles.categoryContainer}>
81
- <AtomicText style={styles.categoryTitle}>{category.title}</AtomicText>
82
- <View style={styles.optionsContainer}>
83
- {category.options.map(option => renderOption(option, category))}
84
- </View>
85
- </View>
86
- ))}
87
- </ScrollView>
88
- </BottomSheetModal>
89
- );
90
- });
91
-
92
- const useStyles = (tokens: any) => StyleSheet.create({
93
- content: {
94
- padding: tokens.spacing.md,
95
- paddingBottom: tokens.spacing.xl,
96
- },
97
- header: {
98
- flexDirection: 'row',
99
- justifyContent: 'space-between',
100
- alignItems: 'center',
101
- paddingHorizontal: tokens.spacing.md,
102
- paddingBottom: tokens.spacing.sm,
103
- borderBottomWidth: 1,
104
- borderBottomColor: tokens.colors.outline,
105
- },
106
- headerTitle: {
107
- fontSize: 20,
108
- fontWeight: '700',
109
- color: tokens.colors.textPrimary,
110
- },
111
- clearButton: {
112
- color: tokens.colors.primary,
113
- fontSize: 14,
114
- fontWeight: '600',
115
- },
116
- categoryContainer: {
117
- marginTop: tokens.spacing.md,
118
- },
119
- categoryTitle: {
120
- marginBottom: tokens.spacing.xs,
121
- color: tokens.colors.textSecondary,
122
- fontSize: 16,
123
- fontWeight: '600',
124
- },
125
- optionsContainer: {
126
- backgroundColor: tokens.colors.background,
127
- borderRadius: tokens.borderRadius.md,
128
- overflow: 'hidden',
129
- },
130
- option: {
131
- flexDirection: 'row',
132
- alignItems: 'center',
133
- justifyContent: 'space-between',
134
- padding: tokens.spacing.md,
135
- backgroundColor: tokens.colors.background,
136
- borderBottomWidth: 1,
137
- borderBottomColor: tokens.colors.surface,
138
- },
139
- optionSelected: {
140
- backgroundColor: tokens.colors.surface,
141
- },
142
- optionContent: {
143
- flexDirection: 'row',
144
- alignItems: 'center',
145
- },
146
- optionIcon: {
147
- marginRight: tokens.spacing.sm,
148
- },
149
- optionLabel: {
150
- color: tokens.colors.text,
151
- fontSize: 14,
152
- },
153
- optionLabelSelected: {
154
- color: tokens.colors.primary,
155
- fontWeight: 'bold',
156
- },
157
- });
@@ -1,105 +0,0 @@
1
- /**
2
- * FilterChips Component
3
- * Displays filter chips for creation types
4
- */
5
-
6
- import React, { useMemo } from "react";
7
- import { View, TouchableOpacity, StyleSheet, ScrollView } from "react-native";
8
- import { AtomicText, useAppDesignTokens } from "@umituz/react-native-design-system";
9
- import type { CreationType } from "../../domain/value-objects/CreationsConfig";
10
-
11
- interface FilterChipsProps {
12
- readonly types: readonly CreationType[];
13
- readonly availableTypes: string[];
14
- readonly selectedType: string;
15
- readonly allLabel: string;
16
- readonly onSelect: (type: string) => void;
17
- readonly style?: any;
18
- }
19
-
20
- export function FilterChips({
21
- types,
22
- availableTypes,
23
- selectedType,
24
- allLabel,
25
- onSelect,
26
- style,
27
- }: FilterChipsProps) {
28
- const tokens = useAppDesignTokens();
29
-
30
- const styles = useMemo(
31
- () =>
32
- StyleSheet.create({
33
- container: {
34
- marginBottom: tokens.spacing.md,
35
- },
36
- scrollContent: {
37
- paddingHorizontal: tokens.spacing.md,
38
- gap: tokens.spacing.sm,
39
- flexDirection: "row",
40
- },
41
- chip: {
42
- paddingHorizontal: tokens.spacing.md,
43
- paddingVertical: tokens.spacing.sm,
44
- borderRadius: tokens.spacing.lg,
45
- backgroundColor: tokens.colors.backgroundSecondary,
46
- },
47
- chipSelected: {
48
- backgroundColor: tokens.colors.primary,
49
- },
50
- chipText: {
51
- ...tokens.typography.bodySmall,
52
- color: tokens.colors.textSecondary,
53
- },
54
- chipTextSelected: {
55
- color: tokens.colors.textInverse,
56
- },
57
- }),
58
- [tokens],
59
- );
60
-
61
- const visibleTypes = types.filter((t) => availableTypes.includes(t.id));
62
-
63
- return (
64
- <View style={[styles.container, style]}>
65
- <ScrollView
66
- horizontal
67
- showsHorizontalScrollIndicator={false}
68
- contentContainerStyle={styles.scrollContent}
69
- >
70
- <TouchableOpacity
71
- style={[styles.chip, selectedType === "all" && styles.chipSelected]}
72
- onPress={() => onSelect("all")}
73
- >
74
- <AtomicText
75
- style={[
76
- styles.chipText,
77
- selectedType === "all" && styles.chipTextSelected,
78
- ]}
79
- >
80
- {allLabel}
81
- </AtomicText>
82
- </TouchableOpacity>
83
- {visibleTypes.map((type) => (
84
- <TouchableOpacity
85
- key={type.id}
86
- style={[
87
- styles.chip,
88
- selectedType === type.id && styles.chipSelected,
89
- ]}
90
- onPress={() => onSelect(type.id)}
91
- >
92
- <AtomicText
93
- style={[
94
- styles.chipText,
95
- selectedType === type.id && styles.chipTextSelected,
96
- ]}
97
- >
98
- {type.icon} {type.labelKey}
99
- </AtomicText>
100
- </TouchableOpacity>
101
- ))}
102
- </ScrollView>
103
- </View>
104
- );
105
- }