diff --git a/lib/backend/api_requests/api_manager.dart b/lib/backend/api_requests/api_manager.dart index 57c421d5..aaaef549 100644 --- a/lib/backend/api_requests/api_manager.dart +++ b/lib/backend/api_requests/api_manager.dart @@ -15,22 +15,9 @@ import 'package:mime_type/mime_type.dart'; import '/flutter_flow/uploaded_file.dart'; import 'get_streamed_response.dart'; -enum ApiCallType { - GET, - POST, - DELETE, - PUT, - PATCH, -} +enum ApiCallType { GET, POST, DELETE, PUT, PATCH } -enum BodyType { - NONE, - JSON, - TEXT, - X_WWW_FORM_URL_ENCODED, - MULTIPART, - BLOB, -} +enum BodyType { NONE, JSON, TEXT, X_WWW_FORM_URL_ENCODED, MULTIPART, BLOB } class ApiCallOptions extends Equatable { const ApiCallOptions({ diff --git a/lib/components/templates_components/details_component/details_component_action.dart b/lib/components/templates_components/details_component/details_component_action.dart index 48dbabee..d4c2d9a3 100644 --- a/lib/components/templates_components/details_component/details_component_action.dart +++ b/lib/components/templates_components/details_component/details_component_action.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:hub/backend/api_requests/api_calls.dart'; import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; -import 'package:hub/custom_code/actions/convert_to_upload_file.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'; diff --git a/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_widget.dart b/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_widget.dart index 3abfdf48..f1988f78 100644 --- a/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_widget.dart +++ b/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_widget.dart @@ -3,12 +3,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/image_util.dart'; import 'package:hub/shared/utils/validator_util.dart'; import 'package:provider/provider.dart'; import 'package:rxdart/rxdart.dart'; import '/backend/api_requests/api_calls.dart'; -import '/custom_code/actions/index.dart' as actions; import '/flutter_flow/flutter_flow_drop_down.dart'; import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_util.dart'; @@ -843,7 +843,7 @@ class _RegisiterVistorTemplateComponentWidgetState onPressed: _isFormValid(context) ? () async { _model.imgBase64 = - await actions.convertImageFileToBase64( + await ImageUtils.convertImageFileToBase64( _model.uploadedLocalFile, ); _model.scheduleVisitor = diff --git a/lib/components/templates_components/sign_in_template_component/sign_in_template_component_model.dart b/lib/components/templates_components/sign_in_template_component/sign_in_template_component_model.dart index 4869dc1f..e17c09d5 100644 --- a/lib/components/templates_components/sign_in_template_component/sign_in_template_component_model.dart +++ b/lib/components/templates_components/sign_in_template_component/sign_in_template_component_model.dart @@ -1,10 +1,10 @@ import 'package:hub/backend/api_requests/api_calls.dart'; import 'package:hub/backend/api_requests/api_manager.dart'; -import 'package:hub/custom_code/actions/get_dev_u_u_i_d.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/random_data_util.dart'; import 'package:hub/pages/home_page/home_page_model.dart'; import 'package:hub/shared/helpers/db_helper.dart'; +import 'package:hub/shared/utils/device_util.dart'; import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/log_util.dart'; @@ -108,7 +108,7 @@ class SignInTemplateComponentModel email = emailAdress!; passwd = password!; - devUUID = await getDevUUID(); + devUUID = await DeviceUtil.getDevUUID(); if ((email != '') && (passwd != '')) { AppState().email = email; diff --git a/lib/custom_code/actions/convert_image_file_to_base64.dart b/lib/custom_code/actions/convert_image_file_to_base64.dart deleted file mode 100644 index 33f4fd83..00000000 --- a/lib/custom_code/actions/convert_image_file_to_base64.dart +++ /dev/null @@ -1,17 +0,0 @@ - - -// Automatic FlutterFlow imports - -import 'index.dart'; // Imports other custom actions -import 'package:flutter/material.dart'; -import 'dart:convert'; -import 'dart:typed_data'; -import '../../flutter_flow/uploaded_file.dart'; - -Future convertImageFileToBase64(FFUploadedFile imageFile) async { - List? imageBytes = imageFile.bytes; - if (imageBytes != null) { - String base64Image = base64Encode(imageBytes); - return base64Image; - } -} \ No newline at end of file diff --git a/lib/custom_code/actions/convert_to_upload_file.dart b/lib/custom_code/actions/convert_to_upload_file.dart deleted file mode 100644 index 709be7ad..00000000 --- a/lib/custom_code/actions/convert_to_upload_file.dart +++ /dev/null @@ -1,31 +0,0 @@ -// Automatic FlutterFlow imports -import '/backend/schema/structs/index.dart'; -import '/backend/schema/enums/enums.dart'; -import '/flutter_flow/flutter_flow_theme.dart'; -import '/flutter_flow/flutter_flow_util.dart'; -import 'index.dart'; // Imports other custom actions -import '/flutter_flow/custom_functions.dart'; // Imports custom functions -import 'package:flutter/material.dart'; -// Begin custom action code -// DO NOT REMOVE OR MODIFY THE CODE ABOVE! - -import 'dart:convert'; // Import for base64 decoding -import 'dart:io'; // Import for file operations -import 'package:path_provider/path_provider.dart'; // Import for temporary directory - -Future convertToUploadFile(String img) async { - // Decode the base64 string into bytes - Uint8List bytes = base64.decode(img); - - // Create a temporary file to store the image - final tempDir = await getTemporaryDirectory(); - final tempPath = tempDir.path; - final tempFile = await File('$tempPath/image.jpg').create(); - await tempFile.writeAsBytes(bytes); - - // Create an FFUploadedFile object using the temporary file - return FFUploadedFile( - bytes: bytes, - name: 'image.jpg', - ); -} diff --git a/lib/custom_code/actions/get_dev_u_u_i_d.dart b/lib/custom_code/actions/get_dev_u_u_i_d.dart deleted file mode 100644 index 1be7def9..00000000 --- a/lib/custom_code/actions/get_dev_u_u_i_d.dart +++ /dev/null @@ -1,34 +0,0 @@ -import '/backend/schema/structs/index.dart'; -import 'dart:developer'; -import '/backend/schema/enums/enums.dart'; -import '/flutter_flow/flutter_flow_theme.dart'; -import '/flutter_flow/flutter_flow_util.dart'; -import 'index.dart'; // Imports other custom actions -import '/flutter_flow/custom_functions.dart'; // Imports custom functions -import 'package:flutter/material.dart'; -import 'dart:io'; -import 'package:device_info_plus/device_info_plus.dart'; - -Future getDevUUID() async { - var deviceInfo = DeviceInfoPlugin(); - if (Platform.isIOS) { - // import 'dart:io' - var iosDeviceInfo = await deviceInfo.iosInfo; - return iosDeviceInfo.identifierForVendor; // unique ID on iOS - } else if (Platform.isAndroid) { - var androidDeviceInfo = await deviceInfo.androidInfo; - return androidDeviceInfo.id; // unique ID on Android - } -} - -Future getSerialNumber() async { - var deviceInfo = DeviceInfoPlugin(); - if (Platform.isIOS) { - // import 'dart:io' - var iosDeviceInfo = await deviceInfo.iosInfo; - return iosDeviceInfo.identifierForVendor; // unique ID on iOS - } else if (Platform.isAndroid) { - var androidDeviceInfo = await deviceInfo.androidInfo; - return androidDeviceInfo.serialNumber; // unique ID on Android - } -} diff --git a/lib/custom_code/actions/index.dart b/lib/custom_code/actions/index.dart deleted file mode 100644 index 2110f043..00000000 --- a/lib/custom_code/actions/index.dart +++ /dev/null @@ -1,3 +0,0 @@ -export 'convert_image_file_to_base64.dart' show convertImageFileToBase64; -export 'convert_to_upload_file.dart' show convertToUploadFile; -export 'get_dev_u_u_i_d.dart' show getDevUUID; diff --git a/lib/custom_code/widgets/index.dart b/lib/custom_code/widgets/index.dart deleted file mode 100644 index ec35fd3e..00000000 --- a/lib/custom_code/widgets/index.dart +++ /dev/null @@ -1 +0,0 @@ -export 'image_cropper.dart' show ImageCropper; diff --git a/lib/custom_code/widgets/menu.dart b/lib/custom_code/widgets/menu.dart deleted file mode 100644 index b3fa00c7..00000000 --- a/lib/custom_code/widgets/menu.dart +++ /dev/null @@ -1,61 +0,0 @@ - -import 'dart:collection'; - -import 'package:flutter/material.dart'; - -LinkedHashMap menu = LinkedHashMap.from({ - "Schedule": - [{ - "title": "Schedule\nVisit", - "icon": Icons.settings, - "route": "/Schedule", - }, - { - "title": "Complete\Schedule", - "icon": Icons.calendar_today, - "route": "/Complete", - }, - { - "title": "Provisional\Schedule", - "icon": Icons.calendar_today, - "route": "/Provisional", - }, - { - "title": "Fast\Schedule", - "icon": Icons.calendar_today, - "route": "/Fast", - }], - "Consult": - [{ - "title": "Consult", - "icon": Icons.search, - "route": "/consult", - }, - { - "title": "Liberation\nConsult", - "icon": Icons.search, - "route": "/Liberation", - }, - { - "title": "Access\nConsult", - "icon": Icons.search, - "route": "/Access", - }, - { - "title": "Poeple\nConsult", - "icon": Icons.search, - "route": "/Poeple", - }, - { - "title": "QR Code\nConsult", - "icon": Icons.search, - "route": "/qrcode", - }], - "Preferences": - [{ - "title": "Preferences", - "icon": Icons.settings, - "route": "/preferences", - }], - -}); \ No newline at end of file diff --git a/lib/flutter_flow/custom_functions.dart b/lib/flutter_flow/custom_functions.dart index f33176c1..ddd01694 100644 --- a/lib/flutter_flow/custom_functions.dart +++ b/lib/flutter_flow/custom_functions.dart @@ -9,48 +9,23 @@ import 'lat_lng.dart'; import 'place.dart'; import 'uploaded_file.dart'; - -String? isOneAcliID(String jsonString) { - // Converte o JSON em um Map - final Map data = jsonDecode(jsonString); - - // Extrai a lista de locais - final List locais = data['locais']; - - // Filtra os locais onde CLU_STATUS é igual a "A" - final List locaisAtivos = - locais.where((local) => local['CLU_STATUS'] == 'A').toList(); - - // Verifica se existe somente um local ativo - if (locaisAtivos.length == 1) { - return locaisAtivos.first['CLI_ID']; - } else { - return null; - } -} - String? convertToUppercase(String input) { - // recebe uuma string qualquer e retorna ela em uppercase return input.toUpperCase(); } String? uploadFileToBase64(String? uploadFile) { - // takes an UploadFile of an image as an argument and returns a base64 string of that image if (uploadFile == null) { return null; } - // Converte a string em uma lista de inteiros final List bytes = uploadFile.codeUnits; - // Converte os bytes em uma string base64 final String base64String = base64.encode(bytes); return base64String; } String jsonListToStr(List visitorList) { - // rece um json list e retorna uma string de $.visitante.VTE_DOCUMENTO separado por virgula String result = ''; for (var visitor in visitorList) { result += '${visitor['VTE_DOCUMENTO']},'; @@ -62,7 +37,6 @@ List listStrJsonToJsonList( dynamic jsonList, List strList, ) { - // Recebe um jsonList e uma stringList como argumento e retorna uma nova jsonList associando cada item List result = []; for (int i = 0; i < jsonList.length; i++) { @@ -79,13 +53,10 @@ List listStrJsonToJsonList( } String strListToStr(List strList) { - // recebe uma stringList como argumento e retorna uma str com cada item da strList separado por virgula - return strList.join(','); } int extractIdToStr(String str) { - // recebe um uma string e retorna um inteiro com o valor entre '_ID:' e a próxima vírgula ',' final idStart = str.indexOf('_ID:') + 4; final idEnd = str.indexOf(',', idStart); final idStr = str.substring(idStart, idEnd); @@ -93,14 +64,12 @@ int extractIdToStr(String str) { } String extractDescToStr(String str) { - // recebe um uma string e retorna uma string com o valor entre '_DESCRICAO' e a próxima vírgula ',' final startIndex = str.indexOf('_DESCRICAO:') + '_DESCRICAO:'.length; final endIndex = str.indexOf(',', startIndex); return str.substring(startIndex, endIndex); } String jsonToStr(dynamic json) { - // recebe um json como parametro, converte-o em string e retorna essa string String jsonString = jsonEncode(json); return jsonString; } @@ -115,4 +84,4 @@ Stream getProgressValue() { final progress = math.max(0.0, 1.0 - (elapsedTime / (endTime - startTime))); return progress; }); -} \ No newline at end of file +} diff --git a/lib/flutter_flow/nav/nav.dart b/lib/flutter_flow/nav/nav.dart index a2f8afbc..a10061f8 100644 --- a/lib/flutter_flow/nav/nav.dart +++ b/lib/flutter_flow/nav/nav.dart @@ -155,7 +155,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter( FFRoute( name: 'acessHistoryPage', path: '/acessHistoryPage', - builder: (context, params) => AcessHistoryPageWidget(opt: const { + builder: (context, params) => AccessHistoryScreen(opt: const { 'personType': '.*', 'accessType': '.*', 'search': '.*', diff --git a/lib/index.dart b/lib/index.dart index 28c34aa1..3278d9b5 100644 --- a/lib/index.dart +++ b/lib/index.dart @@ -1,17 +1,17 @@ -export '/pages/acess_history_page/acess_history_page_widget.dart' - show AcessHistoryPageWidget; -export '/pages/home_page/home_page_widget.dart' show HomePageWidget; -export '/pages/liberation_history/liberation_history_widget.dart' +export 'pages/acess_history_page/acess_history_page_widget.dart' + show AccessHistoryScreen; +export 'pages/home_page/home_page_widget.dart' show HomePageWidget; +export 'pages/liberation_history/liberation_history_widget.dart' show LiberationHistoryWidget; -export '/pages/people_on_the_property_page/people_on_the_property_page_widget.dart' +export 'pages/people_on_the_property_page/people_on_the_property_page_widget.dart' show PeopleOnThePropertyPageWidget; -export '/pages/preferences_settings_page/preferences_settings_widget.dart' +export 'pages/preferences_settings_page/preferences_settings_widget.dart' show PreferencesPageWidget; -export '/pages/qr_code_page/qr_code_page_widget.dart' show QrCodePageWidget; -export '/pages/register_visitor_page/register_visitor_page_widget.dart' +export 'pages/qr_code_page/qr_code_page_widget.dart' show QrCodePageWidget; +export 'pages/register_visitor_page/register_visitor_page_widget.dart' show RegisterVisitorPageWidget; -export '/pages/schedule_complete_visit_page/schedule_complete_visit_page_widget.dart' +export 'pages/schedule_complete_visit_page/schedule_complete_visit_page_widget.dart' show ScheduleCompleteVisitPageWidget; -export '/pages/sign_in_page/sign_in_page_widget.dart' show SignInPageWidget; -export '/pages/sign_up_page/sign_up_page_widget.dart' show SignUpPageWidget; -export '/pages/welcome_page/welcome_page_widget.dart' show WelcomePageWidget; +export 'pages/sign_in_page/sign_in_page_widget.dart' show SignInPageWidget; +export 'pages/sign_up_page/sign_up_page_widget.dart' show SignUpPageWidget; +export 'pages/welcome_page/welcome_page_widget.dart' show WelcomePageWidget; diff --git a/lib/pages/acess_history_page/acess_history_page_model.dart b/lib/pages/acess_history_page/acess_history_page_model.dart index d8402b2b..fcfbb302 100644 --- a/lib/pages/acess_history_page/acess_history_page_model.dart +++ b/lib/pages/acess_history_page/acess_history_page_model.dart @@ -1,16 +1,48 @@ import 'package:flutter/material.dart'; +import 'package:hub/backend/api_requests/api_calls.dart'; import 'package:hub/backend/api_requests/api_manager.dart'; import 'package:hub/components/molecular_components/message_opt_modal/opt_modal_widget.dart'; import 'package:hub/flutter_flow/flutter_flow_model.dart'; +import 'package:hub/flutter_flow/flutter_flow_theme.dart'; +import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/flutter_flow/request_manager.dart'; import 'package:hub/pages/acess_history_page/acess_history_page_widget.dart'; import 'package:hub/shared/helpers/db_helper.dart'; +import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/log_util.dart'; +import 'package:rxdart/rxdart.dart'; + +class AccessHistoryModel extends FlutterFlowModel { + // Singleton instance + static final AccessHistoryModel _instance = AccessHistoryModel._internal(); + + // Private constructor + AccessHistoryModel._internal() : super(); + + // Factory constructor to return the singleton instance + factory AccessHistoryModel() { + return _instance; + } -class AcessHistoryPageModel extends FlutterFlowModel { final DatabaseHelper db = DatabaseHelper(); late final String devUUID; late final String userUUID; late final String cliUUID; + final BehaviorSubject> selectedTypeSubject; + bool isSubjectClosed = false; + final scaffoldKey = GlobalKey(); + late Function(Function) safeSetState; + + late ScrollController scrollController; + int pageNumber = 1; + final int pageSize = 10; + bool hasData = false; + bool loading = false; + + String personType = '.*'; + + late Future accessFuture; + List accessWrap = []; final unfocusNode = FocusNode(); final _accessHistoryManager = FutureRequestManager(); @@ -30,10 +62,10 @@ class AcessHistoryPageModel extends FlutterFlowModel { @override void initState(BuildContext context) { - initDatabase(); + _initAsync(); } - Future initDatabase() async { + Future _initAsync() async { devUUID = await db .get(key: 'devUUID', field: 'value') .then((value) => value.toString()); @@ -45,11 +77,95 @@ class AcessHistoryPageModel extends FlutterFlowModel { .then((value) => value.toString()); } - @override - void dispose() { - unfocusNode.dispose(); + void _updateAccessHistoryAction( + Map newType, BuildContext context) { + if (!isSubjectClosed) { + final currentType = selectedTypeSubject.value; + final updatedType = Map.from(currentType); + bool needsUpdate = false; + newType.forEach((key, newValue) { + if (currentType[key] != newValue) { + updatedType[key] = newValue; + needsUpdate = true; + } + }); + if (needsUpdate) { + selectedTypeSubject.add(updatedType); + fetchCardListViewService(updatedType, context); + safeSetState?.call(() {}); + } + } + } - clearAccessHistoryCache(); + Future fetchAccessHistoryService( + BuildContext context) async { + try { + safeSetState.call(() => loading = true); + var response = await PhpGroup.getAccessCall.call( + pageSize: pageSize.toString(), + pageNumber: pageNumber.toString(), + pesTipo: personType != 'E' && personType != 'O' ? 'T' : personType, + ); + + final List accessHistory = response.jsonBody['acessos'] ?? []; + + List filteredAccess = accessHistory.where((item) { + final personTypeMatches = + personType == '.*' || item["PES_TIPO"].toString() == personType; + return personTypeMatches; + }).toList(); + + if (filteredAccess != null && filteredAccess.isNotEmpty) { + safeSetState.call(() { + accessWrap.addAll(filteredAccess); + hasData = true; + loading = false; + }); + return response; + } + _showNoMoreDataSnackbar(context); + safeSetState.call(() { + hasData = false; + loading = false; + }); + return null; + } catch (e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed('processRequest', "", "Busca Acesso", e, s); + safeSetState.call(() { + hasData = false; + loading = false; + }); + } + return null; + } + + 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, + ), + ); + } + + void _loadMoreAccess(BuildContext context) { + if (hasData == true) { + pageNumber++; + accessFuture = fetchAccessHistoryService(context); + } + } + + void fetchCardListViewService( + Map select, BuildContext context) { + personType = select['personType']!; + accessWrap = []; + pageNumber = 1; + accessFuture = fetchAccessHistoryService(context); } Future toggleOptionsAction(BuildContext context) async { @@ -71,4 +187,11 @@ class AcessHistoryPageModel extends FlutterFlowModel { }, ); } + + @override + void dispose() { + unfocusNode.dispose(); + + clearAccessHistoryCache(); + } } diff --git a/lib/pages/acess_history_page/acess_history_page_widget.dart b/lib/pages/acess_history_page/acess_history_page_widget.dart index d0cfcf45..4876f91c 100644 --- a/lib/pages/acess_history_page/acess_history_page_widget.dart +++ b/lib/pages/acess_history_page/acess_history_page_widget.dart @@ -15,36 +15,22 @@ import 'package:hub/shared/utils/log_util.dart'; import 'package:rxdart/rxdart.dart'; @immutable -class AcessHistoryPageWidget extends StatefulWidget { +// ignore: must_be_immutable +class AccessHistoryScreen extends StatefulWidget { late Map opt = { 'personType': '.*', 'accessType': '.*', 'search': '.*', }; - AcessHistoryPageWidget({super.key, required this.opt}); + AccessHistoryScreen({super.key, required this.opt}); @override - State createState() => - _AcessHistoryPageWidgetState(opt); + State createState() => _AccessHistoryScreenState(opt); } -class _AcessHistoryPageWidgetState extends State { - late AcessHistoryPageModel _model; - final BehaviorSubject> selectedTypeSubject; - bool _isSubjectClosed = false; - final scaffoldKey = GlobalKey(); +class _AccessHistoryScreenState extends State { + late AccessHistoryModel _model; - late ScrollController _scrollController; - int _pageNumber = 1; - final int _pageSize = 10; - bool _hasData = false; - bool _loading = false; - - String _personType = '.*'; - - late Future _accessFuture; - List _accessWrap = []; - - _AcessHistoryPageWidgetState(Map opt) + _AccessHistoryScreenState(Map opt) : selectedTypeSubject = BehaviorSubject.seeded(opt) { selectedTypeSubject.listen((value) {}); } @@ -52,13 +38,13 @@ class _AcessHistoryPageWidgetState extends State { @override void initState() { super.initState(); - _model = createModel(context, () => AcessHistoryPageModel()); - _accessFuture = fetchAccessHistoryService(); + _model = createModel(context, () => AccessHistoryModel()); + _model.accessFuture = fetchAccessHistoryService(); - _scrollController = ScrollController() + _model.scrollController = ScrollController() ..addListener(() { - if (_scrollController.position.atEdge && - _scrollController.position.pixels != 0) { + if (_model.scrollController.position.atEdge && + _model.scrollController.position.pixels != 0) { _loadMoreAccess(); } }); @@ -67,7 +53,7 @@ class _AcessHistoryPageWidgetState extends State { @override void dispose() { selectedTypeSubject.close(); - _isSubjectClosed = true; + _model.isSubjectClosed = true; super.dispose(); } @@ -76,7 +62,7 @@ class _AcessHistoryPageWidgetState extends State { final theme = FlutterFlowTheme.of(context); return Scaffold( - key: scaffoldKey, + key: _model.scaffoldKey, backgroundColor: FlutterFlowTheme.of(context).primaryBackground, appBar: _appBar(context, theme), body: _body(context)); @@ -164,84 +150,13 @@ class _AcessHistoryPageWidgetState extends State { ); } - void _updateAccessHistoryAction(Map newType) { - if (!_isSubjectClosed) { - final currentType = selectedTypeSubject.value; - final updatedType = Map.from(currentType); - bool needsUpdate = false; - newType.forEach((key, newValue) { - if (currentType[key] != newValue) { - updatedType[key] = newValue; - needsUpdate = true; - } - }); - if (needsUpdate) { - selectedTypeSubject.add(updatedType); - fetchCardListViewService(updatedType); - safeSetState(() {}); - } - } - } - - Future fetchAccessHistoryService() async { - try { - setState(() => _loading = true); - var response = await PhpGroup.getAccessCall.call( - pageSize: _pageSize.toString(), - pageNumber: _pageNumber.toString(), - pesTipo: _personType != 'E' && _personType != 'O' ? 'T' : _personType, - ); - - final List accessHistory = response.jsonBody['acessos'] ?? []; - - List filteredAccess = accessHistory.where((item) { - final personTypeMatches = - _personType == '.*' || item["PES_TIPO"].toString() == _personType; - return personTypeMatches; - }).toList(); - - if (filteredAccess != null && filteredAccess.isNotEmpty) { - setState(() { - _accessWrap.addAll(filteredAccess); - _hasData = true; - _loading = false; - }); - return response; - } - _showNoMoreDataSnackbar(context); - setState(() { - _hasData = false; - _loading = false; - }); - return null; - } catch (e, s) { - DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed('processRequest', "", "Busca Acesso", e, s); - setState(() { - _hasData = false; - _loading = false; - }); - } - } - - 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 _body(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - if (_hasData == false && _pageNumber <= 1 && _loading == false) + if (_model.hasData == false && + _model.pageNumber <= 1 && + _model.loading == false) Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -256,9 +171,9 @@ class _AcessHistoryPageWidgetState extends State { ], ), ) - else if (_hasData || _pageNumber >= 1) + else if (_model.hasData || _model.pageNumber >= 1) Expanded(child: _cardListViewOrganismWidget()), - if (_hasData == true && _loading) + if (_model.hasData == true && _model.loading) Container( padding: const EdgeInsets.only(top: 15, bottom: 15), child: Center( @@ -273,26 +188,12 @@ class _AcessHistoryPageWidgetState extends State { ); } - void _loadMoreAccess() { - if (_hasData == true) { - _pageNumber++; - _accessFuture = fetchAccessHistoryService(); - } - } - - void fetchCardListViewService(Map select) { - _personType = select['personType']!; - _accessWrap = []; - _pageNumber = 1; - _accessFuture = fetchAccessHistoryService(); - } - Widget _cardListViewOrganismWidget() { return FutureBuilder( - future: _accessFuture, + future: _model.accessFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting && - _accessWrap.isEmpty) { + _model.accessWrap.isEmpty) { return Center( child: SizedBox( width: 50.0, @@ -314,10 +215,10 @@ class _AcessHistoryPageWidgetState extends State { return ListView.builder( shrinkWrap: true, physics: const BouncingScrollPhysics(), - controller: _scrollController, - itemCount: _accessWrap.length, + controller: _model.scrollController, + itemCount: _model.accessWrap.length, itemBuilder: (context, index) { - final accessHistoryItem = _accessWrap[index]; + final accessHistoryItem = _model.accessWrap[index]; return _accessHistoryCardMoleculeWidget(context, accessHistoryItem); }, ); @@ -396,3 +297,104 @@ class _AcessHistoryPageWidgetState extends State { ); } } + +class AccessHistoryAppBar extends StatelessWidget { + AccessHistoryAppBar(this.model, this.selectedTypeSubject); + final AccessHistoryModel model; + final BehaviorSubject> selectedTypeSubject; + + late final FlutterFlowTheme theme; + + @override + Widget build(BuildContext context) { + theme = FlutterFlowTheme.of(context); + + return AppBar( + backgroundColor: theme.primaryBackground, + automaticallyImplyLeading: false, + leading: _backButton(context, theme), + title: _title(context, theme), + centerTitle: true, + elevation: 0.0, + actions: [_filterButton(context)], + ); + } + + Widget _backButton(BuildContext context, FlutterFlowTheme theme) { + return FlutterFlowIconButton( + borderColor: Colors.transparent, + borderRadius: 30.0, + borderWidth: 1.0, + buttonSize: 60.0, + icon: Icon( + Icons.keyboard_arrow_left, + color: theme.primaryText, + size: 30.0, + ), + onPressed: () => Navigator.of(context).pop(), + ); + } + + Widget _title(BuildContext context, FlutterFlowTheme theme) { + return Text( + FFLocalizations.of(context).getText('ch8qymga'), + style: theme.headlineMedium.override( + fontFamily: theme.headlineMediumFamily, + color: theme.primaryText, + fontSize: 16.0, + letterSpacing: 0.0, + useGoogleFonts: + GoogleFonts.asMap().containsKey(theme.headlineMediumFamily), + ), + ); + } + + Widget _filterButton(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), + child: IconButton( + icon: const Icon(Icons.filter_list), + onPressed: () async { + final Map? selectedFilter = + await showModalBottomSheet>( + isScrollControlled: true, + backgroundColor: Colors.transparent, + context: context, + builder: (context) { + return GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + color: Colors.transparent, + child: GestureDetector( + onTap: () {}, + child: OptModalWidget( + defaultPersonType: + selectedTypeSubject.value['personType'] ?? + '.*', + ), + ), + ), + ); + }); + + if (selectedFilter != null) { + _updateAccessHistoryAction(selectedFilter); + } + }, + ), + ), + ], + ); + } +} + +class AccessHistoryList extends StatelessWidget { + @override + Widget build(BuildContext context) { + // TODO: implement build + throw UnimplementedError(); + } +} diff --git a/lib/pages/people_on_the_property_page/people_on_the_property_page_model.dart b/lib/pages/people_on_the_property_page/people_on_the_property_page_model.dart index cc62f4f5..b33ee6b3 100644 --- a/lib/pages/people_on_the_property_page/people_on_the_property_page_model.dart +++ b/lib/pages/people_on_the_property_page/people_on_the_property_page_model.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:hub/flutter_flow/flutter_flow_model.dart'; import 'package:hub/pages/people_on_the_property_page/people_on_the_property_page_widget.dart'; @@ -16,4 +15,4 @@ class PeopleOnThePropertyPageModel void dispose() { unfocusNode.dispose(); } -} \ No newline at end of file +} diff --git a/lib/pages/pets_page/pets_page_model.dart b/lib/pages/pets_page/pets_page_model.dart index e16b9c1d..68d21a7c 100644 --- a/lib/pages/pets_page/pets_page_model.dart +++ b/lib/pages/pets_page/pets_page_model.dart @@ -5,15 +5,14 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:hub/backend/api_requests/api_calls.dart'; import 'package:hub/backend/api_requests/api_manager.dart'; -import 'package:hub/custom_code/actions/convert_to_upload_file.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/form_field_controller.dart'; import 'package:hub/pages/pets_page/pets_page_widget.dart'; import 'package:hub/shared/helpers/db_helper.dart'; import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/image_util.dart'; import 'package:hub/shared/utils/log_util.dart'; import 'package:hub/shared/utils/validator_util.dart'; -import '/custom_code/actions/index.dart' as actions; class PetsPageModel extends FlutterFlowModel { final DatabaseHelper db = DatabaseHelper(); @@ -164,7 +163,7 @@ class PetsPageModel extends FlutterFlowModel { Response response = await get(Uri.parse( 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId')); String base64 = base64Encode(response.bodyBytes); - uploadedTempFile = await convertToUploadFile(base64); + uploadedTempFile = await ImageUtils.convertToUploadFile(base64); updateImage?.call(); })(); @@ -269,7 +268,7 @@ class PetsPageModel extends FlutterFlowModel { } Future updatePet() async { - var img = await actions.convertImageFileToBase64(uploadedLocalFile!); + var img = await ImageUtils.convertImageFileToBase64(uploadedLocalFile!); img = "base64;jpeg,$img"; final url = 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${devUUID}&userUUID=${userUUID}&cliID=${cliUUID}&atividade=consultaFotoPet&petId=$petId'; @@ -314,7 +313,7 @@ class PetsPageModel extends FlutterFlowModel { } Future registerPet() async { - var img = await actions.convertImageFileToBase64(uploadedLocalFile!); + var img = await ImageUtils.convertImageFileToBase64(uploadedLocalFile!); img = "base64;jpeg,$img"; final response = await PhpGroup.registerPet.call( image: img, diff --git a/lib/pages/pets_page/pets_page_widget.dart b/lib/pages/pets_page/pets_page_widget.dart index e704d5a6..c12af2fe 100644 --- a/lib/pages/pets_page/pets_page_widget.dart +++ b/lib/pages/pets_page/pets_page_widget.dart @@ -18,7 +18,6 @@ import 'package:hub/components/atomic_components/shared_components_atoms/custom_ import 'package:hub/components/atomic_components/shared_components_atoms/media_upload_button.dart'; import 'package:hub/components/atomic_components/shared_components_atoms/submit_button.dart'; import 'package:hub/components/atomic_components/shared_components_atoms/tabview.dart'; -import 'package:hub/custom_code/actions/convert_to_upload_file.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; @@ -28,13 +27,13 @@ import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/upload_data.dart'; import 'package:hub/pages/pets_page/pets_history_screen.dart'; - import 'package:hub/pages/pets_page/pets_page_model.dart'; + import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/image_util.dart'; import 'package:hub/shared/utils/validator_util.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:sqflite/sqflite.dart'; -import '/custom_code/actions/index.dart' as actions; class PetsPageWidget extends StatefulWidget { dynamic pet; @@ -83,7 +82,8 @@ class _PetsPageWidgetState extends State Response response = await get(Uri.parse( 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${_model.devUUID}&userUUID=${_model.userUUID}&cliID=${_model.cliUUID}&atividade=consultaFotoPet&petId=$petId')); String base64 = base64Encode(response.bodyBytes); - FFUploadedFile uploadedFile = await convertToUploadFile(base64); + FFUploadedFile uploadedFile = + await ImageUtils.convertToUploadFile(base64); setState(() { _model.handleUploadComplete(uploadedFile); }); diff --git a/lib/shared/utils/device_util.dart b/lib/shared/utils/device_util.dart new file mode 100644 index 00000000..76fb92d2 --- /dev/null +++ b/lib/shared/utils/device_util.dart @@ -0,0 +1,35 @@ +import '/backend/schema/structs/index.dart'; +import 'dart:developer'; +import '/backend/schema/enums/enums.dart'; +import '/flutter_flow/flutter_flow_theme.dart'; +import '/flutter_flow/flutter_flow_util.dart'; +import '/flutter_flow/custom_functions.dart'; // Imports custom functions +import 'package:flutter/material.dart'; +import 'dart:io'; +import 'package:device_info_plus/device_info_plus.dart'; + +class DeviceUtil { + static Future getDevUUID() async { + var deviceInfo = DeviceInfoPlugin(); + if (Platform.isIOS) { + // import 'dart:io' + var iosDeviceInfo = await deviceInfo.iosInfo; + return iosDeviceInfo.identifierForVendor; // unique ID on iOS + } else if (Platform.isAndroid) { + var androidDeviceInfo = await deviceInfo.androidInfo; + return androidDeviceInfo.id; // unique ID on Android + } + } + + static Future getSerialNumber() async { + var deviceInfo = DeviceInfoPlugin(); + if (Platform.isIOS) { + // import 'dart:io' + var iosDeviceInfo = await deviceInfo.iosInfo; + return iosDeviceInfo.identifierForVendor; // unique ID on iOS + } else if (Platform.isAndroid) { + var androidDeviceInfo = await deviceInfo.androidInfo; + return androidDeviceInfo.serialNumber; // unique ID on Android + } + } +} diff --git a/lib/shared/utils/image_util.dart b/lib/shared/utils/image_util.dart new file mode 100644 index 00000000..25c56281 --- /dev/null +++ b/lib/shared/utils/image_util.dart @@ -0,0 +1,38 @@ +// Automatic FlutterFlow imports + +import 'dart:io'; + +import 'package:path_provider/path_provider.dart'; + +import 'package:flutter/material.dart'; +import 'dart:convert'; +import 'dart:typed_data'; +import '../../flutter_flow/uploaded_file.dart'; + +class ImageUtils { + static Future convertImageFileToBase64( + FFUploadedFile imageFile) async { + List? imageBytes = imageFile.bytes; + if (imageBytes != null) { + String base64Image = base64Encode(imageBytes); + return base64Image; + } + } + + static Future convertToUploadFile(String img) async { + // Decode the base64 string into bytes + Uint8List bytes = base64.decode(img); + + // Create a temporary file to store the image + final tempDir = await getTemporaryDirectory(); + final tempPath = tempDir.path; + final tempFile = await File('$tempPath/image.jpg').create(); + await tempFile.writeAsBytes(bytes); + + // Create an FFUploadedFile object using the temporary file + return FFUploadedFile( + bytes: bytes, + name: 'image.jpg', + ); + } +} diff --git a/lib/custom_code/widgets/image_cropper.dart b/lib/shared/widgets/image_cropper_widget/image_cropper.dart similarity index 100% rename from lib/custom_code/widgets/image_cropper.dart rename to lib/shared/widgets/image_cropper_widget/image_cropper.dart diff --git a/lib/shared/widgets/menu.dart b/lib/shared/widgets/menu.dart new file mode 100644 index 00000000..affa655f --- /dev/null +++ b/lib/shared/widgets/menu.dart @@ -0,0 +1,58 @@ + + +// // LinkedHashMap menu = LinkedHashMap.from({ +// "Schedule": +// [{ +// "title": "Schedule\nVisit", +// "icon": Icons.settings, +// "route": "/Schedule", +// }, +// { +// "title": "Complete\Schedule", +// "icon": Icons.calendar_today, +// "route": "/Complete", +// }, +// { +// "title": "Provisional\Schedule", +// "icon": Icons.calendar_today, +// "route": "/Provisional", +// }, +// { +// "title": "Fast\Schedule", +// "icon": Icons.calendar_today, +// "route": "/Fast", +// }], +// "Consult": +// [{ +// "title": "Consult", +// "icon": Icons.search, +// "route": "/consult", +// }, +// { +// "title": "Liberation\nConsult", +// "icon": Icons.search, +// "route": "/Liberation", +// }, +// { +// "title": "Access\nConsult", +// "icon": Icons.search, +// "route": "/Access", +// }, +// { +// "title": "Poeple\nConsult", +// "icon": Icons.search, +// "route": "/Poeple", +// }, +// { +// "title": "QR Code\nConsult", +// "icon": Icons.search, +// "route": "/qrcode", +// }], +// "Preferences": +// [{ +// "title": "Preferences", +// "icon": Icons.settings, +// "route": "/preferences", +// }], + +// }); \ No newline at end of file