import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map_geojson2/flutter_map_geojson2.dart'; import 'package:latlong2/latlong.dart'; import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/modules/asset_tracking/asset_tracking_provider.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/item_views/info_header_widget.dart'; import 'package:test_sa/views/widgets/item_views/info_text_widget.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; import 'map_tracking_page.dart'; class AssetTrackingPage extends StatefulWidget { AssetTrackingPage({Key? key}) : super(key: key); @override _AssetTrackingPageState createState() { return _AssetTrackingPageState(); } } class _AssetTrackingPageState extends State with SingleTickerProviderStateMixin { int selectedIndex = 1; late AnimationController _animationController; late AssetTrackingProvider assetTrackingProvider; @override void initState() { super.initState(); assetTrackingProvider = Provider.of(context, listen: false); _animationController = AnimationController( duration: const Duration(milliseconds: 1200), vsync: this, ); _animationController.forward(); WidgetsBinding.instance.addPostFrameCallback((_) { assetTrackingProvider.reset(); assetTrackingProvider.getAssetsFromPenguin(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: const DefaultAppBar(title: "Live Asset Tracking"), body: Column( // crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: double.infinity, child: SegmentedButton( multiSelectionEnabled: false, emptySelectionAllowed: false, expandedInsets: const EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), style: SegmentedButton.styleFrom( side: BorderSide(color: AppColor.borderColor(context)), textStyle: AppTextStyles.bodyText, backgroundColor: AppColor.background(context), foregroundColor: context.isDark ? AppColor.neutral30 : AppColor.black20, selectedForegroundColor: AppColor.addItemButtonColor(context), selectedBackgroundColor: AppColor.primary10, ), segments: >[ ButtonSegment( value: 1, label: const Text("List"), icon: Icon(Icons.list_rounded, color: AppColor.icon2Color(context)), ), ButtonSegment( value: 2, label: const Text("Grid"), icon: Icon(Icons.grid_view_rounded, color: AppColor.icon2Color(context)), ), ButtonSegment( value: 3, label: const Text("Map"), icon: Icon(Icons.map, color: AppColor.icon2Color(context)), ), ], selected: {selectedIndex}, onSelectionChanged: (Set newSelection) { setState(() { selectedIndex = newSelection.first; }); }, ), ), SafeArea( child: AnimatedSwitcher( duration: const Duration(milliseconds: 300), child: selectedIndex == 3 ? MapTrackingPage(inAppView: true) : listView(), ), ).expanded, ], ), ); } Widget listView() { return Consumer(builder: (context, provider, _) { return (provider.assetsList.isEmpty && !provider.isLoading) ? NoDataFound(message: context.translation.noDataFound).center : ListView.separated( key: const ValueKey('asset-list_view'), padding: const EdgeInsets.all(16), itemCount: provider.isLoading ? 6 : provider.assetsList.length, separatorBuilder: (listContext, itemIndex) => 12.height, itemBuilder: (listContext, itemIndex) { if (provider.isLoading) return const SizedBox().toAssetListShimmer(listContext, provider.isLoading); // Calculate staggered animation delay final delay = itemIndex * 0.08; final animation = Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: _animationController, curve: Interval( delay.clamp(0.0, 0.7), (delay + 0.4).clamp(0.0, 1.0), curve: Curves.easeOut, ), ), ); final slideAnimation = Tween( begin: const Offset(0.0, 0.15), end: Offset.zero, ).animate( CurvedAnimation( parent: _animationController, curve: Interval( delay.clamp(0.0, 0.7), (delay + 0.4).clamp(0.0, 1.0), curve: Curves.easeOutCubic, ), ), ); return FadeTransition( opacity: animation, child: SlideTransition( position: slideAnimation, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ StatusLabel( label: (provider.assetsList[itemIndex].location?.isLive ?? false) ? "Live" : "Not Live", radius: 4, textColor: AppColor.getPriorityStatusTextColor(context, (provider.assetsList[itemIndex].location?.isLive ?? false) ? 0 : 1), backgroundColor: AppColor.getPriorityStatusColor(context, (provider.assetsList[itemIndex].location?.isLive ?? false) ? 0 : 1), ), 4.height, InfoHeader16Widget(provider.assetsList[itemIndex].label ?? ""), InfoTextWidget(label: "Serial No", value: provider.assetsList[itemIndex].label, showEmptyValue: true), InfoTextWidget(label: "Type", value: provider.assetsList[itemIndex].type?.name, showEmptyValue: true), InfoTextWidget(label: "Status", value: provider.assetsList[itemIndex].status?.name, showEmptyValue: true), InfoTextWidget(label: "Department", value: provider.assetsList[itemIndex].department?.name, showEmptyValue: true), InfoTextWidget( label: "Last seen", value: provider.assetsList[itemIndex].location?.lastSeen?.toServiceRequestDetailsFormat, showEmptyValue: true, showArrow: true, arrowMsg: "View on map", ), ], ).toShadowContainer(context)).onPress((){ Navigator.push(context, MaterialPageRoute(builder: (context) => MapTrackingPage(assetTrackingData: provider.assetsList[itemIndex]))); }), ); }, ); }); // Selector( // selector: (_, myModel) => myModel, // Selects only the userName // builder: (_, isLoading, __) { // // }); } }