add costum alerts and finalize profile user interface

feature/passo/PASSO-#1-Sync-data-from-device-to-postgre-and-vice-versa
rodolfobacuinjr 2022-12-13 14:56:09 +08:00
parent cbca4ec97d
commit 8d5f713e52
13 changed files with 483 additions and 259 deletions

View File

@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.unit2">
<uses-permission android:name="android.permission.CAMERA" />
<application
android:label="unit2"
android:name="${applicationName}"

View File

@ -63,7 +63,7 @@ class _MenuScreenState extends State<MenuScreen> {
Expanded(
child: Align(
alignment: FractionalOffset.bottomLeft,
child: getTile(WebSymbols.logout, "Logout", '/', context),
child: getTile(WebSymbols.logout, "Logout", 'login', context),
)),
],
),

View File

@ -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);
}
},
);
}

View File

@ -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<UniT2Login> {
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: <Widget>[
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<UserBloc>(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: <Widget>[
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<UserBloc>(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<UserBloc>(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<UserBloc>(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),
)),
)
],
),
),
),
),
],
),
],
),
),
),
);
}),
),
),
);

View File

@ -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',

View File

@ -1,5 +1,5 @@
import 'package:azlistview/azlistview.dart';
String uuid = 'f68c3142-b939-11ec-9acb-3939f0cc109a';
List<String> levels = ['Establishments', 'Office'];
List<String> establishments = ['Provincial Government of Agusan del Norte'];
List<String> checkPointAreas = [

View File

@ -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,
);
}

View File

@ -13,7 +13,7 @@ final GoRouter goRouter = GoRouter(routes: <GoRoute>[
GoRoute(
path: '/',
name: 'login',
builder: (context, state) => Register(),
builder: (context, state) => UniT2Login(),
routes: [
GoRoute(
name: 'home',

View File

@ -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<BarcodeFormat> selectedFormats = [..._possibleFormats];
Future<ScanResult> 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;
}
}

View File

@ -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:

View File

@ -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: