diff --git a/assets/icons/place_holder.svg b/assets/icons/place_holder.svg new file mode 100644 index 0000000..cfd772b --- /dev/null +++ b/assets/icons/place_holder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/place_holder.png b/assets/images/place_holder.png new file mode 100644 index 0000000..fe12c5a Binary files /dev/null and b/assets/images/place_holder.png differ diff --git a/lib/presentation/common/assets.dart b/lib/presentation/common/assets.dart new file mode 100644 index 0000000..295cf2d --- /dev/null +++ b/lib/presentation/common/assets.dart @@ -0,0 +1,80 @@ +///This file is automatically generated. DO NOT EDIT, all your changes would be lost. +class Assets { + Assets._(); + + static const String iconsAdd = 'assets/icons/add.svg'; + static const String iconsArrowLeft = 'assets/icons/arrow_left.svg'; + static const String iconsArrowRight = 'assets/icons/arrow_right.svg'; + static const String iconsBgHeaderUserProfile = 'assets/icons/bg_header_user_profile.svg'; + static const String iconsCalendar = 'assets/icons/calendar.svg'; + static const String iconsCalendarSearch = 'assets/icons/calendar_search.svg'; + static const String iconsCall = 'assets/icons/call.svg'; + static const String iconsDiagram = 'assets/icons/diagram.svg'; + static const String iconsDownload = 'assets/icons/download.svg'; + static const String iconsEdit = 'assets/icons/edit.svg'; + static const String iconsExcelDownload = 'assets/icons/excel_download.svg'; + static const String iconsFilter = 'assets/icons/filter.svg'; + static const String iconsGps = 'assets/icons/gps.svg'; + static const String iconsInformation = 'assets/icons/information.svg'; + static const String iconsInspection = 'assets/icons/inspection.svg'; + static const String iconsKey = 'assets/icons/key.svg'; + static const String iconsLiveStock = 'assets/icons/liveStock.svg'; + static const String iconsLogout = 'assets/icons/logout.svg'; + static const String iconsMap = 'assets/icons/map.svg'; + static const String iconsMapMarker = 'assets/icons/map_marker.svg'; + static const String iconsMessageAdd = 'assets/icons/message_add.svg'; + static const String iconsPdfDownload = 'assets/icons/pdf_download.svg'; + static const String iconsPictureFrame = 'assets/icons/picture_frame.svg'; + static const String iconsPlaceHolder = 'assets/icons/place_holder.svg'; + static const String iconsProfileCircle = 'assets/icons/profile_circle.svg'; + static const String iconsProfileUser = 'assets/icons/profile_user.svg'; + static const String iconsReceiptDiscount = 'assets/icons/receipt_discount.svg'; + static const String iconsScan = 'assets/icons/scan.svg'; + static const String iconsScanBarcode = 'assets/icons/scan_barcode.svg'; + static const String iconsSearch = 'assets/icons/search.svg'; + static const String iconsSecurityTime = 'assets/icons/security_time.svg'; + static const String iconsSetting = 'assets/icons/setting.svg'; + static const String iconsTagUser = 'assets/icons/tag_user.svg'; + static const String iconsTrash = 'assets/icons/trash.svg'; + static const String iconsUser = 'assets/icons/user.svg'; + static const String iconsUserSquare = 'assets/icons/user_square.svg'; + static const String imagesInnerSplash = 'assets/images/inner_splash.webp'; + static const String imagesOutterSplash = 'assets/images/outter_splash.webp'; + static const String imagesPlaceHolder = 'assets/images/place_holder.png'; + static const String vecAddSvg = 'assets/vec/add.svg.vec'; + static const String vecArrowLeftSvg = 'assets/vec/arrow_left.svg.vec'; + static const String vecArrowRightSvg = 'assets/vec/arrow_right.svg.vec'; + static const String vecBgHeaderUserProfileSvg = 'assets/vec/bg_header_user_profile.svg.vec'; + static const String vecCalendarSearchSvg = 'assets/vec/calendar_search.svg.vec'; + static const String vecCalendarSvg = 'assets/vec/calendar.svg.vec'; + static const String vecCallSvg = 'assets/vec/call.svg.vec'; + static const String vecDiagramSvg = 'assets/vec/diagram.svg.vec'; + static const String vecDownloadSvg = 'assets/vec/download.svg.vec'; + static const String vecEditSvg = 'assets/vec/edit.svg.vec'; + static const String vecExcelDownloadSvg = 'assets/vec/excel_download.svg.vec'; + static const String vecFilterSvg = 'assets/vec/filter.svg.vec'; + static const String vecGpsSvg = 'assets/vec/gps.svg.vec'; + static const String vecInformationSvg = 'assets/vec/information.svg.vec'; + static const String vecInspectionSvg = 'assets/vec/inspection.svg.vec'; + static const String vecKeySvg = 'assets/vec/key.svg.vec'; + static const String vecLiveStockSvg = 'assets/vec/liveStock.svg.vec'; + static const String vecLogoutSvg = 'assets/vec/logout.svg.vec'; + static const String vecMapMarkerSvg = 'assets/vec/map_marker.svg.vec'; + static const String vecMapSvg = 'assets/vec/map.svg.vec'; + static const String vecMessageAddSvg = 'assets/vec/message_add.svg.vec'; + static const String vecPdfDownloadSvg = 'assets/vec/pdf_download.svg.vec'; + static const String vecPictureFrameSvg = 'assets/vec/picture_frame.svg.vec'; + static const String vecProfileCircleSvg = 'assets/vec/profile_circle.svg.vec'; + static const String vecProfileUserSvg = 'assets/vec/profile_user.svg.vec'; + static const String vecReceiptDiscountSvg = 'assets/vec/receipt_discount.svg.vec'; + static const String vecScanBarcodeSvg = 'assets/vec/scan_barcode.svg.vec'; + static const String vecScanSvg = 'assets/vec/scan.svg.vec'; + static const String vecSearchSvg = 'assets/vec/search.svg.vec'; + static const String vecSecurityTimeSvg = 'assets/vec/security_time.svg.vec'; + static const String vecSettingSvg = 'assets/vec/setting.svg.vec'; + static const String vecTagUserSvg = 'assets/vec/tag_user.svg.vec'; + static const String vecTrashSvg = 'assets/vec/trash.svg.vec'; + static const String vecUserSquareSvg = 'assets/vec/user_square.svg.vec'; + static const String vecUserSvg = 'assets/vec/user.svg.vec'; + +} diff --git a/packages/core/lib/presentation/common/assets.gen.dart b/packages/core/lib/presentation/common/assets.gen.dart index 815f89f..7604588 100644 --- a/packages/core/lib/presentation/common/assets.gen.dart +++ b/packages/core/lib/presentation/common/assets.gen.dart @@ -84,6 +84,9 @@ class $AssetsIconsGen { /// File path: assets/icons/picture_frame.svg SvgGenImage get pictureFrame => const SvgGenImage('assets/icons/picture_frame.svg'); + /// File path: assets/icons/place_holder.svg + SvgGenImage get placeHolder => const SvgGenImage('assets/icons/place_holder.svg'); + /// File path: assets/icons/profile_circle.svg SvgGenImage get profileCircle => const SvgGenImage('assets/icons/profile_circle.svg'); @@ -145,6 +148,7 @@ class $AssetsIconsGen { messageAdd, pdfDownload, pictureFrame, + placeHolder, profileCircle, profileUser, receiptDiscount, @@ -169,8 +173,11 @@ class $AssetsImagesGen { /// File path: assets/images/outter_splash.webp AssetGenImage get outterSplash => const AssetGenImage('assets/images/outter_splash.webp'); + /// File path: assets/images/place_holder.png + AssetGenImage get placeHolder => const AssetGenImage('assets/images/place_holder.png'); + /// List of all assets - List get values => [innerSplash, outterSplash]; + List get values => [innerSplash, outterSplash, placeHolder]; } class $AssetsVecGen { diff --git a/packages/core/lib/presentation/widget/app_bar/r_app_bar.dart b/packages/core/lib/presentation/widget/app_bar/r_app_bar.dart index 6db58bb..67bec05 100644 --- a/packages/core/lib/presentation/widget/app_bar/r_app_bar.dart +++ b/packages/core/lib/presentation/widget/app_bar/r_app_bar.dart @@ -13,6 +13,7 @@ class RAppBar extends StatelessWidget implements PreferredSizeWidget { final TextStyle? titleTextStyle; final VoidCallback? onBackPressed; final List? additionalActions; + final int? leadingWidth; final Widget? leading; const RAppBar({ @@ -24,8 +25,9 @@ class RAppBar extends StatelessWidget implements PreferredSizeWidget { this.onBackPressed, this.additionalActions, this.leading, - this.hasBack = false, + this.hasBack = true, this.centerTitle = false, + this.leadingWidth }); @override @@ -41,11 +43,13 @@ class RAppBar extends StatelessWidget implements PreferredSizeWidget { titleTextStyle ?? AppFonts.yekan16.copyWith(color:Colors.white), title: Text(title), + leadingWidth: leadingWidth?.toDouble(), leading:leading!=null ? Padding( padding: const EdgeInsets.only(right: 16), child: leading, ) : null, + titleSpacing: 8, actions: [ if (additionalActions != null) ...additionalActions!, if(hasBack)...{ diff --git a/packages/core/lib/presentation/widget/buttons/fab.dart b/packages/core/lib/presentation/widget/buttons/fab.dart index 200f0ab..3a33df7 100644 --- a/packages/core/lib/presentation/widget/buttons/fab.dart +++ b/packages/core/lib/presentation/widget/buttons/fab.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:rasadyar_core/presentation/common/app_color.dart'; import 'package:rasadyar_core/presentation/utils/color_utils.dart'; + import '../../common/assets.gen.dart'; class RFab extends StatefulWidget { @@ -21,10 +22,7 @@ class RFab extends StatefulWidget { RFab.smallAdd({required VoidCallback? onPressed, Key? key}) : this.small( onPressed: onPressed, - icon: Assets.vec.addSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.addSvg.svg(width: 20, height: 20), backgroundColor: AppColor.greenNormal, key: key, ); @@ -32,10 +30,7 @@ class RFab extends StatefulWidget { RFab.add({required VoidCallback? onPressed, Key? key}) : this( onPressed: onPressed, - icon: Assets.vec.addSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.addSvg.svg(width: 40, height: 40), backgroundColor: AppColor.greenNormal, key: key, ); @@ -46,10 +41,7 @@ class RFab extends StatefulWidget { RFab.smallEdit({required VoidCallback? onPressed, Key? key}) : this.small( onPressed: onPressed, - icon: Assets.vec.addSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.addSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); @@ -57,10 +49,7 @@ class RFab extends StatefulWidget { RFab.edit({required VoidCallback? onPressed, Key? key}) : this( onPressed: onPressed, - icon: Assets.vec.addSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.addSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); @@ -71,10 +60,7 @@ class RFab extends StatefulWidget { RFab.smallDelete({required VoidCallback? onPressed, Key? key}) : this.small( onPressed: onPressed, - icon: Assets.vec.trashSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.trashSvg.svg(width: 20, height: 20), backgroundColor: AppColor.redNormal, key: key, ); @@ -82,10 +68,7 @@ class RFab extends StatefulWidget { RFab.delete({required VoidCallback? onPressed, Key? key}) : this( onPressed: onPressed, - icon: Assets.vec.trashSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.trashSvg.svg(width: 20, height: 20), backgroundColor: AppColor.redNormal, key: key, ); @@ -96,10 +79,7 @@ class RFab extends StatefulWidget { RFab.smallAction({required VoidCallback? onPressed, Key? key}) : this.small( onPressed: onPressed, - icon: Assets.vec.scanSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.scanSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); @@ -107,10 +87,7 @@ class RFab extends StatefulWidget { RFab.action({required VoidCallback? onPressed, Key? key}) : this( onPressed: onPressed, - icon: Assets.vec.scanSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.scanSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); @@ -121,10 +98,7 @@ class RFab extends StatefulWidget { RFab.smallFilter({required VoidCallback? onPressed, Key? key}) : this.small( onPressed: onPressed, - icon: Assets.vec.scanSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.scanSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); @@ -132,10 +106,7 @@ class RFab extends StatefulWidget { RFab.filter({required VoidCallback? onPressed, Key? key}) : this( onPressed: onPressed, - icon: Assets.vec.scanSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.scanSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); @@ -146,10 +117,7 @@ class RFab extends StatefulWidget { RFab.smallDownload({required VoidCallback? onPressed, Key? key}) : this.small( onPressed: onPressed, - icon: Assets.vec.downloadSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.downloadSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); @@ -157,10 +125,7 @@ class RFab extends StatefulWidget { RFab.download({required VoidCallback? onPressed, Key? key}) : this( onPressed: onPressed, - icon: Assets.vec.downloadSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.downloadSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); @@ -171,10 +136,7 @@ class RFab extends StatefulWidget { RFab.smallExcel({required VoidCallback? onPressed, Key? key}) : this.small( onPressed: onPressed, - icon: Assets.vec.excelDownloadSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.excelDownloadSvg.svg(width: 20, height: 20), backgroundColor: AppColor.greenDark, key: key, ); @@ -182,10 +144,7 @@ class RFab extends StatefulWidget { RFab.excel({required VoidCallback? onPressed, Key? key}) : this( onPressed: onPressed, - icon: Assets.vec.excelDownloadSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.excelDownloadSvg.svg(width: 20, height: 20), backgroundColor: AppColor.greenDark, key: key, ); @@ -196,10 +155,7 @@ class RFab extends StatefulWidget { RFab.smallBack({required VoidCallback? onPressed, Key? key}) : this.small( onPressed: onPressed, - icon: Assets.vec.arrowLeftSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.arrowLeftSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); @@ -207,10 +163,7 @@ class RFab extends StatefulWidget { RFab.back({required VoidCallback? onPressed, Key? key}) : this( onPressed: onPressed, - icon: Assets.vec.arrowLeftSvg.svg( - width: 20, - height: 20, - ), + icon: Assets.vec.arrowLeftSvg.svg(width: 20, height: 20), backgroundColor: AppColor.blueNormal, key: key, ); diff --git a/packages/core/lib/presentation/widget/buttons/outline_elevated_icon.dart b/packages/core/lib/presentation/widget/buttons/outline_elevated_icon.dart index 7afef0e..d4c57a0 100644 --- a/packages/core/lib/presentation/widget/buttons/outline_elevated_icon.dart +++ b/packages/core/lib/presentation/widget/buttons/outline_elevated_icon.dart @@ -32,10 +32,10 @@ class ROutlinedElevatedIcon extends StatefulWidget { Widget? icon; @override - State createState() => _ROutlinedElevatedStateIcon(); + State createState() => _ROutlinedElevatedIconState(); } -class _ROutlinedElevatedStateIcon extends State { +class _ROutlinedElevatedIconState extends State { @override Widget build(BuildContext context) { return OutlinedButton.icon( diff --git a/packages/core/lib/presentation/widget/draggable_bottom_sheet/draggable_bottom_sheet2.dart b/packages/core/lib/presentation/widget/draggable_bottom_sheet/draggable_bottom_sheet2.dart new file mode 100644 index 0000000..91826d5 --- /dev/null +++ b/packages/core/lib/presentation/widget/draggable_bottom_sheet/draggable_bottom_sheet2.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import 'draggable_bottom_sheet_controller.dart'; + + +class DraggableBottomSheet2 extends GetView { + final Color? backgroundColor; + + const DraggableBottomSheet2({super.key, this.backgroundColor = Colors.white}); + + @override + Widget build(BuildContext context) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (controller.isVisible.value && !controller.isVisible.value) { + controller.show(); + } + }); + + return ObxValue((data) { + return Stack( + children: [ + // پس‌زمینه تیره + Positioned.fill( + child: GestureDetector( + onTap: () {}, + child: Container(color: Colors.black54), + ), + ), + // محتوای BottomSheet + AnimatedPositioned( + duration: Duration(milliseconds: 300), + curve: Curves.easeOut, + left: 0, + right: 0, + bottom: 0, + child: GestureDetector( + onVerticalDragUpdate: (details) { + controller.updateHeight(details.primaryDelta); + }, + child: Container( + height: 350, + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.vertical(top: Radius.circular(20)), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.1), + blurRadius: 10, + ), + ], + ), + child: Column( + children: [ + GestureDetector( + onTap: () {}, + child: Container( + padding: EdgeInsets.all(10), + child: Icon(Icons.drag_handle), + ), + ), + Expanded( + child: controller.items[data.value], + ), + ], + ), + ), + ), + ), + ], + ); + }, controller.currentIndex); + } +} diff --git a/packages/core/lib/presentation/widget/draggable_bottom_sheet/draggable_bottom_sheet_controller.dart b/packages/core/lib/presentation/widget/draggable_bottom_sheet/draggable_bottom_sheet_controller.dart index 5a1caef..2bf39e1 100644 --- a/packages/core/lib/presentation/widget/draggable_bottom_sheet/draggable_bottom_sheet_controller.dart +++ b/packages/core/lib/presentation/widget/draggable_bottom_sheet/draggable_bottom_sheet_controller.dart @@ -129,7 +129,8 @@ import 'draggable_bottom_sheet.dart'; class DraggableBottomSheetController extends GetxController { final RxBool isVisible = false.obs; final RxDouble currentHeight = 200.0.obs; - + RxList items = [].obs; + RxInt currentIndex = 0.obs; late double initialHeight; late double minHeight; late double maxHeight; @@ -158,9 +159,5 @@ class DraggableBottomSheetController extends GetxController { } } - @override - void onInit() { - super.onInit(); - } } diff --git a/packages/core/lib/presentation/widget/map/custom_marker.dart b/packages/core/lib/presentation/widget/map/custom_marker.dart new file mode 100644 index 0000000..d1e5cae --- /dev/null +++ b/packages/core/lib/presentation/widget/map/custom_marker.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; +import 'package:latlong2/latlong.dart'; + +class CustomMarker { + final LatLng point; + final VoidCallback? onTap; +final int? id; + + CustomMarker({ this.id, required this.point, this.onTap}); +} \ No newline at end of file diff --git a/packages/core/lib/presentation/widget/map/logic.dart b/packages/core/lib/presentation/widget/map/logic.dart index 0824b14..78ab225 100644 --- a/packages/core/lib/presentation/widget/map/logic.dart +++ b/packages/core/lib/presentation/widget/map/logic.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:flutter/animation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map_animations/flutter_map_animations.dart'; import 'package:geolocator/geolocator.dart'; @@ -8,13 +8,16 @@ import 'package:get/get.dart'; import 'package:latlong2/latlong.dart'; import 'package:rasadyar_core/utils/logger_utils.dart'; +import 'custom_marker.dart'; + enum ErrorLocationType { serviceDisabled, permissionDenied, none } class MapWidgetLogic extends GetxController with GetTickerProviderStateMixin { Rx currentLocation = LatLng(35.824891, 50.948025).obs; String tileType = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; - RxList markers = [].obs; + + RxList markers = [].obs; RxList allMarkers = [].obs; Rx mapController = MapController().obs; RxList errorLocationType = RxList(); @@ -61,6 +64,7 @@ class MapWidgetLogic extends GetxController with GetTickerProviderStateMixin { @override void onClose() { super.onClose(); + _debounceTimer?.cancel(); animatedMapController.dispose(); mapController.close(); } @@ -113,7 +117,9 @@ class MapWidgetLogic extends GetxController with GetTickerProviderStateMixin { final latLng = LatLng(position.latitude, position.longitude); currentLocation.value = latLng; - markers.add(latLng); + markers.add( + CustomMarker(id: -1, point: latLng, ), + ); animatedMapController.animateTo( dest: latLng, zoom: 18, @@ -132,7 +138,7 @@ class MapWidgetLogic extends GetxController with GetTickerProviderStateMixin { 'radius': 1000.0, }); - markers.addAll(filtered); + // markers.addAll(filtered); }); } @@ -148,4 +154,17 @@ class MapWidgetLogic extends GetxController with GetTickerProviderStateMixin { .where((marker) => distance(center, marker) <= radiusInMeters) .toList(); } + + void addMarker(CustomMarker marker) { + markers.add(marker); + } + + void setMarkers(List newMarkers) { + markers.value = newMarkers; + } + + void clearMarkers() { + markers.clear(); + } + } diff --git a/packages/core/lib/presentation/widget/map/view.dart b/packages/core/lib/presentation/widget/map/view.dart index 8fe6cc2..4204919 100644 --- a/packages/core/lib/presentation/widget/map/view.dart +++ b/packages/core/lib/presentation/widget/map/view.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:geolocator/geolocator.dart'; import 'package:get/get.dart'; -import 'package:latlong2/latlong.dart'; import 'package:rasadyar_core/presentation/common/app_color.dart'; import 'package:rasadyar_core/presentation/common/app_fonts.dart'; import 'package:rasadyar_core/presentation/common/assets.gen.dart'; @@ -13,7 +12,16 @@ import 'package:rasadyar_core/presentation/widget/buttons/outline_elevated.dart' import 'logic.dart'; class MapWidget extends GetView { - const MapWidget({super.key}); + final VoidCallback? initOnTap; + final Widget? initMarkerWidget; + final Widget markerWidget; + + const MapWidget({ + this.initOnTap, + this.initMarkerWidget, + required this.markerWidget, + super.key, + }); @override Widget build(BuildContext context) { @@ -48,8 +56,7 @@ class MapWidget extends GetView { onPressed: () async { var res = await Geolocator.openLocationSettings(); if (res) { - var service = - await controller.locationServiceEnabled(); + var service = await controller.locationServiceEnabled(); if (service) { controller.errorLocationType.remove( ErrorLocationType.serviceDisabled, @@ -59,7 +66,6 @@ class MapWidget extends GetView { } }, ), - contentPadding: EdgeInsets.all(8), onWillPop: () async { return controller.errorLocationType.isEmpty; @@ -71,9 +77,7 @@ class MapWidget extends GetView { Future.microtask(() { Get.defaultDialog( title: 'خطا', - content: const Text( - ' دسترسی به سرویس مکان‌یابی غیرفعال است', - ), + content: const Text(' دسترسی به سرویس مکان‌یابی غیرفعال است'), cancel: ROutlinedElevated( text: 'بررسی مجدد', width: 120, @@ -87,9 +91,7 @@ class MapWidget extends GetView { textStyle: AppFonts.yekan16, width: 120, onPressed: () async { - var res = await controller.checkPermission( - request: true, - ); + var res = await controller.checkPermission(request: true); if (res) { controller.errorLocationType.remove( ErrorLocationType.permissionDenied, @@ -110,7 +112,10 @@ class MapWidget extends GetView { } return const SizedBox.shrink(); }, controller.errorLocationType), - _buildMap(), _buildGpsButton(), _buildFilterButton()], + _buildMap(), + _buildGpsButton(), + _buildFilterButton(), + ], ); } @@ -122,16 +127,30 @@ class MapWidget extends GetView { initialCenter: currentLocation.value, initialZoom: 18, onPositionChanged: (camera, hasGesture) { - controller.debouncedUpdateVisibleMarkers(center: camera.center); + if (hasGesture) { + controller.debouncedUpdateVisibleMarkers(center: camera.center); + } + //controller.debouncedUpdateVisibleMarkers(center: camera.center); }, ), children: [ TileLayer(urlTemplate: controller.tileType), - ObxValue((markers) { + ObxValue((markers) { return MarkerLayer( markers: markers - .map((e) => markerWidget(marker: e, onTap: () {})) + .map( + (e) => Marker( + point: e.point, + child: GestureDetector( + onTap: e.id != -1 ? e.onTap : initOnTap, + child: + e.id != -1 + ? markerWidget + : initMarkerWidget ?? SizedBox.shrink(), + ), + ), + ) .toList(), ); }, controller.markers), @@ -171,21 +190,18 @@ class MapWidget extends GetView { ); } - Marker markerWidget({required LatLng marker, required VoidCallback onTap}) { + /*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, - ) + width: 36, + height: 36, + child: Assets.vec.mapMarkerSvg.svg(width: 30, height: 30), ), ), ); - } + }*/ } diff --git a/packages/core/lib/presentation/widget/widget.dart b/packages/core/lib/presentation/widget/widget.dart index 546efec..bdcab01 100644 --- a/packages/core/lib/presentation/widget/widget.dart +++ b/packages/core/lib/presentation/widget/widget.dart @@ -6,6 +6,7 @@ export 'buttons/outline_elevated.dart'; export 'buttons/outline_elevated_icon.dart'; export 'buttons/text_button.dart'; export 'draggable_bottom_sheet/draggable_bottom_sheet.dart'; +export 'draggable_bottom_sheet/draggable_bottom_sheet2.dart'; export 'draggable_bottom_sheet/draggable_bottom_sheet_controller.dart'; export 'draggable_bottom_sheet/bottom_sheet_manger.dart'; export 'inputs/r_input.dart'; diff --git a/packages/livestock/lib/presentation/page/map/logic.dart b/packages/livestock/lib/presentation/page/map/logic.dart index c54ed07..04370f3 100644 --- a/packages/livestock/lib/presentation/page/map/logic.dart +++ b/packages/livestock/lib/presentation/page/map/logic.dart @@ -2,7 +2,7 @@ import 'package:rasadyar_core/core.dart'; class MapLogic extends GetxController { - + var ss = Get.find(); } diff --git a/packages/livestock/lib/presentation/page/map/view.dart b/packages/livestock/lib/presentation/page/map/view.dart index d05b39f..6935217 100644 --- a/packages/livestock/lib/presentation/page/map/view.dart +++ b/packages/livestock/lib/presentation/page/map/view.dart @@ -1,9 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter/material.dart' as mt; import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/presentation/widget/map/view.dart'; - - import 'logic.dart'; class MapPage extends GetView { @@ -14,9 +11,20 @@ class MapPage extends GetView { return Scaffold( body: Stack( children: [ - MapWidget(), + MapWidget( + markerWidget: Icon(Icons.pin_drop_rounded), + initOnTap: () { + + }, + initMarkerWidget: Assets.vec.mapMarkerSvg.svg( + width: 30, + height: 30, + ), + ), + ], ), ); } -} \ No newline at end of file +} + diff --git a/packages/livestock/lib/presentation/page/request_tagging/logic.dart b/packages/livestock/lib/presentation/page/request_tagging/logic.dart index ee5f9ee..de94cdb 100644 --- a/packages/livestock/lib/presentation/page/request_tagging/logic.dart +++ b/packages/livestock/lib/presentation/page/request_tagging/logic.dart @@ -1,9 +1,10 @@ +import 'package:flutter/material.dart'; import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_livestock/presentation/page/root/logic.dart'; class RequestTaggingLogic extends GetxController { - +final TextEditingController phoneController = TextEditingController(); @override void onReady() { super.onReady(); diff --git a/packages/livestock/lib/presentation/page/request_tagging/view.dart b/packages/livestock/lib/presentation/page/request_tagging/view.dart index 67d773a..0ff57ed 100644 --- a/packages/livestock/lib/presentation/page/request_tagging/view.dart +++ b/packages/livestock/lib/presentation/page/request_tagging/view.dart @@ -1,5 +1,7 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:get/get.dart'; +import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_livestock/presentation/routes/app_pages.dart'; import 'logic.dart'; @@ -9,37 +11,98 @@ class RequestTaggingPage extends GetView { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: const Text('Request Tagging'), - centerTitle: true, - actions: [ - IconButton( - icon: const Icon(Icons.search), - onPressed: () { - // Implement search functionality - }, - ), - ], + backgroundColor: Colors.white, + appBar: RAppBar( + title: 'درخواست پلاک کوبی', + leadingWidth: 40, + leading: Assets.vec.messageAddSvg.svg(width: 12, height: 12), ), - body: Column( - children: [ - const SizedBox(height: 16), - - const SizedBox(height: 16), - Expanded( - child: ListView.builder( - itemCount: 10, // Replace with your data length - itemBuilder: (context, index) { - return ListTile( - title: Text('Request Item $index'), - onTap: () { - // Handle item tap - }, - ); - }, + body: Padding( + padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 15), + child: Column( + children: [ + RTextField( + controller: controller.phoneController, + label: 'تلفن دامدار', ), - ), - ], + + SizedBox( + width: Get.width, + height: 356, + child: Card( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Expanded( + child: Container( + width: Get.width, + + decoration: BoxDecoration( + color: AppColor.lightGreyNormal, + borderRadius: BorderRadius.circular(8), + ), + child: Center( + child: Assets.images.placeHolder.image( + height: 150, + width: 200, + ), + ), + ), + ), + SizedBox(height: 15), + Container( + width: Get.width, + height: 40, + clipBehavior: Clip.antiAlias, + decoration: ShapeDecoration( + color: AppColor.blueNormal, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + ' تصویر گله', + style: AppFonts.yekan14.copyWith( + color: Colors.white, + ), + ), + Icon( + CupertinoIcons.arrow_up_doc, + color: Colors.white, + ), + ], + ), + ), + ), + ], + ), + ), + ), + ), + + Spacer(), + + + + RElevated( + text: 'ارسال تصویر گله', + onPressed: () { + Get.toNamed(LiveStockRoutes.tagging); + }, + height: 40, + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + ), + ], + ), ), ); } diff --git a/packages/livestock/lib/presentation/page/requests/view.dart b/packages/livestock/lib/presentation/page/requests/view.dart index 966ea7c..b656387 100644 --- a/packages/livestock/lib/presentation/page/requests/view.dart +++ b/packages/livestock/lib/presentation/page/requests/view.dart @@ -93,7 +93,7 @@ class RequestsPage extends GetView { itemBuilder: (context, index) { return GestureDetector( onTap: () { - Get.toNamed(LiveStockRoutes.requestTagging,id: 0); + Get.toNamed(LiveStockRoutes.requestTagging); }, child: Container( width: Get.width, diff --git a/packages/livestock/lib/presentation/page/root/view.dart b/packages/livestock/lib/presentation/page/root/view.dart index 879add1..f506375 100644 --- a/packages/livestock/lib/presentation/page/root/view.dart +++ b/packages/livestock/lib/presentation/page/root/view.dart @@ -9,6 +9,7 @@ class RootPage extends GetView { @override Widget build(BuildContext context) { return ObxValue((currentIndex) { + return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { @@ -16,7 +17,6 @@ class RootPage extends GetView { eLog('Pop invoked with result: $result, didPop: $didPop'); navigatorKey?.currentState?.pop(); - /*eLog('Pop invoked with result: $result, didPop: $didPop'); iLog(Get.currentRoute); iLog(Get.previousRoute); @@ -39,11 +39,11 @@ class RootPage extends GetView { child: Scaffold( body: IndexedStack( - children: controller.pages, + children: [...controller.pages], index: currentIndex.value, sizing: StackFit.expand, ), - + extendBody: true, bottomNavigationBar: BottomNavigation1( items: [ BottomNavigation1Item( diff --git a/packages/livestock/lib/presentation/page/tagging/logic.dart b/packages/livestock/lib/presentation/page/tagging/logic.dart new file mode 100644 index 0000000..f543973 --- /dev/null +++ b/packages/livestock/lib/presentation/page/tagging/logic.dart @@ -0,0 +1,15 @@ +import 'package:get/get.dart'; + +class TaggingLogic extends GetxController { + @override + void onReady() { + // TODO: implement onReady + super.onReady(); + } + + @override + void onClose() { + // TODO: implement onClose + super.onClose(); + } +} diff --git a/packages/livestock/lib/presentation/page/tagging/view.dart b/packages/livestock/lib/presentation/page/tagging/view.dart new file mode 100644 index 0000000..6bb7f25 --- /dev/null +++ b/packages/livestock/lib/presentation/page/tagging/view.dart @@ -0,0 +1,239 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_core/presentation/widget/buttons/fab.dart'; + +import 'logic.dart'; + +class TaggingPage extends GetView { + const TaggingPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: RAppBar( + title: 'پلاک کوبی', + leadingWidth: 40, + leading: Assets.vec.messageAddSvg.svg(width: 12, height: 12), + ), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 15), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Container( + height: 40, + decoration: BoxDecoration( + color: AppColor.greenLightHover, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight), + ), + alignment: Alignment.center, + child: Text('آمار ثبت شده : سبک 5 و سنگین 8 راس'), + ), + ), + SizedBox(width: 4), + IconButton( + onPressed: () {}, + style: IconButton.styleFrom( + backgroundColor: AppColor.blueNormal, + fixedSize: Size(40, 40), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + icon: Assets.vec.editSvg.svg(), + ), + ], + ), + + Expanded( + child: Card( + clipBehavior: Clip.hardEdge, + color: Colors.white, + child: Stack( + fit: StackFit.expand, + children: [ + GridView.builder( + padding: EdgeInsets.symmetric( + horizontal: 20, + vertical: 10, + ), + itemCount: 20, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 12, + mainAxisSpacing: 8, + ), + itemBuilder: (context, index) { + return Container( + decoration: ShapeDecoration( + color: AppColor.lightGreyLightHover, + shape: RoundedRectangleBorder( + side: BorderSide( + width: 1, + color: AppColor.blackLightHover, + ), + borderRadius: BorderRadius.circular(8), + ), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Assets.vec.editSvg.svg( + width: 16, + height: 16, + colorFilter: ColorFilter.mode( + AppColor.blueNormal, + BlendMode.srcIn, + ), + ), + Assets.vec.trashSvg.svg( + width: 16, + height: 16, + colorFilter: ColorFilter.mode( + AppColor.error, + BlendMode.srcIn, + ), + ), + ], + ), + Text( + 'گوسفند ماده', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith( + color: AppColor.blueNormal, + ), + ), + SizedBox(height: 10), + Text( + 'سن : 18 ماه', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith( + color: AppColor.darkGreyNormal, + ), + ), + Text( + 'نوع نژاد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith( + color: AppColor.bgDark, + ), + ), + Text( + '1212115112512', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith( + color: AppColor.blueNormal, + ), + ), + Text( + 'نوع پلاک', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith( + color: AppColor.bgDark, + ), + ), + ], + ), + ), + ); + }, + ), + + Positioned( + bottom: 10, + right: 3, + child: RFab.add( + onPressed: () { + Get.bottomSheet( + Container( + padding: EdgeInsets.all(20), + color: Colors.white, + height: 300, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + height: 40, + width: Get.width, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all( + width: 1, + color: AppColor.darkGreyLight, + ), + ), + child: GestureDetector( + onTap: () { + + }, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + 'گونه دام', + style: AppFonts.yekan14, + ), + Icon(CupertinoIcons.chevron_up), + ], + ), + ), + ), + /* DropdownMenu( + width: Get.width, + + dropdownMenuEntries: [ + DropdownMenuEntry( + value: 'گوسفند', + label: 'گوسفند', + ), + DropdownMenuEntry( + value: 'بز', + label: 'بز', + ), + DropdownMenuEntry( + value: 'گوساله', + label: 'گوساله', + ), + ], + ),*/ + ], + ), + ), + isScrollControlled: true, + ); + }, + ), + ), + ], + ), + ), + ), + + SizedBox(height: 10), + + RElevated( + text: 'ثبت نهایی و ارسال به اتحادیه', + textStyle: AppFonts.yekan18, + height: 40, + backgroundColor: AppColor.greenNormal, + onPressed: () {}, + isFullWidth: true, + ), + ], + ), + ), + ); + } +} diff --git a/packages/livestock/lib/presentation/routes/app_pages.dart b/packages/livestock/lib/presentation/routes/app_pages.dart index b74d313..1ca33e7 100644 --- a/packages/livestock/lib/presentation/routes/app_pages.dart +++ b/packages/livestock/lib/presentation/routes/app_pages.dart @@ -8,6 +8,8 @@ import 'package:rasadyar_livestock/presentation/page/request_tagging/view.dart'; import 'package:rasadyar_livestock/presentation/page/requests/logic.dart'; import 'package:rasadyar_livestock/presentation/page/root/logic.dart'; import 'package:rasadyar_livestock/presentation/page/root/view.dart'; +import 'package:rasadyar_livestock/presentation/page/tagging/logic.dart'; +import 'package:rasadyar_livestock/presentation/page/tagging/view.dart'; part 'app_routes.dart'; @@ -26,18 +28,35 @@ sealed class LiveStockPages { Get.lazyPut(() => ProfileLogic()); Get.lazyPut(() => ProfileLogic()); Get.lazyPut(() => MapWidgetLogic()); + Get.lazyPut(() => DraggableBottomSheetController()); }), children: [ - GetPage( + /*GetPage( name: LiveStockRoutes.requestTagging, page: () => RequestTaggingPage(), middlewares: [AuthMiddleware()], binding: BindingsBuilder(() { Get.lazyPut(() => RequestTaggingLogic()); }), - ), - ] + ),*/ + ], ), + GetPage( + name: LiveStockRoutes.requestTagging, + page: () => RequestTaggingPage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => RequestTaggingLogic()); + }), + ), + GetPage( + name: LiveStockRoutes.tagging, + page: () => TaggingPage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => TaggingLogic()); + }), + ), ]; } diff --git a/packages/livestock/lib/presentation/routes/app_routes.dart b/packages/livestock/lib/presentation/routes/app_routes.dart index 616d5ee..95a777a 100644 --- a/packages/livestock/lib/presentation/routes/app_routes.dart +++ b/packages/livestock/lib/presentation/routes/app_routes.dart @@ -6,5 +6,8 @@ sealed class LiveStockRoutes { static const init = '/liveStock'; static const requests = '/requests'; static const profile = '/profile'; - static const requestTagging = '$init/tagging'; + + //static const requestTagging = '$init/tagging'; + static const requestTagging = '$requests/tagging'; + static const tagging = '/tagging'; }