diff --git a/staff/jose-canto/project/FactuClient/package-lock.json b/staff/jose-canto/project/FactuClient/package-lock.json
index 7ace631f5..1df0b33a9 100644
--- a/staff/jose-canto/project/FactuClient/package-lock.json
+++ b/staff/jose-canto/project/FactuClient/package-lock.json
@@ -8,6 +8,7 @@
"name": "factuclient",
"version": "0.0.0",
"dependencies": {
+ "@react-pdf/renderer": "^3.4.4",
"com": "file:../com",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@@ -347,6 +348,17 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/runtime": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz",
+ "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/template": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz",
@@ -1007,6 +1019,167 @@
"node": ">=14"
}
},
+ "node_modules/@react-pdf/fns": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@react-pdf/fns/-/fns-2.2.1.tgz",
+ "integrity": "sha512-s78aDg0vDYaijU5lLOCsUD+qinQbfOvcNeaoX9AiE7+kZzzCo6B/nX+l48cmt9OosJmvZvE9DWR9cLhrhOi2pA==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13"
+ }
+ },
+ "node_modules/@react-pdf/font": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@react-pdf/font/-/font-2.5.1.tgz",
+ "integrity": "sha512-Hyb2zBb92Glc3lvhmJfy4dO2Mj29KB26Uk12Ua9EhKAdiuCTLBqgP8Oe1cGwrvDI7xA4OOcwvBMdYh0vhOUHzA==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/types": "^2.5.0",
+ "cross-fetch": "^3.1.5",
+ "fontkit": "^2.0.2",
+ "is-url": "^1.2.4"
+ }
+ },
+ "node_modules/@react-pdf/image": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/@react-pdf/image/-/image-2.3.6.tgz",
+ "integrity": "sha512-7iZDYZrZlJqNzS6huNl2XdMcLFUo68e6mOdzQeJ63d5eApdthhSHBnkGzHfLhH5t8DCpZNtClmklzuLL63ADfw==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/png-js": "^2.3.1",
+ "cross-fetch": "^3.1.5",
+ "jay-peg": "^1.0.2"
+ }
+ },
+ "node_modules/@react-pdf/layout": {
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/@react-pdf/layout/-/layout-3.12.1.tgz",
+ "integrity": "sha512-BxSeykDxvADlpe4OGtQ7NH46QXq3uImAYsTHOPLCwbXMniQ1O3uCBx7H+HthxkCNshgYVPp9qS3KyvQv/oIZwg==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/fns": "2.2.1",
+ "@react-pdf/image": "^2.3.6",
+ "@react-pdf/pdfkit": "^3.1.10",
+ "@react-pdf/primitives": "^3.1.1",
+ "@react-pdf/stylesheet": "^4.2.5",
+ "@react-pdf/textkit": "^4.4.1",
+ "@react-pdf/types": "^2.5.0",
+ "cross-fetch": "^3.1.5",
+ "emoji-regex": "^10.3.0",
+ "queue": "^6.0.1",
+ "yoga-layout": "^2.0.1"
+ }
+ },
+ "node_modules/@react-pdf/layout/node_modules/emoji-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
+ "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw=="
+ },
+ "node_modules/@react-pdf/pdfkit": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/@react-pdf/pdfkit/-/pdfkit-3.1.10.tgz",
+ "integrity": "sha512-P/qPBtCFo2HDJD0i6NfbmoBRrsOVO8CIogYsefwG4fklTo50zNgnMM5U1WLckTuX8Qt1ThiQuokmTG5arheblA==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/png-js": "^2.3.1",
+ "browserify-zlib": "^0.2.0",
+ "crypto-js": "^4.2.0",
+ "fontkit": "^2.0.2",
+ "jay-peg": "^1.0.2",
+ "vite-compatible-readable-stream": "^3.6.1"
+ }
+ },
+ "node_modules/@react-pdf/png-js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/@react-pdf/png-js/-/png-js-2.3.1.tgz",
+ "integrity": "sha512-pEZ18I4t1vAUS4lmhvXPmXYP4PHeblpWP/pAlMMRkEyP7tdAeHUN7taQl9sf9OPq7YITMY3lWpYpJU6t4CZgZg==",
+ "dependencies": {
+ "browserify-zlib": "^0.2.0"
+ }
+ },
+ "node_modules/@react-pdf/primitives": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@react-pdf/primitives/-/primitives-3.1.1.tgz",
+ "integrity": "sha512-miwjxLwTnO3IjoqkTVeTI+9CdyDggwekmSLhVCw+a/7FoQc+gF3J2dSKwsHvAcVFM0gvU8mzCeTofgw0zPDq0w=="
+ },
+ "node_modules/@react-pdf/render": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/@react-pdf/render/-/render-3.4.4.tgz",
+ "integrity": "sha512-CfGxWmVgrY3JgmB1iMnz2W6Ck+8pisZeFt8vGlxP+JfT+0onr208pQvGSV5KwA9LGhAdABxqc/+y17V3vtKdFA==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/fns": "2.2.1",
+ "@react-pdf/primitives": "^3.1.1",
+ "@react-pdf/textkit": "^4.4.1",
+ "@react-pdf/types": "^2.5.0",
+ "abs-svg-path": "^0.1.1",
+ "color-string": "^1.9.1",
+ "normalize-svg-path": "^1.1.0",
+ "parse-svg-path": "^0.1.2",
+ "svg-arc-to-cubic-bezier": "^3.2.0"
+ }
+ },
+ "node_modules/@react-pdf/renderer": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/@react-pdf/renderer/-/renderer-3.4.4.tgz",
+ "integrity": "sha512-j1TWMHHXDeHdoQE3xjhBh0MZ2rn7wHIlP/uglr/EJZXqnPbfg6bfLzRJCM6bs+XJV3d8+zLQjHf6sF/fWcBDfg==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/font": "^2.5.1",
+ "@react-pdf/layout": "^3.12.1",
+ "@react-pdf/pdfkit": "^3.1.10",
+ "@react-pdf/primitives": "^3.1.1",
+ "@react-pdf/render": "^3.4.4",
+ "@react-pdf/types": "^2.5.0",
+ "events": "^3.3.0",
+ "object-assign": "^4.1.1",
+ "prop-types": "^15.6.2",
+ "queue": "^6.0.1",
+ "scheduler": "^0.17.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-pdf/renderer/node_modules/scheduler": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.17.0.tgz",
+ "integrity": "sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA==",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1"
+ }
+ },
+ "node_modules/@react-pdf/stylesheet": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/@react-pdf/stylesheet/-/stylesheet-4.2.5.tgz",
+ "integrity": "sha512-XnmapeCW+hDuNdVwpuvO04WKv71wAs8aH+saIq29Bo2fp1SxznHTcQArTZtK6Wgr/E9BHXeB2iAPpUZuI6G+xA==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/fns": "2.2.1",
+ "@react-pdf/types": "^2.5.0",
+ "color-string": "^1.9.1",
+ "hsl-to-hex": "^1.0.0",
+ "media-engine": "^1.0.3",
+ "postcss-value-parser": "^4.1.0"
+ }
+ },
+ "node_modules/@react-pdf/textkit": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@react-pdf/textkit/-/textkit-4.4.1.tgz",
+ "integrity": "sha512-Jl9wdTqIvJ5pX+vAGz0EOhP7ut5Two9H6CzTKo/YYPeD79cM2yTXF3JzTERBC28y7LR0Waq9D2LHQjI+b/EYUQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/fns": "2.2.1",
+ "bidi-js": "^1.0.2",
+ "hyphen": "^1.6.4",
+ "unicode-properties": "^1.4.1"
+ }
+ },
+ "node_modules/@react-pdf/types": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@react-pdf/types/-/types-2.5.0.tgz",
+ "integrity": "sha512-XsVRkt0hQ60I4e3leAVt+aZR3KJCaJd179BfJHAv4F4x6Vq3yqkry8lcbUWKGKDw1j3/8sW4FsgGR41SFvsG9A=="
+ },
"node_modules/@remix-run/router": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz",
@@ -1223,6 +1396,14 @@
"win32"
]
},
+ "node_modules/@swc/helpers": {
+ "version": "0.5.12",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.12.tgz",
+ "integrity": "sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@@ -1320,6 +1501,11 @@
"vite": "^4.2.0 || ^5.0.0"
}
},
+ "node_modules/abs-svg-path": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz",
+ "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA=="
+ },
"node_modules/acorn": {
"version": "8.12.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
@@ -1597,6 +1783,33 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/bidi-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
+ "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
+ "dependencies": {
+ "require-from-string": "^2.0.2"
+ }
+ },
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
@@ -1631,6 +1844,22 @@
"node": ">=8"
}
},
+ "node_modules/brotli": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
+ "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==",
+ "dependencies": {
+ "base64-js": "^1.1.2"
+ }
+ },
+ "node_modules/browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dependencies": {
+ "pako": "~1.0.5"
+ }
+ },
"node_modules/browserslist": {
"version": "4.23.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz",
@@ -1770,6 +1999,14 @@
"node": ">= 6"
}
},
+ "node_modules/clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -1782,8 +2019,16 @@
"node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "node_modules/color-string": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+ "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
},
"node_modules/com": {
"resolved": "../com",
@@ -1810,6 +2055,14 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
+ "node_modules/cross-fetch": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
+ "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
+ "dependencies": {
+ "node-fetch": "^2.6.12"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -1824,6 +2077,11 @@
"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=="
+ },
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -1950,6 +2208,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/dfa": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz",
+ "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q=="
+ },
"node_modules/didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@@ -2510,11 +2773,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-glob": {
"version": "3.3.2",
@@ -2625,6 +2895,22 @@
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
"dev": true
},
+ "node_modules/fontkit": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.4.tgz",
+ "integrity": "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.12",
+ "brotli": "^1.3.2",
+ "clone": "^2.1.2",
+ "dfa": "^1.2.0",
+ "fast-deep-equal": "^3.1.3",
+ "restructure": "^3.0.0",
+ "tiny-inflate": "^1.0.3",
+ "unicode-properties": "^1.4.0",
+ "unicode-trie": "^2.0.0"
+ }
+ },
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -2921,6 +3207,24 @@
"node": ">= 0.4"
}
},
+ "node_modules/hsl-to-hex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hsl-to-hex/-/hsl-to-hex-1.0.0.tgz",
+ "integrity": "sha512-K6GVpucS5wFf44X0h2bLVRDsycgJmf9FF2elg+CrqD8GcFU8c6vYhgXn8NjUkFCwj+xDFb70qgLbTUm6sxwPmA==",
+ "dependencies": {
+ "hsl-to-rgb-for-reals": "^1.1.0"
+ }
+ },
+ "node_modules/hsl-to-rgb-for-reals": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/hsl-to-rgb-for-reals/-/hsl-to-rgb-for-reals-1.1.1.tgz",
+ "integrity": "sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg=="
+ },
+ "node_modules/hyphen": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/hyphen/-/hyphen-1.10.4.tgz",
+ "integrity": "sha512-SejXzIpv9gOVdDWXd4suM1fdF1k2dxZGvuTdkOVLoazYfK7O4DykIQbdrvuyG+EaTNlXAGhMndtKrhykgbt0gg=="
+ },
"node_modules/ignore": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
@@ -2969,8 +3273,7 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/internal-slot": {
"version": "1.0.7",
@@ -3002,6 +3305,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+ },
"node_modules/is-async-function": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
@@ -3316,6 +3624,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-url": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
+ "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
+ },
"node_modules/is-weakmap": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
@@ -3396,6 +3709,14 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/jay-peg": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/jay-peg/-/jay-peg-1.0.2.tgz",
+ "integrity": "sha512-fyV3NVvv6pTys/3BTapBUGAWAuU9rM2gRcgijZHzptd5KKL+s+S7hESFN+wOsbDH1MzFwdlRAXi0aGxS6uiMKg==",
+ "dependencies": {
+ "restructure": "^3.0.0"
+ }
+ },
"node_modules/jiti": {
"version": "1.21.6",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
@@ -3557,6 +3878,11 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/media-engine": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/media-engine/-/media-engine-1.0.3.tgz",
+ "integrity": "sha512-aa5tG6sDoK+k70B9iEX1NeyfT8ObCKhNDs6lJVpwF6r8vhUfuKMslIcirq6HIUYuuUYLefcEQOn9bSBOvawtwg=="
+ },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -3641,6 +3967,25 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
"node_modules/node-releases": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
@@ -3665,11 +4010,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/normalize-svg-path": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz",
+ "integrity": "sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==",
+ "dependencies": {
+ "svg-arc-to-cubic-bezier": "^3.0.0"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -3833,6 +4185,11 @@
"integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
"dev": true
},
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -3845,6 +4202,11 @@
"node": ">=6"
}
},
+ "node_modules/parse-svg-path": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
+ "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -4114,8 +4476,7 @@
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
"node_modules/prelude-ls": {
"version": "1.2.1",
@@ -4219,7 +4580,6 @@
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "dev": true,
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
@@ -4235,6 +4595,14 @@
"node": ">=6"
}
},
+ "node_modules/queue": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
+ "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
+ "dependencies": {
+ "inherits": "~2.0.3"
+ }
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -4289,8 +4657,7 @@
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "dev": true
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-refresh": {
"version": "0.14.2",
@@ -4373,6 +4740,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+ },
"node_modules/regexp.prototype.flags": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
@@ -4391,6 +4763,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/resolve": {
"version": "2.0.0-next.5",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
@@ -4417,6 +4797,11 @@
"node": ">=4"
}
},
+ "node_modules/restructure": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz",
+ "integrity": "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw=="
+ },
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -4519,6 +4904,25 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/safe-regex-test": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
@@ -4636,6 +5040,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "dependencies": {
+ "is-arrayish": "^0.3.1"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
@@ -4645,6 +5057,14 @@
"node": ">=0.10.0"
}
},
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
@@ -4922,6 +5342,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/svg-arc-to-cubic-bezier": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz",
+ "integrity": "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g=="
+ },
"node_modules/tailwindcss": {
"version": "3.4.7",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.7.tgz",
@@ -5003,6 +5428,11 @@
"node": ">=0.8"
}
},
+ "node_modules/tiny-inflate": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
+ "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
+ },
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@@ -5024,12 +5454,22 @@
"node": ">=8.0"
}
},
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"dev": true
},
+ "node_modules/tslib": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
+ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -5142,6 +5582,29 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/unicode-properties": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz",
+ "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==",
+ "dependencies": {
+ "base64-js": "^1.3.0",
+ "unicode-trie": "^2.0.0"
+ }
+ },
+ "node_modules/unicode-trie": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz",
+ "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==",
+ "dependencies": {
+ "pako": "^0.2.5",
+ "tiny-inflate": "^1.0.0"
+ }
+ },
+ "node_modules/unicode-trie/node_modules/pako": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="
+ },
"node_modules/update-browserslist-db": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
@@ -5184,8 +5647,7 @@
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/vite": {
"version": "5.3.5",
@@ -5242,6 +5704,33 @@
}
}
},
+ "node_modules/vite-compatible-readable-stream": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/vite-compatible-readable-stream/-/vite-compatible-readable-stream-3.6.1.tgz",
+ "integrity": "sha512-t20zYkrSf868+j/p31cRIGN28Phrjm3nRSLR2fyc2tiWi4cZGVdv68yNlwnIINTkMTmPoMiSlc0OadaO7DXZaQ==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -5507,6 +5996,11 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/yoga-layout": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-2.0.1.tgz",
+ "integrity": "sha512-tT/oChyDXelLo2A+UVnlW9GU7CsvFMaEnd9kVFsaiCQonFAXd3xrHhkLYu+suwwosrAEQ746xBU+HvYtm1Zs2Q=="
}
}
}
diff --git a/staff/jose-canto/project/FactuClient/package.json b/staff/jose-canto/project/FactuClient/package.json
index 9d7347e23..967ed6c92 100644
--- a/staff/jose-canto/project/FactuClient/package.json
+++ b/staff/jose-canto/project/FactuClient/package.json
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
+ "@react-pdf/renderer": "^3.4.4",
"com": "file:../com",
"react": "^18.3.1",
"react-dom": "^18.3.1",
diff --git a/staff/jose-canto/project/FactuClient/src/components/Confirm/index.css b/staff/jose-canto/project/FactuClient/src/components/Confirm/index.css
new file mode 100644
index 000000000..e563a9007
--- /dev/null
+++ b/staff/jose-canto/project/FactuClient/src/components/Confirm/index.css
@@ -0,0 +1,19 @@
+@tailwind components;
+
+@layer components {
+ .Confirm {
+ @apply absolute mx-auto w-auto flex-1 flex-col items-center rounded-lg bg-[#e4e4e4] p-4 shadow-custom-shadow;
+ }
+
+ .Confirm h2 {
+ @apply text-center text-2xl font-bold;
+ }
+
+ .Confirm p {
+ @apply mt-4 text-center;
+ }
+
+ .Confirm-Buttons {
+ @apply flex w-auto gap-10;
+ }
+}
diff --git a/staff/jose-canto/project/FactuClient/src/components/Confirm/index.jsx b/staff/jose-canto/project/FactuClient/src/components/Confirm/index.jsx
new file mode 100644
index 000000000..e34e3dbab
--- /dev/null
+++ b/staff/jose-canto/project/FactuClient/src/components/Confirm/index.jsx
@@ -0,0 +1,22 @@
+import Button from "../core/Button"
+import Title from "../Title"
+
+import "./index.css"
+
+export default function Confirm({ setShowConfirmDelete, handleDeleteDeliveryNote }) {
+ return (
+ <>
+
+
¿Seguro que quieres eliminar?
+
+
+
+
+
+ >
+ )
+}
diff --git a/staff/jose-canto/project/FactuClient/src/components/Header/index.jsx b/staff/jose-canto/project/FactuClient/src/components/Header/index.jsx
index 89b041046..2d6a651fd 100644
--- a/staff/jose-canto/project/FactuClient/src/components/Header/index.jsx
+++ b/staff/jose-canto/project/FactuClient/src/components/Header/index.jsx
@@ -9,7 +9,14 @@ import logic from "../../logic"
import RegisterCustomer from "../RegisterCustomerForm"
import EditProfileForm from "../EditProfileForm"
-export default function Header({ className, iconUser, children, iconLeftHeader, onRegisterCustomer }) {
+export default function Header({
+ className,
+ iconUser,
+ children,
+ iconLeftHeader,
+ onRegisterCustomer,
+ onDeleteDeliveryNote
+}) {
const navigate = useNavigate()
const location = useLocation()
const [showRegisterCustomer, setShowRegisterCustomer] = useState(false)
@@ -111,6 +118,9 @@ export default function Header({ className, iconUser, children, iconLeftHeader,
{isCustomerProfilePathDeliveryNoteId && (
+
+ {iconLeftHeader}
+
{iconUser}
{children}
diff --git a/staff/jose-canto/project/FactuClient/src/components/core/Button/index.css b/staff/jose-canto/project/FactuClient/src/components/core/Button/index.css
index 36a60a1d5..e115faae6 100644
--- a/staff/jose-canto/project/FactuClient/src/components/core/Button/index.css
+++ b/staff/jose-canto/project/FactuClient/src/components/core/Button/index.css
@@ -4,4 +4,8 @@
.Button {
@apply mt-4 flex h-12 w-3/4 cursor-pointer items-center justify-center rounded-2xl border-[2px] border-white bg-custom-gradient p-2 text-2xl font-bold shadow-custom-shadow;
}
+
+ .Button:hover {
+ @apply border-[3px] border-black bg-black text-white;
+ }
}
diff --git a/staff/jose-canto/project/FactuClient/src/components/view/DeliveryInfo.css b/staff/jose-canto/project/FactuClient/src/components/view/DeliveryInfo.css
index a1fe3a893..7a6f4b349 100644
--- a/staff/jose-canto/project/FactuClient/src/components/view/DeliveryInfo.css
+++ b/staff/jose-canto/project/FactuClient/src/components/view/DeliveryInfo.css
@@ -4,6 +4,9 @@
.MainDeliveryInfo {
@apply relative bottom-7;
}
+ .HeaderDeliveryInfo .IconLeftHeader {
+ @apply text-6xl;
+ }
.DeliveryWork {
@apply relative flex w-[90%] flex-col;
}
diff --git a/staff/jose-canto/project/FactuClient/src/components/view/DeliveryInfo.jsx b/staff/jose-canto/project/FactuClient/src/components/view/DeliveryInfo.jsx
index ae5691e9f..cd81dc3dd 100644
--- a/staff/jose-canto/project/FactuClient/src/components/view/DeliveryInfo.jsx
+++ b/staff/jose-canto/project/FactuClient/src/components/view/DeliveryInfo.jsx
@@ -1,21 +1,27 @@
import { useEffect, useState } from "react"
-import { useParams } from "react-router-dom"
+import { useParams, useNavigate } from "react-router-dom"
+import { PDFDownloadLink } from "@react-pdf/renderer"
import { GiStabbedNote } from "react-icons/gi"
+import { MdDeleteForever } from "react-icons/md"
import Header from "../Header"
import Main from "../core/Main"
import Time from "../core/Time"
import Footer from "../core/Footer"
+import Confirm from "../Confirm"
+import DeliveryNotePDF from "./DeliveryNotePDF"
import logic from "../../logic/index"
import "./DeliveryInfo.css"
export default function DeliveryInfo() {
+ const navigate = useNavigate()
const { deliveryNoteId } = useParams()
const [deliveryNote, setDeliveryNote] = useState(null)
const [total, setTotal] = useState(0)
+ const [showConfirmDelete, setShowConfirmDelete] = useState(false)
useEffect(() => {
try {
@@ -28,16 +34,41 @@ export default function DeliveryInfo() {
setTotal(calculateTotal)
})
.catch((error) => {
- alert.error(error.message)
+ alert(error.message)
})
} catch (error) {
alert(error.message)
}
}, [deliveryNoteId])
+ const handleDeleteDeliveryNote = () => {
+ try {
+ //prettier-ignore
+ logic.deleteDeliveryNote(deliveryNoteId)
+ .then(() => {
+ navigate(-1)
+ })
+ .catch((error) => {
+ alert(error.message)
+ })
+ } catch (error) {
+ alert(error.message)
+ }
+ }
+
+ const handleShowConfirmDelete = () => {
+ setShowConfirmDelete(!showConfirmDelete)
+ }
+
return (
<>
- } className={"HeaderDeliveryInfo"}>
+ }
+ iconLeftHeader={}
+ className={"HeaderDeliveryInfo"}
+ onDeleteDeliveryNote={handleShowConfirmDelete}
+ >
+
{deliveryNote?.customer &&
{deliveryNote.customer.companyName}
}
@@ -46,7 +77,7 @@ export default function DeliveryInfo() {
- {deliveryNote?.number &&
Albarán nº:{deliveryNote.number}
}
+ {deliveryNote?.number &&
Albarán nº: {deliveryNote.number}
}
{deliveryNote?.date &&
}
@@ -75,9 +106,22 @@ export default function DeliveryInfo() {
{deliveryNote?.customer &&
Observaciones:{deliveryNote.observations}
}
-
TOTAL: {total.toFixed(2)} €
+
TOTAL: {total.toFixed(2)} €
+
+ {showConfirmDelete && (
+
+ )}
+ {deliveryNote && (
+
}
+ fileName={`delivery-note-${deliveryNote.number}.pdf`}
+ >
+ {({ loading }) => (loading ? "Generando PDF..." : "Descargar PDF")}
+
+ )}
+
>
)
diff --git a/staff/jose-canto/project/FactuClient/src/components/view/DeliveryNotePDF.jsx b/staff/jose-canto/project/FactuClient/src/components/view/DeliveryNotePDF.jsx
new file mode 100644
index 000000000..27f8424b9
--- /dev/null
+++ b/staff/jose-canto/project/FactuClient/src/components/view/DeliveryNotePDF.jsx
@@ -0,0 +1,149 @@
+import { Page, Text, View, Document, StyleSheet, Image } from "@react-pdf/renderer"
+
+const styles = StyleSheet.create({
+ page: {
+ padding: 10,
+ backgroundColor: "aliceblue"
+ },
+ section: {
+ margin: 5,
+ padding: 5,
+ flexGrow: 1
+ },
+ headerRow: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
+ marginBottom: 15
+ },
+ header: {
+ fontSize: 16,
+ textAlign: "center"
+ },
+ date: {
+ fontSize: 12,
+ textAlign: "center"
+ },
+ borderedSection: {
+ border: "1px solid black",
+ padding: 10,
+ marginBottom: 10,
+ flex: 1,
+ textAlign: "center"
+ },
+ companyInfo: {
+ backgroundColor: "#e0f7fa"
+ },
+ customerInfo: {
+ backgroundColor: "#f1f8e9"
+ },
+ infoRow: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ marginBottom: 5,
+ fontSize: 12
+ },
+ workInfoHeader: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ marginBottom: 5,
+ fontWeight: "bold",
+ fontSize: 14,
+ backgroundColor: "#d5cabd",
+ padding: 5
+ },
+ workInfo: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ marginBottom: 5,
+ fontSize: 12
+ },
+ concept: {
+ flex: 3,
+ textAlign: "left"
+ },
+ quantity: {
+ flex: 1,
+ textAlign: "right"
+ },
+ price: {
+ flex: 1,
+ textAlign: "right"
+ },
+ totalAmount: {
+ flex: 1,
+ textAlign: "right"
+ },
+ total: {
+ marginTop: 20,
+ fontSize: 16,
+ textAlign: "right"
+ },
+ logo: {
+ width: 50,
+ height: 50,
+ marginBottom: 15
+ }
+})
+
+const DeliveryNotePDF = ({ deliveryNote, total }) => {
+ const formattedDate = new Date(deliveryNote.date).toLocaleDateString()
+
+ return (
+
+
+
+
+
+
+ Albarán nº: {deliveryNote.number}
+ Fecha: {formattedDate}
+
+
+
+
+ {deliveryNote.company.companyName}
+ {"\n"}
+ {deliveryNote.company.address}
+ {"\n"}
+ {deliveryNote.company.taxId}
+ {"\n"}
+ {deliveryNote.company.email}
+
+
+ Cliente:
+
+ {deliveryNote.customer.companyName}
+ {"\n"}
+ {deliveryNote.customer.address}
+ {"\n"}
+ {deliveryNote.customer.taxId}
+ {"\n"}
+ {deliveryNote.customer.email}
+
+
+
+
+
+ Concepto
+ Cantidad
+ Precio
+ Total
+
+ {deliveryNote.works.map((work) => (
+
+ {work.concept}
+ {work.quantity.toFixed(2)}
+ {work.price.toFixed(2)}
+ {(work.quantity * work.price).toFixed(2)}
+
+ ))}
+
+ TOTAL: {total.toFixed(2)} €
+
+
+
+ )
+}
+
+export default DeliveryNotePDF
diff --git a/staff/jose-canto/project/FactuClient/src/components/view/DeliveryNotesList.css b/staff/jose-canto/project/FactuClient/src/components/view/DeliveryNotesList.css
index e63cdeb47..795e39262 100644
--- a/staff/jose-canto/project/FactuClient/src/components/view/DeliveryNotesList.css
+++ b/staff/jose-canto/project/FactuClient/src/components/view/DeliveryNotesList.css
@@ -6,7 +6,7 @@
}
.DeliveryLink {
- @apply flex items-start;
+ @apply flex items-center;
}
.DeliveryNote {
diff --git a/staff/jose-canto/project/FactuClient/src/logic/deleteDeliveryNote.js b/staff/jose-canto/project/FactuClient/src/logic/deleteDeliveryNote.js
new file mode 100644
index 000000000..9cc704189
--- /dev/null
+++ b/staff/jose-canto/project/FactuClient/src/logic/deleteDeliveryNote.js
@@ -0,0 +1,27 @@
+import errors, { SystemError } from "com/errors.js"
+import validate from "com/validate.js"
+
+const deleteDeliveryNote = (deliveryNoteId) => {
+ validate.id(deliveryNoteId, "deliveryNoteId")
+
+ return fetch(`${import.meta.env.VITE_API_URL}/delivery-notes/${deliveryNoteId}`, {
+ method: "DELETE",
+ headers: {
+ "Content-Type": "application/json",
+ "Authorization": `Bearer ${sessionStorage.token}`
+ }
+ })
+ .catch(() => { throw new SystemError("connection error") })
+ .then(response => {
+ if (response.status === 204) return
+
+ return response.json()
+ .catch(() => { throw new SystemError("connection error") })
+ .then(body => {
+ const { error, message } = body
+ const constructor = errors[error]
+ throw new constructor(message)
+ })
+ })
+}
+export default deleteDeliveryNote
\ No newline at end of file
diff --git a/staff/jose-canto/project/FactuClient/src/logic/index.js b/staff/jose-canto/project/FactuClient/src/logic/index.js
index 601672ca9..d9540eb2b 100644
--- a/staff/jose-canto/project/FactuClient/src/logic/index.js
+++ b/staff/jose-canto/project/FactuClient/src/logic/index.js
@@ -12,6 +12,7 @@ import getProfileUser from "./getProfileUser.js"
import getAllDeliveryNotes from "./getAllDeliveryNotes.js"
import getDeliveryNote from "./getDeliveryNote.js"
+import deleteDeliveryNote from "./deleteDeliveryNote.js"
import createDeliveryNote from "./createDeliveryNote.js"
import createWork from "./createWork.js"
@@ -19,6 +20,7 @@ import createWork from "./createWork.js"
import getAllInvoices from "./getAllInvoices.js"
import getInvoice from "./getInvoice.js"
+
const logic = {
isUserLoggedIn,
loginUser,
@@ -34,6 +36,7 @@ const logic = {
getAllDeliveryNotes,
getDeliveryNote,
+ deleteDeliveryNote,
createDeliveryNote,
createWork,
diff --git a/staff/jose-canto/project/api/handlers/deleteDeliveryNoteHandler.js b/staff/jose-canto/project/api/handlers/deleteDeliveryNoteHandler.js
new file mode 100644
index 000000000..5f64da31a
--- /dev/null
+++ b/staff/jose-canto/project/api/handlers/deleteDeliveryNoteHandler.js
@@ -0,0 +1,31 @@
+import jwt from "../utils/jsonwebtoken-promised.js";
+import { CredentialsError } from "com/errors.js"
+import logic from "../logic/index.js";
+
+const { JWT_SECRET } = process.env
+
+export default ((req, res, next) => {
+
+ try {
+ const token = req.headers.authorization.slice(7)
+
+ jwt.verify(token, JWT_SECRET)
+ .then(payload => {
+ const { sub: userId } = payload
+ const { deliveryNoteId } = req.params
+
+ try {
+ logic.deleteDeliveryNote(userId, deliveryNoteId)
+ .then(() => res.status(204).send())
+ .catch(error => next(error))
+
+ } catch (error) {
+ next(error)
+ }
+ })
+ .catch(error => next(new CredentialsError(error.message)))
+
+ } catch (error) {
+ next(error)
+ }
+})
\ No newline at end of file
diff --git a/staff/jose-canto/project/api/handlers/index.js b/staff/jose-canto/project/api/handlers/index.js
index b537afff1..50e8a9f33 100644
--- a/staff/jose-canto/project/api/handlers/index.js
+++ b/staff/jose-canto/project/api/handlers/index.js
@@ -16,6 +16,7 @@ import createWorkHandler from "./createWorkHandler.js"
import getAllInvoicesHandler from "./getAllInvoicesHandler.js"
import getInvoiceHandler from "./getInvoiceHandler.js"
+import deleteDeliveryNoteHandler from "./deleteDeliveryNoteHandler.js"
export default {
@@ -30,6 +31,7 @@ export default {
getAllDeliveryNotesHandler,
getDeliveryNoteHandler,
+ deleteDeliveryNoteHandler,
createDeliveryNoteHandler,
diff --git a/staff/jose-canto/project/api/logic/deleteDeliveryNote.js b/staff/jose-canto/project/api/logic/deleteDeliveryNote.js
index 5a6b30fdc..23b7bc1df 100644
--- a/staff/jose-canto/project/api/logic/deleteDeliveryNote.js
+++ b/staff/jose-canto/project/api/logic/deleteDeliveryNote.js
@@ -20,11 +20,13 @@ const deleteDeliveryNote = (userId, deliveryNoteId) => {
throw new NotFoundError("Delivery Note not found")
}
+ if (deliveryNote.company.toString() !== userId) {
+ throw new NotFoundError("No puedes borrar una nota de entrega que no es tuya")
+ }
+
return DeliveryNote.deleteOne({ _id: deliveryNoteId })
.catch(error => { throw new SystemError(error.message) })
- .then(() => {
- return deliveryNote
- })
+ .then(() => { })
})
})
}
diff --git a/staff/jose-canto/project/api/logic/deleteDeliveryNote.test.js b/staff/jose-canto/project/api/logic/deleteDeliveryNote.test.js
index a93d1304a..c1da507e7 100644
--- a/staff/jose-canto/project/api/logic/deleteDeliveryNote.test.js
+++ b/staff/jose-canto/project/api/logic/deleteDeliveryNote.test.js
@@ -8,9 +8,9 @@ mongoose.connect(MONGODB_URL)
.then(() => {
try {
- deleteDeliveryNote("66b1237dd5adf0eb620e97bc", "66b8d630e4f3e5906c89d05b")
+ deleteDeliveryNote("66b1237dd5adf0eb620e97bc", "66b8cbece4f3e5906c7f2f69")
.then((deliveryNote) => {
- console.log(`Delivery note ${deliveryNote} deleted`)
+ console.log(`Delivery note deleted`)
})
.catch(error => console.error(error))
diff --git a/staff/jose-canto/project/api/logic/getAllInvoices.js b/staff/jose-canto/project/api/logic/getAllInvoices.js
index 7ee437e1d..4ceca9947 100644
--- a/staff/jose-canto/project/api/logic/getAllInvoices.js
+++ b/staff/jose-canto/project/api/logic/getAllInvoices.js
@@ -9,7 +9,7 @@ const getAllInvoices = (userId) => {
.catch(error => { throw new SystemError(error.message) })
.then(user => {
if (!user) {
- throw new NotFoundError("user not found")
+ throw new NotFoundError("User not found")
}
return Invoice.find({}).populate("company").populate("customer").sort({ date: -1 }).select("-__v").lean()
diff --git a/staff/jose-canto/project/api/logic/getAllInvoices.spec.js b/staff/jose-canto/project/api/logic/getAllInvoices.spec.js
new file mode 100644
index 000000000..1c8aabc10
--- /dev/null
+++ b/staff/jose-canto/project/api/logic/getAllInvoices.spec.js
@@ -0,0 +1,69 @@
+import { mongoose, Types } from "mongoose"
+import bcrypt from "bcryptjs"
+import { expect } from "chai"
+import { User, Invoice } from "../model/index.js"
+import getAllInvoices from "./getAllInvoices.js"
+import { NotFoundError, ContentError } from "com/errors.js"
+
+const { ObjectId } = Types
+const { MONGODB_URL_TEST } = process.env
+
+describe("getAllInvoices", () => {
+ before(() => mongoose.connect(MONGODB_URL_TEST).then(() => User.deleteMany().then(() => Invoice.deleteMany())))
+
+ beforeEach(() => User.deleteMany().then(() => Invoice.deleteMany()))
+
+ it("succeeds on getting all invoices", () =>
+ bcrypt.hash("1234", 10)
+ .then((hash) => User.create({ username: "Jack", email: "jack@email.es", password: hash }))
+ .then((user) => {
+ const { id } = user
+
+ return Invoice.create({ company: id, customer: id, number: "2024/123", date: new Date(), observations: "test", paymentType: "cash" })
+ .then(() => Invoice.create({ company: id, customer: id, number: "2024/124", date: new Date(), observations: "test2", paymentType: "credit card" }))
+ .then(() => getAllInvoices(id))
+ .then((invoices) => {
+ expect(invoices).to.be.an("array")
+ expect(invoices.length).to.equal(2)
+
+ invoices.map(invoice => {
+ expect(invoice.id).to.be.a("string")
+ expect(invoice.company).to.be.an("object")
+ expect(invoice.customer).to.be.an("object")
+ expect(invoice.date).to.be.an.instanceOf(Date)
+ expect(invoice.number).to.be.a("string")
+ expect(invoice.deliveryNotes).to.be.an("array")
+ expect(invoice.observations).to.be.a("string")
+ expect(invoice.paymentType).to.be.a("string")
+ });
+ });
+ })
+ );
+
+ it("fails on existing customer user", () => {
+ let errorThrown
+
+ return getAllInvoices(new ObjectId().toString())
+ .catch((error) => errorThrown = error)
+ .finally(() => {
+ expect(errorThrown).to.be.instanceOf(NotFoundError)
+ expect(errorThrown.message).to.equal("User not found")
+ })
+ })
+
+ it("fails on invalid userId", () => {
+ let errorThrown
+
+ try {
+ getAllInvoices(77777)
+ } catch (error) {
+ errorThrown = error
+
+ } finally {
+ expect(errorThrown).to.be.instanceOf(ContentError)
+ expect(errorThrown.message).to.equal("userId is not valid")
+ }
+ })
+
+ after(() => User.deleteMany().then(() => mongoose.disconnect()))
+})
\ No newline at end of file
diff --git a/staff/jose-canto/project/api/logic/registerCustomer.js b/staff/jose-canto/project/api/logic/registerCustomer.js
index a94fdea5d..f94211a15 100644
--- a/staff/jose-canto/project/api/logic/registerCustomer.js
+++ b/staff/jose-canto/project/api/logic/registerCustomer.js
@@ -1,11 +1,8 @@
import validate from "com/validate.js"
import { User } from "../model/index.js"
-import { DuplicityError, NotFoundError, SystemError } from "com/errors.js"
+import { NotFoundError, SystemError } from "com/errors.js"
import bcrypt from "bcryptjs"
-import mongoose from "mongoose"
-const { ObjectId } = mongoose.Types
-
const registerCustomer = (userId, username, companyName, email, password, taxId, address, phone) => {
validate.id(userId)
validate.username(username)
@@ -23,34 +20,27 @@ const registerCustomer = (userId, username, companyName, email, password, taxId,
throw new NotFoundError('User not found')
}
- return User.findOne({ $or: [{ username }, { email }, { taxId }] })
- .catch((error) => { throw new SystemError(error.message) })
- .then(user => {
- if (user) {
- throw new DuplicityError('User already exists')
+ return bcrypt.hash(password, 10)
+ .catch(error => { throw new SystemError(error.message) })
+ .then(hash => {
+
+ const newCustomer = {
+ username,
+ companyName,
+ email,
+ password: hash,
+ taxId,
+ address,
+ phone,
+ role: "customer",
+ manager: userId
}
- return bcrypt.hash(password, 10)
+ return User.create(newCustomer)
.catch(error => { throw new SystemError(error.message) })
- .then(hash => {
-
- const newCustomer = {
- username,
- companyName,
- email,
- password: hash,
- taxId,
- address,
- phone,
- role: "customer",
- manager: userId
- }
-
- return User.create(newCustomer)
- .catch(error => { throw new SystemError(error.message) })
- .then(() => { })
- })
+ .then(() => { })
})
+
})
}
export default registerCustomer
diff --git a/staff/jose-canto/project/api/logic/registerCustomer.spec.js b/staff/jose-canto/project/api/logic/registerCustomer.spec.js
index 460476ef1..0b429af40 100644
--- a/staff/jose-canto/project/api/logic/registerCustomer.spec.js
+++ b/staff/jose-canto/project/api/logic/registerCustomer.spec.js
@@ -7,12 +7,11 @@ import { expect } from "chai"
import { User } from "../model/index.js"
import registerCustomer from "./registerCustomer.js"
-import { NotFoundError, DuplicityError, ContentError } from "com/errors.js"
+import { NotFoundError, ContentError } from "com/errors.js"
const { ObjectId } = Types
const { MONGODB_URL_TEST } = process.env
-
describe("registerCustomer", () => {
before(() => mongoose.connect(MONGODB_URL_TEST).then(() => User.deleteMany()))
@@ -50,17 +49,6 @@ describe("registerCustomer", () => {
})
})
- it("fails on exist customer user", () =>
-
- bcrypt.hash("1234", 10)
- .then((hash) => User.create({ username: "Jack", email: "jack@email.es", password: hash }))
- .then((user) => registerCustomer(user.id, "Jack", "Pepito Enterprise, Inc.", "jack@email.es", "1234", "B03413111", "Calle falsa 123", "666555443"))
- .catch((error) => {
- expect(error).to.be.instanceOf(DuplicityError)
- expect(error.message).to.equal("User already exists")
- })
- )
-
it("fails on invalid username", () => {
let errorThrown
diff --git a/staff/jose-canto/project/api/model/User.js b/staff/jose-canto/project/api/model/User.js
index 810634436..ce8336970 100644
--- a/staff/jose-canto/project/api/model/User.js
+++ b/staff/jose-canto/project/api/model/User.js
@@ -10,7 +10,6 @@ const user = new Schema({
email: {
type: String,
required: true,
- unique: true
},
password: {
type: String,
diff --git a/staff/jose-canto/project/api/routes.js b/staff/jose-canto/project/api/routes.js
index 6449b1b27..29d8b3375 100644
--- a/staff/jose-canto/project/api/routes.js
+++ b/staff/jose-canto/project/api/routes.js
@@ -17,6 +17,7 @@ router.get("/users/:targetUserId/profile", routes.getProfileUserHandler)
router.get("/delivery-notes", routes.getAllDeliveryNotesHandler)
router.get("/delivery-notes/:deliveryNoteId", routes.getDeliveryNoteHandler)
+router.delete("/delivery-notes/:deliveryNoteId", routes.deleteDeliveryNoteHandler)
router.post("/create/delivery-notes/:customerId", jsonBodyParser, routes.createDeliveryNoteHandler)
router.patch("/create/work/delivery-notes/:deliveryNoteId", jsonBodyParser, routes.createWorkHandler)