From 57b8bdc067ef00ca6522e2f14f44a025733eb17f Mon Sep 17 00:00:00 2001 From: Patrick Alvin Alcala Date: Fri, 31 Jan 2025 11:21:11 +0800 Subject: [PATCH] update --- lib/pages/add_generics.dart | 2 +- lib/pages/add_medicine.dart | 2 +- lib/pages/add_stock.dart | 2 +- lib/pages/add_type.dart | 2 +- lib/pages/index_page.dart | 11 +- lib/pages/list_stocks.dart | 2 +- lib/pages/login_page.dart | 140 +++++++++++------- lib/pages/main_page.dart | 84 ++++++----- lib/widgets/button_widget.dart | 10 +- lib/widgets/input_widget.dart | 10 +- lib/widgets/page_background_widget.dart | 5 +- lib/widgets/text_widget.dart | 10 +- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 72 +++++++++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 17 files changed, 245 insertions(+), 114 deletions(-) diff --git a/lib/pages/add_generics.dart b/lib/pages/add_generics.dart index 3126cf3..d148799 100644 --- a/lib/pages/add_generics.dart +++ b/lib/pages/add_generics.dart @@ -77,7 +77,7 @@ class AddGenericsPageState extends State { child: Center( child: Column( children: [ - const Gap(120), + const Gap(104), const TitleWidget(firstTextSize: 16, secondTextSize: 32), const Gap(32), const TextWidget(text: 'Add Generics'), diff --git a/lib/pages/add_medicine.dart b/lib/pages/add_medicine.dart index 4ab391d..a11084c 100644 --- a/lib/pages/add_medicine.dart +++ b/lib/pages/add_medicine.dart @@ -111,7 +111,7 @@ class AddMedicinePageState extends State { child: Center( child: Column( children: [ - const Gap(120), + const Gap(104), const TitleWidget(firstTextSize: 16, secondTextSize: 32), const Gap(32), const TextWidget(text: 'Add Medicine'), diff --git a/lib/pages/add_stock.dart b/lib/pages/add_stock.dart index 6d69bdb..5fee428 100644 --- a/lib/pages/add_stock.dart +++ b/lib/pages/add_stock.dart @@ -83,7 +83,7 @@ class _AddStockPageState extends State { child: Center( child: Column( children: [ - const Gap(120), + const Gap(104), const TitleWidget(firstTextSize: 16, secondTextSize: 32), const Gap(32), const TextWidget(text: 'Add Stock'), diff --git a/lib/pages/add_type.dart b/lib/pages/add_type.dart index e8c26fa..10a2932 100644 --- a/lib/pages/add_type.dart +++ b/lib/pages/add_type.dart @@ -42,7 +42,7 @@ class _AddTypePageState extends State { child: Center( child: Column( children: [ - const Gap(120), + const Gap(104), const TitleWidget(firstTextSize: 16, secondTextSize: 32), const Gap(32), const TextWidget(text: 'Add Medicine Type'), diff --git a/lib/pages/index_page.dart b/lib/pages/index_page.dart index eac1b81..e6abafe 100644 --- a/lib/pages/index_page.dart +++ b/lib/pages/index_page.dart @@ -23,7 +23,7 @@ class IndexPage extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - const Gap(120), + const Gap(104), const TitleWidget(firstTextSize: 32, secondTextSize: 40), const Gap(32), Padding( @@ -34,8 +34,13 @@ class IndexPage extends StatelessWidget { const Gap(32), ButtonWidget(text: 'Login', onPressed: gotoLogin), const MaxGap(500), - const TextWidget(text: 'Copyright © 2025 - Ofelia Franco-Alcala Pharmacy', size: 14), - const TextWidget(text: 'Developed By: Pat Alcala', size: 12) + const TextWidget( + text: 'Copyright © 2025 - Ofelia Franco-Alcala Pharmacy', + size: 12, + bold: true, + ), + const TextWidget(text: 'Developed By: Pat Alcala', size: 10, opacity: 0.8), + const Gap(8), ], ), ), diff --git a/lib/pages/list_stocks.dart b/lib/pages/list_stocks.dart index 15a1f35..7bd95b6 100644 --- a/lib/pages/list_stocks.dart +++ b/lib/pages/list_stocks.dart @@ -28,7 +28,7 @@ class _ListStocksPageState extends State { return Scaffold( body: PageBackgroundWidget( child: Column(children: [ - const Gap(120), + const Gap(104), const TitleWidget(firstTextSize: 16, secondTextSize: 32), const Gap(32), const TextWidget(text: 'List of Stocks'), diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 037cc87..ee205ed 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -9,6 +9,7 @@ import 'package:pharmacy_mobile/widgets/page_background_widget.dart'; import 'package:pharmacy_mobile/widgets/text_widget.dart'; import 'package:pharmacy_mobile/widgets/title_widget.dart'; import 'package:quickalert/quickalert.dart'; +import 'package:internet_connection_checker/internet_connection_checker.dart'; class LoginPage extends StatefulWidget { const LoginPage({super.key}); @@ -23,31 +24,55 @@ class _LoginPageState extends State { final _passwordController = TextEditingController(); final FocusNode _focusNode = FocusNode(); + bool _isLoading = false; + void _signIn() async { + if (_isLoading) return; + final email = _emailController.text; final password = _passwordController.text; + setState(() => _isLoading = true); + try { - await _authService.signIn(email, password); - // QuickAlert.show( - // context: context, - // type: QuickAlertType.success, - // text: 'Login Successful', - // autoCloseDuration: const Duration(seconds: 1), - // showConfirmBtn: false, - // ); - context.push('/main'); + if (await InternetConnectionChecker.instance.hasConnection) { + await _authService.signIn(email, password); + if (mounted) { + QuickAlert.show( + context: context, + type: QuickAlertType.success, + text: 'Login Successful', + autoCloseDuration: const Duration(seconds: 2), + showConfirmBtn: false, + ).then((value) => { + if (mounted && context.mounted) {context.push('/main')} + }); + } + } else { + if (mounted) { + QuickAlert.show( + context: context, + type: QuickAlertType.error, + text: 'No Internet Connection', + autoCloseDuration: const Duration(seconds: 2), + showConfirmBtn: false, + ); + // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error: $e'))); + } + } } catch (e) { if (mounted) { QuickAlert.show( context: context, type: QuickAlertType.error, text: 'Error: $e', - autoCloseDuration: const Duration(seconds: 2), + autoCloseDuration: const Duration(seconds: 5), showConfirmBtn: false, ); // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error: $e'))); } + } finally { + setState(() => _isLoading = false); } // if (mounted) { @@ -68,50 +93,61 @@ class _LoginPageState extends State { @override Widget build(BuildContext context) { return Scaffold( + resizeToAvoidBottomInset: false, body: PageBackgroundWidget( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - const Gap(120), - const TitleWidget(firstTextSize: 16, secondTextSize: 32), - const Gap(32), - const TextWidget(text: 'Login'), - const Gap(16), - Padding( - padding: const EdgeInsets.only(left: 16, right: 16), - child: Container( - padding: EdgeInsets.all(16), - decoration: BoxDecoration( - border: Border.all(color: Colors.white), borderRadius: BorderRadius.all(Radius.circular(16))), - child: Form( - child: Column( - children: [ - InputWidget(label: 'Email', controller: _emailController), - const Gap(16), - KeyboardListener( - focusNode: _focusNode, - onKeyEvent: (event) { - if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { - _signIn(); - } - }, - child: InputWidget( - label: 'Password', - controller: _passwordController, - password: true, - ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const Gap(104), + const TitleWidget(firstTextSize: 16, secondTextSize: 32), + const Gap(32), + const TextWidget(text: 'Login'), + const Gap(16), + Padding( + padding: const EdgeInsets.only(left: 16, right: 16), + child: Container( + padding: EdgeInsets.all(32), + decoration: BoxDecoration( + color: const Color.fromARGB(219, 38, 17, 46), + borderRadius: BorderRadius.all(Radius.circular(16)), + // boxShadow: [ + // BoxShadow( + // color: const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.4), // Subtle shadow to give depth + // spreadRadius: 0, + // blurRadius: 4, + // offset: Offset(0, 2), + // ) + // ] ), - const Gap(24), - // TextButton(onPressed: () => {_signIn()}, child: const Text('Login')) - ButtonWidget(text: 'Login', onPressed: _signIn) - ], - )), - ), + child: Form( + child: Column( + children: [ + InputWidget(label: 'Email', controller: _emailController), + const Gap(16), + KeyboardListener( + focusNode: _focusNode, + onKeyEvent: (event) { + if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { + _signIn(); + } + }, + child: InputWidget( + label: 'Password', + controller: _passwordController, + password: true, + ), + ), + const Gap(24), + // TextButton(onPressed: () => {_signIn()}, child: const Text('Login')) + ButtonWidget(text: 'Login', onPressed: _signIn) + ], + )), + ), + ), + ], ), - ], - ), - ), - )); + ), + )); } } diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 9b10872..30203d2 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -17,8 +17,7 @@ class MainPage extends StatelessWidget { final authService = AuthService(); void signOut() async { - await authService.signOut(); - context.push('/'); + await authService.signOut().then((_) => {context.push('/')}); } void gotoAddMedicine() { @@ -30,46 +29,49 @@ class MainPage extends StatelessWidget { } return Scaffold( - body: PageBackgroundWidget( - child: Center( - child: Column( - children: [ - const Gap(120), - const TitleWidget(firstTextSize: 16, secondTextSize: 32), - const Gap(32), - const TextWidget(text: 'Menu'), - const Gap(16), - MenuWidget( - icon: FontAwesomeIcons.squarePlus, - text: 'Add Medicine', - onPressed: gotoAddMedicine, - ), - const Gap(16), - MenuWidget( - icon: FontAwesomeIcons.squarePlus, - text: 'Add Generics', - onPressed: gotoAddGenerics, - ), - const Gap(16), - MenuWidget( - icon: FontAwesomeIcons.squarePlus, text: 'Add Stock', onPressed: () => {context.push('/addstock')}), - const Gap(16), - MenuWidget( + resizeToAvoidBottomInset: false, + body: SingleChildScrollView( + child: PageBackgroundWidget( + child: Center( + child: Column( + children: [ + const Gap(104), + const TitleWidget(firstTextSize: 16, secondTextSize: 32), + const Gap(32), + const TextWidget(text: 'Menu'), + const Gap(16), + MenuWidget( icon: FontAwesomeIcons.squarePlus, - text: 'Add Medicine Type', - onPressed: () => {context.push('/addtype')}), - const Gap(32), - MenuWidget( - icon: FontAwesomeIcons.listCheck, - text: 'List of Stocks', - onPressed: () => {context.push('/liststocks')}), - const Gap(32), - // TextButton(onPressed: () => {_signOut()}, child: const Text('Logout')), - ButtonWidget( - text: 'Logout', - onPressed: signOut, - ) - ], + text: 'Add Medicine', + onPressed: gotoAddMedicine, + ), + const Gap(16), + MenuWidget( + icon: FontAwesomeIcons.squarePlus, + text: 'Add Generics', + onPressed: gotoAddGenerics, + ), + const Gap(16), + MenuWidget( + icon: FontAwesomeIcons.squarePlus, text: 'Add Stock', onPressed: () => {context.push('/addstock')}), + const Gap(16), + MenuWidget( + icon: FontAwesomeIcons.squarePlus, + text: 'Add Medicine Type', + onPressed: () => {context.push('/addtype')}), + const Gap(32), + MenuWidget( + icon: FontAwesomeIcons.listCheck, + text: 'List of Stocks', + onPressed: () => {context.push('/liststocks')}), + const Gap(32), + // TextButton(onPressed: () => {_signOut()}, child: const Text('Logout')), + ButtonWidget( + text: 'Logout', + onPressed: signOut, + ) + ], + ), ), ), ), diff --git a/lib/widgets/button_widget.dart b/lib/widgets/button_widget.dart index 38cc929..b1efb67 100644 --- a/lib/widgets/button_widget.dart +++ b/lib/widgets/button_widget.dart @@ -12,19 +12,19 @@ class ButtonWidget extends StatelessWidget { Widget build(BuildContext context) { return ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Color(0xFF8E44AD), // text color - backgroundColor: const Color(0xFFE8DAEF), // background color - side: const BorderSide(color: Color.fromARGB(55, 255, 255, 255)), // border color + foregroundColor: Color.fromRGBO(0, 0, 0, 1), // text color + backgroundColor: const Color.fromRGBO(198, 133, 232, 1), // background color + side: const BorderSide(color: Color.fromRGBO(79, 51, 94, 1)), // border color shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(26), // rounded corners ), - minimumSize: Size(MediaQuery.of(context).size.width - 64, 40), // minimum size + minimumSize: Size(MediaQuery.of(context).size.width - 96, 40), // minimum size padding: EdgeInsets.symmetric(vertical: 10, horizontal: 16), // padding ), onPressed: onPressed, child: Text( text, - style: GoogleFonts.outfit(textStyle: const TextStyle(fontSize: 18)), + style: GoogleFonts.outfit(textStyle: const TextStyle(fontSize: 16)), )); } } diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 21e0981..ff6bcda 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -16,15 +16,17 @@ class InputWidget extends StatelessWidget { children: [ Text('$label:', style: GoogleFonts.outfit( - textStyle: const TextStyle(color: Colors.white, fontSize: 16), + textStyle: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500), )), const Gap(8), TextField( controller: controller, decoration: InputDecoration( - border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)), - ), - style: GoogleFonts.outfit(textStyle: TextStyle(color: Colors.white, fontSize: 16)), + filled: true, // Enable filling the background + fillColor: Colors.white, + border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), + contentPadding: EdgeInsets.symmetric(vertical: 10, horizontal: 24)), + style: GoogleFonts.outfit(textStyle: TextStyle(color: const Color.fromRGBO(0, 0, 0, 1), fontSize: 16)), obscureText: password ?? false, ), ], diff --git a/lib/widgets/page_background_widget.dart b/lib/widgets/page_background_widget.dart index eb05276..227b117 100644 --- a/lib/widgets/page_background_widget.dart +++ b/lib/widgets/page_background_widget.dart @@ -14,8 +14,9 @@ class PageBackgroundWidget extends StatelessWidget { gradient: RadialGradient( tileMode: TileMode.clamp, colors: [ - Color.fromRGBO(132, 84, 125, 1), - Color.fromRGBO(96, 48, 90, 1), + // Color.fromRGBO(132, 84, 125, 1), + // Color.fromRGBO(96, 48, 90, 1), + Color.fromRGBO(45, 15, 43, 1), Color.fromRGBO(77, 29, 73, 1), // Color.fromRGBO(241, 220, 223, 1), ], diff --git a/lib/widgets/text_widget.dart b/lib/widgets/text_widget.dart index 0d3053b..e1ecd35 100644 --- a/lib/widgets/text_widget.dart +++ b/lib/widgets/text_widget.dart @@ -4,12 +4,18 @@ import 'package:google_fonts/google_fonts.dart'; class TextWidget extends StatelessWidget { final String text; final double? size; + final double? opacity; + final bool? bold; - const TextWidget({super.key, required this.text, this.size}); + const TextWidget({super.key, required this.text, this.size, this.opacity, this.bold}); @override Widget build(BuildContext context) { return Text(text, - style: GoogleFonts.outfit(textStyle: TextStyle(color: Color.fromRGBO(255, 255, 255, 1), fontSize: size ?? 32))); + style: GoogleFonts.outfit( + textStyle: TextStyle( + color: Color.fromRGBO(255, 255, 255, opacity ?? 1), + fontSize: size ?? 32, + fontWeight: bold == true ? FontWeight.bold : FontWeight.normal))); } } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 92b6497..68d7312 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,12 +6,14 @@ import FlutterMacOS import Foundation import app_links +import connectivity_plus import path_provider_foundation import shared_preferences_foundation import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) + ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 13d727d..1470e3b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -33,6 +33,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + args: + dependency: transitive + description: + name: args + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + url: "https://pub.dev" + source: hosted + version: "2.6.0" async: dependency: transitive description: @@ -81,6 +89,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.0" + connectivity_plus: + dependency: transitive + description: + name: connectivity_plus + sha256: "8a68739d3ee113e51ad35583fdf9ab82c55d09d693d3c39da1aebab87c938412" + url: "https://pub.dev" + source: hosted + version: "6.1.2" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" + url: "https://pub.dev" + source: hosted + version: "2.0.1" crypto: dependency: transitive description: @@ -97,6 +121,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + dbus: + dependency: transitive + description: + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + url: "https://pub.dev" + source: hosted + version: "0.7.11" + equatable: + dependency: transitive + description: + name: equatable + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" + url: "https://pub.dev" + source: hosted + version: "2.0.7" fake_async: dependency: transitive description: @@ -224,6 +264,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + internet_connection_checker: + dependency: "direct main" + description: + name: internet_connection_checker + sha256: ee08f13d8b13b978affe226e9274ca3ba7a9bed07c9479e8ae245f785b7a488a + url: "https://pub.dev" + source: hosted + version: "3.0.1" intl: dependency: "direct main" description: @@ -312,6 +360,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" path: dependency: transitive description: @@ -368,6 +424,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" platform: dependency: transitive description: @@ -701,6 +765,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" yet_another_json_isolate: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4f3c55e..8cf9df7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,7 @@ dependencies: bottom_picker: ^2.10.1 intl: ^0.20.2 visibility_detector: ^0.4.0+2 + internet_connection_checker: ^3.0.1 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 785a046..9eb38ec 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,11 +7,14 @@ #include "generated_plugin_registrant.h" #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { AppLinksPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("AppLinksPluginCApi")); + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 8f8ee4f..64c0dfb 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST app_links + connectivity_plus url_launcher_windows )