@imksh/create 1.0.23 → 1.0.25

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 (163) hide show
  1. package/package.json +1 -1
  2. package/src/utils/copyTemplate.js +6 -0
  3. package/templates/mern-react-native/client/src/vite-env.d.ts +1 -0
  4. package/templates/mern-react-native/mobile/babel.config.js +1 -0
  5. package/templates/mern-react-native/mobile/drizzle.config.ts +8 -0
  6. package/templates/mern-react-native/mobile/expo-env.d.ts +3 -0
  7. package/templates/mern-react-native/mobile/package.json +6 -0
  8. package/templates/mern-react-native/mobile/src/app/(auth)/_layout.tsx +12 -0
  9. package/templates/mern-react-native/mobile/src/app/(auth)/change-password.tsx +112 -0
  10. package/templates/mern-react-native/mobile/src/app/(auth)/edit-profile.tsx +160 -0
  11. package/templates/mern-react-native/mobile/src/app/(auth)/forgot-password.tsx +191 -0
  12. package/templates/mern-react-native/mobile/src/app/{login.tsx → (auth)/login.tsx} +69 -21
  13. package/templates/mern-react-native/mobile/src/app/(tabs)/index.tsx +18 -17
  14. package/templates/mern-react-native/mobile/src/app/(tabs)/profile.tsx +23 -60
  15. package/templates/mern-react-native/mobile/src/app/_layout.tsx +22 -4
  16. package/templates/mern-react-native/mobile/src/components/common/AnimatedHeader.tsx +328 -0
  17. package/templates/mern-react-native/mobile/src/components/common/LocationLoader.tsx +591 -0
  18. package/templates/mern-react-native/mobile/src/components/common/ScreenHeader.tsx +41 -17
  19. package/templates/mern-react-native/mobile/src/components/common/TabHeader.tsx +58 -0
  20. package/templates/mern-react-native/mobile/src/components/common/Typography.tsx +49 -30
  21. package/templates/mern-react-native/mobile/src/components/common/Welcome.tsx +2 -2
  22. package/templates/mern-react-native/mobile/src/components/ui/BottomModal.tsx +31 -20
  23. package/templates/mern-react-native/mobile/src/components/ui/ClassicTabBar.tsx +4 -3
  24. package/templates/mern-react-native/mobile/src/components/ui/CustomTabBar.tsx +108 -71
  25. package/templates/mern-react-native/mobile/src/components/ui/Sidebar.tsx +81 -56
  26. package/templates/mern-react-native/mobile/src/components/ui/buttons/Button.tsx +106 -37
  27. package/templates/mern-react-native/mobile/src/components/ui/buttons/IconButton.tsx +4 -2
  28. package/templates/mern-react-native/mobile/src/components/ui/data-display/Accordion.tsx +3 -2
  29. package/templates/mern-react-native/mobile/src/components/ui/data-display/Avatar.tsx +4 -3
  30. package/templates/mern-react-native/mobile/src/components/ui/data-display/Badge.tsx +45 -17
  31. package/templates/mern-react-native/mobile/src/components/ui/data-display/ImageViewer.tsx +19 -9
  32. package/templates/mern-react-native/mobile/src/components/ui/feedback/CircularProgress.tsx +5 -4
  33. package/templates/mern-react-native/mobile/src/components/ui/feedback/ProgressBar.tsx +4 -3
  34. package/templates/mern-react-native/mobile/src/components/ui/feedback/Skeleton.tsx +3 -0
  35. package/templates/mern-react-native/mobile/src/components/ui/feedback/Spinner.tsx +11 -3
  36. package/templates/mern-react-native/mobile/src/components/ui/inputs/Checkbox.tsx +3 -2
  37. package/templates/mern-react-native/mobile/src/components/ui/inputs/DatePicker.tsx +186 -0
  38. package/templates/mern-react-native/mobile/src/components/ui/inputs/ImagePickerModal.tsx +129 -0
  39. package/templates/mern-react-native/mobile/src/components/ui/inputs/Input.tsx +54 -14
  40. package/templates/mern-react-native/mobile/src/components/ui/inputs/LocationPicker.tsx +211 -0
  41. package/templates/mern-react-native/mobile/src/components/ui/inputs/OTPInput.tsx +32 -9
  42. package/templates/mern-react-native/mobile/src/components/ui/inputs/PasswordInput.tsx +2 -1
  43. package/templates/mern-react-native/mobile/src/components/ui/inputs/Radio.tsx +3 -2
  44. package/templates/mern-react-native/mobile/src/components/ui/inputs/SearchBar.tsx +41 -4
  45. package/templates/mern-react-native/mobile/src/components/ui/inputs/Slider.tsx +4 -3
  46. package/templates/mern-react-native/mobile/src/components/ui/inputs/Switch.tsx +3 -2
  47. package/templates/mern-react-native/mobile/src/components/ui/inputs/TextArea.tsx +2 -1
  48. package/templates/mern-react-native/mobile/src/components/ui/inputs/WebLocationPicker.tsx +321 -0
  49. package/templates/mern-react-native/mobile/src/components/ui/layout/Grid.tsx +52 -10
  50. package/templates/mern-react-native/mobile/src/components/ui/layout/Section.tsx +7 -8
  51. package/templates/mern-react-native/mobile/src/components/ui/navigation/Pagination.tsx +4 -3
  52. package/templates/mern-react-native/mobile/src/components/ui/navigation/ProgressStepper.tsx +6 -5
  53. package/templates/mern-react-native/mobile/src/components/ui/navigation/Tabs.tsx +30 -4
  54. package/templates/mern-react-native/mobile/src/config/api.ts +12 -1
  55. package/templates/mern-react-native/mobile/src/config/sidebar.config.ts +72 -0
  56. package/templates/mern-react-native/mobile/src/config/tabNavigation.ts +37 -7
  57. package/templates/mern-react-native/mobile/src/db/index.ts +9 -0
  58. package/templates/mern-react-native/mobile/src/db/schema.ts +14 -0
  59. package/templates/mern-react-native/mobile/src/hooks/useDebounce.ts +17 -0
  60. package/templates/mern-react-native/mobile/src/services/socket.service.ts +36 -0
  61. package/templates/mern-react-native/mobile/src/store/useAuthStore.ts +122 -27
  62. package/templates/mern-react-native/mobile/src/store/useNotificationStore.ts +53 -0
  63. package/templates/mern-react-native/mobile/src/types/auth.type.ts +14 -0
  64. package/templates/mern-react-native/mobile/tsconfig.json +1 -0
  65. package/templates/mern-ts/client/src/vite-env.d.ts +1 -0
  66. package/templates/react-native/babel.config.js +1 -0
  67. package/templates/react-native/drizzle.config.ts +8 -0
  68. package/templates/react-native/expo-env.d.ts +3 -0
  69. package/templates/react-native/package.json +6 -0
  70. package/templates/react-native/src/app/(auth)/_layout.tsx +12 -0
  71. package/templates/react-native/src/app/(auth)/change-password.tsx +112 -0
  72. package/templates/react-native/src/app/(auth)/edit-profile.tsx +160 -0
  73. package/templates/react-native/src/app/(auth)/forgot-password.tsx +191 -0
  74. package/templates/react-native/src/app/{login.tsx → (auth)/login.tsx} +69 -21
  75. package/templates/react-native/src/app/(tabs)/index.tsx +18 -17
  76. package/templates/react-native/src/app/(tabs)/profile.tsx +23 -60
  77. package/templates/react-native/src/app/_layout.tsx +22 -4
  78. package/templates/react-native/src/components/common/AnimatedHeader.tsx +328 -0
  79. package/templates/react-native/src/components/common/LocationLoader.tsx +591 -0
  80. package/templates/react-native/src/components/common/ScreenHeader.tsx +41 -17
  81. package/templates/react-native/src/components/common/TabHeader.tsx +58 -0
  82. package/templates/react-native/src/components/common/Typography.tsx +49 -30
  83. package/templates/react-native/src/components/common/Welcome.tsx +2 -2
  84. package/templates/react-native/src/components/ui/BottomModal.tsx +31 -20
  85. package/templates/react-native/src/components/ui/ClassicTabBar.tsx +4 -3
  86. package/templates/react-native/src/components/ui/CustomTabBar.tsx +108 -71
  87. package/templates/react-native/src/components/ui/Sidebar.tsx +81 -56
  88. package/templates/react-native/src/components/ui/buttons/Button.tsx +106 -37
  89. package/templates/react-native/src/components/ui/buttons/IconButton.tsx +4 -2
  90. package/templates/react-native/src/components/ui/data-display/Accordion.tsx +3 -2
  91. package/templates/react-native/src/components/ui/data-display/Avatar.tsx +4 -3
  92. package/templates/react-native/src/components/ui/data-display/Badge.tsx +45 -17
  93. package/templates/react-native/src/components/ui/data-display/ImageViewer.tsx +19 -9
  94. package/templates/react-native/src/components/ui/feedback/CircularProgress.tsx +5 -4
  95. package/templates/react-native/src/components/ui/feedback/ProgressBar.tsx +4 -3
  96. package/templates/react-native/src/components/ui/feedback/Skeleton.tsx +3 -0
  97. package/templates/react-native/src/components/ui/feedback/Spinner.tsx +11 -3
  98. package/templates/react-native/src/components/ui/inputs/Checkbox.tsx +3 -2
  99. package/templates/react-native/src/components/ui/inputs/DatePicker.tsx +186 -0
  100. package/templates/react-native/src/components/ui/inputs/ImagePickerModal.tsx +129 -0
  101. package/templates/react-native/src/components/ui/inputs/Input.tsx +54 -14
  102. package/templates/react-native/src/components/ui/inputs/LocationPicker.tsx +211 -0
  103. package/templates/react-native/src/components/ui/inputs/OTPInput.tsx +32 -9
  104. package/templates/react-native/src/components/ui/inputs/PasswordInput.tsx +2 -1
  105. package/templates/react-native/src/components/ui/inputs/Radio.tsx +3 -2
  106. package/templates/react-native/src/components/ui/inputs/SearchBar.tsx +41 -4
  107. package/templates/react-native/src/components/ui/inputs/Slider.tsx +4 -3
  108. package/templates/react-native/src/components/ui/inputs/Switch.tsx +3 -2
  109. package/templates/react-native/src/components/ui/inputs/TextArea.tsx +2 -1
  110. package/templates/react-native/src/components/ui/inputs/WebLocationPicker.tsx +321 -0
  111. package/templates/react-native/src/components/ui/layout/Grid.tsx +52 -10
  112. package/templates/react-native/src/components/ui/layout/Section.tsx +7 -8
  113. package/templates/react-native/src/components/ui/navigation/Pagination.tsx +4 -3
  114. package/templates/react-native/src/components/ui/navigation/ProgressStepper.tsx +6 -5
  115. package/templates/react-native/src/components/ui/navigation/Tabs.tsx +30 -4
  116. package/templates/react-native/src/config/api.ts +12 -1
  117. package/templates/react-native/src/config/sidebar.config.ts +72 -0
  118. package/templates/react-native/src/config/tabNavigation.ts +37 -7
  119. package/templates/react-native/src/db/index.ts +9 -0
  120. package/templates/react-native/src/db/schema.ts +14 -0
  121. package/templates/react-native/src/hooks/useDebounce.ts +17 -0
  122. package/templates/react-native/src/services/socket.service.ts +36 -0
  123. package/templates/react-native/src/store/useAuthStore.ts +122 -27
  124. package/templates/react-native/src/store/useNotificationStore.ts +53 -0
  125. package/templates/react-native/src/types/auth.type.ts +14 -0
  126. package/templates/react-native/tsconfig.json +1 -0
  127. package/templates/react-ts/src/vite-env.d.ts +1 -0
  128. package/templates/mern-react-native/mobile/.env +0 -2
  129. package/templates/mern-react-native/mobile/.env.example +0 -2
  130. package/templates/mern-react-native/mobile/.vscode/extensions.json +0 -1
  131. package/templates/mern-react-native/mobile/.vscode/settings.json +0 -7
  132. package/templates/mern-react-native/mobile/README.md +0 -159
  133. package/templates/mern-react-native/mobile/docs/README.md +0 -17
  134. package/templates/mern-react-native/mobile/docs/components/buttons.md +0 -40
  135. package/templates/mern-react-native/mobile/docs/components/data-display.md +0 -44
  136. package/templates/mern-react-native/mobile/docs/components/feedback.md +0 -36
  137. package/templates/mern-react-native/mobile/docs/components/gestures.md +0 -60
  138. package/templates/mern-react-native/mobile/docs/components/inputs.md +0 -41
  139. package/templates/mern-react-native/mobile/docs/components/layout.md +0 -34
  140. package/templates/mern-react-native/mobile/docs/components/navigation.md +0 -31
  141. package/templates/mern-react-native/mobile/docs/features.md +0 -85
  142. package/templates/mern-react-native/mobile/docs/getting-started.md +0 -47
  143. package/templates/mern-react-native/mobile/src/components/common/HomeHeader.tsx +0 -43
  144. package/templates/mern-react-native/mobile/src/components/settings/SettingToggle.tsx +0 -26
  145. package/templates/mern-react-native/mobile/src/components/settings/SettingsOptions.tsx +0 -47
  146. package/templates/react-native/.env +0 -2
  147. package/templates/react-native/.env.example +0 -2
  148. package/templates/react-native/.vscode/extensions.json +0 -1
  149. package/templates/react-native/.vscode/settings.json +0 -7
  150. package/templates/react-native/README.md +0 -159
  151. package/templates/react-native/docs/README.md +0 -17
  152. package/templates/react-native/docs/components/buttons.md +0 -40
  153. package/templates/react-native/docs/components/data-display.md +0 -44
  154. package/templates/react-native/docs/components/feedback.md +0 -36
  155. package/templates/react-native/docs/components/gestures.md +0 -60
  156. package/templates/react-native/docs/components/inputs.md +0 -41
  157. package/templates/react-native/docs/components/layout.md +0 -34
  158. package/templates/react-native/docs/components/navigation.md +0 -31
  159. package/templates/react-native/docs/features.md +0 -85
  160. package/templates/react-native/docs/getting-started.md +0 -47
  161. package/templates/react-native/src/components/common/HomeHeader.tsx +0 -43
  162. package/templates/react-native/src/components/settings/SettingToggle.tsx +0 -26
  163. package/templates/react-native/src/components/settings/SettingsOptions.tsx +0 -47
@@ -1,28 +1,34 @@
1
- import React, { useState } from "react";
1
+ import React, { useState, useCallback } from "react";
2
2
  import { View } from "react-native";
3
- import { useAuthStore } from "../store/useAuthStore";
4
- import { Txt } from "../components/common/Typography";
5
- import { Redirect } from "expo-router";
6
-
7
- import ScrollContainer from "../components/ui/layout/ScrollContainer";
8
- import Input from "../components/ui/inputs/Input";
9
- import Button from "../components/ui/buttons/Button";
10
- import Tabs from "../components/ui/navigation/Tabs";
3
+ import { useAuthStore } from "../../store/useAuthStore";
4
+ import { Txt } from "../../components/common/Typography";
5
+ import { Redirect, router, useFocusEffect } from "expo-router";
6
+ import ScrollContainer from "../../components/ui/layout/ScrollContainer";
7
+ import Input from "../../components/ui/inputs/Input";
8
+ import Button from "../../components/ui/buttons/Button";
9
+ import Tabs from "../../components/ui/navigation/Tabs";
11
10
  import Image from "@/components/ui/data-display/Image";
12
- import logo from "../../assets/images/logo/logo.png";
11
+ import logo from "../../../assets/images/logo/logo.png";
13
12
 
14
13
  export default function LoginScreen() {
15
14
  const {
16
15
  login,
17
- demoLogin,
18
16
  signup,
19
17
  sendOtp,
20
18
  loading,
21
19
  error,
22
20
  user,
23
21
  isCheckingAuth,
22
+ clearError,
23
+ demoLogin,
24
24
  } = useAuthStore();
25
25
 
26
+ useFocusEffect(
27
+ useCallback(() => {
28
+ return () => clearError();
29
+ }, [clearError]),
30
+ );
31
+
26
32
  const [mode, setMode] = useState("login");
27
33
  const [showPassword, setShowPassword] = useState(false);
28
34
  const [form, setForm] = useState({
@@ -32,6 +38,17 @@ export default function LoginScreen() {
32
38
  otp: "",
33
39
  });
34
40
  const [otpSent, setOtpSent] = useState(false);
41
+ const [timer, setTimer] = useState(0);
42
+
43
+ React.useEffect(() => {
44
+ let interval: ReturnType<typeof setInterval>;
45
+ if (timer > 0) {
46
+ interval = setInterval(() => {
47
+ setTimer((prev) => prev - 1);
48
+ }, 1000);
49
+ }
50
+ return () => clearInterval(interval);
51
+ }, [timer]);
35
52
 
36
53
  const handleChange = (name: string, value: string) => {
37
54
  setForm((prev) => ({ ...prev, [name]: value }));
@@ -44,7 +61,10 @@ export default function LoginScreen() {
44
61
  } else {
45
62
  if (!otpSent) {
46
63
  ok = await sendOtp(form.email);
47
- if (ok) setOtpSent(true);
64
+ if (ok) {
65
+ setOtpSent(true);
66
+ setTimer(60);
67
+ }
48
68
  } else {
49
69
  ok = await signup(form.name, form.email, form.password, form.otp);
50
70
  }
@@ -62,22 +82,23 @@ export default function LoginScreen() {
62
82
  justifyContent: "center",
63
83
  padding: 16,
64
84
  }}
85
+ className="bg-base-100"
65
86
  >
66
- <View className="w-full p-6">
87
+ <View className="w-full p-6 ">
67
88
  {/* Header */}
68
89
  <View className="items-center mb-8 w-full">
69
90
  <View className="w-16 h-16 rounded-2xl bg-primary/10 border border-primary/20 items-center justify-center mb-4">
70
91
  <Image src={logo} height={40} width={40} />
71
92
  </View>
72
93
  <Txt
73
- variant="h1"
94
+ variant="xl"
74
95
  className="text-2xl mb-1 text-center"
75
96
  numberOfLines={1}
76
97
  >
77
98
  {mode === "login" ? "Welcome back" : "Create account"}
78
99
  </Txt>
79
100
  <Txt
80
- variant="regular"
101
+ variant="sm"
81
102
  className="text-xs text-base-content/50 text-center px-2"
82
103
  >
83
104
  {mode === "login"
@@ -105,7 +126,7 @@ export default function LoginScreen() {
105
126
  {/* Error */}
106
127
  {error ? (
107
128
  <View className="bg-error/10 border border-error/20 rounded-2xl p-3 mb-4">
108
- <Txt variant="mid" className="text-error text-xs text-center">
129
+ <Txt variant="md" className="text-error text-xs text-center">
109
130
  ⚠️ {error}
110
131
  </Txt>
111
132
  </View>
@@ -141,6 +162,18 @@ export default function LoginScreen() {
141
162
  secureTextEntry={!showPassword}
142
163
  />
143
164
 
165
+ {mode === "login" && (
166
+ <View className="items-end mt-1 mb-2">
167
+ <Txt
168
+ variant="md"
169
+ className="text-primary text-xs"
170
+ onPress={() => router.push("/(auth)/forgot-password")}
171
+ >
172
+ Forgot Password?
173
+ </Txt>
174
+ </View>
175
+ )}
176
+
144
177
  {mode === "signup" && otpSent && (
145
178
  <Input
146
179
  leftIcon="key"
@@ -170,9 +203,24 @@ export default function LoginScreen() {
170
203
  {mode === "login" && (
171
204
  <View className="mt-2">
172
205
  <Button
173
- label="Use Demo Account"
174
- onPress={demoLogin}
175
- disabled={loading}
206
+ label="Demo Login"
207
+ onPress={() => demoLogin()}
208
+ isLoading={loading}
209
+ variant="outline"
210
+ isFullWidth
211
+ />
212
+ </View>
213
+ )}
214
+
215
+ {mode === "signup" && otpSent && (
216
+ <View className="mt-2">
217
+ <Button
218
+ label={timer > 0 ? `Resend OTP in ${timer}s` : "Resend OTP"}
219
+ onPress={async () => {
220
+ const ok = await sendOtp(form.email);
221
+ if (ok) setTimer(60);
222
+ }}
223
+ disabled={timer > 0 || loading}
176
224
  variant="outline"
177
225
  isFullWidth
178
226
  />
@@ -183,12 +231,12 @@ export default function LoginScreen() {
183
231
  {/* Footer */}
184
232
  <View className="mt-8">
185
233
  <Txt
186
- variant="regular"
234
+ variant="sm"
187
235
  className="text-sm text-base-content/50 text-center"
188
236
  >
189
237
  {mode === "login" ? "New here? " : "Already have an account? "}
190
238
  <Txt
191
- variant="mid"
239
+ variant="md"
192
240
  className="text-primary text-sm"
193
241
  onPress={() => {
194
242
  setMode(mode === "login" ? "signup" : "login");
@@ -9,6 +9,7 @@ import { toast } from "@/utils/toast";
9
9
  import ScrollContainer from "@/components/ui/layout/ScrollContainer";
10
10
  import Container from "@/components/ui/layout/Container";
11
11
  import Section from "@/components/ui/layout/Section";
12
+ import Divider from "@/components/ui/layout/Divider";
12
13
  import { HStack, VStack } from "@/components/ui/layout/Stack";
13
14
 
14
15
  import Button from "@/components/ui/buttons/Button";
@@ -79,7 +80,7 @@ const Index = () => {
79
80
  >
80
81
  <HStack justify="space-between" align="center">
81
82
  <VStack>
82
- <Txt variant="h2" className="font-extrabold tracking-tight">
83
+ <Txt variant="3xl" className="font-extrabold tracking-tight">
83
84
  imksh-create
84
85
  </Txt>
85
86
  <Txt
@@ -115,12 +116,12 @@ const Index = () => {
115
116
  <Badge label="SOFT" variant="primary" soft={true} />
116
117
  </HStack>
117
118
  <Txt
118
- variant="h1"
119
+ variant="4xl"
119
120
  className="text-primary font-black leading-tight"
120
121
  >
121
122
  Stop configuring. Start building.
122
123
  </Txt>
123
- <Txt variant="body" className="text-primary/70 font-medium">
124
+ <Txt variant="base" className="text-primary/70 font-medium">
124
125
  Skip the setup. Build your product. A complete boilerplate with auth, state management, navigation, and beautiful prebuilt components.
125
126
  </Txt>
126
127
  </VStack>
@@ -197,7 +198,7 @@ const Index = () => {
197
198
  size={50}
198
199
  />
199
200
  <VStack style={{ flex: 1 }}>
200
- <Txt variant="mid" className="font-bold">
201
+ <Txt variant="md" className="font-bold">
201
202
  Swipe me left!
202
203
  </Txt>
203
204
  <Txt
@@ -234,7 +235,7 @@ const Index = () => {
234
235
  color={colors.accent}
235
236
  style={{ marginBottom: 12 }}
236
237
  />
237
- <Txt variant="h3" className="text-accent text-center">
238
+ <Txt variant="2xl" className="text-accent text-center">
238
239
  Double Tap or Swipe Up
239
240
  </Txt>
240
241
  <Txt
@@ -258,11 +259,11 @@ const Index = () => {
258
259
  placeholder="Search components..."
259
260
  />
260
261
 
261
- <View className="h-px w-full bg-base-300/50" />
262
+ <Divider />
262
263
 
263
264
  <HStack justify="space-between" align="center">
264
265
  <VStack>
265
- <Txt variant="mid" className="font-bold">
266
+ <Txt variant="md" className="font-bold">
266
267
  Biometric Login
267
268
  </Txt>
268
269
  <Txt
@@ -275,11 +276,11 @@ const Index = () => {
275
276
  <Switch checked={isEnabled} onChange={setIsEnabled} />
276
277
  </HStack>
277
278
 
278
- <View className="h-px w-full bg-base-300/50" />
279
+ <Divider />
279
280
 
280
281
  <VStack spacing={12}>
281
282
  <HStack justify="space-between" align="center">
282
- <Txt variant="mid" className="font-bold">
283
+ <Txt variant="md" className="font-bold">
283
284
  Intensity
284
285
  </Txt>
285
286
  <Badge label={`${sliderVal}%`} variant="secondary" />
@@ -292,7 +293,7 @@ const Index = () => {
292
293
  />
293
294
  </VStack>
294
295
 
295
- <View className="h-px w-full bg-base-300/50 mt-2" />
296
+ <Divider style={{ marginTop: 8 }} />
296
297
 
297
298
  {/* Text Input */}
298
299
  <Input
@@ -301,7 +302,7 @@ const Index = () => {
301
302
  leftIcon="mail-outline"
302
303
  />
303
304
 
304
- <View className="h-px w-full bg-base-300/50" />
305
+ <Divider />
305
306
 
306
307
  {/* Selection Controls */}
307
308
  <VStack spacing={16}>
@@ -341,7 +342,7 @@ const Index = () => {
341
342
  ]}
342
343
  />
343
344
  <View className="py-6 items-center justify-center">
344
- <Txt variant="body" className="text-base-content/60 italic">
345
+ <Txt variant="base" className="text-base-content/60 italic">
345
346
  Currently viewing {activeTab} content.
346
347
  </Txt>
347
348
  </View>
@@ -380,7 +381,7 @@ const Index = () => {
380
381
 
381
382
  <Card elevation={1} className="rounded-3xl p-6 mt-4">
382
383
  <HStack justify="space-between" align="center" className="mb-4">
383
- <Txt variant="mid" className="font-bold">
384
+ <Txt variant="md" className="font-bold">
384
385
  Background Sync
385
386
  </Txt>
386
387
  <Spinner size={24} />
@@ -399,14 +400,14 @@ const Index = () => {
399
400
  <Section title="Information & FAQs" className="pb-20">
400
401
  <VStack spacing={12}>
401
402
  <Accordion title="How to use this library?">
402
- <Txt variant="body">
403
+ <Txt variant="base">
403
404
  Simply import the components from the `@/components/ui`
404
405
  directory. They are fully typed, gesture-driven, and styled
405
406
  with NativeWind.
406
407
  </Txt>
407
408
  </Accordion>
408
409
  <Accordion title="Does it support dark mode?">
409
- <Txt variant="body">
410
+ <Txt variant="base">
410
411
  Yes! All components automatically respond to the device&apos;s
411
412
  color scheme, utilizing the custom CSS variables defined in
412
413
  global.css.
@@ -437,11 +438,11 @@ const Index = () => {
437
438
  color={colors.primary}
438
439
  />
439
440
  </View>
440
- <Txt variant="h2" className="text-center font-black">
441
+ <Txt variant="3xl" className="text-center font-black">
441
442
  Premium Modal
442
443
  </Txt>
443
444
  <Txt
444
- variant="body"
445
+ variant="base"
445
446
  className="text-center text-base-content/70 leading-relaxed px-4"
446
447
  >
447
448
  This highly responsive bottom sheet is gesture-driven. You can
@@ -3,10 +3,10 @@ import { useAuthStore } from "../../store/useAuthStore";
3
3
  import { useColorScheme } from "nativewind";
4
4
  import { Ionicons } from "@expo/vector-icons";
5
5
  import { Txt } from "../../components/common/Typography";
6
- import SettingsOptions from "../../components/settings/SettingsOptions";
7
- import SettingToggle from "../../components/settings/SettingToggle";
8
6
  import AsyncStorage from "@react-native-async-storage/async-storage";
9
7
  import Avatar from "@/components/ui/data-display/Avatar";
8
+ import Button from "@/components/ui/buttons/Button";
9
+ import Switch from "@/components/ui/inputs/Switch";
10
10
 
11
11
  const Profile = () => {
12
12
  const { user, logout } = useAuthStore();
@@ -22,10 +22,6 @@ const Profile = () => {
22
22
  await logout();
23
23
  };
24
24
 
25
- const handleEditProfile = () => {
26
- console.log("Edit profile clicked");
27
- };
28
-
29
25
  return (
30
26
  <View className="flex-1 bg-base-100">
31
27
  <View className="pt-16 pb-8 px-6 bg-primary/10 rounded-b-[40px] items-center border-b border-primary/20">
@@ -50,63 +46,30 @@ const Profile = () => {
50
46
  </Txt>
51
47
  </View>
52
48
  </View>
53
- <ScrollView className="flex-1 bg-base-100">
54
- {/* Settings Section */}
55
- <View className="px-6 py-8 pb-20">
56
- <Txt
57
- variant="h3"
58
- className="mb-6 text-base-content/80 uppercase tracking-widest text-xs"
59
- >
60
- Account Settings
61
- </Txt>
62
49
 
63
- <SettingsOptions
64
- name="Edit Profile"
65
- icon="person-outline"
66
- message="Are you sure you want to edit your profile?"
67
- fun={handleEditProfile}
68
- check={false}
69
- />
70
-
71
- <SettingsOptions
72
- name="Change Password"
73
- icon="lock-closed-outline"
74
- message="Do you want to update your password?"
75
- fun={() => {}}
76
- check={false}
77
- />
78
-
79
- <Txt
80
- variant="h3"
81
- className="mt-6 mb-6 text-base-content/80 uppercase tracking-widest text-xs"
82
- >
83
- Preferences
84
- </Txt>
85
-
86
- <SettingToggle
87
- name="Dark Theme"
88
- icon="moon-outline"
89
- check={colorScheme === "dark"}
90
- fun={handleToggleTheme}
91
- />
92
-
93
- <SettingToggle
94
- name="Push Notifications"
95
- icon="notifications-outline"
96
- check={true}
97
- fun={() => {}}
98
- />
99
-
100
- <View className="mt-8 mb-12">
101
- <SettingsOptions
102
- name="Log Out"
103
- icon="log-out-outline"
104
- message="Are you sure you want to log out from this device?"
105
- fun={handleLogout}
106
- check={false}
107
- />
50
+ <ScrollView className="flex-1 px-6 pt-6">
51
+ <View className="bg-base-200 rounded-2xl p-4 mb-6">
52
+ <View className="flex-row items-center justify-between py-2">
53
+ <View className="flex-row items-center">
54
+ <Ionicons
55
+ name={colorScheme === "dark" ? "moon" : "sunny"}
56
+ size={22}
57
+ color={colorScheme === "dark" ? "#fff" : "#000"}
58
+ />
59
+ <Txt variant="base" className="ml-3 font-semibold">Dark Mode</Txt>
60
+ </View>
61
+ <Switch checked={colorScheme === "dark"} onChange={handleToggleTheme} />
108
62
  </View>
109
63
  </View>
64
+
65
+ <Button
66
+ label="Logout"
67
+ variant="error"
68
+ isFullWidth
69
+ leftIcon="log-out-outline"
70
+ onPress={handleLogout}
71
+ style={{ marginTop: 20, marginBottom: 40 }}
72
+ />
110
73
  </ScrollView>
111
74
  </View>
112
75
  );
@@ -1,5 +1,5 @@
1
1
  import { useEffect } from "react";
2
- import { Stack } from "expo-router";
2
+ import { Stack, useRouter, useSegments } from "expo-router";
3
3
  import Toast from "react-native-toast-message";
4
4
  import { useAuthStore } from "../store/useAuthStore";
5
5
  import { useColorScheme } from "nativewind";
@@ -25,9 +25,12 @@ export default function RootLayout() {
25
25
  InterExtraBold: require("../../assets/fonts/Inter_ExtraBold.ttf"),
26
26
  });
27
27
 
28
- const { getMe, isCheckingAuth } = useAuthStore();
28
+ const { getMe, isCheckingAuth, loadCachedUser, user } = useAuthStore();
29
29
  const { colorScheme, setColorScheme } = useColorScheme();
30
30
  const colors = Colors[colorScheme ?? "light"];
31
+
32
+ const segments = useSegments();
33
+ const router = useRouter();
31
34
 
32
35
  useEffect(() => {
33
36
  if (fontsLoaded || fontError) {
@@ -36,7 +39,10 @@ export default function RootLayout() {
36
39
  }, [fontsLoaded, fontError]);
37
40
 
38
41
  useEffect(() => {
39
- getMe();
42
+ // Load cached user quickly, then fetch fresh in background
43
+ loadCachedUser().then(() => {
44
+ getMe();
45
+ });
40
46
 
41
47
  // Load saved theme
42
48
  AsyncStorage.getItem("theme").then((savedTheme) => {
@@ -47,7 +53,19 @@ export default function RootLayout() {
47
53
  // eslint-disable-next-line react-hooks/exhaustive-deps
48
54
  }, []);
49
55
 
56
+ useEffect(() => {
57
+ if (isCheckingAuth) return;
58
+
59
+ const inAuthGroup = segments[0] === "(auth)";
50
60
 
61
+ if (!user && !inAuthGroup) {
62
+ // Redirect to the auth group
63
+ router.replace("/(auth)/login");
64
+ } else if (user && inAuthGroup) {
65
+ // Redirect away from auth
66
+ router.replace("/(tabs)");
67
+ }
68
+ }, [user, isCheckingAuth, segments]);
51
69
 
52
70
  if (!fontsLoaded && !fontError) {
53
71
  return null;
@@ -69,7 +87,7 @@ export default function RootLayout() {
69
87
  >
70
88
  <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
71
89
  <Stack.Screen
72
- name="login"
90
+ name="(auth)"
73
91
  options={{ headerShown: false, animation: "fade" }}
74
92
  />
75
93
  </Stack>