create-flutterinit 0.1.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.
- package/bin/index.ts +3 -0
- package/package.json +46 -0
- package/templates/base/.cursor/rules/flutter-project.mdc.hbs +132 -0
- package/templates/base/AGENTS.md.hbs +137 -0
- package/templates/base/DESIGN.md.hbs +149 -0
- package/templates/base/README.md.hbs +19 -0
- package/templates/base/SETUP.md.hbs +253 -0
- package/templates/base/analysis_options.yaml +88 -0
- package/templates/base/assets/.keep +1 -0
- package/templates/base/assets/icons/apple.svg +1 -0
- package/templates/base/assets/icons/facebook.svg +1 -0
- package/templates/base/assets/icons/google.svg +1 -0
- package/templates/base/assets/images/.gitkeep +0 -0
- package/templates/base/flutter_native_splash.yaml.hbs +8 -0
- package/templates/base/lib/main.dart.hbs +43 -0
- package/templates/base/lib/src/app.dart.hbs +105 -0
- package/templates/base/lib/src/config/app_config.dart.hbs +112 -0
- package/templates/base/lib/src/extensions/collection_extension.dart.hbs +55 -0
- package/templates/base/lib/src/extensions/context_extension.dart.hbs +167 -0
- package/templates/base/lib/src/extensions/date_time_extension.dart.hbs +40 -0
- package/templates/base/lib/src/extensions/extensions.dart.hbs +6 -0
- package/templates/base/lib/src/extensions/num_extension.dart.hbs +14 -0
- package/templates/base/lib/src/extensions/string_extension.dart.hbs +91 -0
- package/templates/base/lib/src/extensions/widget_extension.dart.hbs +47 -0
- package/templates/base/lib/src/imports/core_imports.dart.hbs +50 -0
- package/templates/base/lib/src/imports/imports.dart.hbs +2 -0
- package/templates/base/lib/src/imports/packages_imports.dart.hbs +110 -0
- package/templates/base/lib/src/routing/(isGetX)@app_bindings.dart.hbs +23 -0
- package/templates/base/lib/src/routing/app_router.dart.hbs +252 -0
- package/templates/base/lib/src/routing/app_routes.dart.hbs +46 -0
- package/templates/base/lib/src/routing/global_navigator.dart.hbs +15 -0
- package/templates/base/lib/src/services/auth_service.dart.hbs +78 -0
- package/templates/base/lib/src/services/copy_service.dart.hbs +16 -0
- package/templates/base/lib/src/services/internet_connection_service.dart.hbs +10 -0
- package/templates/base/lib/src/services/services.dart.hbs +45 -0
- package/templates/base/lib/src/shared/app_assets.dart.hbs +15 -0
- package/templates/base/lib/src/shared/enums/app_status.dart.hbs +40 -0
- package/templates/base/lib/src/shared/enums/button_enums.dart.hbs +22 -0
- package/templates/base/lib/src/shared/enums/enums.dart.hbs +3 -0
- package/templates/base/lib/src/shared/enums/snack_bar_type.dart.hbs +22 -0
- package/templates/base/lib/src/shared/helpers/format_number.dart.hbs +18 -0
- package/templates/base/lib/src/shared/helpers/imports.dart.hbs +3 -0
- package/templates/base/lib/src/shared/helpers/show_app_sheet.dart.hbs +42 -0
- package/templates/base/lib/src/shared/helpers/show_dialog.dart.hbs +49 -0
- package/templates/base/lib/src/shared/helpers/show_toast.dart.hbs +92 -0
- package/templates/base/lib/src/shared/hooks/hooks.dart.hbs +13 -0
- package/templates/base/lib/src/shared/hooks/use_copy.dart.hbs +41 -0
- package/templates/base/lib/src/shared/hooks/use_timer.dart.hbs +158 -0
- package/templates/base/lib/src/shared/shared.dart.hbs +12 -0
- package/templates/base/lib/src/shared/widgets/app_button.dart.hbs +144 -0
- package/templates/base/lib/src/shared/widgets/app_card.dart.hbs +126 -0
- package/templates/base/lib/src/shared/widgets/app_divider.dart.hbs +88 -0
- package/templates/base/lib/src/shared/widgets/app_empty_state.dart.hbs +73 -0
- package/templates/base/lib/src/shared/widgets/app_error_widget.dart.hbs +69 -0
- package/templates/base/lib/src/shared/widgets/app_icon.dart.hbs +25 -0
- package/templates/base/lib/src/shared/widgets/app_loading.dart.hbs +54 -0
- package/templates/base/lib/src/shared/widgets/app_text_field.dart.hbs +89 -0
- package/templates/base/lib/src/shared/widgets/app_top_bar.dart.hbs +105 -0
- package/templates/base/lib/src/shared/widgets/common_image.dart.hbs +120 -0
- package/templates/base/lib/src/shared/widgets/toast/imports.dart.hbs +4 -0
- package/templates/base/lib/src/shared/widgets/toast/raw_toast.dart.hbs +109 -0
- package/templates/base/lib/src/shared/widgets/toast/toast.dart.hbs +142 -0
- package/templates/base/lib/src/shared/widgets/toast/toast_card.dart.hbs +57 -0
- package/templates/base/lib/src/shared/widgets/widgets.dart.hbs +14 -0
- package/templates/base/lib/src/shared/wrappers/(isRiverpod,isProvider,isBloc,isGetX,isMobX)@state_wrapper.dart.hbs +51 -0
- package/templates/base/lib/src/shared/wrappers/(supportsLocalization)@localization_wrapper.dart.hbs +25 -0
- package/templates/base/lib/src/shared/wrappers/(usesScreenutil)@screen_util_wrapper.dart.hbs +27 -0
- package/templates/base/lib/src/shared/wrappers/(usesSkeletonizer)@skeleton_wrapper.dart.hbs +81 -0
- package/templates/base/lib/src/shared/wrappers/session_listener_wrapper.dart.hbs +258 -0
- package/templates/base/lib/src/shared/wrappers/wrappers.dart.hbs +15 -0
- package/templates/base/lib/src/theme/app_borders.dart.hbs +70 -0
- package/templates/base/lib/src/theme/app_curves.dart.hbs +69 -0
- package/templates/base/lib/src/theme/app_durations.dart.hbs +48 -0
- package/templates/base/lib/src/theme/app_shadows.dart.hbs +73 -0
- package/templates/base/lib/src/theme/app_spacing.dart.hbs +80 -0
- package/templates/base/lib/src/theme/color_schemes.dart.hbs +126 -0
- package/templates/base/lib/src/theme/text_theme.dart.hbs +167 -0
- package/templates/base/lib/src/theme/theme.dart.hbs +431 -0
- package/templates/base/lib/src/theme/theme_constants.dart.hbs +20 -0
- package/templates/base/lib/src/utils/app_utils.dart.hbs +46 -0
- package/templates/base/lib/src/utils/debouncer.dart.hbs +31 -0
- package/templates/base/lib/src/utils/error_handler.dart.hbs +14 -0
- package/templates/base/lib/src/utils/failure.dart.hbs +30 -0
- package/templates/base/lib/src/utils/input_formatters.dart.hbs +27 -0
- package/templates/base/lib/src/utils/logger.dart.hbs +37 -0
- package/templates/base/lib/src/utils/platform_info.dart.hbs +13 -0
- package/templates/base/lib/src/utils/task_runner.dart.hbs +42 -0
- package/templates/base/lib/src/utils/typedefs.dart.hbs +6 -0
- package/templates/base/lib/src/utils/utils.dart.hbs +9 -0
- package/templates/base/pubspec.yaml.hbs +256 -0
- package/templates/base/test/widget_test.dart.hbs +56 -0
- package/templates/overlays/architecture/clean/architecture.md +6 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/architecture.md +5 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/architecture.md +6 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/datasources/local/.gitkeep +0 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/datasources/remote/.gitkeep +0 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/domain/entities/user.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/domain/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/domain/usecases/auth/.gitkeep +0 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@auth_view_model.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/home/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/onboarding/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/widgets/.gitkeep +0 -0
- package/templates/overlays/architecture/mvc/architecture.md +5 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/services/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/services/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/auth/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/auth/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/auth/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/home/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/onboarding/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/architecture.md +6 -0
- package/templates/overlays/architecture/mvvm/lib/src/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/auth_view_model.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/home/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/onboarding/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/backend/appwrite/lib/src/services/(usesAppwriteAuth)@auth_service.dart.hbs +101 -0
- package/templates/overlays/backend/custom/lib/src/services/auth_service.dart.hbs +158 -0
- package/templates/overlays/backend/firebase/lib/src/services/(usesFirebaseAuth)@auth_service.dart.hbs +96 -0
- package/templates/overlays/backend/supabase/lib/src/services/(usesSupabaseAuth)@auth_service.dart.hbs +97 -0
- package/templates/overlays/device/app_version_update/lib/src/services/(usesAppVersionUpdate)@version_update_service.dart.hbs +118 -0
- package/templates/overlays/device/device_info/lib/src/services/(usesDeviceInfoPlus)@device_info_service.dart.hbs +54 -0
- package/templates/overlays/extras/dotenv/.env.hbs +33 -0
- package/templates/overlays/extras/flavors/lib/src/flavors.dart.hbs +15 -0
- package/templates/overlays/extras/localization/assets/translations/en.json.hbs +47 -0
- package/templates/overlays/media/lib/src/services/(usesImagePicker,usesFilePicker)@media_service.dart.hbs +148 -0
- package/templates/overlays/networking/cached_image/lib/src/shared/widgets/app_cached_image.dart.hbs +160 -0
- package/templates/overlays/networking/dio/lib/src/services/(usesDio)@dio_service.dart.hbs +50 -0
- package/templates/overlays/networking/http/lib/src/services/(usesHttp)@http_service.dart.hbs +82 -0
- package/templates/overlays/storage/hive/lib/src/services/(usesHive)@hive_service.dart.hbs +59 -0
- package/templates/overlays/storage/secure_storage/lib/src/services/(usesSecureStorage)@secure_storage_service.dart.hbs +39 -0
- package/templates/overlays/storage/shared_preferences/lib/src/services/(usesSharedPreferences)@storage_service.dart.hbs +53 -0
- package/templates/overlays/utilities/geolocator/lib/src/services/(usesGeolocator)@location_service.dart.hbs +78 -0
- package/templates/overlays/utilities/path_provider/lib/src/services/(usesPathProvider)@path_service.dart.hbs +30 -0
- package/templates/overlays/utilities/permission_handler/lib/src/services/(usesPermissionHandler)@permission_service.dart.hbs +28 -0
- package/templates/overlays/utilities/permission_handler/lib/src/shared/hooks/use_permission.dart.hbs +44 -0
- package/templates/overlays/utilities/share_plus/lib/src/services/(usesSharePlus)@share_service.dart.hbs +22 -0
- package/templates/overlays/utilities/share_plus/lib/src/shared/hooks/use_share.dart.hbs +26 -0
- package/templates/overlays/utilities/url_launcher/lib/src/services/(usesUrlLauncher)@url_launcher_service.dart.hbs +37 -0
- package/templates/overlays/utilities/url_launcher/lib/src/shared/hooks/use_launch_url.dart.hbs +52 -0
- package/templates/partials/features/auth/auth_logic.hbs +611 -0
- package/templates/partials/features/auth/auth_repository.hbs +32 -0
- package/templates/partials/features/auth/auth_repository_impl.hbs +116 -0
- package/templates/partials/features/auth/forgot_password_screen.hbs +368 -0
- package/templates/partials/features/auth/login_screen.hbs +540 -0
- package/templates/partials/features/auth/session_provider.hbs +437 -0
- package/templates/partials/features/auth/signup_screen.hbs +511 -0
- package/templates/partials/features/auth/user_model.hbs +23 -0
- package/templates/partials/features/home/home_page.hbs +156 -0
- package/templates/partials/features/onboarding/onboarding_page.hbs +264 -0
- package/templates/partials/llm/add-feature-workflow.hbs +38 -0
- package/templates/partials/llm/architecture-rules.hbs +92 -0
- package/templates/partials/llm/backend-rules.hbs +30 -0
- package/templates/partials/llm/build-runner-note.hbs +15 -0
- package/templates/partials/llm/design-quick-ref.hbs +14 -0
- package/templates/partials/llm/design-quick-reference.hbs +14 -0
- package/templates/partials/llm/navigation-rules.hbs +27 -0
- package/templates/partials/llm/networking-rules.hbs +16 -0
- package/templates/partials/llm/packages-list.hbs +26 -0
- package/templates/partials/llm/services-conventions.hbs +20 -0
- package/templates/partials/llm/stack-summary.hbs +22 -0
- package/templates/partials/llm/state-management-rules.hbs +40 -0
- package/templates/partials/state_label.hbs +1 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import 'package:{{flags.appSnake}}/src/imports/imports.dart';
|
|
2
|
+
|
|
3
|
+
{{#if (eq flags.routerPackage "auto_route")}}
|
|
4
|
+
@RoutePage()
|
|
5
|
+
{{/if}}
|
|
6
|
+
{{#if flags.usesFlutterHooks}}
|
|
7
|
+
class OnboardingPage extends HookWidget {
|
|
8
|
+
const OnboardingPage({super.key});
|
|
9
|
+
|
|
10
|
+
@override
|
|
11
|
+
Widget build(BuildContext context) {
|
|
12
|
+
final theme = context.theme;
|
|
13
|
+
final colorScheme = theme.colorScheme;
|
|
14
|
+
final textTheme = theme.textTheme;
|
|
15
|
+
|
|
16
|
+
final pageController = usePageController();
|
|
17
|
+
final currentIndex = useState(0);
|
|
18
|
+
|
|
19
|
+
final List<Map<String, dynamic>> onboardingData = useMemoized(() => [
|
|
20
|
+
{
|
|
21
|
+
'title': {{#if flags.supportsLocalization}}'onboarding.onboarding_title_1'.tr(){{else}}'Your Journey,\nPerfectly Planned'{{/if}},
|
|
22
|
+
'subtitle':
|
|
23
|
+
{{#if flags.supportsLocalization}}'onboarding.onboarding_subtitle_1'.tr(){{else}}'Effortlessly create and organize your\ndream trips. Start exploring now!'{{/if}},
|
|
24
|
+
'pageWidget': const FlutterLogo(size: 200),
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
'title': {{#if flags.supportsLocalization}}'onboarding.onboarding_title_2'.tr(){{else}}'Discover\nFriends Nearby'{{/if}},
|
|
28
|
+
'subtitle':
|
|
29
|
+
{{#if flags.supportsLocalization}}'onboarding.onboarding_subtitle_2'.tr(){{else}}'See where your friends are traveling and\nexplore the world together.'{{/if}},
|
|
30
|
+
'pageWidget': const FlutterLogo(size: 200),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
'title': {{#if flags.supportsLocalization}}'onboarding.onboarding_title_3'.tr(){{else}}'Stay Updated\nwith Top Places'{{/if}},
|
|
34
|
+
'subtitle':
|
|
35
|
+
{{#if flags.supportsLocalization}}'onboarding.onboarding_subtitle_3'.tr(){{else}}'Find trending destinations and must-see attractions,\nall tailored to enhance your travel plans.'{{/if}},
|
|
36
|
+
'pageWidget': const FlutterLogo(size: 200),
|
|
37
|
+
},
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
void onGetStarted() {
|
|
41
|
+
// Navigate back or to home. For template purpose:
|
|
42
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
43
|
+
context.go(AppRoutes.login);
|
|
44
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
45
|
+
context.replaceRoute(const LoginRoute());
|
|
46
|
+
{{else}}
|
|
47
|
+
Navigator.pushReplacementNamed(context, AppRoutes.login);
|
|
48
|
+
{{/if}}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return _OnboardingView(
|
|
52
|
+
theme: theme,
|
|
53
|
+
colorScheme: colorScheme,
|
|
54
|
+
textTheme: textTheme,
|
|
55
|
+
pageController: pageController,
|
|
56
|
+
currentIndex: currentIndex.value,
|
|
57
|
+
onboardingData: onboardingData,
|
|
58
|
+
onPageChanged: (index) => currentIndex.value = index,
|
|
59
|
+
onGetStarted: onGetStarted,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
{{else}}
|
|
64
|
+
class OnboardingPage extends StatefulWidget {
|
|
65
|
+
const OnboardingPage({super.key});
|
|
66
|
+
|
|
67
|
+
@override
|
|
68
|
+
State<OnboardingPage> createState() => _OnboardingPageState();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
class _OnboardingPageState extends State<OnboardingPage> {
|
|
72
|
+
late final PageController _pageController;
|
|
73
|
+
int _currentIndex = 0;
|
|
74
|
+
|
|
75
|
+
late final List<Map<String, dynamic>> _onboardingData;
|
|
76
|
+
|
|
77
|
+
@override
|
|
78
|
+
void initState() {
|
|
79
|
+
super.initState();
|
|
80
|
+
_pageController = PageController();
|
|
81
|
+
_onboardingData = [
|
|
82
|
+
{
|
|
83
|
+
'title': {{#if flags.supportsLocalization}}'onboarding.onboarding_title_1'.tr(){{else}}'Your Journey,\nPerfectly Planned'{{/if}},
|
|
84
|
+
'subtitle':
|
|
85
|
+
{{#if flags.supportsLocalization}}'onboarding.onboarding_subtitle_1'.tr(){{else}}'Effortlessly create and organize your\ndream trips. Start exploring now!'{{/if}},
|
|
86
|
+
'pageWidget': const FlutterLogo(size: 200),
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
'title': {{#if flags.supportsLocalization}}'onboarding.onboarding_title_2'.tr(){{else}}'Discover\nFriends Nearby'{{/if}},
|
|
90
|
+
'subtitle':
|
|
91
|
+
{{#if flags.supportsLocalization}}'onboarding.onboarding_subtitle_2'.tr(){{else}}'See where your friends are traveling and\nexplore the world together.'{{/if}},
|
|
92
|
+
'pageWidget': const FlutterLogo(size: 200),
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
'title': {{#if flags.supportsLocalization}}'onboarding.onboarding_title_3'.tr(){{else}}'Stay Updated\nwith Top Places'{{/if}},
|
|
96
|
+
'subtitle':
|
|
97
|
+
{{#if flags.supportsLocalization}}'onboarding.onboarding_subtitle_3'.tr(){{else}}'Find trending destinations and must-see attractions,\nall tailored to enhance your travel plans.'{{/if}},
|
|
98
|
+
'pageWidget': const FlutterLogo(size: 200),
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@override
|
|
104
|
+
void dispose() {
|
|
105
|
+
_pageController.dispose();
|
|
106
|
+
super.dispose();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
void _onGetStarted() {
|
|
110
|
+
// Navigate back or to home. For template purpose:
|
|
111
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
112
|
+
context.go(AppRoutes.login);
|
|
113
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
114
|
+
context.replaceRoute(const LoginRoute());
|
|
115
|
+
{{else}}
|
|
116
|
+
Navigator.pushReplacementNamed(context, AppRoutes.login);
|
|
117
|
+
{{/if}}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@override
|
|
121
|
+
Widget build(BuildContext context) {
|
|
122
|
+
final theme = context.theme;
|
|
123
|
+
final colorScheme = theme.colorScheme;
|
|
124
|
+
final textTheme = theme.textTheme;
|
|
125
|
+
|
|
126
|
+
return _OnboardingView(
|
|
127
|
+
theme: theme,
|
|
128
|
+
colorScheme: colorScheme,
|
|
129
|
+
textTheme: textTheme,
|
|
130
|
+
pageController: _pageController,
|
|
131
|
+
currentIndex: _currentIndex,
|
|
132
|
+
onboardingData: _onboardingData,
|
|
133
|
+
onPageChanged: (index) => setState(() => _currentIndex = index),
|
|
134
|
+
onGetStarted: _onGetStarted,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
{{/if}}
|
|
139
|
+
|
|
140
|
+
class _OnboardingView extends StatelessWidget {
|
|
141
|
+
const _OnboardingView({
|
|
142
|
+
required this.theme,
|
|
143
|
+
required this.colorScheme,
|
|
144
|
+
required this.textTheme,
|
|
145
|
+
required this.pageController,
|
|
146
|
+
required this.currentIndex,
|
|
147
|
+
required this.onboardingData,
|
|
148
|
+
required this.onPageChanged,
|
|
149
|
+
required this.onGetStarted,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
final ThemeData theme;
|
|
153
|
+
final ColorScheme colorScheme;
|
|
154
|
+
final TextTheme textTheme;
|
|
155
|
+
final PageController pageController;
|
|
156
|
+
final int currentIndex;
|
|
157
|
+
final List<Map<String, dynamic>> onboardingData;
|
|
158
|
+
final ValueChanged<int> onPageChanged;
|
|
159
|
+
final VoidCallback onGetStarted;
|
|
160
|
+
|
|
161
|
+
@override
|
|
162
|
+
Widget build(BuildContext context) {
|
|
163
|
+
return Scaffold(
|
|
164
|
+
backgroundColor: colorScheme.surface,
|
|
165
|
+
body: SafeArea(
|
|
166
|
+
child: Column(
|
|
167
|
+
children: [
|
|
168
|
+
// Top branding
|
|
169
|
+
Padding(
|
|
170
|
+
padding: EdgeInsets.only(
|
|
171
|
+
top: {{res 'AppSpacing.lg' 'h' flags.usesScreenutil}},
|
|
172
|
+
bottom: {{res 'AppSpacing.md' 'h' flags.usesScreenutil}},
|
|
173
|
+
),
|
|
174
|
+
child: Text(
|
|
175
|
+
'FlutterInit.',
|
|
176
|
+
style: textTheme.titleLarge?.copyWith(
|
|
177
|
+
fontWeight: FontWeight.w900,
|
|
178
|
+
color: colorScheme.onSurface,
|
|
179
|
+
fontSize: {{res 22 'sp' flags.usesScreenutil}},
|
|
180
|
+
),
|
|
181
|
+
),
|
|
182
|
+
),
|
|
183
|
+
|
|
184
|
+
// PageView
|
|
185
|
+
Expanded(
|
|
186
|
+
child: PageView.builder(
|
|
187
|
+
controller: pageController,
|
|
188
|
+
itemCount: onboardingData.length,
|
|
189
|
+
onPageChanged: onPageChanged,
|
|
190
|
+
itemBuilder: (context, index) {
|
|
191
|
+
return Column(
|
|
192
|
+
children: [
|
|
193
|
+
// Dynamic Illustration Section
|
|
194
|
+
Expanded(
|
|
195
|
+
child: Center(
|
|
196
|
+
child: Padding(
|
|
197
|
+
padding: EdgeInsets.symmetric(
|
|
198
|
+
horizontal: {{res 'AppSpacing.lg' 'w' flags.usesScreenutil}},
|
|
199
|
+
),
|
|
200
|
+
child: onboardingData[index]['pageWidget'] as Widget,
|
|
201
|
+
),
|
|
202
|
+
),
|
|
203
|
+
),
|
|
204
|
+
|
|
205
|
+
// Text Section
|
|
206
|
+
Padding(
|
|
207
|
+
padding: EdgeInsets.symmetric(
|
|
208
|
+
horizontal: {{res 'AppSpacing.xl' 'w' flags.usesScreenutil}},
|
|
209
|
+
),
|
|
210
|
+
child: Column(
|
|
211
|
+
children: [
|
|
212
|
+
Text(
|
|
213
|
+
onboardingData[index]['title'] as String,
|
|
214
|
+
textAlign: TextAlign.center,
|
|
215
|
+
style: textTheme.headlineMedium?.copyWith(
|
|
216
|
+
fontWeight: FontWeight.w700,
|
|
217
|
+
color: colorScheme.onSurface,
|
|
218
|
+
height: 1.2,
|
|
219
|
+
fontSize: {{res 24 'sp' flags.usesScreenutil}},
|
|
220
|
+
),
|
|
221
|
+
),
|
|
222
|
+
SizedBox(height: {{res 'AppSpacing.md' 'h' flags.usesScreenutil}}),
|
|
223
|
+
Text(
|
|
224
|
+
onboardingData[index]['subtitle'] as String,
|
|
225
|
+
textAlign: TextAlign.center,
|
|
226
|
+
style: textTheme.bodyMedium?.copyWith(
|
|
227
|
+
color: colorScheme.onSurfaceVariant,
|
|
228
|
+
height: 1.5,
|
|
229
|
+
fontSize: {{res 14 'sp' flags.usesScreenutil}},
|
|
230
|
+
),
|
|
231
|
+
),
|
|
232
|
+
],
|
|
233
|
+
),
|
|
234
|
+
),
|
|
235
|
+
{{#if flags.usesScreenutil}}SizedBox(height: 40.h){{else}}const SizedBox(height: 40){{/if}},
|
|
236
|
+
],
|
|
237
|
+
);
|
|
238
|
+
},
|
|
239
|
+
),
|
|
240
|
+
),
|
|
241
|
+
|
|
242
|
+
// Bottom Section: Dots and Button
|
|
243
|
+
Padding(
|
|
244
|
+
padding: EdgeInsets.all({{res 'AppSpacing.xl' 'w' flags.usesScreenutil}}),
|
|
245
|
+
child: Column(
|
|
246
|
+
children: [
|
|
247
|
+
{{#if flags.usesScreenutil}}SizedBox(height: AppSpacing.xl){{else}}const SizedBox(height: 32){{/if}},
|
|
248
|
+
// Get Started Button
|
|
249
|
+
AppButton(
|
|
250
|
+
label: {{#if flags.supportsLocalization}}'shared.get_started'.tr(){{else}}'Get Started'{{/if}},
|
|
251
|
+
onPressed: onGetStarted,
|
|
252
|
+
variant: ButtonVariant.primary,
|
|
253
|
+
width: ButtonSize.medium,
|
|
254
|
+
),
|
|
255
|
+
{{#if flags.usesScreenutil}}SizedBox(height: AppSpacing.md){{else}}const SizedBox(height: 16){{/if}},
|
|
256
|
+
],
|
|
257
|
+
),
|
|
258
|
+
),
|
|
259
|
+
],
|
|
260
|
+
),
|
|
261
|
+
),
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## How to add a new feature
|
|
2
|
+
|
|
3
|
+
{{#if (eq architecture "clean")}}
|
|
4
|
+
1. Create domain entity and repository contract under `lib/src/features/<feature>/domain/`.
|
|
5
|
+
2. Add use case(s) in `domain/usecases/` (single responsibility).
|
|
6
|
+
3. Add data model, datasource, and repository implementation under `data/`.
|
|
7
|
+
4. Wire state ({{stateManagement}}) under `presentation/`.
|
|
8
|
+
5. Build screens and widgets under `presentation/`.
|
|
9
|
+
6. Register the route in `lib/src/routing/app_router.dart`.
|
|
10
|
+
7. Export new public API only through existing barrel files if needed.
|
|
11
|
+
{{/if}}
|
|
12
|
+
|
|
13
|
+
{{#if (eq architecture "feature-first")}}
|
|
14
|
+
1. Create `lib/src/features/<feature>/` with model, service, state, and view folders as needed.
|
|
15
|
+
2. Keep all feature code inside that folder — use `shared/` only for truly global UI/utils.
|
|
16
|
+
3. Register the route in `lib/src/routing/app_router.dart`.
|
|
17
|
+
{{/if}}
|
|
18
|
+
|
|
19
|
+
{{#if (eq architecture "mvc")}}
|
|
20
|
+
1. Add models under `lib/src/models/` (or feature subfolder if you introduce one).
|
|
21
|
+
2. Add or extend services in `lib/src/services/`.
|
|
22
|
+
3. Add a controller under `lib/src/controllers/<feature>/`.
|
|
23
|
+
4. Add views under `lib/src/views/<feature>/`.
|
|
24
|
+
5. Register the route in `lib/src/routing/app_router.dart`.
|
|
25
|
+
{{/if}}
|
|
26
|
+
|
|
27
|
+
{{#if (eq architecture "mvvm")}}
|
|
28
|
+
1. Add data models and repository under `lib/src/data/`.
|
|
29
|
+
2. Add UI, view model / provider / bloc under `lib/src/ui/<feature>/`.
|
|
30
|
+
3. Register the route in `lib/src/routing/app_router.dart`.
|
|
31
|
+
{{/if}}
|
|
32
|
+
|
|
33
|
+
{{#if (eq architecture "layer-first")}}
|
|
34
|
+
1. Add domain entity and repository contract under `lib/src/domain/`.
|
|
35
|
+
2. Implement datasource/model/repository under `lib/src/data/`.
|
|
36
|
+
3. Add presentation (screens + state) under `lib/src/presentation/`.
|
|
37
|
+
4. Register the route in `lib/src/routing/app_router.dart`.
|
|
38
|
+
{{/if}}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
## Architecture (`{{architecture}}`)
|
|
2
|
+
|
|
3
|
+
{{#if (eq architecture "clean")}}
|
|
4
|
+
```text
|
|
5
|
+
lib/src/
|
|
6
|
+
├── features/<feature>/
|
|
7
|
+
│ ├── data/ # datasources, models, repository impls
|
|
8
|
+
│ ├── domain/ # entities, repo contracts, use cases
|
|
9
|
+
│ └── presentation/ # screens, widgets, state ({{stateManagement}})
|
|
10
|
+
├── routing/
|
|
11
|
+
├── services/
|
|
12
|
+
├── shared/
|
|
13
|
+
└── theme/
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Rules**
|
|
17
|
+
|
|
18
|
+
- `domain/` is pure Dart — no Flutter imports, no imports from `data/`.
|
|
19
|
+
- `data/` implements contracts from `domain/` — never the reverse.
|
|
20
|
+
- Entities are not models — no `fromJson`/`toJson` on domain entities.
|
|
21
|
+
- Use cases expose a single responsibility (typically one public `call()`).
|
|
22
|
+
- `presentation/` talks to use cases or state layer — not datasources directly.
|
|
23
|
+
{{/if}}
|
|
24
|
+
|
|
25
|
+
{{#if (eq architecture "feature-first")}}
|
|
26
|
+
```text
|
|
27
|
+
lib/src/
|
|
28
|
+
├── features/<feature>/ # model, service, state, view per feature
|
|
29
|
+
├── shared/ # cross-feature widgets & utils only
|
|
30
|
+
├── routing/
|
|
31
|
+
├── services/
|
|
32
|
+
└── theme/
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Rules**
|
|
36
|
+
|
|
37
|
+
- Each feature is self-contained — no imports from another feature's internals.
|
|
38
|
+
- Shared code lives only under `lib/src/shared/`.
|
|
39
|
+
{{/if}}
|
|
40
|
+
|
|
41
|
+
{{#if (eq architecture "mvc")}}
|
|
42
|
+
```text
|
|
43
|
+
lib/src/
|
|
44
|
+
├── controllers/ # state & orchestration ({{stateManagement}})
|
|
45
|
+
├── models/
|
|
46
|
+
├── services/ # repositories & API access
|
|
47
|
+
├── views/ # screens & widgets
|
|
48
|
+
├── routing/
|
|
49
|
+
└── theme/
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Rules**
|
|
53
|
+
|
|
54
|
+
- Views only talk to controllers — no direct service calls from widgets.
|
|
55
|
+
- Controllers orchestrate services — no Flutter widget imports in controllers.
|
|
56
|
+
- One controller per screen or cohesive flow.
|
|
57
|
+
{{/if}}
|
|
58
|
+
|
|
59
|
+
{{#if (eq architecture "mvvm")}}
|
|
60
|
+
```text
|
|
61
|
+
lib/src/
|
|
62
|
+
├── ui/ # screens, widgets, state ({{stateManagement}})
|
|
63
|
+
├── data/ # models, repository impls
|
|
64
|
+
├── routing/
|
|
65
|
+
├── services/
|
|
66
|
+
└── theme/
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Rules**
|
|
70
|
+
|
|
71
|
+
- UI layer binds to view models / providers / controllers under `ui/`.
|
|
72
|
+
- Data access goes through repositories in `data/` or `services/`.
|
|
73
|
+
- No business logic in widget `build()` methods.
|
|
74
|
+
{{/if}}
|
|
75
|
+
|
|
76
|
+
{{#if (eq architecture "layer-first")}}
|
|
77
|
+
```text
|
|
78
|
+
lib/src/
|
|
79
|
+
├── presentation/ # screens, providers/blocs, widgets
|
|
80
|
+
├── domain/ # entities, repo contracts
|
|
81
|
+
├── data/ # models, datasources, repository impls
|
|
82
|
+
├── routing/
|
|
83
|
+
├── services/
|
|
84
|
+
└── theme/
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Rules**
|
|
88
|
+
|
|
89
|
+
- `domain/` has no Flutter or `data/` imports.
|
|
90
|
+
- `data/` implements `domain/` contracts only.
|
|
91
|
+
- `presentation/` depends on domain abstractions — not concrete datasources.
|
|
92
|
+
{{/if}}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
## Backend ({{backend.provider}})
|
|
2
|
+
|
|
3
|
+
{{#if flags.usesFirebase}}
|
|
4
|
+
- All Firebase access goes through `lib/src/services/` and repository/datasource layers — never from widgets.
|
|
5
|
+
- Use `FirebaseAuth` / SDK instances via existing app initialization in `lib/main.dart` — do not re-initialize Firebase in features.
|
|
6
|
+
{{#if flags.usesFirebaseAuth}}- Auth: email/Google/phone options are pre-wired per generator config.{{/if}}
|
|
7
|
+
{{#if flags.usesFirebaseFirestore}}- Firestore: keep security rules enabled; map errors to domain failures in the data layer.{{/if}}
|
|
8
|
+
{{#if flags.usesFirebaseStorage}}- Storage: upload/download via repository or service abstractions.{{/if}}
|
|
9
|
+
- Native config: place `google-services.json` and `GoogleService-Info.plist` per **SETUP.md** — do not commit secrets.
|
|
10
|
+
{{/if}}
|
|
11
|
+
|
|
12
|
+
{{#if flags.usesSupabase}}
|
|
13
|
+
- All Supabase calls go through services/repositories — not from UI.
|
|
14
|
+
- Assume Row Level Security on tables — never bypass RLS in client code.
|
|
15
|
+
- Session persistence is handled by the SDK — avoid manual token caching.
|
|
16
|
+
- Configure URL and anon key via `.env` / **SETUP.md** when `usesDotenv` is enabled.
|
|
17
|
+
{{/if}}
|
|
18
|
+
|
|
19
|
+
{{#if flags.usesAppwrite}}
|
|
20
|
+
- Use the configured Appwrite client from app config/services — do not instantiate ad hoc clients in widgets.
|
|
21
|
+
- Auth and database flags follow generator options — extend services, not screens.
|
|
22
|
+
{{/if}}
|
|
23
|
+
|
|
24
|
+
{{#if flags.usesCustomBackend}}
|
|
25
|
+
- HTTP/Dio client is configured in `lib/src/config/app_config.dart`.
|
|
26
|
+
- API calls belong in `lib/src/services/` (e.g. auth service) using the shared client.
|
|
27
|
+
- Base URL comes from environment / config — see **SETUP.md**.
|
|
28
|
+
{{/if}}
|
|
29
|
+
|
|
30
|
+
For console setup (keys, native files, env), follow **[SETUP.md](SETUP.md)** — do not duplicate platform steps here.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{{#if (or flags.isMobX (eq flags.routerPackage "auto_route") flags.usesHive flags.usesFirebase)}}
|
|
2
|
+
### Code generation
|
|
3
|
+
|
|
4
|
+
This stack uses `build_runner` ({{#if flags.usesHive}}Hive, {{/if}}{{#if flags.isMobX}}MobX, {{/if}}{{#if (eq flags.routerPackage "auto_route")}}Auto Route, {{/if}}{{#if flags.usesFirebase}}Firebase, {{/if}}etc.):
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
dart run build_runner build --delete-conflicting-outputs
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Re-run after changing generated routes, MobX stores, Hive adapters, or Firebase-related generated code.
|
|
11
|
+
{{else}}
|
|
12
|
+
### Code generation
|
|
13
|
+
|
|
14
|
+
No `build_runner` step is required for the selected stack.
|
|
15
|
+
{{/if}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## Design system (summary)
|
|
2
|
+
|
|
3
|
+
Full reference: **[DESIGN.md](DESIGN.md)**
|
|
4
|
+
|
|
5
|
+
- **Theme:** `lib/src/theme/theme.dart` — global `ThemeData` only; no per-widget theme overrides.
|
|
6
|
+
- **Preset:** `{{theme.preset}}`{{#if flags.isCupertino}} (Cupertino){{/if}}{{#if theme.primaryColor}} · seed `{{theme.primaryColor}}`{{/if}}
|
|
7
|
+
- **Dark mode:** {{#if flags.hasDarkMode}}on{{#if theme.darkMode.system}} (system){{/if}}{{else}}off (light only){{/if}}
|
|
8
|
+
- **Colors:** `context.colors` (Material roles), `context.appColors` (`success`, `warning`, `info`)
|
|
9
|
+
- **Typography:** `context.textTheme` / `context.typography` — no raw `fontFamily` in widgets
|
|
10
|
+
{{#if flags.hasCustomFonts}}- **Fonts:** primary `{{flags.primaryFontFamily}}` (see `lib/src/theme/text_theme.dart`){{/if}}
|
|
11
|
+
- **Tokens:** `AppSpacing`, `AppBorders`, `AppShadows`, `AppDurations`, `AppCurves` from `lib/src/theme/theme_constants.dart`
|
|
12
|
+
- **Extensions:** `context_extension.dart` — `width`, `height`, `isDarkMode`, `showAppDialog`, `showTypedSnackBar`
|
|
13
|
+
{{#if flags.usesScreenutil}}- **ScreenUtil:** baseline 390×844; `.w` `.h` `.r` `.sp`; wrapper already in app — no second `ScreenUtilInit`{{else}}- **Layout:** `MediaQuery` / `LayoutBuilder` / `Flexible` — no ScreenUtil{{/if}}
|
|
14
|
+
- **Widgets:** reusable UI in `lib/src/shared/widgets/`; use tokens not magic numbers
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## Design system (summary)
|
|
2
|
+
|
|
3
|
+
Full reference: **[DESIGN.md](DESIGN.md)**
|
|
4
|
+
|
|
5
|
+
- **Theme:** `lib/src/theme/theme.dart` — no per-widget `ThemeData` overrides
|
|
6
|
+
- **Tokens:** `package:{{flags.appSlug}}/src/theme/theme_constants.dart` → `AppSpacing`, `AppBorders`, `AppShadows`, `AppDurations`, `AppCurves`
|
|
7
|
+
- **Colors:** `context.colors` (Material roles); `context.appColors` (`success`, `warning`, `info` in `color_schemes.dart`)
|
|
8
|
+
- **Typography:** `context.textTheme` / `context.typography` — no raw `fontFamily` in widgets
|
|
9
|
+
{{#if theme.primaryColor}}- **Seed color:** `{{theme.primaryColor}}`{{/if}}
|
|
10
|
+
{{#if flags.hasCustomFonts}}- **Primary font:** {{flags.primaryFontFamily}}{{/if}}
|
|
11
|
+
{{#if flags.hasDarkMode}}- **Dark mode:** enabled{{#if theme.darkMode.system}} (system){{/if}} — use semantic colors, not `Colors.white`/`Colors.black`{{/if}}
|
|
12
|
+
{{#if flags.usesScreenutil}}- **ScreenUtil:** baseline 390×844; `.w` `.h` `.r` `.sp`; single `ScreenUtilInit` in app wrapper{{else}}- **Layout:** `MediaQuery` / `LayoutBuilder` / `Flexible` — no ScreenUtil{{/if}}
|
|
13
|
+
- **Extensions:** `lib/src/extensions/context_extension.dart` — `showAppDialog`, `showTypedSnackBar`, `width`/`height`
|
|
14
|
+
- **Widgets:** reusable UI in `lib/src/shared/widgets/` only
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
## Navigation
|
|
2
|
+
|
|
3
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
4
|
+
- All routes are defined in `lib/src/routing/app_router.dart` — do not scatter route tables elsewhere.
|
|
5
|
+
- Prefer typed/named routes from the central config — avoid hard-coded path strings in widgets when a named route exists.
|
|
6
|
+
- `context.go()` replaces the stack; `context.push()` pushes on top.
|
|
7
|
+
- Redirects and guards belong in the router configuration, not inside individual screens.
|
|
8
|
+
{{/if}}
|
|
9
|
+
|
|
10
|
+
{{#if (eq flags.routerPackage "auto_route")}}
|
|
11
|
+
- Annotate routable pages with `@RoutePage()`.
|
|
12
|
+
- Routes are code-generated — run `build_runner` after adding, renaming, or removing pages.
|
|
13
|
+
- Use `context.router.push()`, `context.router.replace()`, and `context.router.pop()` for navigation.
|
|
14
|
+
- Route definitions live in `lib/src/routing/app_router.dart` and generated `app_router.gr.dart`.
|
|
15
|
+
{{/if}}
|
|
16
|
+
|
|
17
|
+
{{#if (eq flags.routerPackage "getx")}}
|
|
18
|
+
- Pages and bindings are registered via `AppRouter.getPages` in `lib/src/routing/app_router.dart`.
|
|
19
|
+
- Use GetX navigation APIs consistent with the existing router setup.
|
|
20
|
+
- Do not mix in a second routing package alongside GetX pages.
|
|
21
|
+
{{/if}}
|
|
22
|
+
|
|
23
|
+
{{#unless flags.routerPackage}}
|
|
24
|
+
- Imperative navigation uses `AppRouter.onGenerateRoute` in `lib/src/routing/app_router.dart`.
|
|
25
|
+
- Use `Navigator` APIs / extension helpers on `BuildContext` from `context_extension.dart`.
|
|
26
|
+
- Register new screens in the central router — not ad hoc `MaterialPageRoute` factories in widgets.
|
|
27
|
+
{{/unless}}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Networking
|
|
2
|
+
|
|
3
|
+
{{#if flags.usesDio}}
|
|
4
|
+
- Use the shared `Dio` instance from `lib/src/config/app_config.dart` — never `Dio()` inside a widget or screen.
|
|
5
|
+
- Extend or use existing services under `lib/src/services/` for HTTP calls.
|
|
6
|
+
- Map transport errors to `Failure` / `FutureEither` results via `runTask()` — do not leak raw `DioException` to UI.
|
|
7
|
+
{{/if}}
|
|
8
|
+
|
|
9
|
+
{{#if (and flags.usesHttp (not flags.usesDio))}}
|
|
10
|
+
- Use the HTTP service exported from `lib/src/services/` — do not call `http.get` directly from presentation code.
|
|
11
|
+
- Handle timeouts and socket errors explicitly in the service layer.
|
|
12
|
+
{{/if}}
|
|
13
|
+
|
|
14
|
+
{{#unless (or flags.usesDio flags.usesHttp)}}
|
|
15
|
+
- No HTTP client package is enabled — use mock/local data patterns already in the template or add Dio/HTTP via `pubspec.yaml` deliberately.
|
|
16
|
+
{{/unless}}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
## Key packages
|
|
2
|
+
|
|
3
|
+
{{#if (eq flags.routerPackage "go_router")}}- `go_router` — declarative routing{{/if}}
|
|
4
|
+
{{#if (eq flags.routerPackage "auto_route")}}- `auto_route` — code-generated routing{{/if}}
|
|
5
|
+
{{#if flags.isGetX}}- `get` — state & navigation{{/if}}
|
|
6
|
+
{{#if flags.isRiverpod}}- `flutter_riverpod` — state management{{/if}}
|
|
7
|
+
{{#if flags.isProvider}}- `provider` — state management{{/if}}
|
|
8
|
+
{{#if flags.isBloc}}- `flutter_bloc` — state management{{/if}}
|
|
9
|
+
{{#if flags.isMobX}}- `mobx`, `flutter_mobx` — state management{{/if}}
|
|
10
|
+
{{#if flags.usesFirebase}}- `firebase_core`{{#if flags.usesFirebaseAuth}}, `firebase_auth`{{/if}}{{#if flags.usesFirebaseFirestore}}, `cloud_firestore`{{/if}}{{#if flags.usesFirebaseStorage}}, `firebase_storage`{{/if}}{{/if}}
|
|
11
|
+
{{#if flags.usesSupabase}}- `supabase_flutter`{{/if}}
|
|
12
|
+
{{#if flags.usesAppwrite}}- `appwrite`{{/if}}
|
|
13
|
+
{{#if flags.usesDio}}- `dio`{{/if}}
|
|
14
|
+
{{#if (and flags.usesHttp (not flags.usesDio))}}- `http`{{/if}}
|
|
15
|
+
{{#if flags.usesHive}}- `hive`, `hive_flutter`{{/if}}
|
|
16
|
+
{{#if flags.usesSharedPreferences}}- `shared_preferences`{{/if}}
|
|
17
|
+
{{#if flags.usesSecureStorage}}- `flutter_secure_storage`{{/if}}
|
|
18
|
+
{{#if flags.usesCachedNetworkImage}}- `cached_network_image`{{/if}}
|
|
19
|
+
{{#if flags.usesGeolocator}}- `geolocator`{{/if}}
|
|
20
|
+
{{#if flags.usesImagePicker}}- `image_picker`{{/if}}
|
|
21
|
+
{{#if flags.usesFilePicker}}- `file_picker`{{/if}}
|
|
22
|
+
{{#if flags.supportsLocalization}}- `easy_localization`{{/if}}
|
|
23
|
+
{{#if flags.usesScreenutil}}- `flutter_screenutil`{{/if}}
|
|
24
|
+
{{#if flags.usesFlutterHooks}}- `flutter_hooks`{{/if}}
|
|
25
|
+
{{#if flags.usesDotenv}}- `flutter_dotenv`{{/if}}
|
|
26
|
+
{{#if flags.usesSkeletonizer}}- `skeletonizer`{{/if}}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## Services & shared conventions
|
|
2
|
+
|
|
3
|
+
- Services are singletons with `ClassName.instance`, returning `FutureEither<T>` via `runTask()`.
|
|
4
|
+
- Never pass `BuildContext` into services — use `rootContext` from the global navigator helper when UI is required.
|
|
5
|
+
- Logging: `AppLogger`; user feedback: `showGlobalToast()`; dialogs: `showAppDialog()` / `context.showAppDialog()`.
|
|
6
|
+
- Primary import barrel: `package:{{flags.appSlug}}/src/imports/imports.dart`.
|
|
7
|
+
- File names: `snake_case.dart`; classes: `PascalCase`; private members: `_camelCase`.
|
|
8
|
+
- Prefer `const` constructors where possible; avoid `dynamic` without justification.
|
|
9
|
+
- No empty `catch` blocks — log, map to failure, or rethrow.
|
|
10
|
+
- Do not add packages that duplicate existing stack choices (routing, state, backend).
|
|
11
|
+
|
|
12
|
+
### Dart / Flutter anti-patterns
|
|
13
|
+
|
|
14
|
+
- No business logic in widget `build()` methods.
|
|
15
|
+
- No direct backend or network calls from presentation widgets.
|
|
16
|
+
{{#if flags.isRiverpod}}- Do not use `ref.read` inside `build()`.{{/if}}
|
|
17
|
+
{{#if flags.isBloc}}- Do not put heavy logic inside bloc event handlers — delegate outward.{{/if}}
|
|
18
|
+
{{#if flags.isProvider}}- Do not use `context.watch` inside callbacks.{{/if}}
|
|
19
|
+
{{#if flags.isGetX}}- Do not mix GetX routing with GoRouter/AutoRoute in the same app.{{/if}}
|
|
20
|
+
{{#if flags.isMobX}}- Do not mutate `@observable` fields outside `@action` methods.{{/if}}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Project
|
|
2
|
+
|
|
3
|
+
**{{appName}}**{{#if description}} — {{description}}{{/if}}
|
|
4
|
+
|
|
5
|
+
Generated by [FlutterInit](https://flutterinit.com). Package: `{{packageId}}`.
|
|
6
|
+
|
|
7
|
+
### Stack
|
|
8
|
+
|
|
9
|
+
| Area | Choice |
|
|
10
|
+
|------|--------|
|
|
11
|
+
| Architecture | `{{architecture}}` |
|
|
12
|
+
| State management | `{{stateManagement}}` |
|
|
13
|
+
| Navigation | `{{navigation}}` |
|
|
14
|
+
| Backend | `{{backend.provider}}` |
|
|
15
|
+
| Networking | {{#if flags.usesDio}}Dio{{else if flags.usesHttp}}HTTP{{else}}—{{/if}} |
|
|
16
|
+
| Local storage | {{#if flags.usesHive}}Hive{{/if}}{{#if (and flags.usesHive flags.usesSharedPreferences)}}, {{/if}}{{#if flags.usesSharedPreferences}}SharedPreferences{{/if}}{{#if (and (or flags.usesHive flags.usesSharedPreferences) flags.usesSecureStorage)}}, {{/if}}{{#if flags.usesSecureStorage}}Secure storage{{/if}}{{#unless (or flags.usesHive flags.usesSharedPreferences flags.usesSecureStorage)}}—{{/unless}} |
|
|
17
|
+
| Theme preset | `{{theme.preset}}` |
|
|
18
|
+
| Dark mode | {{#if flags.hasDarkMode}}enabled{{#if theme.darkMode.system}} (follows system){{/if}}{{else}}light only{{/if}} |
|
|
19
|
+
| ScreenUtil | {{#if flags.usesScreenutil}}yes{{else}}no{{/if}} |
|
|
20
|
+
| Localization | {{#if flags.supportsLocalization}}`easy_localization` ({{#each flags.supportedLocales}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}){{else}}disabled{{/if}} |
|
|
21
|
+
| Flutter Hooks | {{#if flags.usesFlutterHooks}}enabled{{else}}disabled{{/if}} |
|
|
22
|
+
| Dotenv | {{#if flags.usesDotenv}}enabled{{else}}disabled{{/if}} |
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
## State management ({{stateManagement}})
|
|
2
|
+
|
|
3
|
+
{{#if flags.isRiverpod}}
|
|
4
|
+
- Use `ConsumerWidget` / `ConsumerStatefulWidget` where reactive state is needed.
|
|
5
|
+
- Providers live next to features (see overlay paths under `presentation/providers/` or equivalent).
|
|
6
|
+
- `ref.watch` inside `build()`; `ref.read` inside callbacks and one-off actions — never `ref.read` in `build()`.
|
|
7
|
+
- Do not nest a second `ProviderScope` — one at app root is already configured.
|
|
8
|
+
- This project does **not** use `@riverpod` / `riverpod_generator` — define providers manually.
|
|
9
|
+
{{/if}}
|
|
10
|
+
|
|
11
|
+
{{#if flags.isBloc}}
|
|
12
|
+
- Events and states are immutable — prefer `const` constructors.
|
|
13
|
+
- `BlocBuilder` for UI rebuilds; `BlocListener` for side effects; `BlocConsumer` when both are needed.
|
|
14
|
+
- Keep handlers thin — delegate to use cases, repositories, or services.
|
|
15
|
+
- One bloc per feature flow — do not share blocs across unrelated features.
|
|
16
|
+
{{/if}}
|
|
17
|
+
|
|
18
|
+
{{#if flags.isProvider}}
|
|
19
|
+
- Call `notifyListeners()` after every state change in `ChangeNotifier`s.
|
|
20
|
+
- `context.watch` in `build()`; `context.read` in callbacks — never reversed.
|
|
21
|
+
- Scope providers at the appropriate subtree — not everything belongs at app root.
|
|
22
|
+
{{/if}}
|
|
23
|
+
|
|
24
|
+
{{#if flags.isGetX}}
|
|
25
|
+
- Controllers extend `GetxController`; reactive fields use `.obs` with `Obx()`.
|
|
26
|
+
- Register controllers via bindings / route setup — avoid inline `Get.put()` inside widgets.
|
|
27
|
+
- `GetMaterialApp` is configured when navigation uses GetX — do not add a second material app wrapper.
|
|
28
|
+
{{/if}}
|
|
29
|
+
|
|
30
|
+
{{#if flags.isMobX}}
|
|
31
|
+
- Annotate state with `@observable`; mutations with `@action`; derived values with `@computed`.
|
|
32
|
+
- Wrap reactive UI in `Observer`.
|
|
33
|
+
- Run `dart run build_runner build --delete-conflicting-outputs` after changing any store.
|
|
34
|
+
{{/if}}
|
|
35
|
+
|
|
36
|
+
{{#if flags.isNoneState}}
|
|
37
|
+
- Session and feature state use manager / `ChangeNotifier` classes in architecture overlay paths.
|
|
38
|
+
- Keep state classes free of widget imports.
|
|
39
|
+
- Prefer explicit loading/error fields over silent failures.
|
|
40
|
+
{{/if}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
State: {{stateManagement}}
|