From 11aa18c46cffc0a56ec9b03aa59487f805d12d90 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Thu, 16 Apr 2026 14:22:46 +0700 Subject: [PATCH] major file change --- .editorconfig | 5 + .gitignore | 0 README.md | 0 ...64-BE4B.251210.005-2026-03-06-09-42-33.zip | Bin capacitor.config.json | 0 components.json | 0 entities/probindo.com/Comodity.json | 0 entities/probindo.com/Distribution.json | 0 entities/probindo.com/Farmer.json | 0 entities/probindo.com/Harvest.json | 0 entities/probindo.com/Land.json | 0 entities/probindo.com/LandValidation.json | 0 entities/probindo.com/Offtakers.json | 0 entities/probindo.com/Plant.json | 0 entities/probindo.com/PlantInspection.json | 0 entities/probindo.com/Synclog.json | 0 entities/probindo.com/User/me.json | 0 entities/probindo.com/Validator.json | 0 entities/public-settings/probindo.com.json | 0 eslint.config.js | 0 index.html | 2 +- jsconfig.json | 0 package-lock.json | 26 + package.json | 1 + pertanian-app.code-workspace | 9 + postcss.config.js | 0 public/logo1.png | Bin 0 -> 70171 bytes public/logo_001.png | Bin 0 -> 24539 bytes public/sql-wasm.wasm | Bin src/.gitignore | 0 src/App.jsx | 0 src/App_baru.jsx | 0 src/Layout copy.jsx | 0 src/Layout.jsx | 33 +- src/Layout2.jsx | 2 +- src/_mock/api_lama.js | 0 src/_mock/data/Comodity.json | 0 src/_mock/data/Distribution.json | 0 src/_mock/data/Farmer.json | 0 src/_mock/data/Harvest.json | 0 src/_mock/data/Inspection.json | 0 src/_mock/data/Land.json | 0 src/_mock/data/LandValidation.json | 0 src/_mock/data/Offtaker.json | 0 src/_mock/data/Plant.json | 0 src/_mock/data/PlantInspection.json | 0 src/_mock/data/Province.json | 0 src/_mock/data/Synclog.json | 0 src/_mock/data/offlineData.js | 0 src/_mock/data/propinsi.json | 0 src/_mock/data/validator.json | 0 src/_mock/schema/Comodity.json | 0 src/_mock/schema/Distribution.json | 0 src/_mock/schema/Farmer.json | 0 src/_mock/schema/Land.json | 0 src/_mock/schema/LandValidation.json | 0 src/_mock/schema/Plant.json | 0 src/_mock/schema/PlantInspection.json | 0 src/_mock/schema/Synclog.json | 0 src/_mock/schema/Validator.json | 0 src/_mock/schema/farmers.json | 0 src/_mock/schema/lands.json | 0 src/_mock/schema/plants.json | 0 src/api/Client.js | 0 src/api/entities.js | 0 src/components/UserNotRegisteredError.jsx | 0 src/components/common/EmptyState.jsx | 0 src/components/common/OfflineStorage_001.jsx | 0 src/components/common/OfflineStorage_002.jsx | 0 src/components/common/RoleBasedGuard.jsx | 0 src/components/common/SyncManager copy.jsx | 0 src/components/common/SyncManager.jsx | 5 +- src/components/common/SyncStatus.jsx | 0 src/components/common/SyncStatusBar.jsx | 0 src/components/common/offlineStorage.jsx | 120 ++++- .../common/useOfflineEntity copy.jsx | 0 src/components/common/useOfflineEntity.jsx | 0 .../dashboard/CommodityPieChart.jsx | 0 src/components/dashboard/RegionChart.jsx | 0 src/components/dashboard/StatCard.jsx | 0 .../distribution/DistributionForm.jsx | 0 .../distribution/DistributionForm_01.jsx | 0 .../distribution/DistributionGrading.jsx | 0 src/components/farmers/FarmerCard.jsx | 23 +- src/components/farmers/FarmerForm.jsx | 0 src/components/farmers/LinkUserAccount.jsx | 0 src/components/harvest/HarvestForm.jsx | 0 src/components/lands/GPSLandMapper copy 2.jsx | 242 +++++++++ src/components/lands/GPSLandMapper copy.jsx | 0 src/components/lands/GPSLandMapper.jsx | 370 ++++++------- src/components/lands/LandCard.jsx | 22 +- src/components/lands/LandMap copy.jsx | 0 src/components/lands/LandMap.jsx | 0 src/components/plants/GPSPLantTagger copy.jsx | 0 src/components/plants/GPSPLantTagger.jsx | 0 src/components/plants/PlantForm.jsx | 0 src/components/plants/PlantInspectionForm.jsx | 0 src/components/ui/accordion.jsx | 0 src/components/ui/alert-dialog.jsx | 0 src/components/ui/alert.jsx | 0 src/components/ui/aspect-ratio.jsx | 0 src/components/ui/avatar.jsx | 0 src/components/ui/badge.jsx | 0 src/components/ui/breadcrumb.jsx | 0 src/components/ui/button.jsx | 0 src/components/ui/calendar.jsx | 0 src/components/ui/card.jsx | 0 src/components/ui/carousel.jsx | 0 src/components/ui/chart.jsx | 0 src/components/ui/checkbox.jsx | 0 src/components/ui/collapsible.jsx | 0 src/components/ui/command.jsx | 0 src/components/ui/context-menu.jsx | 0 src/components/ui/dialog.jsx | 0 src/components/ui/drawer.jsx | 0 src/components/ui/dropdown-menu.jsx | 0 src/components/ui/form.jsx | 0 src/components/ui/hover-card.jsx | 0 src/components/ui/input-otp.jsx | 0 src/components/ui/input.jsx | 0 src/components/ui/label.jsx | 0 src/components/ui/menubar.jsx | 0 src/components/ui/navigation-menu.jsx | 0 src/components/ui/pagination.jsx | 0 src/components/ui/popper.jsx | 0 src/components/ui/progress.jsx | 0 src/components/ui/radio-group.jsx | 0 src/components/ui/resizable.jsx | 0 src/components/ui/scroll-area.jsx | 0 src/components/ui/select.jsx | 0 src/components/ui/sheet.jsx | 0 src/components/ui/sidebar.jsx | 0 src/components/ui/skeleton.jsx | 0 src/components/ui/slider.jsx | 0 src/components/ui/sonner.jsx | 0 src/components/ui/sparator.jsx | 0 src/components/ui/switch.jsx | 0 src/components/ui/table.jsx | 0 src/components/ui/tabs.jsx | 0 src/components/ui/textarea.jsx | 0 src/components/ui/toast.jsx | 0 src/components/ui/toaster.jsx | 0 src/components/ui/toggle-group.jsx | 0 src/components/ui/toggle.jsx | 0 src/components/ui/tooltip.jsx | 0 src/components/ui/use-toast.jsx | 0 src/hooks/use-mobile.jsx | 0 src/index.css | 0 src/lib/AuthContext copy.jsx | 0 src/lib/AuthContext.jsx | 26 +- src/lib/NavigationTracker.jsx | 0 src/lib/PageNotFound.jsx | 0 src/lib/app-params.js | 0 src/lib/query-client.js | 0 src/lib/utils.js | 0 src/main.jsx | 0 src/pages.config.js | 0 src/pages/Dashboard copy.jsx | 0 src/pages/Dashboard.jsx | 0 src/pages/FarmerDetail.jsx | 7 +- src/pages/FarmerPortal copy 2.jsx | 0 src/pages/FarmerPortal copy.jsx | 0 src/pages/FarmerPortal.jsx | 158 +++++- src/pages/FarmerRegister copy.jsx | 0 src/pages/FarmerRegister.jsx | 0 src/pages/Farmers.jsx | 15 +- src/pages/LandDetail.jsx | 2 +- src/pages/LandRegister.jsx | 0 src/pages/Lands.jsx | 28 +- src/pages/Login.jsx | 0 src/pages/NotAccessible.jsx | 0 src/pages/OfftakerPortal copy.jsx | 0 src/pages/OfftakerPortal.jsx | 0 src/pages/Offtakers.jsx | 8 +- src/pages/Plants.jsx | 36 +- src/pages/ProductivityMonitoring.jsx | 217 +++++++- src/pages/Register.jsx | 0 src/pages/ValidatorPortal copy.jsx | 398 ++++++++++++++ src/pages/ValidatorPortal.jsx | 505 ++++++++---------- src/pages/Validators.jsx | 12 +- src/repository/landRepository_lama.js | 0 src/services/networkService.js | 0 src/services/syncService_lama.js | 0 src/utils/db.js | 4 +- src/utils/index.ts | 0 src/utils/sqlClient.js | 0 src/utils/sqliteClient_2.js | 0 src/utils/sqliteClient_i.js | 0 tailwind.config.js | 0 vite.config.js | 0 190 files changed, 1651 insertions(+), 625 deletions(-) create mode 100644 .editorconfig mode change 100644 => 100755 .gitignore mode change 100644 => 100755 README.md mode change 100644 => 100755 bugreport-sdk_gphone64_arm64-BE4B.251210.005-2026-03-06-09-42-33.zip mode change 100644 => 100755 capacitor.config.json mode change 100644 => 100755 components.json mode change 100644 => 100755 entities/probindo.com/Comodity.json mode change 100644 => 100755 entities/probindo.com/Distribution.json mode change 100644 => 100755 entities/probindo.com/Farmer.json mode change 100644 => 100755 entities/probindo.com/Harvest.json mode change 100644 => 100755 entities/probindo.com/Land.json mode change 100644 => 100755 entities/probindo.com/LandValidation.json mode change 100644 => 100755 entities/probindo.com/Offtakers.json mode change 100644 => 100755 entities/probindo.com/Plant.json mode change 100644 => 100755 entities/probindo.com/PlantInspection.json mode change 100644 => 100755 entities/probindo.com/Synclog.json mode change 100644 => 100755 entities/probindo.com/User/me.json mode change 100644 => 100755 entities/probindo.com/Validator.json mode change 100644 => 100755 entities/public-settings/probindo.com.json mode change 100644 => 100755 eslint.config.js mode change 100644 => 100755 index.html mode change 100644 => 100755 jsconfig.json mode change 100644 => 100755 package-lock.json mode change 100644 => 100755 package.json mode change 100644 => 100755 pertanian-app.code-workspace mode change 100644 => 100755 postcss.config.js create mode 100644 public/logo1.png create mode 100755 public/logo_001.png mode change 100644 => 100755 public/sql-wasm.wasm mode change 100644 => 100755 src/.gitignore mode change 100644 => 100755 src/App.jsx mode change 100644 => 100755 src/App_baru.jsx mode change 100644 => 100755 src/Layout copy.jsx mode change 100644 => 100755 src/Layout.jsx mode change 100644 => 100755 src/Layout2.jsx mode change 100644 => 100755 src/_mock/api_lama.js mode change 100644 => 100755 src/_mock/data/Comodity.json mode change 100644 => 100755 src/_mock/data/Distribution.json mode change 100644 => 100755 src/_mock/data/Farmer.json mode change 100644 => 100755 src/_mock/data/Harvest.json mode change 100644 => 100755 src/_mock/data/Inspection.json mode change 100644 => 100755 src/_mock/data/Land.json mode change 100644 => 100755 src/_mock/data/LandValidation.json mode change 100644 => 100755 src/_mock/data/Offtaker.json mode change 100644 => 100755 src/_mock/data/Plant.json mode change 100644 => 100755 src/_mock/data/PlantInspection.json mode change 100644 => 100755 src/_mock/data/Province.json mode change 100644 => 100755 src/_mock/data/Synclog.json mode change 100644 => 100755 src/_mock/data/offlineData.js mode change 100644 => 100755 src/_mock/data/propinsi.json mode change 100644 => 100755 src/_mock/data/validator.json mode change 100644 => 100755 src/_mock/schema/Comodity.json mode change 100644 => 100755 src/_mock/schema/Distribution.json mode change 100644 => 100755 src/_mock/schema/Farmer.json mode change 100644 => 100755 src/_mock/schema/Land.json mode change 100644 => 100755 src/_mock/schema/LandValidation.json mode change 100644 => 100755 src/_mock/schema/Plant.json mode change 100644 => 100755 src/_mock/schema/PlantInspection.json mode change 100644 => 100755 src/_mock/schema/Synclog.json mode change 100644 => 100755 src/_mock/schema/Validator.json mode change 100644 => 100755 src/_mock/schema/farmers.json mode change 100644 => 100755 src/_mock/schema/lands.json mode change 100644 => 100755 src/_mock/schema/plants.json mode change 100644 => 100755 src/api/Client.js mode change 100644 => 100755 src/api/entities.js mode change 100644 => 100755 src/components/UserNotRegisteredError.jsx mode change 100644 => 100755 src/components/common/EmptyState.jsx mode change 100644 => 100755 src/components/common/OfflineStorage_001.jsx mode change 100644 => 100755 src/components/common/OfflineStorage_002.jsx mode change 100644 => 100755 src/components/common/RoleBasedGuard.jsx mode change 100644 => 100755 src/components/common/SyncManager copy.jsx mode change 100644 => 100755 src/components/common/SyncManager.jsx mode change 100644 => 100755 src/components/common/SyncStatus.jsx mode change 100644 => 100755 src/components/common/SyncStatusBar.jsx mode change 100644 => 100755 src/components/common/offlineStorage.jsx mode change 100644 => 100755 src/components/common/useOfflineEntity copy.jsx mode change 100644 => 100755 src/components/common/useOfflineEntity.jsx mode change 100644 => 100755 src/components/dashboard/CommodityPieChart.jsx mode change 100644 => 100755 src/components/dashboard/RegionChart.jsx mode change 100644 => 100755 src/components/dashboard/StatCard.jsx mode change 100644 => 100755 src/components/distribution/DistributionForm.jsx mode change 100644 => 100755 src/components/distribution/DistributionForm_01.jsx mode change 100644 => 100755 src/components/distribution/DistributionGrading.jsx mode change 100644 => 100755 src/components/farmers/FarmerCard.jsx mode change 100644 => 100755 src/components/farmers/FarmerForm.jsx mode change 100644 => 100755 src/components/farmers/LinkUserAccount.jsx mode change 100644 => 100755 src/components/harvest/HarvestForm.jsx create mode 100755 src/components/lands/GPSLandMapper copy 2.jsx mode change 100644 => 100755 src/components/lands/GPSLandMapper copy.jsx mode change 100644 => 100755 src/components/lands/GPSLandMapper.jsx mode change 100644 => 100755 src/components/lands/LandCard.jsx mode change 100644 => 100755 src/components/lands/LandMap copy.jsx mode change 100644 => 100755 src/components/lands/LandMap.jsx mode change 100644 => 100755 src/components/plants/GPSPLantTagger copy.jsx mode change 100644 => 100755 src/components/plants/GPSPLantTagger.jsx mode change 100644 => 100755 src/components/plants/PlantForm.jsx mode change 100644 => 100755 src/components/plants/PlantInspectionForm.jsx mode change 100644 => 100755 src/components/ui/accordion.jsx mode change 100644 => 100755 src/components/ui/alert-dialog.jsx mode change 100644 => 100755 src/components/ui/alert.jsx mode change 100644 => 100755 src/components/ui/aspect-ratio.jsx mode change 100644 => 100755 src/components/ui/avatar.jsx mode change 100644 => 100755 src/components/ui/badge.jsx mode change 100644 => 100755 src/components/ui/breadcrumb.jsx mode change 100644 => 100755 src/components/ui/button.jsx mode change 100644 => 100755 src/components/ui/calendar.jsx mode change 100644 => 100755 src/components/ui/card.jsx mode change 100644 => 100755 src/components/ui/carousel.jsx mode change 100644 => 100755 src/components/ui/chart.jsx mode change 100644 => 100755 src/components/ui/checkbox.jsx mode change 100644 => 100755 src/components/ui/collapsible.jsx mode change 100644 => 100755 src/components/ui/command.jsx mode change 100644 => 100755 src/components/ui/context-menu.jsx mode change 100644 => 100755 src/components/ui/dialog.jsx mode change 100644 => 100755 src/components/ui/drawer.jsx mode change 100644 => 100755 src/components/ui/dropdown-menu.jsx mode change 100644 => 100755 src/components/ui/form.jsx mode change 100644 => 100755 src/components/ui/hover-card.jsx mode change 100644 => 100755 src/components/ui/input-otp.jsx mode change 100644 => 100755 src/components/ui/input.jsx mode change 100644 => 100755 src/components/ui/label.jsx mode change 100644 => 100755 src/components/ui/menubar.jsx mode change 100644 => 100755 src/components/ui/navigation-menu.jsx mode change 100644 => 100755 src/components/ui/pagination.jsx mode change 100644 => 100755 src/components/ui/popper.jsx mode change 100644 => 100755 src/components/ui/progress.jsx mode change 100644 => 100755 src/components/ui/radio-group.jsx mode change 100644 => 100755 src/components/ui/resizable.jsx mode change 100644 => 100755 src/components/ui/scroll-area.jsx mode change 100644 => 100755 src/components/ui/select.jsx mode change 100644 => 100755 src/components/ui/sheet.jsx mode change 100644 => 100755 src/components/ui/sidebar.jsx mode change 100644 => 100755 src/components/ui/skeleton.jsx mode change 100644 => 100755 src/components/ui/slider.jsx mode change 100644 => 100755 src/components/ui/sonner.jsx mode change 100644 => 100755 src/components/ui/sparator.jsx mode change 100644 => 100755 src/components/ui/switch.jsx mode change 100644 => 100755 src/components/ui/table.jsx mode change 100644 => 100755 src/components/ui/tabs.jsx mode change 100644 => 100755 src/components/ui/textarea.jsx mode change 100644 => 100755 src/components/ui/toast.jsx mode change 100644 => 100755 src/components/ui/toaster.jsx mode change 100644 => 100755 src/components/ui/toggle-group.jsx mode change 100644 => 100755 src/components/ui/toggle.jsx mode change 100644 => 100755 src/components/ui/tooltip.jsx mode change 100644 => 100755 src/components/ui/use-toast.jsx mode change 100644 => 100755 src/hooks/use-mobile.jsx mode change 100644 => 100755 src/index.css mode change 100644 => 100755 src/lib/AuthContext copy.jsx mode change 100644 => 100755 src/lib/AuthContext.jsx mode change 100644 => 100755 src/lib/NavigationTracker.jsx mode change 100644 => 100755 src/lib/PageNotFound.jsx mode change 100644 => 100755 src/lib/app-params.js mode change 100644 => 100755 src/lib/query-client.js mode change 100644 => 100755 src/lib/utils.js mode change 100644 => 100755 src/main.jsx mode change 100644 => 100755 src/pages.config.js mode change 100644 => 100755 src/pages/Dashboard copy.jsx mode change 100644 => 100755 src/pages/Dashboard.jsx mode change 100644 => 100755 src/pages/FarmerDetail.jsx mode change 100644 => 100755 src/pages/FarmerPortal copy 2.jsx mode change 100644 => 100755 src/pages/FarmerPortal copy.jsx mode change 100644 => 100755 src/pages/FarmerPortal.jsx mode change 100644 => 100755 src/pages/FarmerRegister copy.jsx mode change 100644 => 100755 src/pages/FarmerRegister.jsx mode change 100644 => 100755 src/pages/Farmers.jsx mode change 100644 => 100755 src/pages/LandDetail.jsx mode change 100644 => 100755 src/pages/LandRegister.jsx mode change 100644 => 100755 src/pages/Lands.jsx mode change 100644 => 100755 src/pages/Login.jsx mode change 100644 => 100755 src/pages/NotAccessible.jsx mode change 100644 => 100755 src/pages/OfftakerPortal copy.jsx mode change 100644 => 100755 src/pages/OfftakerPortal.jsx mode change 100644 => 100755 src/pages/Offtakers.jsx mode change 100644 => 100755 src/pages/Plants.jsx mode change 100644 => 100755 src/pages/ProductivityMonitoring.jsx mode change 100644 => 100755 src/pages/Register.jsx create mode 100755 src/pages/ValidatorPortal copy.jsx mode change 100644 => 100755 src/pages/ValidatorPortal.jsx mode change 100644 => 100755 src/pages/Validators.jsx mode change 100644 => 100755 src/repository/landRepository_lama.js mode change 100644 => 100755 src/services/networkService.js mode change 100644 => 100755 src/services/syncService_lama.js mode change 100644 => 100755 src/utils/db.js mode change 100644 => 100755 src/utils/index.ts mode change 100644 => 100755 src/utils/sqlClient.js mode change 100644 => 100755 src/utils/sqliteClient_2.js mode change 100644 => 100755 src/utils/sqliteClient_i.js mode change 100644 => 100755 tailwind.config.js mode change 100644 => 100755 vite.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..92b4e9c4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +[*] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true +insert_final_newline = true \ No newline at end of file diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/bugreport-sdk_gphone64_arm64-BE4B.251210.005-2026-03-06-09-42-33.zip b/bugreport-sdk_gphone64_arm64-BE4B.251210.005-2026-03-06-09-42-33.zip old mode 100644 new mode 100755 diff --git a/capacitor.config.json b/capacitor.config.json old mode 100644 new mode 100755 diff --git a/components.json b/components.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/Comodity.json b/entities/probindo.com/Comodity.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/Distribution.json b/entities/probindo.com/Distribution.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/Farmer.json b/entities/probindo.com/Farmer.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/Harvest.json b/entities/probindo.com/Harvest.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/Land.json b/entities/probindo.com/Land.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/LandValidation.json b/entities/probindo.com/LandValidation.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/Offtakers.json b/entities/probindo.com/Offtakers.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/Plant.json b/entities/probindo.com/Plant.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/PlantInspection.json b/entities/probindo.com/PlantInspection.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/Synclog.json b/entities/probindo.com/Synclog.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/User/me.json b/entities/probindo.com/User/me.json old mode 100644 new mode 100755 diff --git a/entities/probindo.com/Validator.json b/entities/probindo.com/Validator.json old mode 100644 new mode 100755 diff --git a/entities/public-settings/probindo.com.json b/entities/public-settings/probindo.com.json old mode 100644 new mode 100755 diff --git a/eslint.config.js b/eslint.config.js old mode 100644 new mode 100755 diff --git a/index.html b/index.html old mode 100644 new mode 100755 index 34a8e295..56a3dbe2 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - + Agro Monev diff --git a/jsconfig.json b/jsconfig.json old mode 100644 new mode 100755 diff --git a/package-lock.json b/package-lock.json old mode 100644 new mode 100755 index af6d3c31..c848ee23 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@capacitor/android": "^8.1.0", "@capacitor/cli": "^8.1.0", "@capacitor/core": "^8.1.0", + "@capacitor/geolocation": "^8.1.0", "@capacitor/ios": "^8.1.0", "@emotion/is-prop-valid": "^1.4.0", "@hello-pangea/dnd": "^17.0.0", @@ -52,6 +53,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.0", + "crypto-js": "^4.2.0", "date-fns": "^3.6.0", "dexie": "^4.3.0", "dexie-react-hooks": "^4.2.0", @@ -493,6 +495,18 @@ "tslib": "^2.1.0" } }, + "node_modules/@capacitor/geolocation": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@capacitor/geolocation/-/geolocation-8.1.0.tgz", + "integrity": "sha512-dHeGuVlT3ELxxn8WaoRsGjfx8tmziaC0ZuaKhUBCoKFjOue4fAnmLczCMQsYW7OykgiyBh0pirNPwWZ0/LXB7Q==", + "license": "MIT", + "dependencies": { + "@capacitor/synapse": "^1.0.4" + }, + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, "node_modules/@capacitor/ios": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-8.1.0.tgz", @@ -502,6 +516,12 @@ "@capacitor/core": "^8.1.0" } }, + "node_modules/@capacitor/synapse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@capacitor/synapse/-/synapse-1.0.4.tgz", + "integrity": "sha512-/C1FUo8/OkKuAT4nCIu/34ny9siNHr9qtFezu4kxm6GY1wNFxrCFWjfYx5C1tUhVGz3fxBABegupkpjXvjCHrw==", + "license": "ISC" + }, "node_modules/@emotion/is-prop-valid": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", @@ -4607,6 +4627,12 @@ "node": ">= 8" } }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" + }, "node_modules/css-box-model": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 15e303c5..88e4ccb5 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@capacitor/android": "^8.1.0", "@capacitor/cli": "^8.1.0", "@capacitor/core": "^8.1.0", + "@capacitor/geolocation": "^8.1.0", "@capacitor/ios": "^8.1.0", "@emotion/is-prop-valid": "^1.4.0", "@hello-pangea/dnd": "^17.0.0", diff --git a/pertanian-app.code-workspace b/pertanian-app.code-workspace old mode 100644 new mode 100755 index 68f93f75..e53c7909 --- a/pertanian-app.code-workspace +++ b/pertanian-app.code-workspace @@ -11,6 +11,15 @@ }, { "path": "../pertamina-point" + }, + { + "path": "../dev/wayfinder-project" + }, + { + "path": "../own-cloud" + }, + { + "path": "../skhp" } ], "settings": {} diff --git a/postcss.config.js b/postcss.config.js old mode 100644 new mode 100755 diff --git a/public/logo1.png b/public/logo1.png new file mode 100644 index 0000000000000000000000000000000000000000..aded690f52e39312a9b9f4fda4646279818bb5ca GIT binary patch literal 70171 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 literal 0 HcmV?d00001 diff --git a/public/logo_001.png b/public/logo_001.png new file mode 100755 index 0000000000000000000000000000000000000000..778f20bfff92bc7335af51d194ddef30b48cf33f GIT binary patch literal 24539 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

#2lXRd$? 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 KMNUMnLSTY&*kJSk literal 0 HcmV?d00001 diff --git a/public/sql-wasm.wasm b/public/sql-wasm.wasm old mode 100644 new mode 100755 diff --git a/src/.gitignore b/src/.gitignore old mode 100644 new mode 100755 diff --git a/src/App.jsx b/src/App.jsx old mode 100644 new mode 100755 diff --git a/src/App_baru.jsx b/src/App_baru.jsx old mode 100644 new mode 100755 diff --git a/src/Layout copy.jsx b/src/Layout copy.jsx old mode 100644 new mode 100755 diff --git a/src/Layout.jsx b/src/Layout.jsx old mode 100644 new mode 100755 index e7ea036e..a3888fa1 --- a/src/Layout.jsx +++ b/src/Layout.jsx @@ -19,7 +19,7 @@ function SyncIndicator() { const updateStatus = async () => { const isConnected = await checkInternet(); - const count = await OfflineService.getPendingCount(); // Ambil dari SQLite + const count = await OfflineService.getPendingCount(); if (mounted) { setOnline(isConnected); @@ -94,7 +94,6 @@ async function checkInternet() { try { const controller = new AbortController(); setTimeout(() => controller.abort(), 3000); - // Gunakan favicon google sebagai probe yang ringan await fetch("https://www.google.com/favicon.ico", { method: "HEAD", mode: "no-cors", @@ -109,16 +108,16 @@ async function checkInternet() { const navigation = [ - { name: "Dashboard", page: "Dashboard", icon: LayoutDashboard , roles: ['super_admin']}, - { name: "Petani", page: "Farmers", icon: Users, roles: ['super_admin'] }, - { name: "Lahan", page: "Lands", icon: Map, roles: ['super_admin'] }, - { name: "Tanaman", page: "Plants", icon: TreePine, roles: ['super_admin'] }, - { name: "Produktivitas", page: "ProductivityMonitoring", icon: LayoutDashboard, roles: ['super_admin', 'petani'] }, - { name: "Validator", page: "Validators", icon: Shield, roles: ['super_admin'] }, - { name: "Offtaker", page: "Offtakers", icon: Users, roles: ['super_admin'] }, - { name: "Portal Petani", page: "FarmerPortal", icon: Users, roles: ['super_admin', 'petani'] }, - { name: "Portal Validator", page: "ValidatorPortal", icon: Shield, roles: ['super_admin'] }, - { name: "Portal Offtaker", page: "OfftakerPortal", icon: Users, roles: ['super_admin'] }, + { name: "Dashboard", page: "Dashboard", icon: LayoutDashboard , roles: ['super_admin','fasilitator']}, + { name: "Petani", page: "Farmers", icon: Users, roles: ['super_admin','fasilitator'] }, + { name: "Lahan", page: "Lands", icon: Map, roles: ['super_admin','fasilitator'] }, + { name: "Tanaman", page: "Plants", icon: TreePine, roles: ['super_admin','fasilitator'] }, + { name: "Produktivitas", page: "ProductivityMonitoring", icon: LayoutDashboard, roles: ['super_admin', 'petani','fasilitator'] }, + { name: "Facilitator", page: "Validators", icon: Shield, roles: ['super_admin','fasilitator'] }, + { name: "Offtaker", page: "Offtakers", icon: Users, roles: ['super_admin','fasilitator'] }, + { name: "Portal Petani", page: "FarmerPortal", icon: Users, roles: ['super_admin', 'petani','fasilitator'] }, + { name: "Portal Validator", page: "ValidatorPortal", icon: Shield, roles: ['super_admin','fasilitator'] }, + { name: "Portal Offtaker", page: "OfftakerPortal", icon: Users, roles: ['super_admin','fasilitator'] }, ]; export default function Layout({ children, currentPageName }) { @@ -148,8 +147,9 @@ export default function Layout({ children, currentPageName }) {

-
- +
+ {/* */} +
AgroMonev
@@ -173,8 +173,9 @@ export default function Layout({ children, currentPageName }) {
-
- +
+ {/* */} +

AgroMonev

diff --git a/src/Layout2.jsx b/src/Layout2.jsx old mode 100644 new mode 100755 index 6d3017dc..0134da17 --- a/src/Layout2.jsx +++ b/src/Layout2.jsx @@ -60,7 +60,7 @@ const navigation = [ { name: "Lahan", page: "Lands", icon: Map }, { name: "Tanaman", page: "Plants", icon: TreePine }, { name: "Produktivitas", page: "ProductivityMonitoring", icon: LayoutDashboard }, - { name: "Validator", page: "Validators", icon: Shield }, + { name: "Facilitator", page: "Validators", icon: Shield }, { name: "Offtaker", page: "Offtakers", icon: Users }, { name: "Portal Petani", page: "FarmerPortal", icon: Users }, { name: "Portal Validator", page: "ValidatorPortal", icon: Shield }, diff --git a/src/_mock/api_lama.js b/src/_mock/api_lama.js old mode 100644 new mode 100755 diff --git a/src/_mock/data/Comodity.json b/src/_mock/data/Comodity.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/Distribution.json b/src/_mock/data/Distribution.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/Farmer.json b/src/_mock/data/Farmer.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/Harvest.json b/src/_mock/data/Harvest.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/Inspection.json b/src/_mock/data/Inspection.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/Land.json b/src/_mock/data/Land.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/LandValidation.json b/src/_mock/data/LandValidation.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/Offtaker.json b/src/_mock/data/Offtaker.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/Plant.json b/src/_mock/data/Plant.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/PlantInspection.json b/src/_mock/data/PlantInspection.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/Province.json b/src/_mock/data/Province.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/Synclog.json b/src/_mock/data/Synclog.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/offlineData.js b/src/_mock/data/offlineData.js old mode 100644 new mode 100755 diff --git a/src/_mock/data/propinsi.json b/src/_mock/data/propinsi.json old mode 100644 new mode 100755 diff --git a/src/_mock/data/validator.json b/src/_mock/data/validator.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/Comodity.json b/src/_mock/schema/Comodity.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/Distribution.json b/src/_mock/schema/Distribution.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/Farmer.json b/src/_mock/schema/Farmer.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/Land.json b/src/_mock/schema/Land.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/LandValidation.json b/src/_mock/schema/LandValidation.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/Plant.json b/src/_mock/schema/Plant.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/PlantInspection.json b/src/_mock/schema/PlantInspection.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/Synclog.json b/src/_mock/schema/Synclog.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/Validator.json b/src/_mock/schema/Validator.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/farmers.json b/src/_mock/schema/farmers.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/lands.json b/src/_mock/schema/lands.json old mode 100644 new mode 100755 diff --git a/src/_mock/schema/plants.json b/src/_mock/schema/plants.json old mode 100644 new mode 100755 diff --git a/src/api/Client.js b/src/api/Client.js old mode 100644 new mode 100755 diff --git a/src/api/entities.js b/src/api/entities.js old mode 100644 new mode 100755 diff --git a/src/components/UserNotRegisteredError.jsx b/src/components/UserNotRegisteredError.jsx old mode 100644 new mode 100755 diff --git a/src/components/common/EmptyState.jsx b/src/components/common/EmptyState.jsx old mode 100644 new mode 100755 diff --git a/src/components/common/OfflineStorage_001.jsx b/src/components/common/OfflineStorage_001.jsx old mode 100644 new mode 100755 diff --git a/src/components/common/OfflineStorage_002.jsx b/src/components/common/OfflineStorage_002.jsx old mode 100644 new mode 100755 diff --git a/src/components/common/RoleBasedGuard.jsx b/src/components/common/RoleBasedGuard.jsx old mode 100644 new mode 100755 diff --git a/src/components/common/SyncManager copy.jsx b/src/components/common/SyncManager copy.jsx old mode 100644 new mode 100755 diff --git a/src/components/common/SyncManager.jsx b/src/components/common/SyncManager.jsx old mode 100644 new mode 100755 index 77f81fc8..40cef171 --- a/src/components/common/SyncManager.jsx +++ b/src/components/common/SyncManager.jsx @@ -17,12 +17,11 @@ export function useSyncManager() { const hasPending = await OfflineService.hasPendingData(); if (hasPending) { - // console.log("📤 Memulai Push Sinkronisasi..."); await OfflineService.syncAllPending(); toast.success("Sinkronisasi data berhasil"); } else { - // console.log("🔄 Data lokal bersih. Melakukan Pull dari server..."); - await OfflineService.downloadFromServer(); + // await OfflineService.downloadFromServer(); + await OfflineService.syncDataFromServer(); } } catch (error) { console.error('Sync process failed:', error); diff --git a/src/components/common/SyncStatus.jsx b/src/components/common/SyncStatus.jsx old mode 100644 new mode 100755 diff --git a/src/components/common/SyncStatusBar.jsx b/src/components/common/SyncStatusBar.jsx old mode 100644 new mode 100755 diff --git a/src/components/common/offlineStorage.jsx b/src/components/common/offlineStorage.jsx old mode 100644 new mode 100755 index ff55a4f0..e0c3f881 --- a/src/components/common/offlineStorage.jsx +++ b/src/components/common/offlineStorage.jsx @@ -14,7 +14,7 @@ const agroApi = axios.create({ export const OfflineService = { hasPendingData: async () => { - const tables = ['farmers', 'lands', 'plants', 'harvest', 'plant_inspections', 'offtakers', 'validators']; + const tables = ['farmers', 'lands', 'plants', 'harvests', 'plant_inspections', 'offtakers', 'validators', 'distributions','profiles']; for (const table of tables) { const count = await db[table].where('sync_status').equals('pending').count(); if (count > 0) return true; @@ -44,7 +44,7 @@ export const OfflineService = { }); return id; } catch (err) { - console.error("❌ Dexie Error:", err); + console.error("Error:", err); throw err; } }, @@ -78,8 +78,6 @@ export const OfflineService = { if (filter && typeof filter === 'object' && Object.keys(filter).length > 0) { return await dbTable.where(filter).toArray(); } - - console.log(`Fetching ...... all from ${table}`); return await dbTable.reverse().toArray(); } catch (e) { @@ -93,9 +91,11 @@ export const OfflineService = { db.farmers.where('sync_status').equals('pending').count(), db.lands.where('sync_status').equals('pending').count(), db.plants.where('sync_status').equals('pending').count(), - db.harvest.where('sync_status').equals('pending').count(), + db.harvests.where('sync_status').equals('pending').count(), db.plant_inspections.where('sync_status').equals('pending').count(), db.offtakers.where('sync_status').equals('pending').count(), + db.profiles.where('sync_status').equals('pending').count(), + db.distributions.where('sync_status').equals('pending').count(), // db.validators.where('sync_status').equals('pending').count(), ]); @@ -126,6 +126,50 @@ export const OfflineService = { throw err; } }, + syncDataFromServer : async () => { + const token = localStorage.getItem('access_token'); + const baseURL = import.meta.env.VITE_BASE44_API_URL.replace(/\/+$/, ""); + const syncConfigs = [ + { from: db.farmers, to:"profile", endpoint: 'auth/profile/1' }, + { from: db.lands, to:"lahan", endpoint: 'map/lahan' }, + { from: db.plants, to:"tanaman", endpoint: 'map/tanaman' }, + { from: db.harvests, to:"panen", endpoint: 'map/panen'}, + { from: db.plant_inspections, to:"inspeksi", endpoint: 'map/inspeksi'}, + { from: db.offtakers, to:"offtaker", endpoint: 'map/offtaker'}, + { from: db.distributions, to:"panen", endpoint: 'distribusi/panen'}, + { from: db.villages, to: "desa-kelurahan", endpoint: "master/desa-kelurahan" }, + { from: db.districts, to: "kecamatan", endpoint: "master/kecamatan"}, + { from: db.regencies, to: "kabupaten-kota", endpoint: "master/kabupaten-kota"}, + { from: db.provinces, to: "provinsi", endpoint: "master/provinsi"}, + ]; + + for (const config of syncConfigs) { + try { + console.log(`Syncing table: ${config.from.name}...`); + + const response = await axios.get(`${baseURL}/api/${config.endpoint}`, { + headers: { Authorization: `Bearer ${token}` } + }); + console.log(response, "Res") + if (response.status !== 200) throw new Error(`HTTP error! status: ${response.status}`); + + const result = await response; + const dataToSave = config.to ? result[config.to] : (result.data || result.data.data || []); + + if (Array.isArray(dataToSave)) { + await config.table.bulkPut(dataToSave); + console.log(`Berhasil sinkron ${dataToSave.length} data ke ${config.table.name}`); + } else if (typeof dataToSave === 'object' && dataToSave !== null) { + await config.table.put(dataToSave); + } + + } catch (error) { + console.error(`Gagal sinkronisasi ${config.endpoint}:`, error); + // Lanjut ke config berikutnya meski satu error + continue; + } + } + }, syncAll: async () => { const queue = await db.pending_sync.toArray(); for (const item of queue) { @@ -147,18 +191,19 @@ export const OfflineService = { const baseURL = import.meta.env.VITE_BASE44_API_URL.replace(/\/+$/, ""); console.log(user, "Userr") const syncConfigs = [ - { endpoint: `auth/profile/1`, table: db.farmers }, + { endpoint: `auth/profile/1`, table: db.farmers }, + // { endpoint: `auth/me`, table: db.users }, { endpoint: 'map/lahan', table: db.lands }, { endpoint: 'map/tanaman', table: db.plants }, - { endpoint: 'map/panen', table: db.harvest}, + { endpoint: 'map/panen', table: db.harvests}, { endpoint: 'map/inspeksi', table: db.plant_inspections}, { endpoint: 'map/offtaker', table: db.offtakers}, { endpoint: 'distribusi/panen', table: db.distributions}, // { endpoint: 'map/validator', table: db.validators} - { table: db.villages, to: "desa-kelurahan", endpoint: "master/desa-kelurahan" }, - { table: db.districts, to: "kecamatan", endpoint: "master/kecamatan"}, - { table: db.regencies, to: "kabupaten-kota", endpoint: "master/kabupaten-kota"}, - { table: db.provinces, to: "provinsi", endpoint: "master/provinsi"}, + { endpoint: "master/desa-kelurahan", table: db.villages, to: "desa-kelurahan"}, + { endpoint: "master/kecamatan", table: db.districts, to: "kecamatan"}, + { endpoint: "master/kabupaten-kota", table: db.regencies, to: "kabupaten-kota"}, + { endpoint: "master/provinsi", table: db.provinces, to: "provinsi"}, ]; @@ -168,34 +213,55 @@ export const OfflineService = { headers: { Authorization: `Bearer ${token}` } }); - const respondData = Array.isArray(respond.data) ? respond.data : respond.data.data || []; - if(respondData.length > 0){ - const localIds = await config.table.toCollection().primaryKeys(); - const newData = respondData.filter(item => !localIds.includes(item.id)); - if(newData.length > 0){ - await config.table.bulkAdd(newData.map(item => ({ - ...item, - sync_status: 'synced' - }))); - }else { - // console.log(` Data ${config.endpoint} sudah mutakhir (tidak ada data baru).`); + const rawData = respond.data?.data || respond.data; + console.log(rawData, "Raw Data") + let respondData = []; + + // const respondData = (config.endpoint.includes('auth/profile') || config.endpoint.includes('auth/me')) + // ? [rawData] + // : Array.isArray(rawData) ? rawData : []; + + if (config.endpoint.includes('auth/profile') || config.endpoint.includes('auth/me')) { + if (rawData && typeof rawData === 'object') { + const { password, ...cleanData } = rawData; + respondData = [cleanData] + } + } else { + // Jika data memang seharusnya array (List) + respondData = Array.isArray(rawData) ? rawData : []; + } + + console.log(respondData," || data " ,config.table) + if(respondData.length > 0 && respondData[0] !== null){ + const preparedData = respondData.map(item => ({ + ...item, + id: item.id, + sync_status: 'synced' + })).filter(item => item.id !== undefined); + + if (preparedData.length > 0) { + await config.table.bulkPut(preparedData); + console.log(`✅ Berhasil sync ${preparedData.length} data ke ${config.table.name}`); } } } } catch (err) { console.error("Gagal download data:", err); + if (err.failures) { + console.error("Detail kegagalan Dexie:", err.failures); + } } }, syncAllPending: async () => { const tables = [ - { from: db.farmers, to:"profile", endpoint: 'auth/profile' }, + { from: db.farmers, to:"profile", endpoint: 'auth/profile/1' }, { from: db.lands, to:"lahan", endpoint: 'map/lahan' }, { from: db.plants, to:"tanaman", endpoint: 'map/tanaman' }, - { endpoint: 'map/panen', to:"panen", from: db.harvest}, - { endpoint: 'map/inspeksi', to:"inspeksi", from: db.plant_inspections}, - { endpoint: 'map/offtaker', to:"offtaker", from: db.offtakers}, - { endpoint: 'distribusi/panen', to:"panen", from: db.distributions}, + { from: db.harvests, to:"panen", endpoint: 'map/panen'}, + { from: db.plant_inspections, to:"inspeksi", endpoint: 'map/inspeksi'}, + { from: db.offtakers, to:"offtaker", endpoint: 'map/offtaker'}, + { from: db.distributions, to:"panen", endpoint: 'distribusi/panen'}, // { endpoint: 'map/validator', to:"validator", from: db.validators} { from: db.villages, to: "desa-kelurahan", endpoint: "master/desa-kelurahan" }, { from: db.districts, to: "kecamatan", endpoint: "master/kecamatan"}, diff --git a/src/components/common/useOfflineEntity copy.jsx b/src/components/common/useOfflineEntity copy.jsx old mode 100644 new mode 100755 diff --git a/src/components/common/useOfflineEntity.jsx b/src/components/common/useOfflineEntity.jsx old mode 100644 new mode 100755 diff --git a/src/components/dashboard/CommodityPieChart.jsx b/src/components/dashboard/CommodityPieChart.jsx old mode 100644 new mode 100755 diff --git a/src/components/dashboard/RegionChart.jsx b/src/components/dashboard/RegionChart.jsx old mode 100644 new mode 100755 diff --git a/src/components/dashboard/StatCard.jsx b/src/components/dashboard/StatCard.jsx old mode 100644 new mode 100755 diff --git a/src/components/distribution/DistributionForm.jsx b/src/components/distribution/DistributionForm.jsx old mode 100644 new mode 100755 diff --git a/src/components/distribution/DistributionForm_01.jsx b/src/components/distribution/DistributionForm_01.jsx old mode 100644 new mode 100755 diff --git a/src/components/distribution/DistributionGrading.jsx b/src/components/distribution/DistributionGrading.jsx old mode 100644 new mode 100755 diff --git a/src/components/farmers/FarmerCard.jsx b/src/components/farmers/FarmerCard.jsx old mode 100644 new mode 100755 index 8571c631..fde3322d --- a/src/components/farmers/FarmerCard.jsx +++ b/src/components/farmers/FarmerCard.jsx @@ -12,18 +12,19 @@ const statusColors = { }; const statusLabels = { - pending: "Menunggu Verifikasi", - verified: "Terverifikasi", - rejected: "Ditolak" + pending: "W", + verified: "V", + rejected: "X" }; export default function FarmerCard({ farmer }) { + console.log("Petani : ", farmer); return (
{farmer.photo_url ? ( - {farmer.full_name} + {farmer?.name ) : ( {farmer.full_name?.charAt(0)?.toUpperCase() || "P"} @@ -34,18 +35,18 @@ export default function FarmerCard({ farmer }) {
-

{farmer.full_name}

-

NIK: {farmer.nik}

+

{farmer?.full_name || farmer?.name || farmer?.nama }

+

NIK: {farmer?.kk}

- - {statusLabels[farmer.verification_status]} + + {statusLabels[farmer.user.email_verified_at !== null || farmer.user.email_verified_at !== undefined ? 'verified' : 'pending']}
- {farmer.village}, {farmer.district} + {farmer.alamat}
{farmer.farmer_group && (
@@ -53,10 +54,10 @@ export default function FarmerCard({ farmer }) { {farmer.farmer_group}
)} - {farmer.phone && ( + {farmer.telepon && (
- {farmer.phone} + {farmer?.telepon}
)}
diff --git a/src/components/farmers/FarmerForm.jsx b/src/components/farmers/FarmerForm.jsx old mode 100644 new mode 100755 diff --git a/src/components/farmers/LinkUserAccount.jsx b/src/components/farmers/LinkUserAccount.jsx old mode 100644 new mode 100755 diff --git a/src/components/harvest/HarvestForm.jsx b/src/components/harvest/HarvestForm.jsx old mode 100644 new mode 100755 diff --git a/src/components/lands/GPSLandMapper copy 2.jsx b/src/components/lands/GPSLandMapper copy 2.jsx new file mode 100755 index 00000000..b89f21de --- /dev/null +++ b/src/components/lands/GPSLandMapper copy 2.jsx @@ -0,0 +1,242 @@ +import { useState, useEffect, useMemo } from "react"; +import { MapContainer, TileLayer, Marker, Polygon, useMap, Circle } from "react-leaflet"; +import { Card } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { Locate, MapPin, Trash2, Save, Navigation, RotateCcw, AlertTriangle } from "lucide-react"; +import { toast } from "sonner"; +import "leaflet/dist/leaflet.css"; +import L from "leaflet"; + +// Fix default marker icon +delete L.Icon.Default.prototype._getIconUrl; +L.Icon.Default.mergeOptions({ + iconRetinaUrl: "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png", + iconUrl: "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png", + shadowUrl: "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png", +}); + +const getColorByIndex = (index) => { + const colors = ["#ef4444", "#f59e0b", "#22c55e", "#3b82f6", "#8b5cf6", "#ec4899", "#14b8a6"]; + return colors[index % colors.length]; +}; + +/** + * Kalkulasi Luas Lahan (Hektar) yang lebih presisi + */ +function calculatePolygonArea(points) { + if (points.length < 3) return 0; + + const radius = 6378137; // Radius Bumi (meters) + let area = 0; + + for (let i = 0; i < points.length; i++) { + const p1 = points[i]; + const p2 = points[(i + 1) % points.length]; + + // Konversi ke Radians + const lat1 = p1[0] * Math.PI / 180; + const lon1 = p1[1] * Math.PI / 180; + const lat2 = p2[0] * Math.PI / 180; + const lon2 = p2[1] * Math.PI / 180; + + area += (lon2 - lon1) * (2 + Math.sin(lat1) + Math.sin(lat2)); + } + + area = Math.abs(area * radius * radius / 2.0); + return area / 10000; // Return in Hectares +} + +function MapController({ center, zoom }) { + const map = useMap(); + useEffect(() => { + if (center) { + // Zoom 20 untuk melihat detail batas lahan lebih dekat + map.flyTo(center, zoom || 20, { duration: 1.5 }); + } + }, [center, map, zoom]); + return null; +} + +export default function GPSLandMapper({ existingPolygon, onSave, readOnly = false }) { + const [points, setPoints] = useState([]); + const [currentLocation, setCurrentLocation] = useState(null); + const [isLocating, setIsLocating] = useState(false); + const [gpsAccuracy, setGpsAccuracy] = useState(null); + const [watchId, setWatchId] = useState(null); + + const area = useMemo(() => calculatePolygonArea(points), [points]); + + const getDistance = (p1, p2) => { + if (!p1 || !p2) return 0; + const R = 6371000; + const dLat = (p2[0] - p1[0]) * Math.PI / 180; + const dLon = (p2[1] - p1[1]) * Math.PI / 180; + const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.cos(p1[0] * Math.PI / 180) * Math.cos(p2[0] * Math.PI / 180) * + Math.sin(dLon / 2) * Math.sin(dLon / 2); + return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + }; + + useEffect(() => { + if (existingPolygon && existingPolygon.length > 0) { + // Pastikan format dari database [lng, lat] dibalik ke [lat, lng] untuk Leaflet + const converted = Array.isArray(existingPolygon[0]) + ? existingPolygon.map(p => [p[1], p[0]]) + : []; + setPoints(converted); + } + }, [existingPolygon]); + + const startGPSTracking = () => { + if (!navigator.geolocation) { + toast.error("GPS tidak didukung"); + return; + } + setIsLocating(true); + const id = navigator.geolocation.watchPosition( + (pos) => { + setCurrentLocation([pos.coords.latitude, pos.coords.longitude]); + setGpsAccuracy(pos.coords.accuracy); + setIsLocating(false); + }, + (err) => { + setIsLocating(false); + toast.error("Gagal mendapatkan lokasi GPS"); + }, + { enableHighAccuracy: true, maximumAge: 0 } + ); + setWatchId(id); + }; + + const stopGPSTracking = () => { + if (watchId !== null) navigator.geolocation.clearWatch(watchId); + }; + + useEffect(() => { + startGPSTracking(); + return () => stopGPSTracking(); + }, []); + + const addCornerPoint = () => { + if (!currentLocation) { + toast.error("Tunggu GPS mengunci lokasi"); + return; + } + + if (gpsAccuracy > 10) { + toast.error(`Akurasi buruk (±${gpsAccuracy.toFixed(0)}m). Pindah ke tempat terbuka.`); + return; + } + + if (points.length > 0) { + const dist = getDistance(points[points.length - 1], currentLocation); + if (dist < 1) { + toast.error("Anda belum bergerak dari titik terakhir"); + return; + } + } + + setPoints([...points, currentLocation]); + toast.success(`Titik ${points.length + 1} ditandai`); + }; + + const removeLastPoint = () => setPoints(points.slice(0, -1)); + const clearAllPoints = () => setPoints([]); + + const handleSave = () => { + if (points.length < 3) { + toast.error("Minimal harus ada 3 titik"); + return; + } + onSave({ + polygon_coordinates: points.map(p => [p[1], p[0]]), // [lng, lat] + center_lat: points.reduce((s, p) => s + p[0], 0) / points.length, + center_lng: points.reduce((s, p) => s + p[1], 0) / points.length, + area_hectares: area + }); + }; + + const createCornerIcon = (index) => L.divIcon({ + className: "custom-corner-icon", + html: `
${index + 1}
`, + iconSize: [32, 32], iconAnchor: [16, 16] + }); + + return ( + +
+
+
+
+
+

GPS {currentLocation ? "Aktif" : "Mencari..."}

+

10 ? 'text-red-500' : 'text-slate-500'}`}> + Akurasi: ±{gpsAccuracy?.toFixed(1)}m {gpsAccuracy > 10 && "(Lemah)"} +

+
+
+ {currentLocation && {currentLocation[0].toFixed(5)}, {currentLocation[1].toFixed(5)}} +
+ + {!readOnly && ( +
+ + + +
+ )} + + {points.length >= 3 && ( +
+
+

Estimasi Luas

+

{area.toFixed(4)} Ha

+
+ {!readOnly && } +
+ )} +
+ +
+ + {/* LAYER SATELIT UNTUK PRESISI */} + + + + + {currentLocation && ( + <> + +
`, + iconSize:[20,20], iconAnchor:[10,10] + })} /> + + )} + + {points.map((p, i) => )} + {points.length >= 3 && } + + + {!readOnly && ( +
+

+ Tips: Berjalanlah ke setiap sudut lahan. Tunggu lingkaran biru mengecil sebelum menekan "Tandai Titik" untuk hasil yang lebih presisi. +

+
+ )} +
+
+ ); +} \ No newline at end of file diff --git a/src/components/lands/GPSLandMapper copy.jsx b/src/components/lands/GPSLandMapper copy.jsx old mode 100644 new mode 100755 diff --git a/src/components/lands/GPSLandMapper.jsx b/src/components/lands/GPSLandMapper.jsx old mode 100644 new mode 100755 index b89f21de..66ed99c4 --- a/src/components/lands/GPSLandMapper.jsx +++ b/src/components/lands/GPSLandMapper.jsx @@ -3,146 +3,52 @@ import { MapContainer, TileLayer, Marker, Polygon, useMap, Circle } from "react- import { Card } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; -import { Locate, MapPin, Trash2, Save, Navigation, RotateCcw, AlertTriangle } from "lucide-react"; +import { Trash2, Save, Navigation, RotateCcw, Zap, ZapOff, Map as MapIcon, Loader2 } from "lucide-react"; import { toast } from "sonner"; import "leaflet/dist/leaflet.css"; import L from "leaflet"; +import { Geolocation } from '@capacitor/geolocation'; -// Fix default marker icon -delete L.Icon.Default.prototype._getIconUrl; -L.Icon.Default.mergeOptions({ - iconRetinaUrl: "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png", +// Konfigurasi Icon Marker agar muncul di Android +const customMarkerIcon = new L.Icon({ iconUrl: "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png", + iconRetinaUrl: "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png", shadowUrl: "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png", + iconSize: [25, 41], + iconAnchor: [12, 41], }); const getColorByIndex = (index) => { const colors = ["#ef4444", "#f59e0b", "#22c55e", "#3b82f6", "#8b5cf6", "#ec4899", "#14b8a6"]; return colors[index % colors.length]; }; - -/** - * Kalkulasi Luas Lahan (Hektar) yang lebih presisi - */ -function calculatePolygonArea(points) { - if (points.length < 3) return 0; - - const radius = 6378137; // Radius Bumi (meters) - let area = 0; - - for (let i = 0; i < points.length; i++) { - const p1 = points[i]; - const p2 = points[(i + 1) % points.length]; - - // Konversi ke Radians - const lat1 = p1[0] * Math.PI / 180; - const lon1 = p1[1] * Math.PI / 180; - const lat2 = p2[0] * Math.PI / 180; - const lon2 = p2[1] * Math.PI / 180; - - area += (lon2 - lon1) * (2 + Math.sin(lat1) + Math.sin(lat2)); - } - - area = Math.abs(area * radius * radius / 2.0); - return area / 10000; // Return in Hectares -} - -function MapController({ center, zoom }) { +// Komponen Pengatur Peta (PENTING: Memperbaiki masalah layar putih) +function MapController({ center, isTracking }) { const map = useMap(); + useEffect(() => { - if (center) { - // Zoom 20 untuk melihat detail batas lahan lebih dekat - map.flyTo(center, zoom || 20, { duration: 1.5 }); + // Memaksa Leaflet menghitung ulang ukuran container setelah render pertama + setTimeout(() => { + map.invalidateSize(); + }, 500); + }, [map]); + + useEffect(() => { + if (center && isTracking) { + map.setView(center, 19, { animate: true }); } - }, [center, map, zoom]); + }, [center, isTracking, map]); + return null; } -export default function GPSLandMapper({ existingPolygon, onSave, readOnly = false }) { +export default function GPSLandMapper({ onSave, readOnly = false }) { const [points, setPoints] = useState([]); const [currentLocation, setCurrentLocation] = useState(null); - const [isLocating, setIsLocating] = useState(false); const [gpsAccuracy, setGpsAccuracy] = useState(null); const [watchId, setWatchId] = useState(null); - - const area = useMemo(() => calculatePolygonArea(points), [points]); - - const getDistance = (p1, p2) => { - if (!p1 || !p2) return 0; - const R = 6371000; - const dLat = (p2[0] - p1[0]) * Math.PI / 180; - const dLon = (p2[1] - p1[1]) * Math.PI / 180; - const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + - Math.cos(p1[0] * Math.PI / 180) * Math.cos(p2[0] * Math.PI / 180) * - Math.sin(dLon / 2) * Math.sin(dLon / 2); - return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - }; - - useEffect(() => { - if (existingPolygon && existingPolygon.length > 0) { - // Pastikan format dari database [lng, lat] dibalik ke [lat, lng] untuk Leaflet - const converted = Array.isArray(existingPolygon[0]) - ? existingPolygon.map(p => [p[1], p[0]]) - : []; - setPoints(converted); - } - }, [existingPolygon]); - - const startGPSTracking = () => { - if (!navigator.geolocation) { - toast.error("GPS tidak didukung"); - return; - } - setIsLocating(true); - const id = navigator.geolocation.watchPosition( - (pos) => { - setCurrentLocation([pos.coords.latitude, pos.coords.longitude]); - setGpsAccuracy(pos.coords.accuracy); - setIsLocating(false); - }, - (err) => { - setIsLocating(false); - toast.error("Gagal mendapatkan lokasi GPS"); - }, - { enableHighAccuracy: true, maximumAge: 0 } - ); - setWatchId(id); - }; - - const stopGPSTracking = () => { - if (watchId !== null) navigator.geolocation.clearWatch(watchId); - }; - - useEffect(() => { - startGPSTracking(); - return () => stopGPSTracking(); - }, []); - - const addCornerPoint = () => { - if (!currentLocation) { - toast.error("Tunggu GPS mengunci lokasi"); - return; - } - - if (gpsAccuracy > 10) { - toast.error(`Akurasi buruk (±${gpsAccuracy.toFixed(0)}m). Pindah ke tempat terbuka.`); - return; - } - - if (points.length > 0) { - const dist = getDistance(points[points.length - 1], currentLocation); - if (dist < 1) { - toast.error("Anda belum bergerak dari titik terakhir"); - return; - } - } - - setPoints([...points, currentLocation]); - toast.success(`Titik ${points.length + 1} ditandai`); - }; - - const removeLastPoint = () => setPoints(points.slice(0, -1)); - const clearAllPoints = () => setPoints([]); + const [isTracking, setIsTracking] = useState(false); + const [positionBuffer, setPositionBuffer] = useState([]); const handleSave = () => { if (points.length < 3) { @@ -157,83 +63,181 @@ export default function GPSLandMapper({ existingPolygon, onSave, readOnly = fals }); }; - const createCornerIcon = (index) => L.divIcon({ - className: "custom-corner-icon", - html: `
${index + 1}
`, - iconSize: [32, 32], iconAnchor: [16, 16] - }); + // Hitung Luas + const area = useMemo(() => { + if (points.length < 3) return 0; + const radius = 6378137; + let areaVal = 0; + for (let i = 0; i < points.length; i++) { + const p1 = points[i]; + const p2 = points[(i + 1) % points.length]; + const lat1 = p1[0] * Math.PI / 180; + const lon1 = p1[1] * Math.PI / 180; + const lat2 = p2[0] * Math.PI / 180; + const lon2 = p2[1] * Math.PI / 180; + areaVal += (lon2 - lon1) * (2 + Math.sin(lat1) + Math.sin(lat2)); + } + return Math.abs(areaVal * radius * radius / 2.0) / 10000; + }, [points]); + + const startGPSTracking = async () => { + try { + const permissions = await Geolocation.requestPermissions(); + if (permissions.location !== 'granted') { + toast.error("Izin lokasi diperlukan"); + return; + } + + const id = await Geolocation.watchPosition( + { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }, + (position, err) => { + if (err) return; + if (position) { + const coords = [position.coords.latitude, position.coords.longitude]; + setCurrentLocation(coords); + setGpsAccuracy(position.coords.accuracy); + setPositionBuffer(prev => [...prev, coords].slice(-5)); + } + } + ); + setWatchId(id); + } catch (e) { + toast.error("GPS Error: " + e.message); + } + }; + + const stopGPSTracking = async () => { + if (watchId) { + await Geolocation.clearWatch({ id: watchId }); + setWatchId(null); + } + }; + + useEffect(() => { + if (isTracking) startGPSTracking(); + else stopGPSTracking(); + return () => stopGPSTracking(); + }, [isTracking]); + + const addPoint = () => { + if (!currentLocation) return; + if (gpsAccuracy > 15) { + toast.error("Akurasi terlalu rendah, tunggu sinyal stabil"); + return; + } + // Averaging + const lat = positionBuffer.reduce((a, b) => a + b[0], 0) / positionBuffer.length; + const lng = positionBuffer.reduce((a, b) => a + b[1], 0) / positionBuffer.length; + setPoints([...points, [lat, lng]]); + toast.success("Titik sudut ditambahkan"); + }; return ( - -
-
-
-
-
-

GPS {currentLocation ? "Aktif" : "Mencari..."}

-

10 ? 'text-red-500' : 'text-slate-500'}`}> - Akurasi: ±{gpsAccuracy?.toFixed(1)}m {gpsAccuracy > 10 && "(Lemah)"} -

-
+ + + {/* SECTION 1: KONTROL UTAMA (Selalu Ada) */} +
+
+
+
+ + {isTracking ? `Akurasi: ±${gpsAccuracy?.toFixed(1)}m` : "GPS Nonaktif"} +
- {currentLocation && {currentLocation[0].toFixed(5)}, {currentLocation[1].toFixed(5)}} + {currentLocation && Sinyal Terkunci}
- {!readOnly && ( -
- - - -
- )} - - {points.length >= 3 && ( -
-
-

Estimasi Luas

-

{area.toFixed(4)} Ha

-
- {!readOnly && } -
- )} -
- -
- - {/* LAYER SATELIT UNTUK PRESISI */} - - - - - {currentLocation && ( + ) : ( <> - -
`, - iconSize:[20,20], iconAnchor:[10,10] - })} /> + + )} +
+
- {points.map((p, i) => )} - {points.length >= 3 && } + {/* SECTION 2: AREA INFORMASI LUAS & SIMPAN (Muncul jika titik >= 3) */} + {points.length >= 3 && ( +
+
+

Total Estimasi Luas

+
+ {area.toFixed(4)} + Ha +
+
+ + {!readOnly && ( + + )} +
+ )} + + {/* SECTION 3: MAP CONTAINER */} +
+ + + + + {currentLocation && isTracking && ( + + )} + + {points.map((p, i) => ( + ${i+1}
` + })} + /> + ))} + + {points.length >= 3 && ( + + )} - {!readOnly && ( -
-

- Tips: Berjalanlah ke setiap sudut lahan. Tunggu lingkaran biru mengecil sebelum menekan "Tandai Titik" untuk hasil yang lebih presisi. -

+ {/* Floating Reset Button (Hanya ini yang di dalam peta) */} + {points.length > 0 && ( +
+ +
)}
diff --git a/src/components/lands/LandCard.jsx b/src/components/lands/LandCard.jsx old mode 100644 new mode 100755 index b635f873..cef22de5 --- a/src/components/lands/LandCard.jsx +++ b/src/components/lands/LandCard.jsx @@ -4,6 +4,9 @@ import { Button } from "@/components/ui/button"; import { MapPin, Maximize2, TreePine, ChevronRight } from "lucide-react"; import { Link } from "react-router-dom"; import { createPageUrl } from "@/utils"; +import { entity } from "@/api/entities"; +import { OfflineService } from "../common/offlineStorage"; +import { useEffect, useState } from "react"; const validationColors = { valid: "bg-emerald-100 text-emerald-700 border-emerald-200", @@ -27,15 +30,26 @@ const statusColors = { }; export default function LandCard({ land, farmerName, plantCount = 0 }) { + const [village, setVillage] = useState(); + + useEffect(() => { + const fetchVillages = async () => { + const villages = await OfflineService.getEntities('villages'); + const findvillage = villages.find(data => data.id === land.desa_kelurahan_id); + + setVillage(findvillage); + }; + fetchVillages(); + }); + return (
-

{land.nama}

+

{land.nama || land?.name}

{farmerName &&

{farmerName}

}
- - {validationLabels[land.validation_status]} + Lahan
@@ -61,7 +75,7 @@ export default function LandCard({ land, farmerName, plantCount = 0 }) {
- {land.village || land.desa_kelurahan_id }, {land.district || 'Unknown'} + {village?.nama || village?.name || land.desa_kelurahan_id }
+ + + +
+ ); + } return (
@@ -1123,7 +1240,7 @@ export default function FarmerPortal() {
-
+
-
+
setNewLandData(prev => ({ ...prev, district: e.target.value ? '1' : '0' }))} + value={locationData.districts[0]?.nama || "-"} + readOnly placeholder="Nama kecamatan" />
+
+
setNewLandData(prev => ({ ...prev, regency: e.target.value ? '1' : '0'}))} + value={locationData.regencies[0]?.nama} + readOnly placeholder="Nama kabupaten" />
-
-
- + setNewLandData(prev => ({ - ...prev, - village: e.target.value, - }))} + value={locationData.provinces[0]?.nama} + readOnly placeholder="Nama desa" />
diff --git a/src/pages/FarmerRegister copy.jsx b/src/pages/FarmerRegister copy.jsx old mode 100644 new mode 100755 diff --git a/src/pages/FarmerRegister.jsx b/src/pages/FarmerRegister.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Farmers.jsx b/src/pages/Farmers.jsx old mode 100644 new mode 100755 index b8e76ae6..fdde0aba --- a/src/pages/Farmers.jsx +++ b/src/pages/Farmers.jsx @@ -23,7 +23,7 @@ export default function Farmers() { queryFn: async () => { let serverData; try { - serverData = await entity("map","petani").list(); + serverData = await entity("auth","users").list(); } catch (err) { console.warn("Server unreachable, loading local data only"); } @@ -47,13 +47,16 @@ export default function Farmers() { // Filter farmers const filteredFarmers = farmersSafe.filter(farmer => { const matchSearch = !search || - farmer.full_name?.toLowerCase().includes(search.toLowerCase()) || - farmer.nik?.includes(search) || + farmer.full_name?.toLowerCase().includes(search.toLowerCase()) || farmer.nama?.toLowerCase().includes(search.toLowerCase()) || + farmer.nik?.includes(search) || farmer.kk?.includes(search) || farmer.ktp?.includes(search) || farmer.farmer_group?.toLowerCase().includes(search.toLowerCase()); - - const matchStatus = statusFilter === "all" || farmer.verification_status === statusFilter; - const matchRegion = regionFilter === "all" || farmer.regency === regionFilter; + + const currentStatus = farmer.user.email_verified_at !== null || farmer.user.email_verified_at !== undefined ? 'verified' : 'pending'; + const matchStatus = statusFilter === "all" || currentStatus === statusFilter; + + const matchRegion = regionFilter === "all" || farmer.regency === regionFilter; + console.log("status filter => ", matchStatus, farmer.user.email_verified_at, statusFilter); return matchSearch && matchStatus && matchRegion; }); diff --git a/src/pages/LandDetail.jsx b/src/pages/LandDetail.jsx old mode 100644 new mode 100755 index e022cd6b..4852dee2 --- a/src/pages/LandDetail.jsx +++ b/src/pages/LandDetail.jsx @@ -277,7 +277,7 @@ export default function LandDetail() { }); } }, [land, isEditing]); - console.log(land, "Data lahan"); + if (isLoading) { return (
diff --git a/src/pages/LandRegister.jsx b/src/pages/LandRegister.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Lands.jsx b/src/pages/Lands.jsx old mode 100644 new mode 100755 index 044febbd..e04cba80 --- a/src/pages/Lands.jsx +++ b/src/pages/Lands.jsx @@ -34,17 +34,17 @@ import { OfflineService } from "@/components/common/offlineStorage"; console.log(resp) if (Array.isArray(resp)) serverData = resp; } catch (e) { - console.warn("Server lands offline/error"); + console.warn("Server lands offline/error : ", e); } const localData = await OfflineService.getEntities("lands"); - console.log(localData) + const combined = new Map(); serverData.forEach(l => { if(l.id) combined.set(l.id, l); }); localData.forEach(l => { if(l.id) combined.set(l.id, l); }); const result = Array.from(combined.values()); - console.log("🔍 Total Lands Loaded (Server + Local):", result.length); + // console.log("🔍 Total Lands Loaded (Server + Local):", result.length); return result; } }); @@ -59,8 +59,8 @@ import { OfflineService } from "@/components/common/offlineStorage"; queryFn: async () => { let serverData = []; try { - const resp = await base44.entities.Farmer.list(); - serverData = Array.isArray(resp) ? resp : []; + const resp = await entity("map","profile").list(); + serverData = Array.isArray(resp?.data) ? resp.data : Array.isArray(resp?.data?.data) ? resp?.data?.data : []; } catch (e) { } const localData = await OfflineService.getEntities("farmers"); const combined = new Map(); @@ -72,7 +72,12 @@ import { OfflineService } from "@/components/common/offlineStorage"; const { data: rawplants = [] } = useQuery({ queryKey: ["plants"], - queryFn: () => base44.entities.Plant.list() + queryFn: async () => { + const rawplants = await entity('map','tanaman').list(); + const plants = Array.isArray(rawplants?.data) ? rawplants?.data : Array.isArray(rawplants?.data?.data) ? rawplants?.data?.data : []; + console.log(plants, "Tanamana") + return plants + } }); const lands = Array.isArray(rawlands) ? rawlands : []; @@ -82,7 +87,7 @@ import { OfflineService } from "@/components/common/offlineStorage"; const farmerMap = useMemo(() => { const map = {}; farmers.forEach(f => { - if (f?.id) map[f.id] = f.full_name; + if (f?.id) map[f.id] = f?.nama || f?.full_name || `Petani ${f.id}`; }); return map; }, [farmers]); @@ -99,13 +104,12 @@ import { OfflineService } from "@/components/common/offlineStorage"; // }); const filteredLands = useMemo(() => { - // Pastikan lands adalah array sebelum filter if (!Array.isArray(lands)) return []; return lands.filter(land => { if (!land) return false; - const landName = land.name?.toLowerCase() || ""; + const landName = land.nama?.toLowerCase() || ""; const village = land.village?.toLowerCase() || ""; const farmerName = farmerMap[land.farmer_id]?.toLowerCase() || ""; const searchTerm = search.toLowerCase(); @@ -134,7 +138,7 @@ import { OfflineService } from "@/components/common/offlineStorage"; }); return map; }, [plants]); - + console.log(farmerMap,farmers, "FArmer MAp", plants, lands); return (
@@ -242,8 +246,8 @@ import { OfflineService } from "@/components/common/offlineStorage"; > p.land_id === land.id).length} + farmerName={farmerMap[land.profile_id]} + plantCount={plants.filter(p => p.lahan.id === land.id).length} /> ))} diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx old mode 100644 new mode 100755 diff --git a/src/pages/NotAccessible.jsx b/src/pages/NotAccessible.jsx old mode 100644 new mode 100755 diff --git a/src/pages/OfftakerPortal copy.jsx b/src/pages/OfftakerPortal copy.jsx old mode 100644 new mode 100755 diff --git a/src/pages/OfftakerPortal.jsx b/src/pages/OfftakerPortal.jsx old mode 100644 new mode 100755 diff --git a/src/pages/Offtakers.jsx b/src/pages/Offtakers.jsx old mode 100644 new mode 100755 index 764e2feb..2ace09fd --- a/src/pages/Offtakers.jsx +++ b/src/pages/Offtakers.jsx @@ -12,6 +12,7 @@ import EmptyState from "@/components/common/EmptyState"; import { Package, Plus, Phone, MapPin, Loader2, Trash2 } from "lucide-react"; import { toast } from "sonner"; import { motion } from "framer-motion"; +import { entity } from "@/api/entities"; export default function Offtakers() { const queryClient = useQueryClient(); @@ -27,10 +28,11 @@ export default function Offtakers() { const { data: offtakers = [], isLoading } = useQuery({ queryKey: ["offtakers"], - queryFn: () => { + queryFn: async() => { try{ - const data = base44.entities.Offtaker.list(); - return Array.isArray(data) ? data : []; + const dataRaw = await entity('map', 'offtaker').list(); + const data = Array.isArray(dataRaw) ? dataRaw : Array.isArray(dataRaw?.data) ? dataRaw?.data : Array.isArray(dataRaw?.data?.data) ? dataRaw?.data?.data : []; + return data; }catch(e){ return []; } diff --git a/src/pages/Plants.jsx b/src/pages/Plants.jsx old mode 100644 new mode 100755 index a880e80e..2fbe1166 --- a/src/pages/Plants.jsx +++ b/src/pages/Plants.jsx @@ -12,6 +12,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { TreePine, Search, Filter, MapPin, Calendar, ChevronRight } from "lucide-react"; import { motion } from "framer-motion"; import { format } from "date-fns"; +import { entity } from "@/api/entities"; const statusColors = { alive: "bg-emerald-100 text-emerald-700 border-emerald-200", @@ -34,17 +35,26 @@ export default function Plants() { const { data: rawplants = [], isLoading } = useQuery({ queryKey: ["plants"], - queryFn: () => base44.entities.Plant.list("-created_date") + queryFn: async() => { + const rawData = await entity('map', 'tanaman').list(); + const data = Array.isArray(rawData?.data) ? rawData?.data : Array.isArray(rawData?.data?.data) ? rawData?.data?.data: []; + + return data; + } }); const { data: rawlands = [] } = useQuery({ queryKey: ["lands"], - queryFn: () => base44.entities.Land.list() + queryFn: async() => { + const rawData = await entity('map', 'lahan').list(); + const data = Array.isArray(rawData?.data) ? rawData?.data : Array.isArray(rawData?.data?.data) ? rawData?.data?.data : []; + return data; + } }); const { data: rawfarmers = [] } = useQuery({ queryKey: ["farmers"], - queryFn: () => base44.entities.Farmer.list() + queryFn: async() => await entity('auth', 'profile').list() }); const lands = Array.isArray(rawlands) ? rawlands : []; @@ -83,7 +93,7 @@ export default function Plants() { // return matchSearch && matchStatus && matchCommodity; // }); - + const filteredPlants = useMemo(() => { const searchTerm = search.toLowerCase(); return plants.filter(plant => { @@ -91,7 +101,7 @@ export default function Plants() { const matchSearch = !search || plant.commodity_name?.toLowerCase().includes(searchTerm) || - landMap[plant.land_id]?.name?.toLowerCase().includes(searchTerm) || + landMap[plant.land_id]?.nama?.toLowerCase().includes(searchTerm) || farmerMap[plant.farmer_id]?.toLowerCase().includes(searchTerm); const matchStatus = statusFilter === "all" || plant.status === statusFilter; @@ -112,7 +122,7 @@ export default function Plants() { const groupedByCommodity = useMemo(() => { const groups = {}; filteredPlants.forEach(plant => { - const key = plant.commodity_name || "Lainnya"; + const key = plant?.nama || plant?.commodity_name || "Lainnya"; if (!groups[key]) groups[key] = []; groups[key].push(plant); }); @@ -256,7 +266,7 @@ export default function Plants() {
{commodityPlants.map((plant, idx) => { - const land = landMap[plant.land_id]; + const land = landMap[plant.lahan.id]; return (
- - {statusLabels[plant.status]} + + {statusLabels[plant.status ?? 'alive']}
@@ -281,11 +291,11 @@ export default function Plants() {
- {land?.name || "Lahan tidak diketahui"} + {land?.nama || land?.name || "Lahan tidak diketahui"}
- {plant.plant_date ? format(new Date(plant.plant_date), "dd MMM yyyy") : "-"} + {plant.created_at ? format(new Date(plant.created_at), "dd MMM yyyy") : "-"}
diff --git a/src/pages/ProductivityMonitoring.jsx b/src/pages/ProductivityMonitoring.jsx old mode 100644 new mode 100755 index 4624722a..70df058a --- a/src/pages/ProductivityMonitoring.jsx +++ b/src/pages/ProductivityMonitoring.jsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect, useMemo } from "react"; import { useQuery } from "@tanstack/react-query"; import base44 from "@/api/Client"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -40,19 +40,37 @@ const issueLabels = { export default function ProductivityMonitoring() { const [filterLevel, setFilterLevel] = useState("regency"); const [selectedRegion, setSelectedRegion] = useState("all"); + + // Reset selected region when filter level changes + useEffect(() => { + setSelectedRegion("all"); + }, [filterLevel]); + + const getMe = async() => { + const resp = await entity('auth', 'profile/1').list(); + const me = resp.data; + return me; + }; + const {data: rawLands = []} = useQuery({ queryKey: ['lands'], queryFn: async () => { + let me; let dataServer = []; try{ + me = await getMe(); + const res = await entity('map', 'lahan').list(); - dataServer = Array.isArray(res.data) ? res.data : []; + const data = res.data; + dataServer = Array.isArray(data) ? data.filter((land) => land.profile_id === me.id) : []; }catch(err){ console.error(err) } - const localData = await OfflineService.getEntities('lands'); + const localRes = await OfflineService.getEntities('lands'); + const localData = localRes.filter((data) => data.profile_id === me.id); + const combined = new Map(); dataServer.forEach(d => { if (d.id) combined.set(d.id, { ...d, storage: 'server' }); @@ -71,15 +89,28 @@ export default function ProductivityMonitoring() { } }); + const { data: villages = []} = useQuery({ + queryKey: ['villages'], + queryFn: async () => { + const resp = await OfflineService.getEntities('villages'); + + return resp||resp?.data || resp?.data?.data || []; + } + }); + const {data: rawPlants = []} = useQuery({ queryKey: ['plants'], queryFn: async () => { let data = []; + let me; try{ + me = await getMe(); + console.log(me, "Med") const res = await entity('map', 'tanaman').list(); - data = Array.isArray(res.data.data) ? res.data.data :[]; + if(me){data = Array.isArray(res.data.data) ? res.data.data.filter((data) => data.profile_id === me.id) :[];} }catch(e){} - const local = await OfflineService.getEntities('plants'); + let local = await OfflineService.getEntities('plants'); + local = Array.isArray(local) ? local.filter((l) => l.profile_id === me.id) : []; const mapped = new Map(); data.forEach(d => { if(d.id) mapped.set(d.id, {...d, storage:'server'}) @@ -93,18 +124,14 @@ export default function ProductivityMonitoring() { const lands = Array.isArray(rawLands) ? rawLands : []; const plants = Array.isArray(rawPlants) ? rawPlants : []; - - // const { data: harvests = [] } = useQuery({ - // queryKey: ["harvests"], - // queryFn: () => base44.entities.Harvest.list() - // }); const { data: rawHarvests = [] } = useQuery({ queryKey: ["harvests"], queryFn: async () => { try { const res = await entity('map', 'panen').list(); - return Array.isArray(res.data.data) ? res.data.data : []; + let harvests = res?.data || res?.data?.data || []; + return Array.isArray(harvests) ? harvests.filter((hr) => hr.profile_id === getMe.id) : []; } catch (e) { return []; } @@ -114,30 +141,60 @@ export default function ProductivityMonitoring() { const harvests = Array.isArray(rawHarvests) ? rawHarvests : []; // Get unique regions - const regions = { + const regions = useMemo(() => ({ regency: [...new Set(lands.map(l => l.regency).filter(Boolean))], district: [...new Set(lands.map(l => l.district).filter(Boolean))], - village: [...new Set(lands.map(l => l.village).filter(Boolean))] - }; + village: filterLevel === "village" + ? [...new Set([ + ...villages.map(v => v.name || v.desa || v.village_name).filter(Boolean), + ...lands.map(l => l.village || l.village_name || l.desa || l.village_id).filter(Boolean) + ])] + : [...new Set(lands.map(l => l.village || l.village_name || l.desa || l.village_id).filter(Boolean))] + }), [lands, villages, filterLevel]); + + // Create village mapping for proper filtering + const villageMapping = lands.reduce((acc, land) => { + const villageName = land.village || land.village_name || land.desa || land.village_id; + const villageId = land.village_id || land.village; + if (villageName && villageId) { + acc[villageName] = villageId; + } + return acc; + }, {}); // Filter data by region const filteredLands = selectedRegion === "all" ? lands - : lands.filter(l => l[filterLevel] === selectedRegion); + : filterLevel === "village" + ? lands.filter(l => { + const villageName = l.village || l.village_name || l.desa || l.village_id; + const villageId = l.village_id || l.village; + return villageName === selectedRegion || villageId === selectedRegion; + }) + : lands.filter(l => l[filterLevel] === selectedRegion); const filteredLandIds = filteredLands.map(l => l.id); const filteredPlants = plants.filter(p => filteredLandIds.includes(p.land_id || p.lahan_id)); - - // Calculate productivity stats + const calculateProductivityStats = () => { const totalLands = filteredLands.length; - if (totalLands === 0) return { avg: 0, distribution: [] }; - + if (totalLands === 0) return { avg: 0, distribution: [], harvestBasedAvg: 0, combinedAvg: 0 }; + const landsWithProductivity = filteredLands.filter(l => l.productivity_percentage !== undefined); - const avgProductivity = landsWithProductivity.length > 0 + const landBasedAvg = landsWithProductivity.length > 0 ? landsWithProductivity.reduce((sum, l) => sum + (l.productivity_percentage || 0), 0) / landsWithProductivity.length : 0; + // Calculate harvest-based productivity + const harvestProductivity = calculateHarvestBasedProductivity(); + + // Combined average (weighted) + const combinedAvg = landsWithProductivity.length > 0 && harvestProductivity.totalHarvests > 0 + ? (landBasedAvg + harvestProductivity.avg) / 2 + : landsWithProductivity.length > 0 + ? landBasedAvg + : harvestProductivity.avg; + const distribution = [ { name: "Sangat Produktif (>80%)", value: filteredLands.filter(l => (l.productivity_percentage || 0) > 80).length, color: "#10b981" }, { name: "Produktif (60-80%)", value: filteredLands.filter(l => (l.productivity_percentage || 0) >= 60 && (l.productivity_percentage || 0) <= 80).length, color: "#22c55e" }, @@ -145,7 +202,65 @@ export default function ProductivityMonitoring() { { name: "Tidak Produktif (<40%)", value: filteredLands.filter(l => (l.productivity_percentage || 0) < 40).length, color: "#ef4444" } ]; - return { avg: avgProductivity, distribution }; + return { + avg: landBasedAvg, + distribution, + harvestBasedAvg: harvestProductivity.avg, + combinedAvg, + harvestDetails: harvestProductivity + }; + }; + + // Calculate harvest-based productivity + const calculateHarvestBasedProductivity = () => { + const filteredHarvests = harvests.filter(h => filteredLandIds.includes(h.land_id)); + + if (filteredHarvests.length === 0) { + return { avg: 0, totalHarvests: 0, totalWeight: 0, landProductivity: [] }; + } + + // Group harvests by land + const harvestByLand = filteredHarvests.reduce((acc, harvest) => { + if (!acc[harvest.land_id]) { + acc[harvest.land_id] = { totalWeight: 0, harvestCount: 0 }; + } + acc[harvest.land_id].totalWeight += harvest.weight_kg || 0; + acc[harvest.land_id].harvestCount++; + return acc; + }, {}); + + // Calculate productivity per land based on harvest weight vs land area + const landProductivity = Object.entries(harvestByLand).map(([landId, data]) => { + const land = filteredLands.find(l => l.id === landId); + const area = land?.area_hectares || 1; // Default to 1 hectare if not specified + const yieldPerHa = data.totalWeight / area; + + // Normalize to percentage (assuming 1000kg/ha as optimal yield) + const productivityPercentage = Math.min((yieldPerHa / 1000) * 100, 100); + + return { + landId, + landName: land?.name || `Lahan ${landId.slice(0, 8)}`, + area, + totalWeight: data.totalWeight, + harvestCount: data.harvestCount, + yieldPerHa, + productivityPercentage + }; + }); + + const totalWeight = filteredHarvests.reduce((sum, h) => sum + (h.weight_kg || 0), 0); + const totalArea = landProductivity.reduce((sum, lp) => sum + lp.area, 0); + const overallYieldPerHa = totalArea > 0 ? totalWeight / totalArea : 0; + const avgProductivity = Math.min((overallYieldPerHa / 1000) * 100, 100); + + return { + avg: avgProductivity, + totalHarvests: filteredHarvests.length, + totalWeight, + landProductivity, + overallYieldPerHa + }; }; // Calculate plant health stats @@ -227,7 +342,13 @@ export default function ProductivityMonitoring() {

Pantau produktivitas lahan dan tanaman

- { + console.log('Filter level changed to:', v); + console.log('Before setFilterLevel, current filterLevel:', filterLevel); + setFilterLevel(v); + setSelectedRegion("all"); + console.log('After setFilterLevel, new value should be:', v); + }}> @@ -261,7 +382,8 @@ export default function ProductivityMonitoring() {

Avg Produktivitas

-

{productivityStats.avg.toFixed(0)}%

+

{productivityStats.combinedAvg.toFixed(0)}%

+

Lahan: {productivityStats.avg.toFixed(0)}% | Panen: {productivityStats.harvestBasedAvg.toFixed(0)}%

@@ -301,7 +423,8 @@ export default function ProductivityMonitoring() {

Bermasalah

- {filteredPlants.filter(p => p.issue_type && p.issue_type !== "none").length} + + {filteredPlants.filter(p => p?.kondisi_tanaman === 'sakit').length}

@@ -309,6 +432,52 @@ export default function ProductivityMonitoring() { + {/* Productivity Details */} + + + +
+
+ +
+
+

Produktivitas Lahan

+

{productivityStats.avg.toFixed(1)}%

+

Berdasarkan data lahan

+
+
+
+
+ + +
+
+ +
+
+

Produktivitas Panen

+

{productivityStats.harvestBasedAvg.toFixed(1)}%

+

{productivityStats.harvestDetails?.totalWeight || 0}kg dari {productivityStats.harvestDetails?.totalHarvests || 0} panen

+
+
+
+
+ + +
+
+ +
+
+

Rata-rata Hasil/Ha

+

{productivityStats.harvestDetails?.overallYieldPerHa?.toFixed(0) || 0} kg

+

Total produktivitas per hektar

+
+
+
+
+
+ {/* Charts */}
{/* Regional Productivity Chart */} diff --git a/src/pages/Register.jsx b/src/pages/Register.jsx old mode 100644 new mode 100755 diff --git a/src/pages/ValidatorPortal copy.jsx b/src/pages/ValidatorPortal copy.jsx new file mode 100755 index 00000000..168b07bd --- /dev/null +++ b/src/pages/ValidatorPortal copy.jsx @@ -0,0 +1,398 @@ +import { useState, useEffect } from "react"; +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; +import base44 from "@/api/Client"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { Textarea } from "@/components/ui/textarea"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import LandMap from "@/components/lands/LandMap"; +import EmptyState from "@/components/common/EmptyState"; +import { + Shield, Map, CheckCircle, XCircle, Clock, LogOut, + User, MapPin, Loader2, FileCheck, AlertTriangle +} from "lucide-react"; +import { toast } from "sonner"; +import { motion } from "framer-motion"; +import { format } from "date-fns"; +import { id } from "date-fns/locale"; +import { entity } from "@/api/entities"; + +const roleLabels = { + kepala_desa: "Kepala Desa", + kepala_dusun: "Kepala Dusun", + rt: "Ketua RT", + rw: "Ketua RW", + fasilitator: "Fasilitator" +}; + +const statusStyles = { + pending: { bg: "bg-amber-100", text: "text-amber-700", label: "Menunggu Validasi" }, + valid: { bg: "bg-emerald-100", text: "text-emerald-700", label: "Valid" }, + invalid: { bg: "bg-red-100", text: "text-red-700", label: "Tidak Valid" }, + need_review: { bg: "bg-blue-100", text: "text-blue-700", label: "Perlu Review" } +}; + +export default function ValidatorPortal() { + const queryClient = useQueryClient(); + const [user, setUser] = useState(null); + const [validator, setValidator] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [selectedLand, setSelectedLand] = useState(null); + const [validationNotes, setValidationNotes] = useState(""); + + useEffect(() => { + const loadData = async () => { + try { + const currentUser = await entity('auth', 'me').list(); + console.log((currentUser).data.role) + // if(currentUser.data.role !== 'validator'){ + // setUser(null) + // setValidator(null) + // } else{ + setUser(currentUser); + setValidator(currentUser) + // } + + // const validators = await base44.entities.Validator.filter({ user_email: currentUser.email }); + // if (validators.length > 0 && validators[0].is_active) { + // setValidator(validators[0]); + // } + } catch (error) { + } finally { + setIsLoading(false); + } + }; + loadData(); + }, []); + + // Load lands in validator's area that need validation + const { data: lands = [] } = useQuery({ + queryKey: ["validator-lands", validator?.village], + queryFn: () => base44.entities.Land.filter({ village: validator.village }), + enabled: !!validator?.village + }); + + // Load farmers for reference + const { data: farmers = [] } = useQuery({ + queryKey: ["farmers"], + queryFn: () => base44.entities.Farmer.list(), + enabled: !!validator + }); + + // Load validation history + const { data: validations = [] } = useQuery({ + queryKey: ["validations", validator?.id], + queryFn: () => base44.entities.LandValidation.filter({ validator_email: validator.user_email }), + enabled: !!validator + }); + + // Validate land mutation + const validateMutation = useMutation({ + mutationFn: async ({ landId, status }) => { + const validationStatus = status === "approved" ? "valid" : "invalid"; + + // Update land status + await base44.entities.Land.update(landId, { + validation_status: validationStatus, + validation_notes: validationNotes + }); + + // Create validation record + await base44.entities.LandValidation.create({ + land_id: landId, + validator_role: validator.role, + validator_name: validator.full_name, + validator_email: validator.user_email, + status: status, + notes: validationNotes, + validated_at: new Date().toISOString() + }); + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["validator-lands"] }); + queryClient.invalidateQueries({ queryKey: ["validations"] }); + setSelectedLand(null); + setValidationNotes(""); + toast.success("Validasi berhasil disimpan!"); + } + }); + + const handleLogin = () => { + base44.auth.redirectToLogin(window.location.href); + }; + + const handleLogout = () => { + base44.auth.logout(); + }; + + const getFarmerName = (farmerId) => { + const farmer = farmers.find(f => f.id === farmerId); + return farmer?.full_name || "Tidak diketahui"; + }; + + const pendingLands = lands.filter(l => l.validation_status === "pending" || l.validation_status === "need_review"); + const validatedLands = lands.filter(l => l.validation_status === "valid" || l.validation_status === "invalid"); + + if (isLoading) { + return ( +
+ +
+ ); + } + + if (!user) { + return ( +
+ + + +
+ +
+

Portal Validator

+

+ Masuk untuk memvalidasi lahan di wilayah Anda +

+ +
+
+
+
+ ); + } + + if (!validator) { + return ( +
+ + + +
+ +
+

Akses Ditolak

+

+ Email {user.email} tidak terdaftar sebagai validator. +

+

+ Hubungi admin untuk mendaftarkan Anda sebagai validator wilayah. +

+ +
+
+
+
+ ); + } + + return ( +
+
+ {/* Header */} + +
+
+ +
+
+

{validator.full_name}

+ + {roleLabels[validator.role]} - {validator.village} + +
+
+ +
+ + {/* Stats */} + + + +

{pendingLands.length}

+

Perlu Validasi

+
+ + +

{validations.filter(v => v.status === "approved").length}

+

Disetujui

+
+ + +

{validations.filter(v => v.status === "rejected").length}

+

Ditolak

+
+
+ + {/* Tabs */} + + + + + + Perlu Validasi ({pendingLands.length}) + + + + Riwayat + + + + + {pendingLands.length > 0 ? ( +
+ {pendingLands.map(land => ( + + +
+
+

{land.name}

+

Pemilik: {getFarmerName(land.farmer_id)}

+
+ + {statusStyles[land.validation_status]?.label} + +
+
+ + + {land.village}, {land.district} + + {land.area_hectares?.toFixed(2)} Ha +
+ +
+
+ ))} +
+ ) : ( + + )} +
+ + + {validations.length > 0 ? ( +
+ {validations.map(v => { + const land = lands.find(l => l.id === v.land_id); + return ( + +
+
+

{land?.name || "Lahan"}

+

+ {v.validated_at ? format(new Date(v.validated_at), "dd MMM yyyy, HH:mm", { locale: id }) : "-"} +

+
+ + {v.status === "approved" ? "Disetujui" : "Ditolak"} + +
+ {v.notes &&

{v.notes}

} +
+ ); + })} +
+ ) : ( + + )} +
+
+
+
+ + {/* Validation Dialog */} + setSelectedLand(null)}> + + + Validasi Lahan: {selectedLand?.name} + + + {selectedLand && ( +
+
+
+

Pemilik

+

{getFarmerName(selectedLand.farmer_id)}

+
+
+

Luas

+

{selectedLand.area_hectares?.toFixed(4)} Ha

+
+
+

Lokasi

+

{selectedLand.village}, {selectedLand.district}, {selectedLand.regency}

+
+
+ +
+ +
+ +
+ +