Adicionado um component de toast, tratado o erro de campo data vazio e ajustado as cores dos modais de datetimepicker

This commit is contained in:
Lucas 2024-08-19 12:07:38 -03:00
parent 981c718e41
commit 5b778d6523
8 changed files with 266 additions and 127 deletions

View File

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class ToastUtil {
static void showToast({
required String message,
ToastGravity gravity = ToastGravity.BOTTOM,
Toast toastLength = Toast.LENGTH_SHORT,
Color backgroundColor = Colors.black,
Color textColor = Colors.white,
double fontSize = 16.0,
}) {
Fluttertoast.showToast(
msg: message,
toastLength: toastLength,
gravity: gravity,
backgroundColor: backgroundColor,
textColor: textColor,
fontSize: fontSize,
);
}
}

View File

@ -2,6 +2,7 @@ import 'dart:developer';
import 'package:flutter/services.dart';
import 'package:hub/backend/api_requests/api_calls.dart';
import 'package:hub/components/atomic_components/shared_components_atoms/toast.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';
import 'package:hub/components/templates_components/visitor_search_modal_template_component/visitor_search_modal_template_component_model.dart';
@ -84,12 +85,12 @@ class _VisitorSearchModalTemplateComponentWidgetState
context.watch<FFAppState>();
return Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 20.0, 0.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 10.0, 0.0, 0.0),
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
decoration: const BoxDecoration(
color: Colors.transparent,
borderRadius: const BorderRadius.only(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(0.0),
bottomRight: Radius.circular(0.0),
topLeft: Radius.circular(15.0),
@ -110,7 +111,7 @@ class _VisitorSearchModalTemplateComponentWidgetState
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(16.0, 15.0, 16.0, 0.0),
const EdgeInsetsDirectional.fromSTEB(16.0, 25.0, 16.0, 0.0),
child: TextFormField(
controller: _model.textController,
focusNode: _model.textFieldFocusNode,
@ -488,7 +489,10 @@ class _VisitorSearchModalTemplateComponentWidgetState
_model.addToDocs(_model.textController.text);
safeSetState(() {});
} else if (existDoc == true) {
_showErrorSnackbar(context);
ToastUtil.showToast(
message: FFLocalizations.of(context).getVariableText(
ptText: 'Visitante já adicionado!',
enText: 'Visitor already added!'));
}
} else {
await showAdaptiveDialog(

View File

@ -182,6 +182,7 @@ Theme wrapInMaterialTimePickerTheme(
required Color headerForegroundColor,
required TextStyle headerTextStyle,
required Color pickerBackgroundColor,
required Color pickerDialForegroundColor,
required Color pickerForegroundColor,
required Color selectedDateTimeBackgroundColor,
required Color selectedDateTimeForegroundColor,
@ -263,7 +264,7 @@ Theme wrapInMaterialTimePickerTheme(
dialTextColor: WidgetStateColor.resolveWith((states) =>
states.contains(WidgetState.selected)
? selectedDateTimeForegroundColor
: pickerForegroundColor),
: pickerDialForegroundColor),
dayPeriodBorderSide: BorderSide(
color: pickerForegroundColor,
),

View File

@ -98,7 +98,7 @@ class ScheduleCompleteVisitPageModel
ptText: 'Este campo é obrigatório.',
);
}
if (val != null) {
if (val != '0') {
try {
DateTime startDate = DateFormat('d/M/y H:mm:ss').parse(val);
DateTime endDate =
@ -116,7 +116,9 @@ class ScheduleCompleteVisitPageModel
);
}
} catch (e) {
return '$e';
return FFLocalizations.of(context).getVariableText(
ptText: 'Preencha corretamente o campo de término da visita!',
enText: 'Fill in the end of visit field correctly!');
}
}
return null;
@ -136,9 +138,10 @@ class ScheduleCompleteVisitPageModel
}
if (val != null) {
try {
DateTime endDate = DateFormat('d/M/y H:mm:ss').parse(val);
DateTime endDate = DateFormat('dd/M/yyyy HH:mm:ss').parse(val);
DateTime startDate =
DateFormat('d/M/y H:mm:ss').parse(textController1!.text);
DateFormat('dd/MM/yyyy HH:mm:ss').parse(textController1!.text);
if (endDate.isBefore(startDate)) {
return FFLocalizations.of(context).getVariableText(
enText: 'End date must be after start date.',
@ -152,7 +155,9 @@ class ScheduleCompleteVisitPageModel
);
}
} catch (e) {
return '$e';
return FFLocalizations.of(context).getVariableText(
ptText: 'Preencha corretamente o campo de início da visita!',
enText: 'Fill in the visit start field correctly!');
}
}
return null;

View File

@ -64,7 +64,10 @@ class _ScheduleCompleteVisitPageWidgetState
// On page load action.
SchedulerBinding.instance.addPostFrameCallback((_) async {
if ((widget.visitorStrList != null && widget.visitorStrList != '') && ((widget.visitorJsonList != null && (widget.visitorJsonList)!.isNotEmpty) != null)) {
if ((widget.visitorStrList != null && widget.visitorStrList != '') &&
((widget.visitorJsonList != null &&
(widget.visitorJsonList)!.isNotEmpty) !=
null)) {
_model.visitorJsonList = widget.visitorJsonList!
.where((e) =>
widget.visitorStrList ==
@ -82,7 +85,8 @@ class _ScheduleCompleteVisitPageWidgetState
return;
}
if ((widget.dropdownValue1 != null && widget.dropdownValue1 != '') && (widget.dropdownValue2 != null && widget.dropdownValue2 != '')) {
if ((widget.dropdownValue1 != null && widget.dropdownValue1 != '') &&
(widget.dropdownValue2 != null && widget.dropdownValue2 != '')) {
_model.dropDownValue1 = widget.dropdownValue1!;
_model.dropDownValue2 = widget.dropdownValue2!;
safeSetState(() {});
@ -391,7 +395,7 @@ Widget scheduleVisit(BuildContext context,
.bodyMediumFamily),
lineHeight: 1.8,
),
textAlign: TextAlign.center,
textAlign: TextAlign.start,
validator: _model.textController1Validator
.asValidator(context)),
),
@ -486,13 +490,15 @@ Widget scheduleVisit(BuildContext context,
FlutterFlowTheme.of(context)
.primaryBackground,
pickerForegroundColor:
FlutterFlowTheme.of(context)
.primaryText,
FlutterFlowTheme.of(context).info,
selectedDateTimeBackgroundColor:
FlutterFlowTheme.of(context)
.primary,
selectedDateTimeForegroundColor:
FlutterFlowTheme.of(context).info,
pickerDialForegroundColor:
FlutterFlowTheme.of(context)
.primaryText,
actionButtonForegroundColor:
FlutterFlowTheme.of(context)
.primaryText,
@ -638,7 +644,7 @@ Widget scheduleVisit(BuildContext context,
.bodyMediumFamily),
lineHeight: 1.8,
),
textAlign: TextAlign.center,
textAlign: TextAlign.start,
validator: _model.textController2Validator
.asValidator(context),
),
@ -734,13 +740,15 @@ Widget scheduleVisit(BuildContext context,
FlutterFlowTheme.of(context)
.primaryBackground,
pickerForegroundColor:
FlutterFlowTheme.of(context)
.primaryText,
FlutterFlowTheme.of(context).info,
selectedDateTimeBackgroundColor:
FlutterFlowTheme.of(context)
.primary,
selectedDateTimeForegroundColor:
FlutterFlowTheme.of(context).info,
pickerDialForegroundColor:
FlutterFlowTheme.of(context)
.primaryText,
actionButtonForegroundColor:
FlutterFlowTheme.of(context)
.primaryText,
@ -1098,29 +1106,58 @@ Widget scheduleVisit(BuildContext context,
);
}
final dropDownGetDadosResponse = snapshot.data!;
final reasonsJsonList = PhpGroup.getDadosCall.reasonsJsonList(dropDownGetDadosResponse.jsonBody);
final dropDownGetDadosResponse =
snapshot.data!;
final reasonsJsonList =
PhpGroup.getDadosCall.reasonsJsonList(
dropDownGetDadosResponse.jsonBody);
if (_model.dropDownValue1 != '' && _model.dropDownValue1 != null) {
String value = _model.dropDownValue1.toString() ?? '';
if (_model.dropDownValue1 != '' &&
_model.dropDownValue1 != null) {
String value =
_model.dropDownValue1.toString() ??
'';
if (value.contains('{') && value.contains('}') && value.contains(':')) {
if (value.contains('{') &&
value.contains('}') &&
value.contains(':')) {
// log("Valor e um Objeto | Usuário Escolheu o Motivo ${_model.dropDownValue1}");
} else {
// log("Valor e uma String | Usuário Escolheu o Motivo ${_model.dropDownValue1}");
if (reasonsJsonList != null && reasonsJsonList.isNotEmpty) {
var item = reasonsJsonList.where((reason) => reason['MOT_DESCRICAO'].toString().contains(_model.dropDownValue1 ?? ''));
_model.dropDownValue1 = item.firstOrNull.toString() ?? '';
if (reasonsJsonList != null &&
reasonsJsonList.isNotEmpty) {
var item = reasonsJsonList.where(
(reason) =>
reason['MOT_DESCRICAO']
.toString()
.contains(_model
.dropDownValue1 ??
''));
_model.dropDownValue1 =
item.firstOrNull.toString() ?? '';
}
}
}
return FlutterFlowDropDown<String>(
fillColor: FlutterFlowTheme.of(context).primaryBackground,
controller: _model.dropDownValueController1 ??= FormFieldController<String>(_model.dropDownValue1 ??= ''),
options: reasonsJsonList != null && reasonsJsonList != [] ? reasonsJsonList.map((e) => e.toString()).toList() : [],
optionLabels: PhpGroup.getDadosCall.reasonsMotDescStrList(dropDownGetDadosResponse.jsonBody),
onChanged: (val) => safeSetState(() => _model.dropDownValue1 = val),
fillColor: FlutterFlowTheme.of(context)
.primaryBackground,
controller:
_model.dropDownValueController1 ??=
FormFieldController<String>(
_model.dropDownValue1 ??= ''),
options: reasonsJsonList != null &&
reasonsJsonList != []
? reasonsJsonList
.map((e) => e.toString())
.toList()
: [],
optionLabels: PhpGroup.getDadosCall
.reasonsMotDescStrList(
dropDownGetDadosResponse
.jsonBody),
onChanged: (val) => safeSetState(
() => _model.dropDownValue1 = val),
width: double.infinity,
height: double.infinity,
textStyle: FlutterFlowTheme.of(context)
@ -1223,28 +1260,55 @@ Widget scheduleVisit(BuildContext context,
);
}
final dropDownGetDadosResponse = snapshot.data!;
final lavelList = PhpGroup.getDadosCall.levelJsonList(dropDownGetDadosResponse.jsonBody);
final dropDownGetDadosResponse =
snapshot.data!;
final lavelList = PhpGroup.getDadosCall
.levelJsonList(
dropDownGetDadosResponse.jsonBody);
if (_model.dropDownValue2 != '' && _model.dropDownValue2 != null) {
String value = _model.dropDownValue2.toString() ?? '';
if (_model.dropDownValue2 != '' &&
_model.dropDownValue2 != null) {
String value =
_model.dropDownValue2.toString() ??
'';
if (value.contains('{') && value.contains('}') && value.contains(':')) {
if (value.contains('{') &&
value.contains('}') &&
value.contains(':')) {
// log("Valor e um Objeto | Usuário Escolheu o Nivel ${_model.dropDownValue2}");
} else {
// log("Valor e uma String | Usuário Escolheu o Nivel ${_model.dropDownValue2}");
if (lavelList != null && lavelList.isNotEmpty) {
var item = lavelList.where((level) => level['NAC_DESCRICAO'].toString().contains(_model.dropDownValue2 ?? ''));
_model.dropDownValue2 = item.firstOrNull.toString() ?? '';
if (lavelList != null &&
lavelList.isNotEmpty) {
var item = lavelList.where((level) =>
level['NAC_DESCRICAO']
.toString()
.contains(
_model.dropDownValue2 ??
''));
_model.dropDownValue2 =
item.firstOrNull.toString() ?? '';
}
}
}
return FlutterFlowDropDown<String>(
controller: _model.dropDownValueController2 ??= FormFieldController<String>(_model.dropDownValue2 ??= ''),
options: lavelList != null && lavelList != [] ? lavelList.map((e) => e.toString()).toList() : [],
optionLabels: PhpGroup.getDadosCall.levelNACDescricaoStrList(dropDownGetDadosResponse.jsonBody),
onChanged: (val) => safeSetState(() => _model.dropDownValue2 = val),
controller:
_model.dropDownValueController2 ??=
FormFieldController<String>(
_model.dropDownValue2 ??= ''),
options:
lavelList != null && lavelList != []
? lavelList
.map((e) => e.toString())
.toList()
: [],
optionLabels: PhpGroup.getDadosCall
.levelNACDescricaoStrList(
dropDownGetDadosResponse
.jsonBody),
onChanged: (val) => safeSetState(
() => _model.dropDownValue2 = val),
width: double.infinity,
height: double.infinity,
textStyle: FlutterFlowTheme.of(context)
@ -1552,7 +1616,6 @@ Widget scheduleVisit(BuildContext context,
),
onPressed: _model.isValid()
? () async {
await showDialog(
context: context,
builder: (context) {

View File

@ -17,7 +17,6 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:hub/pages/schedule_provisional_visit_page/schedule_provisional_visit_page_model.dart';
import 'package:provider/provider.dart';
class ScheduleProvisionalVisitPageWidget extends StatefulWidget {
const ScheduleProvisionalVisitPageWidget({super.key});
@ -55,7 +54,8 @@ class _ScheduleProvisionalVisitPageWidgetState
}
bool _isFormValid() {
if (_model.personNameTextController.text == '' || _model.personNameTextController.text.length > 80) {
if (_model.personNameTextController.text == '' ||
_model.personNameTextController.text.length > 80) {
return false;
}
@ -161,10 +161,12 @@ class _ScheduleProvisionalVisitPageWidgetState
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Align(
alignment: const AlignmentDirectional(-1.0, 0.0),
alignment:
const AlignmentDirectional(-1.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 0.0, 0.0),
padding:
const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 0.0, 0.0),
child: Text(
FFLocalizations.of(context).getText(
'8d3679lf' /* Propriedade */,
@ -210,7 +212,8 @@ class _ScheduleProvisionalVisitPageWidgetState
MainAxisAlignment.start,
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
borderRadius:
const BorderRadius.only(
bottomLeft: Radius.circular(50.0),
bottomRight:
Radius.circular(50.0),
@ -218,10 +221,10 @@ class _ScheduleProvisionalVisitPageWidgetState
topRight: Radius.circular(50.0),
),
child: CachedNetworkImage(
fadeInDuration:
const Duration(milliseconds: 200),
fadeOutDuration:
const Duration(milliseconds: 200),
fadeInDuration: const Duration(
milliseconds: 200),
fadeOutDuration: const Duration(
milliseconds: 200),
imageUrl:
'https://freaccess.com.br/freaccess/Images/Clients/${FFAppState().cliUUID}.png',
width: 35.0,
@ -232,9 +235,8 @@ class _ScheduleProvisionalVisitPageWidgetState
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(
15.0, 0.0, 0.0, 0.0),
padding: const EdgeInsetsDirectional
.fromSTEB(15.0, 0.0, 0.0, 0.0),
child: Text(
FFAppState().local,
style:
@ -272,10 +274,12 @@ class _ScheduleProvisionalVisitPageWidgetState
MainAxisAlignment.spaceEvenly,
children: [
Align(
alignment: const AlignmentDirectional(-1.0, 0.0),
alignment:
const AlignmentDirectional(-1.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 10.0, 0.0, 10.0),
padding:
const EdgeInsetsDirectional.fromSTEB(
24.0, 10.0, 0.0, 10.0),
child: Text(
FFLocalizations.of(context).getText(
'z6aawgqa' /* Dados da Visita */,
@ -303,12 +307,11 @@ class _ScheduleProvisionalVisitPageWidgetState
Container(
height: 80.0,
decoration: const BoxDecoration(),
alignment:
const AlignmentDirectional(0.0, 0.0),
alignment: const AlignmentDirectional(
0.0, 0.0),
child: Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
padding: const EdgeInsetsDirectional
.fromSTEB(24.0, 0.0, 24.0, 0.0),
child: SizedBox(
width: double.infinity,
child: TextFormField(
@ -319,7 +322,8 @@ class _ScheduleProvisionalVisitPageWidgetState
onChanged: (_) =>
EasyDebounce.debounce(
'_model.personNameTextController',
const Duration(milliseconds: 500),
const Duration(
milliseconds: 500),
() => setState(() {}),
),
autofocus: false,
@ -463,12 +467,13 @@ class _ScheduleProvisionalVisitPageWidgetState
SizedBox(
height: 80.0,
child: Stack(
alignment:
const AlignmentDirectional(0.0, 0.0),
alignment: const AlignmentDirectional(
0.0, 0.0),
children: [
Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(
padding:
const EdgeInsetsDirectional
.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: TextFormField(
controller: _model
@ -478,7 +483,8 @@ class _ScheduleProvisionalVisitPageWidgetState
onChanged: (_) =>
EasyDebounce.debounce(
'_model.dateTimeTextController',
const Duration(milliseconds: 500),
const Duration(
milliseconds: 500),
() => setState(() {}),
),
readOnly: true,
@ -590,8 +596,9 @@ class _ScheduleProvisionalVisitPageWidgetState
),
),
Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(
padding:
const EdgeInsetsDirectional
.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: InkWell(
splashColor: Colors.transparent,
@ -715,11 +722,15 @@ class _ScheduleProvisionalVisitPageWidgetState
pickerForegroundColor:
FlutterFlowTheme.of(
context)
.primaryText,
.info,
selectedDateTimeBackgroundColor:
FlutterFlowTheme.of(
context)
.primary,
pickerDialForegroundColor:
FlutterFlowTheme.of(
context)
.primaryText,
selectedDateTimeForegroundColor:
FlutterFlowTheme.of(
context)
@ -787,24 +798,28 @@ class _ScheduleProvisionalVisitPageWidgetState
],
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0.0, 10.0, 0.0, 10.0),
padding:
const EdgeInsetsDirectional.fromSTEB(
0.0, 10.0, 0.0, 10.0),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Align(
alignment:
const AlignmentDirectional(0.0, 0.0),
alignment: const AlignmentDirectional(
0.0, 0.0),
child: Container(
decoration: const BoxDecoration(),
alignment:
const AlignmentDirectional(0.0, 0.0),
const AlignmentDirectional(
0.0, 0.0),
child: Align(
alignment: const AlignmentDirectional(
0.0, 0.0),
alignment:
const AlignmentDirectional(
0.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(
padding:
const EdgeInsetsDirectional
.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: SizedBox(
width: double.infinity,
@ -961,51 +976,71 @@ class _ScheduleProvisionalVisitPageWidgetState
),
),
FFButtonWidget(
onPressed: !_isFormValid() ? null : () async {
onPressed: !_isFormValid()
? null
: () async {
try {
_model.provVisitSchedule = await PhpGroup
.postProvVisitSchedulingCall
.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'putAgendamentoProv',
data:
_model.dateTimeTextController.text,
motivo: _model.notesTextController.text,
nome: _model
.personNameTextController.text,
proID: FFAppState().ownerUUID,
);
try {
_model.provVisitSchedule = await PhpGroup.postProvVisitSchedulingCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'putAgendamentoProv',
data: _model.dateTimeTextController.text,
motivo: _model.notesTextController.text,
nome: _model.personNameTextController.text,
proID: FFAppState().ownerUUID,
);
if (PhpGroup.postProvVisitSchedulingCall
.error((_model.provVisitSchedule
?.jsonBody ??
'')) ==
false) {
DialogUtil.success(
context,
FFLocalizations.of(context).getVariableText(
ptText:
"Agendamento Provisório Realizado com Sucesso!",
enText:
"Provisional Scheduling Successfully Completed"));
setState(() {
_model.dateTimeTextController
?.clear();
_model.personNameTextController
?.clear();
_model.notesTextController?.clear();
});
} else {
var message = PhpGroup
.postProvVisitSchedulingCall
.msg((_model.provVisitSchedule
?.jsonBody ??
''));
if (message != null) {
DialogUtil.error(context, message);
} else {
DialogUtil.errorDefault(context);
}
}
if (PhpGroup.postProvVisitSchedulingCall.error((_model.provVisitSchedule?.jsonBody ?? '')) == false) {
DialogUtil.success(
context,
FFLocalizations.of(context).getVariableText(
ptText: "Agendamento Provisório Realizado com Sucesso!",
enText: "Provisional Scheduling Successfully Completed"
)
);
setState(() {
_model.dateTimeTextController?.clear();
_model.personNameTextController?.clear();
_model.notesTextController?.clear();
});
} else {
var message = PhpGroup.postProvVisitSchedulingCall.msg((_model.provVisitSchedule?.jsonBody ?? ''));
if (message != null) {
DialogUtil.error(context, message);
} else {
DialogUtil.errorDefault(context);
}
}
setState(() {});
} catch (e, s) {
DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed("processRequest.php", "", "Cadastrar Visita Provisória", e, s);
}
},
setState(() {});
} catch (e, s) {
DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed(
"processRequest.php",
"",
"Cadastrar Visita Provisória",
e,
s);
}
},
showLoadingIndicator: true,
text: FFLocalizations.of(context).getText('bv5fg9sv' /* Enviar */),
text: FFLocalizations.of(context)
.getText('bv5fg9sv' /* Enviar */),
options: FFButtonOptions(
width: 150.0,
height: 50.0,

View File

@ -653,6 +653,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
fluttertoast:
dependency: "direct main"
description:
name: fluttertoast
sha256: "95f349437aeebe524ef7d6c9bde3e6b4772717cf46a0eb6a3ceaddc740b297cc"
url: "https://pub.dev"
source: hosted
version: "8.2.8"
font_awesome_flutter:
dependency: "direct main"
description:

View File

@ -108,6 +108,7 @@ dependencies:
qr_flutter: ^4.1.0
permission_handler: ^11.3.1
firebase_crashlytics: ^4.0.1
fluttertoast: ^8.2.8
dependency_overrides:
http: 1.2.1