@highbeek/create-rnstarterkit 1.0.0 → 1.0.1-beta.0

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.
Files changed (121) hide show
  1. package/dist/bin/create-rnstarterkit.js +21 -7
  2. package/dist/src/generators/appGenerator.js +976 -60
  3. package/dist/templates/cli-base/.bundle/config +2 -0
  4. package/dist/templates/cli-base/.eslintrc.js +4 -0
  5. package/dist/templates/cli-base/.prettierrc.js +5 -0
  6. package/dist/templates/cli-base/.watchmanconfig +1 -0
  7. package/dist/templates/cli-base/App.tsx +45 -0
  8. package/dist/templates/cli-base/Gemfile +16 -0
  9. package/dist/templates/cli-base/Gemfile.lock +169 -0
  10. package/dist/templates/cli-base/README.md +97 -0
  11. package/dist/templates/cli-base/__tests__/App.test.tsx +13 -0
  12. package/dist/templates/cli-base/android/app/build.gradle +119 -0
  13. package/dist/templates/cli-base/android/app/debug.keystore +0 -0
  14. package/dist/templates/cli-base/android/app/proguard-rules.pro +10 -0
  15. package/dist/templates/cli-base/android/app/src/main/AndroidManifest.xml +27 -0
  16. package/dist/templates/cli-base/android/app/src/main/java/com/baseapp/MainActivity.kt +22 -0
  17. package/dist/templates/cli-base/android/app/src/main/java/com/baseapp/MainApplication.kt +27 -0
  18. package/dist/templates/cli-base/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  19. package/dist/templates/cli-base/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  20. package/dist/templates/cli-base/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  21. package/dist/templates/cli-base/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  22. package/dist/templates/cli-base/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  23. package/dist/templates/cli-base/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  24. package/dist/templates/cli-base/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  25. package/dist/templates/cli-base/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  26. package/dist/templates/cli-base/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  27. package/dist/templates/cli-base/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  28. package/dist/templates/cli-base/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  29. package/dist/templates/cli-base/android/app/src/main/res/values/strings.xml +3 -0
  30. package/dist/templates/cli-base/android/app/src/main/res/values/styles.xml +9 -0
  31. package/dist/templates/cli-base/android/build.gradle +21 -0
  32. package/dist/templates/cli-base/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  33. package/dist/templates/cli-base/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  34. package/dist/templates/cli-base/android/gradle.properties +44 -0
  35. package/dist/templates/cli-base/android/gradlew +251 -0
  36. package/dist/templates/cli-base/android/gradlew.bat +99 -0
  37. package/dist/templates/cli-base/android/settings.gradle +6 -0
  38. package/dist/templates/cli-base/app.json +4 -0
  39. package/dist/templates/cli-base/babel.config.js +3 -0
  40. package/dist/templates/cli-base/index.js +9 -0
  41. package/dist/templates/cli-base/ios/.xcode.env +11 -0
  42. package/dist/templates/cli-base/ios/BaseApp/AppDelegate.swift +48 -0
  43. package/dist/templates/cli-base/ios/BaseApp/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  44. package/dist/templates/cli-base/ios/BaseApp/Images.xcassets/Contents.json +6 -0
  45. package/dist/templates/cli-base/ios/BaseApp/Info.plist +60 -0
  46. package/dist/templates/cli-base/ios/BaseApp/LaunchScreen.storyboard +47 -0
  47. package/dist/templates/cli-base/ios/BaseApp/PrivacyInfo.xcprivacy +37 -0
  48. package/dist/templates/cli-base/ios/BaseApp.xcodeproj/project.pbxproj +494 -0
  49. package/dist/templates/cli-base/ios/BaseApp.xcodeproj/xcshareddata/xcschemes/BaseApp.xcscheme +88 -0
  50. package/dist/templates/cli-base/ios/BaseApp.xcworkspace/contents.xcworkspacedata +10 -0
  51. package/dist/templates/cli-base/ios/Podfile +34 -0
  52. package/dist/templates/cli-base/ios/Podfile.lock +2165 -0
  53. package/dist/templates/cli-base/jest.config.js +3 -0
  54. package/dist/templates/cli-base/metro.config.js +11 -0
  55. package/dist/templates/cli-base/package-lock.json +11859 -0
  56. package/dist/templates/cli-base/package.json +41 -0
  57. package/dist/templates/cli-base/tsconfig.json +8 -0
  58. package/dist/templates/expo-base/.vscode/extensions.json +1 -0
  59. package/dist/templates/expo-base/.vscode/settings.json +7 -0
  60. package/dist/templates/expo-base/README.md +50 -0
  61. package/dist/templates/expo-base/app/_layout.tsx +12 -0
  62. package/dist/templates/expo-base/app/index.tsx +9 -0
  63. package/dist/templates/expo-base/app.json +48 -0
  64. package/dist/templates/expo-base/assets/images/android-icon-background.png +0 -0
  65. package/dist/templates/expo-base/assets/images/android-icon-foreground.png +0 -0
  66. package/dist/templates/expo-base/assets/images/android-icon-monochrome.png +0 -0
  67. package/dist/templates/expo-base/assets/images/favicon.png +0 -0
  68. package/dist/templates/expo-base/assets/images/icon.png +0 -0
  69. package/dist/templates/expo-base/assets/images/partial-react-logo.png +0 -0
  70. package/dist/templates/expo-base/assets/images/react-logo.png +0 -0
  71. package/dist/templates/expo-base/assets/images/react-logo@2x.png +0 -0
  72. package/dist/templates/expo-base/assets/images/react-logo@3x.png +0 -0
  73. package/dist/templates/expo-base/assets/images/splash-icon.png +0 -0
  74. package/dist/templates/expo-base/components/ui/collapsible.tsx +45 -0
  75. package/dist/templates/expo-base/components/ui/icon-symbol.ios.tsx +32 -0
  76. package/dist/templates/expo-base/components/ui/icon-symbol.tsx +41 -0
  77. package/dist/templates/expo-base/eslint.config.js +10 -0
  78. package/dist/templates/expo-base/package-lock.json +12916 -0
  79. package/dist/templates/expo-base/package.json +46 -0
  80. package/dist/templates/expo-base/tsconfig.json +17 -0
  81. package/dist/templates/optional/apiClient/api/client.ts +142 -0
  82. package/dist/templates/optional/apiClient/api/index.ts +1 -0
  83. package/dist/templates/optional/apiClient/config/env.cli.ts +5 -0
  84. package/dist/templates/optional/apiClient/config/env.expo.ts +4 -0
  85. package/dist/templates/optional/apiClient/config/env.ts +1 -0
  86. package/dist/templates/optional/apiClient/env.d.ts +3 -0
  87. package/dist/templates/optional/auth-context/api/endpoints/auth.ts +14 -0
  88. package/dist/templates/optional/auth-context/context/AuthContext.tsx +47 -0
  89. package/dist/templates/optional/auth-context/navigation/ProtectedStack.tsx +38 -0
  90. package/dist/templates/optional/auth-context/navigation/cli/BottomTabs.tsx +17 -0
  91. package/dist/templates/optional/auth-context/navigation/expo/BottomTabs.tsx +29 -0
  92. package/dist/templates/optional/auth-context/screens/HomeScreen.tsx +15 -0
  93. package/dist/templates/optional/auth-context/screens/LoginScreen.tsx +63 -0
  94. package/dist/templates/optional/auth-context/screens/ProfileScreen.tsx +11 -0
  95. package/dist/templates/optional/auth-context/screens/RegisterScreen.tsx +63 -0
  96. package/dist/templates/optional/auth-context/screens/SettingsScreen.tsx +11 -0
  97. package/dist/templates/optional/auth-context/utils/storage.ts +13 -0
  98. package/dist/templates/optional/auth-redux/api/endpoints/auth.ts +14 -0
  99. package/dist/templates/optional/auth-redux/navigation/ProtectedStack.tsx +30 -0
  100. package/dist/templates/optional/auth-redux/navigation/cli/BottomTabs.tsx +17 -0
  101. package/dist/templates/optional/auth-redux/navigation/expo/BottomTabs.tsx +31 -0
  102. package/dist/templates/optional/auth-redux/screens/HomeScreen.tsx +16 -0
  103. package/dist/templates/optional/auth-redux/screens/LoginScreen.tsx +64 -0
  104. package/dist/templates/optional/auth-redux/screens/ProfileScreen.tsx +15 -0
  105. package/dist/templates/optional/auth-redux/screens/RegisterScreen.tsx +64 -0
  106. package/dist/templates/optional/auth-redux/screens/SettingsScreen.tsx +15 -0
  107. package/dist/templates/optional/auth-redux/store/authSlice.ts +25 -0
  108. package/dist/templates/optional/auth-redux/store/store.ts +11 -0
  109. package/dist/templates/optional/auth-zustand/api/endpoints/auth.ts +14 -0
  110. package/dist/templates/optional/auth-zustand/navigation/BottomTabs.tsx +1 -0
  111. package/dist/templates/optional/auth-zustand/navigation/ProtectedStack.tsx +44 -0
  112. package/dist/templates/optional/auth-zustand/navigation/cli/BottomTabs.tsx +17 -0
  113. package/dist/templates/optional/auth-zustand/navigation/expo/BottomTabs.tsx +31 -0
  114. package/dist/templates/optional/auth-zustand/screens/HomeScreen.tsx +15 -0
  115. package/dist/templates/optional/auth-zustand/screens/LoginScreen.tsx +63 -0
  116. package/dist/templates/optional/auth-zustand/screens/ProfileScreen.tsx +11 -0
  117. package/dist/templates/optional/auth-zustand/screens/RegisterScreen.tsx +63 -0
  118. package/dist/templates/optional/auth-zustand/screens/SettingsScreen.tsx +11 -0
  119. package/dist/templates/optional/auth-zustand/store/authStore.ts +30 -0
  120. package/dist/templates/optional/auth-zustand/utils/storage.ts +13 -0
  121. package/package.json +2 -2
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { Text, Button } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { useDispatch } from "react-redux";
5
+ import { logout } from "../store/authSlice";
6
+
7
+ export default function HomeScreen() {
8
+ const dispatch = useDispatch();
9
+
10
+ return (
11
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
12
+ <Text>Welcome Home!</Text>
13
+ <Button title="Logout" onPress={() => dispatch(logout())} />
14
+ </SafeAreaView>
15
+ );
16
+ }
@@ -0,0 +1,64 @@
1
+ import React, { useState } from "react";
2
+ import { TextInput, Button, Text } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { useDispatch } from "react-redux";
5
+ import { login } from "../store/authSlice";
6
+ import { loginApi } from "../api";
7
+
8
+ export default function LoginScreen() {
9
+ const dispatch = useDispatch();
10
+ const [email, setEmail] = useState("");
11
+ const [password, setPassword] = useState("");
12
+ const [error, setError] = useState("");
13
+
14
+ const handleLogin = async () => {
15
+ try {
16
+ setError("");
17
+ const token = await loginApi(email, password);
18
+ dispatch(login(token));
19
+ } catch (err) {
20
+ setError(err instanceof Error ? err.message : "Login failed");
21
+ }
22
+ };
23
+
24
+ return (
25
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
26
+ <TextInput
27
+ placeholder="Email"
28
+ value={email}
29
+ onChangeText={setEmail}
30
+ autoCapitalize="none"
31
+ autoCorrect={false}
32
+ keyboardType="email-address"
33
+ placeholderTextColor="#888"
34
+ style={{
35
+ borderWidth: 1,
36
+ borderColor: "#ccc",
37
+ borderRadius: 8,
38
+ paddingHorizontal: 12,
39
+ paddingVertical: 10,
40
+ color: "#111",
41
+ marginBottom: 12,
42
+ }}
43
+ />
44
+ <TextInput
45
+ placeholder="Password"
46
+ value={password}
47
+ onChangeText={setPassword}
48
+ secureTextEntry
49
+ placeholderTextColor="#888"
50
+ style={{
51
+ borderWidth: 1,
52
+ borderColor: "#ccc",
53
+ borderRadius: 8,
54
+ paddingHorizontal: 12,
55
+ paddingVertical: 10,
56
+ color: "#111",
57
+ marginBottom: 12,
58
+ }}
59
+ />
60
+ {!!error && <Text style={{ color: "red", marginBottom: 8 }}>{error}</Text>}
61
+ <Button title="Login" onPress={() => void handleLogin()} />
62
+ </SafeAreaView>
63
+ );
64
+ }
@@ -0,0 +1,15 @@
1
+ import { StyleSheet, Text } from 'react-native';
2
+ import { SafeAreaView } from 'react-native-safe-area-context'
3
+ import React from 'react'
4
+
5
+ const ProfileScreen = () => {
6
+ return (
7
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
8
+ <Text>ProfileScreen</Text>
9
+ </SafeAreaView>
10
+ )
11
+ }
12
+
13
+ export default ProfileScreen
14
+
15
+ const styles = StyleSheet.create({})
@@ -0,0 +1,64 @@
1
+ import React, { useState } from "react";
2
+ import { TextInput, Button, Text } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { useDispatch } from "react-redux";
5
+ import { login } from "../store/authSlice";
6
+ import { registerApi } from "../api";
7
+
8
+ export default function RegisterScreen() {
9
+ const dispatch = useDispatch();
10
+ const [email, setEmail] = useState("");
11
+ const [password, setPassword] = useState("");
12
+ const [error, setError] = useState("");
13
+
14
+ const handleRegister = async () => {
15
+ try {
16
+ setError("");
17
+ const token = await registerApi(email, password);
18
+ dispatch(login(token));
19
+ } catch (err) {
20
+ setError(err instanceof Error ? err.message : "Registration failed");
21
+ }
22
+ };
23
+
24
+ return (
25
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
26
+ <TextInput
27
+ placeholder="Email"
28
+ value={email}
29
+ onChangeText={setEmail}
30
+ autoCapitalize="none"
31
+ autoCorrect={false}
32
+ keyboardType="email-address"
33
+ placeholderTextColor="#888"
34
+ style={{
35
+ borderWidth: 1,
36
+ borderColor: "#ccc",
37
+ borderRadius: 8,
38
+ paddingHorizontal: 12,
39
+ paddingVertical: 10,
40
+ color: "#111",
41
+ marginBottom: 12,
42
+ }}
43
+ />
44
+ <TextInput
45
+ placeholder="Password"
46
+ value={password}
47
+ onChangeText={setPassword}
48
+ secureTextEntry
49
+ placeholderTextColor="#888"
50
+ style={{
51
+ borderWidth: 1,
52
+ borderColor: "#ccc",
53
+ borderRadius: 8,
54
+ paddingHorizontal: 12,
55
+ paddingVertical: 10,
56
+ color: "#111",
57
+ marginBottom: 12,
58
+ }}
59
+ />
60
+ {!!error && <Text style={{ color: "red", marginBottom: 8 }}>{error}</Text>}
61
+ <Button title="Register" onPress={() => void handleRegister()} />
62
+ </SafeAreaView>
63
+ );
64
+ }
@@ -0,0 +1,15 @@
1
+ import { StyleSheet, Text } from "react-native";
2
+ import { SafeAreaView } from "react-native-safe-area-context";
3
+ import React from "react";
4
+
5
+ const SettingsScreen = () => {
6
+ return (
7
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
8
+ <Text>SettingsScreen</Text>
9
+ </SafeAreaView>
10
+ );
11
+ };
12
+
13
+ export default SettingsScreen;
14
+
15
+ const styles = StyleSheet.create({});
@@ -0,0 +1,25 @@
1
+ import { createSlice, PayloadAction } from "@reduxjs/toolkit";
2
+
3
+ interface AuthState {
4
+ token: string | null;
5
+ }
6
+
7
+ const initialState: AuthState = {
8
+ token: null,
9
+ };
10
+
11
+ const authSlice = createSlice({
12
+ name: "auth",
13
+ initialState,
14
+ reducers: {
15
+ login(state, action: PayloadAction<string>) {
16
+ state.token = action.payload;
17
+ },
18
+ logout(state) {
19
+ state.token = null;
20
+ },
21
+ },
22
+ });
23
+
24
+ export const { login, logout } = authSlice.actions;
25
+ export default authSlice.reducer;
@@ -0,0 +1,11 @@
1
+ import { configureStore } from "@reduxjs/toolkit";
2
+ import authReducer from "./authSlice";
3
+
4
+ export const store = configureStore({
5
+ reducer: {
6
+ auth: authReducer,
7
+ },
8
+ });
9
+
10
+ export type RootState = ReturnType<typeof store.getState>;
11
+ export type AppDispatch = typeof store.dispatch;
@@ -0,0 +1,14 @@
1
+ function assertCredentials(email: string, password: string) {
2
+ if (!email.trim()) throw new Error("Email is required");
3
+ if (!password.trim()) throw new Error("Password is required");
4
+ }
5
+
6
+ export const loginApi = async (email: string, password: string) => {
7
+ assertCredentials(email, password);
8
+ return `demo-token-${email.trim().toLowerCase()}`;
9
+ };
10
+
11
+ export const registerApi = async (email: string, password: string) => {
12
+ assertCredentials(email, password);
13
+ return `demo-token-${email.trim().toLowerCase()}`;
14
+ };
@@ -0,0 +1 @@
1
+ export { default } from "./cli/BottomTabs";
@@ -0,0 +1,44 @@
1
+ import React, { useEffect } from "react";
2
+ import { ActivityIndicator, View } from "react-native";
3
+ import { createNativeStackNavigator } from "@react-navigation/native-stack";
4
+ import LoginScreen from "../screens/LoginScreen";
5
+ import RegisterScreen from "../screens/RegisterScreen";
6
+ import BottomTabs from "./BottomTabs";
7
+ import { useAuthStore } from "../store/authStore";
8
+
9
+ const Stack = createNativeStackNavigator();
10
+
11
+ export default function ProtectedStack() {
12
+ const token = useAuthStore((state) => state.token);
13
+ const isHydrated = useAuthStore((state) => state.isHydrated);
14
+ const hydrate = useAuthStore((state) => state.hydrate);
15
+
16
+ useEffect(() => {
17
+ void hydrate();
18
+ }, [hydrate]);
19
+
20
+ if (!isHydrated) {
21
+ return (
22
+ <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
23
+ <ActivityIndicator />
24
+ </View>
25
+ );
26
+ }
27
+
28
+ return (
29
+ <Stack.Navigator>
30
+ {token ? (
31
+ <Stack.Screen
32
+ name="Main"
33
+ component={BottomTabs}
34
+ options={{ headerShown: false }}
35
+ />
36
+ ) : (
37
+ <>
38
+ <Stack.Screen name="Login" component={LoginScreen} />
39
+ <Stack.Screen name="Register" component={RegisterScreen} />
40
+ </>
41
+ )}
42
+ </Stack.Navigator>
43
+ );
44
+ }
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
3
+ import HomeScreen from "../../screens/HomeScreen";
4
+ import ProfileScreen from "../../screens/ProfileScreen";
5
+ import SettingsScreen from "../../screens/SettingsScreen";
6
+
7
+ const Tab = createBottomTabNavigator();
8
+
9
+ export default function BottomTabs() {
10
+ return (
11
+ <Tab.Navigator screenOptions={{ headerShown: false }}>
12
+ <Tab.Screen name="Home" component={HomeScreen} />
13
+ <Tab.Screen name="Profile" component={ProfileScreen} />
14
+ <Tab.Screen name="Settings" component={SettingsScreen} />
15
+ </Tab.Navigator>
16
+ );
17
+ }
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
3
+ import { Ionicons } from "@expo/vector-icons";
4
+ import HomeScreen from "../../screens/HomeScreen";
5
+ import ProfileScreen from "../../screens/ProfileScreen";
6
+ import SettingsScreen from "../../screens/SettingsScreen";
7
+
8
+ const Tab = createBottomTabNavigator();
9
+
10
+ export default function BottomTabs() {
11
+ return (
12
+ <Tab.Navigator
13
+ screenOptions={({ route }) => ({
14
+ headerShown: false,
15
+ tabBarIcon: ({ color, size }) => {
16
+ let iconName: string = "home";
17
+
18
+ if (route.name === "Home") iconName = "home";
19
+ else if (route.name === "Profile") iconName = "person";
20
+ else if (route.name === "Settings") iconName = "settings";
21
+
22
+ return <Ionicons name={iconName as any} size={size} color={color} />;
23
+ },
24
+ })}
25
+ >
26
+ <Tab.Screen name="Home" component={HomeScreen} />
27
+ <Tab.Screen name="Profile" component={ProfileScreen} />
28
+ <Tab.Screen name="Settings" component={SettingsScreen} />
29
+ </Tab.Navigator>
30
+ );
31
+ }
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import { Text, Button } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { useAuthStore } from "../store/authStore";
5
+
6
+ export default function HomeScreen() {
7
+ const logout = useAuthStore((state) => state.logout);
8
+
9
+ return (
10
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
11
+ <Text>Welcome Home!</Text>
12
+ <Button title="Logout" onPress={() => void logout()} />
13
+ </SafeAreaView>
14
+ );
15
+ }
@@ -0,0 +1,63 @@
1
+ import React, { useState } from "react";
2
+ import { TextInput, Button, Text } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { loginApi } from "../api";
5
+ import { useAuthStore } from "../store/authStore";
6
+
7
+ export default function LoginScreen() {
8
+ const login = useAuthStore((state) => state.login);
9
+ const [email, setEmail] = useState("");
10
+ const [password, setPassword] = useState("");
11
+ const [error, setError] = useState("");
12
+
13
+ const handleLogin = async () => {
14
+ try {
15
+ setError("");
16
+ const token = await loginApi(email, password);
17
+ await login(token);
18
+ } catch (err) {
19
+ setError(err instanceof Error ? err.message : "Login failed");
20
+ }
21
+ };
22
+
23
+ return (
24
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
25
+ <TextInput
26
+ placeholder="Email"
27
+ value={email}
28
+ onChangeText={setEmail}
29
+ autoCapitalize="none"
30
+ autoCorrect={false}
31
+ keyboardType="email-address"
32
+ placeholderTextColor="#888"
33
+ style={{
34
+ borderWidth: 1,
35
+ borderColor: "#ccc",
36
+ borderRadius: 8,
37
+ paddingHorizontal: 12,
38
+ paddingVertical: 10,
39
+ color: "#111",
40
+ marginBottom: 12,
41
+ }}
42
+ />
43
+ <TextInput
44
+ placeholder="Password"
45
+ value={password}
46
+ onChangeText={setPassword}
47
+ secureTextEntry
48
+ placeholderTextColor="#888"
49
+ style={{
50
+ borderWidth: 1,
51
+ borderColor: "#ccc",
52
+ borderRadius: 8,
53
+ paddingHorizontal: 12,
54
+ paddingVertical: 10,
55
+ color: "#111",
56
+ marginBottom: 12,
57
+ }}
58
+ />
59
+ {!!error && <Text style={{ color: "red", marginBottom: 8 }}>{error}</Text>}
60
+ <Button title="Login" onPress={() => void handleLogin()} />
61
+ </SafeAreaView>
62
+ );
63
+ }
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { Text } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+
5
+ export default function ProfileScreen() {
6
+ return (
7
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
8
+ <Text>This is the Profile Screen</Text>
9
+ </SafeAreaView>
10
+ );
11
+ }
@@ -0,0 +1,63 @@
1
+ import React, { useState } from "react";
2
+ import { TextInput, Button, Text } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { registerApi } from "../api";
5
+ import { useAuthStore } from "../store/authStore";
6
+
7
+ export default function RegisterScreen() {
8
+ const login = useAuthStore((state) => state.login);
9
+ const [email, setEmail] = useState("");
10
+ const [password, setPassword] = useState("");
11
+ const [error, setError] = useState("");
12
+
13
+ const handleRegister = async () => {
14
+ try {
15
+ setError("");
16
+ const token = await registerApi(email, password);
17
+ await login(token);
18
+ } catch (err) {
19
+ setError(err instanceof Error ? err.message : "Registration failed");
20
+ }
21
+ };
22
+
23
+ return (
24
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
25
+ <TextInput
26
+ placeholder="Email"
27
+ value={email}
28
+ onChangeText={setEmail}
29
+ autoCapitalize="none"
30
+ autoCorrect={false}
31
+ keyboardType="email-address"
32
+ placeholderTextColor="#888"
33
+ style={{
34
+ borderWidth: 1,
35
+ borderColor: "#ccc",
36
+ borderRadius: 8,
37
+ paddingHorizontal: 12,
38
+ paddingVertical: 10,
39
+ color: "#111",
40
+ marginBottom: 12,
41
+ }}
42
+ />
43
+ <TextInput
44
+ placeholder="Password"
45
+ value={password}
46
+ onChangeText={setPassword}
47
+ secureTextEntry
48
+ placeholderTextColor="#888"
49
+ style={{
50
+ borderWidth: 1,
51
+ borderColor: "#ccc",
52
+ borderRadius: 8,
53
+ paddingHorizontal: 12,
54
+ paddingVertical: 10,
55
+ color: "#111",
56
+ marginBottom: 12,
57
+ }}
58
+ />
59
+ {!!error && <Text style={{ color: "red", marginBottom: 8 }}>{error}</Text>}
60
+ <Button title="Register" onPress={() => void handleRegister()} />
61
+ </SafeAreaView>
62
+ );
63
+ }
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { Text } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+
5
+ export default function SettingsScreen() {
6
+ return (
7
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
8
+ <Text>This is the Settings Screen</Text>
9
+ </SafeAreaView>
10
+ );
11
+ }
@@ -0,0 +1,30 @@
1
+ import { create } from "zustand";
2
+ import { getToken, removeToken, storeToken } from "../utils/storage";
3
+
4
+ type AuthState = {
5
+ token: string | null;
6
+ isHydrated: boolean;
7
+ hydrate: () => Promise<void>;
8
+ login: (token: string) => Promise<void>;
9
+ logout: () => Promise<void>;
10
+ };
11
+
12
+ export const useAuthStore = create<AuthState>((set) => ({
13
+ token: null,
14
+ isHydrated: false,
15
+
16
+ hydrate: async () => {
17
+ const token = await getToken();
18
+ set({ token, isHydrated: true });
19
+ },
20
+
21
+ login: async (token: string) => {
22
+ await storeToken(token);
23
+ set({ token });
24
+ },
25
+
26
+ logout: async () => {
27
+ await removeToken();
28
+ set({ token: null });
29
+ },
30
+ }));
@@ -0,0 +1,13 @@
1
+ import AsyncStorage from "@react-native-async-storage/async-storage";
2
+
3
+ export const storeToken = async (token: string) => {
4
+ await AsyncStorage.setItem("@token", token);
5
+ };
6
+
7
+ export const getToken = async () => {
8
+ return await AsyncStorage.getItem("@token");
9
+ };
10
+
11
+ export const removeToken = async () => {
12
+ await AsyncStorage.removeItem("@token");
13
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highbeek/create-rnstarterkit",
3
- "version": "1.0.0",
3
+ "version": "1.0.1-beta.0",
4
4
  "description": "CLI to scaffold production-ready React Native app structures.",
5
5
  "main": "dist/src/generators/appGenerator.js",
6
6
  "bin": {
@@ -11,7 +11,7 @@
11
11
  "README.md"
12
12
  ],
13
13
  "scripts": {
14
- "build": "tsc -p tsconfig.build.json",
14
+ "build": "tsc -p tsconfig.build.json && node scripts/copy-templates.js",
15
15
  "prepublishOnly": "npm run build",
16
16
  "test": "echo \"Error: no test specified\" && exit 1"
17
17
  },