diff --git a/frontend/app/lib/assets/fonts/JosefinSans-Italic-VariableFont_wght.ttf b/frontend/app/lib/assets/fonts/JosefinSans-Italic-VariableFont_wght.ttf new file mode 100644 index 0000000..d2d2dd6 Binary files /dev/null and b/frontend/app/lib/assets/fonts/JosefinSans-Italic-VariableFont_wght.ttf differ diff --git a/frontend/app/lib/assets/fonts/JosefinSans-VariableFont_wght.ttf b/frontend/app/lib/assets/fonts/JosefinSans-VariableFont_wght.ttf new file mode 100644 index 0000000..00ea1e7 Binary files /dev/null and b/frontend/app/lib/assets/fonts/JosefinSans-VariableFont_wght.ttf differ diff --git a/frontend/app/lib/main.dart b/frontend/app/lib/main.dart index 537dffe..2ef1cba 100644 --- a/frontend/app/lib/main.dart +++ b/frontend/app/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:app/pages/home_page.dart'; import 'package:app/pages/login_page.dart'; import 'package:app/widgets/background.dart'; import 'package:flutter/material.dart'; @@ -42,7 +43,9 @@ void main() async { backgroundColor: Colors.black, foregroundColor: Colors.white, )), - home: const Background(child: LoginPage()), + home: const Background( + child: HomePage(), + ), ), ); } diff --git a/frontend/app/lib/pages/home_page.dart b/frontend/app/lib/pages/home_page.dart new file mode 100644 index 0000000..1e23107 --- /dev/null +++ b/frontend/app/lib/pages/home_page.dart @@ -0,0 +1,154 @@ +import 'package:app/gapi/client.dart'; +import 'package:app/pages/login_page.dart'; +import 'package:app/pages/start_page.dart'; +import 'package:flutter/material.dart'; +import 'package:app/pages/pages.dart'; + +Map> bottomBarButtons = { + Pages.start: const [ + BottomNavigationBarItem( + label: 'Zurueck', + backgroundColor: Colors.white, + icon: Icon( + Icons.arrow_back, + color: Colors.white, + ), + ), + BottomNavigationBarItem( + backgroundColor: Colors.white, + label: 'AccountInf', + icon: Icon( + Icons.person, + color: Colors.white, + ), + ), + ], + Pages.persons: const [ + BottomNavigationBarItem( + label: 'Zurueck', + backgroundColor: Colors.white, + icon: Icon( + Icons.arrow_back, + color: Colors.white, + ), + ), + BottomNavigationBarItem( + backgroundColor: Colors.white, + label: 'AccountInf', + icon: Icon( + Icons.person, + color: Colors.white, + ), + ), + ], + Pages.about: const [ + BottomNavigationBarItem( + label: 'Zurueck', + backgroundColor: Colors.white, + icon: Icon( + Icons.arrow_back, + color: Colors.white, + ), + ), + BottomNavigationBarItem( + backgroundColor: Colors.white, + label: 'AccountInf', + icon: Icon( + Icons.person, + color: Colors.white, + ), + ), + ], + Pages.login: const [ + BottomNavigationBarItem( + label: 'Zurueck', + backgroundColor: Colors.white, + icon: Icon( + Icons.arrow_back, + color: Colors.white, + ), + ), + BottomNavigationBarItem( + backgroundColor: Colors.white, + label: 'AccountInf', + icon: Icon( + Icons.person, + color: Colors.white, + ), + ), + ] +}; + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + bool _loading = false; + + Pages _selectedPage = Pages.start; + + Widget _selectPage(Pages page) { + switch (page) { + case Pages.login: + return const LoginPage(); + default: + return StartPage(onChangePage: changePage); + } + } + + Future _onWillPop() async { + changePage(Pages.start); + return false; + } + + void changePage(Pages page) { + if (!Pages.values.contains(page)) { + page = _selectedPage; + } + setState(() { + _selectedPage = page; + }); + } + + void _setLoading(bool loading) { + setState(() { + _loading = loading; + }); + } + + final Client client = Client(); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: _selectedPage == 'start' + ? AppBar( + automaticallyImplyLeading: false, + ) + : AppBar( + automaticallyImplyLeading: false, + flexibleSpace: Image.asset( + 'lib/assets/logo_300x200.png', + height: 80, + ), + ), + bottomNavigationBar: BottomNavigationBar( + items: bottomBarButtons[_selectedPage]!.toList(), + backgroundColor: Colors.transparent, + ), + body: Container( + padding: const EdgeInsets.fromLTRB(16, 32, 16, 32), + child: Center( + child: WillPopScope( + child: _selectPage(_selectedPage), + onWillPop: () => _onWillPop(), + ), + ), + ), + ); + } +} diff --git a/frontend/app/lib/pages/login_page.dart b/frontend/app/lib/pages/login_page.dart index 89ddd00..b9239c8 100644 --- a/frontend/app/lib/pages/login_page.dart +++ b/frontend/app/lib/pages/login_page.dart @@ -27,131 +27,101 @@ class _LoginPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - automaticallyImplyLeading: false, - flexibleSpace: Image.asset( - 'lib/assets/logo_300x200.png', - height: 80, - ), - ), - bottomNavigationBar: BottomNavigationBar( - items: const [ - BottomNavigationBarItem( - label: 'Zurueck', - backgroundColor: Colors.white, - icon: Icon( - Icons.arrow_back, - color: Colors.white, - ), - ), - BottomNavigationBarItem( - backgroundColor: Colors.white, - label: 'AccountInf', - icon: Icon( - Icons.person, - color: Colors.white, - ), - ), - ], - backgroundColor: Colors.transparent, - ), - body: !_loading - ? Form( - key: _formKey, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - TextFormField( - // style: TextStyle( - // color: Theme.of(context).colorScheme.primary, - // ), - controller: mailController, - decoration: const InputDecoration( - fillColor: Color.fromARGB(30, 255, 255, 255), - filled: true, - hintStyle: TextStyle( - color: Colors.white38, - ), - hintText: 'E-Mail Adresse', + return !_loading + ? Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TextFormField( + // style: TextStyle( + // color: Theme.of(context).colorScheme.primary, + // ), + controller: mailController, + decoration: const InputDecoration( + fillColor: Color.fromARGB(30, 255, 255, 255), + filled: true, + hintStyle: TextStyle( + color: Colors.white38, ), - keyboardType: TextInputType.emailAddress, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Bitte eine gültige E-Mail Adresse eingeben'; - } - return null; - }, + hintText: 'E-Mail Adresse', ), - TextFormField( - style: const TextStyle( - color: Colors.white, - ), - controller: passwordController, - decoration: const InputDecoration( - fillColor: Color.fromARGB(30, 255, 255, 255), - filled: true, - hintStyle: TextStyle( - color: Colors.white38, - ), - hintText: 'Passwort', - ), - keyboardType: TextInputType.visiblePassword, - obscureText: true, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Bitte geben Sie Ihr Passwort ein'; - } - return null; - }, + keyboardType: TextInputType.emailAddress, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Bitte eine gültige E-Mail Adresse eingeben'; + } + return null; + }, + ), + TextFormField( + style: const TextStyle( + color: Colors.white, ), - ElevatedButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - // final navigator = Navigator.of(context); - _setLoading(true); - client - .login( - email: mailController.text, - password: passwordController.text, - onError: () { - _setLoading(false); - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text('Login fehlgeschlagen'), - )); - }, - onSuccess: () { - // _setLoading(false); - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text('Login erfolgreich'), - )); - }, - ) - .then( - (r) { - if (r.accessToken != '') { - Navigator.pushAndRemoveUntil( - context, - MaterialPageRoute( - builder: (ctx) => DashboardPage( - client: client, - ), - ), - (route) => false); - } - // _setLoading(false); - }, - ); - } - }, - child: const Icon(Icons.arrow_forward)) - ], - ), - ) - : const LoadingWidget(), - ); + controller: passwordController, + decoration: const InputDecoration( + fillColor: Color.fromARGB(30, 255, 255, 255), + filled: true, + hintStyle: TextStyle( + color: Colors.white38, + ), + hintText: 'Passwort', + ), + keyboardType: TextInputType.visiblePassword, + obscureText: true, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Bitte geben Sie Ihr Passwort ein'; + } + return null; + }, + ), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + // final navigator = Navigator.of(context); + _setLoading(true); + client + .login( + email: mailController.text, + password: passwordController.text, + onError: () { + _setLoading(false); + ScaffoldMessenger.of(context) + .showSnackBar(const SnackBar( + content: Text('Login fehlgeschlagen'), + )); + }, + onSuccess: () { + // _setLoading(false); + ScaffoldMessenger.of(context) + .showSnackBar(const SnackBar( + content: Text('Login erfolgreich'), + )); + }, + ) + .then( + (r) { + if (r.accessToken != '') { + Navigator.push( + context, + MaterialPageRoute( + builder: (ctx) => DashboardPage( + client: client, + ), + ), + ); + } + // _setLoading(false); + }, + ); + } + }, + child: const Icon(Icons.arrow_forward)) + ], + ), + ) + : const LoadingWidget(); } } diff --git a/frontend/app/lib/pages/pages.dart b/frontend/app/lib/pages/pages.dart new file mode 100644 index 0000000..b8f802a --- /dev/null +++ b/frontend/app/lib/pages/pages.dart @@ -0,0 +1 @@ +enum Pages { start, login, about, persons } diff --git a/frontend/app/lib/pages/start_page.dart b/frontend/app/lib/pages/start_page.dart new file mode 100644 index 0000000..0896168 --- /dev/null +++ b/frontend/app/lib/pages/start_page.dart @@ -0,0 +1,87 @@ +import 'package:app/pages/pages.dart'; +import 'package:flutter/material.dart'; +import 'dart:core'; + +class StartPage extends StatelessWidget { + StartPage({ + super.key, + required this.onChangePage, + }); + + void Function(Pages page) onChangePage; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Image( + image: AssetImage( + 'lib/assets/logo_300x200.png', + ), + ), + // Text( + // 'Peace of Mind \nin the\nAfterlife', + // textAlign: TextAlign.center, + // style: TextStyle( + // fontFamily: 'JosefinSans', + // height: 1.7, + // letterSpacing: 8, + // wordSpacing: 2, + // fontWeight: FontWeight.bold, + // fontSize: 32, + // color: Colors.white, + // decoration: TextDecoration.none, + // decorationColor: Colors.white, + // ), + // ), + const SizedBox( + height: 40, + ), + Text( + 'Digitale Spuren auf Knopfdruck entfernen'.toUpperCase(), + textAlign: TextAlign.center, + style: const TextStyle( + fontFamily: 'sans-serif', + fontSize: 24, + height: 1.6, + fontWeight: FontWeight.normal, + letterSpacing: 6, + ), + ), + const Spacer(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ElevatedButton.icon( + label: const Text('Login'), + onPressed: () { + onChangePage(Pages.login); + }, + icon: const Icon( + Icons.login, + semanticLabel: 'Login', + size: 16, + ), + ), + ElevatedButton.icon( + label: const Text('Registrieren'), + onPressed: () {}, + icon: const Icon( + Icons.person_add, + semanticLabel: 'Register', + size: 16, + ), + ), + ], + ), + // const SizedBox( + // height: 32, + // ), + + // const Text('data'), + ], + ); + } +} diff --git a/frontend/app/pubspec.yaml b/frontend/app/pubspec.yaml index 6b33b3f..07e48bb 100644 --- a/frontend/app/pubspec.yaml +++ b/frontend/app/pubspec.yaml @@ -81,8 +81,12 @@ flutter: # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: - # fonts: - # - family: Schyler + fonts: + - family: JosefinSans + fonts: + - asset: lib/assets/fonts/JosefinSans-Italic-VariableFont_wght.ttf + style: italic + - asset: lib/assets/fonts/JosefinSans-VariableFont_wght.ttf # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf