@imksh/create 1.0.24 → 1.0.26

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 (415) hide show
  1. package/package.json +1 -1
  2. package/src/commands/create.js +2 -1
  3. package/src/index.js +1 -1
  4. package/src/utils/askTemplate.js +1 -0
  5. package/templates/mern-react-native/client/src/vite-env.d.ts +1 -0
  6. package/templates/mern-react-native/mobile/_gitignore +43 -0
  7. package/templates/mern-react-native/mobile/babel.config.js +1 -0
  8. package/templates/mern-react-native/mobile/drizzle.config.ts +8 -0
  9. package/templates/mern-react-native/mobile/expo-env.d.ts +3 -0
  10. package/templates/mern-react-native/mobile/package.json +8 -1
  11. package/templates/mern-react-native/mobile/src/app/(auth)/_layout.tsx +12 -0
  12. package/templates/mern-react-native/mobile/src/app/(auth)/change-password.tsx +112 -0
  13. package/templates/mern-react-native/mobile/src/app/(auth)/edit-profile.tsx +156 -0
  14. package/templates/mern-react-native/mobile/src/app/(auth)/forgot-password.tsx +191 -0
  15. package/templates/mern-react-native/mobile/src/app/{login.tsx → (auth)/login.tsx} +69 -21
  16. package/templates/mern-react-native/mobile/src/app/(tabs)/dashboard.tsx +2 -2
  17. package/templates/mern-react-native/mobile/src/app/(tabs)/index.tsx +18 -17
  18. package/templates/mern-react-native/mobile/src/app/(tabs)/profile.tsx +23 -60
  19. package/templates/mern-react-native/mobile/src/app/(tabs)/search.tsx +2 -2
  20. package/templates/mern-react-native/mobile/src/app/_layout.tsx +22 -4
  21. package/templates/mern-react-native/mobile/src/components/common/AnimatedHeader.tsx +328 -0
  22. package/templates/mern-react-native/mobile/src/components/common/LocationLoader.tsx +591 -0
  23. package/templates/mern-react-native/mobile/src/components/common/ScreenHeader.tsx +41 -17
  24. package/templates/mern-react-native/mobile/src/components/common/TabHeader.tsx +58 -0
  25. package/templates/mern-react-native/mobile/src/components/common/Typography.tsx +49 -30
  26. package/templates/mern-react-native/mobile/src/components/common/Welcome.tsx +2 -2
  27. package/templates/mern-react-native/mobile/src/components/ui/BottomModal.tsx +31 -20
  28. package/templates/mern-react-native/mobile/src/components/ui/ClassicTabBar.tsx +4 -3
  29. package/templates/mern-react-native/mobile/src/components/ui/CustomTabBar.tsx +108 -71
  30. package/templates/mern-react-native/mobile/src/components/ui/Sidebar.tsx +81 -56
  31. package/templates/mern-react-native/mobile/src/components/ui/buttons/Button.tsx +106 -37
  32. package/templates/mern-react-native/mobile/src/components/ui/buttons/IconButton.tsx +4 -2
  33. package/templates/mern-react-native/mobile/src/components/ui/data-display/Accordion.tsx +3 -2
  34. package/templates/mern-react-native/mobile/src/components/ui/data-display/Avatar.tsx +4 -3
  35. package/templates/mern-react-native/mobile/src/components/ui/data-display/Badge.tsx +45 -17
  36. package/templates/mern-react-native/mobile/src/components/ui/data-display/ImageViewer.tsx +19 -9
  37. package/templates/mern-react-native/mobile/src/components/ui/feedback/CircularProgress.tsx +5 -4
  38. package/templates/mern-react-native/mobile/src/components/ui/feedback/ProgressBar.tsx +4 -3
  39. package/templates/mern-react-native/mobile/src/components/ui/feedback/Skeleton.tsx +3 -0
  40. package/templates/mern-react-native/mobile/src/components/ui/feedback/Spinner.tsx +11 -3
  41. package/templates/mern-react-native/mobile/src/components/ui/inputs/Checkbox.tsx +3 -2
  42. package/templates/mern-react-native/mobile/src/components/ui/inputs/DatePicker.tsx +186 -0
  43. package/templates/mern-react-native/mobile/src/components/ui/inputs/ImagePickerModal.tsx +129 -0
  44. package/templates/mern-react-native/mobile/src/components/ui/inputs/Input.tsx +54 -14
  45. package/templates/mern-react-native/mobile/src/components/ui/inputs/LocationPicker.tsx +211 -0
  46. package/templates/mern-react-native/mobile/src/components/ui/inputs/OTPInput.tsx +32 -9
  47. package/templates/mern-react-native/mobile/src/components/ui/inputs/PasswordInput.tsx +2 -1
  48. package/templates/mern-react-native/mobile/src/components/ui/inputs/Radio.tsx +3 -2
  49. package/templates/mern-react-native/mobile/src/components/ui/inputs/SearchBar.tsx +41 -4
  50. package/templates/mern-react-native/mobile/src/components/ui/inputs/Slider.tsx +4 -3
  51. package/templates/mern-react-native/mobile/src/components/ui/inputs/Switch.tsx +3 -2
  52. package/templates/mern-react-native/mobile/src/components/ui/inputs/TextArea.tsx +2 -1
  53. package/templates/mern-react-native/mobile/src/components/ui/inputs/WebLocationPicker.tsx +321 -0
  54. package/templates/mern-react-native/mobile/src/components/ui/layout/Grid.tsx +52 -10
  55. package/templates/mern-react-native/mobile/src/components/ui/layout/Section.tsx +7 -8
  56. package/templates/mern-react-native/mobile/src/components/ui/navigation/Pagination.tsx +4 -3
  57. package/templates/mern-react-native/mobile/src/components/ui/navigation/ProgressStepper.tsx +6 -5
  58. package/templates/mern-react-native/mobile/src/components/ui/navigation/Tabs.tsx +30 -4
  59. package/templates/mern-react-native/mobile/src/config/api.ts +12 -1
  60. package/templates/mern-react-native/mobile/src/config/sidebar.config.ts +12 -0
  61. package/templates/mern-react-native/mobile/src/config/tabNavigation.ts +1 -1
  62. package/templates/mern-react-native/mobile/src/db/index.ts +9 -0
  63. package/templates/mern-react-native/mobile/src/db/schema.ts +14 -0
  64. package/templates/mern-react-native/mobile/src/hooks/useDebounce.ts +17 -0
  65. package/templates/mern-react-native/mobile/src/services/notification.service.ts +22 -0
  66. package/templates/mern-react-native/mobile/src/services/socket.service.ts +36 -0
  67. package/templates/mern-react-native/mobile/src/store/useAuthStore.ts +122 -27
  68. package/templates/mern-react-native/mobile/src/store/useNotificationStore.ts +178 -0
  69. package/templates/mern-react-native/mobile/src/types/auth.type.ts +14 -0
  70. package/templates/mern-react-native/mobile/tsconfig.json +1 -0
  71. package/templates/mern-ts/client/src/vite-env.d.ts +1 -0
  72. package/templates/next/next.config.mjs +1 -0
  73. package/templates/next/package.json +10 -9
  74. package/templates/next/postcss.config.js +5 -0
  75. package/templates/next/src/app/layout.js +1 -0
  76. package/templates/next/src/app/page.js +1 -1
  77. package/templates/next/src/components/layout/ProtectedRoute.jsx +3 -3
  78. package/templates/next/src/index.css +1 -0
  79. package/templates/next/src/store/useUiStore.js +13 -7
  80. package/templates/next-ts/.env.example +0 -0
  81. package/templates/next-ts/AGENTS.md +37 -0
  82. package/templates/next-ts/CLAUDE.md +1 -0
  83. package/templates/next-ts/_gitignore +0 -24
  84. package/templates/next-ts/next-env.d.ts +3 -1
  85. package/templates/next-ts/next.config.mjs +1 -0
  86. package/templates/next-ts/package.json +13 -12
  87. package/templates/next-ts/postcss.config.js +5 -0
  88. package/templates/next-ts/public/logo.png +0 -0
  89. package/templates/next-ts/src/app/error.tsx +41 -0
  90. package/templates/next-ts/src/app/layout.tsx +2 -1
  91. package/templates/next-ts/src/app/not-found.tsx +5 -0
  92. package/templates/next-ts/src/app/page.tsx +1 -1
  93. package/templates/next-ts/src/components/layout/ProtectedRoute.tsx +3 -3
  94. package/templates/next-ts/src/components/ui/Button.tsx +63 -0
  95. package/templates/next-ts/src/components/ui/Input.tsx +79 -0
  96. package/templates/next-ts/src/index.css +1 -0
  97. package/templates/next-ts/src/store/useUiStore.ts +13 -7
  98. package/templates/next-ts/tsconfig.json +19 -5
  99. package/templates/production-fullstack/client/index.html +14 -0
  100. package/templates/production-fullstack/client/package.json +47 -0
  101. package/templates/production-fullstack/client/public/_redirects +1 -0
  102. package/templates/production-fullstack/client/public/favicon.ico +0 -0
  103. package/templates/production-fullstack/client/public/favicon.svg +1 -0
  104. package/templates/production-fullstack/client/public/logo.png +0 -0
  105. package/templates/production-fullstack/client/public/manifest.json +24 -0
  106. package/templates/production-fullstack/client/public/sw.js +56 -0
  107. package/templates/production-fullstack/client/src/App.tsx +68 -0
  108. package/templates/production-fullstack/client/src/assets/animations/loading.json +1 -0
  109. package/templates/production-fullstack/client/src/assets/data/navigation.ts +29 -0
  110. package/templates/production-fullstack/client/src/assets/images/logo.png +0 -0
  111. package/templates/production-fullstack/client/src/components/layout/ProtectedRoute.tsx +23 -0
  112. package/templates/production-fullstack/client/src/components/layout/PublicLayout.tsx +13 -0
  113. package/templates/production-fullstack/client/src/components/layout/SidebarLayout.tsx +37 -0
  114. package/templates/production-fullstack/client/src/components/shared/Breadcrumbs.tsx +27 -0
  115. package/templates/production-fullstack/client/src/components/shared/LottieIcon.tsx +36 -0
  116. package/templates/production-fullstack/client/src/components/shared/NotFound.tsx +78 -0
  117. package/templates/production-fullstack/client/src/components/shared/PwaInstallPrompt.tsx +72 -0
  118. package/templates/production-fullstack/client/src/components/shared/SEO.tsx +67 -0
  119. package/templates/production-fullstack/client/src/components/shared/Scroll.tsx +25 -0
  120. package/templates/production-fullstack/client/src/components/shared/Unauthorized.tsx +76 -0
  121. package/templates/production-fullstack/client/src/components/shared/skeletons/common/CardSkeleton.tsx +23 -0
  122. package/templates/production-fullstack/client/src/components/shared/skeletons/common/DashboardSkeleton.tsx +19 -0
  123. package/templates/production-fullstack/client/src/components/shared/skeletons/common/ListSkeleton.tsx +24 -0
  124. package/templates/production-fullstack/client/src/components/shared/skeletons/common/PageSkeleton.tsx +26 -0
  125. package/templates/production-fullstack/client/src/components/shared/skeletons/common/ProfileSkeleton.tsx +23 -0
  126. package/templates/production-fullstack/client/src/components/shared/skeletons/common/Skeleton.tsx +18 -0
  127. package/templates/production-fullstack/client/src/components/shared/skeletons/common/TableSkeleton.tsx +33 -0
  128. package/templates/production-fullstack/client/src/components/ui/ConfirmModal.tsx +152 -0
  129. package/templates/production-fullstack/client/src/components/ui/Header.tsx +230 -0
  130. package/templates/production-fullstack/client/src/components/ui/Loading.tsx +19 -0
  131. package/templates/production-fullstack/client/src/components/ui/Modal.tsx +106 -0
  132. package/templates/production-fullstack/client/src/components/ui/SidebarHeader.tsx +34 -0
  133. package/templates/production-fullstack/client/src/components/ui/Table.tsx +118 -0
  134. package/templates/production-fullstack/client/src/components/ui/ToggleSwitch.tsx +38 -0
  135. package/templates/production-fullstack/client/src/components/ui/sidebar.tsx +152 -0
  136. package/templates/production-fullstack/client/src/config/index.ts +44 -0
  137. package/templates/production-fullstack/client/src/constants/navigation.ts +14 -0
  138. package/templates/production-fullstack/client/src/features/auth/api/authService.ts +19 -0
  139. package/templates/production-fullstack/client/src/features/auth/pages/Login.tsx +233 -0
  140. package/templates/production-fullstack/client/src/features/auth/store/useAuthStore.ts +143 -0
  141. package/templates/production-fullstack/client/src/features/core/pages/Home.tsx +150 -0
  142. package/templates/production-fullstack/client/src/features/core/pages/Profile.tsx +9 -0
  143. package/templates/production-fullstack/client/src/hooks/useLenis.ts +28 -0
  144. package/templates/production-fullstack/client/src/hooks/usePwaInstall.ts +45 -0
  145. package/templates/production-fullstack/client/src/hooks/useWindowSize.ts +25 -0
  146. package/templates/production-fullstack/client/src/index.css +158 -0
  147. package/templates/production-fullstack/client/src/lib/axios.ts +22 -0
  148. package/templates/production-fullstack/client/src/lib/dayjs.ts +12 -0
  149. package/templates/production-fullstack/client/src/lib/query-client.ts +11 -0
  150. package/templates/production-fullstack/client/src/lib/socket.ts +6 -0
  151. package/templates/production-fullstack/client/src/main.tsx +28 -0
  152. package/templates/production-fullstack/client/src/store/useUiStore.ts +74 -0
  153. package/templates/production-fullstack/client/src/utils/formatDate.ts +19 -0
  154. package/templates/production-fullstack/client/src/utils/getInitials.ts +10 -0
  155. package/templates/production-fullstack/client/src/vite-env.d.ts +1 -0
  156. package/templates/production-fullstack/client/tsconfig.json +25 -0
  157. package/templates/production-fullstack/client/tsconfig.node.json +10 -0
  158. package/templates/production-fullstack/client/vite.config.ts +8 -0
  159. package/templates/production-fullstack/mobile/LICENSE +21 -0
  160. package/templates/production-fullstack/mobile/app.json +84 -0
  161. package/templates/production-fullstack/mobile/assets/animations/celebrate.json +1 -0
  162. package/templates/production-fullstack/mobile/assets/animations/infinity.json +1 -0
  163. package/templates/production-fullstack/mobile/assets/animations/loading.json +1 -0
  164. package/templates/production-fullstack/mobile/assets/fonts/Inter_Bold.ttf +0 -0
  165. package/templates/production-fullstack/mobile/assets/fonts/Inter_ExtraBold.ttf +0 -0
  166. package/templates/production-fullstack/mobile/assets/fonts/Inter_Medium.ttf +0 -0
  167. package/templates/production-fullstack/mobile/assets/fonts/Inter_Regular.ttf +0 -0
  168. package/templates/production-fullstack/mobile/assets/fonts/Inter_SemiBold.ttf +0 -0
  169. package/templates/production-fullstack/mobile/assets/images/logo/logo.png +0 -0
  170. package/templates/production-fullstack/mobile/assets/images/logo/logo.svg +1 -0
  171. package/templates/production-fullstack/mobile/assets/images/logo/logoWithBg.png +0 -0
  172. package/templates/production-fullstack/mobile/babel.config.js +13 -0
  173. package/templates/production-fullstack/mobile/drizzle.config.ts +8 -0
  174. package/templates/production-fullstack/mobile/eas.json +24 -0
  175. package/templates/production-fullstack/mobile/eslint.config.js +10 -0
  176. package/templates/production-fullstack/mobile/expo-env.d.ts +3 -0
  177. package/templates/production-fullstack/mobile/metro.config.js +6 -0
  178. package/templates/production-fullstack/mobile/nativewind-env.d.ts +3 -0
  179. package/templates/production-fullstack/mobile/package.json +89 -0
  180. package/templates/production-fullstack/mobile/src/app/(auth)/_layout.tsx +12 -0
  181. package/templates/production-fullstack/mobile/src/app/(auth)/change-password.tsx +112 -0
  182. package/templates/production-fullstack/mobile/src/app/(auth)/edit-profile.tsx +160 -0
  183. package/templates/production-fullstack/mobile/src/app/(auth)/forgot-password.tsx +191 -0
  184. package/templates/production-fullstack/mobile/src/app/(auth)/login.tsx +253 -0
  185. package/templates/production-fullstack/mobile/src/app/_layout.tsx +102 -0
  186. package/templates/production-fullstack/mobile/src/app/global.css +82 -0
  187. package/templates/production-fullstack/mobile/src/components/common/AnimatedHeader.tsx +328 -0
  188. package/templates/production-fullstack/mobile/src/components/common/ConfirmationToast.tsx +67 -0
  189. package/templates/production-fullstack/mobile/src/components/common/Loading.tsx +26 -0
  190. package/templates/production-fullstack/mobile/src/components/common/LocationLoader.tsx +591 -0
  191. package/templates/production-fullstack/mobile/src/components/common/ScreenHeader.tsx +68 -0
  192. package/templates/production-fullstack/mobile/src/components/common/TabHeader.tsx +58 -0
  193. package/templates/production-fullstack/mobile/src/components/common/Typography.tsx +113 -0
  194. package/templates/production-fullstack/mobile/src/components/common/Welcome.tsx +55 -0
  195. package/templates/production-fullstack/mobile/src/components/ui/BottomModal.tsx +159 -0
  196. package/templates/production-fullstack/mobile/src/components/ui/ClassicTabBar.tsx +129 -0
  197. package/templates/production-fullstack/mobile/src/components/ui/CustomTabBar.tsx +238 -0
  198. package/templates/production-fullstack/mobile/src/components/ui/Sidebar.tsx +258 -0
  199. package/templates/production-fullstack/mobile/src/components/ui/buttons/Button.tsx +180 -0
  200. package/templates/production-fullstack/mobile/src/components/ui/buttons/ButtonGroup.tsx +32 -0
  201. package/templates/production-fullstack/mobile/src/components/ui/buttons/FloatingActionButton.tsx +72 -0
  202. package/templates/production-fullstack/mobile/src/components/ui/buttons/IconButton.tsx +84 -0
  203. package/templates/production-fullstack/mobile/src/components/ui/data-display/Accordion.tsx +82 -0
  204. package/templates/production-fullstack/mobile/src/components/ui/data-display/Avatar.tsx +47 -0
  205. package/templates/production-fullstack/mobile/src/components/ui/data-display/Badge.tsx +104 -0
  206. package/templates/production-fullstack/mobile/src/components/ui/data-display/Card.tsx +36 -0
  207. package/templates/production-fullstack/mobile/src/components/ui/data-display/Image.tsx +43 -0
  208. package/templates/production-fullstack/mobile/src/components/ui/data-display/ImageViewer.tsx +33 -0
  209. package/templates/production-fullstack/mobile/src/components/ui/data-display/SwipeableRow.tsx +94 -0
  210. package/templates/production-fullstack/mobile/src/components/ui/feedback/CircularProgress.tsx +38 -0
  211. package/templates/production-fullstack/mobile/src/components/ui/feedback/GestureWrapper.tsx +114 -0
  212. package/templates/production-fullstack/mobile/src/components/ui/feedback/ProgressBar.tsx +51 -0
  213. package/templates/production-fullstack/mobile/src/components/ui/feedback/Skeleton.tsx +84 -0
  214. package/templates/production-fullstack/mobile/src/components/ui/feedback/Spinner.tsx +50 -0
  215. package/templates/production-fullstack/mobile/src/components/ui/inputs/Checkbox.tsx +54 -0
  216. package/templates/production-fullstack/mobile/src/components/ui/inputs/DatePicker.tsx +186 -0
  217. package/templates/production-fullstack/mobile/src/components/ui/inputs/ImagePickerModal.tsx +129 -0
  218. package/templates/production-fullstack/mobile/src/components/ui/inputs/Input.tsx +158 -0
  219. package/templates/production-fullstack/mobile/src/components/ui/inputs/LocationPicker.tsx +211 -0
  220. package/templates/production-fullstack/mobile/src/components/ui/inputs/OTPInput.tsx +83 -0
  221. package/templates/production-fullstack/mobile/src/components/ui/inputs/PasswordInput.tsx +16 -0
  222. package/templates/production-fullstack/mobile/src/components/ui/inputs/Radio.tsx +54 -0
  223. package/templates/production-fullstack/mobile/src/components/ui/inputs/SearchBar.tsx +53 -0
  224. package/templates/production-fullstack/mobile/src/components/ui/inputs/Slider.tsx +49 -0
  225. package/templates/production-fullstack/mobile/src/components/ui/inputs/Switch.tsx +75 -0
  226. package/templates/production-fullstack/mobile/src/components/ui/inputs/TextArea.tsx +15 -0
  227. package/templates/production-fullstack/mobile/src/components/ui/inputs/WebLocationPicker.tsx +321 -0
  228. package/templates/production-fullstack/mobile/src/components/ui/layout/Container.tsx +23 -0
  229. package/templates/production-fullstack/mobile/src/components/ui/layout/Divider.tsx +20 -0
  230. package/templates/production-fullstack/mobile/src/components/ui/layout/Grid.tsx +62 -0
  231. package/templates/production-fullstack/mobile/src/components/ui/layout/KeyboardAvoidingViewWrapper.tsx +16 -0
  232. package/templates/production-fullstack/mobile/src/components/ui/layout/ScrollContainer.tsx +21 -0
  233. package/templates/production-fullstack/mobile/src/components/ui/layout/Section.tsx +51 -0
  234. package/templates/production-fullstack/mobile/src/components/ui/layout/Spacer.tsx +6 -0
  235. package/templates/production-fullstack/mobile/src/components/ui/layout/Stack.tsx +34 -0
  236. package/templates/production-fullstack/mobile/src/components/ui/navigation/Pagination.tsx +61 -0
  237. package/templates/production-fullstack/mobile/src/components/ui/navigation/ProgressStepper.tsx +66 -0
  238. package/templates/production-fullstack/mobile/src/components/ui/navigation/Tabs.tsx +173 -0
  239. package/templates/production-fullstack/mobile/src/config/sidebar.config.ts +72 -0
  240. package/templates/production-fullstack/mobile/src/config/tabNavigation.ts +64 -0
  241. package/templates/production-fullstack/mobile/src/constants/Colors.ts +71 -0
  242. package/templates/production-fullstack/mobile/src/db/index.ts +9 -0
  243. package/templates/production-fullstack/mobile/src/db/schema.ts +14 -0
  244. package/templates/production-fullstack/mobile/src/features/auth/api/auth.service.ts +35 -0
  245. package/templates/production-fullstack/mobile/src/features/auth/store/useAuthStore.ts +273 -0
  246. package/templates/production-fullstack/mobile/src/features/auth/types/auth.type.ts +14 -0
  247. package/templates/production-fullstack/mobile/src/hooks/useDebounce.ts +17 -0
  248. package/templates/production-fullstack/mobile/src/lib/axios.ts +27 -0
  249. package/templates/production-fullstack/mobile/src/lib/query-client.ts +11 -0
  250. package/templates/production-fullstack/mobile/src/lib/socket.ts +36 -0
  251. package/templates/production-fullstack/mobile/src/lib/storage.ts +55 -0
  252. package/templates/production-fullstack/mobile/src/services/permission.service.ts +214 -0
  253. package/templates/production-fullstack/mobile/src/store/localStore.ts +7 -0
  254. package/templates/production-fullstack/mobile/src/store/useNotificationStore.ts +53 -0
  255. package/templates/production-fullstack/mobile/src/types/common.type.ts +6 -0
  256. package/templates/production-fullstack/mobile/src/types/images.d.ts +24 -0
  257. package/templates/production-fullstack/mobile/src/utils/toast.ts +26 -0
  258. package/templates/production-fullstack/mobile/tailwind.config.js +71 -0
  259. package/templates/production-fullstack/mobile/tsconfig.json +23 -0
  260. package/templates/production-fullstack/server/.env.example +63 -0
  261. package/templates/production-fullstack/server/README.md +75 -0
  262. package/templates/production-fullstack/server/eslint.config.js +13 -0
  263. package/templates/production-fullstack/server/package.json +58 -0
  264. package/templates/production-fullstack/server/prisma/schema/core/attachment.prisma +14 -0
  265. package/templates/production-fullstack/server/prisma/schema/core/notification.prisma +18 -0
  266. package/templates/production-fullstack/server/prisma/schema/core/permission.prisma +26 -0
  267. package/templates/production-fullstack/server/prisma/schema/core/role.prisma +25 -0
  268. package/templates/production-fullstack/server/prisma/schema/core/user.prisma +56 -0
  269. package/templates/production-fullstack/server/prisma/schema/enums/common.prisma +13 -0
  270. package/templates/production-fullstack/server/prisma/schema/enums/notification.prisma +6 -0
  271. package/templates/production-fullstack/server/prisma/schema/enums/user.prisma +11 -0
  272. package/templates/production-fullstack/server/prisma/schema/schema.prisma +7 -0
  273. package/templates/production-fullstack/server/prisma.config.ts +14 -0
  274. package/templates/production-fullstack/server/src/app.ts +36 -0
  275. package/templates/production-fullstack/server/src/common/middlewares/auth.middleware.ts +45 -0
  276. package/templates/production-fullstack/server/src/common/middlewares/errorHandler.ts +16 -0
  277. package/templates/production-fullstack/server/src/common/middlewares/multer.ts +20 -0
  278. package/templates/production-fullstack/server/src/common/middlewares/rateLimiter.ts +53 -0
  279. package/templates/production-fullstack/server/src/common/services/email.service.ts +28 -0
  280. package/templates/production-fullstack/server/src/common/services/push.service.ts +65 -0
  281. package/templates/production-fullstack/server/src/common/services/storage.service.ts +9 -0
  282. package/templates/production-fullstack/server/src/common/types/express.d.ts +10 -0
  283. package/templates/production-fullstack/server/src/common/utils/cloudinaryUpload.ts +44 -0
  284. package/templates/production-fullstack/server/src/common/utils/emailOtp.ts +30 -0
  285. package/templates/production-fullstack/server/src/common/utils/genOtpToken.ts +22 -0
  286. package/templates/production-fullstack/server/src/common/utils/generateVapidKeys.ts +12 -0
  287. package/templates/production-fullstack/server/src/common/utils/jwt.ts +27 -0
  288. package/templates/production-fullstack/server/src/common/utils/pushHelper.ts +22 -0
  289. package/templates/production-fullstack/server/src/config/env.ts +2 -0
  290. package/templates/production-fullstack/server/src/config/logger.ts +58 -0
  291. package/templates/production-fullstack/server/src/config/prisma.ts +26 -0
  292. package/templates/production-fullstack/server/src/features/attachments/upload.controller.ts +22 -0
  293. package/templates/production-fullstack/server/src/features/attachments/upload.routes.ts +11 -0
  294. package/templates/production-fullstack/server/src/features/auth/auth.controller.ts +124 -0
  295. package/templates/production-fullstack/server/src/features/auth/auth.routes.ts +22 -0
  296. package/templates/production-fullstack/server/src/features/auth/auth.service.ts +155 -0
  297. package/templates/production-fullstack/server/src/features/notifications/push.controller.ts +55 -0
  298. package/templates/production-fullstack/server/src/features/notifications/push.routes.ts +11 -0
  299. package/templates/production-fullstack/server/src/index.ts +17 -0
  300. package/templates/production-fullstack/server/src/routes/index.ts +12 -0
  301. package/templates/production-fullstack/server/src/sockets/auth.ts +0 -0
  302. package/templates/production-fullstack/server/src/sockets/connection.ts +31 -0
  303. package/templates/production-fullstack/server/src/sockets/emitters/assignment.emitter.ts +0 -0
  304. package/templates/production-fullstack/server/src/sockets/emitters/attendance.emitter.ts +0 -0
  305. package/templates/production-fullstack/server/src/sockets/emitters/exam.emitter.ts +0 -0
  306. package/templates/production-fullstack/server/src/sockets/emitters/notification.emitter.ts +17 -0
  307. package/templates/production-fullstack/server/src/sockets/events.ts +27 -0
  308. package/templates/production-fullstack/server/src/sockets/handlers/attendance.handler.ts +0 -0
  309. package/templates/production-fullstack/server/src/sockets/handlers/chat.handler.ts +0 -0
  310. package/templates/production-fullstack/server/src/sockets/handlers/index.ts +15 -0
  311. package/templates/production-fullstack/server/src/sockets/handlers/lms.handler.ts +0 -0
  312. package/templates/production-fullstack/server/src/sockets/handlers/notification.handler.ts +39 -0
  313. package/templates/production-fullstack/server/src/sockets/index.ts +39 -0
  314. package/templates/production-fullstack/server/src/sockets/middleware.ts +54 -0
  315. package/templates/production-fullstack/server/src/sockets/rooms.ts +11 -0
  316. package/templates/production-fullstack/server/src/sockets/types.ts +32 -0
  317. package/templates/production-fullstack/server/tsconfig.json +14 -0
  318. package/templates/react-native/babel.config.js +1 -0
  319. package/templates/react-native/drizzle.config.ts +8 -0
  320. package/templates/react-native/package.json +8 -1
  321. package/templates/react-native/src/app/(auth)/_layout.tsx +12 -0
  322. package/templates/react-native/src/app/(auth)/change-password.tsx +112 -0
  323. package/templates/react-native/src/app/(auth)/edit-profile.tsx +156 -0
  324. package/templates/react-native/src/app/(auth)/forgot-password.tsx +191 -0
  325. package/templates/react-native/src/app/{login.tsx → (auth)/login.tsx} +69 -21
  326. package/templates/react-native/src/app/(tabs)/dashboard.tsx +2 -2
  327. package/templates/react-native/src/app/(tabs)/index.tsx +18 -17
  328. package/templates/react-native/src/app/(tabs)/profile.tsx +23 -60
  329. package/templates/react-native/src/app/(tabs)/search.tsx +2 -2
  330. package/templates/react-native/src/app/_layout.tsx +22 -4
  331. package/templates/react-native/src/components/common/AnimatedHeader.tsx +328 -0
  332. package/templates/react-native/src/components/common/LocationLoader.tsx +591 -0
  333. package/templates/react-native/src/components/common/ScreenHeader.tsx +41 -17
  334. package/templates/react-native/src/components/common/TabHeader.tsx +58 -0
  335. package/templates/react-native/src/components/common/Typography.tsx +49 -30
  336. package/templates/react-native/src/components/common/Welcome.tsx +2 -2
  337. package/templates/react-native/src/components/ui/BottomModal.tsx +31 -20
  338. package/templates/react-native/src/components/ui/ClassicTabBar.tsx +4 -3
  339. package/templates/react-native/src/components/ui/CustomTabBar.tsx +108 -71
  340. package/templates/react-native/src/components/ui/Sidebar.tsx +81 -56
  341. package/templates/react-native/src/components/ui/buttons/Button.tsx +106 -37
  342. package/templates/react-native/src/components/ui/buttons/IconButton.tsx +4 -2
  343. package/templates/react-native/src/components/ui/data-display/Accordion.tsx +3 -2
  344. package/templates/react-native/src/components/ui/data-display/Avatar.tsx +4 -3
  345. package/templates/react-native/src/components/ui/data-display/Badge.tsx +45 -17
  346. package/templates/react-native/src/components/ui/data-display/ImageViewer.tsx +19 -9
  347. package/templates/react-native/src/components/ui/feedback/CircularProgress.tsx +5 -4
  348. package/templates/react-native/src/components/ui/feedback/ProgressBar.tsx +4 -3
  349. package/templates/react-native/src/components/ui/feedback/Skeleton.tsx +3 -0
  350. package/templates/react-native/src/components/ui/feedback/Spinner.tsx +11 -3
  351. package/templates/react-native/src/components/ui/inputs/Checkbox.tsx +3 -2
  352. package/templates/react-native/src/components/ui/inputs/DatePicker.tsx +186 -0
  353. package/templates/react-native/src/components/ui/inputs/ImagePickerModal.tsx +129 -0
  354. package/templates/react-native/src/components/ui/inputs/Input.tsx +54 -14
  355. package/templates/react-native/src/components/ui/inputs/LocationPicker.tsx +211 -0
  356. package/templates/react-native/src/components/ui/inputs/OTPInput.tsx +32 -9
  357. package/templates/react-native/src/components/ui/inputs/PasswordInput.tsx +2 -1
  358. package/templates/react-native/src/components/ui/inputs/Radio.tsx +3 -2
  359. package/templates/react-native/src/components/ui/inputs/SearchBar.tsx +41 -4
  360. package/templates/react-native/src/components/ui/inputs/Slider.tsx +4 -3
  361. package/templates/react-native/src/components/ui/inputs/Switch.tsx +3 -2
  362. package/templates/react-native/src/components/ui/inputs/TextArea.tsx +2 -1
  363. package/templates/react-native/src/components/ui/inputs/WebLocationPicker.tsx +321 -0
  364. package/templates/react-native/src/components/ui/layout/Grid.tsx +52 -10
  365. package/templates/react-native/src/components/ui/layout/Section.tsx +7 -8
  366. package/templates/react-native/src/components/ui/navigation/Pagination.tsx +4 -3
  367. package/templates/react-native/src/components/ui/navigation/ProgressStepper.tsx +6 -5
  368. package/templates/react-native/src/components/ui/navigation/Tabs.tsx +30 -4
  369. package/templates/react-native/src/config/api.ts +12 -1
  370. package/templates/react-native/src/config/sidebar.config.ts +12 -0
  371. package/templates/react-native/src/config/tabNavigation.ts +1 -1
  372. package/templates/react-native/src/db/index.ts +9 -0
  373. package/templates/react-native/src/db/schema.ts +14 -0
  374. package/templates/react-native/src/hooks/useDebounce.ts +17 -0
  375. package/templates/react-native/src/services/notification.service.ts +22 -0
  376. package/templates/react-native/src/services/socket.service.ts +36 -0
  377. package/templates/react-native/src/store/useAuthStore.ts +122 -27
  378. package/templates/react-native/src/store/useNotificationStore.ts +178 -0
  379. package/templates/react-native/src/types/auth.type.ts +14 -0
  380. package/templates/react-native/tsconfig.json +1 -0
  381. package/templates/react-ts/src/vite-env.d.ts +1 -0
  382. package/templates/mern-react-native/mobile/.env.example +0 -2
  383. package/templates/mern-react-native/mobile/.vscode/extensions.json +0 -1
  384. package/templates/mern-react-native/mobile/.vscode/settings.json +0 -7
  385. package/templates/mern-react-native/mobile/README.md +0 -159
  386. package/templates/mern-react-native/mobile/docs/README.md +0 -17
  387. package/templates/mern-react-native/mobile/docs/components/buttons.md +0 -40
  388. package/templates/mern-react-native/mobile/docs/components/data-display.md +0 -44
  389. package/templates/mern-react-native/mobile/docs/components/feedback.md +0 -36
  390. package/templates/mern-react-native/mobile/docs/components/gestures.md +0 -60
  391. package/templates/mern-react-native/mobile/docs/components/inputs.md +0 -41
  392. package/templates/mern-react-native/mobile/docs/components/layout.md +0 -34
  393. package/templates/mern-react-native/mobile/docs/components/navigation.md +0 -31
  394. package/templates/mern-react-native/mobile/docs/features.md +0 -85
  395. package/templates/mern-react-native/mobile/docs/getting-started.md +0 -47
  396. package/templates/mern-react-native/mobile/src/components/common/HomeHeader.tsx +0 -43
  397. package/templates/mern-react-native/mobile/src/components/settings/SettingToggle.tsx +0 -26
  398. package/templates/mern-react-native/mobile/src/components/settings/SettingsOptions.tsx +0 -47
  399. package/templates/react-native/.env.example +0 -2
  400. package/templates/react-native/.vscode/extensions.json +0 -1
  401. package/templates/react-native/.vscode/settings.json +0 -7
  402. package/templates/react-native/README.md +0 -159
  403. package/templates/react-native/docs/README.md +0 -17
  404. package/templates/react-native/docs/components/buttons.md +0 -40
  405. package/templates/react-native/docs/components/data-display.md +0 -44
  406. package/templates/react-native/docs/components/feedback.md +0 -36
  407. package/templates/react-native/docs/components/gestures.md +0 -60
  408. package/templates/react-native/docs/components/inputs.md +0 -41
  409. package/templates/react-native/docs/components/layout.md +0 -34
  410. package/templates/react-native/docs/components/navigation.md +0 -31
  411. package/templates/react-native/docs/features.md +0 -85
  412. package/templates/react-native/docs/getting-started.md +0 -47
  413. package/templates/react-native/src/components/common/HomeHeader.tsx +0 -43
  414. package/templates/react-native/src/components/settings/SettingToggle.tsx +0 -26
  415. package/templates/react-native/src/components/settings/SettingsOptions.tsx +0 -47
@@ -0,0 +1,23 @@
1
+ import Skeleton from "./Skeleton";
2
+
3
+ const CardSkeleton = () => {
4
+ return (
5
+ <div className="card bg-base-100 shadow border border-base-300">
6
+ <div className="card-body space-y-4">
7
+
8
+ <Skeleton className="h-40 w-full rounded-xl" />
9
+
10
+ <Skeleton className="h-6 w-2/3" />
11
+
12
+ <Skeleton className="h-4 w-full" />
13
+
14
+ <Skeleton className="h-4 w-5/6" />
15
+
16
+ <Skeleton className="h-10 w-28" />
17
+
18
+ </div>
19
+ </div>
20
+ );
21
+ };
22
+
23
+ export default CardSkeleton;
@@ -0,0 +1,19 @@
1
+ import CardSkeleton from "./CardSkeleton";
2
+
3
+ const DashboardSkeleton = () => {
4
+ return (
5
+ <div className="space-y-8">
6
+
7
+ <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6">
8
+ {[...Array(4)].map((_, i) => (
9
+ <CardSkeleton key={i} />
10
+ ))}
11
+ </div>
12
+
13
+ <CardSkeleton />
14
+
15
+ </div>
16
+ );
17
+ };
18
+
19
+ export default DashboardSkeleton;
@@ -0,0 +1,24 @@
1
+ import Skeleton from "./Skeleton";
2
+
3
+ const ListSkeleton = ({ items = 6 }) => {
4
+ return (
5
+ <div className="space-y-4">
6
+ {Array.from({ length: items }).map((_, i) => (
7
+ <div
8
+ key={i}
9
+ className="flex items-center gap-4"
10
+ >
11
+ <Skeleton className="w-12 h-12 rounded-full" />
12
+
13
+ <div className="flex-1 space-y-2">
14
+ <Skeleton className="h-5 w-1/3" />
15
+
16
+ <Skeleton className="h-4 w-2/3" />
17
+ </div>
18
+ </div>
19
+ ))}
20
+ </div>
21
+ );
22
+ };
23
+
24
+ export default ListSkeleton;
@@ -0,0 +1,26 @@
1
+ import Skeleton from "./Skeleton";
2
+
3
+ const PageSkeleton = () => {
4
+ return (
5
+ <div className="space-y-8">
6
+
7
+ <Skeleton className="h-10 w-56" />
8
+
9
+ <Skeleton className="h-64 w-full rounded-2xl" />
10
+
11
+ <div className="grid md:grid-cols-3 gap-6">
12
+
13
+ {[1, 2, 3].map((i) => (
14
+ <Skeleton
15
+ key={i}
16
+ className="h-40 rounded-xl"
17
+ />
18
+ ))}
19
+
20
+ </div>
21
+
22
+ </div>
23
+ );
24
+ };
25
+
26
+ export default PageSkeleton;
@@ -0,0 +1,23 @@
1
+ import Skeleton from "./Skeleton";
2
+
3
+ const ProfileSkeleton = () => {
4
+ return (
5
+ <div className="flex gap-6 items-center">
6
+
7
+ <Skeleton className="w-24 h-24 rounded-full" />
8
+
9
+ <div className="flex-1 space-y-3">
10
+
11
+ <Skeleton className="h-6 w-48" />
12
+
13
+ <Skeleton className="h-4 w-64" />
14
+
15
+ <Skeleton className="h-10 w-32" />
16
+
17
+ </div>
18
+
19
+ </div>
20
+ );
21
+ };
22
+
23
+ export default ProfileSkeleton;
@@ -0,0 +1,18 @@
1
+ const Skeleton = ({
2
+ className = "",
3
+ rounded = "rounded-lg",
4
+ animate = true,
5
+ }) => {
6
+ return (
7
+ <div
8
+ className={`
9
+ bg-base-300
10
+ ${rounded}
11
+ ${animate ? "animate-pulse" : ""}
12
+ ${className}
13
+ `}
14
+ />
15
+ );
16
+ };
17
+
18
+ export default Skeleton;
@@ -0,0 +1,33 @@
1
+ import Skeleton from "./Skeleton";
2
+
3
+ const TableSkeleton = ({ rows = 6, columns = 5 }) => {
4
+ return (
5
+ <div className="overflow-x-auto border border-base-300 rounded-xl">
6
+ <table className="table">
7
+ <thead>
8
+ <tr>
9
+ {Array.from({ length: columns }).map((_, i) => (
10
+ <th key={i}>
11
+ <Skeleton className="h-4 w-20" />
12
+ </th>
13
+ ))}
14
+ </tr>
15
+ </thead>
16
+
17
+ <tbody>
18
+ {Array.from({ length: rows }).map((_, row) => (
19
+ <tr key={row}>
20
+ {Array.from({ length: columns }).map((_, col) => (
21
+ <td key={col}>
22
+ <Skeleton className="h-4 w-full" />
23
+ </td>
24
+ ))}
25
+ </tr>
26
+ ))}
27
+ </tbody>
28
+ </table>
29
+ </div>
30
+ );
31
+ };
32
+
33
+ export default TableSkeleton;
@@ -0,0 +1,152 @@
1
+ import { useEffect } from "react";
2
+ import { createPortal } from "react-dom";
3
+ import {
4
+ FaTriangleExclamation,
5
+ FaCircleInfo,
6
+ FaCircleCheck,
7
+ FaCircleXmark,
8
+ } from "react-icons/fa6";
9
+
10
+ const variants: Record<
11
+ "warning" | "error" | "success" | "info",
12
+ { icon: any; iconBg: string; iconColor: string; button: string }
13
+ > = {
14
+ warning: {
15
+ icon: FaTriangleExclamation,
16
+ iconBg: "bg-warning/15",
17
+ iconColor: "text-warning",
18
+ button: "btn-warning",
19
+ },
20
+ error: {
21
+ icon: FaCircleXmark,
22
+ iconBg: "bg-error/15",
23
+ iconColor: "text-error",
24
+ button: "btn-error",
25
+ },
26
+ success: {
27
+ icon: FaCircleCheck,
28
+ iconBg: "bg-success/15",
29
+ iconColor: "text-success",
30
+ button: "btn-success",
31
+ },
32
+ info: {
33
+ icon: FaCircleInfo,
34
+ iconBg: "bg-info/15",
35
+ iconColor: "text-info",
36
+ button: "btn-info",
37
+ },
38
+ };
39
+
40
+ export interface ConfirmModalProps {
41
+ open: boolean;
42
+ variant?: "warning" | "error" | "success" | "info";
43
+ title?: string;
44
+ message?: string;
45
+ confirmText?: string;
46
+ cancelText?: string;
47
+ loading?: boolean;
48
+ closeOnBackdrop?: boolean;
49
+ closeOnEsc?: boolean;
50
+ onConfirm: () => void | Promise<void>;
51
+ onCancel: () => void;
52
+ }
53
+
54
+ const ConfirmModal = ({
55
+ open,
56
+ variant = "warning",
57
+ title = "Confirm Action",
58
+ message = "Are you sure you want to continue?",
59
+ confirmText = "Confirm",
60
+ cancelText = "Cancel",
61
+ loading = false,
62
+ closeOnBackdrop = true,
63
+ closeOnEsc = true,
64
+ onConfirm,
65
+ onCancel,
66
+ }: ConfirmModalProps) => {
67
+ useEffect(() => {
68
+ if (!open || !closeOnEsc) return;
69
+
70
+ const handleKeyDown = (e: KeyboardEvent) => {
71
+ if (e.key === "Escape") {
72
+ onCancel?.();
73
+ }
74
+ };
75
+
76
+ window.addEventListener("keydown", handleKeyDown);
77
+
78
+ return () => window.removeEventListener("keydown", handleKeyDown);
79
+ }, [open, closeOnEsc, onCancel]);
80
+
81
+ if (!open) return null;
82
+
83
+ const style = variants[variant || "warning"];
84
+ const Icon = style.icon;
85
+
86
+ return createPortal(
87
+ <div className="fixed inset-0 z-[9999] flex items-center justify-center">
88
+ {/* Backdrop */}
89
+
90
+ <div
91
+ className="absolute inset-0 bg-black/60 backdrop-blur-sm"
92
+ onClick={closeOnBackdrop ? onCancel : undefined}
93
+ />
94
+
95
+ {/* Modal */}
96
+
97
+ <div className="relative w-full max-w-md mx-4 rounded-2xl bg-base-100 shadow-2xl animate-in fade-in zoom-in duration-200">
98
+ <div className="p-6">
99
+
100
+ <div className="flex gap-4">
101
+
102
+ <div
103
+ className={`w-14 h-14 rounded-full flex items-center justify-center shrink-0 ${style.iconBg}`}
104
+ >
105
+ <Icon className={`text-2xl ${style.iconColor}`} />
106
+ </div>
107
+
108
+ <div className="flex-1">
109
+
110
+ <h2 className="text-xl font-bold">
111
+ {title}
112
+ </h2>
113
+
114
+ <p className="mt-2 text-sm text-base-content/70 leading-relaxed">
115
+ {message}
116
+ </p>
117
+
118
+ </div>
119
+
120
+ </div>
121
+
122
+ <div className="mt-8 flex justify-end gap-3">
123
+
124
+ <button
125
+ className="btn btn-ghost"
126
+ disabled={loading}
127
+ onClick={onCancel}
128
+ >
129
+ {cancelText}
130
+ </button>
131
+
132
+ <button
133
+ className={`btn ${style.button}`}
134
+ disabled={loading}
135
+ onClick={onConfirm}
136
+ >
137
+ {loading && (
138
+ <span className="loading loading-spinner loading-xs" />
139
+ )}
140
+
141
+ {confirmText}
142
+ </button>
143
+
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </div>,
148
+ document.body,
149
+ );
150
+ };
151
+
152
+ export default ConfirmModal;
@@ -0,0 +1,230 @@
1
+ import React, { useEffect, useRef } from "react";
2
+ import { Link, useNavigate, useLocation } from "react-router-dom";
3
+ import { FiMenu, FiBookOpen } from "react-icons/fi";
4
+ import { Moon, Sun, X, Globe } from "lucide-react";
5
+ import { useUiStore } from "../../store/useUiStore";
6
+ import appConfig from "../../config/index";
7
+ import { useAuthStore } from "../../features/auth/store/useAuthStore";
8
+ import { getInitials } from "../../utils/getInitials";
9
+ import { motion, AnimatePresence } from "framer-motion";
10
+ import { navigation } from "../../constants/navigation";
11
+
12
+ const Header = () => {
13
+ const {
14
+ theme,
15
+ toggleTheme,
16
+ isMobileMenuOpened: isMobileMenuOpen,
17
+ setMobileMenuOpened: setIsMobilemenuOpen
18
+ } = useUiStore();
19
+ const { user } = useAuthStore();
20
+ const navigate = useNavigate();
21
+ const location = useLocation().pathname;
22
+ const headerRef = useRef(null);
23
+
24
+ // Close mobile menu on scroll
25
+ useEffect(() => {
26
+ const handleScroll = () => {
27
+ setIsMobilemenuOpen(false);
28
+ };
29
+ window.addEventListener("scroll", handleScroll, { passive: true });
30
+ return () => window.removeEventListener("scroll", handleScroll);
31
+ }, [setIsMobilemenuOpen]);
32
+
33
+ // Close mobile menu on click outside
34
+ useEffect(() => {
35
+ const handleClickOutside = (event) => {
36
+ if (headerRef.current && !headerRef.current.contains(event.target)) {
37
+ setIsMobilemenuOpen(false);
38
+ }
39
+ };
40
+ document.addEventListener("mousedown", handleClickOutside);
41
+ return () => document.removeEventListener("mousedown", handleClickOutside);
42
+ }, [setIsMobilemenuOpen]);
43
+
44
+ return (
45
+ <header ref={headerRef} className="sticky top-0 z-40 p-4">
46
+ <div className="max-w-7xl mx-auto relative">
47
+ {/* Main Navbar Bar */}
48
+ <div className="bg-primary text-primary-content rounded-full shadow-lg px-5 py-2.5 flex items-center justify-between relative">
49
+ {/* Left */}
50
+ <div className="flex items-center gap-3">
51
+ <Link to="/" className="flex items-center gap-2">
52
+ {appConfig.app.logo ? (
53
+ <img src={appConfig.logo} alt="logo" className="h-10 w-10" />
54
+ ) : (
55
+ <div className="flex items-center">
56
+ <div className="w-8 h-8 rounded-full bg-base-100/25 flex items-center justify-center text-primary-content shadow-inner">
57
+ <FiBookOpen size={16} />
58
+ </div>
59
+ </div>
60
+ )}
61
+
62
+ <span className="font-bold text-lg hidden sm:block">
63
+ {appConfig.app.name}
64
+ </span>
65
+ </Link>
66
+ </div>
67
+
68
+ {/* Center: Dynamic Navigation */}
69
+ <nav className="hidden lg:flex items-center gap-6 text-sm font-medium absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
70
+ {navigation.map((item) => (
71
+ <Link
72
+ key={item.path}
73
+ to={item.path}
74
+ className={`hover:text-primary transition-colors ${
75
+ location === item.path ? "text-white font-bold" : "text-white/80"
76
+ }`}
77
+ >
78
+ {item.title}
79
+ </Link>
80
+ ))}
81
+ </nav>
82
+
83
+ {/* Right */}
84
+ <div className="flex items-center gap-2">
85
+ {/* Desktop Theme Switcher */}
86
+ <button
87
+ onClick={toggleTheme}
88
+ className="hidden md:flex btn btn-outline btn-soft border-none btn-circle btn-xs"
89
+ title="Toggle Theme"
90
+ >
91
+ {theme === "dark" ? (
92
+ <Sun size={16} className="text-primary-content" />
93
+ ) : (
94
+ <Moon size={16} className="text-primary-content" />
95
+ )}
96
+ </button>
97
+
98
+ {/* Desktop Auth */}
99
+ {user ? (
100
+ <button
101
+ onClick={() => navigate("/profile")}
102
+ className="hidden md:flex btn btn-sm btn-circle overflow-hidden shadow-none hover:ring-1 hover:ring-offset-2 hover:ring-base-300 cursor-pointer btn-primary"
103
+ >
104
+ <img
105
+ src={`https://placehold.co/600x400?text=${getInitials(user?.name) || "KS"}`}
106
+ alt="avatar"
107
+ className="w-full h-full object-cover object-center"
108
+ />
109
+ </button>
110
+ ) : (
111
+ <button
112
+ onClick={() => navigate("/login")}
113
+ className="hidden md:flex btn btn-primary btn-sm rounded-full px-4"
114
+ >
115
+ Login
116
+ </button>
117
+ )}
118
+
119
+ {/* Mobile Dropdown Menu Button */}
120
+ <button
121
+ onClick={() => setIsMobilemenuOpen(!isMobileMenuOpen)}
122
+ className="lg:hidden btn btn-outline btn-soft border-none btn-circle btn-xs text-primary-content transition-transform duration-200"
123
+ title="Toggle Menu"
124
+ >
125
+ {isMobileMenuOpen ? <X size={18} /> : <FiMenu size={18} />}
126
+ </button>
127
+ </div>
128
+ </div>
129
+
130
+ {/* Mobile Dropdown Menu style from user's request */}
131
+ <AnimatePresence>
132
+ {isMobileMenuOpen && (
133
+ <motion.div
134
+ initial={{ opacity: 0, y: -40 }}
135
+ animate={{ opacity: 1, y: 0 }}
136
+ exit={{ opacity: 0, y: -40 }}
137
+ transition={{ duration: 0.3 }}
138
+ className="lg:hidden mt-3 bg-primary backdrop-blur-lg rounded-2xl shadow-xl border border-white/20 overflow-hidden text-primary-content absolute w-full"
139
+ >
140
+ <div className="p-4 space-y-2">
141
+ {/* Dynamic Navigation Links */}
142
+ {navigation.map((item) => (
143
+ <Link
144
+ key={item.path}
145
+ to={item.path}
146
+ onClick={() => setIsMobilemenuOpen(false)}
147
+ className={`block px-4 py-3 rounded-xl hover:bg-white/10 transition-colors font-semibold ${
148
+ location === item.path ? "bg-white/15 text-white" : "text-white/80"
149
+ }`}
150
+ >
151
+ {item.title}
152
+ </Link>
153
+ ))}
154
+
155
+ {/* Theme Toggle */}
156
+ <button
157
+ onClick={toggleTheme}
158
+ className="w-full px-4 py-3 rounded-xl hover:bg-white/10 transition-colors flex items-center gap-3 font-semibold text-white/90"
159
+ >
160
+ <span className="p-2 rounded-lg bg-white/10">
161
+ {theme === "dark" ? <Sun size={16} /> : <Moon size={16} />}
162
+ </span>
163
+ <span>{theme === "dark" ? "Light Mode" : "Dark Mode"}</span>
164
+ </button>
165
+
166
+ {/* Language (Mock Selector matching user design layout) */}
167
+ <button className="w-full px-4 py-3 rounded-xl hover:bg-white/10 transition-colors flex items-center gap-3 font-semibold text-white/90">
168
+ <span className="p-2 rounded-lg bg-white/10">
169
+ <Globe size={16} />
170
+ </span>
171
+ <span>English</span>
172
+ </button>
173
+
174
+ {/* Auth Buttons */}
175
+ {!user ? (
176
+ <div className="pt-4 mt-4 border-t border-white/10 space-y-2">
177
+ <button
178
+ onClick={() => {
179
+ navigate("/login");
180
+ setIsMobilemenuOpen(false);
181
+ }}
182
+ className="w-full px-4 py-3 bg-white/10 border border-white/20 text-white font-semibold rounded-xl hover:bg-white/20 transition-all"
183
+ >
184
+ Login
185
+ </button>
186
+
187
+ <button
188
+ onClick={() => {
189
+ navigate("/login");
190
+ setIsMobilemenuOpen(false);
191
+ }}
192
+ className="w-full px-4 py-3 bg-white text-primary font-semibold rounded-xl hover:bg-white/90 transition-all"
193
+ >
194
+ Register
195
+ </button>
196
+ </div>
197
+ ) : (
198
+ <div className="pt-4 mt-4 border-t border-white/10 space-y-2">
199
+ <div className="flex items-center gap-3 bg-white/10 p-3 rounded-xl border border-white/15">
200
+ <img
201
+ src={`https://placehold.co/100x100?text=${getInitials(user.name)}`}
202
+ className="w-10 h-10 rounded-full border border-white/20 shrink-0"
203
+ alt="avatar"
204
+ />
205
+ <div className="text-left">
206
+ <div className="font-bold text-sm text-white">{user.name}</div>
207
+ <div className="text-xs text-white/70 truncate max-w-[180px]">{user.email}</div>
208
+ </div>
209
+ </div>
210
+ <button
211
+ onClick={() => {
212
+ setIsMobilemenuOpen(false);
213
+ navigate("/profile");
214
+ }}
215
+ className="w-full px-4 py-3 bg-white text-primary font-semibold rounded-xl hover:bg-white/90 transition-all"
216
+ >
217
+ Profile
218
+ </button>
219
+ </div>
220
+ )}
221
+ </div>
222
+ </motion.div>
223
+ )}
224
+ </AnimatePresence>
225
+ </div>
226
+ </header>
227
+ );
228
+ };
229
+
230
+ export default Header;
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import LottieAnimation from "../shared/LottieIcon";
3
+ import loader from "../../assets/animations/loading.json";
4
+
5
+ const Loading = ({
6
+ className = "w-60 h-60",
7
+ bgClass = "bg-base-100",
8
+ animationData = loader,
9
+ }) => {
10
+ return (
11
+ <div
12
+ className={`absolute inset-0 flex items-center justify-center z-50 ${bgClass} max-h-dvh`}
13
+ >
14
+ <LottieAnimation animation={animationData} className={className} />
15
+ </div>
16
+ );
17
+ };
18
+
19
+ export default Loading;
@@ -0,0 +1,106 @@
1
+ import { useEffect, ReactNode } from "react";
2
+ import { createPortal } from "react-dom";
3
+ import { IoClose } from "react-icons/io5";
4
+
5
+ export interface ModalProps {
6
+ open: boolean;
7
+ onClose: () => void;
8
+ title: string;
9
+ children: ReactNode;
10
+ size?: "sm" | "md" | "lg" | "xl" | "2xl" | "full";
11
+ closeOnBackdrop?: boolean;
12
+ closeOnEsc?: boolean;
13
+ showCloseButton?: boolean;
14
+ footer?: ReactNode;
15
+ }
16
+
17
+ const sizes = {
18
+ sm: "max-w-sm",
19
+ md: "max-w-md",
20
+ lg: "max-w-lg",
21
+ xl: "max-w-2xl",
22
+ "2xl": "max-w-4xl",
23
+ full: "max-w-7xl",
24
+ };
25
+
26
+ const Modal = ({
27
+ open,
28
+ onClose,
29
+ title,
30
+ children,
31
+ size = "md",
32
+ closeOnBackdrop = true,
33
+ closeOnEsc = true,
34
+ showCloseButton = true,
35
+ footer,
36
+ }: ModalProps) => {
37
+ useEffect(() => {
38
+ if (!open || !closeOnEsc) return;
39
+
40
+ const handleKeyDown = (e) => {
41
+ if (e.key === "Escape") {
42
+ onClose?.();
43
+ }
44
+ };
45
+
46
+ document.addEventListener("keydown", handleKeyDown);
47
+
48
+ return () =>
49
+ document.removeEventListener("keydown", handleKeyDown);
50
+ }, [open, closeOnEsc, onClose]);
51
+
52
+ if (!open) return null;
53
+
54
+ return createPortal(
55
+ <div className="fixed inset-0 z-[9999] flex items-center justify-center p-4">
56
+ {/* Backdrop */}
57
+ <div
58
+ className="absolute inset-0 bg-black/50 backdrop-blur-sm"
59
+ onClick={closeOnBackdrop ? onClose : undefined}
60
+ />
61
+
62
+ {/* Modal */}
63
+ <div
64
+ className={`
65
+ relative
66
+ w-full
67
+ ${sizes[size]}
68
+ rounded-2xl
69
+ bg-base-100
70
+ shadow-2xl
71
+ border border-base-300
72
+ animate-in zoom-in-95 fade-in duration-200
73
+ `}
74
+ >
75
+ {/* Header */}
76
+ <div className="flex items-center justify-between border-b border-base-300 px-6 py-4">
77
+ <h2 className="text-lg font-bold">{title}</h2>
78
+
79
+ {showCloseButton && (
80
+ <button
81
+ className="btn btn-circle btn-sm btn-ghost"
82
+ onClick={onClose}
83
+ >
84
+ <IoClose size={20} />
85
+ </button>
86
+ )}
87
+ </div>
88
+
89
+ {/* Body */}
90
+ <div className="max-h-[70vh] overflow-y-auto p-6">
91
+ {children}
92
+ </div>
93
+
94
+ {/* Footer */}
95
+ {footer && (
96
+ <div className="border-t border-base-300 px-6 py-4">
97
+ {footer}
98
+ </div>
99
+ )}
100
+ </div>
101
+ </div>,
102
+ document.body,
103
+ );
104
+ };
105
+
106
+ export default Modal;