import 'dart:developer'; // 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/backend/api_requests/api_manager.dart'; import 'package:hub/components/molecular_components/option_selection_modal/option_selection_modal_widget.dart'; import 'package:hub/components/molecular_components/throw_exception/throw_exception_widget.dart'; import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_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:flutter/material.dart'; import 'package:hub/flutter_flow/random_data_util.dart'; import 'package:hub/pages/home_page/home_page_model.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; Future openTermsOfUse(BuildContext context) async { log('openTermsOfUse'); 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 { log('visitStatusStr: $visitStatusStr'); 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, { String? emailAdress, String? password, }) async { String? devUUID; ApiCallResponse? loginCall; await Future.wait([ Future(() async { FFAppState().email = emailAdress!; }), Future(() async { FFAppState().passwd = password!; }), ]); if ((FFAppState().email != '') && (FFAppState().passwd != '')) { devUUID = await getDevUUID(); FFAppState().devUUID = devUUID!; loginCall = await PhpGroup.loginCall.call( email: FFAppState().email, password: FFAppState().passwd, uuid: FFAppState().devUUID, type: FFAppState().device, description: randomString( 10, 10, true, false, false, ), ); if (PhpGroup.loginCall.error( (loginCall.jsonBody ?? ''), ) == false) { FFAppState().userUUID = PhpGroup.loginCall.userUUID( (loginCall.jsonBody ?? ''), )!; // FFAppState().token = await FirebaseMessaging.instance.getToken(); FFAppState().createdAt = dateTimeFormat( 'd/M/y H:mm:ss', getCurrentTimestamp, locale: FFLocalizations.of(context).languageCode, ); FFAppState().updatedAt = '00/00/0000 00:00:00'; FFAppState().status = PhpGroup.loginCall.userStatus( (loginCall.jsonBody ?? ''), )!; FFAppState().userDevUUID = PhpGroup.loginCall.userDeviceId( (loginCall.jsonBody ?? ''), )!; FFAppState().name = PhpGroup.loginCall.userName( (loginCall.jsonBody ?? ''), )!; FFAppState().serialNumber = await getSerialNumber() ?? ''; FFAppState().isLogged = true; await toggleHomePage(context); return; } else { await showModalBottomSheet( isScrollControlled: true, backgroundColor: Colors.transparent, useSafeArea: true, context: context, builder: (context) { return Padding( padding: MediaQuery.viewInsetsOf(context), child: ThrowExceptionWidget( msg: PhpGroup.loginCall.msg( (loginCall?.jsonBody ?? ''), )!, ), ); }, ); FFAppState().deleteEmail(); FFAppState().email = ''; FFAppState().deletePasswd(); FFAppState().passwd = ''; FFAppState().update(() {}); } return; } else { return; } } Future signUpRegisterAction( BuildContext context, { required String? name, String? passwd, required String? email, String? device, }) async { ApiCallResponse? registerCall; if ((email != null && email != '') && (passwd != null && passwd != '') && (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; } await showDialog( context: context, builder: (alertDialogContext) { return AlertDialog( title: const Text('Error'), content: Text('${registerCall?.jsonBody}'), actions: [ TextButton( onPressed: () => Navigator.pop(alertDialogContext), child: const Text('ERROR2 '), ), ], ); }, ); return false; } else { await showDialog( context: context, builder: (alertDialogContext) { return AlertDialog( title: Text(FFLocalizations.of(context).getVariableText( enText: 'Error', ptText: 'Erro', )), content: Text(FFLocalizations.of(context).getVariableText( enText: 'Please fill in all fields', ptText: 'Por favor, preencha todos os campos', )), actions: [ TextButton( onPressed: () => Navigator.pop(alertDialogContext), child: Text(FFLocalizations.of(context).getVariableText( ptText: 'Fechar', enText: 'Close', )), ), ], ); }, ); 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 (FFAppState().isLogged == true) { context.pushNamed('homePage'); } else { if (isAndroid == true) { FFAppState().device = 'Android'; } else if (isiOS == true) { FFAppState().device = 'iOS'; } else { FFAppState().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 toggleHomePage(BuildContext context) async { context.goNamed( 'homePage', extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, transitionType: PageTransitionType.fade, ), }, ); } Future visitRequestComponentAction( BuildContext context, { required String? actionValue, required String? refUUID, required String? responseValue, required String? vteUUID, }) async { ApiCallResponse? respondeSolicitacaoCall; respondeSolicitacaoCall = await PhpGroup.respondeSolicitacaoCall.call( userUUID: FFAppState().userUUID, devUUID: FFAppState().devUUID, cliUUID: FFAppState().cliUUID, atividade: 'respondeSolicitacao', referencia: refUUID, tarefa: actionValue, resposta: responseValue, idVisitante: vteUUID, ); if (respondeSolicitacaoCall.statusCode == 200) { return true; } else { log('headers: ${respondeSolicitacaoCall.headers}'); log('bodyText: ${respondeSolicitacaoCall.bodyText}'); log('jsonBody: ${respondeSolicitacaoCall.jsonBody}'); log('userUUID: ${FFAppState().userUUID}'); log('devUUID: ${FFAppState().devUUID}'); log('cliUUID: ${FFAppState().cliUUID}'); log('atividade: respondeSolicitacao'); log('referencia: $refUUID'); log('tarefa: $actionValue'); log('resposta: $responseValue'); log('idVisitante: $vteUUID'); 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 HomePageModel model, required void Function(void Function()) safeSetState, }) async { // A chamada para a API permanece a mesma, assumindo que é necessária sempre. final response = await PhpGroup.getLocalsCall.call( devUUID: FFAppState().devUUID, userUUID: FFAppState().userUUID, ); // Verificação rápida de erro para evitar processamento desnecessário. if (response.jsonBody['error']) { log("checkLocals => Erro encontrado na resposta"); return false; } // Uso eficiente de coleções para verificar a condição desejada. final String uuid = cliUUID ?? FFAppState().cliUUID; final bool itemFound = response.jsonBody['locais'].any( (local) => local['CLI_ID'] == uuid && local['CLU_STATUS'] == "A", ); // Log e retorno condicional baseado no resultado da busca. if (itemFound) { log("checkLocals => Item encontrado com CLI_ID $uuid e CLU_STATUS A"); return true; } else { log("checkLocals => Item não encontrado com CLI_ID $uuid e CLU_STATUS A"); // A chamada para showModalBottomSheet permanece, mas a atualização da UI é otimizada. await showModalBottomSheet( isScrollControlled: true, backgroundColor: Colors.transparent, enableDrag: false, context: context, builder: (context) => GestureDetector( onTap: () => model.unfocusNode.canRequestFocus ? FocusScope.of(context).requestFocus(model.unfocusNode) : FocusScope.of(context).unfocus(), child: Padding( padding: MediaQuery.viewInsetsOf(context), child: const BottomArrowLinkedLocalsComponentWidget(), ), ), ); safeSetState(() {}); // Chamada otimizada fora do then para evitar encadeamentos desnecessários. return false; } } Future changeStatusAction( BuildContext context, String status, String vawREF, String msg, String vteUUID, ) async { log('status: $status'); switch (status) { case 'L': Navigator.pop(context, true); bool? approveVisitRequest; approveVisitRequest = await visitRequestComponentAction( context, actionValue: status, refUUID: vawREF, responseValue: msg, vteUUID: vteUUID, ); if (!context.mounted) return; if (approveVisitRequest == true) { log('Aprovado'); } else { log('Erro ao aprovar'); } break; case 'B': Navigator.pop(context, true); bool? blockVisitRequest; blockVisitRequest = await visitRequestComponentAction( context, actionValue: status, refUUID: vawREF, responseValue: msg, vteUUID: vteUUID, ); if (!context.mounted) return; if (blockVisitRequest == true) { log('Bloqueado'); } else { log('Erro ao bloquear'); } break; default: break; } } /// QR Code Uint8List assembleQRPacket(int direction, String identifier, String password) { List packet = [direction]; String paddedBadge = identifier.padLeft(30, '0'); log("Badge: $paddedBadge"); 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((' ')); log("Pacote: $packet"); log("Bytes: $bytes"); 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 { log("pass: $pass"); 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, ), }, ); }