Merge pull request #11 from FRE-Informatica/develop

Develop
This commit is contained in:
Ivan Antunes 2024-08-14 09:42:04 -03:00 committed by GitHub
commit 10668c9f97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
49 changed files with 4247 additions and 4636 deletions

View File

@ -1,4 +1,7 @@
PODS:
- connectivity_plus (0.0.1):
- Flutter
- FlutterMacOS
- device_info_plus (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.9):
@ -225,6 +228,7 @@ PODS:
- Flutter
DEPENDENCIES:
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
@ -271,6 +275,8 @@ SPEC REPOS:
- SwiftyGif
EXTERNAL SOURCES:
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/darwin"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
file_picker:
@ -313,6 +319,7 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
SPEC CHECKSUMS:
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60

View File

@ -41,6 +41,8 @@
4C588A6A63D12FBFE8C3D586 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
4C7A2C30DCF835BA60FAD235 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
50BE974D08F66282C0031620 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
6436409127A31CDB00820AF7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
6436409227A31CD800820AF7 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/InfoPlist.strings; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };

View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
@ -14,13 +16,14 @@
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-16" y="-40"/>
</scene>
</scenes>
</document>

View File

@ -22,7 +22,6 @@ import 'package:url_launcher/url_launcher.dart';
import '../shared/utils/log_util.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');
@ -90,7 +89,6 @@ Future<Color> manageStatusColorAction(
BuildContext context, {
required String? visitStatusStr,
}) async {
log('visitStatusStr: $visitStatusStr');
if (visitStatusStr == 'A') {
return FlutterFlowTheme.of(context).success;
} else if ((visitStatusStr == 'C') ||
@ -322,40 +320,28 @@ Future toggleHomePage(BuildContext context) async {
);
}
Future<bool> visitRequestComponentAction(
BuildContext context, {
required String? actionValue,
required String? refUUID,
required String? responseValue,
required String? vteUUID,
}) async {
ApiCallResponse? respondeSolicitacaoCall;
Future<bool> visitCancelAction(BuildContext context,
{required int? idDestino,
required int? idVisita,
required String? accessKey,
required String? email}) async {
ApiCallResponse? apiCallResponse;
respondeSolicitacaoCall = await PhpGroup.respondeSolicitacaoCall.call(
apiCallResponse = await PhpGroup.cancelaVisita.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliUUID: FFAppState().cliUUID,
atividade: 'respondeSolicitacao',
referencia: refUUID,
tarefa: actionValue,
resposta: responseValue,
idVisitante: vteUUID,
cliID: FFAppState().cliUUID,
atividade: 'cancelaVisita',
idDestino: idDestino,
idVisita: idVisita,
AccessKey: accessKey,
UsuEmail: email,
DevDesc: '',
);
if (respondeSolicitacaoCall.statusCode == 200) {
return true;
if (apiCallResponse.statusCode == 200) {
return !apiCallResponse.jsonBody['error'];
} 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;
}
}
@ -401,7 +387,6 @@ Future<bool> checkLocals({
// Verificação rápida de erro para evitar processamento desnecessário.
if (response.jsonBody['error']) {
log("checkLocals => Erro encontrado na resposta");
return false;
}
@ -413,10 +398,8 @@ Future<bool> checkLocals({
// 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,
@ -439,54 +422,50 @@ Future<bool> checkLocals({
}
}
Future answersRequest(BuildContext context, String? ref, String? task,
String? response, String? id) async {
ApiCallResponse? respondeSolicitacaoCall;
respondeSolicitacaoCall = await PhpGroup.respondeSolicitacaoCall.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliUUID: FFAppState().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,
String status,
String vawREF,
String msg,
String vteUUID,
int idDestino,
int idVisita,
String accessKey,
String email,
) async {
log('status: $status');
Navigator.pop(context, true);
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;
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;
}
}
@ -497,8 +476,6 @@ Uint8List assembleQRPacket(int direction, String identifier, String password) {
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));
}
@ -540,8 +517,6 @@ Uint8List assembleQRPacket(int direction, String identifier, String password) {
var bytes =
packet.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join((' '));
log("Pacote: $packet");
log("Bytes: $bytes");
return Uint8List.fromList(packet);
}
@ -577,7 +552,6 @@ Widget buildQrCode(
required String pass,
required int direction}) {
try {
log("pass: $pass");
const Color backgroundColor = Colors.white;
const Color foregroundColor = Colors.black;
return QrImageView.withQr(
@ -779,3 +753,22 @@ Future accessQRCodeOptAction(BuildContext context) async {
},
);
}
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;
}
}

View File

@ -20,7 +20,6 @@ class FFAppState extends ChangeNotifier {
return await auth.canCheckBiometrics;
} catch (e) {
clearBiometricAuthentication();
debugPrint('Error checking biometrics: $e');
return false;
}
}
@ -44,8 +43,6 @@ class FFAppState extends ChangeNotifier {
// Salvar o estado de autenticação biométrica, se necessário
}
} catch (e) {
print(e);
debugPrint('Error authenticating: $e');
clearBiometricAuthentication();
return Future.error(e);
}

View File

@ -12,7 +12,6 @@ export 'api_manager.dart' show ApiCallResponse;
const _kPrivateApiFunctionName = 'ffPrivateApiCall';
/// Start PHP Group Code
class PhpGroup {
@ -47,6 +46,128 @@ class PhpGroup {
static ChangeNotifica changeNotifica = ChangeNotifica();
static RespondeVinculo resopndeVinculo = RespondeVinculo();
static ChangePass changePass = ChangePass();
static ChangePanic changePanic = ChangePanic();
static DeleteAccount deleteAccount = DeleteAccount();
static CancelaVisita cancelaVisita = CancelaVisita();
}
class CancelaVisita {
Future<ApiCallResponse> call({
String? devUUID = '',
String? userUUID = '',
String? cliID = '',
String? atividade = '',
int? idDestino,
int? idVisita,
String? AccessKey = '',
String? UsuEmail = '',
String? DevDesc = '',
}) async {
final baseUrl = PhpGroup.getBaseUrl();
return ApiManager.instance.makeApiCall(
callName: 'cancelaVisita',
apiUrl: '$baseUrl/processRequest.php',
callType: ApiCallType.POST,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
params: {
'devUUID': devUUID,
'userUUID': userUUID,
'atividade': atividade,
'cliID': cliID,
'idVisita': idVisita,
'AccessKey': AccessKey,
'UsuEmail': UsuEmail,
'DevDesc': DevDesc,
},
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
alwaysAllowBody: false,
);
}
bool? error(dynamic response) => castToType<bool>(getJsonField(
response,
r'''$.error''',
));
}
class DeleteAccount {
Future<ApiCallResponse> call({
String? devUUID = '',
String? userUUID = '',
}) async {
final baseUrl = PhpGroup.getBaseUrl();
return ApiManager.instance.makeApiCall(
callName: 'deleteAccount',
apiUrl: '$baseUrl/deleteAccount.php',
callType: ApiCallType.POST,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
params: {
'devUUID': devUUID,
'userUUID': userUUID,
},
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
isStreamingApi: false,
alwaysAllowBody: false,
);
}
bool? error(dynamic response) => castToType<bool>(getJsonField(
response,
r'''$.error''',
));
}
class ChangePanic {
Future<ApiCallResponse> call({
String? devUUID = '',
String? userUUID = '',
String? cliID = '',
String? atividade = '',
String? newSenhaPanico = '',
}) async {
final baseUrl = PhpGroup.getBaseUrl();
return ApiManager.instance.makeApiCall(
callName: 'changePass',
apiUrl: '$baseUrl/processRequest.php',
callType: ApiCallType.POST,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
params: {
'devUUID': devUUID,
'userUUID': userUUID,
'cliID': cliID,
'atividade': atividade,
'newSenhaPanico': newSenhaPanico,
},
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
isStreamingApi: false,
alwaysAllowBody: false,
);
}
bool? error(dynamic response) => castToType<bool>(getJsonField(
response,
r'''$.error''',
));
}
class ChangePass {
@ -96,31 +217,30 @@ class RespondeVinculo {
String? cliID = '',
String? tarefa = '',
}) async {
final baseUrl = PhpGroup.getBaseUrl();
final baseUrl = PhpGroup.getBaseUrl();
return ApiManager.instance.makeApiCall(
callName: 'respondeVinculo',
apiUrl: '$baseUrl/processRequest.php',
callType: ApiCallType.POST,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
params: {
'devUUID': devUUID,
'userUUID': userUUID,
'cliID': cliID,
'tarefa': tarefa,
},
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
isStreamingApi: false,
alwaysAllowBody: false,
);
return ApiManager.instance.makeApiCall(
callName: 'respondeVinculo',
apiUrl: '$baseUrl/responderVinculo.php',
callType: ApiCallType.POST,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
params: {
'devUUID': devUUID,
'userUUID': userUUID,
'cliID': cliID,
'tarefa': tarefa,
},
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
isStreamingApi: false,
alwaysAllowBody: false,
);
}
}
class ChangeNotifica {
@ -2405,9 +2525,7 @@ String _serializeList(List? list) {
try {
return json.encode(list, toEncodable: _toEncodable);
} catch (_) {
if (kDebugMode) {
log("List serialization failed. Returning empty list.");
}
if (kDebugMode) {}
return '[]';
}
}
@ -2417,9 +2535,7 @@ String _serializeJson(dynamic jsonVar, [bool isList = false]) {
try {
return json.encode(jsonVar, toEncodable: _toEncodable);
} catch (_) {
if (kDebugMode) {
log("Json serialization failed. Returning empty json.");
}
if (kDebugMode) {}
return isList ? '[]' : '{}';
}
}

View File

@ -2,6 +2,7 @@
import 'dart:convert';
import 'dart:core';
import 'dart:developer';
import 'dart:io';
import 'dart:typed_data';
@ -15,9 +16,6 @@ import '/flutter_flow/uploaded_file.dart';
import 'get_streamed_response.dart';
enum ApiCallType {
GET,
POST,
@ -413,6 +411,7 @@ class ApiManager {
ApiCallOptions? options,
http.Client? client,
}) async {
final callOptions = options ??
ApiCallOptions(
callName: callName,

View File

@ -4,8 +4,6 @@ import 'dart:developer';
import 'dart:io';
import 'dart:math' as math;
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -17,11 +15,16 @@ import 'package:hub/backend/api_requests/api_manager.dart';
import 'package:hub/components/templates_components/access_notification_modal_template_component/access_notification_modal_template_component_widget.dart';
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
import 'package:hub/components/templates_components/message_notificaion_modal_template_component/message_notification_widget.dart';
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'package:rxdart/rxdart.dart';
//
class PushNotificationService {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
@ -57,10 +60,7 @@ class PushNotificationService {
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
log('User granted permission');
} else {
log('User declined or has not accepted permission');
}
} else {}
}
Map<String, dynamic> validJsonFromString(String? jsonString) {
@ -99,13 +99,10 @@ class PushNotificationService {
// Passo 4: Decodificar o JSON corrigido
return jsonDecode(correctedJson);
} catch (e) {
log('Error decoding JSON: $e');
return {};
}
}
void _initializeLocalNotifications(
BehaviorSubject<BuildContext> context) async {
while (context.valueOrNull == null) {
@ -126,18 +123,12 @@ class PushNotificationService {
_flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) async {
log('Response payload:${response.payload}');
if (response.payload != null) {
try {
Map<String, dynamic> message =
validJsonFromString(response.payload!);
log('Notification payload: $message');
Map<String, dynamic> message = validJsonFromString(response.payload!);
var data = _notificationDetails; // Assuming getOnMessage() now returns the latest RemoteMessage
log('Extra: ${data.value}');
_handleNotificationClick(message, extra: data.value);
} catch (e) {
log('Error decoding notification payload: $e');
}
_handleNotificationClick(message, extra: data.value);
} catch (e) {}
}
},
);
@ -173,8 +164,7 @@ class PushNotificationService {
void _listenToForegroundMessages(BuildContext context) {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
log('Got a message whilst in the foreground!');
log('Message data: ${message.toMap()}');
log("Message Foregroud: ${message.data}");
_onMessage.add(message);
_notificationDetails.add(message.toMap()['notification']);
_showNotification(message);
@ -187,31 +177,25 @@ class PushNotificationService {
void _listenToNotificationClicks(BuildContext context) {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
log('Notification clicked!');
_onMessage.add(message);
log('Extra: ${message.notification?.body}');
NotificationHandler().handleMessage(message.data, context); });
NotificationHandler().handleMessage(message.data, context);
});
}
void configureTokenRefresh() {
_firebaseMessaging.onTokenRefresh.listen(_handleTokenUpdate).onError((err) {
log("Error refreshing token: $err");
});
_firebaseMessaging.onTokenRefresh
.listen(_handleTokenUpdate)
.onError((err) {});
}
Future<void> _updateToken(String token) async {
FFAppState().token = token;
final ApiCallResponse? response = await _updateTokenOnServer(token);
if (_isTokenUpdateSuccessful(response)) {
log('Token updated successfully on server. Token: $token');
} else {
log('Error updating token on server');
}
} else {}
}
Future<void> _handleTokenUpdate(String newToken) async {
log('Token refreshed: $newToken');
await _updateToken(newToken);
}
@ -224,11 +208,8 @@ class PushNotificationService {
final String? deviceToken = await _firebaseMessaging.getToken();
if (deviceToken != null) {
log('Push Messaging token: $deviceToken');
await _updateToken(deviceToken);
} else {
log('Failed to get Firebase Messaging token');
}
} else {}
}
Future<NotificationSettings> _requestNotificationPermission() async {
@ -278,10 +259,8 @@ class PushNotificationService {
priority: Priority.high,
);
var iOSDetails = DarwinNotificationDetails();
var generalNotificationDetails =
NotificationDetails(android: androidDetails, iOS: iOSDetails);
var generalNotificationDetails = NotificationDetails(android: androidDetails, iOS: iOSDetails);
log('Showing notification: ${message.messageId.hashCode}');
await _flutterLocalNotificationsPlugin.show(
// DateTime.now().millisecondsSinceEpoch % (1 << 31),
math.Random().nextInt(1 << 30),
@ -292,39 +271,32 @@ class PushNotificationService {
);
}
_handleNotificationClick(Map<String, dynamic> payload, {Map<String, dynamic> extra = const {}}) {
_handleNotificationClick(Map<String, dynamic> payload,
{Map<String, dynamic> extra = const {}}) {
switch (payload.isNotEmpty) {
case true:
// Print the 'data' property
log('Notification payload: $payload');
log('Extra: $extra');
// Handle the message data as needed
NotificationHandler().handleMessage(payload, _context.value, extra: extra.isEmpty ? {} : extra);
// Access the 'data' property of 'RemoteMessage'
case false:
log('Notification payload is empty');
// Handle the message notification as needed
break;
}
}
static Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message) async {
log('Handling a background message: ${message.messageId}');
static Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
log("Mensagem firebase: $message");
}
}
class NotificationHandler {
void handleMessage(Map<String, dynamic> message, BuildContext context, {Map<String, dynamic> extra = const {}}) {
log('Notification Received!');
message.forEach((key, value) {
log('$key: $value');
});
message.forEach((key, value) {});
switch (message['click_action']) {
case 'visit_request':
_showVisitRequestDialog(message, context);
break;
case '':
break;
@ -332,13 +304,12 @@ class NotificationHandler {
_showAcessNotificationModal(message, context);
break;
case 'mensagem':
_showMessageNotificationDialog(message, context, extra);
log("Extra Handle Message: $extra");
_showMessageNotificationDialog(message, context, extra);
break;
case 'enroll_cond':
log('enroll_cond');
break;
default:
log('Notification type not recognized');
}
}
@ -358,10 +329,6 @@ class NotificationHandler {
void _showAcessNotificationModal(
Map<String, dynamic> message, BuildContext context) {
log('Showing access notification dialog');
log('USR_TIPO: ${message['USR_TIPO']}');
log('USR_ID: ${message['USR_ID']}');
log('USR_DOCUMENTO: ${message['USR_DOCUMENTO']}');
showDialog(
context: context,
builder: (BuildContext context) {
@ -385,46 +352,199 @@ class NotificationHandler {
);
}
void _showMessageNotificationDialog(
Map<String, dynamic> message, BuildContext context, Map<String, dynamic> extra) {
log('Showing message notification dialog');
log('Notification "message": $message');
void _showMessageNotificationDialog(Map<String, dynamic> message, BuildContext context, Map<String, dynamic> extra) {
showDialog(
useSafeArea: true,
barrierDismissible: true,
context: context,
builder: (BuildContext context) {
return Dialog(
backgroundColor: Colors.transparent,
child: MessageNotificationModalTemplateComponentWidget(
id: message['local']['CLI_ID'].toString(),
from: message['remetente'].toString(),
to: message['destinatario'].toString() == 'O' ? 'Morador' : 'Visitante',
message: extra['body'].toString().isEmpty ? 'Unknown' : extra['body'].toString(),
String localId = '';
try {
localId = jsonDecode(message['local'])['CLI_ID'];
} catch(e, s) {
localId = message['local']['CLI_ID'].toString();
}
log("Mensagem: $message");
log("Extra: $extra");
return GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Dialog(
backgroundColor: Colors.transparent,
child: GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: MessageNotificationModalTemplateComponentWidget(
id: localId,
from: message['remetente'].toString(),
to: message['destinatario'].toString() == 'O'
? 'Morador'
: 'Visitante',
message: extra['body'].toString().isEmpty
? 'Unknown'
: extra['body'].toString(),
),
),
),
),
),
);
},
);
}
void _showVisitRequestDialog(
Map<String, dynamic> message, BuildContext context) {
log('Showing visit request notification dialog');
showDialog(
context: context,
barrierDismissible: true,
// barrierColor: Colors.green,
builder: (BuildContext context) {
_getIdBasedOnUserType(message);
return Dialog(
backgroundColor: Colors.transparent,
child: DetailsComponentWidget(
vteName: message['mensagem'] ?? 'Unknown',
vteReason: message['motivo'] ?? 'Unknown',
vteMsg: message['mensagem'] ?? 'Unknown',
vteDocument: message['documento'] ?? '',
vteUUID: message['idVisitante'].toString(),
vawRef: message['referencia'].toString(),
vawStatus: 'S',
changeStatusAction: changeStatusAction,
buttons: [
FlutterFlowIconButton(
icon: const Icon(Icons.done),
onPressed: () async {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Aprovar Visita',
enText: 'Approve Visit',
),
),
content: Text(
FFLocalizations.of(context).getVariableText(
ptText:
'Você tem certeza que deseja aprovar essa visita?',
enText:
'Are you sure you want to approve this visit?',
),
),
backgroundColor:
FlutterFlowTheme.of(context).primaryBackground,
actions: [
FFButtonWidget(
text: FFLocalizations.of(context).getVariableText(
enText: 'No',
ptText: 'Não',
),
onPressed: () {
Navigator.pop(context);
},
options: FFButtonOptions(
width: 100,
height: 40,
color: FlutterFlowTheme.of(context)
.primaryBackground,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context)
.primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context)
.primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10)),
),
FFButtonWidget(
text: FFLocalizations.of(context).getVariableText(
enText: 'Yes',
ptText: 'Sim',
),
onPressed: () async {
await answersRequest.call(
context,
message['referencia'].toString(),
'L',
'Mensagem',
message['idVisitante'].toString(),
);
},
options: FFButtonOptions(
width: 100,
height: 40,
color: FlutterFlowTheme.of(context)
.primaryBackground,
textStyle: TextStyle(
color:
FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context)
.primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
),
],
);
});
},
),
FlutterFlowIconButton(
icon: const Icon(Icons.close),
onPressed: () async {
showAlertDialog(
context,
FFLocalizations.of(context).getVariableText(
ptText: 'Bloquear Visita',
enText: 'Block Visit',
),
FFLocalizations.of(context).getVariableText(
ptText:
'Você tem certeza que deseja bloquear essa visita?',
enText: 'Are you sure you want to block this visit?',
), () async {
await answersRequest.call(
context,
message['referencia'].toString(),
'B',
'Mensagem',
message['idVisitante'].toString(),
);
});
},
),
],
labelsHashMap: Map<String, String>.from({
FFLocalizations.of(context).getVariableText(
enText: 'Visitor',
ptText: 'Visitante',
): message['nomevisita'],
FFLocalizations.of(context).getVariableText(
enText: 'Reason',
ptText: 'Motivo',
): message['motivo'],
FFLocalizations.of(context).getVariableText(
enText: 'Message',
ptText: 'Mensagem',
): message['mensagem'],
}),
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${message['documento'] ?? ''}&tipo=E',
statusHashMap: [
{
FFLocalizations.of(context).getVariableText(
enText: 'Active',
ptText: 'Ativo',
): FlutterFlowTheme.of(context).warning,
},
],
// changeStatusAction: answersRequest,
),
);
},
@ -448,6 +568,4 @@ class PushNotificationManager {
void dispose() {
_onMessageReceivedController.close();
}
}

View File

@ -1,90 +1 @@
// import 'package:f_r_e_hub/components/templates_components/visit_request_template_component/visit_request_template_component_widget.dart';
// import 'package:firebase_messaging/firebase_messaging.dart';
// import 'package:flutter/material.dart';
// import 'package:rxdart/rxdart.dart';
// class NotificationHandler {
// // Criar BehaviorSubjects para mensagens em primeiro plano e mensagens que abriram o app
// final BehaviorSubject<RemoteMessage> _onMessage =
// BehaviorSubject<RemoteMessage>();
// final BehaviorSubject<RemoteMessage> _onMessageOpenedApp =
// BehaviorSubject<RemoteMessage>();
// // Inicializar listeners no construtor
// NotificationHandler() {
// initializeListeners();
// }
// void initializeListeners() async {
// // Listener para mensagens em primeiro plano
// // FirebaseMessaging.onMessage.listen((message) {
// // _onMessage.add(message); // Adicionar mensagem ao stream
// // });
// RemoteMessage? initialMessage =
// await FirebaseMessaging.instance.getInitialMessage();
// if (initialMessage != null) _onMessage.add(initialMessage);
// // Listener para mensagens que abriram o app
// FirebaseMessaging.onMessageOpenedApp.listen((message) {
// _onMessageOpenedApp.add(message); // Adicionar mensagem ao stream
// });
// }
// void openedAppVisitRequestNotification(
// RemoteMessage message, BuildContext context) {
// log('openedAppVisitRequestNotification');
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return Dialog(
// backgroundColor:
// Colors.transparent, // Faz o fundo do Dialog ser transparente
// child: VisitRequestTemplateComponentWidget(
// name: message.data['nome'] ?? 'blabla',
// reason: message.data['motivo'] ?? 'blabla',
// message: message.data['mensagem'] ?? 'blabla',
// document: message.data['document']),
// );
// });
// }
// // Método para tratar mensagens recebidas
// void handleMessage(RemoteMessage message, BuildContext context) {
// log('Notification Received!');
// message.data.forEach((key, value) {
// log('$key: $value');
// });
// switch (message.data['type']) {
// case 'visit_request':
// openedAppVisitRequestNotification(message, context);
// break;
// case '':
// break;
// default:
// log('Notification type not recognized');
// }
// }
// // Ouvir streams
// void listenToNotifications(BuildContext context) {
// _onMessage.listen((message) {
// handleMessage(message, context);
// });
// _onMessageOpenedApp.listen((message) {
// handleMessage(message, context);
// });
// }
// // Dispor streams
// void dispose() {
// _onMessage.close();
// _onMessageOpenedApp.close();
// }
// }

View File

@ -93,7 +93,6 @@ class _ThrowExceptionWidgetState extends State<ThrowExceptionWidget>
case EnumThrowException.success:
return FFLocalizations.of(context)
.getVariableText(ptText: "Sucesso ;)", enText: "Success ;)");
;
}
}

View File

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:hub/components/molecular_components/visitor_not_found_component/visitor_not_found_component_model.dart';
import 'package:hub/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_widget.dart';
import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
@ -9,8 +11,9 @@ import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
class VisitorNotFoundComponentWidget extends StatefulWidget {
const VisitorNotFoundComponentWidget({super.key});
const VisitorNotFoundComponentWidget({this.doc, Key? key}) : super(key: key);
final String? doc;
@override
State<VisitorNotFoundComponentWidget> createState() =>
_VisitorNotFoundComponentWidgetState();
@ -41,138 +44,144 @@ class _VisitorNotFoundComponentWidgetState
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.height * 0.5,
height: MediaQuery.of(context).size.height * 0.4,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(25.0),
bottomRight: Radius.circular(25.0),
topLeft: Radius.circular(25.0),
topRight: Radius.circular(25.0),
return SingleChildScrollView(
child: Container(
// width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(25.0),
bottomRight: Radius.circular(25.0),
topLeft: Radius.circular(25.0),
topRight: Radius.circular(25.0),
),
),
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Align(
alignment: const AlignmentDirectional(1.0, -1.0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 5.0, 5.0, 0.0),
child: FlutterFlowIconButton(
borderRadius: 20.0,
borderWidth: 1.0,
buttonSize: 40.0,
icon: Icon(
Icons.close,
color: FlutterFlowTheme.of(context).accent1,
size: 24.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Align(
alignment: const AlignmentDirectional(1.0, -1.0),
child: Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(0.0, 5.0, 5.0, 0.0),
child: FlutterFlowIconButton(
borderRadius: 20.0,
borderWidth: 1.0,
buttonSize: 40.0,
icon: Icon(
Icons.close,
color: FlutterFlowTheme.of(context).accent1,
size: 24.0,
),
onPressed: () async {
Navigator.pop(context);
},
),
onPressed: () async {
Navigator.pop(context);
},
),
),
),
Icon(
Icons.notifications_none,
color: FlutterFlowTheme.of(context).accent1,
size: 72.0,
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 16.0, 0.0, 0.0),
child: Text(
FFLocalizations.of(context).getText(
'1p9mykbj' /* Usuário não encontrado */,
),
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily:
FlutterFlowTheme.of(context).headlineMediumFamily,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).headlineMediumFamily),
),
Icon(
Icons.notifications_none,
color: FlutterFlowTheme.of(context).accent1,
size: 72.0,
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(20.0, 4.0, 20.0, 0.0),
child: Text(
FFLocalizations.of(context).getText(
'kt937sp6' /* O documento inserido não corre... */,
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(0.0, 16.0, 0.0, 0.0),
child: Text(
FFLocalizations.of(context).getText(
'1p9mykbj' /* Usuário não encontrado */,
),
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily:
FlutterFlowTheme.of(context).headlineMediumFamily,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).headlineMediumFamily),
),
),
style: FlutterFlowTheme.of(context).labelMedium.override(
fontFamily: FlutterFlowTheme.of(context).labelMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontStyle: FontStyle.italic,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).labelMediumFamily),
),
),
),
Expanded(
child: Align(
alignment: const AlignmentDirectional(0.0, 1.0),
child: FFButtonWidget(
onPressed: () async {
Navigator.pop(context);
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
enableDrag: true,
useSafeArea: true,
isDismissible: true,
context: context,
builder: (context) {
return Padding(
padding: MediaQuery.viewInsetsOf(context),
child: SizedBox(
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(20.0, 4.0, 20.0, 0.0),
child: Text(
FFLocalizations.of(context).getText(
'kt937sp6' /* O documento inserido não corre... */,
),
style: FlutterFlowTheme.of(context).labelMedium.override(
fontFamily:
FlutterFlowTheme.of(context).labelMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontStyle: FontStyle.italic,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).labelMediumFamily),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Align(
alignment: const AlignmentDirectional(0.0, 1.0),
child: FFButtonWidget(
onPressed: () async {
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
enableDrag: true,
useSafeArea: true,
isDismissible: true,
context: context,
builder: (context) {
return Padding(
padding: MediaQuery.viewInsetsOf(context),
child: SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.9,
child: const RegisiterVistorTemplateComponentWidget(
child: RegisiterVistorTemplateComponentWidget(
source: 'VisitorNotFoundComponent',
)),
);
},
).then((value) => safeSetState(() {}));
},
text: FFLocalizations.of(context)
.getVariableText(enText: 'Add', ptText: 'Adicionar'),
options: FFButtonOptions(
width: double.infinity,
height: 30.0,
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
iconPadding:
const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0),
color: FlutterFlowTheme.of(context).primary,
textStyle: FlutterFlowTheme.of(context).titleSmall.override(
fontFamily:
FlutterFlowTheme.of(context).titleSmallFamily,
color: Colors.white,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).titleSmallFamily),
),
elevation: 3.0,
borderSide: const BorderSide(
color: Colors.transparent,
width: 1.0,
),
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(25.0),
bottomRight: Radius.circular(25.0),
topLeft: Radius.circular(15.0),
topRight: Radius.circular(15.0),
doc: _model.widget?.doc,
),
),
);
},
).then((value) => Navigator.pop(context, value));
},
text: FFLocalizations.of(context)
.getVariableText(enText: 'Add', ptText: 'Adicionar'),
options: FFButtonOptions(
height: 30.0,
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
iconPadding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 0.0, 0.0),
color: FlutterFlowTheme.of(context).primary,
textStyle: FlutterFlowTheme.of(context).titleSmall.override(
fontFamily:
FlutterFlowTheme.of(context).titleSmallFamily,
color: Colors.white,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).titleSmallFamily),
),
elevation: 3.0,
borderSide: const BorderSide(
color: Colors.transparent,
width: 1.0,
),
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(25.0),
bottomRight: Radius.circular(25.0),
topLeft: Radius.circular(25.0),
topRight: Radius.circular(25.0),
),
),
),
),
),
),
],
],
),
),
);
}

View File

@ -10,7 +10,6 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:provider/provider.dart';
class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget {
const BottomArrowLinkedLocalsComponentWidget({super.key});
@ -100,9 +99,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
color: FlutterFlowTheme.of(context).primary,
size: 24.0,
),
onPressed: () {
print('IconButton pressed ...');
},
onPressed: () {},
),
),
Expanded(
@ -180,8 +177,8 @@ class _BottomArrowLinkedLocalsComponentWidgetState
width: 50.0,
height: double.infinity,
decoration: const BoxDecoration(),
alignment:
const AlignmentDirectional(0.0, 0.0),
alignment: const AlignmentDirectional(
0.0, 0.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
@ -232,14 +229,15 @@ class _BottomArrowLinkedLocalsComponentWidgetState
width: double.infinity,
height: double.infinity,
fit: BoxFit.fill,
alignment:
const Alignment(0.0, 0.0),
alignment: const Alignment(
0.0, 0.0),
),
),
),
Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(
padding:
const EdgeInsetsDirectional
.fromSTEB(
0.0, 10.0, 0.0, 0.0),
child: Text(
getJsonField(

View File

@ -1,4 +1,3 @@
import '/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
@ -12,10 +11,7 @@ export 'local_profile_component_model.dart';
////
class LocalProfileComponentWidget extends StatefulWidget {
const LocalProfileComponentWidget({
required bool localStatus,
super.key
});
const LocalProfileComponentWidget({required bool localStatus, super.key});
@override
State<LocalProfileComponentWidget> createState() =>
@ -87,35 +83,34 @@ class _LocalProfileComponentWidgetState
padding: MediaQuery.viewInsetsOf(context),
child: const SizedBox(
height: double.infinity,
child:
BottomArrowLinkedLocalsComponentWidget(),
child: BottomArrowLinkedLocalsComponentWidget(),
),
);
},
).then((value) => safeSetState(() {}));
},
child: ClipRRect(
borderRadius: BorderRadius.circular(200.0),
child:
Image.network(
'https://freaccess.com.br/freaccess/Images/Clients/${FFAppState().cliUUID}.png',
width: 80.0,
height: 80.0,
fit: BoxFit.cover,
alignment: const Alignment(0.0, 0.0),
errorBuilder: (context, error, stackTrace) => Image.network(
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
borderRadius: BorderRadius.circular(200.0),
child: Image.network(
'https://freaccess.com.br/freaccess/Images/Clients/${FFAppState().cliUUID}.png',
width: 80.0,
height: 80.0,
fit: BoxFit.cover,
alignment: const Alignment(0.0, 0.0),
errorBuilder: (context, error, stackTrace) => Image.asset('assets/images/error_image.svg'),
),
)
),
),
errorBuilder: (context, error, stackTrace) =>
Image.network(
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
width: 80.0,
height: 80.0,
fit: BoxFit.cover,
alignment: const Alignment(0.0, 0.0),
errorBuilder: (context, error, stackTrace) =>
Image.asset('assets/images/error_image.svg'),
),
)),
),
),
),
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
@ -125,16 +120,15 @@ class _LocalProfileComponentWidgetState
functions.convertToUppercase(FFAppState().local),
'NOME DO LOCAL',
),
style:
FlutterFlowTheme.of(context).labelMedium.override(
fontFamily: 'Nunito',
color: FlutterFlowTheme.of(context).info,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts:
GoogleFonts.asMap().containsKey('Nunito'),
),
style: FlutterFlowTheme.of(context).labelMedium.override(
fontFamily: 'Nunito',
color: FlutterFlowTheme.of(context).info,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts:
GoogleFonts.asMap().containsKey('Nunito'),
),
),
],
),

View File

@ -13,17 +13,16 @@ import 'package:flutter/material.dart';
import 'menu_component_model.dart';
export 'menu_component_model.dart';
class MenuComponentWidget extends StatefulWidget {
const MenuComponentWidget({
Key? key,
required this.style,
required this.item,
required this.expandable,
});
final MenuView style;
final MenuItem item;
final bool expandable;
Key? key,
required this.style,
required this.item,
required this.expandable,
});
final MenuView style;
final MenuItem item;
final bool expandable;
@override
State<MenuComponentWidget> createState() => _MenuComponentWidgetState();
}
@ -31,11 +30,8 @@ class MenuComponentWidget extends StatefulWidget {
class _MenuComponentWidgetState extends State<MenuComponentWidget> {
late MenuComponentModel _model;
@override
void setState(VoidCallback callback) {
super.setState(callback);
_model.onUpdate();
}
@ -44,7 +40,6 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
void initState() {
super.initState();
_model = createModel(context, () => MenuComponentModel());
}
@override
@ -57,43 +52,165 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
@override
Widget build(BuildContext context) {
final options = widget.item == MenuItem.button
? <MenuEntry>[
MenuButtonWidget(icon: FFIcons.kvector1, action: () async { await _model.scheduleVisitOptAction(context);setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Schedule\nVisit' , ptText:'Agendar\nVisita' ,),),
? <MenuEntry>[
MenuButtonWidget(
icon: FFIcons.kvector1,
action: () async {
await _model.scheduleVisitOptAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Schedule\nVisit',
ptText: 'Agendar\nVisita',
),
),
MenuButtonWidget(icon: FFIcons.khome, action: () async {await _model.registerVisitorOptAction(context); setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Register\nVisitor' , ptText:'Cadastro\nde Visitante' ,),),
MenuButtonWidget(
icon: FFIcons.khome,
action: () async {
await _model.registerVisitorOptAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Register\nVisitor',
ptText: 'Cadastro\nde Visitante',
),
),
// MenuButtonWidget(icon: FFIcons.kvector2, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Link\nCondominum' , ptText:'' ,),),
// MenuButtonWidget(icon: FFIcons.kpets, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Register\Pet' , ptText:'' ,),),
// MenuButtonWidget(icon: FFIcons.kvector2, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Link\nCondominum' , ptText:'' ,),),
// MenuButtonWidget(icon: FFIcons.kpets, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Register\Pet' , ptText:'' ,),),
MenuButtonWidget(icon: Icons.qr_code, action: () async {await _model.accessQRCodeOptAction(context); setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'QRCode\nAccess' , ptText:'QRCode\nde Acesso' ,),),
MenuButtonWidget(
icon: Icons.qr_code,
action: () async {
await _model.accessQRCodeOptAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'QRCode\nAccess',
ptText: 'QRCode\nde Acesso',
),
),
MenuButtonWidget(icon: Icons.people, action: () async {await _model.peopleOnThePropertyAction(context); setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Poeple on\nthe Property' , ptText:'Pessoas na\nPropriedade' ,),),
MenuButtonWidget(
icon: Icons.people,
action: () async {
await _model.peopleOnThePropertyAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Poeple on\nthe Property',
ptText: 'Pessoas na\nPropriedade',
),
),
MenuButtonWidget(icon: Icons.history_sharp, action: () async {await _model.liberationHistoryOptAction(context);setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Consult\nHistories' , ptText:'Consultar\nHistóricos' ,),),
MenuButtonWidget(
icon: Icons.history_sharp,
action: () async {
await _model.liberationHistoryOptAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Consult\nHistories',
ptText: 'Consultar\nHistóricos',
),
),
MenuButtonWidget(icon: Icons.settings, action: () async {await _model.preferencesSettings(context);setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Preferences\nSettings' , ptText:'Configurações' ,),),
] : <MenuEntry>[
MenuCardItem(icon: FFIcons.kvector1, action: () async { await _model.scheduleVisitOptAction(context);setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Schedule Visit' , ptText:'Agendar\nVisita' ,),),
MenuButtonWidget(
icon: Icons.settings,
action: () async {
await _model.preferencesSettings(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Preferences\nSettings',
ptText: 'Preferências \nde Configurações',
),
),
]
: <MenuEntry>[
MenuCardItem(
icon: FFIcons.kvector1,
action: () async {
await _model.scheduleVisitOptAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Schedule\nVisit',
ptText: 'Agendar\nVisita',
),
),
MenuCardItem(icon: FFIcons.khome, action: () async {await _model.registerVisitorOptAction(context); setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Register Visitor' , ptText:'Cadastro de Visitante' ,),),
MenuCardItem(
icon: FFIcons.khome,
action: () async {
await _model.registerVisitorOptAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Register\nVisitor',
ptText: 'Cadastro\nde Visitante',
),
),
// MenuCardItem(icon: FFIcons.kvector2, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Link Condominum' , ptText:'' ,),),
// MenuCardItem(icon: FFIcons.kpets, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Register\Pet' , ptText:'' ,),),
// MenuCardItem(icon: FFIcons.kvector2, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Link Condominum' , ptText:'' ,),),
// MenuCardItem(icon: FFIcons.kpets, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Register\Pet' , ptText:'' ,),),
MenuCardItem(icon: Icons.qr_code, action: () async {await _model.accessQRCodeOptAction(context); setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'QRCode Access' , ptText:'QRCode de Acesso' ,),),
MenuCardItem(
icon: Icons.qr_code,
action: () async {
await _model.accessQRCodeOptAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'QRCode\nAccess',
ptText: 'QRCode\nde Acesso',
),
),
MenuCardItem(icon: Icons.people, action: () async {await _model.peopleOnThePropertyAction(context); setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Poeple on the Property' , ptText:'Pessoas na Propriedade' ,),),
MenuCardItem(
icon: Icons.people,
action: () async {
await _model.peopleOnThePropertyAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Poeple on\nthe Property',
ptText: 'Pessoas\nna Propriedade',
),
),
MenuCardItem(icon: Icons.history_sharp, action: () async {await _model.liberationHistoryOptAction(context);setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Consult Histories' , ptText:'Consultar Historicos' ,),),
MenuCardItem(
icon: Icons.history_sharp,
action: () async {
await _model.liberationHistoryOptAction(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Consult\nHistories',
ptText: 'Consultar\nHistoricos',
),
),
MenuCardItem(icon: Icons.settings, action: () async {await _model.preferencesSettings(context);setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Preferences Settings' , ptText:'Configurações' ,),),
];
MenuCardItem(
icon: Icons.settings,
action: () async {
await _model.preferencesSettings(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Preferences\nSettings',
ptText: 'Preferências\nde Configuração',
),
),
];
return Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 10.0, 0.0, 0.0),
child: Builder(
builder: (context) {
if (widget.style == MenuView.list_grid && widget.expandable == true && widget.item == MenuItem.button) {
if (widget.style == MenuView.list_grid &&
widget.expandable == true &&
widget.item == MenuItem.button) {
if (_model.isGrid == true) {
return wrapWithModel(
model: _model.menuListViewComponentModel,
@ -126,21 +243,23 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
);
}
}
if (widget.style == MenuView.list && widget.expandable == false && widget.item == MenuItem.card){
return wrapWithModel(
model: _model.menuListViewComponentModel,
updateCallback: () => setState(() {}),
updateOnChange: true,
child: MenuListViewComponentWidget(
options: options,
expandable: widget.expandable,
item: widget.item,
changeMenuStyle: () async {
await _model.changeMenuStyle(context);
setState(() {});
},
),
);
if (widget.style == MenuView.list &&
widget.expandable == false &&
widget.item == MenuItem.card) {
return wrapWithModel(
model: _model.menuListViewComponentModel,
updateCallback: () => setState(() {}),
updateOnChange: true,
child: MenuListViewComponentWidget(
options: options,
expandable: widget.expandable,
item: widget.item,
changeMenuStyle: () async {
await _model.changeMenuStyle(context);
setState(() {});
},
),
);
}
return const SizedBox();
},
@ -148,7 +267,7 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
);
}
Future accessQRCodeOptAction(BuildContext context) async {
Future accessQRCodeOptAction(BuildContext context) async {
context.pushNamed(
'qrCodePage',
extra: <String, dynamic>{
@ -160,6 +279,4 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
},
);
}
}

View File

@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:collection';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -14,7 +13,6 @@ import 'package:rxdart/rxdart.dart';
//
final dropdown = BehaviorSubject<LinkedHashMap<String, String>>.seeded(
LinkedHashMap.from({
'All': 'A',
@ -82,7 +80,6 @@ class _MessageWellComponentWidgetState
);
}
Widget _buildMenuMessageWell(BuildContext context, FlutterFlowTheme theme) {
final dropdownItems = LinkedHashMap.from({
'All': 'A',
@ -148,7 +145,8 @@ class _MessageWellComponentWidgetState
fillColor: theme.primary,
),
onChanged: (String? newValue) {
safeSetState(() => dropdown.value = LinkedHashMap.from({newValue!: dropdownItems[newValue].toString()}));
safeSetState(() => dropdown.value = LinkedHashMap.from(
{newValue!: dropdownItems[newValue].toString()}));
},
items: dropdownItems.entries
.map((entry) => DropdownMenuItem<String>(
@ -178,84 +176,138 @@ class _MessageWellComponentWidgetState
);
}
Widget _buildMessageItem(
BuildContext context, dynamic message, int index) {
Widget _buildMessageItem(BuildContext context, dynamic message, int index) {
final theme = FlutterFlowTheme.of(context);
String formatMessageOrigin(String messageOrigin) {
final words = messageOrigin.split(' ');
final formattedWords = words.map((word) {
if (word.isEmpty) return word; // Handle empty words
final firstLetter = word.substring(0, 1).toUpperCase();
final remainingLetters = word.substring(1).toLowerCase();
final remainingLetters =
word.length > 1 ? word.substring(1).toLowerCase() : '';
return '$firstLetter$remainingLetters';
});
return formattedWords.join(' ');
}
return GestureDetector(
onTap: () => {},
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 5, 20, 5),
child: Container(
width: MediaQuery.of(context).size.width * 0.9,
height: 127.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Container(
width: 64.0,
height: 64.0,
decoration: const BoxDecoration(shape: BoxShape.circle),
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Card(
color: FlutterFlowTheme.of(context).primaryBackground,
child: Container(
// height: 100,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Icon(
message['MSG_DESTINO_TP'] == 'T'
? Icons.language
: message['MSG_DESTINO_TP'] == 'P'
? Icons.person
: Icons.home,
color: FlutterFlowTheme.of(context).primary,
size: 25,
),
Expanded(
child: Text(
message['MSG_ORIGEM_DESC'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: FlutterFlowTheme.of(context).primary,
),
overflow: TextOverflow.fade,
),
),
].divide(const SizedBox(width: 10)),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsets.only(left: 5),
child: Icon(
Icons.history,
color:
FlutterFlowTheme.of(context).customColor6,
size: 15,
),
),
Expanded(
child: Text(
message['MSG_DATE'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 10,
color:
FlutterFlowTheme.of(context).customColor6,
),
overflow: TextOverflow.ellipsis,
),
),
].divide(const SizedBox(width: 15)),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsets.only(left: 5),
child: Icon(
Icons.message,
color:
FlutterFlowTheme.of(context).customColor6,
size: 15,
),
),
Expanded(
child: Text(
message['MSG_TEXTO'].toString(),
),
),
].divide(const SizedBox(width: 15)),
),
].divide(const SizedBox(height: 4)),
),
),
// Row(
// children: [
// Icon(
// Icons.message,
// color: FlutterFlowTheme.of(context).customColor6,
// size: 15,
// ),
// Expanded(
// child: Padding(
// padding: const EdgeInsets.all(8.0),
// child: Text(
// message['MSG_TEXTO'].toString(),
// ),
// ),
// ),
// ]
// .addToStart(const SizedBox(width: 8))
// .addToEnd(const SizedBox(width: 8))),
].divide(
const SizedBox(height: 8),
),
),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 8.0),
Center(
child: Text(
'~ ${formatMessageOrigin(message['MSG_ORIGEM_DESC'].toString())}',
style: theme.bodyMedium.copyWith(
fontFamily: 'Nunito Sans',
color: theme.primary,
fontSize: 14.0,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 8.0),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(
formatMessageOrigin(message['MSG_TEXTO'].toString()),
style: theme.bodyMedium.copyWith(
fontFamily: 'Nunito Sans',
color: theme.bodyMedium.color,
fontSize: 14.0,
),
softWrap: true,
maxLines: 10,
),
),
),
],
),
)
],
),
),
),
),
);
));
}
}
class MessageWellState {
@ -277,9 +329,8 @@ class MessageWellState {
return MessageWellState(
messages: messages ?? this.messages,
pageNumber: pageNumber ?? this.pageNumber,
allowScrollInSingleChildScrollView:
allowScrollInSingleChildScrollView ??
this.allowScrollInSingleChildScrollView,
allowScrollInSingleChildScrollView: allowScrollInSingleChildScrollView ??
this.allowScrollInSingleChildScrollView,
);
}
}
@ -300,7 +351,7 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
fetchMessages();
}
void fetchMessages() async {
void fetchMessages() async {
if (state.pageNumber <= totalPageNumber) {
var apiCall = GetMessagesCall();
var response = await apiCall.call(
@ -322,17 +373,14 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
// .toList();
// Provider.of<MessageCounter>(context, listen: false).setCounter(int.parse(response.jsonBody['total_pages']));
// totalPageNumber = int.parse(response.jsonBody['total_pages']);
} else {
log('Error fetching messages: ${response.statusCode}');
}
} else {
log('No more messages to fetch ...');
}
} else {}
} else {}
}
List<dynamic> getMessages() {
return state.messages;
}
void incrementPageNumber() {
if (state.pageNumber <= totalPageNumber) {
state = state.copyWith(pageNumber: state.pageNumber + 1);

View File

@ -40,8 +40,6 @@ class ScheduleVisitDetailModel
String convertDateFormat(String dateStr) {
try {
log('Received date string: $dateStr');
// Formato original
DateFormat originalFormat = DateFormat('d/M/y H:mm:ss');
// Novo formato
@ -50,7 +48,6 @@ class ScheduleVisitDetailModel
// Validate the input string format
if (!RegExp(r'^\d{1,2}/\d{1,2}/\d{4} \d{1,2}:\d{2}:\d{2}$')
.hasMatch(dateStr)) {
log('Invalid date format: $dateStr');
return 'Invalid date format';
}
@ -59,11 +56,9 @@ class ScheduleVisitDetailModel
// Converte DateTime para a nova string formatada
String formattedDate = newFormat.format(dateTime);
log('Formatted date: $formattedDate');
return formattedDate;
} catch (e) {
// Handle the exception by returning an error message or a default value
log('Error parsing date: $e');
return 'Invalid date format';
}
}

View File

@ -19,13 +19,13 @@ class CardItemTemplateComponentWidget extends StatefulWidget {
super.key,
required this.labelsHashMap,
required this.statusHashMap,
required this.imageHashMap,
required this.imagePath,
required this.onTapCardItemAction,
});
final Map<String, String>? labelsHashMap;
final List<Map<String, Color>?> statusHashMap;
final Map<String, String> imageHashMap;
final String? imagePath;
final Future Function()? onTapCardItemAction;
@override
@ -84,7 +84,6 @@ class _CardItemTemplateComponentWidgetState
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
context.watch<FFAppState>();
return InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
@ -97,7 +96,7 @@ class _CardItemTemplateComponentWidgetState
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Card(
clipBehavior: Clip.antiAliasWithSaveLayer,
color: FlutterFlowTheme.of(context).secondaryBackground,
color: FlutterFlowTheme.of(context).primaryBackground,
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
@ -106,7 +105,7 @@ class _CardItemTemplateComponentWidgetState
width: 350.0,
height: 115.0,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
color: FlutterFlowTheme.of(context).primaryBackground,
),
child: Row(
mainAxisSize: MainAxisSize.max,
@ -114,28 +113,27 @@ class _CardItemTemplateComponentWidgetState
children: [
Expanded(
child: Container(
width: 100.0,
height: 100.0,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: const BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: labelsLinkedHashMap.length,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
String key =
labelsLinkedHashMap.keys.elementAt(index);
String value = labelsLinkedHashMap[key]!;
return Padding(
padding:
const EdgeInsets.fromLTRB(0, 2, 0, 5),
child: Padding(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: labelsLinkedHashMap.length,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
String key =
labelsLinkedHashMap.keys.elementAt(index);
String value = labelsLinkedHashMap[key]!;
return Padding(
padding:
const EdgeInsets.fromLTRB(20, 0, 0, 0),
const EdgeInsets.fromLTRB(20, 0, 0, 5),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
@ -166,38 +164,37 @@ class _CardItemTemplateComponentWidgetState
const SizedBox(
width:
5.0), // Espaçamento entre o label e o valor
Text(
truncate(20, value),
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(context)
.bodyMediumFamily,
fontSize: screenWidth * 0.030,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
Flexible(
child: Text(
value,
overflow: TextOverflow.ellipsis,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(
context)
.bodyMediumFamily,
fontSize: 12.5,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
),
),
],
),
),
);
},
);
},
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children:
statusLinkedHashMap.expand((linkedHashMap) {
@ -212,7 +209,7 @@ class _CardItemTemplateComponentWidgetState
padding: const EdgeInsets.symmetric(
horizontal: 1.0, vertical: 3.0),
child: Container(
width: screenWidth * 0.20,
width: 100.0,
height: 27.0,
decoration: BoxDecoration(
color: item
@ -225,7 +222,6 @@ class _CardItemTemplateComponentWidgetState
child: Text(
item.key, // Usa a chave do item atual como texto
style: TextStyle(
fontSize: screenWidth * 0.03,
color: FlutterFlowTheme.of(
context)
.info, // Ajuste conforme necessário
@ -240,8 +236,8 @@ class _CardItemTemplateComponentWidgetState
}).toList();
}).toList(),
),
),
]),
]),
),
),
),
Padding(
@ -249,18 +245,18 @@ class _CardItemTemplateComponentWidgetState
10.0, 10.0, 10.0, 10.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(22.0),
child: CachedNetworkImage(
fadeInDuration: const Duration(milliseconds: 500),
fadeOutDuration: const Duration(milliseconds: 500),
imageUrl: valueOrDefault<String>(
// 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${widget.imageHashMap['key']}&tipo=${widget.imageHashMap['value']}',
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${widget.imageHashMap['key']}&tipo=${widget.imageHashMap['value']}',
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
child: AspectRatio(
aspectRatio:
1.0, // Define a proporção desejada (1:1 neste caso)
child: CachedNetworkImage(
fadeInDuration: const Duration(milliseconds: 500),
fadeOutDuration: const Duration(milliseconds: 500),
imageUrl: widget.imagePath ?? '',
fit: BoxFit.cover,
),
fit: BoxFit.cover,
),
),
),
)
],
),
),

View File

@ -0,0 +1,226 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:hub/actions/actions.dart';
import 'package:hub/app_state.dart';
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/pages/schedule_complete_visit_page/schedule_complete_visit_page_widget.dart';
import 'package:rxdart/rxdart.dart';
import 'package:share_plus/share_plus.dart';
Widget buildDetails(
dynamic visitaWrapItem,
BuildContext context,
Future<dynamic> Function(BuildContext, int, int, String, String)?
changeStatusAction) {
return DetailsComponentWidget(
buttons: [
if (getStatus(visitaWrapItem['VAW_STATUS']) ==
status.active) // REJECT ACTION
FFButtonWidget(
text: FFLocalizations.of(context).getVariableText(
ptText: 'Cancelar',
enText: 'Cancel',
),
icon: const Icon(Icons.close),
onPressed: () async {
showAlertDialog(
context,
FFLocalizations.of(context).getVariableText(
ptText: 'Bloquear Visita',
enText: 'Block Visit',
),
FFLocalizations.of(context).getVariableText(
ptText: 'Você tem certeza que deseja bloquear essa visita?',
enText: 'Are you sure you want to block this visit?',
), () async {
await changeStatusAction
?.call(
context,
int.parse(visitaWrapItem['VAW_DESTINO']),
int.parse(visitaWrapItem['VAW_ID']),
visitaWrapItem['VAW_CHAVE'] ?? '',
visitaWrapItem['VTE_DOCUMENTO'] ?? '',
)
.then((value) {
Navigator.pop(context, value);
if (value == false) {
showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
enText: 'Error blocking visit',
ptText: 'Erro ao bloquear visita',
),
true,
);
} else if (value == true) {
showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
enText: 'Success canceling visit',
ptText: 'Succeso ao cancelar visita',
),
false,
);
}
}).catchError((err, stack) {
Navigator.pop(context);
showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
enText: 'Error blocking visit',
ptText: 'Erro ao bloquear visita',
),
true,
);
});
});
},
options: FFButtonOptions(
width: 130,
height: 40,
color: FlutterFlowTheme.of(context).primaryBackground,
elevation: 0,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
// borderRadius: 12,
),
),
if (getStatus(visitaWrapItem['VAW_STATUS']) !=
status.active) // RECALL ACTION
FFButtonWidget(
text: FFLocalizations.of(context).getVariableText(
ptText: 'Reagendar',
enText: 'Reschedule',
),
icon: const Icon(Icons.refresh),
onPressed: () async {
Navigator.pop(context);
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ScheduleCompleteVisitPageWidget(
dropdownValue1: visitaWrapItem['MOT_DESCRICAO'],
dropdownValue2: visitaWrapItem['NAC_DESCRICAO'],
visitorJsonList: [visitaWrapItem],
visitorStrList: visitaWrapItem['VTE_DOCUMENTO'],
)
),
);
},
options: FFButtonOptions(
width: 130,
height: 40,
color: FlutterFlowTheme.of(context).primaryBackground,
elevation: 0,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
// borderRadius: 12,
),
),
if (getStatus(visitaWrapItem['VAW_STATUS']) ==
status.active) // SHARE ACTION
FFButtonWidget(
text: FFLocalizations.of(context).getVariableText(
ptText: 'Compartilhar',
enText: 'Share',
),
icon: const Icon(Icons.share),
onPressed: () async {
Share.share('''
Olá, \*${visitaWrapItem['VTE_NOME']}\*! Você foi convidado para \*${visitaWrapItem['NAC_DESCRICAO']}\*.
\*Validade do Convite\*:
- Início: ${visitaWrapItem['VAW_DTINICIO']}
- Fim: ${visitaWrapItem['VAW_DTFIM']}
URL do Convite: https://visita.freaccess.com.br/${visitaWrapItem['VAW_ID']}/${visitaWrapItem['CLI_ID']}/${visitaWrapItem['VAW_CHAVE']}
''');
},
options: FFButtonOptions(
width: 130,
height: 40,
color: FlutterFlowTheme.of(context).primaryBackground,
elevation: 0,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
// borderRadius: 12,
),
),
],
labelsHashMap: Map<String, String>.from({
'Nome': visitaWrapItem['VTE_NOME'] ?? '',
'Inicio': visitaWrapItem['VAW_DTINICIO'] ?? '',
'Fim': visitaWrapItem['VAW_DTFIM'] ?? '',
}),
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${visitaWrapItem['VTE_DOCUMENTO'] ?? ''}&tipo=E',
statusHashMap: [
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.active)
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Ativo',
enText: 'Active',
): FlutterFlowTheme.of(context).warning,
}),
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.unknown)
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Pendente',
enText: 'Pending',
): FlutterFlowTheme.of(context).alternate,
}),
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.canceled)
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Cancelado',
enText: 'Canceled',
): FlutterFlowTheme.of(context).error,
}),
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.finished)
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Finalizado',
enText: 'Finished',
): FlutterFlowTheme.of(context).success,
}),
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.blocked)
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Bloqueado',
enText: 'Blocked',
): FlutterFlowTheme.of(context).error,
}),
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.inactive)
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Inativo',
enText: 'Inactive',
): FlutterFlowTheme.of(context).warning,
}),
],
);
}

View File

@ -16,6 +16,8 @@ import 'package:google_fonts/google_fonts.dart';
import 'forgot_password_template_component_model.dart';
export 'forgot_password_template_component_model.dart';
//
class ForgotPasswordTemplateComponentWidget extends StatefulWidget {
const ForgotPasswordTemplateComponentWidget({super.key});
@ -81,7 +83,8 @@ class _ForgotPasswordTemplateComponentWidgetState
tablet: false,
))
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 16.0, 8.0),
padding:
const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 16.0, 8.0),
child: InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
@ -103,20 +106,20 @@ class _ForgotPasswordTemplateComponentWidgetState
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(12.0, 0.0, 0.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(
12.0, 0.0, 0.0, 0.0),
child: Text(
'',
style:
FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Plus Jakarta Sans',
color: const Color(0xFF15161E),
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Plus Jakarta Sans',
color: const Color(0xFF15161E),
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
),
),
],
@ -124,43 +127,46 @@ class _ForgotPasswordTemplateComponentWidgetState
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 0.0, 0.0),
padding:
const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 0.0, 0.0),
child: Text(
FFLocalizations.of(context).getText(
'xxm3ajsy' /* ESQUECEU SUA SENHA? */,
),
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: 'Outfit',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 24.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap().containsKey('Outfit'),
),
fontFamily: 'Outfit',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 24.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap().containsKey('Outfit'),
),
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 4.0, 16.0, 4.0),
padding:
const EdgeInsetsDirectional.fromSTEB(16.0, 4.0, 16.0, 4.0),
child: Text(
FFLocalizations.of(context).getText(
'wu2f7yzo' /* Não se preucupe nós vamos te a... */,
),
style: FlutterFlowTheme.of(context).labelMedium.override(
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts:
GoogleFonts.asMap().containsKey('Plus Jakarta Sans'),
),
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts:
GoogleFonts.asMap().containsKey('Plus Jakarta Sans'),
),
),
),
Form(
key: _model.formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 12.0, 16.0, 0.0),
padding:
const EdgeInsetsDirectional.fromSTEB(16.0, 12.0, 16.0, 0.0),
child: SizedBox(
width: double.infinity,
child: TextFormField(
@ -169,7 +175,7 @@ class _ForgotPasswordTemplateComponentWidgetState
onChanged: (_) => EasyDebounce.debounce(
'_model.emailAddressTextController',
const Duration(milliseconds: 500),
() => setState(() {}),
() => setState(() {}),
),
autofocus: true,
autofillHints: const [AutofillHints.email],
@ -226,14 +232,14 @@ class _ForgotPasswordTemplateComponentWidgetState
),
),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
maxLines: null,
keyboardType: TextInputType.emailAddress,
cursorColor: FlutterFlowTheme.of(context).primary,
@ -246,64 +252,73 @@ class _ForgotPasswordTemplateComponentWidgetState
Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 24.0, 0.0, 0.0),
padding:
const EdgeInsetsDirectional.fromSTEB(0.0, 24.0, 0.0, 0.0),
child: FFButtonWidget(
onPressed: (_model.emailAddressTextController.text == '' || !ValidatorUtil.isValidEmail(_model.emailAddressTextController.text))
onPressed: (_model.emailAddressTextController.text == '' ||
!ValidatorUtil.isValidEmail(
_model.emailAddressTextController.text))
? null
: () async {
try {
_model.req = await PhpGroup.forgotPasswordCall.call(
email: _model.emailAddressTextController.text,
);
try {
_model.req = await PhpGroup.forgotPasswordCall.call(
email: _model.emailAddressTextController.text,
);
if (PhpGroup.forgotPasswordCall
.error((_model.req?.jsonBody ?? '')) ==
false) {
await DialogUtil.success(
context,
FFLocalizations.of(context).getVariableText(
enText: "Send E-mail Successful!",
ptText: "E-mail Enviado com Sucesso!"));
Navigator.pop(context);
} else {
await DialogUtil.error(
context,
PhpGroup.forgotPasswordCall
.msg((_model.req?.jsonBody ?? ''))!);
}
if (PhpGroup.forgotPasswordCall.error((_model.req?.jsonBody ?? '')) == false) {
await DialogUtil.success(context, FFLocalizations.of(context).getVariableText(
enText: "Send E-mail Successful!",
ptText: "E-mail Enviado com Sucesso!"
));
Navigator.pop(context);
} else {
await DialogUtil.error(context, PhpGroup.forgotPasswordCall.msg((_model.req?.jsonBody ?? ''))!);
}
setState(() {});
} catch (error, stack) {
LogUtil.requestAPIFailed("iforgot.php", _model.emailAddressTextController.text, "Recuperar Senha", error, stack);
await DialogUtil.errorDefault(context);
}
},
setState(() {});
} catch (error, stack) {
LogUtil.requestAPIFailed(
"iforgot.php",
_model.emailAddressTextController.text,
"Recuperar Senha",
error,
stack);
await DialogUtil.errorDefault(context);
}
},
text: FFLocalizations.of(context).getText(
'74rnd5bu' /* Enviar */,
),
options: FFButtonOptions(
width: 270.0,
height: 50.0,
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0),
iconPadding:
const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 0.0, 0.0),
iconPadding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 0.0, 0.0),
color: FlutterFlowTheme.of(context).primary,
textStyle: FlutterFlowTheme.of(context).titleSmall.override(
fontFamily: 'Plus Jakarta Sans',
color: Colors.white,
fontSize: 16.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
fontFamily: 'Plus Jakarta Sans',
color: Colors.white,
fontSize: 16.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
elevation: 3.0,
borderSide: const BorderSide(
color: Colors.transparent,
width: 1.0,
),
disabledColor:
FlutterFlowTheme.of(
context)
.customColor5,
disabledTextColor:
Colors.white,
disabledColor: FlutterFlowTheme.of(context).customColor5,
disabledTextColor: Colors.white,
),
showLoadingIndicator: true,
),

View File

@ -5,7 +5,6 @@ import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
@ -54,7 +53,6 @@ class _MessageNotificationModalTemplateComponentWidgetState
_model.textController3 ??= TextEditingController(text: widget.to);
_model.textFieldFocusNode3 ??= FocusNode();
}
@override
@ -73,7 +71,7 @@ class _MessageNotificationModalTemplateComponentWidgetState
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(10.0, 0.0, 10.0, 0.0),
child: Container(
width: MediaQuery.sizeOf(context).width * 0.9,
width: MediaQuery.sizeOf(context).width,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
borderRadius: const BorderRadius.only(
@ -88,7 +86,6 @@ class _MessageNotificationModalTemplateComponentWidgetState
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
@ -105,7 +102,6 @@ class _MessageNotificationModalTemplateComponentWidgetState
ptText: 'Mensagem',
enText: 'Message',
),
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
@ -163,7 +159,8 @@ class _MessageNotificationModalTemplateComponentWidgetState
obscureText: false,
decoration: InputDecoration(
isDense: true,
labelText: FFLocalizations.of(context).getVariableText(
labelText:
FFLocalizations.of(context).getVariableText(
ptText: 'De',
enText: 'From',
),
@ -278,8 +275,6 @@ class _MessageNotificationModalTemplateComponentWidgetState
_model.textController3Validator.asValidator(context),
),
),
]
.divide(const SizedBox(height: 10.0))
.addToStart(const SizedBox(height: 20.0))

View File

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:developer';
import 'package:hub/components/molecular_components/throw_exception/throw_exception_widget.dart';
@ -14,12 +15,20 @@ import 'regisiter_vistor_template_component_widget.dart';
class RegisiterVistorTemplateComponentModel
extends FlutterFlowModel<RegisiterVistorTemplateComponentWidget> {
/// State fields for stateful widgets in this page.
Timer? _debounceTimer;
final unfocusNode = FocusNode();
bool isDataUploading = false;
FFUploadedFile uploadedLocalFile =
FFUploadedFile(bytes: Uint8List.fromList([]));
void debounce(Function() fn, Duration time) {
if (_debounceTimer != null) {
_debounceTimer!.cancel();
}
_debounceTimer = Timer(time, fn);
}
// State field(s) for TextField widget.
FocusNode? textFieldFocusNode1;
TextEditingController? textController1;
@ -35,7 +44,7 @@ class RegisiterVistorTemplateComponentModel
return null;
}
Future<bool?> getVisitanteByDocument(
Future<bool> getVisitanteByDocument(
String document, BuildContext context) async {
final response = await PhpGroup.getVisitorByDocCall.call(
devUUID: FFAppState().devUUID,
@ -44,12 +53,12 @@ class RegisiterVistorTemplateComponentModel
atividade: 'getVisitante',
documento: document,
);
log('${response.jsonBody}');
if (response.jsonBody['visitante']['VTE_ID'] != '0' &&
response.jsonBody['error'] != 'false') {
return true;
}
return null;
return false;
}
// State field(s) for TextField widget.

View File

@ -23,9 +23,10 @@ export 'regisiter_vistor_template_component_model.dart';
class RegisiterVistorTemplateComponentWidget extends StatefulWidget {
final String source;
final String? doc;
const RegisiterVistorTemplateComponentWidget(
{super.key, required this.source});
{super.key, required this.source, this.doc});
@override
State<RegisiterVistorTemplateComponentWidget> createState() =>
@ -38,15 +39,22 @@ class _RegisiterVistorTemplateComponentWidgetState
final scaffoldKey = GlobalKey<ScaffoldState>();
bool _isVisitorRegistered = false;
BehaviorSubject<bool> visitorAlreadyRegistered = BehaviorSubject<bool>();
@override
void initState() {
super.initState();
visitorAlreadyRegistered = BehaviorSubject<bool>.seeded(false);
_model =
createModel(context, () => RegisiterVistorTemplateComponentModel());
_model.textController1 ??= TextEditingController();
_model.textFieldFocusNode1 ??= FocusNode();
log('doc: ${widget.doc}');
_model.textController2 ??= TextEditingController();
_model.textFieldFocusNode2 ??= FocusNode();
_model.textController2?.addListener(_onTextChanged);
@ -56,6 +64,10 @@ class _RegisiterVistorTemplateComponentWidgetState
_model.textController4 ??= TextEditingController();
_model.textFieldFocusNode4 ??= FocusNode();
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
_model.textController2.text = widget.doc ?? '';
});
}
@override
@ -67,17 +79,40 @@ class _RegisiterVistorTemplateComponentWidgetState
}
void _onTextChanged() {
log('changed');
setState(() {});
}
bool _isFormValid(BuildContext context) {
if (_model.uploadedLocalFile.bytes?.isEmpty ?? true) {
return false;
}
if (_model.textController1.text.isEmpty ||
_model.textController1.text == '') {
return false;
}
if (_model.dropDownValue == null ||
_model.dropDownValue!.isEmpty ||
_model.dropDownValue == '') {
return false;
}
if (_model.textController2.text.isEmpty ||
_model.textController2.text == '') {
return false;
}
if (_isVisitorRegistered) {
return false;
}
return true;
}
@override
Widget build(BuildContext context) {
BehaviorSubject<bool> visitorAlreadyRegistered = BehaviorSubject<bool>();
context.watch<FFAppState>();
log(context
.describeWidget('RegisiterVistorTemplateComponentWidget')
.toString());
return Align(
alignment: const AlignmentDirectional(0.0, 1.0),
child: Container(
@ -123,133 +158,137 @@ class _RegisiterVistorTemplateComponentWidgetState
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: TextFormField(
controller: _model.textController2,
focusNode: _model.textFieldFocusNode2,
autovalidateMode: AutovalidateMode.onUserInteraction,
autofocus: false,
textCapitalization: TextCapitalization.none,
autofillHints: const [AutofillHints.password],
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
obscureText: false,
decoration: InputDecoration(
isDense: true,
labelText: FFLocalizations.of(context).getText(
'rl8tvwnr' /* Documento */,
child: Column(children: [
TextFormField(
controller: _model.textController2,
focusNode: _model.textFieldFocusNode2,
autovalidateMode: AutovalidateMode.onUserInteraction,
autofocus: false,
textCapitalization: TextCapitalization.none,
autofillHints: const [AutofillHints.password],
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
obscureText: false,
decoration: InputDecoration(
isDense: true,
labelText: FFLocalizations.of(context).getText(
'rl8tvwnr' /* Documento */,
),
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: FlutterFlowTheme.of(context)
.labelMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context)
.labelMediumFamily),
),
hintStyle:
FlutterFlowTheme.of(context).labelMedium.override(
fontFamily: FlutterFlowTheme.of(context)
.labelMediumFamily,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(FlutterFlowTheme.of(context)
.labelMediumFamily),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).customColor6,
width: 0.5,
),
borderRadius: BorderRadius.circular(10.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primary,
width: 0.5,
),
borderRadius: BorderRadius.circular(10.0),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 0.5,
),
borderRadius: BorderRadius.circular(10.0),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 0.5,
),
borderRadius: BorderRadius.circular(10.0),
),
suffixIcon: Icon(
Icons.document_scanner,
color: FlutterFlowTheme.of(context).accent1,
),
),
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily:
FlutterFlowTheme.of(context).labelMediumFamily,
FlutterFlowTheme.of(context).bodyMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).labelMediumFamily),
FlutterFlowTheme.of(context).bodyMediumFamily),
),
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily:
FlutterFlowTheme.of(context).labelMediumFamily,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).labelMediumFamily),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).customColor6,
width: 0.5,
),
borderRadius: BorderRadius.circular(10.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primary,
width: 0.5,
),
borderRadius: BorderRadius.circular(10.0),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 0.5,
),
borderRadius: BorderRadius.circular(10.0),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 0.5,
),
borderRadius: BorderRadius.circular(10.0),
),
suffixIcon: Icon(
Icons.document_scanner,
color: FlutterFlowTheme.of(context).accent1,
),
onChanged: (value) {
_model.debounce(() async {
var data = await _model.getVisitanteByDocument(
value, context);
setState(() {
_isVisitorRegistered = data;
});
}, const Duration(milliseconds: 500));
},
validator:
_model.textController2Validator.asValidator(context),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
],
),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily:
FlutterFlowTheme.of(context).bodyMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).bodyMediumFamily),
),
validator:
_model.textController2Validator.asValidator(context),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
],
),
),
FutureBuilder(
future: _model.textController2.text.isNotEmpty
? _model.getVisitanteByDocument(
_model.textController2.text, context)
: null,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const SizedBox();
} else if (snapshot.hasError ||
snapshot.data == null ||
snapshot.data == '') {
visitorAlreadyRegistered.add(true);
return const SizedBox();
} else {
visitorAlreadyRegistered.add(false);
return _model.textController2.text.isEmpty
? const SizedBox()
: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: EdgeInsets.only(
right: MediaQuery.sizeOf(context).width *
0.1),
child: Text(
FFLocalizations.of(context)
.getVariableText(
enText: 'Visitor already registered',
ptText: 'Visitante já cadastrado',
),
style: FlutterFlowTheme.of(context)
.bodySmall
.override(
fontFamily: 'Nunito',
color: FlutterFlowTheme.of(context)
.error,
fontSize: 14.0,
letterSpacing: 0.0,
)),
),
],
);
}
},
_model.textController2.text.isEmpty
? const SizedBox()
: _isVisitorRegistered == true
? Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsetsDirectional.only(
top: 5, start: 12),
child: Text(
FFLocalizations.of(context)
.getVariableText(
enText: 'Visitor already registered',
ptText: 'Visitante já cadastrado',
),
style: FlutterFlowTheme.of(context)
.labelSmall
.override(
fontFamily: 'Nunito',
color: Theme.of(context)
.brightness ==
Brightness.dark
? Color.alphaBlend(
Colors.white
.withOpacity(0.7),
Colors.red)
: Color.alphaBlend(
Colors.black
.withOpacity(0.25),
Colors.red),
fontSize: 13.0,
letterSpacing: 0.0,
)),
),
],
)
: const SizedBox()
]),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
@ -334,119 +373,86 @@ class _RegisiterVistorTemplateComponentWidgetState
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 10.0),
child: Container(
width: MediaQuery.sizeOf(context).width * 0.95,
decoration: const BoxDecoration(),
child: Column(
children: [
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 10.0),
child: Column(
children: [
FlutterFlowDropDown<String>(
controller: _model.dropDownValueController ??=
FormFieldController<String>(null),
options: [
FFLocalizations.of(context).getText(
'n8vddmcq' /* Visitante */,
),
FFLocalizations.of(context).getText(
'9luaa09e' /* Prestador de Serviço */,
)
],
onChanged: (val) =>
setState(() => _model.dropDownValue = val),
width: MediaQuery.sizeOf(context).width * 0.9,
// height: 44.0,
textStyle: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(context).bodyMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context)
.bodyMediumFamily),
),
hintText: FFLocalizations.of(context).getText(
'pmezihb4' /* Selecione... */,
),
icon: Icon(
Icons.keyboard_arrow_down_rounded,
color: FlutterFlowTheme.of(context).primaryText,
size: 24.0,
),
elevation: 2.0,
borderColor: FlutterFlowTheme.of(context).customColor6,
borderWidth: 0.5,
borderRadius: 8.0,
margin: const EdgeInsetsDirectional.fromSTEB(
16.0, 0.0, 16.0, 0.0),
hidesUnderline: true,
isOverButton: true,
isSearchable: false,
isMultiSelect: false,
),
if (_model.dropDownValue == null ||
_model.dropDownValue == '')
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 0.0, 7.0),
padding: const EdgeInsetsDirectional.only(
top: 5, start: 15),
child: Text(
FFLocalizations.of(context).getText(
'yp23q90m' /* Selecione o tipo: */,
),
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: FlutterFlowTheme.of(context)
.bodyMediumFamily,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(
FlutterFlowTheme.of(context)
.bodyMediumFamily),
),
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 0.0, 5.0),
child: FlutterFlowDropDown<String>(
controller: _model.dropDownValueController ??=
FormFieldController<String>(null),
options: [
FFLocalizations.of(context).getText(
'n8vddmcq' /* Visitante */,
FFLocalizations.of(context).getVariableText(
enText: 'This field is required',
ptText: 'Este campo é obrigatório',
),
FFLocalizations.of(context).getText(
'9luaa09e' /* Prestador de Serviço */,
)
],
onChanged: (val) =>
setState(() => _model.dropDownValue = val),
width: 200.0,
height: 44.0,
textStyle: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: FlutterFlowTheme.of(context)
.bodyMediumFamily,
color: FlutterFlowTheme.of(context)
.primaryText,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(
FlutterFlowTheme.of(context)
.bodyMediumFamily),
),
hintText: FFLocalizations.of(context).getText(
'pmezihb4' /* Selecione... */,
),
icon: Icon(
Icons.keyboard_arrow_down_rounded,
color:
FlutterFlowTheme.of(context).primaryText,
size: 24.0,
),
elevation: 2.0,
borderColor:
FlutterFlowTheme.of(context).customColor6,
borderWidth: 0.5,
borderRadius: 8.0,
margin: const EdgeInsetsDirectional.fromSTEB(
16.0, 0.0, 16.0, 0.0),
hidesUnderline: true,
isOverButton: true,
isSearchable: false,
isMultiSelect: false,
),
style: FlutterFlowTheme.of(context)
.bodySmall
.override(
fontFamily: FlutterFlowTheme.of(context)
.bodySmallFamily,
color: FlutterFlowTheme.of(context)
.customColor6,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(
FlutterFlowTheme.of(context)
.bodySmallFamily),
)),
),
]
.divide(const SizedBox(width: 19.0))
.addToStart(const SizedBox(width: 30.0)),
],
),
if (_model.dropDownValue == null ||
_model.dropDownValue == '')
Align(
alignment: const AlignmentDirectional(0.4, 0),
child: Text(
FFLocalizations.of(context).getVariableText(
enText: 'This field is required',
ptText: 'Este campo é obrigatório',
),
style: FlutterFlowTheme.of(context)
.bodySmall
.override(
fontFamily: FlutterFlowTheme.of(context)
.bodySmallFamily,
color: FlutterFlowTheme.of(context)
.customColor6,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(
FlutterFlowTheme.of(context)
.bodySmallFamily),
)),
),
],
),
],
),
),
Builder(
@ -491,10 +497,11 @@ class _RegisiterVistorTemplateComponentWidgetState
allowPhoto: true,
includeDimensions: true,
);
if (selectedMedia != null &&
selectedMedia.every((m) =>
validateFileFormat(
m.storagePath, context))) {
if (selectedMedia != null) {
// &&
// selectedMedia.every((m) =>
// validateFileFormat(
// m.storagePath, context))) {
setState(() => _model.isDataUploading = true);
var selectedUploadedFiles =
<FFUploadedFile>[];
@ -793,119 +800,112 @@ class _RegisiterVistorTemplateComponentWidgetState
padding:
const EdgeInsetsDirectional.fromSTEB(0.0, 65.0, 0.0, 0.0),
child: FFButtonWidget(
onPressed: (((_model.uploadedLocalFile.bytes?.isNotEmpty ??
false)) &&
(_model.textController1.text != '') &&
(_model.dropDownValue != null &&
_model.dropDownValue != '') &&
(_model.textController2.text != ''))
onPressed: _isFormValid(context)
? () async {
log(visitorAlreadyRegistered.value.toString());
if (visitorAlreadyRegistered.value == true) {
_model.imgBase64 =
await actions.convertImageFileToBase64(
_model.uploadedLocalFile,
);
_model.scheduleVisitor =
await PhpGroup.postScheduleVisitorCall
.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'putVisitante',
documento: _model.textController2.text,
nome: _model.textController1.text,
tipo: _model.dropDownValue ==
FFLocalizations.of(context).getText(
'n8vddmcq' /* Visitante */,
)
? 'V'
: 'P',
foto: 'base64;jpeg,${_model.imgBase64}',
)
.onError((e, s) async {
return await showAdaptiveDialog(
context: context,
builder: (context) {
return GestureDetector(
onTap: () => Navigator.pop(context),
child: Padding(
padding:
MediaQuery.viewInsetsOf(context),
child: Dialog(
backgroundColor: Colors.transparent,
child: ThrowExceptionWidget(
msg: FFLocalizations.of(context)
.getVariableText(
ptText:
'Você esqueceu de adicionar algum dado obrigatório. Verifique se a imagem, nome, tipo e documento foram preenchidos corretamente.',
enText:
'You forgot to add some required data. Check if the image, name, type and document were filled in correctly.',
),
_model.imgBase64 =
await actions.convertImageFileToBase64(
_model.uploadedLocalFile,
);
_model.scheduleVisitor =
await PhpGroup.postScheduleVisitorCall
.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'putVisitante',
documento: _model.textController2.text,
nome: _model.textController1.text,
tipo: _model.dropDownValue ==
FFLocalizations.of(context).getText(
'n8vddmcq' /* Visitante */,
)
? 'V'
: 'P',
foto: 'base64;jpeg,${_model.imgBase64}',
)
.onError((e, s) async {
return await showAdaptiveDialog(
context: context,
builder: (context) {
return GestureDetector(
onTap: () => Navigator.pop(context),
child: Padding(
padding: MediaQuery.viewInsetsOf(context),
child: Dialog(
backgroundColor: Colors.transparent,
child: ThrowExceptionWidget(
msg: FFLocalizations.of(context)
.getVariableText(
ptText:
'Você esqueceu de adicionar algum dado obrigatório. Verifique se a imagem, nome, tipo e documento foram preenchidos corretamente.',
enText:
'You forgot to add some required data. Check if the image, name, type and document were filled in correctly.',
),
),
),
);
},
);
});
if (PhpGroup.postScheduleVisitorCall.error(
(_model.scheduleVisitor?.jsonBody ?? ''),
) ==
false) {
setState(() {
_model.textController1?.clear();
_model.textController2?.clear();
_model.textController3?.clear();
_model.textController4?.clear();
_model.dropDownValueController?.reset();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText:
'Visitante cadastrado com sucesso.',
enText:
'Visitor successfully registered.'),
style: TextStyle(
color:
FlutterFlowTheme.of(context)
.info)),
backgroundColor:
FlutterFlowTheme.of(context).primary,
duration: const Duration(seconds: 3),
width: MediaQuery.of(context).size.width,
behavior: SnackBarBehavior.floating,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
),
),
);
if (widget.source ==
'VisitorNotFoundComponent') {
Navigator.pop(context);
}
});
} else {
return DialogUtil.error(
context,
PhpGroup.postScheduleVisitorCall
.errorMsg(
_model.scheduleVisitor?.jsonBody)
.toString());
}
},
);
});
if (PhpGroup.postScheduleVisitorCall.error(
(_model.scheduleVisitor?.jsonBody ?? ''),
) ==
false) {
setState(() {
_model.textController1?.clear();
_model.textController2?.clear();
_model.textController3?.clear();
_model.textController4?.clear();
_model.dropDownValueController?.reset();
_model.uploadedLocalFile = FFUploadedFile(
bytes: Uint8List.fromList([]));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText:
'Visitante cadastrado com sucesso.',
enText:
'Visitor successfully registered.'),
style: TextStyle(
color: FlutterFlowTheme.of(context)
.info)),
backgroundColor:
FlutterFlowTheme.of(context).primary,
duration: const Duration(seconds: 3),
width: MediaQuery.of(context).size.width,
behavior: SnackBarBehavior.floating,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
),
),
);
if (widget.source ==
'VisitorNotFoundComponent') {
Navigator.pop(context, true);
}
});
} else {
DialogUtil.error(
return DialogUtil.error(
context,
FFLocalizations.of(context).getVariableText(
ptText:
'Visitante já cadastrado. Verifique se o documento foi preenchido corretamente.',
enText:
'Visitor already registered. Check if the document was filled in correctly.',
));
PhpGroup.postScheduleVisitorCall.errorMsg(
_model
.scheduleVisitor?.jsonBody) ==
null
? FFLocalizations.of(context)
.getVariableText(
ptText:
'Erro ao se conectar com o servidor',
enText: 'Error connecting to server',
)
: PhpGroup.postScheduleVisitorCall
.errorMsg(
_model.scheduleVisitor?.jsonBody)
.toString());
}
}
: null,

View File

@ -99,8 +99,9 @@ class _SignInTemplateComponentWidgetState
super.dispose();
}
bool _isFormInvalid() {
if (_model.emailAddressTextController.text == '' || _model.passwordTextController.text == '') {
bool _isFormInvalid() {
if (_model.emailAddressTextController.text == '' ||
_model.passwordTextController.text == '') {
return true;
}
@ -185,7 +186,8 @@ class _SignInTemplateComponentWidgetState
decoration: const BoxDecoration(),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: const AtomImageSvgTheme(filename: 'login', width: 600, height: 155),
child: const AtomImageSvgTheme(
filename: 'login', width: 600, height: 155),
),
),
Column(
@ -697,26 +699,37 @@ class _SignInTemplateComponentWidgetState
.fromSTEB(0.0, 0.0,
0.0, 16.0),
child: FFButtonWidget(
onPressed: _isFormInvalid()
? null
: () async {
try {
await action_blocks
.singInLoginAction(
context,
emailAdress: _model
.emailAddressTextController
.text,
password: _model
.passwordTextController
.text,
);
setState(() {});
} catch (e, s) {
await DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed('login.php', _model.emailAddressTextController.text, "Login", e, s);
}
},
onPressed:
_isFormInvalid()
? null
: () async {
try {
await action_blocks
.singInLoginAction(
context,
emailAdress: _model
.emailAddressTextController
.text,
password: _model
.passwordTextController
.text,
);
setState(
() {});
} catch (e, s) {
await DialogUtil
.errorDefault(
context);
LogUtil.requestAPIFailed(
'login.php',
_model
.emailAddressTextController
.text,
"Login",
e,
s);
}
},
text: FFLocalizations.of(
context)
.getText(
@ -773,7 +786,8 @@ class _SignInTemplateComponentWidgetState
const Color(
0xE81AAB5F),
),
showLoadingIndicator: true,
showLoadingIndicator:
true,
),
),
),
@ -866,15 +880,20 @@ class _SignInTemplateComponentWidgetState
onTap: () async {
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
backgroundColor:
Colors.transparent,
context: context,
builder: (context) {
return Padding(
padding: MediaQuery.viewInsetsOf(context),
child: const ForgotPasswordTemplateComponentWidget(),
padding:
MediaQuery.viewInsetsOf(
context),
child:
const ForgotPasswordTemplateComponentWidget(),
);
},
).then((value) => safeSetState(() {}));
).then(
(value) => safeSetState(() {}));
},
child: RichText(
textScaler: MediaQuery.of(context)

View File

@ -3,6 +3,7 @@ import 'dart:developer';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/flutter_flow/nav/serialization_util.dart';
import 'package:hub/shared/utils/dialog_util.dart';
import '/backend/api_requests/api_calls.dart';
import '/components/molecular_components/throw_exception/throw_exception_widget.dart';
@ -63,7 +64,6 @@ List<dynamic>? findVisitorById(List<dynamic>? jsonList, String? id) {
);
return foundItem != null ? [foundItem] : null;
} catch (e) {
log("Error searching item: $e");
return null;
}
}
@ -131,10 +131,10 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
context.watch<FFAppState>();
return Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 35.0, 0.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 200.0, 0.0, 0.0),
child: Container(
width: double.infinity,
height: double.infinity,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
borderRadius: const BorderRadius.only(
@ -264,6 +264,10 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
focusNode: _model.textFieldFocusNode1,
autofocus: false,
obscureText: false,
showCursor: false,
enabled: false,
cursorColor: FlutterFlowTheme.of(context).primary,
readOnly: true,
decoration: InputDecoration(
labelText: FFLocalizations.of(context).getText(
'9yu35pzg' /* Encerramento da Visita */,
@ -348,6 +352,10 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
focusNode: _model.textFieldFocusNode2,
autofocus: false,
obscureText: false,
showCursor: false,
enabled: false,
cursorColor: FlutterFlowTheme.of(context).primary,
readOnly: true,
decoration: InputDecoration(
labelText: FFLocalizations.of(context).getText(
'aj6scczp' /* Início */,
@ -436,6 +444,10 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
focusNode: _model.textFieldFocusNode3,
autofocus: false,
obscureText: false,
showCursor: false,
enabled: false,
cursorColor: FlutterFlowTheme.of(context).primary,
readOnly: true,
decoration: InputDecoration(
labelText: FFLocalizations.of(context).getText(
'rvi5z7wg' /* Término */,
@ -534,6 +546,10 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
focusNode: _model.textFieldFocusNode4,
autofocus: false,
obscureText: false,
showCursor: false,
enabled: false,
cursorColor: FlutterFlowTheme.of(context).primary,
readOnly: true,
decoration: InputDecoration(
labelText: FFLocalizations.of(context).getText(
'yxilg7ek' /* Motivo da Visita */,
@ -622,6 +638,10 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
focusNode: _model.textFieldFocusNode5,
autofocus: false,
obscureText: false,
showCursor: false,
enabled: false,
cursorColor: FlutterFlowTheme.of(context).primary,
readOnly: true,
decoration: InputDecoration(
labelText: FFLocalizations.of(context).getText(
'dgr3pk3a' /* Nível de Acesso */,
@ -714,6 +734,10 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
focusNode: _model.textFieldFocusNode6,
autofocus: false,
obscureText: false,
showCursor: false,
enabled: false,
cursorColor: FlutterFlowTheme.of(context).primary,
readOnly: true,
decoration: InputDecoration(
labelText: FFLocalizations.of(context).getText(
'lppn9rxa' /* Observações da Visita */,
@ -785,178 +809,150 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
],
),
),
Align(
alignment: const AlignmentDirectional(0.0, 1.0),
child: Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(0.0, 6.0, 0.0, 0.0),
child: Container(
width: double.infinity,
height: 35.0,
decoration: BoxDecoration(
color: widget.visitStatusColor,
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(0.0),
bottomRight: Radius.circular(0.0),
topLeft: Radius.circular(0.0),
topRight: Radius.circular(0.0),
),
),
child: Builder(
builder: (context) {
if (widget.visitStatusStr == 'A') {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FlutterFlowIconButton(
borderRadius: 20.0,
borderWidth: 1.0,
buttonSize: 40.0,
icon: Icon(
Icons.block_sharp,
color: FlutterFlowTheme.of(context)
.primaryBackground,
size: 24.0,
),
onPressed: () async {
_model.deleteVisit =
await PhpGroup.deleteVisitCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'cancelaVisita',
idVisita: widget.visitIdStr,
);
Builder(
builder: (context) {
if (widget.visitStatusStr == 'A') {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FlutterFlowIconButton(
borderRadius: 20.0,
borderWidth: 1.0,
buttonSize: 40.0,
// fillColor: widget.visitStatusColor,
icon: Icon(
Icons.block_sharp,
color: FlutterFlowTheme.of(context).error,
size: 24.0,
),
onPressed: () async {
_model.deleteVisit =
await PhpGroup.deleteVisitCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'cancelaVisita',
idVisita: widget.visitIdStr,
);
if (PhpGroup.deleteVisitCall.error(
(_model.deleteVisit?.jsonBody ?? ''),
) ==
false) {
Navigator.pop(context);
} else {
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
enableDrag: false,
context: context,
builder: (context) {
return Padding(
padding:
MediaQuery.viewInsetsOf(context),
child: ThrowExceptionWidget(
msg: PhpGroup.deleteVisitCall.msg(
(_model.deleteVisit?.jsonBody ??
''),
)!,
),
);
},
).then((value) => safeSetState(() {}));
}
setState(() {});
},
),
FlutterFlowIconButton(
borderColor: Colors.transparent,
borderRadius: 20.0,
borderWidth: 1.0,
buttonSize: 40.0,
icon: Icon(
Icons.share,
color: FlutterFlowTheme.of(context)
.primaryBackground,
size: 24.0,
),
onPressed: () {
log('IconButton pressed ...');
// Implement share functionality here
Share.share(
'Visita agendada para ${widget.visitStartDate} com término previsto para ${widget.visitEndDate}. Motivo: ${widget.visitReasonStr}. Nível de acesso: ${widget.visitLevelStr}. Observações: ${widget.visitObsStr}.',
);
},
),
],
);
} else if ((widget.visitStatusStr == 'C') ||
(widget.visitStatusStr == 'F') ||
(widget.visitStatusStr == 'B') ||
(widget.visitStatusStr == 'I')) {
return InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () async {
if (PhpGroup.deleteVisitCall.error(
(_model.deleteVisit?.jsonBody ?? ''),
) ==
false) {
Navigator.pop(context);
} else {
final error =
await DialogUtil.errorDefault(context);
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
enableDrag: false,
context: context,
builder: (context) {
return Padding(
padding: MediaQuery.viewInsetsOf(context),
child: error,
);
},
).then((value) => safeSetState(() {}));
}
context.pushNamed(
'scheduleCompleteVisitPage',
queryParameters: {
'visitStartDateStr': serializeParam(
dateTimeFormat(
'd/M/y H:mm:ss',
getCurrentTimestamp,
locale: FFLocalizations.of(context)
.languageCode,
),
ParamType.String,
),
'visitEndDateStr': serializeParam(
'',
ParamType.String,
),
'visitReasonStr': serializeParam(
widget.visitReasonStr,
ParamType.String,
),
'visitLevelStr': serializeParam(
widget.visitLevelStr,
ParamType.String,
),
'visitTempBol': serializeParam(
widget.visitTempStr == 'Sim' ? true : false,
ParamType.bool,
),
'visitObsStr': serializeParam(
widget.visitObsStr,
ParamType.String,
),
'visitorStrList': serializeParam(
widget.visitorStrList,
ParamType.String,
),
'visitorJsonList': serializeParam(
filteredVisitorJsonList,
ParamType.JSON,
isList: true,
),
}.withoutNulls,
);
},
child: Icon(
Icons.repeat,
color: FlutterFlowTheme.of(context).secondaryText,
size: 24.0,
setState(() {});
},
),
FlutterFlowIconButton(
borderColor: Colors.transparent,
borderRadius: 20.0,
borderWidth: 1.0,
buttonSize: 40.0,
icon: Icon(
Icons.share,
color: FlutterFlowTheme.of(context).accent1,
size: 24.0,
),
onPressed: () {
// Implement share functionality here
Share.share(
'Visita agendada para ${widget.visitStartDate} com término previsto para ${widget.visitEndDate}. Motivo: ${widget.visitReasonStr}. Nível de acesso: ${widget.visitLevelStr}. Observações: ${widget.visitObsStr}.',
);
},
),
],
);
} else if ((widget.visitStatusStr == 'C') ||
(widget.visitStatusStr == 'F') ||
(widget.visitStatusStr == 'B') ||
(widget.visitStatusStr == 'I')) {
return InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () async {
Navigator.pop(context);
context.pushNamed(
'scheduleCompleteVisitPage',
queryParameters: {
'visitStartDateStr': serializeParam(
dateTimeFormat(
'd/M/y H:mm:ss',
getCurrentTimestamp,
locale: FFLocalizations.of(context).languageCode,
),
ParamType.String,
),
);
} else {
return Container(
width: 100.0,
height: 100.0,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
'visitEndDateStr': serializeParam(
'',
ParamType.String,
),
);
}
'visitReasonStr': serializeParam(
widget.visitReasonStr,
ParamType.String,
),
'visitLevelStr': serializeParam(
widget.visitLevelStr,
ParamType.String,
),
'visitTempBol': serializeParam(
widget.visitTempStr == 'Sim' ? true : false,
ParamType.bool,
),
'visitObsStr': serializeParam(
widget.visitObsStr,
ParamType.String,
),
'visitorStrList': serializeParam(
widget.visitorStrList,
ParamType.String,
),
'visitorJsonList': serializeParam(
filteredVisitorJsonList,
ParamType.JSON,
isList: true,
),
}.withoutNulls,
);
},
),
),
),
child: Icon(
Icons.repeat,
color: widget.visitStatusColor,
size: 24.0,
),
);
} else {
return Container(
width: 100.0,
height: 100.0,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
),
);
}
},
),
],
].addToEnd(const SizedBox(height: 5.0)),
),
),
);

View File

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:hub/components/organism_components/schedule_visit_detail/schedule_visit_detail_widget.dart';
import 'package:hub/components/templates_components/view_visit_detail/view_visit_detail_widget.dart';

View File

@ -1,3 +1,6 @@
import 'dart:developer';
import 'package:flutter/services.dart';
import 'package:hub/backend/api_requests/api_calls.dart';
import 'package:hub/components/molecular_components/visitor_not_found_component/visitor_not_found_component_widget.dart';
import 'package:hub/components/templates_components/visitor_details_modal_template_component/visitor_details_modal_template_component_widget.dart';
@ -34,7 +37,7 @@ class _VisitorSearchModalTemplateComponentWidgetState
late VisitorSearchModalTemplateComponentModel _model;
@override
void setState(VoidCallback callback) {
safeSetState(VoidCallback callback) {
super.setState(callback);
_model.onUpdate();
}
@ -84,51 +87,8 @@ class _VisitorSearchModalTemplateComponentWidgetState
controller: _model.textController,
focusNode: _model.textFieldFocusNode,
onFieldSubmitted: (_) async {
setState(() {
_model.textController?.text = _model.textController.text;
_model.textController?.selection = TextSelection.collapsed(
offset: _model.textController!.text.length);
});
_model.getVisitorByDoc =
await PhpGroup.getVisitorByDocCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'getVisitante',
documento: _model.textController.text,
);
if (PhpGroup.getVisitorByDocCall.vistanteId(
(_model.getVisitorByDoc?.jsonBody ?? ''),
) !=
'0') {
_model.addToVisitors(PhpGroup.getVisitorByDocCall.visitante(
(_model.getVisitorByDoc?.jsonBody ?? ''),
));
setState(() {});
_model.addToDocs(_model.textController.text);
setState(() {});
} else {
await showAdaptiveDialog(
useSafeArea: true,
context: context,
builder: (context) {
return Dialog(
child: Padding(
padding: MediaQuery.viewInsetsOf(context),
child: Container(
color: Colors.transparent,
// width: MediaQuery.of(context).size.height * 0.1,
// height:
// MediaQuery.of(context).size.height * 0.4,
child: const VisitorNotFoundComponentWidget()),
),
);
},
).then((value) => safeSetState(() {}));
}
setState(() {});
await addVisitor(context);
safeSetState(() {});
},
autofocus: false,
textInputAction: TextInputAction.done,
@ -146,9 +106,6 @@ class _VisitorSearchModalTemplateComponentWidgetState
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).labelMediumFamily),
),
hintText: FFLocalizations.of(context).getText(
'8i1qszba' /* test */,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).accent1,
@ -212,6 +169,9 @@ class _VisitorSearchModalTemplateComponentWidgetState
),
keyboardType: TextInputType.number,
validator: _model.textControllerValidator.asValidator(context),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
],
),
),
if (_model.visitors.isNotEmpty && _model.visitors.length > 0)
@ -307,7 +267,7 @@ class _VisitorSearchModalTemplateComponentWidgetState
// ),
// );
// },
// ).then((value) => safeSetState(() {}));
// ).then((value) => safeSetState(() {}));
},
child: Container(
width: 100.0,
@ -396,7 +356,7 @@ class _VisitorSearchModalTemplateComponentWidgetState
onPressed: () async {
_model.removeFromVisitors(
visitorItem);
setState(() {});
safeSetState(() {});
},
),
],
@ -427,19 +387,24 @@ class _VisitorSearchModalTemplateComponentWidgetState
mainAxisSize: MainAxisSize.max,
children: [
FFButtonWidget(
onPressed: () async {
await widget.getVisitors?.call(
_model.visitors,
);
await widget.getDocs?.call(
_model.docs,
);
Navigator.pop(context);
},
text: FFLocalizations.of(context).getVariableText(
enText: 'Add',
ptText: 'Adicionar',
),
onPressed: MediaQuery.of(context).viewInsets.bottom > 0
? () async {
await addVisitor(context);
safeSetState(() {});
}
: () async {
await sendVisitors(context);
},
text: MediaQuery.of(context).viewInsets.bottom > 0
? FFLocalizations.of(context).getVariableText(
enText: 'Add',
ptText: 'Adicionar',
)
: FFLocalizations.of(context).getVariableText(
enText: 'Submit',
ptText: 'Enviar',
),
options: FFButtonOptions(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.width * 0.1,
@ -472,11 +437,70 @@ class _VisitorSearchModalTemplateComponentWidgetState
],
),
const SizedBox(
height: 10.0,
height: 20.0,
)
],
),
),
);
}
Future<void> sendVisitors(BuildContext context) async {
await widget.getVisitors?.call(
_model.visitors,
);
await widget.getDocs?.call(
_model.docs,
);
Navigator.pop(context);
}
Future<void> addVisitor(BuildContext context) async {
safeSetState(() {
_model.textController?.text = _model.textController.text;
_model.textController?.selection =
TextSelection.collapsed(offset: _model.textController!.text.length);
});
_model.getVisitorByDoc = await PhpGroup.getVisitorByDocCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'getVisitante',
documento: _model.textController.text,
);
if (PhpGroup.getVisitorByDocCall.vistanteId(
(_model.getVisitorByDoc?.jsonBody ?? ''),
) !=
'0' &&
PhpGroup.getVisitorByDocCall
.error((_model.getVisitorByDoc?.jsonBody ?? '')) ==
false &&
PhpGroup.getVisitorByDocCall
.vistanteId((_model.getVisitorByDoc?.jsonBody ?? '')) !=
null) {
_model.addToVisitors(PhpGroup.getVisitorByDocCall.visitante(
(_model.getVisitorByDoc?.jsonBody ?? ''),
));
safeSetState(() {});
_model.addToDocs(_model.textController.text);
safeSetState(() {});
} else {
await showAdaptiveDialog(
useSafeArea: true,
context: context,
builder: (context) {
return Dialog(
child: VisitorNotFoundComponentWidget(
doc: _model.textController.text,
),
);
},
).then((value) => safeSetState(() {
if (value != null) {
addVisitor(context);
}
}));
}
}
}

View File

@ -1,5 +1,3 @@
import '/backend/schema/structs/index.dart';
import 'dart:developer';
import '/backend/schema/enums/enums.dart';
@ -12,29 +10,14 @@ import 'package:flutter/material.dart';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
Future<String?> getDevUUID() async {
var deviceInfo = DeviceInfoPlugin();
if (Platform.isIOS) {
// import 'dart:io'
var iosDeviceInfo = await deviceInfo.iosInfo;
log('DeviceInfoPlugin => iosDeviceInfo.utsname.machine: ${iosDeviceInfo.utsname.machine}'); // e.g. "iPod7,1"
log('DeviceInfoPlugin => iosDeviceInfo.systemName: ${iosDeviceInfo.systemName}'); // e.g. "iOS"
log('DeviceInfoPlugin => iosDeviceInfo.systemVersion: ${iosDeviceInfo.systemVersion}'); // e.g. "13.3"
log('DeviceInfoPlugin => iosDeviceInfo.model: ${iosDeviceInfo.model}'); // e.g. "iPhone"
log('DeviceInfoPlugin => iosDeviceInfo.localizedModel: ${iosDeviceInfo.localizedModel}'); // e.g. "iPhone"
log('DeviceInfoPlugin => iosDeviceInfo.identifierForVendor: ${iosDeviceInfo.identifierForVendor}'); // e.g. "A8E9F7C8-4D1F-4D97-9C3B-3A3D0F0F3E9E"
return iosDeviceInfo.identifierForVendor; // unique ID on iOS
} else if (Platform.isAndroid) {
var androidDeviceInfo = await deviceInfo.androidInfo;
// log('Running on ${androidDeviceInfo.androidId}'); // e.g. "A8E9F7C8-4D1F-4D97-9C3B-3A3D0F0F3E9E"
log('DeviceInfoPLugin => androidDeviceInfo.model: ${androidDeviceInfo.model}'); // e.g. "iPhone"
log('DeviceInfoPLugin => androidDeviceInfo.manufacturer: ${androidDeviceInfo.manufacturer}'); // e.g. "iPhone"
log('DeviceInfoPLugin => androidDeviceInfo.product: ${androidDeviceInfo.product}'); // e.g. "iPhone"
log('DeviceInfoPLugin => androidDeviceInfo.device: ${androidDeviceInfo.device}'); // e.g. "iPhone"
log('DeviceInfoPLugin => androidDeviceInfo.id: ${androidDeviceInfo.id}'); // e.g. "iPhone"
return androidDeviceInfo.id; // unique ID on Android
}
}
@ -44,21 +27,9 @@ Future<String?> getSerialNumber() async {
if (Platform.isIOS) {
// import 'dart:io'
var iosDeviceInfo = await deviceInfo.iosInfo;
log('DeviceInfoPlugin => iosDeviceInfo.utsname.machine: ${iosDeviceInfo.utsname.machine}'); // e.g. "iPod7,1"
log('DeviceInfoPlugin => iosDeviceInfo.systemName: ${iosDeviceInfo.systemName}'); // e.g. "iOS"
log('DeviceInfoPlugin => iosDeviceInfo.systemVersion: ${iosDeviceInfo.systemVersion}'); // e.g. "13.3"
log('DeviceInfoPlugin => iosDeviceInfo.model: ${iosDeviceInfo.model}'); // e.g. "iPhone"
log('DeviceInfoPlugin => iosDeviceInfo.localizedModel: ${iosDeviceInfo.localizedModel}'); // e.g. "iPhone"
log('DeviceInfoPlugin => iosDeviceInfo.identifierForVendor: ${iosDeviceInfo.identifierForVendor}'); // e.g. "A8E9F7C8-4D1F-4D97-9C3B-3A3D0F0F3E9E"
return iosDeviceInfo.identifierForVendor; // unique ID on iOS
} else if (Platform.isAndroid) {
var androidDeviceInfo = await deviceInfo.androidInfo;
// log('Running on ${androidDeviceInfo.androidId}'); // e.g. "A8E9F7C8-4D1F-4D97-9C3B-3A3D0F0F3E9E"
log('DeviceInfoPLugin => androidDeviceInfo.model: ${androidDeviceInfo.model}'); // e.g. "iPhone"
log('DeviceInfoPLugin => androidDeviceInfo.manufacturer: ${androidDeviceInfo.manufacturer}'); // e.g. "iPhone"
log('DeviceInfoPLugin => androidDeviceInfo.product: ${androidDeviceInfo.product}'); // e.g. "iPhone"
log('DeviceInfoPLugin => androidDeviceInfo.device: ${androidDeviceInfo.device}'); // e.g. "iPhone"
log('DeviceInfoPLugin => androidDeviceInfo.id: ${androidDeviceInfo.id}'); // e.g. "iPhone"
return androidDeviceInfo.serialNumber; // unique ID on Android
}
}
}

View File

@ -60,7 +60,6 @@
// final path = _getStoragePath(_firebasePathPrefix(),
// widget.imageFile!.name!, false, 0);
// uploadData(path, image).then((value) {
// log('image cropped');
// widget.callBackAction!.call(value!);
// loading = false;
// });
@ -95,7 +94,6 @@
// setState(() {
// loading = true;
// });
// log('Button pressed ...');
// _crop_controller.crop();
// //widget.loading = true;

View File

@ -5,6 +5,9 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:collection/collection.dart';
import 'package:from_css_color/from_css_color.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'dart:math' show pow, pi, sin;
import 'package:intl/intl.dart';
import 'package:json_path/json_path.dart';
@ -505,7 +508,8 @@ void setDarkModeSetting(BuildContext context, ThemeMode themeMode) =>
void showSnackbar(
BuildContext context,
String message, {
String message,
bool error, {
bool loading = false,
int duration = 4,
}) {
@ -515,24 +519,101 @@ void showSnackbar(
content: Row(
children: [
if (loading)
const Padding(
padding: EdgeInsetsDirectional.only(end: 10.0),
Padding(
padding: const EdgeInsetsDirectional.only(end: 10.0),
child: SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
color: Colors.white,
color: FlutterFlowTheme.of(context).info,
),
),
),
Text(message),
Text(
message,
style: TextStyle(
color: FlutterFlowTheme.of(context).info,
),
),
],
),
duration: Duration(seconds: duration),
backgroundColor: error
? FlutterFlowTheme.of(context).error
: FlutterFlowTheme.of(context).success,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}
void showAlertDialog(BuildContext context, String title, String content,
Future<void> Function() action) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
title: Text(title),
content: Text(content),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
FFButtonWidget(
onPressed: () => Navigator.pop(context),
options: FFButtonOptions(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.05,
color: FlutterFlowTheme.of(context).primaryBackground,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10),
elevation: 0,
),
text: FFLocalizations.of(context).getVariableText(
enText: 'No',
ptText: 'Não',
),
),
FFButtonWidget(
onPressed: () async {
action();
},
options: FFButtonOptions(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.05,
color: FlutterFlowTheme.of(context).primaryBackground,
elevation: 0,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
text: FFLocalizations.of(context).getVariableText(
enText: 'Yes',
ptText: 'Sim',
),
),
],
),
],
);
});
}
extension FFStringExt on String {
String maybeHandleOverflow({int? maxChars, String replacement = ''}) =>
maxChars != null && length > maxChars

View File

@ -76,19 +76,18 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
FFRoute(
name: 'homePage',
path: '/homePage',
builder: (context, params) => params.isEmpty
? const HomePageWidget()
: const HomePageWidget(),
builder: (context, params) =>
params.isEmpty ? const HomePageWidget() : const HomePageWidget(),
),
// FFRoute(
// name: 'visitHistoryPage',
// path: '/visitHistoryPage',
// builder: (context, params) => const VisitHistoryPageWidget(),
// ),
FFRoute(
name: 'visitHistoryPage',
path: '/visitHistoryPage',
builder: (context, params) => const VisitHistoryPageWidget(),
),
FFRoute(
name: 'messageHistoryPage',
path: '/messageHistoryPage',
builder: (context, params) => const MessageHistoryPageWidget()),
name: 'messageHistoryPage',
path: '/messageHistoryPage',
builder: (context, params) => const MessageHistoryPageWidget()),
FFRoute(
name: 'registerVisitorPage',
path: '/registerVisitorPage',
@ -98,38 +97,10 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
name: 'scheduleCompleteVisitPage',
path: '/scheduleCompleteVisitPage',
builder: (context, params) => ScheduleCompleteVisitPageWidget(
// get current datatime picker dd/mm/aaaa hh:mm:ss
// visitStartDateStr: DateTime.now().toString(),
// post 1 day
// visitEndDateStr: DateTime.now().add(const Duration(days: 1)).toString(),
visitorStrList: params.getParam(
'visitorStrList',
ParamType.String,
),
visitStartDateStr: params.getParam(
'visitStartDateStr',
ParamType.String,
),
visitEndDateStr: params.getParam(
'visitEndDateStr',
ParamType.String,
),
visitReasonStr: params.getParam(
'visitReasonStr',
ParamType.String,
),
visitLevelStr: params.getParam(
'visitLevelStr',
ParamType.String,
),
visitTempBol: params.getParam(
'visitTempBol',
ParamType.bool,
),
visitObsStr: params.getParam(
'visitObsStr',
ParamType.String,
),
visitorJsonList: params.getParam<dynamic>(
'visitorJsonList',
ParamType.JSON,
@ -148,9 +119,12 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
path: '/fastPassPage',
builder: (context, params) => /*const*/ FastPassPageWidget(),
),
FFRoute(name: 'preferencesSettings', path: '/preferencesSettings', builder: (context, params) => const PreferencesPageWidget(
key: Key('preferencesSettings'),
)),
FFRoute(
name: 'preferencesSettings',
path: '/preferencesSettings',
builder: (context, params) => const PreferencesPageWidget(
key: Key('preferencesSettings'),
)),
FFRoute(
name: 'peopleOnThePropertyPage',
path: '/peopleOnThePropertyPage',

View File

@ -10,7 +10,6 @@ import '../../flutter_flow/lat_lng.dart';
import '../../flutter_flow/place.dart';
import '../../flutter_flow/uploaded_file.dart';
/// SERIALIZATION HELPERS
String dateTimeRangeToString(DateTimeRange dateTimeRange) {
@ -85,7 +84,6 @@ String? serializeParam(
}
return data;
} catch (e) {
log('Error serializing parameter: $e');
return null;
}
}
@ -226,7 +224,6 @@ dynamic deserializeParam<T>(
return null;
}
} catch (e) {
log('Error deserializing parameter: $e');
return null;
}
}

View File

@ -11,7 +11,7 @@ import 'package:video_player/video_player.dart';
import 'flutter_flow_theme.dart';
import 'flutter_flow_util.dart';
const allowedFormats = {'image/png', 'image/jpeg', 'video/mp4', 'image/gif'};
const allowedFormats = {'image/png', 'image/jpeg'};
class SelectedFile {
const SelectedFile({

View File

@ -20,17 +20,16 @@ void main() async {
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
await initializeApp();
await init();
runApp(ChangeNotifierProvider(
create: (context) => FFAppState(),
child: const MyApp(),
));
}
Future<void> initializeApp() async {
Future<void> init() async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
await FlutterFlowTheme.initialize();
await FFLocalizations.initialize();
final appState = FFAppState();

View File

@ -354,10 +354,8 @@ class _AcessHistoryPageWidgetState extends State<AcessHistoryPageWidget> {
Widget _accessHistoryCardMoleculeWidget(
BuildContext context, dynamic accessHistoryItem) {
return CardItemTemplateComponentWidget(
imageHashMap: Map<String, String>.from({
'key': accessHistoryItem['PES_ID'] ?? '',
'value': accessHistoryItem['PES_TIPO'] ?? '',
}),
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${accessHistoryItem['PES_ID'] ?? ''}&tipo=${accessHistoryItem['PES_TIPO'] ?? ''}',
labelsHashMap: Map<String, String>.from({
'Nome:': accessHistoryItem['PES_NOME'] ?? '',
'Acesso:': accessHistoryItem['ACE_DATAHORA'] ?? '',

View File

@ -298,9 +298,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
color: FlutterFlowTheme.of(context).info,
size: 24.0,
),
onPressed: () {
log('IconButton pressed ...');
},
onPressed: () {},
),
),
),
@ -545,7 +543,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
),
FFButtonWidget(
onPressed: () async {
FFAppState().isLogged = false;
FFAppState().deleteAll();
setState(() {});
context.goNamed(

View File

@ -12,6 +12,7 @@ import 'package:hub/flutter_flow/custom_functions.dart';
import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:cached_network_image/cached_network_image.dart';
@ -21,7 +22,6 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:hub/pages/liberation_history/liberation_history_model.dart';
import 'package:provider/provider.dart';
class LiberationHistoryWidget extends StatefulWidget {
const LiberationHistoryWidget({super.key});
@ -53,7 +53,7 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
void onUpdate(BuildContext context) {
_model.clearGetLiberationsCache();
setState(() {});
safeSetState(() {});
}
@override
@ -258,11 +258,9 @@ Widget liberationDynamicListView(
.where((item) => jsonToStr(getJsonField(
item,
r'''$.VTE_NOME''',
))
.toLowerCase()
.contains(
_model.textController.text.toLowerCase(),
))
)).toLowerCase().contains(
_model.textController.text.toLowerCase(),
))
.toList()
: liberationHistory;
@ -300,60 +298,126 @@ Widget liberationDynamicListView(
Widget liberationHistoryItemCard(
BuildContext context, dynamic liberationHistoryItem) {
return CardItemTemplateComponentWidget(
imageHashMap: Map<String, String>.from({
'key': liberationHistoryItem['VTE_ID'],
'value': 'E',
}),
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${liberationHistoryItem['VTE_ID'] ?? ''}&tipo=E',
labelsHashMap: Map<String, String>.from({
'Nome:': liberationHistoryItem['VTE_NOME'],
'Data:': liberationHistoryItem['NOT_DTENVIO'],
'Motivo:': liberationHistoryItem['NOT_MOTIVO'],
}),
statusHashMap: [liberationHistoryItem['NOT_STATUS'] == 'L'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Ativo',
enText: 'Active',
): FlutterFlowTheme.of(context).success,
})
: liberationHistoryItem['NOT_STATUS'] == 'B'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Bloqueado',
enText: 'Blocked',
): FlutterFlowTheme.of(context).error,
})
: Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Pendente',
enText: 'Pending',
): FlutterFlowTheme.of(context).warning,
})],
statusHashMap: [
liberationHistoryItem['NOT_STATUS'] == 'L'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Finalizado',
enText: 'Finished',
): FlutterFlowTheme.of(context).success,
})
: liberationHistoryItem['NOT_STATUS'] == 'B'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Bloqueado',
enText: 'Blocked',
): FlutterFlowTheme.of(context).error,
})
: Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Ativo',
enText: 'Active',
): FlutterFlowTheme.of(context).warning,
})
],
onTapCardItemAction: () async {
showModalBottomSheet(
isScrollControlled: true,
isDismissible: true,
backgroundColor: Colors.transparent,
showDialog(
// isScrollControlled: true,
// isDismissible: true,
// backgroundColor: Colors.transparent,
useSafeArea: true,
context: context,
builder: (context) {
return DetailsComponentWidget(
vteName: liberationHistoryItem['VTE_NOME'],
vteReason: liberationHistoryItem['NOT_MOTIVO'],
vawDate: liberationHistoryItem['NOT_STATUS'] == 'S'
? liberationHistoryItem['NOT_DTENVIO']
: liberationHistoryItem['NOT_DTRESPOSTA'],
vawStatus: liberationHistoryItem['NOT_STATUS'],
vteMsg: liberationHistoryItem['NOT_MSGENVIO'],
vteUUID: liberationHistoryItem['VTE_ID'],
cliUUID: FFAppState().cliUUID,
msgUUID: liberationHistoryItem['NOT_ID'],
vawDestino: liberationHistoryItem['NOT_DESTINO'],
vawUUID: liberationHistoryItem['NOT_ID'],
vawName: liberationHistoryItem['NOT_NOME'],
vawRef: liberationHistoryItem['NOT_ID'],
changeStatusAction: changeStatusAction,
// vteDocument: liberationHistoryItem['VTE_DOCUMENTO'],
return Dialog(
alignment: Alignment.center,
child: DetailsComponentWidget(
// vteName: liberationHistoryItem['VTE_NOME'],
// vteReason: liberationHistoryItem['NOT_MOTIVO'],
// vawDate: liberationHistoryItem['NOT_STATUS'] == 'S'
// ? liberationHistoryItem['NOT_DTENVIO']
// : liberationHistoryItem['NOT_DTRESPOSTA'],
// vawStatus: liberationHistoryItem['NOT_STATUS'],
// vteMsg: liberationHistoryItem['NOT_MSGENVIO'],
// vteUUID: liberationHistoryItem['VTE_ID'],
// cliUUID: FFAppState().cliUUID,
// msgUUID: liberationHistoryItem['NOT_ID'],
// vawDestino: liberationHistoryItem['NOT_DESTINO'],
// vawUUID: liberationHistoryItem['NOT_ID'],
// vawName: liberationHistoryItem['NOT_NOME'],
// vawRef: liberationHistoryItem['NOT_ID'],
labelsHashMap: Map<String, String>.from({
'Nome:': liberationHistoryItem['VTE_NOME'],
'Data:': liberationHistoryItem['NOT_DTENVIO'],
'Motivo:': liberationHistoryItem['NOT_MOTIVO'],
'Mensagem:': liberationHistoryItem['NOT_MSGENVIO'],
// 'Resposta:': liberationHistoryItem['NOT_MSGRESPOSTA'],
}),
buttons: [
if (liberationHistoryItem['NOT_STATUS'] == 'S')
FlutterFlowIconButton(
icon: const Icon(Icons.done),
onPressed: () async {
Navigator.pop(context);
await answersRequest
.call(
context,
liberationHistoryItem['NOT_ID'].toString(),
'L',
'Mensagem',
liberationHistoryItem['VTE_ID'].toString(),
)
.then((value) {
if (value) {
return showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
enText: 'Successfully resolved visit',
ptText: 'Visita resolvida com sucesso'),
false);
} else {
return showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
enText: 'Error resolving visit',
ptText: 'Erro ao resolver visita'),
true);
}
});
},
),
],
statusHashMap: [
liberationHistoryItem['NOT_STATUS'] == 'L'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Finalizado',
enText: 'Finished',
): FlutterFlowTheme.of(context).success,
})
: liberationHistoryItem['NOT_STATUS'] == 'B'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Bloqueado',
enText: 'Blocked',
): FlutterFlowTheme.of(context).error,
})
: Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Ativo',
enText: 'Active',
): FlutterFlowTheme.of(context).warning,
})
],
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${liberationHistoryItem['VTE_ID'] ?? ''}&tipo=E',
),
);
},
).then((_) {
@ -362,9 +426,13 @@ Widget liberationHistoryItemCard(
_pushNotificationService.onMessageReceived.listen((received) {
if (received.data['click_action'] == 'cancel_request') {
log('Aprovado');
_pushNotificationService.dispose();
snackbar(context, opt: true);
showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
enText: 'Successfully resolved visit',
ptText: 'Visita resolvida com sucesso'),
false);
context.pushReplacementNamed(
'liberationHistory',
extra: <String, dynamic>{

View File

@ -1,10 +1,7 @@
// import 'dart:js_interop';
import 'dart:developer';
import 'package:hub/app_state.dart';
import 'package:hub/backend/api_requests/api_calls.dart';
import 'package:hub/backend/api_requests/api_manager.dart';
import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
@ -15,6 +12,8 @@ import 'package:hub/pages/message_history_page/message_history_page_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hub/shared/utils/dialog_util.dart';
import 'package:hub/shared/utils/log_util.dart';
import 'package:provider/provider.dart';
class MessageHistoryPageWidget extends StatefulWidget {
@ -31,16 +30,48 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
final scaffoldKey = GlobalKey<ScaffoldState>();
late ScrollController _scrollController;
int _pageNumber = 1;
final int _pageSize = 10;
bool _hasData = false;
bool _loading = false;
String _destinyType = "P";
late Future<void> _messageFuture;
List<dynamic> _messageWrap = [];
@override
void initState() {
super.initState();
_model = createModel(context, () => MessageHistoryPageModel());
_model.tabBarController = TabController(
vsync: this,
length: 3,
initialIndex: 1,
)..addListener(() => setState(() {}));
_messageFuture = fetchMessage();
_scrollController = ScrollController()
..addListener(() {
if (_scrollController.position.atEdge &&
_scrollController.position.pixels != 0) {
_loadMore();
}
});
_model.tabBarController =
TabController(vsync: this, length: 3, initialIndex: 0)
..addListener(() {
if (_model.tabBarController?.index == 0) {
_destinyType = "P";
} else if (_model.tabBarController?.index == 1) {
_destinyType = "A";
} else {
_destinyType = "T";
}
_pageNumber = 1;
_messageWrap = [];
_messageFuture = fetchMessage();
});
_model.textController ??= TextEditingController();
_model.textFieldFocusNode ??= FocusNode();
@ -49,13 +80,13 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
@override
void dispose() {
_model.dispose();
_scrollController.dispose();
super.dispose();
}
void onUpdate(BuildContext context) {
_model.clearGetLiberationsCache();
setState(() {});
safeSetState(() {});
}
@override
@ -64,245 +95,302 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
return Scaffold(
key: scaffoldKey,
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
appBar: appBarMessage(context),
body: bodyMessage(context, _model),
appBar: _appBar(context),
body: _body(context),
);
}
}
PreferredSizeWidget appBarMessage(BuildContext context) {
return AppBar(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
automaticallyImplyLeading: false,
leading: FlutterFlowIconButton(
borderColor: Colors.transparent,
borderRadius: 30.0,
borderWidth: 1.0,
buttonSize: 60.0,
icon: Icon(
Icons.keyboard_arrow_left,
color: FlutterFlowTheme.of(context).primaryText,
size: 30.0,
),
onPressed: () async {
context.pop();
},
),
title: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Message History',
ptText: 'Histórico de Mensagens',
),
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: 'Nunito',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 17.0,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'),
),
),
actions: const [],
centerTitle: true,
);
}
Future<ApiCallResponse?> fetchMessage() async {
try {
setState(() => _loading = true);
Widget bodyMessage(BuildContext context, MessageHistoryPageModel _model) {
return SafeArea(
top: true,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Align(
alignment: const Alignment(0.0, 0),
child: TabBar(
labelColor: FlutterFlowTheme.of(context).primaryText,
unselectedLabelColor: FlutterFlowTheme.of(context).primaryText,
labelStyle: FlutterFlowTheme.of(context).titleMedium.override(
fontFamily: FlutterFlowTheme.of(context).titleMediumFamily,
fontSize: 13.0,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).titleMediumFamily),
),
unselectedLabelStyle: const TextStyle(),
indicatorColor: FlutterFlowTheme.of(context).primary,
padding: const EdgeInsets.all(4.0),
tabs: [
Tab(
text: FFLocalizations.of(context).getVariableText(
ptText: 'Pessoal',
enText: 'Personal',
),
),
Tab(
text: FFLocalizations.of(context).getVariableText(
enText: 'All',
ptText: 'Todos',
),
),
Tab(
text: FFLocalizations.of(context).getVariableText(
ptText: 'Global',
enText: 'Global',
),
),
],
controller: _model.tabBarController,
onTap: (i) async {
[() async {}, () async {}][i]();
},
),
),
Expanded(
child: TabBarView(controller: _model.tabBarController, children: [
liberationDynamicListView(context, _model, 'P'),
liberationDynamicListView(context, _model, 'A'),
liberationDynamicListView(context, _model, 'T'),
])),
].addToStart(const SizedBox(height: 0)),
),
);
}
Widget liberationDynamicListView(
BuildContext context, MessageHistoryPageModel _model, String DestIndex) {
return Container(
width: double.infinity,
height: double.infinity,
decoration: const BoxDecoration(),
child: FutureBuilder<ApiCallResponse>(
future: PhpGroup.getMessagesCall
.call(
var response = await PhpGroup.getMessagesCall.call(
devUUID: FFAppState().devUUID.toString(),
userUUID: FFAppState().userUUID.toString(),
cliID: FFAppState().cliUUID.toString(),
atividade: 'getMensagens',
pageSize: '100',
pageNumber: '1',
tipoDestino: DestIndex,
)
.catchError((error) {
log('Error: ${error.toString()}');
return Future.delayed(Duration(seconds: 1), () {
return Center(
child: Text('Erro ao carregar mensagens'),
);
});
}),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: SizedBox(
width: 50.0,
height: 50.0,
child: SpinKitCircle(
color: FlutterFlowTheme.of(context).primary,
size: 50.0,
),
),
);
}
if (snapshot.hasError == true || snapshot.data == null) {
log('Error: ${snapshot.error.toString()}');
// log('Error: ${snapshot.data!.jsonBody['mensagens']}');
return const Center(
child: Text('Erro ao carregar mensagens'),
);
}
final mensagens = snapshot.data!.jsonBody['mensagens'];
final totalRows = snapshot.data!.jsonBody['total_rows'];
if (totalRows == 0 || mensagens == null || mensagens.isEmpty) {
return const Center(
child: Text('Nenhuma mensagem encontrada'),
);
}
return ListView.builder(
itemCount: totalRows,
addAutomaticKeepAlives: false,
addRepaintBoundaries: true,
cacheExtent: 1000.0,
itemBuilder: (BuildContext context, int index) {
return messageHistoryItem(
context,
snapshot.data!.jsonBody['mensagens'][index],
);
},
);
},
),
);
}
pageSize: _pageSize.toString(),
pageNumber: _pageNumber.toString(),
tipoDestino: _destinyType,
);
Widget messageHistoryItem(BuildContext context, dynamic jsonBody) {
log(jsonBody.toString());
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Card(
child: Container(
// height: 100,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
final List<dynamic> messages = response.jsonBody['mensagens'] ?? [];
if (messages != null && messages.isNotEmpty) {
setState(() {
_messageWrap.addAll(messages);
_hasData = true;
_loading = false;
});
return response;
}
_showNoMoreDataSnackBar(context);
setState(() {
_hasData = false;
_loading = false;
});
return null;
} catch (e, s) {
DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed(
"proccessRequest.php", "", "Consulta de Mensagems", e, s);
setState(() {
_hasData = false;
_loading = false;
});
}
}
void _loadMore() {
if (_hasData == true) {
_pageNumber++;
_messageFuture = fetchMessage();
}
}
PreferredSizeWidget _appBar(BuildContext context) {
return AppBar(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
automaticallyImplyLeading: false,
leading: FlutterFlowIconButton(
borderColor: Colors.transparent,
borderRadius: 30.0,
borderWidth: 1.0,
buttonSize: 60.0,
icon: Icon(
Icons.keyboard_arrow_left,
color: FlutterFlowTheme.of(context).primaryText,
size: 30.0,
),
onPressed: () async {
context.pop();
},
),
title: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Message History',
ptText: 'Histórico de Mensagens',
),
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: 'Nunito',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 17.0,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'),
),
),
actions: const [],
centerTitle: true,
);
}
Widget _body(BuildContext context) {
return SafeArea(
top: true,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Align(
alignment: const Alignment(0.0, 0),
child: TabBar(
labelColor: FlutterFlowTheme.of(context).primaryText,
unselectedLabelColor: FlutterFlowTheme.of(context).primaryText,
labelStyle: FlutterFlowTheme.of(context).titleMedium.override(
fontFamily: FlutterFlowTheme.of(context).titleMediumFamily,
fontSize: 13.0,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).titleMediumFamily),
),
unselectedLabelStyle: const TextStyle(),
indicatorColor: FlutterFlowTheme.of(context).primary,
padding: const EdgeInsets.all(4.0),
tabs: [
Tab(
text: FFLocalizations.of(context).getVariableText(
ptText: 'Pessoal',
enText: 'Personal',
),
),
Tab(
text: FFLocalizations.of(context).getVariableText(
enText: 'All',
ptText: 'Todos',
),
),
Tab(
text: FFLocalizations.of(context).getVariableText(
ptText: 'Global',
enText: 'Global',
),
),
],
controller: _model.tabBarController,
),
),
if (_hasData == false && _pageNumber <= 1 && _loading == false)
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Text(
jsonBody['MSG_DATE'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 10,
color: FlutterFlowTheme.of(context).customColor6,
overflow: TextOverflow.ellipsis,
),
),
),
],
),
Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Text(
jsonBody['MSG_ORIGEM_DESC'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 12,
color: FlutterFlowTheme.of(context).primary,
),
overflow: TextOverflow.fade,
),
),
Icon(
jsonBody['MSG_DESTINO_TP'] == 'T'
? Icons.group
: Icons.person,
color: FlutterFlowTheme.of(context).primary,
),
],
),
Center(
child: Text(FFLocalizations.of(context).getVariableText(
ptText: "Nenhuma mensagem encontrada!",
enText: "No message found")),
)
],
),
SizedBox(height: 8),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
jsonBody['MSG_TEXTO'].toString(),
)
else if (_hasData == true || _pageNumber >= 1)
Expanded(
child: FutureBuilder<void>(
future: _messageFuture,
builder: (context, snapshot) {
return ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
controller: _scrollController,
itemCount: _messageWrap.length,
itemBuilder: (context, index) {
final item = _messageWrap[index];
return _item(context, item);
});
},
),
),
if (_hasData == true && _loading == true)
Container(
padding: const EdgeInsets.only(top: 15, bottom: 15),
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
FlutterFlowTheme.of(context).primary,
),
),
),
SizedBox(height: 8),
],
),
),
)
].addToStart(const SizedBox(height: 0)),
),
),
);
);
}
void _showNoMoreDataSnackBar(BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText: "Não há mais dados.", enText: "No more data."),
),
duration: const Duration(seconds: 3),
backgroundColor: FlutterFlowTheme.of(context).primary,
),
);
}
Widget _item(BuildContext context, dynamic jsonBody) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Card(
color: FlutterFlowTheme.of(context).primaryBackground,
child: Container(
// height: 100,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Icon(
jsonBody['MSG_DESTINO_TP'] == 'T'
? Icons.language
: jsonBody['MSG_DESTINO_TP'] == 'P'
? Icons.person
: Icons.home,
color: FlutterFlowTheme.of(context).primary,
size: 25,
),
Expanded(
child: Text(
jsonBody['MSG_ORIGEM_DESC'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: FlutterFlowTheme.of(context).primary,
),
overflow: TextOverflow.fade,
),
),
].divide(const SizedBox(width: 10)),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsets.only(left: 5),
child: Icon(
Icons.history,
color:
FlutterFlowTheme.of(context).customColor6,
size: 15,
),
),
Expanded(
child: Text(
jsonBody['MSG_DATE'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 10,
color:
FlutterFlowTheme.of(context).customColor6,
),
overflow: TextOverflow.ellipsis,
),
),
].divide(const SizedBox(width: 15)),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsets.only(left: 5),
child: Icon(
Icons.message,
color:
FlutterFlowTheme.of(context).customColor6,
size: 15,
),
),
Expanded(
child: Text(
jsonBody['MSG_TEXTO'].toString(),
),
),
].divide(const SizedBox(width: 15)),
),
].divide(const SizedBox(height: 4)),
),
),
].divide(
const SizedBox(height: 8),
),
),
),
),
));
}
}

View File

@ -8,6 +8,7 @@ import 'package:hub/components/templates_components/change_passs_qr_code_pass_ke
import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:share_plus/share_plus.dart';
@ -38,202 +39,699 @@ class PreferencesPageModel with ChangeNotifier {
padding: MediaQuery.viewInsetsOf(context),
child: PassKeyTemplateWidget(
toggleActionStatus: (key) async {
log(key);
FFAppState().fingerprintPass = key;
FFAppState().fingerprint = true;
},
),
);
},
).whenComplete(() => notifyListeners());
).then((value) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Fingerprint changed successfully',
ptText: 'Impressão digital alterada com sucesso',
),
style: TextStyle(color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).success,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}).catchError((err, stack) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao alterar impressão digital',
enText: 'Error changing fingerprint',
),
style: TextStyle(color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}).whenComplete(() => notifyListeners());
}
}
void enablePerson(BuildContext context) {
notifyListeners();
Share.share(
FFAppState().userDevUUID,
FFLocalizations.of(context).getVariableText(
ptText:
'Este é o meu identificador de acesso: ${FFAppState().userDevUUID}',
enText: 'This is my access identifier: ${FFAppState().userDevUUID}',
),
);
}
void toggleNotify(BuildContext context) {
FFAppState().notify = !FFAppState().notify;
PhpGroup.changeNotifica
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
atividade: 'updVisitado',
notifica: FFAppState().notify ? 'S' : 'N',
)
.catchError((err) {
log(err.toString());
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
showDialog(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
title: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Error changing notification',
ptText: 'Erro ao alterar notificação',
enText: FFAppState().notify
? 'Disable Access Notification'
: 'Access Notification',
ptText: FFAppState().notify
? 'Desativar notificação de acesso'
: 'Notificação de acesso'),
),
content: Text(
FFLocalizations.of(context).getVariableText(
ptText: FFAppState().notify
? 'Tem certeza que deseja desativar as suas notificações de acesso?'
: 'Tem certeza que deseja receber as suas notificações de acesso?',
enText: FFAppState().notify
? 'Are you sure you want to disable your access notifications?'
: 'Are you sure you want to receive your access notifications?'),
),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
FFButtonWidget(
text: FFLocalizations.of(context).getVariableText(
enText: 'No',
ptText: 'Não',
),
onPressed: () {
Navigator.pop(context);
},
options: FFButtonOptions(
elevation: 0,
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.05,
color: FlutterFlowTheme.of(context).primaryBackground,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10)),
),
FFButtonWidget(
onPressed: () async {
try {
PhpGroup.changeNotifica
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
atividade: 'updVisitado',
notifica: FFAppState().notify ? 'S' : 'N',
)
.then((value) {
if (value.jsonBody['error'] == false) {
Navigator.pop(context);
FFAppState().notify = !FFAppState().notify;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText:
'Notificação alterada com sucesso',
enText:
'Notification changed successfully',
),
style: TextStyle(
color:
FlutterFlowTheme.of(context).info)),
backgroundColor:
FlutterFlowTheme.of(context).success,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao alterar notificação',
enText: 'Error changing notification',
),
style: TextStyle(
color:
FlutterFlowTheme.of(context).info)),
backgroundColor:
FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}
}).catchError((err) {
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Error changing notification',
ptText: 'Erro ao alterar notificação',
),
style: TextStyle(
color:
FlutterFlowTheme.of(context).info)),
backgroundColor:
FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}).whenComplete(() => notifyListeners());
} on Exception catch (e) {
log(e.toString());
Navigator.pop(context);
}
},
text: FFLocalizations.of(context).getVariableText(
enText: 'Yes',
ptText: 'Sim',
),
options: FFButtonOptions(
elevation: 0,
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.05,
color: FlutterFlowTheme.of(context).primaryBackground,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
),
],
),
style: TextStyle(color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
});
],
);
});
notifyListeners();
}
void localUnlink(BuildContext context) {
PhpGroup.resopndeVinculo
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
tarefa: 'I',
)
.catchError((err) {
log(err.toString());
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
showDialog(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
title: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Error unlinking device',
ptText: 'Erro ao desvincular dispositivo',
enText: 'Unlink device',
ptText: 'Desvincular dispositivo',
),
style: TextStyle(color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}).then(
(value) {
FFAppState().deleteCliUUID();
FFAppState().deleteLocal();
FFAppState().deleteOwnerUUID();
Navigator.pop(context);
},
);
),
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Are you sure you want to unlink this device?',
ptText: 'Tem certeza que deseja desvincular este dispositivo?',
),
),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
FFButtonWidget(
text: FFLocalizations.of(context).getVariableText(
enText: 'Cancel',
ptText: 'Cancelar',
),
onPressed: () {
Navigator.pop(context);
},
options: FFButtonOptions(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.05,
color: FlutterFlowTheme.of(context).primaryBackground,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10)),
),
FFButtonWidget(
onPressed: () async {
try {
await PhpGroup.resopndeVinculo
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
tarefa: 'I',
)
.then((value) {
if (value.jsonBody['error'] == false) {
FFAppState().deleteCliUUID();
FFAppState().deleteLocal();
FFAppState().deleteOwnerUUID();
Navigator.pop(context);
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Device unlinked successfully',
ptText:
'Dispositivo desvinculado com sucesso',
),
style: TextStyle(
color:
FlutterFlowTheme.of(context).info)),
backgroundColor:
FlutterFlowTheme.of(context).success,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}
})
// ignore: body_might_complete_normally_catch_error
.catchError((err, stack) {
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Error unlinking device',
ptText: 'Erro ao desvincular dispositivo',
),
style: TextStyle(
color:
FlutterFlowTheme.of(context).info)),
backgroundColor:
FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
});
notifyListeners();
} catch (err, stack) {
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Error unlinking device',
ptText: 'Erro ao desvincular dispositivo',
),
style: TextStyle(
color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}
},
text: FFLocalizations.of(context).getVariableText(
enText: 'Unlink',
ptText: 'Desvincular',
),
options: FFButtonOptions(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.05,
color: FlutterFlowTheme.of(context).primaryBackground,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
),
],
),
],
);
});
notifyListeners();
}
void deleteAccount(BuildContext context) {
FFAppState().deleteAll();
FFAppState().isLogged = false;
context.goNamed(
'welcomePage',
extra: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.scale,
alignment: Alignment.bottomCenter,
),
},
);
showDialog(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
title: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Delete account',
ptText: 'Deletar conta',
),
),
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Are you sure you want to delete your account?',
ptText: 'Tem certeza que deseja deletar sua conta?',
),
),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
FFButtonWidget(
onPressed: () => Navigator.pop(context),
options: FFButtonOptions(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.05,
color: FlutterFlowTheme.of(context).primaryBackground,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
text: FFLocalizations.of(context).getVariableText(
enText: 'Cancel',
ptText: 'Cancelar',
),
),
FFButtonWidget(
onPressed: () async {
try {
await PhpGroup.deleteAccount
.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
)
.then((value) {
if (value.jsonBody['error'] == false) {
FFAppState().deleteAll();
FFAppState().isLogged = false;
context.goNamed(
'welcomePage',
extra: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.scale,
alignment: Alignment.bottomCenter,
),
},
);
}
}).catchError((err) {
log(err.toString());
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Error deleting account',
ptText: 'Erro ao deletar conta',
),
style: TextStyle(
color:
FlutterFlowTheme.of(context).info)),
backgroundColor:
FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
});
notifyListeners();
} catch (err, stack) {
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Error deleting account',
ptText: 'Erro ao deletar conta',
),
style: TextStyle(
color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}
},
options: FFButtonOptions(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.05,
color: FlutterFlowTheme.of(context).primaryBackground,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
text: FFLocalizations.of(context).getVariableText(
enText: 'Delete',
ptText: 'Deletar',
),
),
],
),
],
);
});
notifyListeners();
}
Future<void> togglePass(BuildContext context) async {
debugPrint('pass: ${FFAppState().pass}');
if (FFAppState().pass) {
FFAppState().pass = false;
FFAppState().deleteAccessPass();
notifyListeners();
} else {
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
useSafeArea: true,
context: context,
builder: (context) {
return Padding(
padding: MediaQuery.viewInsetsOf(context),
child: PassKeyTemplateWidget(
toggleActionStatus: (key) async {
FFAppState().accessPass = key;
notifyListeners();
debugPrint('key: $key');
await PhpGroup.changePass
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
atividade: 'updVisitado',
newSenha: FFAppState().accessPass,
)
.then((value) {
// if (FFAppState().pass) {
// FFAppState().pass = false;
// FFAppState().deleteAccessPass();
// notifyListeners();
// } else {
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
useSafeArea: true,
context: context,
builder: (context) {
return Padding(
padding: MediaQuery.viewInsetsOf(context),
child: PassKeyTemplateWidget(
toggleActionStatus: (key) async {
FFAppState().accessPass = key;
notifyListeners();
await PhpGroup.changePass
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
atividade: 'updVisitado',
newSenha: FFAppState().accessPass,
)
.then((value) {
// var error = jsonDecode(value.jsonBody['error'].toString());
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
FFAppState().pass = true;
// var error = jsonDecode(value.jsonBody['error'].toString());
// log('${jsonDecode(value.jsonBody['error'].toString())}');
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
FFAppState().pass = true;
} else {
FFAppState().pass = false;
}
}).onError((error, StackTrace) {
FFAppState().pass = false;
log(error.toString());
log(StackTrace.toString());
}).whenComplete(() => notifyListeners());
},
),
);
},
);
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Access password changed successfully',
ptText: 'Senha de acesso alterada com sucesso',
),
style: TextStyle(
color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).success,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao alterar senha de acesso',
enText: 'Error changing access password',
),
style: TextStyle(
color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
// FFAppState().pass = false;
}
}).catchError((error, StackTrace) {
// FFAppState().pass = false;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao alterar senha de acesso',
enText: 'Error changing access password',
),
style: TextStyle(
color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}).whenComplete(() => notifyListeners());
},
),
);
},
);
// }
}
Future<void> togglePanic(BuildContext context) async {
if (FFAppState().panic) {
FFAppState().panic = false;
FFAppState().deletePanicPass();
notifyListeners();
} else {
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
useSafeArea: true,
context: context,
builder: (context) {
return Padding(
padding: MediaQuery.viewInsetsOf(context),
child: PassKeyTemplateWidget(
toggleActionStatus: (key) async {
FFAppState().panicPass = key;
notifyListeners();
await PhpGroup.changePass
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
atividade: 'updVisitado',
newSenha: FFAppState().panicPass,
)
.then((value) {
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
useSafeArea: true,
context: context,
builder: (context) {
return Padding(
padding: MediaQuery.viewInsetsOf(context),
child: PassKeyTemplateWidget(
toggleActionStatus: (key) async {
FFAppState().panicPass = key;
notifyListeners();
await PhpGroup.changePanic
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
atividade: 'updVisitado',
newSenhaPanico: FFAppState().panicPass,
)
.then((value) {
FFAppState().panic = true;
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
FFAppState().panic = true;
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
FFAppState().panic = true;
} else {
FFAppState().panic = false;
}
}).onError((e, s) {
FFAppState().panic = false;
log(e.toString());
log(s.toString());
}).whenComplete(() => notifyListeners());
},
),
);
},
);
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Panic password changed successfully',
ptText: 'Senha de pânico alterada com sucesso',
),
style: TextStyle(
color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).success,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao alterar senha de pânico',
enText: 'Error changing panic password',
),
style: TextStyle(
color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
// FFAppState().panic = false;
}
}).catchError((e, s) {
// FFAppState().panic = false;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao alterar senha de pânico',
enText: 'Error changing panic password',
),
style: TextStyle(
color: FlutterFlowTheme.of(context).info)),
backgroundColor: FlutterFlowTheme.of(context).error,
duration: const Duration(seconds: 3),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
);
}).whenComplete(() => notifyListeners());
},
),
);
},
);
}
@override

View File

@ -16,7 +16,6 @@ import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/pages/qr_code_page/qr_code_page_model.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
import 'dart:async';
// import 'package:barcode_widget/barcode_widget.dart';
import 'package:flutter/material.dart';
@ -27,81 +26,76 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:qr_flutter/qr_flutter.dart';
class QrCodePageWidget extends StatefulWidget {
const QrCodePageWidget({super.key});
@override
State<QrCodePageWidget> createState() => _QrCodePageWidgetState();
}
class _QrCodePageWidgetState extends State<QrCodePageWidget>
with TickerProviderStateMixin {
late QrCodePageModel _model;
final scaffoldKey = GlobalKey<ScaffoldState>();
final animationsMap = <String, AnimationInfo>{};
@override
void initState() {
super.initState();
_model = createModel(context, () => QrCodePageModel());
@override
void initState() {
super.initState();
_model = createModel(context, () => QrCodePageModel());
// On page load action.
SchedulerBinding.instance.addPostFrameCallback((_) async {
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!.controller.fling();
}
});
// On page load action.
SchedulerBinding.instance.addPostFrameCallback((_) async {
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!.controller.fling();
}
});
animationsMap.addAll({
'barcodeOnActionTriggerAnimation': AnimationInfo(
trigger: AnimationTrigger.onActionTrigger,
applyInitialState: true,
effectsBuilder: () => [
VisibilityEffect(duration: 1.ms),
BlurEffect(
curve: Curves.linear,
delay: 0.0.ms,
duration: 600.0.ms,
begin: const Offset(0.0, 0.0),
end: const Offset(10.0, 10.0),
),
],
),
});
setupAnimations(
animationsMap.values.where((anim) =>
anim.trigger == AnimationTrigger.onActionTrigger ||
!anim.applyInitialState),
this,
);
animationsMap.addAll({
'barcodeOnActionTriggerAnimation': AnimationInfo(
trigger: AnimationTrigger.onActionTrigger,
applyInitialState: true,
effectsBuilder: () => [
VisibilityEffect(duration: 1.ms),
BlurEffect(
curve: Curves.linear,
delay: 0.0.ms,
duration: 600.0.ms,
begin: const Offset(0.0, 0.0),
end: const Offset(10.0, 10.0),
),
],
),
});
setupAnimations(
animationsMap.values.where((anim) =>
anim.trigger == AnimationTrigger.onActionTrigger ||
!anim.applyInitialState),
this,
);
// // Adicionando um ouvinte de status à animação para reiniciá-la após a conclusão
// animationsMap['barcodeOnActionTriggerAnimation']?.controller.addStatusListener((status) {
// if (status == AnimationStatus.completed) {
// animationsMap['barcodeOnActionTriggerAnimation']!.controller.reset();
// animationsMap['barcodeOnActionTriggerAnimation']!.controller.forward();
// }
// });
}
@override
void dispose() {
// Removendo o ouvinte antes de chamar super.dispose para evitar vazamentos de memória
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!.controller.removeStatusListener((status) {});
// // Adicionando um ouvinte de status à animação para reiniciá-la após a conclusão
// animationsMap['barcodeOnActionTriggerAnimation']?.controller.addStatusListener((status) {
// if (status == AnimationStatus.completed) {
// animationsMap['barcodeOnActionTriggerAnimation']!.controller.reset();
// animationsMap['barcodeOnActionTriggerAnimation']!.controller.forward();
// }
// });
}
super.dispose();
}
@override
void dispose() {
// Removendo o ouvinte antes de chamar super.dispose para evitar vazamentos de memória
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!
.controller
.removeStatusListener((status) {});
}
super.dispose();
}
@override
Widget build(BuildContext context) {
@ -114,46 +108,46 @@ void dispose() {
}
Widget buildBody(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
double smallerDimension = screenWidth < screenHeight ? screenWidth : screenHeight;
double dimension = smallerDimension * 0.75;
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
double smallerDimension =
screenWidth < screenHeight ? screenWidth : screenHeight;
double dimension = smallerDimension * 0.75;
double totalTimeInSeconds = 100.0;
return SafeArea(
// top: true,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (_model.isAccess == true && _model.key != null)
// top: true,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (_model.isAccess == true && _model.key != null)
Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Use esse QR Code para acesso',
enText: 'Use this QR Code for access',
),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily:
FlutterFlowTheme.of(context).bodyMediumFamily,
fontSize: 20.0,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).bodyMediumFamily),
),
FFLocalizations.of(context).getVariableText(
ptText: 'Use esse QR Code para acesso',
enText: 'Use this QR Code for access',
),
Stack(
children: [
if (_model.isAccess == true && _model.key != null)
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
fontSize: 20.0,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).bodyMediumFamily),
),
),
Stack(
children: [
if (_model.isAccess == true && _model.key != null)
Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: InkWell(
onTap: () {
safeSetState(() async {
_resetAnimationAndToggleAccess();
FFAppState().fingerprint ? await _showBiometricsAuth(context) : await _showQrCodeBottomSheet(context);
});
onTap: () async {
safeSetState(() async {
_resetAnimationAndToggleAccess();
});
FFAppState().fingerprint
? await _showBiometricsAuth(context)
: await _showQrCodeBottomSheet(context);
},
child: buildQrCode(
dimension: dimension,
@ -164,260 +158,266 @@ void dispose() {
),
),
),
if(_model.isAccess == false && _model.key == null)
if (_model.isAccess == false && _model.key == null)
Align(
alignment: const AlignmentDirectional(0, 0),
child: BarcodeWidget(
data: 'Barcode',
barcode: Barcode.qrCode(),
data: 'Barcode',
barcode: Barcode.qrCode(),
width: 300.0,
height: 200.0,
color: FlutterFlowTheme.of(context).primaryText,
backgroundColor: Colors.transparent,
errorBuilder: (context, error) => const SizedBox(
width: 300.0,
height: 200.0,
color: FlutterFlowTheme.of(context).primaryText,
backgroundColor: Colors.transparent,
errorBuilder: (context, error) => const SizedBox(
width: 300.0,
height: 200.0,
),
drawText: false,
).animateOnActionTrigger(
animationsMap['barcodeOnActionTriggerAnimation']!,
),
drawText: false,
).animateOnActionTrigger(
animationsMap['barcodeOnActionTriggerAnimation']!,
),
),
if (_model.isAccess == false && _model.key == null)
if (_model.isAccess == false && _model.key == null)
Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
onLongPress: () async {
await _model.qrCodeEncoder(
context,
key: _model.key,
);
setState(() {});
},
child: Container(
width: 200.0,
height: 200.0,
decoration: const BoxDecoration(),
child: Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: FFButtonWidget(
onPressed: () async {
FFAppState().fingerprint ? await _showBiometricsAuth(context) : await _showQrCodeBottomSheet(context);
},
text: FFLocalizations.of(context).getVariableText(
ptText: 'Gerar QR Code',
enText: 'Generate QR Code',
),
options: FFButtonOptions(
height: 40.0,
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
iconPadding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 0.0, 0.0),
color: FlutterFlowTheme.of(context).primary,
textStyle: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: FlutterFlowTheme.of(context)
.titleSmallFamily,
color: Colors.white,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(
FlutterFlowTheme.of(context)
.titleSmallFamily),
),
elevation: 3.0,
borderSide: const BorderSide(
color: Colors.transparent,
width: 1.0,
),
borderRadius: BorderRadius.circular(8.0),
),
alignment: const AlignmentDirectional(0.0, 0.0),
child: InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
onLongPress: () async {
await _model.qrCodeEncoder(
context,
key: _model.key,
);
setState(() {});
},
child: Container(
width: 200.0,
height: 200.0,
decoration: const BoxDecoration(),
child: Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: FFButtonWidget(
onPressed: () async {
FFAppState().fingerprint
? await _showBiometricsAuth(context)
: await _showQrCodeBottomSheet(context);
},
text: FFLocalizations.of(context).getVariableText(
ptText: 'Gerar QR Code',
enText: 'Generate QR Code',
),
),
),
),
),
],
),
if (_model.isAccess == true && _model.key != null)
Container(
width: 300.0,
decoration: const BoxDecoration(),
child: Visibility(
visible: _model.isAccess == true,
child: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Certifique-se de que o QRCode está visivel para o leitor',
enText: 'Make sure the QRCode is visible to the reader',
// '6z6kvmhl' /* Certifique-se de que o QRCode ... */,
),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily:
FlutterFlowTheme.of(context).bodyMediumFamily,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).bodyMediumFamily),
),
),
),
),
if (_model.isAccess == true && _model.key != null)
Container(
width: 250.0,
height: 80.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100.0),
border: Border.all(
color: FlutterFlowTheme.of(context).primary,
),
),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
10.0, 0.0, 0.0, 0.0),
child: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Expirando QR code em',
enText: 'Expiring QR code in',
// 'wkjkxd2e' /* Trocando QR code em */,
),
textAlign: TextAlign.center,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: FlutterFlowTheme.of(context)
.bodyMediumFamily,
letterSpacing: 0.0,
fontWeight: FontWeight.w600,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(FlutterFlowTheme.of(context)
.bodyMediumFamily),
),
),
),
),
Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 20.0, 0.0),
child: StreamBuilder<double>(
stream: getProgressValue(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else if (!snapshot.hasData) {
return Text('No data');
} else {
final progress = snapshot.data!;
return CircularPercentIndicator(
percent: progress,
restartAnimation: true,
reverse: false,
radius: 30.0,
lineWidth: 7.0,
animation: true,
animateFromLastPercent: true,
onAnimationEnd: () {
_resetAnimationAndToggleAccess();
},
progressColor: FlutterFlowTheme.of(context).primary,
backgroundColor: FlutterFlowTheme.of(context).primaryText,
center: Text(
'${(progress * totalTimeInSeconds / 5).toStringAsFixed(1)}s',
style: FlutterFlowTheme.of(context).headlineSmall.override(
fontFamily: FlutterFlowTheme.of(context).headlineSmallFamily,
fontSize: 14.0,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).headlineSmallFamily),
),
),
startAngle: 20.0,
);
}
},
options: FFButtonOptions(
height: 40.0,
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
iconPadding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 0.0, 0.0),
color: FlutterFlowTheme.of(context).primary,
textStyle: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: FlutterFlowTheme.of(context)
.titleSmallFamily,
color: Colors.white,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(FlutterFlowTheme.of(context)
.titleSmallFamily),
),
elevation: 3.0,
borderSide: const BorderSide(
color: Colors.transparent,
width: 1.0,
),
borderRadius: BorderRadius.circular(8.0),
),
),
),
),
],
),
),
],
),
if (_model.isAccess == true && _model.key != null)
Container(
width: 300.0,
decoration: const BoxDecoration(),
child: Visibility(
visible: _model.isAccess == true,
child: Text(
FFLocalizations.of(context).getVariableText(
ptText:
'Certifique-se de que o QRCode está visivel para o leitor',
enText: 'Make sure the QRCode is visible to the reader',
// '6z6kvmhl' /* Certifique-se de que o QRCode ... */,
),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily:
FlutterFlowTheme.of(context).bodyMediumFamily,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).bodyMediumFamily),
),
),
),
],
),
);
),
if (_model.isAccess == true && _model.key != null)
Container(
width: 250.0,
height: 80.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100.0),
border: Border.all(
color: FlutterFlowTheme.of(context).primary,
),
),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
10.0, 0.0, 0.0, 0.0),
child: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Expirando QR code em',
enText: 'Expiring QR code in',
// 'wkjkxd2e' /* Trocando QR code em */,
),
textAlign: TextAlign.center,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily:
FlutterFlowTheme.of(context).bodyMediumFamily,
letterSpacing: 0.0,
fontWeight: FontWeight.w600,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context)
.bodyMediumFamily),
),
),
),
),
Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 20.0, 0.0),
child: StreamBuilder<double>(
stream: getProgressValue(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else if (!snapshot.hasData) {
return Text('No data');
} else {
final progress = snapshot.data!;
return CircularPercentIndicator(
percent: progress,
restartAnimation: true,
reverse: false,
radius: 30.0,
lineWidth: 7.0,
animation: true,
animateFromLastPercent: true,
onAnimationEnd: () {
_resetAnimationAndToggleAccess();
},
progressColor:
FlutterFlowTheme.of(context).primary,
backgroundColor:
FlutterFlowTheme.of(context).primaryText,
center: Text(
'${(progress * totalTimeInSeconds / 5).toStringAsFixed(1)}s',
style: FlutterFlowTheme.of(context)
.headlineSmall
.override(
fontFamily: FlutterFlowTheme.of(context)
.headlineSmallFamily,
fontSize: 14.0,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(
FlutterFlowTheme.of(context)
.headlineSmallFamily),
),
),
startAngle: 20.0,
);
}
},
),
),
),
],
),
),
],
),
);
}
Future<void> _showBiometricsAuth(BuildContext context) async {
FFAppState().checkBiometrics()
.then((value) => FFAppState().authenticateBiometric()
.then( (value) {
safeSetState(() {
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!.controller.stop();
animationsMap['barcodeOnActionTriggerAnimation']!.controller.reverse();
}
_model.isAccess = !_model.isAccess;
_model.key = FFAppState().fingerprintPass;
});
} ))
.onError((error, StackTrace) {
_showQrCodeBottomSheet(context);
});
FFAppState()
.checkBiometrics()
.then((value) => FFAppState().authenticateBiometric().then((value) {
safeSetState(() {
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!
.controller
.stop();
animationsMap['barcodeOnActionTriggerAnimation']!
.controller
.reverse();
}
_model.isAccess = !_model.isAccess;
_model.key = FFAppState().fingerprintPass;
});
}))
.onError((error, StackTrace) {
_showQrCodeBottomSheet(context);
});
}
Future<void> _showQrCodeBottomSheet(BuildContext context) async {
await showModalBottomSheet(
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
useSafeArea: true,
context: context,
builder: (context) {
return GestureDetector(
onTap: () => _model
.unfocusNode.canRequestFocus
? FocusScope.of(context)
.requestFocus(_model.unfocusNode)
onTap: () => _model.unfocusNode.canRequestFocus
? FocusScope.of(context).requestFocus(_model.unfocusNode)
: FocusScope.of(context).unfocus(),
child: Padding(
padding:
MediaQuery.viewInsetsOf(context),
child:
QrCodePassKeyTemplateComponentWidget(
padding: MediaQuery.viewInsetsOf(context),
child: QrCodePassKeyTemplateComponentWidget(
toggleActionStatus: (key) async {
log('Key: $key');
safeSetState(() {
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!.controller.stop();
animationsMap['barcodeOnActionTriggerAnimation']!.controller.reverse();
if (animationsMap['barcodeOnActionTriggerAnimation'] !=
null) {
animationsMap['barcodeOnActionTriggerAnimation']!
.controller
.stop();
animationsMap['barcodeOnActionTriggerAnimation']!
.controller
.reverse();
}
_model.isAccess = !_model.isAccess;
_model.key = key;
});
_model.isAccess = !_model.isAccess;
_model.key = key;
});
},
),
),
);
},
)
.catchError((error) => safeSetState((){
log('Error: $error');
_resetAnimationAndToggleAccess();
).catchError((error) => safeSetState(() {
_resetAnimationAndToggleAccess();
}));
unawaited(
() async {
@ -431,50 +431,50 @@ void dispose() {
}
void _resetAnimationAndToggleAccess() {
safeSetState(() {
// Reinicia a animação
animationsMap['barcodeOnActionTriggerAnimation']!.controller.reset();
animationsMap['barcodeOnActionTriggerAnimation']!.controller.forward();
// Alterna o estado de acesso
_model.isAccess = !_model.isAccess;
_model.key = null;
});
}
safeSetState(() {
// Reinicia a animação
animationsMap['barcodeOnActionTriggerAnimation']!.controller.reset();
animationsMap['barcodeOnActionTriggerAnimation']!.controller.forward();
// Alterna o estado de acesso
_model.isAccess = !_model.isAccess;
_model.key = null;
});
}
AppBar buildAppBar(BuildContext context) {
return AppBar(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
automaticallyImplyLeading: false,
leading: FlutterFlowIconButton(
borderColor: Colors.transparent,
borderRadius: 30.0,
borderWidth: 1.0,
buttonSize: 60.0,
icon: Icon(
Icons.keyboard_arrow_left,
color: FlutterFlowTheme.of(context).primaryText,
size: 30.0,
),
onPressed: () async {
context.pop();
},
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
automaticallyImplyLeading: false,
leading: FlutterFlowIconButton(
borderColor: Colors.transparent,
borderRadius: 30.0,
borderWidth: 1.0,
buttonSize: 60.0,
icon: Icon(
Icons.keyboard_arrow_left,
color: FlutterFlowTheme.of(context).primaryText,
size: 30.0,
),
title: Text(
FFLocalizations.of(context).getText(
'ku7jqe53' /* QR Code de Acesso */,
),
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 16.0,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).headlineMediumFamily),
),
onPressed: () async {
context.pop();
},
),
title: Text(
FFLocalizations.of(context).getText(
'ku7jqe53' /* QR Code de Acesso */,
),
actions: const [],
centerTitle: true,
elevation: 0.0,
);
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 16.0,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).headlineMediumFamily),
),
),
actions: const [],
centerTitle: true,
elevation: 0.0,
);
}
}

View File

@ -2,6 +2,7 @@ import 'package:hub/backend/api_requests/api_calls.dart';
import 'package:hub/backend/api_requests/api_manager.dart';
import 'package:hub/flutter_flow/flutter_flow_model.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/form_field_controller.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/flutter_flow/request_manager.dart';
@ -29,6 +30,31 @@ class ScheduleCompleteVisitPageModel
/// Local state fields for this page.
String convertDateFormat(String dateStr) {
try {
// Formato original
DateFormat originalFormat = DateFormat('d/M/y H:mm:ss');
// Novo formato
DateFormat newFormat = DateFormat('y-M-d H:mm:ss');
// Validate the input string format
if (!RegExp(r'^\d{1,2}/\d{1,2}/\d{4} \d{1,2}:\d{2}:\d{2}$')
.hasMatch(dateStr)) {
return 'Invalid date format';
}
// Converte a string para DateTime
DateTime dateTime = originalFormat.parse(dateStr);
// Converte DateTime para a nova string formatada
String formattedDate = newFormat.format(dateTime);
return formattedDate;
} catch (e) {
// Handle the exception by returning an error message or a default value
return 'Invalid date format';
}
}
List<dynamic> visitorJsonList = [];
void addToVisitorJsonList(dynamic item) => visitorJsonList.add(item);
void removeFromVisitorJsonList(dynamic item) => visitorJsonList.remove(item);
@ -164,11 +190,21 @@ class ScheduleCompleteVisitPageModel
);
textFieldFocusNode1 = FocusNode();
textController1 = TextEditingController();
textController1 = TextEditingController(
text: dateTimeFormat(
'd/M/y H:mm:ss',
DateTime.now().add(const Duration(minutes: 10)),
// locale: FFLocalizations.of(context).languageCode,
));
textController1Validator = _textController1Validator;
textFieldFocusNode2 = FocusNode();
textController2 = TextEditingController();
textController2 = TextEditingController(
text: dateTimeFormat(
'd/M/y H:mm:ss',
DateTime.now().add(const Duration(days: 1)),
// locale: FFLocalizations.of(context).languageCode,
));
textController2Validator = _textController2Validator;
textFieldFocusNode3 = FocusNode();

View File

@ -53,7 +53,6 @@
// imageHashMap: imageKeyValue,
// onTapCardItemAction: () async {
// // Ação ao tocar no card
// log('Card tapped');
// },
// );
// }),

View File

@ -1,108 +1 @@
import 'package:flutter/material.dart';
import 'package:hub/backend/api_requests/api_manager.dart';
import 'package:hub/flutter_flow/flutter_flow_model.dart';
import 'package:hub/flutter_flow/form_field_controller.dart';
import 'package:hub/flutter_flow/request_manager.dart';
import 'package:hub/pages/visit_history_page/visit_history_page_widget.dart';
class VisitHistoryPageModel extends FlutterFlowModel<VisitHistoryPageWidget> {
final _visitHistoryManager = FutureRequestManager<ApiCallResponse>();
Future<ApiCallResponse> visitHistory({
String? uniqueQueryKey,
bool? overrideCache,
required Future<ApiCallResponse> Function() requestFn,
}) =>
_visitHistoryManager.performRequest(
uniqueQueryKey: uniqueQueryKey,
overrideCache: overrideCache,
requestFn: requestFn,
);
void clearVisitHistoryCache() => _visitHistoryManager.clear();
void clearVisitHistoryCacheKey(String? uniqueKey) =>
_visitHistoryManager.clearRequest(uniqueKey);
/// Local state fields for this page.
List<dynamic> visitorJsonList = [];
void addToVisitorJsonList(dynamic item) => visitorJsonList.add(item);
void removeFromVisitorJsonList(dynamic item) => visitorJsonList.remove(item);
void removeAtIndexFromVisitorJsonList(int index) =>
visitorJsonList.removeAt(index);
void insertAtIndexInVisitorJsonList(int index, dynamic item) =>
visitorJsonList.insert(index, item);
void updateVisitorJsonListAtIndex(int index, Function(dynamic) updateFn) =>
visitorJsonList[index] = updateFn(visitorJsonList[index]);
String visitorStrList = '0';
/// State fields for stateful widgets in this page.
final unfocusNode = FocusNode();
// State field(s) for TabBar widget.
TabController? tabBarController;
int get tabBarCurrentIndex =>
tabBarController != null ? tabBarController!.index : 0;
// State field(s) for TextField widget.
FocusNode? textFieldFocusNode1;
TextEditingController? textController1;
String? Function(BuildContext, String?)? textController1Validator;
DateTime? datePicked1;
// State field(s) for TextField widget.
FocusNode? textFieldFocusNode2;
TextEditingController? textController2;
String? Function(BuildContext, String?)? textController2Validator;
DateTime? datePicked2;
// State field(s) for DropDown widget.
String? dropDownValue1;
FormFieldController<String>? dropDownValueController1;
// State field(s) for DropDown widget.
String? dropDownValue2;
FormFieldController<String>? dropDownValueController2;
// State field(s) for Switch widget.
bool? switchValue;
// State field(s) for TextField widget.
FocusNode? textFieldFocusNode3;
TextEditingController? textController3;
String? Function(BuildContext, String?)? textController3Validator;
@override
void initState(BuildContext context) {}
@override
void dispose() {
unfocusNode.dispose();
tabBarController?.dispose();
textFieldFocusNode1?.dispose();
textController1?.dispose();
textFieldFocusNode2?.dispose();
textController2?.dispose();
textFieldFocusNode3?.dispose();
textController3?.dispose();
clearVisitHistoryCache();
}
/// Action blocks.
Future getVisitorsActionPage(
BuildContext context, {
List<dynamic>? visitorsJsonList,
}) async {
visitorJsonList = visitorsJsonList!.toList().cast<dynamic>();
}
Future<bool> toggleCurrentSelectionHeader(
BuildContext context, {
required bool? toggleIndexValue,
}) async {
if (toggleIndexValue == true) {
return true;
}
return false;
}
}

View File

@ -1,757 +1,199 @@
import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hub/actions/actions.dart';
import 'package:hub/app_state.dart';
import 'package:hub/backend/api_requests/api_calls.dart';
import 'package:hub/components/templates_components/visit_details_modal_template_component/visit_details_modal_template_component_widget.dart';
import 'package:hub/flutter_flow/custom_functions.dart';
import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
import 'package:hub/backend/api_requests/api_manager.dart';
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart';
import 'package:hub/components/templates_components/details_component/details_component_action.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/internationalization.dart';
import 'package:hub/pages/schedule_complete_visit_page/schedule_complete_visit_page_model.dart';
import 'package:hub/pages/visit_history_page/visit_history_page_model.dart';
import 'package:provider/provider.dart';
class VisitHistoryPageWidget extends StatefulWidget {
const VisitHistoryPageWidget({
super.key,
this.visitorStrList,
this.visitStartDateStr,
this.visitEndDateStr,
this.visitReasonStr,
this.visitLevelStr,
this.visitTempBol,
this.visitObsStr,
this.visitorJsonList,
});
final String? visitorStrList;
final String? visitStartDateStr;
final String? visitEndDateStr;
final String? visitReasonStr;
final String? visitLevelStr;
final bool? visitTempBol;
final String? visitObsStr;
final List<dynamic>? visitorJsonList;
class VisitHistoryWidget extends StatefulWidget {
VisitHistoryWidget({
Key? key,
}) : super(key: key);
@override
State<VisitHistoryPageWidget> createState() => _VisitHistoryPageWidgetState();
_VisitHistoryWidgetState createState() => _VisitHistoryWidgetState();
}
class _VisitHistoryPageWidgetState extends State<VisitHistoryPageWidget>
with TickerProviderStateMixin {
late VisitHistoryPageModel _model;
int _visitHistoryLoadingIdx = 0;
final int _visitHistoryLoadingCount = 10;
List<dynamic> _visitHistoryList = [];
ScrollController _visitHistoryController = ScrollController();
final scaffoldKey = GlobalKey<ScaffoldState>();
class _VisitHistoryWidgetState extends State<VisitHistoryWidget> {
List<dynamic> visitaWrap = [];
var pageNumber = 1;
late Future<void> visitFuture;
@override
void initState() {
super.initState();
_model = createModel(context, () => VisitHistoryPageModel());
visitFuture = _fetchVisits();
}
// On page load action.
SchedulerBinding.instance.addPostFrameCallback((_) async {
if ((widget.visitorStrList != null && widget.visitorStrList != '') &&
((widget.visitorJsonList != null &&
(widget.visitorJsonList)!.isNotEmpty) !=
null)) {
_model.visitorJsonList = widget.visitorJsonList!
.where((e) =>
widget.visitorStrList ==
getJsonField(
e,
r'''$.VTE_DOCUMENTO''',
).toString().toString())
.toList()
.toList()
.cast<dynamic>();
_model.visitorStrList = widget.visitorStrList!;
setState(() {});
Future<ApiCallResponse?> _fetchVisits() async {
try {
var response = await ScheduleCompleteVisitPageModel().visitHistory(
requestFn: () => PhpGroup.getVisitsCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'getVisitas',
pageSize: 10,
pageNumber: pageNumber,
),
);
var newVisits = response.jsonBody['visitas']
as List<dynamic>?; // Ajuste conforme a estrutura da resposta
if (newVisits != null && newVisits.isNotEmpty) {
safeSetState(() {
visitaWrap.addAll(newVisits);
});
return response;
} else {
return;
log('No new visits found');
return null;
}
});
_model.tabBarController = TabController(
vsync: this,
length: 2,
initialIndex: 0,
)..addListener(() => setState(() {}));
_model.textController1 ??= TextEditingController();
_model.textFieldFocusNode1 ??= FocusNode();
_model.textController2 ??= TextEditingController();
_model.textFieldFocusNode2 ??= FocusNode();
_model.switchValue = true;
_model.textController3 ??= TextEditingController();
_model.textFieldFocusNode3 ??= FocusNode();
}
void _loadMoreVisitHistory() async {
// Simulate fetching data from an API or database
Future<List<String>> fetchVisitHistory(int start, int limit) async {
// Simulate network delay
await Future.delayed(Duration(seconds: 1));
// Generate a list of visit history items
return List.generate(limit, (index) => "Item ${start + index}");
}
// Calculate the start index for the next batch of items to load
final int start = _visitHistoryLoadingIdx * _visitHistoryLoadingCount;
// Fetch the next batch of items
final List<String> newItems =
await fetchVisitHistory(start, _visitHistoryLoadingCount);
// If new items were fetched, add them to the list and update the index
if (newItems.isNotEmpty) {
_visitHistoryList.addAll(newItems);
_visitHistoryLoadingIdx++;
setState(() {});
} catch (err) {
log('Erro ao carregar mais visitas: $err');
}
}
void_scrollListener() {
if (_visitHistoryController.position.pixels ==
_visitHistoryController.position.maxScrollExtent) {
_loadMoreVisitHistory();
}
}
@override
void dispose() {
_model.dispose();
super.dispose();
void _loadMoreVisits() {
pageNumber++;
visitFuture = _fetchVisits();
}
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
return FutureBuilder<void>(
future: visitFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting &&
visitaWrap.isEmpty) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
FlutterFlowTheme.of(context).primary,
),
),
);
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (visitaWrap.isEmpty) {
return Center(
child: Text(
FFLocalizations.of(context).getVariableText(
ptText: 'Nenhum visitante foi encontrado',
enText: 'No visitors found',
),
),
);
}
return GestureDetector(
onTap: () => _model.unfocusNode.canRequestFocus
? FocusScope.of(context).requestFocus(_model.unfocusNode)
: FocusScope.of(context).unfocus(),
child: Scaffold(
key: scaffoldKey,
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
appBar: appBarScheduleCompleteVisit(context),
body:
bodyScheduleCompleteVisit(context, _model, setState, safeSetState),
),
return ListView.builder(
itemCount: visitaWrap.length + 1,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
if (index == visitaWrap.length) {
_loadMoreVisits();
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
FlutterFlowTheme.of(context).primary,
),
),
);
}
final visitaWrapItem = visitaWrap[index];
return CardItemTemplateComponentWidget(
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${visitaWrapItem['VTE_DOCUMENTO'] ?? ''}&tipo=E',
labelsHashMap: {
'Nome:': visitaWrapItem['VTE_NOME'] ?? '',
'Inicio:': visitaWrapItem['VAW_DTINICIO'] ?? '',
'Fim:': visitaWrapItem['VAW_DTFIM'] ?? '',
},
statusHashMap: [
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.active)
{
FFLocalizations.of(context).getVariableText(
ptText: 'Ativo',
enText: 'Active',
): FlutterFlowTheme.of(context).warning,
},
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.finished)
{
FFLocalizations.of(context).getVariableText(
ptText: 'Finalizado',
enText: 'Finished',
): FlutterFlowTheme.of(context).success,
},
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.unknown)
{
FFLocalizations.of(context).getVariableText(
ptText: 'Desconhecido',
enText: 'Unknown',
): FlutterFlowTheme.of(context).alternate,
},
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.canceled)
{
FFLocalizations.of(context).getVariableText(
ptText: 'Cancelado',
enText: 'Canceled',
): FlutterFlowTheme.of(context).error,
},
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.blocked)
{
FFLocalizations.of(context).getVariableText(
ptText: 'Bloqueado',
enText: 'Blocked',
): FlutterFlowTheme.of(context).error,
},
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.inactive)
{
FFLocalizations.of(context).getVariableText(
ptText: 'Inativo',
enText: 'Inactive',
): FlutterFlowTheme.of(context).error,
},
],
onTapCardItemAction: () async {
await showDialog(
useSafeArea: true,
context: context,
builder: (context) {
return Dialog(
alignment: Alignment.center,
child: buildDetails(
visitaWrapItem,
context,
changeStatusAction,
),
);
},
).whenComplete(() {
// updateVisitFuture();
_fetchVisits().then((response) {
safeSetState(() {
visitaWrap = PhpGroup.getVisitsCall
.visitasList(response!.jsonBody)
?.toList() ??
[];
visitFuture = Future.value(response);
});
});
}).catchError((err, stack) {});
},
);
},
);
},
);
}
}
PreferredSizeWidget appBarScheduleCompleteVisit(BuildContext context) {
return AppBar(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
automaticallyImplyLeading: false,
leading: FlutterFlowIconButton(
borderColor: Colors.transparent,
borderRadius: 30.0,
borderWidth: 1.0,
buttonSize: 60.0,
icon: Icon(
Icons.keyboard_arrow_left,
color: FlutterFlowTheme.of(context).primaryText,
size: 30.0,
),
onPressed: () async {
context.pop();
},
),
title: Text(
FFLocalizations.of(context).getText(
'61lcxdgm' /* Agendar Visita */,
),
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: 'Nunito',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 15.0,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'),
),
),
actions: const [],
centerTitle: true,
);
}
Widget bodyScheduleCompleteVisit(BuildContext context,
VisitHistoryPageModel _model, Function setState, Function safeSetState) {
return SafeArea(
top: true,
child: visitHistory(context, _model, safeSetState),
);
}
Widget visitHistory(
BuildContext context,
VisitHistoryPageModel _model,
Function safeSetState,
) {
return Container(
width: double.infinity,
height: 900.0,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FlutterFlowIconButton(
borderColor: Colors.transparent,
borderRadius: 20.0,
borderWidth: 1.0,
buttonSize: 40.0,
icon: Icon(
Icons.settings_sharp,
color: FlutterFlowTheme.of(context).primary,
size: 24.0,
),
onPressed: () {
log('IconButton pressed ...');
},
),
],
),
FutureBuilder<ApiCallResponse>(
future: _model.visitHistory(
requestFn: () => PhpGroup.getVisitsCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'getVisitas',
),
),
builder: (context, snapshot) {
// Customize what your widget looks like when it's loading.
if (!snapshot.hasData) {
return Center(
child: SizedBox(
width: 50.0,
height: 50.0,
child: SpinKitCircle(
color: FlutterFlowTheme.of(context).primary,
size: 50.0,
),
),
);
}
final wrapGetVisitsResponse = snapshot.data!;
return Builder(
builder: (context) {
final visitaWrap = PhpGroup.getVisitsCall
.visitasList(
wrapGetVisitsResponse.jsonBody,
)
?.toList() ??
[];
return ListView.builder(
itemCount: visitaWrap.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(),
addAutomaticKeepAlives: true,
cacheExtent: 1000.0,
addRepaintBoundaries: true,
addSemanticIndexes: true,
itemBuilder: (context, index) {
final visitaWrapItem = visitaWrap[index];
// visitaWrap.length, (visitaWrapIndex) {
return InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () async {
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
enableDrag: false,
useSafeArea: true,
context: context,
builder: (context) {
return GestureDetector(
onTap: () =>
_model.unfocusNode.canRequestFocus
? FocusScope.of(context)
.requestFocus(_model.unfocusNode)
: FocusScope.of(context).unfocus(),
child: Padding(
padding: MediaQuery.viewInsetsOf(context),
child:
VisitDetailsModalTemplateComponentWidget(
visitStatusStr: getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
).toString(),
visitStartDateStr: getJsonField(
visitaWrapItem,
r'''$.VAW_DTINICIO''',
).toString(),
visitEndDateStr: getJsonField(
visitaWrapItem,
r'''$.VAW_DTFIM''',
).toString(),
visitReasonStr: getJsonField(
visitaWrapItem,
r'''$.MOT_DESCRICAO''',
).toString(),
visitLevelStr: getJsonField(
visitaWrapItem,
r'''$.NAC_DESCRICAO''',
).toString(),
visitTempStr: getJsonField(
visitaWrapItem,
r'''$.VTE_UNICA''',
).toString(),
visitObsStr: getJsonField(
visitaWrapItem,
r'''$.VAW_OBS''',
).toString(),
visitorImgPath: valueOrDefault<String>(
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
visitaWrapItem,
r'''$.VTE_DOCUMENTO''',
).toString()}&tipo=E",
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
),
visitorStrList: getJsonField(
visitaWrapItem,
r'''$.VTE_DOCUMENTO''',
).toString(),
visitIdStr: getJsonField(
visitaWrapItem,
r'''$.VAW_ID''',
).toString(),
visitStatusColor: getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
).toString() ==
'A'
? FlutterFlowTheme.of(context).success
: FlutterFlowTheme.of(context).error,
visitorJsonList:
PhpGroup.getVisitsCall.visitasList(
wrapGetVisitsResponse.jsonBody,
),
updateToggleIdx: () async {},
repeatVisitSchedule: () async {},
),
),
);
},
).then((value) => safeSetState(() {}));
},
child: Card(
clipBehavior: Clip.antiAliasWithSaveLayer,
color: FlutterFlowTheme.of(context)
.secondaryBackground,
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Container(
width: 350.0,
height: 115.0,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
width: 100.0,
height: 100.0,
decoration: const BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
FFLocalizations.of(context)
.getText(
'i46frqyi' /* Visitante: */,
),
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(
context)
.bodyMediumFamily,
fontSize: 12.5,
letterSpacing: 0.0,
fontWeight:
FontWeight.bold,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
),
Align(
alignment:
const AlignmentDirectional(
-1.0, -1.0),
child: Text(
getJsonField(
visitaWrapItem,
r'''$.VTE_NOME''',
).toString(),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(
context)
.bodyMediumFamily,
fontSize: 12.5,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
),
),
].addToStart(
const SizedBox(width: 10.0)),
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
FFLocalizations.of(context)
.getText(
'73b1kj59' /* Início em: */,
),
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(
context)
.bodyMediumFamily,
fontSize: 12.5,
letterSpacing: 0.0,
fontWeight:
FontWeight.bold,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
),
Text(
getJsonField(
visitaWrapItem,
r'''$.VAW_DTINICIO''',
).toString(),
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(
context)
.bodyMediumFamily,
fontSize: 12.5,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
),
].addToStart(
const SizedBox(width: 10.0)),
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
FFLocalizations.of(context)
.getText(
'klzzrfbn' /* Fim em: */,
),
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(
context)
.bodyMediumFamily,
fontSize: 12.5,
letterSpacing: 0.0,
fontWeight:
FontWeight.bold,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
),
Text(
getJsonField(
visitaWrapItem,
r'''$.VAW_DTFIM''',
).toString(),
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(
context)
.bodyMediumFamily,
fontSize: 12.5,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
),
].addToStart(
const SizedBox(width: 10.0)),
),
Align(
alignment:
const AlignmentDirectional(
-1.0, 0.0),
child: Padding(
padding:
const EdgeInsetsDirectional
.fromSTEB(
10.0, 0.0, 0.0, 0.0),
child: Container(
width: 200.0,
height: 27.0,
decoration: BoxDecoration(
color: valueOrDefault<Color>(
() {
if (jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"A\"') {
return FlutterFlowTheme
.of(context)
.success;
} else if ((
jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"C\"') ||
(jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"F\"') ||
(jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"B\"') ||
(jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"I\"')) {
return FlutterFlowTheme
.of(context)
.error;
} else if (
jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"I\"') {
return FlutterFlowTheme
.of(context)
.warning;
} else {
return FlutterFlowTheme
.of(context)
.primary;
}
}(),
FlutterFlowTheme.of(context)
.primary,
),
borderRadius:
BorderRadius.circular(
5.0),
),
child: Align(
alignment:
const AlignmentDirectional(
0.0, 0.0),
child: Text(
() {
if (jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"A\"') {
return FFLocalizations
.of(context)
.getVariableText(
ptText: 'Ativo',
enText: 'Active',
);
} else if ((
jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"F\"') ||
(jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"C\"') ||
(jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"B\"') ||
(jsonToStr(
getJsonField(
visitaWrapItem,
r'''$.VAW_STATUS''',
)) ==
'\"I\"')) {
return FFLocalizations
.of(context)
.getVariableText(
ptText: 'Cancelado',
enText: 'Canceled',
);
} else {
return FFLocalizations
.of(context)
.getVariableText(
ptText: 'Pendente',
enText: 'Pending',
);
}
}(),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(
context)
.bodyMediumFamily,
color: FlutterFlowTheme
.of(context)
.info,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
),
),
),
),
),
].divide(const SizedBox(height: 3.0)),
),
),
),
ClipRRect(
borderRadius: BorderRadius.circular(0.0),
child: CachedNetworkImage(
fadeInDuration:
const Duration(milliseconds: 500),
fadeOutDuration:
const Duration(milliseconds: 500),
imageUrl: valueOrDefault<String>(
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
visitaWrapItem,
r'''$.VTE_DOCUMENTO''',
).toString()}&tipo=E',
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
),
fit: BoxFit.cover,
),
),
],
),
),
),
);
});
},
);
},
)
],
),
),
);
}

View File

@ -137,6 +137,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.18.0"
connectivity_plus:
dependency: "direct main"
description:
name: connectivity_plus
sha256: "2056db5241f96cdc0126bd94459fc4cdc13876753768fc7a31c425e50a7177d0"
url: "https://pub.dev"
source: hosted
version: "6.0.5"
connectivity_plus_platform_interface:
dependency: transitive
description:
name: connectivity_plus_platform_interface
sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
crop_your_image:
dependency: "direct main"
description:
@ -941,6 +957,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.0"
nm:
dependency: transitive
description:
name: nm
sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
octo_image:
dependency: transitive
description:

View File

@ -3,7 +3,7 @@ description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
publish_to: "none" # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
@ -48,6 +48,7 @@ dependencies:
flutter_cache_manager: 3.3.2
flutter_plugin_android_lifecycle: 2.0.20
share_plus: ^9.0.0
connectivity_plus: ^6.0.5
flutter_secure_storage: 9.2.2
flutter_secure_storage_linux: 1.2.1
flutter_secure_storage_macos: 3.1.2
@ -99,7 +100,6 @@ dependencies:
video_player_platform_interface: 6.2.2
video_player_web: 2.3.1
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.0
@ -123,24 +123,20 @@ dev_dependencies:
flutter_test:
sdk: flutter
flutter_launcher_icons:
android: 'launcher_icon'
android: "launcher_icon"
ios: true
web:
generate: true
image_path: 'assets/images/app_launcher_icon.svg'
adaptive_icon_background: 'assets/images/adaptive_background_icon.svg'
adaptive_icon_foreground: 'assets/images/adaptive_foreground_icon.svg'
image_path: "assets/images/app_launcher_icon.svg"
adaptive_icon_background: "assets/images/adaptive_background_icon.svg"
adaptive_icon_foreground: "assets/images/adaptive_foreground_icon.svg"
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
@ -158,7 +154,7 @@ flutter:
- assets/rive_animations/
- assets/pdfs/
fonts:
- family: 'SF Pro'
- family: "SF Pro"
fonts:
- asset: assets/fonts/SFPRODISPLAYREGULAR.OTF
- asset: assets/fonts/SFPRODISPLAYMEDIUM.OTF
@ -173,7 +169,6 @@ flutter:
fonts:
- asset: assets/fonts/menu.ttf
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.

View File

@ -0,0 +1,6 @@
#!/bin/bash
# Encontra e remove todos os arquivos com final :Zone.Identifier
find . -type f -name '*:Zone.Identifier' -exec rm -f {} +
echo "Todos os arquivos :Zone.Identifier foram removidos."