Compare commits

...

3 commits

Author SHA1 Message Date
5584af0fb7 Added bottom bar widget 2026-02-23 17:02:46 +08:00
4b6326dd95 Updated widget 2026-02-23 17:02:22 +08:00
57ea482f66 Updated pages 2026-02-23 17:01:57 +08:00
6 changed files with 152 additions and 81 deletions

View file

@ -1,6 +1,10 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gap/gap.dart'; import 'package:gap/gap.dart';
import 'package:ocbo_esign_mobile/blocs/user/functions/bloc_getuser.dart'; import 'package:ocbo_esign_mobile/blocs/user/functions/bloc_getuser.dart';
import 'package:ocbo_esign_mobile/functions/get_api.dart';
import 'package:ocbo_esign_mobile/widgets/box_widget.dart';
import 'package:ocbo_esign_mobile/widgets/image_widget.dart'; import 'package:ocbo_esign_mobile/widgets/image_widget.dart';
import 'package:ocbo_esign_mobile/widgets/text_widget.dart'; import 'package:ocbo_esign_mobile/widgets/text_widget.dart';
@ -13,14 +17,28 @@ class ApprovalPage extends StatefulWidget {
class _ApprovalPageState extends State<ApprovalPage> { class _ApprovalPageState extends State<ApprovalPage> {
late String blocUser = ''; late String blocUser = '';
late List<dynamic> _applicationList = [];
late List<dynamic> _nameList = [];
Future<String> _getUser() async { Future<String> _getUser() async {
final user = await blocGetUser(context); final user = await blocGetUser(context);
return user; return user;
} }
Future<void> _getListForApprovalElectrical() async {
final response = await getApi('get-listopapproval-electrical', null, null);
_applicationList = response["result"];
_nameList = response["result2"];
}
void _initUser() async { void _initUser() async {
blocUser = await _getUser(); final user = await _getUser();
await _getListForApprovalElectrical();
setState(() {
blocUser = user;
});
} }
@override @override
@ -52,18 +70,60 @@ class _ApprovalPageState extends State<ApprovalPage> {
child: Column( child: Column(
children: [ children: [
const Gap(76), const Gap(76),
Row( Column(
children: [ children: [
const Gap(16), BoxWidget(
const ImageWidget(imagePath: 'assets/logo.png', size: 32, measureByHeight: true), padding: const EdgeInsets.only(bottom: 8),
content: Center(
child: Column(
children: [
TextWidget(text: _applicationList.length.toString(), size: 32, bold: true),
const Gap(4),
const TextWidget(text: 'Ready to Sign and Approve Applications', size: 12, bold: false),
],
),
),
),
const Gap(8), const Gap(8),
TextWidget(text: blocUser, size: 16, bold: true), Expanded(
const MaxGap(80), flex: 1,
Icon(Icons.menu, size: 20, color: Colors.white), child: ListView.builder(
padding: EdgeInsets.only(bottom: 16),
itemCount: _applicationList.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
// onTap: () => _showDetails(_applicationList[index]),
child: BoxWidget(
alignment: CrossAxisAlignment.start,
circular: 16,
content: Row(
children: [
// const ImageWidget(imagePath: 'assets/esign-check.webp', size: 40, measureByHeight: true),
const Gap(16),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextWidget(text: _applicationList[index], size: 18, bold: true),
const Gap(4),
SizedBox(width: 180, child: TextWidget(text: _nameList[index], size: 10, opacity: 1)),
const Gap(4),
const TextWidget(text: 'Tap to show details', size: 9, opacity: 0.6),
],
),
],
),
),
);
},
),
),
// // TextWidget(text: blocUser, size: 16, bold: true),
// const MaxGap(80),
// Icon(Icons.menu, size: 20, color: Colors.white),
], ],
), ),
const Gap(32), // const Gap(32),
TextWidget(text: blocUser, size: 16, bold: true), // TextWidget(text: blocUser, size: 16, bold: true),
], ],
), ),
), ),

View file

@ -1,11 +1,13 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:gap/gap.dart'; import 'package:gap/gap.dart';
// import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
// import 'package:hashlib/hashlib.dart'; import 'package:hashlib/hashlib.dart';
// import 'package:ocbo_esign_mobile/blocs/user/functions/bloc_setuser.dart'; import 'package:ocbo_esign_mobile/blocs/user/functions/bloc_setuser.dart';
// import 'package:ocbo_esign_mobile/functions/get_api.dart'; import 'package:ocbo_esign_mobile/functions/get_api.dart';
// import 'package:ocbo_esign_mobile/functions/modal.dart'; import 'package:ocbo_esign_mobile/functions/modal.dart';
import 'package:ocbo_esign_mobile/widgets/button_widget.dart'; import 'package:ocbo_esign_mobile/widgets/button_widget.dart';
import 'package:ocbo_esign_mobile/widgets/image_widget.dart'; import 'package:ocbo_esign_mobile/widgets/image_widget.dart';
import 'package:ocbo_esign_mobile/widgets/input_widget.dart'; import 'package:ocbo_esign_mobile/widgets/input_widget.dart';
@ -22,7 +24,7 @@ class LoginPage extends StatefulWidget {
class _LoginPageState extends State<LoginPage> { class _LoginPageState extends State<LoginPage> {
final _passwordController = TextEditingController(); final _passwordController = TextEditingController();
final _approver = dotenv.env['HEAD']!; final _approver = dotenv.env['HEAD']!;
// final _approverId = dotenv.env['HEADID']!; final _approverId = dotenv.env['HEADID']!;
late ValueNotifier<String> passwordNotifier; late ValueNotifier<String> passwordNotifier;
@override @override
@ -34,58 +36,58 @@ class _LoginPageState extends State<LoginPage> {
}); });
} }
// Future<bool> _checkConnection() async { Future<bool> _checkConnection() async {
// try { try {
// final connection = await getApi('check-connection', null, null); final connection = await getApi('check-connection', null, null);
// return connection["result"]; return connection["result"];
// } catch (e) { } catch (e) {
// return false; return false;
// } }
// } }
// Future<String> _getPassword(String employeeid) async { Future<String> _getPassword(String employeeid) async {
// try { try {
// final response = await getApi('get-password', employeeid, null); final response = await getApi('get-password', employeeid, null);
// return (response["result"]); return (response["result"]);
// } catch (e) { } catch (e) {
// return "0"; return "0";
// } }
// } }
// Future<String> _securePassword(String password) async { Future<String> _securePassword(String password) async {
// final firstHash = sha1.string(password); final firstHash = sha1.string(password);
// final secondHash = sha384.string(firstHash.toString()); final secondHash = sha384.string(firstHash.toString());
// final thirdHash = sha1.string(secondHash.toString()); final thirdHash = sha1.string(secondHash.toString());
// return thirdHash.toString(); return thirdHash.toString();
// } }
// void _login() async { void _login() async {
// final connected = await _checkConnection(); final connected = await _checkConnection();
// if (connected) { if (connected) {
// final employeeid = _approverId; final employeeid = _approverId;
// final dbpassword = await _getPassword(employeeid); final dbpassword = await _getPassword(employeeid);
// final hashPassword = await _securePassword(_passwordController.text); final hashPassword = await _securePassword(_passwordController.text);
// if (context.mounted) { if (context.mounted) {
// if (dbpassword == hashPassword) { if (dbpassword == hashPassword) {
// _setLogin(); _setLogin();
// } else { } else {
// _showDialog(); _showDialog();
// } }
// } }
// } }
// } }
// void _setLogin() { void _setLogin() {
// blocSetUser(context, _approver); blocSetUser(context, _approver);
// context.push('/approval'); context.push('/approval');
// } }
// void _showDialog() { void _showDialog() {
// showModal(context, 'Error', 'Invalid password, try again.', true); showModal(context, 'Error', 'Invalid password, try again.', true);
// } }
void _ignoreButton() {} void _ignoreButton() {}
@ -135,28 +137,28 @@ class _LoginPageState extends State<LoginPage> {
InputWidget(controller: _passwordController, password: true), InputWidget(controller: _passwordController, password: true),
const Gap(24), const Gap(24),
// ValueListenableBuilder<String>(
// valueListenable: passwordNotifier,
// builder: (context, password, child) {
// return ButtonWidget(
// text: password.isNotEmpty ? 'Login' : 'Required password',
// onPressed: password.isNotEmpty ? _login : _ignoreButton,
// disabled: password.isEmpty,
// );
// },
// ),
ValueListenableBuilder<String>( ValueListenableBuilder<String>(
valueListenable: passwordNotifier, valueListenable: passwordNotifier,
builder: (context, password, child) { builder: (context, password, child) {
return ButtonWidget( return ButtonWidget(
text: _passwordController.text.isNotEmpty text: password.isNotEmpty ? 'Login' : 'Required password',
? "Stop typing, login not ready" onPressed: password.isNotEmpty ? _login : _ignoreButton,
: 'Not yet functional', disabled: password.isEmpty,
onPressed: _ignoreButton,
disabled: true,
); );
}, },
), ),
// ValueListenableBuilder<String>(
// valueListenable: passwordNotifier,
// builder: (context, password, child) {
// return ButtonWidget(
// text: _passwordController.text.isNotEmpty
// ? "Stop typing, login not ready"
// : 'Not yet functional',
// onPressed: _ignoreButton,
// disabled: true,
// );
// },
// ),
], ],
), ),
), ),

View file

@ -26,8 +26,8 @@ class BarcodeScannerScreen extends StatefulWidget {
} }
class _BarcodeScannerScreenState extends State<BarcodeScannerScreen> { class _BarcodeScannerScreenState extends State<BarcodeScannerScreen> {
final Color _redColorShade = const Color.fromRGBO(86, 38, 38, 0.2); final Color _redColorShade = const Color(0x33562626);
final Color _redColor = const Color.fromRGBO(235, 88, 115, 0.8); final Color _redColor = const Color(0xCCEB5873);
final Color _greenColorShade = const Color.fromRGBO(41, 115, 43, 0.2); final Color _greenColorShade = const Color.fromRGBO(41, 115, 43, 0.2);
final Color _greenColor = const Color.fromRGBO(76, 206, 81, 0.8); final Color _greenColor = const Color.fromRGBO(76, 206, 81, 0.8);
@ -61,7 +61,7 @@ class _BarcodeScannerScreenState extends State<BarcodeScannerScreen> {
_qrResult = 'invalid'; _qrResult = 'invalid';
}); });
Future.delayed(Duration(seconds: 3), () { Future.delayed(Duration(seconds: 8), () {
setState(() { setState(() {
_qrResult = ''; _qrResult = '';
}); });
@ -74,7 +74,7 @@ class _BarcodeScannerScreenState extends State<BarcodeScannerScreen> {
_scanning = true; _scanning = true;
}); });
final value = "Use OCBO e-Sign Validator - scanid=0918d59e"; final value = "Use OCBO e-Sig Validator - scanid=0918d59e";
if (value.contains('OCBO e-Sign')) { if (value.contains('OCBO e-Sign')) {
final qr = value.substring(35); final qr = value.substring(35);
@ -153,7 +153,7 @@ class _BarcodeScannerScreenState extends State<BarcodeScannerScreen> {
Container( Container(
padding: EdgeInsets.only(top: 8, bottom: 8, left: 20, right: 20), padding: EdgeInsets.only(top: 8, bottom: 8, left: 20, right: 20),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color.fromRGBO(9, 13, 16, 0.725), color: const Color.fromRGBO(9, 13, 16, 0.722),
borderRadius: BorderRadius.circular(32), borderRadius: BorderRadius.circular(32),
), ),
child: const TextWidget(text: 'Scan OCBO e-Sign QR Code', size: 14, bold: true), child: const TextWidget(text: 'Scan OCBO e-Sign QR Code', size: 14, bold: true),

View file

@ -13,8 +13,8 @@ class ButtonWidget extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ElevatedButton( return ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
foregroundColor: const Color.fromRGBO(250, 250, 250, 1), // text color foregroundColor: const Color.fromRGBO(250, 250, 250, 1),
backgroundColor: disabled ? const Color.fromARGB(112, 13, 109, 253) : const Color(0xff0d6efd), backgroundColor: disabled ? const Color.fromRGBO(13, 109, 253, 0.435) : const Color.fromRGBO(13, 109, 253, 0.8),
elevation: disabled ? 0 : 4, elevation: disabled ? 0 : 4,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8), // rounded corners borderRadius: BorderRadius.circular(8), // rounded corners

View file

@ -41,6 +41,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.2"
bottom_bar:
dependency: "direct main"
description:
name: bottom_bar
sha256: a2c96d8be21ab6173ac95bae3bcb2beb4c9a4cae7d82674f5551303986e121bf
url: "https://pub.dev"
source: hosted
version: "2.0.5"
characters: characters:
dependency: transitive dependency: transitive
description: description:

View file

@ -24,6 +24,7 @@ dependencies:
vibration: ^3.1.4 vibration: ^3.1.4
intl: ^0.20.2 intl: ^0.20.2
loading_animation_widget: ^1.3.0 loading_animation_widget: ^1.3.0
bottom_bar: ^2.0.5
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: