diff --git a/unit2/android/app/src/main/AndroidManifest.xml b/unit2/android/app/src/main/AndroidManifest.xml index 9e1ccf9..1e8a920 100644 --- a/unit2/android/app/src/main/AndroidManifest.xml +++ b/unit2/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ + { Expanded( child: Align( alignment: FractionalOffset.bottomLeft, - child: getTile(WebSymbols.logout, "Logout", '/', context), + child: getTile(WebSymbols.logout, "Logout", 'login', context), )), ], ), diff --git a/unit2/lib/screens/unit2/homepage.dart/components/menu.dart b/unit2/lib/screens/unit2/homepage.dart/components/menu.dart index 204fdd0..ec3a330 100644 --- a/unit2/lib/screens/unit2/homepage.dart/components/menu.dart +++ b/unit2/lib/screens/unit2/homepage.dart/components/menu.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart'; import 'package:go_router/go_router.dart'; - +import 'package:cool_alert/cool_alert.dart'; +import 'package:unit2/utils/alerts.dart'; import '../../../../theme-data.dart/colors.dart'; Widget getTile( @@ -17,9 +18,13 @@ Widget getTile( style: const TextStyle(color: Colors.black), ), onTap: () async { - debugPrint(title); - ZoomDrawer.of(context)!.toggle(); + if (title.toLowerCase() == "logout") { + confirmAlert(context, () { + context.goNamed("login"); + }); + } else { context.goNamed(route); + } }, ); } diff --git a/unit2/lib/screens/unit2/login/login.dart b/unit2/lib/screens/unit2/login/login.dart index e19f924..c3d2e58 100644 --- a/unit2/lib/screens/unit2/login/login.dart +++ b/unit2/lib/screens/unit2/login/login.dart @@ -1,10 +1,16 @@ +import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:fluttericon/font_awesome5_icons.dart'; import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:go_router/go_router.dart'; + +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:unit2/utils/alerts.dart'; +import 'package:unit2/utils/scanner.dart'; import 'package:unit2/utils/text_container.dart'; + import '../../../widgets/wave.dart'; import '../../../utils/global.dart'; import '../../../theme-data.dart/colors.dart'; @@ -29,215 +35,234 @@ class _UniT2LoginState extends State { return WillPopScope( onWillPop: pressAgainToExit, child: Scaffold( - body: SizedBox( - child: SingleChildScrollView( - child: Stack( - children: [ - Positioned( - bottom: 0, - right: 0, - child: WaveReverse(height: blockSizeVertical * 7)), - SizedBox( - height: blockSizeVertical * 100, - child: FormBuilder( - key: _formKey, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 25), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox(height: blockSizeVertical * 7), - SvgPicture.asset( - 'assets/svgs/logo.svg', - height: blockSizeVertical * 16, - allowDrawingOutsideViewBox: true, - color: primary, - ), - - Text( - welcome, - style: TextStyle( - fontSize: blockSizeVertical * 5, - fontWeight: FontWeight.w600), - ), - Text(unitApp, - style: TextStyle( - fontSize: blockSizeVertical * 8, - fontWeight: FontWeight.w800, - letterSpacing: .2, - height: 1, - color: primary)), - Text( - loginToContinue, - style: TextStyle( - fontSize: blockSizeVertical * 2, - height: 1.5, - fontWeight: FontWeight.w600), - ), - SizedBox( - height: blockSizeVertical * 1.5, - ), - // USERNAME - FormBuilderTextField( - name: 'username', - validator: FormBuilderValidators.required( - errorText: "Username is required"), - autofocus: false, - style: const TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black87), - decoration: loginTextFieldStyle()), - SizedBox( - height: blockSizeVertical * 1.5, - ), - // PASSWORD - FormBuilderTextField( - name: 'password', - validator: FormBuilderValidators.required( - errorText: "Password is required"), - - // initialValue: state.password, - onChanged: (value) { - value!.isEmpty - ? setState(() { - showSuffixIcon = false; - }) - : setState(() { - showSuffixIcon = true; - }); - }, - autofocus: false, - style: const TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black87), - decoration: loginTextFieldStyle().copyWith( - suffixIcon: Visibility( - visible: showSuffixIcon, - child: _showPassword - ? IconButton( - icon: Icon(FontAwesome5.eye_slash, - size: 24, - color: Theme.of(context) - .textTheme - .displayLarge - ?.color), - onPressed: () { - setState(() { - _showPassword = false; - }); - }, - ) - : IconButton( - onPressed: () { - setState(() { - _showPassword = true; - }); - }, - icon: Icon(FontAwesome5.eye, - size: 24, - color: Theme.of(context) - .textTheme - .displayLarge - ?.color)), - ), - prefixIcon: const Icon(Icons.lock), - labelText: "Password", - hintText: "Enter Password..."), - obscureText: _showPassword ? true : false, - ), - SizedBox( - height: blockSizeVertical * 2, - ), - SizedBox( - height: blockSizeVertical * 7, - // Login Button - child: SizedBox( - width: MediaQuery.of(context).size.width, - child: ElevatedButton( - style: mainBtnStyle( - second, Colors.transparent, Colors.white54), - child: const Text( - "LOGIN", - style: TextStyle(color: Colors.white), - ), - onPressed: () { - if (_formKey.currentState! - .saveAndValidate()) { - context.go(context.namedLocation('home')); - } - - // if (_formKey.currentState.validate()) { - // _formKey.currentState.save(); - // BlocProvider.of(context) - // .add(UserWebLogin( - // password: password, - // username: username)); - // } - }, + body: ProgressHUD( + child: Builder(builder: (context) { + return SizedBox( + child: SingleChildScrollView( + child: Stack( + children: [ + Positioned( + bottom: 0, + right: 0, + child: WaveReverse(height: blockSizeVertical * 7)), + SizedBox( + height: blockSizeVertical * 100, + child: FormBuilder( + key: _formKey, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(height: blockSizeVertical * 7), + SvgPicture.asset( + 'assets/svgs/logo.svg', + height: blockSizeVertical * 16, + allowDrawingOutsideViewBox: true, + color: primary, ), - ), - ), - SizedBox( - height: blockSizeVertical * 1.5, - ), - SizedBox( - height: blockSizeVertical * 7, - child: SizedBox( + Text( + welcome, + style: TextStyle( + fontSize: blockSizeVertical * 5, + fontWeight: FontWeight.w600), + ), + Text(unitApp, + style: TextStyle( + fontSize: blockSizeVertical * 8, + fontWeight: FontWeight.w800, + letterSpacing: .2, + height: 1, + color: primary)), + Text( + loginToContinue, + style: TextStyle( + fontSize: blockSizeVertical * 2, + height: 1.5, + fontWeight: FontWeight.w600), + ), + SizedBox( + height: blockSizeVertical * 1.5, + ), + // USERNAME + FormBuilderTextField( + name: 'username', + validator: FormBuilderValidators.required( + errorText: "Username is required"), + autofocus: false, + style: const TextStyle( + fontWeight: FontWeight.bold, + color: Colors.black87), + decoration: loginTextFieldStyle()), + SizedBox( + height: blockSizeVertical * 1.5, + ), + // PASSWORD + FormBuilderTextField( + name: 'password', + validator: FormBuilderValidators.required( + errorText: "Password is required"), + + // initialValue: state.password, + onChanged: (value) { + value!.isEmpty + ? setState(() { + showSuffixIcon = false; + }) + : setState(() { + showSuffixIcon = true; + }); + }, + autofocus: false, + style: const TextStyle( + fontWeight: FontWeight.bold, + color: Colors.black87), + decoration: loginTextFieldStyle().copyWith( + suffixIcon: Visibility( + visible: showSuffixIcon, + child: _showPassword + ? IconButton( + icon: Icon(FontAwesome5.eye_slash, + size: 24, + color: Theme.of(context) + .textTheme + .displayLarge + ?.color), + onPressed: () { + setState(() { + _showPassword = false; + }); + }, + ) + : IconButton( + onPressed: () { + setState(() { + _showPassword = true; + }); + }, + icon: Icon(FontAwesome5.eye, + size: 24, + color: Theme.of(context) + .textTheme + .displayLarge + ?.color)), + ), + prefixIcon: const Icon(Icons.lock), + labelText: "Password", + hintText: "Enter Password..."), + obscureText: _showPassword ? true : false, + ), + SizedBox( + height: blockSizeVertical * 2, + ), + SizedBox( + height: blockSizeVertical * 7, + // Login Button + child: SizedBox( + width: MediaQuery.of(context).size.width, + child: ElevatedButton( + style: mainBtnStyle(second, + Colors.transparent, Colors.white54), + child: const Text( + login, + style: TextStyle(color: Colors.white), + ), + onPressed: () { + final progress = ProgressHUD.of(context); + progress?.showWithText( + 'Logging in...', + ); + Future.delayed(const Duration(seconds: 5), + () { + progress!.dismiss(); + + context.goNamed("home"); + }); + // if (_formKey.currentState! + // .saveAndValidate()) { + // context.go(context.namedLocation('home')); + // } + + // if (_formKey.currentState.validate()) { + // _formKey.currentState.save(); + // BlocProvider.of(context) + // .add(UserWebLogin( + // password: password, + // username: username)); + // } + }, + ), + ), + ), + SizedBox( + height: blockSizeVertical * 1.5, + ), + + SizedBox( + height: blockSizeVertical * 7, + child: SizedBox( + width: MediaQuery.of(context).size.width, + child: ElevatedButton.icon( + style: mainBtnStyle(Colors.white, second, + primary.withOpacity(.4)), + icon: const Icon( + Icons.qr_code, + color: second, + ), + label: const Text( + loginViaQr, + style: TextStyle(color: second), + ), + onPressed: () async { + ScanResult result = + await QRCodeBarCodeScanner.instance + .scanner(); + + debugPrint(result.type.toString()); + debugPrint( + result.rawContent.toString()); + // BlocProvider.of(context) + // .add(QRCodelogin()); + }, + ), + )), + SizedBox( + height: blockSizeVertical * 1, + ), + const LoginViaQr(text: emergencyReponseLabel), + SizedBox( + height: blockSizeVertical * 1, + ), + // REQUEST SOS + SizedBox( + height: screenHeight * .07, width: MediaQuery.of(context).size.width, child: ElevatedButton.icon( - style: mainBtnStyle(Colors.white, second, - primary.withOpacity(.4)), - icon: const Icon( - Icons.qr_code, - color: second, - ), - label: const Text( - loginViaQr, - style: TextStyle(color: second), - ), - onPressed: () async { - context.go(context.namedLocation('home')); - - // BlocProvider.of(context) - // .add(QRCodelogin()); - }, - ), - )), - SizedBox( - height: blockSizeVertical * 1, + icon: const Icon( + FontAwesome5.life_ring, + color: Colors.white, + ), + style: mainBtnStyle(third, + Colors.transparent, Colors.white38), + onPressed: () { + context.goNamed('add-mobile'); + }, + label: const Text( + requestSOS, + style: TextStyle(color: Colors.white), + )), + ) + ], ), - const LoginViaQr(text: emergencyReponseLabel), - SizedBox( - height: blockSizeVertical * 1, - ), - // REQUEST SOS - SizedBox( - height: screenHeight * .07, - width: MediaQuery.of(context).size.width, - child: ElevatedButton.icon( - icon: const Icon( - FontAwesome5.life_ring, - color: Colors.white, - ), - style: mainBtnStyle( - third, Colors.transparent, Colors.white38), - onPressed: () { - context.goNamed('add-mobile'); - }, - label: const Text( - requestSOS, - style: TextStyle(color: Colors.white), - )), - ) - ], + ), ), ), - ), + ], ), - ], - ), - ), + ), + ); + }), ), ), ); diff --git a/unit2/lib/screens/unit2/profile/components/cover-image.dart b/unit2/lib/screens/unit2/profile/components/cover-image.dart index 5ce6aaf..69c734c 100644 --- a/unit2/lib/screens/unit2/profile/components/cover-image.dart +++ b/unit2/lib/screens/unit2/profile/components/cover-image.dart @@ -17,4 +17,4 @@ class CoverImage extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/unit2/lib/screens/unit2/profile/profile.dart b/unit2/lib/screens/unit2/profile/profile.dart index 5803e2f..8228e25 100644 --- a/unit2/lib/screens/unit2/profile/profile.dart +++ b/unit2/lib/screens/unit2/profile/profile.dart @@ -1,7 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:fluttericon/font_awesome5_icons.dart'; +import 'package:fluttericon/web_symbols_icons.dart'; import 'package:go_router/go_router.dart'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'package:unit2/test_data.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/utils/global.dart'; +import '../../../theme-data.dart/colors.dart'; import './components/cover-image.dart'; class Profile extends StatelessWidget { @@ -15,26 +21,40 @@ class Profile extends StatelessWidget { }, child: SafeArea( child: Scaffold( - body: Stack( - clipBehavior: Clip.none, - alignment: Alignment.center, - children: [ - const CoverImage(), - const Positioned(top: 125, child: BuildProfileImage()), - Positioned( - top: 10, - left: 20, - child: IconButton( - onPressed: () { - context.go(context.namedLocation('home')); - }, - icon: const Icon( - FontAwesome5.arrow_left, - size: 24, - color: Colors.white, - ), - )), - ], + body: SizedBox( + width: screenWidth, + child: Stack( + clipBehavior: Clip.none, + alignment: Alignment.center, + children: [ + const CoverImage(), + const Positioned(top: 125, child: BuildProfileImage()), + Positioned( + top: 10, + left: 20, + child: IconButton( + onPressed: () { + context.go(context.namedLocation('home')); + }, + icon: const Icon( + FontAwesome5.arrow_left, + size: 24, + color: Colors.white, + ), + )), + Positioned( + top: 10, + right: 20, + child: IconButton( + onPressed: () {}, + icon: const Icon( + Icons.edit, + size: 24, + color: Colors.white, + ), + )), + ], + ), ), ), ), @@ -46,35 +66,55 @@ class BuildInformation extends StatelessWidget { const BuildInformation({super.key}); @override Widget build(BuildContext context) { - return Column( - children: [ - const SizedBox( - height: 8, - ), - Text( - "Rodolfo Bernales Acuin", - style: Theme.of(context) - .textTheme - .headline5! - .copyWith(fontWeight: FontWeight.bold), - ), - Row( - children: [ - Icon( - FontAwesome5.birthday_cake, - color: Colors.blueAccent, + return Container( + padding: const EdgeInsets.symmetric(horizontal: 25), + width: screenWidth, + child: Column( + children: [ + const SizedBox( + height: 25, + ), + Text( + "Rodolfo Bernales Acuin", + style: Theme.of(context) + .textTheme + .headline5! + .copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox( + height: 10, + ), + Text( + "july 14, 1994 | Male", + style: Theme.of(context).textTheme.caption!.copyWith(fontSize: 18), + ), + const SizedBox( + height: 15, + ), + QrImage( + data: uuid, + size: blockSizeVertical * 30, + ), + SizedBox( + height: 25, + ), + SizedBox( + height: blockSizeVertical * 6, + width: screenWidth * .60, + child: ElevatedButton.icon( + label: const Text("Signature pad"), + icon: const Icon( + FontAwesome5.signature, + ), + style: mainBtnStyle(third, Colors.transparent, Colors.white54), + onPressed: () {}, ), - const SizedBox( - width: 20, - ), - Text( - "july 14, 1994 | Male", - style: - Theme.of(context).textTheme.caption!.copyWith(fontSize: 22), - ), - ], - ), - ], + ), + const SizedBox( + height: 5, + ), + ], + ), ); } } @@ -89,12 +129,12 @@ class BuildProfileImage extends StatelessWidget { Stack( alignment: Alignment.center, children: [ - CircleAvatar( - radius: 85, + const CircleAvatar( + radius: 72, backgroundColor: Colors.white, ), CircleAvatar( - radius: 80, + radius: 69, backgroundColor: Colors.grey.shade800, child: SvgPicture.asset( 'assets/svgs/male.svg', diff --git a/unit2/lib/screens/unit2/signature/pad.dart b/unit2/lib/screens/unit2/signature/pad.dart new file mode 100644 index 0000000..e69de29 diff --git a/unit2/lib/test_data.dart b/unit2/lib/test_data.dart index a16e395..47714c3 100644 --- a/unit2/lib/test_data.dart +++ b/unit2/lib/test_data.dart @@ -1,5 +1,5 @@ import 'package:azlistview/azlistview.dart'; - +String uuid = 'f68c3142-b939-11ec-9acb-3939f0cc109a'; List levels = ['Establishments', 'Office']; List establishments = ['Provincial Government of Agusan del Norte']; List checkPointAreas = [ diff --git a/unit2/lib/utils/alerts.dart b/unit2/lib/utils/alerts.dart new file mode 100644 index 0000000..39c65f6 --- /dev/null +++ b/unit2/lib/utils/alerts.dart @@ -0,0 +1,29 @@ +import 'package:cool_alert/cool_alert.dart'; +import 'package:flutter/material.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; + +confirmAlert(context, Function() yes) { + CoolAlert.show( + loopAnimation: true, + context: context, + type: CoolAlertType.confirm, + title: 'LOGOUT!', + text: 'Are you sure you want to logout?', + cancelBtnText: 'No', + confirmBtnText: 'Yes', + confirmBtnColor: second, + showCancelBtn: true, + barrierDismissible: false, + onConfirmBtnTap: yes); +} + +errorAlert(context) { + CoolAlert.show( + context: context, + type: CoolAlertType.error, + confirmBtnColor: second, + title: 'Login Failed!', + text: 'username or password is incorrect.', + loopAnimation: false, + ); +} diff --git a/unit2/lib/utils/router.dart b/unit2/lib/utils/router.dart index 956278b..37864e3 100644 --- a/unit2/lib/utils/router.dart +++ b/unit2/lib/utils/router.dart @@ -13,7 +13,7 @@ final GoRouter goRouter = GoRouter(routes: [ GoRoute( path: '/', name: 'login', - builder: (context, state) => Register(), + builder: (context, state) => UniT2Login(), routes: [ GoRoute( name: 'home', diff --git a/unit2/lib/utils/scanner.dart b/unit2/lib/utils/scanner.dart new file mode 100644 index 0000000..25501f6 --- /dev/null +++ b/unit2/lib/utils/scanner.dart @@ -0,0 +1,36 @@ +import 'package:barcode_scan2/barcode_scan2.dart'; + +class QRCodeBarCodeScanner { + static final QRCodeBarCodeScanner _instance = QRCodeBarCodeScanner(); + static QRCodeBarCodeScanner get instance => _instance; + final _selectedCamera = -1; + final bool _useAutoFocus = true; + static final _possibleFormats = BarcodeFormat.values.toList() + ..removeWhere((e) => e == BarcodeFormat.unknown); + ScanResult scanResult = ScanResult(); + + List selectedFormats = [..._possibleFormats]; + + Future scanner() async { + ScanOptions options = ScanOptions( + strings: { + "cancel": "Back", + "flash_on": "Flash on", + "flash_off": "Flash off", + }, + restrictFormat: selectedFormats, + useCamera: _selectedCamera, +// autoEnableFlash: _autoEnableFlash, + android: AndroidOptions( +// aspectTolerance: _aspectTolerance, + useAutoFocus: _useAutoFocus, + ), + ); + try { + scanResult = await BarcodeScanner.scan(options: options); + } on Error catch (e) { + throw (e.toString()); + } + return scanResult; + } +} diff --git a/unit2/pubspec.lock b/unit2/pubspec.lock index d2f2cea..e19a094 100644 --- a/unit2/pubspec.lock +++ b/unit2/pubspec.lock @@ -8,6 +8,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.2" + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.5" async: dependency: transitive description: @@ -29,6 +36,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + barcode_scan2: + dependency: "direct main" + description: + name: barcode_scan2 + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.1" boolean_selector: dependency: transitive description: @@ -78,6 +92,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.16.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" convex_bottom_bar: dependency: "direct main" description: @@ -85,6 +106,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.0+1" + cool_alert: + dependency: "direct main" + description: + name: cool_alert + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" crypto: dependency: transitive description: @@ -141,6 +169,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.4" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + flare_flutter: + dependency: transitive + description: + name: flare_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" flutter: dependency: "direct main" description: flutter @@ -186,6 +228,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_progress_hud: + dependency: "direct main" + description: + name: flutter_progress_hud + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" flutter_spinkit: dependency: "direct main" description: @@ -301,6 +350,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + lottie: + dependency: transitive + description: + name: lottie + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.3" matcher: dependency: transitive description: @@ -434,6 +490,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.3" + pointycastle: + dependency: transitive + description: + name: pointycastle + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.2" process: dependency: transitive description: @@ -441,6 +504,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.4" + protobuf: + dependency: transitive + description: + name: protobuf + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" provider: dependency: transitive description: @@ -448,6 +518,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.0.4" + qr: + dependency: transitive + description: + name: qr + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" rxdart: dependency: transitive description: diff --git a/unit2/pubspec.yaml b/unit2/pubspec.yaml index b08bfd4..6947ded 100644 --- a/unit2/pubspec.yaml +++ b/unit2/pubspec.yaml @@ -54,6 +54,10 @@ dependencies: azlistview: ^2.0.0 intl: ^0.17.0 date_time_picker: ^2.1.0 + flutter_progress_hud: ^2.0.2 + barcode_scan2: ^4.2.1 + cool_alert: ^1.1.0 + qr_flutter: ^4.0.0 dev_dependencies: flutter_test: