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,4 +1,83 @@
1
1
  {
2
+ "admin_console": {
3
+ "tabs": {
4
+ "overview": "Visão geral",
5
+ "users": "Usuários",
6
+ "requests": "Solicitações",
7
+ "kit": "Kit",
8
+ "tools": "Ferramentas"
9
+ },
10
+ "overview": {
11
+ "section": "Projeto",
12
+ "backend": "Backend",
13
+ "account": "Conta",
14
+ "guest": "Visitante",
15
+ "user_id": "ID do usuário",
16
+ "build": "Versão",
17
+ "session_title": "Sessão atual",
18
+ "requests_metric": "Solicitações de recurso",
19
+ "users_hint": "Abra a aba Usuários para gerenciar todas as contas.",
20
+ "debug_note": "Console de debug — visível só em builds de desenvolvimento."
21
+ },
22
+ "users": {
23
+ "title": "Usuários",
24
+ "search_hint": "Buscar por nome ou e-mail",
25
+ "col_user": "Usuário",
26
+ "col_status": "Status",
27
+ "col_plan": "Plano",
28
+ "col_joined": "Cadastro",
29
+ "status_active": "Ativo",
30
+ "status_inactive": "Inativo",
31
+ "plan_subscriber": "Assinante",
32
+ "plan_free": "Grátis",
33
+ "empty": "Nenhum usuário encontrado",
34
+ "error": "Não foi possível carregar os usuários. Confirme que você é admin.",
35
+ "page": "Página $page de $total",
36
+ "prev": "Anterior",
37
+ "next": "Próxima",
38
+ "anonymous": "Anônimo",
39
+ "filter_all": "Todos os usuários",
40
+ "filter_subscribers": "Assinantes",
41
+ "loading": "Carregando usuários…",
42
+ "results": "Mostrando $from a $to de $total",
43
+ "truncated": "Mostrando os $count mais recentes. A busca cobre só os carregados.",
44
+ "empty_search": "Nenhum usuário corresponde à busca",
45
+ "empty_search_hint": "Tente outro nome ou e-mail.",
46
+ "refresh": "Atualizar",
47
+ "retry": "Tentar de novo"
48
+ },
49
+ "requests": {
50
+ "title": "Solicitações de recurso",
51
+ "empty": "Ainda não há solicitações",
52
+ "votes": "$count votos",
53
+ "visible": "Visível",
54
+ "hidden": "Oculto",
55
+ "edit": "Editar traduções",
56
+ "error": "Não foi possível carregar as solicitações",
57
+ "saved": "Solicitação atualizada",
58
+ "editor_title": "Editar solicitação",
59
+ "field_title": "Título",
60
+ "field_description": "Descrição",
61
+ "lang_en": "Inglês",
62
+ "lang_pt": "Português",
63
+ "lang_es": "Espanhol",
64
+ "visibility": "Visível para os usuários",
65
+ "save": "Salvar",
66
+ "cancel": "Cancelar"
67
+ },
68
+ "groups": {
69
+ "features": "Recursos",
70
+ "showcase": "Vitrine",
71
+ "preview": "Preview",
72
+ "debug_actions": "Ações de debug",
73
+ "identity": "Identidade"
74
+ },
75
+ "settings_entry": {
76
+ "title": "Admin",
77
+ "caption": "Visível só para administradores e em modo de desenvolvimento."
78
+ },
79
+ "requires_admin": "Você precisa ser admin para ver isto."
80
+ },
2
81
  "home": {
3
82
  "title": "Exemplo Kasy",
4
83
  "welcome": "Bem-vindo ao demo do Kasy",
@@ -12,7 +91,7 @@
12
91
  "signup_title": "Cadastro",
13
92
  "signup_description": "Usuário anônimo pode se cadastrar com e-mail ou rede social",
14
93
  "assistant_title": "Assistente IA",
15
- "assistant_description": "Abrir a página de modelo de chat com IA"
94
+ "assistant_description": "Conversar com o assistente de IA"
16
95
  },
17
96
  "features_page": {
18
97
  "title": "Recursos do kit",
@@ -78,8 +157,11 @@
78
157
  },
79
158
  "recover": {
80
159
  "title": "Recuperar senha",
160
+ "subtitle": "Digite seu e-mail e enviaremos um link para criar uma nova senha.",
81
161
  "email_label": "E-mail",
82
162
  "submit": "Recuperar senha",
163
+ "remember": "Lembrou sua senha?",
164
+ "signin_link": "Entrar",
83
165
  "error_title": "Erro",
84
166
  "error_text": "Informe um e-mail válido"
85
167
  }
@@ -148,6 +230,9 @@
148
230
  "unsubscribe_feedback_min_chars": "Mínimo de 6 caracteres necessários",
149
231
  "unsubscribe_confirm_button": "Prosseguir",
150
232
  "lifetime_user_description": "Você é um usuário vitalício",
233
+ "managed_elsewhere_title": "Assinatura em outra plataforma",
234
+ "managed_elsewhere_description": "Esta assinatura foi feita em outra plataforma e não pode ser gerenciada ou cancelada por aqui. Acesse a conta na plataforma onde você fez a compra.",
235
+ "restore_button": "Restaurar compras",
151
236
  "cancel_button": "Fechar"
152
237
  },
153
238
  "paywallWithSwitch": {
@@ -172,58 +257,89 @@
172
257
  },
173
258
  "onboarding": {
174
259
  "feature_1": {
175
- "title": "Módulo de assinaturas",
176
- "description": "Gerencie assinaturas com paywalls prontos para usar",
260
+ "title": "Fature desde o dia um",
261
+ "description": "Paywalls, assinaturas e período de teste prontos para produção. Sem montar backend de cobrança.",
177
262
  "action": "Continuar",
178
263
  "skip": "Pular",
179
264
  "login": "Já tem conta? Entrar"
180
265
  },
181
266
  "feature_2": {
182
- "title": "Módulo de autenticação",
183
- "description": "Gerencie a autenticação com telas prontas (login, cadastro, esqueci a senha, etc.)",
267
+ "title": "Login pronto para produção",
268
+ "description": "E-mail, login social e recuperação de senha. Seguro e pronto para publicar.",
184
269
  "action": "Continuar"
185
270
  },
186
271
  "feature_3": {
187
- "title": "Módulo de notificações",
188
- "description": "Receba notificações push, mostre notificações no app, gerencie permissões, lista de notificações com status...",
272
+ "title": "Traga seus usuários de volta",
273
+ "description": "Push, avisos no app e permissões integrados para engajar e reter.",
189
274
  "action": "Continuar"
190
275
  },
276
+ "mockups": {
277
+ "paywall": {
278
+ "title": "Premium",
279
+ "annual": "Anual",
280
+ "monthly": "Mensal",
281
+ "save_badge": "-40%",
282
+ "price_year": "R$ 39,99 / ano",
283
+ "price_month": "R$ 4,99 / mês",
284
+ "cta": "Iniciar teste grátis"
285
+ },
286
+ "auth": {
287
+ "welcome": "Bem-vindo de volta",
288
+ "email_hint": "voce@email.com",
289
+ "sign_in": "Entrar",
290
+ "divider": "ou"
291
+ },
292
+ "notification": {
293
+ "title": "Nova mensagem",
294
+ "time": "agora"
295
+ },
296
+ "push_permission": {
297
+ "title": "Ativar notificações?",
298
+ "allow": "Permitir",
299
+ "deny": "Agora não"
300
+ },
301
+ "tracking_permission": {
302
+ "title": "Permitir rastreamento?",
303
+ "allow": "Permitir",
304
+ "deny": "Pedir para não rastrear"
305
+ }
306
+ },
191
307
  "ageQuestion": {
192
- "title": "Qual é a sua idade?",
193
- "description": "Isso nos ajuda a personalizar sua experiência no app.",
308
+ "title": "Qual a sua idade?",
309
+ "description": "Isso nos ajuda a personalizar a sua experiência.",
194
310
  "options(map)": {
195
- "age18_30": "[18 - 30] anos",
196
- "age31_40": "[31 - 40] anos",
197
- "age41_50": "[41 - 50] anos",
198
- "age51_60": "50 anos ou mais",
199
- "none": "Prefiro não responder"
311
+ "age18_30": "18 a 30 anos",
312
+ "age31_40": "31 a 40 anos",
313
+ "age41_50": "41 a 50 anos",
314
+ "age51_60": "Mais de 50 anos",
315
+ "none": "Prefiro não dizer"
200
316
  },
201
317
  "action": "Continuar"
202
318
  },
203
319
  "genderQuestion": {
204
- "title": "Qual é o seu gênero?",
205
- "description": "Escolha a opção que melhor representa você. Você pode pular se preferir.",
320
+ "title": "Como você se identifica?",
321
+ "description": "Escolha o que combina com você. Pode pular se preferir.",
206
322
  "options(map)": {
207
323
  "male": "Masculino",
208
324
  "female": "Feminino",
209
- "none": "Prefiro não responder"
325
+ "none": "Prefiro não dizer"
210
326
  },
211
327
  "action": "Continuar"
212
328
  },
213
329
  "notifications": {
214
- "title": "Permitir notificações",
215
- "description": "Enviaremos apenas notificações importantes",
216
- "continue_button": "Permitir notificações",
217
- "skip_button": "Talvez mais tarde"
330
+ "title": "Fique por dentro",
331
+ "description": " falamos com você quando realmente importa. Nada de spam.",
332
+ "continue_button": "Ativar notificações",
333
+ "skip_button": "Agora não"
218
334
  },
219
335
  "att": {
220
- "title": "Transparência de Rastreamento de Apps",
221
- "description": "Precisamos disso apenas para melhorar nossas campanhas de anúncios",
336
+ "title": "Você no controle",
337
+ "description": "Permita o rastreamento para anúncios mais relevantes. A escolha é sempre sua.",
222
338
  "continue_button": "Continuar"
223
339
  },
224
340
  "loading": {
225
- "title": "Criando seu perfil",
226
- "subtitle": "Aguarde alguns segundos"
341
+ "title": "Preparando tudo para você",
342
+ "subtitle": "Leva um instante"
227
343
  }
228
344
  },
229
345
  "feature_requests": {
@@ -289,13 +405,10 @@
289
405
  },
290
406
  "navigation": {
291
407
  "home": "Início",
292
- "wishlist": "Desejos",
408
+ "support": "Suporte",
293
409
  "notifications": "Notificações",
294
- "settings": "Config."
295
- },
296
- "wishlist": {
297
- "empty_title": "Nada por aqui ainda",
298
- "empty_subtitle": "Salve seus favoritos para encontrá-los aqui"
410
+ "settings": "Config.",
411
+ "logout": "Sair"
299
412
  },
300
413
  "reminderPage": {
301
414
  "title": "Lembretes",
@@ -368,10 +481,11 @@
368
481
  "premium": "Premium",
369
482
  "privacy": "Política de privacidade",
370
483
  "support": "Suporte",
371
- "disconnect": "Desconectar",
372
- "disconnect_confirm_title": "Sair",
484
+ "disconnect": "Sim, sair",
485
+ "disconnect_confirm_title": "Sair da conta?",
373
486
  "disconnect_confirm_message": "Tem certeza que deseja sair?",
374
487
  "disconnect_cancel": "Cancelar",
488
+ "logout": "Sair",
375
489
  "my_account": "Minha conta",
376
490
  "not_signed_in": "Não conectado",
377
491
  "register": "Cadastrar",
@@ -381,8 +495,8 @@
381
495
  "admin_panel_debug_notice": "Toda esta seção Admin (título, painel e opções) só existe em build de debug. Em release esse bloco não é incluído; quem instala pela loja ou por APK de produção não vê nada disso.",
382
496
  "delete_account": {
383
497
  "button": "Quero excluir minha conta",
384
- "title": "Excluir minha conta?",
385
- "content": "Atenção: esta ação é irreversível",
498
+ "title": "Quer excluir sua conta?",
499
+ "content": "Atenção: esta ação é irreversível.",
386
500
  "cancel": "Cancelar",
387
501
  "confirm": "Sim, excluir"
388
502
  },
@@ -421,6 +535,10 @@
421
535
  "send_push_no_emails": "Adicione pelo menos um e-mail",
422
536
  "send_push_route_label": "Rota ao abrir (opcional)",
423
537
  "send_push_route_hint": "Ex: /premium, /notifications",
538
+ "send_push_preview_label": "Prévia",
539
+ "send_push_preview_now": "agora",
540
+ "send_push_preview_title_placeholder": "Título da notificação",
541
+ "send_push_preview_body_placeholder": "O corpo da mensagem aparece aqui",
424
542
  "device_preview_title": "Device Preview (somente web)"
425
543
  }
426
544
  },
@@ -448,7 +566,7 @@
448
566
  "delete_all": "Excluir tudo",
449
567
  "delete_all_confirm_title": "Excluir todas as notificações?",
450
568
  "delete_all_confirm_message": "Isso vai remover todas as notificações da sua conta. Essa ação não pode ser desfeita.",
451
- "delete_action": "Excluir",
569
+ "delete_action": "Sim, excluir",
452
570
  "cancel_action": "Cancelar",
453
571
  "deleted_one": "Notificação excluída",
454
572
  "deleted_all": "Todas as notificações foram excluídas"
@@ -456,13 +574,20 @@
456
574
  "bottom_router": {
457
575
  "fake_page_text": "Esta é uma página de exemplo"
458
576
  },
459
- "llm_chat": {
460
- "title": "Modelo de Chat IA",
577
+ "ai_chat": {
578
+ "title": "Assistente IA",
461
579
  "empty_state": "Inicie uma conversa com seu assistente.",
462
580
  "hint": "Pergunte algo...",
463
- "error_not_configured": "Endpoint de LLM não configurado. Use --dart-define=LLM_CHAT_ENDPOINT=...",
464
- "error_no_reply": "Nenhum campo de resposta encontrado na API.",
465
- "error_network": "Não foi possível conectar ao assistente de IA."
581
+ "error_not_configured": "O assistente ainda não está disponível. Tente novamente mais tarde.",
582
+ "error_no_reply": "Não conseguimos obter uma resposta. Tente de novo.",
583
+ "error_network": "Não foi possível conectar ao assistente de IA.",
584
+ "new_conversation": "Nova conversa",
585
+ "conversations_empty": "Nenhuma conversa ainda",
586
+ "no_conversation_selected": "Escolha uma conversa ou comece uma nova.",
587
+ "delete_title": "Excluir conversa?",
588
+ "delete_message": "Esta conversa e todas as mensagens serão excluídas permanentemente.",
589
+ "delete_cancel": "Cancelar",
590
+ "delete_confirm": "Sim, excluir"
466
591
  },
467
592
  "phone_auth": {
468
593
  "title_input": "Autenticação por Telefone",
@@ -20,12 +20,13 @@ import 'package:kasy_kit/core/shared_preferences/shared_preferences.dart';
20
20
  import 'package:kasy_kit/core/states/user_state_notifier.dart';
21
21
  import 'package:kasy_kit/core/theme/theme.dart';
22
22
  import 'package:kasy_kit/core/web_device_preview/web_device_preview.dart';
23
- import 'package:kasy_kit/environnements.dart';
23
+ import 'package:kasy_kit/core/web_viewport_scale.dart';
24
+ import 'package:kasy_kit/environments.dart';
24
25
  import 'package:kasy_kit/features/authentication/api/authentication_api.dart';
25
26
  import 'package:kasy_kit/features/notifications/api/local_notifier.dart';
26
27
  import 'package:kasy_kit/features/notifications/repositories/background_notification_handler.dart';
27
28
  import 'package:kasy_kit/features/notifications/repositories/notifications_repository.dart';
28
- import 'package:kasy_kit/features/subscription/repositories/subscription_repository.dart';
29
+ import 'package:kasy_kit/features/subscriptions/repositories/subscription_repository.dart';
29
30
  import 'package:kasy_kit/firebase_options_dev.dart' as firebase_dev;
30
31
  import 'package:kasy_kit/i18n/translations.g.dart';
31
32
  import 'package:kasy_kit/router.dart';
@@ -188,7 +189,9 @@ class _MyAppState extends ConsumerState<MyApp> {
188
189
  analyticsApiProvider,
189
190
  facebookEventApiProvider,
190
191
  ],
191
- onReady: DevicePreview.appBuilder(context, child),
192
+ onReady: WebViewportScale.wrap(
193
+ DevicePreview.appBuilder(context, child),
194
+ ),
192
195
  onError: (_, error) => InitializationErrorPage(error: error),
193
196
  onLoading: Scaffold(
194
197
  body: Center(
@@ -19,16 +19,15 @@ import 'package:kasy_kit/features/home/design_system_page.dart';
19
19
  import 'package:kasy_kit/features/home/home_components_page.dart';
20
20
  import 'package:kasy_kit/features/home/home_components_preview_page.dart';
21
21
  import 'package:kasy_kit/features/home/home_components_preview_registry.dart';
22
- import 'package:kasy_kit/features/home/home_features_page.dart';
23
- import 'package:kasy_kit/features/llm_chat/llm_chat_page.dart';
24
- import 'package:kasy_kit/features/local_reminder/ui/reminder_page.dart';
22
+ import 'package:kasy_kit/features/local_reminders/ui/reminder_page.dart';
25
23
  import 'package:kasy_kit/features/onboarding/ui/onboarding_page.dart';
26
24
  import 'package:kasy_kit/features/settings/ui/components/admin/admin_home_widgets.dart';
25
+ import 'package:kasy_kit/features/settings/ui/components/admin/admin_page.dart';
27
26
  import 'package:kasy_kit/features/settings/ui/components/admin/admin_paywalls.dart';
28
27
  import 'package:kasy_kit/features/settings/ui/components/admin/admin_routes.dart';
29
28
  import 'package:kasy_kit/features/settings/ui/components/admin/send_push_notification_page.dart';
30
- import 'package:kasy_kit/features/subscription/ui/component/premium_page_factory.dart';
31
- import 'package:kasy_kit/features/subscription/ui/premium_page.dart';
29
+ import 'package:kasy_kit/features/subscriptions/ui/component/premium_page_factory.dart';
30
+ import 'package:kasy_kit/features/subscriptions/ui/premium_page.dart';
32
31
  import 'package:logger/logger.dart';
33
32
 
34
33
  final goRouterProvider = Provider<GoRouter>((ref) => generateRouter());
@@ -82,14 +81,6 @@ GoRouter generateRouter({
82
81
  // '/', not children of the BottomMenu shell), so go_router renders them on
83
82
  // the root navigator: full-screen, above the bottom bar, URL-addressable.
84
83
  // Returning pops back to the tab with its menu intact.
85
- GoRoute(
86
- name: 'features',
87
- path: '/features',
88
- pageBuilder: (context, state) => kasyTransitionPage(
89
- key: state.pageKey,
90
- child: const HomeFeaturesPage(),
91
- ),
92
- ),
93
84
  GoRoute(
94
85
  name: 'design_system',
95
86
  path: '/design-system',
@@ -185,16 +176,7 @@ GoRouter generateRouter({
185
176
  child: const FeedbackPage(),
186
177
  ),
187
178
  ),
188
- if (withLlmChat)
189
- GoRoute(
190
- name: 'assistant',
191
- path: '/assistant',
192
- pageBuilder: (context, state) => kasyTransitionPage(
193
- key: state.pageKey,
194
- child: const LlmChatPage(),
195
- ),
196
- ),
197
- if (withLocalNotifications)
179
+ if (withLocalReminders)
198
180
  GoRoute(
199
181
  name: 'reminder',
200
182
  path: '/reminder',
@@ -233,6 +215,16 @@ GoRouter generateRouter({
233
215
  child: const RecoverPasswordPage(),
234
216
  ),
235
217
  ),
218
+ // Admin console: registered always so administrators reach it in release
219
+ // builds too. Access is gated inside AdminPage (admin role || debug).
220
+ GoRoute(
221
+ name: 'admin',
222
+ path: '/admin',
223
+ pageBuilder: (context, state) => kasyTransitionPage(
224
+ key: state.pageKey,
225
+ child: const AdminPage(),
226
+ ),
227
+ ),
236
228
  if (kDebugMode) ...[
237
229
  GoRoute(
238
230
  name: 'admin_paywalls',
@@ -124,7 +124,6 @@ flutter:
124
124
  assets:
125
125
  - .env
126
126
  - assets/images/
127
- - assets/images/onboarding/
128
127
  - assets/icons/
129
128
  flutter_launcher_icons:
130
129
  image_path: assets/images/icon.png
@@ -141,16 +140,16 @@ flutter_launcher_icons:
141
140
  flutter_native_splash:
142
141
  # Match KasyColors.background (light / dark) so the splash → app transition
143
142
  # has zero white/black flash on web, iOS and Android.
144
- color: "#F7F7F7"
145
- color_dark: "#060608"
143
+ color: "#FAF9FC"
144
+ color_dark: "#0C0A14"
146
145
  fullscreen: true
147
146
  ios: true
148
147
  android: true
149
148
  image: assets/images/splash_logo_light.png
150
149
  image_dark: assets/images/splash_logo_dark.png
151
150
  android_12:
152
- color: "#F7F7F7"
153
- color_dark: "#060608"
151
+ color: "#FAF9FC"
152
+ color_dark: "#0C0A14"
154
153
  image: assets/images/splash_logo_light_android12.png
155
154
  image_dark: assets/images/splash_logo_dark_android12.png
156
155
 
@@ -2,12 +2,12 @@ import 'package:flutter/services.dart';
2
2
  import 'package:flutter_test/flutter_test.dart';
3
3
  import 'package:kasy_kit/core/data/entities/upload_result.dart';
4
4
  import 'package:kasy_kit/core/data/repositories/user_repository.dart';
5
- import 'package:kasy_kit/features/subscription/repositories/subscription_repository.dart';
5
+ import 'package:kasy_kit/features/subscriptions/repositories/subscription_repository.dart';
6
6
  import 'package:shared_preferences/shared_preferences.dart';
7
7
 
8
8
  import '../../../features/authentication/data/api/user_api_fake.dart';
9
- import '../../../features/subscription/api/fake_inapp_subscription_api.dart';
10
- import '../../../features/subscription/api/fake_subscription_api.dart';
9
+ import '../../../features/subscriptions/api/fake_inapp_subscription_api.dart';
10
+ import '../../../features/subscriptions/api/fake_subscription_api.dart';
11
11
  import '../api/storage_api_fake.dart';
12
12
 
13
13
  void main() {
@@ -4,18 +4,18 @@ import 'package:kasy_kit/core/data/api/http_client.dart';
4
4
  import 'package:kasy_kit/core/data/models/user.dart';
5
5
  import 'package:kasy_kit/core/data/repositories/user_repository.dart';
6
6
  import 'package:kasy_kit/core/states/user_state_notifier.dart';
7
- import 'package:kasy_kit/environnements.dart';
7
+ import 'package:kasy_kit/environments.dart';
8
8
  import 'package:kasy_kit/features/authentication/repositories/authentication_repository.dart';
9
9
  import 'package:kasy_kit/features/notifications/repositories/device_repository.dart';
10
- import 'package:kasy_kit/features/subscription/repositories/subscription_repository.dart';
10
+ import 'package:kasy_kit/features/subscriptions/repositories/subscription_repository.dart';
11
11
  import 'package:logger/logger.dart';
12
12
  import 'package:shared_preferences/shared_preferences.dart';
13
13
 
14
14
  import '../../features/authentication/data/api/auth_api_fake.dart';
15
15
  import '../../features/authentication/data/api/user_api_fake.dart';
16
16
  import '../../features/notifications/data/device_api_fake.dart';
17
- import '../../features/subscription/api/fake_inapp_subscription_api.dart';
18
- import '../../features/subscription/api/fake_subscription_api.dart';
17
+ import '../../features/subscriptions/api/fake_inapp_subscription_api.dart';
18
+ import '../../features/subscriptions/api/fake_subscription_api.dart';
19
19
  import '../data/api/storage_api_fake.dart';
20
20
  import '../security/secured_storage_fake.dart';
21
21
 
@@ -0,0 +1,55 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'package:flutter_test/flutter_test.dart';
3
+ import 'package:kasy_kit/components/components.dart';
4
+ import 'package:kasy_kit/core/icons/kasy_icons.dart';
5
+ import 'package:kasy_kit/core/theme/colors.dart';
6
+ import 'package:kasy_kit/core/theme/texts.dart';
7
+ import 'package:kasy_kit/core/widgets/kasy_focus_ring.dart';
8
+
9
+ void main() {
10
+ // The keyboard focus ring must hug the round orb (a square box), not the
11
+ // taller tap target the pressable stretches to — otherwise it draws an oval
12
+ // around the circular send button. Regression guard for that.
13
+ testWidgets('icon-only button focus ring stays square', (tester) async {
14
+ await tester.pumpWidget(
15
+ MaterialApp(
16
+ theme: ThemeData(
17
+ extensions: <ThemeExtension<dynamic>>[
18
+ KasyColors.light(),
19
+ KasyTextTheme.build(),
20
+ ],
21
+ ),
22
+ home: Scaffold(
23
+ body: Center(
24
+ child: Row(
25
+ mainAxisSize: MainAxisSize.min,
26
+ crossAxisAlignment: CrossAxisAlignment.end,
27
+ children: [
28
+ // A taller neighbour forces the row taller than the orb, which
29
+ // is exactly what made the ring stretch into an oval.
30
+ const Expanded(child: SizedBox(height: 80)),
31
+ Padding(
32
+ padding: const EdgeInsets.only(bottom: 2),
33
+ child: KasyButton.iconOnly(
34
+ icon: KasyIcons.arrowUp,
35
+ onPressed: () {},
36
+ size: KasyButtonSize.small,
37
+ iconOnlyLayoutExtent: 36,
38
+ iconGlyphSize: 18,
39
+ semanticLabel: 'send',
40
+ ),
41
+ ),
42
+ ],
43
+ ),
44
+ ),
45
+ ),
46
+ ),
47
+ );
48
+ await tester.pumpAndSettle();
49
+
50
+ final Size ringSize = tester.getSize(find.byType(KasyFocusRing));
51
+ expect(ringSize.width, ringSize.height,
52
+ reason: 'focus ring around a round orb must be square, got $ringSize');
53
+ expect(ringSize.width, 36);
54
+ });
55
+ }
@@ -1,5 +1,7 @@
1
+ import 'package:kasy_kit/core/data/models/entitlement.dart';
1
2
  import 'package:kasy_kit/core/data/models/subscription.dart';
2
- import 'package:kasy_kit/features/subscription/api/inapp_subscription_api.dart';
3
+ import 'package:kasy_kit/features/subscriptions/api/entities/subscription_entity.dart';
4
+ import 'package:kasy_kit/features/subscriptions/api/inapp_subscription_api.dart';
3
5
  import 'package:purchases_flutter/purchases_flutter.dart';
4
6
 
5
7
  import 'fake_revenuecat_product.dart';
@@ -37,7 +39,7 @@ class InAppSubscriptionApiFake implements RevenueCatPaymentApi {
37
39
  }
38
40
 
39
41
  @override
40
- Future<List<EntitlementInfo>> getPermissions() {
42
+ Future<List<Entitlement>> getPermissions() {
41
43
  // TODO: implement getPermissions
42
44
  throw UnimplementedError();
43
45
  }
@@ -60,11 +62,16 @@ class InAppSubscriptionApiFake implements RevenueCatPaymentApi {
60
62
  activeSubscriptions.add(FakeRevenueCatProduct.month());
61
63
  }
62
64
 
65
+ @override
66
+ Future<void> purchaseProduct(SubscriptionProduct product) async {
67
+ activeSubscriptions.add(FakeRevenueCatProduct.month());
68
+ }
69
+
63
70
  @override
64
71
  Future<void> restorePurchase() async {}
65
72
 
66
73
  @override
67
- Future<void> unsubscribe() async {}
74
+ Future<void> unsubscribe(SubscriptionStore? origin) async {}
68
75
 
69
76
  @override
70
77
  Future<SubscriptionProduct?> getFromProductId(String productId) async {
@@ -77,7 +84,7 @@ class InAppSubscriptionApiFake implements RevenueCatPaymentApi {
77
84
  }
78
85
 
79
86
  @override
80
- Future<List<EntitlementInfo>?> getEntitlements() {
87
+ Future<List<Entitlement>?> getEntitlements() {
81
88
  return Future.value([]);
82
89
  }
83
90
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  import 'package:flutter/widgets.dart';
4
4
  import 'package:kasy_kit/core/data/models/subscription.dart';
5
+ import 'package:kasy_kit/features/subscriptions/api/revenuecat_product.dart';
5
6
  import 'package:purchases_flutter/purchases_flutter.dart';
6
7
 
7
8
  /// Fake implementation of [RevenueCatProduct]
@@ -1,5 +1,5 @@
1
- import 'package:kasy_kit/features/subscription/api/entities/subscription_entity.dart';
2
- import 'package:kasy_kit/features/subscription/api/subscription_api.dart';
1
+ import 'package:kasy_kit/features/subscriptions/api/entities/subscription_entity.dart';
2
+ import 'package:kasy_kit/features/subscriptions/api/subscription_api.dart';
3
3
 
4
4
  class SubscriptionApiFake implements SubscriptionApi {
5
5
  SubscriptionEntity? currentFake;
@@ -3,10 +3,10 @@ import 'package:flutter_test/flutter_test.dart';
3
3
  import 'package:kasy_kit/core/data/models/subscription.dart';
4
4
  import 'package:kasy_kit/core/data/models/user.dart';
5
5
  import 'package:kasy_kit/core/states/models/user_state.dart';
6
- import 'package:kasy_kit/features/subscription/ui/component/active_premium_content.dart';
7
- import 'package:kasy_kit/features/subscription/ui/component/premium_content.dart';
8
- import 'package:kasy_kit/features/subscription/ui/component/premium_page_factory.dart';
9
- import 'package:kasy_kit/features/subscription/ui/premium_page.dart';
6
+ import 'package:kasy_kit/features/subscriptions/ui/component/active_premium_content.dart';
7
+ import 'package:kasy_kit/features/subscriptions/ui/component/premium_content.dart';
8
+ import 'package:kasy_kit/features/subscriptions/ui/component/premium_page_factory.dart';
9
+ import 'package:kasy_kit/features/subscriptions/ui/premium_page.dart';
10
10
 
11
11
  import '../../test_utils.dart';
12
12
  import 'api/fake_inapp_subscription_api.dart';