login.dart 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. import 'dart:convert';
  2. import 'package:auto_route/auto_route.dart';
  3. import 'package:cached_network_image/cached_network_image.dart';
  4. import 'package:easy_localization/easy_localization.dart';
  5. import 'package:flutter/foundation.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:flutter_cache_manager/flutter_cache_manager.dart';
  8. import 'package:jwt_decoder/jwt_decoder.dart';
  9. import 'package:telnow_mobile_new/src/api/api_auth_provider.dart';
  10. import 'package:telnow_mobile_new/src/api/api_auth_repository.dart';
  11. import 'package:telnow_mobile_new/src/api/jwt_token.dart';
  12. import 'package:telnow_mobile_new/src/injector/injector.dart';
  13. import 'package:telnow_mobile_new/src/layouts/components/template.dart';
  14. import 'package:telnow_mobile_new/src/model/login/login_body.dart';
  15. import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
  16. import 'package:telnow_mobile_new/src/utils/U.dart';
  17. import 'package:telnow_mobile_new/src/utils/cache_manager.dart';
  18. import 'package:toggle_switch/toggle_switch.dart';
  19. import 'package:url_launcher/url_launcher.dart';
  20. import 'package:telnow_mobile_new/src/model/token/token.dart';
  21. @RoutePage()
  22. class LoginPage extends StatefulWidget {
  23. const LoginPage({Key? key}) : super(key: key);
  24. @override
  25. State<LoginPage> createState() => _LoginPageState();
  26. }
  27. class _LoginPageState extends State<LoginPage> {
  28. final JwtToken token = JwtToken();
  29. final ApiAuthProvider apiAuthProvider = ApiAuthProvider();
  30. final ApiAuthRepository apiAuthRepository = ApiAuthRepository();
  31. final SharedPreferencesManager sharedPreferencesManager = locator<SharedPreferencesManager>();
  32. String companyName = '';
  33. String serialNumber = '';
  34. String companyLogo = '';
  35. bool loading = false;
  36. String username = '';
  37. String password = '';
  38. String imageUrl = '';
  39. List lang = [];
  40. @override
  41. void initState() {
  42. try{imageUrl = apiAuthProvider.baseUrl + U.decodeBase64Url(Uri.decodeComponent(U.getAccessCode()!))+'/assets/background/tn';}catch(e){}
  43. getCompanyName();
  44. // TODO: implement initState
  45. super.initState();
  46. }
  47. getCompanyName() async {
  48. var lics = await U.reloadLicense();
  49. if (lics != null && mounted) {
  50. setState(() {
  51. companyName = lics['companyName']??'';
  52. serialNumber = lics['serialNumber']??'';
  53. companyLogo = lics['logo']??'';
  54. if(1698720817 <= lics['serverVersion']){
  55. lang = lics['languages'] != null ? lics['languages'].split(',') : [];
  56. }
  57. });
  58. }
  59. }
  60. @override
  61. Widget build(BuildContext context) {
  62. return Scaffold(
  63. resizeToAvoidBottomInset: false,
  64. body: Stack(
  65. children: [
  66. Container(
  67. width: double.infinity, height: double.infinity,
  68. child: Image.network(imageUrl, fit: BoxFit.cover, width: double.infinity, height: double.infinity, errorBuilder: (context, error, stackTrace) {
  69. return Image.asset('assets/image/background/background.jpg', fit: BoxFit.cover, width: double.infinity, height: double.infinity);
  70. }),
  71. ),
  72. SingleChildScrollView(
  73. child: Container(
  74. padding: EdgeInsets.fromLTRB(16, kIsWeb?80:50, 16, 16),
  75. width: MediaQuery.of(context).size.width,
  76. height: kIsWeb && MediaQuery.of(context).size.height<700 ? 700 : MediaQuery.of(context).size.height,
  77. decoration: BoxDecoration(gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [primaryColor.withValues(alpha: 0.50), Colors.black.withValues(alpha: 0.91)])),
  78. child: Column(
  79. children: [
  80. kIsWeb?Container():Container(
  81. margin: EdgeInsets.only(bottom: companyLogo.isNotEmpty?50:120),
  82. child: GestureDetector(
  83. child: Row(
  84. children: [
  85. U.iconsax('arrow-left', color: Colors.white),
  86. SizedBox(width: 15),
  87. Column(
  88. crossAxisAlignment: CrossAxisAlignment.start,
  89. children: [
  90. Text('buttonBack'.tr(), style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500)),
  91. Text('buttonScan'.tr(), style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500)),
  92. ],
  93. )
  94. ],
  95. ),
  96. onTap: (){
  97. context.router.removeLast();
  98. context.navigateToPath('/qr?new=true');
  99. },
  100. ),
  101. ),
  102. Image.asset('assets/image/logo/logo.png', height: companyLogo.isNotEmpty?25:40),
  103. companyLogo.isNotEmpty?Container(
  104. margin: EdgeInsets.only(top: 30, bottom: 40),
  105. width: 160, height: 160,
  106. decoration: BoxDecoration(
  107. borderRadius: BorderRadius.all(Radius.circular(80)),
  108. image: DecorationImage(image: CachedNetworkImageProvider(companyLogo+'?bridge-cache=true', cacheManager: CacheManager(CacheMan.config(companyLogo))), fit: BoxFit.cover)
  109. ),
  110. ):SizedBox(height: 115),
  111. Expanded(
  112. child: Column(
  113. mainAxisAlignment: MainAxisAlignment.start,
  114. children: [
  115. Container(
  116. alignment: Alignment.topCenter,
  117. width: U.bodyWidth(context),
  118. child: Column(
  119. children: [
  120. loginFieldTemplate(placeholder: 'userId'.tr(), value: username, action: (val)=>username = val, submit: (val)=>loginAction()),
  121. SizedBox(height: 12),
  122. loginFieldTemplate(placeholder: 'password'.tr(), value: password, action: (val)=>password = val, isPassword: true, submit: (val)=>loginAction()),
  123. GestureDetector(
  124. child: Container(
  125. width: double.infinity,
  126. margin: EdgeInsets.only(top: 40, bottom: 20),
  127. padding: EdgeInsets.symmetric(vertical: 16),
  128. child: !loading?Text('buttonLogin'.tr(), style: TextStyle(color: Colors.white, fontSize: 17), textAlign: TextAlign.center):Center(
  129. child: SizedBox(
  130. width: 22, height: 22, child: CircularProgressIndicator(color: Colors.white),
  131. ),
  132. ),
  133. decoration: BoxDecoration(
  134. color: primaryColor.withValues(alpha: 0.50),
  135. border: Border.all(color: Colors.white),
  136. borderRadius: BorderRadius.all(Radius.circular(12))
  137. ),
  138. ),
  139. onTap: ()=>loginAction(),
  140. ),
  141. ],
  142. ),
  143. ),
  144. companyName.isNotEmpty?Text(companyName, style: TextStyle(fontSize: 16, color: Colors.white), textAlign: TextAlign.center):Container(),
  145. SizedBox(height: companyName.isNotEmpty?5:0),
  146. serialNumber.isNotEmpty?Text('serialNumber'.tr() + ' ' + serialNumber, style: TextStyle(color: Colors.white, fontSize: 14)):Container(),
  147. ],
  148. ),
  149. ),
  150. Container(
  151. margin: EdgeInsets.only(top: 20, bottom: 5),
  152. alignment: Alignment.bottomCenter,
  153. child: GestureDetector(
  154. child: Text('policy'.tr(), style: TextStyle(color: Colors.white, fontSize: 14, decoration: TextDecoration.underline)),
  155. onTap: () async {
  156. Uri _url = Uri.parse('https://telmessenger.com/privacy-police/telnow.html');
  157. await canLaunchUrl(_url) ? await launchUrl(_url) : print('Could not launch $_url');
  158. },
  159. ),
  160. ),
  161. Text('${'version'.tr()} ${ApiAuthProvider().displayVersion}', style: TextStyle(color: Colors.white, fontSize: 14)),
  162. SizedBox(height: 5),
  163. Text('Build ${ApiAuthProvider().buildNumber}', style: TextStyle(color: Colors.white, fontSize: 13)),
  164. ],
  165. ),
  166. ),
  167. ),
  168. Container(
  169. margin: EdgeInsets.only(top: kIsWeb?16:50, right: 16),
  170. child: Align(
  171. alignment: Alignment.topRight,
  172. child: lang.length > 0 ? GestureDetector(
  173. child: Container(
  174. width: 65, height: 30, padding: EdgeInsets.symmetric(horizontal: 10),
  175. child: Row(
  176. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  177. children: [
  178. U.iconsax('bold/global', color: Colors.white),
  179. Text(context.locale.toString().toUpperCase(), style: TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.bold))
  180. ],
  181. ),
  182. decoration: BoxDecoration(
  183. color: Colors.deepOrange,
  184. borderRadius: BorderRadius.all(Radius.circular(50))
  185. ),
  186. ),
  187. onTap: () => changeLangLogin(context, lang),
  188. ) : ToggleSwitch(
  189. minWidth: 40,
  190. minHeight: 30,
  191. cornerRadius: 20,
  192. initialLabelIndex: context.locale.toString() == 'en' ? 0 : 1,
  193. activeBgColor: [Colors.deepOrange],
  194. activeFgColor: Colors.white,
  195. inactiveBgColor: Colors.white54,
  196. inactiveFgColor: Colors.white,
  197. labels: ['EN', 'ID'],
  198. onToggle: (index) {
  199. if (index == 0) {
  200. context.setLocale(Locale('en'));
  201. } else {
  202. context.setLocale(Locale('id'));
  203. }
  204. },
  205. ),
  206. ),
  207. )
  208. ],
  209. ),
  210. );
  211. }
  212. loginAction() async{
  213. if(!loading){
  214. setState(()=>loading = true);
  215. String errMsg = '';
  216. if (password.isEmpty) {
  217. errMsg = 'passwordEmpty'.tr();
  218. } else if (username.isEmpty) {
  219. errMsg = 'userEmpty'.tr();
  220. }
  221. if (errMsg.isNotEmpty) {
  222. showError(context, errMsg);
  223. setState(()=>loading = false);
  224. return;
  225. }
  226. Token token = await apiAuthRepository.postLoginUser(LoginBody(username.trim(), password.trim(), "password"));
  227. if (token.error != null) {
  228. showError(context, token.error);
  229. setState(()=>loading = false);
  230. return;
  231. }
  232. var pid = U.getPidFromUrl(context.router.currentUrl);
  233. await sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessToken, token.accessToken!);
  234. await sharedPreferencesManager.putString(SharedPreferencesManager.keyRefreshToken, token.refreshToken!);
  235. // print(JwtDecoder.decode(token.accessToken!));
  236. var accTkn = JwtDecoder.decode(token.accessToken!);
  237. switchLang(context, context.locale.toLanguageTag(), accTkn);
  238. if(await setUsername()){
  239. var data = {
  240. 'username': username.trim(),
  241. 'password': password.trim()
  242. };
  243. Navigator.push(context, MaterialPageRoute(builder: (context) => ForceChgPassPage(data: data))).then((value) async {
  244. if (!U.getChangedPassword()) {
  245. await U.clearPreferences();
  246. U.setHidePayload(true);
  247. context.router.removeLast();
  248. context.navigateToPath("/app/$pid/menu");
  249. return;
  250. }
  251. });
  252. }
  253. else{
  254. await sharedPreferencesManager.putBool(SharedPreferencesManager.keyIsLogin, true);
  255. await sharedPreferencesManager.putString(SharedPreferencesManager.keyScoope, 'INSIDE');
  256. await sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 0);
  257. await sharedPreferencesManager.putString(SharedPreferencesManager.keyPendingData, jsonEncode([]));
  258. U.setHidePayload(true);
  259. context.router.removeLast();
  260. context.navigateToPath("/app/$pid/menu");
  261. }
  262. }
  263. }
  264. switchLang(BuildContext context, code, tkn) async {
  265. // print("switchLang called");
  266. try{
  267. var res = await apiAuthProvider.patchData('/api/informants/' + tkn['userId'].toString(), {'userId': tkn['user_name'].toString().replaceFirst('inf-', ""), 'language': code.toUpperCase()}, context);
  268. if (res != null) {
  269. // print("res $res");
  270. // context.setLocale(Locale(code));
  271. }
  272. }catch(e){}
  273. }
  274. setUsername() async {
  275. try{
  276. String? accessToken = sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken);
  277. var jwt = token.parseJwtPayLoad(accessToken!);
  278. await sharedPreferencesManager.putString(SharedPreferencesManager.keyUsername, jwt['user_name'].substring(4));
  279. await U.setChangedPassword(false);
  280. return jwt['forceChgPass'];
  281. } catch(e) {
  282. print(e.toString());
  283. }
  284. }
  285. }
  286. changeLangLogin(BuildContext context, List lang){
  287. showModalBottomSheet(
  288. context: context,
  289. backgroundColor: Colors.white,
  290. builder: (BuildContext context) {
  291. return Column(
  292. mainAxisSize: MainAxisSize.min,
  293. children: <Widget>[
  294. Padding(
  295. padding: EdgeInsets.symmetric(vertical: 16),
  296. child: Center(
  297. child: Text('chooseLanguage'.tr(), style: TextStyle(color: textColor)),
  298. ),
  299. ),
  300. divider(),
  301. SizedBox(height: 16),
  302. Column(
  303. crossAxisAlignment: CrossAxisAlignment.start,
  304. children: [
  305. ListTile(
  306. title: Text('bahasa'.tr(), style: TextStyle(color: textColor, fontSize: 14)),
  307. trailing: Icon(context.locale.toString()=='id'?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  308. onTap: context.locale.toString() != 'id' ? () async {
  309. Navigator.of(context).pop();
  310. context.setLocale(Locale('id'));
  311. } : null,
  312. ),
  313. ListTile(
  314. title: Text('english'.tr(), style: TextStyle(color: textColor, fontSize: 14)),
  315. trailing: Icon(context.locale.toString()=='en'?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  316. onTap: context.locale.toString() != 'en' ? () async {
  317. Navigator.of(context).pop();
  318. context.setLocale(Locale('en'));
  319. } : null,
  320. ),
  321. lang.contains('ja') ? ListTile(
  322. title: Text('japanese'.tr(), style: TextStyle(color: textColor, fontSize: 14)),
  323. trailing: Icon(context.locale.toString()=='ja'?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  324. onTap: context.locale.toString() != 'ja' ? () async {
  325. Navigator.of(context).pop();
  326. context.setLocale(Locale('ja'));
  327. } : null,
  328. ) : Container(),
  329. lang.contains('zh') ? ListTile(
  330. title: Text('chinese'.tr(), style: TextStyle(color: textColor, fontSize: 14)),
  331. trailing: Icon(context.locale.toString()=='zh'?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  332. onTap: context.locale.toString() != 'zh' ? () async {
  333. Navigator.of(context).pop();
  334. context.setLocale(Locale('zh'));
  335. } : null,
  336. ) : Container(),
  337. lang.contains('ko') ? ListTile(
  338. title: Text('korean'.tr(), style: TextStyle(color: textColor, fontSize: 14)),
  339. trailing: Icon(context.locale.toString()=='ko'?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  340. onTap: context.locale.toString() != 'ko' ? () async {
  341. Navigator.of(context).pop();
  342. context.setLocale(Locale('ko'));
  343. } : null,
  344. ) : Container()
  345. ],
  346. ),
  347. SizedBox(height: 16)
  348. ],
  349. );
  350. }
  351. );
  352. }
  353. //------------------------------------------------------------------------------
  354. class ForceChgPassPage extends StatefulWidget {
  355. Map<String, String> data;
  356. ForceChgPassPage({required this.data, Key? key}) : super(key: key);
  357. @override
  358. State<ForceChgPassPage> createState() => _ForceChgPassPageState();
  359. }
  360. class _ForceChgPassPageState extends State<ForceChgPassPage> {
  361. final JwtToken token = JwtToken();
  362. final ApiAuthProvider apiAuthProvider = ApiAuthProvider();
  363. final ApiAuthRepository apiAuthRepository = ApiAuthRepository();
  364. final SharedPreferencesManager sharedPreferencesManager = locator<SharedPreferencesManager>();
  365. var tokenData;
  366. String companyName = '';
  367. String serialNumber = '';
  368. String guestName = '';
  369. bool loading = false;
  370. String imageUrl = '';
  371. String newPassword = '';
  372. String cfrmPassword = '';
  373. @override
  374. void initState() {
  375. try{imageUrl = apiAuthProvider.baseUrl + U.decodeBase64Url(Uri.decodeComponent(U.getAccessCode()!))+'/assets/background/tn';}catch(e){}
  376. getTokenData();
  377. getCompanyName();
  378. // TODO: implement initState
  379. super.initState();
  380. }
  381. getTokenData() async {
  382. String accessToken = sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken)!;
  383. var jwt = token.parseJwtPayLoad(accessToken);
  384. var user = await apiAuthProvider.getData('/api/informants/'+jwt['userId'].toString(), null, context);
  385. if(user!=null){
  386. setState((){
  387. tokenData = jwt;
  388. context.setLocale(Locale(tokenData['language'].toLowerCase()));
  389. guestName = user['guestName'];
  390. });
  391. }
  392. }
  393. getCompanyName() async {
  394. var lics = await U.reloadLicense();
  395. if (lics != null && mounted) {
  396. setState(() {
  397. companyName = lics['companyName']??'';
  398. serialNumber = lics['serialNumber']??'';
  399. });
  400. }
  401. }
  402. @override
  403. Widget build(BuildContext context) {
  404. return WillPopScope(
  405. onWillPop: (){
  406. sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAccessToken);
  407. sharedPreferencesManager.clearKey(SharedPreferencesManager.keyRefreshToken);
  408. sharedPreferencesManager.clearKey(SharedPreferencesManager.keyUsername);
  409. sharedPreferencesManager.clearKey(SharedPreferencesManager.keyIsLogin);
  410. sharedPreferencesManager.clearKey(SharedPreferencesManager.keyScoope);
  411. sharedPreferencesManager.clearKey(SharedPreferencesManager.keyMenuDisplay);
  412. sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAutoTranslate);
  413. sharedPreferencesManager.clearKey(SharedPreferencesManager.keyPendingData);
  414. navigateBack(context);
  415. return Future.value(true);
  416. },
  417. child: Scaffold(
  418. resizeToAvoidBottomInset: false,
  419. body: Stack(
  420. children: [
  421. SizedBox(
  422. width: double.infinity, height: double.infinity,
  423. child: Image.network(imageUrl, fit: BoxFit.cover, width: double.infinity, height: double.infinity, errorBuilder: (context, error, stackTrace) {
  424. return Image.asset('assets/image/background/background.jpg', fit: BoxFit.cover, width: double.infinity, height: double.infinity);
  425. }),
  426. ),
  427. Container(
  428. width: MediaQuery.of(context).size.width,
  429. height: MediaQuery.of(context).size.height,
  430. decoration: BoxDecoration(
  431. gradient: LinearGradient(
  432. begin: Alignment.topCenter, end: Alignment.bottomCenter,
  433. colors: [
  434. primaryColor.withValues(alpha: 0.50), Colors.black.withValues(alpha: 0.91)
  435. ]
  436. )
  437. ),
  438. child: SingleChildScrollView(
  439. padding: EdgeInsets.fromLTRB(16, 50, 16, 16),
  440. child: Column(
  441. crossAxisAlignment: CrossAxisAlignment.center,
  442. children: [
  443. Container(
  444. margin: EdgeInsets.only(bottom: 100),
  445. child: Row(
  446. children: [
  447. GestureDetector(
  448. child: U.iconsax('arrow-left', color: Colors.white),
  449. onTap: (){
  450. context.router.removeLast();
  451. context.navigateToPath('/qr?new=true');
  452. },
  453. ),
  454. SizedBox(width: 15),
  455. Expanded(
  456. child: GestureDetector(
  457. child: Column(
  458. crossAxisAlignment: CrossAxisAlignment.start,
  459. children: [
  460. Text('buttonBack'.tr(), style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500)),
  461. Text('buttonScan'.tr(), style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500)),
  462. ],
  463. ),
  464. onTap: (){
  465. context.router.removeLast();
  466. context.navigateToPath('/qr?new=true');
  467. },
  468. ),
  469. ),
  470. Image.asset('assets/image/logo/logo.png', width: 120)
  471. ],
  472. )
  473. ),
  474. Column(
  475. children: [
  476. Text('${'welcome'.tr()} $guestName', style: TextStyle(color: Colors.white, fontSize: 16), textAlign: TextAlign.center),
  477. SizedBox(height: 16),
  478. Text('createNewPassText'.tr(), style: TextStyle(color: Colors.white, fontSize: 16), textAlign: TextAlign.center),
  479. ],
  480. ),
  481. SizedBox(height: 80),
  482. Container(
  483. alignment: Alignment.topCenter,
  484. width: U.bodyWidth(context),
  485. child: Column(
  486. children: [
  487. loginFieldTemplate(placeholder: 'newPassword'.tr(), value: newPassword, action: (val)=>newPassword = val, isPassword: true, submit: (val)=>loginAction()),
  488. SizedBox(height: 12),
  489. loginFieldTemplate(placeholder: 'confirmPassword'.tr(), value: cfrmPassword, action: (val)=>cfrmPassword = val, isPassword: true, submit: (val)=>loginAction()),
  490. GestureDetector(
  491. child: Container(
  492. width: double.infinity,
  493. margin: EdgeInsets.only(top: 40, bottom: 20),
  494. padding: EdgeInsets.symmetric(vertical: 16),
  495. decoration: BoxDecoration(
  496. color: primaryColor.withValues(alpha: 0.50),
  497. border: Border.all(color: Colors.white),
  498. borderRadius: BorderRadius.all(Radius.circular(12))
  499. ),
  500. child: !loading?Text('buttonLogin'.tr(), style: TextStyle(color: Colors.white, fontSize: 17), textAlign: TextAlign.center):Center(
  501. child: SizedBox(
  502. width: 22, height: 22, child: CircularProgressIndicator(color: Colors.white),
  503. ),
  504. ),
  505. ),
  506. onTap: ()=>loginAction(),
  507. ),
  508. ],
  509. ),
  510. ),
  511. companyName.isNotEmpty?Text(companyName, style: TextStyle(fontSize: 16, color: Colors.white), textAlign: TextAlign.center):Container(),
  512. SizedBox(height: companyName.isNotEmpty?5:0),
  513. serialNumber.isNotEmpty?Text('${'serialNumber'.tr()} $serialNumber', style: TextStyle(color: Colors.white, fontSize: 14)):Container(),
  514. Container(
  515. margin: const EdgeInsets.only(top: 145),
  516. alignment: Alignment.bottomCenter,
  517. child: Text('version'.tr() + ' ' + ApiAuthProvider().displayVersion, style: TextStyle(color: Colors.white, fontSize: 14))
  518. ),
  519. ],
  520. ),
  521. ),
  522. ),
  523. ],
  524. ),
  525. ),
  526. );
  527. }
  528. loginAction() async{
  529. if(!loading){
  530. if(newPassword.isNotEmpty && cfrmPassword.isNotEmpty){
  531. if(newPassword.trim() == cfrmPassword.trim()){
  532. setState(()=>loading = true);
  533. var data = {'oldPassword': widget.data['password'], 'password': newPassword.trim()};
  534. try {
  535. var res = await apiAuthProvider.patchData('/api/informants/${tokenData['userId']}/changePassword', data, context);
  536. if (res != null) {
  537. String password = tokenData['related'] && tokenData['tenantCode'] != null && tokenData['tenantCode'] != '' ? tokenData['tenantCode'] + ' ' + data['password'] : data['password'];
  538. LoginBody loginBody = LoginBody(widget.data['username']!, password, 'password');
  539. Token token = await apiAuthRepository.postLoginUser(loginBody);
  540. if (token.error != null) {
  541. setState(()=>loading = false);
  542. showError(context, token.error);
  543. } else {
  544. await U.setChangedPassword(true);
  545. var parsedToken = U.token.parseJwtPayLoad(token.accessToken!);
  546. await sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessToken, token.accessToken!);
  547. await sharedPreferencesManager.putString(SharedPreferencesManager.keyRefreshToken, token.refreshToken!);
  548. await sharedPreferencesManager.putString(SharedPreferencesManager.keyUsername, tokenData['related'] ? parsedToken['user_name'].split("-").last : widget.data['username']);
  549. await sharedPreferencesManager.putBool(SharedPreferencesManager.keyIsLogin, true);
  550. await sharedPreferencesManager.putString(SharedPreferencesManager.keyScoope, 'INSIDE');
  551. await sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 0);
  552. await sharedPreferencesManager.putString(SharedPreferencesManager.keyPendingData, jsonEncode([]));
  553. U.setHidePayload(true);
  554. // var pid = U.getAccessCode();
  555. var pid = U.getPidFromUrl(context.router.currentUrl);
  556. context.router.removeLast();
  557. context.navigateToPath("/app/$pid/menu");
  558. }
  559. }
  560. } catch(e) {
  561. print(e.toString());
  562. setState(()=>loading = false);
  563. }
  564. }
  565. else{
  566. showError(context, 'checkNewPass'.tr());
  567. }
  568. }
  569. else{
  570. showError(context, 'cannotEmpty'.tr());
  571. }
  572. }
  573. }
  574. }