@modhamanish/rn-mm-template 1.0.1 → 1.0.3
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/MMTemplate/App.tsx +15 -2
- package/MMTemplate/package.json +3 -0
- package/MMTemplate/src/components/AppText.tsx +125 -0
- package/MMTemplate/src/components/CustomToast.tsx +8 -6
- package/MMTemplate/src/components/FeatureItem.tsx +11 -8
- package/MMTemplate/src/components/InfoCard.tsx +10 -6
- package/MMTemplate/src/components/LanguageSwitcher.tsx +8 -7
- package/MMTemplate/src/components/TextInput.tsx +214 -23
- package/MMTemplate/src/components/ThemeSwitcher.tsx +12 -7
- package/MMTemplate/src/context/ThemeContext.tsx +15 -1
- package/MMTemplate/src/locales/en.json +19 -2
- package/MMTemplate/src/locales/hi.json +19 -2
- package/MMTemplate/src/navigation/AppStack.tsx +2 -0
- package/MMTemplate/src/navigation/MainTab.tsx +15 -4
- package/MMTemplate/src/navigation/routes.ts +2 -0
- package/MMTemplate/src/screens/AddNoteScreen.tsx +155 -0
- package/MMTemplate/src/screens/HomeScreen.tsx +60 -33
- package/MMTemplate/src/screens/LoginScreen.tsx +67 -25
- package/MMTemplate/src/screens/NoteScreen.tsx +241 -0
- package/MMTemplate/src/screens/ProfileScreen.tsx +26 -25
- package/MMTemplate/src/screens/SettingsScreen.tsx +17 -16
- package/MMTemplate/src/screens/WelcomeScreen.tsx +23 -23
- package/MMTemplate/src/services/axiosInstance.ts +41 -0
- package/MMTemplate/src/services/note.query.ts +40 -0
- package/MMTemplate/src/services/queryKeys.ts +4 -0
- package/MMTemplate/src/types/components.types.ts +47 -1
- package/MMTemplate/src/types/navigation.types.ts +2 -0
- package/MMTemplate/src/types/services.types.ts +6 -0
- package/MMTemplate/src/utils/storageHelper.ts +2 -0
- package/MMTemplate/src/utils/validationSchemas.ts +6 -0
- package/README.md +1 -1
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from 'react';
|
|
10
10
|
import { darkTheme, lightTheme, ThemeType } from '../theme/Colors';
|
|
11
11
|
import { EdgeInsets, useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
12
|
+
import storageHelper from '../utils/storageHelper';
|
|
12
13
|
|
|
13
14
|
export type ThemeContextType = {
|
|
14
15
|
colors: ThemeType['colors'];
|
|
@@ -31,6 +32,11 @@ export const ThemeProvider: FC<ThemeProviderProps> = ({ children }) => {
|
|
|
31
32
|
lightTheme.colors,
|
|
32
33
|
);
|
|
33
34
|
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const theme = storageHelper.getItem(storageHelper.STORAGE_KEYS.THEME);
|
|
37
|
+
setCurrentTheme(theme === 'dark' ? 'dark' : 'light');
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
34
40
|
useEffect(() => {
|
|
35
41
|
if (currentTheme === 'dark') {
|
|
36
42
|
setColors(darkTheme.colors);
|
|
@@ -40,7 +46,15 @@ export const ThemeProvider: FC<ThemeProviderProps> = ({ children }) => {
|
|
|
40
46
|
}, [currentTheme]);
|
|
41
47
|
|
|
42
48
|
const toggleTheme = useCallback(() => {
|
|
43
|
-
setCurrentTheme(prev =>
|
|
49
|
+
setCurrentTheme(prev => {
|
|
50
|
+
if (prev === 'dark') {
|
|
51
|
+
storageHelper.saveItem(storageHelper.STORAGE_KEYS.THEME, 'light');
|
|
52
|
+
return 'light';
|
|
53
|
+
} else {
|
|
54
|
+
storageHelper.saveItem(storageHelper.STORAGE_KEYS.THEME, 'dark');
|
|
55
|
+
return 'dark';
|
|
56
|
+
}
|
|
57
|
+
});
|
|
44
58
|
}, []);
|
|
45
59
|
|
|
46
60
|
return (
|
|
@@ -15,11 +15,25 @@
|
|
|
15
15
|
"error": "Error",
|
|
16
16
|
"success": "Success",
|
|
17
17
|
"home": "Home",
|
|
18
|
-
"profile": "Profile"
|
|
18
|
+
"profile": "Profile",
|
|
19
|
+
"note": "Note",
|
|
20
|
+
"notes": "Notes",
|
|
21
|
+
"noNotesFound": "No notes found",
|
|
22
|
+
"addNote": "Add Note",
|
|
23
|
+
"searchNotes": "Search notes...",
|
|
24
|
+
"title": "Title",
|
|
25
|
+
"description": "Description",
|
|
26
|
+
"enterTitle": "Enter title",
|
|
27
|
+
"enterDescription": "Enter description",
|
|
28
|
+
"creating": "Creating...",
|
|
29
|
+
"noteCreated": "Note created successfully",
|
|
30
|
+
"titleRequired": "Title is required",
|
|
31
|
+
"descriptionRequired": "Description is required"
|
|
19
32
|
},
|
|
20
33
|
"auth": {
|
|
21
34
|
"welcomeBack": "Welcome Back!",
|
|
22
35
|
"signInToContinue": "Sign in to continue",
|
|
36
|
+
"mockCredentialsHint": "Use the following credentials to login:",
|
|
23
37
|
"email": "Email",
|
|
24
38
|
"password": "Password",
|
|
25
39
|
"enterEmail": "Enter your email",
|
|
@@ -62,7 +76,10 @@
|
|
|
62
76
|
"storageSupport": "Fast Storage",
|
|
63
77
|
"storageDescription": "High-performance persistence with react-native-mmkv",
|
|
64
78
|
"localesDescription": "Translation files for multi-language support.",
|
|
65
|
-
"mockDescription": "Mock data for development and testing."
|
|
79
|
+
"mockDescription": "Mock data for development and testing.",
|
|
80
|
+
"assetsDescription": "Global assets like images, icons, and fonts.",
|
|
81
|
+
"servicesDescription": "API calls and external service integrations.",
|
|
82
|
+
"typesDescription": "TypeScript interfaces and type definitions."
|
|
66
83
|
},
|
|
67
84
|
"settings": {
|
|
68
85
|
"settings": "Settings",
|
|
@@ -15,11 +15,25 @@
|
|
|
15
15
|
"error": "त्रुटि",
|
|
16
16
|
"success": "सफलता",
|
|
17
17
|
"home": "होम",
|
|
18
|
-
"profile": "प्रोफ़ाइल"
|
|
18
|
+
"profile": "प्रोफ़ाइल",
|
|
19
|
+
"note": "नोट",
|
|
20
|
+
"notes": "नोट्स",
|
|
21
|
+
"noNotesFound": "कोई नोट्स नहीं मिले",
|
|
22
|
+
"addNote": "नोट जोड़ें",
|
|
23
|
+
"searchNotes": "नोट्स खोजें...",
|
|
24
|
+
"title": "शीर्षक",
|
|
25
|
+
"description": "विवरण",
|
|
26
|
+
"enterTitle": "शीर्षक दर्ज करें",
|
|
27
|
+
"enterDescription": "विवरण दर्ज करें",
|
|
28
|
+
"creating": "बनाया जा रहा है...",
|
|
29
|
+
"noteCreated": "नोट सफलतापूर्वक बनाया गया",
|
|
30
|
+
"titleRequired": "शीर्षक आवश्यक है",
|
|
31
|
+
"descriptionRequired": "विवरण आवश्यक है"
|
|
19
32
|
},
|
|
20
33
|
"auth": {
|
|
21
34
|
"welcomeBack": "वापसी पर स्वागत है!",
|
|
22
35
|
"signInToContinue": "जारी रखने के लिए साइन इन करें",
|
|
36
|
+
"mockCredentialsHint": "लॉगिन करने के लिए निम्न क्रेडेंशियल का उपयोग करें:",
|
|
23
37
|
"email": "ईमेल",
|
|
24
38
|
"password": "पासवर्ड",
|
|
25
39
|
"enterEmail": "अपना ईमेल दर्ज करें",
|
|
@@ -62,7 +76,10 @@
|
|
|
62
76
|
"storageSupport": "तेज़ स्टोरेज",
|
|
63
77
|
"storageDescription": "react-native-mmkv के साथ उच्च प्रदर्शन दृढ़ता",
|
|
64
78
|
"localesDescription": "बहु-भाषा समर्थन के लिए अनुवाद फ़ाइलें।",
|
|
65
|
-
"mockDescription": "विकास और परीक्षण के लिए मॉक डेटा।"
|
|
79
|
+
"mockDescription": "विकास और परीक्षण के लिए मॉक डेटा।",
|
|
80
|
+
"assetsDescription": "छवियों, आइकन और फोंट जैसे वैश्विक एसेट्स।",
|
|
81
|
+
"servicesDescription": "API कॉल और बाहरी सेवा एकीकरण।",
|
|
82
|
+
"typesDescription": "TypeScript इंटरफेस और टाइप परिभाषाएं।"
|
|
66
83
|
},
|
|
67
84
|
"settings": {
|
|
68
85
|
"settings": "सेटिंग्स",
|
|
@@ -7,6 +7,7 @@ import { AppStackParamList } from '../types/navigation.types';
|
|
|
7
7
|
// Screens
|
|
8
8
|
import MainTab from './MainTab';
|
|
9
9
|
import SettingsScreen from '../screens/SettingsScreen';
|
|
10
|
+
import AddNoteScreen from '../screens/AddNoteScreen';
|
|
10
11
|
|
|
11
12
|
const Stack = createNativeStackNavigator<AppStackParamList>();
|
|
12
13
|
|
|
@@ -20,6 +21,7 @@ const AppStack: FC = () => {
|
|
|
20
21
|
>
|
|
21
22
|
<Stack.Screen name={Routes.MainTab} component={MainTab} />
|
|
22
23
|
<Stack.Screen name={Routes.SettingsScreen} component={SettingsScreen} />
|
|
24
|
+
<Stack.Screen name={Routes.AddNoteScreen} component={AddNoteScreen} />
|
|
23
25
|
</Stack.Navigator>
|
|
24
26
|
);
|
|
25
27
|
};
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import React, { FC } from 'react';
|
|
2
|
-
import
|
|
2
|
+
import AppText from '../components/AppText';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
|
5
5
|
import Routes from './routes';
|
|
6
6
|
import { MainTabParamList } from '../types/navigation.types';
|
|
7
|
+
import { useTheme } from '../context/ThemeContext';
|
|
8
|
+
|
|
9
|
+
// Screens
|
|
7
10
|
import HomeScreen from '../screens/HomeScreen';
|
|
8
11
|
import ProfileScreen from '../screens/ProfileScreen';
|
|
9
|
-
import
|
|
12
|
+
import NoteScreen from '../screens/NoteScreen';
|
|
10
13
|
|
|
11
14
|
const BottomTab = createBottomTabNavigator<MainTabParamList>();
|
|
12
15
|
|
|
@@ -32,7 +35,15 @@ const MainTab: FC = () => {
|
|
|
32
35
|
component={HomeScreen}
|
|
33
36
|
options={{
|
|
34
37
|
tabBarLabel: t('common.home'),
|
|
35
|
-
tabBarIcon: () => <
|
|
38
|
+
tabBarIcon: () => <AppText>🏠</AppText>,
|
|
39
|
+
}}
|
|
40
|
+
/>
|
|
41
|
+
<BottomTab.Screen
|
|
42
|
+
name={Routes.NoteScreen}
|
|
43
|
+
component={NoteScreen}
|
|
44
|
+
options={{
|
|
45
|
+
tabBarLabel: t('common.note'),
|
|
46
|
+
tabBarIcon: () => <AppText>📝</AppText>,
|
|
36
47
|
}}
|
|
37
48
|
/>
|
|
38
49
|
<BottomTab.Screen
|
|
@@ -40,7 +51,7 @@ const MainTab: FC = () => {
|
|
|
40
51
|
component={ProfileScreen}
|
|
41
52
|
options={{
|
|
42
53
|
tabBarLabel: t('common.profile'),
|
|
43
|
-
tabBarIcon: () => <
|
|
54
|
+
tabBarIcon: () => <AppText>👤</AppText>,
|
|
44
55
|
}}
|
|
45
56
|
/>
|
|
46
57
|
</BottomTab.Navigator>
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
StyleSheet,
|
|
4
|
+
View,
|
|
5
|
+
TouchableOpacity,
|
|
6
|
+
ActivityIndicator,
|
|
7
|
+
ScrollView,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import AppText from '../components/AppText';
|
|
10
|
+
import { useTranslation } from 'react-i18next';
|
|
11
|
+
import { useTheme } from '../context/ThemeContext';
|
|
12
|
+
import { ThemeType } from '../theme/Colors';
|
|
13
|
+
import FullScreenContainer from '../components/FullScreenContainer';
|
|
14
|
+
import TextInput from '../components/TextInput';
|
|
15
|
+
import AnimationView from '../components/AnimationView';
|
|
16
|
+
import { useAddNoteMutation } from '../services/note.query';
|
|
17
|
+
import { goBack } from '../utils/navigationUtils';
|
|
18
|
+
import { useFormik } from 'formik';
|
|
19
|
+
import { NoteSchema } from '../utils/validationSchemas';
|
|
20
|
+
|
|
21
|
+
const AddNoteScreen: FC = () => {
|
|
22
|
+
const { t } = useTranslation();
|
|
23
|
+
const theme = useTheme();
|
|
24
|
+
const styles = getStyles(theme);
|
|
25
|
+
|
|
26
|
+
const { mutate: addNote, isPending } = useAddNoteMutation();
|
|
27
|
+
|
|
28
|
+
const formik = useFormik({
|
|
29
|
+
initialValues: {
|
|
30
|
+
title: '',
|
|
31
|
+
description: '',
|
|
32
|
+
},
|
|
33
|
+
validationSchema: NoteSchema,
|
|
34
|
+
onSubmit: values => {
|
|
35
|
+
addNote(values);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const { values, errors, touched, handleChange, handleBlur, handleSubmit } =
|
|
40
|
+
formik;
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<FullScreenContainer style={styles.container}>
|
|
44
|
+
<View style={styles.header}>
|
|
45
|
+
<TouchableOpacity style={styles.backButton} onPress={() => goBack()}>
|
|
46
|
+
<AppText size="xlarge" style={styles.backIcon}>
|
|
47
|
+
←
|
|
48
|
+
</AppText>
|
|
49
|
+
</TouchableOpacity>
|
|
50
|
+
<AppText variant="h3" style={styles.headerTitle}>
|
|
51
|
+
{t('common.addNote')}
|
|
52
|
+
</AppText>
|
|
53
|
+
<View style={{ width: 40 }} />
|
|
54
|
+
</View>
|
|
55
|
+
|
|
56
|
+
<ScrollView contentContainerStyle={styles.content}>
|
|
57
|
+
<AnimationView animType="FadeIn" duration={500}>
|
|
58
|
+
<TextInput
|
|
59
|
+
label={t('common.title')}
|
|
60
|
+
placeholder={t('common.enterTitle')}
|
|
61
|
+
value={values.title}
|
|
62
|
+
onChangeText={handleChange('title')}
|
|
63
|
+
onBlur={handleBlur('title')}
|
|
64
|
+
error={errors.title}
|
|
65
|
+
touched={touched.title}
|
|
66
|
+
/>
|
|
67
|
+
|
|
68
|
+
<TextInput
|
|
69
|
+
label={t('common.description')}
|
|
70
|
+
placeholder={t('common.enterDescription')}
|
|
71
|
+
value={values.description}
|
|
72
|
+
onChangeText={handleChange('description')}
|
|
73
|
+
onBlur={handleBlur('description')}
|
|
74
|
+
error={errors.description}
|
|
75
|
+
touched={touched.description}
|
|
76
|
+
multiline
|
|
77
|
+
numberOfLines={10}
|
|
78
|
+
style={styles.textArea}
|
|
79
|
+
/>
|
|
80
|
+
|
|
81
|
+
<TouchableOpacity
|
|
82
|
+
style={[styles.saveButton, isPending && styles.saveButtonDisabled]}
|
|
83
|
+
onPress={() => handleSubmit()}
|
|
84
|
+
disabled={isPending}
|
|
85
|
+
activeOpacity={0.8}
|
|
86
|
+
>
|
|
87
|
+
{isPending ? (
|
|
88
|
+
<ActivityIndicator color={theme.colors.white} />
|
|
89
|
+
) : (
|
|
90
|
+
<AppText variant="bold" size={18} style={styles.saveButtonText}>
|
|
91
|
+
{t('common.save')}
|
|
92
|
+
</AppText>
|
|
93
|
+
)}
|
|
94
|
+
</TouchableOpacity>
|
|
95
|
+
</AnimationView>
|
|
96
|
+
</ScrollView>
|
|
97
|
+
</FullScreenContainer>
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export default AddNoteScreen;
|
|
102
|
+
|
|
103
|
+
const getStyles = ({ colors }: ThemeType) =>
|
|
104
|
+
StyleSheet.create({
|
|
105
|
+
container: {
|
|
106
|
+
flex: 1,
|
|
107
|
+
backgroundColor: colors.backgroundColor,
|
|
108
|
+
},
|
|
109
|
+
header: {
|
|
110
|
+
flexDirection: 'row',
|
|
111
|
+
alignItems: 'center',
|
|
112
|
+
justifyContent: 'space-between',
|
|
113
|
+
paddingHorizontal: 16,
|
|
114
|
+
paddingVertical: 12,
|
|
115
|
+
borderBottomWidth: 1,
|
|
116
|
+
borderBottomColor: colors.textColor + '10',
|
|
117
|
+
},
|
|
118
|
+
backButton: {
|
|
119
|
+
width: 40,
|
|
120
|
+
height: 40,
|
|
121
|
+
justifyContent: 'center',
|
|
122
|
+
alignItems: 'center',
|
|
123
|
+
},
|
|
124
|
+
backIcon: {
|
|
125
|
+
color: colors.textColor,
|
|
126
|
+
},
|
|
127
|
+
headerTitle: {
|
|
128
|
+
color: colors.textColor,
|
|
129
|
+
},
|
|
130
|
+
content: {
|
|
131
|
+
padding: 20,
|
|
132
|
+
},
|
|
133
|
+
textArea: {
|
|
134
|
+
height: 150,
|
|
135
|
+
textAlignVertical: 'top',
|
|
136
|
+
},
|
|
137
|
+
saveButton: {
|
|
138
|
+
backgroundColor: colors.primary,
|
|
139
|
+
borderRadius: 12,
|
|
140
|
+
padding: 16,
|
|
141
|
+
alignItems: 'center',
|
|
142
|
+
marginTop: 24,
|
|
143
|
+
shadowColor: colors.primary,
|
|
144
|
+
shadowOffset: { width: 0, height: 4 },
|
|
145
|
+
shadowOpacity: 0.3,
|
|
146
|
+
shadowRadius: 8,
|
|
147
|
+
elevation: 5,
|
|
148
|
+
},
|
|
149
|
+
saveButtonDisabled: {
|
|
150
|
+
opacity: 0.6,
|
|
151
|
+
},
|
|
152
|
+
saveButtonText: {
|
|
153
|
+
color: colors.white,
|
|
154
|
+
},
|
|
155
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Image, StyleSheet,
|
|
1
|
+
import { Image, StyleSheet, View, ScrollView } from 'react-native';
|
|
2
|
+
import AppText from '../components/AppText';
|
|
2
3
|
import React, { FC } from 'react';
|
|
3
4
|
import { useTranslation } from 'react-i18next';
|
|
4
5
|
import FullScreenContainer from '../components/FullScreenContainer';
|
|
@@ -33,10 +34,10 @@ const HomeScreen: FC = () => {
|
|
|
33
34
|
/>
|
|
34
35
|
</AnimationView>
|
|
35
36
|
<AnimationView delay={400} animType="SlideInDown" duration={800}>
|
|
36
|
-
<
|
|
37
|
+
<AppText variant="h2" style={styles.welcomeText}>
|
|
37
38
|
{t('home.welcomeToTemplate')}
|
|
38
|
-
</
|
|
39
|
-
<
|
|
39
|
+
</AppText>
|
|
40
|
+
<AppText style={styles.subtitle}>{t('home.subtitle')}</AppText>
|
|
40
41
|
</AnimationView>
|
|
41
42
|
</View>
|
|
42
43
|
</AnimationView>
|
|
@@ -44,15 +45,23 @@ const HomeScreen: FC = () => {
|
|
|
44
45
|
{/* Quick Start Section */}
|
|
45
46
|
<AnimationView delay={600} animType="FadeIn" duration={800}>
|
|
46
47
|
<InfoCard title={`🚀 ${t('home.quickStart')}`} icon="">
|
|
47
|
-
<
|
|
48
|
+
<AppText style={styles.cardText}>
|
|
49
|
+
{t('home.quickStartDesc')}
|
|
50
|
+
</AppText>
|
|
48
51
|
<View style={styles.codeBlock}>
|
|
49
|
-
<
|
|
52
|
+
<AppText size={13} style={styles.codeText}>
|
|
53
|
+
yarn install
|
|
54
|
+
</AppText>
|
|
50
55
|
</View>
|
|
51
56
|
<View style={styles.codeBlock}>
|
|
52
|
-
<
|
|
57
|
+
<AppText size={13} style={styles.codeText}>
|
|
58
|
+
cd ios && pod install
|
|
59
|
+
</AppText>
|
|
53
60
|
</View>
|
|
54
61
|
<View style={styles.codeBlock}>
|
|
55
|
-
<
|
|
62
|
+
<AppText size={13} style={styles.codeText}>
|
|
63
|
+
yarn ios / yarn android
|
|
64
|
+
</AppText>
|
|
56
65
|
</View>
|
|
57
66
|
</InfoCard>
|
|
58
67
|
</AnimationView>
|
|
@@ -100,6 +109,21 @@ const HomeScreen: FC = () => {
|
|
|
100
109
|
title="context/"
|
|
101
110
|
description="React Context for global state management."
|
|
102
111
|
/>
|
|
112
|
+
<FeatureItem
|
|
113
|
+
icon="🖼️"
|
|
114
|
+
title="assets/"
|
|
115
|
+
description={t('home.assetsDescription')}
|
|
116
|
+
/>
|
|
117
|
+
<FeatureItem
|
|
118
|
+
icon="⚡"
|
|
119
|
+
title="services/"
|
|
120
|
+
description={t('home.servicesDescription')}
|
|
121
|
+
/>
|
|
122
|
+
<FeatureItem
|
|
123
|
+
icon="🏷️"
|
|
124
|
+
title="types/"
|
|
125
|
+
description={t('home.typesDescription')}
|
|
126
|
+
/>
|
|
103
127
|
</InfoCard>
|
|
104
128
|
</AnimationView>
|
|
105
129
|
|
|
@@ -183,33 +207,45 @@ const HomeScreen: FC = () => {
|
|
|
183
207
|
{/* Next Steps Section */}
|
|
184
208
|
<AnimationView delay={1400} animType="FadeIn" duration={800}>
|
|
185
209
|
<InfoCard title={`🎯 ${t('home.nextSteps')}`} icon="">
|
|
186
|
-
<
|
|
210
|
+
<AppText style={styles.cardText}>
|
|
187
211
|
1. Customize the theme in{' '}
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
212
|
+
<AppText variant="semiBold" style={styles.highlight}>
|
|
213
|
+
theme/Colors.ts
|
|
214
|
+
</AppText>
|
|
215
|
+
</AppText>
|
|
216
|
+
<AppText style={styles.cardText}>
|
|
191
217
|
2. Add your screens in{' '}
|
|
192
|
-
<
|
|
193
|
-
|
|
194
|
-
|
|
218
|
+
<AppText variant="semiBold" style={styles.highlight}>
|
|
219
|
+
screens/
|
|
220
|
+
</AppText>
|
|
221
|
+
</AppText>
|
|
222
|
+
<AppText style={styles.cardText}>
|
|
195
223
|
3. Update navigation in{' '}
|
|
196
|
-
<
|
|
197
|
-
|
|
198
|
-
|
|
224
|
+
<AppText variant="semiBold" style={styles.highlight}>
|
|
225
|
+
navigation/
|
|
226
|
+
</AppText>
|
|
227
|
+
</AppText>
|
|
228
|
+
<AppText style={styles.cardText}>
|
|
199
229
|
4. Create reusable components in{' '}
|
|
200
|
-
<
|
|
201
|
-
|
|
202
|
-
|
|
230
|
+
<AppText variant="semiBold" style={styles.highlight}>
|
|
231
|
+
components/
|
|
232
|
+
</AppText>
|
|
233
|
+
</AppText>
|
|
234
|
+
<AppText style={styles.cardText}>
|
|
203
235
|
5. Configure your app name and bundle ID
|
|
204
|
-
</
|
|
236
|
+
</AppText>
|
|
205
237
|
</InfoCard>
|
|
206
238
|
</AnimationView>
|
|
207
239
|
|
|
208
240
|
{/* Footer */}
|
|
209
241
|
<AnimationView delay={1600} animType="FadeIn" duration={800}>
|
|
210
242
|
<View style={styles.footer}>
|
|
211
|
-
<
|
|
212
|
-
|
|
243
|
+
<AppText variant="semiBold" size={18} style={styles.footerText}>
|
|
244
|
+
{t('home.happyCoding')}
|
|
245
|
+
</AppText>
|
|
246
|
+
<AppText size={13} style={styles.footerSubtext}>
|
|
247
|
+
{t('home.builtWith')}
|
|
248
|
+
</AppText>
|
|
213
249
|
</View>
|
|
214
250
|
</AnimationView>
|
|
215
251
|
</ScrollView>
|
|
@@ -241,19 +277,15 @@ const getStyles = ({ colors }: ThemeType) =>
|
|
|
241
277
|
marginBottom: 16,
|
|
242
278
|
},
|
|
243
279
|
welcomeText: {
|
|
244
|
-
fontSize: 24,
|
|
245
|
-
fontWeight: '700',
|
|
246
280
|
color: colors.textColor,
|
|
247
281
|
textAlign: 'center',
|
|
248
282
|
marginBottom: 8,
|
|
249
283
|
},
|
|
250
284
|
subtitle: {
|
|
251
|
-
fontSize: 14,
|
|
252
285
|
color: colors.textColor + 'CC',
|
|
253
286
|
textAlign: 'center',
|
|
254
287
|
},
|
|
255
288
|
cardText: {
|
|
256
|
-
fontSize: 14,
|
|
257
289
|
color: colors.textColor,
|
|
258
290
|
lineHeight: 20,
|
|
259
291
|
marginBottom: 8,
|
|
@@ -268,12 +300,10 @@ const getStyles = ({ colors }: ThemeType) =>
|
|
|
268
300
|
},
|
|
269
301
|
codeText: {
|
|
270
302
|
fontFamily: 'monospace',
|
|
271
|
-
fontSize: 13,
|
|
272
303
|
color: colors.textColor,
|
|
273
304
|
},
|
|
274
305
|
highlight: {
|
|
275
306
|
color: colors.primary,
|
|
276
|
-
fontWeight: '600',
|
|
277
307
|
fontFamily: 'monospace',
|
|
278
308
|
},
|
|
279
309
|
footer: {
|
|
@@ -284,13 +314,10 @@ const getStyles = ({ colors }: ThemeType) =>
|
|
|
284
314
|
borderTopColor: colors.textColor + '20',
|
|
285
315
|
},
|
|
286
316
|
footerText: {
|
|
287
|
-
fontSize: 18,
|
|
288
|
-
fontWeight: '600',
|
|
289
317
|
color: colors.primary,
|
|
290
318
|
marginBottom: 4,
|
|
291
319
|
},
|
|
292
320
|
footerSubtext: {
|
|
293
|
-
fontSize: 13,
|
|
294
321
|
color: colors.textColor + 'CC',
|
|
295
322
|
},
|
|
296
323
|
});
|