flutter-freaccess-hub/lib/actions/actions.dart

813 lines
22 KiB
Dart

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<void> 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<dynamic>? 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: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.fade,
),
},
);
}
Future<Color> 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<bool> 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: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.fade,
),
},
);
}
Future toggleSignUpPage(BuildContext context) async {
context.pushNamed(
'signUpPage',
extra: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.fade,
),
},
);
}
Future toggleHomePage(BuildContext context) async {
context.goNamed(
'homePage',
extra: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.fade,
),
},
);
}
Future<bool> 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<void> 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<bool> 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<int> 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<String> 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<String> 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<Widget> 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<Image> 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: <String>[
'scheduleCompleteVisitPage',
'scheduleProvisionalVisitPage',
'fastPassPage',
],
iconsListIcon: <IconData>[
Icons.date_range_rounded,
Icons.date_range_rounded,
Icons.date_range_rounded,
],
nameListStr: <String>[
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: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.scale,
alignment: Alignment.bottomCenter,
),
},
);
}
Future peopleOnThePropertyAction(BuildContext context) async {
context.pushNamed(
'peopleOnThePropertyPage',
extra: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.fade,
),
},
);
}
Future preferencesSettings(BuildContext context) async {
context.pushNamed(
'preferencesSettings',
extra: <String, dynamic>{
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: <String>[
'liberationHistory',
'acessHistoryPage',
'scheduleCompleteVisitPage',
// 'messageHistoryPage',
],
iconsListIcon: <IconData>[
Icons.history_rounded,
Icons.history_rounded,
Icons.history_rounded,
// Icons.history_rounded,
],
nameListStr: <String>[
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: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.scale,
alignment: Alignment.bottomCenter,
),
},
);
}