This commit is contained in:
J. A. Messias 2024-12-09 16:22:34 -03:00
parent a1d361b777
commit cb352b42ff
15 changed files with 1 additions and 690 deletions

View File

@ -1,3 +0,0 @@
export 'data_sources/index.dart';
export 'repositories/index.dart';
export 'models/index.dart';

View File

@ -1,3 +0,0 @@
export 'entities/index.dart';
export 'respositories/index.dart';
export 'usecases/index.dart';

View File

@ -1,3 +0,0 @@
export 'blocs/index.dart';
export 'pages/index.dart';
export 'widgets/index.dart';

View File

@ -1,449 +0,0 @@
import 'package:flutter/material.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/request_manager.dart';
import 'package:hub/shared/helpers/storage/base_storage.dart';
import 'package:hub/shared/helpers/storage/storage_helper.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hub/backend/api_requests/api_calls.dart';
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_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/shared/utils/dialog_util.dart';
import 'package:hub/shared/utils/limited_text_size.dart';
import 'package:hub/shared/utils/log_util.dart';
import 'package:rxdart/rxdart.dart';
class ProvisionalScheduleHistoryModel extends FlutterFlowModel<ProvisionalScheduleHistoryScreen> {
late final String devUUID;
late final String userUUID;
late final String cliUUID;
final unfocusNode = FocusNode();
final _ProvisionalScheduleHistoryManager = FutureRequestManager<ApiCallResponse>();
Future<ApiCallResponse> ProvisionalScheduleHistory({
String? uniqueQueryKey,
bool? overrideCache,
required Future<ApiCallResponse> Function() requestFn,
}) =>
_ProvisionalScheduleHistoryManager.performRequest(
uniqueQueryKey: uniqueQueryKey,
overrideCache: overrideCache,
requestFn: requestFn,
);
void clearProvisionalScheduleHistoryCache() => _ProvisionalScheduleHistoryManager.clear();
void clearProvisionalScheduleHistoryCacheKey(String? uniqueKey) => _ProvisionalScheduleHistoryManager.clearRequest(uniqueKey);
@override
void initState(BuildContext context) {
initDatabase();
}
Future<void> initDatabase() async {
devUUID = (await StorageHelper().get(KeychainStorageKey.devUUID.value)) ?? '';
userUUID = (await StorageHelper().get(KeychainStorageKey.userUUID.value)) ?? '';
cliUUID = (await StorageHelper().get(KeychainStorageKey.clientUUID.value)) ?? '';
}
@override
void dispose() {
unfocusNode.dispose();
clearProvisionalScheduleHistoryCache();
}
Future toggleOptionsAction(BuildContext context) async {
await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
useSafeArea: true,
context: context,
builder: (context) {
return GestureDetector(
onTap: () => unfocusNode.canRequestFocus
? FocusScope.of(context).requestFocus(unfocusNode)
: FocusScope.of(context).unfocus(),
child: Padding(
padding: MediaQuery.viewInsetsOf(context),
child: const OptModalWidget(),
),
);
},
);
}
}
// ignore: must_be_immutable
class ProvisionalScheduleHistoryScreen extends StatefulWidget {
late Map<String, String> opt = {
'personType': '.*',
'accessType': '.*',
'search': '.*',
};
ProvisionalScheduleHistoryScreen({super.key, required this.opt});
@override
State<ProvisionalScheduleHistoryScreen> createState() => _ProvisionalScheduleHistoryState(opt);
}
class _ProvisionalScheduleHistoryState extends State<ProvisionalScheduleHistoryScreen> {
late ProvisionalScheduleHistoryModel _model;
final BehaviorSubject<Map<String, String>> selectedTypeSubject;
bool _isSubjectClosed = false;
final scaffoldKey = GlobalKey<ScaffoldState>();
late ScrollController _scrollController;
int _pageNumber = 1;
final int _pageSize = 10;
bool _hasData = false;
bool _loading = false;
String _personType = '.*';
late Future<void> _accessFuture;
List<dynamic> _accessWrap = [];
_ProvisionalScheduleHistoryState(Map<String, String> opt) : selectedTypeSubject = BehaviorSubject.seeded(opt) {
selectedTypeSubject.listen((value) {});
}
@override
void initState() {
super.initState();
_model = createModel(context, () => ProvisionalScheduleHistoryModel());
_accessFuture = fetchProvisionalScheduleHistoryService();
_scrollController = ScrollController()
..addListener(() {
if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) {
_loadMoreAccess();
}
});
}
@override
void dispose() {
selectedTypeSubject.close();
_isSubjectClosed = true;
super.dispose();
}
@override
Widget build(BuildContext context) {
final theme = FlutterFlowTheme.of(context);
return Scaffold(
key: scaffoldKey,
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
appBar: _appBar(context, theme),
body: _body(context));
}
PreferredSizeWidget _appBar(BuildContext context, FlutterFlowTheme theme) {
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<String, String>? selectedFilter = await showModalBottomSheet<Map<String, String>>(
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) {
_updateProvisionalScheduleHistoryAction(selectedFilter);
}
},
),
),
],
);
}
void _updateProvisionalScheduleHistoryAction(Map<String, String> newType) {
if (!_isSubjectClosed) {
final currentType = selectedTypeSubject.value;
final updatedType = Map<String, String>.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<ApiCallResponse?> fetchProvisionalScheduleHistoryService() async {
try {
setState(() => _loading = true);
var response = await PhpGroup.getProvSchedules.call(_pageNumber.toString());
final List<dynamic> ProvisionalScheduleHistory = response.jsonBody['agendamento']['value'] ?? [];
List<dynamic> filteredAccess = ProvisionalScheduleHistory.where((item) {
final personTypeMatches = _personType == '.*' || item["AGP_STATUS"].toString() == _personType;
return personTypeMatches;
}).toList();
if (filteredAccess.isNotEmpty) {
setState(() {
_accessWrap.addAll(filteredAccess);
_hasData = true;
_loading = false;
});
return response;
}
_showNoMoreDataSnackbar(context);
setState(() {
_hasData = false;
_loading = false;
});
return null;
} catch (e, s) {
await DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed('processRequest', "", "Busca Acesso", e, s);
setState(() {
_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."),
style: TextStyle(
color: Colors.white,
fontSize: LimitedFontSizeUtil.getBodyFontSize(context),
),
),
duration: const Duration(seconds: 3),
backgroundColor: FlutterFlowTheme.of(context).primary,
),
);
}
Widget _body(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
if (_hasData == false && _pageNumber <= 1 && _loading == false)
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Center(
child: Text(
FFLocalizations.of(context)
.getVariableText(ptText: "Nenhum histórico encontrado!", enText: "No history found!"),
)),
],
),
)
else if (_hasData || _pageNumber >= 1)
Expanded(child: _cardListViewOrganismWidget()),
if (_hasData == true && _loading)
Container(
padding: const EdgeInsets.only(top: 15, bottom: 15),
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
FlutterFlowTheme.of(context).primary,
),
),
),
)
],
);
}
void _loadMoreAccess() {
if (_hasData == true) {
_pageNumber++;
_accessFuture = fetchProvisionalScheduleHistoryService();
}
}
void fetchCardListViewService(Map<String, String> select) {
_personType = select['personType']!;
_accessWrap = [];
_pageNumber = 1;
_accessFuture = fetchProvisionalScheduleHistoryService();
}
Widget _cardListViewOrganismWidget() {
return FutureBuilder<void>(
future: _accessFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting && _accessWrap.isEmpty) {
return Center(
child: SizedBox(
width: 50.0,
height: 50.0,
child: SpinKitCircle(
color: FlutterFlowTheme.of(context).primary,
size: 50.0,
),
),
);
} else if (snapshot.hasError) {
return Center(
child: Text(FFLocalizations.of(context)
.getVariableText(ptText: "Falha ao efetuar operação!", enText: "Failed to perform operation!")),
);
}
return ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
controller: _scrollController,
itemCount: _accessWrap.length,
itemBuilder: (context, index) {
final ProvisionalScheduleHistoryItem = _accessWrap[index];
return _ProvisionalScheduleHistoryCardMoleculeWidget(context, ProvisionalScheduleHistoryItem);
},
);
},
);
}
Widget _ProvisionalScheduleHistoryCardMoleculeWidget(BuildContext context, dynamic ProvisionalScheduleHistoryItem) {
return CardItemTemplateComponentWidget(
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${_model.cliUUID}&atividade=getFoto&Documento=${ProvisionalScheduleHistoryItem['PES_ID'] ?? ''}&tipo=${ProvisionalScheduleHistoryItem['PES_TIPO'] ?? ''}',
labelsHashMap: Map<String, String>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Nome:',
enText: 'Name:',
): ProvisionalScheduleHistoryItem['AGP_NOME'] ?? '',
FFLocalizations.of(context).getVariableText(
ptText: 'Acesso:',
enText: 'Access:',
): ProvisionalScheduleHistoryItem['AGP_DT_VISITA'] ?? '',
FFLocalizations.of(context).getVariableText(
ptText: 'Setor',
enText: 'Sector',
): ProvisionalScheduleHistoryItem['AGP_OBSERVACAO'] ?? '',
}),
statusHashMap: [
ProvisionalScheduleHistoryItem['AGP_STATUS'] == 'AT'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Morador',
enText: 'Resident',
): FlutterFlowTheme.of(context).alternate2,
})
: ProvisionalScheduleHistoryItem['AGP_STATUS'] == 'IN'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Visitante',
enText: 'Visitor',
): FlutterFlowTheme.of(context).alternate2,
})
: Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Desconhecido',
enText: 'Unknown',
): FlutterFlowTheme.of(context).alternate2,
}),
ProvisionalScheduleHistoryItem['AGP_STATUS'] == 'CO'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Entrada',
enText: 'Entrance',
): FlutterFlowTheme.of(context).success,
})
: ProvisionalScheduleHistoryItem['AGP_STATUS'] == 'AA'
? Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Saída',
enText: 'Exit',
): FlutterFlowTheme.of(context).error,
})
: Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Desconhecido',
enText: 'Unknown',
): FlutterFlowTheme.of(context).warning,
})
],
onTapCardItemAction: () async {});
}
String imageUrlAtomWidget(String document, String type) {
return valueOrDefault<String>(
"https://freaccess.com.br/freaccess/getImage.php?&cliID=${_model.cliUUID}&atividade=getFoto&Documento=$document&tipo=$type",
"https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg",
);
}
}

View File

@ -1,229 +0,0 @@
import 'package:flutter/material.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/flutter_flow/form_field_controller.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/shared/utils/limited_text_size.dart';
class FilterModal extends FlutterFlowModel<FilterModalWidget> {
FocusNode? textFieldFocusNode;
TextEditingController? textController;
String? Function(BuildContext, String?)? textControllerValidator;
bool? checkboxValue1;
bool? checkboxValue2;
FormFieldController<List<String>>? checkboxGroupValueController;
List<String>? get checkboxGroupValues => checkboxGroupValueController?.value;
set checkboxGroupValues(List<String>? v) => checkboxGroupValueController?.value = v;
@override
void initState(BuildContext context) {}
@override
void dispose() {
textFieldFocusNode?.dispose();
textController?.dispose();
}
}
class FilterModalWidget extends StatefulWidget {
final Map<String, dynamic> defaultSelections;
final Map<String, List<Map<String, String>>> filterOptions;
final Map<String, String> filterTitles;
const FilterModalWidget({
super.key,
required this.defaultSelections,
required this.filterOptions,
required this.filterTitles,
});
@override
_FilterModalWidgetState createState() => _FilterModalWidgetState();
}
class _FilterModalWidgetState extends State<FilterModalWidget> {
late FilterModal _model;
late Map<String, dynamic> selected;
@override
void setState(VoidCallback callback) {
super.setState(callback);
_model.onUpdate();
}
@override
void initState() {
super.initState();
_model = createModel(context, () => FilterModal());
_model.textController ??= TextEditingController();
_model.textFieldFocusNode ??= FocusNode();
selected = widget.defaultSelections;
}
void _applyFilter() {
Map<String, String> filterResult = {
'search': _model.textController?.text == '' ? '' : _model.textController!.text.toLowerCase(),
};
widget.filterOptions.forEach((key, options) {
filterResult[key] = selected[key]!.isEmpty || selected[key]!.length > 1
? ''
: selected[key]!;
});
context.pop(filterResult);
}
Widget _buildCheckboxListTile(String key, List<Map<String, String>> options, double fontsize) {
double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context);
return Column(
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 3.0, 0.0, 0.0),
child: Text(
widget.filterTitles[key]!,
textAlign: TextAlign.left,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
fontSize: limitedInputFontSize,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily),
color: FlutterFlowTheme.of(context).primaryText,
),
),
),
],
),
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (context, index) {
final option = options[index];
return CheckboxListTile(
title: Text(
option['title']!,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
letterSpacing: 0.0,
fontSize: limitedInputFontSize,
useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily),
color: FlutterFlowTheme.of(context).primaryText,
),
),
dense: true,
value: selected[key]!.contains(option['value']),
onChanged: (bool? value) {
setState(() {
if (value == true) {
if (!selected[key]!.contains(option['value'])) {
selected[key] = (option['value']);
}
} else {
selected[key] = '';
}
});
},
activeColor: FlutterFlowTheme.of(context).primary,
checkColor: FlutterFlowTheme.of(context).info,
checkboxShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100),
),
enableFeedback: true,
side: BorderSide(
width: 5,
color: FlutterFlowTheme.of(context).secondaryText,
),
controlAffinity: ListTileControlAffinity.leading,
);
},
),
],
);
}
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
return Center(
child: Container(
width: screenWidth - (screenWidth * 0.35),
height: screenWidth - (screenWidth * 0.1),
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
borderRadius: BorderRadius.circular(24.0),
),
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(10.0, 10.0, 0.0, 10.0),
child: Text(
FFLocalizations.of(context).getText('yfj9pd6k'),
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
fontSize: LimitedFontSizeUtil.getHeaderFontSize(context),
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts:
GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).headlineMediumFamily),
),
),
),
],
),
Expanded(
child: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: widget.filterOptions.keys.map((key) {
return _buildCheckboxListTile(key, widget.filterOptions[key]!, 14);
}).toList(),
),
),
),
),
ElevatedButton(
onPressed: _applyFilter,
style: ElevatedButton.styleFrom(
foregroundColor: FlutterFlowTheme.of(context).info,
backgroundColor: FlutterFlowTheme.of(context).primary,
),
child: Text(FFLocalizations.of(context).getText('88kshkph'),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
color: FlutterFlowTheme.of(context).info,
fontSize: LimitedFontSizeUtil.getInputFontSize(context),
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts:
GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily),
)),
),
],
),
),
),
);
}
}

View File

@ -1 +0,0 @@
export 'filter_modal.dart';

View File

@ -4,7 +4,6 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hub/backend/schema/util/schema_util.dart';
import 'package:hub/features/histories/presentation/pages/prov_schedule_page.dart';
import 'package:hub/features/home/index.dart';
import 'package:hub/features/property/index.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
@ -132,7 +131,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
FFRoute(name: 'petsOnThePropertyPage', path: '/petsOnThePropertyPage', builder: (context, params) => Scaffold(body: const PetsHistoryScreen(isApp: true))),
FFRoute(name: 'vehiclesOnThePropertyPage', path: '/vehiclesOnThePropertyPage', builder: (context, params) => const VehicleOnTheProperty()),
FFRoute(name: 'receptionPage', path: '/receptionPage', builder: (context, params) => const ReceptionPageWidget()),
FFRoute(name: 'messageHistoryPage', path: '/messageHistoryPage', builder: (context, params) => ProvisionalScheduleHistoryScreen(opt: const {'personType': '.*', 'accessType': '.*', 'search': '.*'})),
FFRoute(name: 'messageHistoryPage', path: '/messageHistoryPage', builder: (context, params) => const MessageHistoryPageWidget()),
FFRoute(name: 'registerVisitorPage', path: '/registerVisitorPage', builder: (context, params) => const RegisterVisitorPageWidget()),
FFRoute(name: 'scheduleCompleteVisitPage', path: '/scheduleCompleteVisitPage', builder: (context, params) => const ScheduleCompleteVisitPageWidget()),
FFRoute(name: 'deliverySchedule', path: '/deliverySchedule', builder: (context, params) => const DeliverySchedule()),