Add login screen + logic + appcontext + redirection to main

This commit is contained in:
Thomas Fransolet 2021-04-20 17:10:15 +02:00
parent 9e4cd502cc
commit ea7f3876c1
12 changed files with 446 additions and 150 deletions

View File

@ -0,0 +1,42 @@
import 'package:flutter/material.dart';
import 'package:manager_app/constants.dart';
class RoundedButton extends StatelessWidget {
final String text;
final Function press;
final Color color, textColor;
final double fontSize;
const RoundedButton({
Key key,
this.text,
this.press,
this.color = kPrimaryColor,
this.textColor = kWhite,
this.fontSize
}) : super(key: key);
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.resolveWith((states) => EdgeInsets.symmetric(vertical: 25, horizontal: 85)),
backgroundColor: MaterialStateColor.resolveWith((states) => color),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
)
)
),
onPressed: () => {
press()
},
child: Text(
text,
style: new TextStyle(color: textColor, fontSize: fontSize, fontWeight: FontWeight.w400),
),
);
}
}

View File

@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import 'package:manager_app/Components/text_field_container.dart';
import 'package:manager_app/constants.dart';
class RoundedInputField extends StatelessWidget {
final String hintText;
final IconData icon;
final ValueChanged<String> onChanged;
const RoundedInputField({
Key key,
this.hintText,
this.icon = Icons.person,
this.onChanged,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextFieldContainer(
child: TextField(
onChanged: onChanged,
cursorColor: kPrimaryColor,
style: TextStyle(fontSize: 20, color: kBlack),
decoration: InputDecoration(
icon: Icon(
icon,
color: kPrimaryColor,
),
hintText: hintText,
hintStyle: TextStyle(fontSize: 20.0, color: kBlack),
border: InputBorder.none,
),
),
);
}
}

View File

@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:manager_app/Components/text_field_container.dart';
import 'package:manager_app/constants.dart';
class RoundedPasswordField extends StatefulWidget {
final ValueChanged<String> onChanged;
const RoundedPasswordField({
Key key,
this.onChanged,
}) : super(key: key);
@override
_RoundedPasswordFieldState createState() => _RoundedPasswordFieldState();
}
class _RoundedPasswordFieldState extends State<RoundedPasswordField> {
bool isVisible = true;
@override
Widget build(BuildContext context) {
return TextFieldContainer(
child: TextField(
obscureText: isVisible,
onChanged: widget.onChanged,
cursorColor: kPrimaryColor,
style: TextStyle(fontSize: 20, color: kBlack),
decoration: InputDecoration(
hintText: "Password",
hintStyle: TextStyle(fontSize: 20.0, color: kBlack),
icon: Icon(
Icons.lock,
color: kPrimaryColor,
),
suffixIcon: IconButton(
icon: Icon(Icons.visibility),
onPressed: () {
setState(() {
isVisible = !isVisible;
});
},
color: kPrimaryColor,
),
border: InputBorder.none,
),
),
);
}
}

View File

@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import 'package:manager_app/constants.dart';
class TextFieldContainer extends StatelessWidget {
final Widget child;
const TextFieldContainer({
Key key,
this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 5),
width: size.width * 0.8,
decoration: BoxDecoration(
color: kTextLightColor,
borderRadius: BorderRadius.circular(29),
),
child: child,
);
}
}

View File

@ -0,0 +1,18 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:managerapi/api.dart';
class ManagerAppContext with ChangeNotifier{
String email;
TokenDTO token;
dynamic clientAPI;
ManagerAppContext({this.email, this.token});
// Implement toString to make it easier to see information about
@override
String toString() {
return 'ManagerAppContext{email: $email, token: $token}';
}
}

View File

@ -0,0 +1,46 @@
import 'package:manager_app/app_context.dart';
import 'package:managerapi/api.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MainScreen extends StatefulWidget {
MainScreen({Key key, this.title}) : super(key: key);
final String title;
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
int _counter = 0;
@override
Widget build(BuildContext context) {
final appContext = Provider.of<AppContext>(context);
print(appContext.getContext().email);
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => print("YOULOU"),
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}

View File

@ -0,0 +1,155 @@
import 'package:flutter/material.dart';
import 'package:manager_app/Components/rounded_button.dart';
import 'package:manager_app/Components/rounded_input_field.dart';
import 'package:manager_app/Components/rounded_password_field.dart';
import 'package:manager_app/Models/managerContext.dart';
import 'package:manager_app/Screens/Main/main_screen.dart';
import 'package:manager_app/app_context.dart';
import 'package:manager_app/client.dart';
import 'package:manager_app/constants.dart';
import 'package:managerapi/api.dart';
import 'package:provider/provider.dart';
class LoginScreen extends StatefulWidget {
LoginScreen({Key key}) : super(key: key);
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
String email;// = "test@email.be";
String password;// = "kljqsdkljqsd";
final clientAPI = Client();
void authenticateTRY(dynamic appContext) async {
print("try auth.. ");
print(this.email);
print(this.password);
// if () {} // Add if token exist and not null + not expired
var isError = true;
try {
LoginDTO loginDTO = new LoginDTO(email: email, password: password);
TokenDTO token = await clientAPI.authenticationApi.authenticationAuthenticateWithJson(loginDTO);
print("Token ??");
print(token);
print(token.accessToken);
setAccessToken(token.accessToken);
isError = false;
// Set the appContext
if (appContext.getContext() == null) {
ManagerAppContext managerAppContext = new ManagerAppContext();
// store user info locally
managerAppContext.email = email;
managerAppContext.token = token;
managerAppContext.clientAPI = clientAPI;
print(managerAppContext);
appContext.setContext(managerAppContext);
}
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) {
return MainScreen();
},
),
(Route<dynamic> route) => false // For pushAndRemoveUntil
);
}
catch (e) {
print("error auth");
}
/*if (!isError) {
UserDetailDTO user = await clientAPI.userApi.userGetDetail("6071f74aaf542f03116f2b9b");
print("user values ??");
print(user.email);
print(user.id);
List<ConfigurationDTO> configurations = await clientAPI.configurationApi.configurationGet();
print("number of configurations " + configurations.length.toString());
configurations.forEach((element) {
print(element);
});
List<SectionDTO> sections = await clientAPI.sectionApi.sectionGet();
print("number of sections " + sections.length.toString());
sections.forEach((element) {
print(element);
});
List<RessourceDTO> ressources = await clientAPI.ressourceApi.ressourceGet();
print("number of ressources " + ressources.length.toString());
ressources.forEach((element) {
print(element);
});
}*/
}
void setAccessToken(String accessToken) {
clientAPI.apiApi.authentications.forEach((key, auth) {
if (auth is OAuth) {
auth.accessToken = accessToken;
}
});
}
@override
Widget build(BuildContext context) {
final appContext = Provider.of<AppContext>(context);
Size size = MediaQuery.of(context).size;
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Container(
height: size.height *0.5,
width: size.width *0.5,
decoration: BoxDecoration(
color: kWhite,
borderRadius: BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: kWhite.withOpacity(0.3),
spreadRadius: 0.5,
blurRadius: 0.5,
offset: Offset(0, 1.5), // changes position of shadow
),
],
),
child: Padding(
padding: const EdgeInsets.only(left: 60.0, right: 60.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RoundedInputField(
hintText: "Your Email",
onChanged: (value) {
email = value;
},
),
RoundedPasswordField(
onChanged: (value) {
password = value;
},
),
SizedBox(height: size.height * 0.02),
RoundedButton(
text: "LOGIN",
fontSize: 25,
press: () {
authenticateTRY(appContext);
},
),
],
),
),
),
),
),
);
}
}

22
lib/app_context.dart Normal file
View File

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'Models/managerContext.dart';
class AppContext with ChangeNotifier {
ManagerAppContext _managerContext;
AppContext(this._managerContext);
getContext() => _managerContext;
setContext(ManagerAppContext appContext) async {
_managerContext = appContext;
// STORE IT LOCALLY (SQLite)
//await DatabaseHelper.instance.update(appContext);
// Store it in Firestore
//await FirestoreHelper.instance.add(appContext);
notifyListeners();
}
}

View File

@ -1,10 +1,17 @@
import 'package:flutter/material.dart';
// Colors - TO FILL WIT CORRECT COLOR
const kBackgroundColor = Color(0xFFFFFFFF);
//const kBackgroundColor = Color(0xFFFFFFFF);
const kTitleTextColor = Color(0xFF303030);
const kBodyTextColor = Color(0xFF4B4B4B); // TODO
const kTextLightColor = Color(0xFFCED5DF); // #ced5df
const kBackgroundColor = Color(0xFFf5f5f7);
const kPrimaryColor = Color(0xFFCA413F);
const kTextLightColor = Color(0xFFE3DfDE);
const kSecond = Color(0xFFC4B1AE);
const kWhite = Color(0xFFFFFFFF);
const kBlack = Color(0xFF000000);
/*
const kTextStyle = TextStyle(

View File

@ -1,12 +1,17 @@
import 'package:manager_app/Models/managerContext.dart';
import 'package:manager_app/Screens/Main/main_screen.dart';
import 'package:managerapi/api.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'Screens/login_screen.dart';
import 'app_context.dart';
import 'client.dart';
import 'constants.dart';
void main() {
String initialRoute;
initialRoute = '/home';
initialRoute = '/welcome';
final MyApp myApp = MyApp(
initialRoute: initialRoute,
@ -18,8 +23,8 @@ void main() {
class MyApp extends StatefulWidget {
final String initialRoute;
//final Context context;
MyApp({this.initialRoute});
final ManagerAppContext managerAppContext;
MyApp({this.initialRoute, this.managerAppContext});
// This widget is the root of your application.
@override
@ -29,7 +34,9 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
return ChangeNotifierProvider<AppContext>(
create: (_) => AppContext(widget.managerAppContext),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Manager App Demo',
initialRoute: widget.initialRoute,
@ -45,136 +52,11 @@ class _MyAppState extends State<MyApp> {
visualDensity: VisualDensity.adaptivePlatformDensity,
),
routes: {
'/home': (context) => MyHomePage(title: 'Manager App Demo Home Page')
'/welcome': (context) => LoginScreen(),
'/main': (context) => MainScreen(title: 'Manager App Demo Home Page')
}
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
final clientAPI = Client();
void authenticateTRY() async {
print("try auth.. ");
// if () {} // Add if token exist and not null + not expired
var isError = true;
try {
LoginDTO loginDTO = new LoginDTO(email: "test@email.be", password: "kljqsdkljqsd");
TokenDTO token = await clientAPI.authenticationApi.authenticationAuthenticateWithJson(loginDTO);
print("Token ??");
print(token);
print(token.accessToken);
setAccessToken(token.accessToken);
isError = false;
}
catch (e) {
print("error auth");
}
if (!isError) {
UserDetailDTO user = await clientAPI.userApi.userGetDetail("6071f74aaf542f03116f2b9b");
print("user values ??");
print(user.email);
print(user.id);
List<ConfigurationDTO> configurations = await clientAPI.configurationApi.configurationGet();
print("number of configurations " + configurations.length.toString());
configurations.forEach((element) {
print(element);
});
List<SectionDTO> sections = await clientAPI.sectionApi.sectionGet();
print("number of sections " + sections.length.toString());
sections.forEach((element) {
print(element);
});
List<RessourceDTO> ressources = await clientAPI.ressourceApi.ressourceGet();
print("number of ressources " + ressources.length.toString());
ressources.forEach((element) {
print(element);
});
}
}
void setAccessToken(String accessToken) {
clientAPI.apiApi.authentications.forEach((key, auth) {
if (auth is OAuth) {
auth.accessToken = accessToken;
}
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: authenticateTRY,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}

View File

@ -109,6 +109,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
nested:
dependency: transitive
description:
name: nested
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
path:
dependency: transitive
description:
@ -123,6 +130,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.0"
provider:
dependency: "direct main"
description:
name: provider
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0"
rxdart:
dependency: "direct main"
description:
@ -193,3 +207,4 @@ packages:
version: "2.1.0"
sdks:
dart: ">=2.12.0-0.0 <3.0.0"
flutter: ">=1.16.0"

View File

@ -25,6 +25,7 @@ dependencies:
sdk: flutter
rxdart: 0.22.0
provider: ^5.0.0
managerapi:
path: manager_api