kasy-cli 1.21.8 → 1.22.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 (269) hide show
  1. package/lib/commands/add.js +93 -80
  2. package/lib/commands/configure.js +100 -32
  3. package/lib/commands/doctor.js +28 -2
  4. package/lib/commands/new.js +86 -38
  5. package/lib/commands/notifications.js +1 -1
  6. package/lib/commands/remove.js +43 -15
  7. package/lib/commands/run.js +2 -2
  8. package/lib/commands/update.js +2 -2
  9. package/lib/scaffold/CHANGELOG.json +14 -0
  10. package/lib/scaffold/backends/api/generator.js +14 -14
  11. package/lib/scaffold/backends/api/patch/README.md +83 -0
  12. package/lib/scaffold/backends/api/patch/lib/core/data/api/storage_api.dart +1 -1
  13. package/lib/scaffold/backends/api/patch/lib/core/data/entities/user_entity.dart +5 -0
  14. package/lib/scaffold/backends/api/patch/lib/{environnements.dart → environments.dart} +3 -11
  15. package/lib/scaffold/backends/api/patch/lib/features/ai_chat/api/ai_chat_api.dart +108 -0
  16. package/lib/scaffold/backends/api/patch/lib/features/ai_chat/api/ai_chat_conversation_entity.dart +51 -0
  17. package/lib/scaffold/backends/api/patch/lib/features/{llm_chat/api/llm_chat_message_entity.dart → ai_chat/api/ai_chat_message_entity.dart} +5 -5
  18. package/lib/scaffold/backends/api/patch/lib/features/{llm_chat/providers/llm_chat_notifier.dart → ai_chat/providers/ai_chat_notifier.dart} +71 -38
  19. package/lib/scaffold/backends/api/patch/lib/features/authentication/api/authentication_api.dart +2 -2
  20. package/lib/scaffold/backends/api/patch/lib/features/feedbacks/api/feature_request_api.dart +54 -0
  21. package/lib/scaffold/backends/api/patch/lib/features/onboarding/models/user_info.dart +16 -16
  22. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/components/onboarding_att_setup.dart +4 -3
  23. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +38 -28
  24. package/lib/scaffold/backends/api/patch/lib/features/settings/ui/components/admin/admin_users_api.dart +100 -0
  25. package/lib/scaffold/backends/api/patch/lib/features/{subscription → subscriptions}/api/entities/subscription_entity.dart +13 -0
  26. package/lib/scaffold/backends/api/patch/lib/features/subscriptions/api/stripe_backend_api.dart +60 -0
  27. package/lib/scaffold/backends/api/patch/lib/features/{subscription → subscriptions}/api/subscription_api.dart +1 -1
  28. package/lib/scaffold/backends/api/pubspec.yaml.tpl +4 -5
  29. package/lib/scaffold/backends/firebase/deploy.js +87 -13
  30. package/lib/scaffold/backends/firebase/enable-auth-via-cli.js +14 -6
  31. package/lib/scaffold/backends/firebase/generator.js +5 -5
  32. package/lib/scaffold/backends/firebase/setup-from-scratch.js +69 -45
  33. package/lib/scaffold/backends/firebase/tokens.js +4 -4
  34. package/lib/scaffold/backends/supabase/deploy.js +63 -11
  35. package/lib/scaffold/backends/supabase/edge-functions/admin-list-users/index.ts +149 -0
  36. package/lib/scaffold/backends/supabase/edge-functions/{llm-chat → ai-chat}/index.ts +19 -19
  37. package/lib/scaffold/backends/supabase/edge-functions/revenuecat-webhook/index.ts +2 -0
  38. package/lib/scaffold/backends/supabase/edge-functions/stripe-create-checkout-session/index.ts +123 -0
  39. package/lib/scaffold/backends/supabase/edge-functions/stripe-create-portal-session/index.ts +97 -0
  40. package/lib/scaffold/backends/supabase/edge-functions/stripe-list-prices/index.ts +83 -0
  41. package/lib/scaffold/backends/supabase/edge-functions/stripe-webhook/index.ts +138 -0
  42. package/lib/scaffold/backends/supabase/generator.js +17 -17
  43. package/lib/scaffold/backends/supabase/migrations/20240101000009_ai_messages.sql +50 -0
  44. package/lib/scaffold/backends/supabase/migrations/20240101000012_stripe_customers.sql +36 -0
  45. package/lib/scaffold/backends/supabase/migrations/20240101000013_admin_role.sql +62 -0
  46. package/lib/scaffold/backends/supabase/patch/lib/core/data/entities/user_entity.dart +4 -0
  47. package/lib/scaffold/backends/supabase/patch/lib/{environnements.dart → environments.dart} +3 -13
  48. package/lib/scaffold/backends/supabase/patch/lib/features/ai_chat/api/ai_chat_api.dart +95 -0
  49. package/lib/scaffold/backends/supabase/patch/lib/features/ai_chat/api/ai_chat_conversation_entity.dart +52 -0
  50. package/lib/scaffold/backends/supabase/patch/lib/features/{llm_chat/api/llm_chat_message_entity.dart → ai_chat/api/ai_chat_message_entity.dart} +6 -6
  51. package/lib/scaffold/backends/supabase/patch/lib/features/{llm_chat/providers/llm_chat_notifier.dart → ai_chat/providers/ai_chat_notifier.dart} +63 -35
  52. package/lib/scaffold/backends/supabase/patch/lib/features/authentication/api/authentication_api.dart +1 -1
  53. package/lib/scaffold/backends/supabase/patch/lib/features/feedbacks/api/feature_request_api.dart +46 -0
  54. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/models/user_info.dart +16 -16
  55. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/components/onboarding_att_setup.dart +4 -3
  56. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +38 -28
  57. package/lib/scaffold/backends/supabase/patch/lib/features/settings/ui/components/admin/admin_users_api.dart +93 -0
  58. package/lib/scaffold/backends/supabase/patch/lib/features/{subscription → subscriptions}/api/entities/subscription_entity.dart +13 -0
  59. package/lib/scaffold/backends/supabase/patch/lib/features/subscriptions/api/stripe_backend_api.dart +52 -0
  60. package/lib/scaffold/backends/supabase/patch/lib/features/{subscription → subscriptions}/api/subscription_api.dart +1 -1
  61. package/lib/scaffold/backends/supabase/pubspec.yaml.tpl +4 -5
  62. package/lib/scaffold/backends/supabase/tokens.js +3 -3
  63. package/lib/scaffold/catalog.js +9 -11
  64. package/lib/scaffold/generate.js +45 -31
  65. package/lib/scaffold/shared/generator-utils.js +188 -81
  66. package/lib/scaffold/shared/sort-imports.js +191 -0
  67. package/lib/scaffold/shared/template-strings.js +3 -3
  68. package/lib/utils/checks.js +2 -2
  69. package/lib/utils/i18n/messages-en.js +50 -35
  70. package/lib/utils/i18n/messages-es.js +50 -35
  71. package/lib/utils/i18n/messages-pt.js +52 -37
  72. package/lib/utils/updates.js +15 -15
  73. package/package.json +1 -1
  74. package/templates/firebase/.env.example +2 -2
  75. package/templates/firebase/android/app/src/main/res/drawable/background.png +0 -0
  76. package/templates/firebase/android/app/src/main/res/drawable-night/background.png +0 -0
  77. package/templates/firebase/android/app/src/main/res/drawable-night-v21/background.png +0 -0
  78. package/templates/firebase/android/app/src/main/res/drawable-v21/background.png +0 -0
  79. package/templates/firebase/android/app/src/main/res/values-night-v31/styles.xml +1 -1
  80. package/templates/firebase/android/app/src/main/res/values-v31/styles.xml +1 -1
  81. package/templates/firebase/assets/images/logo_wordmark_dark.png +0 -0
  82. package/templates/firebase/assets/images/logo_wordmark_light.png +0 -0
  83. package/templates/firebase/docs/revenuecat-setup.es.md +1 -1
  84. package/templates/firebase/docs/revenuecat-setup.pt.md +1 -1
  85. package/templates/firebase/firestore.rules +24 -5
  86. package/templates/firebase/functions/package-lock.json +22 -1
  87. package/templates/firebase/functions/package.json +2 -1
  88. package/templates/firebase/functions/src/admin/functions.ts +113 -0
  89. package/templates/firebase/functions/src/{llm_chat → ai_chat}/index.ts +16 -16
  90. package/templates/firebase/functions/src/index.ts +8 -2
  91. package/templates/firebase/functions/src/notifications/device_triggers.ts +2 -2
  92. package/templates/firebase/functions/src/notifications/triggers.ts +3 -3
  93. package/templates/firebase/functions/src/subscriptions/models/subscription_status.ts +2 -0
  94. package/templates/firebase/functions/src/subscriptions/stripe_functions.ts +222 -0
  95. package/templates/firebase/functions/src/subscriptions/subscriptions_functions.ts +2 -2
  96. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png +0 -0
  97. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png +0 -0
  98. package/templates/firebase/lib/components/components.dart +4 -1
  99. package/templates/firebase/lib/components/kasy_app_bar.dart +22 -7
  100. package/templates/firebase/lib/components/kasy_avatar.dart +7 -6
  101. package/templates/firebase/lib/components/kasy_button.dart +23 -99
  102. package/templates/firebase/lib/components/kasy_dialog.dart +11 -11
  103. package/templates/firebase/lib/components/kasy_image_viewer.dart +84 -0
  104. package/templates/firebase/lib/components/{kasy_sidebar_pro.dart → kasy_sidebar.dart} +692 -425
  105. package/templates/firebase/lib/components/kasy_status_tag.dart +91 -0
  106. package/templates/firebase/lib/components/kasy_text_area.dart +1 -3
  107. package/templates/firebase/lib/components/kasy_text_field.dart +5 -6
  108. package/templates/firebase/lib/components/kasy_text_field_otp.dart +1 -3
  109. package/templates/firebase/lib/components/kasy_toast.dart +2 -2
  110. package/templates/firebase/lib/components/kasy_web_header.dart +209 -0
  111. package/templates/firebase/lib/core/ads/ads_provider.dart +1 -1
  112. package/templates/firebase/lib/core/bottom_menu/bottom_menu.dart +57 -4
  113. package/templates/firebase/lib/core/bottom_menu/bottom_router.dart +19 -91
  114. package/templates/firebase/lib/core/bottom_menu/kasy_bottom_bar_factory.dart +196 -96
  115. package/templates/firebase/lib/core/bottom_menu/web_content_wrapper.dart +41 -0
  116. package/templates/firebase/lib/core/config/app_env.dart +5 -11
  117. package/templates/firebase/lib/core/config/features.dart +5 -4
  118. package/templates/firebase/lib/core/data/api/analytics_api.dart +1 -1
  119. package/templates/firebase/lib/core/data/api/http_client.dart +1 -1
  120. package/templates/firebase/lib/core/data/entities/user_entity.dart +3 -0
  121. package/templates/firebase/lib/core/data/models/entitlement.dart +35 -0
  122. package/templates/firebase/lib/core/data/models/subscription.dart +13 -186
  123. package/templates/firebase/lib/core/data/models/user.dart +11 -0
  124. package/templates/firebase/lib/core/data/repositories/user_repository.dart +1 -1
  125. package/templates/firebase/lib/core/home_widgets/home_widget_background_task.dart +1 -1
  126. package/templates/firebase/lib/core/home_widgets/home_widget_mywidget_service.dart +1 -1
  127. package/templates/firebase/lib/core/icons/kasy_icons.dart +31 -1
  128. package/templates/firebase/lib/core/rating/api/rating_api.dart +2 -2
  129. package/templates/firebase/lib/core/states/logout_action.dart +25 -0
  130. package/templates/firebase/lib/core/states/user_state_notifier.dart +3 -3
  131. package/templates/firebase/lib/core/theme/colors.dart +488 -188
  132. package/templates/firebase/lib/core/theme/radius.dart +22 -11
  133. package/templates/firebase/lib/core/theme/shadows.dart +66 -0
  134. package/templates/firebase/lib/core/theme/texts.dart +75 -41
  135. package/templates/firebase/lib/core/theme/universal_theme.dart +9 -4
  136. package/templates/firebase/lib/core/web_device_preview/web_device_preview.dart +5 -4
  137. package/templates/firebase/lib/core/web_viewport_scale.dart +52 -0
  138. package/templates/firebase/lib/core/widgets/kasy_brand_badge.dart +118 -0
  139. package/templates/firebase/lib/core/widgets/kasy_brand_logo.dart +40 -0
  140. package/templates/firebase/lib/core/widgets/kasy_focus_ring.dart +125 -0
  141. package/templates/firebase/lib/core/widgets/kasy_hover.dart +33 -13
  142. package/templates/firebase/lib/core/widgets/kasy_pressable_depth.dart +18 -13
  143. package/templates/firebase/lib/{environnements.dart → environments.dart} +3 -14
  144. package/templates/firebase/lib/features/ai_chat/ai_chat_page.dart +159 -0
  145. package/templates/firebase/lib/features/ai_chat/api/ai_chat_api.dart +107 -0
  146. package/templates/firebase/lib/features/ai_chat/api/ai_chat_conversation_entity.dart +64 -0
  147. package/templates/firebase/lib/features/{llm_chat/api/llm_chat_message_entity.dart → ai_chat/api/ai_chat_message_entity.dart} +6 -6
  148. package/templates/firebase/lib/features/{llm_chat/providers/llm_chat_notifier.dart → ai_chat/providers/ai_chat_notifier.dart} +73 -38
  149. package/templates/firebase/lib/features/ai_chat/providers/ai_conversations_notifier.dart +103 -0
  150. package/templates/firebase/lib/features/{llm_chat/ui/widgets/llm_chat_avatars.dart → ai_chat/ui/widgets/ai_chat_avatars.dart} +13 -13
  151. package/templates/firebase/lib/features/{llm_chat/ui/widgets/llm_chat_composer.dart → ai_chat/ui/widgets/ai_chat_composer.dart} +10 -10
  152. package/templates/firebase/lib/features/{llm_chat/llm_chat_page.dart → ai_chat/ui/widgets/ai_chat_conversation_view.dart} +80 -67
  153. package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_list.dart +285 -0
  154. package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_tile.dart +163 -0
  155. package/templates/firebase/lib/features/authentication/api/authentication_api.dart +52 -13
  156. package/templates/firebase/lib/features/authentication/api/popup_dismiss_watcher.dart +12 -0
  157. package/templates/firebase/lib/features/authentication/api/popup_dismiss_watcher_web.dart +35 -0
  158. package/templates/firebase/lib/features/authentication/ui/recover_password_page.dart +108 -68
  159. package/templates/firebase/lib/features/authentication/ui/signin_page.dart +38 -51
  160. package/templates/firebase/lib/features/authentication/ui/signup_page.dart +38 -51
  161. package/templates/firebase/lib/features/authentication/ui/widgets/auth_card_scaffold.dart +118 -0
  162. package/templates/firebase/lib/features/authentication/ui/widgets/recover_password_result.dart +61 -44
  163. package/templates/firebase/lib/features/feedbacks/api/feature_request_api.dart +32 -0
  164. package/templates/firebase/lib/features/feedbacks/models/feedback_state.dart +5 -5
  165. package/templates/firebase/lib/features/feedbacks/providers/feedback_page_notifier.dart +2 -2
  166. package/templates/firebase/lib/features/home/design_system_page.dart +808 -170
  167. package/templates/firebase/lib/features/home/home_components_page.dart +6 -3
  168. package/templates/firebase/lib/features/home/home_components_preview_page.dart +6 -6
  169. package/templates/firebase/lib/features/home/home_components_preview_registry.dart +325 -186
  170. package/templates/firebase/lib/features/home/home_feed.dart +289 -0
  171. package/templates/firebase/lib/features/home/home_image_grid.dart +355 -0
  172. package/templates/firebase/lib/features/home/home_page.dart +11 -250
  173. package/templates/firebase/lib/features/{local_reminder → local_reminders}/providers/reminder_notifier.dart +1 -1
  174. package/templates/firebase/lib/features/{local_reminder → local_reminders}/ui/reminder_page.dart +2 -2
  175. package/templates/firebase/lib/features/notifications/shared/att_permission.dart +1 -1
  176. package/templates/firebase/lib/features/notifications/ui/request_notification_permission.dart +25 -61
  177. package/templates/firebase/lib/features/notifications/ui/widgets/permission_request_view.dart +117 -0
  178. package/templates/firebase/lib/features/onboarding/models/user_info.dart +16 -16
  179. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_att_setup.dart +4 -3
  180. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_features.dart +7 -9
  181. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_loader.dart +71 -48
  182. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +3 -2
  183. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_questions.dart +5 -5
  184. package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +4 -4
  185. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_background.dart +4 -2
  186. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_feature.dart +39 -121
  187. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +105 -70
  188. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_module_mockups.dart +639 -0
  189. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_progress.dart +62 -50
  190. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +38 -28
  191. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_step_header.dart +75 -0
  192. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_sticky_footer.dart +16 -5
  193. package/templates/firebase/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +26 -22
  194. package/templates/firebase/lib/features/settings/settings_page.dart +601 -90
  195. package/templates/firebase/lib/features/settings/ui/components/admin/admin_page.dart +1193 -0
  196. package/templates/firebase/lib/features/settings/ui/components/admin/admin_paywalls.dart +1 -1
  197. package/templates/firebase/lib/features/settings/ui/components/admin/admin_routes.dart +2 -3
  198. package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_api.dart +86 -0
  199. package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_tab.dart +1215 -0
  200. package/templates/firebase/lib/features/settings/ui/components/admin/send_push_notification_page.dart +236 -0
  201. package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +3 -3
  202. package/templates/firebase/lib/features/settings/ui/widgets/kasy_user_avatar.dart +77 -0
  203. package/templates/firebase/lib/features/settings/ui/widgets/settings_tile.dart +1 -0
  204. package/templates/firebase/lib/features/{subscription → subscriptions}/api/entities/subscription_entity.dart +17 -0
  205. package/templates/firebase/lib/features/{subscription → subscriptions}/api/inapp_subscription_api.dart +67 -46
  206. package/templates/firebase/lib/features/subscriptions/api/revenuecat_product.dart +189 -0
  207. package/templates/firebase/lib/features/subscriptions/api/stripe_backend_api.dart +55 -0
  208. package/templates/firebase/lib/features/subscriptions/api/stripe_payment_api.dart +82 -0
  209. package/templates/firebase/lib/features/subscriptions/api/stripe_product.dart +178 -0
  210. package/templates/firebase/lib/features/{subscription → subscriptions}/api/subscription_api.dart +1 -1
  211. package/templates/firebase/lib/features/subscriptions/api/subscription_payment_api.dart +53 -0
  212. package/templates/firebase/lib/features/subscriptions/api/subscription_payment_api_provider.dart +21 -0
  213. package/templates/firebase/lib/features/{subscription → subscriptions}/providers/premium_page_provider.dart +9 -6
  214. package/templates/firebase/lib/features/{subscription → subscriptions}/repositories/subscription_repository.dart +26 -30
  215. package/{lib/scaffold/backends/supabase/patch/lib/features/subscription → templates/firebase/lib/features/subscriptions}/shared/maybeshow_premium.dart +0 -2
  216. package/templates/firebase/lib/features/subscriptions/shared/subscription_management.dart +45 -0
  217. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/active_premium_content.dart +28 -4
  218. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/paywall_minimal.dart +7 -7
  219. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/paywall_row.dart +8 -8
  220. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/paywall_with_switch.dart +7 -7
  221. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/premium_content.dart +7 -7
  222. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/premium_page_factory.dart +5 -5
  223. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/premium_page.dart +5 -5
  224. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/comparison_table.dart +1 -1
  225. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/paywall_empty_state.dart +4 -4
  226. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_bottom_menu.dart +3 -4
  227. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/selectable_col.dart +1 -1
  228. package/templates/firebase/lib/i18n/en.i18n.json +171 -46
  229. package/templates/firebase/lib/i18n/es.i18n.json +175 -50
  230. package/templates/firebase/lib/i18n/pt.i18n.json +166 -41
  231. package/templates/firebase/lib/main.dart +6 -3
  232. package/templates/firebase/lib/router.dart +15 -23
  233. package/templates/firebase/pubspec.yaml +4 -5
  234. package/templates/firebase/test/core/data/repositories/user_repository_test.dart +3 -3
  235. package/templates/firebase/test/core/states/user_state_notifier_test.dart +4 -4
  236. package/templates/firebase/test/core/widgets/focus_ring_shape_test.dart +55 -0
  237. package/templates/firebase/test/features/{subscription → subscriptions}/api/fake_inapp_subscription_api.dart +11 -4
  238. package/templates/firebase/test/features/{subscription → subscriptions}/api/fake_revenuecat_product.dart +1 -0
  239. package/templates/firebase/test/features/{subscription → subscriptions}/api/fake_subscription_api.dart +2 -2
  240. package/templates/firebase/test/features/{subscription → subscriptions}/subscription_page_test.dart +4 -4
  241. package/templates/firebase/test/test_utils.dart +6 -6
  242. package/templates/firebase/web/index.html +5 -2
  243. package/lib/scaffold/backends/api/patch/lib/features/llm_chat/api/llm_chat_api.dart +0 -58
  244. package/lib/scaffold/backends/api/patch/lib/features/subscription/shared/maybeshow_premium.dart +0 -86
  245. package/lib/scaffold/backends/supabase/migrations/20240101000009_llm_messages.sql +0 -22
  246. package/lib/scaffold/backends/supabase/patch/lib/features/llm_chat/api/llm_chat_api.dart +0 -47
  247. package/templates/firebase/assets/images/onboarding/authentication-login-template.jpg +0 -0
  248. package/templates/firebase/assets/images/onboarding/img2.jpg +0 -0
  249. package/templates/firebase/assets/images/onboarding/img3.jpg +0 -0
  250. package/templates/firebase/assets/images/onboarding/notifications.png +0 -0
  251. package/templates/firebase/assets/images/onboarding/purchase.png +0 -0
  252. package/templates/firebase/lib/core/sidebar/kasy_sidebar.dart +0 -2021
  253. package/templates/firebase/lib/features/authentication/ui/widgets/auth_brand.dart +0 -35
  254. package/templates/firebase/lib/features/home/home_features_page.dart +0 -207
  255. package/templates/firebase/lib/features/llm_chat/api/llm_chat_api.dart +0 -50
  256. package/templates/firebase/lib/features/settings/ui/components/admin/admin_bottom_sheet.dart +0 -316
  257. package/templates/firebase/lib/features/subscription/shared/maybeshow_premium.dart +0 -85
  258. /package/templates/firebase/lib/features/{local_reminder → local_reminders}/repositories/reminder_preferences.dart +0 -0
  259. /package/templates/firebase/lib/features/{subscription → subscriptions}/providers/models/premium_state.dart +0 -0
  260. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/feature_line.dart +0 -0
  261. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_background.dart +0 -0
  262. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_background_gradient.dart +0 -0
  263. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_banner.dart +0 -0
  264. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_card.dart +0 -0
  265. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_close_button.dart +0 -0
  266. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_feature.dart +0 -0
  267. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/selectable_row.dart +0 -0
  268. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/trial_switcher.dart +0 -0
  269. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/unsubscribe_feedback_popup.dart +0 -0
@@ -1,5 +1,6 @@
1
1
  import 'package:flutter/material.dart';
2
2
  import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_feature.dart';
3
+ import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_module_mockups.dart';
3
4
  import 'package:kasy_kit/i18n/translations.g.dart';
4
5
 
5
6
  class OnboardingFeatureOne extends StatelessWidget {
@@ -22,9 +23,8 @@ class OnboardingFeatureOne extends StatelessWidget {
22
23
  description: translations.description,
23
24
  btnText: translations.action,
24
25
  nextRoute: nextRoute,
25
- imgPath: 'assets/images/onboarding/purchase.png',
26
- withBg: true,
27
- progress: 0.1,
26
+ step: 1,
27
+ image: const PaywallMockup(),
28
28
  onSkip: onSkip,
29
29
  skipLabel: translations.skip,
30
30
  onSecondary: onLogin,
@@ -49,9 +49,8 @@ class OnboardingFeatureTwo extends StatelessWidget {
49
49
  description: translations.description,
50
50
  btnText: translations.action,
51
51
  nextRoute: nextRoute,
52
- imgPath: 'assets/images/onboarding/authentication-login-template.jpg',
53
- withBg: true,
54
- progress: 0.2,
52
+ step: 2,
53
+ image: const AuthMockup(),
55
54
  );
56
55
  }
57
56
  }
@@ -72,9 +71,8 @@ class OnboardingFeatureThree extends StatelessWidget {
72
71
  description: translations.description,
73
72
  btnText: translations.action,
74
73
  nextRoute: nextRoute,
75
- imgPath: 'assets/images/onboarding/notifications.png',
76
- withBg: true,
77
- progress: 0.3,
74
+ step: 3,
75
+ image: const NotificationsMockup(),
78
76
  );
79
77
  }
80
78
  }
@@ -1,4 +1,5 @@
1
1
  import 'package:flutter/material.dart';
2
+ import 'package:flutter_animate/flutter_animate.dart';
2
3
  import 'package:flutter_riverpod/flutter_riverpod.dart';
3
4
  import 'package:kasy_kit/core/theme/theme.dart';
4
5
  import 'package:kasy_kit/features/onboarding/providers/onboarding_provider.dart';
@@ -27,66 +28,88 @@ class _OnboardingJournalLoaderState extends ConsumerState<OnboardingLoader> {
27
28
 
28
29
  @override
29
30
  Widget build(BuildContext context) {
31
+ final colors = context.colors;
30
32
  final translations = Translations.of(context).onboarding.loading;
31
33
  return OnboardingBackground(
32
34
  child: SafeArea(
33
- child: Column(
34
- mainAxisAlignment: MainAxisAlignment.center,
35
- children: [
36
- Flexible(
37
- flex: 0,
38
- child: Padding(
39
- padding: const EdgeInsets.fromLTRB(
40
- KasySpacing.md,
41
- KasySpacing.xl,
42
- KasySpacing.md,
43
- 0,
44
- ),
45
- child: Text(
46
- translations.title,
47
- textAlign: TextAlign.center,
48
- style: context.textTheme.headlineMedium?.copyWith(
49
- color: context.colors.onBackground,
50
- ),
35
+ child: Padding(
36
+ padding: const EdgeInsets.symmetric(horizontal: KasySpacing.xl),
37
+ child: Column(
38
+ mainAxisAlignment: MainAxisAlignment.center,
39
+ children: [
40
+ const _PulsingOrb(),
41
+ const SizedBox(height: KasySpacing.xl),
42
+ Text(
43
+ translations.title,
44
+ textAlign: TextAlign.center,
45
+ style: context.textTheme.headlineSmall?.copyWith(
46
+ color: colors.onBackground,
51
47
  ),
52
48
  ),
53
- ),
54
- Flexible(
55
- flex: 0,
56
- child: Padding(
57
- padding: const EdgeInsets.fromLTRB(
58
- KasySpacing.xl,
59
- KasySpacing.md,
60
- KasySpacing.xl,
61
- 0,
62
- ),
63
- child: Text(
64
- translations.subtitle,
65
- textAlign: TextAlign.center,
66
- style: context.textTheme.bodyMedium?.copyWith(
67
- color: context.colors.muted,
68
- fontWeight: FontWeight.w400,
69
- ),
49
+ const SizedBox(height: KasySpacing.smd),
50
+ Text(
51
+ translations.subtitle,
52
+ textAlign: TextAlign.center,
53
+ style: context.textTheme.bodyMedium?.copyWith(
54
+ color: colors.muted,
70
55
  ),
71
56
  ),
72
- ),
73
- Padding(
74
- // Intentionally narrow (100px lateral) — visual design choice for loader
75
- padding: const EdgeInsets.fromLTRB(100, KasySpacing.xl, 100, 0),
76
- child: ClipRRect(
77
- borderRadius: KasyRadius.fullBorderRadius,
78
- child: LinearProgressIndicator(
79
- minHeight: 12,
80
- valueColor: AlwaysStoppedAnimation<Color>(
81
- context.colors.primary,
57
+ const SizedBox(height: KasySpacing.xl),
58
+ ConstrainedBox(
59
+ constraints: const BoxConstraints(maxWidth: 180),
60
+ child: ClipRRect(
61
+ borderRadius: KasyRadius.fullBorderRadius,
62
+ child: LinearProgressIndicator(
63
+ minHeight: 6,
64
+ valueColor: AlwaysStoppedAnimation<Color>(colors.primary),
65
+ backgroundColor: colors.primary.withValues(alpha: 0.12),
82
66
  ),
83
- backgroundColor: context.colors.primary.withValues(alpha: 0.1),
84
67
  ),
85
68
  ),
86
- ),
87
- ],
69
+ ],
70
+ ),
88
71
  ),
89
72
  ),
90
73
  );
91
74
  }
92
75
  }
76
+
77
+ /// Brand‑gradient orb that gently breathes while the profile is prepared.
78
+ class _PulsingOrb extends StatelessWidget {
79
+ const _PulsingOrb();
80
+
81
+ @override
82
+ Widget build(BuildContext context) {
83
+ final colors = context.colors;
84
+ return Container(
85
+ width: 76,
86
+ height: 76,
87
+ decoration: BoxDecoration(
88
+ shape: BoxShape.circle,
89
+ gradient: LinearGradient(
90
+ begin: Alignment.topLeft,
91
+ end: Alignment.bottomRight,
92
+ colors: [
93
+ colors.primary,
94
+ Color.lerp(colors.primary, Colors.black, 0.18)!,
95
+ ],
96
+ ),
97
+ boxShadow: [
98
+ BoxShadow(
99
+ color: colors.primary.withValues(alpha: 0.45),
100
+ blurRadius: 32,
101
+ spreadRadius: 2,
102
+ ),
103
+ ],
104
+ ),
105
+ child: Icon(KasyIcons.flash, color: colors.onPrimary, size: 34),
106
+ )
107
+ .animate(onPlay: (c) => c.repeat(reverse: true))
108
+ .scaleXY(
109
+ begin: 0.94,
110
+ end: 1.06,
111
+ duration: const Duration(milliseconds: 900),
112
+ curve: Curves.easeInOut,
113
+ );
114
+ }
115
+ }
@@ -8,6 +8,7 @@ import 'package:kasy_kit/features/notifications/repositories/notifications_repos
8
8
  import 'package:kasy_kit/features/onboarding/providers/onboarding_provider.dart';
9
9
  import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_background.dart';
10
10
  import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart';
11
+ import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_module_mockups.dart';
11
12
  import 'package:kasy_kit/i18n/translations.g.dart';
12
13
 
13
14
  final _formStep3Key = GlobalKey<FormState>();
@@ -36,10 +37,10 @@ class NotificationsPermissionStep extends ConsumerWidget {
36
37
  return Form(
37
38
  key: _formStep3Key,
38
39
  child: OnboardingIllustrationScaffold(
39
- progress: 0.9,
40
+ step: 6,
40
41
  title: translations.title,
41
42
  description: translations.description,
42
- imageAsset: 'assets/images/onboarding/img2.jpg',
43
+ image: const PushPermissionMockup(),
43
44
  footerActions: [
44
45
  KasyButton(
45
46
  label: translations.continue_button,
@@ -9,10 +9,10 @@ import 'package:kasy_kit/i18n/translations.g.dart';
9
9
  //--------------------------------------------
10
10
  /// Question about the user's gender
11
11
  //--------------------------------------------
12
- class UserSexeOnboardingQuestion extends ConsumerWidget {
12
+ class UserGenderOnboardingQuestion extends ConsumerWidget {
13
13
  final String nextRoute;
14
14
 
15
- const UserSexeOnboardingQuestion({
15
+ const UserGenderOnboardingQuestion({
16
16
  super.key,
17
17
  required this.nextRoute,
18
18
  });
@@ -24,7 +24,7 @@ class UserSexeOnboardingQuestion extends ConsumerWidget {
24
24
  title: translations.title,
25
25
  description: translations.description,
26
26
  btnText: translations.action,
27
- progress: 0.3,
27
+ step: 4,
28
28
  optionIds: translations.options.keys.toList(),
29
29
  optionBuilder: (key, selected) => SelectableRowTile(
30
30
  title: translations.options[key],
@@ -39,7 +39,7 @@ class UserSexeOnboardingQuestion extends ConsumerWidget {
39
39
  if (key != null) {
40
40
  ref
41
41
  .read(onboardingProvider.notifier)
42
- .onAnsweredQuestion(UserSexeInfo.fromString(key));
42
+ .onAnsweredQuestion(UserGenderInfo.fromString(key));
43
43
  }
44
44
  Navigator.of(context).pushReplacementNamed(nextRoute);
45
45
  },
@@ -65,7 +65,7 @@ class UserAgeOnboardingQuestion extends ConsumerWidget {
65
65
  title: translations.title,
66
66
  description: translations.description,
67
67
  btnText: translations.action,
68
- progress: 0.3,
68
+ step: 5,
69
69
  optionIds: translations.options.keys.toList(),
70
70
  optionBuilder: (key, selected) => SelectableRowTile(
71
71
  title: translations.options[key],
@@ -9,7 +9,7 @@ import 'package:kasy_kit/features/onboarding/ui/components/onboarding_features.d
9
9
  import 'package:kasy_kit/features/onboarding/ui/components/onboarding_loader.dart';
10
10
  import 'package:kasy_kit/features/onboarding/ui/components/onboarding_notifications_setup.dart';
11
11
  import 'package:kasy_kit/features/onboarding/ui/components/onboarding_questions.dart';
12
- import 'package:kasy_kit/features/subscription/ui/premium_page.dart';
12
+ import 'package:kasy_kit/features/subscriptions/ui/premium_page.dart';
13
13
  import 'package:kasy_kit/router.dart';
14
14
 
15
15
 
@@ -45,12 +45,12 @@ class OnboardingPage extends ConsumerWidget {
45
45
  ),
46
46
  'feature_3' => OnboardingRouteTransition(
47
47
  builder: (context) => const OnboardingFeatureThree(
48
- nextRoute: 'sexe_question',
48
+ nextRoute: 'gender_question',
49
49
  ),
50
50
  settings: settings,
51
51
  ),
52
- 'sexe_question' => OnboardingRouteTransition(
53
- builder: (context) => const UserSexeOnboardingQuestion(
52
+ 'gender_question' => OnboardingRouteTransition(
53
+ builder: (context) => const UserGenderOnboardingQuestion(
54
54
  nextRoute: 'age_question',
55
55
  ),
56
56
  settings: settings,
@@ -46,10 +46,12 @@ class OnboardingBackground extends StatelessWidget {
46
46
  begin: Alignment.topCenter,
47
47
  end: Alignment.bottomCenter,
48
48
  colors: [
49
- bgColor ?? context.colors.primary.withValues(alpha: .15),
49
+ bgColor ??
50
+ context.colors.primary
51
+ .withValues(alpha: context.isDark ? 0.16 : 0.10),
50
52
  bgColor ?? context.colors.primary.withValues(alpha: 0),
51
53
  ],
52
- stops: const [0.0, .5],
54
+ stops: const [0.0, .45],
53
55
  ),
54
56
  )),
55
57
  ),
@@ -1,23 +1,21 @@
1
1
  import 'package:flutter/material.dart';
2
- import 'package:flutter_animate/flutter_animate.dart';
3
2
  import 'package:kasy_kit/components/components.dart';
4
3
  import 'package:kasy_kit/core/theme/theme.dart';
5
- import 'package:kasy_kit/core/widgets/responsive_layout.dart';
6
4
  import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_background.dart';
7
5
  import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart';
6
+ import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_progress.dart';
8
7
 
9
- /// A generic onboarding step widget with text and image.
8
+ /// A generic onboarding presentation step: a live module mockup as hero, a
9
+ /// left‑aligned title/description and a sticky primary action.
10
10
  class OnboardingStep extends StatelessWidget {
11
- final String? title;
12
- final Widget? titleWidget;
13
- final String imgPath;
11
+ final String title;
14
12
  final String description;
15
13
  final String btnText;
16
14
  final String nextRoute;
15
+ final int step;
16
+ final int totalSteps;
17
+ final Widget image;
17
18
  final VoidCallback? onNext;
18
- final double progress;
19
- final Widget? image;
20
- final bool withBg;
21
19
  final VoidCallback? onSkip;
22
20
  final String? skipLabel;
23
21
  final VoidCallback? onSecondary;
@@ -25,16 +23,14 @@ class OnboardingStep extends StatelessWidget {
25
23
 
26
24
  const OnboardingStep({
27
25
  super.key,
28
- this.title,
29
- this.titleWidget,
30
- required this.imgPath,
26
+ required this.title,
31
27
  required this.description,
32
28
  required this.btnText,
33
29
  required this.nextRoute,
34
- required this.progress,
30
+ required this.step,
31
+ required this.image,
32
+ this.totalSteps = kOnboardingSteps,
35
33
  this.onNext,
36
- this.withBg = false,
37
- this.image,
38
34
  this.onSkip,
39
35
  this.skipLabel,
40
36
  this.onSecondary,
@@ -43,116 +39,38 @@ class OnboardingStep extends StatelessWidget {
43
39
 
44
40
  @override
45
41
  Widget build(BuildContext context) {
46
- final Widget? illustration = image ??
47
- (imgPath.isNotEmpty
48
- ? Animate(
49
- effects: const [
50
- FadeEffect(
51
- delay: Duration(milliseconds: 100),
52
- duration: Duration(milliseconds: 200),
53
- curve: Curves.easeIn,
54
- ),
55
- MoveEffect(
56
- delay: Duration(milliseconds: 100),
57
- duration: Duration(milliseconds: 450),
58
- curve: Curves.easeOut,
59
- begin: Offset(0, 50),
60
- end: Offset.zero,
61
- ),
62
- ],
63
- child: Image.asset(imgPath, fit: BoxFit.contain),
64
- )
65
- : null);
66
-
67
- final scaffold = OnboardingIllustrationScaffold(
68
- progress: progress,
69
- onSkip: onSkip,
70
- skipLabel: skipLabel,
71
- title: title ?? '',
72
- titleWidget: title != null
73
- ? Animate(
74
- effects: const [
75
- FadeEffect(
76
- delay: Duration(milliseconds: 200),
77
- duration: Duration(milliseconds: 200),
78
- curve: Curves.easeIn,
79
- ),
80
- MoveEffect(
81
- delay: Duration(milliseconds: 200),
82
- duration: Duration(milliseconds: 450),
83
- curve: Curves.easeOut,
84
- begin: Offset(0, 50),
85
- end: Offset.zero,
86
- ),
87
- ],
88
- child: Text(
89
- title!,
90
- textAlign: TextAlign.center,
91
- style: context.textTheme.headlineMedium?.copyWith(
92
- color: context.colors.onBackground,
93
- fontWeight: FontWeight.w600,
94
- ),
95
- ),
96
- )
97
- : titleWidget,
98
- description: description,
99
- descriptionWidget: Animate(
100
- effects: const [
101
- FadeEffect(
102
- delay: Duration(milliseconds: 300),
103
- duration: Duration(milliseconds: 200),
104
- curve: Curves.easeIn,
105
- ),
106
- MoveEffect(
107
- delay: Duration(milliseconds: 300),
108
- duration: Duration(milliseconds: 450),
109
- curve: Curves.easeOut,
110
- begin: Offset(0, 50),
111
- end: Offset.zero,
112
- ),
113
- ],
114
- child: Text(
115
- description,
116
- textAlign: TextAlign.center,
117
- style: context.textTheme.bodyLarge?.copyWith(
118
- color: context.colors.onBackground.withValues(alpha: 0.6),
119
- ),
120
- ),
121
- ),
122
- image: illustration,
123
- footerActions: [
124
- KasyButton(
125
- label: btnText,
126
- expand: true,
127
- onPressed: () {
128
- if (onNext != null) {
129
- onNext!.call();
130
- } else {
131
- Navigator.of(context).pushReplacementNamed(nextRoute);
132
- }
133
- },
134
- ),
135
- if (onSecondary != null && secondaryLabel != null) ...[
136
- const SizedBox(height: KasySpacing.xs),
42
+ return OnboardingBackground(
43
+ child: OnboardingIllustrationScaffold(
44
+ step: step,
45
+ totalSteps: totalSteps,
46
+ title: title,
47
+ description: description,
48
+ image: image,
49
+ onSkip: onSkip,
50
+ skipLabel: skipLabel,
51
+ footerActions: [
137
52
  KasyButton(
138
- label: secondaryLabel!,
139
- variant: KasyButtonVariant.link,
53
+ label: btnText,
140
54
  expand: true,
141
- onPressed: onSecondary,
55
+ onPressed: () {
56
+ if (onNext != null) {
57
+ onNext!.call();
58
+ } else {
59
+ Navigator.of(context).pushReplacementNamed(nextRoute);
60
+ }
61
+ },
142
62
  ),
143
- ],
144
- ],
145
- );
146
-
147
- final content = ResponsiveLayout(
148
- small: withBg
149
- ? OnboardingBackground(child: scaffold)
150
- : ColoredBox(
151
- color: context.colors.background,
152
- child: scaffold,
63
+ if (onSecondary != null && secondaryLabel != null) ...[
64
+ const SizedBox(height: KasySpacing.xs),
65
+ KasyButton(
66
+ label: secondaryLabel!,
67
+ variant: KasyButtonVariant.link,
68
+ expand: true,
69
+ onPressed: onSecondary,
153
70
  ),
71
+ ],
72
+ ],
73
+ ),
154
74
  );
155
-
156
- return content;
157
75
  }
158
76
  }