diff --git a/assets/icons/app_bar_inspection.svg b/assets/icons/app_bar_inspection.svg new file mode 100644 index 0000000..ea72d5f --- /dev/null +++ b/assets/icons/app_bar_inspection.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/icons/people.svg b/assets/icons/people.svg new file mode 100644 index 0000000..9c1edd3 --- /dev/null +++ b/assets/icons/people.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/assets/icons/profile2.svg b/assets/icons/profile2.svg new file mode 100644 index 0000000..a164e84 --- /dev/null +++ b/assets/icons/profile2.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/assets/icons/shop.svg b/assets/icons/shop.svg new file mode 100644 index 0000000..1c5dde5 --- /dev/null +++ b/assets/icons/shop.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/vec/app_bar_inspection.svg.vec b/assets/vec/app_bar_inspection.svg.vec new file mode 100644 index 0000000..eaa08e3 Binary files /dev/null and b/assets/vec/app_bar_inspection.svg.vec differ diff --git a/assets/vec/people.svg.vec b/assets/vec/people.svg.vec new file mode 100644 index 0000000..acf8c0b Binary files /dev/null and b/assets/vec/people.svg.vec differ diff --git a/assets/vec/profile2.svg.vec b/assets/vec/profile2.svg.vec new file mode 100644 index 0000000..d9f7baa Binary files /dev/null and b/assets/vec/profile2.svg.vec differ diff --git a/assets/vec/shop.svg.vec b/assets/vec/shop.svg.vec new file mode 100644 index 0000000..f02a218 Binary files /dev/null and b/assets/vec/shop.svg.vec differ diff --git a/lib/presentation/pages/splash/logic.dart b/lib/presentation/pages/splash/logic.dart index 4c779be..1000b9a 100644 --- a/lib/presentation/pages/splash/logic.dart +++ b/lib/presentation/pages/splash/logic.dart @@ -6,6 +6,7 @@ import 'package:rasadyar_app/data/model/app_info_model.dart'; import 'package:rasadyar_app/presentation/routes/app_pages.dart'; import 'package:rasadyar_auth/data/services/token_storage_service.dart'; import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_inspection/inspection.dart'; class SplashLogic extends GetxController with GetTickerProviderStateMixin { late final AnimationController scaleController; @@ -156,7 +157,7 @@ class SplashLogic extends GetxController with GetTickerProviderStateMixin { final module = tokenService.appModule.value; final target = getTargetPage(module); - Get.offAndToNamed(target); + Get.offAndToNamed(InspectionRoutes.init); } catch (e, st) { debugPrint("onReady error: $e\n$st"); } diff --git a/lib/presentation/routes/app_pages.dart b/lib/presentation/routes/app_pages.dart index 049b90d..534f0e8 100644 --- a/lib/presentation/routes/app_pages.dart +++ b/lib/presentation/routes/app_pages.dart @@ -1,11 +1,9 @@ import 'package:rasadyar_app/presentation/pages/splash/logic.dart'; import 'package:rasadyar_app/presentation/pages/splash/view.dart'; import 'package:rasadyar_app/presentation/pages/system_design/system_design.dart'; -import 'package:rasadyar_auth/auth.dart'; import 'package:rasadyar_auth/data/models/local/user_local/user_local_model.dart'; import 'package:rasadyar_auth/presentation/routes/pages.dart'; import 'package:rasadyar_chicken/chicken.dart'; -import 'package:rasadyar_chicken/presentation/routes/pages.dart'; import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_inspection/inspection.dart'; import 'package:rasadyar_livestock/presentation/routes/app_pages.dart'; @@ -36,12 +34,12 @@ sealed class AppPages { String getTargetPage(Module? value) { switch (value) { case Module.inspection: - return InspectionRoutes.inspection; + return InspectionRoutes.init; case Module.liveStocks: return LiveStockRoutes.init; case Module.chicken: return ChickenRoutes.init; default: - return ChickenRoutes.init; + return InspectionRoutes.init; } } diff --git a/packages/auth/lib/presentation/pages/auth/logic.dart b/packages/auth/lib/presentation/pages/auth/logic.dart index a339239..76fdc40 100644 --- a/packages/auth/lib/presentation/pages/auth/logic.dart +++ b/packages/auth/lib/presentation/pages/auth/logic.dart @@ -133,7 +133,7 @@ class AuthLogic extends GetxController { await safeCall( call: () => authTmp.login( authRequest: { - "username": phoneNumberController.value.text, + "username": usernameController.value.text, "password": passwordController.value.text, }, ), diff --git a/packages/auth/lib/presentation/pages/auth/view.dart b/packages/auth/lib/presentation/pages/auth/view.dart index 80215ad..60fe93a 100644 --- a/packages/auth/lib/presentation/pages/auth/view.dart +++ b/packages/auth/lib/presentation/pages/auth/view.dart @@ -102,13 +102,13 @@ class AuthPage extends GetView { label: 'نام کاربری', maxLength: 11, maxLines: 1, - controller: controller.phoneNumberController.value, + controller: controller.usernameController.value, keyboardType: TextInputType.number, - initText: controller.phoneNumberController.value.text, + initText: controller.usernameController.value.text, autofillHints: [AutofillHints.username], onChanged: (value) async { - controller.phoneNumberController.value.text = value; - controller.phoneNumberController.refresh(); + controller.usernameController.value.text = value; + controller.usernameController.refresh(); if (value.length == 11) { await controller.getUserInfo(value); } @@ -117,18 +117,18 @@ class AuthPage extends GetView { padding: const EdgeInsets.fromLTRB(0, 8, 6, 8), child: Assets.vec.callSvg.svg(width: 12, height: 12), ), - suffixIcon: controller.phoneNumberController.value.text.trim().isNotEmpty + suffixIcon: controller.usernameController.value.text.trim().isNotEmpty ? clearButton(() { - controller.phoneNumberController.value.clear(); - controller.phoneNumberController.refresh(); + controller.usernameController.value.clear(); + controller.usernameController.refresh(); }) : null, validator: (value) { - if (value == null || value.isEmpty) { + /* if (value == null || value.isEmpty) { return '⚠️ شماره موبایل را وارد کنید'; - } else if (value.length < 11) { + } else if (value.length < 10) { return '⚠️ شماره موبایل باید 11 رقم باشد'; - } + }*/ return null; }, style: AppFonts.yekan13, diff --git a/packages/chicken/lib/presentation/pages/root/view.dart b/packages/chicken/lib/presentation/pages/root/view.dart index 6579a21..cceffb6 100644 --- a/packages/chicken/lib/presentation/pages/root/view.dart +++ b/packages/chicken/lib/presentation/pages/root/view.dart @@ -160,7 +160,7 @@ class RootPage extends GetView { mainAxisAlignment: MainAxisAlignment.center, spacing: 4, children: [ - Assets.icons.cubeScan.svg(width: 30, height: 30), + Assets.icons.cubeScan.svg(width: 30.w, height: 30), Text( 'بارهای امروز', textAlign: TextAlign.right, diff --git a/packages/core/lib/presentation/common/app_color.dart b/packages/core/lib/presentation/common/app_color.dart index f676d19..40069d1 100644 --- a/packages/core/lib/presentation/common/app_color.dart +++ b/packages/core/lib/presentation/common/app_color.dart @@ -147,6 +147,9 @@ class AppColor { static const Color redDarkActive = Color(0xFF6a2727); // #6a2727 rgb(106, 39, 39) static const Color redDarker = Color(0xFF521e1e); // #521e1e rgb(82, 30, 30) static const Color redDarkerText = Color(0xFFD24E4E); // #D34E4E rgba(211, 78, 78, 1) + + static const Color redLight2 = Color(0xFFEDDCE0); // #EDDCE0 rgb(237, 220, 224) + static const Color redLightActive2 = Color(0xFFE0BCC5); // #E0BCC5 rgb(224, 188, 197) //endregion //region --- Teal Colors --- @@ -166,6 +169,8 @@ class AppColor { static const Color bgDark = Color(0xFF979797); // #083940 rgb(8, 57, 64) static const Color textColor = Color(0xFF5B5B5B); // #083940 rgb(8, 57, 64) static const Color textColorLight = Color(0xFFB2B2B2); + static const Color iconColor = Color(0xFF444444); // #444444 rgb(68, 68, 68) + static const Color borderColor = Color(0xFFC7CFCD); // #C7CFCD rgb(199, 207, 205)` //endregion diff --git a/packages/core/lib/presentation/common/assets.gen.dart b/packages/core/lib/presentation/common/assets.gen.dart index 9eda0b7..44a3854 100644 --- a/packages/core/lib/presentation/common/assets.gen.dart +++ b/packages/core/lib/presentation/common/assets.gen.dart @@ -37,6 +37,9 @@ class $AssetsIconsGen { /// File path: assets/icons/add.svg SvgGenImage get add => const SvgGenImage('assets/icons/add.svg'); + /// File path: assets/icons/app_bar_inspection.svg + SvgGenImage get appBarInspection => const SvgGenImage('assets/icons/app_bar_inspection.svg'); + /// File path: assets/icons/arrow_left.svg SvgGenImage get arrowLeft => const SvgGenImage('assets/icons/arrow_left.svg'); @@ -172,12 +175,18 @@ class $AssetsIconsGen { /// File path: assets/icons/pdf_download.svg SvgGenImage get pdfDownload => const SvgGenImage('assets/icons/pdf_download.svg'); + /// File path: assets/icons/people.svg + SvgGenImage get people => const SvgGenImage('assets/icons/people.svg'); + /// 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/profile2.svg + SvgGenImage get profile2 => const SvgGenImage('assets/icons/profile2.svg'); + /// File path: assets/icons/profile_circle.svg SvgGenImage get profileCircle => const SvgGenImage('assets/icons/profile_circle.svg'); @@ -205,6 +214,9 @@ class $AssetsIconsGen { /// File path: assets/icons/setting.svg SvgGenImage get setting => const SvgGenImage('assets/icons/setting.svg'); + /// File path: assets/icons/shop.svg + SvgGenImage get shop => const SvgGenImage('assets/icons/shop.svg'); + /// File path: assets/icons/shopping_basket.svg SvgGenImage get shoppingBasket => const SvgGenImage('assets/icons/shopping_basket.svg'); @@ -251,6 +263,7 @@ class $AssetsIconsGen { List get values => [ a3dCubeSquare, add, + appBarInspection, arrowLeft, arrowRight, bgHeaderUserProfile, @@ -296,8 +309,10 @@ class $AssetsIconsGen { messageAdd, outside, pdfDownload, + people, pictureFrame, placeHolder, + profile2, profileCircle, profileUser, receiptDiscount, @@ -307,6 +322,7 @@ class $AssetsIconsGen { search, securityTime, setting, + shop, shoppingBasket, tagLabel, tagUser, @@ -362,6 +378,9 @@ class $AssetsVecGen { /// File path: assets/vec/add.svg.vec SvgGenImage get addSvg => const SvgGenImage.vec('assets/vec/add.svg.vec'); + /// File path: assets/vec/app_bar_inspection.svg.vec + SvgGenImage get appBarInspectionSvg => const SvgGenImage.vec('assets/vec/app_bar_inspection.svg.vec'); + /// File path: assets/vec/arrow_left.svg.vec SvgGenImage get arrowLeftSvg => const SvgGenImage.vec('assets/vec/arrow_left.svg.vec'); @@ -497,12 +516,18 @@ class $AssetsVecGen { /// File path: assets/vec/pdf_download.svg.vec SvgGenImage get pdfDownloadSvg => const SvgGenImage.vec('assets/vec/pdf_download.svg.vec'); + /// File path: assets/vec/people.svg.vec + SvgGenImage get peopleSvg => const SvgGenImage.vec('assets/vec/people.svg.vec'); + /// File path: assets/vec/picture_frame.svg.vec SvgGenImage get pictureFrameSvg => const SvgGenImage.vec('assets/vec/picture_frame.svg.vec'); /// File path: assets/vec/place_holder.svg.vec SvgGenImage get placeHolderSvg => const SvgGenImage.vec('assets/vec/place_holder.svg.vec'); + /// File path: assets/vec/profile2.svg.vec + SvgGenImage get profile2Svg => const SvgGenImage.vec('assets/vec/profile2.svg.vec'); + /// File path: assets/vec/profile_circle.svg.vec SvgGenImage get profileCircleSvg => const SvgGenImage.vec('assets/vec/profile_circle.svg.vec'); @@ -530,6 +555,9 @@ class $AssetsVecGen { /// File path: assets/vec/setting.svg.vec SvgGenImage get settingSvg => const SvgGenImage.vec('assets/vec/setting.svg.vec'); + /// File path: assets/vec/shop.svg.vec + SvgGenImage get shopSvg => const SvgGenImage.vec('assets/vec/shop.svg.vec'); + /// File path: assets/vec/shopping_basket.svg.vec SvgGenImage get shoppingBasketSvg => const SvgGenImage.vec('assets/vec/shopping_basket.svg.vec'); @@ -576,6 +604,7 @@ class $AssetsVecGen { List get values => [ a3dCubeSquareSvg, addSvg, + appBarInspectionSvg, arrowLeftSvg, arrowRightSvg, bgHeaderUserProfileSvg, @@ -621,8 +650,10 @@ class $AssetsVecGen { messageAddSvg, outsideSvg, pdfDownloadSvg, + peopleSvg, pictureFrameSvg, placeHolderSvg, + profile2Svg, profileCircleSvg, profileUserSvg, receiptDiscountSvg, @@ -632,6 +663,7 @@ class $AssetsVecGen { searchSvg, securityTimeSvg, settingSvg, + shopSvg, shoppingBasketSvg, tagLabelSvg, tagUserSvg, 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 d6b921b..e04ebaf 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 @@ -53,7 +53,9 @@ class RAppBar extends StatelessWidget implements PreferredSizeWidget { ) : null, leadingWidth: leadingWidth?.toDouble(), - leading: leading != null ? Padding(padding: const EdgeInsets.only(right: 6), child: leading) : null, + leading: leading != null + ? Padding(padding: const EdgeInsets.only(right: 6), child: leading) + : null, titleSpacing: 8, actions: [ if (additionalActions != null) ...additionalActions!, diff --git a/packages/core/lib/presentation/widget/bottom_navigation/r_bottom_navigation.dart b/packages/core/lib/presentation/widget/bottom_navigation/r_bottom_navigation.dart index 0d91e27..d4299bc 100644 --- a/packages/core/lib/presentation/widget/bottom_navigation/r_bottom_navigation.dart +++ b/packages/core/lib/presentation/widget/bottom_navigation/r_bottom_navigation.dart @@ -2,9 +2,10 @@ import 'package:flutter/material.dart'; import 'package:rasadyar_core/core.dart'; class RBottomNavigation extends StatefulWidget { - const RBottomNavigation({super.key, required this.items}); + RBottomNavigation({super.key, required this.items,this.mainAxisAlignment}); final List items; + MainAxisAlignment? mainAxisAlignment; @override State createState() => _RBottomNavigationState(); @@ -18,9 +19,15 @@ class _RBottomNavigationState extends State { padding: EdgeInsets.symmetric(horizontal: 11.w, vertical: 18.h), decoration: BoxDecoration( color: AppColor.blueNormal, - borderRadius: const BorderRadius.only(topLeft: Radius.circular(32), topRight: Radius.circular(32)), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(32), + topRight: Radius.circular(32), + ), + ), + child: Row( + mainAxisAlignment: widget.mainAxisAlignment??MainAxisAlignment.spaceBetween, + children: widget.items, ), - child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: widget.items), ); } } @@ -57,10 +64,18 @@ class RBottomNavigationItem extends StatelessWidget { SvgGenImage.vec(icon).svg( width: 40.w, height: 40.h, - colorFilter: ColorFilter.mode(isSelected ? AppColor.blueNormal : Colors.white, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + isSelected ? AppColor.blueNormal : Colors.white, + BlendMode.srcIn, + ), ), SizedBox(height: 5.h), - Text(label, style: AppFonts.yekan10.copyWith(color: isSelected ? AppColor.blueNormal : Colors.white)), + Text( + label, + style: AppFonts.yekan10.copyWith( + color: isSelected ? AppColor.blueNormal : Colors.white, + ), + ), ], ), ), diff --git a/packages/inspection/lib/presentation/filter/view.dart b/packages/inspection/lib/presentation/filter/view.dart index 1508409..6dad128 100644 --- a/packages/inspection/lib/presentation/filter/view.dart +++ b/packages/inspection/lib/presentation/filter/view.dart @@ -11,7 +11,7 @@ class SupervisionFilterPage extends GetView { @override Widget build(BuildContext context) { return Scaffold( - appBar: RAppBar.noBack(title: 'نقشه', additionalActions: [_searchButton(), _filterButton()]), + appBar: RAppBar(title: 'نقشه', additionalActions: [_searchButton(), _filterButton()]), body: PopScope( canPop: !controller.bottomSheetManager.isAnyVisible, onPopInvokedWithResult: (didPop, result) { diff --git a/packages/inspection/lib/presentation/inspection_map/logic.dart b/packages/inspection/lib/presentation/inspection_map/logic.dart new file mode 100644 index 0000000..fdd97c7 --- /dev/null +++ b/packages/inspection/lib/presentation/inspection_map/logic.dart @@ -0,0 +1,151 @@ + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_inspection/data/utils/marker_generator.dart'; +import 'package:rasadyar_inspection/presentation/widget/base_page/logic.dart'; + +import '../filter/view.dart'; + +class InspectionMapLogic extends GetxController with GetTickerProviderStateMixin { + + final BaseLogic baseLogic = Get.find(); + + Rx currentLocation = LatLng(35.824891, 50.948025).obs; + RxList allMarkers = [].obs; + RxList markers = [].obs; + Timer? _debounceTimer; + RxBool isLoading = false.obs; + + RxInt filterIndex = 0.obs; + RxInt showIndex = 0.obs; + bool showSlideHint = true; + + late Rx slidController; + + Rx mapController = MapController().obs; + late final AnimatedMapController animatedMapController; + + late DraggableBottomSheetController filterBottomSheetController; + late DraggableBottomSheetController selectedLocationBottomSheetController; + late DraggableBottomSheetController detailsLocationBottomSheetController; + late final BottomSheetManager bottomSheetManager; + + Future determineCurrentPosition() async { + isLoading.value = true; + final position = await Geolocator.getCurrentPosition( + locationSettings: AndroidSettings(accuracy: LocationAccuracy.best), + ); + final latLng = LatLng(position.latitude, position.longitude); + + currentLocation.value = latLng; + markers.add(latLng); + animatedMapController.animateTo( + dest: latLng, + zoom: 18, + curve: Curves.easeInOut, + duration: const Duration(seconds: 1), + ); + isLoading.value = false; + } + + void debouncedUpdateVisibleMarkers({required LatLng center}) { + _debounceTimer?.cancel(); + _debounceTimer = Timer(const Duration(milliseconds: 300), () { + final filtered = filterNearbyMarkers({ + 'markers': allMarkers, + 'centerLat': center.latitude, + 'centerLng': center.longitude, + 'radius': 2000.0, + }); + + markers.addAll(filtered); + }); + } + + List filterNearbyMarkers(Map args) { + final List rawMarkers = args['markers']; + final double centerLat = args['centerLat']; + final double centerLng = args['centerLng']; + final double radiusInMeters = args['radius']; + final center = LatLng(centerLat, centerLng); + final distance = Distance(); + + return rawMarkers + .where((marker) => distance(center, marker) <= radiusInMeters) + .toList(); + } + + Future generatedMarkers() async { + final generatedMarkers = await generateLocationsUsingCompute(100000); + allMarkers.value = generatedMarkers; + } + + @override + void onInit() { + super.onInit(); + animatedMapController = AnimatedMapController( + vsync: this, + duration: const Duration(milliseconds: 500), + curve: Curves.easeInOut, + cancelPreviousAnimations: true, + ); + + filterBottomSheetController = DraggableBottomSheetController( + initialHeight: 350, + minHeight: 200, + maxHeight: Get.height * 0.5, + ); + + selectedLocationBottomSheetController = DraggableBottomSheetController( + initialHeight: 200, + minHeight: 100, + maxHeight: 200, + ); + + + detailsLocationBottomSheetController = DraggableBottomSheetController( + initialHeight: Get.height * 0.5, + minHeight: Get.height * 0.37, + maxHeight: Get.height * 0.5, + ); + + slidController = SlidableController(this).obs; + bottomSheetManager = BottomSheetManager({ + filterBottomSheetController: + () => filterWidget(filterIndex: filterIndex, showIndex: showIndex), + selectedLocationBottomSheetController: + () => selectedLocationWidget( + showHint: + selectedLocationBottomSheetController.isVisible.value && + showSlideHint, + sliderController: slidController.value, + trigger: triggerSlidableAnimation, + toggle: selectedLocationBottomSheetController.toggle, + ), + detailsLocationBottomSheetController: () => markerDetailsWidget(), + }); + } + + @override + void onReady() { + super.onReady(); + determineCurrentPosition(); + generatedMarkers(); + } + + Future triggerSlidableAnimation() async { + await Future.delayed(Duration(milliseconds: 200)); + await slidController.value.openEndActionPane(); + await Future.delayed(Duration(milliseconds: 200)); + await slidController.value.close(); + showSlideHint = false; + } + + @override + void onClose() { + slidController.close(); + super.onClose(); + } +} diff --git a/packages/inspection/lib/presentation/inspection_map/view.dart b/packages/inspection/lib/presentation/inspection_map/view.dart new file mode 100644 index 0000000..385af1f --- /dev/null +++ b/packages/inspection/lib/presentation/inspection_map/view.dart @@ -0,0 +1,650 @@ +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/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'), + 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(), + ], + ), + ), + ), + ), + ), + ); +} diff --git a/packages/inspection/lib/presentation/root/logic.dart b/packages/inspection/lib/presentation/root/logic.dart index 31bd149..26c3d93 100644 --- a/packages/inspection/lib/presentation/root/logic.dart +++ b/packages/inspection/lib/presentation/root/logic.dart @@ -2,13 +2,14 @@ import 'package:flutter/material.dart'; import 'package:rasadyar_core/core.dart' ; import 'package:rasadyar_inspection/presentation/action/view.dart'; import 'package:rasadyar_inspection/presentation/filter/view.dart'; +import 'package:rasadyar_inspection/presentation/inspection_map/view.dart'; import 'package:rasadyar_inspection/presentation/profile/view.dart'; enum ErrorLocationType { serviceDisabled, permissionDenied, none } class RootLogic extends GetxController { RxInt currentIndex = 0.obs; - List pages = [SupervisionFilterPage(), ActionPage(), ProfilePage()]; + List pages = [InspectionMapPage(), ActionPage(), ProfilePage()]; RxList errorLocationType = RxList(); Stream listenToLocationServiceStatus() { diff --git a/packages/inspection/lib/presentation/root/view.dart b/packages/inspection/lib/presentation/root/view.dart index 2994617..578c5f8 100644 --- a/packages/inspection/lib/presentation/root/view.dart +++ b/packages/inspection/lib/presentation/root/view.dart @@ -8,168 +8,49 @@ class RootPage extends GetView { @override Widget build(BuildContext context) { - return Scaffold( - body: Stack( - children: [ - ObxValue((errorType) { - if (errorType.isNotEmpty) { - if (errorType.contains(ErrorLocationType.serviceDisabled)) { - Future.microtask(() { - Get.defaultDialog( - title: 'خطا', - content: const Text('سرویس مکان‌یابی غیرفعال است'), - cancel: ROutlinedElevated( - text: 'بررسی مجدد', - width: 120, - textStyle: AppFonts.yekan16, - onPressed: () async { - var service = await controller.locationServiceEnabled(); - eLog(service); - if (service) { - controller.errorLocationType.remove( - ErrorLocationType.serviceDisabled, - ); - Get.back(); - } - // Don't call Get.back() if service is still disabled - }, - ), - confirm: RElevated( - text: 'روشن کردن', - textStyle: AppFonts.yekan16, - width: 120, - onPressed: () async { - var res = await Geolocator.openLocationSettings(); - if (res) { - var service = - await controller.locationServiceEnabled(); - if (service) { - controller.errorLocationType.remove( - ErrorLocationType.serviceDisabled, - ); - Get.back(); - } - } - }, - ), + return ObxValue((currentIndex) { + return Scaffold( + body: ObxValue( + (currentIndex) => IndexedStack(index: currentIndex.value, children: controller.pages), + controller.currentIndex, + ), + bottomNavigationBar: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + items: [ + RBottomNavigationItem( + label: 'نقشه', + icon: Assets.vec.mapSvg.path, + isSelected: currentIndex.value == 0, + onTap: () { + Get.nestedKey(1)?.currentState?.popUntil((route) => route.isFirst); - contentPadding: EdgeInsets.all(8), - onWillPop: () async { - return controller.errorLocationType.isEmpty; - }, - barrierDismissible: false, - ); - }); - } else { - Future.microtask(() { - Get.defaultDialog( - title: 'خطا', - content: const Text( - ' دسترسی به سرویس مکان‌یابی غیرفعال است', - ), - cancel: ROutlinedElevated( - text: 'بررسی مجدد', - width: 120, - textStyle: AppFonts.yekan16, - onPressed: () async { - await controller.checkPermission(); - }, - ), - confirm: RElevated( - text: 'اجازه دادن', - textStyle: AppFonts.yekan16, - width: 120, - onPressed: () async { - var res = await controller.checkPermission( - request: true, - ); - if (res) { - controller.errorLocationType.remove( - ErrorLocationType.permissionDenied, - ); - Get.back(); - } - }, - ), + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'اقدام', + icon: Assets.vec.settingSvg.path, + isSelected: currentIndex.value == 1, + onTap: () { + Get.nestedKey(0)?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), - contentPadding: EdgeInsets.all(8), - onWillPop: () async { - return controller.errorLocationType.isEmpty; - }, - barrierDismissible: false, - ); - }); - } - } - return const SizedBox.shrink(); - }, controller.errorLocationType), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: currentIndex.value == 4, + onTap: () { + Get.nestedKey(1)?.currentState?.popUntil((route) => route.isFirst); + Get.nestedKey(0)?.currentState?.popUntil((route) => route.isFirst); - ObxValue( - (currentIndex) => IndexedStack( - index: currentIndex.value, - children: controller.pages, + controller.changePage(4); + }, ), - controller.currentIndex, - ), - - ], - ), - bottomNavigationBar: WaveBottomNavigation( - items: [ - WaveBottomNavigationItem(title: 'خانه', icon: Assets.vec.mapSvg.svg( - width: 32, - height: 32, - colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn), - )), - WaveBottomNavigationItem( - title: 'عملیات', - icon: Assets.vec.userSvg.svg( - width: 32, - height: 32, - colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn), - ), - ), - WaveBottomNavigationItem( - title: 'افزودن', - icon: Assets.vec.addSvg.svg( - width: 32, - height: 32, - colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn), - ), - ), - WaveBottomNavigationItem( - title: 'آمار', - icon: Assets.vec.diagramSvg.svg(width: 32,height: 32,colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn),), - ), - WaveBottomNavigationItem( - title: 'تماس', - icon: Assets.vec.callSvg.svg( - width: 32, - height: 32, - colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn), - ), - ), - WaveBottomNavigationItem( - title: 'مکان ', - icon: Assets.vec.gpsSvg.svg( - width: 32, - height: 32, - colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn), - ), - ), - WaveBottomNavigationItem( - title: 'تاریخ', - icon: Assets.vec.calendarSvg.svg( - width: 32, - height: 32, - colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn), - ), - ), - ], - onPageChanged: (index) { - controller.changePage(index); - }, - ), - ); + ], + ), + ); + }, controller.currentIndex); } } diff --git a/packages/inspection/lib/presentation/routes/app_pages.dart b/packages/inspection/lib/presentation/routes/app_pages.dart index 69ac156..816ae56 100644 --- a/packages/inspection/lib/presentation/routes/app_pages.dart +++ b/packages/inspection/lib/presentation/routes/app_pages.dart @@ -8,6 +8,7 @@ import 'package:rasadyar_inspection/presentation/add_supervision/view.dart'; import 'package:rasadyar_inspection/presentation/display_information/logic.dart'; import 'package:rasadyar_inspection/presentation/display_information/view.dart'; import 'package:rasadyar_inspection/presentation/filter/logic.dart'; +import 'package:rasadyar_inspection/presentation/inspection_map/logic.dart'; import 'package:rasadyar_inspection/presentation/location_details/logic.dart'; import 'package:rasadyar_inspection/presentation/location_details/view.dart'; import 'package:rasadyar_inspection/presentation/profile/logic.dart'; @@ -17,18 +18,21 @@ import 'package:rasadyar_inspection/presentation/registration_of_violation/view. import 'package:rasadyar_inspection/presentation/root/logic.dart'; import 'package:rasadyar_inspection/presentation/root/view.dart'; import 'package:rasadyar_inspection/presentation/routes/app_routes.dart'; +import 'package:rasadyar_inspection/presentation/widget/base_page/logic.dart'; sealed class InspectionPages { InspectionPages._(); static final pages = [ GetPage( - name: InspectionRoutes.inspection, + name: InspectionRoutes.init, page: () => RootPage(), - middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { Get.put(RootLogic()); Get.put(InspectorFilterLogic()); + Get.lazyPut(()=>InspectionMapLogic()); + Get.lazyPut(()=>BaseLogic()); Get.lazyPut(() => LocationDetailsLogic(), fenix: true); Get.lazyPut(() => ActionLogic(), fenix: true); Get.lazyPut(() => ProfileLogic(), fenix: true); diff --git a/packages/inspection/lib/presentation/routes/app_routes.dart b/packages/inspection/lib/presentation/routes/app_routes.dart index beff1e6..97b9549 100644 --- a/packages/inspection/lib/presentation/routes/app_routes.dart +++ b/packages/inspection/lib/presentation/routes/app_routes.dart @@ -1,10 +1,10 @@ sealed class InspectionRoutes { InspectionRoutes._(); - static const inspection = '/supervision'; - static const inspectionAction = '$inspection/action'; - static const inspectionUserProfile = '$inspection/userSettings'; - static const inspectionLocationDetails = '$inspection/locationDetails'; + static const init = '/supervision'; + static const inspectionAction = '$init/action'; + static const inspectionUserProfile = '$init/userSettings'; + static const inspectionLocationDetails = '$init/locationDetails'; static const inspectionAddSupervision = '$inspectionLocationDetails/addSupervision'; static const inspectionAddMobileInspector = '$inspectionLocationDetails/addMobileInspector'; static const inspectionRegistrationOfViolation = '$inspectionAddSupervision/RegistrationOfViolation'; diff --git a/packages/inspection/lib/presentation/widget/app_bar/i_app_bar.dart b/packages/inspection/lib/presentation/widget/app_bar/i_app_bar.dart new file mode 100644 index 0000000..d49c50d --- /dev/null +++ b/packages/inspection/lib/presentation/widget/app_bar/i_app_bar.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_inspection/presentation/widget/base_page/logic.dart'; + +RAppBar inspectionAppBar({ + bool hasBack = true, + bool hasFilter = true, + bool hasSearch = true, + bool isBase = false, + VoidCallback? onBackPressed, + GestureTapCallback? onFilterTap, + GestureTapCallback? onSearchTap, +}) { + return RAppBar( + hasBack: isBase == true ? false : hasBack, + onBackPressed: onBackPressed, + leadingWidth: 155, + leading: Row( + mainAxisSize: MainAxisSize.min, + spacing: 6, + children: [ + Text('رصدبان', style: AppFonts.yekan16Bold.copyWith(color: Colors.white)), + Assets.vec.appBarInspectionSvg.svg(width: 24, height: 24), + ], + ), + additionalActions: [ + if (!isBase && hasSearch) searchWidget(onSearchTap), + SizedBox(width: 8), + if (!isBase && hasFilter) filterWidget(onFilterTap), + SizedBox(width: 8), + ], + ); +} + +GestureDetector filterWidget(GestureTapCallback? onFilterTap) { + return GestureDetector( + onTap: onFilterTap, + child: Stack( + alignment: Alignment.topRight, + children: [ + Assets.vec.filterOutlineSvg.svg( + width: 20, + height: 20, + colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), + ), + Obx(() { + final controller = Get.find(); + return Visibility( + visible: controller.isFilterSelected.value, + child: Container( + width: 8, + height: 8, + decoration: const BoxDecoration(color: Colors.red, shape: BoxShape.circle), + ), + ); + }), + ], + ), + ); +} + +GestureDetector searchWidget(GestureTapCallback? onSearchTap) { + return GestureDetector( + onTap: onSearchTap, + child: Stack( + alignment: Alignment.topRight, + children: [ + Assets.vec.searchSvg.svg( + width: 24, + height: 24, + colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), + ), + Obx(() { + final controller = Get.find(); + return Visibility( + visible: controller.searchValue.value != null, + child: Container( + width: 8, + height: 8, + decoration: const BoxDecoration(color: Colors.red, shape: BoxShape.circle), + ), + ); + }), + ], + ), + ); +} diff --git a/packages/inspection/lib/presentation/widget/base_page/logic.dart b/packages/inspection/lib/presentation/widget/base_page/logic.dart new file mode 100644 index 0000000..dbba195 --- /dev/null +++ b/packages/inspection/lib/presentation/widget/base_page/logic.dart @@ -0,0 +1,23 @@ +import 'package:rasadyar_core/core.dart'; + +class BaseLogic extends GetxController { + final RxBool isFilterSelected = false.obs; + final RxBool isSearchSelected = false.obs; + final RxnString searchValue = RxnString(); + + void setSearchCallback(void Function(String)? onSearchChanged) { + debounce(searchValue, (val) { + if (val != null && val.trim().isNotEmpty) { + onSearchChanged?.call(val); + } + }, time: const Duration(milliseconds: 600)); + } + + void toggleFilter() { + isFilterSelected.value = !isFilterSelected.value; + } + + void toggleSearch() { + isSearchSelected.value = !isSearchSelected.value; + } +} diff --git a/packages/inspection/lib/presentation/widget/base_page/view.dart b/packages/inspection/lib/presentation/widget/base_page/view.dart new file mode 100644 index 0000000..278cb89 --- /dev/null +++ b/packages/inspection/lib/presentation/widget/base_page/view.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_inspection/presentation/widget/app_bar/i_app_bar.dart'; +import 'package:rasadyar_inspection/presentation/widget/search.dart'; + +import 'logic.dart'; + +class BasePage extends StatefulWidget { + const BasePage({ + super.key, + this.routes, + required this.widgets, + this.routesWidget, + this.floatingActionButtonLocation, + this.floatingActionButton, + this.onSearchChanged, + this.hasBack = true, + this.hasFilter = true, + this.hasSearch = true, + this.isBase = false, + this.defaultSearch = true, + this.onBackPressed, + this.onFilterTap, + this.onSearchTap, + this.filteringWidget, + + }); + + final List? routes; + final Widget? routesWidget; + final bool defaultSearch; + final List widgets; + final FloatingActionButtonLocation? floatingActionButtonLocation; + final Widget? floatingActionButton; + final Widget? filteringWidget; + final void Function(String?)? onSearchChanged; + final bool hasBack; + final bool hasFilter; + final bool hasSearch; + final bool isBase; + final VoidCallback? onBackPressed; + final GestureTapCallback? onFilterTap; + final GestureTapCallback? onSearchTap; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + BaseLogic get controller => Get.find(); + Worker? filterWorker; + bool _isBottomSheetOpen = false; + + @override + void initState() { + super.initState(); + /* filterWorker = ever(controller.isFilterSelected, (bool isSelected) { + if (!mounted) return; + + if (isSelected && widget.filteringWidget != null) { + // بررسی اینکه آیا bottomSheet از قبل باز است یا نه + if (_isBottomSheetOpen) { + controller.isFilterSelected.value = false; + return; + } + + // بررسی اینکه آیا route فعلی current است یا نه + if (ModalRoute.of(context)?.isCurrent != true) { + controller.isFilterSelected.value = false; + return; + } + + _isBottomSheetOpen = true; + Get.bottomSheet( + widget.filteringWidget!, + isScrollControlled: true, + isDismissible: true, + enableDrag: true, + ).then((_) { + // تنظیم مقدار به false بعد از بسته شدن bottomSheet + if (mounted) { + _isBottomSheetOpen = false; + controller.isFilterSelected.value = false; + } + }); + } + });*/ + } + + @override + void dispose() { + filterWorker?.dispose(); + super.dispose(); + } + + void _onFilterTap() { + if (widget.hasFilter && widget.filteringWidget != null) { + + final currentRoute = ModalRoute.of(context); + if (currentRoute?.isCurrent != true) { + return; + } + + + Get.bottomSheet( + widget.filteringWidget!, + isScrollControlled: true, + isDismissible: true, + enableDrag: true, + ); + } + } + + @override + Widget build(BuildContext context) { + return PopScope( + canPop: false, + onPopInvokedWithResult: (didPop, result) => widget.onBackPressed, + child: Scaffold( + backgroundColor: AppColor.bgLight, + appBar: inspectionAppBar( + hasBack: widget.isBase ? false : widget.hasBack, + onBackPressed: widget.onBackPressed, + hasFilter: widget.hasFilter, + hasSearch: widget.hasSearch, + isBase: widget.isBase, + onFilterTap: widget.hasFilter ? _onFilterTap : null, + onSearchTap: widget.hasSearch ? () => controller.toggleSearch() : null, + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //widget.routesWidget != null ? widget.routesWidget! : buildPageRoute(widget.routes!), + if (!widget.isBase && widget.hasSearch && widget.defaultSearch) ...{ + SearchWidget(onSearchChanged: widget.onSearchChanged), + }, + ...widget.widgets, + ], + ), + floatingActionButtonLocation: + widget.floatingActionButtonLocation ?? FloatingActionButtonLocation.startFloat, + floatingActionButton: widget.floatingActionButton, + ), + ); + } +} diff --git a/packages/inspection/lib/presentation/widget/search.dart b/packages/inspection/lib/presentation/widget/search.dart new file mode 100644 index 0000000..9c72439 --- /dev/null +++ b/packages/inspection/lib/presentation/widget/search.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_inspection/presentation/widget/base_page/logic.dart'; + + +class SearchWidget extends StatefulWidget { + const SearchWidget({super.key, this.onSearchChanged}); + + final void Function(String?)? onSearchChanged; + + @override + State createState() => _SearchWidgetState(); +} + +class _SearchWidgetState extends State { + late final BaseLogic controller; + final TextEditingController textEditingController = TextEditingController(); + + @override + void initState() { + super.initState(); + controller = Get.find(); + controller.setSearchCallback(widget.onSearchChanged); + } + + @override + Widget build(BuildContext context) { + return ObxValue((data) { + return AnimatedContainer( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + height: data.value ? 40 : 0, + child: Visibility( + visible: data.value, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: RTextField( + height: 40, + borderColor: AppColor.blackLight, + suffixIcon: ObxValue( + (data) => Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: (data.value == null) + ? Assets.vec.searchSvg.svg( + width: 10, + height: 10, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ) + : IconButton( + onPressed: () { + textEditingController.clear(); + controller.searchValue.value = null; + controller.isSearchSelected.value = false; + widget.onSearchChanged?.call(null); + }, + enableFeedback: true, + padding: EdgeInsets.zero, + iconSize: 24, + splashRadius: 50, + icon: Assets.vec.closeCircleSvg.svg( + width: 20, + height: 20, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ), + controller.searchValue, + ), + hintText: 'جستجو کنید ...', + hintStyle: AppFonts.yekan16.copyWith(color: AppColor.blueNormal), + filledColor: Colors.white, + filled: true, + controller: textEditingController, + onChanged: (val) => controller.searchValue.value = val, + ), + ), + ), + ); + }, controller.isSearchSelected); + } +} diff --git a/packages/inspection/pubspec.lock b/packages/inspection/pubspec.lock index 50a6a53..ac492d9 100644 --- a/packages/inspection/pubspec.lock +++ b/packages/inspection/pubspec.lock @@ -5,18 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: e55636ed79578b9abca5fecf9437947798f5ef7456308b5cb85720b793eac92f + sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f url: "https://pub.dev" source: hosted - version: "82.0.0" + version: "85.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "904ae5bb474d32c38fb9482e2d925d5454cda04ddd0e55d2e6826bc72f6ba8c0" + sha256: "974859dc0ff5f37bc4313244b3218c791810d03ab3470a579580279ba971a48d" url: "https://pub.dev" source: hosted - version: "7.4.5" + version: "7.7.1" + android_intent_plus: + dependency: transitive + description: + name: android_intent_plus + sha256: dfc1fd3a577205ae8f11e990fb4ece8c90cceabbee56fcf48e463ecf0bd6aae3 + url: "https://pub.dev" + source: hosted + version: "5.3.0" archive: dependency: transitive description: @@ -37,10 +45,10 @@ packages: dependency: transitive description: name: asn1lib - sha256: "0511d6be23b007e95105ae023db599aea731df604608978dada7f9faf2637623" + sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" url: "https://pub.dev" source: hosted - version: "1.6.4" + version: "1.6.5" async: dependency: transitive description: @@ -49,14 +57,78 @@ packages: url: "https://pub.dev" source: hosted version: "2.13.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" build: dependency: transitive description: name: build - sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0 + sha256: "7d95cbbb1526ab5ae977df9b4cc660963b9b27f6d1075c0b34653868911385e4" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "3.0.0" + build_config: + dependency: transitive + description: + name: build_config + sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa" + url: "https://pub.dev" + source: hosted + version: "4.0.4" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "38c9c339333a09b090a638849a4c56e70a404c6bdd3b511493addfbc113b60c2" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + build_runner: + dependency: transitive + description: + name: build_runner + sha256: b971d4a1c789eba7be3e6fe6ce5e5b50fd3719e3cb485b3fad6d04358304351d + url: "https://pub.dev" + source: hosted + version: "2.6.0" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: c04e612ca801cd0928ccdb891c263a2b1391cb27940a5ea5afcf9ba894de5d62 + url: "https://pub.dev" + source: hosted + version: "9.2.0" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "0b1b12a0a549605e5f04476031cd0bc91ead1d7c8e830773a18ee54179b3cb62" + url: "https://pub.dev" + source: hosted + version: "8.11.0" characters: dependency: transitive description: @@ -65,6 +137,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + url: "https://pub.dev" + source: hosted + version: "2.0.4" clock: dependency: transitive description: @@ -73,6 +153,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + url: "https://pub.dev" + source: hosted + version: "4.10.1" collection: dependency: transitive description: @@ -97,6 +185,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + url: "https://pub.dev" + source: hosted + version: "0.3.4+2" crypto: dependency: transitive description: @@ -121,14 +217,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + dart_polylabel2: + dependency: transitive + description: + name: dart_polylabel2 + sha256: "7eeab15ce72894e4bdba6a8765712231fc81be0bd95247de4ad9966abc57adc6" + url: "https://pub.dev" + source: hosted + version: "1.0.0" dart_style: dependency: transitive description: name: dart_style - sha256: "5b236382b47ee411741447c1f1e111459c941ea1b3f2b540dde54c210a3662af" + sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" dartx: dependency: transitive description: @@ -137,6 +241,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + dbus: + dependency: transitive + description: + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + url: "https://pub.dev" + source: hosted + version: "0.7.11" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a" + url: "https://pub.dev" + source: hosted + version: "11.5.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f + url: "https://pub.dev" + source: hosted + version: "7.0.3" dio: dependency: transitive description: @@ -177,6 +305,38 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.1" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" + url: "https://pub.dev" + source: hosted + version: "0.9.3+2" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: "8c9250b2bd2d8d4268e39c82543bacbaca0fda7d29e0728c3c4bbb7c820fd711" + url: "https://pub.dev" + source: hosted + version: "0.9.4+3" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + url: "https://pub.dev" + source: hosted + version: "2.6.2" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" + url: "https://pub.dev" + source: hosted + version: "0.9.3+4" fixnum: dependency: transitive description: @@ -194,18 +354,18 @@ packages: dependency: transitive description: name: flutter_gen_core - sha256: "3eaa2d3d8be58267ac4cd5e215ac965dd23cae0410dc073de2e82e227be32bfc" + sha256: eda54fdc5de08e7eeea663eb8442aafc8660b5a13fda4e0c9e572c64e50195fb url: "https://pub.dev" source: hosted - version: "5.10.0" + version: "5.11.0" flutter_gen_runner: dependency: transitive description: name: flutter_gen_runner - sha256: e74b4ead01df3e8f02e73a26ca856759dbbe8cb3fd60941ba9f4005cd0cd19c9 + sha256: "669bf8b7a9b4acbdcb7fcc5e12bf638aca19acedf43341714cbca3bf3a219521" url: "https://pub.dev" source: hosted - version: "5.10.0" + version: "5.11.0" flutter_localizations: dependency: transitive description: flutter @@ -215,10 +375,10 @@ packages: dependency: transitive description: name: flutter_map - sha256: f7d0379477274f323c3f3bc12d369a2b42eb86d1e7bd2970ae1ea3cff782449a + sha256: df33e784b09fae857c6261a5521dd42bd4d3342cb6200884bb70730638af5fd5 url: "https://pub.dev" source: hosted - version: "8.1.1" + version: "8.2.1" flutter_map_animations: dependency: transitive description: @@ -227,6 +387,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e + url: "https://pub.dev" + source: hosted + version: "2.0.28" flutter_rating_bar: dependency: transitive description: @@ -235,6 +403,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.1" + flutter_screenutil: + dependency: transitive + description: + name: flutter_screenutil + sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de" + url: "https://pub.dev" + source: hosted + version: "5.9.3" flutter_secure_storage: dependency: transitive description: @@ -295,10 +471,10 @@ packages: dependency: transitive description: name: flutter_svg - sha256: d44bf546b13025ec7353091516f6881f1d4c633993cb109c3916c3a0159dadf1 + sha256: cd57f7969b4679317c17af6fd16ee233c1e60a82ed209d8a475c54fd6fd6f845 url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.2.0" flutter_web_plugins: dependency: transitive description: flutter @@ -316,26 +492,42 @@ packages: dependency: transitive description: name: freezed_annotation - sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b + sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.1.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + geoclue: + dependency: transitive + description: + name: geoclue + sha256: c2a998c77474fc57aa00c6baa2928e58f4b267649057a1c76738656e9dbd2a7f + url: "https://pub.dev" + source: hosted + version: "0.1.1" geolocator: dependency: transitive description: name: geolocator - sha256: ee2212a3df8292ec4c90b91183b8001d3f5a800823c974b570c5f9344ca320dc + sha256: "79939537046c9025be47ec645f35c8090ecadb6fe98eba146a0d25e8c1357516" url: "https://pub.dev" source: hosted - version: "14.0.1" + version: "14.0.2" geolocator_android: dependency: transitive description: name: geolocator_android - sha256: "114072db5d1dce0ec0b36af2697f55c133bc89a2c8dd513e137c0afe59696ed4" + sha256: "179c3cb66dfa674fc9ccbf2be872a02658724d1c067634e2c427cf6df7df901a" url: "https://pub.dev" source: hosted - version: "5.0.1+1" + version: "5.0.2" geolocator_apple: dependency: transitive description: @@ -344,6 +536,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.13" + geolocator_linux: + dependency: transitive + description: + name: geolocator_linux + sha256: c4e966f0a7a87e70049eac7a2617f9e16fd4c585a26e4330bdfc3a71e6a721f3 + url: "https://pub.dev" + source: hosted + version: "0.2.3" geolocator_platform_interface: dependency: transitive description: @@ -392,6 +592,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + gsettings: + dependency: transitive + description: + name: gsettings + sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c" + url: "https://pub.dev" + source: hosted + version: "0.2.8" hashcodes: dependency: transitive description: @@ -420,10 +636,18 @@ packages: dependency: transitive description: name: http - sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" + sha256: "85ab0074f9bf2b24625906d8382bbec84d3d6919d285ba9c106b07b65791fb99" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.5.0-beta.2" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.dev" + source: hosted + version: "3.2.2" http_parser: dependency: transitive description: @@ -432,6 +656,78 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + url: "https://pub.dev" + source: hosted + version: "4.5.4" + image_picker: + dependency: transitive + description: + name: image_picker + sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: "6fae381e6af2bbe0365a5e4ce1db3959462fa0c4d234facf070746024bb80c8d" + url: "https://pub.dev" + source: hosted + version: "0.8.12+24" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83" + url: "https://pub.dev" + source: hosted + version: "3.0.6" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100" + url: "https://pub.dev" + source: hosted + version: "0.8.12+2" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9" + url: "https://pub.dev" + source: hosted + version: "0.2.1+2" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1" + url: "https://pub.dev" + source: hosted + version: "0.2.1+2" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0" + url: "https://pub.dev" + source: hosted + version: "2.10.1" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" image_size_getter: dependency: transitive description: @@ -448,6 +744,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.20.2" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://pub.dev" + source: hosted + version: "1.0.5" isolate_channel: dependency: transitive description: @@ -492,10 +796,10 @@ packages: dependency: transitive description: name: logger - sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 + sha256: "55d6c23a6c15db14920e037fe7e0dc32e7cdaf3b64b4b25df2d541b5b6b81c0c" url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.1" logging: dependency: transitive description: @@ -504,6 +808,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + lottie: + dependency: transitive + description: + name: lottie + sha256: c5fa04a80a620066c15cf19cc44773e19e9b38e989ff23ea32e5903ef1015950 + url: "https://pub.dev" + source: hosted + version: "3.3.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.dev" + source: hosted + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -544,6 +864,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + package_info_plus: + dependency: transitive + description: + name: package_info_plus + sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191" + url: "https://pub.dev" + source: hosted + version: "8.3.0" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c" + url: "https://pub.dev" + source: hosted + version: "3.2.0" path: dependency: transitive description: @@ -612,10 +948,10 @@ packages: dependency: transitive description: name: permission_handler - sha256: "2d070d8684b68efb580a5997eb62f675e8a885ef0be6e754fb9ef489c177470f" + sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1 url: "https://pub.dev" source: hosted - version: "12.0.0+1" + version: "12.0.1" permission_handler_android: dependency: transitive description: @@ -696,22 +1032,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.9.1" - polylabel: + pool: dependency: transitive description: - name: polylabel - sha256: "41b9099afb2aa6c1730bdd8a0fab1400d287694ec7615dd8516935fa3144214b" + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.5.1" posix: dependency: transitive description: name: posix - sha256: f0d7856b6ca1887cfa6d1d394056a296ae33489db914e365e2044fdada449e62 + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" url: "https://pub.dev" source: hosted - version: "6.0.2" + version: "6.0.3" pretty_dio_logger: dependency: transitive description: @@ -736,20 +1072,28 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + url: "https://pub.dev" + source: hosted + version: "1.5.0" rasadyar_auth: dependency: "direct main" description: path: "../auth" relative: true source: path - version: "0.0.1" + version: "1.0.3" rasadyar_core: dependency: "direct main" description: path: "../core" relative: true source: path - version: "1.0.0+1" + version: "1.2.0+2" rxdart: dependency: transitive description: @@ -762,10 +1106,34 @@ packages: dependency: transitive description: name: shamsi_date - sha256: b6c79ff34ddfb1e9e4761347f18e30afdd7d16cc3db77defd5a40e2d93894c51 + sha256: "0383fddc9bce91e9e08de0c909faf93c3ab3a0e532abd271fb0dcf5d0617487b" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + shimmer: + dependency: transitive + description: + name: shimmer + sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9" + url: "https://pub.dev" + source: hosted + version: "3.0.0" sky_engine: dependency: transitive description: flutter @@ -787,6 +1155,30 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://pub.dev" + source: hosted + version: "2.1.1" string_scanner: dependency: transitive description: @@ -803,6 +1195,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.2" + test_api: + dependency: transitive + description: + name: test_api + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + url: "https://pub.dev" + source: hosted + version: "0.7.7" time: dependency: transitive description: @@ -811,6 +1211,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.5" + timing: + dependency: transitive + description: + name: timing + sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" + url: "https://pub.dev" + source: hosted + version: "1.0.2" typed_data: dependency: transitive description: @@ -839,10 +1247,10 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de" + sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 url: "https://pub.dev" source: hosted - version: "1.1.18" + version: "1.1.19" vector_graphics_codec: dependency: transitive description: @@ -871,10 +1279,10 @@ packages: dependency: transitive description: name: watcher - sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" + sha256: "0b7fd4a0bbc4b92641dbf20adfd7e3fd1398fe17102d94b674234563e110088a" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" web: dependency: transitive description: @@ -883,14 +1291,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" win32: dependency: transitive description: name: win32 - sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba" + sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "5.14.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + url: "https://pub.dev" + source: hosted + version: "2.1.0" wkt_parser: dependency: transitive description: @@ -925,4 +1357,4 @@ packages: version: "3.1.3" sdks: dart: ">=3.8.1 <4.0.0" - flutter: ">=3.27.0" + flutter: ">=3.29.0" diff --git a/packages/inspection/pubspec.yaml b/packages/inspection/pubspec.yaml index 2af4c35..a4ab581 100644 --- a/packages/inspection/pubspec.yaml +++ b/packages/inspection/pubspec.yaml @@ -1,7 +1,7 @@ name: rasadyar_inspection description: "inspection module for rasadyar" publish_to: 'none' -version: 1.0.1 +version: 1.2.0 environment: sdk: ^3.8.1