create-flutterinit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/bin/index.ts +3 -0
  2. package/package.json +46 -0
  3. package/templates/base/.cursor/rules/flutter-project.mdc.hbs +132 -0
  4. package/templates/base/AGENTS.md.hbs +137 -0
  5. package/templates/base/DESIGN.md.hbs +149 -0
  6. package/templates/base/README.md.hbs +19 -0
  7. package/templates/base/SETUP.md.hbs +253 -0
  8. package/templates/base/analysis_options.yaml +88 -0
  9. package/templates/base/assets/.keep +1 -0
  10. package/templates/base/assets/icons/apple.svg +1 -0
  11. package/templates/base/assets/icons/facebook.svg +1 -0
  12. package/templates/base/assets/icons/google.svg +1 -0
  13. package/templates/base/assets/images/.gitkeep +0 -0
  14. package/templates/base/flutter_native_splash.yaml.hbs +8 -0
  15. package/templates/base/lib/main.dart.hbs +43 -0
  16. package/templates/base/lib/src/app.dart.hbs +105 -0
  17. package/templates/base/lib/src/config/app_config.dart.hbs +112 -0
  18. package/templates/base/lib/src/extensions/collection_extension.dart.hbs +55 -0
  19. package/templates/base/lib/src/extensions/context_extension.dart.hbs +167 -0
  20. package/templates/base/lib/src/extensions/date_time_extension.dart.hbs +40 -0
  21. package/templates/base/lib/src/extensions/extensions.dart.hbs +6 -0
  22. package/templates/base/lib/src/extensions/num_extension.dart.hbs +14 -0
  23. package/templates/base/lib/src/extensions/string_extension.dart.hbs +91 -0
  24. package/templates/base/lib/src/extensions/widget_extension.dart.hbs +47 -0
  25. package/templates/base/lib/src/imports/core_imports.dart.hbs +50 -0
  26. package/templates/base/lib/src/imports/imports.dart.hbs +2 -0
  27. package/templates/base/lib/src/imports/packages_imports.dart.hbs +110 -0
  28. package/templates/base/lib/src/routing/(isGetX)@app_bindings.dart.hbs +23 -0
  29. package/templates/base/lib/src/routing/app_router.dart.hbs +252 -0
  30. package/templates/base/lib/src/routing/app_routes.dart.hbs +46 -0
  31. package/templates/base/lib/src/routing/global_navigator.dart.hbs +15 -0
  32. package/templates/base/lib/src/services/auth_service.dart.hbs +78 -0
  33. package/templates/base/lib/src/services/copy_service.dart.hbs +16 -0
  34. package/templates/base/lib/src/services/internet_connection_service.dart.hbs +10 -0
  35. package/templates/base/lib/src/services/services.dart.hbs +45 -0
  36. package/templates/base/lib/src/shared/app_assets.dart.hbs +15 -0
  37. package/templates/base/lib/src/shared/enums/app_status.dart.hbs +40 -0
  38. package/templates/base/lib/src/shared/enums/button_enums.dart.hbs +22 -0
  39. package/templates/base/lib/src/shared/enums/enums.dart.hbs +3 -0
  40. package/templates/base/lib/src/shared/enums/snack_bar_type.dart.hbs +22 -0
  41. package/templates/base/lib/src/shared/helpers/format_number.dart.hbs +18 -0
  42. package/templates/base/lib/src/shared/helpers/imports.dart.hbs +3 -0
  43. package/templates/base/lib/src/shared/helpers/show_app_sheet.dart.hbs +42 -0
  44. package/templates/base/lib/src/shared/helpers/show_dialog.dart.hbs +49 -0
  45. package/templates/base/lib/src/shared/helpers/show_toast.dart.hbs +92 -0
  46. package/templates/base/lib/src/shared/hooks/hooks.dart.hbs +13 -0
  47. package/templates/base/lib/src/shared/hooks/use_copy.dart.hbs +41 -0
  48. package/templates/base/lib/src/shared/hooks/use_timer.dart.hbs +158 -0
  49. package/templates/base/lib/src/shared/shared.dart.hbs +12 -0
  50. package/templates/base/lib/src/shared/widgets/app_button.dart.hbs +144 -0
  51. package/templates/base/lib/src/shared/widgets/app_card.dart.hbs +126 -0
  52. package/templates/base/lib/src/shared/widgets/app_divider.dart.hbs +88 -0
  53. package/templates/base/lib/src/shared/widgets/app_empty_state.dart.hbs +73 -0
  54. package/templates/base/lib/src/shared/widgets/app_error_widget.dart.hbs +69 -0
  55. package/templates/base/lib/src/shared/widgets/app_icon.dart.hbs +25 -0
  56. package/templates/base/lib/src/shared/widgets/app_loading.dart.hbs +54 -0
  57. package/templates/base/lib/src/shared/widgets/app_text_field.dart.hbs +89 -0
  58. package/templates/base/lib/src/shared/widgets/app_top_bar.dart.hbs +105 -0
  59. package/templates/base/lib/src/shared/widgets/common_image.dart.hbs +120 -0
  60. package/templates/base/lib/src/shared/widgets/toast/imports.dart.hbs +4 -0
  61. package/templates/base/lib/src/shared/widgets/toast/raw_toast.dart.hbs +109 -0
  62. package/templates/base/lib/src/shared/widgets/toast/toast.dart.hbs +142 -0
  63. package/templates/base/lib/src/shared/widgets/toast/toast_card.dart.hbs +57 -0
  64. package/templates/base/lib/src/shared/widgets/widgets.dart.hbs +14 -0
  65. package/templates/base/lib/src/shared/wrappers/(isRiverpod,isProvider,isBloc,isGetX,isMobX)@state_wrapper.dart.hbs +51 -0
  66. package/templates/base/lib/src/shared/wrappers/(supportsLocalization)@localization_wrapper.dart.hbs +25 -0
  67. package/templates/base/lib/src/shared/wrappers/(usesScreenutil)@screen_util_wrapper.dart.hbs +27 -0
  68. package/templates/base/lib/src/shared/wrappers/(usesSkeletonizer)@skeleton_wrapper.dart.hbs +81 -0
  69. package/templates/base/lib/src/shared/wrappers/session_listener_wrapper.dart.hbs +258 -0
  70. package/templates/base/lib/src/shared/wrappers/wrappers.dart.hbs +15 -0
  71. package/templates/base/lib/src/theme/app_borders.dart.hbs +70 -0
  72. package/templates/base/lib/src/theme/app_curves.dart.hbs +69 -0
  73. package/templates/base/lib/src/theme/app_durations.dart.hbs +48 -0
  74. package/templates/base/lib/src/theme/app_shadows.dart.hbs +73 -0
  75. package/templates/base/lib/src/theme/app_spacing.dart.hbs +80 -0
  76. package/templates/base/lib/src/theme/color_schemes.dart.hbs +126 -0
  77. package/templates/base/lib/src/theme/text_theme.dart.hbs +167 -0
  78. package/templates/base/lib/src/theme/theme.dart.hbs +431 -0
  79. package/templates/base/lib/src/theme/theme_constants.dart.hbs +20 -0
  80. package/templates/base/lib/src/utils/app_utils.dart.hbs +46 -0
  81. package/templates/base/lib/src/utils/debouncer.dart.hbs +31 -0
  82. package/templates/base/lib/src/utils/error_handler.dart.hbs +14 -0
  83. package/templates/base/lib/src/utils/failure.dart.hbs +30 -0
  84. package/templates/base/lib/src/utils/input_formatters.dart.hbs +27 -0
  85. package/templates/base/lib/src/utils/logger.dart.hbs +37 -0
  86. package/templates/base/lib/src/utils/platform_info.dart.hbs +13 -0
  87. package/templates/base/lib/src/utils/task_runner.dart.hbs +42 -0
  88. package/templates/base/lib/src/utils/typedefs.dart.hbs +6 -0
  89. package/templates/base/lib/src/utils/utils.dart.hbs +9 -0
  90. package/templates/base/pubspec.yaml.hbs +256 -0
  91. package/templates/base/test/widget_test.dart.hbs +56 -0
  92. package/templates/overlays/architecture/clean/architecture.md +6 -0
  93. package/templates/overlays/architecture/clean/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
  94. package/templates/overlays/architecture/clean/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
  95. package/templates/overlays/architecture/clean/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
  96. package/templates/overlays/architecture/clean/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
  97. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
  98. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
  99. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
  100. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
  101. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
  102. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
  103. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
  104. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
  105. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
  106. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
  107. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
  108. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
  109. package/templates/overlays/architecture/clean/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
  110. package/templates/overlays/architecture/clean/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
  111. package/templates/overlays/architecture/feature-first/architecture.md +5 -0
  112. package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
  113. package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
  114. package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
  115. package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
  116. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
  117. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
  118. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
  119. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
  120. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
  121. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
  122. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
  123. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
  124. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
  125. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
  126. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
  127. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
  128. package/templates/overlays/architecture/feature-first/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
  129. package/templates/overlays/architecture/feature-first/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
  130. package/templates/overlays/architecture/layer-first/architecture.md +6 -0
  131. package/templates/overlays/architecture/layer-first/lib/src/data/datasources/local/.gitkeep +0 -0
  132. package/templates/overlays/architecture/layer-first/lib/src/data/datasources/remote/.gitkeep +0 -0
  133. package/templates/overlays/architecture/layer-first/lib/src/data/models/user_model.dart.hbs +1 -0
  134. package/templates/overlays/architecture/layer-first/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
  135. package/templates/overlays/architecture/layer-first/lib/src/domain/entities/user.dart.hbs +1 -0
  136. package/templates/overlays/architecture/layer-first/lib/src/domain/repositories/auth_repository.dart.hbs +1 -0
  137. package/templates/overlays/architecture/layer-first/lib/src/domain/usecases/auth/.gitkeep +0 -0
  138. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
  139. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
  140. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
  141. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
  142. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
  143. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
  144. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@auth_view_model.dart.hbs +1 -0
  145. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
  146. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
  147. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
  148. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/forgot_password_screen.dart.hbs +1 -0
  149. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/login_screen.dart.hbs +1 -0
  150. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/signup_screen.dart.hbs +1 -0
  151. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/home/home_page.dart.hbs +1 -0
  152. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/onboarding/onboarding_page.dart.hbs +1 -0
  153. package/templates/overlays/architecture/layer-first/lib/src/presentation/widgets/.gitkeep +0 -0
  154. package/templates/overlays/architecture/mvc/architecture.md +5 -0
  155. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@auth_bloc.dart.hbs +1 -0
  156. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@session_bloc.dart.hbs +1 -0
  157. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@auth_controller.dart.hbs +1 -0
  158. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@session_controller.dart.hbs +1 -0
  159. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@auth_store.dart.hbs +1 -0
  160. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@session_store.dart.hbs +1 -0
  161. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isNoneState)@session_manager.dart.hbs +1 -0
  162. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
  163. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
  164. package/templates/overlays/architecture/mvc/lib/src/models/user_model.dart.hbs +1 -0
  165. package/templates/overlays/architecture/mvc/lib/src/services/auth_repository.dart.hbs +1 -0
  166. package/templates/overlays/architecture/mvc/lib/src/services/auth_repository_impl.dart.hbs +1 -0
  167. package/templates/overlays/architecture/mvc/lib/src/views/auth/forgot_password_screen.dart.hbs +1 -0
  168. package/templates/overlays/architecture/mvc/lib/src/views/auth/login_screen.dart.hbs +1 -0
  169. package/templates/overlays/architecture/mvc/lib/src/views/auth/signup_screen.dart.hbs +1 -0
  170. package/templates/overlays/architecture/mvc/lib/src/views/home/home_page.dart.hbs +1 -0
  171. package/templates/overlays/architecture/mvc/lib/src/views/onboarding/onboarding_page.dart.hbs +1 -0
  172. package/templates/overlays/architecture/mvvm/architecture.md +6 -0
  173. package/templates/overlays/architecture/mvvm/lib/src/data/models/user_model.dart.hbs +1 -0
  174. package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository.dart.hbs +1 -0
  175. package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
  176. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/auth_bloc.dart.hbs +1 -0
  177. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/session_bloc.dart.hbs +1 -0
  178. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/auth_controller.dart.hbs +1 -0
  179. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/session_controller.dart.hbs +1 -0
  180. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/auth_store.dart.hbs +1 -0
  181. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/session_store.dart.hbs +1 -0
  182. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/auth_view_model.dart.hbs +1 -0
  183. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/session_manager.dart.hbs +1 -0
  184. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/auth_provider.dart.hbs +1 -0
  185. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/session_provider.dart.hbs +1 -0
  186. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/forgot_password_screen.dart.hbs +1 -0
  187. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/login_screen.dart.hbs +1 -0
  188. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/signup_screen.dart.hbs +1 -0
  189. package/templates/overlays/architecture/mvvm/lib/src/ui/home/home_page.dart.hbs +1 -0
  190. package/templates/overlays/architecture/mvvm/lib/src/ui/onboarding/onboarding_page.dart.hbs +1 -0
  191. package/templates/overlays/backend/appwrite/lib/src/services/(usesAppwriteAuth)@auth_service.dart.hbs +101 -0
  192. package/templates/overlays/backend/custom/lib/src/services/auth_service.dart.hbs +158 -0
  193. package/templates/overlays/backend/firebase/lib/src/services/(usesFirebaseAuth)@auth_service.dart.hbs +96 -0
  194. package/templates/overlays/backend/supabase/lib/src/services/(usesSupabaseAuth)@auth_service.dart.hbs +97 -0
  195. package/templates/overlays/device/app_version_update/lib/src/services/(usesAppVersionUpdate)@version_update_service.dart.hbs +118 -0
  196. package/templates/overlays/device/device_info/lib/src/services/(usesDeviceInfoPlus)@device_info_service.dart.hbs +54 -0
  197. package/templates/overlays/extras/dotenv/.env.hbs +33 -0
  198. package/templates/overlays/extras/flavors/lib/src/flavors.dart.hbs +15 -0
  199. package/templates/overlays/extras/localization/assets/translations/en.json.hbs +47 -0
  200. package/templates/overlays/media/lib/src/services/(usesImagePicker,usesFilePicker)@media_service.dart.hbs +148 -0
  201. package/templates/overlays/networking/cached_image/lib/src/shared/widgets/app_cached_image.dart.hbs +160 -0
  202. package/templates/overlays/networking/dio/lib/src/services/(usesDio)@dio_service.dart.hbs +50 -0
  203. package/templates/overlays/networking/http/lib/src/services/(usesHttp)@http_service.dart.hbs +82 -0
  204. package/templates/overlays/storage/hive/lib/src/services/(usesHive)@hive_service.dart.hbs +59 -0
  205. package/templates/overlays/storage/secure_storage/lib/src/services/(usesSecureStorage)@secure_storage_service.dart.hbs +39 -0
  206. package/templates/overlays/storage/shared_preferences/lib/src/services/(usesSharedPreferences)@storage_service.dart.hbs +53 -0
  207. package/templates/overlays/utilities/geolocator/lib/src/services/(usesGeolocator)@location_service.dart.hbs +78 -0
  208. package/templates/overlays/utilities/path_provider/lib/src/services/(usesPathProvider)@path_service.dart.hbs +30 -0
  209. package/templates/overlays/utilities/permission_handler/lib/src/services/(usesPermissionHandler)@permission_service.dart.hbs +28 -0
  210. package/templates/overlays/utilities/permission_handler/lib/src/shared/hooks/use_permission.dart.hbs +44 -0
  211. package/templates/overlays/utilities/share_plus/lib/src/services/(usesSharePlus)@share_service.dart.hbs +22 -0
  212. package/templates/overlays/utilities/share_plus/lib/src/shared/hooks/use_share.dart.hbs +26 -0
  213. package/templates/overlays/utilities/url_launcher/lib/src/services/(usesUrlLauncher)@url_launcher_service.dart.hbs +37 -0
  214. package/templates/overlays/utilities/url_launcher/lib/src/shared/hooks/use_launch_url.dart.hbs +52 -0
  215. package/templates/partials/features/auth/auth_logic.hbs +611 -0
  216. package/templates/partials/features/auth/auth_repository.hbs +32 -0
  217. package/templates/partials/features/auth/auth_repository_impl.hbs +116 -0
  218. package/templates/partials/features/auth/forgot_password_screen.hbs +368 -0
  219. package/templates/partials/features/auth/login_screen.hbs +540 -0
  220. package/templates/partials/features/auth/session_provider.hbs +437 -0
  221. package/templates/partials/features/auth/signup_screen.hbs +511 -0
  222. package/templates/partials/features/auth/user_model.hbs +23 -0
  223. package/templates/partials/features/home/home_page.hbs +156 -0
  224. package/templates/partials/features/onboarding/onboarding_page.hbs +264 -0
  225. package/templates/partials/llm/add-feature-workflow.hbs +38 -0
  226. package/templates/partials/llm/architecture-rules.hbs +92 -0
  227. package/templates/partials/llm/backend-rules.hbs +30 -0
  228. package/templates/partials/llm/build-runner-note.hbs +15 -0
  229. package/templates/partials/llm/design-quick-ref.hbs +14 -0
  230. package/templates/partials/llm/design-quick-reference.hbs +14 -0
  231. package/templates/partials/llm/navigation-rules.hbs +27 -0
  232. package/templates/partials/llm/networking-rules.hbs +16 -0
  233. package/templates/partials/llm/packages-list.hbs +26 -0
  234. package/templates/partials/llm/services-conventions.hbs +20 -0
  235. package/templates/partials/llm/stack-summary.hbs +22 -0
  236. package/templates/partials/llm/state-management-rules.hbs +40 -0
  237. package/templates/partials/state_label.hbs +1 -0
@@ -0,0 +1 @@
1
+ {{> features/auth/session_provider }}
@@ -0,0 +1 @@
1
+ {{> features/auth/session_provider }}
@@ -0,0 +1 @@
1
+ {{> features/auth/forgot_password_screen }}
@@ -0,0 +1 @@
1
+ {{> features/auth/login_screen }}
@@ -0,0 +1 @@
1
+ {{> features/auth/signup_screen }}
@@ -0,0 +1 @@
1
+ {{> features/home/home_page }}
@@ -0,0 +1 @@
1
+ {{> features/onboarding/onboarding_page }}
@@ -0,0 +1,101 @@
1
+ import 'dart:async';
2
+ import '../utils/utils.dart';
3
+ import '../config/app_config.dart';
4
+ import 'package:appwrite/appwrite.dart';
5
+
6
+ class AuthService {
7
+ AuthService._();
8
+ static final AuthService instance = AuthService._();
9
+
10
+ Account get _account => AppConfig.appwriteAccount;
11
+
12
+ // Appwrite doesn't have a built-in auth state stream, so we manage our own
13
+ final StreamController<Map<String, dynamic>?> _authStateController =
14
+ StreamController<Map<String, dynamic>?>.broadcast();
15
+
16
+ /// Stream of auth state changes. Emits the current user map or null.
17
+ Stream<Map<String, dynamic>?> get authStateChanges => _authStateController.stream;
18
+
19
+ FutureEither<Map<String, dynamic>?> login({
20
+ required String email,
21
+ required String password,
22
+ }) async {
23
+ return runTask(() async {
24
+ await _account.createEmailPasswordSession(
25
+ email: email,
26
+ password: password
27
+ );
28
+ final user = await _account.get();
29
+ final userData = {
30
+ 'id': user.$id,
31
+ 'email': user.email,
32
+ 'name': user.name,
33
+ };
34
+ _authStateController.add(userData);
35
+ return userData;
36
+ }, requiresNetwork: true);
37
+ }
38
+
39
+ FutureEither<Map<String, dynamic>?> signUp({
40
+ required String name,
41
+ required String email,
42
+ required String password,
43
+ }) async {
44
+ return runTask(() async {
45
+ final user = await _account.create(
46
+ userId: ID.unique(),
47
+ email: email,
48
+ password: password,
49
+ name: name,
50
+ );
51
+ // login after signup to get session
52
+ await _account.createEmailPasswordSession(
53
+ email: email,
54
+ password: password
55
+ );
56
+ final userData = {
57
+ 'id': user.$id,
58
+ 'email': user.email,
59
+ 'name': user.name,
60
+ };
61
+ _authStateController.add(userData);
62
+ return userData;
63
+ }, requiresNetwork: true);
64
+ }
65
+
66
+ FutureEither<void> forgotPassword({required String email}) async {
67
+ return runTask(() async {
68
+ // url for password recovery in your app
69
+ await _account.createRecovery(
70
+ email: email,
71
+ url: 'https://example.com/recovery'
72
+ );
73
+ }, requiresNetwork: true);
74
+ }
75
+
76
+ FutureEither<void> logout() async {
77
+ return runTask(() async {
78
+ await _account.deleteSession(sessionId: 'current');
79
+ _authStateController.add(null);
80
+ }, requiresNetwork: true);
81
+ }
82
+
83
+ FutureEither<Map<String, dynamic>?> getCurrentUser() async {
84
+ return runTask(() async {
85
+ try {
86
+ final user = await _account.get();
87
+ return {
88
+ 'id': user.$id,
89
+ 'email': user.email,
90
+ 'name': user.name,
91
+ };
92
+ } catch (e) {
93
+ return null; // session likely missing or invalid
94
+ }
95
+ });
96
+ }
97
+
98
+ void dispose() {
99
+ _authStateController.close();
100
+ }
101
+ }
@@ -0,0 +1,158 @@
1
+ import 'dart:async';
2
+ import '../utils/utils.dart';
3
+ import '../config/app_config.dart';
4
+ {{#if flags.usesDio}}
5
+ import 'package:dio/dio.dart';
6
+ {{else if flags.usesHttp}}
7
+ import 'package:http/http.dart' as http;
8
+ import 'dart:convert';
9
+ {{/if}}
10
+
11
+ class AuthService {
12
+ AuthService._();
13
+ static final AuthService instance = AuthService._();
14
+
15
+ {{#if flags.usesDio}}
16
+ Dio get _dio => AppConfig.dio;
17
+ {{else if flags.usesHttp}}
18
+ http.Client get _http => AppConfig.httpClient;
19
+ {{/if}}
20
+
21
+ // Custom Backend doesn't have a built-in auth state stream, so we manage our own
22
+ final StreamController<Map<String, dynamic>?> _authStateController =
23
+ StreamController<Map<String, dynamic>?>.broadcast();
24
+
25
+ /// Stream of auth state changes. Emits the current user map or null.
26
+ Stream<Map<String, dynamic>?> get authStateChanges => _authStateController.stream;
27
+
28
+ FutureEither<Map<String, dynamic>?> login({
29
+ required String email,
30
+ required String password,
31
+ }) async {
32
+ return runTask(() async {
33
+ {{#if flags.usesDio}}
34
+ final response = await _dio.post<Map<String, dynamic>>('/auth/login', data: {
35
+ 'email': email,
36
+ 'password': password,
37
+ });
38
+ final data = response.data!;
39
+ _authStateController.add(data);
40
+ return data;
41
+ {{else if flags.usesHttp}}
42
+ final http.Response response = await _http.post(
43
+ Uri.parse('${AppConfig.baseUrl}/auth/login'),
44
+ body: jsonEncode({'email': email, 'password': password}),
45
+ headers: {'Content-Type': 'application/json'},
46
+ );
47
+ if (response.statusCode != 200) throw Exception('Login failed');
48
+ final data = jsonDecode(response.body) as Map<String, dynamic>;
49
+ _authStateController.add(data);
50
+ return data;
51
+ {{else}}
52
+ // Mock implementation if no networking flag is set
53
+ await Future.delayed(const Duration(seconds: 1));
54
+ if (email == 'admin@example.com' && password == 'admin123') {
55
+ final data = {
56
+ 'id': '1',
57
+ 'email': email,
58
+ 'name': 'Admin User',
59
+ };
60
+ _authStateController.add(data);
61
+ return data;
62
+ }
63
+ throw Exception('Invalid credentials');
64
+ {{/if}}
65
+ }, requiresNetwork: true);
66
+ }
67
+
68
+ FutureEither<Map<String, dynamic>?> signUp({
69
+ required String name,
70
+ required String email,
71
+ required String password,
72
+ }) async {
73
+ return runTask(() async {
74
+ {{#if flags.usesDio}}
75
+ final response = await _dio.post<Map<String, dynamic>>('/auth/signup', data: {
76
+ 'name': name,
77
+ 'email': email,
78
+ 'password': password,
79
+ });
80
+ final data = response.data!;
81
+ _authStateController.add(data);
82
+ return data;
83
+ {{else if flags.usesHttp}}
84
+ final http.Response response = await _http.post(
85
+ Uri.parse('${AppConfig.baseUrl}/auth/signup'),
86
+ body: jsonEncode({
87
+ 'name': name,
88
+ 'email': email,
89
+ 'password': password,
90
+ }),
91
+ headers: {'Content-Type': 'application/json'},
92
+ );
93
+ if (response.statusCode != 201) throw Exception('Signup failed');
94
+ final data = jsonDecode(response.body) as Map<String, dynamic>;
95
+ _authStateController.add(data);
96
+ return data;
97
+ {{else}}
98
+ // Mock implementation if no networking flag is set
99
+ await Future.delayed(const Duration(seconds: 1));
100
+ final data = {
101
+ 'id': '100',
102
+ 'email': email,
103
+ 'name': name,
104
+ };
105
+ _authStateController.add(data);
106
+ return data;
107
+ {{/if}}
108
+ }, requiresNetwork: true);
109
+ }
110
+
111
+ FutureEither<void> forgotPassword({required String email}) async {
112
+ return runTask(() async {
113
+ {{#if flags.usesDio}}
114
+ await _dio.post<void>('/auth/forgot-password', data: {'email': email});
115
+ {{else if flags.usesHttp}}
116
+ final http.Response _ = await _http.post(
117
+ Uri.parse('${AppConfig.baseUrl}/auth/forgot-password'),
118
+ body: jsonEncode({'email': email}),
119
+ headers: {'Content-Type': 'application/json'},
120
+ );
121
+ {{else}}
122
+ await Future.delayed(const Duration(seconds: 1));
123
+ {{/if}}
124
+ }, requiresNetwork: true);
125
+ }
126
+
127
+ FutureEither<void> logout() async {
128
+ return runTask(() async {
129
+ {{#if flags.usesDio}}
130
+ await _dio.post<void>('/auth/logout');
131
+ {{else if flags.usesHttp}}
132
+ final http.Response _ = await _http.post(Uri.parse('${AppConfig.baseUrl}/auth/logout'));
133
+ {{else}}
134
+ await Future.delayed(const Duration(seconds: 1));
135
+ {{/if}}
136
+ _authStateController.add(null);
137
+ }, requiresNetwork: true);
138
+ }
139
+
140
+ FutureEither<Map<String, dynamic>?> getCurrentUser() async {
141
+ return runTask(() async {
142
+ {{#if flags.usesDio}}
143
+ final response = await _dio.get<Map<String, dynamic>>('/auth/me');
144
+ return response.data;
145
+ {{else if flags.usesHttp}}
146
+ final http.Response response = await _http.get(Uri.parse('${AppConfig.baseUrl}/auth/me'));
147
+ if (response.statusCode != 200) return null;
148
+ return jsonDecode(response.body) as Map<String, dynamic>;
149
+ {{else}}
150
+ return null;
151
+ {{/if}}
152
+ });
153
+ }
154
+
155
+ void dispose() {
156
+ _authStateController.close();
157
+ }
158
+ }
@@ -0,0 +1,96 @@
1
+ import '../utils/utils.dart';
2
+ import '../config/app_config.dart';
3
+ import 'package:firebase_auth/firebase_auth.dart';
4
+
5
+ class AuthService {
6
+ AuthService._();
7
+ static final AuthService instance = AuthService._();
8
+
9
+ FirebaseAuth get _firebaseAuth => AppConfig.firebaseAuth;
10
+
11
+ /// Stream of auth state changes. Emits the current user map or null.
12
+ Stream<Map<String, dynamic>?> get authStateChanges {
13
+ return _firebaseAuth.authStateChanges().map((User? user) {
14
+ if (user == null) return null;
15
+ return {
16
+ 'id': user.uid,
17
+ 'email': user.email ?? '',
18
+ 'name': user.displayName ?? '',
19
+ 'photoUrl': user.photoURL,
20
+ };
21
+ });
22
+ }
23
+
24
+ {{#if backend.options.authEmail}}
25
+ FutureEither<Map<String, dynamic>?> login({
26
+ required String email,
27
+ required String password,
28
+ }) async {
29
+ return runTask(() async {
30
+ final credentials = await _firebaseAuth.signInWithEmailAndPassword(
31
+ email: email,
32
+ password: password
33
+ );
34
+ final user = credentials.user;
35
+ if (user == null) return null;
36
+ return {
37
+ 'id': user.uid,
38
+ 'email': user.email ?? '',
39
+ 'name': user.displayName ?? '',
40
+ 'photoUrl': user.photoURL,
41
+ };
42
+ }, requiresNetwork: true);
43
+ }
44
+
45
+ FutureEither<Map<String, dynamic>?> signUp({
46
+ required String name,
47
+ required String email,
48
+ required String password,
49
+ }) async {
50
+ return runTask(() async {
51
+ final credentials = await _firebaseAuth.createUserWithEmailAndPassword(
52
+ email: email,
53
+ password: password
54
+ );
55
+ final user = credentials.user;
56
+ if (user == null) return null;
57
+ await user.updateDisplayName(name);
58
+ return {
59
+ 'id': user.uid,
60
+ 'email': user.email ?? '',
61
+ 'name': name,
62
+ 'photoUrl': user.photoURL,
63
+ };
64
+ }, requiresNetwork: true);
65
+ }
66
+
67
+ FutureEither<void> forgotPassword({required String email}) async {
68
+ return runTask(() async {
69
+ await _firebaseAuth.sendPasswordResetEmail(email: email);
70
+ }, requiresNetwork: true);
71
+ }
72
+ {{/if}}
73
+
74
+ FutureEither<void> logout() async {
75
+ return runTask(() async {
76
+ await _firebaseAuth.signOut();
77
+ }, requiresNetwork: true);
78
+ }
79
+
80
+ FutureEither<Map<String, dynamic>?> getCurrentUser() async {
81
+ return runTask(() async {
82
+ final user = _firebaseAuth.currentUser;
83
+ if (user == null) return null;
84
+ return {
85
+ 'id': user.uid,
86
+ 'email': user.email ?? '',
87
+ 'name': user.displayName ?? '',
88
+ 'photoUrl': user.photoURL,
89
+ };
90
+ });
91
+ }
92
+
93
+ void dispose() {
94
+ // Firebase manages its own streams
95
+ }
96
+ }
@@ -0,0 +1,97 @@
1
+ import '../utils/utils.dart';
2
+ import '../config/app_config.dart';
3
+ import 'package:supabase_flutter/supabase_flutter.dart';
4
+
5
+ class AuthService {
6
+ AuthService._();
7
+ static final AuthService instance = AuthService._();
8
+
9
+ SupabaseClient get _supabaseClient => AppConfig.supabase;
10
+
11
+ /// Stream of auth state changes. Emits the current user map or null.
12
+ Stream<Map<String, dynamic>?> get authStateChanges {
13
+ return _supabaseClient.auth.onAuthStateChange.map((data) {
14
+ final session = data.session;
15
+ if (session == null) return null;
16
+ final user = session.user;
17
+ return {
18
+ 'id': user.id,
19
+ 'email': user.email,
20
+ 'name': user.userMetadata?['name'] ?? '',
21
+ 'photoUrl': user.userMetadata?['avatar_url'],
22
+ };
23
+ });
24
+ }
25
+
26
+ FutureEither<Map<String, dynamic>?> login({
27
+ required String email,
28
+ required String password,
29
+ }) async {
30
+ return runTask(() async {
31
+ final response = await _supabaseClient.auth.signInWithPassword(
32
+ email: email,
33
+ password: password,
34
+ );
35
+ final user = response.user;
36
+ if (user == null) return null;
37
+ return {
38
+ 'id': user.id,
39
+ 'email': user.email,
40
+ 'name': user.userMetadata?['name'] ?? '',
41
+ 'photoUrl': user.userMetadata?['avatar_url'],
42
+ };
43
+ }, requiresNetwork: true);
44
+ }
45
+
46
+ FutureEither<Map<String, dynamic>?> signUp({
47
+ required String name,
48
+ required String email,
49
+ required String password,
50
+ }) async {
51
+ return runTask(() async {
52
+ final response = await _supabaseClient.auth.signUp(
53
+ email: email,
54
+ password: password,
55
+ data: {'name': name},
56
+ );
57
+ final user = response.user;
58
+ if (user == null) return null;
59
+ return {
60
+ 'id': user.id,
61
+ 'email': user.email,
62
+ 'name': name,
63
+ 'photoUrl': user.userMetadata?['avatar_url'],
64
+ };
65
+ }, requiresNetwork: true);
66
+ }
67
+
68
+ FutureEither<void> forgotPassword({required String email}) async {
69
+ return runTask(() async {
70
+ await _supabaseClient.auth.resetPasswordForEmail(email);
71
+ }, requiresNetwork: true);
72
+ }
73
+
74
+ FutureEither<void> logout() async {
75
+ return runTask(() async {
76
+ await _supabaseClient.auth.signOut();
77
+ }, requiresNetwork: true);
78
+ }
79
+
80
+ FutureEither<Map<String, dynamic>?> getCurrentUser() async {
81
+ return runTask(() async {
82
+ final session = _supabaseClient.auth.currentSession;
83
+ if (session == null) return null;
84
+ final user = session.user;
85
+ return {
86
+ 'id': user.id,
87
+ 'email': user.email,
88
+ 'name': user.userMetadata?['name'] ?? '',
89
+ 'photoUrl': user.userMetadata?['avatar_url'],
90
+ };
91
+ });
92
+ }
93
+
94
+ void dispose() {
95
+ // Supabase manages its own streams
96
+ }
97
+ }
@@ -0,0 +1,118 @@
1
+ import 'package:app_version_update/data/models/app_version_result.dart';
2
+
3
+ import '../imports/imports.dart';
4
+
5
+ /// A service to check for app updates and manage version information using
6
+ /// the `app_version_update` package.
7
+ class VersionUpdateService {
8
+ VersionUpdateService._();
9
+ static final VersionUpdateService instance = VersionUpdateService._();
10
+
11
+ /// Check if a newer version of the app is available in the store.
12
+ FutureEither<AppVersionResult?> checkForUpdate({
13
+ String? appleId,
14
+ String? playStoreId,
15
+ }) async {
16
+ return runTask(() async {
17
+ return await AppVersionUpdate.checkForUpdates(
18
+ appleId: appleId,
19
+ playStoreId: playStoreId,
20
+ );
21
+ }, requiresNetwork: true);
22
+ }
23
+
24
+ /// High-level method to check for updates and show the dialog automatically if available.
25
+ FutureEither<void> checkAndShowUpdate({
26
+ String? appleId,
27
+ String? playStoreId,
28
+ bool mandatory = false,
29
+ }) async {
30
+ return runTask(() async {
31
+ final result = await AppVersionUpdate.checkForUpdates(
32
+ appleId: appleId,
33
+ playStoreId: playStoreId,
34
+ );
35
+
36
+ if (result.canUpdate ?? false) {
37
+ final context = rootContext;
38
+ if (context == null) {
39
+ AppLogger.warning('Cannot show update dialog: rootContext is null');
40
+ return;
41
+ }
42
+
43
+ if(context.mounted){
44
+ AppVersionUpdate.showAlertUpdate(
45
+ appVersionResult: result,
46
+ context: context,
47
+ mandatory: mandatory,
48
+ );
49
+ }
50
+ }
51
+ }, requiresNetwork: true);
52
+ }
53
+
54
+ /// Display a platform-specific update dialog.
55
+ FutureEither<void> showUpdateAlert({
56
+ required AppVersionResult updateResult,
57
+ bool mandatory = false,
58
+ String? title,
59
+ String? content,
60
+ String? cancelText,
61
+ String? updateText,
62
+ }) async {
63
+ return runTask(() async {
64
+ final context = rootContext;
65
+ if (context == null) return;
66
+
67
+ AppVersionUpdate.showAlertUpdate(
68
+ appVersionResult: updateResult,
69
+ context: context,
70
+ mandatory: mandatory,
71
+ title: title ?? 'New version available',
72
+ content: content ?? 'Would you like to update your application?',
73
+ cancelButtonText: cancelText ?? 'UPDATE LATER',
74
+ updateButtonText: updateText ?? 'UPDATE',
75
+ );
76
+ });
77
+ }
78
+
79
+ /// Display a platform-specific update bottom sheet.
80
+ FutureEither<void> showUpdateBottomSheet({
81
+ required AppVersionResult updateResult,
82
+ bool mandatory = false,
83
+ String? title,
84
+ Widget? content,
85
+ }) async {
86
+ return runTask(() async {
87
+ final context = rootContext;
88
+ if (context == null) return;
89
+
90
+ AppVersionUpdate.showBottomSheetUpdate(
91
+ appVersionResult: updateResult,
92
+ context: context,
93
+ mandatory: mandatory,
94
+ title: title ?? 'New version available',
95
+ content: content,
96
+ );
97
+ });
98
+ }
99
+
100
+ /// Display a dedicated update page.
101
+ FutureEither<void> showUpdatePage({
102
+ required AppVersionResult updateResult,
103
+ bool mandatory = false,
104
+ Widget? page,
105
+ }) async {
106
+ return runTask(() async {
107
+ final context = rootContext;
108
+ if (context == null) return;
109
+
110
+ AppVersionUpdate.showPageUpdate(
111
+ appVersionResult: updateResult,
112
+ context: context,
113
+ mandatory: mandatory,
114
+ page: page,
115
+ );
116
+ });
117
+ }
118
+ }
@@ -0,0 +1,54 @@
1
+ import 'dart:io';
2
+ import 'package:device_info_plus/device_info_plus.dart';
3
+ import '../utils/utils.dart';
4
+
5
+ /// A service to retrieve detailed information about the current device.
6
+ class DeviceInfoService {
7
+ DeviceInfoService._();
8
+ static final DeviceInfoService instance = DeviceInfoService._();
9
+
10
+ final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();
11
+
12
+ /// Retrieve full device information as a Map.
13
+ FutureEither<Map<String, dynamic>> getFullDeviceInfo() async {
14
+ return runTask(() async {
15
+ if (Platform.isAndroid) {
16
+ final androidInfo = await _deviceInfo.androidInfo;
17
+ return {
18
+ 'model': androidInfo.model,
19
+ 'manufacturer': androidInfo.manufacturer,
20
+ 'version': androidInfo.version.release,
21
+ 'sdkInt': androidInfo.version.sdkInt,
22
+ 'id': androidInfo.id,
23
+ 'isPhysicalDevice': androidInfo.isPhysicalDevice,
24
+ };
25
+ } else if (Platform.isIOS) {
26
+ final iosInfo = await _deviceInfo.iosInfo;
27
+ return {
28
+ 'name': iosInfo.name,
29
+ 'model': iosInfo.model,
30
+ 'systemName': iosInfo.systemName,
31
+ 'systemVersion': iosInfo.systemVersion,
32
+ 'identifierForVendor': iosInfo.identifierForVendor,
33
+ 'isPhysicalDevice': iosInfo.isPhysicalDevice,
34
+ };
35
+ } else if (Platform.isMacOS) {
36
+ final macInfo = await _deviceInfo.macOsInfo;
37
+ return {
38
+ 'computerName': macInfo.computerName,
39
+ 'hostName': macInfo.hostName,
40
+ 'model': macInfo.model,
41
+ 'osRelease': macInfo.osRelease,
42
+ };
43
+ } else if (Platform.isWindows) {
44
+ final winInfo = await _deviceInfo.windowsInfo;
45
+ return {
46
+ 'computerName': winInfo.computerName,
47
+ 'numberOfCores': winInfo.numberOfCores,
48
+ 'systemMemoryInMegabytes': winInfo.systemMemoryInMegabytes,
49
+ };
50
+ }
51
+ return {'platform': 'unknown'};
52
+ });
53
+ }
54
+ }