diff --git a/unit2/assets/pngs/bg.png b/unit2/assets/pngs/bg.png new file mode 100644 index 0000000..b8afe26 Binary files /dev/null and b/unit2/assets/pngs/bg.png differ diff --git a/unit2/assets/svgs/add_mobile.svg b/unit2/assets/svgs/add_mobile.svg new file mode 100644 index 0000000..83b7834 --- /dev/null +++ b/unit2/assets/svgs/add_mobile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/unit2/assets/svgs/no_module.svg b/unit2/assets/svgs/no_module.svg new file mode 100644 index 0000000..7d09b1e --- /dev/null +++ b/unit2/assets/svgs/no_module.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/unit2/assets/svgs/request_sos.svg b/unit2/assets/svgs/request_sos.svg new file mode 100644 index 0000000..f4cd5b8 --- /dev/null +++ b/unit2/assets/svgs/request_sos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/unit2/lib/main.dart b/unit2/lib/main.dart index 7bfa0d4..f87f8ef 100644 --- a/unit2/lib/main.dart +++ b/unit2/lib/main.dart @@ -1,6 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:device_preview/device_preview.dart'; +import 'package:flutter/services.dart'; import './utils/router.dart'; import './utils/global.dart'; @@ -33,14 +34,21 @@ class MyApp extends StatelessWidget { mediaQueryData.padding.top + mediaQueryData.padding.bottom; safeBlockHorizontal = (screenWidth - safeAreaHorizontal) / 100; safeBlockVertical = (screenHeight - safeAreaVertical) / 100; + return MaterialApp.router( // useInheritedMediaQuery: true, // locale: DevicePreview.locale(context), // builder: DevicePreview.appBuilder, routeInformationParser: goRouter.routeInformationParser, - routerDelegate: goRouter.routerDelegate, + routerDelegate: goRouter.routerDelegate, + // routeInformationProvider: goRouter.routeInformationProvider, title: 'uniT2 - Universal Tracker and Tracer', theme: ThemeData( + appBarTheme: const AppBarTheme( + systemOverlayStyle: SystemUiOverlayStyle( + statusBarBrightness: Brightness.dark, + statusBarColor: Colors.black), + ), fontFamily: 'LexendDeca', ), debugShowCheckedModeBanner: false, diff --git a/unit2/lib/screen/sos/add_mobile.dart b/unit2/lib/screen/sos/add_mobile.dart new file mode 100644 index 0000000..c102a0a --- /dev/null +++ b/unit2/lib/screen/sos/add_mobile.dart @@ -0,0 +1,139 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:go_router/go_router.dart'; +import 'package:unit2/theme-data.dart/text-styles.dart'; +import 'package:unit2/utils/screen_info.dart'; +import '../../theme-data.dart/btn-style.dart'; +import '../../theme-data.dart/colors.dart'; +import '../../theme-data.dart/form-style.dart'; +import '../../utils/global.dart'; +import '../../utils/text_container.dart'; +import '../../utils/validators.dart'; +import '../../widgets/wave.dart'; + +class AddMobile extends StatelessWidget { + AddMobile({super.key}); + final _formKey = GlobalKey(); + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + return true; + }, + child: Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + leading: IconButton( + icon: const Icon( + FontAwesome.left_big, + ), + onPressed: () { + context.go(context.namedLocation('login')); + }, + color: primary, + ), + ), + resizeToAvoidBottomInset: true, + body: SingleChildScrollView( + child: SizedBox( + height: screenHeight * .89, + child: Stack( + children: [ + Positioned( + bottom: 0, + right: 0, + child: WaveReverse(height: blockSizeVertical * 8)), + Container( + height: screenHeight, + padding: isMobile() + ? const EdgeInsets.symmetric(horizontal: 24) + : const EdgeInsets.symmetric(horizontal: 60), + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: isMobile() + ? screenHeight * .12 + : screenHeight * .20), + SvgPicture.asset( + 'assets/svgs/add_mobile.svg', + height: isMobile() + ? blockSizeVertical * 22 + : blockSizeVertical * 30, + allowDrawingOutsideViewBox: true, + ), + const SizedBox( + height: 24, + ), + Text(addMobile, style: titleTextStyle()), + const SizedBox( + height: 8, + ), + Text(addMobileCaption, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.caption), + const SizedBox( + height: 24, + ), + FormBuilder( + key: _formKey, + child: Column( + children: [ + // Mobile number 1 + FormBuilderTextField( + name: 'mobile1', + validator: mobileNumberValidator, + decoration: normalTextFieldStyle( + "mobile number 1", "+63")), + const SizedBox( + height: 12, + ), + FormBuilderTextField( + name: 'mobile2', + validator: mobileNumberValidator, + decoration: normalTextFieldStyle( + "mobile number 2", "+63")), + + SizedBox( + height: isMobile() + ? blockSizeVertical * 3 + : blockSizeHorizontal * 5), + SizedBox( + width: double.infinity, + height: screenHeight * .06, + child: ElevatedButton( + style: secondaryBtnStyle(second, + Colors.transparent, Colors.white54), + child: const Text( + submit, + style: TextStyle(color: Colors.white), + ), + onPressed: () { + context.go( + context.namedLocation('request-sos')); + // if (_formKey.currentState.validate()) { + // _formKey.currentState.save(); + // BlocProvider.of(context) + // .add(UserWebLogin( + // password: password, + // username: username)); + // } + }, + ), + ), + ], + )) + ]), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/unit2/lib/screen/sos/components/mobile.dart b/unit2/lib/screen/sos/components/mobile.dart new file mode 100644 index 0000000..bd0c522 --- /dev/null +++ b/unit2/lib/screen/sos/components/mobile.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:fluttericon/font_awesome5_icons.dart'; + +import '../../../theme-data.dart/colors.dart'; + +class Mobile extends StatelessWidget { + final String title; + final String subtitle; + final Function onPressed; + const Mobile({ + super.key, + required this.title, + required this.subtitle, + required this.onPressed, + }); + + @override + Widget build(BuildContext context) { + return ListTile( + leading: const Icon( + FontAwesome5.sim_card, + color: second, + ), + title: Text(title), + subtitle: Text( + subtitle, + style: Theme.of(context).textTheme.caption, + ), + trailing: IconButton( + icon: const Icon(Icons.edit), + onPressed: () { + onPressed(); + }, + ), + ); + } +} diff --git a/unit2/lib/screen/sos/request_sos.dart b/unit2/lib/screen/sos/request_sos.dart new file mode 100644 index 0000000..e284efd --- /dev/null +++ b/unit2/lib/screen/sos/request_sos.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/container.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:fluttericon/font_awesome5_icons.dart'; +import 'package:fluttericon/typicons_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:unit2/screen/sos/components/mobile.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/text_container.dart'; + +import '../../theme-data.dart/btn-style.dart'; +import '../../theme-data.dart/form-style.dart'; +import '../../utils/global.dart'; + +class RequestSOS extends StatefulWidget { + const RequestSOS({super.key}); + + @override + State createState() => _RequestSOSState(); +} + +class _RequestSOSState extends State { + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + appBar: AppBar( + centerTitle: true, + title: const Text(sOSTitle), + backgroundColor: second, + ), + body: SingleChildScrollView( + child: Container( + height: screenHeight * .89, + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10), + child: Column( + children: [ + SizedBox( + height: blockSizeVertical * 2, + ), + SvgPicture.asset( + 'assets/svgs/request_sos.svg', + height: blockSizeVertical * 22, + allowDrawingOutsideViewBox: true, + ), + Mobile( + title: "09661548775", + subtitle: mobile1, + onPressed: () {}), + const Divider(), + Mobile( + title: "09661548775", + subtitle: mobile2, + onPressed: () {}), + const Divider(), + ListTile( + leading: const Icon( + Typicons.location, + color: second, + ), + title: Text("Latitude/Longitude"), + subtitle: Text( + currentLocation, + style: Theme.of(context).textTheme.caption, + ), + ), + FormBuilderTextField( + name: "message", + validator: FormBuilderValidators.compose([ + FormBuilderValidators.required( + errorText: "Message is required") + ]), + autovalidateMode: AutovalidateMode.onUserInteraction, + maxLines: 5, + decoration: normalTextFieldStyle("", "SOS message.."), + ), + Expanded( + child: SizedBox(), + ), + SizedBox( + width: double.infinity, + height: screenHeight * .06, + child: ElevatedButton( + style: secondaryBtnStyle( + second, Colors.transparent, Colors.white54), + child: const Text( + submit, + style: TextStyle(color: Colors.white), + ), + onPressed: () { + // if (_formKey.currentState.validate()) { + // _formKey.currentState.save(); + // BlocProvider.of(context) + // .add(UserWebLogin( + // password: password, + // username: username)); + // } + }, + ), + ), + ], + )), + ), + ), + ); + } +} diff --git a/unit2/lib/screen/sos/sos_received.dart b/unit2/lib/screen/sos/sos_received.dart new file mode 100644 index 0000000..8a2de78 --- /dev/null +++ b/unit2/lib/screen/sos/sos_received.dart @@ -0,0 +1,133 @@ +import 'package:animate_do/animate_do.dart'; +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/utils/text_container.dart'; +import '../../theme-data.dart/colors.dart'; +import '../../utils/global.dart'; + +class SOSreceived extends StatelessWidget { + final Function onpressed; + const SOSreceived({required Key key, required this.onpressed}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(vertical: 40, horizontal: 35), + height: screenHeight, + child: Stack( + children: [ + Positioned( + bottom: 0, + child: SizedBox( + width: screenWidth, + height: screenHeight / 2, + child: Opacity( + opacity: .2, + child: Image.asset( + "assets/emergency.png", + fit: BoxFit.cover, + ), + ), + )), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + height: blockSizeVertical * 6, + ), + Bounce( + from: 20, + infinite: true, + delay: const Duration(milliseconds: 800), + child: Stack( + alignment: AlignmentDirectional.topCenter, + children: [ + Container( + margin: const EdgeInsets.only(top: 20), + child: CircleAvatar( + radius: blockSizeVertical * 8, + backgroundColor: second, + child: Container( + margin: const EdgeInsets.only(top: 25), + child: SvgPicture.asset( + 'assets/sos.svg', + height: blockSizeHorizontal * 17, + color: Colors.white, + allowDrawingOutsideViewBox: true, + alignment: Alignment.bottomCenter, + ), + ), + ), + ), + Positioned( + top: blockSizeVertical * 3, + child: SpinKitPulse( + color: primary, + size: 120, + ), + ), + ], + ), + ), + const SizedBox(height: 16), + SlideInUp( + from: 50, + child: AutoSizeText( + "SOS Received!", + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.displayMedium!.copyWith( + fontSize: 40, + color: third, + fontWeight: FontWeight.w500, + ), + ), + ), + const SizedBox( + height: 8, + ), + SlideInUp( + from: 50, + child: Container( + padding: const EdgeInsets.all(15), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(15))), + child: AutoSizeText( + sOSReceivedMessage, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.caption!.copyWith( + fontSize: 16, + color: Colors.black87, + ), + ), + ), + ), + const SizedBox( + height: 40, + ), + Expanded(child: Container()), + SlideInUp( + child: SizedBox( + height: 50, + width: 200, + child: TextButton( + style: mainBtnStyle(second, Colors.transparent, second), + onPressed: () {}, + child: const Text("Cancel request", + style: TextStyle( + color: Colors.white, + )), + ), + ), + ) + ], + ), + ], + ), + ); + } +} diff --git a/unit2/lib/screen/unit2/homepage.dart/components/drawer-screen.dart b/unit2/lib/screen/unit2/homepage.dart/components/drawer-screen.dart new file mode 100644 index 0000000..4ffd092 --- /dev/null +++ b/unit2/lib/screen/unit2/homepage.dart/components/drawer-screen.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_zoom_drawer/config.dart'; +import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'menu-screen.dart'; +import '../module-screen.dart'; + +class DrawerScreen extends StatefulWidget { + const DrawerScreen({Key? key}) : super(key: key); + @override + State createState() => _DrawerScreenState(); +} + +class _DrawerScreenState extends State { + final zoomDrawerController = ZoomDrawerController(); + @override + Widget build(BuildContext context) { + return ZoomDrawer( + controller: zoomDrawerController, + menuScreen: const MenuScreen(), + mainScreen: const MainScreen(), + style: DrawerStyle.defaultStyle, + borderRadius: 24.0, + showShadow: false, + angle: -0.0, + slideWidth: MediaQuery.of(context).size.width * .90, + openCurve: Curves.fastOutSlowIn, + closeCurve: Curves.easeOut, + menuBackgroundColor: Colors.grey, + ); + } +} diff --git a/unit2/lib/screen/unit2/homepage.dart/components/empty_module.dart b/unit2/lib/screen/unit2/homepage.dart/components/empty_module.dart new file mode 100644 index 0000000..e7c9590 --- /dev/null +++ b/unit2/lib/screen/unit2/homepage.dart/components/empty_module.dart @@ -0,0 +1,53 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/container.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:unit2/theme-data.dart/text-styles.dart'; + +import '../../../../utils/global.dart'; +import '../../../../utils/text_container.dart'; + +class NoModule extends StatelessWidget { + const NoModule({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 25), + width: double.infinity, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + 'assets/svgs/no_module.svg', + height: blockSizeVertical * 30, + allowDrawingOutsideViewBox: true, + ), + const SizedBox( + height: 24, + ), + Text( + noModule, + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith(fontSize: blockSizeVertical * 5, height: .8), + ), + const SizedBox( + height: 5, + ), + Text( + noModuleSubTitle, + style: Theme.of(context) + .textTheme + .caption! + .copyWith(fontSize: blockSizeVertical * 1.5), + textAlign: TextAlign.center, + ) + ]), + ); + } +} diff --git a/unit2/lib/screen/unit2/homepage.dart/components/menu-screen.dart b/unit2/lib/screen/unit2/homepage.dart/components/menu-screen.dart new file mode 100644 index 0000000..f207fde --- /dev/null +++ b/unit2/lib/screen/unit2/homepage.dart/components/menu-screen.dart @@ -0,0 +1,75 @@ +import 'package:flutter/material.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:fluttericon/web_symbols_icons.dart'; +import 'package:fluttericon/typicons_icons.dart'; +import 'package:fluttericon/font_awesome5_icons.dart'; +import 'menu.dart'; +import '../../../../utils/global.dart'; + +class MenuScreen extends StatefulWidget { + const MenuScreen({Key? key}) : super(key: key); + + @override + State createState() => _MenuScreenState(); +} + +class _MenuScreenState extends State { + @override + Widget build(BuildContext context) { + return SafeArea( + child: Drawer( + child: SingleChildScrollView( + child: SizedBox( + height: blockSizeVertical * 96, + child: Column( + // ignore: prefer_const_literals_to_create_immutables + children: [ + const UserAccountsDrawerHeader( + decoration: BoxDecoration( + color: primary, + image: DecorationImage( + image: AssetImage('assets/pngs/bg.png'), + fit: BoxFit.cover)), + accountName: Text("ACUIN" ", " "RODOLFO" " " "BERNALIS"), + accountEmail: null, + currentAccountPicture: CircleAvatar( + radius: 40, + backgroundColor: fifth, + child: CircleAvatar( + radius: 33, + backgroundColor: third, + child: //Icon(Icons.person, size: 40, color: fifth), + Text( + "A", + style: TextStyle(fontSize: 45.0, color: fifth), + ), + ), + ), + ), + getTile(Typicons.user_outline, "Profile", 'profile', context), + const Divider(), + getTile(Typicons.home_outline, "Address", '/SelfAddressScreen', + context), + const Divider(), + getTile(Typicons.contacts, "Contact Number", + '/SelfContactScreen', context), + const Divider(), + getTile(Typicons.mail, "Email Address", '/SelfEmailAddScreen', + context), + const Divider(), + getTile(FontAwesome5.life_ring, "Request SOS", 'request-sos', + context), + const Divider(), + Expanded( + child: Align( + alignment: FractionalOffset.bottomLeft, + child: getTile(WebSymbols.logout, "Logout", '/', context), + )), + ], + ), + ), + ), + ), + ); + } +} diff --git a/unit2/lib/screen/unit2/homepage.dart/components/menu.dart b/unit2/lib/screen/unit2/homepage.dart/components/menu.dart new file mode 100644 index 0000000..204fdd0 --- /dev/null +++ b/unit2/lib/screen/unit2/homepage.dart/components/menu.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart'; +import 'package:go_router/go_router.dart'; + +import '../../../../theme-data.dart/colors.dart'; + +Widget getTile( + IconData icondata, String title, String route, BuildContext context) { + return ListTile( + dense: true, + leading: Icon( + icondata, + color: primary, + ), + title: Text( + title, + style: const TextStyle(color: Colors.black), + ), + onTap: () async { + debugPrint(title); + ZoomDrawer.of(context)!.toggle(); + context.goNamed(route); + }, + ); +} diff --git a/unit2/lib/screen/unit2/homepage.dart/module-screen.dart b/unit2/lib/screen/unit2/homepage.dart/module-screen.dart index f55a9c9..96b7a99 100644 --- a/unit2/lib/screen/unit2/homepage.dart/module-screen.dart +++ b/unit2/lib/screen/unit2/homepage.dart/module-screen.dart @@ -1,16 +1,53 @@ -import 'package:flutter/src/widgets/container.dart'; -import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/text_container.dart'; -class ModuleScreen extends StatefulWidget { - const ModuleScreen({super.key}); +import 'components/empty_module.dart'; + +class MainScreen extends StatefulWidget { + const MainScreen({Key? key}) : super(key: key); @override - State createState() => _ModuleScreenState(); + State createState() => _MainScreenState(); } -class _ModuleScreenState extends State { +class _MainScreenState extends State { + bool hasModule = false; @override Widget build(BuildContext context) { - return Container(); + return WillPopScope( + onWillPop: () async { + return Future.value(true); + }, + child: SafeArea( + child: Scaffold( + appBar: AppBar( + backgroundColor: primary, + leading: IconButton( + onPressed: () { + ZoomDrawer.of(context)!.toggle(); + }, + icon: const Icon( + Icons.menu, + color: Colors.white, + ), + ), + centerTitle: true, + title: const Text( + unit2ModuleScreen, + style: TextStyle( + fontSize: 18.0, + color: Colors.white, + ), + ), + ), + body: hasModule + ? const Center( + child: Text('Main Screen'), + ) + : const NoModule(), + )), + ); } -} \ No newline at end of file +} diff --git a/unit2/lib/screen/unit2/login/login.dart b/unit2/lib/screen/unit2/login/login.dart index 4dc993e..31da7a8 100644 --- a/unit2/lib/screen/unit2/login/login.dart +++ b/unit2/lib/screen/unit2/login/login.dart @@ -3,6 +3,8 @@ 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:unit2/utils/text_container.dart'; import '../../../widgets/wave.dart'; import '../../../utils/global.dart'; import '../../../theme-data.dart/colors.dart'; @@ -53,12 +55,12 @@ class _UniT2LoginState extends State { ), Text( - "Welcome to!", + welcome, style: TextStyle( fontSize: blockSizeVertical * 5, fontWeight: FontWeight.w600), ), - Text("uniT-App", + Text(unitApp, style: TextStyle( fontSize: blockSizeVertical * 8, fontWeight: FontWeight.w800, @@ -66,7 +68,7 @@ class _UniT2LoginState extends State { height: 1, color: primary)), Text( - "Please login to continue.", + loginToContinue, style: TextStyle( fontSize: blockSizeVertical * 2, height: 1.5, @@ -78,10 +80,8 @@ class _UniT2LoginState extends State { // USERNAME FormBuilderTextField( name: 'username', - validator: FormBuilderValidators.compose([ - FormBuilderValidators.required( - errorText: "Username is required") - ]), + validator: FormBuilderValidators.required( + errorText: "Username is required"), autofocus: false, style: const TextStyle( fontWeight: FontWeight.bold, @@ -93,10 +93,9 @@ class _UniT2LoginState extends State { // PASSWORD FormBuilderTextField( name: 'password', - validator: FormBuilderValidators.compose([ - FormBuilderValidators.required( - errorText: "Password is required") - ]), + validator: FormBuilderValidators.required( + errorText: "Password is required"), + // initialValue: state.password, onChanged: (value) { value!.isEmpty @@ -155,20 +154,14 @@ class _UniT2LoginState extends State { child: SizedBox( width: MediaQuery.of(context).size.width, child: ElevatedButton( - style: btnStyle( + style: mainBtnStyle( second, Colors.transparent, Colors.white54), child: const Text( "LOGIN", style: TextStyle(color: Colors.white), ), - onPressed: () async { - if (_formKey.currentState! - .saveAndValidate()) { - debugPrint( - _formKey.currentState!.value['name']); - debugPrint(_formKey - .currentState!.value['password']); - } + onPressed: () { + context.go(context.namedLocation('home')); // if (_formKey.currentState.validate()) { // _formKey.currentState.save(); // BlocProvider.of(context) @@ -189,14 +182,14 @@ class _UniT2LoginState extends State { child: SizedBox( width: MediaQuery.of(context).size.width, child: ElevatedButton.icon( - style: btnStyle(Colors.white, second, + style: mainBtnStyle(Colors.white, second, primary.withOpacity(.4)), icon: const Icon( Icons.qr_code, color: second, ), label: const Text( - "Login via QR code", + loginViaQr, style: TextStyle(color: second), ), onPressed: () async { @@ -208,8 +201,7 @@ class _UniT2LoginState extends State { SizedBox( height: blockSizeVertical * 1, ), - const LoginViaQr( - text: " Request Emergency Response "), + const LoginViaQr(text: emergencyReponseLabel), SizedBox( height: blockSizeVertical * 1, ), @@ -222,13 +214,14 @@ class _UniT2LoginState extends State { FontAwesome5.life_ring, color: Colors.white, ), - style: btnStyle( + style: mainBtnStyle( third, Colors.transparent, Colors.white38), onPressed: () { - Navigator.pushNamed(context, '/SosScreen'); + context + .go(context.namedLocation('add-mobile')); }, label: const Text( - "Request SOS", + requestSOS, style: TextStyle(color: Colors.white), )), ) diff --git a/unit2/lib/screen/unit2/profile/components/cover-image.dart b/unit2/lib/screen/unit2/profile/components/cover-image.dart new file mode 100644 index 0000000..5ce6aaf --- /dev/null +++ b/unit2/lib/screen/unit2/profile/components/cover-image.dart @@ -0,0 +1,20 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; + +class CoverImage extends StatelessWidget { + const CoverImage({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.grey, + child: CachedNetworkImage( + imageUrl: + 'https://static.vecteezy.com/system/resources/thumbnails/008/074/253/small/tropical-forest-sunset-nature-background-with-coconut-trees-vector.jpg', + width: double.infinity, + height: 220, + fit: BoxFit.cover, + ), + ); + } +} \ No newline at end of file diff --git a/unit2/lib/screen/unit2/profile/profile.dart b/unit2/lib/screen/unit2/profile/profile.dart new file mode 100644 index 0000000..5803e2f --- /dev/null +++ b/unit2/lib/screen/unit2/profile/profile.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:fluttericon/font_awesome5_icons.dart'; +import 'package:go_router/go_router.dart'; +import './components/cover-image.dart'; + +class Profile extends StatelessWidget { + const Profile({super.key}); + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + return Future.value(true); + }, + 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, + ), + )), + ], + ), + ), + ), + ); + } +} + +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, + ), + const SizedBox( + width: 20, + ), + Text( + "july 14, 1994 | Male", + style: + Theme.of(context).textTheme.caption!.copyWith(fontSize: 22), + ), + ], + ), + ], + ); + } +} + +class BuildProfileImage extends StatelessWidget { + const BuildProfileImage({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Stack( + alignment: Alignment.center, + children: [ + CircleAvatar( + radius: 85, + backgroundColor: Colors.white, + ), + CircleAvatar( + radius: 80, + backgroundColor: Colors.grey.shade800, + child: SvgPicture.asset( + 'assets/svgs/male.svg', + ), + ), + ], + ), + BuildInformation(), + ], + ); + } +} diff --git a/unit2/lib/theme-data.dart/btn-style.dart b/unit2/lib/theme-data.dart/btn-style.dart index 998f54d..89f7e86 100644 --- a/unit2/lib/theme-data.dart/btn-style.dart +++ b/unit2/lib/theme-data.dart/btn-style.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -ButtonStyle btnStyle(Color background, Color borderColor, Color overlay) { +ButtonStyle mainBtnStyle(Color background, Color borderColor, Color overlay) { return ButtonStyle( elevation: MaterialStateProperty.all(0), backgroundColor: MaterialStateProperty.all(background), @@ -13,3 +13,18 @@ ButtonStyle btnStyle(Color background, Color borderColor, Color overlay) { color: borderColor, )))); } + +ButtonStyle secondaryBtnStyle( + Color background, Color borderColor, Color overlay) { + return ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all(background), + overlayColor: MaterialStateProperty.all(overlay), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + side: BorderSide( + width: 2, + color: borderColor, + )))); +} diff --git a/unit2/lib/theme-data.dart/form-style.dart b/unit2/lib/theme-data.dart/form-style.dart index 2f339a1..6fbcc4c 100644 --- a/unit2/lib/theme-data.dart/form-style.dart +++ b/unit2/lib/theme-data.dart/form-style.dart @@ -1,5 +1,53 @@ import 'package:flutter/material.dart'; +InputDecoration normalTextFieldStyle(String labelText, String hintText) { + return InputDecoration( + contentPadding: EdgeInsets.fromLTRB(12, 6, 6, 6), + floatingLabelBehavior: FloatingLabelBehavior.auto, + labelText: labelText, + labelStyle: const TextStyle(color: Colors.grey), + hintText: hintText, + hintStyle: const TextStyle( + color: Colors.grey, + ), + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + width: 1, + color: Colors.black87, + ), + borderRadius: BorderRadius.circular(5), + ), + enabledBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: Colors.grey, + width: 1, + ), + borderRadius: BorderRadius.circular(5), + ), + disabledBorder: OutlineInputBorder( + borderSide: const BorderSide( + width: 1, + color: Colors.grey, + ), + borderRadius: BorderRadius.circular(5), + ), + errorBorder: const OutlineInputBorder( + borderSide: BorderSide( + color: Colors.red, + width: 1, + ), + borderRadius: BorderRadius.all(Radius.circular(5)), + ), + focusedErrorBorder: const OutlineInputBorder( + borderSide: BorderSide( + color: Colors.red, + width: 1, + ), + borderRadius: BorderRadius.all(Radius.circular(5)), + ), + filled: false); +} + InputDecoration loginTextFieldStyle() { return InputDecoration( floatingLabelBehavior: FloatingLabelBehavior.never, @@ -37,4 +85,4 @@ InputDecoration loginTextFieldStyle() { borderRadius: BorderRadius.all(Radius.circular(5)), ), filled: false); -} \ No newline at end of file +} diff --git a/unit2/lib/theme-data.dart/text-styles.dart b/unit2/lib/theme-data.dart/text-styles.dart new file mode 100644 index 0000000..7ad4888 --- /dev/null +++ b/unit2/lib/theme-data.dart/text-styles.dart @@ -0,0 +1,7 @@ +import 'package:flutter/material.dart'; +import 'package:unit2/utils/global.dart'; + +TextStyle titleTextStyle() { + return TextStyle( + fontSize: blockSizeVertical * 2.5, fontWeight: FontWeight.w500); +} diff --git a/unit2/lib/utils/router.dart b/unit2/lib/utils/router.dart index 98a746a..7794074 100644 --- a/unit2/lib/utils/router.dart +++ b/unit2/lib/utils/router.dart @@ -1,11 +1,36 @@ import 'package:go_router/go_router.dart'; +import '../screen/sos/add_mobile.dart'; +import '../screen/sos/request_sos.dart'; import '../screen/unit2/login/login.dart'; +import '../screen/unit2/homepage.dart/components/drawer-screen.dart'; +import '../screen/unit2/profile/profile.dart'; - -final GoRouter goRouter = GoRouter( - routes: [ - GoRoute(path: '/', - builder: (context,state) => const UniT2Login() - ) - ] -); \ No newline at end of file +final GoRouter goRouter = GoRouter(routes: [ + GoRoute( + path: '/', + name: 'login', + builder: (context, state) => const UniT2Login(), + routes: [ + GoRoute( + name: 'home', + path: 'home', + builder: (context, state) => const DrawerScreen(), + routes: [ + GoRoute( + name: 'profile', + path: 'profile', + builder: (context, state) => const Profile()) + ]), + GoRoute( + name: 'add-mobile', + path: 'add-moble', + builder: (context, state) => AddMobile(), + routes: [ + GoRoute( + name: 'request-sos', + path: 'request-sos', + builder: (context, state) => const RequestSOS(), + ) + ]), + ]), +]); diff --git a/unit2/lib/utils/screen_info.dart b/unit2/lib/utils/screen_info.dart new file mode 100644 index 0000000..a536655 --- /dev/null +++ b/unit2/lib/utils/screen_info.dart @@ -0,0 +1,9 @@ +import 'package:unit2/utils/global.dart'; + +bool isMobile() { + if (screenWidth > 500.00) { + return false; + } else { + return true; + } +} diff --git a/unit2/lib/utils/text_container.dart b/unit2/lib/utils/text_container.dart new file mode 100644 index 0000000..a214c0b --- /dev/null +++ b/unit2/lib/utils/text_container.dart @@ -0,0 +1,23 @@ +const String addMobile = "Enter your mobile number(s)"; +const String addMobileCaption = + "These mobile numbers will be used to contact you if you request an emergency response. Please provide at least one active number"; +const String mobileNumberRequired = "You must add atleast one mobile"; +const String numericValidator = "Please a number only"; +const String mobile1 = "Mobile number 1"; +const String mobile2 = "Mobile number 2"; +const String currentLocation = "You current location"; +const String noModule = "No Module Assigned"; +const String noModuleSubTitle = + "Please contact the admin if you want to access a module."; +const String submit = "SUBMIT"; +const String login = "LOGIN"; +const String sOSTitle = "Request SOS"; +const String sOSReceivedMessage = + "your SOS request has been received. Please wait for respondent's acknowledgement."; +const String unit2ModuleScreen = "uniT2 Modules"; +const String welcome = "Welcome to!"; +const String unitApp = 'uniT-App'; +const String loginToContinue = "Please login to continue."; +const String loginViaQr = "Login via QR code"; +const String emergencyReponseLabel = " Request Emergency Response "; +const String requestSOS = "Request SOS"; \ No newline at end of file diff --git a/unit2/lib/utils/validators.dart b/unit2/lib/utils/validators.dart new file mode 100644 index 0000000..704e733 --- /dev/null +++ b/unit2/lib/utils/validators.dart @@ -0,0 +1,12 @@ +import 'package:form_builder_validators/form_builder_validators.dart'; +import '../utils/text_container.dart'; + + +final mobileNumberValidator = FormBuilderValidators.compose([ + FormBuilderValidators.required( + errorText: mobileNumberRequired), + FormBuilderValidators.numeric( + errorText: numericValidator) + ]); + + diff --git a/unit2/macos/Flutter/GeneratedPluginRegistrant.swift b/unit2/macos/Flutter/GeneratedPluginRegistrant.swift index 287b6a9..e9cf192 100644 --- a/unit2/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/unit2/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,8 +5,12 @@ import FlutterMacOS import Foundation +import path_provider_macos import shared_preferences_macos +import sqflite func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) } diff --git a/unit2/pubspec.lock b/unit2/pubspec.lock index cd07b24..06adf03 100644 --- a/unit2/pubspec.lock +++ b/unit2/pubspec.lock @@ -1,6 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + animate_do: + dependency: "direct main" + description: + name: animate_do + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" async: dependency: transitive description: @@ -8,6 +15,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.9.0" + auto_size_text: + dependency: "direct main" + description: + name: auto_size_text + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" boolean_selector: dependency: transitive description: @@ -15,6 +29,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + cached_network_image: + dependency: "direct main" + description: + name: cached_network_image + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.3" + cached_network_image_platform_interface: + dependency: transitive + description: + name: cached_network_image_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + cached_network_image_web: + dependency: transitive + description: + name: cached_network_image_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" characters: dependency: transitive description: @@ -36,6 +71,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.16.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" cupertino_icons: dependency: "direct main" description: @@ -83,6 +125,20 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_blurhash: + dependency: transitive + description: + name: flutter_blurhash + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.0" flutter_custom_clippers: dependency: "direct main" description: @@ -109,6 +165,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_spinkit: + dependency: "direct main" + description: + name: flutter_spinkit + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0" flutter_svg: dependency: "direct main" description: @@ -167,7 +230,21 @@ packages: name: go_router url: "https://pub.dartlang.org" source: hosted - version: "5.2.0" + version: "3.1.1" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.5" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.2" intl: dependency: transitive description: @@ -231,6 +308,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + octo_image: + dependency: transitive + description: + name: octo_image + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" path: dependency: transitive description: @@ -252,6 +336,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.22" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" path_provider_linux: dependency: transitive description: @@ -259,6 +364,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.7" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" path_provider_platform_interface: dependency: transitive description: @@ -273,6 +385,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.3" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" petitparser: dependency: transitive description: @@ -308,6 +427,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.0.4" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.27.7" shared_preferences: dependency: transitive description: @@ -376,6 +502,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.0" + sqflite: + dependency: transitive + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0+3" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0+2" stack_trace: dependency: transitive description: @@ -397,6 +537,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0+3" term_glyph: dependency: transitive description: @@ -411,6 +558,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.12" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.7" vector_math: dependency: transitive description: diff --git a/unit2/pubspec.yaml b/unit2/pubspec.yaml index 21b322e..af6129a 100644 --- a/unit2/pubspec.yaml +++ b/unit2/pubspec.yaml @@ -36,7 +36,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 - go_router: ^5.2.0 + go_router: ^3.0.6 flutter_custom_clippers: ^2.0.0 flutter_svg: ^1.1.6 flutter_form_builder: ^7.7.0 @@ -45,6 +45,10 @@ dependencies: fluttertoast: ^8.1.1 device_preview: ^1.1.0 flutter_zoom_drawer: ^3.0.3 + cached_network_image: ^3.2.3 + auto_size_text: ^3.0.0 + animate_do: ^3.0.2 + flutter_spinkit: ^5.1.0 dev_dependencies: flutter_test: