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,252 @@
1
+ {{#if (eq flags.routerPackage "go_router")}}
2
+ import 'package:go_router/go_router.dart';
3
+ import 'package:{{flags.appSnake}}/src/routing/global_navigator.dart';
4
+ import 'package:{{flags.appSnake}}/src/routing/app_routes.dart';
5
+
6
+ {{#if (eq architecture "layer-first")}}
7
+ import 'package:{{flags.appSnake}}/src/presentation/screens/auth/login_screen.dart';
8
+ import 'package:{{flags.appSnake}}/src/presentation/screens/auth/signup_screen.dart';
9
+ import 'package:{{flags.appSnake}}/src/presentation/screens/auth/forgot_password_screen.dart';
10
+ {{else if (eq architecture "mvc")}}
11
+ import 'package:{{flags.appSnake}}/src/views/auth/login_screen.dart';
12
+ import 'package:{{flags.appSnake}}/src/views/auth/signup_screen.dart';
13
+ import 'package:{{flags.appSnake}}/src/views/auth/forgot_password_screen.dart';
14
+ {{else if (eq architecture "mvvm")}}
15
+ import 'package:{{flags.appSnake}}/src/ui/auth/login_screen.dart';
16
+ import 'package:{{flags.appSnake}}/src/ui/auth/signup_screen.dart';
17
+ import 'package:{{flags.appSnake}}/src/ui/auth/forgot_password_screen.dart';
18
+ {{else}}
19
+ import 'package:{{flags.appSnake}}/src/features/auth/presentation/screens/login_screen.dart';
20
+ import 'package:{{flags.appSnake}}/src/features/auth/presentation/screens/signup_screen.dart';
21
+ import 'package:{{flags.appSnake}}/src/features/auth/presentation/screens/forgot_password_screen.dart';
22
+ {{/if}}
23
+
24
+ {{#if (eq architecture "layer-first")}}
25
+ import 'package:{{flags.appSnake}}/src/presentation/screens/home/home_page.dart';
26
+ import 'package:{{flags.appSnake}}/src/presentation/screens/onboarding/onboarding_page.dart';
27
+
28
+ {{else if (eq architecture "mvc")}}
29
+ import 'package:{{flags.appSnake}}/src/views/home/home_page.dart';
30
+ import 'package:{{flags.appSnake}}/src/views/onboarding/onboarding_page.dart';
31
+
32
+ {{else if (eq architecture "mvvm")}}
33
+ import 'package:{{flags.appSnake}}/src/ui/home/home_page.dart';
34
+ import 'package:{{flags.appSnake}}/src/ui/onboarding/onboarding_page.dart';
35
+
36
+ {{else}}
37
+ import 'package:{{flags.appSnake}}/src/features/home/presentation/screens/home_page.dart';
38
+ import 'package:{{flags.appSnake}}/src/features/onboarding/presentation/screens/onboarding_page.dart';
39
+
40
+ {{/if}}
41
+
42
+ final GoRouter appRouter = GoRouter(
43
+ navigatorKey: rootNavigatorKey,
44
+ initialLocation: AppRoutes.onboarding,
45
+ routes: <RouteBase>[
46
+ GoRoute(
47
+ path: AppRoutes.onboarding,
48
+ name: 'onboarding',
49
+ builder: (context, state) => const OnboardingPage(),
50
+ ),
51
+ GoRoute(
52
+ path: AppRoutes.login,
53
+ name: 'login',
54
+ builder: (context, state) => const LoginScreen(),
55
+ ),
56
+ GoRoute(
57
+ path: AppRoutes.signup,
58
+ name: 'signup',
59
+ builder: (context, state) => const SignupScreen(),
60
+ ),
61
+ GoRoute(
62
+ path: AppRoutes.forgotPassword,
63
+ name: 'forgotPassword',
64
+ builder: (context, state) => const ForgotPasswordScreen(),
65
+ ),
66
+ GoRoute(
67
+ path: AppRoutes.home,
68
+ name: 'home',
69
+ builder: (context, state) => const HomePage(),
70
+ ),
71
+ ],
72
+ );
73
+ {{else if (eq flags.routerPackage "auto_route")}}
74
+ import 'package:auto_route/auto_route.dart';
75
+ import 'package:{{flags.appSnake}}/src/routing/global_navigator.dart';
76
+ import 'package:{{flags.appSnake}}/src/routing/app_routes.dart';
77
+ export 'app_router.gr.dart';
78
+ import 'app_router.gr.dart';
79
+
80
+ @AutoRouterConfig()
81
+ class AppRouter extends RootStackRouter {
82
+ AppRouter() : super(navigatorKey: rootNavigatorKey);
83
+
84
+ @override
85
+ List<AutoRoute> get routes => [
86
+ AutoRoute(
87
+ page: OnboardingRoute.page,
88
+ path: AppRoutes.onboarding,
89
+ initial: true,
90
+ ),
91
+ AutoRoute(
92
+ page: LoginRoute.page,
93
+ path: AppRoutes.login,
94
+ ),
95
+ AutoRoute(
96
+ page: SignupRoute.page,
97
+ path: AppRoutes.signup,
98
+ ),
99
+ AutoRoute(
100
+ page: ForgotPasswordRoute.page,
101
+ path: AppRoutes.forgotPassword,
102
+ ),
103
+ AutoRoute(
104
+ page: HomeRoute.page,
105
+ path: AppRoutes.home,
106
+ ),
107
+ ];
108
+ }
109
+ {{else if (eq flags.routerPackage "getx")}}
110
+ import 'package:{{flags.appSnake}}/src/imports/imports.dart';
111
+ import 'package:{{flags.appSnake}}/src/routing/app_routes.dart';
112
+
113
+ {{#if (eq architecture "layer-first")}}
114
+ import 'package:{{flags.appSnake}}/src/presentation/screens/auth/login_screen.dart';
115
+ import 'package:{{flags.appSnake}}/src/presentation/screens/auth/signup_screen.dart';
116
+ import 'package:{{flags.appSnake}}/src/presentation/screens/auth/forgot_password_screen.dart';
117
+ {{else if (eq architecture "mvc")}}
118
+ import 'package:{{flags.appSnake}}/src/views/auth/login_screen.dart';
119
+ import 'package:{{flags.appSnake}}/src/views/auth/signup_screen.dart';
120
+ import 'package:{{flags.appSnake}}/src/views/auth/forgot_password_screen.dart';
121
+ {{else if (eq architecture "mvvm")}}
122
+ import 'package:{{flags.appSnake}}/src/ui/auth/login_screen.dart';
123
+ import 'package:{{flags.appSnake}}/src/ui/auth/signup_screen.dart';
124
+ import 'package:{{flags.appSnake}}/src/ui/auth/forgot_password_screen.dart';
125
+ {{else}}
126
+ import 'package:{{flags.appSnake}}/src/features/auth/presentation/screens/login_screen.dart';
127
+ import 'package:{{flags.appSnake}}/src/features/auth/presentation/screens/signup_screen.dart';
128
+ import 'package:{{flags.appSnake}}/src/features/auth/presentation/screens/forgot_password_screen.dart';
129
+ {{/if}}
130
+
131
+ {{#if (eq architecture "layer-first")}}
132
+ import 'package:{{flags.appSnake}}/src/presentation/screens/home/home_page.dart';
133
+ import 'package:{{flags.appSnake}}/src/presentation/screens/onboarding/onboarding_page.dart';
134
+
135
+ {{else if (eq architecture "mvc")}}
136
+ import 'package:{{flags.appSnake}}/src/views/home/home_page.dart';
137
+ import 'package:{{flags.appSnake}}/src/views/onboarding/onboarding_page.dart';
138
+
139
+ {{else if (eq architecture "mvvm")}}
140
+ import 'package:{{flags.appSnake}}/src/ui/home/home_page.dart';
141
+ import 'package:{{flags.appSnake}}/src/ui/onboarding/onboarding_page.dart';
142
+
143
+ {{else}}
144
+ import 'package:{{flags.appSnake}}/src/features/home/presentation/screens/home_page.dart';
145
+ import 'package:{{flags.appSnake}}/src/features/onboarding/presentation/screens/onboarding_page.dart';
146
+
147
+ {{/if}}
148
+
149
+ class AppRouter {
150
+ static List<GetPage> get getPages => [
151
+ GetPage(
152
+ name: AppRoutes.onboarding,
153
+ page: () => const OnboardingPage(),
154
+ ),
155
+ GetPage(
156
+ name: AppRoutes.login,
157
+ page: () => const LoginScreen(),
158
+ ),
159
+ GetPage(
160
+ name: AppRoutes.signup,
161
+ page: () => const SignupScreen(),
162
+ ),
163
+ GetPage(
164
+ name: AppRoutes.forgotPassword,
165
+ page: () => const ForgotPasswordScreen(),
166
+ ),
167
+ GetPage(
168
+ name: AppRoutes.home,
169
+ page: () => const HomePage(),
170
+ ),
171
+ ];
172
+ }
173
+ {{else}}
174
+ import 'package:flutter/material.dart';
175
+ {{#if flags.isCupertino}}
176
+ import 'package:flutter/cupertino.dart';
177
+ {{/if}}
178
+ import 'package:{{flags.appSnake}}/src/routing/app_routes.dart';
179
+
180
+ {{#if (eq architecture "layer-first")}}
181
+ import 'package:{{flags.appSnake}}/src/presentation/screens/auth/login_screen.dart';
182
+ import 'package:{{flags.appSnake}}/src/presentation/screens/auth/signup_screen.dart';
183
+ import 'package:{{flags.appSnake}}/src/presentation/screens/auth/forgot_password_screen.dart';
184
+ {{else if (eq architecture "mvc")}}
185
+ import 'package:{{flags.appSnake}}/src/views/auth/login_screen.dart';
186
+ import 'package:{{flags.appSnake}}/src/views/auth/signup_screen.dart';
187
+ import 'package:{{flags.appSnake}}/src/views/auth/forgot_password_screen.dart';
188
+ {{else if (eq architecture "mvvm")}}
189
+ import 'package:{{flags.appSnake}}/src/ui/auth/login_screen.dart';
190
+ import 'package:{{flags.appSnake}}/src/ui/auth/signup_screen.dart';
191
+ import 'package:{{flags.appSnake}}/src/ui/auth/forgot_password_screen.dart';
192
+ {{else}}
193
+ import 'package:{{flags.appSnake}}/src/features/auth/presentation/screens/login_screen.dart';
194
+ import 'package:{{flags.appSnake}}/src/features/auth/presentation/screens/signup_screen.dart';
195
+ import 'package:{{flags.appSnake}}/src/features/auth/presentation/screens/forgot_password_screen.dart';
196
+ {{/if}}
197
+
198
+ {{#if (eq architecture "layer-first")}}
199
+ import 'package:{{flags.appSnake}}/src/presentation/screens/home/home_page.dart';
200
+ import 'package:{{flags.appSnake}}/src/presentation/screens/onboarding/onboarding_page.dart';
201
+
202
+ {{else if (eq architecture "mvc")}}
203
+ import 'package:{{flags.appSnake}}/src/views/home/home_page.dart';
204
+ import 'package:{{flags.appSnake}}/src/views/onboarding/onboarding_page.dart';
205
+
206
+ {{else if (eq architecture "mvvm")}}
207
+ import 'package:{{flags.appSnake}}/src/ui/home/home_page.dart';
208
+ import 'package:{{flags.appSnake}}/src/ui/onboarding/onboarding_page.dart';
209
+
210
+ {{else}}
211
+ import 'package:{{flags.appSnake}}/src/features/home/presentation/screens/home_page.dart';
212
+ import 'package:{{flags.appSnake}}/src/features/onboarding/presentation/screens/onboarding_page.dart';
213
+
214
+ {{/if}}
215
+
216
+ class AppRouter {
217
+ static Route<dynamic> onGenerateRoute(RouteSettings settings) {
218
+ switch (settings.name) {
219
+ case AppRoutes.onboarding:
220
+ return {{#if flags.isCupertino}}CupertinoPageRoute{{else}}MaterialPageRoute{{/if}}(
221
+ builder: (_) => const OnboardingPage(),
222
+ settings: settings,
223
+ );
224
+ case AppRoutes.login:
225
+ return {{#if flags.isCupertino}}CupertinoPageRoute{{else}}MaterialPageRoute{{/if}}(
226
+ builder: (_) => const LoginScreen(),
227
+ settings: settings,
228
+ );
229
+ case AppRoutes.signup:
230
+ return {{#if flags.isCupertino}}CupertinoPageRoute{{else}}MaterialPageRoute{{/if}}(
231
+ builder: (_) => const SignupScreen(),
232
+ settings: settings,
233
+ );
234
+ case AppRoutes.forgotPassword:
235
+ return {{#if flags.isCupertino}}CupertinoPageRoute{{else}}MaterialPageRoute{{/if}}(
236
+ builder: (_) => const ForgotPasswordScreen(),
237
+ settings: settings,
238
+ );
239
+ case AppRoutes.home:
240
+ return {{#if flags.isCupertino}}CupertinoPageRoute{{else}}MaterialPageRoute{{/if}}(
241
+ builder: (_) => const HomePage(),
242
+ settings: settings,
243
+ );
244
+ default:
245
+ return {{#if flags.isCupertino}}CupertinoPageRoute{{else}}MaterialPageRoute{{/if}}(
246
+ builder: (_) => const HomePage(),
247
+ settings: settings,
248
+ );
249
+ }
250
+ }
251
+ }
252
+ {{/if}}
@@ -0,0 +1,46 @@
1
+ {{#if (eq flags.routerPackage "go_router")}}
2
+ /// Centralized route path constants for GoRouter.
3
+ ///
4
+ /// Use these variables instead of raw strings throughout the app.
5
+ /// Example: `context.go(AppRoutes.onboarding)` instead of `context.go('/')`.
6
+ abstract final class AppRoutes {
7
+ AppRoutes._();
8
+
9
+ static const String splash = '/splash';
10
+ static const String home = '/';
11
+ static const String onboarding = '/onboarding';
12
+ static const String login = '/login';
13
+ static const String signup = '/signup';
14
+ static const String forgotPassword = '/forgot-password';
15
+ }
16
+ {{else if (eq flags.routerPackage "auto_route")}}
17
+ /// Centralized route name constants for AutoRoute.
18
+ ///
19
+ /// Reference these constants when navigating or defining routes
20
+ /// to avoid typos in route names.
21
+ abstract final class AppRoutes {
22
+ AppRoutes._();
23
+
24
+ static const String splash = '/splash';
25
+ static const String home = '/';
26
+ static const String onboarding = '/onboarding';
27
+ static const String login = '/login';
28
+ static const String signup = '/signup';
29
+ static const String forgotPassword = '/forgot-password';
30
+ }
31
+ {{else}}
32
+ /// Centralized route name constants for named Navigator routes.
33
+ ///
34
+ /// Use these constants with `Navigator.pushNamed(context, AppRoutes.onboarding)`
35
+ /// instead of inline strings to prevent typos and ease refactoring.
36
+ abstract final class AppRoutes {
37
+ AppRoutes._();
38
+
39
+ static const String splash = '/splash';
40
+ static const String home = '/';
41
+ static const String onboarding = '/onboarding';
42
+ static const String login = '/login';
43
+ static const String signup = '/signup';
44
+ static const String forgotPassword = '/forgot-password';
45
+ }
46
+ {{/if}}
@@ -0,0 +1,15 @@
1
+ import 'package:flutter/material.dart';
2
+
3
+ /// Global [NavigatorState] key used by the app's root [Navigator].
4
+ ///
5
+ /// This is wired into `MaterialApp.navigatorKey` in `app.dart` so that
6
+ /// navigation and overlays (e.g. toasts) can be triggered without a
7
+ /// local [BuildContext] reference.
8
+ final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();
9
+
10
+ /// Convenient accessor for the current root [BuildContext].
11
+ ///
12
+ /// Returns `null` before the app is mounted. Check for `null` before
13
+ /// using this in background services or repositories.
14
+ BuildContext? get rootContext => rootNavigatorKey.currentContext;
15
+
@@ -0,0 +1,78 @@
1
+ import 'dart:async';
2
+ import '../utils/utils.dart';
3
+
4
+ class AuthService {
5
+ AuthService._();
6
+ static final AuthService instance = AuthService._();
7
+
8
+ // In-memory session for mock backend
9
+ Map<String, dynamic>? _currentUser;
10
+ final StreamController<Map<String, dynamic>?> _authStateController =
11
+ StreamController<Map<String, dynamic>?>.broadcast();
12
+
13
+ /// Stream of auth state changes. Emits the current user map or null.
14
+ Stream<Map<String, dynamic>?> get authStateChanges => _authStateController.stream;
15
+
16
+ FutureEither<Map<String, dynamic>?> login({
17
+ required String email,
18
+ required String password,
19
+ }) async {
20
+ return runTask(() async {
21
+ await Future<void>.delayed(const Duration(seconds: 2));
22
+
23
+ // Mock validation
24
+ if (email.contains('error')) {
25
+ throw Exception('Mock authentication error');
26
+ }
27
+
28
+ _currentUser = {
29
+ 'id': 'mock-id-123',
30
+ 'email': email,
31
+ 'name': 'Mock User',
32
+ };
33
+ _authStateController.add(_currentUser);
34
+ return _currentUser;
35
+ }, requiresNetwork: true);
36
+ }
37
+
38
+ FutureEither<Map<String, dynamic>?> signUp({
39
+ required String name,
40
+ required String email,
41
+ required String password,
42
+ }) async {
43
+ return runTask(() async {
44
+ await Future<void>.delayed(const Duration(seconds: 2));
45
+ _currentUser = {
46
+ 'id': 'mock-id-${DateTime.now().millisecondsSinceEpoch}',
47
+ 'email': email,
48
+ 'name': name,
49
+ };
50
+ _authStateController.add(_currentUser);
51
+ return _currentUser;
52
+ }, requiresNetwork: true);
53
+ }
54
+
55
+ FutureEither<void> forgotPassword({required String email}) async {
56
+ return runTask(() async {
57
+ await Future<void>.delayed(const Duration(seconds: 1));
58
+ }, requiresNetwork: true);
59
+ }
60
+
61
+ FutureEither<void> logout() async {
62
+ return runTask(() async {
63
+ await Future<void>.delayed(const Duration(milliseconds: 500));
64
+ _currentUser = null;
65
+ _authStateController.add(null);
66
+ });
67
+ }
68
+
69
+ FutureEither<Map<String, dynamic>?> getCurrentUser() async {
70
+ return runTask(() async {
71
+ return _currentUser;
72
+ });
73
+ }
74
+
75
+ void dispose() {
76
+ _authStateController.close();
77
+ }
78
+ }
@@ -0,0 +1,16 @@
1
+ import 'package:flutter/services.dart';
2
+ import '../utils/utils.dart';
3
+
4
+ /// A service to handle clipboard operations.
5
+ class CopyService {
6
+ CopyService._();
7
+ static final CopyService instance = CopyService._();
8
+
9
+ /// Copy text to the system clipboard.
10
+ FutureEither<void> copy(String text) async {
11
+ return runTask(() async {
12
+ await Clipboard.setData(ClipboardData(text: text));
13
+ AppLogger.info('Text copied to clipboard');
14
+ });
15
+ }
16
+ }
@@ -0,0 +1,10 @@
1
+ import '../imports/imports.dart';
2
+
3
+ class InternetConnectionService {
4
+ InternetConnectionService();
5
+
6
+ final InternetConnection internetConnection = InternetConnection();
7
+
8
+ Future<bool> hasConnection() async =>
9
+ await internetConnection.hasInternetAccess;
10
+ }
@@ -0,0 +1,45 @@
1
+ export 'auth_service.dart';
2
+ export 'internet_connection_service.dart';
3
+ {{#if flags.usesDio}}
4
+ export 'dio_service.dart';
5
+ {{/if}}
6
+ {{#if (and flags.usesHttp (not flags.usesDio))}}
7
+ export 'http_service.dart';
8
+ {{/if}}
9
+ {{#if flags.usesHive}}
10
+ export 'hive_service.dart';
11
+ {{/if}}
12
+ {{#if flags.usesSharedPreferences}}
13
+ export 'storage_service.dart';
14
+ {{/if}}
15
+ {{#if flags.usesSecureStorage}}
16
+ export 'secure_storage_service.dart';
17
+ {{/if}}
18
+ {{#if flags.usesPathProvider}}
19
+ export 'path_service.dart';
20
+ {{/if}}
21
+ {{#if flags.usesGeolocator}}
22
+ export 'location_service.dart';
23
+ {{/if}}
24
+ {{#unless flags.usesFlutterHooks}}
25
+ export 'copy_service.dart';
26
+ {{#if flags.usesSharePlus}}
27
+ export 'share_service.dart';
28
+ {{/if}}
29
+ {{#if flags.usesPermissionHandler}}
30
+ export 'permission_service.dart';
31
+ {{/if}}
32
+ {{#if flags.usesUrlLauncher}}
33
+ export 'url_launcher_service.dart';
34
+ {{/if}}
35
+ {{#if (or flags.usesImagePicker flags.usesFilePicker)}}
36
+ export 'media_service.dart';
37
+ {{/if}}
38
+ {{#if flags.usesDeviceInfoPlus}}
39
+ export 'device_info_service.dart';
40
+ {{/if}}
41
+ {{#if flags.usesAppVersionUpdate}}
42
+ export 'version_update_service.dart';
43
+ {{/if}}
44
+ {{/unless}}
45
+
@@ -0,0 +1,15 @@
1
+ class AppAssets {
2
+ AppAssets._();
3
+
4
+ static const String _basePath = 'assets';
5
+ static const String _iconsPath = '$_basePath/icons';
6
+
7
+ // SVGs
8
+ static const String googleIcon = '$_iconsPath/google.svg';
9
+ static const String facebookIcon = '$_iconsPath/facebook.svg';
10
+ static const String appleIcon = '$_iconsPath/apple.svg';
11
+
12
+ // You can add more categories here as well, such as:
13
+ // static const String _imagesPath = '$_basePath/images';
14
+ // static const String logo = '$_imagesPath/logo.png';
15
+ }
@@ -0,0 +1,40 @@
1
+ /// Represents the async lifecycle state of any data/operation.
2
+ ///
3
+ /// Use this in state classes across all state management patterns (Riverpod,
4
+ /// Bloc, Provider, etc.) to replace ad-hoc boolean flags with a clean enum.
5
+ ///
6
+ /// Usage:
7
+ /// ```dart
8
+ /// // In your state class
9
+ /// AppStatus status = AppStatus.initial;
10
+ ///
11
+ /// // In your UI
12
+ /// switch (status) {
13
+ /// AppStatus.initial => const SizedBox.shrink(),
14
+ /// AppStatus.loading => const AppLoading(),
15
+ /// AppStatus.success => YourContentWidget(),
16
+ /// AppStatus.failure => AppErrorWidget(onRetry: _load),
17
+ /// }
18
+ /// ```
19
+ enum AppStatus {
20
+ /// No operation started yet — initial empty state.
21
+ initial,
22
+
23
+ /// Async operation in progress.
24
+ loading,
25
+
26
+ /// Operation completed successfully.
27
+ success,
28
+
29
+ /// Operation failed.
30
+ failure,
31
+ }
32
+
33
+ /// Extension helpers for [AppStatus].
34
+ extension AppStatusX on AppStatus {
35
+ bool get isInitial => this == AppStatus.initial;
36
+ bool get isLoading => this == AppStatus.loading;
37
+ bool get isSuccess => this == AppStatus.success;
38
+ bool get isFailure => this == AppStatus.failure;
39
+ bool get isDone => isSuccess || isFailure;
40
+ }
@@ -0,0 +1,22 @@
1
+ enum ButtonVariant {
2
+ primary,
3
+ secondary,
4
+ outline,
5
+ ghost,
6
+ danger,
7
+ success,
8
+ }
9
+
10
+ enum ButtonSize {
11
+ small,
12
+ medium,
13
+ large,
14
+ }
15
+
16
+ enum ButtonState {
17
+ idle,
18
+ loading,
19
+ disabled,
20
+ success,
21
+ error,
22
+ }
@@ -0,0 +1,3 @@
1
+ export 'button_enums.dart';
2
+ export 'app_status.dart';
3
+ export 'snack_bar_type.dart';
@@ -0,0 +1,22 @@
1
+ /// Type of snackbar to show — drives colour and icon selection.
2
+ ///
3
+ /// Used by `context.showTypedSnackBar()` in `context_extension.dart`.
4
+ ///
5
+ /// Usage:
6
+ /// ```dart
7
+ /// context.showTypedSnackBar('Saved!', type: SnackBarType.success);
8
+ /// context.showTypedSnackBar('No internet', type: SnackBarType.warning);
9
+ /// ```
10
+ enum SnackBarType {
11
+ /// Neutral informational message.
12
+ info,
13
+
14
+ /// Operation succeeded.
15
+ success,
16
+
17
+ /// Non-blocking warning the user should notice.
18
+ warning,
19
+
20
+ /// Something went wrong.
21
+ error,
22
+ }
@@ -0,0 +1,18 @@
1
+ /// Formats a number with comma separators for thousands (e.g. 1,000,000).
2
+ String formatNumber(num number) {
3
+ final parts = number.toString().split('.');
4
+ final whole = parts[0];
5
+ final buffer = StringBuffer();
6
+ int count = 0;
7
+
8
+ for (int i = whole.length - 1; i >= 0; i--) {
9
+ buffer.write(whole[i]);
10
+ count++;
11
+ if (count % 3 == 0 && i != 0) {
12
+ buffer.write(',');
13
+ }
14
+ }
15
+
16
+ final formattedWhole = buffer.toString().split('').reversed.join();
17
+ return parts.length > 1 ? '$formattedWhole.${parts[1]}' : formattedWhole;
18
+ }
@@ -0,0 +1,3 @@
1
+ export 'show_toast.dart';
2
+ export 'show_dialog.dart';
3
+ export 'show_app_sheet.dart';
@@ -0,0 +1,42 @@
1
+ import 'dart:ui';
2
+ import '../../imports/imports.dart';
3
+
4
+ /// Shows a highly customizable bottom sheet with premium features like backdrop blur.
5
+ ///
6
+ /// This helper uses the [rootNavigatorKey] to display the sheet
7
+ /// without needing a local [BuildContext].
8
+ Future<T?> showAppSheet<T>({
9
+ required Widget child,
10
+ bool hasBlur = true,
11
+ bool enableDrag = true,
12
+ bool isScrollControlled = true,
13
+ bool useSafeArea = true,
14
+ }) {
15
+ final context = rootContext;
16
+ if (context == null) return Future.value(null);
17
+
18
+ return showModalBottomSheet<T>(
19
+ context: context,
20
+ isScrollControlled: isScrollControlled,
21
+ backgroundColor: Colors.transparent,
22
+ barrierColor: context.theme.colorScheme.scrim.withValues(alpha: 0.2),
23
+ elevation: 0,
24
+ useSafeArea: useSafeArea,
25
+ enableDrag: enableDrag,
26
+ shape: const RoundedRectangleBorder(
27
+ borderRadius: AppBorders.bottomSheet,
28
+ ),
29
+ builder: (context) => GestureDetector(
30
+ behavior: HitTestBehavior.opaque,
31
+ child: BackdropFilter(
32
+ filter: ImageFilter.blur(
33
+ sigmaX: hasBlur ? 3 : 0,
34
+ sigmaY: hasBlur ? 3 : 0,
35
+ ),
36
+ child: SizedBox(
37
+ child: child,
38
+ ),
39
+ ),
40
+ ),
41
+ );
42
+ }