kasy-cli 1.21.9 → 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 (267) 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 +80 -37
  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/generator.js +5 -5
  31. package/lib/scaffold/backends/firebase/tokens.js +4 -4
  32. package/lib/scaffold/backends/supabase/deploy.js +63 -11
  33. package/lib/scaffold/backends/supabase/edge-functions/admin-list-users/index.ts +149 -0
  34. package/lib/scaffold/backends/supabase/edge-functions/{llm-chat → ai-chat}/index.ts +19 -19
  35. package/lib/scaffold/backends/supabase/edge-functions/revenuecat-webhook/index.ts +2 -0
  36. package/lib/scaffold/backends/supabase/edge-functions/stripe-create-checkout-session/index.ts +123 -0
  37. package/lib/scaffold/backends/supabase/edge-functions/stripe-create-portal-session/index.ts +97 -0
  38. package/lib/scaffold/backends/supabase/edge-functions/stripe-list-prices/index.ts +83 -0
  39. package/lib/scaffold/backends/supabase/edge-functions/stripe-webhook/index.ts +138 -0
  40. package/lib/scaffold/backends/supabase/generator.js +17 -17
  41. package/lib/scaffold/backends/supabase/migrations/20240101000009_ai_messages.sql +50 -0
  42. package/lib/scaffold/backends/supabase/migrations/20240101000012_stripe_customers.sql +36 -0
  43. package/lib/scaffold/backends/supabase/migrations/20240101000013_admin_role.sql +62 -0
  44. package/lib/scaffold/backends/supabase/patch/lib/core/data/entities/user_entity.dart +4 -0
  45. package/lib/scaffold/backends/supabase/patch/lib/{environnements.dart → environments.dart} +3 -13
  46. package/lib/scaffold/backends/supabase/patch/lib/features/ai_chat/api/ai_chat_api.dart +95 -0
  47. package/lib/scaffold/backends/supabase/patch/lib/features/ai_chat/api/ai_chat_conversation_entity.dart +52 -0
  48. 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
  49. package/lib/scaffold/backends/supabase/patch/lib/features/{llm_chat/providers/llm_chat_notifier.dart → ai_chat/providers/ai_chat_notifier.dart} +63 -35
  50. package/lib/scaffold/backends/supabase/patch/lib/features/authentication/api/authentication_api.dart +1 -1
  51. package/lib/scaffold/backends/supabase/patch/lib/features/feedbacks/api/feature_request_api.dart +46 -0
  52. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/models/user_info.dart +16 -16
  53. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/components/onboarding_att_setup.dart +4 -3
  54. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +38 -28
  55. package/lib/scaffold/backends/supabase/patch/lib/features/settings/ui/components/admin/admin_users_api.dart +93 -0
  56. package/lib/scaffold/backends/supabase/patch/lib/features/{subscription → subscriptions}/api/entities/subscription_entity.dart +13 -0
  57. package/lib/scaffold/backends/supabase/patch/lib/features/subscriptions/api/stripe_backend_api.dart +52 -0
  58. package/lib/scaffold/backends/supabase/patch/lib/features/{subscription → subscriptions}/api/subscription_api.dart +1 -1
  59. package/lib/scaffold/backends/supabase/pubspec.yaml.tpl +4 -5
  60. package/lib/scaffold/backends/supabase/tokens.js +3 -3
  61. package/lib/scaffold/catalog.js +9 -11
  62. package/lib/scaffold/generate.js +45 -31
  63. package/lib/scaffold/shared/generator-utils.js +188 -81
  64. package/lib/scaffold/shared/sort-imports.js +191 -0
  65. package/lib/scaffold/shared/template-strings.js +3 -3
  66. package/lib/utils/checks.js +2 -2
  67. package/lib/utils/i18n/messages-en.js +50 -35
  68. package/lib/utils/i18n/messages-es.js +50 -35
  69. package/lib/utils/i18n/messages-pt.js +52 -37
  70. package/lib/utils/updates.js +15 -15
  71. package/package.json +1 -1
  72. package/templates/firebase/.env.example +2 -2
  73. package/templates/firebase/android/app/src/main/res/drawable/background.png +0 -0
  74. package/templates/firebase/android/app/src/main/res/drawable-night/background.png +0 -0
  75. package/templates/firebase/android/app/src/main/res/drawable-night-v21/background.png +0 -0
  76. package/templates/firebase/android/app/src/main/res/drawable-v21/background.png +0 -0
  77. package/templates/firebase/android/app/src/main/res/values-night-v31/styles.xml +1 -1
  78. package/templates/firebase/android/app/src/main/res/values-v31/styles.xml +1 -1
  79. package/templates/firebase/assets/images/logo_wordmark_dark.png +0 -0
  80. package/templates/firebase/assets/images/logo_wordmark_light.png +0 -0
  81. package/templates/firebase/docs/revenuecat-setup.es.md +1 -1
  82. package/templates/firebase/docs/revenuecat-setup.pt.md +1 -1
  83. package/templates/firebase/firestore.rules +24 -5
  84. package/templates/firebase/functions/package-lock.json +22 -1
  85. package/templates/firebase/functions/package.json +2 -1
  86. package/templates/firebase/functions/src/admin/functions.ts +113 -0
  87. package/templates/firebase/functions/src/{llm_chat → ai_chat}/index.ts +16 -16
  88. package/templates/firebase/functions/src/index.ts +8 -2
  89. package/templates/firebase/functions/src/notifications/device_triggers.ts +2 -2
  90. package/templates/firebase/functions/src/notifications/triggers.ts +3 -3
  91. package/templates/firebase/functions/src/subscriptions/models/subscription_status.ts +2 -0
  92. package/templates/firebase/functions/src/subscriptions/stripe_functions.ts +222 -0
  93. package/templates/firebase/functions/src/subscriptions/subscriptions_functions.ts +2 -2
  94. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png +0 -0
  95. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png +0 -0
  96. package/templates/firebase/lib/components/components.dart +4 -1
  97. package/templates/firebase/lib/components/kasy_app_bar.dart +22 -7
  98. package/templates/firebase/lib/components/kasy_avatar.dart +7 -6
  99. package/templates/firebase/lib/components/kasy_button.dart +23 -99
  100. package/templates/firebase/lib/components/kasy_dialog.dart +11 -11
  101. package/templates/firebase/lib/components/kasy_image_viewer.dart +84 -0
  102. package/templates/firebase/lib/components/{kasy_sidebar_pro.dart → kasy_sidebar.dart} +692 -425
  103. package/templates/firebase/lib/components/kasy_status_tag.dart +91 -0
  104. package/templates/firebase/lib/components/kasy_text_area.dart +1 -3
  105. package/templates/firebase/lib/components/kasy_text_field.dart +5 -6
  106. package/templates/firebase/lib/components/kasy_text_field_otp.dart +1 -3
  107. package/templates/firebase/lib/components/kasy_toast.dart +2 -2
  108. package/templates/firebase/lib/components/kasy_web_header.dart +209 -0
  109. package/templates/firebase/lib/core/ads/ads_provider.dart +1 -1
  110. package/templates/firebase/lib/core/bottom_menu/bottom_menu.dart +57 -4
  111. package/templates/firebase/lib/core/bottom_menu/bottom_router.dart +19 -91
  112. package/templates/firebase/lib/core/bottom_menu/kasy_bottom_bar_factory.dart +196 -96
  113. package/templates/firebase/lib/core/bottom_menu/web_content_wrapper.dart +41 -0
  114. package/templates/firebase/lib/core/config/app_env.dart +5 -11
  115. package/templates/firebase/lib/core/config/features.dart +5 -4
  116. package/templates/firebase/lib/core/data/api/analytics_api.dart +1 -1
  117. package/templates/firebase/lib/core/data/api/http_client.dart +1 -1
  118. package/templates/firebase/lib/core/data/entities/user_entity.dart +3 -0
  119. package/templates/firebase/lib/core/data/models/entitlement.dart +35 -0
  120. package/templates/firebase/lib/core/data/models/subscription.dart +13 -186
  121. package/templates/firebase/lib/core/data/models/user.dart +11 -0
  122. package/templates/firebase/lib/core/data/repositories/user_repository.dart +1 -1
  123. package/templates/firebase/lib/core/home_widgets/home_widget_background_task.dart +1 -1
  124. package/templates/firebase/lib/core/home_widgets/home_widget_mywidget_service.dart +1 -1
  125. package/templates/firebase/lib/core/icons/kasy_icons.dart +31 -1
  126. package/templates/firebase/lib/core/rating/api/rating_api.dart +2 -2
  127. package/templates/firebase/lib/core/states/logout_action.dart +25 -0
  128. package/templates/firebase/lib/core/states/user_state_notifier.dart +3 -3
  129. package/templates/firebase/lib/core/theme/colors.dart +488 -188
  130. package/templates/firebase/lib/core/theme/radius.dart +22 -11
  131. package/templates/firebase/lib/core/theme/shadows.dart +66 -0
  132. package/templates/firebase/lib/core/theme/texts.dart +75 -41
  133. package/templates/firebase/lib/core/theme/universal_theme.dart +9 -4
  134. package/templates/firebase/lib/core/web_device_preview/web_device_preview.dart +5 -4
  135. package/templates/firebase/lib/core/web_viewport_scale.dart +52 -0
  136. package/templates/firebase/lib/core/widgets/kasy_brand_badge.dart +118 -0
  137. package/templates/firebase/lib/core/widgets/kasy_brand_logo.dart +40 -0
  138. package/templates/firebase/lib/core/widgets/kasy_focus_ring.dart +125 -0
  139. package/templates/firebase/lib/core/widgets/kasy_hover.dart +33 -13
  140. package/templates/firebase/lib/core/widgets/kasy_pressable_depth.dart +18 -13
  141. package/templates/firebase/lib/{environnements.dart → environments.dart} +3 -14
  142. package/templates/firebase/lib/features/ai_chat/ai_chat_page.dart +159 -0
  143. package/templates/firebase/lib/features/ai_chat/api/ai_chat_api.dart +107 -0
  144. package/templates/firebase/lib/features/ai_chat/api/ai_chat_conversation_entity.dart +64 -0
  145. package/templates/firebase/lib/features/{llm_chat/api/llm_chat_message_entity.dart → ai_chat/api/ai_chat_message_entity.dart} +6 -6
  146. package/templates/firebase/lib/features/{llm_chat/providers/llm_chat_notifier.dart → ai_chat/providers/ai_chat_notifier.dart} +73 -38
  147. package/templates/firebase/lib/features/ai_chat/providers/ai_conversations_notifier.dart +103 -0
  148. package/templates/firebase/lib/features/{llm_chat/ui/widgets/llm_chat_avatars.dart → ai_chat/ui/widgets/ai_chat_avatars.dart} +13 -13
  149. package/templates/firebase/lib/features/{llm_chat/ui/widgets/llm_chat_composer.dart → ai_chat/ui/widgets/ai_chat_composer.dart} +10 -10
  150. package/templates/firebase/lib/features/{llm_chat/llm_chat_page.dart → ai_chat/ui/widgets/ai_chat_conversation_view.dart} +80 -67
  151. package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_list.dart +285 -0
  152. package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_tile.dart +163 -0
  153. package/templates/firebase/lib/features/authentication/api/authentication_api.dart +52 -13
  154. package/templates/firebase/lib/features/authentication/api/popup_dismiss_watcher.dart +12 -0
  155. package/templates/firebase/lib/features/authentication/api/popup_dismiss_watcher_web.dart +35 -0
  156. package/templates/firebase/lib/features/authentication/ui/recover_password_page.dart +108 -68
  157. package/templates/firebase/lib/features/authentication/ui/signin_page.dart +38 -51
  158. package/templates/firebase/lib/features/authentication/ui/signup_page.dart +38 -51
  159. package/templates/firebase/lib/features/authentication/ui/widgets/auth_card_scaffold.dart +118 -0
  160. package/templates/firebase/lib/features/authentication/ui/widgets/recover_password_result.dart +61 -44
  161. package/templates/firebase/lib/features/feedbacks/api/feature_request_api.dart +32 -0
  162. package/templates/firebase/lib/features/feedbacks/models/feedback_state.dart +5 -5
  163. package/templates/firebase/lib/features/feedbacks/providers/feedback_page_notifier.dart +2 -2
  164. package/templates/firebase/lib/features/home/design_system_page.dart +808 -170
  165. package/templates/firebase/lib/features/home/home_components_page.dart +6 -3
  166. package/templates/firebase/lib/features/home/home_components_preview_page.dart +6 -6
  167. package/templates/firebase/lib/features/home/home_components_preview_registry.dart +325 -186
  168. package/templates/firebase/lib/features/home/home_feed.dart +289 -0
  169. package/templates/firebase/lib/features/home/home_image_grid.dart +355 -0
  170. package/templates/firebase/lib/features/home/home_page.dart +11 -250
  171. package/templates/firebase/lib/features/{local_reminder → local_reminders}/providers/reminder_notifier.dart +1 -1
  172. package/templates/firebase/lib/features/{local_reminder → local_reminders}/ui/reminder_page.dart +2 -2
  173. package/templates/firebase/lib/features/notifications/shared/att_permission.dart +1 -1
  174. package/templates/firebase/lib/features/notifications/ui/request_notification_permission.dart +25 -61
  175. package/templates/firebase/lib/features/notifications/ui/widgets/permission_request_view.dart +117 -0
  176. package/templates/firebase/lib/features/onboarding/models/user_info.dart +16 -16
  177. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_att_setup.dart +4 -3
  178. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_features.dart +7 -9
  179. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_loader.dart +71 -48
  180. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +3 -2
  181. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_questions.dart +5 -5
  182. package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +4 -4
  183. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_background.dart +4 -2
  184. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_feature.dart +39 -121
  185. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +105 -70
  186. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_module_mockups.dart +639 -0
  187. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_progress.dart +62 -50
  188. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +38 -28
  189. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_step_header.dart +75 -0
  190. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_sticky_footer.dart +16 -5
  191. package/templates/firebase/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +26 -22
  192. package/templates/firebase/lib/features/settings/settings_page.dart +601 -90
  193. package/templates/firebase/lib/features/settings/ui/components/admin/admin_page.dart +1193 -0
  194. package/templates/firebase/lib/features/settings/ui/components/admin/admin_paywalls.dart +1 -1
  195. package/templates/firebase/lib/features/settings/ui/components/admin/admin_routes.dart +2 -3
  196. package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_api.dart +86 -0
  197. package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_tab.dart +1215 -0
  198. package/templates/firebase/lib/features/settings/ui/components/admin/send_push_notification_page.dart +236 -0
  199. package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +3 -3
  200. package/templates/firebase/lib/features/settings/ui/widgets/kasy_user_avatar.dart +77 -0
  201. package/templates/firebase/lib/features/settings/ui/widgets/settings_tile.dart +1 -0
  202. package/templates/firebase/lib/features/{subscription → subscriptions}/api/entities/subscription_entity.dart +17 -0
  203. package/templates/firebase/lib/features/{subscription → subscriptions}/api/inapp_subscription_api.dart +67 -46
  204. package/templates/firebase/lib/features/subscriptions/api/revenuecat_product.dart +189 -0
  205. package/templates/firebase/lib/features/subscriptions/api/stripe_backend_api.dart +55 -0
  206. package/templates/firebase/lib/features/subscriptions/api/stripe_payment_api.dart +82 -0
  207. package/templates/firebase/lib/features/subscriptions/api/stripe_product.dart +178 -0
  208. package/templates/firebase/lib/features/{subscription → subscriptions}/api/subscription_api.dart +1 -1
  209. package/templates/firebase/lib/features/subscriptions/api/subscription_payment_api.dart +53 -0
  210. package/templates/firebase/lib/features/subscriptions/api/subscription_payment_api_provider.dart +21 -0
  211. package/templates/firebase/lib/features/{subscription → subscriptions}/providers/premium_page_provider.dart +9 -6
  212. package/templates/firebase/lib/features/{subscription → subscriptions}/repositories/subscription_repository.dart +26 -30
  213. package/{lib/scaffold/backends/supabase/patch/lib/features/subscription → templates/firebase/lib/features/subscriptions}/shared/maybeshow_premium.dart +0 -2
  214. package/templates/firebase/lib/features/subscriptions/shared/subscription_management.dart +45 -0
  215. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/active_premium_content.dart +28 -4
  216. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/paywall_minimal.dart +7 -7
  217. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/paywall_row.dart +8 -8
  218. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/paywall_with_switch.dart +7 -7
  219. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/premium_content.dart +7 -7
  220. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/premium_page_factory.dart +5 -5
  221. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/premium_page.dart +5 -5
  222. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/comparison_table.dart +1 -1
  223. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/paywall_empty_state.dart +4 -4
  224. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_bottom_menu.dart +3 -4
  225. package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/selectable_col.dart +1 -1
  226. package/templates/firebase/lib/i18n/en.i18n.json +171 -46
  227. package/templates/firebase/lib/i18n/es.i18n.json +175 -50
  228. package/templates/firebase/lib/i18n/pt.i18n.json +166 -41
  229. package/templates/firebase/lib/main.dart +6 -3
  230. package/templates/firebase/lib/router.dart +15 -23
  231. package/templates/firebase/pubspec.yaml +4 -5
  232. package/templates/firebase/test/core/data/repositories/user_repository_test.dart +3 -3
  233. package/templates/firebase/test/core/states/user_state_notifier_test.dart +4 -4
  234. package/templates/firebase/test/core/widgets/focus_ring_shape_test.dart +55 -0
  235. package/templates/firebase/test/features/{subscription → subscriptions}/api/fake_inapp_subscription_api.dart +11 -4
  236. package/templates/firebase/test/features/{subscription → subscriptions}/api/fake_revenuecat_product.dart +1 -0
  237. package/templates/firebase/test/features/{subscription → subscriptions}/api/fake_subscription_api.dart +2 -2
  238. package/templates/firebase/test/features/{subscription → subscriptions}/subscription_page_test.dart +4 -4
  239. package/templates/firebase/test/test_utils.dart +6 -6
  240. package/templates/firebase/web/index.html +5 -2
  241. package/lib/scaffold/backends/api/patch/lib/features/llm_chat/api/llm_chat_api.dart +0 -58
  242. package/lib/scaffold/backends/api/patch/lib/features/subscription/shared/maybeshow_premium.dart +0 -86
  243. package/lib/scaffold/backends/supabase/migrations/20240101000009_llm_messages.sql +0 -22
  244. package/lib/scaffold/backends/supabase/patch/lib/features/llm_chat/api/llm_chat_api.dart +0 -47
  245. package/templates/firebase/assets/images/onboarding/authentication-login-template.jpg +0 -0
  246. package/templates/firebase/assets/images/onboarding/img2.jpg +0 -0
  247. package/templates/firebase/assets/images/onboarding/img3.jpg +0 -0
  248. package/templates/firebase/assets/images/onboarding/notifications.png +0 -0
  249. package/templates/firebase/assets/images/onboarding/purchase.png +0 -0
  250. package/templates/firebase/lib/core/sidebar/kasy_sidebar.dart +0 -2021
  251. package/templates/firebase/lib/features/authentication/ui/widgets/auth_brand.dart +0 -35
  252. package/templates/firebase/lib/features/home/home_features_page.dart +0 -207
  253. package/templates/firebase/lib/features/llm_chat/api/llm_chat_api.dart +0 -50
  254. package/templates/firebase/lib/features/settings/ui/components/admin/admin_bottom_sheet.dart +0 -316
  255. package/templates/firebase/lib/features/subscription/shared/maybeshow_premium.dart +0 -85
  256. /package/templates/firebase/lib/features/{local_reminder → local_reminders}/repositories/reminder_preferences.dart +0 -0
  257. /package/templates/firebase/lib/features/{subscription → subscriptions}/providers/models/premium_state.dart +0 -0
  258. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/feature_line.dart +0 -0
  259. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_background.dart +0 -0
  260. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_background_gradient.dart +0 -0
  261. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_banner.dart +0 -0
  262. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_card.dart +0 -0
  263. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_close_button.dart +0 -0
  264. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_feature.dart +0 -0
  265. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/selectable_row.dart +0 -0
  266. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/trial_switcher.dart +0 -0
  267. /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/unsubscribe_feedback_popup.dart +0 -0
@@ -1,25 +1,24 @@
1
1
  import 'package:flutter/material.dart';
2
2
  import 'package:flutter_riverpod/flutter_riverpod.dart';
3
- import 'package:go_router/go_router.dart';
4
3
  import 'package:kasy_kit/components/kasy_app_bar.dart';
5
4
  import 'package:kasy_kit/core/haptics/kasy_haptics.dart';
6
5
  import 'package:kasy_kit/core/states/components/maybe_ask_rating.dart';
7
6
  import 'package:kasy_kit/core/states/components/maybe_show_update_bottom_sheet.dart';
8
7
  import 'package:kasy_kit/core/states/components/maybeshow_component.dart';
9
8
  import 'package:kasy_kit/core/theme/theme.dart';
10
- import 'package:kasy_kit/features/home/home_components_page.dart';
11
- import 'package:kasy_kit/features/home/home_features_page.dart';
9
+ import 'package:kasy_kit/features/home/home_feed.dart';
12
10
  import 'package:kasy_kit/features/notifications/shared/att_permission.dart';
13
- import 'package:kasy_kit/features/subscription/shared/maybeshow_premium.dart';
11
+ import 'package:kasy_kit/features/subscriptions/shared/maybeshow_premium.dart';
14
12
  import 'package:kasy_kit/i18n/translations.g.dart';
15
13
 
16
- /// Home hub with dashboard cards linking to the Features and Components screens.
14
+ /// Home hub. Intentionally minimal for now the Features/Components showcase
15
+ /// cards moved into the debug admin console (those are an administrator concern,
16
+ /// not the end user's home). A real product home lands here later.
17
17
  class HomePage extends ConsumerWidget {
18
18
  const HomePage({super.key});
19
19
 
20
20
  @override
21
21
  Widget build(BuildContext context, WidgetRef ref) {
22
- final bool isDark = Theme.of(context).brightness == Brightness.dark;
23
22
  return ConditionalWidgetsEvents(
24
23
  eventWidgets: [
25
24
  MaybeAskForReview(),
@@ -32,76 +31,13 @@ class HomePage extends ConsumerWidget {
32
31
  color: context.colors.background,
33
32
  child: Stack(
34
33
  children: [
35
- CustomScrollView(
36
- slivers: [
37
- SliverToBoxAdapter(
38
- child: SizedBox(height: kasyAppBarBodyTopOverlap(context)),
34
+ Positioned.fill(
35
+ child: Padding(
36
+ padding: EdgeInsets.only(
37
+ top: kasyAppBarBodyTopOverlap(context),
39
38
  ),
40
- SliverPadding(
41
- padding: EdgeInsets.only(
42
- left: KasySpacing.pageHorizontalGutter,
43
- right: KasySpacing.pageHorizontalGutter,
44
- top: KasySpacing.belowChromeContentGap,
45
- bottom: MediaQuery.paddingOf(context).bottom,
46
- ),
47
- sliver: SliverList(
48
- delegate: SliverChildListDelegate([
49
- LayoutBuilder(
50
- builder: (context, constraints) {
51
- final isWide = constraints.maxWidth > 600;
52
- final featuresCard = _DashboardGradientCard(
53
- countLabel: t.home.dashboard.count_total(
54
- count: homeFeaturesEntryCount(),
55
- ),
56
- countBadgeTextColor: const Color(0xFF4A3D6B),
57
- title: t.home.dashboard.features_title,
58
- subtitle: t.home.dashboard.features_subtitle,
59
- gradient: _featuresGradient(context, isDark),
60
- onOpen: () {
61
- KasyHaptics.medium(context);
62
- // Top-level go_router route: opens full-screen on the
63
- // root navigator (above the BottomMenu, no bottom bar)
64
- // and pops back to home with the menu intact.
65
- context.push('/features');
66
- },
67
- );
68
- final componentsCard = _DashboardGradientCard(
69
- countLabel: t.home.dashboard.count_total(
70
- count: HomeComponentsPage.sectionCount,
71
- ),
72
- countBadgeTextColor: const Color(0xFF2D3A4D),
73
- title: t.home.dashboard.components_title,
74
- subtitle: t.home.dashboard.components_subtitle,
75
- gradient: _componentsGradient(context, isDark),
76
- onOpen: () {
77
- KasyHaptics.medium(context);
78
- context.push('/components');
79
- },
80
- );
81
- if (isWide) {
82
- return Row(
83
- crossAxisAlignment: CrossAxisAlignment.start,
84
- children: [
85
- Expanded(child: featuresCard),
86
- const SizedBox(width: KasySpacing.md),
87
- Expanded(child: componentsCard),
88
- ],
89
- );
90
- }
91
- return Column(
92
- children: [
93
- featuresCard,
94
- const SizedBox(height: KasySpacing.md),
95
- componentsCard,
96
- ],
97
- );
98
- },
99
- ),
100
- const SizedBox(height: KasySpacing.xl),
101
- ]),
102
- ),
103
- ),
104
- ],
39
+ child: const HomeFeed(),
40
+ ),
105
41
  ),
106
42
  Positioned(
107
43
  top: 0,
@@ -121,179 +57,4 @@ class HomePage extends ConsumerWidget {
121
57
  ),
122
58
  );
123
59
  }
124
-
125
- /// Soft product-style gradients (calm blues / lilac); same geometry, distinct hue.
126
- static LinearGradient _componentsGradient(BuildContext context, bool isDark) {
127
- if (isDark) {
128
- return LinearGradient(
129
- begin: Alignment.topLeft,
130
- end: Alignment.bottomRight,
131
- colors: [
132
- context.colors.primary.withValues(alpha: 0.32),
133
- const Color(0xFF2D3A4D).withValues(alpha: 0.92),
134
- const Color(0xFF353D52).withValues(alpha: 0.88),
135
- ],
136
- );
137
- }
138
- return const LinearGradient(
139
- begin: Alignment.topLeft,
140
- end: Alignment.bottomRight,
141
- colors: [Color(0xFFDCE6FF), Color(0xFFF0F6FF), Color(0xFFE2E8F6)],
142
- );
143
- }
144
-
145
- static LinearGradient _featuresGradient(BuildContext context, bool isDark) {
146
- if (isDark) {
147
- return LinearGradient(
148
- begin: Alignment.topLeft,
149
- end: Alignment.bottomRight,
150
- colors: [
151
- const Color(0xFF4A3D6B).withValues(alpha: 0.94),
152
- const Color(0xFF4F3D58).withValues(alpha: 0.9),
153
- context.colors.primary.withValues(alpha: 0.22),
154
- ],
155
- );
156
- }
157
- return const LinearGradient(
158
- begin: Alignment.topLeft,
159
- end: Alignment.bottomRight,
160
- colors: [Color(0xFFE2D8FC), Color(0xFFF5ECFA), Color(0xFFDCE8FF)],
161
- );
162
- }
163
- }
164
-
165
- class _DashboardGradientCard extends StatelessWidget {
166
- final String countLabel;
167
- final Color countBadgeTextColor;
168
- final String title;
169
- final String subtitle;
170
- final LinearGradient gradient;
171
- final VoidCallback onOpen;
172
-
173
- const _DashboardGradientCard({
174
- required this.countLabel,
175
- required this.countBadgeTextColor,
176
- required this.title,
177
- required this.subtitle,
178
- required this.gradient,
179
- required this.onOpen,
180
- });
181
-
182
- @override
183
- Widget build(BuildContext context) {
184
- final bool isDark = Theme.of(context).brightness == Brightness.dark;
185
- final Color titleColor = isDark ? Colors.white : const Color(0xFF1A1D26);
186
- final Color subtitleColor = titleColor.withValues(alpha: 0.62);
187
- final Color arrowCircleColor = isDark
188
- ? Colors.black.withValues(alpha: 0.38)
189
- : Colors.white.withValues(alpha: 0.82);
190
- final Color arrowIconColor = isDark
191
- ? Colors.white
192
- : const Color(0xFF1A1D26);
193
- final Color countBadgeFill = isDark
194
- ? Colors.white.withValues(alpha: 0.14)
195
- : Colors.white.withValues(alpha: 0.38);
196
- final Color countBadgeBorder = isDark
197
- ? Colors.white.withValues(alpha: 0.24)
198
- : Colors.black.withValues(alpha: 0.06);
199
- final Color countBadgeLabelColor = isDark
200
- ? Colors.white.withValues(alpha: 0.94)
201
- : countBadgeTextColor;
202
- final Color cardOutlineColor = context.colors.outline.withValues(
203
- alpha: isDark ? 0.34 : 0.30,
204
- );
205
- return Material(
206
- color: Colors.transparent,
207
- child: InkWell(
208
- onTap: onOpen,
209
- borderRadius: BorderRadius.circular(28),
210
- child: Ink(
211
- height: 156,
212
- decoration: BoxDecoration(
213
- borderRadius: BorderRadius.circular(28),
214
- gradient: gradient,
215
- border: Border.all(color: cardOutlineColor),
216
- ),
217
- child: Padding(
218
- padding: const EdgeInsets.all(KasySpacing.md + 2),
219
- child: Stack(
220
- children: [
221
- Positioned(
222
- left: 0,
223
- top: 0,
224
- child: DecoratedBox(
225
- decoration: BoxDecoration(
226
- color: countBadgeFill,
227
- borderRadius: BorderRadius.circular(KasyRadius.full),
228
- border: Border.all(color: countBadgeBorder),
229
- ),
230
- child: Padding(
231
- padding: const EdgeInsets.symmetric(
232
- horizontal: 12,
233
- vertical: 6,
234
- ),
235
- child: Text(
236
- countLabel,
237
- style: context.textTheme.labelMedium?.copyWith(
238
- color: countBadgeLabelColor,
239
- fontWeight: FontWeight.w600,
240
- ),
241
- ),
242
- ),
243
- ),
244
- ),
245
- Positioned(
246
- left: 0,
247
- right: 56,
248
- bottom: 0,
249
- child: Column(
250
- crossAxisAlignment: CrossAxisAlignment.start,
251
- mainAxisSize: MainAxisSize.min,
252
- children: [
253
- Text(
254
- title,
255
- style: context.textTheme.headlineSmall?.copyWith(
256
- fontWeight: FontWeight.w800,
257
- color: titleColor,
258
- letterSpacing: -0.3,
259
- ),
260
- ),
261
- const SizedBox(height: 4),
262
- Text(
263
- subtitle,
264
- style: context.textTheme.bodyMedium?.copyWith(
265
- color: subtitleColor,
266
- fontWeight: FontWeight.w400,
267
- ),
268
- ),
269
- ],
270
- ),
271
- ),
272
- Positioned(
273
- right: 0,
274
- bottom: 0,
275
- child: Material(
276
- color: arrowCircleColor,
277
- shape: const CircleBorder(),
278
- child: InkWell(
279
- customBorder: const CircleBorder(),
280
- onTap: onOpen,
281
- child: Padding(
282
- padding: const EdgeInsets.all(12),
283
- child: Icon(
284
- KasyIcons.northEast,
285
- size: 20,
286
- color: arrowIconColor,
287
- ),
288
- ),
289
- ),
290
- ),
291
- ),
292
- ],
293
- ),
294
- ),
295
- ),
296
- ),
297
- );
298
- }
299
60
  }
@@ -1,5 +1,5 @@
1
1
  import 'package:kasy_kit/core/states/translations.dart';
2
- import 'package:kasy_kit/features/local_reminder/repositories/reminder_preferences.dart';
2
+ import 'package:kasy_kit/features/local_reminders/repositories/reminder_preferences.dart';
3
3
  import 'package:kasy_kit/features/notifications/api/local_notifier.dart';
4
4
  import 'package:riverpod_annotation/riverpod_annotation.dart';
5
5
 
@@ -3,8 +3,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
3
3
  import 'package:kasy_kit/components/kasy_app_bar.dart';
4
4
  import 'package:kasy_kit/core/theme/theme.dart';
5
5
  import 'package:kasy_kit/core/widgets/kasy_scroll_behavior.dart';
6
- import 'package:kasy_kit/features/local_reminder/providers/reminder_notifier.dart';
7
- import 'package:kasy_kit/features/local_reminder/repositories/reminder_preferences.dart';
6
+ import 'package:kasy_kit/features/local_reminders/providers/reminder_notifier.dart';
7
+ import 'package:kasy_kit/features/local_reminders/repositories/reminder_preferences.dart';
8
8
  import 'package:kasy_kit/i18n/translations.g.dart';
9
9
 
10
10
  class ReminderPage extends ConsumerWidget {
@@ -8,7 +8,7 @@ import 'package:kasy_kit/core/shared_preferences/shared_preferences.dart';
8
8
  import 'package:kasy_kit/core/states/components/maybeshow_component.dart';
9
9
  import 'package:kasy_kit/core/states/models/event_model.dart';
10
10
  import 'package:kasy_kit/core/states/user_state_notifier.dart';
11
- import 'package:kasy_kit/features/subscription/repositories/subscription_repository.dart';
11
+ import 'package:kasy_kit/features/subscriptions/repositories/subscription_repository.dart';
12
12
  import 'package:kasy_kit/i18n/translations.g.dart';
13
13
  import 'package:permission_handler/permission_handler.dart';
14
14
 
@@ -1,18 +1,20 @@
1
1
  import 'package:flutter/material.dart';
2
2
  import 'package:flutter_riverpod/flutter_riverpod.dart';
3
- import 'package:kasy_kit/components/components.dart';
4
- import 'package:kasy_kit/core/theme/theme.dart';
3
+ import 'package:kasy_kit/core/icons/kasy_icons.dart';
5
4
  import 'package:kasy_kit/features/notifications/api/local_notifier.dart';
5
+ import 'package:kasy_kit/features/notifications/ui/widgets/permission_request_view.dart';
6
6
  import 'package:kasy_kit/i18n/translations.g.dart';
7
7
 
8
8
  typedef FutureCallback = Future<void> Function();
9
9
 
10
- /// A Page to ask the user to accept or refuse a permission before showing the real permission dialog
11
- /// - ex : ask for notification permission. If the user accept, we show the real permission dialog
12
- /// On iOS you can't ask more than once for it
10
+ /// Asks the user to opt in BEFORE showing the real OS notification dialog.
11
+ /// On iOS the OS prompt can only be shown once, so this soft pre‑prompt protects
12
+ /// that single shot: if the user accepts here, we trigger the system dialog.
13
13
  ///
14
- /// TIPS: use this on onboarding to ask for permissions
15
- /// You can also use the same logic to ask for location permission, camera permission, etc.
14
+ /// It is just a thin wrapper over [PermissionRequestView] (the reusable
15
+ /// skeleton) wired to the notification permission. To build the same screen for
16
+ /// location, camera, contacts, … copy this file, swap the icon/copy and call the
17
+ /// matching permission API inside `onAccept`.
16
18
  class RequestNotificationPermission extends ConsumerWidget {
17
19
  final FutureCallback? onAccept;
18
20
  final FutureCallback? onRefuse;
@@ -25,60 +27,22 @@ class RequestNotificationPermission extends ConsumerWidget {
25
27
 
26
28
  @override
27
29
  Widget build(BuildContext context, WidgetRef ref) {
28
- final translations = Translations.of(context) //
29
- .request_notification_permission;
30
- return Padding(
31
- padding: const EdgeInsets.fromLTRB(KasySpacing.lg, KasySpacing.xl, KasySpacing.lg, 0),
32
- child: Column(
33
- crossAxisAlignment: CrossAxisAlignment.stretch,
34
- mainAxisAlignment: MainAxisAlignment.center,
35
- children: [
36
- const Spacer(),
37
- Padding(
38
- padding: const EdgeInsets.only(bottom: KasySpacing.lg),
39
- child: Icon(
40
- KasyIcons.notification,
41
- size: 40,
42
- color: context.colors.primary,
43
- ),
44
- ),
45
- Text(
46
- translations.title,
47
- textAlign: TextAlign.center,
48
- style: context.textTheme.headlineMedium?.copyWith(
49
- fontWeight: FontWeight.bold,
50
- ),
51
- ),
52
- const SizedBox(height: KasySpacing.md),
53
- Text(
54
- translations.description,
55
- textAlign: TextAlign.center,
56
- style: context.textTheme.bodyLarge,
57
- ),
58
- const SizedBox(height: KasySpacing.xl),
59
- const Spacer(),
60
- KasyButton(
61
- label: translations.continue_button,
62
- expand: true,
63
- onPressed: () {
64
- ref.read(notificationsSettingsProvider).askPermission().then(
65
- (accepted) => switch (accepted) {
66
- true => onAccept?.call(),
67
- false => onRefuse?.call(),
68
- },
69
- );
70
- },
71
- ),
72
- const SizedBox(height: KasySpacing.smd),
73
- KasyButton(
74
- label: translations.skip_button,
75
- variant: KasyButtonVariant.soft,
76
- expand: true,
77
- onPressed: () => onRefuse?.call(),
78
- ),
79
- const SizedBox(height: KasySpacing.md),
80
- ],
81
- ),
30
+ final translations = Translations.of(context).request_notification_permission;
31
+ return PermissionRequestView(
32
+ icon: KasyIcons.notification,
33
+ title: translations.title,
34
+ description: translations.description,
35
+ acceptLabel: translations.continue_button,
36
+ skipLabel: translations.skip_button,
37
+ onAccept: () {
38
+ ref.read(notificationsSettingsProvider).askPermission().then(
39
+ (accepted) => switch (accepted) {
40
+ true => onAccept?.call(),
41
+ false => onRefuse?.call(),
42
+ },
43
+ );
44
+ },
45
+ onSkip: () => onRefuse?.call(),
82
46
  );
83
47
  }
84
48
  }
@@ -0,0 +1,117 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'package:kasy_kit/components/components.dart';
3
+ import 'package:kasy_kit/core/animations/movefade_anim.dart';
4
+ import 'package:kasy_kit/core/theme/theme.dart';
5
+ import 'package:kasy_kit/core/widgets/kasy_brand_badge.dart';
6
+
7
+ /// Reusable "ask before the OS dialog" permission screen.
8
+ ///
9
+ /// This is the painted skeleton: a brand badge (or your own [illustration]) over
10
+ /// a title, a description and two actions (accept / skip). Drop it into any page
11
+ /// or sheet and feed it copy + callbacks. The OS permission call itself lives in
12
+ /// [onAccept] so this widget stays UI‑only and reusable for ANY permission.
13
+ ///
14
+ /// Example — a camera permission screen in ~10 lines:
15
+ /// ```dart
16
+ /// PermissionRequestView(
17
+ /// icon: KasyIcons.camera,
18
+ /// title: 'Enable the camera?',
19
+ /// description: 'Scan documents and snap photos right inside the app.',
20
+ /// acceptLabel: 'Allow camera',
21
+ /// skipLabel: 'Not now',
22
+ /// onAccept: () => askCameraPermission(),
23
+ /// onSkip: () => Navigator.of(context).pop(),
24
+ /// );
25
+ /// ```
26
+ class PermissionRequestView extends StatelessWidget {
27
+ const PermissionRequestView({
28
+ super.key,
29
+ this.icon,
30
+ this.illustration,
31
+ required this.title,
32
+ required this.description,
33
+ required this.acceptLabel,
34
+ required this.skipLabel,
35
+ required this.onAccept,
36
+ this.onSkip,
37
+ }) : assert(
38
+ icon != null || illustration != null,
39
+ 'PermissionRequestView needs an icon or an illustration',
40
+ );
41
+
42
+ /// Icon shown in the brand badge. Ignored when [illustration] is set.
43
+ final IconData? icon;
44
+
45
+ /// Custom hero (e.g. a module mockup). Overrides the badge when provided.
46
+ final Widget? illustration;
47
+
48
+ final String title;
49
+ final String description;
50
+
51
+ /// Primary action label. Trigger the real OS permission request in [onAccept].
52
+ final String acceptLabel;
53
+
54
+ /// Secondary ("maybe later") action label.
55
+ final String skipLabel;
56
+
57
+ final VoidCallback onAccept;
58
+ final VoidCallback? onSkip;
59
+
60
+ @override
61
+ Widget build(BuildContext context) {
62
+ return SafeArea(
63
+ child: Padding(
64
+ padding: const EdgeInsets.fromLTRB(
65
+ KasySpacing.lg,
66
+ KasySpacing.xl,
67
+ KasySpacing.lg,
68
+ KasySpacing.lg,
69
+ ),
70
+ child: Column(
71
+ crossAxisAlignment: CrossAxisAlignment.stretch,
72
+ children: [
73
+ const Spacer(),
74
+ MoveFadeAnim(
75
+ delayInMs: 40,
76
+ child: Center(
77
+ child:
78
+ illustration ??
79
+ KasyBrandBadge(icon: icon, size: 76, glyphSize: 36),
80
+ ),
81
+ ),
82
+ const SizedBox(height: KasySpacing.xl),
83
+ Text(
84
+ title,
85
+ textAlign: TextAlign.center,
86
+ style: context.textTheme.headlineMedium?.copyWith(
87
+ fontWeight: FontWeight.w700,
88
+ ),
89
+ ),
90
+ const SizedBox(height: KasySpacing.smd),
91
+ Text(
92
+ description,
93
+ textAlign: TextAlign.center,
94
+ style: context.textTheme.bodyLarge?.copyWith(
95
+ color: context.colors.muted,
96
+ height: 1.45,
97
+ ),
98
+ ),
99
+ const Spacer(),
100
+ KasyButton(
101
+ label: acceptLabel,
102
+ expand: true,
103
+ onPressed: onAccept,
104
+ ),
105
+ const SizedBox(height: KasySpacing.smd),
106
+ KasyButton(
107
+ label: skipLabel,
108
+ variant: KasyButtonVariant.soft,
109
+ expand: true,
110
+ onPressed: onSkip,
111
+ ),
112
+ ],
113
+ ),
114
+ ),
115
+ );
116
+ }
117
+ }
@@ -1,11 +1,11 @@
1
1
  import 'package:kasy_kit/features/onboarding/api/entities/user_info_entity.dart';
2
2
 
3
3
  enum UserInfoKeys {
4
- genre,
4
+ gender,
5
5
  age,
6
6
  }
7
7
 
8
- enum Genre {
8
+ enum Gender {
9
9
  male,
10
10
  female,
11
11
  none,
@@ -44,11 +44,11 @@ class UserAgeInfo extends UserInfoDetail<AgeRange> {
44
44
  }
45
45
 
46
46
  factory UserAgeInfo.fromString(String value) {
47
- final sexe = AgeRange.values.firstWhere(
47
+ final range = AgeRange.values.firstWhere(
48
48
  (element) => element.name == value,
49
49
  orElse: () => AgeRange.none,
50
50
  );
51
- return UserAgeInfo(sexe);
51
+ return UserAgeInfo(range);
52
52
  }
53
53
 
54
54
  @override
@@ -61,30 +61,30 @@ class UserAgeInfo extends UserInfoDetail<AgeRange> {
61
61
  }
62
62
 
63
63
  /// ======================================
64
- /// user genre info
64
+ /// user gender info
65
65
  /// ======================================
66
- class UserSexeInfo extends UserInfoDetail<Genre> {
67
- UserSexeInfo(super.value);
66
+ class UserGenderInfo extends UserInfoDetail<Gender> {
67
+ UserGenderInfo(super.value);
68
68
 
69
- factory UserSexeInfo.fromEntity(UserInfoEntity entity) {
70
- final value = Genre.values.firstWhere(
69
+ factory UserGenderInfo.fromEntity(UserInfoEntity entity) {
70
+ final value = Gender.values.firstWhere(
71
71
  (element) => element.name == entity.value,
72
- orElse: () => Genre.none,
72
+ orElse: () => Gender.none,
73
73
  );
74
- return UserSexeInfo(value);
74
+ return UserGenderInfo(value);
75
75
  }
76
76
 
77
- factory UserSexeInfo.fromString(String value) {
78
- final genre = Genre.values.firstWhere(
77
+ factory UserGenderInfo.fromString(String value) {
78
+ final gender = Gender.values.firstWhere(
79
79
  (element) => element.name == value,
80
- orElse: () => Genre.none,
80
+ orElse: () => Gender.none,
81
81
  );
82
- return UserSexeInfo(genre);
82
+ return UserGenderInfo(gender);
83
83
  }
84
84
 
85
85
  @override
86
86
  UserInfoEntity toEntity() => UserInfoEntity(
87
- key: UserInfoKeys.genre.name,
87
+ key: UserInfoKeys.gender.name,
88
88
  value: value.name,
89
89
  );
90
90
 
@@ -6,7 +6,8 @@ import 'package:kasy_kit/core/data/api/tracking_api.dart';
6
6
  import 'package:kasy_kit/core/states/user_state_notifier.dart';
7
7
  import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_background.dart';
8
8
  import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart';
9
- import 'package:kasy_kit/features/subscription/repositories/subscription_repository.dart';
9
+ import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_module_mockups.dart';
10
+ import 'package:kasy_kit/features/subscriptions/repositories/subscription_repository.dart';
10
11
  import 'package:kasy_kit/i18n/translations.g.dart';
11
12
  import 'package:permission_handler/permission_handler.dart';
12
13
 
@@ -29,10 +30,10 @@ class AttPermissionStep extends ConsumerWidget {
29
30
 
30
31
  return OnboardingBackground(
31
32
  child: OnboardingIllustrationScaffold(
32
- progress: 0.9,
33
+ step: 6,
33
34
  title: translations.title,
34
35
  description: translations.description,
35
- imageAsset: 'assets/images/onboarding/img3.jpg',
36
+ image: const TrackingPermissionMockup(),
36
37
  footerActions: [
37
38
  KasyButton(
38
39
  label: translations.continue_button,