kasy-cli 1.12.1 → 1.13.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 (138) hide show
  1. package/bin/kasy.js +21 -0
  2. package/lib/commands/splash.js +220 -0
  3. package/lib/scaffold/CHANGELOG.json +9 -0
  4. package/lib/scaffold/backends/api/patch/lib/main.dart +29 -10
  5. package/lib/scaffold/backends/supabase/patch/lib/main.dart +29 -10
  6. package/lib/scaffold/features/README.md +15 -139
  7. package/lib/scaffold/shared/generator-utils.js +16 -15
  8. package/lib/utils/i18n.js +78 -0
  9. package/package.json +2 -2
  10. package/templates/firebase/android/app/src/main/res/drawable-hdpi/android12splash.png +0 -0
  11. package/templates/firebase/android/app/src/main/res/drawable-hdpi/splash.png +0 -0
  12. package/templates/firebase/android/app/src/main/res/drawable-mdpi/android12splash.png +0 -0
  13. package/templates/firebase/android/app/src/main/res/drawable-mdpi/splash.png +0 -0
  14. package/templates/firebase/android/app/src/main/res/drawable-night/background.png +0 -0
  15. package/templates/firebase/android/app/src/main/res/drawable-night/launch_background.xml +9 -0
  16. package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/android12splash.png +0 -0
  17. package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/splash.png +0 -0
  18. package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/android12splash.png +0 -0
  19. package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/splash.png +0 -0
  20. package/templates/firebase/android/app/src/main/res/drawable-night-v21/background.png +0 -0
  21. package/templates/firebase/android/app/src/main/res/drawable-night-v21/launch_background.xml +9 -0
  22. package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/android12splash.png +0 -0
  23. package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/splash.png +0 -0
  24. package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png +0 -0
  25. package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/splash.png +0 -0
  26. package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png +0 -0
  27. package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/splash.png +0 -0
  28. package/templates/firebase/android/app/src/main/res/drawable-xhdpi/android12splash.png +0 -0
  29. package/templates/firebase/android/app/src/main/res/drawable-xhdpi/splash.png +0 -0
  30. package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/android12splash.png +0 -0
  31. package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/splash.png +0 -0
  32. package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/android12splash.png +0 -0
  33. package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/splash.png +0 -0
  34. package/templates/firebase/android/app/src/main/res/values-night-v31/styles.xml +2 -1
  35. package/templates/firebase/android/app/src/main/res/values-v31/styles.xml +1 -0
  36. package/templates/firebase/assets/images/splash_logo_dark.png +0 -0
  37. package/templates/firebase/assets/images/splash_logo_light.png +0 -0
  38. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json +9 -8
  39. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png +0 -0
  40. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +33 -0
  41. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +0 -0
  42. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +0 -0
  43. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +0 -0
  44. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png +0 -0
  45. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png +0 -0
  46. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png +0 -0
  47. package/templates/firebase/ios/Runner/Base.lproj/LaunchScreen.storyboard +1 -1
  48. package/templates/firebase/lib/core/theme/providers/theme_provider.dart +48 -24
  49. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_features.dart +4 -0
  50. package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +1 -0
  51. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_feature.dart +13 -0
  52. package/templates/firebase/lib/features/settings/settings_page.dart +158 -18
  53. package/templates/firebase/lib/i18n/en.i18n.json +6 -2
  54. package/templates/firebase/lib/i18n/es.i18n.json +6 -2
  55. package/templates/firebase/lib/i18n/pt.i18n.json +6 -2
  56. package/templates/firebase/lib/main.dart +29 -10
  57. package/templates/firebase/pubspec.yaml +4 -5
  58. package/templates/firebase/test/core/data/repositories/user_repository_test.dart +1 -1
  59. package/templates/firebase/web/index.html +47 -39
  60. package/templates/firebase/web/splash/img/dark-1x.png +0 -0
  61. package/templates/firebase/web/splash/img/dark-2x.png +0 -0
  62. package/templates/firebase/web/splash/img/dark-3x.png +0 -0
  63. package/templates/firebase/web/splash/img/dark-4x.png +0 -0
  64. package/templates/firebase/web/splash/img/light-1x.png +0 -0
  65. package/templates/firebase/web/splash/img/light-2x.png +0 -0
  66. package/templates/firebase/web/splash/img/light-3x.png +0 -0
  67. package/templates/firebase/web/splash/img/light-4x.png +0 -0
  68. package/lib/scaffold/features/analytics/lib/core/data/api/analytics_api.dart +0 -124
  69. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.es.md +0 -35
  70. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.md +0 -35
  71. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.pt.md +0 -35
  72. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.es.md +0 -12
  73. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.md +0 -12
  74. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.pt.md +0 -12
  75. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.es.md +0 -17
  76. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  77. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.pt.md +0 -17
  78. package/lib/scaffold/features/ci/.github/dependabot.yml +0 -16
  79. package/lib/scaffold/features/ci/.github/workflows/app.yml +0 -20
  80. package/lib/scaffold/features/ci/.gitlab/templates/deploy.yaml +0 -14
  81. package/lib/scaffold/features/ci/.gitlab/templates/dropbox.yaml +0 -19
  82. package/lib/scaffold/features/ci/.gitlab/templates/flutter.yaml +0 -163
  83. package/lib/scaffold/features/ci/.gitlab/templates/mailgun.yaml +0 -28
  84. package/lib/scaffold/features/ci/.gitlab-ci.yml +0 -37
  85. package/lib/scaffold/features/ci/codemagic.yaml +0 -157
  86. package/lib/scaffold/features/facebook/lib/core/data/api/tracking_api.dart +0 -111
  87. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_request_entity.dart +0 -27
  88. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_vote_entity.dart +0 -27
  89. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_request_api.dart +0 -50
  90. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_vote_api.dart +0 -79
  91. package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feature_requests.dart +0 -48
  92. package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feedback_state.dart +0 -42
  93. package/lib/scaffold/features/feedback/lib/features/feedbacks/providers/feedback_page_notifier.dart +0 -147
  94. package/lib/scaffold/features/feedback/lib/features/feedbacks/repositories/feature_request_repository.dart +0 -95
  95. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/component/add_feature_form.dart +0 -199
  96. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/feedback_page.dart +0 -175
  97. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/add_feature_button.dart +0 -76
  98. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/feature_card.dart +0 -279
  99. package/lib/scaffold/features/ios-release/.kasy/apple.env.example +0 -8
  100. package/lib/scaffold/features/ios-release/.kasy/codemagic.env.example +0 -7
  101. package/lib/scaffold/features/ios-release/docs/codemagic-release.en.md +0 -50
  102. package/lib/scaffold/features/ios-release/docs/codemagic-release.es.md +0 -50
  103. package/lib/scaffold/features/ios-release/docs/codemagic-release.pt.md +0 -50
  104. package/lib/scaffold/features/ios-release/docs/ios-release.en.md +0 -41
  105. package/lib/scaffold/features/ios-release/docs/ios-release.es.md +0 -41
  106. package/lib/scaffold/features/ios-release/docs/ios-release.pt.md +0 -41
  107. package/lib/scaffold/features/ios-release/scripts/bump-ios-version.js +0 -38
  108. package/lib/scaffold/features/ios-release/scripts/release-ios.sh +0 -137
  109. package/lib/scaffold/features/llm_chat/lib/features/llm_chat/llm_chat_page.dart +0 -301
  110. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/providers/reminder_notifier.dart +0 -81
  111. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/repositories/reminder_preferences.dart +0 -76
  112. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/ui/reminder_page.dart +0 -282
  113. package/lib/scaffold/features/onboarding/lib/features/onboarding/api/entities/user_info_entity.dart +0 -24
  114. package/lib/scaffold/features/onboarding/lib/features/onboarding/api/user_infos_api.dart +0 -71
  115. package/lib/scaffold/features/onboarding/lib/features/onboarding/models/user_info.dart +0 -92
  116. package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_model.dart +0 -15
  117. package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_provider.dart +0 -78
  118. package/lib/scaffold/features/onboarding/lib/features/onboarding/repositories/user_infos_repository.dart +0 -29
  119. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/animations/page_transitions.dart +0 -30
  120. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_att_setup.dart +0 -66
  121. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_features.dart +0 -72
  122. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_loader.dart +0 -92
  123. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +0 -73
  124. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_questions.dart +0 -89
  125. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/onboarding_page.dart +0 -94
  126. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_background.dart +0 -80
  127. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_feature.dart +0 -139
  128. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +0 -110
  129. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_progress.dart +0 -84
  130. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +0 -173
  131. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_reassurance.dart +0 -45
  132. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_sticky_footer.dart +0 -77
  133. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +0 -392
  134. package/lib/scaffold/features/revenuecat/lib/core/data/api/tracking_api.dart +0 -116
  135. package/lib/scaffold/features/revenuecat/lib/core/data/models/subscription.dart +0 -322
  136. package/lib/scaffold/features/revenuecat/lib/core/home_widgets/home_widget_background_task.dart +0 -41
  137. package/lib/scaffold/features/revenuecat/lib/core/states/user_state_notifier.dart +0 -305
  138. package/templates/firebase/assets/images/splashscreen.png +0 -0
@@ -1,199 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:flutter_riverpod/flutter_riverpod.dart';
3
- import 'package:go_router/go_router.dart';
4
- import 'package:kasy_kit/components/components.dart';
5
- import 'package:kasy_kit/core/theme/theme.dart';
6
- import 'package:kasy_kit/core/widgets/kasy_scroll_behavior.dart';
7
- import 'package:kasy_kit/features/feedbacks/providers/feedback_page_notifier.dart';
8
- import 'package:kasy_kit/i18n/translations.g.dart';
9
-
10
- Future<void> showAddFeatureBottomSheet(BuildContext context) {
11
- return showModalBottomSheet<bool?>(
12
- context: context,
13
- isScrollControlled: true,
14
- builder: (context) => const FractionallySizedBox(
15
- heightFactor: .8,
16
- child: AddFeatureComponent(),
17
- ),
18
- ).then((res) {
19
- if (!context.mounted) return;
20
- final translations = Translations.of(context).feature_requests.add_feature;
21
- if (res == true) {
22
- showSuccessToast(
23
- context: context,
24
- title: translations.toast_success.title,
25
- text: translations.toast_success.description,
26
- );
27
- }
28
- });
29
- }
30
-
31
- class AddFeatureComponent extends ConsumerStatefulWidget {
32
- const AddFeatureComponent({super.key});
33
-
34
- @override
35
- ConsumerState<ConsumerStatefulWidget> createState() =>
36
- _AddFeatureComponentState();
37
- }
38
-
39
- class _AddFeatureComponentState extends ConsumerState<AddFeatureComponent> {
40
- String title = '';
41
- String description = '';
42
- bool locked = false;
43
-
44
- final titleFocusNode = FocusNode();
45
- final textFocusNode = FocusNode();
46
-
47
- bool get _titleFilled => title.trim().isNotEmpty;
48
- bool get _descriptionValid => description.length >= 40;
49
- bool get canSubmit => _titleFilled && _descriptionValid && !locked;
50
-
51
- void _onSubmitAttempt() {
52
- final tr = Translations.of(context).feature_requests.add_feature;
53
- if (!_titleFilled || description.trim().isEmpty) {
54
- ref.read(toastProvider).error(
55
- title: tr.error_title,
56
- text: tr.error_required,
57
- );
58
- return;
59
- }
60
- if (!_descriptionValid) {
61
- ref.read(toastProvider).error(
62
- title: tr.error_title,
63
- text: tr.error_too_short,
64
- );
65
- return;
66
- }
67
- }
68
-
69
- void _submit() {
70
- if (locked) return;
71
- FocusScope.of(context).unfocus();
72
- locked = true;
73
- final tr = Translations.of(context).feature_requests.add_feature;
74
- ref
75
- .read(feedbackPageProvider.notifier)
76
- .createFeatureSuggestion(
77
- title: title,
78
- description: description,
79
- )
80
- .then(
81
- (_) {
82
- locked = false;
83
- if (!mounted) return;
84
- context.pop(true);
85
- },
86
- onError: (_) {
87
- locked = false;
88
- ref.read(toastProvider).error(
89
- title: tr.error_title,
90
- text: tr.error_sending,
91
- );
92
- },
93
- );
94
- }
95
-
96
- @override
97
- Widget build(BuildContext context) {
98
- final translations = Translations.of(context).feature_requests.add_feature;
99
-
100
- final Widget submitButton = KasyButton(
101
- label: translations.save_button,
102
- expand: true,
103
- onPressed: canSubmit ? _submit : null,
104
- );
105
-
106
- return Scaffold(
107
- body: Stack(
108
- fit: StackFit.expand,
109
- children: [
110
- Positioned.fill(
111
- child: ScrollConfiguration(
112
- behavior: const KasyKitScrollBehavior(),
113
- child: CustomScrollView(
114
- slivers: kasyOverlayPaddedSlivers(
115
- context,
116
- contentPadding: EdgeInsets.fromLTRB(
117
- KasySpacing.pageHorizontalGutter,
118
- KasySpacing.belowChromeContentGap,
119
- KasySpacing.pageHorizontalGutter,
120
- MediaQuery.paddingOf(context).bottom + KasySpacing.xxxl,
121
- ),
122
- slivers: [
123
- SliverToBoxAdapter(
124
- child: Column(
125
- crossAxisAlignment: CrossAxisAlignment.stretch,
126
- children: [
127
- const SizedBox(height: KasySpacing.md),
128
- Text(
129
- translations.description,
130
- style: context.textTheme.bodyMedium?.copyWith(
131
- color: context.colors.muted,
132
- height: 1.5,
133
- ),
134
- ),
135
- const SizedBox(height: KasySpacing.xl),
136
- KasyTextField(
137
- label: translations.title_label,
138
- hint: translations.title_hint,
139
- showRequiredIndicator: true,
140
- variant: KasyTextFieldVariant.secondary,
141
- onChanged: (value) =>
142
- setState(() => title = value),
143
- focusNode: titleFocusNode,
144
- textInputAction: TextInputAction.next,
145
- onSubmitted: (_) {
146
- titleFocusNode.unfocus();
147
- textFocusNode.requestFocus();
148
- },
149
- maxLength: 40,
150
- ),
151
- const SizedBox(height: KasySpacing.md),
152
- KasyTextField(
153
- label: translations.description_label,
154
- hint: translations.description_hint,
155
- showRequiredIndicator: true,
156
- variant: KasyTextFieldVariant.secondary,
157
- minLines: 6,
158
- maxLines: 6,
159
- onChanged: (value) =>
160
- setState(() => description = value),
161
- textInputAction: TextInputAction.done,
162
- onSubmitted: (_) => textFocusNode.unfocus(),
163
- maxLength: 1000,
164
- focusNode: textFocusNode,
165
- ),
166
- const SizedBox(height: KasySpacing.xl),
167
- ],
168
- ),
169
- ),
170
- ],
171
- ),
172
- ),
173
- ),
174
- ),
175
- Positioned(
176
- top: 0,
177
- left: 0,
178
- right: 0,
179
- child: KasyAppBar(
180
- title: translations.title,
181
- onBack: () => context.pop(),
182
- ),
183
- ),
184
- Positioned(
185
- left: KasySpacing.pageHorizontalGutter,
186
- right: KasySpacing.pageHorizontalGutter,
187
- bottom: MediaQuery.paddingOf(context).bottom + KasySpacing.md,
188
- child: canSubmit
189
- ? submitButton
190
- : GestureDetector(
191
- onTap: _onSubmitAttempt,
192
- child: submitButton,
193
- ),
194
- ),
195
- ],
196
- ),
197
- );
198
- }
199
- }
@@ -1,175 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:flutter_riverpod/flutter_riverpod.dart';
3
- import 'package:go_router/go_router.dart';
4
- import 'package:kasy_kit/components/kasy_toast.dart';
5
- import 'package:kasy_kit/core/theme/theme.dart';
6
- import 'package:kasy_kit/core/widgets/responsive_layout.dart';
7
- import 'package:kasy_kit/i18n/translations.g.dart';
8
- import 'package:kasy_kit/features/feedbacks/providers/feedback_page_notifier.dart';
9
- import 'package:kasy_kit/features/feedbacks/ui/widgets/add_feature_button.dart';
10
- import 'package:kasy_kit/features/feedbacks/ui/widgets/feature_card.dart';
11
-
12
- class FeedbackPage extends ConsumerWidget {
13
- const FeedbackPage({super.key});
14
-
15
- @override
16
- Widget build(BuildContext context, WidgetRef ref) {
17
- final state = ref.watch(feedbackPageProvider);
18
- final translations = Translations.of(context).feature_requests;
19
-
20
- return Scaffold(
21
- backgroundColor: context.colors.background,
22
- body: SafeArea(
23
- child: LargeLayoutContainer(
24
- child: CustomScrollView(
25
- slivers: [
26
- SliverAppBar(
27
- backgroundColor: Colors.transparent,
28
- leading: IconButton(
29
- icon: const Icon(Icons.arrow_back),
30
- onPressed: () =>
31
- context.canPop() ? context.pop() : context.go('/'),
32
- ),
33
- ),
34
- SliverToBoxAdapter(
35
- child: Padding(
36
- padding: const EdgeInsets.fromLTRB(
37
- KasySpacing.lg,
38
- KasySpacing.xl,
39
- KasySpacing.lg,
40
- 0,
41
- ),
42
- child: Text(
43
- translations.title,
44
- style: context.textTheme.headlineMedium?.copyWith(
45
- fontWeight: FontWeight.bold,
46
- ),
47
- ),
48
- ),
49
- ),
50
- SliverToBoxAdapter(
51
- child: Padding(
52
- padding: const EdgeInsets.fromLTRB(
53
- KasySpacing.lg,
54
- KasySpacing.sm,
55
- KasySpacing.lg,
56
- KasySpacing.md,
57
- ),
58
- child: Text(
59
- translations.description,
60
- style: context.textTheme.bodyLarge?.copyWith(
61
- fontWeight: FontWeight.w400,
62
- color: context.colors.muted,
63
- ),
64
- ),
65
- ),
66
- ),
67
- SliverToBoxAdapter(
68
- child: Padding(
69
- padding: const EdgeInsets.symmetric(
70
- horizontal: KasySpacing.lg,
71
- vertical: KasySpacing.md,
72
- ),
73
- child: AddFeatureButton(
74
- title: translations.add_feature.title,
75
- description: translations.add_feature.description,
76
- onPressed: () async {
77
- final success = await context.push<bool>('/feedback/new');
78
- if (success == true && context.mounted) {
79
- showSuccessToast(
80
- context: context,
81
- title: translations.add_feature.toast_success.title,
82
- text: translations.add_feature.toast_success.description,
83
- );
84
- }
85
- },
86
- ),
87
- ),
88
- ),
89
- state.map(
90
- data: (data) {
91
- if (data.value.featureRequests.isEmpty) {
92
- return SliverToBoxAdapter(
93
- child: Padding(
94
- padding: const EdgeInsets.symmetric(
95
- horizontal: KasySpacing.lg,
96
- vertical: KasySpacing.md,
97
- ),
98
- child: Text(
99
- translations.no_requests,
100
- textAlign: TextAlign.center,
101
- style: context.textTheme.bodyMedium?.copyWith(
102
- fontWeight: FontWeight.w300,
103
- color: context.colors.muted,
104
- ),
105
- ),
106
- ),
107
- );
108
- }
109
- return SliverList.separated(
110
- itemBuilder: (context, index) => Padding(
111
- padding: const EdgeInsets.symmetric(
112
- horizontal: KasySpacing.lg,
113
- ),
114
- child: FeatureCard(
115
- title: data.value.featureRequests[index].title,
116
- description:
117
- data.value.featureRequests[index].description,
118
- votes: data.value.featureRequests[index].votes,
119
- onVote: () {
120
- ref
121
- .read(feedbackPageProvider.notifier)
122
- .vote(data.value.featureRequests[index]);
123
- },
124
- voted: data.value.hasVoted(
125
- data.value.featureRequests[index],
126
- ),
127
- ),
128
- ),
129
- separatorBuilder: (context, index) =>
130
- const SizedBox(height: KasySpacing.smd),
131
- itemCount: data.value.featureRequests.length,
132
- );
133
- },
134
- error: (error) => SliverFillRemaining(
135
- child: Center(child: Text(error.error.toString())),
136
- ),
137
- loading: (data) {
138
- if (!data.hasValue) {
139
- return const SliverFillRemaining(
140
- child: Center(child: CircularProgressIndicator()),
141
- );
142
- }
143
- return SliverList.separated(
144
- itemBuilder: (context, index) => Padding(
145
- padding: const EdgeInsets.symmetric(
146
- horizontal: KasySpacing.lg,
147
- ),
148
- child: FeatureCard(
149
- title: data.value!.featureRequests[index].title,
150
- description:
151
- data.value!.featureRequests[index].description,
152
- votes: data.value!.featureRequests[index].votes,
153
- onVote: () {},
154
- disabled: true,
155
- voted: data.value!.hasVoted(
156
- data.value!.featureRequests[index],
157
- ),
158
- ),
159
- ),
160
- separatorBuilder: (context, index) =>
161
- const SizedBox(height: KasySpacing.smd),
162
- itemCount: data.value!.featureRequests.length,
163
- );
164
- },
165
- ),
166
- const SliverToBoxAdapter(
167
- child: SizedBox(height: KasySpacing.xxxl),
168
- ),
169
- ],
170
- ),
171
- ),
172
- ),
173
- );
174
- }
175
- }
@@ -1,76 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:kasy_kit/core/theme/theme.dart';
3
-
4
- class AddFeatureButton extends StatefulWidget {
5
- final String title;
6
- final String description;
7
- final VoidCallback onPressed;
8
-
9
- const AddFeatureButton({
10
- super.key,
11
- required this.title,
12
- required this.description,
13
- required this.onPressed,
14
- });
15
-
16
- @override
17
- State<AddFeatureButton> createState() => _AddFeatureButtonState();
18
- }
19
-
20
- class _AddFeatureButtonState extends State<AddFeatureButton> {
21
- @override
22
- Widget build(BuildContext context) {
23
- return InkWell(
24
- onTap: widget.onPressed,
25
- borderRadius: KasyRadius.mdBorderRadius,
26
- child: Ink(
27
- padding: const EdgeInsets.symmetric(
28
- horizontal: KasySpacing.lg,
29
- vertical: KasySpacing.md,
30
- ),
31
- decoration: BoxDecoration(
32
- color: context.colors.primary,
33
- borderRadius: KasyRadius.mdBorderRadius,
34
- border: Border.all(
35
- color: context.colors.onBackground.withValues(alpha: .05),
36
- ),
37
- boxShadow: [
38
- BoxShadow(
39
- color: context.colors.primary.withValues(alpha: 0.05),
40
- blurRadius: 8,
41
- offset: const Offset(0, 4),
42
- ),
43
- ],
44
- ),
45
- child: Row(
46
- children: [
47
- Icon(Icons.add, size: 32, color: context.colors.onPrimary),
48
- const SizedBox(width: KasySpacing.md),
49
- Expanded(
50
- child: Column(
51
- crossAxisAlignment: CrossAxisAlignment.start,
52
- spacing: KasySpacing.xs,
53
- children: [
54
- Text(
55
- widget.title,
56
- style: context.textTheme.titleLarge?.copyWith(
57
- fontWeight: FontWeight.bold,
58
- color: context.colors.onPrimary,
59
- ),
60
- ),
61
- Text(
62
- widget.description,
63
- style: context.textTheme.bodyMedium?.copyWith(
64
- fontWeight: FontWeight.w400,
65
- color: context.colors.onPrimary.withValues(alpha: 0.7),
66
- ),
67
- ),
68
- ],
69
- ),
70
- ),
71
- ],
72
- ),
73
- ),
74
- );
75
- }
76
- }