bharat_erp/lib/modules/settings/presentation/screens/security_settings_screen.dart
2026-07-14 18:15:26 +05:30

197 lines
7.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../../core/constants/route_constants.dart';
import '../../../../shared/widgets/app_button.dart';
import '../../../../shared/widgets/app_text_field.dart';
import '../../domain/entities/app_settings.dart';
import '../providers/settings_provider.dart';
import '../widgets/settings_widgets.dart';
import '../../../../shared/widgets/app_toast.dart';
class SecuritySettingsScreen extends ConsumerStatefulWidget {
const SecuritySettingsScreen({super.key});
@override
ConsumerState<SecuritySettingsScreen> createState() =>
_SecuritySettingsScreenState();
}
class _SecuritySettingsScreenState extends ConsumerState<SecuritySettingsScreen> {
final _formKey = GlobalKey<FormState>();
late final TextEditingController _minPasswordController;
late final TextEditingController _passwordExpiryController;
late final TextEditingController _sessionTimeoutController;
late final TextEditingController _loginAttemptController;
late final TextEditingController _lockDurationController;
late final TextEditingController _ipWhitelistController;
late bool _otpEnabled;
late bool _mfaEnabled;
late bool _autoLogout;
late bool _concurrentLogin;
late bool _auditLogging;
@override
void initState() {
super.initState();
final security = ref.read(appSettingsProvider).security;
_minPasswordController =
TextEditingController(text: '${security.minPasswordLength}');
_passwordExpiryController =
TextEditingController(text: '${security.passwordExpiryDays}');
_sessionTimeoutController =
TextEditingController(text: '${security.sessionTimeoutMinutes}');
_loginAttemptController =
TextEditingController(text: '${security.loginAttemptLimit}');
_lockDurationController =
TextEditingController(text: '${security.accountLockDurationMinutes}');
_ipWhitelistController = TextEditingController(text: security.ipWhitelist);
_otpEnabled = security.otpEnabled;
_mfaEnabled = security.mfaEnabled;
_autoLogout = security.autoLogout;
_concurrentLogin = security.concurrentLoginControl;
_auditLogging = security.auditLoggingEnabled;
}
@override
void dispose() {
_minPasswordController.dispose();
_passwordExpiryController.dispose();
_sessionTimeoutController.dispose();
_loginAttemptController.dispose();
_lockDurationController.dispose();
_ipWhitelistController.dispose();
super.dispose();
}
Future<void> _save() async {
if (!_formKey.currentState!.validate()) return;
await ref.read(appSettingsProvider.notifier).updateSecurity(
SecuritySettingsConfig(
minPasswordLength: int.parse(_minPasswordController.text.trim()),
passwordExpiryDays: int.parse(_passwordExpiryController.text.trim()),
otpEnabled: _otpEnabled,
mfaEnabled: _mfaEnabled,
sessionTimeoutMinutes:
int.parse(_sessionTimeoutController.text.trim()),
autoLogout: _autoLogout,
concurrentLoginControl: _concurrentLogin,
loginAttemptLimit: int.parse(_loginAttemptController.text.trim()),
accountLockDurationMinutes:
int.parse(_lockDurationController.text.trim()),
auditLoggingEnabled: _auditLogging,
ipWhitelist: _ipWhitelistController.text.trim(),
),
);
if (mounted) {
showAppToastFromSnackBar(context,
const SnackBar(content: Text('Security settings saved')),
);
}
}
@override
Widget build(BuildContext context) {
return SettingsPageLayout(
title: 'Security Settings',
subtitle: 'Authentication, session, and audit policies',
actions: [
TextButton.icon(
onPressed: () => context.push(RouteConstants.changePassword),
icon: const Icon(Icons.password),
label: const Text('Change Password'),
),
],
child: Form(
key: _formKey,
child: Column(
children: [
SettingsFormCard(
title: 'Authentication',
children: [
AppTextField(
controller: _minPasswordController,
label: 'Minimum Password Length',
keyboardType: TextInputType.number,
),
const SizedBox(height: 16),
AppTextField(
controller: _passwordExpiryController,
label: 'Password Expiry Days',
keyboardType: TextInputType.number,
),
SettingsSwitchTile(
title: 'OTP Enable/Disable',
value: _otpEnabled,
onChanged: (v) => setState(() => _otpEnabled = v),
),
SettingsSwitchTile(
title: 'MFA Enable/Disable',
value: _mfaEnabled,
onChanged: (v) => setState(() => _mfaEnabled = v),
),
],
),
const SizedBox(height: 16),
SettingsFormCard(
title: 'Session Settings',
children: [
AppTextField(
controller: _sessionTimeoutController,
label: 'Session Timeout (Minutes)',
keyboardType: TextInputType.number,
),
SettingsSwitchTile(
title: 'Auto Logout',
value: _autoLogout,
onChanged: (v) => setState(() => _autoLogout = v),
),
SettingsSwitchTile(
title: 'Concurrent Login Control',
value: _concurrentLogin,
onChanged: (v) => setState(() => _concurrentLogin = v),
),
],
),
const SizedBox(height: 16),
SettingsFormCard(
title: 'Security Policies',
children: [
AppTextField(
controller: _loginAttemptController,
label: 'Login Attempt Limit',
keyboardType: TextInputType.number,
),
const SizedBox(height: 16),
AppTextField(
controller: _lockDurationController,
label: 'Account Lock Duration (Minutes)',
keyboardType: TextInputType.number,
),
const SizedBox(height: 16),
AppTextField(
controller: _ipWhitelistController,
label: 'IP Whitelist',
hint: '192.168.1.1, 10.0.0.0/24',
maxLines: 2,
),
SettingsSwitchTile(
title: 'Audit Logging',
subtitle: 'Track login, asset changes, and allocations',
value: _auditLogging,
onChanged: (v) => setState(() => _auditLogging = v),
),
],
),
const SizedBox(height: 24),
AppButton(label: 'Save Changes', onPressed: _save),
],
),
),
);
}
}