Business Login Flutter Apps
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

1772 linhas
89 KiB

  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:flutter/services.dart';
  5. import 'package:flutter/rendering.dart';
  6. import 'package:flutter/widgets.dart';
  7. import 'package:flutter_bloc/flutter_bloc.dart';
  8. import 'package:in_app_update/in_app_update.dart';
  9. import 'package:package_info/package_info.dart';
  10. import 'package:path/path.dart' as paths;
  11. import 'package:flutter/cupertino.dart';
  12. import 'package:flutter/material.dart';
  13. import 'package:path_provider/path_provider.dart';
  14. // import 'Util/download_Upload_Handler.dart';
  15. import 'package:intl/intl.dart';
  16. import 'package:unitstocks/Blocs/Cabang/cabang_bloc.dart';
  17. import 'package:unitstocks/Blocs/Logout/logout_bloc.dart';
  18. import 'package:unitstocks/Blocs/Stock_Taking/Restore/restore_bloc.dart';
  19. import '../main.dart';
  20. import '../Utils/keys.dart';
  21. // import 'Util/UnitModel.dart';
  22. import 'package:permission_handler/permission_handler.dart' as pHandler;
  23. import '../Blocs/Stock_Taking/State/load_state_bloc.dart';
  24. import '../Blocs/Stock_Taking/Unit/get_unit_bloc.dart';
  25. import '../Blocs/Stock_Taking/Clear/clear_data_bloc.dart';
  26. import 'package:pull_to_refresh/pull_to_refresh.dart';
  27. import '../Blocs/Stock_Taking/Backup/backup_bloc.dart';
  28. import '../Blocs/Stock_Taking/Send/upload_bloc.dart';
  29. import '../Blocs/Stock_Taking/Process/process_units_bloc.dart';
  30. import '../Blocs/Stock_Taking/Submit/submit_unit_bloc.dart';
  31. class HomePage extends StatefulWidget {
  32. const HomePage({Key? key}) : super(key: key);
  33. @override
  34. _HomePageState createState() => _HomePageState();
  35. }
  36. class _HomePageState extends State<HomePage> with RouteAware {
  37. StreamSubscription? progressDLStream, progressULStream;
  38. String lastDownload = '';
  39. String lastUpload = '';
  40. double? progressDL, progressUL;
  41. String timeString = '';
  42. bool isLoading = false;
  43. String? state = '';
  44. late LoadStateBloc _stateBloc;
  45. late GetUnitBloc _getDataBloc;
  46. late BackupBloc _backupBloc;
  47. late RestoreBloc _restoreBloc;
  48. late UploadBloc _uploadBloc;
  49. late ProcessUnitsBloc _processBloc;
  50. late SubmitUnitBloc _submitBloc;
  51. final hostAddress = new TextEditingController();
  52. final _refreshController = new RefreshController(initialRefresh: false);
  53. String currentVersion = '';
  54. clearData(contextParent)async{
  55. ClearDataBloc _clearBloc = ClearDataBloc();
  56. setState(() {
  57. progressDL = null;
  58. isLoading = false;
  59. });
  60. bool? result;
  61. await showDialog(
  62. context: contextParent,builder: (context)=>WillPopScope(
  63. onWillPop: ()async{
  64. Navigator.pop(context,false);
  65. return false;
  66. },
  67. child: BlocProvider<ClearDataBloc>(
  68. create: (context) => _clearBloc,
  69. child: BlocListener<ClearDataBloc, ClearDataState>(
  70. listener: (context, state) {
  71. setState(() {
  72. isLoading =(state is ClearDataLoading);
  73. });
  74. if(state is ClearDataFinish){
  75. result = state.cleared;
  76. if(result??false) {
  77. Navigator.pop(context);
  78. setState(() {
  79. lastDownload = "";
  80. });
  81. }
  82. util.showFlushbar(contextParent, state.msg,color: (result??false)?Colors.grey:Colors.red);
  83. }
  84. },
  85. child: AlertDialog(
  86. title: const Text('Clear Data ?'),
  87. content: const Text('Proceed to clear any remaining units data on this device?'),
  88. actions: <Widget>[
  89. TextButton(
  90. child: const Text('Proceed'),
  91. onPressed: ()async{
  92. _clearBloc.add(ClearDataInit());
  93. },
  94. ),
  95. TextButton(
  96. child: const Text('Cancel'),
  97. onPressed: (){Navigator.pop(context);},
  98. )
  99. ],
  100. ),
  101. ),
  102. ),
  103. ));
  104. return result??false;
  105. }
  106. @override
  107. void initState() {
  108. // TODO: implement initState
  109. super.initState();
  110. _stateBloc = LoadStateBloc();
  111. _getDataBloc = GetUnitBloc();
  112. _backupBloc = BackupBloc();
  113. _restoreBloc = RestoreBloc();
  114. _processBloc = ProcessUnitsBloc();
  115. _submitBloc = SubmitUnitBloc();
  116. _uploadBloc = UploadBloc();
  117. lastDownload = prefs.getString(Keys.lastDownload) ?? '';
  118. lastUpload = prefs.getString(Keys.lastUpload) ?? '';
  119. WidgetsBinding.instance!.addPostFrameCallback((_) async {
  120. await _check_Update();
  121. await util.permissionCheck(context,pHandler.Permission.storage,()async{print("storage permit granted!");},customMessage: " untuk menyimpan data backup");
  122. if(prefs.getString(Keys.stockId)!= null){
  123. _stateBloc.add(const LoadState());
  124. }
  125. });
  126. }
  127. _check_Update() async {
  128. if (defaultTargetPlatform == TargetPlatform.android) {
  129. try {
  130. final PackageInfo info = await PackageInfo.fromPlatform();
  131. AppUpdateInfo _updateInfo = await InAppUpdate.checkForUpdate();
  132. currentVersion = info.version.trim();
  133. String latestversion = '0.0.0';
  134. var result = await util.getMinAppVer();
  135. if (result['STATUS'] == 1) {
  136. latestversion = result['DATA'];
  137. }
  138. var current = currentVersion.split('.');
  139. var latest = latestversion.split('.');
  140. if (int.parse(current[0]) == int.parse(latest[0])) {
  141. if (int.parse(current[1]) == int.parse(latest[1])) {
  142. if (int.parse(current[2]) < int.parse(latest[2])) {
  143. await util.updateDialog(context);
  144. } else {
  145. if (_updateInfo.updateAvailability == 2) {
  146. await InAppUpdate.startFlexibleUpdate();
  147. await InAppUpdate.completeFlexibleUpdate();
  148. }
  149. }
  150. } else if (int.parse(current[1]) < int.parse(latest[1])) {
  151. await util.updateDialog(context);
  152. // await InAppUpdate.performImmediateUpdate();
  153. } else {
  154. if (_updateInfo.updateAvailability == 2) {
  155. await InAppUpdate.startFlexibleUpdate();
  156. await InAppUpdate.completeFlexibleUpdate();
  157. }
  158. }
  159. } else if (int.parse(current[0]) < int.parse(latest[0])) {
  160. await util.updateDialog(context);
  161. // await InAppUpdate.performImmediateUpdate();
  162. } else {
  163. if (_updateInfo.updateAvailability == 2) {
  164. await InAppUpdate.startFlexibleUpdate();
  165. await InAppUpdate.completeFlexibleUpdate();
  166. }
  167. }
  168. } catch (e) {
  169. print("error Update $e");
  170. }
  171. }
  172. }
  173. changeCabang(context) async {
  174. String selected = prefs.getString(Keys.cabangId) ?? '';
  175. return await showDialog(
  176. context: context,
  177. builder: (context) => StatefulBuilder(
  178. builder: (context, setState) => BlocProvider<CabangBloc>(
  179. create: (_) => CabangBloc(),
  180. child: BlocListener<CabangBloc, CabangState>(
  181. listener: (context, cabangState) async {
  182. if (cabangState is CabangFinished) {
  183. if (cabangState.cabangChanged) {
  184. setState(() {
  185. lastUpload = '';
  186. lastDownload = '';
  187. timeString = '';
  188. });
  189. }
  190. Navigator.pop(context, cabangState.cabangChanged);
  191. }
  192. },
  193. child: Material(
  194. color: Colors.white.withOpacity(0.9),
  195. child: BlocBuilder<CabangBloc, CabangState>(
  196. builder: (context, cabangState) {
  197. if (cabangState is CabangLoading) {
  198. return const Center(
  199. child: SizedBox(
  200. height: 10,
  201. width: 10,
  202. child: CircularProgressIndicator(),
  203. ),
  204. );
  205. } else if (cabangState is CabangInitial) {
  206. BlocProvider.of<CabangBloc>(context).add(CabangInit(
  207. userId: prefs.getString(Keys.loginId),
  208. company: prefs.getString(Keys.company)));
  209. } else if (cabangState is CabangDisplay) {
  210. selected = (selected == '')
  211. ? cabangState.cabangList[0]["RETURN_VALUE"]
  212. : selected;
  213. return Center(
  214. child: Container(
  215. decoration: BoxDecoration(
  216. color: Colors.white,
  217. boxShadow: [
  218. BoxShadow(
  219. color: Colors.grey.withOpacity(0.5),
  220. spreadRadius: 2,
  221. blurRadius: 2,
  222. offset: const Offset(
  223. 0, 0), // changes position of shadow
  224. ),
  225. ],
  226. borderRadius: BorderRadius.circular(5)),
  227. // height: MediaQuery.of(context).size.height/3.2,
  228. height: 220,
  229. width: MediaQuery.of(context).size.width * 0.75,
  230. child: Column(
  231. children: <Widget>[
  232. Flexible(
  233. flex: 3,
  234. child: Container(
  235. padding: const EdgeInsets.only(
  236. top: 10, left: 10, right: 10),
  237. alignment: Alignment.center,
  238. decoration: const BoxDecoration(
  239. borderRadius: BorderRadius.only(
  240. topLeft: Radius.circular(5),
  241. topRight: Radius.circular(5))),
  242. child: Column(
  243. mainAxisSize: MainAxisSize.min,
  244. crossAxisAlignment:
  245. CrossAxisAlignment.center,
  246. children: const <Widget>[
  247. Icon(
  248. Icons.business,
  249. size: 70,
  250. color: Colors.indigo,
  251. ),
  252. SizedBox(
  253. height: 5,
  254. ),
  255. Text(
  256. 'Set Cabang',
  257. style: TextStyle(
  258. fontWeight: FontWeight.bold,
  259. fontSize: 16,
  260. color: Colors.indigo),
  261. )
  262. ],
  263. ),
  264. ),
  265. ),
  266. Flexible(
  267. flex: 1,
  268. child: Container(
  269. padding: const EdgeInsets.only(
  270. left: 20, right: 20),
  271. alignment: Alignment.centerLeft,
  272. child: Theme(
  273. data: ThemeData(
  274. canvasColor: Colors.white,
  275. primaryColor: Colors.indigo,
  276. accentColor: Colors.indigo,
  277. hintColor: Colors.indigo),
  278. child: DropdownButtonFormField(
  279. style: TextStyle(
  280. color: Colors.black.withOpacity(0.6),
  281. fontWeight: FontWeight.w500,
  282. fontSize: 14,
  283. ),
  284. decoration: const InputDecoration(
  285. contentPadding: EdgeInsets.all(8.0),
  286. ),
  287. value: selected,
  288. onChanged: (value) {
  289. setState(() {
  290. selected = value.toString();
  291. });
  292. },
  293. items:
  294. cabangState.cabangList.map((item) {
  295. return DropdownMenuItem(
  296. value: item['RETURN_VALUE'],
  297. child: Text(
  298. (item["DISPLAY_VALUE"].length >
  299. 20)
  300. ? item["DISPLAY_VALUE"]
  301. .substring(0, 20) +
  302. "..."
  303. : item["DISPLAY_VALUE"]),
  304. );
  305. }).toList(),
  306. ),
  307. ),
  308. ),
  309. ),
  310. Flexible(
  311. flex: 1,
  312. child: Container(
  313. child: Row(
  314. mainAxisAlignment: MainAxisAlignment.end,
  315. children: <Widget>[
  316. TextButton(
  317. child: const Text(
  318. 'OK',
  319. style:
  320. TextStyle(color: Colors.indigo),
  321. ),
  322. onPressed: () async {
  323. BlocProvider.of<CabangBloc>(context)
  324. .add(CabangPicked(
  325. cabangId: selected));
  326. },
  327. ),
  328. ],
  329. ),
  330. ),
  331. )
  332. ],
  333. ),
  334. ),
  335. );
  336. } else if (cabangState is CabangError) {
  337. return Center(
  338. child: Container(
  339. decoration: BoxDecoration(
  340. color: Colors.white,
  341. boxShadow: [
  342. BoxShadow(
  343. color: Colors.grey.withOpacity(0.5),
  344. spreadRadius: 2,
  345. blurRadius: 2,
  346. offset: const Offset(
  347. 0, 0), // changes position of shadow
  348. ),
  349. ],
  350. borderRadius: BorderRadius.circular(5)),
  351. // height: MediaQuery.of(context).size.height/3.2,
  352. height: 220,
  353. width: MediaQuery.of(context).size.width * 0.75,
  354. child: Column(
  355. children: <Widget>[
  356. Flexible(
  357. flex: 3,
  358. child: Container(
  359. padding: const EdgeInsets.only(
  360. top: 10, left: 10, right: 10),
  361. alignment: Alignment.center,
  362. decoration: const BoxDecoration(
  363. borderRadius: BorderRadius.only(
  364. topLeft: Radius.circular(5),
  365. topRight: Radius.circular(5))),
  366. child: Column(
  367. mainAxisSize: MainAxisSize.min,
  368. crossAxisAlignment:
  369. CrossAxisAlignment.center,
  370. children: const <Widget>[
  371. Icon(
  372. Icons.business,
  373. size: 70,
  374. color: Colors.indigo,
  375. ),
  376. SizedBox(
  377. height: 5,
  378. ),
  379. Text(
  380. 'Error',
  381. style: TextStyle(
  382. fontWeight: FontWeight.bold,
  383. fontSize: 16,
  384. color: Colors.indigo),
  385. )
  386. ],
  387. ),
  388. ),
  389. ),
  390. Flexible(
  391. flex: 1,
  392. child: Container(
  393. padding: const EdgeInsets.only(
  394. left: 20, right: 20),
  395. alignment: Alignment.centerLeft,
  396. child: Theme(
  397. data: ThemeData(
  398. canvasColor: Colors.white,
  399. primaryColor: Colors.indigo,
  400. accentColor: Colors.indigo,
  401. hintColor: Colors.indigo),
  402. child: const Text(
  403. "Error menarik data list cabang!"),
  404. ),
  405. ),
  406. ),
  407. Flexible(
  408. flex: 1,
  409. child: Container(
  410. child: Row(
  411. mainAxisAlignment: MainAxisAlignment.end,
  412. children: <Widget>[
  413. TextButton(
  414. child: const Text(
  415. 'Retry',
  416. style:
  417. TextStyle(color: Colors.indigo),
  418. ),
  419. onPressed: () async {
  420. BlocProvider.of<CabangBloc>(context)
  421. .add(CabangInit(
  422. userId: prefs.getString(
  423. Keys.loginId),
  424. company: prefs.getString(
  425. Keys.company)));
  426. },
  427. ),
  428. ],
  429. ),
  430. ),
  431. )
  432. ],
  433. ),
  434. ),
  435. );
  436. }
  437. return Container();
  438. }),
  439. ),
  440. ),
  441. ),
  442. ));
  443. }
  444. @override
  445. Widget build(BuildContext context) {
  446. return WillPopScope(
  447. onWillPop: () async {
  448. await showDialog(
  449. context: context,
  450. builder: (context) => Material(
  451. color: Colors.white.withOpacity(0.9),
  452. child: Center(
  453. child: Container(
  454. decoration: BoxDecoration(
  455. color: Colors.white,
  456. boxShadow: [
  457. BoxShadow(
  458. color: Colors.grey.withOpacity(0.5),
  459. spreadRadius: 2,
  460. blurRadius: 2,
  461. offset: const Offset(0, 0), // changes position of shadow
  462. ),
  463. ],
  464. borderRadius: BorderRadius.circular(5)),
  465. // height: MediaQuery.of(context).size.height/4.8,
  466. height: 220,
  467. width: MediaQuery.of(context).size.width * 0.75,
  468. child: Column(
  469. children: <Widget>[
  470. Flexible(
  471. flex: 3,
  472. child: Container(
  473. padding: const EdgeInsets.only(top: 10, left: 10, right: 10),
  474. alignment: Alignment.center,
  475. decoration: const BoxDecoration(
  476. // color: Colors.indigo,
  477. borderRadius: BorderRadius.only(
  478. topLeft: const Radius.circular(5),
  479. topRight: Radius.circular(5))),
  480. child: Column(
  481. mainAxisSize: MainAxisSize.min,
  482. crossAxisAlignment: CrossAxisAlignment.center,
  483. children: <Widget>[
  484. const Icon(
  485. Icons.exit_to_app,
  486. size: 70,
  487. color: Colors.indigo,
  488. ),
  489. ],
  490. ),
  491. ),
  492. ),
  493. Flexible(
  494. flex: 1,
  495. child: Container(
  496. padding: const EdgeInsets.only(left: 20, right: 20),
  497. alignment: Alignment.centerLeft,
  498. child: Text(
  499. 'Keluar dari aplikasi?',
  500. style: TextStyle(
  501. fontWeight: FontWeight.w500,
  502. fontSize: 14,
  503. color: Colors.black.withOpacity(0.6)),
  504. )),
  505. ),
  506. Flexible(
  507. flex: 1,
  508. child: Container(
  509. padding: const EdgeInsets.only(bottom: 10),
  510. child: Row(
  511. mainAxisAlignment: MainAxisAlignment.end,
  512. children: <Widget>[
  513. TextButton(
  514. child: const Text(
  515. 'Exit',
  516. style: TextStyle(color: Colors.indigo),
  517. ),
  518. onPressed: () async {
  519. Navigator.pop(context);
  520. await locationStream?.cancel();
  521. exit(0);
  522. },
  523. ),
  524. TextButton(
  525. child: const Text(
  526. 'Cancel',
  527. style: TextStyle(color: Colors.indigo),
  528. ),
  529. onPressed: () {
  530. Navigator.pop(context);
  531. },
  532. )
  533. ],
  534. ),
  535. ),
  536. )
  537. ],
  538. ),
  539. ),
  540. ),
  541. ),
  542. );
  543. return false;
  544. },
  545. child: MultiBlocProvider(
  546. providers: [
  547. BlocProvider<LoadStateBloc>(
  548. create: (BuildContext context) => _stateBloc,
  549. ),
  550. BlocProvider<GetUnitBloc>(
  551. create: (BuildContext context) => _getDataBloc,
  552. ),
  553. BlocProvider<BackupBloc>(
  554. create: (BuildContext context) => _backupBloc,
  555. ),
  556. BlocProvider<RestoreBloc>(
  557. create: (BuildContext context) => _restoreBloc,
  558. ),
  559. BlocProvider<UploadBloc>(
  560. create: (BuildContext context) => _uploadBloc,
  561. ),
  562. BlocProvider<ProcessUnitsBloc>(
  563. create: (BuildContext context) => _processBloc,
  564. ),
  565. BlocProvider<SubmitUnitBloc>(
  566. create: (BuildContext context) => _submitBloc,
  567. ),
  568. ],
  569. child: MultiBlocListener(
  570. listeners: [
  571. BlocListener<GetUnitBloc,GetUnitState>(
  572. listener: (context,state){
  573. if(state is GetUnitLoading){
  574. setState(() {
  575. isLoading = true;
  576. progressDL= state.percent;
  577. });
  578. }
  579. else if(state is GetUnitFinish){
  580. setState(() {
  581. isLoading = false;
  582. progressDL= null;
  583. });
  584. if(state.success){
  585. setState(() {
  586. lastDownload = prefs.getString(Keys.lastDownload);
  587. });
  588. util.showFlushbar(context, state.respond);
  589. _stateBloc.add(const LoadState());
  590. }
  591. else util.showFlushbar(context, state.respond,color: Colors.red);
  592. }
  593. },
  594. ),
  595. BlocListener<LoadStateBloc,LoadStateState>(
  596. listener: (context,states){
  597. setState(() {
  598. isLoading = (states is StateLoading);
  599. });
  600. if(states is LoadFailed){
  601. util.showFlushbar(context, states.err,color: Colors.red);
  602. }
  603. else if(states is LoadSuccess){
  604. setState(() {
  605. state = states.state;
  606. });
  607. }
  608. },
  609. ),
  610. BlocListener<BackupBloc,BackupState>(
  611. listener: (context,state){
  612. setState(() {
  613. isLoading = (state is BackupLoading);
  614. });
  615. if(state is BackupFinish){
  616. util.showFlushbar(context, state.msg,color: state.success?Colors.grey:Colors.red);
  617. }
  618. },
  619. ),
  620. BlocListener<RestoreBloc,RestoreState>(
  621. listener: (context,state){
  622. setState(() {
  623. isLoading = (state is RestoreLoading);
  624. });
  625. if(state is RestoreFinish){
  626. util.showFlushbar(context, state.msg,color: state.success?Colors.grey:Colors.red);
  627. setState(() {
  628. lastDownload = prefs.getString(Keys.lastDownload);
  629. });
  630. _stateBloc.add(const LoadState());
  631. }
  632. },
  633. ),
  634. BlocListener<UploadBloc,UploadState>(
  635. listener: (context,state){
  636. setState(() {
  637. isLoading = (state is UploadLoading);
  638. });
  639. if(state is UploadFinish){
  640. util.showFlushbar(context, state.msg,color: state.success?Colors.grey:Colors.red);
  641. if(state.success){
  642. setState(() {
  643. lastUpload = prefs.getString(Keys.lastUpload);
  644. });
  645. }
  646. _stateBloc.add(const LoadState());
  647. }
  648. },
  649. ),
  650. BlocListener<ProcessUnitsBloc,ProcessUnitsState>(
  651. listener: (context,state){
  652. setState(() {
  653. isLoading = (state is ProcessLoading);
  654. });
  655. if(state is ProcessLoading){
  656. util.showLoading(context);
  657. }
  658. else if(state is ProcessFinish){
  659. Navigator.pop(context);
  660. util.showFlushbar(context, state.msg,color: state.success?Colors.grey:Colors.red);
  661. _stateBloc.add(const LoadState());
  662. }
  663. },
  664. ),
  665. BlocListener<SubmitUnitBloc,SubmitUnitState>(
  666. listener: (context,state){
  667. setState(() {
  668. isLoading = (state is SubmitLoading);
  669. });
  670. if(state is SubmitLoading){
  671. util.showLoading(context);
  672. }
  673. else if(state is SubmitFinish){
  674. Navigator.pop(context);
  675. util.showFlushbar(context, state.msg,color: state.success?Colors.grey:Colors.red);
  676. _stateBloc.add(const LoadState());
  677. }
  678. },
  679. )
  680. ],
  681. child: Scaffold(
  682. body: Column(
  683. crossAxisAlignment: CrossAxisAlignment.end,
  684. children: <Widget>[
  685. Container(
  686. padding: const EdgeInsets.only(bottom: 0, left: 15, right: 10, top: 10),
  687. height: MediaQuery.of(context).size.height / 13,
  688. width: MediaQuery.of(context).size.width,
  689. alignment: Alignment.bottomLeft,
  690. child: Row(
  691. crossAxisAlignment: CrossAxisAlignment.end,
  692. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  693. children: <Widget>[
  694. Text(
  695. 'Home',
  696. style: TextStyle(
  697. color: Colors.indigo.withOpacity(0.8),
  698. fontSize: 18,
  699. fontWeight: FontWeight.bold),
  700. ),
  701. PopupMenuButton(
  702. enabled: !isLoading,
  703. child: Padding(
  704. padding: const EdgeInsets.only(right: 2.0),
  705. child: Icon(
  706. Icons.menu,
  707. color: Colors.indigo.withOpacity(0.8),
  708. ),
  709. ),
  710. itemBuilder: (context) {
  711. return [
  712. // PopupMenuItem(
  713. // value:'hostChange',
  714. // child: Row(
  715. // children: <Widget>[
  716. // Icon(Icons.network_wifi,color: Colors.black,),
  717. // SizedBox(width: 10,),
  718. // Text('Change Ip Address')
  719. // ],
  720. // ),
  721. // ),
  722. PopupMenuItem(
  723. value: 'cabangChange',
  724. child: Row(
  725. children: const <Widget>[
  726. Icon(
  727. Icons.business,
  728. color: Colors.black,
  729. ),
  730. SizedBox(
  731. width: 10,
  732. ),
  733. Text('Change Cabang')
  734. ],
  735. ),
  736. ),
  737. PopupMenuItem(
  738. value:'backup',
  739. child: Row(
  740. children: <Widget>[
  741. const Icon(Icons.save,color: Colors.black,),
  742. const SizedBox(width: 10,),
  743. const Text('Backup Data')
  744. ],
  745. ),
  746. ),
  747. PopupMenuItem(
  748. value: 'restore',
  749. child: Row(
  750. children: const <Widget>[
  751. Icon(
  752. Icons.sync,
  753. color: Colors.black,
  754. ),
  755. SizedBox(
  756. width: 10,
  757. ),
  758. Text('Restore Backup')
  759. ],
  760. ),
  761. ),
  762. PopupMenuItem(
  763. value: 'logout',
  764. child: Row(
  765. children: const <Widget>[
  766. Icon(
  767. Icons.exit_to_app,
  768. color: Colors.black,
  769. ),
  770. SizedBox(
  771. width: 10,
  772. ),
  773. Text('Logout')
  774. ],
  775. ),
  776. ),
  777. ];
  778. },
  779. onSelected: (value) async {
  780. // if(value == 'hostChange'){
  781. // hostAddress.text = prefs.getString(Keys.hostAddress);
  782. // await showDialog(context: context,builder: (context)=>
  783. // Material(
  784. // color: Colors.white.withOpacity(0.9),
  785. // child: Center(
  786. // child: Container(
  787. // decoration: BoxDecoration(
  788. // color: Colors.white,
  789. // boxShadow: [
  790. // BoxShadow(
  791. // color: Colors.grey.withOpacity(0.5),
  792. // spreadRadius: 2,
  793. // blurRadius: 2,
  794. // offset: Offset(0, 0), // changes position of shadow
  795. // ),
  796. // ],
  797. // borderRadius: BorderRadius.circular(5)
  798. // ),
  799. // height:220,
  800. // // height: MediaQuery.of(context).size.height/3.2,
  801. // width: MediaQuery.of(context).size.width*0.75,
  802. // child: Column(
  803. // children: <Widget>[
  804. // Flexible(
  805. // flex:3,
  806. // child: Container(
  807. // padding: EdgeInsets.only(top:10,left: 10,right: 10),
  808. // alignment: Alignment.center,
  809. // decoration: BoxDecoration(
  810. // // color: Colors.indigo,
  811. // borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5))
  812. // ),
  813. // child: Column(
  814. // mainAxisSize: MainAxisSize.min,
  815. // crossAxisAlignment: CrossAxisAlignment.center,
  816. // children: <Widget>[
  817. // Icon(Icons.network_wifi,size: 70,color: Colors.indigo,),
  818. // SizedBox(height: 5,),
  819. // Text('Set Ip Address',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16,color: Colors.indigo),)
  820. // ],
  821. // ),
  822. // ),
  823. // ),
  824. // Flexible(
  825. // flex: 1,
  826. // child: Container(
  827. // padding: EdgeInsets.only(left: 20,right: 20),
  828. // alignment: Alignment.centerLeft,
  829. // child: Theme(
  830. // data: ThemeData(
  831. // canvasColor: Colors.white,
  832. // primaryColor: Colors.indigo,
  833. // accentColor: Colors.indigo,
  834. // hintColor: Colors.indigo
  835. // ),
  836. // child: TextField(
  837. // controller: hostAddress,
  838. // decoration: const InputDecoration(
  839. // contentPadding: EdgeInsets.all(8),
  840. // ),
  841. // onSubmitted: (value){
  842. // prefs.setString(Keys.hostAddress,(value=='')?'https://tbg.thamringroup.web.id/ords/tbs/unit/v1':value);
  843. // Navigator.pop(context);
  844. // },
  845. // ),
  846. // ),
  847. // ),
  848. // ),
  849. // Flexible(
  850. // flex: 1,
  851. // child: Container(
  852. // child: Row(
  853. // mainAxisAlignment: MainAxisAlignment.end,
  854. // children: <Widget>[
  855. // TextButton(
  856. // child: Text('OK',style: TextStyle(color: Colors.indigo),),
  857. // onPressed: (){
  858. // prefs.setString(Keys.hostAddress,(hostAddress.text=='')?'https://tbg.thamringroup.web.id/ords/tbs/unit/v1':hostAddress.text);
  859. // Navigator.pop(context);
  860. // },
  861. // )
  862. // ],
  863. // ),
  864. // ),
  865. // )
  866. // ],
  867. // ),
  868. // ),
  869. // ),
  870. // )
  871. // );
  872. // }
  873. if (value == "cabangChange") {
  874. var res = await changeCabang(context);
  875. if (res ?? false) {
  876. setState(() {});
  877. }
  878. }
  879. if (value == 'logout') {
  880. await showDialog(
  881. context: context,
  882. builder: (context) => Material(
  883. color: Colors.white.withOpacity(0.9),
  884. child: BlocProvider(
  885. create: (_) => LogoutBloc(),
  886. child: Center(
  887. child: Container(
  888. decoration: BoxDecoration(
  889. color: Colors.white,
  890. boxShadow: [
  891. BoxShadow(
  892. color: Colors.grey
  893. .withOpacity(0.5),
  894. spreadRadius: 2,
  895. blurRadius: 2,
  896. offset: const Offset(0,
  897. 0), // changes position of shadow
  898. ),
  899. ],
  900. borderRadius:
  901. BorderRadius.circular(5)),
  902. height: 220,
  903. // height: MediaQuery.of(context).size.height/3.2,
  904. width:
  905. MediaQuery.of(context).size.width *
  906. 0.75,
  907. child: BlocBuilder<LogoutBloc,
  908. LogoutState>(
  909. bloc: LogoutBloc(),
  910. builder: (context, state) {
  911. final blocLogout =
  912. BlocProvider.of<LogoutBloc>(
  913. context);
  914. if (state is LogoutLoading) {
  915. return const Center(
  916. child: SizedBox(
  917. height: 10,
  918. width: 10,
  919. child:
  920. CircularProgressIndicator(),
  921. ),
  922. );
  923. }
  924. return Column(
  925. children: <Widget>[
  926. Flexible(
  927. flex: 3,
  928. child: Container(
  929. padding: const EdgeInsets.only(
  930. top: 10,
  931. left: 10,
  932. right: 10),
  933. alignment: Alignment.center,
  934. decoration: const BoxDecoration(
  935. borderRadius:
  936. BorderRadius.only(
  937. topLeft: Radius
  938. .circular(
  939. 5),
  940. topRight: Radius
  941. .circular(
  942. 5))),
  943. child: Column(
  944. mainAxisSize:
  945. MainAxisSize.min,
  946. crossAxisAlignment:
  947. CrossAxisAlignment
  948. .center,
  949. children: const <Widget>[
  950. Icon(
  951. Icons.logout,
  952. size: 70,
  953. color: Colors.indigo,
  954. ),
  955. SizedBox(
  956. height: 5,
  957. ),
  958. Text(
  959. 'Logout',
  960. style: TextStyle(
  961. fontWeight:
  962. FontWeight
  963. .bold,
  964. fontSize: 16,
  965. color: Colors
  966. .indigo),
  967. )
  968. ],
  969. ),
  970. ),
  971. ),
  972. Flexible(
  973. flex: 1,
  974. child: Container(
  975. padding: const EdgeInsets.only(
  976. left: 20, right: 20),
  977. alignment:
  978. Alignment.centerLeft,
  979. child: const Text(
  980. "Kembali ke halaman login?"),
  981. ),
  982. ),
  983. Flexible(
  984. flex: 1,
  985. child: Container(
  986. child: Row(
  987. mainAxisAlignment:
  988. MainAxisAlignment.end,
  989. children: <Widget>[
  990. TextButton(
  991. child: const Text(
  992. 'Logout',
  993. style: TextStyle(
  994. color: Colors
  995. .indigo),
  996. ),
  997. onPressed: () {
  998. blocLogout.add(
  999. LogoutInitiate(
  1000. context:
  1001. context));
  1002. },
  1003. ),
  1004. TextButton(
  1005. child: const Text(
  1006. 'Cancel',
  1007. style: TextStyle(
  1008. color: Colors
  1009. .indigo),
  1010. ),
  1011. onPressed: () {
  1012. Navigator.pop(context);
  1013. },
  1014. )
  1015. ],
  1016. ),
  1017. ),
  1018. )
  1019. ],
  1020. );
  1021. },
  1022. ),
  1023. ),
  1024. ),
  1025. ),
  1026. ));
  1027. }
  1028. if(value == 'backup'){
  1029. if(lastDownload != null && lastDownload != '' ){
  1030. bool? isBackup = await showDialog(context: context,builder: (context)=>AlertDialog(
  1031. title: const Text('Backup Data ?'),
  1032. content: const Text('Backup data akan menghapus dan mengganti data backup unit dan cabang sebelumnya.'),
  1033. actions: <Widget>[
  1034. TextButton(
  1035. child: const Text('OK'),
  1036. onPressed: ()async{
  1037. Navigator.pop(context,true);
  1038. },
  1039. ),
  1040. TextButton(
  1041. child: const Text('Cancel'),
  1042. onPressed: ()=>Navigator.pop(context,false),
  1043. )
  1044. ],
  1045. ));
  1046. if(isBackup??false){
  1047. _backupBloc.add(BackupInit(context: context));
  1048. }
  1049. }
  1050. else{
  1051. util.showFlushbar(context, "Data Unit cabang tidak ditemukan. Silakan get data terlbih dahulu.");
  1052. }
  1053. }
  1054. if(value == 'restore'){
  1055. if(prefs.getString(Keys.stockId) == null){
  1056. util.showFlushbar(context, "Data Unit cabang tidak ditemukan. Silakan get data terlbih dahulu.");
  1057. }
  1058. else{
  1059. if(prefs.getString(Keys.stockId) == prefs.getString(Keys.backupStockId)){
  1060. // _stateBloc.add(LoadState());
  1061. // state di load waktu get data
  1062. if(['Open','Submitted'].contains(state)){
  1063. bool? isRestore = await showDialog(context: context,builder: (context)=>AlertDialog(
  1064. title: const Text('Restore Data ?'),
  1065. content: const Text('Restore data akan menghapus dan mengganti data unit dan cabang yang ada dengan data backup.'),
  1066. actions: <Widget>[
  1067. TextButton(
  1068. child: const Text('OK'),
  1069. onPressed: ()async{
  1070. Navigator.pop(context,true);
  1071. },
  1072. ),
  1073. TextButton(
  1074. child: const Text('Cancel'),
  1075. onPressed: ()=>Navigator.pop(context,false),
  1076. )
  1077. ],
  1078. ));
  1079. if(isRestore??false){
  1080. bool? isclear;
  1081. // check exist
  1082. Directory? documentsDirectory = await getExternalStorageDirectory();
  1083. String path = paths.join(documentsDirectory!.path, "UnitStocking.db");
  1084. File db = File(path);
  1085. if(db.existsSync()){
  1086. isclear = await clearData(context);
  1087. }
  1088. else{
  1089. isclear = true;
  1090. }
  1091. if(isclear??false){
  1092. _restoreBloc.add(RestoreInit(context: context));
  1093. }
  1094. }
  1095. }
  1096. else{
  1097. util.showFlushbar(context, "Stocking Unit sudah selesai dan tidak perlu di restore");
  1098. }
  1099. }
  1100. else {
  1101. util.showFlushbar(context, "File Backup tidak ditemukan atau sudah selesai");
  1102. }
  1103. }
  1104. }
  1105. // if (value == 'restore') {
  1106. // await showDialog(context: context,builder: (context)=>BlocProvider<RestoreBloc>(
  1107. // create: (_)=>RestoreBloc(),
  1108. // child: BlocBuilder<RestoreBloc,RestoreState>(
  1109. // builder: (context,restoreState) {
  1110. // if(restoreState is RestoreLoading){
  1111. // return const Center(
  1112. // child: SizedBox(
  1113. // height: 10,
  1114. // width: 10,
  1115. // child:
  1116. // CircularProgressIndicator(),
  1117. // ),
  1118. // );
  1119. // }
  1120. // else if(restoreState is RestoreSuccess){
  1121. // Navigator.pop(context);
  1122. // setState(() {
  1123. // lastUpload = '';
  1124. // lastDownload = '';
  1125. // timeString = '';
  1126. // });
  1127. // }
  1128. // return AlertDialog(
  1129. // title: Text((restoreState is RestoreFailed)?"Error":'Restore Data ?'),
  1130. // content: Text((restoreState is RestoreFailed)?"${restoreState.err}. Ulangi?":'Restore data akan menghapus dan mengganti data unit yang ada dengan data unit backup.'),
  1131. // actions: <Widget>[
  1132. // TextButton(
  1133. // child: const Text('OK'),
  1134. // onPressed: ()async{
  1135. // BlocProvider.of<RestoreBloc>(context).add(const RestoreInit());
  1136. // },
  1137. // ),
  1138. // TextButton(
  1139. // child: const Text('Batal'),
  1140. // onPressed: ()=>Navigator.pop(context),
  1141. // )
  1142. // ],
  1143. // );
  1144. // }
  1145. // ),
  1146. // ));
  1147. // }
  1148. },
  1149. ),
  1150. ],
  1151. ),
  1152. ),
  1153. (prefs.getString(Keys.stockId) == null)
  1154. ? Container()
  1155. : Padding(
  1156. padding: const EdgeInsets.only(top: 8, right: 8),
  1157. child: Container(
  1158. decoration: BoxDecoration(
  1159. color: Colors.indigo.withOpacity(0.9),
  1160. borderRadius: BorderRadius.circular(8)
  1161. // border: Border.all(),
  1162. ),
  1163. padding: const EdgeInsets.all(8),
  1164. child: Row(
  1165. mainAxisSize: MainAxisSize.min,
  1166. mainAxisAlignment: MainAxisAlignment.end,
  1167. crossAxisAlignment: CrossAxisAlignment.center,
  1168. children: <Widget>[
  1169. const Text(
  1170. 'Status : ',
  1171. style: TextStyle(color: Colors.white),
  1172. ),
  1173. Text(
  1174. state ?? '-',
  1175. style: const TextStyle(
  1176. fontWeight: FontWeight.bold,
  1177. color: Colors.white),
  1178. ),
  1179. ],
  1180. ),
  1181. ),
  1182. ),
  1183. Expanded(
  1184. child: Container(
  1185. child:
  1186. SmartRefresher(
  1187. controller: _refreshController,
  1188. enablePullDown: !(isLoading),
  1189. onRefresh: (){
  1190. if(prefs.getString(Keys.stockId)!= null){
  1191. _stateBloc.add(const LoadState());
  1192. }
  1193. else {
  1194. util.showFlushbar(context, "Silakan tarik data unit terlebih dulu");
  1195. }
  1196. _refreshController.refreshCompleted();
  1197. },
  1198. child: GridView.count(
  1199. padding: const EdgeInsets.all(10),
  1200. crossAxisSpacing: 10,
  1201. mainAxisSpacing: 10,
  1202. crossAxisCount: 2,
  1203. children: <Widget>[
  1204. AbsorbPointer(
  1205. absorbing: isLoading,
  1206. child: InkWell(
  1207. splashColor: Colors.black,
  1208. onTap: () async {
  1209. bool? getData = await showDialog(
  1210. context: context,
  1211. builder: (context)=>AlertDialog(
  1212. title: const Text("Get Data Units?"),
  1213. content: const Text('Fetch data unit for stocking'),
  1214. actions: <Widget>[
  1215. TextButton(
  1216. child: const Text('Proceed'),
  1217. onPressed: (){
  1218. Navigator.pop(context,true);
  1219. },
  1220. ),
  1221. TextButton(
  1222. child: const Text('Cancel'),
  1223. onPressed: (){
  1224. Navigator.pop(context,false);
  1225. },
  1226. )
  1227. ],
  1228. )
  1229. );
  1230. if(getData??false){
  1231. setState(() {
  1232. isLoading = true;
  1233. });
  1234. // var a = Stopwatch();
  1235. // a.start();
  1236. await Future.delayed(const Duration(milliseconds: 200));
  1237. bool? isclear;
  1238. Directory? documentsDirectory = await getExternalStorageDirectory();
  1239. String path = paths.join(documentsDirectory!.path, "UnitStocking.db");
  1240. File db = File(path);
  1241. if(db.existsSync()){
  1242. isclear = await clearData(context);
  1243. }
  1244. else{
  1245. isclear = true;
  1246. }
  1247. if(isclear??false){
  1248. _getDataBloc.add(GetUnitInit());
  1249. }
  1250. }
  1251. },
  1252. child: Container(
  1253. padding: const EdgeInsets.all(5),
  1254. decoration: BoxDecoration(
  1255. boxShadow: [
  1256. BoxShadow(
  1257. color: Colors.grey.withOpacity(0.5),
  1258. spreadRadius: 2,
  1259. blurRadius: 2,
  1260. offset:
  1261. const Offset(0, 0), // changes position of shadow
  1262. ),
  1263. ],
  1264. borderRadius: const BorderRadius.all(const Radius.circular(5.0)),
  1265. color: Colors.green.withAlpha(220).withOpacity(0.7),
  1266. ),
  1267. child: Stack(
  1268. children: <Widget>[
  1269. Container(
  1270. alignment: (progressDL != null)
  1271. ? Alignment.bottomCenter
  1272. : Alignment.bottomLeft,
  1273. padding: const EdgeInsets.only(
  1274. left: 10, right: 10, top: 10, bottom: 15),
  1275. child: (progressDL != null)
  1276. ? Column(
  1277. mainAxisSize: MainAxisSize.min,
  1278. children: <Widget>[
  1279. LinearProgressIndicator(
  1280. value: progressDL,
  1281. ),
  1282. Text(
  1283. '${(progressDL! * 100).floor()}%',
  1284. style: const TextStyle(
  1285. color: Colors.white,
  1286. fontWeight: FontWeight.bold),
  1287. )
  1288. ],
  1289. )
  1290. : (lastDownload == '')
  1291. ? null
  1292. : Text(
  1293. 'Last download : ${DateFormat('dd MMM yyyy HH:mm').format(DateTime.parse(lastDownload))}',
  1294. style: const TextStyle(
  1295. color: Colors.white,
  1296. fontSize: 11,
  1297. fontWeight: FontWeight.bold)),
  1298. ),
  1299. Positioned.fill(
  1300. child: Column(
  1301. mainAxisAlignment: MainAxisAlignment.center,
  1302. children: <Widget>[
  1303. Icon(
  1304. Icons.file_upload,
  1305. size: MediaQuery.of(context).size.width / 6,
  1306. color: Colors.white,
  1307. ),
  1308. const SizedBox(
  1309. height: 5,
  1310. ),
  1311. const Text(
  1312. 'Get Data Master',
  1313. style: TextStyle(
  1314. color: Colors.white,
  1315. fontWeight: FontWeight.bold,
  1316. fontSize: 16),
  1317. ),
  1318. ],
  1319. ),
  1320. ),
  1321. ],
  1322. ),
  1323. ),
  1324. ),
  1325. ),
  1326. InkWell(
  1327. splashColor: Colors.black,
  1328. onTap: () async {
  1329. await Future.delayed(const Duration(milliseconds: 200));
  1330. if (lastDownload != '') {
  1331. Navigator.pushNamed(context, '/units');
  1332. } else {
  1333. util.showFlushbar(context,
  1334. 'Data Master tidak ditemukan. Get data master dulu.');
  1335. }
  1336. },
  1337. child: Container(
  1338. padding: const EdgeInsets.all(5),
  1339. decoration: BoxDecoration(
  1340. boxShadow: [
  1341. BoxShadow(
  1342. color: Colors.grey.withOpacity(0.5),
  1343. spreadRadius: 2,
  1344. blurRadius: 2,
  1345. offset: const Offset(0, 0), // changes position of shadow
  1346. ),
  1347. ],
  1348. borderRadius: const BorderRadius.all(const Radius.circular(5.0)),
  1349. color: Colors.blueGrey.withAlpha(230).withOpacity(0.8),
  1350. ),
  1351. child: Column(
  1352. mainAxisAlignment: MainAxisAlignment.center,
  1353. children: <Widget>[
  1354. Icon(
  1355. Icons.receipt,
  1356. size: MediaQuery.of(context).size.width / 6,
  1357. color: Colors.white,
  1358. ),
  1359. const SizedBox(
  1360. height: 5,
  1361. ),
  1362. const Text(
  1363. 'Stocking',
  1364. style: TextStyle(
  1365. color: Colors.white,
  1366. fontWeight: FontWeight.bold,
  1367. fontSize: 16),
  1368. )
  1369. ],
  1370. ),
  1371. ),
  1372. ),
  1373. InkWell(
  1374. splashColor: Colors.black,
  1375. onTap: () async {
  1376. _uploadBloc.add(Upload(context: context));
  1377. },
  1378. child: Container(
  1379. padding: const EdgeInsets.all(5),
  1380. decoration: BoxDecoration(
  1381. boxShadow: [
  1382. BoxShadow(
  1383. color: Colors.grey.withOpacity(0.5),
  1384. spreadRadius: 2,
  1385. blurRadius: 2,
  1386. offset: const Offset(0, 0), // changes position of shadow
  1387. ),
  1388. ],
  1389. borderRadius: const BorderRadius.all(const Radius.circular(5.0)),
  1390. color: Colors.indigo.withAlpha(220).withOpacity(0.7),
  1391. ),
  1392. child: Stack(
  1393. children: [
  1394. BlocBuilder(
  1395. bloc: _uploadBloc,
  1396. builder: (context, state){
  1397. if(state is UploadLoading){
  1398. return Column(
  1399. mainAxisSize: MainAxisSize.min,
  1400. children: <Widget>[
  1401. LinearProgressIndicator(
  1402. value: progressUL,
  1403. ),
  1404. Text(
  1405. '${(progressUL ?? 0 * 100).floor()}%',
  1406. style: const TextStyle(
  1407. color: Colors.white,
  1408. fontWeight: FontWeight.bold),
  1409. )
  1410. ],
  1411. );
  1412. }
  1413. if(lastUpload != ''){
  1414. return Positioned.fill(
  1415. child: Container(
  1416. alignment: Alignment.bottomCenter,
  1417. child: Text(
  1418. 'Last upload : ${DateFormat('dd MMM yyyy HH:mm').format(DateTime.parse(lastUpload))}\n${(timeString != '') ? 'Duration: $timeString' : ''}',
  1419. style: const TextStyle(
  1420. color: Colors.white,
  1421. fontSize: 11,
  1422. fontWeight: FontWeight.bold)),
  1423. ),
  1424. );
  1425. }
  1426. return Container();
  1427. }),
  1428. Positioned.fill(
  1429. child: Column(
  1430. mainAxisAlignment: MainAxisAlignment.center,
  1431. children: <Widget>[
  1432. Icon(
  1433. Icons.file_upload,
  1434. size: MediaQuery.of(context).size.width / 6,
  1435. color: Colors.white,
  1436. ),
  1437. const SizedBox(
  1438. height: 5,
  1439. ),
  1440. const Text(
  1441. 'Send Data Stokan',
  1442. style: TextStyle(
  1443. color: Colors.white,
  1444. fontWeight: FontWeight.bold,
  1445. fontSize: 16),
  1446. ),
  1447. ],
  1448. ),
  1449. ),
  1450. ],
  1451. ),
  1452. ),
  1453. ),
  1454. (prefs.getString(Keys.targetProccess) == null &&
  1455. prefs.getBool(Keys.submitProccess) == null)
  1456. ? InkWell(
  1457. splashColor: Colors.black,
  1458. onTap: () async {
  1459. await Future.delayed(const Duration(milliseconds: 200));
  1460. await clearData(context);
  1461. },
  1462. child: Container(
  1463. padding: const EdgeInsets.all(5),
  1464. decoration: BoxDecoration(
  1465. boxShadow: [
  1466. BoxShadow(
  1467. color: Colors.grey.withOpacity(0.5),
  1468. spreadRadius: 2,
  1469. blurRadius: 2,
  1470. offset: const Offset(
  1471. 0, 0), // changes position of shadow
  1472. ),
  1473. ],
  1474. borderRadius:
  1475. const BorderRadius.all(Radius.circular(5.0)),
  1476. color: Colors.red.withAlpha(200).withOpacity(0.7),
  1477. ),
  1478. child: Column(
  1479. mainAxisAlignment: MainAxisAlignment.center,
  1480. children: <Widget>[
  1481. Icon(
  1482. Icons.restore_from_trash,
  1483. size: MediaQuery.of(context).size.width / 6,
  1484. color: Colors.white,
  1485. ),
  1486. const SizedBox(
  1487. height: 5,
  1488. ),
  1489. const Text(
  1490. 'Clear Data',
  1491. style: const TextStyle(
  1492. color: Colors.white,
  1493. fontWeight: FontWeight.bold,
  1494. fontSize: 16),
  1495. )
  1496. ],
  1497. ),
  1498. ),
  1499. )
  1500. : (prefs.getString(Keys.targetProccess) != null)
  1501. ? InkWell(
  1502. onTap: () async {
  1503. bool result = await showDialog(
  1504. context: context,
  1505. builder: (context) => WillPopScope(
  1506. onWillPop: () async {
  1507. Navigator.pop(context, false);
  1508. return false;
  1509. },
  1510. child: AlertDialog(
  1511. title: const Text('Process Data ?'),
  1512. content: const Text(
  1513. 'Proceed to unpack the uploaded data.'),
  1514. actions: <Widget>[
  1515. TextButton(
  1516. child: const Text('Proceed'),
  1517. onPressed: () async {
  1518. Navigator.pop(context, true);
  1519. },
  1520. ),
  1521. TextButton(
  1522. child: const Text('Cancel'),
  1523. onPressed: () {
  1524. Navigator.pop(context, false);
  1525. },
  1526. )
  1527. ],
  1528. ),
  1529. ));
  1530. if (result) {
  1531. _processBloc.add(ProcessUnit());
  1532. }
  1533. },
  1534. child: Container(
  1535. padding: const EdgeInsets.all(5),
  1536. decoration: BoxDecoration(
  1537. boxShadow: [
  1538. BoxShadow(
  1539. color: Colors.grey.withOpacity(0.5),
  1540. spreadRadius: 2,
  1541. blurRadius: 2,
  1542. offset: const Offset(
  1543. 0, 0), // changes position of shadow
  1544. ),
  1545. ],
  1546. borderRadius:
  1547. const BorderRadius.all(const Radius.circular(5.0)),
  1548. color: Colors.orangeAccent
  1549. .withAlpha(230)
  1550. .withOpacity(0.7),
  1551. ),
  1552. child: Column(
  1553. mainAxisAlignment: MainAxisAlignment.center,
  1554. children: <Widget>[
  1555. Icon(
  1556. Icons.arrow_forward,
  1557. size:
  1558. MediaQuery.of(context).size.width / 6,
  1559. color: Colors.white,
  1560. ),
  1561. const SizedBox(
  1562. height: 5,
  1563. ),
  1564. const Text(
  1565. 'Process Units',
  1566. style: const TextStyle(
  1567. color: Colors.white,
  1568. fontWeight: FontWeight.bold,
  1569. fontSize: 16),
  1570. )
  1571. ],
  1572. ),
  1573. ),
  1574. )
  1575. : InkWell(
  1576. onTap: () async {
  1577. bool result = await showDialog(context: context,builder: (context)=>WillPopScope(
  1578. onWillPop: ()async{
  1579. Navigator.pop(context,false);
  1580. return false;
  1581. },
  1582. child: AlertDialog(
  1583. title: const Text('Submit Data ?'),
  1584. content: const Text('Submit the uploaded data.'),
  1585. actions: <Widget>[
  1586. TextButton(
  1587. child: const Text('Submit'),
  1588. onPressed: ()async{
  1589. Navigator.pop(context,true);
  1590. },
  1591. ),
  1592. TextButton(
  1593. child: const Text('Cancel'),
  1594. onPressed: (){Navigator.pop(context,false);},
  1595. )
  1596. ],
  1597. ),
  1598. ));
  1599. if(result){
  1600. _submitBloc.add(Submit());
  1601. }
  1602. },
  1603. child: Container(
  1604. padding: const EdgeInsets.all(5),
  1605. decoration: BoxDecoration(
  1606. boxShadow: [
  1607. BoxShadow(
  1608. color: Colors.grey.withOpacity(0.5),
  1609. spreadRadius: 2,
  1610. blurRadius: 2,
  1611. offset: const Offset(
  1612. 0, 0), // changes position of shadow
  1613. ),
  1614. ],
  1615. borderRadius:
  1616. const BorderRadius.all(const Radius.circular(5.0)),
  1617. color: Colors.lightGreen.withAlpha(230),
  1618. ),
  1619. child: Column(
  1620. mainAxisAlignment: MainAxisAlignment.center,
  1621. children: <Widget>[
  1622. Icon(
  1623. Icons.arrow_forward,
  1624. size:
  1625. MediaQuery.of(context).size.width / 6,
  1626. color: Colors.white,
  1627. ),
  1628. const SizedBox(
  1629. height: 5,
  1630. ),
  1631. const Text(
  1632. 'Submit Process',
  1633. style: TextStyle(
  1634. color: Colors.white,
  1635. fontWeight: FontWeight.bold,
  1636. fontSize: 16),
  1637. )
  1638. ],
  1639. ),
  1640. ),
  1641. ),
  1642. (prefs.getString(Keys.targetProccess) != null ||
  1643. (prefs.getBool(Keys.submitProccess) != null &&
  1644. prefs.getBool(Keys.submitProccess)))
  1645. ? InkWell(
  1646. splashColor: Colors.black,
  1647. onTap: () async {
  1648. await Future.delayed(const Duration(milliseconds: 200));
  1649. await clearData(context);
  1650. },
  1651. child: Container(
  1652. padding: const EdgeInsets.all(5),
  1653. decoration: BoxDecoration(
  1654. boxShadow: [
  1655. BoxShadow(
  1656. color: Colors.grey.withOpacity(0.5),
  1657. spreadRadius: 2,
  1658. blurRadius: 2,
  1659. offset: const Offset(
  1660. 0, 0), // changes position of shadow
  1661. ),
  1662. ],
  1663. borderRadius:
  1664. const BorderRadius.all(const Radius.circular(5.0)),
  1665. color: Colors.red.withAlpha(200),
  1666. ),
  1667. child: Column(
  1668. mainAxisAlignment: MainAxisAlignment.center,
  1669. children: <Widget>[
  1670. Icon(
  1671. Icons.restore_from_trash,
  1672. size: MediaQuery.of(context).size.width / 6,
  1673. color: Colors.white,
  1674. ),
  1675. const SizedBox(
  1676. height: 5,
  1677. ),
  1678. const Text(
  1679. 'Clear Data',
  1680. style: TextStyle(
  1681. color: Colors.white,
  1682. fontWeight: FontWeight.bold,
  1683. fontSize: 16),
  1684. )
  1685. ],
  1686. ),
  1687. ),
  1688. )
  1689. : Container(),
  1690. ],
  1691. ),
  1692. ),
  1693. ),
  1694. ),
  1695. ],
  1696. ),
  1697. bottomSheet: Container(
  1698. padding: const EdgeInsets.only(bottom: 15, right: 10),
  1699. height: 58,
  1700. alignment: Alignment.bottomRight,
  1701. child: Opacity(
  1702. opacity: 0.5,
  1703. child: Padding(
  1704. padding: const EdgeInsets.all(5),
  1705. child: Column(
  1706. mainAxisSize: MainAxisSize.min,
  1707. crossAxisAlignment: CrossAxisAlignment.end,
  1708. children: <Widget>[
  1709. Text(
  1710. (lastDownload != '')
  1711. ? 'Master Data Downloaded'
  1712. : 'No Master Data Found',
  1713. style: const TextStyle(fontSize: 12),
  1714. ),
  1715. (currentVersion!="")?Text("ver. $currentVersion",style: const TextStyle(fontWeight: FontWeight.bold,fontSize: 12),):Container()
  1716. ]
  1717. )))),
  1718. ),
  1719. ),
  1720. ),
  1721. );
  1722. }
  1723. @override
  1724. void didPushNext() async {
  1725. //pushed from home
  1726. if(prefs.getString(Keys.stockId)!= null){
  1727. _stateBloc.add(const LoadState());
  1728. }
  1729. }
  1730. @override
  1731. void didPopNext() async {
  1732. //popped to home
  1733. if(prefs.getString(Keys.stockId)!= null){
  1734. _stateBloc.add(const LoadState());
  1735. }
  1736. }
  1737. @override
  1738. void didChangeDependencies() {
  1739. super.didChangeDependencies();
  1740. routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute);
  1741. }
  1742. @override
  1743. void dispose() {
  1744. _stateBloc.close();
  1745. _getDataBloc.close();
  1746. _backupBloc.close();
  1747. _restoreBloc.close();
  1748. _uploadBloc.close();
  1749. _processBloc.close();
  1750. _submitBloc.close();
  1751. routeObserver.unsubscribe(this);
  1752. super.dispose();
  1753. }
  1754. }