@imksh/create 1.0.30 → 1.0.32

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 (247) hide show
  1. package/README.md +2 -0
  2. package/package.json +1 -1
  3. package/src/commands/create.js +2 -0
  4. package/src/index.js +1 -1
  5. package/src/utils/askTemplate.js +2 -1
  6. package/templates/layers/electron/base/electron/main.js +262 -0
  7. package/templates/layers/electron/base/electron/preload.js +37 -0
  8. package/templates/layers/electron/base/electron-builder.json5 +68 -0
  9. package/templates/layers/electron/javascript/_gitignore +38 -0
  10. package/templates/layers/electron/javascript/package.json +49 -0
  11. package/templates/layers/electron/javascript/src/components/layout/SidebarLayout.jsx +43 -0
  12. package/templates/layers/electron/javascript/src/components/ui/TitleBar.jsx +130 -0
  13. package/templates/layers/electron/javascript/src/config/appConfig.js +51 -0
  14. package/templates/layers/electron/javascript/src/hooks/useElectron.js +68 -0
  15. package/templates/layers/electron/javascript/src/main.jsx +17 -0
  16. package/templates/layers/electron/javascript/src/store/useUiStore.js +59 -0
  17. package/templates/layers/electron/javascript/vite.config.js +29 -0
  18. package/templates/layers/electron/typescript/_gitignore +38 -0
  19. package/templates/layers/electron/typescript/electron/main.ts +213 -0
  20. package/templates/layers/electron/typescript/electron/preload.ts +52 -0
  21. package/templates/layers/electron/typescript/package.json +52 -0
  22. package/templates/layers/electron/typescript/src/components/layout/SidebarLayout.tsx +42 -0
  23. package/templates/layers/electron/typescript/src/components/ui/TitleBar.tsx +120 -0
  24. package/templates/layers/electron/typescript/src/config/appConfig.ts +52 -0
  25. package/templates/layers/electron/typescript/src/hooks/useElectron.ts +68 -0
  26. package/templates/layers/electron/typescript/src/main.tsx +17 -0
  27. package/templates/layers/electron/typescript/src/store/useUiStore.ts +97 -0
  28. package/templates/layers/electron/typescript/src/vite-env.d.ts +13 -0
  29. package/templates/layers/electron/typescript/tsconfig.json +25 -0
  30. package/templates/layers/electron/typescript/tsconfig.node.json +11 -0
  31. package/templates/layers/electron/typescript/vite.config.ts +29 -0
  32. package/templates/layers/next/javascript/package.json +8 -2
  33. package/templates/layers/next/javascript/src/components/common/Breadcrumbs.jsx +44 -6
  34. package/templates/layers/next/javascript/src/components/common/Loading.jsx +1 -0
  35. package/templates/layers/next/javascript/src/components/common/LottieIcon.jsx +1 -0
  36. package/templates/layers/next/javascript/src/components/common/Pagination.jsx +170 -0
  37. package/templates/layers/next/javascript/src/components/common/SidebarModal.jsx +180 -0
  38. package/templates/layers/next/javascript/src/components/common/StatsCard.jsx +168 -0
  39. package/templates/layers/next/javascript/src/components/common/Table.jsx +191 -41
  40. package/templates/layers/next/javascript/src/components/common/Tabs.jsx +187 -0
  41. package/templates/layers/next/javascript/src/components/common/ToggleSwitch.jsx +4 -3
  42. package/templates/layers/next/javascript/src/components/layout/ProtectedRoute.jsx +2 -1
  43. package/templates/layers/next/javascript/src/components/layout/PublicLayout.jsx +3 -6
  44. package/templates/layers/next/javascript/src/components/layout/SidebarLayout.jsx +4 -17
  45. package/templates/layers/next/javascript/src/components/modals/ConfirmModal.jsx +4 -12
  46. package/templates/layers/next/javascript/src/components/modals/Modal.jsx +50 -19
  47. package/templates/layers/next/javascript/src/components/ui/Input.jsx +50 -0
  48. package/templates/layers/next/{typescript/src/components/ui/sidebar.tsx → javascript/src/components/ui/Sidebar.jsx} +65 -53
  49. package/templates/layers/next/javascript/src/components/ui/SidebarHeader.jsx +11 -6
  50. package/templates/layers/next/javascript/src/config/appConfig.js +4 -4
  51. package/templates/layers/next/javascript/src/hooks/useWindowSize.js +2 -3
  52. package/templates/layers/next/javascript/src/store/useUiStore.js +9 -4
  53. package/templates/layers/next/typescript/.eslintrc.json +12 -0
  54. package/templates/layers/next/typescript/package.json +14 -3
  55. package/templates/layers/next/typescript/src/components/common/Breadcrumbs.tsx +57 -8
  56. package/templates/layers/next/typescript/src/components/common/Loading.tsx +2 -1
  57. package/templates/layers/next/typescript/src/components/common/LottieIcon.tsx +2 -2
  58. package/templates/layers/next/typescript/src/components/common/Pagination.tsx +186 -0
  59. package/templates/layers/next/typescript/src/components/common/SidebarModal.tsx +200 -0
  60. package/templates/layers/next/typescript/src/components/common/StatsCard.tsx +232 -0
  61. package/templates/layers/next/typescript/src/components/common/Table.tsx +205 -39
  62. package/templates/layers/next/typescript/src/components/common/Tabs.tsx +190 -0
  63. package/templates/layers/next/typescript/src/components/common/ToggleSwitch.tsx +12 -8
  64. package/templates/layers/next/typescript/src/components/layout/PublicLayout.tsx +8 -6
  65. package/templates/layers/next/typescript/src/components/layout/SidebarLayout.tsx +8 -17
  66. package/templates/layers/next/typescript/src/components/modals/ConfirmModal.tsx +3 -1
  67. package/templates/layers/next/typescript/src/components/modals/Modal.tsx +67 -21
  68. package/templates/layers/next/typescript/src/components/ui/Button.tsx +1 -0
  69. package/templates/layers/next/typescript/src/components/ui/Header.tsx +2 -2
  70. package/templates/layers/next/typescript/src/components/ui/Input.tsx +40 -60
  71. package/templates/layers/next/{javascript/src/components/ui/sidebar.jsx → typescript/src/components/ui/Sidebar.tsx} +77 -44
  72. package/templates/layers/next/typescript/src/components/ui/SidebarHeader.tsx +16 -10
  73. package/templates/layers/next/typescript/src/config/appConfig.ts +4 -4
  74. package/templates/layers/next/typescript/src/hooks/usePwaInstall.ts +10 -4
  75. package/templates/layers/next/typescript/src/hooks/useWindowSize.ts +2 -3
  76. package/templates/layers/next/typescript/src/services/authService.ts +1 -1
  77. package/templates/layers/next/typescript/src/store/useAuthStore.ts +24 -9
  78. package/templates/layers/next/typescript/src/store/useUiStore.ts +14 -4
  79. package/templates/layers/node/javascript/.env.example +3 -1
  80. package/templates/layers/node/javascript/package.json +12 -3
  81. package/templates/layers/node/javascript/src/app.js +2 -1
  82. package/templates/layers/node/javascript/src/controllers/auth.controller.js +106 -168
  83. package/templates/layers/node/javascript/src/controllers/push.controller.js +51 -58
  84. package/templates/layers/node/javascript/src/controllers/upload.controller.js +12 -19
  85. package/templates/layers/node/javascript/src/middleware/auth.middleware.js +5 -11
  86. package/templates/layers/node/javascript/src/middleware/errorHandler.js +6 -4
  87. package/templates/layers/node/javascript/src/routes/auth.route.js +2 -0
  88. package/templates/layers/node/javascript/src/services/auth.service.js +159 -164
  89. package/templates/layers/node/javascript/src/utils/ApiError.js +20 -0
  90. package/templates/layers/node/javascript/src/utils/SuccessResponse.js +15 -0
  91. package/templates/layers/node/javascript/src/utils/apiResponse.js +4 -0
  92. package/templates/layers/node/javascript/src/utils/asyncHandler.js +5 -0
  93. package/templates/layers/node/typescript/.env.example +3 -1
  94. package/templates/layers/node/typescript/.eslintrc.cjs +28 -0
  95. package/templates/layers/node/typescript/package-lock.json +2 -2
  96. package/templates/layers/node/typescript/package.json +17 -3
  97. package/templates/layers/node/typescript/src/app.ts +3 -2
  98. package/templates/layers/node/typescript/src/config/db.ts +3 -2
  99. package/templates/layers/node/typescript/src/config/socket.ts +5 -4
  100. package/templates/layers/node/typescript/src/controllers/auth.controller.ts +104 -132
  101. package/templates/layers/node/typescript/src/controllers/push.controller.ts +52 -59
  102. package/templates/layers/node/typescript/src/controllers/upload.controller.ts +12 -19
  103. package/templates/layers/node/typescript/src/middleware/auth.middleware.ts +13 -7
  104. package/templates/layers/node/typescript/src/middleware/errorHandler.ts +18 -5
  105. package/templates/layers/node/typescript/src/middleware/rateLimiter.ts +2 -2
  106. package/templates/layers/node/typescript/src/routes/auth.route.ts +2 -0
  107. package/templates/layers/node/typescript/src/services/auth.service.ts +86 -43
  108. package/templates/layers/node/typescript/src/types/express.d.ts +5 -3
  109. package/templates/layers/node/typescript/src/utils/ApiError.ts +25 -0
  110. package/templates/layers/node/typescript/src/utils/SuccessResponse.ts +17 -0
  111. package/templates/layers/node/typescript/src/utils/apiResponse.ts +4 -0
  112. package/templates/layers/node/typescript/src/utils/asyncHandler.ts +13 -0
  113. package/templates/layers/node/typescript/src/utils/cloudinaryUpload.ts +18 -7
  114. package/templates/layers/node/typescript/src/utils/expoNotification.ts +1 -1
  115. package/templates/layers/node/typescript/src/utils/genOtpToken.ts +7 -1
  116. package/templates/layers/node/typescript/src/utils/jwt.ts +8 -2
  117. package/templates/layers/node/typescript/src/utils/logger.ts +2 -1
  118. package/templates/layers/node/typescript/src/utils/pushHelper.ts +13 -9
  119. package/templates/layers/node-prisma/javascript/.env.example +3 -1
  120. package/templates/layers/node-prisma/javascript/package.json +11 -2
  121. package/templates/layers/node-prisma/javascript/src/app.js +2 -1
  122. package/templates/layers/node-prisma/javascript/src/controllers/auth.controller.js +90 -135
  123. package/templates/layers/node-prisma/javascript/src/controllers/push.controller.js +64 -76
  124. package/templates/layers/node-prisma/javascript/src/controllers/upload.controller.js +12 -19
  125. package/templates/layers/node-prisma/javascript/src/middleware/auth.middleware.js +5 -4
  126. package/templates/layers/node-prisma/javascript/src/middleware/errorHandler.js +6 -4
  127. package/templates/layers/node-prisma/javascript/src/routes/auth.route.js +2 -0
  128. package/templates/layers/node-prisma/javascript/src/services/auth.service.js +145 -122
  129. package/templates/layers/node-prisma/javascript/src/utils/ApiError.js +20 -0
  130. package/templates/layers/node-prisma/javascript/src/utils/SuccessResponse.js +15 -0
  131. package/templates/layers/node-prisma/javascript/src/utils/apiResponse.js +4 -0
  132. package/templates/layers/node-prisma/javascript/src/utils/asyncHandler.js +5 -0
  133. package/templates/layers/node-prisma/typescript/.env.example +3 -1
  134. package/templates/layers/node-prisma/typescript/.eslintrc.cjs +28 -0
  135. package/templates/layers/node-prisma/typescript/package.json +19 -5
  136. package/templates/layers/node-prisma/typescript/src/app.ts +3 -2
  137. package/templates/layers/node-prisma/typescript/src/config/prisma.ts +3 -2
  138. package/templates/layers/node-prisma/typescript/src/config/socket.ts +5 -4
  139. package/templates/layers/node-prisma/typescript/src/controllers/auth.controller.ts +89 -105
  140. package/templates/layers/node-prisma/typescript/src/controllers/push.controller.ts +67 -83
  141. package/templates/layers/node-prisma/typescript/src/controllers/upload.controller.ts +12 -19
  142. package/templates/layers/node-prisma/typescript/src/middleware/auth.middleware.ts +9 -13
  143. package/templates/layers/node-prisma/typescript/src/middleware/errorHandler.ts +18 -5
  144. package/templates/layers/node-prisma/typescript/src/middleware/rateLimiter.ts +2 -2
  145. package/templates/layers/node-prisma/typescript/src/routes/auth.route.ts +2 -0
  146. package/templates/layers/node-prisma/typescript/src/services/auth.service.ts +83 -31
  147. package/templates/layers/node-prisma/typescript/src/types/express.d.ts +5 -3
  148. package/templates/layers/node-prisma/typescript/src/utils/ApiError.ts +25 -0
  149. package/templates/layers/node-prisma/typescript/src/utils/SuccessResponse.ts +17 -0
  150. package/templates/layers/node-prisma/typescript/src/utils/apiResponse.ts +4 -0
  151. package/templates/layers/node-prisma/typescript/src/utils/asyncHandler.ts +13 -0
  152. package/templates/layers/node-prisma/typescript/src/utils/cloudinaryUpload.ts +18 -7
  153. package/templates/layers/node-prisma/typescript/src/utils/genOtpToken.ts +7 -1
  154. package/templates/layers/node-prisma/typescript/src/utils/jwt.ts +8 -2
  155. package/templates/layers/node-prisma/typescript/src/utils/logger.ts +2 -1
  156. package/templates/layers/node-prisma/typescript/src/utils/pushHelper.ts +10 -6
  157. package/templates/layers/prisma/javascript/package.json +8 -0
  158. package/templates/layers/prisma/typescript/package.json +14 -1
  159. package/templates/layers/prisma/typescript/prisma/schema.prisma +35 -10
  160. package/templates/layers/prisma/typescript/src/config/db.ts +3 -2
  161. package/templates/layers/react/javascript/package.json +6 -0
  162. package/templates/layers/react/javascript/src/components/common/Breadcrumbs.jsx +62 -58
  163. package/templates/layers/react/javascript/src/components/common/Pagination.jsx +164 -76
  164. package/templates/layers/react/javascript/src/components/common/SidebarModal.jsx +179 -0
  165. package/templates/layers/react/javascript/src/components/common/StatsCard.jsx +167 -0
  166. package/templates/layers/react/javascript/src/components/common/Table.jsx +248 -132
  167. package/templates/layers/react/javascript/src/components/common/Tabs.jsx +164 -112
  168. package/templates/layers/react/javascript/src/components/common/ToggleSwitch.jsx +3 -3
  169. package/templates/layers/react/javascript/src/components/layout/SidebarLayout.jsx +4 -12
  170. package/templates/layers/react/javascript/src/components/modals/Modal.jsx +53 -18
  171. package/templates/layers/react/javascript/src/components/ui/Input.jsx +49 -0
  172. package/templates/layers/react/javascript/src/components/ui/Sidebar.jsx +215 -0
  173. package/templates/layers/react/javascript/src/components/ui/SidebarHeader.jsx +25 -30
  174. package/templates/layers/react/javascript/src/config/appConfig.js +3 -3
  175. package/templates/layers/react/javascript/src/hooks/useWindowSize.js +2 -2
  176. package/templates/layers/react/typescript/.eslintrc.cjs +20 -0
  177. package/templates/layers/react/typescript/package.json +11 -2
  178. package/templates/layers/react/typescript/src/components/common/Breadcrumbs.tsx +32 -6
  179. package/templates/layers/react/typescript/src/components/common/Pagination.tsx +151 -57
  180. package/templates/layers/react/typescript/src/components/common/SidebarModal.tsx +199 -0
  181. package/templates/layers/react/typescript/src/components/common/StatsCard.tsx +231 -0
  182. package/templates/layers/react/typescript/src/components/common/Table.tsx +201 -38
  183. package/templates/layers/react/typescript/src/components/common/Tabs.tsx +56 -12
  184. package/templates/layers/react/typescript/src/components/common/ToggleSwitch.tsx +15 -3
  185. package/templates/layers/react/typescript/src/components/layout/SidebarLayout.tsx +3 -6
  186. package/templates/layers/react/typescript/src/components/modals/Modal.tsx +151 -0
  187. package/templates/layers/react/typescript/src/components/ui/Input.tsx +58 -0
  188. package/templates/layers/react/typescript/src/components/ui/Sidebar.tsx +116 -53
  189. package/templates/layers/react/typescript/src/components/ui/SidebarHeader.tsx +5 -4
  190. package/templates/layers/react/typescript/src/config/appConfig.ts +3 -3
  191. package/templates/layers/react/typescript/src/hooks/useWindowSize.ts +2 -3
  192. package/templates/layers/react/typescript/src/main.tsx +11 -11
  193. package/templates/layers/react/typescript/src/services/authService.ts +1 -1
  194. package/templates/layers/react/typescript/src/store/useAuthStore.ts +24 -9
  195. package/templates/layers/react-native/base/app.json +9 -22
  196. package/templates/layers/react-native/base/eslint.config.js +5 -1
  197. package/templates/layers/react-native/base/package.json +11 -1
  198. package/templates/layers/react-native/base/src/app/(auth)/edit-profile.tsx +7 -7
  199. package/templates/layers/react-native/base/src/app/(auth)/login.tsx +31 -7
  200. package/templates/layers/react-native/base/src/app/(tabs)/_layout.tsx +3 -3
  201. package/templates/layers/react-native/base/src/app/(tabs)/index.tsx +6 -5
  202. package/templates/layers/react-native/base/src/app/_layout.tsx +3 -3
  203. package/templates/layers/react-native/base/src/app/doc-viewer.tsx +3 -3
  204. package/templates/layers/react-native/base/src/components/common/ConfirmationToast.tsx +58 -40
  205. package/templates/layers/react-native/base/src/components/common/GoogleAuthButton.tsx +144 -0
  206. package/templates/layers/react-native/base/src/components/common/LocationLoader.tsx +64 -9
  207. package/templates/layers/react-native/base/src/components/common/Typography.tsx +54 -19
  208. package/templates/layers/react-native/base/src/components/ui/ClassicTabBar.tsx +15 -12
  209. package/templates/layers/react-native/base/src/components/ui/CustomTabBar.tsx +84 -90
  210. package/templates/layers/react-native/base/src/components/ui/Drawer.tsx +344 -0
  211. package/templates/layers/react-native/base/src/components/ui/Sidebar.tsx +4 -4
  212. package/templates/layers/react-native/base/src/components/ui/buttons/Button.tsx +29 -6
  213. package/templates/layers/react-native/base/src/components/ui/data-display/Accordion.tsx +2 -2
  214. package/templates/layers/react-native/base/src/components/ui/data-display/Badge.tsx +1 -2
  215. package/templates/layers/react-native/base/src/components/ui/data-display/Image.tsx +3 -3
  216. package/templates/layers/react-native/base/src/components/ui/data-display/SwipeableRow.tsx +28 -7
  217. package/templates/layers/react-native/base/src/components/ui/feedback/GestureWrapper.tsx +11 -4
  218. package/templates/layers/react-native/base/src/components/ui/inputs/DatePicker.tsx +3 -3
  219. package/templates/layers/react-native/base/src/components/ui/inputs/ImagePickerModal.tsx +45 -19
  220. package/templates/layers/react-native/base/src/components/ui/inputs/Input.tsx +28 -9
  221. package/templates/layers/react-native/base/src/components/ui/inputs/SearchablePicker.tsx +199 -0
  222. package/templates/layers/react-native/base/src/components/ui/inputs/Switch.tsx +7 -7
  223. package/templates/layers/react-native/base/src/components/ui/inputs/WebLocationPicker.tsx +146 -72
  224. package/templates/layers/react-native/base/src/config/api.ts +5 -5
  225. package/templates/layers/react-native/base/src/config/appConfig.ts +1 -1
  226. package/templates/layers/react-native/base/src/services/auth.service.ts +3 -1
  227. package/templates/layers/react-native/base/src/services/permission.service.ts +0 -2
  228. package/templates/layers/react-native/base/src/services/socket.service.ts +0 -7
  229. package/templates/layers/react-native/base/src/store/useAuthStore.ts +61 -16
  230. package/templates/layers/react-native/base/src/store/useNotificationStore.ts +36 -42
  231. package/templates/layers/react-native/base/src/types/images.d.ts +7 -5
  232. package/templates/layers/react-native/base/src/utils/fileDownload.ts +206 -0
  233. package/templates/layers/react-native/base/src/utils/storage.ts +1 -1
  234. package/templates/presets/electron/preset.json +9 -0
  235. package/templates/presets/electron-ts/preset.json +9 -0
  236. package/templates/presets/production-fullstack/overrides/client/package.json +9 -0
  237. package/templates/presets/production-fullstack/overrides/mobile/app.json +2 -15
  238. package/templates/presets/production-fullstack/overrides/mobile/package.json +11 -1
  239. package/templates/presets/production-fullstack/overrides/mobile/src/app/_layout.tsx +3 -3
  240. package/templates/presets/production-fullstack/overrides/mobile/src/components/ui/Drawer.tsx +344 -0
  241. package/templates/presets/production-fullstack/overrides/mobile/src/components/ui/inputs/DatePicker.tsx +3 -3
  242. package/templates/presets/production-fullstack/overrides/mobile/src/components/ui/inputs/ImagePickerModal.tsx +3 -3
  243. package/templates/presets/production-fullstack/overrides/server/package.json +11 -2
  244. package/templates/layers/react/javascript/src/components/ui/sidebar.jsx +0 -169
  245. package/templates/layers/react-native/base/src/components/ui/BottomModal.tsx +0 -176
  246. package/templates/presets/production-fullstack/overrides/mobile/src/components/ui/BottomModal.tsx +0 -159
  247. /package/templates/layers/react-native/base/assets/images/logo/{logoWithBg.png → icon.png} +0 -0
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import {
3
2
  TouchableOpacity,
4
3
  ActivityIndicator,
@@ -32,6 +31,7 @@ export interface ButtonProps extends TouchableOpacityProps {
32
31
  isFullWidth?: boolean;
33
32
  soft?: boolean;
34
33
  outline?: boolean;
34
+ className?: string;
35
35
  }
36
36
 
37
37
  export default function Button({
@@ -46,6 +46,7 @@ export default function Button({
46
46
  outline = false,
47
47
  style,
48
48
  disabled,
49
+ className = "",
49
50
  ...props
50
51
  }: ButtonProps) {
51
52
  const { colorScheme } = useColorScheme();
@@ -109,7 +110,8 @@ export default function Button({
109
110
  const vStyles = getVariantStyles();
110
111
  if (outline) {
111
112
  vStyles.border = vStyles.bg === "transparent" ? theme.base300 : vStyles.bg;
112
- vStyles.text = vStyles.bg === "transparent" ? theme.baseContent : vStyles.bg;
113
+ vStyles.text =
114
+ vStyles.bg === "transparent" ? theme.baseContent : vStyles.bg;
113
115
  vStyles.bg = "transparent";
114
116
  } else if (soft && variant !== "ghost" && variant !== "outline") {
115
117
  vStyles.text = vStyles.bg;
@@ -124,9 +126,10 @@ export default function Button({
124
126
  <TouchableOpacity
125
127
  activeOpacity={0.7}
126
128
  disabled={isDisabled}
129
+ className={className}
127
130
  style={[
128
131
  {
129
- backgroundColor: vStyles.bg as any,
132
+ backgroundColor: vStyles.bg,
130
133
  height: sStyles.height,
131
134
  paddingHorizontal: sStyles.px,
132
135
  borderRadius: 12,
@@ -134,7 +137,7 @@ export default function Button({
134
137
  alignItems: "center",
135
138
  justifyContent: "center",
136
139
  opacity: isDisabled ? 0.6 : 1,
137
- borderWidth: (variant === "outline" || outline) ? 1 : 0,
140
+ borderWidth: variant === "outline" || outline ? 1 : 0,
138
141
  borderColor: vStyles.border,
139
142
  width: isFullWidth ? "100%" : undefined,
140
143
  },
@@ -144,13 +147,29 @@ export default function Button({
144
147
  >
145
148
  {/* Loading overlay */}
146
149
  {isLoading && (
147
- <View style={{ position: "absolute", top: 0, left: 0, right: 0, bottom: 0, justifyContent: "center", alignItems: "center" }}>
150
+ <View
151
+ style={{
152
+ position: "absolute",
153
+ top: 0,
154
+ left: 0,
155
+ right: 0,
156
+ bottom: 0,
157
+ justifyContent: "center",
158
+ alignItems: "center",
159
+ }}
160
+ >
148
161
  <ActivityIndicator color={vStyles.text} size="small" />
149
162
  </View>
150
163
  )}
151
164
 
152
165
  {/* Button content (hidden while loading to maintain dimensions) */}
153
- <View style={{ flexDirection: "row", alignItems: "center", opacity: isLoading ? 0 : 1 }}>
166
+ <View
167
+ style={{
168
+ flexDirection: "row",
169
+ alignItems: "center",
170
+ opacity: isLoading ? 0 : 1,
171
+ }}
172
+ >
154
173
  {leftIcon && (
155
174
  <Ionicons
156
175
  name={leftIcon}
@@ -163,6 +182,10 @@ export default function Button({
163
182
  color={vStyles.text}
164
183
  weight="semibold"
165
184
  style={{ fontSize: sStyles.fontSize }}
185
+ allowFontScaling={true}
186
+ numberOfLines={1}
187
+ ellipsizeMode="tail"
188
+ adjustsFontSizeToFit
166
189
  >
167
190
  {label}
168
191
  </Txt>
@@ -72,9 +72,9 @@ export default function Accordion({ title, children }: AccordionProps) {
72
72
  style={{ position: "absolute", width: "100%", paddingHorizontal: 16, paddingBottom: 16 }}
73
73
  >
74
74
  {/* This inner view is measured */}
75
- <View ref={aref as any}>
75
+ <Animated.View ref={aref}>
76
76
  {children}
77
- </View>
77
+ </Animated.View>
78
78
  </View>
79
79
  </Animated.View>
80
80
  </View>
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import { View, ViewProps } from "react-native";
3
2
  import { useColorScheme } from "nativewind";
4
3
  import { Colors } from "../../../constants/Colors";
@@ -80,7 +79,7 @@ export default function Badge({
80
79
  <View
81
80
  style={[
82
81
  {
83
- backgroundColor: vStyles.bg as any,
82
+ backgroundColor: vStyles.bg,
84
83
  height: sStyles.height,
85
84
  paddingHorizontal: sStyles.px,
86
85
  borderRadius: 9999,
@@ -1,13 +1,13 @@
1
1
  import React from "react";
2
- import { Image as ExpoImage, ImageProps as ExpoImageProps } from "expo-image";
2
+ import { Image as ExpoImage, ImageProps as ExpoImageProps, ImageSource } from "expo-image";
3
3
  import { View, ActivityIndicator, DimensionValue } from "react-native";
4
4
  import { useColorScheme } from "nativewind";
5
5
  import { Colors } from "../../../constants/Colors";
6
6
 
7
7
  export interface ImageProps extends Omit<ExpoImageProps, "source"> {
8
8
  fallbackIcon?: React.ReactNode;
9
- src?: string | number | any;
10
- source?: any;
9
+ src?: string | number | ImageSource;
10
+ source?: ImageSource | string | number;
11
11
  width?: DimensionValue;
12
12
  height?: DimensionValue;
13
13
  }
@@ -1,5 +1,11 @@
1
1
  import React from "react";
2
- import { View, TouchableOpacity, StyleSheet, StyleProp, ViewStyle } from "react-native";
2
+ import {
3
+ View,
4
+ TouchableOpacity,
5
+ StyleSheet,
6
+ StyleProp,
7
+ ViewStyle,
8
+ } from "react-native";
3
9
  import Swipeable from "react-native-gesture-handler/Swipeable";
4
10
  import { useColorScheme } from "nativewind";
5
11
  import { Colors } from "../../../constants/Colors";
@@ -30,13 +36,24 @@ export const SwipeableRow: React.FC<SwipeableRowProps> = ({
30
36
  }) => {
31
37
  const { colorScheme } = useColorScheme();
32
38
  const isDark = colorScheme === "dark";
33
- const colors = Colors[isDark ? "dark" : "light"];
39
+ const _colors = Colors[isDark ? "dark" : "light"];
34
40
 
35
- const renderActions = (actions: SwipeAction[], progress: any, dragX: any, isRight: boolean) => {
41
+ const renderActions = (
42
+ actions: SwipeAction[],
43
+ _progress: unknown,
44
+ _dragX: unknown,
45
+ isRight: boolean,
46
+ ) => {
36
47
  if (actions.length === 0) return null;
37
48
 
38
49
  return (
39
- <View style={[styles.actionsContainer, isRight ? styles.rightActions : styles.leftActions]}>
50
+ <View
51
+ style={[
52
+ styles.actionsContainer,
53
+ isRight ? styles.rightActions : styles.leftActions,
54
+ { borderRadius: 16, overflow: "hidden", marginVertical: 1 },
55
+ ]}
56
+ >
40
57
  {actions.map((action, index) => {
41
58
  const actionWidth = action.width || 75;
42
59
  return (
@@ -62,13 +79,17 @@ export const SwipeableRow: React.FC<SwipeableRowProps> = ({
62
79
  friction={2}
63
80
  leftThreshold={40}
64
81
  rightThreshold={40}
65
- renderLeftActions={(progress, dragX) => renderActions(leftActions, progress, dragX, false)}
66
- renderRightActions={(progress, dragX) => renderActions(rightActions, progress, dragX, true)}
82
+ renderLeftActions={(progress, dragX) =>
83
+ renderActions(leftActions, progress, dragX, false)
84
+ }
85
+ renderRightActions={(progress, dragX) =>
86
+ renderActions(rightActions, progress, dragX, true)
87
+ }
67
88
  onSwipeableOpen={onSwipeOpen}
68
89
  onSwipeableClose={onSwipeClose}
69
90
  containerStyle={containerStyle}
70
91
  >
71
- <View style={{ backgroundColor: colors.base100 }}>
92
+ <View style={{ flex: 1, backgroundColor: "transparent" }}>
72
93
  {children}
73
94
  </View>
74
95
  </Swipeable>
@@ -1,6 +1,13 @@
1
1
  import React from "react";
2
2
  import { StyleProp, ViewStyle } from "react-native";
3
- import { Gesture, GestureDetector, GestureType } from "react-native-gesture-handler";
3
+ import {
4
+ Gesture,
5
+ GestureDetector,
6
+ GestureType,
7
+ GestureStateChangeEvent,
8
+ GestureUpdateEvent,
9
+ PanGestureHandlerEventPayload,
10
+ } from "react-native-gesture-handler";
4
11
  import Animated, { runOnJS } from "react-native-reanimated";
5
12
 
6
13
  interface GestureWrapperProps {
@@ -12,9 +19,9 @@ interface GestureWrapperProps {
12
19
  onDoubleTap?: () => void;
13
20
 
14
21
  // Pan/Drag Gestures
15
- onPanStart?: (e: any) => void;
16
- onPanUpdate?: (e: any) => void;
17
- onPanEnd?: (e: any) => void;
22
+ onPanStart?: (e: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => void;
23
+ onPanUpdate?: (e: GestureUpdateEvent<PanGestureHandlerEventPayload>) => void;
24
+ onPanEnd?: (e: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => void;
18
25
 
19
26
  // Swipe Gestures
20
27
  onSwipeLeft?: () => void;
@@ -4,7 +4,7 @@ import { Txt } from "../../common/Typography";
4
4
  import { Ionicons } from "@expo/vector-icons";
5
5
  import { useColorScheme } from "nativewind";
6
6
  import { Colors } from "../../../constants/Colors";
7
- import BottomModal from "../BottomModal";
7
+ import Drawer from "../Drawer";
8
8
  import Button from "../buttons/Button";
9
9
  import dayjs from "dayjs";
10
10
 
@@ -104,7 +104,7 @@ export default function DatePicker({
104
104
  <Ionicons name="calendar-outline" size={18} color={colors.primary} />
105
105
  </TouchableOpacity>
106
106
 
107
- <BottomModal isOpen={isOpen} onClose={() => setIsOpen(false)} heightPercent={0.65}>
107
+ <Drawer isOpen={isOpen} onClose={() => setIsOpen(false)} position="bottom" sizePercent={0.65}>
108
108
  <View className="p-4 flex-1">
109
109
  <Txt variant="lg" className="font-bold text-center mb-4">
110
110
  {label}
@@ -180,7 +180,7 @@ export default function DatePicker({
180
180
  <Button label="Close" variant="outline" onPress={() => setIsOpen(false)} className="w-full" />
181
181
  </View>
182
182
  </View>
183
- </BottomModal>
183
+ </Drawer>
184
184
  </View>
185
185
  );
186
186
  }
@@ -2,9 +2,10 @@ import React from "react";
2
2
  import { View } from "react-native";
3
3
  import * as ImagePicker from "expo-image-picker";
4
4
  import { Txt } from "@/components/common/Typography";
5
- import BottomModal from "@/components/ui/BottomModal";
5
+ import Drawer from "@/components/ui/Drawer";
6
6
  import Button from "@/components/ui/buttons/Button";
7
7
 
8
+
8
9
  export type ImagePickerSource = "camera" | "gallery" | "both";
9
10
 
10
11
  export interface ImagePickerResult {
@@ -23,6 +24,7 @@ export interface ImagePickerModalProps {
23
24
  subtitle?: string;
24
25
  allowsEditing?: boolean;
25
26
  allowsMultipleSelection?: boolean;
27
+ aspectRatio?: [number, number];
26
28
  }
27
29
 
28
30
  export default function ImagePickerModal({
@@ -34,9 +36,9 @@ export default function ImagePickerModal({
34
36
  title = "Select Image Source",
35
37
  subtitle = "Choose where to pick your image from",
36
38
  allowsEditing = false,
39
+ aspectRatio = [1, 1],
37
40
  allowsMultipleSelection = false,
38
41
  }: ImagePickerModalProps) {
39
-
40
42
  const launchPicker = async (type: "gallery" | "camera") => {
41
43
  onClose();
42
44
 
@@ -51,10 +53,10 @@ export default function ImagePickerModal({
51
53
 
52
54
  result = await ImagePicker.launchImageLibraryAsync({
53
55
  mediaTypes: ["images"],
54
- quality: 0.8,
56
+ quality: 0.6,
55
57
  allowsEditing: !allowsMultipleSelection && allowsEditing, // multi-select cannot have editing on some OS
56
58
  allowsMultipleSelection,
57
- aspect: allowsEditing ? [16, 9] : undefined, // Assuming a common aspect ratio if cropped
59
+ aspect: allowsEditing ? aspectRatio : undefined, // Assuming a common aspect ratio if cropped
58
60
  });
59
61
  } else {
60
62
  const perm = await ImagePicker.requestCameraPermissionsAsync();
@@ -62,23 +64,47 @@ export default function ImagePickerModal({
62
64
 
63
65
  result = await ImagePicker.launchCameraAsync({
64
66
  mediaTypes: ["images"],
65
- quality: 0.8,
67
+ quality: 0.6,
66
68
  allowsEditing,
67
- aspect: allowsEditing ? [16, 9] : undefined,
69
+ aspect: allowsEditing ? aspectRatio : undefined,
68
70
  });
69
71
  }
70
72
 
71
- if (result && !result.canceled && result.assets && result.assets.length > 0) {
72
- const mappedAssets = result.assets.map(asset => {
73
- const filename = asset.uri.split("/").pop() || "image.jpg";
74
- const match = /\.(\w+)$/.exec(filename);
75
- const mimeType = match ? `image/${match[1]}` : "image/jpeg";
76
- return {
77
- uri: asset.uri,
78
- name: filename,
79
- type: mimeType,
80
- };
81
- });
73
+ if (
74
+ result &&
75
+ !result.canceled &&
76
+ result.assets &&
77
+ result.assets.length > 0
78
+ ) {
79
+ const mappedAssets = await Promise.all(
80
+ result.assets.map(async (asset) => {
81
+ let finalUri = asset.uri;
82
+
83
+ // Resize image if it's too large to save bandwidth
84
+ if (asset.width > 1024 || asset.height > 1024) {
85
+ const resizeAction =
86
+ asset.width > asset.height
87
+ ? { resize: { width: 1024 } }
88
+ : { resize: { height: 1024 } };
89
+
90
+ const manipResult = await ImageManipulator.manipulateAsync(
91
+ asset.uri,
92
+ [resizeAction],
93
+ { compress: 0.7, format: ImageManipulator.SaveFormat.JPEG },
94
+ );
95
+ finalUri = manipResult.uri;
96
+ }
97
+
98
+ const filename = finalUri.split("/").pop() || "image.jpg";
99
+ const match = /\.(\w+)$/.exec(filename);
100
+ const mimeType = match ? `image/${match[1]}` : "image/jpeg";
101
+ return {
102
+ uri: finalUri,
103
+ name: filename,
104
+ type: mimeType,
105
+ };
106
+ }),
107
+ );
82
108
 
83
109
  if (allowsMultipleSelection && onImagesSelected) {
84
110
  onImagesSelected(mappedAssets);
@@ -93,7 +119,7 @@ export default function ImagePickerModal({
93
119
  };
94
120
 
95
121
  return (
96
- <BottomModal isOpen={isOpen} onClose={onClose}>
122
+ <Drawer isOpen={isOpen} onClose={onClose} position="bottom">
97
123
  <View className="p-6">
98
124
  <Txt variant="lg" className="font-bold mb-1 text-center">
99
125
  {title}
@@ -124,6 +150,6 @@ export default function ImagePickerModal({
124
150
  )}
125
151
  </View>
126
152
  </View>
127
- </BottomModal>
153
+ </Drawer>
128
154
  );
129
155
  }
@@ -1,4 +1,4 @@
1
- import React, { useState } from "react";
1
+ import { useState } from "react";
2
2
  import {
3
3
  View,
4
4
  TextInput,
@@ -16,11 +16,16 @@ export interface InputProps extends TextInputProps {
16
16
  leftIcon?: keyof typeof Ionicons.glyphMap;
17
17
  rightIcon?: keyof typeof Ionicons.glyphMap;
18
18
  onRightIconPress?: () => void;
19
+ placeHolder?: string;
20
+ style?: import("react-native").StyleProp<import("react-native").ViewStyle>;
19
21
  helperText?: string;
20
22
  containerStyle?: import("react-native").StyleProp<
21
23
  import("react-native").ViewStyle
22
24
  >;
23
25
  labelOnBorder?: boolean;
26
+ className?: string;
27
+ weight?: "normal" | "medium" | "bold" | "semibold" | "black";
28
+ size?: "sm" | "md" | "lg";
24
29
  }
25
30
 
26
31
  export default function Input({
@@ -31,8 +36,12 @@ export default function Input({
31
36
  onRightIconPress,
32
37
  helperText,
33
38
  style,
39
+ placeHolder = "",
34
40
  containerStyle,
35
41
  labelOnBorder = false,
42
+ className = "mb-2",
43
+ weight = "normal",
44
+ size = "md",
36
45
  ...props
37
46
  }: InputProps) {
38
47
  const { colorScheme } = useColorScheme();
@@ -45,13 +54,22 @@ export default function Input({
45
54
  ? theme.primary
46
55
  : theme.base300;
47
56
 
57
+ const inputHeight = size === "sm" ? 40 : size === "lg" ? 64 : 52;
58
+ const inputFontSize = size === "sm" ? 14 : size === "lg" ? 18 : 16;
59
+ const iconSize = size === "sm" ? 16 : size === "lg" ? 24 : 20;
60
+ const labelSize = size === "sm" ? "xs" : size === "lg" ? "lg" : "base";
48
61
  return (
49
- <View className="mb-4 relative">
62
+ <View
63
+ className={`${className} relative ${props.editable === false ? "opacity-50" : ""}`}
64
+ >
50
65
  {!labelOnBorder && label && (
51
66
  <Txt
52
67
  color={theme.baseContent}
53
- weight="semibold"
54
68
  style={{ marginBottom: 6 }}
69
+ weight={weight}
70
+ variant={labelSize}
71
+ adjustsFontSizeToFit
72
+ numberOfLines={1}
55
73
  >
56
74
  {label} {error ? "*" : ""}{" "}
57
75
  </Txt>
@@ -63,7 +81,7 @@ export default function Input({
63
81
  position: "absolute",
64
82
  top: -6,
65
83
  left: 12,
66
- backgroundColor: theme.base100,
84
+ backgroundColor: theme.base200,
67
85
  paddingHorizontal: 6,
68
86
  zIndex: 10,
69
87
  }}
@@ -85,12 +103,12 @@ export default function Input({
85
103
  {
86
104
  flexDirection: "row",
87
105
  alignItems: "center",
88
- backgroundColor: theme.base100,
106
+ backgroundColor: theme.base200,
89
107
  borderWidth: 1,
90
108
  borderColor,
91
109
  borderRadius: 12,
92
110
  paddingHorizontal: 12,
93
- height: 52,
111
+ height: inputHeight,
94
112
  },
95
113
  containerStyle,
96
114
  ]}
@@ -98,7 +116,7 @@ export default function Input({
98
116
  {leftIcon && (
99
117
  <Ionicons
100
118
  name={leftIcon}
101
- size={20}
119
+ size={iconSize}
102
120
  color={isFocused ? theme.primary : theme.secondary}
103
121
  style={{ marginRight: 8 }}
104
122
  />
@@ -109,12 +127,13 @@ export default function Input({
109
127
  {
110
128
  flex: 1,
111
129
  color: theme.baseContent,
112
- fontSize: 16,
130
+ fontSize: inputFontSize,
113
131
  height: "100%",
114
132
  },
115
133
  style,
116
134
  ]}
117
135
  placeholderTextColor={theme.secondary}
136
+ placeholder={placeHolder}
118
137
  onFocus={(e) => {
119
138
  setIsFocused(true);
120
139
  props.onFocus?.(e);
@@ -133,7 +152,7 @@ export default function Input({
133
152
  >
134
153
  <Ionicons
135
154
  name={rightIcon}
136
- size={20}
155
+ size={iconSize}
137
156
  color={theme.secondary}
138
157
  style={{ marginLeft: 8 }}
139
158
  />