fet: Adicionado Encomendas

This commit is contained in:
Ivan Antunes 2024-08-23 17:01:23 -03:00
parent a98d5edfbf
commit f883326f79
11 changed files with 925 additions and 202 deletions

View File

@ -16,7 +16,7 @@ const _kPrivateApiFunctionName = 'ffPrivateApiCall';
class PhpGroup {
static String getBaseUrl() => 'https://freaccess.com.br/freaccess';
// static String getBaseUrl() => 'http://192.168.2.250:8080';
// static String getBaseUrl() => 'http://192.168.2.204:8080';
static Map<String, String> headers = {};
static LoginCall loginCall = LoginCall();
static UpdToken updToken = UpdToken();
@ -49,6 +49,55 @@ class PhpGroup {
static ChangePanic changePanic = ChangePanic();
static DeleteAccount deleteAccount = DeleteAccount();
static CancelaVisita cancelaVisita = CancelaVisita();
static BuscaEnconcomendas buscaEnconcomendas = BuscaEnconcomendas();
}
class BuscaEnconcomendas {
Future<ApiCallResponse> call({
String? devUUID = '',
String? userUUID = '',
String? cliID = '',
String? atividade = '',
String? page = '',
String? pageSize = '',
String? adresseeType = '',
String? status = '',
}) async {
final baseUrl = PhpGroup.getBaseUrl();
return ApiManager.instance.makeApiCall(
callName: 'getEncomendas',
apiUrl: '$baseUrl/processRequest.php',
callType: ApiCallType.POST,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
params: {
'devUUID': devUUID,
'userUUID': userUUID,
'atividade': atividade,
'cliID': cliID,
'page': page,
'pageSize': pageSize,
'adresseeType': adresseeType,
'status': status,
},
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
alwaysAllowBody: false,
);
}
bool? error(dynamic response) => castToType<bool>(getJsonField(
response,
r'''$.error''',
));
}
class CancelaVisita {

View File

@ -85,8 +85,7 @@ class _OptModalWidgetState extends State<OptModalWidget> {
Navigator.pop(context, filterResult);
}
Widget _buildCheckboxListTile(
String key, List<Map<String, String>> options, double fontsize) {
Widget _buildCheckboxListTile(String key, List<Map<String, String>> options, double fontsize) {
return Column(
children: [
Row(
@ -152,8 +151,7 @@ class _OptModalWidgetState extends State<OptModalWidget> {
width: 5,
color: FlutterFlowTheme.of(context).secondaryText,
),
controlAffinity:
ListTileControlAffinity.leading, // Adiciona esta linha
controlAffinity: ListTileControlAffinity.leading, // Adiciona esta linha
);
},
),
@ -182,8 +180,8 @@ class _OptModalWidgetState extends State<OptModalWidget> {
return Center(
child: Container(
width: screenWidth * 0.75,
height: screenHeight * 0.35,
width: screenWidth - (screenWidth * 0.35),
height: 250,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
borderRadius: BorderRadius.circular(24.0),

View File

@ -0,0 +1,32 @@
import '/flutter_flow/flutter_flow_util.dart';
import '/flutter_flow/form_field_controller.dart';
import 'order_filter_modal_widget.dart' show OrderFilterModalWidget;
import 'package:flutter/material.dart';
class OrderFilterModalModel extends FlutterFlowModel<OrderFilterModalWidget> {
// State field(s) for TextField widget.
FocusNode? textFieldFocusNode;
TextEditingController? textController;
String? Function(BuildContext, String?)? textControllerValidator;
// State field(s) for Checkbox widget.
bool? checkboxValue1;
// State field(s) for Checkbox widget.
bool? checkboxValue2;
// State field(s) for CheckboxGroup widget.
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();
}
}

View File

@ -0,0 +1,223 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hub/components/molecular_components/order_filter_modal/order_filter_modal_model.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';
class OrderFilterModalWidget extends StatefulWidget {
final String defaultAdresseeType;
final String defaultStatus;
const OrderFilterModalWidget({
Key? key,
this.defaultAdresseeType = '.*',
this.defaultStatus = '.*',
}) : super(key: key);
@override
_OrderFilterModalWidgetState createState() => _OrderFilterModalWidgetState();
}
class _OrderFilterModalWidgetState extends State<OrderFilterModalWidget> {
late OrderFilterModalModel _model;
late Map<String, dynamic> selected;
final List<Map<String, String>> adresseeTypeOptions = [
{'title': 'Morador', 'value': 'MOR'},
{'title': 'Propriedade', 'value': 'PRO'},
];
final List<Map<String, String>> statusOptions = [
{'title': 'Aguardando Retirada', 'value': 'notPickedUp'},
{'title': 'Retirado', 'value': 'pickedUp'},
];
@override
void setState(VoidCallback callback) {
super.setState(callback);
_model.onUpdate();
}
@override
void initState() {
super.initState();
_model = createModel(context, () => OrderFilterModalModel());
selected = {
'adresseeType': widget.defaultAdresseeType == '.*' ? ['MOR', 'PRO'] : [widget.defaultAdresseeType],
'status': widget.defaultStatus == '.*' ? ['notPickedUp', 'pickedUp'] : [widget.defaultStatus],
};
}
void _applyFilter() {
Map<String, String> filterResult = {
'adresseeType': '',
'status': '',
};
if (selected['adresseeType']!.isEmpty) {
filterResult['adresseeType'] = '.*';
} else if (selected['adresseeType']!.length > 1) {
filterResult['adresseeType'] = '.*';
} else {
filterResult['adresseeType'] = selected['adresseeType']!.first;
}
if (selected['status']!.isEmpty) {
filterResult['status'] = '.*';
} else if (selected['status']!.length > 1) {
filterResult['status'] = '.*';
} else {
filterResult['status'] = selected['status']!.first;
}
Navigator.pop(context, filterResult);
}
Widget _buildCheckboxListTile(String key, List<Map<String, String>> options, double fontsize) {
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(
key == 'status' ? 'Status' : 'Destinátario',
textAlign: TextAlign.left,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
fontSize: fontsize,
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: fontsize,
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]!.add(option['value']);
}
} else {
selected[key]!.remove(option['value']);
}
});
},
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, // Adiciona esta linha
);
},
),
],
);
}
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
return Center(
child: Container(
width: screenWidth - (screenWidth * 0.35),
height: 420,
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'), // Filtros
style:
FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: FlutterFlowTheme.of(context)
.headlineMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 18.0,
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: [
_buildCheckboxListTile('adresseeType', adresseeTypeOptions, 14),
_buildCheckboxListTile('status', statusOptions, 14),
],
),
),
),
),
ElevatedButton(
onPressed: _applyFilter,
style: ElevatedButton.styleFrom(
foregroundColor: FlutterFlowTheme.of(context).info,
backgroundColor: FlutterFlowTheme.of(context).primary,
),
child: Text(FFLocalizations.of(context).getText('88kshkph')),
),
],
),
),
),
);
}
}

View File

@ -150,6 +150,19 @@ class MenuComponentModel extends FlutterFlowModel<MenuComponentWidget> {
).then((value) => true);
}
Future packageOrder(BuildContext context) async {
context.pushNamed(
'packageOrder',
extra: <String, dynamic>{
kTransitionInfoKey: const TransitionInfo(
hasTransition: true,
transitionType: PageTransitionType.scale,
alignment: Alignment.bottomCenter,
),
},
).then((value) => true);
}
Future liberationHistoryOptAction(BuildContext context) async {
await showAdaptiveDialog(
// isScrollControlled: true,

View File

@ -111,6 +111,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
ptText: 'Consultar\nHistóricos',
),
),
MenuButtonWidget(
icon: Icons.inventory_2_rounded,
action: () async {
await _model.packageOrder(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Orders',
ptText: 'Encomendas',
),
),
MenuButtonWidget(
icon: Icons.settings,
action: () async {
@ -122,6 +133,7 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
ptText: 'Preferências \nde Configurações',
),
),
];
}
if (widget.item == MenuItem.card) {
@ -181,6 +193,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
ptText: 'Consultar\nHistoricos',
),
),
MenuCardItem(
icon: Icons.inventory_2_rounded,
action: () async {
await _model.packageOrder(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Orders',
ptText: 'Encomendas',
),
),
MenuCardItem(
icon: Icons.settings,
action: () async {
@ -262,6 +285,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
ptText: 'Sair da Conta',
),
),
MenuCardItem(
icon: Icons.inventory_2_rounded,
action: () async {
await _model.packageOrder(context);
setState(() {});
},
title: FFLocalizations.of(context).getVariableText(
enText: 'Orders',
ptText: 'Encomendas',
),
),
MenuCardItem(
icon: Icons.settings,
action: () async {

View File

@ -2,6 +2,7 @@ import 'dart:collection';
import 'dart:developer';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
@ -29,20 +30,13 @@ class CardItemTemplateComponentWidget extends StatefulWidget {
final Future Function()? onTapCardItemAction;
@override
State<CardItemTemplateComponentWidget> createState() =>
_CardItemTemplateComponentWidgetState();
State<CardItemTemplateComponentWidget> createState() => _CardItemTemplateComponentWidgetState();
}
class _CardItemTemplateComponentWidgetState
extends State<CardItemTemplateComponentWidget> {
class _CardItemTemplateComponentWidgetState extends State<CardItemTemplateComponentWidget> {
late CardItemTemplateComponentModel _model;
LinkedHashMap<String, String> get labelsLinkedHashMap =>
LinkedHashMap.from(widget.labelsHashMap ?? {});
List<LinkedHashMap<String, Color>> get statusLinkedHashMap =>
widget.statusHashMap
.map((map) => LinkedHashMap<String, Color>.from(map ?? {}))
.toList();
LinkedHashMap<String, String> get labelsLinkedHashMap => LinkedHashMap.from(widget.labelsHashMap ?? {});
List<LinkedHashMap<String, Color>> get statusLinkedHashMap => widget.statusHashMap.map((map) => LinkedHashMap<String, Color>.from(map ?? {})).toList();
@override
void setState(VoidCallback callback) {
@ -58,42 +52,165 @@ class _CardItemTemplateComponentWidgetState
@override
void dispose() {
_model.maybeDispose();
super.dispose();
_model.maybeDispose();
}
Color _getColorForStatus(String status) {
if (status.length % 3 == 0) {
return FlutterFlowTheme.of(context).success;
} else if (status.length % 3 == 1) {
return FlutterFlowTheme.of(context).error;
} else {
return FlutterFlowTheme.of(context).primary;
String truncate(int cutoff, String text) {
return (text.length <= cutoff) ? text : '${text.substring(0, cutoff)}...';
}
List<Widget> _generateLabels() {
List<Widget> labels = [];
for (var key in labelsLinkedHashMap.keys) {
String text = labelsLinkedHashMap[key].toString();
Widget widget = Row(
children: [
Text(
key,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily),
color: FlutterFlowTheme.of(context).primaryText,
),
),
const SizedBox(width: 2.5),
Text(
text,
overflow: TextOverflow.ellipsis,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
fontSize: 12.5,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily),
),
)
],
);
labels.add(widget);
}
return labels;
}
String truncate(int cutoff, String mytext) {
return (mytext.length <= cutoff)
? mytext
: '${mytext.substring(0, cutoff)}...';
Widget _generateImage() {
return Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: CachedNetworkImage(
fadeInDuration: const Duration(milliseconds: 500),
fadeOutDuration: const Duration(milliseconds: 500),
imageUrl: widget.imagePath ?? '',
fit: BoxFit.cover,
),
),
);
}
List<Widget> _generateStatus() {
List<Widget> status = [];
statusLinkedHashMap.expand((statusLinked) {
statusLinked.forEach((text, color) {
Widget widget = Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(5)
),
child: Text(
text,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: FlutterFlowTheme.of(context).info,
fontSize: 12,
fontWeight: FontWeight.bold
),
),
);
status.add(widget);
});
return [];
}).toList();
return status;
}
Widget _smallScreen() {
return Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_generateImage(),
const SizedBox(height: 5),
Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
..._generateLabels(),
const SizedBox(height: 5),
Wrap(
spacing: 8,
runSpacing: 8,
children: _generateStatus(),
)
]
),
],
);
}
Widget _largeScreen() {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
..._generateLabels(),
const SizedBox(height: 5),
Wrap(
spacing: 8,
runSpacing: 8,
children: _generateStatus(),
)
]
),
_generateImage()
],
);
}
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
context.watch<AppState>();
return InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () async {
await widget.onTapCardItemAction?.call();
},
onTap: () async => await widget.onTapCardItemAction?.call(),
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
padding: const EdgeInsets.all(8),
child: Card(
clipBehavior: Clip.antiAliasWithSaveLayer,
color: FlutterFlowTheme.of(context).primaryBackground,
@ -102,158 +219,16 @@ class _CardItemTemplateComponentWidgetState
borderRadius: BorderRadius.circular(8.0),
),
child: Container(
width: 350,
height: 125,
width: double.infinity,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).primaryBackground,
),
child: Row(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: const BoxDecoration(),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: labelsLinkedHashMap.length,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
String key =
labelsLinkedHashMap.keys.elementAt(index);
String value = labelsLinkedHashMap[key]!;
return Padding(
padding:
const EdgeInsets.fromLTRB(20, 0, 0, 5),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
key,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(context)
.bodyMediumFamily,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
color:
FlutterFlowTheme.of(context)
.primaryText,
),
),
const SizedBox(width: 3.0), // Espaçamento entre o label e o valor
Flexible(
child: Text(
value,
overflow: TextOverflow.ellipsis,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily:
FlutterFlowTheme.of(
context)
.bodyMediumFamily,
fontSize: 12.5,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyMediumFamily),
),
),
),
],
),
);
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children:
statusLinkedHashMap.expand((linkedHashMap) {
return linkedHashMap.entries
.map((MapEntry<String, Color> item) {
return Container(
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 1.0, vertical: 3.0),
child: Container(
width: 100.0,
height: 27.0,
decoration: BoxDecoration(
color: item
.value, // Usa a cor do item atual
borderRadius:
BorderRadius.circular(5.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
item.key, // Usa a chave do item atual como texto
style: TextStyle(
color: FlutterFlowTheme.of(
context)
.info, // Ajuste conforme necessário
),
),
),
),
),
],
),
);
}).toList();
}).toList(),
),
]),
),
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
10.0, 10.0, 10.0, 10.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(22.0),
child: AspectRatio(
aspectRatio:
1.0, // Define a proporção desejada (1:1 neste caso)
child: CachedNetworkImage(
fadeInDuration: const Duration(milliseconds: 500),
fadeOutDuration: const Duration(milliseconds: 500),
imageUrl: widget.imagePath ?? '',
fit: BoxFit.cover,
),
),
),
)
screenWidth > 360 ? _largeScreen() : _smallScreen(),
],
),
),

View File

@ -5,6 +5,7 @@ import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/pages/fast_pass_page/fast_pass_page_widget.dart';
import 'package:hub/pages/message_history_page/message_history_page_widget.dart';
import 'package:hub/pages/no_connection_page/no_connection_page.dart';
import 'package:hub/pages/package_order_page/package_order_page.dart';
import 'package:provider/provider.dart';
import '/backend/schema/structs/index.dart';
@ -171,6 +172,11 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
path: '/preferencesPage',
builder: (context, params) => const PreferencesPageWidget(),
),
FFRoute(
name: 'packageOrder',
path: '/packageOrder',
builder: (context, params) => const PackageOrderPage(),
),
// FFRoute(
// name: 'settingsPage',
// path: '/settingsPage',

View File

@ -30,23 +30,7 @@ class AcessHistoryPageWidget extends StatefulWidget {
};
AcessHistoryPageWidget({super.key, required this.opt});
@override
State<AcessHistoryPageWidget> createState() =>
_AcessHistoryPageWidgetState(opt);
}
class AccessHistoryItemWidget extends StatelessWidget {
final dynamic accessHistoryItem;
const AccessHistoryItemWidget({Key? key, required this.accessHistoryItem})
: super(key: key);
@override
Widget build(BuildContext context) {
return const Padding(
padding: EdgeInsets.all(8.0),
child: Column(),
);
}
State<AcessHistoryPageWidget> createState() => _AcessHistoryPageWidgetState(opt);
}
class _AcessHistoryPageWidgetState extends State<AcessHistoryPageWidget> {
@ -66,8 +50,7 @@ class _AcessHistoryPageWidgetState extends State<AcessHistoryPageWidget> {
late Future<void> _accessFuture;
List<dynamic> _accessWrap = [];
_AcessHistoryPageWidgetState(Map<String, String> opt)
: selectedTypeSubject = BehaviorSubject.seeded(opt) {
_AcessHistoryPageWidgetState(Map<String, String> opt) : selectedTypeSubject = BehaviorSubject.seeded(opt) {
selectedTypeSubject.listen((value) {});
}

View File

@ -0,0 +1,410 @@
import 'dart:async';
import 'dart:developer';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.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/order_filter_modal/order_filter_modal_widget.dart';
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart';
import 'package:hub/components/templates_components/details_component/details_component_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/log_util.dart';
import 'package:hub/shared/utils/validator_util.dart';
import 'package:rxdart/rxdart.dart';
class PackageOrderPage extends StatefulWidget {
const PackageOrderPage({super.key});
@override
State<PackageOrderPage> createState() => _PackageOrderPage();
}
class _PackageOrderPage extends State<PackageOrderPage> {
late ScrollController _scrollController;
int _pageNumber = 1;
final int _pageSize = 10;
bool _hasData = false;
bool _loading = false;
late Future<void> _orderFuture;
List<dynamic> _orderList = [];
final Map<String, String> filter = {
'adresseeType': '.*',
'status': 'notPickedUp',
};
String _adresseeType = '.*';
String _status = 'notPickedUp';
late BehaviorSubject<Map<String, String>> _selectedTypeSubject;
bool _isSubjectClosed = false;
@override
void initState() {
super.initState();
_selectedTypeSubject = BehaviorSubject.seeded(filter);
_selectedTypeSubject.listen((value) {});
_orderFuture = _fetchOrders();
_scrollController = ScrollController()..addListener(() {
if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) {
_loadMoreOrders();
}
});
}
@override
void dispose() {
super.dispose();
_selectedTypeSubject.close();
_isSubjectClosed = true;
_scrollController.dispose();
}
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,
),
);
}
Future<ApiCallResponse?> _fetchOrders() async {
try {
setState(() => _loading = true);
var response = await PhpGroup.buscaEnconcomendas.call(
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliID: AppState().cliUUID,
atividade: 'getEncomendas',
pageSize: _pageSize.toString(),
page: _pageNumber.toString(),
adresseeType: _adresseeType == '.*' ? 'TOD' : _adresseeType,
status: _status == '.*' ? 'all' : _status
);
final List<dynamic> orders = response.jsonBody['value']['list'] ?? [];
if (orders != null && orders.isNotEmpty) {
setState(() {
_orderList.addAll(orders);
_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 Encomendas", e, s);
setState(() {
_hasData = false;
_loading = false;
});
}
}
void _loadMoreOrders() {
if (_hasData == true) {
_pageNumber++;
_orderFuture = _fetchOrders();
}
}
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 _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: OrderFilterModalWidget(
defaultAdresseeType: _selectedTypeSubject.value['adresseeType'] ?? '.*',
defaultStatus: _selectedTypeSubject.value['status'] ?? '.*',
),
),
),
);
});
if (selectedFilter != null) {
_updateFilterAction(selectedFilter);
}
},
),
),
],
);
}
void _updateFilterAction(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);
_fetchFilterOrder(updatedType);
safeSetState(() {});
}
}
}
void _fetchFilterOrder(Map<String, String> select) {
_adresseeType = select['adresseeType']!;
_status = select['status']!;
_orderList = [];
_pageNumber = 1;
_orderFuture = _fetchOrders();
}
PreferredSizeWidget _appBar(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
return AppBar(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
automaticallyImplyLeading: false,
title: Text(
FFLocalizations.of(context).getVariableText(enText: 'Orders', ptText: 'Encomendas'),
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'),
)
),
leading: _backButton(context, FlutterFlowTheme.of(context)),
centerTitle: true,
elevation: 0.0,
actions: [_filterButton(context)],
);
}
Widget _appBody(BuildContext context) {
return SafeArea(
top: true,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
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: "Nenhuma encomenda encontrada!",
enText: "No orders found!"),
)),
],
),
)
else if (_hasData || _pageNumber >= 1)
Expanded(child: _itemList()),
if (_hasData == true && _loading == true)
Container(
padding: const EdgeInsets.only(top: 15, bottom: 15),
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
FlutterFlowTheme.of(context).primary,
),
),
),
)
],
),
);
}
Widget _itemList() {
return FutureBuilder<void>(
future: _orderFuture,
builder: (context, snapshot) {
return ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
controller: _scrollController,
itemCount: _orderList.length,
itemBuilder: (context, index) {
final order = _orderList[index];
return _item(context, order);
},
);
}
);
}
String _imagePath(dynamic order) {
return '${PhpGroup.getBaseUrl()}/getImage.php?cliID=${AppState().cliUUID}&atividade=getFotoEncomenda&orderId=${order['id'] ?? ''}';
}
Map<String, String> _labelsHashMap(dynamic order) {
return Map<String, String>.from({
if (order['isPending'] == true)
'${FFLocalizations.of(context).getVariableText(ptText: 'Cód. Retirada', enText: 'Pickup Code')}:': order['id'].toString(),
'${FFLocalizations.of(context).getVariableText(ptText: 'Categoria', enText: 'Category')}:': order['customCategory'],
'${FFLocalizations.of(context).getVariableText(ptText: 'Recebido em', enText: 'Received on')}:': ValidatorUtil.toLocalDateTime('yyyy-MM-dd HH:mm:ss', order['dtReceive']),
if (order['isPending'] == false)
'${FFLocalizations.of(context).getVariableText(ptText: 'Retirado em', enText: 'Picked up on')}:': ValidatorUtil.toLocalDateTime('yyyy-MM-dd HH:mm:ss', order['dtPickUp']),
});
}
Map<String, String> _labelsHashMapDialog(dynamic order) {
return Map<String, String>.from({
if (order['isPending'] == true)
'${FFLocalizations.of(context).getVariableText(ptText: 'Cód. Retirada', enText: 'Pickup Code')}:': order['id'].toString(),
'${FFLocalizations.of(context).getVariableText(ptText: 'Categoria', enText: 'Category')}:': order['customCategory'],
if (order['code'] != null)
'${FFLocalizations.of(context).getVariableText(ptText: 'Cód. Objeto', enText: 'Object Code')}:': order['code'],
'${FFLocalizations.of(context).getVariableText(ptText: 'Entregue por', enText: 'Delivered by')}:': order['sendedBy'],
'${FFLocalizations.of(context).getVariableText(ptText: 'Recebido por', enText: 'Received by')}:': order['receivedBy'],
'${FFLocalizations.of(context).getVariableText(ptText: 'Recebido em', enText: 'Received on')}:': ValidatorUtil.toLocalDateTime('yyyy-MM-dd HH:mm:ss', order['dtReceive']),
if (order['isPending'] == false)
'${FFLocalizations.of(context).getVariableText(ptText: 'Retirado por', enText: 'Picked up by')}:': order['pickedUpBy'],
if (order['isPending'] == false)
'${FFLocalizations.of(context).getVariableText(ptText: 'Retirado em', enText: 'Picked up on')}:': ValidatorUtil.toLocalDateTime('yyyy-MM-dd HH:mm:ss', order['dtPickUp']),
if (order['message'] != null)
'${FFLocalizations.of(context).getVariableText(ptText: 'Mensagem', enText: 'Message')}:': order['message']
});
}
List<Map<String, Color>> _statusHashMap(dynamic order) {
return [
if (order['isPending'] == true)
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(ptText: 'Aguardando Retirada', enText: 'Waiting Pick up'): FlutterFlowTheme.of(context).warning,
})
else
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(ptText: 'Retirado', enText: 'Picked up'): FlutterFlowTheme.of(context).primary,
}),
if (order['adresseeType'] == 'PRO')
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Propriedade',
enText: 'Property',
): FlutterFlowTheme.of(context).alternate2,
})
else if (order['adresseeType'] == 'MOR')
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(
ptText: 'Morador',
enText: 'Resident',
): FlutterFlowTheme.of(context).alternate2,
})
];
}
Widget _item(BuildContext context, dynamic order) {
return CardItemTemplateComponentWidget(
imagePath: _imagePath(order),
labelsHashMap: _labelsHashMap(order),
statusHashMap: _statusHashMap(order),
onTapCardItemAction: () async {
showDialog(
useSafeArea: true,
context: context,
builder: (context) {
return Dialog(
child: DetailsComponentWidget(
imagePath: _imagePath(order),
labelsHashMap: _labelsHashMapDialog(order),
statusHashMap: [
if (order['isPending'] == true)
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(ptText: 'Aguardando Retirada', enText: 'Waiting Pick up'): FlutterFlowTheme.of(context).warning,
})
else
Map<String, Color>.from({
FFLocalizations.of(context).getVariableText(ptText: 'Retirado', enText: 'Picked up'): FlutterFlowTheme.of(context).primary,
}),
],
buttons: [],
),
);
}
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _appBar(context),
body: _appBody(context),
);
}
}

View File

@ -66,7 +66,7 @@ packages:
source: hosted
version: "2.0.3"
bloc:
dependency: "direct main"
dependency: transitive
description:
name: bloc
sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"