diff --git a/flutter-app/lib/bloc/auth_bloc.dart b/flutter-app/lib/bloc/auth_bloc.dart index ad69fb8..df1188e 100644 --- a/flutter-app/lib/bloc/auth_bloc.dart +++ b/flutter-app/lib/bloc/auth_bloc.dart @@ -1,39 +1,54 @@ import 'dart:async'; import 'package:flatten/bloc/bloc_provider.dart'; -import 'package:flutter/foundation.dart'; -/// this is the user modal, and we can use this to access current user data -/// once they are logged in -class User implements BlocBase{ - User({@required this.uid, @required this.preName, @required this.name, @required this.zip}); - final String uid; - final String preName; - final String name; - final String zip; +import 'package:flatten/bloc/user_bloc.dart'; +import 'package:flatten/models/api_response.dart'; +import 'package:flatten/services/qr_code_service.dart'; +import 'package:flatten/models/qr_code_add.dart'; +import 'package:flatten/models/qr_code.dart'; - void dispose(){ - - } - - Map get userData => {'uid' : uid, 'preName': preName, 'name': name, 'zip': zip}; -} - - -///this class can be modified to do authenticaion, once we have a database ready, we just have to +///this class can be modified to do authenticaion, once we have a database ready, we just have to ///add the sign-in logic in the singIn() method and enter the user details, we can also add a method here to ///check whether the user already exists in our database or not -class Auth implements BlocBase { - StreamController _controller = StreamController(); - Stream get userStream => _controller.stream; +class Auth_Bloc implements BlocBase { + + StreamController _usercontroller = StreamController(); + StreamController _isAuthenticating = StreamController(); + + Stream get userStream => _usercontroller.stream; + Stream get isAuthenticationStream => _isAuthenticating.stream; - void _setUser(User user) => _controller.add(user); + void _setUser(User_Bloc user) => _usercontroller.add(user); + void _setIsAuthenicating(AuthState authState) => _isAuthenticating.add(authState); - void dispose(){ - _controller.close(); - } - - void signIn(String uid, String preName, String name, String zip){ - User user = User(name: name, uid: uid, preName: preName, zip: zip); - _setUser(user); - } - -} \ No newline at end of file + void dispose() { + _usercontroller.close(); + _isAuthenticating.close(); + } + + void signIn(String preName, String name, String zip) async{ + final qr_code_for_add = QR_Code_For_Add( + name: name, + useCase: 1, + active: true, + additionalInformation: "", + gpsPosition: zip, + status: 1); + QR_Code_Service service = QR_Code_Service(); + _setIsAuthenicating(AuthState(inProgress: true, errorOccured: false)); + final APIResponse qrCodeData = await service.upLoadQR(qr_code_for_add); + final QrCode qrCode = qrCodeData.data; + if(!qrCodeData.error){ + User_Bloc user = User_Bloc(name: qrCode.name, uid: qrCode.id, preName: preName, zip: zip); + _setIsAuthenicating(AuthState(inProgress : false, errorOccured: false)); + _setUser(user); + }else{ + _setIsAuthenicating(AuthState(inProgress:false, errorOccured: true)); + } + } +} + +class AuthState{ + AuthState({this.inProgress, this.errorOccured}); + bool inProgress; + bool errorOccured; +} diff --git a/flutter-app/lib/bloc/user_bloc.dart b/flutter-app/lib/bloc/user_bloc.dart new file mode 100644 index 0000000..8bd6aca --- /dev/null +++ b/flutter-app/lib/bloc/user_bloc.dart @@ -0,0 +1,21 @@ + +import 'package:flatten/bloc/bloc_provider.dart'; +import 'package:flutter/foundation.dart'; + +/// this is the user modal, and we can use this to access current user data +/// once they are logged in + + +class User_Bloc implements BlocBase{ + User_Bloc({@required this.uid, @required this.preName, @required this.name, @required this.zip}); + final String uid; + final String preName; + final String name; + final String zip; + + void dispose(){ + + } + + Map get userData => {'uid' : uid, 'preName': preName, 'name': name, 'zip': zip}; +} diff --git a/flutter-app/lib/main.dart b/flutter-app/lib/main.dart index c3c7a94..68f0f13 100644 --- a/flutter-app/lib/main.dart +++ b/flutter-app/lib/main.dart @@ -16,8 +16,8 @@ void main() { class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocProvider( - bloc: Auth(), + return BlocProvider( + bloc: Auth_Bloc(), child: BlocProvider( bloc: HS_Info_Bloc(), child: MaterialApp( diff --git a/flutter-app/lib/models/api_response.dart b/flutter-app/lib/models/api_response.dart new file mode 100644 index 0000000..882d37c --- /dev/null +++ b/flutter-app/lib/models/api_response.dart @@ -0,0 +1,7 @@ +class APIResponse { + T data; + bool error; + String errorMessage; + + APIResponse({this.data, this.errorMessage, this.error=false}); +} \ No newline at end of file diff --git a/flutter-app/lib/models/qr_code.dart b/flutter-app/lib/models/qr_code.dart index bac37e1..a4c9dbe 100644 --- a/flutter-app/lib/models/qr_code.dart +++ b/flutter-app/lib/models/qr_code.dart @@ -1,21 +1,25 @@ class QrCode { - final String id; - final String createDateTime; - final String name; - final int useCase; - final String additionalInformation; - final bool active; - final int status; + String id; + String createDateTime; + String name; + int useCase; + String additionalInformation; + bool active; + int status; - QrCode(this.id, this.createDateTime, this.name, this.useCase, - this.additionalInformation, this.active, this.status); + QrCode({this.id, this.createDateTime, this.name, this.useCase, + this.additionalInformation, this.active, this.status}); - QrCode.fromJson(Map json) - : id = json["id"], - createDateTime = json["createDateTime"], - name = json["name"], - useCase = json["useCase"], - additionalInformation = json["additionalInformation"], - active = json["active"], - status = json["status"]; + factory QrCode.fromJson(Map json){ + return QrCode( + id: json["id"], + createDateTime: json["createDateTime"], + name: json["name"], + useCase :json["useCase"], + additionalInformation : json["additionalInformation"], + active: json["active"], + status: json["status"] + ); + + } } diff --git a/flutter-app/lib/models/qr_code_add.dart b/flutter-app/lib/models/qr_code_add.dart new file mode 100644 index 0000000..29bd723 --- /dev/null +++ b/flutter-app/lib/models/qr_code_add.dart @@ -0,0 +1,30 @@ +import 'package:flutter/foundation.dart'; + +class QR_Code_For_Add { + String name; + int useCase; + String gpsPosition; + String additionalInformation; + bool active; + int status; + + QR_Code_For_Add({ + @required this.name, + @required this.useCase, + @required this.gpsPosition, + @required this.additionalInformation, + @required this.active, + @required this.status, + }); + + Map toJson() { + return { + "name": name, + "useCase": useCase, + "gpsPosition": gpsPosition, + "additionalInformation": additionalInformation, + "active": active, + "status": status + }; + } +} diff --git a/flutter-app/lib/services/qr_code_service.dart b/flutter-app/lib/services/qr_code_service.dart new file mode 100644 index 0000000..3ef4cbd --- /dev/null +++ b/flutter-app/lib/services/qr_code_service.dart @@ -0,0 +1,28 @@ +import 'dart:convert'; +import 'package:flatten/bloc/user_bloc.dart'; +import 'package:flatten/models/api_response.dart'; +import 'package:flatten/models/qr_code.dart'; +import 'package:flatten/models/qr_code_add.dart'; +import 'package:http/http.dart' as http; +import 'dart:async'; + +class QR_Code_Service { + static const API = 'https://api.flatten-app.de'; + static const headers = {'Content-Type': 'application/json'}; + + Future> upLoadQR(QR_Code_For_Add item) { + print('upLoad called'); + return http + .post(API + '/flatten/qr-codes', + headers: headers, body: json.encode(item.toJson())).timeout(Duration(seconds: 5)) + .then((data) { + print('statusCode: ' + '${data.statusCode}'); + if (data.statusCode == 201) { + final jsonData = json.decode(data.body); + return APIResponse(data: QrCode.fromJson(jsonData)); + } + return APIResponse(error: true, errorMessage: 'An error occured'); + }).catchError((_) => + APIResponse(error: true, errorMessage: 'An error occured')); + } +} diff --git a/flutter-app/lib/ui/handshake/handshake_screen.dart b/flutter-app/lib/ui/handshake/handshake_screen.dart index eda2d7f..deb0b40 100644 --- a/flutter-app/lib/ui/handshake/handshake_screen.dart +++ b/flutter-app/lib/ui/handshake/handshake_screen.dart @@ -1,3 +1,4 @@ +import 'package:flatten/bloc/user_bloc.dart'; import 'package:flutter/material.dart'; import 'package:flatten/ui/handshake/widgets/camera_view.dart'; import 'package:line_awesome_icons/line_awesome_icons.dart'; @@ -20,7 +21,7 @@ class HandshakeScreen extends StatelessWidget { @override Widget build(BuildContext context) { - final user = BlocProvider.of(context); //this gives the current logged in user + final user = BlocProvider.of(context); //this gives the current logged in user return SingleChildScrollView( child: Container( height: MediaQuery.of(context).size.height/1.2, diff --git a/flutter-app/lib/ui/handshake/widgets/qr_view.dart b/flutter-app/lib/ui/handshake/widgets/qr_view.dart index a028281..4b088de 100644 --- a/flutter-app/lib/ui/handshake/widgets/qr_view.dart +++ b/flutter-app/lib/ui/handshake/widgets/qr_view.dart @@ -1,4 +1,5 @@ import 'package:flatten/bloc/bloc_provider.dart'; +import 'package:flatten/bloc/user_bloc.dart'; import 'package:flutter/material.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:flatten/bloc/auth_bloc.dart'; @@ -11,7 +12,7 @@ class QrCodeView extends StatelessWidget { @override Widget build(BuildContext context) { - final user = BlocProvider.of(context); //this gives the current logged in user + final user = BlocProvider.of(context); //this gives the current logged in user TextStyle titleStyle = TextStyle( fontWeight: FontWeight.bold, fontSize: 24, @@ -25,7 +26,7 @@ class QrCodeView extends StatelessWidget { //earlier this was showing // AppLocalizations.of(context).pvhtitel, //this is changed temporarily to check user login: - "Prename: ${user.userData['preName']}\nName: ${user.userData['name']}\nZIP: ${user.userData['zip']}", + "uid: ${user.userData['uid']}\nName: ${user.userData['name']}\nZIP: ${user.userData['zip']}", /*Later this can be changed to a unique is for every user, which is stored in the User class and can be accessed though user.userData['uid'] */ @@ -34,7 +35,7 @@ class QrCodeView extends StatelessWidget { Padding( padding: const EdgeInsets.only(left: 48, right: 48), child: QrImage( - data: "nkldsfkldsfdknflsnkldfs", + data: user.userData['uid'], foregroundColor: Color(0xFF08A388), ), ), diff --git a/flutter-app/lib/ui/home_page.dart b/flutter-app/lib/ui/home_page.dart index e2a8093..b031331 100644 --- a/flutter-app/lib/ui/home_page.dart +++ b/flutter-app/lib/ui/home_page.dart @@ -1,5 +1,6 @@ import 'package:flatten/bloc/auth_bloc.dart'; import 'package:flatten/bloc/bloc_provider.dart'; +import 'package:flatten/bloc/user_bloc.dart'; import 'package:flutter/material.dart'; import 'package:flatten/ui/create/create_qr_screen.dart'; import 'encounters/encounter_list_screen.dart'; @@ -12,7 +13,7 @@ import 'package:flatten/ui/handshake/handshake_decider.dart'; class HomePage extends StatefulWidget { HomePage({@required this.user}); - User user; + User_Bloc user; @override _HomePageState createState() => _HomePageState(); } @@ -56,7 +57,7 @@ class _HomePageState extends State { break; } - return BlocProvider( + return BlocProvider( bloc: widget.user, child: Scaffold( appBar: AppBar( diff --git a/flutter-app/lib/ui/landing_page.dart b/flutter-app/lib/ui/landing_page.dart index c001a94..b52c323 100644 --- a/flutter-app/lib/ui/landing_page.dart +++ b/flutter-app/lib/ui/landing_page.dart @@ -1,5 +1,6 @@ import 'package:flatten/bloc/bloc_provider.dart'; import 'package:flatten/bloc/hs_info_block.dart'; +import 'package:flatten/bloc/user_bloc.dart'; import 'home_page.dart'; import 'package:flutter/material.dart'; import 'package:flatten/bloc/auth_bloc.dart'; @@ -9,7 +10,7 @@ import 'package:flatten/ui/sign_in_page.dart'; class LandingPage extends StatelessWidget { @override Widget build(BuildContext context) { - final Auth auth = BlocProvider.of(context); + final Auth_Bloc auth = BlocProvider.of(context); return StreamBuilder( stream: auth.userStream, initialData: null, @@ -17,7 +18,7 @@ class LandingPage extends StatelessWidget { // this can be used to show a progress indicator when we authenticate from database, // we can un-comment this. // if(snapshot.connectionState == ConnectionState.active){ - User user = snapshot.data; + User_Bloc user = snapshot.data; if(user == null){ return SignInPage(); } diff --git a/flutter-app/lib/ui/sign_in_page.dart b/flutter-app/lib/ui/sign_in_page.dart index a819568..dace629 100644 --- a/flutter-app/lib/ui/sign_in_page.dart +++ b/flutter-app/lib/ui/sign_in_page.dart @@ -5,6 +5,9 @@ import 'sign_in_components/validator.dart'; import 'sign_in_components/constants.dart'; import 'sign_in_components/information_texts.dart'; import 'package:flatten/bloc/auth_bloc.dart'; +import 'package:flatten/services/qr_code_service.dart'; +import 'package:flatten/models/qr_code_add.dart'; + class SignInPage extends StatefulWidget with FeildValidator { @override @@ -12,6 +15,7 @@ class SignInPage extends StatefulWidget with FeildValidator { } class _SignInPageState extends State { + String get _preName => _preNameController.text; String get _name => _nameController.text; @@ -28,7 +32,7 @@ class _SignInPageState extends State { bool _submitted = false; - void _submit() { + void _submit() async { ///this method signs in the user only if all the feilds are valid ///we dont have to add the sign in logic here, we have to do that in the Auth() ///class in the 'services' directory @@ -38,102 +42,108 @@ class _SignInPageState extends State { if (widget.zipValidator.isValid(_zip) && widget.nameValidator.isValid(_name) && widget.preNameValidator.isValid(_preName)) { - final Auth auth = BlocProvider.of(context); - auth.signIn('some uid', _preName, _name, _zip); + final Auth_Bloc auth = BlocProvider.of(context); + auth.signIn(_preName, _name, _zip); } } @override Widget build(BuildContext context) { - final Auth auth = BlocProvider.of(context); - return Scaffold( - body: SingleChildScrollView( - child: Container( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height, - color: Color(0xFF88c7bc), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Spacer( - flex: 3, - ), - informationText( - 'Scan your QR-Code which you have received by post', 250), - Spacer( - flex: 1, - ), - CustomRaisedButton( - color: Color(0xff408aff), - child: Text( - 'Scan QR-Code', - style: TextStyle(fontSize: 20), + final Auth_Bloc auth = BlocProvider.of(context); + return StreamBuilder( + stream: auth.isAuthenticationStream, + initialData: AuthState(errorOccured: false,inProgress: false), + builder: (context, snapshot) => snapshot.data.inProgress == true && snapshot.data.errorOccured == false? + Scaffold(body: Center(child: CircularProgressIndicator(),),) + : Scaffold( + body: SingleChildScrollView( + child: Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + color: Color(0xFF88c7bc), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Spacer( + flex: 3, + ), + informationText( + 'Scan your QR-Code which you have received by post', 250), + Spacer( + flex: 1, + ), + CustomRaisedButton( + color: Color(0xff408aff), + child: Text( + 'Scan QR-Code', + style: TextStyle(fontSize: 20), + ), + borderRadius: 50, + onPressed: () {}, + ), + Spacer( + flex: 2, + ), + informationText( + 'You haven\'t received any post yer, or lost it?\nNo problem. Generate your new code here:', + 320), + Spacer( + flex: 1, + ), + SizedBox(width: 300, height: 80, child: _buildPreNameTextFeild()), + Spacer( + flex: 1, ), - borderRadius: 50, - onPressed: () {}, - ), - Spacer( - flex: 2, - ), - informationText( - 'You haven\'t received any post yer, or lost it?\nNo problem. Generate your new code here:', - 320), - Spacer( - flex: 1, - ), - SizedBox(width: 300, height: 80, child: _buildPreNameTextFeild()), - Spacer( - flex: 1, - ), - SizedBox(width: 300, height: 80, child: _buildnameTextFeild()), - Spacer( - flex: 1, - ), - SizedBox(width: 300, height: 80, child: _buildZipTextFeild()), - Spacer( - flex: 1, - ), - CustomRaisedButton( - color: Color(0xff408aff), - child: Text( - 'Generate', - style: TextStyle(fontSize: 20), + SizedBox(width: 300, height: 80, child: _buildnameTextFeild()), + Spacer( + flex: 1, ), - borderRadius: 50, - onPressed: () { - _submit(); - }, - ), - Spacer( - flex: 2, - ), - SizedBox( - width: 300, - child: Row( - children: [ - Expanded( - child: informationText( - 'What about people who do not have a smartphone', 200), - ), - IconButton( - icon: Icon( - Icons.help, - size: 50, - color: Colors.white, + SizedBox(width: 300, height: 80, child: _buildZipTextFeild()), + Spacer( + flex: 1, + ), + CustomRaisedButton( + color: Color(0xff408aff), + child: Text( + 'Generate', + style: TextStyle(fontSize: 20), + ), + borderRadius: 50, + onPressed: () { + _submit(); + }, + ), + Spacer( + flex: 2, + ), + SizedBox( + width: 300, + child: Row( + children: [ + Expanded( + child: informationText( + 'What about people who do not have a smartphone', 200), ), - onPressed: () {}, - ), - ], + IconButton( + icon: Icon( + Icons.help, + size: 50, + color: Colors.white, + ), + onPressed: () {}, + ), + ], + ), + ), + Spacer( + flex: 1, ), - ), - Spacer( - flex: 1, - ), - ], + ], + ), ), - ), - )); + )), + ); } TextField _buildZipTextFeild() {