Feature: Add feature toggles and settings for modular features (e.g., Car, Inventory), enhance navigation for mobile/desktop, and improve i18n integration.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import 'package:app/core/features/feature_controller.dart';
|
||||
import 'package:app/modules/settings/modules/app/model/feature_settings_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:app/core/i18n/translations.g.dart';
|
||||
|
||||
/// A dedicated section under "Einstellungen" to enable/disable features.
|
||||
/// You can link this screen from your existing Settings list.
|
||||
/// If you keep a single Settings page, render _FeatureSettingsSection in-place.
|
||||
class FeatureSettingsView extends StatelessWidget {
|
||||
const FeatureSettingsView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
final featureController = context.read<FeatureController>();
|
||||
final model = FeatureSettingsViewModel(featureController);
|
||||
|
||||
return ChangeNotifierProvider(
|
||||
create: (BuildContext context) => model,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(title: Text(t.settings.featureSettings)),
|
||||
body: const _FeatureSettingsSection(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// If you prefer to embed this into your existing AppSettingsView,
|
||||
/// use this widget directly inside your Settings ListView/CustomScrollView.
|
||||
class _FeatureSettingsSection extends StatelessWidget {
|
||||
const _FeatureSettingsSection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final controller = context.watch<FeatureController>();
|
||||
final states = controller.allStates;
|
||||
|
||||
return ListView.separated(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
itemCount: states.length,
|
||||
separatorBuilder: (_, __) => const Divider(height: 1),
|
||||
itemBuilder: (ctx, i) {
|
||||
final feature = states.keys.elementAt(i);
|
||||
final enabled = states[feature] ?? feature.defaultEnabled;
|
||||
|
||||
final icon = _iconFor(feature);
|
||||
|
||||
return SwitchListTile(
|
||||
value: enabled,
|
||||
secondary: Icon(icon),
|
||||
title: Text(feature.displayName(context)),
|
||||
subtitle: Text(feature.description(context)),
|
||||
onChanged: (v) => controller.setEnabled(feature, v),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
IconData _iconFor(AppFeature f) {
|
||||
switch (f) {
|
||||
case AppFeature.inventory:
|
||||
return Icons.inventory_2_outlined;
|
||||
case AppFeature.car:
|
||||
return Icons.directions_car;
|
||||
case AppFeature.household:
|
||||
return Icons.home_outlined;
|
||||
case AppFeature.reports:
|
||||
return Icons.bar_chart_outlined;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import 'package:app/core/features/feature_controller.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// Lightweight VM that wraps FeatureController for the Settings screen.
|
||||
/// Mirrors your other *ViewModel classes’ init pattern.
|
||||
class FeatureSettingsViewModel extends ChangeNotifier {
|
||||
FeatureSettingsViewModel(this._featureController);
|
||||
|
||||
final FeatureController _featureController;
|
||||
|
||||
Map<AppFeature, bool> get states => _featureController.allStates;
|
||||
|
||||
bool isEnabled(AppFeature f) => _featureController.isEnabled(f);
|
||||
|
||||
Future<void> toggle(AppFeature f, bool value) async {
|
||||
await _featureController.setEnabled(f, value);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Expose the controller to listen from the view if needed
|
||||
FeatureController get controller => _featureController;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:app/core/i18n/translations.g.dart';
|
||||
import 'package:app/core/ui/panel.dart';
|
||||
import 'package:app/modules/settings/modules/app/app_settings_view.dart';
|
||||
import 'package:app/modules/settings/modules/app/features_settings_view.dart';
|
||||
import 'package:app/modules/settings/modules/help/feedback_view.dart';
|
||||
import 'package:app/modules/settings/modules/help/help_view.dart';
|
||||
import 'package:app/modules/settings/modules/help/legal_view.dart';
|
||||
@@ -16,7 +17,7 @@ class SettingsView extends StatelessWidget {
|
||||
final t = Translations.of(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(t.settings.title)),
|
||||
// appBar: AppBar(title: Text(t.settings.title)),
|
||||
body: PanelNavigator(rootBuilder: (ctx) => _CategoryList()),
|
||||
);
|
||||
}
|
||||
@@ -64,6 +65,12 @@ class _CategoryList extends StatelessWidget {
|
||||
() => const AppSettingsView(),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
tile(
|
||||
Icons.tune,
|
||||
t.settings.featureSettings,
|
||||
() => const FeatureSettingsView(),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
_SectionHeader(t.settings.sections.account),
|
||||
tile(
|
||||
|
||||
Reference in New Issue
Block a user