legacy device setup screen flow from account settings

This commit is contained in:
2026-03-11 13:11:11 +01:00
parent 53cadd8499
commit ffc0a1f103
8 changed files with 150 additions and 113 deletions

View File

@@ -1,16 +1,18 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_auth/legacy_auth.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:navigation/navigation.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:utils/utils.dart';
import 'package:flutter/services.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'widgets/reg_code_dialog.dart';
class AccountSettingsScreen extends ConsumerWidget {
final NavigationContract navigationContract;
static final _privacyUrl = 'https://savefamilygps.com/pages/politica-de-privacidad-reloj-gps-infantil-localizador-savefamily';
const AccountSettingsScreen({super.key, required this.navigationContract});
@@ -21,7 +23,7 @@ class AccountSettingsScreen extends ConsumerWidget {
final selectedDevice = ref.watch(selectedDeviceProvider);
return LegacyPageLayout(
theme: theme,
theme: theme,
title: context.translate(I18n.accountSettings),
body: SingleChildScrollView(child: Container(
padding: SizeUtils.getByScreen(
@@ -43,7 +45,16 @@ theme: theme,
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: (){},
onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => LegacyDeviceSetupScreen(
navigationContract: navigationContract,
isFirstDevice: false
),
),
);
},
icon: Icons.add_circle_outline,
text: I18n.addNewSF
),
@@ -62,7 +73,7 @@ theme: theme,
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: () async {
final Uri url = Uri.parse('https://savefamilygps.com/pages/politica-de-privacidad-reloj-gps-infantil-localizador-savefamily');
final Uri url = Uri.parse(_privacyUrl);
if (!await launchUrl(url)) {
throw Exception('Could not launch $url');
}
@@ -160,103 +171,4 @@ class AppSectionButton extends ConsumerWidget {
)
);
}
}
class RegCodeDialog extends StatelessWidget {
final String regCode;
final String deviceId;
final String name;
const RegCodeDialog({
super.key,
required this.regCode,
required this.deviceId,
required this.name,
});
@override
Widget build(BuildContext context) {
return Container(
height: SizeUtils.getByScreen(small: 330, big: 328),
color: Colors.transparent,
child: Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: SizeUtils.getByScreen(small: 300, big: 298),
width: SizeUtils.getByScreen(small: 350, big: 348),
padding: SizeUtils.getByScreen(
small: EdgeInsets.symmetric(vertical: 14, horizontal: 18),
big: EdgeInsets.symmetric(vertical: 12, horizontal: 16)
),
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Align(
alignment: Alignment.topRight,
child: IconButton(
onPressed: (){Navigator.pop(context);},
icon: Icon(Icons.close),
padding: EdgeInsets.zero,
),
),
Text(name, style: TextStyle()),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(context.translate(I18n.deviceIdLabel,
args: {'deviceId': deviceId})),
TextButton(
onPressed: (){Clipboard.setData(ClipboardData(text: deviceId));},
child: Text(context.translate(I18n.copy)),
)
],
),
QrImageView(
data: regCode,
version: QrVersions.auto,
size: SizeUtils.getByScreen(small: 100, big: 98),
padding: EdgeInsets.zero,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(context.translate(I18n.regCodeLabel,
args: {'regCode': regCode})),
TextButton(
onPressed: (){Clipboard.setData(ClipboardData(text: regCode));},
child: Text(context.translate(I18n.copy))
)
],
)
],
),
),
),
Align(
alignment: Alignment.topCenter,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xFF00A1C6),
),
padding: SizeUtils.getByScreen(
small: EdgeInsets.all(12),
big: EdgeInsets.all(12)
),
child: Icon(
SFIcons.watch,
size: SizeUtils.getByScreen(small: 68, big: 66),
color: Colors.white,
),
)
),
],
),
);
}
}

View File

@@ -0,0 +1,104 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
class RegCodeDialog extends StatelessWidget {
final String regCode;
final String deviceId;
final String name;
const RegCodeDialog({
super.key,
required this.regCode,
required this.deviceId,
required this.name,
});
@override
Widget build(BuildContext context) {
return Container(
height: SizeUtils.getByScreen(small: 330, big: 328),
color: Colors.transparent,
child: Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: SizeUtils.getByScreen(small: 300, big: 298),
width: SizeUtils.getByScreen(small: 350, big: 348),
padding: SizeUtils.getByScreen(
small: EdgeInsets.symmetric(vertical: 14, horizontal: 18),
big: EdgeInsets.symmetric(vertical: 12, horizontal: 16)
),
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Align(
alignment: Alignment.topRight,
child: IconButton(
onPressed: (){Navigator.pop(context);},
icon: Icon(Icons.close),
padding: EdgeInsets.zero,
),
),
Text(name, style: TextStyle()),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(context.translate(I18n.deviceIdLabel,
args: {'deviceId': deviceId})),
TextButton(
onPressed: (){Clipboard.setData(ClipboardData(text: deviceId));},
child: Text(context.translate(I18n.copy)),
)
],
),
QrImageView(
data: regCode,
version: QrVersions.auto,
size: SizeUtils.getByScreen(small: 100, big: 98),
padding: EdgeInsets.zero,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(context.translate(I18n.regCodeLabel,
args: {'regCode': regCode})),
TextButton(
onPressed: (){Clipboard.setData(ClipboardData(text: regCode));},
child: Text(context.translate(I18n.copy))
)
],
)
],
),
),
),
Align(
alignment: Alignment.topCenter,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xFF00A1C6),
),
padding: SizeUtils.getByScreen(
small: EdgeInsets.all(12),
big: EdgeInsets.all(12)
),
child: Icon(
SFIcons.watch,
size: SizeUtils.getByScreen(small: 68, big: 66),
color: Colors.white,
),
)
),
],
),
);
}
}

View File

@@ -586,6 +586,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.2"
legacy_auth:
dependency: "direct main"
description:
path: "../legacy_auth"
relative: true
source: path
version: "0.0.1"
legacy_shared:
dependency: "direct main"
description:

View File

@@ -24,7 +24,8 @@ dependencies:
flutter:
sdk: flutter
#modules dependencies go here
legacy_auth:
path: ../../modules/legacy_auth
#packages dependencies go here
design_system:
path: ../../../../packages/design_system

View File

@@ -1,3 +1,4 @@
# melos_managed_dependency_overrides: legacy_auth
# melos_managed_dependency_overrides: activity,auth,design_system,flutter_treezor_entrust_sdk_bridge,fonts,home,legacy_shared,navigation,notifications,payments,sca_treezor,sf_infrastructure,sf_localizations,sf_shared,utils
dependency_overrides:
activity:
@@ -12,6 +13,8 @@ dependency_overrides:
path: ../../../../packages/fonts
home:
path: ../../../home
legacy_auth:
path: ..\\legacy_auth
legacy_shared:
path: ../../packages/legacy_shared
navigation:

View File

@@ -4,6 +4,7 @@ export 'src/features/link_phone/presentation/verify_code/verify_link_phone_code_
export 'src/features/login/login_builder.dart';
export 'src/features/recover_password/presentation/request_recovery/request_recovery_builder.dart';
export 'src/features/device_setup/device_setup_builder.dart';
export 'src/features/device_setup/presentation/device_setup_screen.dart';
export 'src/features/sign_up/sign_up_builder.dart';
export 'src/core/data/datasource/session_local_datasource.dart';
export 'src/core/providers/auth_repository_provider.dart';

View File

@@ -11,8 +11,13 @@ import 'package:sf_localizations/sf_localizations.dart';
class LegacyDeviceSetupScreen extends ConsumerWidget {
final NavigationContract navigationContract;
final bool isFirstDevice;
const LegacyDeviceSetupScreen({super.key, required this.navigationContract});
const LegacyDeviceSetupScreen({
super.key,
required this.navigationContract,
this.isFirstDevice = true,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -95,13 +100,17 @@ class LegacyDeviceSetupScreen extends ConsumerWidget {
final ok = await vm.createDevice();
if (!context.mounted) return;
if (ok) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => LegacySuccessScreen(
navigationContract: navigationContract,
if (isFirstDevice){
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => LegacySuccessScreen(
navigationContract: navigationContract,
),
),
),
);
);
} else {
Navigator.pop(context);
}
}
return;
}

View File

@@ -12,7 +12,7 @@ Future<void> _pickBornAt(
FocusManager.instance.primaryFocus?.unfocus();
final now = DateTime.now();
final initial = currentBornAt ?? DateTime(now.year - 18, now.month, now.day);
final initial = currentBornAt ?? DateTime(now.year - 4, now.month, now.day);
final safeInitial = initial.isAfter(now) ? now : initial;
final picked = await showDatePicker(