Compare commits

...

3 commits

Author SHA1 Message Date
23911c02cf Added dio for api 2025-12-10 18:12:26 +08:00
5ee5902524 Updated widgets 2025-12-10 18:12:15 +08:00
78259a6f7e Updated pages 2025-12-10 18:11:42 +08:00
8 changed files with 112 additions and 133 deletions

View file

@ -14,20 +14,29 @@ class LoginPage extends StatefulWidget {
} }
class _LoginPageState extends State<LoginPage> { class _LoginPageState extends State<LoginPage> {
// final List _ =;
// ["Cluj-Napoca", "Bucuresti", "Timisoara", "Brasov", "Constanta"];
final _passwordController = TextEditingController(); final _passwordController = TextEditingController();
final _approver = "ARCH. KHASHAYAR L. TOGHYANI"; final _approver = "ARCH. KHASHAYAR L. TOGHYANI";
late ValueNotifier<String> passwordNotifier;
@override
void initState() {
super.initState();
passwordNotifier = ValueNotifier(_passwordController.text);
_passwordController.addListener(() {
passwordNotifier.value = _passwordController.text;
});
}
void _login() { void _login() {
// Add your login logic here debugPrint("Login button clicked");
print("Login button clicked");
} }
void _ignoreButton() {}
@override @override
void dispose() { void dispose() {
_passwordController.dispose(); _passwordController.dispose();
passwordNotifier.dispose();
super.dispose(); super.dispose();
} }
@ -54,7 +63,7 @@ class _LoginPageState extends State<LoginPage> {
children: [ children: [
const Gap(88), const Gap(88),
const ImageWidget(imagePath: 'assets/logo.png', size: 100, measureByHeight: true), const ImageWidget(imagePath: 'assets/logo.png', size: 100, measureByHeight: true),
const Gap(50), const Gap(58),
BoxWidget( BoxWidget(
title: 'Login', title: 'Login',
content: Column( content: Column(
@ -63,12 +72,21 @@ class _LoginPageState extends State<LoginPage> {
const TextWidget(text: 'Name', bold: true, size: 16), const TextWidget(text: 'Name', bold: true, size: 16),
const Gap(8), const Gap(8),
TextWidget(text: _approver, bold: false, size: 16), TextWidget(text: _approver, bold: false, size: 16),
const Gap(8), const Gap(16),
const TextWidget(text: 'Password', bold: true, size: 16), const TextWidget(text: 'Password', bold: true, size: 16),
const Gap(8), const Gap(8),
InputWidget(controller: _passwordController, placeholder: 'placeholder'), InputWidget(controller: _passwordController, password: true),
const Gap(16), const Gap(24),
ButtonWidget(text: 'Login', onPressed: _login), ValueListenableBuilder<String>(
valueListenable: passwordNotifier,
builder: (context, password, child) {
return ButtonWidget(
text: password.isNotEmpty ? 'Login' : 'Required password',
onPressed: password.isNotEmpty ? _login : _ignoreButton,
disabled: password.isEmpty,
);
},
),
], ],
), ),
), ),

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:ocbo_esign_validator/widgets/text_widget.dart'; import 'package:ocbo_esign_validator/widgets/text_widget.dart';
@ -41,11 +42,16 @@ class _BarcodeScannerScreenState extends State<BarcodeScannerScreen> {
), ),
), ),
child: Center( child: Center(
child: Padding(
padding: const EdgeInsets.only(top: 64, left: 16, right: 16),
child: Column( child: Column(
children: [ children: [
Expanded( Expanded(
flex: 3, flex: 2,
child: ClipRRect(
borderRadius: BorderRadius.circular(20), // Adjust the radius as needed
child: MobileScanner( child: MobileScanner(
fit: BoxFit.cover,
onDetect: (BarcodeCapture capture) { onDetect: (BarcodeCapture capture) {
final List<Barcode> barcodes = capture.barcodes; final List<Barcode> barcodes = capture.barcodes;
if (barcodes.isNotEmpty && barcodes.first.rawValue != null) { if (barcodes.isNotEmpty && barcodes.first.rawValue != null) {
@ -56,74 +62,21 @@ class _BarcodeScannerScreenState extends State<BarcodeScannerScreen> {
}, },
), ),
), ),
),
Expanded( Expanded(
flex: 1, flex: 2,
child: Center( child: Column(
child: Center(child: TextWidget(text: barcodeResult, bold: false, size: 18)), children: [
Gap(20),
TextWidget(text: 'Scan OCBO e-Sign QR', size: 20, bold: true),
],
), ),
), ),
], ],
), ),
), ),
), ),
),
); );
} }
} }
// 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

@ -14,11 +14,11 @@ class BoxWidget extends StatelessWidget {
padding: EdgeInsets.all(16), padding: EdgeInsets.all(16),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
color: Color.fromARGB(149, 16, 22, 28), color: Color.fromRGBO(16, 22, 28, 0.584),
border: Border.all(color: const Color.fromRGBO(32, 47, 61, 1)), border: Border.all(color: const Color.fromRGBO(32, 47, 61, 1)),
), ),
width: MediaQuery.of(context).size.width - 100, width: MediaQuery.of(context).size.width - 30,
height: MediaQuery.of(context).size.height / 2.2, // height: MediaQuery.of(context).size.height / 2.2,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

View file

@ -1,35 +1,23 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:ocbo_esign_validator/widgets/text_widget.dart';
class ButtonWidget extends StatelessWidget { class ButtonWidget extends StatelessWidget {
final String text; final String text;
final VoidCallback onPressed; final VoidCallback? onPressed;
final bool? outline;
final double? width; final double? width;
final bool disabled;
const ButtonWidget({super.key, required this.text, required this.onPressed, this.outline, this.width}); const ButtonWidget({super.key, required this.text, this.onPressed, this.width, required this.disabled});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ElevatedButton( return ElevatedButton(
style: outline == true style: ElevatedButton.styleFrom(
? OutlinedButton.styleFrom( foregroundColor: const Color.fromRGBO(250, 250, 250, 1), // text color
foregroundColor: const Color.fromRGBO(0, 0, 0, 1), backgroundColor: disabled ? const Color.fromARGB(112, 13, 109, 253) : const Color(0xff0d6efd),
backgroundColor: Colors.transparent, elevation: disabled ? 0 : 4,
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( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), // rounded corners borderRadius: BorderRadius.circular(8), // rounded corners
), ),
minimumSize: Size( minimumSize: Size(
width ?? (MediaQuery.of(context).size.width <= 768 ? MediaQuery.of(context).size.width - 96 : 320), width ?? (MediaQuery.of(context).size.width <= 768 ? MediaQuery.of(context).size.width - 96 : 320),
@ -39,15 +27,7 @@ class ButtonWidget extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
), ),
onPressed: onPressed, onPressed: onPressed,
child: Text(text, style: _textStyle(outline)), child: TextWidget(text: text, size: 16),
); );
} }
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

@ -1,17 +1,20 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
class InputWidget extends StatelessWidget { class InputWidget extends StatelessWidget {
final TextEditingController controller; final TextEditingController controller;
final String placeholder; final String? placeholder;
final bool password;
const InputWidget({super.key, required this.controller, required this.placeholder}); const InputWidget({super.key, required this.controller, this.placeholder, required this.password});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return TextField( return TextField(
controller: controller, controller: controller,
obscureText: password,
enableSuggestions: !password,
autocorrect: !password,
decoration: InputDecoration( decoration: InputDecoration(
filled: true, filled: true,
fillColor: const Color.fromRGBO(255, 255, 255, 1), fillColor: const Color.fromRGBO(255, 255, 255, 1),

View file

@ -18,7 +18,7 @@ class MenuWidget extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
color: Color.fromARGB(149, 16, 22, 28), color: Color.fromARGB(149, 16, 22, 28),
border: Border.all(color: const Color(0xff202f3d)), border: Border.all(color: const Color.fromRGBO(32, 47, 61, 1)),
), ),
width: 120, width: 120,
height: 120, height: 120,

View file

@ -81,6 +81,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.11" version: "0.7.11"
dio:
dependency: "direct main"
description:
name: dio
sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9
url: "https://pub.dev"
source: hosted
version: "5.9.0"
dio_web_adapter:
dependency: transitive
description:
name: dio_web_adapter
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
equatable: equatable:
dependency: transitive dependency: transitive
description: description:
@ -240,6 +256,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.17.0" version: "1.17.0"
mime:
dependency: transitive
description:
name: mime
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
mobile_scanner: mobile_scanner:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -18,6 +18,7 @@ dependencies:
qr_flutter: ^4.1.0 qr_flutter: ^4.1.0
qr_code_scanner_plus: ^2.0.14 qr_code_scanner_plus: ^2.0.14
mobile_scanner: ^7.1.3 mobile_scanner: ^7.1.3
dio: ^5.9.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: