feat: Implement privacy and legal sections in staff privacy settings page

This commit is contained in:
Achintha Isuru
2026-02-18 14:05:42 -05:00
parent e05fe01a2d
commit 369151ee29
5 changed files with 186 additions and 144 deletions

View File

@@ -5,10 +5,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart';
import '../blocs/privacy_security_bloc.dart';
import '../widgets/settings_action_tile_widget.dart';
import '../widgets/settings_divider_widget.dart';
import '../widgets/settings_section_header_widget.dart';
import '../widgets/settings_switch_tile_widget.dart';
import '../widgets/legal/legal_section_widget.dart';
import '../widgets/privacy/privacy_section_widget.dart';
/// Page displaying privacy & security settings for staff
class PrivacySecurityPage extends StatelessWidget {
@@ -34,79 +32,16 @@ class PrivacySecurityPage extends StatelessWidget {
return const UiLoadingPage();
}
return SingleChildScrollView(
padding: const EdgeInsets.all(UiConstants.space6),
return const SingleChildScrollView(
padding: EdgeInsets.all(UiConstants.space6),
child: Column(
spacing: UiConstants.space6,
children: <Widget>[
// Privacy Section
SettingsSectionHeader(
title: t.staff_privacy_security.privacy_section,
icon: Icons.visibility,
),
const SizedBox(height: 12.0),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
border: Border.all(
color: UiColors.border,
),
),
child: Column(
children: <Widget>[
SettingsSwitchTile(
title:
t.staff_privacy_security.location_sharing.title,
subtitle: t
.staff_privacy_security
.location_sharing
.subtitle,
value:
state.privacySettings?.locationSharing ?? false,
onChanged: (bool value) {
BlocProvider.of<PrivacySecurityBloc>(context)
.add(
UpdateLocationSharingEvent(enabled: value),
);
},
),
],
),
),
const SizedBox(height: 24.0),
PrivacySectionWidget(),
// Legal Section
SettingsSectionHeader(
title: t.staff_privacy_security.legal_section,
icon: Icons.shield,
),
const SizedBox(height: 12.0),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
border: Border.all(
color: UiColors.border,
),
),
child: Column(
children: <Widget>[
SettingsActionTile(
title:
t.staff_privacy_security.terms_of_service.title,
onTap: () => _showTermsDialog(context),
),
const SettingsDivider(),
SettingsActionTile(
title: t.staff_privacy_security.privacy_policy.title,
onTap: () => _showPrivacyPolicyDialog(context),
),
],
),
),
const SizedBox(height: 24.0),
LegalSectionWidget(),
],
),
);
@@ -115,76 +50,4 @@ class PrivacySecurityPage extends StatelessWidget {
),
);
}
/// Show terms of service in a modal dialog
void _showTermsDialog(BuildContext context) {
BlocProvider.of<PrivacySecurityBloc>(context)
.add(const FetchTermsEvent());
showDialog(
context: context,
builder: (BuildContext dialogContext) =>
BlocBuilder<PrivacySecurityBloc, PrivacySecurityState>(
builder: (BuildContext context, PrivacySecurityState state) {
return AlertDialog(
title: Text(
t.staff_privacy_security.terms_of_service.title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
content: SingleChildScrollView(
child: Text(
state.termsContent ?? 'Loading...',
style: const TextStyle(fontSize: 14),
),
),
actions: <Widget>[
TextButton(
onPressed: () => Modular.to.pop(),
child: Text(t.common.ok),
),
],
);
},
),
);
}
/// Show privacy policy in a modal dialog
void _showPrivacyPolicyDialog(BuildContext context) {
BlocProvider.of<PrivacySecurityBloc>(context)
.add(const FetchPrivacyPolicyEvent());
showDialog(
context: context,
builder: (BuildContext dialogContext) =>
BlocBuilder<PrivacySecurityBloc, PrivacySecurityState>(
builder: (BuildContext context, PrivacySecurityState state) {
return AlertDialog(
title: Text(
t.staff_privacy_security.privacy_policy.title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
content: SingleChildScrollView(
child: Text(
state.privacyPolicyContent ?? 'Loading...',
style: const TextStyle(fontSize: 14),
),
),
actions: <Widget>[
TextButton(
onPressed: () => Modular.to.pop(),
child: Text(t.common.ok),
),
],
);
},
),
);
}
}

View File

@@ -0,0 +1,125 @@
import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart';
import '../../blocs/privacy_security_bloc.dart';
import '../settings_action_tile_widget.dart';
import '../settings_divider_widget.dart';
import '../settings_section_header_widget.dart';
/// Widget displaying legal documents (Terms of Service and Privacy Policy)
class LegalSectionWidget extends StatelessWidget {
const LegalSectionWidget({super.key});
@override
Widget build(BuildContext context) {
return Column(
spacing: UiConstants.space4,
children: <Widget>[
// Legal Section Header
SettingsSectionHeader(
title: t.staff_privacy_security.legal_section,
icon: Icons.shield,
),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
border: Border.all(
color: UiColors.border,
),
),
child: Column(
children: <Widget>[
SettingsActionTile(
title: t.staff_privacy_security.terms_of_service.title,
onTap: () => _showTermsDialog(context),
),
const SettingsDivider(),
SettingsActionTile(
title: t.staff_privacy_security.privacy_policy.title,
onTap: () => _showPrivacyPolicyDialog(context),
),
],
),
),
],
);
}
/// Show terms of service in a modal dialog
void _showTermsDialog(BuildContext context) {
BlocProvider.of<PrivacySecurityBloc>(context)
.add(const FetchTermsEvent());
showDialog(
context: context,
builder: (BuildContext dialogContext) =>
BlocBuilder<PrivacySecurityBloc, PrivacySecurityState>(
builder: (BuildContext context, PrivacySecurityState state) {
return AlertDialog(
title: Text(
t.staff_privacy_security.terms_of_service.title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
content: SingleChildScrollView(
child: Text(
state.termsContent ?? 'Loading...',
style: const TextStyle(fontSize: 14),
),
),
actions: <Widget>[
TextButton(
onPressed: () => Modular.to.pop(),
child: Text(t.common.ok),
),
],
);
},
),
);
}
/// Show privacy policy in a modal dialog
void _showPrivacyPolicyDialog(BuildContext context) {
BlocProvider.of<PrivacySecurityBloc>(context)
.add(const FetchPrivacyPolicyEvent());
showDialog(
context: context,
builder: (BuildContext dialogContext) =>
BlocBuilder<PrivacySecurityBloc, PrivacySecurityState>(
builder: (BuildContext context, PrivacySecurityState state) {
return AlertDialog(
title: Text(
t.staff_privacy_security.privacy_policy.title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
content: SingleChildScrollView(
child: Text(
state.privacyPolicyContent ?? 'Loading...',
style: const TextStyle(fontSize: 14),
),
),
actions: <Widget>[
TextButton(
onPressed: () => Modular.to.pop(),
child: Text(t.common.ok),
),
],
);
},
),
);
}
}

View File

@@ -0,0 +1,54 @@
import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../blocs/privacy_security_bloc.dart';
import '../settings_section_header_widget.dart';
import '../settings_switch_tile_widget.dart';
/// Widget displaying privacy settings including location sharing preference
class PrivacySectionWidget extends StatelessWidget {
const PrivacySectionWidget({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<PrivacySecurityBloc, PrivacySecurityState>(
builder: (BuildContext context, PrivacySecurityState state) {
return Column(
children: <Widget>[
// Privacy Section Header
SettingsSectionHeader(
title: t.staff_privacy_security.privacy_section,
icon: Icons.visibility,
),
const SizedBox(height: 12.0),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
border: Border.all(
color: UiColors.border,
),
),
child: Column(
children: <Widget>[
SettingsSwitchTile(
title: t.staff_privacy_security.location_sharing.title,
subtitle: t.staff_privacy_security.location_sharing.subtitle,
value: state.privacySettings?.locationSharing ?? false,
onChanged: (bool value) {
BlocProvider.of<PrivacySecurityBloc>(context).add(
UpdateLocationSharingEvent(enabled: value),
);
},
),
],
),
),
],
);
},
);
}
}