diff --git a/.vscode/launch.json b/.vscode/launch.json index d818e32..e7df63e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,14 +4,14 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - // { - // "name": "run app", - // "request": "launch", - // "type": "dart" - // }, { "name": "run app", "request": "launch", + "type": "dart" + }, + { + "name": "run app terminal", + "request": "launch", "type": "node-terminal", "command": "fvm flutter run", }, @@ -27,17 +27,5 @@ "type": "node-terminal", "command": "fvm flutter build apk --target-platform android-arm64", }, - { - "name": "pharmacy_mobile (profile mode)", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "pharmacy_mobile (release mode)", - "request": "launch", - "type": "dart", - "flutterMode": "release" - } ] } \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 3a69bf4..ffb184c 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,25 +1,11 @@ - - + + - + @@ -27,9 +13,7 @@ - + + diff --git a/android/build/reports/problems/problems-report.html b/android/build/reports/problems/problems-report.html new file mode 100644 index 0000000..462ecf6 --- /dev/null +++ b/android/build/reports/problems/problems-report.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Gradle Configuration Cache + + + +
+ +
+ Loading... +
+ + + + + + diff --git a/android/gradle.properties b/android/gradle.properties index f018a61..3eacd1e 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,4 @@ org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true +dev.steenbakker.mobile_scanner.useUnbundled=true diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 49bc867..20c77c8 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -1,49 +1,51 @@ - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Ocbo Esign Validator - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ocbo_esign_validator - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - - + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Ocbo Esign Validator + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ocbo_esign_validator + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + NSCameraUsageDescription + This app needs camera access to scan QR codes + diff --git a/lib/main.dart b/lib/main.dart index f919ad0..d8b8c43 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,7 +2,9 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:ocbo_esign_validator/pages/approval_page.dart'; import 'package:ocbo_esign_validator/pages/index_page.dart'; +import 'package:ocbo_esign_validator/pages/login_page.dart'; import 'package:ocbo_esign_validator/pages/validate_page.dart'; +import 'package:ocbo_esign_validator/pages/validation_result_page.dart'; void main() { runApp(const MyApp()); @@ -12,8 +14,10 @@ final _router = GoRouter( initialLocation: '/', routes: [ GoRoute(name: 'index', path: '/', builder: (context, state) => const IndexPage()), + GoRoute(name: 'login', path: '/login', builder: (context, state) => const LoginPage()), GoRoute(name: 'approval', path: '/approval', builder: (context, state) => const ApprovalPage()), GoRoute(name: 'validate', path: '/validate', builder: (context, state) => const ValidatePage()), + GoRoute(name: 'result', path: '/result', builder: (context, state) => const ValidationResultPage()), ], ); diff --git a/lib/pages/index_page.dart b/lib/pages/index_page.dart index 723a6a8..44c35ac 100644 --- a/lib/pages/index_page.dart +++ b/lib/pages/index_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; -import 'package:ocbo_esign_validator/widgets/circle_widget.dart'; +import 'package:ocbo_esign_validator/widgets/menu_widget.dart'; import 'package:ocbo_esign_validator/widgets/image_widget.dart'; import 'package:ocbo_esign_validator/widgets/text_widget.dart'; @@ -11,7 +11,7 @@ class IndexPage extends StatelessWidget { @override Widget build(BuildContext context) { void gotoApproval() { - context.push('/approval'); + context.push('/login'); } void gotoValidation() { @@ -20,43 +20,72 @@ class IndexPage extends StatelessWidget { return Scaffold( resizeToAvoidBottomInset: false, - body: Container( - alignment: Alignment.center, - height: MediaQuery.of(context).size.height, - decoration: const BoxDecoration(color: Color.fromRGBO(21, 31, 42, 1)), - child: Center( - child: Column( - children: [ - const Gap(88), - const ImageWidget(imagePath: 'assets/logo.png', size: 140, measureByHeight: true), - const Gap(20), - const TextWidget(text: "OCBO e-Sign", color: Color.fromARGB(255, 244, 243, 243), bold: true, size: 32), - const Gap(2), - const TextWidget(text: "Mobile", color: Color.fromARGB(255, 244, 243, 243), bold: true), - const Gap(200), - Row( - mainAxisAlignment: MainAxisAlignment.center, - spacing: 32, - children: [ - CircleWidget( - icon: Icons.thumb_up, - text: 'Approval', - onPressed: () { - gotoApproval(); - }, + body: LayoutBuilder( + builder: (context, constraints) { + final screenWidth = constraints.maxWidth; + + return Container( + alignment: Alignment.center, + height: MediaQuery.of(context).size.height, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color.fromRGBO(39, 26, 47, 1), + Color.fromRGBO(22, 33, 44, 1), + Color.fromRGBO(22, 33, 44, 1), + Color.fromRGBO(24, 45, 40, 1), + ], + ), + ), + child: Center( + child: Column( + children: [ + const Gap(88), + const ImageWidget(imagePath: 'assets/logo.png', size: 140, measureByHeight: true), + const Gap(24), + const TextWidget( + text: "OCBO e-Sign", + color: Color.fromARGB(255, 244, 243, 243), + bold: true, + size: 34, ), - CircleWidget( - icon: Icons.qr_code, - text: 'Validate', - onPressed: () { - gotoValidation(); - }, + Padding( + padding: EdgeInsets.only(right: (screenWidth / 2) - 100), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextWidget(text: "Mobile", color: Color.fromARGB(255, 244, 243, 243), bold: false, size: 16), + ], + ), + ), + Gap(200), + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 32, + children: [ + MenuWidget( + icon: Icons.person, + text: 'Login', + onPressed: () { + gotoApproval(); + }, + ), + MenuWidget( + icon: Icons.qr_code, + text: 'Validate', + onPressed: () { + gotoValidation(); + }, + ), + ], ), ], ), - ], - ), - ), + ), + ); + }, ), ); } diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart new file mode 100644 index 0000000..682dc17 --- /dev/null +++ b/lib/pages/login_page.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:ocbo_esign_validator/widgets/box_widget.dart'; +import 'package:ocbo_esign_validator/widgets/button_widget.dart'; +import 'package:ocbo_esign_validator/widgets/image_widget.dart'; +import 'package:ocbo_esign_validator/widgets/input_widget.dart'; +import 'package:ocbo_esign_validator/widgets/text_widget.dart'; + +class LoginPage extends StatefulWidget { + const LoginPage({super.key}); + + @override + State createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + // final List _ =; + // ["Cluj-Napoca", "Bucuresti", "Timisoara", "Brasov", "Constanta"]; + + final _passwordController = TextEditingController(); + final _approver = "ARCH. KHASHAYAR L. TOGHYANI"; + + void _login() { + // Add your login logic here + print("Login button clicked"); + } + + @override + void dispose() { + _passwordController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: false, + body: Container( + alignment: Alignment.center, + height: MediaQuery.of(context).size.height, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color.fromRGBO(39, 26, 47, 1), + Color.fromRGBO(22, 33, 44, 1), + Color.fromRGBO(22, 33, 44, 1), + Color.fromRGBO(24, 45, 40, 1), + ], + ), + ), + child: Column( + children: [ + const Gap(88), + const ImageWidget(imagePath: 'assets/logo.png', size: 100, measureByHeight: true), + const Gap(50), + BoxWidget( + title: 'Login', + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const TextWidget(text: 'Name', bold: true, size: 16), + const Gap(8), + TextWidget(text: _approver, bold: false, size: 16), + const Gap(8), + const TextWidget(text: 'Password', bold: true, size: 16), + const Gap(8), + InputWidget(controller: _passwordController, placeholder: 'placeholder'), + const Gap(16), + ButtonWidget(text: 'Login', onPressed: _login), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/validate_page.dart b/lib/pages/validate_page.dart index 03da366..3f58f21 100644 --- a/lib/pages/validate_page.dart +++ b/lib/pages/validate_page.dart @@ -1,10 +1,129 @@ import 'package:flutter/material.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; +import 'package:ocbo_esign_validator/widgets/text_widget.dart'; class ValidatePage extends StatelessWidget { const ValidatePage({super.key}); @override Widget build(BuildContext context) { - return Scaffold(); + return const MaterialApp(debugShowCheckedModeBanner: false, home: BarcodeScannerScreen()); } } + +class BarcodeScannerScreen extends StatefulWidget { + const BarcodeScannerScreen({super.key}); + + @override + State createState() => _BarcodeScannerScreenState(); +} + +class _BarcodeScannerScreenState extends State { + String barcodeResult = "Point the camera at a barcode"; + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: false, + body: Container( + alignment: Alignment.center, + height: MediaQuery.of(context).size.height, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color.fromRGBO(39, 26, 47, 1), + Color.fromRGBO(22, 33, 44, 1), + Color.fromRGBO(22, 33, 44, 1), + Color.fromRGBO(24, 45, 40, 1), + ], + ), + ), + child: Center( + child: Column( + children: [ + Expanded( + flex: 3, + child: MobileScanner( + onDetect: (BarcodeCapture capture) { + final List barcodes = capture.barcodes; + if (barcodes.isNotEmpty && barcodes.first.rawValue != null) { + setState(() { + barcodeResult = barcodes.first.rawValue!; + }); + } + }, + ), + ), + Expanded( + flex: 1, + child: Center( + child: Center(child: TextWidget(text: barcodeResult, bold: false, size: 18)), + ), + ), + ], + ), + ), + ), + ); + } +} + +// class ValidatePage extends StatefulWidget { +// const ValidatePage({super.key}); + +// @override +// State createState() => _ValidatePageState(); +// } + +// class _ValidatePageState extends State { +// final qrKey = GlobalKey(debugLabel: 'QR'); +// String barcodeResult = "Point the camera at a barcode"; + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// resizeToAvoidBottomInset: false, +// body: Container( +// alignment: Alignment.center, +// height: MediaQuery.of(context).size.height, +// decoration: const BoxDecoration( +// gradient: LinearGradient( +// begin: Alignment.topCenter, +// end: Alignment.bottomCenter, +// colors: [ +// Color.fromRGBO(39, 26, 47, 1), +// Color.fromRGBO(22, 33, 44, 1), +// Color.fromRGBO(22, 33, 44, 1), +// Color.fromRGBO(24, 45, 40, 1), +// ], +// ), +// ), +// child: Center( +// child: Column( +// children: [ +// Expanded( +// flex: 2, +// child: MobileScanner( +// onDetect: (BarcodeCapture capture) { +// final List barcodes = capture.barcodes; +// if (barcodes.isNotEmpty && barcodes.first.rawValue != null) { +// setState(() { +// barcodeResult = barcodes.first.rawValue!; +// }); +// } +// }, +// ), +// ), +// Expanded( +// flex: 1, +// child: Center(child: TextWidget(text: barcodeResult, bold: false, size: 18)), +// ), +// ], +// ), +// ), +// ), +// ); +// } +// } diff --git a/lib/pages/validation_result_page.dart b/lib/pages/validation_result_page.dart new file mode 100644 index 0000000..5660806 --- /dev/null +++ b/lib/pages/validation_result_page.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class ValidationResultPage extends StatelessWidget { + const ValidationResultPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/lib/widgets/box_widget.dart b/lib/widgets/box_widget.dart new file mode 100644 index 0000000..e35d944 --- /dev/null +++ b/lib/widgets/box_widget.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:ocbo_esign_validator/widgets/text_widget.dart'; + +class BoxWidget extends StatelessWidget { + final String title; + final Widget content; + + const BoxWidget({super.key, required this.title, required this.content}); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.all(16), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Color.fromARGB(149, 16, 22, 28), + border: Border.all(color: const Color.fromRGBO(32, 47, 61, 1)), + ), + width: MediaQuery.of(context).size.width - 100, + height: MediaQuery.of(context).size.height / 2.2, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [TextWidget(text: title, bold: true, size: 24)], + ), + const Gap(16), + Padding(padding: const EdgeInsets.all(16), child: content), + ], + ), + ); + } +} diff --git a/lib/widgets/button_widget.dart b/lib/widgets/button_widget.dart new file mode 100644 index 0000000..7778db8 --- /dev/null +++ b/lib/widgets/button_widget.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +class ButtonWidget extends StatelessWidget { + final String text; + final VoidCallback onPressed; + final bool? outline; + final double? width; + + const ButtonWidget({super.key, required this.text, required this.onPressed, this.outline, this.width}); + + @override + Widget build(BuildContext context) { + return ElevatedButton( + style: outline == true + ? OutlinedButton.styleFrom( + foregroundColor: const Color.fromRGBO(0, 0, 0, 1), + backgroundColor: Colors.transparent, + side: const BorderSide(color: Color.fromRGBO(198, 133, 232, 1)), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + minimumSize: Size( + MediaQuery.of(context).size.width <= 768 ? MediaQuery.of(context).size.width - 96 : 320, + 44, + ), + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), + ) + : ElevatedButton.styleFrom( + foregroundColor: const Color.fromRGBO(0, 0, 0, 1), // text color + backgroundColor: const Color.fromRGBO(198, 133, 232, 1), + side: const BorderSide(color: Color.fromRGBO(79, 51, 94, 0.4)), // border color + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), // rounded corners + ), + minimumSize: Size( + width ?? (MediaQuery.of(context).size.width <= 768 ? MediaQuery.of(context).size.width - 96 : 320), + 44, + ), + + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), + ), + onPressed: onPressed, + child: Text(text, style: _textStyle(outline)), + ); + } + + TextStyle _textStyle(bool? outline) { + if (outline == true) { + return GoogleFonts.roboto(textStyle: const TextStyle(fontSize: 14, color: Color.fromRGBO(198, 133, 232, 1))); + } else { + return GoogleFonts.roboto(textStyle: const TextStyle(fontSize: 14, color: Color.fromRGBO(0, 0, 0, 1))); + } + } +} diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart new file mode 100644 index 0000000..fd0b3b5 --- /dev/null +++ b/lib/widgets/input_widget.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:google_fonts/google_fonts.dart'; + +class InputWidget extends StatelessWidget { + final TextEditingController controller; + final String placeholder; + + const InputWidget({super.key, required this.controller, required this.placeholder}); + + @override + Widget build(BuildContext context) { + return TextField( + controller: controller, + decoration: InputDecoration( + filled: true, + fillColor: const Color.fromRGBO(255, 255, 255, 1), + border: OutlineInputBorder(borderRadius: BorderRadius.circular(4)), + contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 14), + hintText: placeholder, + ), + style: GoogleFonts.roboto(textStyle: const TextStyle(color: Color.fromRGBO(0, 0, 0, 1), fontSize: 16)), + ); + } +} diff --git a/lib/widgets/circle_widget.dart b/lib/widgets/menu_widget.dart similarity index 54% rename from lib/widgets/circle_widget.dart rename to lib/widgets/menu_widget.dart index 45cb499..1a5bec4 100644 --- a/lib/widgets/circle_widget.dart +++ b/lib/widgets/menu_widget.dart @@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; import 'package:ocbo_esign_validator/widgets/text_widget.dart'; -class CircleWidget extends StatelessWidget { +class MenuWidget extends StatelessWidget { final IconData? icon; final String text; final VoidCallback onPressed; - const CircleWidget({super.key, required this.icon, required this.text, required this.onPressed}); + const MenuWidget({super.key, required this.icon, required this.text, required this.onPressed}); @override Widget build(BuildContext context) { @@ -16,18 +16,18 @@ class CircleWidget extends StatelessWidget { child: Container( padding: EdgeInsets.all(16), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - color: Colors.white10, - border: Border.all(color: const Color.fromARGB(77, 255, 255, 255)), + borderRadius: BorderRadius.circular(8), + color: Color.fromARGB(149, 16, 22, 28), + border: Border.all(color: const Color(0xff202f3d)), ), width: 120, height: 120, child: Column( children: [ - const Gap(8), - Icon(icon, color: Colors.white, size: 32), - const Gap(8), - TextWidget(text: text, size: 16), + const Gap(4), + Icon(icon, color: Colors.white, size: 42), + const Gap(16), + TextWidget(text: text, size: 14), ], ), ), diff --git a/pubspec.lock b/pubspec.lock index 976abd6..e2e4dd8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -148,10 +148,10 @@ packages: dependency: "direct main" description: name: google_fonts - sha256: "517b20870220c48752eafa0ba1a797a092fb22df0d89535fd9991e86ee2cdd9c" + sha256: ba03d03bcaa2f6cb7bd920e3b5027181db75ab524f8891c8bc3aa603885b8055 url: "https://pub.dev" source: hosted - version: "6.3.2" + version: "6.3.3" http: dependency: transitive description: @@ -240,6 +240,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.0" + mobile_scanner: + dependency: "direct main" + description: + name: mobile_scanner + sha256: "023a71afb4d7cfb5529d0f2636aa8b43db66257905b9486d702085989769c5f2" + url: "https://pub.dev" + source: hosted + version: "7.1.3" nm: dependency: transitive description: @@ -268,18 +276,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: e122c5ea805bb6773bb12ce667611265980940145be920cd09a4b0ec0285cb16 + sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e url: "https://pub.dev" source: hosted - version: "2.2.20" + version: "2.2.22" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: efaec349ddfc181528345c56f8eda9d6cccd71c177511b132c6a0ddaefaa2738 + sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4" url: "https://pub.dev" source: hosted - version: "2.4.3" + version: "2.5.1" path_provider_linux: dependency: transitive description: @@ -328,6 +336,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + qr: + dependency: transitive + description: + name: qr + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + qr_code_scanner_plus: + dependency: "direct main" + description: + name: qr_code_scanner_plus + sha256: b764e5004251c58d9dee0c295e6006e05bd8d249e78ac3383abdb5afe0a996cd + url: "https://pub.dev" + source: hosted + version: "2.0.14" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.dev" + source: hosted + version: "4.1.0" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 951dacd..5b8d86a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,6 +15,9 @@ dependencies: go_router: ^17.0.0 gap: ^3.0.1 internet_connection_checker: ^3.0.1 + qr_flutter: ^4.1.0 + qr_code_scanner_plus: ^2.0.14 + mobile_scanner: ^7.1.3 dev_dependencies: flutter_test: