feat: Implement privacy and legal sections in staff privacy settings page
This commit is contained in:
@@ -5,10 +5,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:flutter_modular/flutter_modular.dart';
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
|
|
||||||
import '../blocs/privacy_security_bloc.dart';
|
import '../blocs/privacy_security_bloc.dart';
|
||||||
import '../widgets/settings_action_tile_widget.dart';
|
import '../widgets/legal/legal_section_widget.dart';
|
||||||
import '../widgets/settings_divider_widget.dart';
|
import '../widgets/privacy/privacy_section_widget.dart';
|
||||||
import '../widgets/settings_section_header_widget.dart';
|
|
||||||
import '../widgets/settings_switch_tile_widget.dart';
|
|
||||||
|
|
||||||
/// Page displaying privacy & security settings for staff
|
/// Page displaying privacy & security settings for staff
|
||||||
class PrivacySecurityPage extends StatelessWidget {
|
class PrivacySecurityPage extends StatelessWidget {
|
||||||
@@ -34,79 +32,16 @@ class PrivacySecurityPage extends StatelessWidget {
|
|||||||
return const UiLoadingPage();
|
return const UiLoadingPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return const SingleChildScrollView(
|
||||||
padding: const EdgeInsets.all(UiConstants.space6),
|
padding: EdgeInsets.all(UiConstants.space6),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
spacing: UiConstants.space6,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
// Privacy Section
|
// Privacy Section
|
||||||
SettingsSectionHeader(
|
PrivacySectionWidget(),
|
||||||
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),
|
|
||||||
|
|
||||||
// Legal Section
|
// Legal Section
|
||||||
SettingsSectionHeader(
|
LegalSectionWidget(),
|
||||||
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),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -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),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user