create-ern-boilerplate 0.0.21 → 0.0.23
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/create.js +40 -0
- package/package.json +1 -1
- package/templates/default/app.prod.json +60 -0
- package/templates/default/app.staging.json +60 -0
- package/templates/default/eas.json +42 -0
- package/templates/default/package.json +29 -7
- package/templates/default/src/services/authService.ts +3 -0
- package/templates/default/src/utils/constants.ts +3 -2
- package/templates/default_draft/README.md +3 -0
- package/templates/{simple/app/(admin)/profile.tsx → default_draft/app/(admin)/draft_profile.tsx} +5 -5
- package/templates/{simple/app/(admin)/user-management.tsx → default_draft/app/(admin)/draft_userManagement.tsx} +4 -4
- package/templates/{simple → default_draft}/app/(auth)/_layout.tsx +2 -2
- package/templates/{simple/app/(auth)/login.tsx → default_draft/app/(auth)/draft_login.tsx} +5 -5
- package/templates/{simple/app/(auth)/register.tsx → default_draft/app/(auth)/draft_register.tsx} +4 -4
- package/templates/{simple → default_draft}/app/(protected)/_layout.tsx +5 -5
- package/templates/{simple/app/(protected)/home.tsx → default_draft/app/(protected)/draft_home.tsx} +4 -4
- package/templates/{simple/app/(protected)/settings.tsx → default_draft/app/(protected)/draft_settings.tsx} +6 -6
- package/templates/{simple → default_draft}/app/_layout.tsx +2 -2
- package/templates/{simple → default_draft}/src/components/auth/ProtectedRoute.tsx +2 -2
- package/templates/{simple → default_draft}/src/components/common/Card.tsx +1 -1
- package/templates/{simple → default_draft}/src/components/common/Input.tsx +1 -1
- package/templates/{simple → default_draft}/src/components/common/Loading.tsx +1 -1
- package/templates/{simple → default_draft}/src/components/users/FilterModal.tsx +1 -1
- package/templates/{simple → default_draft}/src/components/users/UserCard.tsx +1 -1
- package/templates/{simple → default_draft}/src/components/users/UserFormModal.tsx +1 -1
- package/templates/{simple/src/contexts/AuthContext.tsx → default_draft/src/contexts/draft_AuthContext.tsx} +6 -6
- package/templates/{simple/src/contexts/ThemeContext.tsx → default_draft/src/contexts/draft_ThemeContext.tsx} +2 -2
- package/templates/{simple/src/hooks/useAuth.ts → default_draft/src/hooks/draft_useAuth.ts} +1 -1
- package/templates/{simple/src/hooks/useTheme.ts → default_draft/src/hooks/draft_useTheme.ts} +1 -1
- package/templates/{simple/src/hooks/useUsers.ts → default_draft/src/hooks/draft_useUsers.ts} +2 -2
- package/templates/{simple/src/services/api.ts → default_draft/src/services/draft_api.ts} +3 -3
- package/templates/{simple/src/services/authService.ts → default_draft/src/services/draft_authService.ts} +3 -3
- package/templates/{simple/src/services/productService.ts → default_draft/src/services/draft_productService.ts} +3 -3
- package/templates/{simple/src/services/userService.ts → default_draft/src/services/draft_userService.ts} +3 -3
- package/templates/{simple/src/services/mockApi/auth.mock.ts → default_draft/src/services/mockApi/draft_auth.mock.ts} +1 -1
- package/templates/{simple/src/services/mockApi/categories.mock.ts → default_draft/src/services/mockApi/draft_categories.mock.ts} +1 -1
- package/templates/{simple/src/services/mockApi/products.mock.ts → default_draft/src/services/mockApi/draft_products.mock.ts} +1 -1
- package/templates/{simple/src/services/mockApi/users.mock.ts → default_draft/src/services/mockApi/draft_users.mock.ts} +2 -2
- package/templates/{simple → default_draft}/src/services/mockApi/index.ts +4 -4
- package/templates/{simple/src/utils/validation.ts → default_draft/src/utils/draft_validation.ts} +1 -1
- package/templates/simple/PROJECT_CONTEXT.MD +0 -663
- package/templates/simple/README.md +0 -274
- /package/templates/{simple → default_draft}/app.json +0 -0
- /package/templates/{simple → default_draft}/babel.config.js +0 -0
- /package/templates/{simple → default_draft}/global.css +0 -0
- /package/templates/{simple → default_draft}/metro.config.js +0 -0
- /package/templates/{simple → default_draft}/nativewind-env.d.ts +0 -0
- /package/templates/{simple → default_draft}/package.json +0 -0
- /package/templates/{simple → default_draft}/server/db.json +0 -0
- /package/templates/{simple → default_draft}/src/assets/images/adaptive-icon.png +0 -0
- /package/templates/{simple → default_draft}/src/assets/images/favicon.png +0 -0
- /package/templates/{simple → default_draft}/src/assets/images/icon.png +0 -0
- /package/templates/{simple → default_draft}/src/assets/images/splash-icon.png +0 -0
- /package/templates/{simple → default_draft}/src/components/common/Button.tsx +0 -0
- /package/templates/{simple → default_draft}/src/components/config/ToastConfig.tsx +0 -0
- /package/templates/{simple/src/components/header/AppHeader.tsx → default_draft/src/components/header/draft_AppHeader.tsx} +0 -0
- /package/templates/{simple → default_draft}/src/components/shared/ConfirmDialog.tsx +0 -0
- /package/templates/{simple → default_draft}/src/components/shared/FormInput.tsx +0 -0
- /package/templates/{simple → default_draft}/src/components/shared/LucideIcon.tsx +0 -0
- /package/templates/{simple → default_draft}/src/components/shared/RoleSelector.tsx +0 -0
- /package/templates/{simple → default_draft}/src/components/users/EmptyState.tsx +0 -0
- /package/templates/{simple → default_draft}/src/components/users/ErrorState.tsx +0 -0
- /package/templates/{simple/src/theme/colors.ts → default_draft/src/theme/draft_colors.ts} +0 -0
- /package/templates/{simple/src/types/api.types.ts → default_draft/src/types/draft_api.types.ts} +0 -0
- /package/templates/{simple/src/types/auth.types.ts → default_draft/src/types/draft_auth.types.ts} +0 -0
- /package/templates/{simple/src/types/product.types.ts → default_draft/src/types/draft_product.types.ts} +0 -0
- /package/templates/{simple/src/types/user.types.ts → default_draft/src/types/draft_user.types.ts} +0 -0
- /package/templates/{simple/src/utils/constants.ts → default_draft/src/utils/draft_constants.ts} +0 -0
- /package/templates/{simple/src/utils/storage.ts → default_draft/src/utils/draft_storage.ts} +0 -0
- /package/templates/{simple → default_draft}/tailwind.config.js +0 -0
- /package/templates/{simple → default_draft}/tsconfig.json +0 -0
package/create.js
CHANGED
|
@@ -138,6 +138,46 @@ async function main() {
|
|
|
138
138
|
await fs.writeJson(appJsonPath, appJson, { spaces: 2 });
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
// === Update app.staging.json ===
|
|
142
|
+
const appJsonPathStaging = path.join(targetDir, "app.staging.json");
|
|
143
|
+
if (fs.existsSync(appJsonPathStaging)) {
|
|
144
|
+
const appJsonStaging = await fs.readJson(appJsonPathStaging);
|
|
145
|
+
appJsonStaging.expo = appJsonStaging.expo || {};
|
|
146
|
+
appJsonStaging.expo.name = projectName;
|
|
147
|
+
appJsonStaging.expo.slug = projectName.toLowerCase().replace(/\s+/g, "-");
|
|
148
|
+
appJsonStaging.expo.ios = appJsonStaging.expo.ios || {};
|
|
149
|
+
appJsonStaging.expo.android = appJsonStaging.expo.android || {};
|
|
150
|
+
appJsonStaging.expo.ios.bundleIdentifier = `com.${projectName.toLowerCase()}.app`;
|
|
151
|
+
appJsonStaging.expo.android.package = `com.${projectName.toLowerCase()}.app`;
|
|
152
|
+
appJsonStaging.expo.scheme = projectName.toLowerCase();
|
|
153
|
+
if (appJsonStaging.expo.extra && appJsonStaging.expo.extra.eas) {
|
|
154
|
+
appJsonStaging.expo.extra.eas.projectId = "";
|
|
155
|
+
}
|
|
156
|
+
appJsonStaging.expo.extra.ENV = "staging";
|
|
157
|
+
appJsonStaging.expo.extra.BASE_URL = "";
|
|
158
|
+
await fs.writeJson(appJsonPathStaging, appJsonStaging, { spaces: 2 });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// === Update app.prod.json ===
|
|
162
|
+
const appJsonPathProd = path.join(targetDir, "app.prod.json");
|
|
163
|
+
if (fs.existsSync(appJsonPathProd)) {
|
|
164
|
+
const appJsonProd = await fs.readJson(appJsonPathProd);
|
|
165
|
+
appJsonProd.expo = appJsonProd.expo || {};
|
|
166
|
+
appJsonProd.expo.name = projectName;
|
|
167
|
+
appJsonProd.expo.slug = projectName.toLowerCase().replace(/\s+/g, "-");
|
|
168
|
+
appJsonProd.expo.ios = appJsonProd.expo.ios || {};
|
|
169
|
+
appJsonProd.expo.android = appJsonProd.expo.android || {};
|
|
170
|
+
appJsonProd.expo.ios.bundleIdentifier = `com.${projectName.toLowerCase()}.app`;
|
|
171
|
+
appJsonProd.expo.android.package = `com.${projectName.toLowerCase()}.app`;
|
|
172
|
+
appJsonProd.expo.scheme = projectName.toLowerCase();
|
|
173
|
+
if (appJsonProd.expo.extra && appJsonProd.expo.extra.eas) {
|
|
174
|
+
appJsonProd.expo.extra.eas.projectId = "";
|
|
175
|
+
}
|
|
176
|
+
appJsonProd.expo.extra.ENV = "production";
|
|
177
|
+
appJsonProd.expo.extra.BASE_URL = "";
|
|
178
|
+
await fs.writeJson(appJsonPathProd, appJsonProd, { spaces: 2 });
|
|
179
|
+
}
|
|
180
|
+
|
|
141
181
|
spinner.succeed(`✅ Template "${templateName}" berhasil dibuat!`);
|
|
142
182
|
} catch (err) {
|
|
143
183
|
spinner.fail("❌ Terjadi kesalahan saat membuat project.");
|
package/package.json
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"expo": {
|
|
3
|
+
"name": "APP_NAME",
|
|
4
|
+
"slug": "APP_SLUG",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"orientation": "portrait",
|
|
7
|
+
"icon": "./src/assets/images/icon.png",
|
|
8
|
+
"scheme": "myapp",
|
|
9
|
+
"userInterfaceStyle": "automatic",
|
|
10
|
+
"splash": {
|
|
11
|
+
"image": "./src/assets/images/splash-icon.png",
|
|
12
|
+
"resizeMode": "contain",
|
|
13
|
+
"backgroundColor": "#ffffff"
|
|
14
|
+
},
|
|
15
|
+
"assetBundlePatterns": ["**/*"],
|
|
16
|
+
"ios": {
|
|
17
|
+
"supportsTablet": true,
|
|
18
|
+
"bundleIdentifier": "com.yourname.APP_SLUG"
|
|
19
|
+
},
|
|
20
|
+
"android": {
|
|
21
|
+
"adaptiveIcon": {
|
|
22
|
+
"foregroundImage": "./src/assets/images/adaptive-icon.png",
|
|
23
|
+
"backgroundColor": "#ffffff"
|
|
24
|
+
},
|
|
25
|
+
"package": "com.yourname.APP_SLUG",
|
|
26
|
+
"versionCode": 1
|
|
27
|
+
},
|
|
28
|
+
"web": {
|
|
29
|
+
"bundler": "metro",
|
|
30
|
+
"output": "static",
|
|
31
|
+
"favicon": "./src/assets/images/favicon.png"
|
|
32
|
+
},
|
|
33
|
+
"plugins": [
|
|
34
|
+
"expo-router",
|
|
35
|
+
[
|
|
36
|
+
"expo-secure-store",
|
|
37
|
+
{
|
|
38
|
+
"requireFullDiskAccess": false
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
],
|
|
42
|
+
"experiments": {
|
|
43
|
+
"typedRoutes": true
|
|
44
|
+
},
|
|
45
|
+
"extra": {
|
|
46
|
+
"eas": {
|
|
47
|
+
"projectId": ""
|
|
48
|
+
},
|
|
49
|
+
"BASE_URL": "https://api.production.com",
|
|
50
|
+
"ENV": "production"
|
|
51
|
+
},
|
|
52
|
+
"updates": {
|
|
53
|
+
"enabled": true,
|
|
54
|
+
"checkAutomatically": "ON_LOAD"
|
|
55
|
+
},
|
|
56
|
+
"runtimeVersion": {
|
|
57
|
+
"policy": "sdkVersion"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"expo": {
|
|
3
|
+
"name": "APP_NAME",
|
|
4
|
+
"slug": "APP_SLUG",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"orientation": "portrait",
|
|
7
|
+
"icon": "./src/assets/images/icon.png",
|
|
8
|
+
"scheme": "myapp",
|
|
9
|
+
"userInterfaceStyle": "automatic",
|
|
10
|
+
"splash": {
|
|
11
|
+
"image": "./src/assets/images/splash-icon.png",
|
|
12
|
+
"resizeMode": "contain",
|
|
13
|
+
"backgroundColor": "#ffffff"
|
|
14
|
+
},
|
|
15
|
+
"assetBundlePatterns": ["**/*"],
|
|
16
|
+
"ios": {
|
|
17
|
+
"supportsTablet": true,
|
|
18
|
+
"bundleIdentifier": "com.yourname.APP_SLUG"
|
|
19
|
+
},
|
|
20
|
+
"android": {
|
|
21
|
+
"adaptiveIcon": {
|
|
22
|
+
"foregroundImage": "./src/assets/images/adaptive-icon.png",
|
|
23
|
+
"backgroundColor": "#ffffff"
|
|
24
|
+
},
|
|
25
|
+
"package": "com.yourname.APP_SLUG",
|
|
26
|
+
"versionCode": 1
|
|
27
|
+
},
|
|
28
|
+
"web": {
|
|
29
|
+
"bundler": "metro",
|
|
30
|
+
"output": "static",
|
|
31
|
+
"favicon": "./src/assets/images/favicon.png"
|
|
32
|
+
},
|
|
33
|
+
"plugins": [
|
|
34
|
+
"expo-router",
|
|
35
|
+
[
|
|
36
|
+
"expo-secure-store",
|
|
37
|
+
{
|
|
38
|
+
"requireFullDiskAccess": false
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
],
|
|
42
|
+
"experiments": {
|
|
43
|
+
"typedRoutes": true
|
|
44
|
+
},
|
|
45
|
+
"extra": {
|
|
46
|
+
"eas": {
|
|
47
|
+
"projectId": ""
|
|
48
|
+
},
|
|
49
|
+
"BASE_URL": "https://api.staging.com",
|
|
50
|
+
"ENV": "staging"
|
|
51
|
+
},
|
|
52
|
+
"updates": {
|
|
53
|
+
"enabled": true,
|
|
54
|
+
"checkAutomatically": "ON_LOAD"
|
|
55
|
+
},
|
|
56
|
+
"runtimeVersion": {
|
|
57
|
+
"policy": "sdkVersion"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cli": {
|
|
3
|
+
"version": ">= 3.0.0"
|
|
4
|
+
},
|
|
5
|
+
"build": {
|
|
6
|
+
"development": {
|
|
7
|
+
"distribution": "internal",
|
|
8
|
+
"developmentClient": true,
|
|
9
|
+
"autoIncrement": true,
|
|
10
|
+
"env": {
|
|
11
|
+
"APP_ENV": "development",
|
|
12
|
+
"API_BASE_URL": "http://localhost:3000"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"staging": {
|
|
16
|
+
"distribution": "internal",
|
|
17
|
+
"autoIncrement": true,
|
|
18
|
+
"env": {
|
|
19
|
+
"APP_ENV": "staging",
|
|
20
|
+
"API_BASE_URL": "https://api.staging.com"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"production": {
|
|
24
|
+
"distribution": "store",
|
|
25
|
+
"autoIncrement": true,
|
|
26
|
+
"env": {
|
|
27
|
+
"APP_ENV": "production",
|
|
28
|
+
"API_BASE_URL": "https://api.production.com"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"submit": {
|
|
33
|
+
"production": {
|
|
34
|
+
"android": {
|
|
35
|
+
"serviceAccountKeyPath": "./credentials/google-service-account.json"
|
|
36
|
+
},
|
|
37
|
+
"ios": {
|
|
38
|
+
"appleId": "you@example.com"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -4,23 +4,39 @@
|
|
|
4
4
|
"main": "expo-router/entry",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "expo start --clear",
|
|
7
|
+
"start:staging": "expo start --clear --config app.staging.json",
|
|
8
|
+
"start:prod": "expo start --clear --config app.prod.json",
|
|
7
9
|
"android": "expo start --android",
|
|
8
10
|
"ios": "expo start --ios",
|
|
9
11
|
"web": "expo start --web",
|
|
10
12
|
"lint": "eslint .",
|
|
11
|
-
"type-check": "tsc --noEmit"
|
|
13
|
+
"type-check": "tsc --noEmit",
|
|
14
|
+
|
|
15
|
+
"build": "eas build --profile development --platform all --local",
|
|
16
|
+
"build:staging": "eas build --profile staging --platform all --local --config app.staging.json",
|
|
17
|
+
"build:prod": "eas build --profile production --platform all --local --config app.prod.json",
|
|
18
|
+
|
|
19
|
+
"build:android": "eas build --profile development --platform android --local",
|
|
20
|
+
"build:ios": "eas build --profile development --platform ios --local",
|
|
21
|
+
|
|
22
|
+
"prebuild": "expo prebuild --clean",
|
|
23
|
+
"clean": "rm -rf node_modules && rm -rf .expo && rm -rf android && rm -rf ios && npm install"
|
|
12
24
|
},
|
|
13
25
|
"dependencies": {
|
|
14
26
|
"axios": "^1.7.2",
|
|
15
27
|
"babel-preset-expo": "^54.0.5",
|
|
16
28
|
"expo": "~54.0.0",
|
|
17
29
|
"expo-constants": "~18.0.9",
|
|
30
|
+
"expo-image-picker": "~17.0.8",
|
|
31
|
+
"expo-linear-gradient": "~15.0.7",
|
|
18
32
|
"expo-linking": "~8.0.8",
|
|
33
|
+
"expo-local-authentication": "~17.0.7",
|
|
19
34
|
"expo-router": "^6.0.12",
|
|
20
35
|
"expo-secure-store": "~15.0.7",
|
|
21
36
|
"expo-status-bar": "~3.0.8",
|
|
22
37
|
"lucide-react-native": "^0.546.0",
|
|
23
|
-
"
|
|
38
|
+
"metro-config": "^0.83.3",
|
|
39
|
+
"nativewind": "^4.0.36",
|
|
24
40
|
"react": "19.1.0",
|
|
25
41
|
"react-dom": "19.1.0",
|
|
26
42
|
"react-native": "^0.81.4",
|
|
@@ -28,27 +44,33 @@
|
|
|
28
44
|
"react-native-reanimated": "~4.1.1",
|
|
29
45
|
"react-native-safe-area-context": "~5.6.0",
|
|
30
46
|
"react-native-screens": "~4.16.0",
|
|
31
|
-
"react-native-worklets": "0.5.1",
|
|
32
47
|
"react-native-svg": "15.12.1",
|
|
33
48
|
"react-native-toast-message": "^2.3.3",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
49
|
+
"react-native-web": "^0.21.0",
|
|
50
|
+
"react-native-worklets": "0.5.1"
|
|
36
51
|
},
|
|
37
52
|
"devDependencies": {
|
|
38
53
|
"@babel/core": "^7.26.0",
|
|
54
|
+
"@babel/plugin-transform-react-jsx": "^7.27.1",
|
|
39
55
|
"@types/react": "~19.1.10",
|
|
40
56
|
"@types/react-native": "^0.73.0",
|
|
41
57
|
"babel-plugin-module-resolver": "^5.0.2",
|
|
42
58
|
"eslint": "^9.12.0",
|
|
43
59
|
"eslint-config-prettier": "^9.1.0",
|
|
44
60
|
"prettier": "^3.3.3",
|
|
61
|
+
"react-refresh": "^0.18.0",
|
|
45
62
|
"tailwindcss": "^3.4.13",
|
|
46
63
|
"typescript": "~5.9.2"
|
|
47
64
|
},
|
|
48
65
|
"private": true,
|
|
49
66
|
"expo": {
|
|
50
67
|
"install": {
|
|
51
|
-
"exclude": [
|
|
68
|
+
"exclude": [
|
|
69
|
+
"react",
|
|
70
|
+
"expo",
|
|
71
|
+
"expo-constants",
|
|
72
|
+
"react-native"
|
|
73
|
+
]
|
|
52
74
|
}
|
|
53
75
|
}
|
|
54
|
-
}
|
|
76
|
+
}
|
|
@@ -4,13 +4,14 @@ const extra = Constants.expoConfig?.extra || {};
|
|
|
4
4
|
|
|
5
5
|
export const APP_CONFIG = {
|
|
6
6
|
NAME: extra.APP_NAME || Constants.expoConfig?.name || 'Default App',
|
|
7
|
-
BASE_URL: extra.BASE_URL
|
|
7
|
+
BASE_URL: extra.BASE_URL,
|
|
8
|
+
MOCK_API: !["staging", "production"].includes(extra.ENV)
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
export const API_CONFIG = {
|
|
11
12
|
BASE_URL: APP_CONFIG.BASE_URL,
|
|
12
13
|
TIMEOUT: 10000,
|
|
13
|
-
MOCK_API:
|
|
14
|
+
MOCK_API: APP_CONFIG.MOCK_API
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
export const ROUTES = {
|
package/templates/{simple/app/(admin)/profile.tsx → default_draft/app/(admin)/draft_profile.tsx}
RENAMED
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
Image,
|
|
12
12
|
} from 'react-native';
|
|
13
13
|
import { User, Mail, Phone, MapPin, Calendar, Edit2, Save, X } from 'lucide-react-native';
|
|
14
|
-
import { useTheme } from '@/hooks/
|
|
15
|
-
import { useAuth } from '@/hooks/
|
|
16
|
-
import { useUsers } from '@/hooks/
|
|
14
|
+
import { useTheme } from '@/hooks/draft_useTheme';
|
|
15
|
+
import { useAuth } from '@/hooks/draft_useAuth';
|
|
16
|
+
import { useUsers } from '@/hooks/draft_useUsers';
|
|
17
17
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
18
|
-
import { AppHeader } from '@/components/header/
|
|
18
|
+
import { AppHeader } from '@/components/header/draft_AppHeader';
|
|
19
19
|
import { useRouter } from 'expo-router';
|
|
20
|
-
import { UpdateUserInput } from '@/types/
|
|
20
|
+
import { UpdateUserInput } from '@/types/draft_user.types';
|
|
21
21
|
|
|
22
22
|
export default function ProfileScreen() {
|
|
23
23
|
const { colors } = useTheme();
|
|
@@ -12,15 +12,15 @@ import {
|
|
|
12
12
|
FlatList,
|
|
13
13
|
} from 'react-native';
|
|
14
14
|
import { Search, UserPlus, Filter, X } from 'lucide-react-native';
|
|
15
|
-
import { useTheme } from '
|
|
16
|
-
import { CreateUserInput, UpdateUserInput } from '@/types/
|
|
15
|
+
import { useTheme } from '@/hooks/draft_useTheme';
|
|
16
|
+
import { CreateUserInput, UpdateUserInput } from '@/types/draft_user.types';
|
|
17
17
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
18
|
-
import { AppHeader } from '@/components/header/
|
|
18
|
+
import { AppHeader } from '@/components/header/draft_AppHeader';
|
|
19
19
|
import { useRouter } from 'expo-router';
|
|
20
20
|
import Toast from 'react-native-toast-message';
|
|
21
21
|
|
|
22
22
|
// Custom Hook
|
|
23
|
-
import { useUsers } from '@/hooks/
|
|
23
|
+
import { useUsers } from '@/hooks/draft_useUsers';
|
|
24
24
|
|
|
25
25
|
// Components
|
|
26
26
|
import { UserCard } from '@/components/users/UserCard';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Slot, useRouter } from 'expo-router';
|
|
2
2
|
import { useContext, useEffect } from 'react';
|
|
3
3
|
import { View, ActivityIndicator } from 'react-native';
|
|
4
|
-
import { AuthContext } from '@/contexts/
|
|
4
|
+
import { AuthContext } from '@/contexts/draft_AuthContext';
|
|
5
5
|
|
|
6
6
|
export default function AuthLayout() {
|
|
7
7
|
const { isAuthenticated, isLoading } = useContext(AuthContext);
|
|
@@ -9,7 +9,7 @@ export default function AuthLayout() {
|
|
|
9
9
|
|
|
10
10
|
useEffect(() => {
|
|
11
11
|
if (!isLoading && isAuthenticated) {
|
|
12
|
-
router.replace('/(protected)/
|
|
12
|
+
router.replace('/(protected)/draft_home'); // atau '/(tabs)' kalau kamu pakai tab navigation
|
|
13
13
|
}
|
|
14
14
|
}, [isLoading, isAuthenticated]);
|
|
15
15
|
|
|
@@ -16,12 +16,12 @@ import { Link } from 'expo-router';
|
|
|
16
16
|
import { Mail, Lock, Eye, EyeOff, LogIn, Sparkles, TentTree, Biohazard, Fingerprint } from 'lucide-react-native';
|
|
17
17
|
import * as LocalAuthentication from 'expo-local-authentication';
|
|
18
18
|
import * as SecureStore from 'expo-secure-store';
|
|
19
|
-
import { useAuth } from '@/hooks/
|
|
20
|
-
import { useTheme } from '@/hooks/
|
|
19
|
+
import { useAuth } from '@/hooks/draft_useAuth';
|
|
20
|
+
import { useTheme } from '@/hooks/draft_useTheme';
|
|
21
21
|
import { Button } from '@/components/common/Button';
|
|
22
|
-
import {
|
|
23
|
-
import { APP_CONFIG } from '@/utils/constants';
|
|
22
|
+
import { APP_CONFIG } from '@/utils/draft_constants';
|
|
24
23
|
import Toast from 'react-native-toast-message';
|
|
24
|
+
import { validation } from '@/utils/draft_validation';
|
|
25
25
|
|
|
26
26
|
const { width, height } = Dimensions.get('window');
|
|
27
27
|
|
|
@@ -525,7 +525,7 @@ export default function LoginScreen() {
|
|
|
525
525
|
<Text style={[styles.signUpText, { color: colors.textSecondary }]}>
|
|
526
526
|
Don't have an account?{' '}
|
|
527
527
|
</Text>
|
|
528
|
-
<Link href="/(auth)/
|
|
528
|
+
<Link href="/(auth)/draft_register" asChild>
|
|
529
529
|
<TouchableOpacity activeOpacity={0.7}>
|
|
530
530
|
<Text style={[styles.signUpLink, { color: colors.primary }]}>
|
|
531
531
|
Sign Up
|
package/templates/{simple/app/(auth)/register.tsx → default_draft/app/(auth)/draft_register.tsx}
RENAMED
|
@@ -14,10 +14,10 @@ import {
|
|
|
14
14
|
} from 'react-native';
|
|
15
15
|
import { Link } from 'expo-router';
|
|
16
16
|
import { User, Mail, Lock, Eye, EyeOff, UserPlus, Sparkles, CheckCircle2 } from 'lucide-react-native';
|
|
17
|
-
import { useAuth } from '@/hooks/
|
|
18
|
-
import { useTheme } from '@/hooks/
|
|
17
|
+
import { useAuth } from '@/hooks/draft_useAuth';
|
|
18
|
+
import { useTheme } from '@/hooks/draft_useTheme';
|
|
19
19
|
import { Button } from '@/components/common/Button';
|
|
20
|
-
import { validation } from '@/utils/
|
|
20
|
+
import { validation } from '@/utils/draft_validation';
|
|
21
21
|
|
|
22
22
|
const { width, height } = Dimensions.get('window');
|
|
23
23
|
|
|
@@ -340,7 +340,7 @@ export default function RegisterScreen() {
|
|
|
340
340
|
<Text style={[styles.signInText, { color: colors.textSecondary }]}>
|
|
341
341
|
Already have an account?{' '}
|
|
342
342
|
</Text>
|
|
343
|
-
<Link href="/(auth)/
|
|
343
|
+
<Link href="/(auth)/draft_register" asChild>
|
|
344
344
|
<TouchableOpacity activeOpacity={0.7}>
|
|
345
345
|
<Text style={[styles.signInLink, { color: colors.primary }]}>
|
|
346
346
|
Sign In
|
|
@@ -3,8 +3,8 @@ import { View, Text, TouchableOpacity, StyleSheet, Platform } from 'react-native
|
|
|
3
3
|
import { Tabs, Redirect } from 'expo-router';
|
|
4
4
|
import { Home, User, Settings } from 'lucide-react-native';
|
|
5
5
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
6
|
-
import { useTheme } from '@/hooks/
|
|
7
|
-
import { useAuth } from '@/hooks/
|
|
6
|
+
import { useTheme } from '@/hooks/draft_useTheme';
|
|
7
|
+
import { useAuth } from '@/hooks/draft_useAuth';
|
|
8
8
|
|
|
9
9
|
export default function MainLayout() {
|
|
10
10
|
const { colors } = useTheme();
|
|
@@ -13,7 +13,7 @@ export default function MainLayout() {
|
|
|
13
13
|
|
|
14
14
|
// Redirect to login if not authenticated
|
|
15
15
|
if (!isAuthenticated) {
|
|
16
|
-
return <Redirect href="/(auth)/
|
|
16
|
+
return <Redirect href="/(auth)/draft_login" />;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// Check if user is admin
|
|
@@ -48,7 +48,7 @@ export default function MainLayout() {
|
|
|
48
48
|
}}
|
|
49
49
|
>
|
|
50
50
|
<Tabs.Screen
|
|
51
|
-
name="
|
|
51
|
+
name="draft_home"
|
|
52
52
|
options={{
|
|
53
53
|
title: 'Home',
|
|
54
54
|
tabBarIcon: ({ color, focused }) => (
|
|
@@ -63,7 +63,7 @@ export default function MainLayout() {
|
|
|
63
63
|
/>
|
|
64
64
|
|
|
65
65
|
<Tabs.Screen
|
|
66
|
-
name="
|
|
66
|
+
name="draft_settings"
|
|
67
67
|
options={{
|
|
68
68
|
title: 'Settings',
|
|
69
69
|
tabBarIcon: ({ color, focused }) => (
|
package/templates/{simple/app/(protected)/home.tsx → default_draft/app/(protected)/draft_home.tsx}
RENAMED
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
ActivityIndicator,
|
|
9
9
|
Dimensions,
|
|
10
10
|
} from 'react-native';
|
|
11
|
-
import { useTheme } from '@/hooks/
|
|
12
|
-
import { useAuth } from '@/hooks/
|
|
11
|
+
import { useTheme } from '@/hooks/draft_useTheme';
|
|
12
|
+
import { useAuth } from '@/hooks/draft_useAuth';
|
|
13
13
|
import { useRouter } from 'expo-router';
|
|
14
14
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
15
|
-
import { AppHeader } from '@/components/header/
|
|
15
|
+
import { AppHeader } from '@/components/header/draft_AppHeader';
|
|
16
16
|
import Toast from 'react-native-toast-message';
|
|
17
17
|
|
|
18
18
|
const { width } = Dimensions.get('window');
|
|
@@ -55,7 +55,7 @@ export default function HomeScreen() {
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
const handleProfilePress = () => {
|
|
58
|
-
router.push('/(protected)/
|
|
58
|
+
router.push('/(protected)/draft_settings');
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
|
|
@@ -21,10 +21,10 @@ import {
|
|
|
21
21
|
Globe,
|
|
22
22
|
User,
|
|
23
23
|
} from 'lucide-react-native';
|
|
24
|
-
import { useTheme } from '
|
|
25
|
-
import { useAuth } from '
|
|
24
|
+
import { useTheme } from '@/hooks/draft_useTheme';
|
|
25
|
+
import { useAuth } from '@/hooks/draft_useAuth';
|
|
26
26
|
import { useRouter } from 'expo-router';
|
|
27
|
-
import { AppHeader } from '@/components/header/
|
|
27
|
+
import { AppHeader } from '@/components/header/draft_AppHeader';
|
|
28
28
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
29
29
|
|
|
30
30
|
export default function SettingsScreen() {
|
|
@@ -49,7 +49,7 @@ export default function SettingsScreen() {
|
|
|
49
49
|
style: 'destructive',
|
|
50
50
|
onPress: async () => {
|
|
51
51
|
await logout();
|
|
52
|
-
router.replace('/(auth)/
|
|
52
|
+
router.replace('/(auth)/draft_login');
|
|
53
53
|
},
|
|
54
54
|
},
|
|
55
55
|
]
|
|
@@ -133,7 +133,7 @@ export default function SettingsScreen() {
|
|
|
133
133
|
icon={User}
|
|
134
134
|
title="My Profile"
|
|
135
135
|
subtitle="Manage your personal information"
|
|
136
|
-
onPress={() => router.push('/(admin)/
|
|
136
|
+
onPress={() => router.push('/(admin)/draft_profile')}
|
|
137
137
|
/>
|
|
138
138
|
</SettingSection>
|
|
139
139
|
|
|
@@ -202,7 +202,7 @@ export default function SettingsScreen() {
|
|
|
202
202
|
icon={Users}
|
|
203
203
|
title="User Management"
|
|
204
204
|
subtitle="Manage users and permissions"
|
|
205
|
-
onPress={() => router.push('/(admin)/
|
|
205
|
+
onPress={() => router.push('/(admin)/draft_userManagement')}
|
|
206
206
|
/>
|
|
207
207
|
<SettingItem
|
|
208
208
|
icon={Globe}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Stack } from 'expo-router';
|
|
2
|
-
import { AuthProvider } from '@/contexts/
|
|
3
|
-
import { ThemeProvider } from '
|
|
2
|
+
import { AuthProvider } from '@/contexts/draft_AuthContext';
|
|
3
|
+
import { ThemeProvider } from '@/contexts/draft_ThemeContext';
|
|
4
4
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
5
5
|
import '../global.css';
|
|
6
6
|
import Toast from 'react-native-toast-message';
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { View, Text, StyleSheet, ActivityIndicator } from 'react-native';
|
|
4
4
|
import { Redirect } from 'expo-router';
|
|
5
|
-
import { useAuth } from '@/hooks/
|
|
6
|
-
import { useTheme } from '@/hooks/
|
|
5
|
+
import { useAuth } from '@/hooks/draft_useAuth';
|
|
6
|
+
import { useTheme } from '@/hooks/draft_useTheme';
|
|
7
7
|
import { ShieldAlert } from 'lucide-react-native';
|
|
8
8
|
|
|
9
9
|
interface ProtectedRouteProps {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { View, TextInput, Text, TouchableOpacity, TextInputProps } from 'react-native';
|
|
3
|
-
import { useTheme } from '
|
|
3
|
+
import { useTheme } from '@/hooks/draft_useTheme';
|
|
4
4
|
|
|
5
5
|
interface InputProps extends TextInputProps {
|
|
6
6
|
label?: string;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import React, { useState } from 'react';
|
|
3
3
|
import { View, Text, Modal, TouchableOpacity, StyleSheet } from 'react-native';
|
|
4
4
|
import { X } from 'lucide-react-native';
|
|
5
|
-
import { UserFilters } from '@/types/
|
|
5
|
+
import { UserFilters } from '@/types/draft_user.types';
|
|
6
6
|
|
|
7
7
|
interface FilterModalProps {
|
|
8
8
|
visible: boolean;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { View, Text, TouchableOpacity, StyleSheet, Image } from 'react-native';
|
|
4
4
|
import { MoreVertical, Edit2, Shield, Trash2 } from 'lucide-react-native';
|
|
5
|
-
import { UserData } from '@/types/
|
|
5
|
+
import { UserData } from '@/types/draft_user.types';
|
|
6
6
|
|
|
7
7
|
interface UserCardProps {
|
|
8
8
|
user: UserData;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import React, { useState, useEffect } from 'react';
|
|
3
3
|
import { View, Text, Modal, TouchableOpacity, StyleSheet, ActivityIndicator } from 'react-native';
|
|
4
4
|
import { X } from 'lucide-react-native';
|
|
5
|
-
import { CreateUserInput, UpdateUserInput } from '@/types/
|
|
5
|
+
import { CreateUserInput, UpdateUserInput } from '@/types/draft_user.types';
|
|
6
6
|
import Toast from 'react-native-toast-message';
|
|
7
7
|
import { FormInput } from '@/components/shared/FormInput';
|
|
8
8
|
import { RoleSelector } from '@/components/shared/RoleSelector';
|