WIP
This commit is contained in:
parent
16f43bbab8
commit
906fbcaf24
|
@ -52,6 +52,7 @@ class _AccessHistoryState extends State<AccessHistoryScreen> {
|
|||
_model = createModel(context, () => AcessHistoryPageModel());
|
||||
_accessFuture = fetchAccessHistoryService();
|
||||
|
||||
|
||||
_scrollController = ScrollController()
|
||||
..addListener(() {
|
||||
if (_scrollController.position.atEdge &&
|
||||
|
|
|
@ -4,21 +4,24 @@ part of 'vehicles_on_the_property.dart';
|
|||
|
||||
// ignore: must_be_immutable
|
||||
class VehicleHistoryScreen extends StatefulWidget {
|
||||
|
||||
VehicleHistoryScreen(this.model, {super.key});
|
||||
late VehicleModel model;
|
||||
|
||||
|
||||
@override
|
||||
State<VehicleHistoryScreen> createState() => _VehicleHistoryScreenState();
|
||||
|
||||
}
|
||||
|
||||
class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
||||
with Remotable {
|
||||
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initializeScrollController();
|
||||
_future = _fetch();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -69,8 +72,8 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
|||
|
||||
Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) {
|
||||
return Expanded(
|
||||
child: FutureBuilder<List<Widget?>>(
|
||||
future: _future,
|
||||
child: FutureBuilder<List<dynamic>>(
|
||||
future: _fetch(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
|
@ -79,38 +82,16 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
|||
} else {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
addAutomaticKeepAlives: true,
|
||||
restorationId: '',
|
||||
physics: const BouncingScrollPhysics(),
|
||||
controller: _scrollController,
|
||||
itemCount: _wrap.length + 1,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == 0) {
|
||||
return _buildHeader(context, limitedBodyTextSize);
|
||||
} else {
|
||||
Widget? item = _wrap[index - 1];
|
||||
return _wrap[index - 1] ?? SizedBox.shrink();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
itemCount: snapshot.data!.length ,
|
||||
itemBuilder: (context, index) => _generateItems(context, snapshot.data![index], index),
|
||||
|
||||
Widget _buildHeader(BuildContext context, double limitedBodyTextSize) {
|
||||
log('amountRegister: ${widget.model.amountRegister}');
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 30, top: 10),
|
||||
child: Text(
|
||||
(widget.model.amountRegister == '0' ||
|
||||
widget.model.amountRegister == null)
|
||||
? ''
|
||||
: "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/${widget.count}",
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Nunito',
|
||||
fontSize: limitedBodyTextSize,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -127,56 +108,59 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Mixin for Fetch Visits
|
||||
mixin Remotable on State<VehicleHistoryScreen> {
|
||||
late Future<List<Widget?>> _future;
|
||||
List<Widget?> _wrap = [];
|
||||
|
||||
late ScrollController _scrollController;
|
||||
double offset = 0.0;
|
||||
List<dynamic> _wrap = [];
|
||||
int _pageNumber = 1;
|
||||
bool _hasData = true;
|
||||
bool _loading = true;
|
||||
int count = 0;
|
||||
|
||||
|
||||
Future<List<Widget?>> _fetch() async {
|
||||
if (!widget._hasData || !widget._loading) return [];
|
||||
|
||||
setState(() => widget._loading = true);
|
||||
|
||||
Future<List<dynamic>> _fetch() async {
|
||||
if (!_hasData || !_loading) return _wrap;
|
||||
print('hasHasData');
|
||||
setState(() => _loading = true);
|
||||
try {
|
||||
var response = await PhpGroup.getVehiclesByProperty.call(widget._pageNumber.toString());
|
||||
final List<dynamic> vehicles = response.jsonBody['vehicles'] as List<dynamic>? ?? [];
|
||||
safeSetState(() => widget.count = response.jsonBody['total_rows'] ?? 0);
|
||||
|
||||
var response = await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString());
|
||||
final List<dynamic> vehicles = response.jsonBody['vehicles'] as List<dynamic>? ?? [];
|
||||
safeSetState(() => count = response.jsonBody['total_rows'] ?? 0);
|
||||
if (vehicles.isNotEmpty) {
|
||||
setState(() {
|
||||
|
||||
widget._hasData = true;
|
||||
widget._loading = false;
|
||||
_hasData = true;
|
||||
_loading = false;
|
||||
});
|
||||
|
||||
|
||||
return _generateItems(context, vehicles);
|
||||
print('vehicles.isNotEmpty');
|
||||
_wrap.addAll(vehicles);
|
||||
return _wrap;
|
||||
}
|
||||
|
||||
_showNoMoreDataSnackBar(context);
|
||||
|
||||
setState(() {
|
||||
widget._hasData = false;
|
||||
widget._loading = false;
|
||||
_hasData = false;
|
||||
_loading = false;
|
||||
});
|
||||
|
||||
return [];
|
||||
print('hasEmpty: ${_wrap.length}');
|
||||
return _wrap;
|
||||
} catch (e, s) {
|
||||
DialogUtil.errorDefault(context);
|
||||
LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s);
|
||||
setState(() {
|
||||
widget._hasData = false;
|
||||
widget._loading = false;
|
||||
_hasData = false;
|
||||
_loading = false;
|
||||
});
|
||||
return [];
|
||||
print('hasError');
|
||||
return _wrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,43 +173,56 @@ mixin Remotable on State<VehicleHistoryScreen> {
|
|||
showSnackbar(context, message, true);
|
||||
}
|
||||
|
||||
Future<List<Widget?>> _generateItems(BuildContext context, List<dynamic> uItem) async {
|
||||
if (!widget._hasData) return [];
|
||||
Widget _buildHeader(BuildContext context) {
|
||||
double limitedBodyTextSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
log('amountRegister: ${widget.model.amountRegister}');
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 30, top: 10),
|
||||
child: Text(
|
||||
(widget.model.amountRegister == '0' ||
|
||||
widget.model.amountRegister == null)
|
||||
? ''
|
||||
: "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/$count",
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Nunito',
|
||||
fontSize: limitedBodyTextSize,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget?> items = [];
|
||||
Widget? _generateItems(BuildContext context, dynamic snapshot, int index) {
|
||||
if (index == 0) return _buildHeader(context);
|
||||
|
||||
for (var uItem in uItem) {
|
||||
final bool? isOwner = uItem['isOwnerVehicle'];
|
||||
final IconData? iconData = isOwner == true ? Symbols.no_crash : Symbols.directions_car;
|
||||
final bool? isOwner = snapshot['isOwnerVehicle'];
|
||||
final IconData? iconData = isOwner == true ? Symbols.garage : Symbols.directions_car;
|
||||
final FreCardIcon? cardIcon = isOwner != null
|
||||
? FreCardIcon(height: 50, width: 100, icon: Icon(iconData, size: 80, opticalSize: 10))
|
||||
: null;
|
||||
|
||||
final String? tag = uItem['tag'];
|
||||
final String? tag = snapshot['tag'];
|
||||
final bool containTag = tag.isNotNullAndEmpty;
|
||||
final Map<String, String> labelsHashMap = _generateLabelsHashMap(context, uItem, tag, containTag);
|
||||
final Map<String, String> labelsHashMap = _generateLabelsHashMap(context, snapshot, tag, containTag);
|
||||
|
||||
final statusHashMapList = await _generateStatusHashMapList(uItem);
|
||||
final List<Map<String, Color>> statusHashMapList = _generateStatusHashMapList(snapshot);
|
||||
|
||||
Future<void> onTapCardItemAction() async {
|
||||
await _handleCardItemTap(context, cardIcon, uItem);
|
||||
_handleCardItemTap(context, cardIcon, snapshot);
|
||||
}
|
||||
|
||||
final statusLinkedHashMap = statusHashMapList.map((map) => LinkedHashMap<String, Color>.from(map)).toList();
|
||||
final length = statusLinkedHashMap.expand((e) => [e.length]);
|
||||
|
||||
items.add(CardItemTemplateComponentWidget(
|
||||
return CardItemTemplateComponentWidget(
|
||||
icon: cardIcon,
|
||||
labelsHashMap: labelsHashMap,
|
||||
statusHashMap: statusHashMapList,
|
||||
onTapCardItemAction: onTapCardItemAction,
|
||||
itemWidthFactor: length == 1 ? 0.25 : 0.50,
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
widget._wrap.addAll(items);
|
||||
return items;
|
||||
}
|
||||
|
||||
Map<String, String> _generateLabelsHashMap(BuildContext context,
|
||||
Map<String, dynamic> uItem, String? tag, bool containTag) {
|
||||
|
@ -242,17 +239,17 @@ mixin Remotable on State<VehicleHistoryScreen> {
|
|||
};
|
||||
}
|
||||
|
||||
Future<List<Map<String, Color>>> _generateStatusHashMapList(
|
||||
Map<String, dynamic> uItem) async {
|
||||
List<Map<String, Color>> _generateStatusHashMapList(
|
||||
Map<String, dynamic> uItem) {
|
||||
final statusHashMap =
|
||||
await widget.model.generateStatusColorMap(uItem, false);
|
||||
widget.model.generateStatusColorMap(uItem, false);
|
||||
return statusHashMap != null ? [statusHashMap] : [];
|
||||
}
|
||||
|
||||
Future<void> _handleCardItemTap(BuildContext context, FreCardIcon? cardIcon,
|
||||
Map<String, dynamic> uItem) async {
|
||||
try {
|
||||
final dialogContent = await widget.model.buildVehicleDetails(
|
||||
final dialogContent = widget.model.buildVehicleDetails(
|
||||
icon: cardIcon,
|
||||
item: uItem,
|
||||
context: context,
|
||||
|
@ -266,9 +263,8 @@ mixin Remotable on State<VehicleHistoryScreen> {
|
|||
Dialog(alignment: Alignment.center, child: dialogContent),
|
||||
).whenComplete(() {
|
||||
safeSetState(() {
|
||||
widget._pageNumber = 1;
|
||||
widget._wrap = [];
|
||||
widget._future = _fetch();
|
||||
_pageNumber = 1;
|
||||
_fetch();
|
||||
});
|
||||
});
|
||||
} catch (e, s) {
|
||||
|
@ -276,31 +272,34 @@ mixin Remotable on State<VehicleHistoryScreen> {
|
|||
LogUtil.requestAPIFailed(
|
||||
"proccessRequest.php", "", "Consulta de Veículos", e, s);
|
||||
safeSetState(() {
|
||||
widget._hasData = false;
|
||||
widget._loading = false;
|
||||
_hasData = false;
|
||||
_loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
late ScrollController _scrollController;
|
||||
|
||||
void _initializeScrollController() {
|
||||
_scrollController = ScrollController()
|
||||
_scrollController = ScrollController(keepScrollOffset: true, initialScrollOffset: offset)
|
||||
..addListener(() {
|
||||
print('ScrollController');
|
||||
if(!widget._hasData) return;
|
||||
if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) {
|
||||
if(!_hasData) return;
|
||||
if
|
||||
// (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent)
|
||||
(_scrollController.position.atEdge && _scrollController.position.pixels != 0)
|
||||
{
|
||||
print('ScrollController -> loadMore');
|
||||
offset = _scrollController.offset;
|
||||
_loadMore();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _loadMore() {
|
||||
if (widget._hasData) {
|
||||
widget._pageNumber++;
|
||||
widget._loading = true;
|
||||
widget._future = _fetch();
|
||||
void _loadMore() async {
|
||||
if (_hasData) {
|
||||
_pageNumber+=1;
|
||||
_loading = true;
|
||||
_fetch();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ class VehicleModel extends FlutterFlowModel<VehiclePage>
|
|||
Future<void> initAsync() async {
|
||||
amountRegister =
|
||||
await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key);
|
||||
autoApproval= await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key);
|
||||
}
|
||||
|
||||
bool isFormValid(BuildContext context, GlobalKey<FormState> formKey) {
|
||||
|
@ -89,6 +90,8 @@ mixin class _BaseVehiclePage {
|
|||
bool isEditing = false;
|
||||
ApiCallResponse? vehicleResponse;
|
||||
String? amountRegister = '0';
|
||||
late final String? autoApproval;
|
||||
|
||||
|
||||
VoidCallback? onUpdateVehicle;
|
||||
VoidCallback? onRegisterVehicle;
|
||||
|
@ -237,10 +240,10 @@ mixin _VehicleUpdateScreenModel on _BaseVehiclePage {
|
|||
|
||||
/// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page.
|
||||
mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
||||
Future<Map<String, Color>?>? generateStatusColorMap(
|
||||
dynamic uItem, bool isDetail) async {
|
||||
final autoApproval =
|
||||
await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key);
|
||||
|
||||
|
||||
Map<String, Color>? generateStatusColorMap(dynamic uItem, bool isDetail) {
|
||||
|
||||
if (autoApproval.toBoolean == true) return null;
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
final localization = FFLocalizations.of(context);
|
||||
|
@ -296,7 +299,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
return {};
|
||||
}
|
||||
|
||||
Future<List<FFButtonWidget>?> generateActionButtons(dynamic item) async {
|
||||
List<FFButtonWidget> generateActionButtons(dynamic item) {
|
||||
final Color iconButtonColor = FlutterFlowTheme.of(context).primaryText;
|
||||
final FFButtonOptions buttonOptions = FFButtonOptions(
|
||||
height: 40,
|
||||
|
@ -339,7 +342,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
ptText: 'Você tem certeza que deseja cancelar essa solicitação?',
|
||||
enText: 'Are you sure you want to delete this request?',
|
||||
),
|
||||
() async => await processCancelRequest(item['status'], item));
|
||||
() async => processCancelRequest(item['status'], item));
|
||||
}
|
||||
|
||||
final deleteText = FFLocalizations.of(context)
|
||||
|
@ -356,7 +359,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
ptText: 'Você tem certeza que deseja excluir esse veículo?',
|
||||
enText: 'Are you sure you want to delete this vehicle?',
|
||||
),
|
||||
() async => await processDeleteRequest(item),
|
||||
() async => processDeleteRequest(item),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -401,7 +404,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
];
|
||||
}
|
||||
|
||||
Future<void> processDeleteRequest(dynamic item) async {
|
||||
void processDeleteRequest(dynamic item) async {
|
||||
log('processDeleteRequest -> item[$item]');
|
||||
return await PhpGroup.deleteVehicle
|
||||
.call(
|
||||
|
@ -448,7 +451,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
});
|
||||
}
|
||||
|
||||
Future<void> processCancelRequest(String status, dynamic item) async {
|
||||
void processCancelRequest(String status, dynamic item) async {
|
||||
late final ApiCallResponse value;
|
||||
try {
|
||||
switch (status) {
|
||||
|
@ -527,7 +530,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
);
|
||||
}
|
||||
|
||||
Future<Map<String, String>> generateLabelsHashMap(dynamic item) async {
|
||||
Map<String, String> generateLabelsHashMap(dynamic item) {
|
||||
return {
|
||||
if (item['model'] != null && item['model'] != '')
|
||||
'${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:':
|
||||
|
@ -547,15 +550,15 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
};
|
||||
}
|
||||
|
||||
Future<Widget> buildVehicleDetails({
|
||||
DetailsComponentWidget buildVehicleDetails({
|
||||
required dynamic item,
|
||||
required BuildContext context,
|
||||
required VehicleModel model,
|
||||
required FreCardIcon? icon,
|
||||
}) async {
|
||||
final status = await generateStatusColorMap(item, true);
|
||||
final buttons = await generateActionButtons(item);
|
||||
final labels = await generateLabelsHashMap(item);
|
||||
}) {
|
||||
final status = generateStatusColorMap(item, true);
|
||||
final buttons = generateActionButtons(item);
|
||||
final labels = generateLabelsHashMap(item);
|
||||
return DetailsComponentWidget(
|
||||
icon: icon,
|
||||
buttons: buttons,
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Define the base URL for the API endpoint
|
||||
BASE_URL="https://freaccess.com.br/freaccess/processRequest.php"
|
||||
|
||||
# Define common parameters
|
||||
DEV_UUID="6b7b81849c115a8a"
|
||||
USER_UUID="678aa05b0c2154.50583237"
|
||||
CLI_ID="7"
|
||||
ACTIVITY="getVehiclesByProperty"
|
||||
PAGE_SIZE="10"
|
||||
|
||||
# Function to perform the HTTP request
|
||||
perform_request() {
|
||||
local page=$1
|
||||
http --form POST "$BASE_URL" \
|
||||
devUUID="$DEV_UUID" \
|
||||
userUUID="$USER_UUID" \
|
||||
cliID="$CLI_ID" \
|
||||
atividade="$ACTIVITY" \
|
||||
page="$page" \
|
||||
pageSize="$PAGE_SIZE" \
|
||||
--check-status \
|
||||
--ignore-stdin \
|
||||
--timeout=10
|
||||
}
|
||||
|
||||
# Perform requests for pages 1 and 2
|
||||
perform_request 1
|
||||
perform_request 2
|
Loading…
Reference in New Issue