ft/adds persistent app state up to mail verification
This commit is contained in:
parent
d0b93581b2
commit
df74e8e12f
@ -1,9 +1,6 @@
|
|||||||
import 'package:app/model/services/auth_service.dart';
|
import 'package:app/model/services/auth_service.dart';
|
||||||
import 'package:app/model/services/storage_service.dart';
|
import 'package:app/model/services/storage_service.dart';
|
||||||
import 'package:app/pages/notifications_page.dart';
|
|
||||||
import 'package:app/pages/start_page.dart';
|
import 'package:app/pages/start_page.dart';
|
||||||
import 'package:app/pages/verify_email_page.dart';
|
|
||||||
import 'package:app/pages/registration_page.dart';
|
|
||||||
import 'package:app/util/colors.dart';
|
import 'package:app/util/colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart'
|
import 'package:flutter_localizations/flutter_localizations.dart'
|
||||||
@ -77,53 +74,39 @@ class _DigitalerFriedenState extends State<DigitalerFrieden> {
|
|||||||
|
|
||||||
void _init() async {
|
void _init() async {
|
||||||
accountLevel = await _storageService.accountLevel;
|
accountLevel = await _storageService.accountLevel;
|
||||||
print(accountLevel!);
|
|
||||||
if (accountLevel! > 0) {
|
if (accountLevel! > 0) {
|
||||||
authenticated = await AuthService.authenticateWithBiometrics();
|
authenticated = await AuthService.authenticateWithBiometrics();
|
||||||
}
|
}
|
||||||
_loading = false;
|
setState(() {
|
||||||
setState(() {});
|
_loading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (_loading) {
|
if (_loading) {
|
||||||
return Center(
|
return SafeArea(
|
||||||
child: Column(
|
child: Center(
|
||||||
children: [
|
child: Column(
|
||||||
Image.asset(
|
children: [
|
||||||
'assets/JPEG.jpg',
|
const SizedBox(
|
||||||
height: 180,
|
height: 150,
|
||||||
),
|
),
|
||||||
CircularProgressIndicator(
|
Hero(
|
||||||
color: CustomColors.primary,
|
tag: 'logo',
|
||||||
),
|
child: Image.asset(
|
||||||
],
|
'assets/JPEG.jpg',
|
||||||
|
height: 180,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color: CustomColors.primary,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (accountLevel == null || accountLevel == 0) {
|
return const StartPage();
|
||||||
return const StartPage();
|
|
||||||
}
|
|
||||||
// else if (authenticated == null) {
|
|
||||||
// AuthService.authenticateWithBiometrics().then((value) {
|
|
||||||
// setState(() {
|
|
||||||
// authenticated = value;
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
switch (accountLevel) {
|
|
||||||
case null:
|
|
||||||
return const StartPage();
|
|
||||||
case < 1:
|
|
||||||
return NotificationsPage();
|
|
||||||
case 1:
|
|
||||||
return const RegistrationPage();
|
|
||||||
case 2:
|
|
||||||
return VerifyEmailPage();
|
|
||||||
default:
|
|
||||||
return const StartPage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,9 @@ class StorageService {
|
|||||||
|
|
||||||
Future<int> get accountLevel async {
|
Future<int> get accountLevel async {
|
||||||
int? level;
|
int? level;
|
||||||
final l = await readData('account_level');
|
final lev = await readData('account_level');
|
||||||
if (l != null) {
|
if (lev != null) {
|
||||||
level = int.tryParse(l);
|
level = int.tryParse(lev);
|
||||||
}
|
}
|
||||||
return level ?? 0;
|
return level ?? 0;
|
||||||
}
|
}
|
||||||
|
@ -3,119 +3,189 @@ import 'package:app/pages/registration_page.dart';
|
|||||||
import 'package:app/util/colors.dart';
|
import 'package:app/util/colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class NotificationsPage extends StatelessWidget {
|
class NotificationsPage extends StatefulWidget {
|
||||||
NotificationsPage({super.key});
|
const NotificationsPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NotificationsPage> createState() => _NotificationsPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NotificationsPageState extends State<NotificationsPage> {
|
||||||
final StorageService _storageService = StorageService();
|
final StorageService _storageService = StorageService();
|
||||||
|
bool _loading = true;
|
||||||
|
|
||||||
void _setNotificationSetting(bool enabled) {
|
Future<void> _setNotificationSetting(bool enabled) async {
|
||||||
_storageService.addAccountLevel();
|
await _storageService.setNotificationSetting(enabled);
|
||||||
_storageService.setNotificationSetting(enabled).then(
|
}
|
||||||
(x) => _storageService.notificationSetting.then(
|
|
||||||
(value) => print('notifications: $value'),
|
@override
|
||||||
),
|
void initState() {
|
||||||
);
|
_init();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _init() async {
|
||||||
|
final accountLevel = await _storageService.accountLevel;
|
||||||
|
if (accountLevel > 2 && mounted) {
|
||||||
|
await Navigator.push(context,
|
||||||
|
MaterialPageRoute(builder: (builder) => const RegistrationPage()));
|
||||||
|
setState(() {
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: _loading
|
||||||
appBar: AppBar(
|
? Center(
|
||||||
iconTheme: IconThemeData(
|
child: Column(
|
||||||
color: CustomColors.primary,
|
children: [
|
||||||
),
|
const SizedBox(
|
||||||
),
|
height: 150,
|
||||||
body: Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(20, 20, 20, 16),
|
|
||||||
child: Column(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
const SizedBox(
|
|
||||||
height: 80,
|
|
||||||
),
|
|
||||||
Image.asset('assets/chat_bubbles.png'),
|
|
||||||
const SizedBox(
|
|
||||||
height: 60,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Erhalte Mitteilungen',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'sans-serif',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
letterSpacing: 2.0,
|
|
||||||
fontSize: 25,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 20,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Du erhältst z. B. eine Mitteilung sobald wir eine Digitale Spur gefunden haben.',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 20,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Du kannst die Mitteilungen jederzeit wieder deaktivieren.',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
const Spacer(
|
|
||||||
flex: 2,
|
|
||||||
),
|
|
||||||
Hero(
|
|
||||||
tag: 'flow-button',
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: CustomColors.primary,
|
|
||||||
),
|
),
|
||||||
onPressed: () {
|
Hero(
|
||||||
_setNotificationSetting(true);
|
tag: 'logo',
|
||||||
Navigator.push(
|
child: Image.asset(
|
||||||
context,
|
'assets/JPEG.jpg',
|
||||||
MaterialPageRoute(
|
height: 180,
|
||||||
builder: (builder) => const RegistrationPage(),
|
|
||||||
// builder: (builder) => SecurityPage(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: const SizedBox(
|
|
||||||
height: 60,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Mitteilungen erhalten',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color: CustomColors.primary,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: BackButton(
|
||||||
|
color: CustomColors.primary,
|
||||||
|
onPressed: () async {
|
||||||
|
await _storageService.setAccountLevel(1);
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
iconTheme: IconThemeData(
|
||||||
|
color: CustomColors.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
body: Padding(
|
||||||
height: 10,
|
padding: const EdgeInsets.fromLTRB(20, 20, 20, 16),
|
||||||
),
|
child: Column(
|
||||||
TextButton(
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
onPressed: () {
|
children: [
|
||||||
_setNotificationSetting(false);
|
const SizedBox(
|
||||||
},
|
height: 80,
|
||||||
child: Text(
|
),
|
||||||
'Später',
|
Image.asset('assets/chat_bubbles.png'),
|
||||||
style: TextStyle(color: CustomColors.primary),
|
const SizedBox(
|
||||||
|
height: 60,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Erhalte Mitteilungen',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
letterSpacing: 2.0,
|
||||||
|
fontSize: 25,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Du erhältst z. B. eine Mitteilung sobald wir eine Digitale Spur gefunden haben.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Du kannst die Mitteilungen jederzeit wieder deaktivieren.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const Spacer(
|
||||||
|
flex: 2,
|
||||||
|
),
|
||||||
|
Hero(
|
||||||
|
tag: 'flow-button',
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: CustomColors.primary,
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
await _setNotificationSetting(true);
|
||||||
|
await _storageService.setAccountLevel(3);
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (builder) => const RegistrationPage(),
|
||||||
|
// builder: (builder) => SecurityPage(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const SizedBox(
|
||||||
|
height: 60,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Text(
|
||||||
|
'Mitteilungen erhalten',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
await _setNotificationSetting(false);
|
||||||
|
await _storageService.setAccountLevel(3);
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (builder) => const RegistrationPage(),
|
||||||
|
// builder: (builder) => SecurityPage(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'Später',
|
||||||
|
style: TextStyle(color: CustomColors.primary),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(
|
||||||
|
flex: 1,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(
|
),
|
||||||
flex: 1,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:app/util/validation.dart';
|
import 'package:app/util/validation.dart';
|
||||||
|
|
||||||
class PasswordPage extends StatefulWidget {
|
class PasswordPage extends StatefulWidget {
|
||||||
PasswordPage({super.key, required this.email, required this.register});
|
const PasswordPage({super.key, required this.email, required this.register});
|
||||||
|
|
||||||
final String email;
|
final String email;
|
||||||
final bool register;
|
final bool register;
|
||||||
@ -47,170 +47,195 @@ class _PasswordPageState extends State<PasswordPage> {
|
|||||||
),
|
),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
child: Form(
|
child: SingleChildScrollView(
|
||||||
key: _formKey,
|
child: Form(
|
||||||
child: Column(
|
key: _formKey,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Column(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
const Text(
|
children: [
|
||||||
'Sichere dein Konto mit einem Passwort',
|
Text(
|
||||||
textAlign: TextAlign.center,
|
widget.register
|
||||||
style: TextStyle(
|
? 'Sichere dein Konto mit einem Passwort'
|
||||||
fontFamily: 'sans-serif',
|
: 'Login',
|
||||||
fontWeight: FontWeight.bold,
|
textAlign: TextAlign.center,
|
||||||
letterSpacing: 2.0,
|
style: const TextStyle(
|
||||||
fontSize: 25,
|
fontFamily: 'sans-serif',
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
letterSpacing: 2.0,
|
||||||
|
fontSize: 25,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
const SizedBox(
|
height: 60,
|
||||||
height: 60,
|
|
||||||
),
|
|
||||||
TextFormField(
|
|
||||||
controller: _passwordController1,
|
|
||||||
autocorrect: false,
|
|
||||||
autofocus: true,
|
|
||||||
keyboardType: TextInputType.visiblePassword,
|
|
||||||
obscureText: !_showPassword1,
|
|
||||||
autovalidateMode: AutovalidateMode.always,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
suffixIcon: IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
setState(() {
|
|
||||||
_showPassword1 = !_showPassword1;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
icon: Icon(_showPassword1
|
|
||||||
? Icons.remove_red_eye
|
|
||||||
: Icons.remove_red_eye_outlined)),
|
|
||||||
label: const Text('Passwort'),
|
|
||||||
filled: true,
|
|
||||||
),
|
),
|
||||||
validator: (value) {
|
TextFormField(
|
||||||
if (value == null || !value.isValidPassword) {
|
controller: _passwordController1,
|
||||||
_validPassword = false;
|
autocorrect: false,
|
||||||
return 'Mindestens 12 Zeichen, Zahlen, Sonderzeichen (-_?!=.,*+), Groß- & Kleinbuchstaben';
|
autofocus: true,
|
||||||
} else {
|
keyboardType: TextInputType.visiblePassword,
|
||||||
_validPassword = true;
|
obscureText: !_showPassword1,
|
||||||
return null;
|
autovalidateMode: AutovalidateMode.always,
|
||||||
}
|
decoration: InputDecoration(
|
||||||
},
|
suffixIcon: IconButton(
|
||||||
onChanged: (value) {
|
onPressed: () {
|
||||||
_formKey.currentState?.validate();
|
setState(() {
|
||||||
if (!value.isValidPassword) {
|
_showPassword1 = !_showPassword1;
|
||||||
setState(() {
|
});
|
||||||
|
},
|
||||||
|
icon: Icon(_showPassword1
|
||||||
|
? Icons.remove_red_eye
|
||||||
|
: Icons.remove_red_eye_outlined)),
|
||||||
|
label: const Text('Passwort'),
|
||||||
|
filled: true,
|
||||||
|
),
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || !value.isValidPassword) {
|
||||||
_validPassword = false;
|
_validPassword = false;
|
||||||
});
|
return 'Mindestens 12 Zeichen, Zahlen, Sonderzeichen (-_?!=.,*+), Groß- & Kleinbuchstaben';
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
if (!widget.register) {
|
||||||
|
_passwordsFilled = true;
|
||||||
|
}
|
||||||
_validPassword = true;
|
_validPassword = true;
|
||||||
});
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
onChanged: (value) {
|
||||||
const SizedBox(
|
_formKey.currentState?.validate();
|
||||||
height: 20,
|
if (!value.isValidPassword) {
|
||||||
),
|
setState(() {
|
||||||
AnimatedSwitcher(
|
_validPassword = false;
|
||||||
duration: const Duration(milliseconds: 300),
|
});
|
||||||
child: !_validPassword
|
} else {
|
||||||
? null
|
setState(() {
|
||||||
: TextFormField(
|
if (!widget.register) {
|
||||||
controller: _passwordController2,
|
_passwordsFilled = true;
|
||||||
keyboardType: TextInputType.visiblePassword,
|
}
|
||||||
obscureText: !_showPassword2,
|
_validPassword = true;
|
||||||
decoration: InputDecoration(
|
});
|
||||||
suffixIcon: IconButton(
|
}
|
||||||
onPressed: () {
|
},
|
||||||
setState(() {
|
),
|
||||||
_showPassword2 = !_showPassword2;
|
const SizedBox(
|
||||||
});
|
height: 20,
|
||||||
},
|
),
|
||||||
icon: Icon(_showPassword2
|
AnimatedSwitcher(
|
||||||
? Icons.remove_red_eye
|
duration: const Duration(milliseconds: 300),
|
||||||
: Icons.remove_red_eye_outlined)),
|
child: !widget.register || !_validPassword
|
||||||
label: const Text('Passwort bestätigen'),
|
? null
|
||||||
filled: true,
|
: TextFormField(
|
||||||
|
controller: _passwordController2,
|
||||||
|
keyboardType: TextInputType.visiblePassword,
|
||||||
|
obscureText: !_showPassword2,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_showPassword2 = !_showPassword2;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: Icon(_showPassword2
|
||||||
|
? Icons.remove_red_eye
|
||||||
|
: Icons.remove_red_eye_outlined)),
|
||||||
|
label: const Text('Passwort bestätigen'),
|
||||||
|
filled: true,
|
||||||
|
),
|
||||||
|
validator: (value) {
|
||||||
|
if (_passwordController1.text !=
|
||||||
|
_passwordController2.text) {
|
||||||
|
setState(() {
|
||||||
|
_passwordsFilled = false;
|
||||||
|
});
|
||||||
|
return 'Passwörter stimmen nicht überein';
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_passwordsFilled = true;
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onTap: () => _formKey.currentState?.validate(),
|
||||||
|
onChanged: (value) {
|
||||||
|
_formKey.currentState?.validate();
|
||||||
|
if (_passwordController1.text !=
|
||||||
|
_passwordController2.text) {
|
||||||
|
setState(() {
|
||||||
|
_passwordsFilled = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_passwordsFilled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
validator: (value) {
|
),
|
||||||
if (_passwordController1.text !=
|
const SizedBox(
|
||||||
_passwordController2.text) {
|
height: 20,
|
||||||
setState(() {
|
),
|
||||||
_passwordsFilled = false;
|
AnimatedSwitcher(
|
||||||
});
|
duration: const Duration(milliseconds: 300),
|
||||||
return 'Passwörter stimmen nicht überein';
|
child: !_passwordsFilled ||
|
||||||
} else {
|
(widget.register &&
|
||||||
setState(() {
|
_passwordController1.text !=
|
||||||
_passwordsFilled = true;
|
_passwordController2.text)
|
||||||
});
|
? null
|
||||||
return null;
|
: ElevatedButton(
|
||||||
}
|
style: ElevatedButton.styleFrom(
|
||||||
},
|
backgroundColor: CustomColors.primary,
|
||||||
onTap: () => _formKey.currentState?.validate(),
|
),
|
||||||
onChanged: (value) {
|
onPressed: _validPassword && _passwordsFilled
|
||||||
_formKey.currentState?.validate();
|
? () async {
|
||||||
if (_passwordController1.text !=
|
if (_formKey.currentState!.validate()) {
|
||||||
_passwordController2.text) {
|
FocusScope.of(context).unfocus();
|
||||||
setState(() {
|
final navigator = Navigator.of(context);
|
||||||
_passwordsFilled = false;
|
bool loggedin = false;
|
||||||
});
|
if (widget.register) {
|
||||||
} else {
|
loggedin = await _vm.createAccount(
|
||||||
setState(() {
|
context,
|
||||||
_passwordsFilled = true;
|
email: widget.email,
|
||||||
});
|
password: _passwordController1.text,
|
||||||
}
|
);
|
||||||
},
|
} else {
|
||||||
),
|
loggedin = await _vm.login(
|
||||||
),
|
context,
|
||||||
const SizedBox(
|
email: widget.email,
|
||||||
height: 20,
|
password: _passwordController1.text,
|
||||||
),
|
);
|
||||||
AnimatedSwitcher(
|
}
|
||||||
duration: const Duration(milliseconds: 300),
|
if (loggedin && mounted) {
|
||||||
child: !_passwordsFilled ||
|
await _storageService.setAccountLevel(4);
|
||||||
_passwordController1.text != _passwordController2.text
|
navigator.push(
|
||||||
? null
|
MaterialPageRoute(
|
||||||
: ElevatedButton(
|
builder: (builder) =>
|
||||||
style: ElevatedButton.styleFrom(
|
const VerifyEmailPage(),
|
||||||
backgroundColor: CustomColors.primary,
|
),
|
||||||
),
|
);
|
||||||
onPressed: _validPassword && _passwordsFilled
|
}
|
||||||
? () async {
|
|
||||||
if (_formKey.currentState!.validate()) {
|
|
||||||
final navigator = Navigator.of(context);
|
|
||||||
final loggedin = await _vm.createAccount(
|
|
||||||
context,
|
|
||||||
email: widget.email,
|
|
||||||
password: _passwordController1.text,
|
|
||||||
);
|
|
||||||
if (loggedin && mounted) {
|
|
||||||
_storageService.addAccountLevel();
|
|
||||||
navigator.push(
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (builder) => VerifyEmailPage(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
: null,
|
||||||
: null,
|
child: SizedBox(
|
||||||
child: const SizedBox(
|
height: 50,
|
||||||
height: 50,
|
child: Row(
|
||||||
child: Row(
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
children: [
|
||||||
children: [
|
Text(
|
||||||
Text(
|
widget.register
|
||||||
'Registrierung abschließen',
|
? 'Registrierung abschließen'
|
||||||
style: TextStyle(
|
: 'Einloggen',
|
||||||
fontSize: 20,
|
style: const TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
import 'package:app/model/services/storage_service.dart';
|
||||||
import 'package:app/pages/password_page.dart';
|
import 'package:app/pages/password_page.dart';
|
||||||
|
import 'package:app/pages/verify_email_page.dart';
|
||||||
import 'package:app/util/colors.dart';
|
import 'package:app/util/colors.dart';
|
||||||
import 'package:app/util/validation.dart';
|
import 'package:app/util/validation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -13,6 +15,30 @@ class RegistrationPage extends StatefulWidget {
|
|||||||
class _RegistrationPageState extends State<RegistrationPage> {
|
class _RegistrationPageState extends State<RegistrationPage> {
|
||||||
final formKey = GlobalKey<FormState>();
|
final formKey = GlobalKey<FormState>();
|
||||||
final mailController = TextEditingController();
|
final mailController = TextEditingController();
|
||||||
|
bool _loading = true;
|
||||||
|
|
||||||
|
final StorageService _storageService = StorageService();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_init();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _init() async {
|
||||||
|
final accountLevel = await _storageService.accountLevel;
|
||||||
|
if (accountLevel > 3 && mounted) {
|
||||||
|
await Navigator.push(context,
|
||||||
|
MaterialPageRoute(builder: (builder) => const VerifyEmailPage()));
|
||||||
|
setState(() {
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@ -23,138 +49,167 @@ class _RegistrationPageState extends State<RegistrationPage> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: _loading
|
||||||
appBar: AppBar(
|
? Center(
|
||||||
iconTheme: IconThemeData(
|
child: Column(
|
||||||
color: CustomColors.primary,
|
children: [
|
||||||
),
|
const SizedBox(
|
||||||
),
|
height: 150,
|
||||||
body: Padding(
|
),
|
||||||
padding: const EdgeInsets.fromLTRB(20, 20, 20, 16),
|
Hero(
|
||||||
child: Column(
|
tag: 'logo',
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
child: Image.asset(
|
||||||
children: [
|
'assets/JPEG.jpg',
|
||||||
const SizedBox(
|
height: 180,
|
||||||
height: 20,
|
),
|
||||||
|
),
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color: CustomColors.primary,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const Text(
|
)
|
||||||
'Jetzt Registrieren',
|
: Scaffold(
|
||||||
textAlign: TextAlign.center,
|
appBar: AppBar(
|
||||||
style: TextStyle(
|
leading: BackButton(
|
||||||
fontFamily: 'sans-serif',
|
color: CustomColors.primary,
|
||||||
fontWeight: FontWeight.bold,
|
onPressed: () async {
|
||||||
letterSpacing: 2.0,
|
await _storageService.setAccountLevel(2);
|
||||||
fontSize: 25,
|
if (mounted) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
iconTheme: IconThemeData(
|
||||||
|
color: CustomColors.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
body: Padding(
|
||||||
height: 20,
|
padding: const EdgeInsets.fromLTRB(20, 20, 20, 16),
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Gib deine E-Mail Adresse ein.',
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 20,
|
|
||||||
),
|
|
||||||
Form(
|
|
||||||
key: formKey,
|
|
||||||
child: Column(
|
child: Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
TextFormField(
|
const SizedBox(
|
||||||
autocorrect: false,
|
height: 20,
|
||||||
autofocus: true,
|
),
|
||||||
controller: mailController,
|
const Text(
|
||||||
keyboardType: TextInputType.emailAddress,
|
'Jetzt Registrieren',
|
||||||
decoration: const InputDecoration(
|
textAlign: TextAlign.center,
|
||||||
helperText: 'test',
|
style: TextStyle(
|
||||||
label: Text('E-Mail Adresse'),
|
fontFamily: 'sans-serif',
|
||||||
filled: true,
|
fontWeight: FontWeight.bold,
|
||||||
|
letterSpacing: 2.0,
|
||||||
|
fontSize: 25,
|
||||||
),
|
),
|
||||||
validator: (value) {
|
),
|
||||||
if (value == null || !value.isValidEmail) {
|
const SizedBox(
|
||||||
return 'Bitte eine valide E-Mail Adresse angeben';
|
height: 20,
|
||||||
} else {
|
),
|
||||||
return null;
|
const Text(
|
||||||
}
|
'Gib deine E-Mail Adresse ein.',
|
||||||
},
|
// textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Form(
|
||||||
|
key: formKey,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
autocorrect: false,
|
||||||
|
autofocus: true,
|
||||||
|
controller: mailController,
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
helperText: 'test',
|
||||||
|
label: Text('E-Mail Adresse'),
|
||||||
|
filled: true,
|
||||||
|
),
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || !value.isValidEmail) {
|
||||||
|
return 'Bitte eine valide E-Mail Adresse angeben';
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (formKey.currentState!.validate()) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (builder) => PasswordPage(
|
||||||
|
email: mailController.text,
|
||||||
|
register: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'Stattdessen anmelden',
|
||||||
|
// textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: CustomColors.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Hero(
|
||||||
|
tag: 'flow-button',
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: CustomColors.primary,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (formKey.currentState!.validate()) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (builder) => PasswordPage(
|
||||||
|
email: mailController.text,
|
||||||
|
register: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const SizedBox(
|
||||||
|
height: 50,
|
||||||
|
width: 100,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Weiter',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Spacer(
|
||||||
|
flex: 2,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
),
|
||||||
height: 20,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
if (formKey.currentState!.validate()) {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (builder) => PasswordPage(
|
|
||||||
email: mailController.text,
|
|
||||||
register: false,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
'Stattdessen anmelden',
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: CustomColors.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Hero(
|
|
||||||
tag: 'flow-button',
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: CustomColors.primary,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
if (formKey.currentState!.validate()) {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (builder) => PasswordPage(
|
|
||||||
email: mailController.text,
|
|
||||||
register: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: const SizedBox(
|
|
||||||
height: 50,
|
|
||||||
width: 100,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Weiter',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const Spacer(
|
|
||||||
flex: 2,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,126 +1,187 @@
|
|||||||
import 'package:app/model/services/auth_service.dart';
|
import 'package:app/model/services/auth_service.dart';
|
||||||
|
import 'package:app/model/services/storage_service.dart';
|
||||||
import 'package:app/pages/notifications_page.dart';
|
import 'package:app/pages/notifications_page.dart';
|
||||||
import 'package:app/util/colors.dart';
|
import 'package:app/util/colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SecurityPage extends StatelessWidget {
|
class SecurityPage extends StatefulWidget {
|
||||||
const SecurityPage({super.key});
|
const SecurityPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SecurityPage> createState() => _SecurityPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SecurityPageState extends State<SecurityPage> {
|
||||||
|
final StorageService _storageService = StorageService();
|
||||||
|
bool _loading = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_init();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _init() async {
|
||||||
|
final accountLevel = await _storageService.accountLevel;
|
||||||
|
if (accountLevel > 1 && mounted) {
|
||||||
|
await Navigator.push(context,
|
||||||
|
MaterialPageRoute(builder: (builder) => const NotificationsPage()));
|
||||||
|
setState(() {
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: _loading
|
||||||
appBar: AppBar(
|
? Center(
|
||||||
iconTheme: IconThemeData(color: CustomColors.primary),
|
child: Column(
|
||||||
),
|
children: [
|
||||||
body: Padding(
|
const SizedBox(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 20, 16, 16),
|
height: 150,
|
||||||
child: Center(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
const Spacer(),
|
|
||||||
const Hero(
|
|
||||||
tag: 'flow-icon',
|
|
||||||
child: Icon(
|
|
||||||
Icons.fingerprint,
|
|
||||||
color: Colors.white,
|
|
||||||
size: 200,
|
|
||||||
),
|
),
|
||||||
),
|
Hero(
|
||||||
const Spacer(),
|
tag: 'logo',
|
||||||
const Text(
|
child: Image.asset(
|
||||||
'Deine Sicherheit kommt an erster Stelle',
|
'assets/JPEG.jpg',
|
||||||
textAlign: TextAlign.center,
|
height: 180,
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'sans-serif',
|
|
||||||
fontSize: 25,
|
|
||||||
fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 30,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Schütze dein Konto mit der biometrischen Erkennung deines Geräts oder lege einen Code fest.',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'sans-serif',
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
Hero(
|
|
||||||
tag: 'flow-button',
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: CustomColors.primary,
|
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
),
|
||||||
bool isAuthenticated =
|
CircularProgressIndicator(
|
||||||
await AuthService.authenticateWithBiometrics();
|
color: CustomColors.primary,
|
||||||
if (isAuthenticated) {
|
),
|
||||||
// ignore: use_build_context_synchronously
|
],
|
||||||
Navigator.push(
|
),
|
||||||
context,
|
)
|
||||||
MaterialPageRoute(
|
: Scaffold(
|
||||||
builder: (context) => NotificationsPage()),
|
appBar: AppBar(
|
||||||
);
|
leading: BackButton(
|
||||||
}
|
color: CustomColors.primary,
|
||||||
},
|
onPressed: () async {
|
||||||
child: const SizedBox(
|
await _storageService.setAccountLevel(0);
|
||||||
height: 60,
|
if (mounted) {
|
||||||
child: Row(
|
Navigator.pop(context);
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
}
|
||||||
children: [
|
},
|
||||||
Text(
|
),
|
||||||
'App absichern',
|
iconTheme: IconThemeData(color: CustomColors.primary),
|
||||||
style: TextStyle(
|
),
|
||||||
fontSize: 20,
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 20, 16, 16),
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Spacer(),
|
||||||
|
const Hero(
|
||||||
|
tag: 'flow-icon',
|
||||||
|
child: Icon(
|
||||||
|
Icons.fingerprint,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 200,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
const Text(
|
||||||
|
'Deine Sicherheit kommt an erster Stelle',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontSize: 25,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Schütze dein Konto mit der biometrischen Erkennung deines Geräts oder lege einen Code fest.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Hero(
|
||||||
|
tag: 'flow-button',
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: CustomColors.primary,
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
bool isAuthenticated =
|
||||||
|
await AuthService.authenticateWithBiometrics();
|
||||||
|
if (isAuthenticated) {
|
||||||
|
await _storageService.setAccountLevel(2);
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) =>
|
||||||
|
const NotificationsPage()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const SizedBox(
|
||||||
|
height: 60,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'App absichern',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
// const SizedBox(
|
||||||
|
// height: 10,
|
||||||
|
// ),
|
||||||
|
// ElevatedButton(
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// backgroundColor: CustomColors.secondary,
|
||||||
|
// ),
|
||||||
|
// onPressed: () {
|
||||||
|
// Navigator.push(
|
||||||
|
// context,
|
||||||
|
// MaterialPageRoute(
|
||||||
|
// builder: (builder) => SecurityPage(),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// child: const SizedBox(
|
||||||
|
// height: 60,
|
||||||
|
// child: Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
// children: [
|
||||||
|
// Text(
|
||||||
|
// 'Eigenen Code festlegen',
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: Colors.white,
|
||||||
|
// fontSize: 22,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
const Spacer(
|
||||||
|
flex: 2,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// const SizedBox(
|
),
|
||||||
// height: 10,
|
|
||||||
// ),
|
|
||||||
// ElevatedButton(
|
|
||||||
// style: ElevatedButton.styleFrom(
|
|
||||||
// backgroundColor: CustomColors.secondary,
|
|
||||||
// ),
|
|
||||||
// onPressed: () {
|
|
||||||
// Navigator.push(
|
|
||||||
// context,
|
|
||||||
// MaterialPageRoute(
|
|
||||||
// builder: (builder) => SecurityPage(),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// child: const SizedBox(
|
|
||||||
// height: 60,
|
|
||||||
// child: Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
// children: [
|
|
||||||
// Text(
|
|
||||||
// 'Eigenen Code festlegen',
|
|
||||||
// style: TextStyle(
|
|
||||||
// color: Colors.white,
|
|
||||||
// fontSize: 22,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
const Spacer(
|
|
||||||
flex: 2,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,112 +1,166 @@
|
|||||||
|
import 'package:app/model/services/storage_service.dart';
|
||||||
import 'package:app/pages/agb_page.dart';
|
import 'package:app/pages/agb_page.dart';
|
||||||
import 'package:app/pages/security_page.dart';
|
import 'package:app/pages/security_page.dart';
|
||||||
import 'package:app/util/colors.dart';
|
import 'package:app/util/colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class StartPage extends StatelessWidget {
|
class StartPage extends StatefulWidget {
|
||||||
const StartPage({super.key});
|
const StartPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StartPage> createState() => _StartPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StartPageState extends State<StartPage> {
|
||||||
|
final StorageService _storageService = StorageService();
|
||||||
|
bool _loading = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_init();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _init() async {
|
||||||
|
int accountLevel = await _storageService.accountLevel;
|
||||||
|
if (accountLevel > 0 && mounted) {
|
||||||
|
await Navigator.push(context,
|
||||||
|
MaterialPageRoute(builder: (builder) => const SecurityPage()));
|
||||||
|
setState(() {
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: _loading
|
||||||
appBar: AppBar(
|
? Center(
|
||||||
iconTheme: IconThemeData(color: CustomColors.primary),
|
child: Column(
|
||||||
),
|
children: [
|
||||||
body: Padding(
|
const SizedBox(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 20, 16, 16),
|
height: 150,
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Hero(
|
|
||||||
tag: 'flow-icon',
|
|
||||||
child: Image.asset(
|
|
||||||
'assets/JPEG.jpg',
|
|
||||||
height: 180,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 30,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Hallo. Digitale Spuren\nentfernen\nper Knopfdruck.',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'sans-serif',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
letterSpacing: 2.0,
|
|
||||||
fontSize: 25,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 20,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Mit uns finden Sie Ihre Digitalen Spuren und können diese entfernen.',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'sans-serif',
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Spacer(
|
|
||||||
flex: 1,
|
|
||||||
),
|
|
||||||
Hero(
|
|
||||||
tag: 'flow-button',
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: CustomColors.primary,
|
|
||||||
),
|
),
|
||||||
onPressed: () {
|
Hero(
|
||||||
Navigator.push(
|
tag: 'logo',
|
||||||
context,
|
child: Image.asset(
|
||||||
MaterialPageRoute(
|
'assets/JPEG.jpg',
|
||||||
builder: (builder) => SecurityPage(),
|
height: 180,
|
||||||
// builder: (builder) => SecurityPage(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: const SizedBox(
|
|
||||||
height: 60,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Weiter',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color: CustomColors.primary,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
iconTheme: IconThemeData(color: CustomColors.primary),
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 20, 16, 16),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Hero(
|
||||||
|
tag: 'flow-icon',
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/JPEG.jpg',
|
||||||
|
height: 180,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Hallo. Digitale Spuren\nentfernen\nper Knopfdruck.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
letterSpacing: 2.0,
|
||||||
|
fontSize: 25,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Mit uns finden Sie Ihre Digitalen Spuren und können diese entfernen.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(
|
||||||
|
flex: 1,
|
||||||
|
),
|
||||||
|
Hero(
|
||||||
|
tag: 'flow-button',
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: CustomColors.primary,
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
await _storageService.setAccountLevel(1);
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (builder) => const SecurityPage(),
|
||||||
|
// builder: (builder) => SecurityPage(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const SizedBox(
|
||||||
|
height: 60,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Weiter',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(
|
||||||
|
flex: 1,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Mit der weiteren Nutzung stimmst du den folgenden Bedingungen zu:',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (builder) => AgbPage());
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'AGB - Datenschutzerklärung',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(color: CustomColors.primary),
|
||||||
|
))
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(
|
),
|
||||||
flex: 1,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Mit der weiteren Nutzung stimmst du den folgenden Bedingungen zu:',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'sans-serif',
|
|
||||||
fontSize: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
showDialog(
|
|
||||||
context: context, builder: (builder) => AgbPage());
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
'AGB - Datenschutzerklärung',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(color: CustomColors.primary),
|
|
||||||
))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,110 +1,156 @@
|
|||||||
|
import 'package:app/model/services/storage_service.dart';
|
||||||
import 'package:app/util/colors.dart';
|
import 'package:app/util/colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class VerifyEmailPage extends StatelessWidget {
|
class VerifyEmailPage extends StatefulWidget {
|
||||||
VerifyEmailPage({super.key});
|
const VerifyEmailPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<VerifyEmailPage> createState() => _VerifyEmailPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VerifyEmailPageState extends State<VerifyEmailPage> {
|
||||||
|
final StorageService _storageService = StorageService();
|
||||||
|
bool _loading = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
setState(() {
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: _loading
|
||||||
appBar: AppBar(
|
? Center(
|
||||||
iconTheme: IconThemeData(
|
child: Column(
|
||||||
color: CustomColors.primary,
|
children: [
|
||||||
),
|
const SizedBox(
|
||||||
),
|
height: 150,
|
||||||
body: Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(20, 20, 20, 16),
|
|
||||||
child: Column(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
const SizedBox(
|
|
||||||
height: 80,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Verifizieren',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'sans-serif',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
letterSpacing: 2.0,
|
|
||||||
fontSize: 25,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 50,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Wir haben dir eine E-Mail geschickt.',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 20,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Bitte verifiziere deine E-Mail Adresse, dann geht es weiter.',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 80,
|
|
||||||
),
|
|
||||||
Hero(
|
|
||||||
tag: 'flow-button',
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: CustomColors.primary,
|
|
||||||
),
|
),
|
||||||
onPressed: () {},
|
Hero(
|
||||||
child: const SizedBox(
|
tag: 'logo',
|
||||||
height: 50,
|
child: Image.asset(
|
||||||
width: 100,
|
'assets/JPEG.jpg',
|
||||||
child: Row(
|
height: 180,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Weiter',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
CircularProgressIndicator(
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 60,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Noch keine E-Mail erhalten?',
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
'Schon im Spam-Ordner nachgeschaut?',
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 20,
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {},
|
|
||||||
child: Text(
|
|
||||||
'Erneut senden',
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: CustomColors.primary,
|
color: CustomColors.primary,
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: BackButton(
|
||||||
|
color: CustomColors.primary,
|
||||||
|
onPressed: () async {
|
||||||
|
await _storageService.setAccountLevel(3);
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
iconTheme: IconThemeData(
|
||||||
|
color: CustomColors.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(
|
body: Padding(
|
||||||
flex: 2,
|
padding: const EdgeInsets.fromLTRB(20, 20, 20, 16),
|
||||||
|
child: Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 80,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Verifizieren',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
letterSpacing: 2.0,
|
||||||
|
fontSize: 25,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 50,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Wir haben dir eine E-Mail geschickt.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
// textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Bitte verifiziere deine E-Mail Adresse, dann geht es weiter.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
// textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 80,
|
||||||
|
),
|
||||||
|
Hero(
|
||||||
|
tag: 'flow-button',
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: CustomColors.primary,
|
||||||
|
),
|
||||||
|
onPressed: () {},
|
||||||
|
child: const SizedBox(
|
||||||
|
height: 50,
|
||||||
|
width: 100,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Weiter',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 60,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Noch keine E-Mail erhalten?',
|
||||||
|
// textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Schon im Spam-Ordner nachgeschaut?',
|
||||||
|
// textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {},
|
||||||
|
child: Text(
|
||||||
|
'Erneut senden',
|
||||||
|
// textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: CustomColors.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(
|
||||||
|
flex: 2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ class CustomColors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Color get success {
|
static Color get success {
|
||||||
return const Color.fromARGB(200, 55, 125, 55);
|
return const Color.fromARGB(255, 51, 217, 178);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Color get primary {
|
static Color get primary {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user