import 'package:flutter/material.dart'; import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_inspection/presentation/routes/app_routes.dart'; import 'package:rasadyar_inspection/presentation/widget/base_page/view.dart'; import 'package:rasadyar_inspection/presentation/widget/list_item/list_item.dart'; import 'package:rasadyar_inspection/presentation/widget/search.dart'; import 'logic.dart'; class InspectionMapPage extends GetView { const InspectionMapPage({super.key}); @override Widget build(BuildContext context) { return BasePage( hasSearch: true, hasFilter: true, hasBack: false, defaultSearch: false, filteringWidget: filterWidget(showIndex: 3.obs, filterIndex: 5.obs), onSearchTap: () { controller.baseLogic.isSearchSelected.value = !controller.baseLogic.isSearchSelected.value; }, widgets: [_buildMap()], floatingActionButton: _buildGpsButton(), ); } Widget _buildMap() { return Expanded( child: Stack( fit: StackFit.expand, children: [ ObxValue((currentLocation) { return FlutterMap( mapController: controller.animatedMapController.mapController, options: MapOptions( initialCenter: currentLocation.value, initialZoom: 18, onPositionChanged: (camera, hasGesture) { controller.debouncedUpdateVisibleMarkers(center: camera.center); }, ), children: [ TileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', userAgentPackageName: 'ir.mnpc.rasadyar', ), ObxValue((markers) { return MarkerLayer( markers: markers .map( (e) => markerWidget( marker: e, onTap: () { Get.bottomSheet( selectedLocationWidget( showHint: false, sliderController: controller.slidController.value, trigger: () {}, toggle: () {}, ), isScrollControlled: true, enableDrag: true, backgroundColor: Colors.transparent, ); }, ), ) .toList(), ); }, controller.markers), ], ); }, controller.currentLocation), Positioned( top: 10, left: 20, right: 20, child: ObxValue((data) { if (data.value) { return SearchWidget( onSearchChanged: (data) { controller.baseLogic.searchValue.value = data; }, ); } else { return SizedBox.shrink(); } }, controller.baseLogic.isSearchSelected), ), ], ), ); } Widget _buildGpsButton() { return ObxValue((data) { return RFab( backgroundColor: AppColor.greenNormal, isLoading: data.value, icon: Assets.vec.gpsSvg.svg(width: 40.w, height: 40.h), onPressed: () async => await controller.determineCurrentPosition(), ); }, controller.isLoading); } } Marker markerWidget({required LatLng marker, required VoidCallback onTap}) { return Marker( point: marker, child: GestureDetector( onTap: onTap, behavior: HitTestBehavior.opaque, child: SizedBox( width: 36, height: 36, child: Assets.vec.mapMarkerSvg.svg(width: 30, height: 30), ), ), ); } Widget filterWidget({required RxInt filterIndex, required RxInt showIndex}) { return BaseBottomSheet( height: Get.height * 0.5, child: Column( spacing: 16, children: [ SizedBox(height: 1), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, spacing: 16, children: [ cardWithLabel( title: 'اصناف', count: 1234567, icon: Assets.vec.shopSvg.svg(width: 24.w, height: 24.h), backgroundColor: AppColor.greenLight, backgroundBadgeColor: AppColor.greenLightActive, ), cardWithLabel( title: 'دامداران', count: 1234567, icon: Assets.vec.peopleSvg.svg(width: 24.w, height: 24.h), backgroundColor: AppColor.blueLight, backgroundBadgeColor: AppColor.blueLightActive, ), cardWithLabel( title: 'مرغداران', count: 1234567, icon: Assets.vec.profile2Svg.svg(width: 24.w, height: 24.h), backgroundColor: AppColor.redLight, backgroundBadgeColor: AppColor.redLightActive, ), ], ), Column( crossAxisAlignment: CrossAxisAlignment.start, spacing: 12, children: [ Text( 'فیلتر نمایش', textAlign: TextAlign.center, style: AppFonts.yekan13.copyWith(color: AppColor.blueNormal), ), ObxValue((data) { return Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, spacing: 8, children: [ customChip( isSelected: data.value == 0, onTap: (data) { filterIndex.value = data; }, index: 0, title: 'دامداران', ), customChip( isSelected: data.value == 1, title: 'مرغداران', onTap: (data) { filterIndex.value = data; }, index: 1, ), customChip( isSelected: data.value == 2, title: 'اصناف', onTap: (data) { filterIndex.value = data; }, index: 2, ), ], ); }, filterIndex), ], ), Column( crossAxisAlignment: CrossAxisAlignment.start, spacing: 12, children: [ Text( 'نمایش', textAlign: TextAlign.center, style: AppFonts.yekan13.copyWith(color: AppColor.blueNormal), ), ObxValue((data) { return SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, spacing: 8, children: [ customChip( isSelected: data.value == 0, title: 'نمایش همه', onTap: (data) { showIndex.value = data; }, index: 0, ), customChip( isSelected: data.value == 1, title: 'دارای تراکنش', onTap: (data) { showIndex.value = data; }, index: 1, ), customChip( isSelected: data.value == 2, title: 'بازرسی شده ها', onTap: (data) { showIndex.value = data; }, index: 2, ), customChip( isSelected: data.value == 3, title: 'بازرسی نشده ها', onTap: (data) { showIndex.value = data; }, index: 3, ), customChip( isSelected: data.value == 4, title: 'متخلفین', onTap: (data) { showIndex.value = data; }, index: 4, ), ], ), ); }, showIndex), ], ), ], ), ); } Widget cardWithLabel({ required String title, required int count, String unit = 'عدد', required Widget icon, required Color backgroundColor, required Color backgroundBadgeColor, }) { return SizedBox( width: 114.w, height: 115.h, child: Stack( clipBehavior: Clip.antiAlias, alignment: Alignment.topCenter, children: [ Positioned( bottom: 0, right: 0, left: 0, child: Container( width: 114.w, height: 91.h, clipBehavior: Clip.antiAlias, decoration: BoxDecoration( color: backgroundColor, borderRadius: BorderRadius.circular(8), border: Border.all(width: 0.25, color: AppColor.blackLightHover), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, spacing: 6, children: [ Text(title, style: AppFonts.yekan12.copyWith(color: AppColor.textColor)), Text( count.separatedByComma, style: AppFonts.yekan16.copyWith(color: AppColor.textColor), ), Text(unit, style: AppFonts.yekan12.copyWith(color: AppColor.textColor)), ], ), ), ), Positioned( top: 5.h, child: Container( width: 32.w, height: 32.h, padding: EdgeInsets.all(4), decoration: BoxDecoration( color: backgroundBadgeColor, borderRadius: BorderRadius.circular(50), border: Border.all(color: AppColor.borderColor, width: 0.25), ), child: Center(child: icon), ), ), ], ), ); } Widget markerDetailsWidget() { return Container( clipBehavior: Clip.antiAlias, margin: EdgeInsets.all(35), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), child: Column( spacing: 15, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, spacing: 12, children: [ Text( 'داود خرم پور', textAlign: TextAlign.center, style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDarkHover), ), Spacer(), vecWidgetWithOnTap( child: Assets.vec.mapSvg.svg(), onTap: () { Get.toNamed(InspectionRoutes.inspectionLocationDetails); }, width: 24, height: 24, color: AppColor.blueNormal, ), vecWidgetWithOnTap( child: Assets.vec.messageAddSvg.svg(), width: 24, height: 24, color: AppColor.greenNormal, onTap: () { Get.toNamed(InspectionRoutes.inspectionAddSupervision); }, ), vecWidgetWithOnTap( child: Assets.vec.securityTimeSvg.svg(), color: AppColor.warning, height: 24, width: 24, onTap: () {}, ), ], ), Container( height: 32, clipBehavior: Clip.antiAlias, padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: ShapeDecoration( color: AppColor.blueLight, shape: RoundedRectangleBorder( side: BorderSide(width: 1, color: AppColor.blueLightHover), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'باقی مانده', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), Text( '0 کیلوگرم', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), ], ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( 'شماره همراه', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), Text( '0326598653', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( 'آخرین فعالیت', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), Text( '1409/12/12', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( 'موجودی', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), Text( '5کیلوگرم', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), ], ), ...List.generate( 5, (index) => Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( 'فروش رفته', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), Text( '0 کیلوگرم', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), ], ), ), ], ), ); } Widget customChip({ bool isSelected = false, required String title, required int index, required Function(int) onTap, }) { return GestureDetector( onTap: () { onTap.call(index); }, child: Container( height: 32.h, padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 8.h), clipBehavior: Clip.antiAlias, decoration: BoxDecoration( color: AppColor.whiteGreyNormal, borderRadius: BorderRadius.circular(8), border: Border.all( width: 1, color: isSelected ? AppColor.blueNormal : AppColor.blackLightActive, ), ), child: Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: 12.w, height: 12.h, child: Transform.scale( scale: 0.70, child: Checkbox( value: isSelected, side: BorderSide(color: AppColor.whiteDarkHover, width: 1), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, visualDensity: VisualDensity.compact, overlayColor: WidgetStateProperty.all(AppColor.blueNormal), fillColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return AppColor.blueNormal; } else { return AppColor.whiteGreyNormal; } }), onChanged: (value) { onTap.call(index); }, ), ), ), SizedBox(width: 8.w), Text( title, textAlign: TextAlign.center, style: AppFonts.yekan12.copyWith( color: isSelected ? AppColor.blueNormal : AppColor.whiteDarkHover, ), ), ], ), ), ); } Widget selectedLocationWidget({ required bool showHint, required SlidableController sliderController, required VoidCallback trigger, required VoidCallback toggle, }) { if (showHint) { trigger.call(); } return BaseBottomSheet( height: 150.h, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 20), child: Slidable( key: Key('selectedLocationWidget'), controller: sliderController, endActionPane: ActionPane( motion: StretchMotion(), children: [ CustomSlidableAction( onPressed: (context) { Get.toNamed(InspectionRoutes.inspectionLocationDetails); }, backgroundColor: AppColor.blueNormal, foregroundColor: Colors.white, padding: EdgeInsets.all(16), borderRadius: BorderRadius.only( bottomRight: Radius.circular(8), topRight: Radius.circular(8), ), child: Assets.vec.mapSvg.svg(width: 24, height: 24), ), CustomSlidableAction( onPressed: (context) { Get.toNamed(InspectionRoutes.inspectionAddSupervision); }, backgroundColor: AppColor.greenNormal, padding: EdgeInsets.all(16), child: Assets.vec.messageAddSvg.svg(), ), CustomSlidableAction( onPressed: (context) {}, backgroundColor: AppColor.warning, padding: EdgeInsets.all(16), borderRadius: BorderRadius.only( bottomLeft: Radius.circular(8), topLeft: Radius.circular(8), ), child: Assets.vec.securityTimeSvg.svg(), ), ], ), child: GestureDetector( onTap: toggle, child: Container( height: 58, padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), border: Border.all(width: 1, color: AppColor.blackLightHover), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( children: [ Text( 'داود خرم مهری پور', style: AppFonts.yekan10.copyWith(color: AppColor.blueNormal), ), Text( 'گوشت و مرغ', style: AppFonts.yekan12.copyWith(color: AppColor.darkGreyDarkHover), ), ], ), Column( children: [ Text( 'باقی مانده', style: AppFonts.yekan10.copyWith(color: AppColor.blueNormal), ), Text( '0 کیلوگرم', style: AppFonts.yekan12.copyWith(color: AppColor.darkGreyDarkHover), ), ], ), Assets.vec.scanBarcodeSvg.svg(), ], ), ), ), ), ), ); } Widget selectedLocationWidget2({ required bool showHint, required SlidableController sliderController, required VoidCallback trigger, required VoidCallback toggle, }) { if (showHint) { trigger.call(); } return BaseBottomSheet( height: 150.h, child: ListItem( index: 0, child:Container( height: 58, padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), border: Border.all(width: 1, color: AppColor.blackLightHover), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( children: [ Text( 'داود خرم مهری پور', style: AppFonts.yekan10.copyWith(color: AppColor.blueNormal), ), Text( 'گوشت و مرغ', style: AppFonts.yekan12.copyWith(color: AppColor.darkGreyDarkHover), ), ], ), Column( children: [ Text( 'باقی مانده', style: AppFonts.yekan10.copyWith(color: AppColor.blueNormal), ), Text( '0 کیلوگرم', style: AppFonts.yekan12.copyWith(color: AppColor.darkGreyDarkHover), ), ], ), Assets.vec.scanBarcodeSvg.svg(), ], ), ) , secondChild: Container( height: 350.h, color: Colors.redAccent, ), labelColor: Colors.blue, labelIcon: Assets.vec.mapSvg.path, onTap: () { }, selected: true, ), ); }