feat: add NumberInput component for enhanced numeric input handling; integrate react-number-format
This commit is contained in:
parent
24253f0cfb
commit
7666f08307
5 changed files with 366 additions and 41 deletions
61
apps/infoalloggi/package-lock.json
generated
61
apps/infoalloggi/package-lock.json
generated
|
|
@ -74,6 +74,7 @@
|
||||||
"react-hot-toast": "^2.5.2",
|
"react-hot-toast": "^2.5.2",
|
||||||
"react-is": "^19.1.1",
|
"react-is": "^19.1.1",
|
||||||
"react-leaflet": "^5.0.0",
|
"react-leaflet": "^5.0.0",
|
||||||
|
"react-number-format": "^5.4.4",
|
||||||
"react-pdf": "^10.1.0",
|
"react-pdf": "^10.1.0",
|
||||||
"react-phone-number-input": "^3.4.12",
|
"react-phone-number-input": "^3.4.12",
|
||||||
"react-reverse-portal": "^2.3.0",
|
"react-reverse-portal": "^2.3.0",
|
||||||
|
|
@ -831,6 +832,7 @@
|
||||||
"integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
|
"integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "^2.2.0",
|
"@ampproject/remapping": "^2.2.0",
|
||||||
"@babel/code-frame": "^7.26.2",
|
"@babel/code-frame": "^7.26.2",
|
||||||
|
|
@ -1233,6 +1235,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
|
||||||
"integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
|
"integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dnd-kit/accessibility": "^3.1.1",
|
"@dnd-kit/accessibility": "^3.1.1",
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
|
|
@ -1369,6 +1372,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
|
||||||
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
|
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.18.3",
|
"@babel/runtime": "^7.18.3",
|
||||||
"@emotion/babel-plugin": "^11.13.5",
|
"@emotion/babel-plugin": "^11.13.5",
|
||||||
|
|
@ -1889,6 +1893,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.3.tgz",
|
||||||
"integrity": "sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==",
|
"integrity": "sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/core": "^1.7.3",
|
"@floating-ui/core": "^1.7.3",
|
||||||
"@floating-ui/utils": "^0.2.10"
|
"@floating-ui/utils": "^0.2.10"
|
||||||
|
|
@ -6290,6 +6295,7 @@
|
||||||
"integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==",
|
"integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
|
|
@ -6300,6 +6306,7 @@
|
||||||
"integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==",
|
"integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/react": "^19.0.0"
|
"@types/react": "^19.0.0"
|
||||||
}
|
}
|
||||||
|
|
@ -6492,6 +6499,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.6",
|
"nanoid": "^3.3.6",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.0.0",
|
||||||
|
|
@ -6539,6 +6547,7 @@
|
||||||
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
|
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
|
|
@ -6549,6 +6558,7 @@
|
||||||
"integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
|
"integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"scheduler": "^0.25.0"
|
"scheduler": "^0.25.0"
|
||||||
},
|
},
|
||||||
|
|
@ -7935,6 +7945,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-7.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-7.8.0.tgz",
|
||||||
"integrity": "sha512-DNXRfYUgkZlrniQORbA/wH8CdFRhiBSE0R56gYU0V5vvpJ9WZwvGrz9tBAZmfq2aTgw6SK7mNpmTizGzLWVezw==",
|
"integrity": "sha512-DNXRfYUgkZlrniQORbA/wH8CdFRhiBSE0R56gYU0V5vvpJ9WZwvGrz9tBAZmfq2aTgw6SK7mNpmTizGzLWVezw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12.16"
|
"node": ">=12.16"
|
||||||
}
|
}
|
||||||
|
|
@ -8360,6 +8371,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.5.tgz",
|
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.5.tgz",
|
||||||
"integrity": "sha512-/X4EFNcnPiSs8wM2v+b6DqS5mmGeuJQvxBglmDxl6ZQb5V26ouD2SJYAcC3VjbNwqhY2zjxVD15rDA5nGbMn3A==",
|
"integrity": "sha512-/X4EFNcnPiSs8wM2v+b6DqS5mmGeuJQvxBglmDxl6ZQb5V26ouD2SJYAcC3VjbNwqhY2zjxVD15rDA5nGbMn3A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/query-core": "5.85.5"
|
"@tanstack/query-core": "5.85.5"
|
||||||
},
|
},
|
||||||
|
|
@ -8436,6 +8448,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.2.0.tgz",
|
||||||
"integrity": "sha512-1Dk1AIwzJejcyi4FOEcKoBSLMkHMfxeDiQ0daG51eS1IZ1ZSF+Xlhg9OD5sAjbUTGQjK1HfU6kGwS9wJcR/9ZQ==",
|
"integrity": "sha512-1Dk1AIwzJejcyi4FOEcKoBSLMkHMfxeDiQ0daG51eS1IZ1ZSF+Xlhg9OD5sAjbUTGQjK1HfU6kGwS9wJcR/9ZQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/sponsors/ueberdosis"
|
"url": "https://github.com/sponsors/ueberdosis"
|
||||||
|
|
@ -8658,6 +8671,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.2.0.tgz",
|
||||||
"integrity": "sha512-/3ZL9MpgDnEOv8tPwFwW3ct/TBbxZg3r3rN9noLHOR+YgiZKwbpMt9pDSJGu8y++rzT3vIHVmRRp0xFOXBvptQ==",
|
"integrity": "sha512-/3ZL9MpgDnEOv8tPwFwW3ct/TBbxZg3r3rN9noLHOR+YgiZKwbpMt9pDSJGu8y++rzT3vIHVmRRp0xFOXBvptQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/sponsors/ueberdosis"
|
"url": "https://github.com/sponsors/ueberdosis"
|
||||||
|
|
@ -8763,6 +8777,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.2.0.tgz",
|
||||||
"integrity": "sha512-voEvFhStH1fxw6PF5Hb7kj7PH+BMYM3d0S6d/V0bNdGB7mMsILruXkXIsxvP8Dkskv07Xmfs+iU6pdVy0hWD7Q==",
|
"integrity": "sha512-voEvFhStH1fxw6PF5Hb7kj7PH+BMYM3d0S6d/V0bNdGB7mMsILruXkXIsxvP8Dkskv07Xmfs+iU6pdVy0hWD7Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/sponsors/ueberdosis"
|
"url": "https://github.com/sponsors/ueberdosis"
|
||||||
|
|
@ -8777,6 +8792,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.2.0.tgz",
|
||||||
"integrity": "sha512-2UTlVts1Q7snQaUlxUtXfwEndNgcBcEIf74f1aEzcLzJRwBRRexCS6M0n+F50IifoB0OVBZENMBv1X/YXIPGPA==",
|
"integrity": "sha512-2UTlVts1Q7snQaUlxUtXfwEndNgcBcEIf74f1aEzcLzJRwBRRexCS6M0n+F50IifoB0OVBZENMBv1X/YXIPGPA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"prosemirror-changeset": "^2.3.0",
|
"prosemirror-changeset": "^2.3.0",
|
||||||
"prosemirror-collab": "^1.3.1",
|
"prosemirror-collab": "^1.3.1",
|
||||||
|
|
@ -8878,6 +8894,7 @@
|
||||||
"https://trpc.io/sponsor"
|
"https://trpc.io/sponsor"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@trpc/server": "11.4.4",
|
"@trpc/server": "11.4.4",
|
||||||
"typescript": ">=5.7.2"
|
"typescript": ">=5.7.2"
|
||||||
|
|
@ -8918,6 +8935,7 @@
|
||||||
"https://trpc.io/sponsor"
|
"https://trpc.io/sponsor"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@tanstack/react-query": "^5.80.3",
|
"@tanstack/react-query": "^5.80.3",
|
||||||
"@trpc/client": "11.4.4",
|
"@trpc/client": "11.4.4",
|
||||||
|
|
@ -8935,6 +8953,7 @@
|
||||||
"https://trpc.io/sponsor"
|
"https://trpc.io/sponsor"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": ">=5.7.2"
|
"typescript": ">=5.7.2"
|
||||||
}
|
}
|
||||||
|
|
@ -9123,6 +9142,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz",
|
||||||
"integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==",
|
"integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.10.0"
|
"undici-types": "~7.10.0"
|
||||||
}
|
}
|
||||||
|
|
@ -9191,6 +9211,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.10.tgz",
|
||||||
"integrity": "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==",
|
"integrity": "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
|
|
@ -9201,6 +9222,7 @@
|
||||||
"integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==",
|
"integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/react": "^19.0.0"
|
"@types/react": "^19.0.0"
|
||||||
}
|
}
|
||||||
|
|
@ -9449,6 +9471,7 @@
|
||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
|
|
@ -9849,6 +9872,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001735",
|
"caniuse-lite": "^1.0.30001735",
|
||||||
"electron-to-chromium": "^1.5.204",
|
"electron-to-chromium": "^1.5.204",
|
||||||
|
|
@ -10456,7 +10480,8 @@
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/d3-array": {
|
"node_modules/d3-array": {
|
||||||
"version": "3.2.4",
|
"version": "3.2.4",
|
||||||
|
|
@ -10901,7 +10926,8 @@
|
||||||
"version": "8.6.0",
|
"version": "8.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
|
||||||
"integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==",
|
"integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/embla-carousel-react": {
|
"node_modules/embla-carousel-react": {
|
||||||
"version": "8.6.0",
|
"version": "8.6.0",
|
||||||
|
|
@ -13027,6 +13053,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/kysely/-/kysely-0.28.5.tgz",
|
"resolved": "https://registry.npmjs.org/kysely/-/kysely-0.28.5.tgz",
|
||||||
"integrity": "sha512-rlB0I/c6FBDWPcQoDtkxi9zIvpmnV5xoIalfCMSMCa7nuA6VGA3F54TW9mEgX4DVf10sXAWCF5fDbamI/5ZpKA==",
|
"integrity": "sha512-rlB0I/c6FBDWPcQoDtkxi9zIvpmnV5xoIalfCMSMCa7nuA6VGA3F54TW9mEgX4DVf10sXAWCF5fDbamI/5ZpKA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
}
|
}
|
||||||
|
|
@ -13053,7 +13080,8 @@
|
||||||
"version": "1.9.4",
|
"version": "1.9.4",
|
||||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||||
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
|
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
|
||||||
"license": "BSD-2-Clause"
|
"license": "BSD-2-Clause",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/leaflet-defaulticon-compatibility": {
|
"node_modules/leaflet-defaulticon-compatibility": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
|
|
@ -13884,6 +13912,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/next/-/next-15.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/next/-/next-15.4.7.tgz",
|
||||||
"integrity": "sha512-OcqRugwF7n7mC8OSYjvsZhhG1AYSvulor1EIUsIkbbEbf1qoE5EbH36Swj8WhF4cHqmDgkiam3z1c1W0J1Wifg==",
|
"integrity": "sha512-OcqRugwF7n7mC8OSYjvsZhhG1AYSvulor1EIUsIkbbEbf1qoE5EbH36Swj8WhF4cHqmDgkiam3z1c1W0J1Wifg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next/env": "15.4.7",
|
"@next/env": "15.4.7",
|
||||||
"@swc/helpers": "0.5.15",
|
"@swc/helpers": "0.5.15",
|
||||||
|
|
@ -14908,6 +14937,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.11",
|
"nanoid": "^3.3.11",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
|
|
@ -15238,6 +15268,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.3.tgz",
|
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.3.tgz",
|
||||||
"integrity": "sha512-dY2HdaNXlARknJbrManZ1WyUtos+AP97AmvqdOQtWtrrC5g4mohVX5DTi9rXNFSk09eczLq9GuNTtq3EfMeMGA==",
|
"integrity": "sha512-dY2HdaNXlARknJbrManZ1WyUtos+AP97AmvqdOQtWtrrC5g4mohVX5DTi9rXNFSk09eczLq9GuNTtq3EfMeMGA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"orderedmap": "^2.0.0"
|
"orderedmap": "^2.0.0"
|
||||||
}
|
}
|
||||||
|
|
@ -15267,6 +15298,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz",
|
||||||
"integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==",
|
"integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"prosemirror-model": "^1.0.0",
|
"prosemirror-model": "^1.0.0",
|
||||||
"prosemirror-transform": "^1.0.0",
|
"prosemirror-transform": "^1.0.0",
|
||||||
|
|
@ -15315,6 +15347,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.40.1.tgz",
|
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.40.1.tgz",
|
||||||
"integrity": "sha512-pbwUjt3G7TlsQQHDiYSupWBhJswpLVB09xXm1YiJPdkjkh9Pe7Y51XdLh5VWIZmROLY8UpUpG03lkdhm9lzIBA==",
|
"integrity": "sha512-pbwUjt3G7TlsQQHDiYSupWBhJswpLVB09xXm1YiJPdkjkh9Pe7Y51XdLh5VWIZmROLY8UpUpG03lkdhm9lzIBA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"prosemirror-model": "^1.20.0",
|
"prosemirror-model": "^1.20.0",
|
||||||
"prosemirror-state": "^1.0.0",
|
"prosemirror-state": "^1.0.0",
|
||||||
|
|
@ -15604,6 +15637,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
|
||||||
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
|
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
|
|
@ -15644,6 +15678,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
|
||||||
"integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
|
"integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"scheduler": "^0.26.0"
|
"scheduler": "^0.26.0"
|
||||||
},
|
},
|
||||||
|
|
@ -15939,6 +15974,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz",
|
||||||
"integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==",
|
"integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
},
|
},
|
||||||
|
|
@ -15987,6 +16023,16 @@
|
||||||
"react-dom": "^19.0.0"
|
"react-dom": "^19.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-number-format": {
|
||||||
|
"version": "5.4.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.4.4.tgz",
|
||||||
|
"integrity": "sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||||
|
"react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-pdf": {
|
"node_modules/react-pdf": {
|
||||||
"version": "10.1.0",
|
"version": "10.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-10.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-10.1.0.tgz",
|
||||||
|
|
@ -16681,6 +16727,7 @@
|
||||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"fast-uri": "^3.0.1",
|
"fast-uri": "^3.0.1",
|
||||||
|
|
@ -17765,7 +17812,8 @@
|
||||||
"version": "4.1.12",
|
"version": "4.1.12",
|
||||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz",
|
||||||
"integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==",
|
"integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/tapable": {
|
"node_modules/tapable": {
|
||||||
"version": "2.2.2",
|
"version": "2.2.2",
|
||||||
|
|
@ -17963,7 +18011,8 @@
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
"license": "0BSD"
|
"license": "0BSD",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/tunnel-rat": {
|
"node_modules/tunnel-rat": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
|
|
@ -18091,6 +18140,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
|
||||||
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
|
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
|
@ -18745,6 +18795,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",
|
||||||
"integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==",
|
"integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@
|
||||||
"react-hot-toast": "^2.5.2",
|
"react-hot-toast": "^2.5.2",
|
||||||
"react-is": "^19.1.1",
|
"react-is": "^19.1.1",
|
||||||
"react-leaflet": "^5.0.0",
|
"react-leaflet": "^5.0.0",
|
||||||
|
"react-number-format": "^5.4.4",
|
||||||
"react-pdf": "^10.1.0",
|
"react-pdf": "^10.1.0",
|
||||||
"react-phone-number-input": "^3.4.12",
|
"react-phone-number-input": "^3.4.12",
|
||||||
"react-reverse-portal": "^2.3.0",
|
"react-reverse-portal": "^2.3.0",
|
||||||
|
|
|
||||||
164
apps/infoalloggi/src/components/custom_ui/InputNumber.tsx
Normal file
164
apps/infoalloggi/src/components/custom_ui/InputNumber.tsx
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
||||||
|
import { forwardRef, useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
import { NumericFormat, type NumericFormatProps } from "react-number-format";
|
||||||
|
import { Button } from "../ui/button";
|
||||||
|
import { Input } from "../ui/input";
|
||||||
|
|
||||||
|
export interface NumberInputProps
|
||||||
|
extends Omit<NumericFormatProps, "value" | "onValueChange"> {
|
||||||
|
stepper?: number;
|
||||||
|
thousandSeparator?: string;
|
||||||
|
placeholder?: string;
|
||||||
|
defaultValue?: number;
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
value?: number; // Controlled value
|
||||||
|
suffix?: string;
|
||||||
|
prefix?: string;
|
||||||
|
onValueChange?: (value: number | undefined) => void;
|
||||||
|
fixedDecimalScale?: boolean;
|
||||||
|
decimalScale?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(
|
||||||
|
(
|
||||||
|
{
|
||||||
|
stepper,
|
||||||
|
thousandSeparator,
|
||||||
|
placeholder,
|
||||||
|
defaultValue,
|
||||||
|
min = -Infinity,
|
||||||
|
max = Infinity,
|
||||||
|
onValueChange,
|
||||||
|
fixedDecimalScale = false,
|
||||||
|
decimalScale = 0,
|
||||||
|
suffix,
|
||||||
|
prefix,
|
||||||
|
value: controlledValue,
|
||||||
|
...props
|
||||||
|
},
|
||||||
|
externalRef,
|
||||||
|
) => {
|
||||||
|
const internalRef = useRef<HTMLInputElement>(null);
|
||||||
|
const inputRef =
|
||||||
|
(externalRef as React.RefObject<HTMLInputElement>) || internalRef;
|
||||||
|
const [value, setValue] = useState<number | undefined>(
|
||||||
|
controlledValue ?? defaultValue,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleIncrement = useCallback(() => {
|
||||||
|
setValue((prev) =>
|
||||||
|
prev === undefined
|
||||||
|
? (stepper ?? 1)
|
||||||
|
: Math.min(prev + (stepper ?? 1), max),
|
||||||
|
);
|
||||||
|
}, [stepper, max]);
|
||||||
|
|
||||||
|
const handleDecrement = useCallback(() => {
|
||||||
|
setValue((prev) =>
|
||||||
|
prev === undefined
|
||||||
|
? -(stepper ?? 1)
|
||||||
|
: Math.max(prev - (stepper ?? 1), min),
|
||||||
|
);
|
||||||
|
}, [stepper, min]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
|
if (!inputRef.current) return;
|
||||||
|
|
||||||
|
if (document.activeElement === inputRef.current) {
|
||||||
|
if (e.key === "ArrowUp") {
|
||||||
|
handleIncrement();
|
||||||
|
} else if (e.key === "ArrowDown") {
|
||||||
|
handleDecrement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("keydown", handleKeyDown);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("keydown", handleKeyDown);
|
||||||
|
};
|
||||||
|
}, [handleIncrement, handleDecrement, inputRef]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (controlledValue !== undefined) {
|
||||||
|
setValue(controlledValue);
|
||||||
|
}
|
||||||
|
}, [controlledValue]);
|
||||||
|
|
||||||
|
const handleChange = (values: {
|
||||||
|
value: string;
|
||||||
|
floatValue: number | undefined;
|
||||||
|
}) => {
|
||||||
|
const newValue =
|
||||||
|
values.floatValue === undefined ? undefined : values.floatValue;
|
||||||
|
setValue(newValue);
|
||||||
|
if (onValueChange) {
|
||||||
|
onValueChange(newValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = () => {
|
||||||
|
if (value !== undefined) {
|
||||||
|
if (value < min) {
|
||||||
|
setValue(min);
|
||||||
|
if (inputRef.current) {
|
||||||
|
inputRef.current.value = String(min);
|
||||||
|
}
|
||||||
|
} else if (value > max) {
|
||||||
|
setValue(max);
|
||||||
|
if (inputRef.current) {
|
||||||
|
inputRef.current.value = String(min);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center">
|
||||||
|
<NumericFormat
|
||||||
|
allowNegative={min < 0}
|
||||||
|
className="relative rounded-r-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
|
||||||
|
customInput={Input}
|
||||||
|
decimalScale={decimalScale}
|
||||||
|
fixedDecimalScale={fixedDecimalScale}
|
||||||
|
getInputRef={inputRef}
|
||||||
|
max={max}
|
||||||
|
min={min}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
onValueChange={handleChange}
|
||||||
|
placeholder={placeholder}
|
||||||
|
prefix={prefix}
|
||||||
|
suffix={suffix}
|
||||||
|
thousandSeparator={thousandSeparator}
|
||||||
|
value={value}
|
||||||
|
valueIsNumericString
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<Button
|
||||||
|
aria-label="Increase value"
|
||||||
|
className="h-5 rounded-l-none rounded-br-none border-input border-b-[0.5px] border-l-0 px-2 focus-visible:relative"
|
||||||
|
disabled={value === max}
|
||||||
|
onClick={handleIncrement}
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
<ChevronUp size={15} />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
aria-label="Decrease value"
|
||||||
|
className="h-5 rounded-l-none rounded-tr-none border-input border-t-[0.5px] border-l-0 px-2 focus-visible:relative"
|
||||||
|
disabled={value === min}
|
||||||
|
onClick={handleDecrement}
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
<ChevronDown size={15} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
@ -3,6 +3,7 @@ import { CircleCheck, ClipboardPaste, Pen, Trash2, Wrench } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
|
import { useDebounce } from "react-use";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { formatCurrency } from "~/lib/utils";
|
import { formatCurrency } from "~/lib/utils";
|
||||||
import { useTranslation } from "~/providers/I18nProvider";
|
import { useTranslation } from "~/providers/I18nProvider";
|
||||||
|
|
@ -21,6 +22,12 @@ import {
|
||||||
CredenzaTitle,
|
CredenzaTitle,
|
||||||
CredenzaTrigger,
|
CredenzaTrigger,
|
||||||
} from "../custom_ui/credenza";
|
} from "../custom_ui/credenza";
|
||||||
|
import { NumberInput } from "../custom_ui/InputNumber";
|
||||||
|
import {
|
||||||
|
type ListOption,
|
||||||
|
MultiSelect,
|
||||||
|
UnpackOptions,
|
||||||
|
} from "../custom_ui/multiselect";
|
||||||
import { LoadingPage } from "../loading";
|
import { LoadingPage } from "../loading";
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
import {
|
import {
|
||||||
|
|
@ -31,7 +38,6 @@ import {
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "../ui/card";
|
} from "../ui/card";
|
||||||
|
|
||||||
import { Label } from "../ui/label";
|
import { Label } from "../ui/label";
|
||||||
import { Switch } from "../ui/switch";
|
import { Switch } from "../ui/switch";
|
||||||
import { UploadModal } from "../upload_modal";
|
import { UploadModal } from "../upload_modal";
|
||||||
|
|
@ -373,6 +379,7 @@ const MotivazioneSection = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { data: servizio } = api.servizio.getServizio.useQuery({ servizioId });
|
const { data: servizio } = api.servizio.getServizio.useQuery({ servizioId });
|
||||||
|
|
||||||
if (!servizio) return null;
|
if (!servizio) return null;
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
|
|
@ -445,10 +452,126 @@ const FileLink = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const SendConferma = () => {
|
const TransitorioSection = () => {
|
||||||
const { servizio } = useServizio();
|
const { servizio } = useServizio();
|
||||||
const { data } = useServizioAnnuncio();
|
const { data } = useServizioAnnuncio();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { servizioId, userId } = useServizio();
|
||||||
|
const utils = api.useUtils();
|
||||||
|
const { mutate: update } = api.servizio.updateServizio.useMutation({
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(error.message);
|
||||||
|
},
|
||||||
|
onSuccess: async () => {
|
||||||
|
toast.success("Servizio modificato con successo");
|
||||||
|
await utils.servizio.getUserServizi.invalidate();
|
||||||
|
await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handlePermanenzaChange = (value: ListOption) => {
|
||||||
|
update({
|
||||||
|
servizioId,
|
||||||
|
data: {
|
||||||
|
permanenza: value.value !== "" ? parseInt(value.value) : null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const preferenzeDescrizione = data.desc_it?.match(/Permanenza:.*$/m);
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="max-w-sm">
|
||||||
|
<Label className="text-base" htmlFor="permanenza">
|
||||||
|
Permanenza (da preferenze servizio):
|
||||||
|
</Label>
|
||||||
|
|
||||||
|
<MultiSelect
|
||||||
|
defaultValue={
|
||||||
|
servizio.permanenza
|
||||||
|
? {
|
||||||
|
label: t.preferenze.permanenza[servizio.permanenza] || "",
|
||||||
|
value: servizio.permanenza.toString(),
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
elementId="permanenza"
|
||||||
|
elementName="permanenza"
|
||||||
|
isMulti={false}
|
||||||
|
onValueChange={handlePermanenzaChange}
|
||||||
|
options={UnpackOptions({
|
||||||
|
options: t.preferenze.permanenza,
|
||||||
|
})}
|
||||||
|
placeholder="Seleziona..."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<span className="font-semibold">Permanenza in descrizione: </span>
|
||||||
|
{preferenzeDescrizione
|
||||||
|
? preferenzeDescrizione[0]
|
||||||
|
: "errore: testo non trovato in descrizione"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const StabileSection = () => {
|
||||||
|
const { servizio, servizioId, userId } = useServizio();
|
||||||
|
const { data } = useServizioAnnuncio();
|
||||||
|
const [value, setValue] = useState(servizio.budget);
|
||||||
|
const utils = api.useUtils();
|
||||||
|
const { mutate: update } = api.servizio.updateServizio.useMutation({
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(error.message);
|
||||||
|
},
|
||||||
|
onSuccess: async () => {
|
||||||
|
toast.success("Servizio modificato con successo");
|
||||||
|
await utils.servizio.getUserServizi.invalidate();
|
||||||
|
await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
useDebounce(
|
||||||
|
() => {
|
||||||
|
if (value === servizio.budget) return;
|
||||||
|
update({
|
||||||
|
servizioId,
|
||||||
|
data: {
|
||||||
|
budget: value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
1000,
|
||||||
|
[value],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex max-w-sm flex-col gap-2">
|
||||||
|
<span className="font-semibold">Budget (da preferenze servizio):</span>
|
||||||
|
<NumberInput
|
||||||
|
allowNegative={false}
|
||||||
|
min={0}
|
||||||
|
onValueChange={(val) => {
|
||||||
|
if (val !== undefined) {
|
||||||
|
setValue(val);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
stepper={50}
|
||||||
|
suffix=" €"
|
||||||
|
value={value}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<span className="font-semibold">Prezzo in descrizione: </span>
|
||||||
|
{formatCurrency(data.prezzo / 100)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const SendConferma = () => {
|
||||||
|
const { servizio } = useServizio();
|
||||||
|
const { data } = useServizioAnnuncio();
|
||||||
const [check, setCheck] = useState(data.hasConfermaAdmin);
|
const [check, setCheck] = useState(data.hasConfermaAdmin);
|
||||||
const utils = api.useUtils();
|
const utils = api.useUtils();
|
||||||
const { mutate: handleUpdate } =
|
const { mutate: handleUpdate } =
|
||||||
|
|
@ -473,40 +596,17 @@ const SendConferma = () => {
|
||||||
controlla i parametri di ricerca prima!
|
controlla i parametri di ricerca prima!
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-10">
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<p>Tipologia servizio: {servizio.tipologia}</p>
|
|
||||||
{(() => {
|
|
||||||
if (servizio.tipologia === TipologiaPosizioneEnum.Transitorio) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<p>
|
<p>
|
||||||
Permanenza specificata dall'utente:{" "}
|
<span className="font-semibold">Tipologia servizio: </span>
|
||||||
{servizio.permanenza
|
{servizio.tipologia}
|
||||||
? t.preferenze.permanenza[servizio.permanenza]
|
|
||||||
: "non inserita"}
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
{servizio.tipologia === TipologiaPosizioneEnum.Transitorio ? (
|
||||||
Permanenza in descrizione: {(() => {
|
<TransitorioSection />
|
||||||
const match = data.desc_it?.match(/Permanenza:.*$/m);
|
) : (
|
||||||
return match
|
<StabileSection />
|
||||||
? `"${match[0]}"`
|
)}
|
||||||
: "errore: testo non trovato in descrizione";
|
|
||||||
})()}
|
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<p>Budget (da preferenze): {formatCurrency(servizio.budget)}</p>
|
|
||||||
<p>
|
|
||||||
Canone Mensile (da descrizione):{" "}
|
|
||||||
{formatCurrency(data.prezzo / 100)}
|
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
})()}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Switch
|
<Switch
|
||||||
|
|
@ -517,7 +617,9 @@ const SendConferma = () => {
|
||||||
setCheck(c);
|
setCheck(c);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="conferma">Conferma lavorata</Label>
|
<Label className="text-base" htmlFor="conferma">
|
||||||
|
Imposta Conferma come Lavorata
|
||||||
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter>
|
<CardFooter>
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,13 @@ const NewServizioModal = ({
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast.success("Servizio modificato con successo");
|
toast.success("Servizio modificato con successo");
|
||||||
await utils.servizio.getUserServizi.invalidate();
|
await utils.servizio.getUserServizi.invalidate();
|
||||||
|
await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
|
||||||
|
await utils.servizio.getServizio.invalidate({
|
||||||
|
servizioId: editData?.servizio_id,
|
||||||
|
});
|
||||||
|
await utils.servizio.getCompatibileAnnunci.invalidate({
|
||||||
|
servizioId: editData?.servizio_id,
|
||||||
|
});
|
||||||
setEditData(undefined);
|
setEditData(undefined);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue