From d7053404747ac42a57d4ce882543430b56a57e22 Mon Sep 17 00:00:00 2001 From: Divyansh Dixit Date: Wed, 1 Apr 2026 03:55:50 +0530 Subject: [PATCH 1/3] Restrict ULPIN generation to India using reverse geocoding --- frontend-ui/package-lock.json | 270 +++++++++++++------------ frontend-ui/src/components/Mapview.jsx | 73 ++++--- 2 files changed, 181 insertions(+), 162 deletions(-) diff --git a/frontend-ui/package-lock.json b/frontend-ui/package-lock.json index 382dd22..d0c07be 100644 --- a/frontend-ui/package-lock.json +++ b/frontend-ui/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "axios": "^1.13.6", + "leaflet": "^1.9.4", "react": "^19.2.4", "react-dom": "^19.2.4" }, @@ -265,24 +266,26 @@ } }, "node_modules/@emnapi/core": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz", - "integrity": "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz", - "integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -294,6 +297,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -558,36 +562,28 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", - "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz", + "integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" - } - }, - "node_modules/@oxc-project/runtime": { - "version": "0.115.0", - "resolved": "https://registry.npmjs.org/@oxc-project/runtime/-/runtime-0.115.0.tgz", - "integrity": "sha512-Rg8Wlt5dCbXhQnsXPrkOjL1DTSvXLgb2R/KYfnf1/K+R0k6UMLEmbQXPM+kwrWqSmWA2t0B1EtHy2/3zikQpvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, "node_modules/@oxc-project/types": { - "version": "0.115.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.115.0.tgz", - "integrity": "sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==", + "version": "0.122.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz", + "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==", "dev": true, "license": "MIT", "funding": { @@ -595,9 +591,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.9.tgz", - "integrity": "sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==", "cpu": [ "arm64" ], @@ -612,9 +608,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.9.tgz", - "integrity": "sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==", "cpu": [ "arm64" ], @@ -629,9 +625,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.9.tgz", - "integrity": "sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.12.tgz", + "integrity": "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==", "cpu": [ "x64" ], @@ -646,9 +642,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.9.tgz", - "integrity": "sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.12.tgz", + "integrity": "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==", "cpu": [ "x64" ], @@ -663,9 +659,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.9.tgz", - "integrity": "sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.12.tgz", + "integrity": "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==", "cpu": [ "arm" ], @@ -680,9 +676,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.9.tgz", - "integrity": "sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==", "cpu": [ "arm64" ], @@ -697,9 +693,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.9.tgz", - "integrity": "sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.12.tgz", + "integrity": "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==", "cpu": [ "arm64" ], @@ -714,9 +710,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.9.tgz", - "integrity": "sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==", "cpu": [ "ppc64" ], @@ -731,9 +727,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.9.tgz", - "integrity": "sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==", "cpu": [ "s390x" ], @@ -748,9 +744,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.9.tgz", - "integrity": "sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==", "cpu": [ "x64" ], @@ -765,9 +761,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.9.tgz", - "integrity": "sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.12.tgz", + "integrity": "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==", "cpu": [ "x64" ], @@ -782,9 +778,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.9.tgz", - "integrity": "sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==", "cpu": [ "arm64" ], @@ -799,9 +795,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.9.tgz", - "integrity": "sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.12.tgz", + "integrity": "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==", "cpu": [ "wasm32" ], @@ -816,9 +812,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.9.tgz", - "integrity": "sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.12.tgz", + "integrity": "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==", "cpu": [ "arm64" ], @@ -833,9 +829,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.9.tgz", - "integrity": "sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.12.tgz", + "integrity": "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==", "cpu": [ "x64" ], @@ -997,14 +993,14 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", - "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz", + "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "proxy-from-env": "^2.1.0" } }, "node_modules/balanced-match": { @@ -1015,9 +1011,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.8", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.8.tgz", - "integrity": "sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ==", + "version": "2.10.13", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.13.tgz", + "integrity": "sha512-BL2sTuHOdy0YT1lYieUxTw/QMtPBC3pmlJC6xk8BBYVv6vcw3SGdKemQ+Xsx9ik2F/lYDO9tqsFQH1r9PFuHKw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1028,9 +1024,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -1039,9 +1035,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, "funding": [ { @@ -1059,11 +1055,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -1096,9 +1092,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001780", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001780.tgz", - "integrity": "sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==", + "version": "1.0.30001782", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001782.tgz", + "integrity": "sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==", "dev": true, "funding": [ { @@ -1260,9 +1256,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.313", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz", - "integrity": "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==", + "version": "1.5.329", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.329.tgz", + "integrity": "sha512-/4t+AS1l4S3ZC0Ja7PHFIWeBIxGA3QGqV8/yKsP36v7NcyUCl+bIcmw6s5zVuMIECWwBrAK/6QLzTmbJChBboQ==", "dev": true, "license": "ISC" }, @@ -1602,9 +1598,9 @@ } }, "node_modules/flatted": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", - "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -1963,6 +1959,12 @@ "json-buffer": "3.0.1" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2445,9 +2447,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -2497,10 +2499,13 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/punycode": { "version": "2.3.1", @@ -2544,14 +2549,14 @@ } }, "node_modules/rolldown": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.9.tgz", - "integrity": "sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.12.tgz", + "integrity": "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.115.0", - "@rolldown/pluginutils": "1.0.0-rc.9" + "@oxc-project/types": "=0.122.0", + "@rolldown/pluginutils": "1.0.0-rc.12" }, "bin": { "rolldown": "bin/cli.mjs" @@ -2560,27 +2565,27 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-rc.9", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.9", - "@rolldown/binding-darwin-x64": "1.0.0-rc.9", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.9", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.9", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.9", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.9", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.9", - "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.9", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.9", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.9", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.9", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.9", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.9", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.9" + "@rolldown/binding-android-arm64": "1.0.0-rc.12", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", + "@rolldown/binding-darwin-x64": "1.0.0-rc.12", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" } }, "node_modules/rolldown/node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.9", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.9.tgz", - "integrity": "sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.12.tgz", + "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==", "dev": true, "license": "MIT" }, @@ -2739,17 +2744,16 @@ } }, "node_modules/vite": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.0.tgz", - "integrity": "sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz", + "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/runtime": "0.115.0", "lightningcss": "^1.32.0", - "picomatch": "^4.0.3", + "picomatch": "^4.0.4", "postcss": "^8.5.8", - "rolldown": "1.0.0-rc.9", + "rolldown": "1.0.0-rc.12", "tinyglobby": "^0.2.15" }, "bin": { @@ -2766,7 +2770,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.0.0-alpha.31", + "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0", "jiti": ">=1.21.0", "less": "^4.0.0", diff --git a/frontend-ui/src/components/Mapview.jsx b/frontend-ui/src/components/Mapview.jsx index c71d553..da62aeb 100644 --- a/frontend-ui/src/components/Mapview.jsx +++ b/frontend-ui/src/components/Mapview.jsx @@ -63,6 +63,7 @@ async function reverseGeocode(lat, lng, signal) { state: addr.state || '', district: addr.county || addr.state_district || '', city: addr.city || addr.town || addr.village || '', + country: addr.country || '', displayName: data.display_name || '', }; } @@ -82,7 +83,7 @@ export default function MapView({ onNavigateRegister }) { const [ulpin, setUlpin] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); - + const [isIndia, setIsIndia] = useState(false); const pinIcon = useCallback(() => L.divIcon({ className: '', html: `
-
- Generated ULPIN -
+
+ Generated ULPIN +
-
- +
- {ulpin} - -
- -

- Tap below to open the Register form with ULPIN and GPS pre-filled. + + {ulpin} + +

+ +

+ Tap below to open the Register form with ULPIN and GPS pre-filled. +

+ + + + ) : ( +

+ ULPIN generation is only available for locations within India.

- - + )}
)} From 090bbf6482743804f462ebbb27091a46a8480614 Mon Sep 17 00:00:00 2001 From: Divyansh Dixit Date: Mon, 6 Apr 2026 22:26:56 +0530 Subject: [PATCH 2/3] Add Leaflet dependency and enhance ULPIN generation for India locations --- frontend-ui/DEPENDENCY_CHANGES.md | 29 ++++++++++ frontend-ui/src/components/Mapview.jsx | 78 +++++++++++++++----------- 2 files changed, 74 insertions(+), 33 deletions(-) create mode 100644 frontend-ui/DEPENDENCY_CHANGES.md diff --git a/frontend-ui/DEPENDENCY_CHANGES.md b/frontend-ui/DEPENDENCY_CHANGES.md new file mode 100644 index 0000000..aeec406 --- /dev/null +++ b/frontend-ui/DEPENDENCY_CHANGES.md @@ -0,0 +1,29 @@ +# Frontend UI - Dependency Version Changes + +## Lockfile Updates (package-lock.json) + +This PR includes the following dependency version upgrades in addition to adding Leaflet for map functionality: + +### Production Dependencies +- **axios**: `1.13.6` → `1.14.0` (minor version bump, backward compatible) +- **leaflet**: `^1.9.4` (newly added for map functionality) + +### Development Dependencies +- **vite**: `8.0.0` → `8.0.3` (patch version bump, bug fixes) +- Various Babel and build tool dependencies updated to compatible versions + +## Rationale + +These version upgrades are the result of: +1. **Leaflet addition**: A new dependency required for the land parcel map visualization feature +2. **npm install resolution**: When adding leaflet, npm resolved dependencies to the latest patch/minor versions compatible with the `^` constraints in package.json + +## Compatibility Notes + +- **axios 1.14.0**: Includes minor improvements and is fully backward-compatible with existing API calls +- **vite 8.0.3**: Patch release with bug fixes; no breaking changes +- All upgrades maintain the caret (`^`) version constraints specified in package.json + +## Recommendation + +If stricter version pinning is desired for production stability, consider updating package.json to use exact versions (e.g., `"vite": "8.0.3"` instead of `"vite": "^8.0.0"`). diff --git a/frontend-ui/src/components/Mapview.jsx b/frontend-ui/src/components/Mapview.jsx index da62aeb..3808739 100644 --- a/frontend-ui/src/components/Mapview.jsx +++ b/frontend-ui/src/components/Mapview.jsx @@ -59,11 +59,14 @@ async function reverseGeocode(lat, lng, signal) { if (!res.ok) throw new Error(`Geocoding failed (${res.status})`); const data = await res.json(); const addr = data.address || {}; + // Use country_code (ISO-3166) for stable India detection; normalize case and trim + const countryCode = (addr.country_code || '').trim().toLowerCase(); return { state: addr.state || '', district: addr.county || addr.state_district || '', city: addr.city || addr.town || addr.village || '', country: addr.country || '', + countryCode, // ISO-3166 code (e.g., 'in' for India) displayName: data.display_name || '', }; } @@ -124,7 +127,9 @@ export default function MapView({ onNavigateRegister }) { // Discard if a newer click already superseded this one if (thisReq !== reqIdRef.current) return; setGeocode(geo); - if (geo.country === 'India') { + // Use ISO-3166 country code ('in' for India) for stable, localization-independent detection + const isIndiaLocation = geo.countryCode === 'in'; + if (isIndiaLocation) { setIsIndia(true); setUlpin(generateUlpin(geo, lat, lng)); } else { @@ -257,45 +262,52 @@ export default function MapView({ onNavigateRegister }) { )} - {!loading && geocode && ( + {!loading && geocode && isIndia && (
Generated ULPIN
- {isIndia ? ( - <> -
+
+ - - {ulpin} - -
- -

- Tap below to open the Register form with ULPIN and GPS pre-filled. -

- - - - ) : ( -

- ULPIN generation is only available for locations within India. + {ulpin} + +

+ +

+ Tap below to open the Register form with ULPIN and GPS pre-filled.

- )} + + + +
+ )} + + {!loading && geocode && !isIndia && ( +
+
+ Location Status +
+ +

+ ULPIN generation is only available for locations within India.
+ Please select a location on the Indian map to enable ULPIN creation. +

)} From 3868f4005b4d4b9482d14246a65b63a54bd53209 Mon Sep 17 00:00:00 2001 From: Divyansh Dixit Date: Tue, 7 Apr 2026 02:31:17 +0530 Subject: [PATCH 3/3] feat: implement authentication system with React Router, login pages, and protected routes --- frontend-ui/package-lock.json | 44 +++++- frontend-ui/package.json | 3 +- frontend-ui/src/App.jsx | 88 ++---------- frontend-ui/src/components/auth/LoginView.jsx | 132 ++++++++++++++++++ .../src/components/auth/ProtectedRoute.jsx | 11 ++ frontend-ui/src/index.css | 89 ++++++++++++ frontend-ui/src/layouts/DashboardLayout.jsx | 97 +++++++++++++ frontend-ui/src/main.jsx | 5 +- frontend-ui/src/pages/AdminLogin.jsx | 12 ++ frontend-ui/src/pages/UserLogin.jsx | 13 ++ 10 files changed, 417 insertions(+), 77 deletions(-) create mode 100644 frontend-ui/src/components/auth/LoginView.jsx create mode 100644 frontend-ui/src/components/auth/ProtectedRoute.jsx create mode 100644 frontend-ui/src/layouts/DashboardLayout.jsx create mode 100644 frontend-ui/src/pages/AdminLogin.jsx create mode 100644 frontend-ui/src/pages/UserLogin.jsx diff --git a/frontend-ui/package-lock.json b/frontend-ui/package-lock.json index d0c07be..b8c1c33 100644 --- a/frontend-ui/package-lock.json +++ b/frontend-ui/package-lock.json @@ -11,7 +11,8 @@ "axios": "^1.13.6", "leaflet": "^1.9.4", "react": "^19.2.4", - "react-dom": "^19.2.4" + "react-dom": "^19.2.4", + "react-router-dom": "^6.30.3" }, "devDependencies": { "@eslint/js": "^9.39.4", @@ -590,6 +591,15 @@ "url": "https://github.com/sponsors/Boshen" } }, + "node_modules/@remix-run/router": { + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz", + "integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz", @@ -2538,6 +2548,38 @@ "react": "^19.2.4" } }, + "node_modules/react-router": { + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz", + "integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz", + "integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.2", + "react-router": "6.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", diff --git a/frontend-ui/package.json b/frontend-ui/package.json index 0fc6e59..dddc819 100644 --- a/frontend-ui/package.json +++ b/frontend-ui/package.json @@ -13,7 +13,8 @@ "axios": "^1.13.6", "leaflet": "^1.9.4", "react": "^19.2.4", - "react-dom": "^19.2.4" + "react-dom": "^19.2.4", + "react-router-dom": "^6.30.3" }, "devDependencies": { "@eslint/js": "^9.39.4", diff --git a/frontend-ui/src/App.jsx b/frontend-ui/src/App.jsx index 917a295..1e52bf4 100644 --- a/frontend-ui/src/App.jsx +++ b/frontend-ui/src/App.jsx @@ -1,80 +1,20 @@ -import { useState } from 'react'; -import RegisterLand from './components/RegisterLand'; -import SearchLand from './components/SearchLand'; -import OwnerSearch from './components/OwnerSearch'; -import TransferLand from './components/TransferLand'; -import MutateLand from './components/MutateLand'; -import AssetHistory from './components/AssetHistory'; -import MapView from "./components/Mapview"; +import { Routes, Route, Navigate } from 'react-router-dom'; +import DashboardLayout from './layouts/DashboardLayout'; +import UserLogin from './pages/UserLogin'; +import AdminLogin from './pages/AdminLogin'; +import ProtectedRoute from './components/auth/ProtectedRoute'; import './index.css'; -const NAV_ITEMS = [ - { id: 'register', label: 'Register Parcel', icon: '⊕' }, - { id: 'search', label: 'Search by ULPIN', icon: '◎' }, - { id: 'owner', label: 'Search by Owner', icon: '◈' }, - { id: 'map', label: 'Search by Map', icon: '⊞' }, - { id: 'transfer', label: 'Transfer Ownership', icon: '⇌' }, - { id: 'mutate', label: 'Mutate / Split', icon: '⊗' }, - { id: 'history', label: 'Audit Trail', icon: '◷' }, -]; - export default function App() { - const [active, setActive] = useState('register'); - const [prefill, setPrefill] = useState(null); - - const navigateTo = (page, data = null) => { - setPrefill(data); - setActive(page); - }; - - const renderPage = () => { - switch (active) { - case 'register': return setPrefill(null)} />; - case 'search': return ; - case 'owner': return ; - case 'map': return navigateTo('register', data)} />; - case 'transfer': return ; - case 'mutate': return ; - case 'history': return ; - default: return null; - } - }; - return ( -
- - -
- {renderPage()} -
-
+ + } /> + } /> + + + + } /> + ); } \ No newline at end of file diff --git a/frontend-ui/src/components/auth/LoginView.jsx b/frontend-ui/src/components/auth/LoginView.jsx new file mode 100644 index 0000000..9988f2d --- /dev/null +++ b/frontend-ui/src/components/auth/LoginView.jsx @@ -0,0 +1,132 @@ +import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +export default function LoginView({ title, subtitle, idPlacholder, idLabel, isUserLogin = true }) { + const navigate = useNavigate(); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + const [formData, setFormData] = useState({ + id: '', + password: '' + }); + + const handleChange = (e) => { + setFormData(prev => ({ + ...prev, + [e.target.name]: e.target.value + })); + if (error) setError(''); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + setLoading(true); + setError(''); + + // Basic frontend validation + if (!formData.id || !formData.password) { + setLoading(false); + setError('Please fill in all fields.'); + return; + } + + if (formData.password.length < 5) { + setLoading(false); + setError('Invalid credentials.'); + return; + } + + // Mock authentication + setTimeout(() => { + setLoading(false); + // On success, set auth state and redirect to dashboard + localStorage.setItem('isAuthenticated', 'true'); + localStorage.setItem('userRole', isUserLogin ? 'user' : 'admin'); + navigate('/'); + }, 1000); + }; + + return ( +
+
+
+
+
+

BHUMI REGISTRY

+

Ministry of Rural Development

+
+
+ +
+
+

{title}

+

{subtitle}

+
+ + {error && ( +
+ {error} +
+ )} + +
+
+ + +
+ +
+
+ + {isUserLogin && ( + e.preventDefault()}>Forgot password? + )} +
+ +
+ + {isUserLogin && ( +
+ + +
+ )} + + +
+ +
+ {isUserLogin ? ( +

Are you an administrator? navigate('/admin/login')}>Admin Login

+ ) : ( +

Are you a citizen? navigate('/login')}>User Login

+ )} +
+
+
+
+ ); +} diff --git a/frontend-ui/src/components/auth/ProtectedRoute.jsx b/frontend-ui/src/components/auth/ProtectedRoute.jsx new file mode 100644 index 0000000..33efd60 --- /dev/null +++ b/frontend-ui/src/components/auth/ProtectedRoute.jsx @@ -0,0 +1,11 @@ +import { Navigate } from 'react-router-dom'; + +export default function ProtectedRoute({ children }) { + const isAuthenticated = localStorage.getItem('isAuthenticated') === 'true'; + + if (!isAuthenticated) { + return ; + } + + return children; +} diff --git a/frontend-ui/src/index.css b/frontend-ui/src/index.css index 7db4496..47d05a6 100644 --- a/frontend-ui/src/index.css +++ b/frontend-ui/src/index.css @@ -438,6 +438,95 @@ body::before { ::-webkit-scrollbar-track { background: var(--bg-base); } ::-webkit-scrollbar-thumb { background: var(--border-default); border-radius: 3px; } +/* ---- AUTHENTICATION ---- */ +.auth-layout { + display: flex; + min-height: 100vh; + align-items: center; + justify-content: center; + position: relative; + z-index: 1; +} + +.auth-container { + width: 100%; + max-width: 420px; + padding: 20px; +} + +.auth-brand { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + margin-bottom: 30px; +} + +.auth-logo-emblem { + width: 54px; height: 54px; + border-radius: 50%; + background: var(--navy); + border: 2px solid var(--navy-mid); + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 12px; + font-family: var(--font-display); + font-size: 22px; + color: rgba(255,255,255,0.9); + box-shadow: 0 4px 12px rgba(15,45,90,0.15); +} + +.auth-logo-name { + font-family: var(--font-display); + font-size: 16px; + font-weight: 700; + letter-spacing: 0.07em; + color: var(--navy); +} + +.auth-logo-dept { + font-size: 11px; + color: var(--text-secondary); + letter-spacing: 0.15em; + text-transform: uppercase; + margin-top: 4px; +} + +.auth-card { + padding: 32px 36px; +} + +.auth-header { + text-align: center; + margin-bottom: 26px; +} + +.auth-header .page-title { + font-size: 20px; + margin-bottom: 8px; +} + +.auth-link { + font-size: 12px; + color: var(--navy-light); + text-decoration: none; + font-weight: 600; + cursor: pointer; +} + +.auth-link:hover { + text-decoration: underline; + color: var(--navy); +} + +.auth-footer { + margin-top: 24px; + text-align: center; + border-top: 1px solid var(--border-subtle); + padding-top: 18px; +} + /* ---- RESPONSIVE ---- */ @media (max-width: 768px) { :root { --sidebar-width: 60px; } diff --git a/frontend-ui/src/layouts/DashboardLayout.jsx b/frontend-ui/src/layouts/DashboardLayout.jsx new file mode 100644 index 0000000..4919fd6 --- /dev/null +++ b/frontend-ui/src/layouts/DashboardLayout.jsx @@ -0,0 +1,97 @@ +import { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import RegisterLand from '../components/RegisterLand'; +import SearchLand from '../components/SearchLand'; +import OwnerSearch from '../components/OwnerSearch'; +import TransferLand from '../components/TransferLand'; +import MutateLand from '../components/MutateLand'; +import AssetHistory from '../components/AssetHistory'; +import MapView from "../components/Mapview"; + +const NAV_ITEMS = [ + { id: 'register', label: 'Register Parcel', icon: '⊕' }, + { id: 'search', label: 'Search by ULPIN', icon: '◎' }, + { id: 'owner', label: 'Search by Owner', icon: '◈' }, + { id: 'map', label: 'Search by Map', icon: '⊞' }, + { id: 'transfer', label: 'Transfer Ownership', icon: '⇌' }, + { id: 'mutate', label: 'Mutate / Split', icon: '⊗' }, + { id: 'history', label: 'Audit Trail', icon: '◷' }, +]; + +export default function DashboardLayout() { + const navigate = useNavigate(); + const userRole = localStorage.getItem('userRole') || 'user'; + + const displayNavItems = NAV_ITEMS.filter(item => { + if (userRole === 'admin') return true; + return ['search', 'owner', 'map', 'history'].includes(item.id); + }); + + const [active, setActive] = useState(userRole === 'admin' ? 'register' : 'search'); + const [prefill, setPrefill] = useState(null); + + const handleLogout = () => { + localStorage.removeItem('isAuthenticated'); + localStorage.removeItem('userRole'); + navigate('/login'); + }; + + const navigateTo = (page, data = null) => { + setPrefill(data); + setActive(page); + }; + + const renderPage = () => { + switch (active) { + case 'register': return setPrefill(null)} />; + case 'search': return ; + case 'owner': return ; + case 'map': return navigateTo('register', data)} />; + case 'transfer': return ; + case 'mutate': return ; + case 'history': return ; + default: return null; + } + }; + + return ( +
+ + +
+ {renderPage()} +
+
+ ); +} diff --git a/frontend-ui/src/main.jsx b/frontend-ui/src/main.jsx index b9a1a6d..2898346 100644 --- a/frontend-ui/src/main.jsx +++ b/frontend-ui/src/main.jsx @@ -1,10 +1,13 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' +import { BrowserRouter } from 'react-router-dom' import './index.css' import App from './App.jsx' createRoot(document.getElementById('root')).render( - + + + , ) diff --git a/frontend-ui/src/pages/AdminLogin.jsx b/frontend-ui/src/pages/AdminLogin.jsx new file mode 100644 index 0000000..e5e5b1b --- /dev/null +++ b/frontend-ui/src/pages/AdminLogin.jsx @@ -0,0 +1,12 @@ +import LoginView from '../components/auth/LoginView'; + +export default function AdminLogin() { + return ( + + ); +} diff --git a/frontend-ui/src/pages/UserLogin.jsx b/frontend-ui/src/pages/UserLogin.jsx new file mode 100644 index 0000000..53bd065 --- /dev/null +++ b/frontend-ui/src/pages/UserLogin.jsx @@ -0,0 +1,13 @@ +import LoginView from '../components/auth/LoginView'; + +export default function UserLogin() { + return ( + + ); +}