@umituz/react-native-settings 4.19.6 → 4.20.1
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 +14 -12
- package/src/domains/about/presentation/components/AboutContent.tsx +12 -9
- package/src/domains/about/presentation/components/AboutHeader.tsx +12 -11
- package/src/domains/about/presentation/components/AboutSettingItem.tsx +18 -17
- package/src/domains/about/presentation/screens/AboutScreen.tsx +13 -12
- package/src/domains/appearance/presentation/components/AppearanceHeader.tsx +2 -2
- package/src/domains/appearance/presentation/components/AppearancePreview.tsx +11 -11
- package/src/domains/appearance/presentation/components/ColorPicker.tsx +3 -3
- package/src/domains/appearance/presentation/components/CustomColorsSection.tsx +4 -4
- package/src/domains/appearance/presentation/components/ThemeModeSection.tsx +3 -3
- package/src/domains/appearance/presentation/components/ThemeOption.tsx +20 -20
- package/src/domains/appearance/presentation/screens/AppearanceScreen.tsx +5 -5
- package/src/domains/disclaimer/presentation/components/DisclaimerCard.tsx +15 -15
- package/src/domains/disclaimer/presentation/components/DisclaimerModal.tsx +5 -5
- package/src/domains/disclaimer/presentation/screens/DisclaimerScreen.tsx +9 -9
- package/src/domains/faqs/presentation/components/FAQCategory.tsx +17 -8
- package/src/domains/faqs/presentation/components/FAQEmptyState.tsx +2 -2
- package/src/domains/faqs/presentation/components/FAQItem.tsx +37 -22
- package/src/domains/faqs/presentation/components/FAQSearchBar.tsx +13 -12
- package/src/domains/faqs/presentation/screens/FAQScreen.tsx +38 -28
- package/src/domains/feedback/presentation/components/FeedbackForm.tsx +21 -19
- package/src/domains/feedback/presentation/components/FeedbackModal.tsx +11 -9
- package/src/domains/legal/presentation/screens/LegalScreen.tsx +8 -8
- package/src/domains/legal/presentation/screens/PrivacyPolicyScreen.tsx +15 -12
- package/src/domains/legal/presentation/screens/TermsOfServiceScreen.tsx +15 -12
- package/src/domains/rating/presentation/components/StarRating.tsx +9 -4
- package/src/domains/video-tutorials/index.ts +1 -0
- package/src/domains/video-tutorials/infrastructure/services/video-tutorial.service.ts +2 -2
- package/src/domains/video-tutorials/presentation/components/VideoTutorialCard.tsx +35 -31
- package/src/domains/video-tutorials/presentation/screens/VideoTutorialsScreen.tsx +11 -9
- package/src/presentation/components/DevSettingsSection.tsx +2 -2
- package/src/presentation/components/SettingItem.tsx +2 -2
- package/src/presentation/components/SettingsErrorBoundary.tsx +2 -2
- package/src/presentation/components/SettingsFooter.tsx +2 -2
- package/src/presentation/components/SettingsItemCard.tsx +2 -2
- package/src/presentation/components/SettingsSection.tsx +2 -2
- package/src/presentation/navigation/SettingsStackNavigator.tsx +2 -2
- package/src/presentation/screens/SettingsScreen.tsx +2 -2
- package/src/presentation/screens/components/SettingsContent.tsx +2 -2
- package/src/presentation/screens/components/SettingsHeader.tsx +2 -2
|
@@ -78,38 +78,38 @@ export const DisclaimerCard: React.FC<DisclaimerCardProps> = ({
|
|
|
78
78
|
const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
79
79
|
StyleSheet.create({
|
|
80
80
|
container: {
|
|
81
|
-
paddingHorizontal: tokens.spacing.md,
|
|
82
|
-
paddingVertical: tokens.spacing.md,
|
|
83
|
-
marginHorizontal: tokens.spacing.md,
|
|
84
|
-
marginTop: 8,
|
|
85
|
-
marginBottom: 8,
|
|
86
|
-
borderRadius: 12,
|
|
81
|
+
paddingHorizontal: tokens.spacing.md * tokens.spacingMultiplier,
|
|
82
|
+
paddingVertical: tokens.spacing.md * tokens.spacingMultiplier,
|
|
83
|
+
marginHorizontal: tokens.spacing.md * tokens.spacingMultiplier,
|
|
84
|
+
marginTop: 8 * tokens.spacingMultiplier,
|
|
85
|
+
marginBottom: 8 * tokens.spacingMultiplier,
|
|
86
|
+
borderRadius: 12 * tokens.spacingMultiplier,
|
|
87
87
|
},
|
|
88
88
|
|
|
89
89
|
headerRow: {
|
|
90
90
|
flexDirection: 'row',
|
|
91
91
|
alignItems: 'center',
|
|
92
|
-
marginBottom: 12,
|
|
92
|
+
marginBottom: 12 * tokens.spacingMultiplier,
|
|
93
93
|
},
|
|
94
94
|
|
|
95
95
|
iconContainer: {
|
|
96
|
-
width: 40,
|
|
97
|
-
height: 40,
|
|
98
|
-
borderRadius: 20,
|
|
96
|
+
width: 40 * tokens.spacingMultiplier,
|
|
97
|
+
height: 40 * tokens.spacingMultiplier,
|
|
98
|
+
borderRadius: 20 * tokens.spacingMultiplier,
|
|
99
99
|
alignItems: 'center',
|
|
100
100
|
justifyContent: 'center',
|
|
101
|
-
marginRight: 12,
|
|
101
|
+
marginRight: 12 * tokens.spacingMultiplier,
|
|
102
102
|
},
|
|
103
103
|
|
|
104
104
|
title: {
|
|
105
105
|
flex: 1,
|
|
106
106
|
fontWeight: tokens.typography.labelLarge.fontWeight as any,
|
|
107
|
-
fontSize: tokens.typography.labelLarge.
|
|
107
|
+
fontSize: tokens.typography.labelLarge.responsiveFontSize,
|
|
108
108
|
},
|
|
109
109
|
|
|
110
110
|
shortMessage: {
|
|
111
|
-
lineHeight: 18,
|
|
112
|
-
paddingLeft: 52, // Align with title (40px icon + 12px margin)
|
|
113
|
-
fontSize: 13,
|
|
111
|
+
lineHeight: 18 * tokens.spacingMultiplier,
|
|
112
|
+
paddingLeft: 52 * tokens.spacingMultiplier, // Align with title (40px icon + 12px margin)
|
|
113
|
+
fontSize: 13 * tokens.spacingMultiplier, // Or tokens.typography.bodySmall.responsiveFontSize
|
|
114
114
|
},
|
|
115
115
|
});
|
|
@@ -81,8 +81,8 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
|
81
81
|
flexDirection: 'row',
|
|
82
82
|
justifyContent: 'space-between',
|
|
83
83
|
alignItems: 'center',
|
|
84
|
-
paddingHorizontal: 20,
|
|
85
|
-
paddingVertical: 16,
|
|
84
|
+
paddingHorizontal: 20 * tokens.spacingMultiplier,
|
|
85
|
+
paddingVertical: 16 * tokens.spacingMultiplier,
|
|
86
86
|
borderBottomWidth: 1,
|
|
87
87
|
},
|
|
88
88
|
|
|
@@ -91,11 +91,11 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
|
91
91
|
},
|
|
92
92
|
|
|
93
93
|
modalContentContainer: {
|
|
94
|
-
padding: 20,
|
|
94
|
+
padding: 20 * tokens.spacingMultiplier,
|
|
95
95
|
},
|
|
96
96
|
|
|
97
97
|
modalText: {
|
|
98
|
-
lineHeight: 24,
|
|
99
|
-
fontSize: 15,
|
|
98
|
+
lineHeight: 24 * tokens.spacingMultiplier,
|
|
99
|
+
fontSize: 15 * tokens.spacingMultiplier, // or tokens.typography.bodyMedium.responsiveFontSize
|
|
100
100
|
},
|
|
101
101
|
});
|
|
@@ -68,7 +68,7 @@ export const DisclaimerScreen: React.FC<DisclaimerScreenProps> = ({
|
|
|
68
68
|
},
|
|
69
69
|
]}
|
|
70
70
|
>
|
|
71
|
-
<AtomicIcon name={iconName as any} color="warning" size="
|
|
71
|
+
<AtomicIcon name={iconName as any} color="warning" size="xl" />
|
|
72
72
|
</View>
|
|
73
73
|
</View>
|
|
74
74
|
|
|
@@ -95,27 +95,27 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
|
95
95
|
flex: 1,
|
|
96
96
|
},
|
|
97
97
|
scrollContent: {
|
|
98
|
-
padding: tokens.spacing.lg,
|
|
99
|
-
paddingTop: tokens.spacing.xl,
|
|
98
|
+
padding: tokens.spacing.lg * tokens.spacingMultiplier,
|
|
99
|
+
paddingTop: tokens.spacing.xl * tokens.spacingMultiplier,
|
|
100
100
|
},
|
|
101
101
|
iconHeader: {
|
|
102
102
|
alignItems: 'center',
|
|
103
|
-
marginBottom: tokens.spacing.lg,
|
|
103
|
+
marginBottom: tokens.spacing.lg * tokens.spacingMultiplier,
|
|
104
104
|
},
|
|
105
105
|
iconContainer: {
|
|
106
|
-
width: 72,
|
|
107
|
-
height: 72,
|
|
108
|
-
borderRadius: 36,
|
|
106
|
+
width: 72 * tokens.spacingMultiplier,
|
|
107
|
+
height: 72 * tokens.spacingMultiplier,
|
|
108
|
+
borderRadius: 36 * tokens.spacingMultiplier,
|
|
109
109
|
alignItems: 'center',
|
|
110
110
|
justifyContent: 'center',
|
|
111
111
|
borderWidth: 2,
|
|
112
112
|
},
|
|
113
113
|
title: {
|
|
114
114
|
textAlign: 'center',
|
|
115
|
-
marginBottom: tokens.spacing.lg,
|
|
115
|
+
marginBottom: tokens.spacing.lg * tokens.spacingMultiplier,
|
|
116
116
|
},
|
|
117
117
|
content: {
|
|
118
|
-
lineHeight: 24,
|
|
118
|
+
lineHeight: 24 * tokens.spacingMultiplier,
|
|
119
119
|
textAlign: 'left',
|
|
120
120
|
},
|
|
121
121
|
});
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { useMemo } from 'react';
|
|
8
8
|
import { View, StyleSheet, ViewStyle } from 'react-native';
|
|
9
|
-
import {
|
|
9
|
+
import { useAppDesignTokens, AtomicText } from '@umituz/react-native-design-system';
|
|
10
10
|
import { FAQCategory as FAQCategoryType } from '../../domain/entities/FAQEntity';
|
|
11
11
|
import { FAQItemComponent, FAQItemStyles } from './FAQItem';
|
|
12
12
|
|
|
@@ -29,18 +29,26 @@ export const FAQCategoryComponent: React.FC<FAQCategoryProps> = ({
|
|
|
29
29
|
onToggleItem,
|
|
30
30
|
styles: customStyles,
|
|
31
31
|
}) => {
|
|
32
|
-
const tokens =
|
|
32
|
+
const tokens = useAppDesignTokens();
|
|
33
33
|
|
|
34
34
|
const styles = useMemo(
|
|
35
35
|
() =>
|
|
36
36
|
StyleSheet.create({
|
|
37
37
|
container: {
|
|
38
|
-
marginBottom: tokens.spacing.
|
|
38
|
+
marginBottom: tokens.spacing.xl * tokens.spacingMultiplier,
|
|
39
39
|
},
|
|
40
40
|
titleContainer: {
|
|
41
|
-
marginBottom: tokens.spacing.
|
|
42
|
-
paddingHorizontal: tokens.spacing.
|
|
41
|
+
marginBottom: tokens.spacing.sm * tokens.spacingMultiplier,
|
|
42
|
+
paddingHorizontal: tokens.spacing.lg * tokens.spacingMultiplier,
|
|
43
|
+
flexDirection: 'row',
|
|
44
|
+
alignItems: 'center',
|
|
43
45
|
},
|
|
46
|
+
titleLine: {
|
|
47
|
+
flex: 1,
|
|
48
|
+
height: 1,
|
|
49
|
+
backgroundColor: tokens.colors.border,
|
|
50
|
+
marginLeft: tokens.spacing.md * tokens.spacingMultiplier,
|
|
51
|
+
}
|
|
44
52
|
}),
|
|
45
53
|
[tokens]
|
|
46
54
|
);
|
|
@@ -49,12 +57,13 @@ export const FAQCategoryComponent: React.FC<FAQCategoryProps> = ({
|
|
|
49
57
|
<View style={[styles.container, customStyles?.container]}>
|
|
50
58
|
<View style={styles.titleContainer}>
|
|
51
59
|
<AtomicText
|
|
52
|
-
type="
|
|
53
|
-
color="
|
|
54
|
-
style={customStyles?.titleStyle}
|
|
60
|
+
type="labelLarge"
|
|
61
|
+
color="textSecondary"
|
|
62
|
+
style={[{ textTransform: 'uppercase', letterSpacing: 1, fontWeight: '700' }, customStyles?.titleStyle]}
|
|
55
63
|
>
|
|
56
64
|
{category.title}
|
|
57
65
|
</AtomicText>
|
|
66
|
+
<View style={styles.titleLine} />
|
|
58
67
|
</View>
|
|
59
68
|
{category.items.map((item, index) => (
|
|
60
69
|
<FAQItemComponent
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { useMemo } from 'react';
|
|
8
8
|
import { View, Text, StyleSheet, ViewStyle, TextStyle } from 'react-native';
|
|
9
|
-
import {
|
|
9
|
+
import { useAppDesignTokens, AtomicText } from '@umituz/react-native-design-system';
|
|
10
10
|
|
|
11
11
|
export interface FAQEmptyStateStyles {
|
|
12
12
|
container?: ViewStyle;
|
|
@@ -28,7 +28,7 @@ export const FAQEmptyState: React.FC<FAQEmptyStateProps> = ({
|
|
|
28
28
|
icon = '❓',
|
|
29
29
|
styles: customStyles,
|
|
30
30
|
}) => {
|
|
31
|
-
const tokens =
|
|
31
|
+
const tokens = useAppDesignTokens();
|
|
32
32
|
|
|
33
33
|
const styles = useMemo(
|
|
34
34
|
() =>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { useMemo } from 'react';
|
|
8
8
|
import { View, TouchableOpacity, StyleSheet, ViewStyle } from 'react-native';
|
|
9
|
-
import {
|
|
9
|
+
import { useAppDesignTokens, AtomicText, AtomicIcon } from '@umituz/react-native-design-system';
|
|
10
10
|
import { FAQItem as FAQItemType } from '../../domain/entities/FAQEntity';
|
|
11
11
|
|
|
12
12
|
export interface FAQItemStyles {
|
|
@@ -32,36 +32,49 @@ export const FAQItemComponent: React.FC<FAQItemProps> = ({
|
|
|
32
32
|
onToggle,
|
|
33
33
|
styles: customStyles,
|
|
34
34
|
}) => {
|
|
35
|
-
const tokens =
|
|
35
|
+
const tokens = useAppDesignTokens();
|
|
36
36
|
|
|
37
37
|
const styles = useMemo(
|
|
38
38
|
() =>
|
|
39
39
|
StyleSheet.create({
|
|
40
40
|
container: {
|
|
41
|
-
marginHorizontal: tokens.spacing.md,
|
|
42
|
-
marginBottom: tokens.spacing.
|
|
43
|
-
borderRadius:
|
|
41
|
+
marginHorizontal: tokens.spacing.md * tokens.spacingMultiplier,
|
|
42
|
+
marginBottom: tokens.spacing.sm * tokens.spacingMultiplier,
|
|
43
|
+
borderRadius: 20 * tokens.spacingMultiplier,
|
|
44
44
|
backgroundColor: tokens.colors.surface,
|
|
45
45
|
borderWidth: 1,
|
|
46
|
-
borderColor: tokens.colors.border,
|
|
46
|
+
borderColor: isExpanded ? tokens.colors.primary : tokens.colors.border,
|
|
47
|
+
overflow: 'hidden',
|
|
47
48
|
},
|
|
48
49
|
header: {
|
|
49
|
-
flexDirection: 'row'
|
|
50
|
-
alignItems: 'center'
|
|
51
|
-
padding: tokens.spacing.
|
|
50
|
+
flexDirection: 'row',
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
padding: tokens.spacing.lg * tokens.spacingMultiplier,
|
|
52
53
|
},
|
|
53
54
|
content: {
|
|
54
55
|
flex: 1,
|
|
55
|
-
marginRight: tokens.spacing.
|
|
56
|
+
marginRight: tokens.spacing.md * tokens.spacingMultiplier,
|
|
57
|
+
},
|
|
58
|
+
questionText: {
|
|
59
|
+
fontWeight: '700',
|
|
56
60
|
},
|
|
57
61
|
answerContainer: {
|
|
58
|
-
paddingHorizontal: tokens.spacing.
|
|
59
|
-
paddingBottom: tokens.spacing.
|
|
62
|
+
paddingHorizontal: tokens.spacing.lg * tokens.spacingMultiplier,
|
|
63
|
+
paddingBottom: tokens.spacing.lg * tokens.spacingMultiplier,
|
|
60
64
|
borderTopWidth: 1,
|
|
61
65
|
borderTopColor: tokens.colors.borderLight,
|
|
66
|
+
backgroundColor: tokens.colors.surfaceSecondary || tokens.colors.backgroundSecondary,
|
|
67
|
+
},
|
|
68
|
+
iconContainer: {
|
|
69
|
+
width: 36 * tokens.spacingMultiplier,
|
|
70
|
+
height: 36 * tokens.spacingMultiplier,
|
|
71
|
+
borderRadius: 18 * tokens.spacingMultiplier,
|
|
72
|
+
backgroundColor: isExpanded ? tokens.colors.primary : tokens.colors.surfaceSecondary || tokens.colors.backgroundSecondary,
|
|
73
|
+
alignItems: 'center',
|
|
74
|
+
justifyContent: 'center',
|
|
62
75
|
},
|
|
63
76
|
}),
|
|
64
|
-
[tokens]
|
|
77
|
+
[tokens, isExpanded]
|
|
65
78
|
);
|
|
66
79
|
|
|
67
80
|
return (
|
|
@@ -69,22 +82,24 @@ export const FAQItemComponent: React.FC<FAQItemProps> = ({
|
|
|
69
82
|
<TouchableOpacity
|
|
70
83
|
onPress={onToggle}
|
|
71
84
|
style={[styles.header, customStyles?.header]}
|
|
72
|
-
activeOpacity={0.
|
|
85
|
+
activeOpacity={0.8}
|
|
73
86
|
>
|
|
74
87
|
<View style={[styles.content, customStyles?.content]}>
|
|
75
88
|
<AtomicText
|
|
76
89
|
type="bodyLarge"
|
|
77
|
-
color="textPrimary"
|
|
78
|
-
style={customStyles?.questionStyle}
|
|
79
|
-
numberOfLines={isExpanded ? undefined : 2}
|
|
90
|
+
color={isExpanded ? "primary" : "textPrimary"}
|
|
91
|
+
style={[styles.questionText, customStyles?.questionStyle]}
|
|
80
92
|
>
|
|
81
93
|
{item.question}
|
|
82
94
|
</AtomicText>
|
|
83
95
|
</View>
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
96
|
+
<View style={styles.iconContainer}>
|
|
97
|
+
<AtomicIcon
|
|
98
|
+
name={isExpanded ? 'chevron-up' : 'chevron-down'}
|
|
99
|
+
size={20}
|
|
100
|
+
color={isExpanded ? "onPrimary" : "textSecondary"}
|
|
101
|
+
/>
|
|
102
|
+
</View>
|
|
88
103
|
</TouchableOpacity>
|
|
89
104
|
|
|
90
105
|
{isExpanded && (
|
|
@@ -92,7 +107,7 @@ export const FAQItemComponent: React.FC<FAQItemProps> = ({
|
|
|
92
107
|
<AtomicText
|
|
93
108
|
type="bodyMedium"
|
|
94
109
|
color="textSecondary"
|
|
95
|
-
style={customStyles?.answerStyle}
|
|
110
|
+
style={[{ lineHeight: 22 * tokens.spacingMultiplier }, customStyles?.answerStyle]}
|
|
96
111
|
>
|
|
97
112
|
{item.answer}
|
|
98
113
|
</AtomicText>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { useMemo } from 'react';
|
|
8
8
|
import { View, TextInput, StyleSheet, ViewStyle, TextStyle } from 'react-native';
|
|
9
|
-
import {
|
|
9
|
+
import { useAppDesignTokens, AtomicIcon } from '@umituz/react-native-design-system';
|
|
10
10
|
|
|
11
11
|
export interface FAQSearchBarStyles {
|
|
12
12
|
container?: ViewStyle;
|
|
@@ -26,27 +26,28 @@ export const FAQSearchBar: React.FC<FAQSearchBarProps> = ({
|
|
|
26
26
|
placeholder,
|
|
27
27
|
styles: customStyles,
|
|
28
28
|
}) => {
|
|
29
|
-
const tokens =
|
|
29
|
+
const tokens = useAppDesignTokens();
|
|
30
30
|
|
|
31
31
|
const styles = useMemo(
|
|
32
32
|
() =>
|
|
33
33
|
StyleSheet.create({
|
|
34
34
|
container: {
|
|
35
|
-
flexDirection: 'row'
|
|
36
|
-
alignItems: 'center'
|
|
37
|
-
backgroundColor: tokens.colors.
|
|
38
|
-
borderRadius:
|
|
39
|
-
paddingHorizontal: tokens.spacing.
|
|
35
|
+
flexDirection: 'row',
|
|
36
|
+
alignItems: 'center',
|
|
37
|
+
backgroundColor: tokens.colors.surfaceSecondary || tokens.colors.backgroundSecondary,
|
|
38
|
+
borderRadius: 16 * tokens.spacingMultiplier,
|
|
39
|
+
paddingHorizontal: tokens.spacing.md * tokens.spacingMultiplier,
|
|
40
40
|
borderWidth: 1,
|
|
41
|
-
borderColor: tokens.colors.
|
|
41
|
+
borderColor: tokens.colors.borderLight,
|
|
42
|
+
height: 48 * tokens.spacingMultiplier,
|
|
42
43
|
},
|
|
43
44
|
iconContainer: {
|
|
44
|
-
marginRight: tokens.spacing.
|
|
45
|
+
marginRight: tokens.spacing.sm * tokens.spacingMultiplier,
|
|
45
46
|
},
|
|
46
47
|
input: {
|
|
47
48
|
flex: 1,
|
|
48
|
-
|
|
49
|
-
fontSize:
|
|
49
|
+
height: '100%',
|
|
50
|
+
fontSize: tokens.typography.bodyMedium.responsiveFontSize,
|
|
50
51
|
color: tokens.colors.textPrimary,
|
|
51
52
|
},
|
|
52
53
|
}),
|
|
@@ -56,7 +57,7 @@ export const FAQSearchBar: React.FC<FAQSearchBarProps> = ({
|
|
|
56
57
|
return (
|
|
57
58
|
<View style={[styles.container, customStyles?.container]}>
|
|
58
59
|
<View style={styles.iconContainer}>
|
|
59
|
-
<AtomicIcon name="search" size=
|
|
60
|
+
<AtomicIcon name="search" size="md" color="textSecondary" />
|
|
60
61
|
</View>
|
|
61
62
|
<TextInput
|
|
62
63
|
style={[styles.input, customStyles?.input]}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import React, { useMemo } from 'react';
|
|
8
|
-
import { View, ScrollView, StyleSheet, ViewStyle, TextStyle } from 'react-native';
|
|
9
|
-
import {
|
|
8
|
+
import { View, ScrollView, StyleSheet, ViewStyle, TextStyle, useWindowDimensions } from 'react-native';
|
|
9
|
+
import { useAppDesignTokens, AtomicText, ScreenLayout, getContentMaxWidth } from '@umituz/react-native-design-system';
|
|
10
10
|
import { FAQCategory } from '../../domain/entities/FAQEntity';
|
|
11
11
|
import { useFAQSearch } from '../hooks/useFAQSearch';
|
|
12
12
|
import { useFAQExpansion } from '../hooks/useFAQExpansion';
|
|
@@ -45,9 +45,10 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
45
45
|
renderHeader,
|
|
46
46
|
styles: customStyles,
|
|
47
47
|
}) => {
|
|
48
|
-
const tokens =
|
|
49
|
-
const {
|
|
50
|
-
|
|
48
|
+
const tokens = useAppDesignTokens();
|
|
49
|
+
const { width: windowWidth } = useWindowDimensions();
|
|
50
|
+
const contentMaxWidth = useMemo(() => getContentMaxWidth(windowWidth), [windowWidth]);
|
|
51
|
+
const { searchQuery, setSearchQuery, filteredCategories, hasResults } = useFAQSearch(categories);
|
|
51
52
|
const { isExpanded, toggleExpansion } = useFAQExpansion();
|
|
52
53
|
|
|
53
54
|
const styles = useMemo(
|
|
@@ -55,12 +56,9 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
55
56
|
StyleSheet.create({
|
|
56
57
|
container: {
|
|
57
58
|
flex: 1,
|
|
58
|
-
backgroundColor: tokens.colors.backgroundPrimary,
|
|
59
59
|
},
|
|
60
60
|
header: {
|
|
61
|
-
padding: tokens.spacing.md,
|
|
62
|
-
borderBottomWidth: 1,
|
|
63
|
-
borderBottomColor: tokens.colors.border,
|
|
61
|
+
padding: tokens.spacing.md * tokens.spacingMultiplier,
|
|
64
62
|
},
|
|
65
63
|
content: {
|
|
66
64
|
flex: 1,
|
|
@@ -81,12 +79,13 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
return (
|
|
84
|
-
<
|
|
85
|
-
style={[styles.content, customStyles?.content]}
|
|
86
|
-
showsVerticalScrollIndicator={false}
|
|
87
|
-
>
|
|
82
|
+
<View style={{ flex: 1 }}>
|
|
88
83
|
<View style={[styles.header, customStyles?.header]}>
|
|
89
|
-
<AtomicText
|
|
84
|
+
<AtomicText
|
|
85
|
+
type="headlineMedium"
|
|
86
|
+
color="textPrimary"
|
|
87
|
+
style={{ marginBottom: tokens.spacing.md * tokens.spacingMultiplier, fontWeight: '700' }}
|
|
88
|
+
>
|
|
90
89
|
{headerTitle}
|
|
91
90
|
</AtomicText>
|
|
92
91
|
<FAQSearchBar
|
|
@@ -97,30 +96,41 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
97
96
|
/>
|
|
98
97
|
</View>
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
99
|
+
<ScrollView
|
|
100
|
+
style={[styles.content, customStyles?.content]}
|
|
101
|
+
contentContainerStyle={{ paddingVertical: tokens.spacing.md * tokens.spacingMultiplier }}
|
|
102
|
+
showsVerticalScrollIndicator={false}
|
|
103
|
+
>
|
|
104
|
+
{filteredCategories.map((category) => (
|
|
105
|
+
<FAQCategoryComponent
|
|
106
|
+
key={category.id}
|
|
107
|
+
category={category}
|
|
108
|
+
isExpanded={isExpanded}
|
|
109
|
+
onToggleItem={toggleExpansion}
|
|
110
|
+
styles={customStyles?.category}
|
|
111
|
+
/>
|
|
112
|
+
))}
|
|
113
|
+
<View style={{ height: tokens.spacing.xl * 2 * tokens.spacingMultiplier }} />
|
|
114
|
+
</ScrollView>
|
|
115
|
+
</View>
|
|
110
116
|
);
|
|
111
117
|
};
|
|
112
118
|
|
|
113
119
|
if (renderHeader) {
|
|
114
120
|
return (
|
|
115
|
-
<View style={
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
<View style={{ flex: 1, backgroundColor: tokens.colors.backgroundPrimary }}>
|
|
122
|
+
<View style={[styles.container, customStyles?.container]}>
|
|
123
|
+
<View style={{ alignSelf: 'center', width: '100%', maxWidth: contentMaxWidth }}>
|
|
124
|
+
{renderHeader({ onBack: onBack || (() => { }) })}
|
|
125
|
+
</View>
|
|
126
|
+
{renderContent()}
|
|
127
|
+
</View>
|
|
118
128
|
</View>
|
|
119
129
|
);
|
|
120
130
|
}
|
|
121
131
|
|
|
122
132
|
return (
|
|
123
|
-
<ScreenLayout edges={['bottom']} scrollable={false}>
|
|
133
|
+
<ScreenLayout edges={['bottom']} scrollable={false} maxWidth={contentMaxWidth}>
|
|
124
134
|
<View style={[styles.container, customStyles?.container]}>
|
|
125
135
|
{renderContent()}
|
|
126
136
|
</View>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import React, { useState } from "react";
|
|
7
7
|
import { View, StyleSheet, TouchableOpacity, ScrollView, TextInput } from "react-native";
|
|
8
|
-
import {
|
|
8
|
+
import { useAppDesignTokens, AtomicText, AtomicButton, AtomicIcon } from "@umituz/react-native-design-system";
|
|
9
9
|
import type { FeedbackType, FeedbackRating } from "../../domain/entities/FeedbackEntity";
|
|
10
10
|
import { useFeedbackForm } from "../hooks/useFeedbackForm";
|
|
11
11
|
|
|
@@ -29,7 +29,8 @@ export const FeedbackForm: React.FC<FeedbackFormProps> = ({
|
|
|
29
29
|
initialType,
|
|
30
30
|
isSubmitting = false,
|
|
31
31
|
}) => {
|
|
32
|
-
const tokens =
|
|
32
|
+
const tokens = useAppDesignTokens();
|
|
33
|
+
const styles = getStyles(tokens);
|
|
33
34
|
const [selectedType, setSelectedType] = useState<FeedbackType>(initialType || texts.feedbackTypes[0].type);
|
|
34
35
|
const [rating, setRating] = useState<FeedbackRating>(5);
|
|
35
36
|
const [description, setDescription] = useState("");
|
|
@@ -48,7 +49,7 @@ export const FeedbackForm: React.FC<FeedbackFormProps> = ({
|
|
|
48
49
|
|
|
49
50
|
const renderRating = () => (
|
|
50
51
|
<View style={styles.ratingContainer}>
|
|
51
|
-
<AtomicText type="bodyMedium" style={{ marginBottom: 8, color: tokens.colors.textSecondary }}>
|
|
52
|
+
<AtomicText type="bodyMedium" style={{ marginBottom: 8 * tokens.spacingMultiplier, color: tokens.colors.textSecondary }}>
|
|
52
53
|
{texts.ratingLabel}
|
|
53
54
|
</AtomicText>
|
|
54
55
|
<View style={styles.stars}>
|
|
@@ -60,7 +61,7 @@ export const FeedbackForm: React.FC<FeedbackFormProps> = ({
|
|
|
60
61
|
>
|
|
61
62
|
<AtomicIcon
|
|
62
63
|
name={star <= rating ? "star" : "star-outline"}
|
|
63
|
-
customSize={32}
|
|
64
|
+
customSize={32 * tokens.spacingMultiplier}
|
|
64
65
|
customColor={star <= rating ? tokens.colors.warning : tokens.colors.border}
|
|
65
66
|
/>
|
|
66
67
|
</TouchableOpacity>
|
|
@@ -142,46 +143,47 @@ export const FeedbackForm: React.FC<FeedbackFormProps> = ({
|
|
|
142
143
|
);
|
|
143
144
|
};
|
|
144
145
|
|
|
145
|
-
const
|
|
146
|
+
const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
147
|
+
StyleSheet.create({
|
|
146
148
|
container: {
|
|
147
149
|
width: "100%",
|
|
148
150
|
},
|
|
149
151
|
typeContainer: {
|
|
150
|
-
marginBottom: 24,
|
|
152
|
+
marginBottom: 24 * tokens.spacingMultiplier,
|
|
151
153
|
},
|
|
152
154
|
typeScroll: {
|
|
153
|
-
gap: 8,
|
|
155
|
+
gap: 8 * tokens.spacingMultiplier,
|
|
154
156
|
},
|
|
155
157
|
typeButton: {
|
|
156
158
|
flexDirection: "row",
|
|
157
159
|
alignItems: "center",
|
|
158
|
-
paddingHorizontal: 16,
|
|
159
|
-
paddingVertical: 8,
|
|
160
|
-
borderRadius: 20,
|
|
160
|
+
paddingHorizontal: 16 * tokens.spacingMultiplier,
|
|
161
|
+
paddingVertical: 8 * tokens.spacingMultiplier,
|
|
162
|
+
borderRadius: 20 * tokens.spacingMultiplier,
|
|
161
163
|
borderWidth: 1,
|
|
162
|
-
gap: 6,
|
|
164
|
+
gap: 6 * tokens.spacingMultiplier,
|
|
163
165
|
},
|
|
164
166
|
ratingContainer: {
|
|
165
167
|
alignItems: "center",
|
|
166
|
-
marginBottom: 24,
|
|
168
|
+
marginBottom: 24 * tokens.spacingMultiplier,
|
|
167
169
|
},
|
|
168
170
|
stars: {
|
|
169
171
|
flexDirection: "row",
|
|
170
|
-
gap: 8,
|
|
172
|
+
gap: 8 * tokens.spacingMultiplier,
|
|
171
173
|
},
|
|
172
174
|
starButton: {
|
|
173
|
-
padding: 4,
|
|
175
|
+
padding: 4 * tokens.spacingMultiplier,
|
|
174
176
|
},
|
|
175
177
|
inputContainer: {
|
|
176
|
-
marginBottom: 24,
|
|
178
|
+
marginBottom: 24 * tokens.spacingMultiplier,
|
|
177
179
|
},
|
|
178
180
|
textArea: {
|
|
179
181
|
textAlignVertical: "top",
|
|
180
|
-
minHeight: 120,
|
|
182
|
+
minHeight: 120 * tokens.spacingMultiplier,
|
|
181
183
|
borderWidth: 1,
|
|
182
|
-
borderRadius: 8,
|
|
183
|
-
padding: 12,
|
|
184
|
-
fontSize:
|
|
184
|
+
borderRadius: 8 * tokens.spacingMultiplier,
|
|
185
|
+
padding: 12 * tokens.spacingMultiplier,
|
|
186
|
+
fontSize: tokens.typography.bodyMedium.responsiveFontSize,
|
|
185
187
|
},
|
|
186
188
|
submitButton: {
|
|
187
189
|
width: "100%",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { View, StyleSheet, TouchableOpacity, ScrollView, KeyboardAvoidingView, Platform } from "react-native";
|
|
8
8
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
9
|
-
import {
|
|
9
|
+
import { useAppDesignTokens, AtomicText, AtomicIcon, BaseModal } from "@umituz/react-native-design-system";
|
|
10
10
|
import { FeedbackForm } from "./FeedbackForm";
|
|
11
11
|
import type { FeedbackType, FeedbackRating } from "../../domain/entities/FeedbackEntity";
|
|
12
12
|
|
|
@@ -31,7 +31,8 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({
|
|
|
31
31
|
subtitle,
|
|
32
32
|
texts,
|
|
33
33
|
}) => {
|
|
34
|
-
const tokens =
|
|
34
|
+
const tokens = useAppDesignTokens();
|
|
35
|
+
const styles = getStyles(tokens);
|
|
35
36
|
|
|
36
37
|
return (
|
|
37
38
|
<BaseModal visible={visible} onClose={onClose}>
|
|
@@ -46,7 +47,7 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({
|
|
|
46
47
|
{title}
|
|
47
48
|
</AtomicText>
|
|
48
49
|
{subtitle && (
|
|
49
|
-
<AtomicText type="bodySmall" color="textSecondary" style={{ marginTop: 4 }}>
|
|
50
|
+
<AtomicText type="bodySmall" color="textSecondary" style={{ marginTop: 4 * tokens.spacingMultiplier }}>
|
|
50
51
|
{subtitle}
|
|
51
52
|
</AtomicText>
|
|
52
53
|
)}
|
|
@@ -77,7 +78,8 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({
|
|
|
77
78
|
};
|
|
78
79
|
|
|
79
80
|
|
|
80
|
-
const
|
|
81
|
+
const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
82
|
+
StyleSheet.create({
|
|
81
83
|
safeArea: {
|
|
82
84
|
flex: 1,
|
|
83
85
|
},
|
|
@@ -88,20 +90,20 @@ const styles = StyleSheet.create({
|
|
|
88
90
|
flexDirection: "row",
|
|
89
91
|
justifyContent: "space-between",
|
|
90
92
|
alignItems: "center",
|
|
91
|
-
padding: 16,
|
|
93
|
+
padding: 16 * tokens.spacingMultiplier,
|
|
92
94
|
borderBottomWidth: 1,
|
|
93
95
|
},
|
|
94
96
|
headerText: {
|
|
95
97
|
flex: 1,
|
|
96
98
|
},
|
|
97
99
|
closeButton: {
|
|
98
|
-
width: 36,
|
|
99
|
-
height: 36,
|
|
100
|
-
borderRadius: 18,
|
|
100
|
+
width: 36 * tokens.spacingMultiplier,
|
|
101
|
+
height: 36 * tokens.spacingMultiplier,
|
|
102
|
+
borderRadius: 18 * tokens.spacingMultiplier,
|
|
101
103
|
justifyContent: "center",
|
|
102
104
|
alignItems: "center",
|
|
103
105
|
},
|
|
104
106
|
content: {
|
|
105
|
-
padding: 20,
|
|
107
|
+
padding: 20 * tokens.spacingMultiplier,
|
|
106
108
|
},
|
|
107
109
|
});
|