@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
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
StyleSheet,
|
|
3
|
-
Text,
|
|
4
|
-
TouchableOpacity,
|
|
5
|
-
View,
|
|
6
|
-
Linking,
|
|
7
|
-
} from 'react-native';
|
|
1
|
+
import { StyleSheet, TouchableOpacity, View, Linking } from 'react-native';
|
|
8
2
|
import React, { FC, useEffect } from 'react';
|
|
9
3
|
import { useTranslation } from 'react-i18next';
|
|
10
4
|
import { ThemeContextType, useTheme } from '../context/ThemeContext';
|
|
@@ -21,6 +15,7 @@ import { mobileScreenHeight, mobileScreenWidth } from '../utils/utilsHelper';
|
|
|
21
15
|
import FullScreenContainer from '../components/FullScreenContainer';
|
|
22
16
|
import { navigate } from '../utils/navigationUtils';
|
|
23
17
|
import Routes from '../navigation/routes';
|
|
18
|
+
import AppText from '../components/AppText';
|
|
24
19
|
|
|
25
20
|
const WelcomeScreen: FC = () => {
|
|
26
21
|
const theme = useTheme();
|
|
@@ -83,14 +78,20 @@ const WelcomeScreen: FC = () => {
|
|
|
83
78
|
</View>
|
|
84
79
|
|
|
85
80
|
<Animated.View style={[styles.contentContainer, { opacity }]}>
|
|
86
|
-
<
|
|
87
|
-
<
|
|
81
|
+
<AppText style={styles.titleText}>
|
|
82
|
+
<AppText variant="bold" size="xxlarge" style={styles.titleBoldText}>
|
|
83
|
+
{t('welcome.titleBold')}
|
|
84
|
+
</AppText>
|
|
88
85
|
{t('welcome.titleText')}
|
|
89
|
-
</
|
|
90
|
-
<
|
|
86
|
+
</AppText>
|
|
87
|
+
<AppText variant="h1" size={36} style={styles.matchBoldText}>
|
|
88
|
+
{t('welcome.appName')}
|
|
89
|
+
</AppText>
|
|
91
90
|
|
|
92
91
|
<Animated.View style={[styles.infoContainer, animatedContentStyle]}>
|
|
93
|
-
<
|
|
92
|
+
<AppText variant="body1" style={styles.subtitleText}>
|
|
93
|
+
{t('welcome.subtitle')}
|
|
94
|
+
</AppText>
|
|
94
95
|
</Animated.View>
|
|
95
96
|
|
|
96
97
|
<FullScreenContainer
|
|
@@ -103,9 +104,13 @@ const WelcomeScreen: FC = () => {
|
|
|
103
104
|
style={styles.githubButton}
|
|
104
105
|
activeOpacity={0.8}
|
|
105
106
|
>
|
|
106
|
-
<
|
|
107
|
+
<AppText
|
|
108
|
+
variant="semiBold"
|
|
109
|
+
size={15}
|
|
110
|
+
style={styles.githubButtonText}
|
|
111
|
+
>
|
|
107
112
|
📦 {t('welcome.githubButton')}
|
|
108
|
-
</
|
|
113
|
+
</AppText>
|
|
109
114
|
</TouchableOpacity>
|
|
110
115
|
|
|
111
116
|
<TouchableOpacity
|
|
@@ -113,7 +118,9 @@ const WelcomeScreen: FC = () => {
|
|
|
113
118
|
style={styles.button}
|
|
114
119
|
activeOpacity={0.8}
|
|
115
120
|
>
|
|
116
|
-
<
|
|
121
|
+
<AppText variant="bold" size={18} style={styles.buttonText}>
|
|
122
|
+
{t('welcome.loginButton')}
|
|
123
|
+
</AppText>
|
|
117
124
|
</TouchableOpacity>
|
|
118
125
|
</FullScreenContainer>
|
|
119
126
|
</Animated.View>
|
|
@@ -150,13 +157,11 @@ const getStyles = ({ colors }: ThemeContextType) =>
|
|
|
150
157
|
fontSize: 32,
|
|
151
158
|
},
|
|
152
159
|
titleBoldText: {
|
|
153
|
-
|
|
160
|
+
color: colors.white,
|
|
154
161
|
},
|
|
155
162
|
matchBoldText: {
|
|
156
163
|
color: colors.white,
|
|
157
|
-
fontWeight: '800',
|
|
158
164
|
textAlign: 'center',
|
|
159
|
-
fontSize: 36,
|
|
160
165
|
marginTop: 4,
|
|
161
166
|
},
|
|
162
167
|
infoContainer: {
|
|
@@ -165,7 +170,6 @@ const getStyles = ({ colors }: ThemeContextType) =>
|
|
|
165
170
|
},
|
|
166
171
|
subtitleText: {
|
|
167
172
|
color: colors.white + 'CC',
|
|
168
|
-
fontSize: 16,
|
|
169
173
|
textAlign: 'center',
|
|
170
174
|
lineHeight: 24,
|
|
171
175
|
},
|
|
@@ -190,8 +194,6 @@ const getStyles = ({ colors }: ThemeContextType) =>
|
|
|
190
194
|
},
|
|
191
195
|
githubButtonText: {
|
|
192
196
|
color: colors.white,
|
|
193
|
-
fontSize: 15,
|
|
194
|
-
fontWeight: '600',
|
|
195
197
|
},
|
|
196
198
|
button: {
|
|
197
199
|
alignSelf: 'center',
|
|
@@ -208,8 +210,6 @@ const getStyles = ({ colors }: ThemeContextType) =>
|
|
|
208
210
|
},
|
|
209
211
|
buttonText: {
|
|
210
212
|
color: colors.textColor,
|
|
211
|
-
fontSize: 18,
|
|
212
213
|
textAlign: 'center',
|
|
213
|
-
fontWeight: '700',
|
|
214
214
|
},
|
|
215
215
|
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import axios, { AxiosResponse, AxiosRequestConfig } from 'axios';
|
|
3
|
+
import Routes from '../navigation/routes';
|
|
4
|
+
import storageHelper from '../utils/storageHelper';
|
|
5
|
+
import { resetAndNavigate } from '../utils/navigationUtils';
|
|
6
|
+
|
|
7
|
+
const axiosInstance = axios.create({
|
|
8
|
+
baseURL: 'https://user-driven-mock-api-generator-serv.vercel.app/man',
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const ResponseInterceptor = (response: AxiosResponse) => {
|
|
12
|
+
return response;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const RequestInterceptor = (config: AxiosRequestConfig | any) => {
|
|
16
|
+
const token = storageHelper.getItem(storageHelper.STORAGE_KEYS.AUTH_TOKEN);
|
|
17
|
+
config.headers.device = Platform.OS;
|
|
18
|
+
|
|
19
|
+
if (token) {
|
|
20
|
+
config.headers.Authorization = `Bearer ${token}`;
|
|
21
|
+
}
|
|
22
|
+
return config;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
axiosInstance.interceptors.request.use(RequestInterceptor);
|
|
26
|
+
|
|
27
|
+
axiosInstance.interceptors.response.use(ResponseInterceptor, error => {
|
|
28
|
+
if (error.response) {
|
|
29
|
+
if (error.response.status === 403) {
|
|
30
|
+
// Unauthorized
|
|
31
|
+
resetAndNavigate(Routes.AuthStack);
|
|
32
|
+
}
|
|
33
|
+
return Promise.reject(error);
|
|
34
|
+
} else if (error.request) {
|
|
35
|
+
return Promise.reject(error);
|
|
36
|
+
} else {
|
|
37
|
+
return Promise.reject(error);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export { axiosInstance };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
2
|
+
import { QUERY_KEY } from './queryKeys';
|
|
3
|
+
import { axiosInstance } from './axiosInstance';
|
|
4
|
+
import { GetNotesResponse, Note } from '../types/services.types';
|
|
5
|
+
import Toast from 'react-native-toast-message';
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
7
|
+
import { goBack } from '../utils/navigationUtils';
|
|
8
|
+
|
|
9
|
+
export const useGetNotesQuery = () => {
|
|
10
|
+
return useQuery({
|
|
11
|
+
queryKey: [QUERY_KEY.GET_NOTES],
|
|
12
|
+
queryFn: async () => {
|
|
13
|
+
const response = await axiosInstance.get<GetNotesResponse>('/notes');
|
|
14
|
+
if (response.status === 200) {
|
|
15
|
+
return response.data;
|
|
16
|
+
}
|
|
17
|
+
throw new Error('Something went wrong');
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const useAddNoteMutation = () => {
|
|
23
|
+
const queryClient = useQueryClient();
|
|
24
|
+
const { t } = useTranslation();
|
|
25
|
+
return useMutation({
|
|
26
|
+
mutationFn: async (note: Omit<Note, 'id'>) => {
|
|
27
|
+
const response = await axiosInstance.post<Note>('/notes', note);
|
|
28
|
+
return response.data;
|
|
29
|
+
},
|
|
30
|
+
onSuccess: () => {
|
|
31
|
+
queryClient.invalidateQueries({ queryKey: [QUERY_KEY.GET_NOTES] });
|
|
32
|
+
Toast.show({
|
|
33
|
+
type: 'success',
|
|
34
|
+
text1: t('common.success'),
|
|
35
|
+
text2: t('common.noteCreated'),
|
|
36
|
+
});
|
|
37
|
+
goBack();
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -1,7 +1,53 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
StatusBarStyle,
|
|
4
|
+
StyleProp,
|
|
5
|
+
TextProps,
|
|
6
|
+
TextStyle,
|
|
7
|
+
ViewStyle,
|
|
8
|
+
} from 'react-native';
|
|
3
9
|
import { Edges } from 'react-native-safe-area-context';
|
|
4
10
|
|
|
11
|
+
export type AppTextSize =
|
|
12
|
+
| 'xxsmall' // 8
|
|
13
|
+
| 'xsmall' // 10
|
|
14
|
+
| 'small' // 12
|
|
15
|
+
| 'normal' // 14
|
|
16
|
+
| 'body' // 16
|
|
17
|
+
| 'large' // 20
|
|
18
|
+
| 'xlarge' // 24
|
|
19
|
+
| 'xxlarge' // 32
|
|
20
|
+
| number;
|
|
21
|
+
|
|
22
|
+
export type AppTextVariant =
|
|
23
|
+
| 'h1'
|
|
24
|
+
| 'h2'
|
|
25
|
+
| 'h3'
|
|
26
|
+
| 'body1'
|
|
27
|
+
| 'body2'
|
|
28
|
+
| 'caption'
|
|
29
|
+
| 'bold'
|
|
30
|
+
| 'semiBold'
|
|
31
|
+
| 'medium'
|
|
32
|
+
| 'regular'
|
|
33
|
+
| 'light';
|
|
34
|
+
|
|
35
|
+
export type AppTextTransform =
|
|
36
|
+
| 'uppercase'
|
|
37
|
+
| 'lowercase'
|
|
38
|
+
| 'capitalize'
|
|
39
|
+
| 'none';
|
|
40
|
+
|
|
41
|
+
export type AppTextProps = TextProps & {
|
|
42
|
+
children?: ReactNode;
|
|
43
|
+
size?: AppTextSize;
|
|
44
|
+
variant?: AppTextVariant;
|
|
45
|
+
color?: string;
|
|
46
|
+
fontFamily?: string;
|
|
47
|
+
transform?: AppTextTransform;
|
|
48
|
+
style?: StyleProp<TextStyle>;
|
|
49
|
+
};
|
|
50
|
+
|
|
5
51
|
export type FullScreenContainerProps = {
|
|
6
52
|
children: ReactNode;
|
|
7
53
|
style?: StyleProp<ViewStyle>;
|
|
@@ -13,6 +13,7 @@ export type RootStackParamList = {
|
|
|
13
13
|
|
|
14
14
|
export type MainTabParamList = {
|
|
15
15
|
[Routes.HomeScreen]: undefined;
|
|
16
|
+
[Routes.NoteScreen]: undefined;
|
|
16
17
|
[Routes.ProfileScreen]: undefined;
|
|
17
18
|
};
|
|
18
19
|
|
|
@@ -24,6 +25,7 @@ export type AuthStackParamList = {
|
|
|
24
25
|
export type AppStackParamList = {
|
|
25
26
|
[Routes.MainTab]: undefined;
|
|
26
27
|
[Routes.SettingsScreen]: undefined;
|
|
28
|
+
[Routes.AddNoteScreen]: undefined;
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
export type ParamsType = RootStackParamList &
|
|
@@ -56,3 +56,9 @@ export const ProfileUpdateSchema = Yup.object().shape({
|
|
|
56
56
|
.matches(/^[0-9]{10}$/, 'Phone number must be 10 digits')
|
|
57
57
|
.optional(),
|
|
58
58
|
});
|
|
59
|
+
|
|
60
|
+
// Note Validation Schema
|
|
61
|
+
export const NoteSchema = Yup.object().shape({
|
|
62
|
+
title: Yup.string().required('Title is required'),
|
|
63
|
+
description: Yup.string().required('Description is required'),
|
|
64
|
+
});
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Welcome to **MMTemplate**! This is a robust and modern React Native template bui
|
|
|
7
7
|
To initialize a new project using this template, run the following command:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npx @react-native-community/cli@latest init AwesomeProject --template
|
|
10
|
+
npx @react-native-community/cli@latest init AwesomeProject --template @modhamanish/rn-mm-template
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Replace `AwesomeProject` with your desired project name.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modhamanish/rn-mm-template",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "A robust and modern React Native template built with TypeScript, designed to jumpstart your mobile application development.",
|
|
5
5
|
"repository": "https://github.com/modhamanish/mm-template.git",
|
|
6
6
|
"author": "Manish Modha",
|