@moamc/rn-cli 1.5.0 → 1.5.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/README.md +0 -24
- package/package.json +1 -1
- package/templates/apiTemplate.js +10 -18
- package/templates/fieldGeneratorTemplate.js +1 -1
- package/templates/hookTemplate.js +27 -74
- package/templates/screenTemplate.js +30 -179
- package/templates/screenTemplate.js.backup +2 -5
- package/utils/fileUtils.js +0 -14
package/README.md
CHANGED
|
@@ -11,7 +11,6 @@ Enterprise-grade Code Generation CLI for React Native Applications
|
|
|
11
11
|
- ✅ Support for multiple field types (text, number, email, date, dropdown, etc.)
|
|
12
12
|
- ✅ Automatic validation generation
|
|
13
13
|
- ✅ TypeScript-ready templates
|
|
14
|
-
- ✅ **Cross-project compatibility** - Automatically detects and adapts to different project structures
|
|
15
14
|
|
|
16
15
|
## 📦 Installation
|
|
17
16
|
|
|
@@ -89,29 +88,6 @@ project-root/
|
|
|
89
88
|
└── navigations/
|
|
90
89
|
```
|
|
91
90
|
|
|
92
|
-
### Component Structure Compatibility
|
|
93
|
-
|
|
94
|
-
The CLI automatically detects your project's component structure:
|
|
95
|
-
|
|
96
|
-
**Option 1: Nested Structure** (e.g., investor-app)
|
|
97
|
-
```
|
|
98
|
-
components/
|
|
99
|
-
└── common/
|
|
100
|
-
├── headers/
|
|
101
|
-
│ └── Header.js
|
|
102
|
-
└── Container.js
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
**Option 2: Flat Structure** (e.g., distributor-app)
|
|
106
|
-
```
|
|
107
|
-
components/
|
|
108
|
-
└── common/
|
|
109
|
-
├── Header.js
|
|
110
|
-
└── Container.js
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
The CLI will automatically generate the correct import paths for your project structure.
|
|
114
|
-
|
|
115
91
|
## 🎨 Form Field Types
|
|
116
92
|
|
|
117
93
|
- **Text** - Standard text input
|
package/package.json
CHANGED
package/templates/apiTemplate.js
CHANGED
|
@@ -85,9 +85,10 @@ ${formFieldsInit}
|
|
|
85
85
|
\tconst [touched, setTouched] = useState({});
|
|
86
86
|
|
|
87
87
|
\t// Fetch data using React Query${getMethod ? `
|
|
88
|
-
\tconst { data, isLoading, error, refetch } = useQuery(
|
|
89
|
-
\t\t
|
|
90
|
-
\t
|
|
88
|
+
\tconst { data, isLoading, error, refetch } = useQuery({
|
|
89
|
+
\t\t...${serviceName}QueryOptions.${getMethod.name}({}),
|
|
90
|
+
\t\tenabled: false,
|
|
91
|
+
\t});` : ''}
|
|
91
92
|
|
|
92
93
|
\t// Submit mutation
|
|
93
94
|
\tconst submitMutation = useMutation({
|
|
@@ -109,13 +110,8 @@ ${formFieldsInit}
|
|
|
109
110
|
\t}, [error]);` : ''}
|
|
110
111
|
|
|
111
112
|
\tconst handleChange = (value, field) => {
|
|
112
|
-
\t\
|
|
113
|
-
\t\tsetFormData(updatedFormData);
|
|
113
|
+
\t\tsetFormData(prev => ({ ...prev, [field]: value }));
|
|
114
114
|
\t\tsetTouched(prev => ({ ...prev, [field]: true }));
|
|
115
|
-
\t\t
|
|
116
|
-
\t\t// Re-validate on change
|
|
117
|
-
\t\tconst validationErrors = validate${screenName}(updatedFormData);
|
|
118
|
-
\t\tsetErrors(validationErrors);
|
|
119
115
|
\t};
|
|
120
116
|
|
|
121
117
|
\tconst handleSubmit = async () => {
|
|
@@ -160,9 +156,10 @@ ${formFieldsInit}
|
|
|
160
156
|
\tconst [touched, setTouched] = useState({});
|
|
161
157
|
|
|
162
158
|
\t// Fetch data using React Query
|
|
163
|
-
\tconst { data, isLoading, error, refetch } = useQuery(
|
|
164
|
-
\t\t
|
|
165
|
-
\t
|
|
159
|
+
\tconst { data, isLoading, error, refetch } = useQuery({
|
|
160
|
+
\t\t...${serviceName}QueryOptions.${method.name}({}),
|
|
161
|
+
\t\tenabled: false,
|
|
162
|
+
\t});
|
|
166
163
|
|
|
167
164
|
\tuseEffect(() => {
|
|
168
165
|
\t\tif (error) {
|
|
@@ -171,13 +168,8 @@ ${formFieldsInit}
|
|
|
171
168
|
\t}, [error]);
|
|
172
169
|
|
|
173
170
|
\tconst handleChange = (value, field) => {
|
|
174
|
-
\t\
|
|
175
|
-
\t\tsetFormData(updatedFormData);
|
|
171
|
+
\t\tsetFormData(prev => ({ ...prev, [field]: value }));
|
|
176
172
|
\t\tsetTouched(prev => ({ ...prev, [field]: true }));
|
|
177
|
-
\t\t
|
|
178
|
-
\t\t// Re-validate on change
|
|
179
|
-
\t\tconst validationErrors = validate${screenName}(updatedFormData);
|
|
180
|
-
\t\tsetErrors(validationErrors);
|
|
181
173
|
\t};
|
|
182
174
|
|
|
183
175
|
\tconst handleSubmit = async () => {
|
|
@@ -52,7 +52,7 @@ const generateTextInputField = (name, label, type, containerStyle) => {
|
|
|
52
52
|
\t\t\t\t\t\t<FloatingTextInput
|
|
53
53
|
\t\t\t\t\t\t\tlabel="${label}"
|
|
54
54
|
\t\t\t\t\t\t\tvalue={formData?.${name} || ''}
|
|
55
|
-
\t\t\t\t\t\t\tonChangeText={
|
|
55
|
+
\t\t\t\t\t\t\tonChangeText={e => handleChange(e, '${name}')}
|
|
56
56
|
\t\t\t\t\t\t\ttextInputStyles={styles.floatContentStyle}
|
|
57
57
|
\t\t\t\t\t\t\tinputContainerStyle={styles.floatStyle}
|
|
58
58
|
\t\t\t\t\t\t\tlabelStyles={styles.floatLabelStyle}
|
|
@@ -36,76 +36,44 @@ const generateInitialValues = (formFields = []) => {
|
|
|
36
36
|
return `\t\tloader: false,\n${fields}${additionalFields}`;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
const { detectProjectStructure } = require('../utils/fileUtils');
|
|
40
|
-
|
|
41
39
|
const generateHookTemplate = (hookName, hasForm = false, formFields = [], eventName = null) => {
|
|
42
|
-
const { hasHeadersFolder } = detectProjectStructure();
|
|
43
|
-
const isDistributorStyle = !hasHeadersFolder;
|
|
44
|
-
|
|
45
40
|
if (hasForm) {
|
|
46
41
|
const hasDropdown = formFields.some(f => f.type === 'dropdown');
|
|
47
42
|
const hasDate = formFields.some(f => f.type === 'date');
|
|
48
43
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return `import { useFormik } from 'formik';
|
|
52
|
-
import { showToastNotification } from '../../../../helpers/common';${hasDate ? '\nimport moment from \'moment\';' : ''}
|
|
53
|
-
import { validate${hookName} } from '../validation';
|
|
54
|
-
|
|
55
|
-
export const use${hookName} = ({ navigation }) => {
|
|
56
|
-
\tconst formikState = useFormik({
|
|
57
|
-
\t\tinitialValues: {
|
|
58
|
-
${formFields.map(f => `\t\t\t${f.name}: '',`).join('\n')}
|
|
59
|
-
\t\t},
|
|
60
|
-
\t\tvalidate: validate${hookName},
|
|
61
|
-
\t\tonSubmit: async (values) => {
|
|
62
|
-
\t\t\ttry {
|
|
63
|
-
\t\t\t\t// Add your API call here
|
|
64
|
-
\t\t\t\tshowToastNotification('Success!');
|
|
65
|
-
\t\t\t} catch (error) {
|
|
66
|
-
\t\t\t\tshowToastNotification(error?.message || 'Something went wrong');
|
|
67
|
-
\t\t\t}
|
|
68
|
-
\t\t},
|
|
69
|
-
\t});
|
|
70
|
-
|
|
71
|
-
\tconst { values: formData, errors, touched, isSubmitting: loading, handleChange: formikHandleChange, handleSubmit } = formikState;
|
|
72
|
-
|
|
73
|
-
\tconst handleChange = (value, field) => {
|
|
74
|
-
\t\tformikState.setFieldValue(field, value);
|
|
75
|
-
\t\tformikState.setFieldTouched(field, true);
|
|
76
|
-
\t};
|
|
77
|
-
|
|
78
|
-
\treturn {
|
|
79
|
-
\t\tformData,
|
|
80
|
-
\t\terrors,
|
|
81
|
-
\t\ttouched,
|
|
82
|
-
\t\tloading,
|
|
83
|
-
\t\thandleChange,
|
|
84
|
-
\t\thandleSubmit,
|
|
85
|
-
\t};
|
|
86
|
-
};
|
|
87
|
-
`;
|
|
88
|
-
} else {
|
|
89
|
-
// Investor app - use useState with useCallback
|
|
90
|
-
return `import { useState, useCallback } from 'react';
|
|
44
|
+
return `import { useState } from 'react';
|
|
45
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
91
46
|
import { showToastNotification } from '../../../../helpers/common';${hasDate ? '\nimport moment from \'moment\';' : ''}
|
|
92
47
|
import { validate${hookName} } from '../validation';
|
|
93
48
|
|
|
94
|
-
export const use${hookName} = (
|
|
49
|
+
export const use${hookName} = () => {
|
|
50
|
+
\tconst queryClient = useQueryClient();
|
|
95
51
|
\tconst [formData, setFormData] = useState({
|
|
96
52
|
${formFields.map(f => `\t\t${f.name}: '',`).join('\n')}
|
|
97
53
|
\t});
|
|
98
54
|
\tconst [errors, setErrors] = useState({});
|
|
99
|
-
\tconst [touched, setTouched] = useState({});
|
|
100
|
-
|
|
55
|
+
\tconst [touched, setTouched] = useState({});${hasDropdown ? '\n\tconst [bottomSheetType, setBottomSheetType] = useState(null);' : ''}${hasDate ? '\n\tconst [openCalendar, setOpenCalendar] = useState(false);' : ''}
|
|
56
|
+
|
|
57
|
+
\tconst submitMutation = useMutation({
|
|
58
|
+
\t\tmutationFn: (data) => {
|
|
59
|
+
\t\t\t// Add your API call here
|
|
60
|
+
\t\t\treturn Promise.resolve(data);
|
|
61
|
+
\t\t},
|
|
62
|
+
\t\tonSuccess: (response) => {
|
|
63
|
+
\t\t\tshowToastNotification('Success!');
|
|
64
|
+
\t\t\tqueryClient.invalidateQueries({ queryKey: ['${hookName.toLowerCase()}'] });
|
|
65
|
+
\t\t},
|
|
66
|
+
\t\tonError: (error) => {
|
|
67
|
+
\t\t\tshowToastNotification(error?.message || 'Something went wrong');
|
|
68
|
+
\t\t},
|
|
69
|
+
\t});
|
|
101
70
|
|
|
102
|
-
\tconst handleChange =
|
|
71
|
+
\tconst handleChange = (value, field) => {
|
|
103
72
|
\t\tsetFormData(prev => ({ ...prev, [field]: value }));
|
|
104
73
|
\t\tsetTouched(prev => ({ ...prev, [field]: true }));
|
|
105
|
-
\t
|
|
106
|
-
\t}, []);
|
|
74
|
+
\t};
|
|
107
75
|
|
|
108
|
-
\tconst handleSubmit =
|
|
76
|
+
\tconst handleSubmit = async () => {
|
|
109
77
|
\t\tconst validationErrors = validate${hookName}(formData);
|
|
110
78
|
\t\tif (Object.keys(validationErrors).length > 0) {
|
|
111
79
|
\t\t\tsetErrors(validationErrors);
|
|
@@ -113,32 +81,23 @@ ${formFields.map(f => `\t\t${f.name}: '',`).join('\n')}
|
|
|
113
81
|
\t\t\treturn;
|
|
114
82
|
\t\t}
|
|
115
83
|
|
|
116
|
-
\t\
|
|
117
|
-
\t
|
|
118
|
-
\t\t\t// Add your API call here
|
|
119
|
-
\t\t\tshowToastNotification('Success!');
|
|
120
|
-
\t\t} catch (error) {
|
|
121
|
-
\t\t\tshowToastNotification(error?.message || 'Something went wrong');
|
|
122
|
-
\t\t} finally {
|
|
123
|
-
\t\t\tsetLoading(false);
|
|
124
|
-
\t\t}
|
|
125
|
-
\t}, [formData]);${hasDropdown ? `
|
|
84
|
+
\t\tsubmitMutation.mutate(formData);
|
|
85
|
+
\t};${hasDropdown ? `
|
|
126
86
|
|
|
127
|
-
\tconst openBottomSheet =
|
|
87
|
+
\tconst openBottomSheet = (type) => {
|
|
128
88
|
\t\tsetBottomSheetType(type);
|
|
129
|
-
\t}
|
|
89
|
+
\t};` : ''}
|
|
130
90
|
|
|
131
91
|
\treturn {
|
|
132
92
|
\t\tformData,
|
|
133
93
|
\t\terrors,
|
|
134
94
|
\t\ttouched,
|
|
135
|
-
\t\tloading,
|
|
95
|
+
\t\tloading: submitMutation.isPending,
|
|
136
96
|
\t\thandleChange,
|
|
137
97
|
\t\thandleSubmit,${hasDropdown ? '\n\t\topenBottomSheet,\n\t\tbottomSheetType,' : ''}${hasDate ? '\n\t\topenCalendar,\n\t\tsetOpenCalendar,' : ''}
|
|
138
98
|
\t};
|
|
139
99
|
};
|
|
140
100
|
`;
|
|
141
|
-
}
|
|
142
101
|
}
|
|
143
102
|
|
|
144
103
|
return `import { useState, useEffect } from 'react';
|
|
@@ -163,15 +122,9 @@ export const use${hookName} = ({ navigation }) => {
|
|
|
163
122
|
\t\t}
|
|
164
123
|
\t}, [error]);
|
|
165
124
|
|
|
166
|
-
\tconst handleSubmit = () => {
|
|
167
|
-
\t\t// Add your submit logic here
|
|
168
|
-
\t\tshowToastNotification('Submit clicked');
|
|
169
|
-
\t};
|
|
170
|
-
|
|
171
125
|
\treturn {
|
|
172
126
|
\t\tloading: isLoading,
|
|
173
127
|
\t\tdata,
|
|
174
|
-
\t\thandleSubmit,
|
|
175
128
|
\t};
|
|
176
129
|
};
|
|
177
130
|
`;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const { generateFormField, FIELD_TYPES } = require('./fieldGeneratorTemplate');
|
|
2
|
-
const { detectProjectStructure } = require('../utils/fileUtils');
|
|
3
2
|
|
|
4
3
|
const groupFieldsByRows = (formFields) => {
|
|
5
4
|
const rows = [];
|
|
@@ -50,126 +49,13 @@ const generateEnhancedTemplate = (screenName, featureName, hasForm = false, form
|
|
|
50
49
|
const componentName = screenName;
|
|
51
50
|
const hasDropdown = formFields.some(f => f.type === 'dropdown');
|
|
52
51
|
const hasDate = formFields.some(f => f.type === 'date');
|
|
53
|
-
const { headerImportPath, hasHeadersFolder } = detectProjectStructure();
|
|
54
|
-
const isDistributorStyle = !hasHeadersFolder;
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
if (hasDropdown) {
|
|
58
|
-
bottomSheetCode = `
|
|
59
|
-
\t\t\t<BottomSheet
|
|
60
|
-
\t\t\t\tmodalVisible={!!openBottomNote}
|
|
61
|
-
\t\t\t\tsetIsModalVisible={() => setOpenBottomNote(null)}
|
|
62
|
-
\t\t\t>
|
|
63
|
-
\t\t\t\t<DropDownReview
|
|
64
|
-
\t\t\t\t\tFundBuyType={/* Add options */[]}
|
|
65
|
-
\t\t\t\t\tselectValue={formData[bottomSheetType]}
|
|
66
|
-
\t\t\t\t\tonSelectValue={e => {
|
|
67
|
-
\t\t\t\t\t\thandleChange(e, bottomSheetType);
|
|
68
|
-
\t\t\t\t\t\tsetOpenBottomNote(null);
|
|
69
|
-
\t\t\t\t\t}}
|
|
70
|
-
\t\t\t\t\tlabel={bottomSheetType}
|
|
71
|
-
\t\t\t\t/>
|
|
72
|
-
\t\t\t</BottomSheet>`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
let datePickerCode = '';
|
|
76
|
-
if (hasDate) {
|
|
77
|
-
datePickerCode = `
|
|
78
|
-
\t\t\t<DatePickerCustom
|
|
79
|
-
\t\t\t\tmodalTransparent={true}
|
|
80
|
-
\t\t\t\tonDateChange={data => {
|
|
81
|
-
\t\t\t\t\thandleChange(moment(data).format('DD MMM YYYY'), 'dateField');
|
|
82
|
-
\t\t\t\t}}
|
|
83
|
-
\t\t\t\tsetModalVisible={() => setOpenCalendar(!openCalendar)}
|
|
84
|
-
\t\t\t\tmodalVisible={openCalendar}
|
|
85
|
-
\t\t\t\tminimumDate={new Date(1920, 0, 1)}
|
|
86
|
-
\t\t\t/>`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (isDistributorStyle) {
|
|
90
|
-
return `import React, { useState } from 'react';
|
|
91
|
-
import { Text, ScrollView, View, StyleSheet } from 'react-native';
|
|
92
|
-
import { colorConstant, fonts, utilities } from '../../../assets/styles';
|
|
93
|
-
import Container from '../../../components/common/Container';
|
|
94
|
-
import Header from '../../../components/common/Header';
|
|
95
|
-
import Footer from '../../../components/common/Footer';
|
|
96
|
-
import Loader from '../../../components/common/Loader';
|
|
97
|
-
import { FloatingTextInput, FormButton } from '../../../components/form';${hasDropdown ? '\nimport { BottomSheet } from \'../../../components/common\';\nimport DropDownReview from \'../../../components/common/DropDownReview\';' : ''}${hasDate ? '\nimport { DatePickerCustom } from \'../../../components/form/DatePicker\';\nimport moment from \'moment\';' : ''}
|
|
98
|
-
import { use${componentName} } from './hooks/use${componentName}';
|
|
99
|
-
|
|
100
|
-
const ${componentName} = ({ navigation }) => {
|
|
101
|
-
\tconst {
|
|
102
|
-
\t\tformData,
|
|
103
|
-
\t\terrors,
|
|
104
|
-
\t\ttouched,
|
|
105
|
-
\t\tloading,
|
|
106
|
-
\t\thandleChange,
|
|
107
|
-
\t\thandleSubmit${hasDropdown ? ',\n\t\topenBottomSheet,\n\t\tbottomSheetType' : ''}${hasDate ? ',\n\t\topenCalendar,\n\t\tsetOpenCalendar' : ''}
|
|
108
|
-
\t} = use${componentName}({ navigation });
|
|
109
|
-
\t${hasDropdown ? '\n\tconst [openBottomNote, setOpenBottomNote] = useState(false);' : ''}
|
|
110
|
-
|
|
111
|
-
\tif (loading) {
|
|
112
|
-
\t\treturn <Loader loaderText="Hang On..." />;
|
|
113
|
-
\t}
|
|
114
|
-
|
|
115
|
-
\treturn (
|
|
116
|
-
\t\t<>
|
|
117
|
-
\t\t\t<Container>
|
|
118
|
-
\t\t\t\t<Header redirect={() => navigation.goBack()} />
|
|
119
|
-
\t\t\t\t<ScrollView
|
|
120
|
-
\t\t\t\t\tshowsVerticalScrollIndicator={false}
|
|
121
|
-
\t\t\t\t\tcontentContainerStyle={styles.scrollContent}
|
|
122
|
-
\t\t\t\t>
|
|
123
|
-
\t\t\t\t\t<Text style={styles.heading}>${screenName}</Text>
|
|
124
|
-
${generateFormFields(formFields)}
|
|
125
|
-
\t\t\t\t</ScrollView>
|
|
126
|
-
\t\t\t</Container>
|
|
127
|
-
\t\t\t<Footer isBottom={true}>
|
|
128
|
-
\t\t\t\t<FormButton title="Submit" onPress={handleSubmit} />
|
|
129
|
-
\t\t\t</Footer>${bottomSheetCode}${datePickerCode}
|
|
130
|
-
\t\t</>
|
|
131
|
-
\t);
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const styles = StyleSheet.create({
|
|
135
|
-
\tscrollContent: {
|
|
136
|
-
\t\t...utilities.rowPadding24,
|
|
137
|
-
\t},
|
|
138
|
-
\theading: {
|
|
139
|
-
\t\t...fonts.fontWSSB18,
|
|
140
|
-
\t\tcolor: colorConstant.moBlack,
|
|
141
|
-
\t\tmarginVertical: 20,
|
|
142
|
-
\t},
|
|
143
|
-
\theadContainer: {
|
|
144
|
-
\t\tflexDirection: 'row',
|
|
145
|
-
\t\tjustifyContent: 'space-between',
|
|
146
|
-
\t\tmarginTop: 16,
|
|
147
|
-
\t},
|
|
148
|
-
\theadWidth: {
|
|
149
|
-
\t\twidth: '48%',
|
|
150
|
-
\t},
|
|
151
|
-
\tfloatContentStyle: {
|
|
152
|
-
\t\t...fonts.fontWSR16,
|
|
153
|
-
\t\tcolor: colorConstant.amcBlack,
|
|
154
|
-
\t},
|
|
155
|
-
\tfloatStyle: {},
|
|
156
|
-
\tfloatLabelStyle: {
|
|
157
|
-
\t\tcolor: colorConstant?.amcMediumGrey,
|
|
158
|
-
\t\tbackgroundColor: colorConstant?.amcWhite,
|
|
159
|
-
\t\t...fonts.fontWSM12,
|
|
160
|
-
\t\tlineHeight: 16,
|
|
161
|
-
\t},
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
export default ${componentName};
|
|
165
|
-
`;
|
|
166
|
-
} else {
|
|
167
|
-
return `import React, { useState } from 'react';
|
|
53
|
+
return `import React, { useState } from 'react';
|
|
168
54
|
import { Text, ScrollView, View } from 'react-native';
|
|
169
55
|
import { TouchableRipple } from 'react-native-paper';
|
|
170
56
|
import { colorConstant, utilities } from '../../../assets/styles';
|
|
171
57
|
import { Container } from '../../../components/common';
|
|
172
|
-
import { Header } from '
|
|
58
|
+
import { Header } from '../../../components/common/headers';
|
|
173
59
|
import Footer from '../../../components/common/Footer';
|
|
174
60
|
import FormButton from '../../../components/form/FormButton';
|
|
175
61
|
import { FloatingTextInput } from '../../../components/form';${hasDropdown ? '\nimport { BottomSheet } from \'../../../components/common\';\nimport DropDownReview from \'../../../components/common/DropDownReview\';' : ''}${hasDate ? '\nimport { DatePickerCustom } from \'../../../components/form/DatePicker\';\nimport moment from \'moment\';' : ''}
|
|
@@ -203,84 +89,50 @@ ${generateFormFields(formFields)}
|
|
|
203
89
|
\t\t\t</Container>
|
|
204
90
|
\t\t\t<Footer style={styles.footerDesign}>
|
|
205
91
|
\t\t\t\t<FormButton title="Submit" onPress={handleSubmit} />
|
|
206
|
-
\t\t\t</Footer>${
|
|
92
|
+
\t\t\t</Footer>${hasDropdown ? `
|
|
93
|
+
\t\t\t<BottomSheet
|
|
94
|
+
\t\t\t\tmodalVisible={!!openBottomNote}
|
|
95
|
+
\t\t\t\tsetIsModalVisible={() => setOpenBottomNote(null)}
|
|
96
|
+
\t\t\t>
|
|
97
|
+
\t\t\t\t<DropDownReview
|
|
98
|
+
\t\t\t\t\tFundBuyType={/* Add options */[]}
|
|
99
|
+
\t\t\t\t\tselectValue={formData[bottomSheetType]}
|
|
100
|
+
\t\t\t\t\tonSelectValue={e => {
|
|
101
|
+
\t\t\t\t\t\thandleChange(e, bottomSheetType);
|
|
102
|
+
\t\t\t\t\t\tsetOpenBottomNote(null);
|
|
103
|
+
\t\t\t\t\t}}
|
|
104
|
+
\t\t\t\t\tlabel={bottomSheetType}
|
|
105
|
+
\t\t\t\t/>
|
|
106
|
+
\t\t\t</BottomSheet>` : ''}${hasDate ? `
|
|
107
|
+
\t\t\t<DatePickerCustom
|
|
108
|
+
\t\t\t\tmodalTransparent={true}
|
|
109
|
+
\t\t\t\tonDateChange={data => {
|
|
110
|
+
\t\t\t\t\thandleChange(moment(data).format('DD MMM YYYY'), 'dateField');
|
|
111
|
+
\t\t\t\t}}
|
|
112
|
+
\t\t\t\tsetModalVisible={() => setOpenCalendar(!openCalendar)}
|
|
113
|
+
\t\t\t\tmodalVisible={openCalendar}
|
|
114
|
+
\t\t\t\tminimumDate={new Date(1920, 0, 1)}
|
|
115
|
+
\t\t\t/>` : ''}
|
|
207
116
|
\t\t</>
|
|
208
117
|
\t);
|
|
209
118
|
};
|
|
210
119
|
|
|
211
120
|
export default ${componentName};
|
|
212
121
|
`;
|
|
213
|
-
}
|
|
214
122
|
};
|
|
215
123
|
|
|
216
124
|
const generateScreenTemplate = (screenName, featureName, hasForm = false, formFields = []) => {
|
|
125
|
+
// Use enhanced template for form screens
|
|
217
126
|
if (hasForm) {
|
|
218
127
|
return generateEnhancedTemplate(screenName, featureName, hasForm, formFields);
|
|
219
128
|
}
|
|
220
129
|
|
|
130
|
+
// Simple screen template
|
|
221
131
|
const componentName = screenName;
|
|
222
|
-
|
|
223
|
-
const isDistributorStyle = !hasHeadersFolder;
|
|
224
|
-
|
|
225
|
-
if (isDistributorStyle) {
|
|
226
|
-
return `import React from 'react';
|
|
227
|
-
import { View, Text, ScrollView, StyleSheet } from 'react-native';
|
|
228
|
-
import { colorConstant, fonts, utilities } from '../../../assets/styles';
|
|
229
|
-
import Container from '../../../components/common/Container';
|
|
230
|
-
import Header from '../../../components/common/Header';
|
|
231
|
-
import Footer from '../../../components/common/Footer';
|
|
232
|
-
import Loader from '../../../components/common/Loader';
|
|
233
|
-
import { FormButton } from '../../../components/form';
|
|
234
|
-
import { use${componentName} } from './hooks/use${componentName}';
|
|
235
|
-
|
|
236
|
-
const ${componentName} = ({ navigation }) => {
|
|
237
|
-
\tconst {
|
|
238
|
-
\t\tloading,
|
|
239
|
-
\t\tdata,
|
|
240
|
-
\t\thandleSubmit,
|
|
241
|
-
\t} = use${componentName}({ navigation });
|
|
242
|
-
|
|
243
|
-
\tif (loading) {
|
|
244
|
-
\t\treturn <Loader loaderText="Hang On..." />;
|
|
245
|
-
\t}
|
|
246
|
-
|
|
247
|
-
\treturn (
|
|
248
|
-
\t\t<>
|
|
249
|
-
\t\t\t<Container>
|
|
250
|
-
\t\t\t\t<Header redirect={() => navigation.goBack()} />
|
|
251
|
-
\t\t\t\t<ScrollView
|
|
252
|
-
\t\t\t\t\tshowsVerticalScrollIndicator={false}
|
|
253
|
-
\t\t\t\t\tcontentContainerStyle={styles.scrollContent}
|
|
254
|
-
\t\t\t\t>
|
|
255
|
-
\t\t\t\t\t<Text style={styles.heading}>${screenName}</Text>
|
|
256
|
-
\t\t\t\t\t{/* Add your content here */}
|
|
257
|
-
\t\t\t\t</ScrollView>
|
|
258
|
-
\t\t\t</Container>
|
|
259
|
-
\t\t\t<Footer isBottom={true}>
|
|
260
|
-
\t\t\t\t<FormButton title="Submit" onPress={handleSubmit} />
|
|
261
|
-
\t\t\t</Footer>
|
|
262
|
-
\t\t</>
|
|
263
|
-
\t);
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
const styles = StyleSheet.create({
|
|
267
|
-
\tscrollContent: {
|
|
268
|
-
\t\t...utilities.rowPadding24,
|
|
269
|
-
\t},
|
|
270
|
-
\theading: {
|
|
271
|
-
\t\t...fonts.fontWSSB18,
|
|
272
|
-
\t\tcolor: colorConstant.moBlack,
|
|
273
|
-
\t\tmarginVertical: 20,
|
|
274
|
-
\t},
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
export default ${componentName};
|
|
278
|
-
`;
|
|
279
|
-
} else {
|
|
280
|
-
return `import React from 'react';
|
|
132
|
+
return `import React from 'react';
|
|
281
133
|
import { View, Text, ScrollView } from 'react-native';
|
|
282
134
|
import { Container, Loader } from '../../../components/common';
|
|
283
|
-
import { Header } from '
|
|
135
|
+
import { Header } from '../../../components/common/headers';
|
|
284
136
|
import { colorConstant, utilities } from '../../../assets/styles';
|
|
285
137
|
import { use${componentName} } from './hooks/use${componentName}';
|
|
286
138
|
import { styles } from './components/styles';
|
|
@@ -308,7 +160,6 @@ const ${componentName} = ({ navigation }) => {
|
|
|
308
160
|
|
|
309
161
|
export default ${componentName};
|
|
310
162
|
`;
|
|
311
|
-
}
|
|
312
163
|
};
|
|
313
164
|
|
|
314
165
|
module.exports = { generateScreenTemplate };
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const { detectProjectStructure } = require('../utils/fileUtils');
|
|
2
|
-
|
|
3
1
|
const generateFormFields = (formFields = []) => {
|
|
4
2
|
if (!formFields || formFields.length === 0) return '\t\t\t\t{/* Add your form fields here */}';
|
|
5
3
|
|
|
@@ -57,7 +55,6 @@ const generateFormFields = (formFields = []) => {
|
|
|
57
55
|
|
|
58
56
|
const generateScreenTemplate = (screenName, featureName, hasForm = false, formFields = []) => {
|
|
59
57
|
const componentName = screenName;
|
|
60
|
-
const { headerImportPath } = detectProjectStructure();
|
|
61
58
|
|
|
62
59
|
if (hasForm) {
|
|
63
60
|
const formFieldsCode = generateFormFields(formFields);
|
|
@@ -67,7 +64,7 @@ const generateScreenTemplate = (screenName, featureName, hasForm = false, formFi
|
|
|
67
64
|
return `import React from 'react';
|
|
68
65
|
import { View, Text, ScrollView, StyleSheet } from 'react-native';
|
|
69
66
|
import { Container, Footer, Loader } from '../../../components/common';
|
|
70
|
-
import { Header } from '
|
|
67
|
+
import { Header } from '../../../components/common/headers';
|
|
71
68
|
import { FloatingTextInput, FormButton } from '../../../components/form';${hasDropdown ? '\nimport RadioForm from \'../../../components/form/RadioForm\';' : ''}${hasCheckbox ? '\nimport CheckBox from \'../../../components/common/CheckBox\';' : ''}
|
|
72
69
|
import { withUser } from '../../../components/HOC';
|
|
73
70
|
import { colorConstant, fonts, utilities } from '../../../assets/styles';
|
|
@@ -113,7 +110,7 @@ export default withUser(${componentName});
|
|
|
113
110
|
return `import React from 'react';
|
|
114
111
|
import { View, Text, ScrollView, StyleSheet } from 'react-native';
|
|
115
112
|
import { Container, Loader } from '../../../components/common';
|
|
116
|
-
import { Header } from '
|
|
113
|
+
import { Header } from '../../../components/common/headers';
|
|
117
114
|
import { withUser } from '../../../components/HOC';
|
|
118
115
|
import { colorConstant, fonts, utilities } from '../../../assets/styles';
|
|
119
116
|
import { use${componentName} } from './use${componentName}';
|
package/utils/fileUtils.js
CHANGED
|
@@ -19,19 +19,6 @@ const findProjectRoot = () => {
|
|
|
19
19
|
|
|
20
20
|
const PROJECT_ROOT = findProjectRoot();
|
|
21
21
|
|
|
22
|
-
// Detect project structure for imports
|
|
23
|
-
const detectProjectStructure = () => {
|
|
24
|
-
const headersPath = path.join(PROJECT_ROOT, 'components', 'common', 'headers');
|
|
25
|
-
const hasHeadersFolder = fs.existsSync(headersPath);
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
hasHeadersFolder,
|
|
29
|
-
headerImportPath: hasHeadersFolder
|
|
30
|
-
? "../../../components/common/headers"
|
|
31
|
-
: "../../../components/common"
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
|
|
35
22
|
const ensureDirectoryExists = (dirPath) => {
|
|
36
23
|
if (!fs.existsSync(dirPath)) {
|
|
37
24
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
@@ -126,5 +113,4 @@ module.exports = {
|
|
|
126
113
|
logWarning,
|
|
127
114
|
logError,
|
|
128
115
|
confirmOverwrite,
|
|
129
|
-
detectProjectStructure,
|
|
130
116
|
};
|