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,8 +1,7 @@
1
1
  import 'package:flutter/material.dart';
2
2
  import 'package:freezed_annotation/freezed_annotation.dart';
3
- import 'package:kasy_kit/features/subscription/api/entities/subscription_entity.dart';
4
- import 'package:kasy_kit/i18n/translations.g.dart';
5
- import 'package:purchases_flutter/purchases_flutter.dart';
3
+ import 'package:kasy_kit/core/data/models/entitlement.dart';
4
+ import 'package:kasy_kit/features/subscriptions/api/entities/subscription_entity.dart';
6
5
 
7
6
  part 'subscription.freezed.dart';
8
7
 
@@ -55,193 +54,14 @@ abstract class SubscriptionProduct {
55
54
  String? pricePerYear(BuildContext context);
56
55
  }
57
56
 
58
- class RevenueCatProduct implements SubscriptionProduct {
59
- final Offering revenueCatOffer;
60
- final Package revenueCatPackage;
61
-
62
- RevenueCatProduct({
63
- required this.revenueCatOffer,
64
- required this.revenueCatPackage,
65
- });
66
-
67
- @override
68
- String get skuId => revenueCatPackage.identifier;
69
-
70
- @override
71
- String get id => revenueCatOffer.identifier;
72
-
73
- @override
74
- String get description => revenueCatOffer.serverDescription;
75
-
76
- @override
77
- String get label =>
78
- revenueCatPackage.presentedOfferingContext.offeringIdentifier;
79
-
80
- @override
81
- double get price => revenueCatPackage.storeProduct.price;
82
-
83
- @override
84
- String get currency => revenueCatPackage.storeProduct.currencyCode;
85
-
86
- @override
87
- int? get trialDays {
88
- final introductory = revenueCatPackage.storeProduct.introductoryPrice;
89
- if (introductory == null) {
90
- return null;
91
- }
92
- if (introductory.price == 0) {
93
- final unit = introductory.periodUnit;
94
- switch (unit) {
95
- case PeriodUnit.day:
96
- return introductory.periodNumberOfUnits;
97
- case PeriodUnit.week:
98
- return introductory.periodNumberOfUnits * 7;
99
- case PeriodUnit.month:
100
- return introductory.periodNumberOfUnits * 30;
101
- case PeriodUnit.year:
102
- return introductory.periodNumberOfUnits * 365;
103
- default:
104
- return null;
105
- }
106
- }
107
- return null;
108
- }
109
-
110
- @override
111
- String? get promotion {
112
- if (revenueCatOffer.metadata["promotions"] == null) {
113
- return null;
114
- }
115
- final data =
116
- revenueCatOffer.metadata["promotions"]! as Map<Object?, Object?>;
117
- final locale = LocaleSettings.currentLocale.languageCode;
118
- final id = skuId;
119
- if (data.containsKey(id)) {
120
- final promotion = data[id]! as Map<Object?, Object?>;
121
- return promotion[locale]! as String;
122
- }
123
- return null;
124
- }
125
-
126
- @override
127
- String? get title {
128
- return revenueCatPackage.storeProduct.title;
129
- }
130
-
131
- @override
132
- List<String>? get features {
133
- final locale = LocaleSettings.currentLocale.languageCode;
134
- if (revenueCatOffer.metadata[locale] == null) {
135
- return null;
136
- }
137
- final data = revenueCatOffer.metadata[locale]! as Map<Object?, Object?>;
138
- final featuerObj = data["features"]! as List<Object?>;
139
- return featuerObj.map((e) => e! as String).toList();
140
- }
141
-
142
- @override
143
- String get priceString {
144
- return revenueCatPackage.storeProduct.priceString;
145
- }
146
-
147
- @override
148
- Duration get duration =>
149
- switch (revenueCatPackage.storeProduct.subscriptionPeriod) {
150
- 'P1W' => const Duration(days: 7),
151
- 'P1M' => const Duration(days: 30),
152
- 'P3M' => const Duration(days: 90),
153
- 'P6M' => const Duration(days: 180),
154
- 'P1Y' => const Duration(days: 365),
155
- _ => Duration.zero,
156
- };
157
-
158
- @override
159
- DurationType get durationType {
160
- final durationCpy = duration;
161
- if (durationCpy.inDays == 7) {
162
- return DurationType.week;
163
- } else if (durationCpy.inDays == 30) {
164
- return DurationType.month;
165
- } else if (durationCpy.inDays == 90) {
166
- return DurationType.threeMonth;
167
- } else if (durationCpy.inDays == 180) {
168
- return DurationType.sixMonth;
169
- } else if (durationCpy.inDays == 365) {
170
- return DurationType.year;
171
- }
172
- return DurationType.lifetime;
173
- }
174
-
175
- @override
176
- String formattedPrice(BuildContext context) {
177
- final translatedDuration = switch (durationType) {
178
- DurationType.week => Translations.of(context).premium.duration_weekly,
179
- DurationType.year => Translations.of(context).premium.duration_annual,
180
- DurationType.month => Translations.of(context).premium.duration_monthly,
181
- DurationType.lifetime => Translations.of(
182
- context,
183
- ).premium.duration_lifetime,
184
- _ => "",
185
- };
186
- return "${revenueCatPackage.storeProduct.priceString} $translatedDuration";
187
- }
188
-
189
- @override
190
- String pricePerMonth(BuildContext context) {
191
- final translatedDuration = Translations.of(
192
- context,
193
- ).premium.duration_monthly;
194
- if (durationType == DurationType.lifetime) {
195
- return revenueCatPackage.storeProduct.priceString;
196
- }
197
- final pricePerMonth = switch (durationType) {
198
- DurationType.year => price / 12,
199
- DurationType.threeMonth => price / 3,
200
- DurationType.sixMonth => price / 6,
201
- DurationType.week => (price * 4) / 12,
202
- _ => 1,
203
- };
204
- final pricePerMonthString = pricePerMonth.toStringAsFixed(2);
205
- final money = revenueCatPackage.storeProduct.currencyCode;
206
- if (money == "USD") {
207
- return "\$$pricePerMonthString/$translatedDuration";
208
- } else if (money == "EUR") {
209
- return "$pricePerMonthString/$translatedDuration";
210
- }
211
- return "$pricePerMonthString $money/$translatedDuration";
212
- }
213
-
214
- @override
215
- String? pricePerYear(BuildContext context) {
216
- final translatedDuration = Translations.of(context).premium.duration_annual;
217
- if (durationType == DurationType.lifetime) {
218
- return revenueCatPackage.storeProduct.priceString;
219
- }
220
- final pricePerMonth = switch (durationType) {
221
- DurationType.year => price,
222
- DurationType.threeMonth => price * 4,
223
- DurationType.sixMonth => price * 2,
224
- DurationType.week => (price * 4) * 12,
225
- _ => 1,
226
- };
227
- final pricePerMonthString = pricePerMonth.toStringAsFixed(2);
228
- final money = revenueCatPackage.storeProduct.currencyCode;
229
- if (money == "USD") {
230
- return "\$$pricePerMonthString/$translatedDuration";
231
- } else if (money == "EUR") {
232
- return "$pricePerMonthString/$translatedDuration";
233
- }
234
- return "$pricePerMonthString $money/$translatedDuration";
235
- }
236
- }
237
-
238
57
  enum DurationType { week, month, threeMonth, sixMonth, year, lifetime }
239
58
 
240
59
  @freezed
241
60
  sealed class Subscription with _$Subscription {
242
61
  const factory Subscription.active({
243
62
  SubscriptionProduct? activeOffer,
244
- List<EntitlementInfo>? entitlements,
63
+ List<Entitlement>? entitlements,
64
+ SubscriptionStore? store,
245
65
  }) = SubscriptionStateData;
246
66
 
247
67
  const factory Subscription.inactive({
@@ -266,7 +86,7 @@ sealed class Subscription with _$Subscription {
266
86
  lastAskingDate: lastAskingDate,
267
87
  );
268
88
  }
269
- return const Subscription.active();
89
+ return Subscription.active(store: entity.store);
270
90
  }
271
91
 
272
92
  bool get canPurchase => switch (this) {
@@ -281,9 +101,16 @@ sealed class Subscription with _$Subscription {
281
101
  SubscriptionStateLoading() => false,
282
102
  };
283
103
 
104
+ /// Where the active subscription was purchased (its origin), if known.
105
+ SubscriptionStore? get store => switch (this) {
106
+ SubscriptionStateData(:final store) => store,
107
+ SubscriptionInactiveStateData() => null,
108
+ SubscriptionStateLoading() => null,
109
+ };
110
+
284
111
  bool get isInTrial => switch (this) {
285
112
  SubscriptionStateData(:final entitlements) =>
286
- entitlements?.firstOrNull?.periodType == PeriodType.trial,
113
+ entitlements?.firstOrNull?.isInTrial == true,
287
114
  SubscriptionInactiveStateData() => false,
288
115
  SubscriptionStateLoading() => false,
289
116
  };
@@ -15,6 +15,8 @@ sealed class User with _$User {
15
15
  DateTime? lastUpdateDate,
16
16
  String? avatarPath,
17
17
  required bool onboarded,
18
+ // Access-control role. Null = normal user; "admin" unlocks server data.
19
+ String? role,
18
20
  // this will be empty only if you don't use the Subscription module
19
21
  Subscription? subscription,
20
22
  }) = AuthenticatedUserData;
@@ -50,6 +52,7 @@ sealed class User with _$User {
50
52
  name: entity.name,
51
53
  onboarded: entity.onboarded ?? false,
52
54
  avatarPath: entity.avatarPath,
55
+ role: entity.role,
53
56
  creationDate: entity.creationDate,
54
57
  lastUpdateDate: entity.lastUpdateDate,
55
58
  );
@@ -67,6 +70,7 @@ sealed class User with _$User {
67
70
  name: value.name ?? '',
68
71
  onboarded: value.onboarded,
69
72
  avatarPath: value.avatarPath,
73
+ role: value.role,
70
74
  creationDate: value.creationDate,
71
75
  lastUpdateDate: value.lastUpdateDate,
72
76
  ),
@@ -104,4 +108,11 @@ sealed class User with _$User {
104
108
  AnonymousUserData(:final onboarded) => onboarded ?? false,
105
109
  LoadingUserData() => false,
106
110
  };
111
+
112
+ /// Whether the signed-in user is an administrator (role == "admin").
113
+ /// Only authenticated users can be admins. Gates server-side admin data.
114
+ bool get isAdmin => switch (this) {
115
+ AuthenticatedUserData(:final role) => role == 'admin',
116
+ _ => false,
117
+ };
107
118
  }
@@ -5,7 +5,7 @@ import 'package:kasy_kit/core/data/api/user_api.dart';
5
5
  import 'package:kasy_kit/core/data/entities/upload_result.dart';
6
6
  import 'package:kasy_kit/core/data/entities/user_entity.dart';
7
7
  import 'package:kasy_kit/core/data/models/user.dart';
8
- import 'package:kasy_kit/features/subscription/repositories/subscription_repository.dart';
8
+ import 'package:kasy_kit/features/subscriptions/repositories/subscription_repository.dart';
9
9
  import 'package:kasy_kit/i18n/translations.g.dart';
10
10
  import 'package:logger/logger.dart';
11
11
 
@@ -3,7 +3,7 @@ import 'package:kasy_kit/core/home_widgets/home_widget_mywidget_service.dart';
3
3
  import 'package:kasy_kit/core/shared_preferences/shared_preferences.dart';
4
4
  import 'package:kasy_kit/core/states/user_state_notifier.dart';
5
5
  import 'package:kasy_kit/features/authentication/api/authentication_api.dart';
6
- import 'package:kasy_kit/features/subscription/repositories/subscription_repository.dart';
6
+ import 'package:kasy_kit/features/subscriptions/repositories/subscription_repository.dart';
7
7
  import 'package:kasy_kit/i18n/translations.g.dart';
8
8
  import 'package:logger/logger.dart';
9
9
 
@@ -2,7 +2,7 @@ import 'package:home_widget/home_widget.dart';
2
2
  import 'package:kasy_kit/core/data/models/user.dart';
3
3
  import 'package:kasy_kit/core/home_widgets/home_widget_service.dart';
4
4
  import 'package:kasy_kit/core/states/user_state_notifier.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:kasy_kit/i18n/translations.g.dart';
7
7
  import 'package:logger/logger.dart';
8
8
  import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -20,6 +20,36 @@ abstract final class KasyIcons {
20
20
  static const IconData voteUp = LucideIcons.chevronUp400;
21
21
  static const IconData book = LucideIcons.book300;
22
22
  static const IconData calendar = LucideIcons.calendar300;
23
+
24
+ /// Dashboard / grid of panels.
25
+ static const IconData dashboard = LucideIcons.layoutDashboard300;
26
+
27
+ /// Bar chart — analytics / reports.
28
+ static const IconData analytics = LucideIcons.barChart3300;
29
+
30
+ /// Folder — projects / collections.
31
+ static const IconData folder = LucideIcons.folder300;
32
+
33
+ /// Briefcase — recruitment / jobs.
34
+ static const IconData briefcase = LucideIcons.briefcase300;
35
+
36
+ /// Flag — activity / milestones.
37
+ static const IconData flag = LucideIcons.flag300;
38
+
39
+ /// Two people — shared / team.
40
+ static const IconData users = LucideIcons.usersRound300;
41
+
42
+ /// Shield with check — privacy / verified.
43
+ static const IconData shieldCheck = LucideIcons.shieldCheck300;
44
+
45
+ /// Speech bubble — chat / conversations.
46
+ static const IconData chat = LucideIcons.messageCircle300;
47
+
48
+ /// Newspaper — news.
49
+ static const IconData newspaper = LucideIcons.newspaper300;
50
+
51
+ /// Collapse the left panel (sidebar) — narrow/expand toggle.
52
+ static const IconData panelLeft = LucideIcons.panelLeft300;
23
53
  static const IconData cameraAlt = LucideIcons.camera400;
24
54
  static const IconData check = LucideIcons.check300;
25
55
  static const IconData checkCircle = LucideIcons.circleCheck300;
@@ -34,7 +64,7 @@ abstract final class KasyIcons {
34
64
  static const IconData favorite = LucideIcons.heart300;
35
65
  static const IconData favoriteOutline = LucideIcons.heartOff300;
36
66
 
37
- /// Coração preenchido (usa glifo Material junto aos Lucides quando precisa fill).
67
+ /// Filled heart (uses a Material glyph alongside Lucide when a fill is needed).
38
68
  static const IconData favoriteFilled = Icons.favorite_rounded;
39
69
  static const IconData flash = LucideIcons.zap300;
40
70
  static const IconData idea = LucideIcons.lightbulb300;
@@ -2,7 +2,7 @@
2
2
  import 'package:flutter_riverpod/flutter_riverpod.dart';
3
3
  import 'package:in_app_review/in_app_review.dart';
4
4
  import 'package:kasy_kit/core/shared_preferences/shared_preferences.dart';
5
- import 'package:kasy_kit/environnements.dart';
5
+ import 'package:kasy_kit/environments.dart';
6
6
  import 'package:shared_preferences/shared_preferences.dart';
7
7
 
8
8
  const _lastAskKey = 'last_asking_date';
@@ -65,7 +65,7 @@ class RatingApi {
65
65
  Future<void> openStoreListing() {
66
66
  if (_env.appStoreId == null) {
67
67
  throw Exception(
68
- '''appStoreId is not defined in your environment, check [environnements.dart] file''',
68
+ '''appStoreId is not defined in your environment, check [environments.dart] file''',
69
69
  );
70
70
  }
71
71
  return _inAppReview.openStoreListing(appStoreId: _env.appStoreId);
@@ -0,0 +1,25 @@
1
+ import 'package:flutter/widgets.dart';
2
+ import 'package:flutter_riverpod/flutter_riverpod.dart';
3
+ import 'package:kasy_kit/components/components.dart';
4
+ import 'package:kasy_kit/core/states/user_state_notifier.dart';
5
+ import 'package:kasy_kit/core/theme/theme.dart';
6
+ import 'package:kasy_kit/i18n/translations.g.dart';
7
+
8
+ /// Standardized logout flow — the single source of truth for signing out.
9
+ ///
10
+ /// Every entry point (settings app bar, sidebar, …) calls this so the confirm
11
+ /// dialog's look (blurred [KasyDialog] with a logout icon), copy and behavior
12
+ /// stay identical everywhere. Feature/host code owns the *when*; the design
13
+ /// system owns the *how*.
14
+ Future<void> confirmLogout(BuildContext context, WidgetRef ref) {
15
+ final tr = context.t.settings;
16
+ return showKasyConfirmDialog(
17
+ context,
18
+ leadingIcon: KasyIcons.logout,
19
+ title: tr.disconnect_confirm_title,
20
+ message: tr.disconnect_confirm_message,
21
+ cancelLabel: tr.disconnect_cancel,
22
+ confirmLabel: tr.disconnect,
23
+ onConfirm: () => ref.read(userStateNotifierProvider.notifier).onLogout(),
24
+ );
25
+ }
@@ -2,18 +2,18 @@ import 'dart:async';
2
2
 
3
3
  import 'package:flutter/foundation.dart';
4
4
  import 'package:kasy_kit/core/config/features.dart';
5
+ import 'package:kasy_kit/core/data/models/entitlement.dart';
5
6
  import 'package:kasy_kit/core/data/models/subscription.dart';
6
7
  import 'package:kasy_kit/core/data/models/user.dart';
7
8
  import 'package:kasy_kit/core/data/repositories/user_repository.dart';
8
9
  import 'package:kasy_kit/core/initializer/onstart_service.dart';
9
10
  import 'package:kasy_kit/core/shared_preferences/shared_preferences.dart';
10
11
  import 'package:kasy_kit/core/states/models/user_state.dart';
11
- import 'package:kasy_kit/environnements.dart';
12
+ import 'package:kasy_kit/environments.dart';
12
13
  import 'package:kasy_kit/features/authentication/repositories/authentication_repository.dart';
13
14
  import 'package:kasy_kit/features/notifications/providers/models/device.dart';
14
15
  import 'package:kasy_kit/features/notifications/repositories/device_repository.dart';
15
16
  import 'package:logger/logger.dart';
16
- import 'package:purchases_flutter/models/entitlement_info_wrapper.dart';
17
17
  import 'package:riverpod_annotation/riverpod_annotation.dart';
18
18
 
19
19
  part 'user_state_notifier.g.dart';
@@ -166,7 +166,7 @@ class UserStateNotifier extends _$UserStateNotifier implements OnStartService {
166
166
  /// On next app start, the subscription will be refreshed from the webhook result
167
167
  Future<void> refreshSubscription({
168
168
  SubscriptionProduct? product,
169
- List<EntitlementInfo>? entitlements,
169
+ List<Entitlement>? entitlements,
170
170
  }) async {
171
171
  if (product != null) {
172
172
  final newUser = switch (state.user) {