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/commons/actions/api_calls.dart'; import 'package:hub/commons/actions/api_manager.dart'; import 'package:hub/modals/details/visit_details_modal/widget.dart'; import 'package:hub/pages/consults/visit/model.dart'; import 'package:provider/provider.dart'; import '/commons/widgets/custom_functions.dart' as functions; import '/commons/widgets/flutter_flow_icon_button.dart'; import '/commons/widgets/flutter_flow_theme.dart'; import '/commons/widgets/flutter_flow_util.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? visitorJsonList; @override State createState() => _VisitHistoryPageWidgetState(); } class _VisitHistoryPageWidgetState extends State with TickerProviderStateMixin { late VisitHistoryPageModel _model; int _visitHistoryLoadingIdx = 0; final int _visitHistoryLoadingCount = 10; List _visitHistoryList = []; ScrollController _visitHistoryController = ScrollController(); final scaffoldKey = GlobalKey(); @override void initState() { super.initState(); _model = createModel(context, () => VisitHistoryPageModel()); // 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(); _model.visitorStrList = widget.visitorStrList!; setState(() {}); } else { return; } }); _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> 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 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(() {}); } } void_scrollListener() { if (_visitHistoryController.position.pixels == _visitHistoryController.position.maxScrollExtent) { _loadMoreVisitHistory(); } } @override void dispose() { _model.dispose(); super.dispose(); } @override Widget build(BuildContext context) { context.watch(); 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), ), ); } } 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( 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( '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( () { if (functions.jsonToStr( getJsonField( visitaWrapItem, r'''$.VAW_STATUS''', )) == '\"A\"') { return FlutterFlowTheme .of(context) .success; } else if ((functions .jsonToStr( getJsonField( visitaWrapItem, r'''$.VAW_STATUS''', )) == '\"C\"') || (functions.jsonToStr( getJsonField( visitaWrapItem, r'''$.VAW_STATUS''', )) == '\"F\"') || (functions.jsonToStr( getJsonField( visitaWrapItem, r'''$.VAW_STATUS''', )) == '\"B\"') || (functions.jsonToStr( getJsonField( visitaWrapItem, r'''$.VAW_STATUS''', )) == '\"I\"')) { return FlutterFlowTheme .of(context) .error; } else if (functions .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 (functions.jsonToStr( getJsonField( visitaWrapItem, r'''$.VAW_STATUS''', )) == '\"A\"') { return FFLocalizations .of(context) .getVariableText( ptText: 'Ativo', enText: 'Active', ); } else if ((functions .jsonToStr( getJsonField( visitaWrapItem, r'''$.VAW_STATUS''', )) == '\"F\"') || (functions.jsonToStr( getJsonField( visitaWrapItem, r'''$.VAW_STATUS''', )) == '\"C\"') || (functions.jsonToStr( getJsonField( visitaWrapItem, r'''$.VAW_STATUS''', )) == '\"B\"') || (functions.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( '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, ), ), ], ), ), ), ); }); }, ); }, ) ], ), ), ); }