Compare commits

..

6 commits

17 changed files with 1165 additions and 133 deletions

22
.vscode/launch.json vendored
View file

@ -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"
}
]
}

View file

@ -1,25 +1,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="ocbo_esign_validator"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<application android:label="ocbo_esign_validator" android:name="${applicationName}" android:icon="@mipmap/ic_launcher">
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:taskAffinity="" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
@ -27,9 +13,7 @@
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<meta-data android:name="flutterEmbedding" android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
@ -42,4 +26,7 @@
<data android:mimeType="text/plain"/>
</intent>
</queries>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
</manifest>

View file

@ -4,4 +4,5 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
</manifest>

File diff suppressed because one or more lines are too long

View file

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

View file

@ -1,49 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Ocbo Esign Validator</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ocbo_esign_validator</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Ocbo Esign Validator</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ocbo_esign_validator</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan QR codes</string>
</dict>
</plist>

View file

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

View file

@ -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: <Widget>[
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: <Widget>[
MenuWidget(
icon: Icons.person,
text: 'Login',
onPressed: () {
gotoApproval();
},
),
MenuWidget(
icon: Icons.qr_code,
text: 'Validate',
onPressed: () {
gotoValidation();
},
),
],
),
],
),
],
),
),
),
);
},
),
);
}

80
lib/pages/login_page.dart Normal file
View file

@ -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<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
// 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),
],
),
),
],
),
),
);
}
}

View file

@ -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<BarcodeScannerScreen> createState() => _BarcodeScannerScreenState();
}
class _BarcodeScannerScreenState extends State<BarcodeScannerScreen> {
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<Barcode> 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<ValidatePage> createState() => _ValidatePageState();
// }
// class _ValidatePageState extends State<ValidatePage> {
// 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<Barcode> 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)),
// ),
// ],
// ),
// ),
// ),
// );
// }
// }

View file

@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class ValidationResultPage extends StatelessWidget {
const ValidationResultPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold();
}
}

View file

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

View file

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

View file

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

View file

@ -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),
],
),
),

View file

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

View file

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