import 'dart:developer'; import 'package:flutter/material.dart'; // import 'package:hub/components/organisms/bottom_arrow_linked_locals/bottom_arrow_linked_locals_component_widget.dart'; import 'package:hub/backend/api_requests/api_calls.dart'; import 'package:hub/components/molecular_components/option_selection_modal/option_selection_modal_widget.dart'; import 'package:hub/custom_code/actions/get_dev_u_u_i_d.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/random_data_util.dart'; import 'package:hub/shared/utils/dialog_util.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; import '../shared/utils/log_util.dart'; Future openTermsOfUse(BuildContext context) async { final Uri url = Uri.parse('https://freaccess.com.br/pp/'); if (!await launchUrl(url)) { throw Exception('Could not launch $url'); } } Future repeatVisitScheduleAction( BuildContext context, { List? visitorJsonList, String? visitorStrList, String? visitStartDateStr, String? visitEndDateStr, String? visitReasonStr, String? visitLevelStr, bool? visitTempBol, String? visitObsStr, }) async { context.pushNamed( 'scheduleCompleteVisitPage', queryParameters: { 'visitStartDateStr': serializeParam( visitStartDateStr, ParamType.String, ), 'visitEndDateStr': serializeParam( visitEndDateStr, ParamType.String, ), 'visitReasonStr': serializeParam( visitReasonStr, ParamType.String, ), 'visitLevelStr': serializeParam( visitLevelStr, ParamType.String, ), 'visitTempBol': serializeParam( visitTempBol, ParamType.bool, ), 'visitObsStr': serializeParam( visitObsStr, ParamType.String, ), 'visitorStrList': serializeParam( visitorStrList, ParamType.String, ), 'visitorJsonList': serializeParam( visitorJsonList, ParamType.JSON, isList: true, ), }.withoutNulls, extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.fade, ), }, ); } Future manageStatusColorAction( BuildContext context, { required String? visitStatusStr, }) async { if (visitStatusStr == 'A') { return FlutterFlowTheme.of(context).success; } else if ((visitStatusStr == 'C') || (visitStatusStr == 'F') || (visitStatusStr == 'B') || (visitStatusStr == 'I')) { return FlutterFlowTheme.of(context).error; } return FlutterFlowTheme.of(context).warning; } Future singInLoginAction( BuildContext context, FlutterFlowModel model, { String? emailAdress, String? password, }) async { try { String? devUUID; ApiCallResponse? loginCall; await Future.wait([ Future(() async { AppState().email = emailAdress!; }), Future(() async { AppState().passwd = password!; }), ]); if ((AppState().email != '') && (AppState().passwd != '')) { devUUID = await getDevUUID(); AppState().devUUID = devUUID!; loginCall = await PhpGroup.loginCall.call( email: AppState().email, password: AppState().passwd, uuid: AppState().devUUID, type: AppState().device, description: randomString( 10, 10, true, false, false, ), ); if (PhpGroup.loginCall.error((loginCall.jsonBody ?? '')) == false) { AppState().userUUID = PhpGroup.loginCall.userUUID( (loginCall.jsonBody ?? ''), )!; AppState().createdAt = dateTimeFormat( 'd/M/y H:mm:ss', getCurrentTimestamp, locale: FFLocalizations.of(context).languageCode, ); AppState().updatedAt = '00/00/0000 00:00:00'; AppState().status = PhpGroup.loginCall.userStatus((loginCall.jsonBody ?? ''))!; AppState().userDevUUID = PhpGroup.loginCall.userDeviceId((loginCall.jsonBody ?? ''))!; PhpGroup.loginCall.userName((loginCall.jsonBody ?? ''))!; AppState().serialNumber = await getSerialNumber() ?? ''; AppState().isLogged = true; AppState().haveLocal = await checkLocals(context: context, model: model); } else { if (PhpGroup.loginCall.msg((loginCall?.jsonBody ?? '')) == null) { DialogUtil.errorDefault(context); } else { DialogUtil.error(context, PhpGroup.loginCall.msg((loginCall?.jsonBody ?? '')).toString()); } AppState().deleteEmail(); AppState().email = ''; AppState().deletePasswd(); AppState().passwd = ''; AppState().update(() {}); } } return; } catch (e, s) { DialogUtil.errorDefault(context); LogUtil.requestAPIFailed( 'login.php', emailAdress.toString(), "Login", e, s); } } Future signUpRegisterAction( BuildContext context, { required String? name, String? passwd, required String? email, String? device, }) async { try { ApiCallResponse? registerCall; if ((email != null && email != '') && (passwd != null && passwd != '' && passwd.length > 7) && (name != null && name != '')) { registerCall = await PhpGroup.registerCall.call( name: name, password: passwd, email: email, token: randomString( 36, 36, false, false, true, ), uuid: randomString( 36, 36, false, false, true, ), tipo: device, descricao: randomString( 36, 36, true, false, false, ), ); if (PhpGroup.registerCall.error( (registerCall.jsonBody ?? ''), ) == false) { return true; } final errorMessage = registerCall?.jsonBody['error_msg']; DialogUtil.error(context, errorMessage); return false; } else { DialogUtil.errorDefault(context); return false; } } catch (e, s) { DialogUtil.errorDefault(context); LogUtil.requestAPIFailed( 'registro.php', email.toString(), "Register", e, s); return false; } } Future forgotPasswdAction( BuildContext context, { required String? email, }) async { ApiCallResponse? forgotPasswd; forgotPasswd = await PhpGroup.forgotPasswordCall.call( email: email, ); if (PhpGroup.forgotPasswordCall.error( (forgotPasswd.jsonBody ?? ''), ) != false) { return; } } Future cachingLoginActionApp(BuildContext context) async { if (AppState().isLogged == true) { context.pushNamed('homePage'); } else { if (isAndroid == true) { AppState().device = 'Android'; } else if (isiOS == true) { AppState().device = 'iOS'; } else { AppState().device = 'Web'; } } } Future toggleSignInPage(BuildContext context) async { context.pushNamed( 'signInPage', extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.fade, ), }, ); } Future toggleSignUpPage(BuildContext context) async { context.pushNamed( 'signUpPage', extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.fade, ), }, ); } Future toggleApp(BuildContext context, bool haveLocal) async { if (haveLocal == true) context.goNamed( 'homePage', extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.fade, ), }, ); else if (haveLocal == false) context.goNamed( 'receptionPage', extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.fade, ) }, ); } Future visitCancelAction(BuildContext context, {required int? idDestino, required int? idVisita, required String? accessKey, required String? email}) async { ApiCallResponse? apiCallResponse; apiCallResponse = await PhpGroup.cancelaVisita.call( userUUID: AppState().userUUID, devUUID: AppState().devUUID, cliID: AppState().cliUUID, atividade: 'cancelaVisita', idDestino: idDestino, idVisita: idVisita, AccessKey: accessKey, UsuEmail: email, DevDesc: '', ); if (apiCallResponse.statusCode == 200) { return !apiCallResponse.jsonBody['error']; } else { return false; } } Future snackbar(BuildContext context, {required bool opt}) async { ScaffoldMessenger.of(context).showSnackBar( SnackBar( elevation: 10, margin: const EdgeInsets.all(50), content: Center( child: Text( opt ? FFLocalizations.of(context).getText('asjd2q3k2j4l21') : FFLocalizations.of(context).getText('asda2e42fafa'), style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.normal, color: FlutterFlowTheme.of(context).info, ), ), ), backgroundColor: opt ? FlutterFlowTheme.of(context).success.withOpacity(0.5) : FlutterFlowTheme.of(context).error.withOpacity(0.5), duration: const Duration(seconds: 3), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), ), ); } Future checkLocals({ String? cliUUID, required BuildContext context, required FlutterFlowModel model, }) async { final response = await PhpGroup.getLocalsCall.call( devUUID: AppState().devUUID, userUUID: AppState().userUUID, ); log(response.jsonBody.toString()); // Verificação rápida de erro para evitar processamento desnecessário. if (response.jsonBody['error']) { DialogUtil.errorDefault(context); return false; } List locals = response.jsonBody['locais'] ?? []; if (locals != null && locals.isEmpty) { await toggleApp(context, false); return false; } else { // else if (locals.where((local) => local['CLU_STATUS'] != 'A').isNotEmpty) { // await showModalBottomSheet( // isScrollControlled: true, // backgroundColor: Colors.transparent, // enableDrag: false, // isDismissible: false, // context: context, // builder: (context) => Padding( // padding: MediaQuery.viewInsetsOf(context), // child: const BottomArrowLinkedLocalsComponentWidget(), // ), // ); // } await toggleApp(context, true); return true; } } Future answersRequest(BuildContext context, String? ref, String? task, String? response, String? id) async { ApiCallResponse? respondeSolicitacaoCall; respondeSolicitacaoCall = await PhpGroup.respondeSolicitacaoCall.call( userUUID: AppState().userUUID, devUUID: AppState().devUUID, cliUUID: AppState().cliUUID, atividade: 'respondeSolicitacao', referencia: ref, tarefa: task, resposta: response, idVisitante: id, ); if (respondeSolicitacaoCall.statusCode == 200) { return !respondeSolicitacaoCall.jsonBody['error']; } else { return false; } } Future changeStatusAction( BuildContext context, int idDestino, int idVisita, String accessKey, String email, ) async { Navigator.pop(context, true); bool? blockVisitRequest; blockVisitRequest = await visitCancelAction( context, accessKey: accessKey, idDestino: idDestino, idVisita: idVisita, email: email, ); if (!context.mounted) return; if (blockVisitRequest == true) { return true; } else { return false; } } /// QR Code Uint8List assembleQRPacket(int direction, String identifier, String password) { List packet = [direction]; String paddedBadge = identifier.padLeft(30, '0'); for (var i = 0; i < paddedBadge.length; i += 2) { packet.add(int.parse(paddedBadge.substring(i, i + 2), radix: 16)); } DateTime now = DateTime.now(); int year = now.year % 100; int month = now.month; int day = now.day; int hour = now.hour; int minute = now.minute; int sum = year + month + day + hour + minute; if (sum == int.parse('0D', radix: 16) || sum == int.parse('0A', radix: 16)) { packet.add(int.parse('FF', radix: 16)); } else { packet.add(sum); } String paddedPassword = password.length != 4 ? 'FFFF' : password; for (var i = 0; i < paddedPassword.length; i += 2) { packet.add(int.parse(paddedPassword.substring(i, i + 2), radix: 16)); } int check = 0x00; for (var b in packet) { check ^= b; } if (check == int.parse('0D', radix: 16) || check == int.parse('0A', radix: 16)) { packet.add(int.parse('FF', radix: 16)); } else { packet.add(check); } var bytes = packet.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join((' ')); return Uint8List.fromList(packet); } Uint8List hexStringToByteArray(String s) { int len = s.length; Uint8List data = Uint8List(len ~/ 2); for (int i = 0; i < len; i += 2) { data[i ~/ 2] = ((int.parse(s[i], radix: 16) << 4) + int.parse(s[i + 1], radix: 16)); } return data; } String byteToHexa(Uint8List pDados) { return pDados .map((byte) => byte.toRadixString(16).padLeft(2, '0').toUpperCase()) .join(); } Future byteToString(Uint8List bytes) async { return String.fromCharCodes(bytes); } Widget buildQrCode( { // required String data, // required String type, // required int version, // required int maskPattern, required int errorCorrectLevel, required double dimension, required String identifier, required String pass, required int direction}) { try { const Color backgroundColor = Colors.white; const Color foregroundColor = Colors.black; return QrImageView.withQr( qr: QrCode.fromUint8List( data: assembleQRPacket(direction, identifier, pass), errorCorrectLevel: errorCorrectLevel), size: dimension, padding: const EdgeInsets.all(10), backgroundColor: backgroundColor, foregroundColor: foregroundColor); } catch (e) { return Text("Erro ao gerar QR Code: ${e.toString()}"); } } // // Retorna o conteúdo a ser codificado no QR Code. // String getContents() { // return data; // } // // Retorna uma versão do conteúdo otimizada para exibição. // String getDisplayContents() { // return data.trim(); // } // // Retorna o título baseado no tipo de conteúdo. // String getTitle() { // return type; // } // // Codifica o conteúdo em uma string adequada para o QR Code. // Future encodeContents() async { // // Implementação específica para codificar o conteúdo. // return data; // Exemplo simplificado. // } // // Codifica o conteúdo específico do QR Code. // Future encodeQRCodeContents() async { // return getQrCode(); // } // // Gera o QR Code como um widget. // // Codifica o conteúdo como um bitmap (pode ser útil para operações de baixo nível). // // Future encodeAsBitmap() async { // // // Implementação para codificar como bitmap. // // return Image(image); // Exemplo simplificado. // // } // // Adivinha a codificação apropriada para o conteúdo. // String guessAppropriateEncoding(String content) { // // Implementação para adivinhar a codificação. // return "UTF-8"; // Exemplo simplificado. // } // // Remove espaços em branco do início e do fim do conteúdo. // String trim(String content) { // return content.trim(); // } // // Escapa caracteres especiais para o formato MECARD. // String escapeMECARD(String content) { // // Implementação para escapar caracteres. // return content.replaceAll(':', '\\:'); // Exemplo simplificado. // } /// menu Future scheduleVisitOptAction(BuildContext context) async { await showAdaptiveDialog( context: context, builder: (context) { return Padding( padding: MediaQuery.viewInsetsOf(context), child: OptionSelectionModalWidget( routesListStr: [ 'scheduleCompleteVisitPage', 'scheduleProvisionalVisitPage', 'fastPassPage', ], iconsListIcon: [ Icons.date_range_rounded, Icons.date_range_rounded, Icons.date_range_rounded, ], nameListStr: [ FFLocalizations.of(context).getVariableText( ptText: 'Visita\nCompleta', enText: 'Complete\nSchedule', ), FFLocalizations.of(context).getVariableText( ptText: 'Visita\nProvisória', enText: 'Provisional\nSchedule', ), FFLocalizations.of(context).getVariableText( ptText: 'Visita\nRápida', enText: 'Fast\nSchedule', ), ], ), ); }, ); } Future registerVisitorOptAction(BuildContext context) async { context.pushNamed( 'registerVisitorPage', extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.scale, alignment: Alignment.bottomCenter, ), }, ); } Future peopleOnThePropertyAction(BuildContext context) async { context.pushNamed( 'peopleOnThePropertyPage', extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.fade, ), }, ); } Future preferencesSettings(BuildContext context) async { context.pushNamed( 'preferencesSettings', extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.scale, alignment: Alignment.bottomCenter, ), }, ); } Future liberationHistoryOptAction(BuildContext context) async { await showAdaptiveDialog( // isScrollControlled: true, // backgroundColor: Colors.transparent, // enableDrag: false, context: context, builder: (context) { return Padding( padding: MediaQuery.viewInsetsOf(context), child: OptionSelectionModalWidget( routesListStr: [ 'liberationHistory', 'acessHistoryPage', 'scheduleCompleteVisitPage', // 'messageHistoryPage', ], iconsListIcon: [ Icons.history_rounded, Icons.history_rounded, Icons.history_rounded, // Icons.history_rounded, ], nameListStr: [ FFLocalizations.of(context).getVariableText( ptText: 'Histórico\nde Liberação', enText: 'Liberation\nHistory', ), FFLocalizations.of(context).getVariableText( ptText: 'Histórico\nde Acesso', enText: 'Access\nHistory', ), FFLocalizations.of(context).getVariableText( ptText: 'Histórico\nde Visita', enText: 'Visit\nHistory', ), // FFLocalizations.of(context).getVariableText( // ptText: 'Histórico\nde Mensagens', // enText: 'Message\nHistory', // ), ], ), ); }, ); } Future accessQRCodeOptAction(BuildContext context) async { context.pushNamed( 'qrCodePage', extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.scale, alignment: Alignment.bottomCenter, ), }, ); } enum status { active, unknown, canceled, finished, blocked, inactive } status? getStatus(dynamic data) { switch (data) { case 'A': return status.active; case 'F': return status.finished; case 'B': return status.blocked; case 'C': return status.canceled; case 'I': return status.inactive; default: return status.unknown; } }