mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 15:55:48 +00:00
feat(FE-181-179-220-271): adding SO export PDF and adjusting delivery form
This commit is contained in:
Generated
+517
-2
@@ -8,6 +8,7 @@
|
|||||||
"name": "lti-web-client",
|
"name": "lti-web-client",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-pdf/renderer": "^4.3.1",
|
||||||
"@tanstack/match-sorter-utils": "^8.19.4",
|
"@tanstack/match-sorter-utils": "^8.19.4",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
"axios": "^1.12.2",
|
"axios": "^1.12.2",
|
||||||
@@ -1274,6 +1275,180 @@
|
|||||||
"node": ">=12.4.0"
|
"node": ">=12.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-pdf/fns": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/fns/-/fns-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-qTKGUf0iAMGg2+OsUcp9ffKnKi41RukM/zYIWMDJ4hRVYSr89Q7e3wSDW/Koqx3ea3Uy/z3h2y3wPX6Bdfxk6g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/font": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/font/-/font-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-N1qQDZr6phXYQOp033Hvm2nkUkx2LkszjGPbmRavs9VOYzi4sp31MaccMKptL24ii6UhBh/z9yPUhnuNe/qHwA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-pdf/pdfkit": "^4.0.4",
|
||||||
|
"@react-pdf/types": "^2.9.1",
|
||||||
|
"fontkit": "^2.0.2",
|
||||||
|
"is-url": "^1.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/image": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/image/-/image-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-lvP5ryzYM3wpbO9bvqLZYwEr5XBDX9jcaRICvtnoRqdJOo7PRrMnmB4MMScyb+Xw10mGeIubZAAomNAG5ONQZQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-pdf/png-js": "^3.0.0",
|
||||||
|
"jay-peg": "^1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/layout": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/layout/-/layout-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-GVzdlWoZWldRDzlWj3SttRXmVDxg7YfraAohwy+o9gb9hrbDJaaAV6jV3pc630Evd3K46OAzk8EFu8EgPDuVuA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-pdf/fns": "3.1.2",
|
||||||
|
"@react-pdf/image": "^3.0.3",
|
||||||
|
"@react-pdf/primitives": "^4.1.1",
|
||||||
|
"@react-pdf/stylesheet": "^6.1.1",
|
||||||
|
"@react-pdf/textkit": "^6.0.0",
|
||||||
|
"@react-pdf/types": "^2.9.1",
|
||||||
|
"emoji-regex-xs": "^1.0.0",
|
||||||
|
"queue": "^6.0.1",
|
||||||
|
"yoga-layout": "^3.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/pdfkit": {
|
||||||
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/pdfkit/-/pdfkit-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-/nITLggsPlB66bVLnm0X7MNdKQxXelLGZG6zB5acF5cCgkFwmXHnLNyxYOUD4GMOMg1HOPShXDKWrwk2ZeHsvw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.20.13",
|
||||||
|
"@react-pdf/png-js": "^3.0.0",
|
||||||
|
"browserify-zlib": "^0.2.0",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
|
"fontkit": "^2.0.2",
|
||||||
|
"jay-peg": "^1.1.1",
|
||||||
|
"linebreak": "^1.1.0",
|
||||||
|
"vite-compatible-readable-stream": "^3.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/png-js": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/png-js/-/png-js-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-eSJnEItZ37WPt6Qv5pncQDxLJRK15eaRwPT+gZoujP548CodenOVp49GST8XJvKMFt9YqIBzGBV/j9AgrOQzVA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"browserify-zlib": "^0.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/primitives": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/primitives/-/primitives-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-IuhxYls1luJb7NUWy6q5avb1XrNaVj9bTNI40U9qGRuS6n7Hje/8H8Qi99Z9UKFV74bBP3DOf3L1wV2qZVgVrQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/reconciler": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/reconciler/-/reconciler-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-oTQDiR/t4Z/Guxac88IavpU2UgN7eR0RMI9DRKvKnvPz2DUasGjXfChAdMqDNmJJxxV26mMy9xQOUV2UU5/okg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"scheduler": "0.25.0-rc-603e6108-20241029"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/reconciler/node_modules/scheduler": {
|
||||||
|
"version": "0.25.0-rc-603e6108-20241029",
|
||||||
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0-rc-603e6108-20241029.tgz",
|
||||||
|
"integrity": "sha512-pFwF6H1XrSdYYNLfOcGlM28/j8CGLu8IvdrxqhjWULe2bPcKiKW4CV+OWqR/9fT52mywx65l7ysNkjLKBda7eA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/render": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/render/-/render-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-v1WAaAhQShQZGcBxfjkEThGCHVH9CSuitrZ1bIOLvB5iBKM14abYK5D6djKhWCwF6FTzYeT2WRjRMVgze/ND2A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.20.13",
|
||||||
|
"@react-pdf/fns": "3.1.2",
|
||||||
|
"@react-pdf/primitives": "^4.1.1",
|
||||||
|
"@react-pdf/textkit": "^6.0.0",
|
||||||
|
"@react-pdf/types": "^2.9.1",
|
||||||
|
"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": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/renderer/-/renderer-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-dPKHiwGTaOsKqNWCHPYYrx8CDfAGsUnV4tvRsEu0VPGxuot1AOq/M+YgfN/Pb+MeXCTe2/lv6NvA8haUtj3tsA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.20.13",
|
||||||
|
"@react-pdf/fns": "3.1.2",
|
||||||
|
"@react-pdf/font": "^4.0.3",
|
||||||
|
"@react-pdf/layout": "^4.4.1",
|
||||||
|
"@react-pdf/pdfkit": "^4.0.4",
|
||||||
|
"@react-pdf/primitives": "^4.1.1",
|
||||||
|
"@react-pdf/reconciler": "^1.1.4",
|
||||||
|
"@react-pdf/render": "^4.3.1",
|
||||||
|
"@react-pdf/types": "^2.9.1",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"prop-types": "^15.6.2",
|
||||||
|
"queue": "^6.0.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/stylesheet": {
|
||||||
|
"version": "6.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/stylesheet/-/stylesheet-6.1.1.tgz",
|
||||||
|
"integrity": "sha512-Iyw0A3wRIeQLN4EkaKf8yF9MvdMxiZ8JjoyzLzDHSxnKYoOA4UGu84veCb8dT9N8MxY5x7a0BUv/avTe586Plg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-pdf/fns": "3.1.2",
|
||||||
|
"@react-pdf/types": "^2.9.1",
|
||||||
|
"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": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/textkit/-/textkit-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-fDt19KWaJRK/n2AaFoVm31hgGmpygmTV7LsHGJNGZkgzXcFyLsx+XUl63DTDPH3iqxj3xUX128t104GtOz8tTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-pdf/fns": "3.1.2",
|
||||||
|
"bidi-js": "^1.0.2",
|
||||||
|
"hyphen": "^1.6.4",
|
||||||
|
"unicode-properties": "^1.4.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-pdf/types": {
|
||||||
|
"version": "2.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-pdf/types/-/types-2.9.1.tgz",
|
||||||
|
"integrity": "sha512-5GoCgG0G5NMgpPuHbKG2xcVRQt7+E5pg3IyzVIIozKG3nLcnsXW4zy25vG1ZBQA0jmo39q34au/sOnL/0d1A4w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-pdf/font": "^4.0.3",
|
||||||
|
"@react-pdf/primitives": "^4.1.1",
|
||||||
|
"@react-pdf/stylesheet": "^6.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rtsao/scc": {
|
"node_modules/@rtsao/scc": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
||||||
@@ -2269,6 +2444,12 @@
|
|||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.15.0",
|
"version": "8.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||||
@@ -2603,6 +2784,35 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"require-from-string": "^2.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.12",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||||
@@ -2627,6 +2837,24 @@
|
|||||||
"node": ">=8"
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"pako": "~1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/call-bind": {
|
"node_modules/call-bind": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
||||||
@@ -2728,6 +2956,15 @@
|
|||||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/clone": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/clsx": {
|
"node_modules/clsx": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||||
@@ -2754,9 +2991,18 @@
|
|||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "^1.0.0",
|
||||||
|
"simple-swizzle": "^0.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/combined-stream": {
|
"node_modules/combined-stream": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
@@ -2813,6 +3059,12 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crypto-js": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"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",
|
||||||
@@ -3003,6 +3255,12 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dfa": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/doctrine": {
|
"node_modules/doctrine": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
||||||
@@ -3047,6 +3305,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/emoji-regex-xs": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.18.3",
|
"version": "5.18.3",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
|
||||||
@@ -3680,11 +3944,19 @@
|
|||||||
"node": ">=0.10.0"
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
@@ -3843,6 +4115,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fontkit": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"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": {
|
"node_modules/for-each": {
|
||||||
"version": "0.3.5",
|
"version": "0.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
|
||||||
@@ -4196,6 +4485,21 @@
|
|||||||
"react-is": "^16.7.0"
|
"react-is": "^16.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"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==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/husky": {
|
"node_modules/husky": {
|
||||||
"version": "9.1.7",
|
"version": "9.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
|
||||||
@@ -4212,6 +4516,12 @@
|
|||||||
"url": "https://github.com/sponsors/typicode"
|
"url": "https://github.com/sponsors/typicode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hyphen": {
|
||||||
|
"version": "1.10.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/hyphen/-/hyphen-1.10.6.tgz",
|
||||||
|
"integrity": "sha512-fXHXcGFTXOvZTSkPJuGOQf5Lv5T/R2itiiCVPg9LxAje5D00O0pP83yJShFq5V89Ly//Gt6acj7z8pbBr34stw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/ignore": {
|
"node_modules/ignore": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||||
@@ -4248,6 +4558,12 @@
|
|||||||
"node": ">=0.8.19"
|
"node": ">=0.8.19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/inputmask": {
|
"node_modules/inputmask": {
|
||||||
"version": "5.0.9",
|
"version": "5.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/inputmask/-/inputmask-5.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/inputmask/-/inputmask-5.0.9.tgz",
|
||||||
@@ -4630,6 +4946,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/is-weakmap": {
|
"node_modules/is-weakmap": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
|
||||||
@@ -4708,6 +5030,15 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jay-peg": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jay-peg/-/jay-peg-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-D62KEuBxz/ip2gQKOEhk/mx14o7eiFRaU+VNNSP4MOiIkwb/D6B3G1Mfas7C/Fit8EsSV2/IWjZElx/Gs6A4ww==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"restructure": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/jiti": {
|
"node_modules/jiti": {
|
||||||
"version": "2.6.1",
|
"version": "2.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
|
||||||
@@ -5110,6 +5441,25 @@
|
|||||||
"url": "https://opencollective.com/parcel"
|
"url": "https://opencollective.com/parcel"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/linebreak": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "0.0.8",
|
||||||
|
"unicode-trie": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/linebreak/node_modules/base64-js": {
|
||||||
|
"version": "0.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
|
||||||
|
"integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lines-and-columns": {
|
"node_modules/lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
@@ -5182,6 +5532,12 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/memoize-one": {
|
"node_modules/memoize-one": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||||
@@ -5392,6 +5748,15 @@
|
|||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"svg-arc-to-cubic-bezier": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-assign": {
|
"node_modules/object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
@@ -5582,6 +5947,12 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pako": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
|
||||||
|
"license": "(MIT AND Zlib)"
|
||||||
|
},
|
||||||
"node_modules/parent-module": {
|
"node_modules/parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -5612,6 +5983,12 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/path-exists": {
|
"node_modules/path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
@@ -5705,6 +6082,12 @@
|
|||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/prelude-ls": {
|
"node_modules/prelude-ls": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
@@ -5764,6 +6147,15 @@
|
|||||||
"node": ">=6"
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "~2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
@@ -5970,6 +6362,15 @@
|
|||||||
"integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==",
|
"integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.11",
|
"version": "1.22.11",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
|
||||||
@@ -6009,6 +6410,12 @@
|
|||||||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/restructure": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/reusify": {
|
"node_modules/reusify": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
|
||||||
@@ -6064,6 +6471,26 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/safe-push-apply": {
|
"node_modules/safe-push-apply": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
|
||||||
@@ -6309,6 +6736,21 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/simple-swizzle": {
|
||||||
|
"version": "0.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
|
||||||
|
"integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-arrayish": "^0.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/simple-swizzle/node_modules/is-arrayish": {
|
||||||
|
"version": "0.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
|
||||||
|
"integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/source-map": {
|
"node_modules/source-map": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||||
@@ -6348,6 +6790,15 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/string.prototype.includes": {
|
"node_modules/string.prototype.includes": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
|
||||||
@@ -6538,6 +6989,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"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==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/swr": {
|
"node_modules/swr": {
|
||||||
"version": "2.3.6",
|
"version": "2.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/swr/-/swr-2.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/swr/-/swr-2.3.6.tgz",
|
||||||
@@ -6588,6 +7045,12 @@
|
|||||||
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
|
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/tiny-warning": {
|
"node_modules/tiny-warning": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||||
@@ -6836,6 +7299,32 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/unrs-resolver": {
|
"node_modules/unrs-resolver": {
|
||||||
"version": "1.11.1",
|
"version": "1.11.1",
|
||||||
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz",
|
||||||
@@ -6916,6 +7405,26 @@
|
|||||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
@@ -7053,6 +7562,12 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/yoga-layout": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/yup": {
|
"node_modules/yup": {
|
||||||
"version": "1.7.1",
|
"version": "1.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"format": "prettier --write ."
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-pdf/renderer": "^4.3.1",
|
||||||
"@tanstack/match-sorter-utils": "^8.19.4",
|
"@tanstack/match-sorter-utils": "^8.19.4",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
"axios": "^1.12.2",
|
"axios": "^1.12.2",
|
||||||
|
|||||||
+6
-4
@@ -1,16 +1,17 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import SalesForm from '@/components/pages/marketing/form/MarketingForm';
|
import MarketingForm from '@/components/pages/marketing/form/MarketingForm';
|
||||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { MarketingApi } from '@/services/api/marketing/marketing';
|
import { MarketingApi } from '@/services/api/marketing/marketing';
|
||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
const EditMarketingDelivery = () => {
|
const EditMarketingDelivery = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
const soId = searchParams.get('salesOrderId');
|
const soId = searchParams.get('marketingId');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: marketing,
|
data: marketing,
|
||||||
@@ -34,12 +35,13 @@ const EditMarketingDelivery = () => {
|
|||||||
router.replace('/404');
|
router.replace('/404');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='w-full p-4'>
|
<div className='w-full p-4'>
|
||||||
{isLoading && <span className='loading loading-spinner loading-xl' />}
|
{isLoading && <span className='loading loading-spinner loading-xl' />}
|
||||||
{!isLoading && isResponseSuccess(marketing) && (
|
{!isLoading && isResponseSuccess(marketing) && (
|
||||||
<SalesForm
|
<MarketingForm
|
||||||
formType='deliver'
|
formType='add_deliver'
|
||||||
initialValues={marketing.data}
|
initialValues={marketing.data}
|
||||||
afterSubmit={() => {
|
afterSubmit={() => {
|
||||||
refreshMarketing();
|
refreshMarketing();
|
||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
import SalesForm from '@/components/pages/marketing/form/MarketingForm';
|
import MarketingForm from '@/components/pages/marketing/form/MarketingForm';
|
||||||
|
|
||||||
const AddSalesOrder = () => {
|
const AddSalesOrder = () => {
|
||||||
return (
|
return (
|
||||||
<div className='size-full p-4'>
|
<div className='size-full p-4'>
|
||||||
<SalesForm />
|
<MarketingForm formType='add' />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import MarketingForm from '@/components/pages/marketing/form/MarketingForm';
|
||||||
|
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||||
|
import { MarketingApi } from '@/services/api/marketing/marketing';
|
||||||
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
|
import useSWR from 'swr';
|
||||||
|
|
||||||
|
const EditMarketingDelivery = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
|
const soId = searchParams.get('marketingId');
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: marketing,
|
||||||
|
isLoading: isLoading,
|
||||||
|
mutate: refreshMarketing,
|
||||||
|
} = useSWR(`get-so-${soId}`, () =>
|
||||||
|
MarketingApi.getSingle(soId ? parseInt(soId) : 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!soId) {
|
||||||
|
router.back();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='w-full flex flex-row justify-center items-center p-4'>
|
||||||
|
<span className='loading loading-spinner loading-xl' />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isLoading && (!marketing || isResponseError(marketing))) {
|
||||||
|
router.replace('/404');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
isResponseSuccess(marketing) &&
|
||||||
|
marketing.data.latest_approval.step_number != 3
|
||||||
|
) {
|
||||||
|
toast.error('Data Marketing perlu dilakukan approval terlebih dahulu!');
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='w-full p-4'>
|
||||||
|
{isLoading && <span className='loading loading-spinner loading-xl' />}
|
||||||
|
{!isLoading && isResponseSuccess(marketing) && (
|
||||||
|
<MarketingForm
|
||||||
|
formType='edit_deliver'
|
||||||
|
initialValues={marketing.data}
|
||||||
|
afterSubmit={() => {
|
||||||
|
refreshMarketing();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default EditMarketingDelivery;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import SuspenseHelper from '@/components/helper/SuspenseHelper';
|
||||||
|
|
||||||
|
const Layout = ({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) => {
|
||||||
|
return <SuspenseHelper>{children}</SuspenseHelper>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Layout;
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import SalesOrderDetail from '@/components/pages/marketing/detail/MarketingDetail';
|
import MarketingDetail from '@/components/pages/marketing/detail/MarketingDetail';
|
||||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { MarketingApi } from '@/services/api/marketing/marketing';
|
import { MarketingApi } from '@/services/api/marketing/marketing';
|
||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
const DetailSalesOrder = () => {
|
const DetailMarketing = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
const soId = searchParams.get('salesOrderId');
|
const soId = searchParams.get('marketingId');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: marketing,
|
data: marketing,
|
||||||
@@ -37,7 +37,7 @@ const DetailSalesOrder = () => {
|
|||||||
<div className='w-full p-4'>
|
<div className='w-full p-4'>
|
||||||
{isLoading && <span className='loading loading-spinner loading-xl' />}
|
{isLoading && <span className='loading loading-spinner loading-xl' />}
|
||||||
{!isLoading && isResponseSuccess(marketing) && (
|
{!isLoading && isResponseSuccess(marketing) && (
|
||||||
<SalesOrderDetail
|
<MarketingDetail
|
||||||
initialValues={marketing.data}
|
initialValues={marketing.data}
|
||||||
refresh={refreshMarketing}
|
refresh={refreshMarketing}
|
||||||
/>
|
/>
|
||||||
@@ -46,4 +46,4 @@ const DetailSalesOrder = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DetailSalesOrder;
|
export default DetailMarketing;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import SuspenseHelper from '@/components/helper/SuspenseHelper';
|
||||||
|
|
||||||
|
const Layout = ({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) => {
|
||||||
|
return <SuspenseHelper>{children}</SuspenseHelper>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Layout;
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import SalesForm from '@/components/pages/marketing/form/MarketingForm';
|
import MarketingForm from '@/components/pages/marketing/form/MarketingForm';
|
||||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { MarketingApi } from '@/services/api/marketing/marketing';
|
import { MarketingApi } from '@/services/api/marketing/marketing';
|
||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
@@ -10,7 +10,7 @@ const EditSalesOrder = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
const soId = searchParams.get('salesOrderId');
|
const soId = searchParams.get('marketingId');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: marketing,
|
data: marketing,
|
||||||
@@ -38,7 +38,7 @@ const EditSalesOrder = () => {
|
|||||||
<div className='w-full p-4'>
|
<div className='w-full p-4'>
|
||||||
{isLoading && <span className='loading loading-spinner loading-xl' />}
|
{isLoading && <span className='loading loading-spinner loading-xl' />}
|
||||||
{!isLoading && isResponseSuccess(marketing) && (
|
{!isLoading && isResponseSuccess(marketing) && (
|
||||||
<SalesForm
|
<MarketingForm
|
||||||
formType='edit'
|
formType='edit'
|
||||||
initialValues={marketing.data}
|
initialValues={marketing.data}
|
||||||
afterSubmit={() => {
|
afterSubmit={() => {
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import MarketingTable from '@/components/pages/marketing/MarketingTable';
|
||||||
|
|
||||||
|
const Marketing = () => {
|
||||||
|
return (
|
||||||
|
<div className='w-full p-4'>
|
||||||
|
<MarketingTable />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Marketing;
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import SalesOrderTable from '@/components/pages/marketing/MarketingTable';
|
|
||||||
|
|
||||||
const SalesOrder = () => {
|
|
||||||
return (
|
|
||||||
<div className='w-full p-4'>
|
|
||||||
<SalesOrderTable />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export default SalesOrder;
|
|
||||||
@@ -22,6 +22,7 @@ import { useTableFilter } from '@/services/hooks/useTableFilter';
|
|||||||
import { BaseSalesOrder, Marketing } from '@/types/api/marketing/marketing';
|
import { BaseSalesOrder, Marketing } from '@/types/api/marketing/marketing';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { CellContext, Row } from '@tanstack/react-table';
|
import { CellContext, Row } from '@tanstack/react-table';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
@@ -30,10 +31,12 @@ const RowsOptionsMenu = ({
|
|||||||
type = 'dropdown',
|
type = 'dropdown',
|
||||||
props,
|
props,
|
||||||
deleteClickHandler,
|
deleteClickHandler,
|
||||||
|
deliveryClickHandler,
|
||||||
}: {
|
}: {
|
||||||
type: 'dropdown' | 'collapse';
|
type: 'dropdown' | 'collapse';
|
||||||
props: CellContext<Marketing, unknown>;
|
props: CellContext<Marketing, unknown>;
|
||||||
deleteClickHandler: () => void;
|
deleteClickHandler: () => void;
|
||||||
|
deliveryClickHandler?: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -48,7 +51,7 @@ const RowsOptionsMenu = ({
|
|||||||
>
|
>
|
||||||
<div className='flex flex-col gap-1'>
|
<div className='flex flex-col gap-1'>
|
||||||
<Button
|
<Button
|
||||||
href={`/marketing/sales-orders/detail/?salesOrderId=${props.row.original.id}`}
|
href={`/marketing/detail?marketingId=${props.row.original.id}`}
|
||||||
variant='ghost'
|
variant='ghost'
|
||||||
color='primary'
|
color='primary'
|
||||||
className='justify-start text-sm'
|
className='justify-start text-sm'
|
||||||
@@ -58,7 +61,18 @@ const RowsOptionsMenu = ({
|
|||||||
</Button>
|
</Button>
|
||||||
{props.row.original.latest_approval.step_number != 1 && (
|
{props.row.original.latest_approval.step_number != 1 && (
|
||||||
<Button
|
<Button
|
||||||
href={`/marketing/sales-orders/detail/edit/delivery?salesOrderId=${props.row.original.id}`}
|
href={
|
||||||
|
props.row.original.latest_approval.step_number == 3
|
||||||
|
? `/marketing/detail/delivery-orders/edit?marketingId=${props.row.original.id}`
|
||||||
|
: props.row.original.latest_approval.step_number == 2
|
||||||
|
? `/marketing/add/delivery-orders?marketingId=${props.row.original.id}`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
if (props.row.original.latest_approval.step_number == 2) {
|
||||||
|
deliveryClickHandler?.();
|
||||||
|
}
|
||||||
|
}}
|
||||||
variant='ghost'
|
variant='ghost'
|
||||||
color='success'
|
color='success'
|
||||||
className='justify-start text-sm'
|
className='justify-start text-sm'
|
||||||
@@ -69,7 +83,7 @@ const RowsOptionsMenu = ({
|
|||||||
)}
|
)}
|
||||||
{props.row.original.latest_approval.step_number != 3 && (
|
{props.row.original.latest_approval.step_number != 3 && (
|
||||||
<Button
|
<Button
|
||||||
href={`/marketing/sales-orders/detail/edit?salesOrderId=${props.row.original.id}`}
|
href={`/marketing/detail/sales-orders/edit?marketingId=${props.row.original.id}`}
|
||||||
variant='ghost'
|
variant='ghost'
|
||||||
color='warning'
|
color='warning'
|
||||||
className='justify-start text-sm'
|
className='justify-start text-sm'
|
||||||
@@ -92,7 +106,7 @@ const RowsOptionsMenu = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const SalesOrderTable = () => {
|
const MarketingTable = () => {
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [pageSize, setPageSize] = useState(10);
|
const [pageSize, setPageSize] = useState(10);
|
||||||
@@ -103,6 +117,8 @@ const SalesOrderTable = () => {
|
|||||||
const [selectedItem, setSelectedItem] = useState<Marketing | null>(null);
|
const [selectedItem, setSelectedItem] = useState<Marketing | null>(null);
|
||||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: marketing,
|
data: marketing,
|
||||||
isLoading: isLoadingMarketing,
|
isLoading: isLoadingMarketing,
|
||||||
@@ -112,6 +128,7 @@ const SalesOrderTable = () => {
|
|||||||
const deleteModal = useModal();
|
const deleteModal = useModal();
|
||||||
const confirmationModal = useModal();
|
const confirmationModal = useModal();
|
||||||
const productsModal = useModal();
|
const productsModal = useModal();
|
||||||
|
const deliveryModal = useModal();
|
||||||
|
|
||||||
const searchChangeHandler = useCallback(
|
const searchChangeHandler = useCallback(
|
||||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
@@ -221,6 +238,16 @@ const SalesOrderTable = () => {
|
|||||||
refreshMarketing();
|
refreshMarketing();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const confirmationModalDeliveryClickHandler = async (notes: string) => {
|
||||||
|
const res = await SalesOrderApi.delivery(selectedItem?.id as number, notes);
|
||||||
|
deliveryModal.closeModal();
|
||||||
|
toast.success(res?.message as string);
|
||||||
|
refreshMarketing?.();
|
||||||
|
router.push(
|
||||||
|
`/marketing/detail/delivery-orders/edit?marketingId=${selectedItem?.id}`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
state: tableFilterState,
|
state: tableFilterState,
|
||||||
updateFilter,
|
updateFilter,
|
||||||
@@ -246,7 +273,7 @@ const SalesOrderTable = () => {
|
|||||||
<div className='flex flex-col gap-2 mb-4'>
|
<div className='flex flex-col gap-2 mb-4'>
|
||||||
<TableToolbar
|
<TableToolbar
|
||||||
addButton={{
|
addButton={{
|
||||||
href: '/marketing/sales-orders/add',
|
href: '/marketing/add/sales-orders',
|
||||||
label: 'Tambah Sales Order',
|
label: 'Tambah Sales Order',
|
||||||
}}
|
}}
|
||||||
search={{
|
search={{
|
||||||
@@ -411,6 +438,11 @@ const SalesOrderTable = () => {
|
|||||||
deleteModal.openModal();
|
deleteModal.openModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const deliveryClickHandler = () => {
|
||||||
|
setSelectedItem(props.row.original);
|
||||||
|
deliveryModal.openModal();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{currentPageSize > 2 && (
|
{currentPageSize > 2 && (
|
||||||
@@ -419,6 +451,7 @@ const SalesOrderTable = () => {
|
|||||||
type='dropdown'
|
type='dropdown'
|
||||||
props={props}
|
props={props}
|
||||||
deleteClickHandler={deleteClickHandler}
|
deleteClickHandler={deleteClickHandler}
|
||||||
|
deliveryClickHandler={deliveryClickHandler}
|
||||||
/>
|
/>
|
||||||
</RowDropdownOptions>
|
</RowDropdownOptions>
|
||||||
)}
|
)}
|
||||||
@@ -429,6 +462,7 @@ const SalesOrderTable = () => {
|
|||||||
type='collapse'
|
type='collapse'
|
||||||
props={props}
|
props={props}
|
||||||
deleteClickHandler={deleteClickHandler}
|
deleteClickHandler={deleteClickHandler}
|
||||||
|
deliveryClickHandler={deliveryClickHandler}
|
||||||
/>
|
/>
|
||||||
</RowCollapseOptions>
|
</RowCollapseOptions>
|
||||||
)}
|
)}
|
||||||
@@ -493,6 +527,19 @@ const SalesOrderTable = () => {
|
|||||||
onClick: deleteMarketingHandler,
|
onClick: deleteMarketingHandler,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<ConfirmationModalWithNotes
|
||||||
|
ref={deliveryModal.ref}
|
||||||
|
type={'success'}
|
||||||
|
text={`Apakah anda yakin ingin deliver penjualan ${selectedItem?.so_number}?`}
|
||||||
|
secondaryButton={{
|
||||||
|
text: 'Tidak',
|
||||||
|
}}
|
||||||
|
primaryButton={{
|
||||||
|
text: 'Ya',
|
||||||
|
color: 'success',
|
||||||
|
onClick: confirmationModalDeliveryClickHandler,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
ref={productsModal.ref}
|
ref={productsModal.ref}
|
||||||
@@ -554,4 +601,4 @@ const SalesOrderTable = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default SalesOrderTable;
|
export default MarketingTable;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import {
|
|||||||
} from '@/services/api/marketing/marketing';
|
} from '@/services/api/marketing/marketing';
|
||||||
import {
|
import {
|
||||||
BaseDelivery,
|
BaseDelivery,
|
||||||
BaseDeliveryOrder,
|
|
||||||
BaseSalesOrder,
|
BaseSalesOrder,
|
||||||
Marketing,
|
Marketing,
|
||||||
} from '@/types/api/marketing/marketing';
|
} from '@/types/api/marketing/marketing';
|
||||||
@@ -32,8 +31,9 @@ import { Icon } from '@iconify/react';
|
|||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
|
import SalesOrderExport from '@/components/pages/marketing/pdf/SalesOrderExport';
|
||||||
|
|
||||||
const SalesOrderDetail = ({
|
const MarketingDetail = ({
|
||||||
initialValues,
|
initialValues,
|
||||||
refresh,
|
refresh,
|
||||||
}: {
|
}: {
|
||||||
@@ -118,17 +118,14 @@ const SalesOrderDetail = ({
|
|||||||
refresh?.();
|
refresh?.();
|
||||||
refreshApproval?.();
|
refreshApproval?.();
|
||||||
router.push(
|
router.push(
|
||||||
`/marketing/sales-orders/detail/edit/delivery?salesOrderId=${initialValues?.id}`
|
`/marketing/detail/delivery-orders/edit?marketingId=${initialValues?.id}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='flex flex-col w-full gap-4'>
|
<div className='flex flex-col w-full gap-4'>
|
||||||
<FormHeader
|
<FormHeader title='Detail Sales Order' backUrl='/marketing' />
|
||||||
title='Detail Sales Order'
|
|
||||||
backUrl='/marketing/sales-orders'
|
|
||||||
/>
|
|
||||||
{!isLoadingApproval && approvals && (
|
{!isLoadingApproval && approvals && (
|
||||||
<ApprovalSteps approvals={approvals} />
|
<ApprovalSteps approvals={approvals} />
|
||||||
)}
|
)}
|
||||||
@@ -156,8 +153,7 @@ const SalesOrderDetail = ({
|
|||||||
{initialValues?.latest_approval?.step_number == 2 && (
|
{initialValues?.latest_approval?.step_number == 2 && (
|
||||||
<Button
|
<Button
|
||||||
color='success'
|
color='success'
|
||||||
// href={`/marketing/sales-orders/detail/edit/delivery?salesOrderId=${initialValues?.id}`}
|
href={`/marketing/add/delivery-orders?marketingId=${initialValues?.id}`}
|
||||||
onClick={deliveryClickHandler}
|
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:truck' width={24} height={24} />
|
<Icon icon='mdi:truck' width={24} height={24} />
|
||||||
Delivery Order
|
Delivery Order
|
||||||
@@ -210,10 +206,7 @@ const SalesOrderDetail = ({
|
|||||||
<td className='font-semibold'>Dokumen</td>
|
<td className='font-semibold'>Dokumen</td>
|
||||||
<td>:</td>
|
<td>:</td>
|
||||||
<td>
|
<td>
|
||||||
<Button className='py-2 px-3 font-medium text-md'>
|
<SalesOrderExport data={initialValues} />
|
||||||
<Icon icon='mdi:file-pdf' width={16} height={16} />
|
|
||||||
{initialValues?.so_number}
|
|
||||||
</Button>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -407,7 +400,7 @@ const SalesOrderDetail = ({
|
|||||||
<Button
|
<Button
|
||||||
color='warning'
|
color='warning'
|
||||||
type='button'
|
type='button'
|
||||||
href={`/marketing/sales-orders/detail/edit?salesOrderId=${initialValues?.id}`}
|
href={`/marketing/detail/${initialValues?.latest_approval.step_number == 3 ? 'delivery-orders' : 'sales-orders'}/edit?marketingId=${initialValues?.id}`}
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:pencil' width={24} height={24} />
|
<Icon icon='mdi:pencil' width={24} height={24} />
|
||||||
Edit
|
Edit
|
||||||
@@ -464,4 +457,4 @@ const SalesOrderDetail = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SalesOrderDetail;
|
export default MarketingDetail;
|
||||||
|
|||||||
@@ -51,7 +51,22 @@ export const DeliveryOrderSchema: Yup.ObjectSchema<DeliveryOrderSchemaType> =
|
|||||||
delivery_order: Yup.array()
|
delivery_order: Yup.array()
|
||||||
.of(DeliveryOrderProductSchema)
|
.of(DeliveryOrderProductSchema)
|
||||||
.min(1, 'Pengiriman wajib diisi!')
|
.min(1, 'Pengiriman wajib diisi!')
|
||||||
.required(),
|
.required()
|
||||||
|
.test(
|
||||||
|
'at-least-one-delivery-date',
|
||||||
|
'Minimal ada satu tanggal pengiriman yang harus diisi!',
|
||||||
|
(value) => {
|
||||||
|
if (!value || value.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return value.some(
|
||||||
|
(item) =>
|
||||||
|
item.delivery_date !== null &&
|
||||||
|
item.delivery_date !== undefined &&
|
||||||
|
item.delivery_date !== ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const UpdateSalesOrderSchema = SalesOrderSchema;
|
export const UpdateSalesOrderSchema = SalesOrderSchema;
|
||||||
|
|||||||
@@ -14,13 +14,15 @@ import { formatCurrency, formatDate } from '@/lib/helper';
|
|||||||
import {
|
import {
|
||||||
BaseDeliveryOrder,
|
BaseDeliveryOrder,
|
||||||
BaseSalesOrder,
|
BaseSalesOrder,
|
||||||
|
CreateDeliveryOrderPayload,
|
||||||
CreateSalesOrderPayload,
|
CreateSalesOrderPayload,
|
||||||
CreateSalesOrderProductPayload,
|
CreateSalesOrderProductPayload,
|
||||||
Marketing,
|
Marketing,
|
||||||
UpdateDeliveryOrderPayload,
|
UpdateDeliveryOrderPayload,
|
||||||
|
UpdateSalesOrderPayload,
|
||||||
} from '@/types/api/marketing/marketing';
|
} from '@/types/api/marketing/marketing';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { Customer } from '@/types/api/master-data/customer';
|
import { Customer } from '@/types/api/master-data/customer';
|
||||||
import { CustomerApi } from '@/services/api/master-data';
|
import { CustomerApi } from '@/services/api/master-data';
|
||||||
import { useFormik } from 'formik';
|
import { useFormik } from 'formik';
|
||||||
@@ -46,6 +48,11 @@ import DeliveryOrderProductTable from './table-view/DeliveryOrderProductTable';
|
|||||||
import DeliveryOrderProductForm from './repeater/delivery-order/DeliverOrderProduct';
|
import DeliveryOrderProductForm from './repeater/delivery-order/DeliverOrderProduct';
|
||||||
import { DeliveryOrderProductFormValues } from './repeater/delivery-order/DeliverOrderProduct.schema';
|
import { DeliveryOrderProductFormValues } from './repeater/delivery-order/DeliverOrderProduct.schema';
|
||||||
|
|
||||||
|
const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable);
|
||||||
|
const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm);
|
||||||
|
const MemoizedDeliveryOrderProductTable = memo(DeliveryOrderProductTable);
|
||||||
|
const MemoizedDeliveryOrderProductForm = memo(DeliveryOrderProductForm);
|
||||||
|
|
||||||
const MarketingProductToFieldValues = (
|
const MarketingProductToFieldValues = (
|
||||||
product: BaseSalesOrder
|
product: BaseSalesOrder
|
||||||
): SalesOrderProductFormValues => {
|
): SalesOrderProductFormValues => {
|
||||||
@@ -113,12 +120,37 @@ const DeliveryProductToFieldValues = (
|
|||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SalesForm = ({
|
const mergeSOwithDO = (
|
||||||
|
salesOrders: SalesOrderProductFormValues[],
|
||||||
|
deliveryOrders: DeliveryOrderProductFormValues[]
|
||||||
|
): DeliveryOrderProductFormValues[] => {
|
||||||
|
return salesOrders.map((so) => {
|
||||||
|
const delivery = deliveryOrders.find(
|
||||||
|
(d) => d?.marketing_product_id === so.id
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...so, // nilai dasar dari sales order
|
||||||
|
marketing_product_id: so.id,
|
||||||
|
delivery_date: delivery?.delivery_date || undefined,
|
||||||
|
do_number: delivery?.do_number || undefined,
|
||||||
|
vehicle_number: delivery?.vehicle_number || so.vehicle_number,
|
||||||
|
unit_price: delivery?.unit_price ?? so.unit_price,
|
||||||
|
total_weight: delivery?.total_weight ?? so.total_weight,
|
||||||
|
qty: delivery?.qty ?? so.qty,
|
||||||
|
avg_weight: delivery?.avg_weight ?? so.avg_weight,
|
||||||
|
total_price: delivery?.total_price ?? so.total_price,
|
||||||
|
marketing_product: so, // jika ada, override
|
||||||
|
} as DeliveryOrderProductFormValues;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const MarketingForm = ({
|
||||||
formType = 'add',
|
formType = 'add',
|
||||||
initialValues,
|
initialValues,
|
||||||
afterSubmit,
|
afterSubmit,
|
||||||
}: {
|
}: {
|
||||||
formType?: 'add' | 'edit' | 'deliver';
|
formType?: 'add' | 'edit' | 'add_deliver' | 'edit_deliver';
|
||||||
initialValues?: Marketing;
|
initialValues?: Marketing;
|
||||||
afterSubmit?: () => void;
|
afterSubmit?: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
@@ -131,6 +163,17 @@ const SalesForm = ({
|
|||||||
const [selectedDeliveryProduct, setSelectedDeliveryProduct] =
|
const [selectedDeliveryProduct, setSelectedDeliveryProduct] =
|
||||||
useState<DeliveryOrderProductFormValues | null>(null);
|
useState<DeliveryOrderProductFormValues | null>(null);
|
||||||
|
|
||||||
|
const [deliveryOrderValues, setDeliveryOrderValues] = useState<
|
||||||
|
DeliveryOrderProductFormValues[]
|
||||||
|
>(
|
||||||
|
mergeSOwithDO(
|
||||||
|
initialValues?.sales_order?.map(MarketingProductToFieldValues) ?? [],
|
||||||
|
initialValues?.delivery_order?.flatMap((delivery) =>
|
||||||
|
DeliveryProductToFieldValues(initialValues.sales_order, delivery)
|
||||||
|
) ?? []
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Repeater Props
|
// Repeater Props
|
||||||
const addSOModal = useModal();
|
const addSOModal = useModal();
|
||||||
const addDOModal = useModal();
|
const addDOModal = useModal();
|
||||||
@@ -171,10 +214,12 @@ const SalesForm = ({
|
|||||||
initialValues?.sales_order?.map((product) =>
|
initialValues?.sales_order?.map((product) =>
|
||||||
MarketingProductToFieldValues(product)
|
MarketingProductToFieldValues(product)
|
||||||
) ?? [],
|
) ?? [],
|
||||||
delivery_order:
|
delivery_order: mergeSOwithDO(
|
||||||
|
initialValues?.sales_order?.map(MarketingProductToFieldValues) ?? [],
|
||||||
initialValues?.delivery_order?.flatMap((delivery) =>
|
initialValues?.delivery_order?.flatMap((delivery) =>
|
||||||
DeliveryProductToFieldValues(initialValues.sales_order, delivery)
|
DeliveryProductToFieldValues(initialValues.sales_order, delivery)
|
||||||
) ?? [],
|
) ?? []
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}, [initialValues]);
|
}, [initialValues]);
|
||||||
|
|
||||||
@@ -182,11 +227,13 @@ const SalesForm = ({
|
|||||||
enableReinitialize: true,
|
enableReinitialize: true,
|
||||||
initialValues: formikInitialValues,
|
initialValues: formikInitialValues,
|
||||||
validationSchema:
|
validationSchema:
|
||||||
formType === 'deliver' ? DeliveryOrderSchema : SalesOrderSchema,
|
formType == 'add_deliver' || formType == 'edit_deliver'
|
||||||
|
? DeliveryOrderSchema
|
||||||
|
: SalesOrderSchema,
|
||||||
validateOnMount: true,
|
validateOnMount: true,
|
||||||
onSubmit: async (values) => {
|
onSubmit: async (values) => {
|
||||||
const payload =
|
const payload =
|
||||||
formType != 'deliver'
|
formType != 'add_deliver' && formType != 'edit_deliver'
|
||||||
? ({
|
? ({
|
||||||
customer_id: values.customer_id as number,
|
customer_id: values.customer_id as number,
|
||||||
sales_person_id: values.sales_person_id as number,
|
sales_person_id: values.sales_person_id as number,
|
||||||
@@ -207,9 +254,12 @@ const SalesForm = ({
|
|||||||
} as CreateSalesOrderPayload)
|
} as CreateSalesOrderPayload)
|
||||||
: ({
|
: ({
|
||||||
marketing_id: initialValues?.id as number,
|
marketing_id: initialValues?.id as number,
|
||||||
delivery_products: values.delivery_order.map((product) => {
|
delivery_products: values.delivery_order
|
||||||
|
.map((product) => {
|
||||||
|
if (Boolean(product.delivery_date)) {
|
||||||
return {
|
return {
|
||||||
marketing_product_id: product.marketing_product_id as number,
|
marketing_product_id:
|
||||||
|
product.marketing_product_id as number,
|
||||||
unit_price: parseFloat(product.unit_price as string),
|
unit_price: parseFloat(product.unit_price as string),
|
||||||
total_weight: parseFloat(product.total_weight as string),
|
total_weight: parseFloat(product.total_weight as string),
|
||||||
qty: parseFloat(product.qty as string),
|
qty: parseFloat(product.qty as string),
|
||||||
@@ -221,7 +271,9 @@ const SalesForm = ({
|
|||||||
),
|
),
|
||||||
vehicle_number: product.vehicle_number,
|
vehicle_number: product.vehicle_number,
|
||||||
};
|
};
|
||||||
}),
|
}
|
||||||
|
})
|
||||||
|
.filter((item) => Boolean(item)),
|
||||||
} as UpdateDeliveryOrderPayload);
|
} as UpdateDeliveryOrderPayload);
|
||||||
console.log('PAYLOAD');
|
console.log('PAYLOAD');
|
||||||
console.log(payload);
|
console.log(payload);
|
||||||
@@ -230,9 +282,12 @@ const SalesForm = ({
|
|||||||
await createMarketingHandler(payload as CreateSalesOrderPayload);
|
await createMarketingHandler(payload as CreateSalesOrderPayload);
|
||||||
break;
|
break;
|
||||||
case 'edit':
|
case 'edit':
|
||||||
await updateMarketingHandler(payload as CreateSalesOrderPayload);
|
await updateMarketingHandler(payload as UpdateSalesOrderPayload);
|
||||||
break;
|
break;
|
||||||
case 'deliver':
|
case 'add_deliver':
|
||||||
|
await createDeliveryHandler(payload as CreateDeliveryOrderPayload);
|
||||||
|
break;
|
||||||
|
case 'edit_deliver':
|
||||||
await updateDeliveryHandler(payload as UpdateDeliveryOrderPayload);
|
await updateDeliveryHandler(payload as UpdateDeliveryOrderPayload);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -256,15 +311,14 @@ const SalesForm = ({
|
|||||||
const createMarketingRes = await SalesOrderApi.create(values);
|
const createMarketingRes = await SalesOrderApi.create(values);
|
||||||
if (isResponseSuccess(createMarketingRes)) {
|
if (isResponseSuccess(createMarketingRes)) {
|
||||||
toast.success(createMarketingRes?.message as string);
|
toast.success(createMarketingRes?.message as string);
|
||||||
router.push('/marketing/sales-orders');
|
router.push('/marketing');
|
||||||
}
|
}
|
||||||
if (isResponseError(createMarketingRes)) {
|
if (isResponseError(createMarketingRes)) {
|
||||||
toast.error(createMarketingRes?.message as string);
|
toast.error(createMarketingRes?.message as string);
|
||||||
}
|
}
|
||||||
afterSubmit?.();
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
};
|
};
|
||||||
const updateMarketingHandler = async (values: CreateSalesOrderPayload) => {
|
const updateMarketingHandler = async (values: UpdateSalesOrderPayload) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
console.log(values);
|
console.log(values);
|
||||||
const updateMarketingRes = await SalesOrderApi.update(
|
const updateMarketingRes = await SalesOrderApi.update(
|
||||||
@@ -273,29 +327,52 @@ const SalesForm = ({
|
|||||||
);
|
);
|
||||||
if (isResponseSuccess(updateMarketingRes)) {
|
if (isResponseSuccess(updateMarketingRes)) {
|
||||||
toast.success(updateMarketingRes?.message as string);
|
toast.success(updateMarketingRes?.message as string);
|
||||||
router.push(
|
router.push(`/marketing/detail?marketingId=${initialValues?.id}`);
|
||||||
`/marketing/sales-orders/detail?salesOrderId=${initialValues?.id}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (isResponseError(updateMarketingRes)) {
|
if (isResponseError(updateMarketingRes)) {
|
||||||
toast.error(updateMarketingRes?.message as string);
|
toast.error(updateMarketingRes?.message as string);
|
||||||
}
|
}
|
||||||
afterSubmit?.();
|
setIsLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const createDeliveryHandler = async (values: CreateDeliveryOrderPayload) => {
|
||||||
|
setIsLoading(true);
|
||||||
|
console.log(initialValues?.id);
|
||||||
|
const createDeliveryRes = await DeliveryOrderApi.create(values);
|
||||||
|
if (isResponseSuccess(createDeliveryRes)) {
|
||||||
|
console.log(createDeliveryRes);
|
||||||
|
toast.success(createDeliveryRes?.message as string);
|
||||||
|
setDeliveryOrderValues(
|
||||||
|
createDeliveryRes.data?.delivery_order?.flatMap((delivery) =>
|
||||||
|
DeliveryProductToFieldValues(
|
||||||
|
createDeliveryRes.data?.sales_order,
|
||||||
|
delivery
|
||||||
|
)
|
||||||
|
) ?? []
|
||||||
|
);
|
||||||
|
router.push(
|
||||||
|
`/marketing/detail/delivery-orders/edit?marketingId=${initialValues?.id}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isResponseError(createDeliveryRes)) {
|
||||||
|
console.log(createDeliveryRes);
|
||||||
|
toast.error(createDeliveryRes?.message as string);
|
||||||
|
}
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateDeliveryHandler = async (values: UpdateDeliveryOrderPayload) => {
|
const updateDeliveryHandler = async (values: UpdateDeliveryOrderPayload) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
console.log(initialValues?.id);
|
console.log(initialValues?.id);
|
||||||
const updateDeliveryRes =
|
const updateDeliveryRes = await DeliveryOrderApi.update(
|
||||||
initialValues?.delivery_order && initialValues?.delivery_order.length > 0
|
initialValues?.id as number,
|
||||||
? await DeliveryOrderApi.update(initialValues?.id as number, values)
|
values
|
||||||
: await DeliveryOrderApi.update(initialValues?.id as number, values);
|
);
|
||||||
if (isResponseSuccess(updateDeliveryRes)) {
|
if (isResponseSuccess(updateDeliveryRes)) {
|
||||||
console.log(updateDeliveryRes);
|
console.log(updateDeliveryRes);
|
||||||
toast.success(updateDeliveryRes?.message as string);
|
toast.success(updateDeliveryRes?.message as string);
|
||||||
formik.setFieldValue(
|
// router.push(`/marketing/detail?marketingId=${initialValues?.id}`);
|
||||||
'delivery_order',
|
setDeliveryOrderValues(
|
||||||
updateDeliveryRes.data?.delivery_order?.flatMap((delivery) =>
|
updateDeliveryRes.data?.delivery_order?.flatMap((delivery) =>
|
||||||
DeliveryProductToFieldValues(
|
DeliveryProductToFieldValues(
|
||||||
updateDeliveryRes.data?.sales_order,
|
updateDeliveryRes.data?.sales_order,
|
||||||
@@ -308,7 +385,6 @@ const SalesForm = ({
|
|||||||
console.log(updateDeliveryRes);
|
console.log(updateDeliveryRes);
|
||||||
toast.error(updateDeliveryRes?.message as string);
|
toast.error(updateDeliveryRes?.message as string);
|
||||||
}
|
}
|
||||||
afterSubmit?.();
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -360,9 +436,9 @@ const SalesForm = ({
|
|||||||
);
|
);
|
||||||
setRowSOSelection({});
|
setRowSOSelection({});
|
||||||
}, [formik, selectedRowSOIds]);
|
}, [formik, selectedRowSOIds]);
|
||||||
const handleDelete = () => {
|
const handleDelete = useCallback(() => {
|
||||||
deleteModal.openModal();
|
deleteModal.openModal();
|
||||||
};
|
}, [deleteModal]);
|
||||||
const handleAddSOClick = useCallback(() => {
|
const handleAddSOClick = useCallback(() => {
|
||||||
setSelectedMarketingProduct(null);
|
setSelectedMarketingProduct(null);
|
||||||
addSOModal.openModal();
|
addSOModal.openModal();
|
||||||
@@ -385,10 +461,7 @@ const SalesForm = ({
|
|||||||
const handleDeleteDO = useCallback(
|
const handleDeleteDO = useCallback(
|
||||||
(id: number) => {
|
(id: number) => {
|
||||||
const currentProducts = formik.values.delivery_order;
|
const currentProducts = formik.values.delivery_order;
|
||||||
formik.setFieldValue(
|
setDeliveryOrderValues((prev) => prev.filter((p) => p.id !== id));
|
||||||
'delivery_order',
|
|
||||||
currentProducts.filter((p) => p.id != id)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
[formik]
|
[formik]
|
||||||
);
|
);
|
||||||
@@ -403,46 +476,50 @@ const SalesForm = ({
|
|||||||
[formik]
|
[formik]
|
||||||
);
|
);
|
||||||
const handleBulkDeleteDO = useCallback(() => {
|
const handleBulkDeleteDO = useCallback(() => {
|
||||||
const currentProducts = formik.values.delivery_order;
|
setDeliveryOrderValues((prev) =>
|
||||||
formik.setFieldValue(
|
prev.filter((product) => !selectedRowDOIds.includes(product.id ?? -1))
|
||||||
'delivery_order',
|
|
||||||
currentProducts.filter(
|
|
||||||
(product) => !selectedRowDOIds.includes(product.id ?? -1)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
setRowDOSelection({});
|
setRowDOSelection({});
|
||||||
}, [formik, selectedRowDOIds]);
|
}, [formik, selectedRowDOIds]);
|
||||||
|
|
||||||
const handleAddDOClick = useCallback(() => {
|
const handleAddDOClick = useCallback(() => {
|
||||||
setSelectedDeliveryProduct(null);
|
setSelectedDeliveryProduct(null);
|
||||||
addDOModal.openModal();
|
addDOModal.openModal();
|
||||||
}, [addDOModal]);
|
}, [addDOModal]);
|
||||||
|
|
||||||
const handleAddSubmitDO = useCallback(
|
const handleAddSubmitDO = useCallback(
|
||||||
async (values: DeliveryOrderProductFormValues) => {
|
async (values: DeliveryOrderProductFormValues) => {
|
||||||
const currentProducts = formik.values.delivery_order;
|
|
||||||
const newValues = {
|
const newValues = {
|
||||||
...values,
|
...values,
|
||||||
id: values.id ?? Date.now(),
|
id: values.id ?? Date.now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
formik.setFieldValue('delivery_order', [...currentProducts, newValues]);
|
setDeliveryOrderValues((prev) => [...prev, newValues]);
|
||||||
|
|
||||||
addDOModal.closeModal();
|
addDOModal.closeModal();
|
||||||
},
|
},
|
||||||
[formik, addDOModal]
|
[formik, addDOModal]
|
||||||
);
|
);
|
||||||
|
const handleInputDate = useCallback(
|
||||||
|
(newData: DeliveryOrderProductFormValues) => {
|
||||||
|
setDeliveryOrderValues((prev) => {
|
||||||
|
return prev.map((item) => {
|
||||||
|
if (item.marketing_product_id == newData.marketing_product_id) {
|
||||||
|
return newData;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
const handleUpdateDO = useCallback(
|
const handleUpdateDO = useCallback(
|
||||||
async (id: number, values: DeliveryOrderProductFormValues) => {
|
async (id: number, values: DeliveryOrderProductFormValues) => {
|
||||||
formik.setFieldValue(
|
setDeliveryOrderValues((prev) =>
|
||||||
'delivery_order',
|
prev.map((product) =>
|
||||||
formik.values.delivery_order.map((product) => {
|
product.id === id ? { ...product, ...values } : product
|
||||||
if (product.id === id) {
|
)
|
||||||
return {
|
|
||||||
...product,
|
|
||||||
...values,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return product;
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
setSelectedDeliveryProduct(null);
|
setSelectedDeliveryProduct(null);
|
||||||
addDOModal.closeModal();
|
addDOModal.closeModal();
|
||||||
@@ -453,7 +530,9 @@ const SalesForm = ({
|
|||||||
|
|
||||||
const memoSalesOrder = formik.values.sales_order;
|
const memoSalesOrder = formik.values.sales_order;
|
||||||
|
|
||||||
const memoDeliveryOrder = formik.values.delivery_order;
|
useEffect(() => {
|
||||||
|
formik.setFieldValue('delivery_order', deliveryOrderValues);
|
||||||
|
}, [deliveryOrderValues, initialValues]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -463,8 +542,8 @@ const SalesForm = ({
|
|||||||
onReset={formik.handleReset}
|
onReset={formik.handleReset}
|
||||||
>
|
>
|
||||||
<FormHeader
|
<FormHeader
|
||||||
title={`${formType === 'add' ? 'Tambah' : 'Edit'} Sales Order`}
|
title={`${formType == 'add' || formType == 'add_deliver' ? 'Tambah' : 'Edit'} ${formType === 'add_deliver' || formType === 'edit_deliver' ? 'Delivery' : 'Sales'} Order`}
|
||||||
backUrl='/marketing/sales-orders'
|
backUrl='/marketing'
|
||||||
/>
|
/>
|
||||||
<Card
|
<Card
|
||||||
title='Informasi Order'
|
title='Informasi Order'
|
||||||
@@ -485,7 +564,9 @@ const SalesForm = ({
|
|||||||
errorMessage={formik.errors.customer_id}
|
errorMessage={formik.errors.customer_id}
|
||||||
isClearable
|
isClearable
|
||||||
placeholder='Pilih Pelanggan'
|
placeholder='Pilih Pelanggan'
|
||||||
isDisabled={formType === 'deliver'}
|
isDisabled={
|
||||||
|
formType === 'add_deliver' || formType === 'edit_deliver'
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<DateInput
|
<DateInput
|
||||||
name='so_date'
|
name='so_date'
|
||||||
@@ -495,10 +576,11 @@ const SalesForm = ({
|
|||||||
isError={formik.touched.so_date && Boolean(formik.errors.so_date)}
|
isError={formik.touched.so_date && Boolean(formik.errors.so_date)}
|
||||||
errorMessage={formik.errors.so_date}
|
errorMessage={formik.errors.so_date}
|
||||||
placeholder='Pilih Tanggal'
|
placeholder='Pilih Tanggal'
|
||||||
readOnly={formType == 'deliver'}
|
readOnly={formType == 'add_deliver' || formType == 'edit_deliver'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
{(formType == 'add' || formType == 'edit') && (
|
||||||
<Card
|
<Card
|
||||||
title='Informasi Produk'
|
title='Informasi Produk'
|
||||||
className={{
|
className={{
|
||||||
@@ -508,7 +590,7 @@ const SalesForm = ({
|
|||||||
{/* <div className='text-blue-500'>{JSON.stringify(initialValues)}</div>
|
{/* <div className='text-blue-500'>{JSON.stringify(initialValues)}</div>
|
||||||
<div className='text-green-500'>{JSON.stringify(formik.values)}</div>
|
<div className='text-green-500'>{JSON.stringify(formik.values)}</div>
|
||||||
<div className='text-red-500'>{JSON.stringify(formik.errors)}</div> */}
|
<div className='text-red-500'>{JSON.stringify(formik.errors)}</div> */}
|
||||||
<SalesOrderProductTable
|
<MemoizedSalesOrderProductTable
|
||||||
formType={formType}
|
formType={formType}
|
||||||
data={memoSalesOrder}
|
data={memoSalesOrder}
|
||||||
rowSelection={rowSOSelection}
|
rowSelection={rowSOSelection}
|
||||||
@@ -519,7 +601,8 @@ const SalesForm = ({
|
|||||||
onAddProductClick={handleAddSOClick}
|
onAddProductClick={handleAddSOClick}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
{formType == 'deliver' &&
|
)}
|
||||||
|
{(formType == 'add_deliver' || formType == 'edit_deliver') &&
|
||||||
initialValues?.sales_order &&
|
initialValues?.sales_order &&
|
||||||
initialValues?.sales_order.length > 0 && (
|
initialValues?.sales_order.length > 0 && (
|
||||||
<Card
|
<Card
|
||||||
@@ -528,11 +611,14 @@ const SalesForm = ({
|
|||||||
wrapper: 'bg-white w-full',
|
wrapper: 'bg-white w-full',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* {JSON.stringify(memoSalesOrder)}
|
{/* {JSON.stringify(memoSalesOrder)} */}
|
||||||
{JSON.stringify(memoDeliveryOrder)} */}
|
{/* <small>{JSON.stringify(memoDeliveryOrder)}</small> */}
|
||||||
<DeliveryOrderProductTable
|
{/* <small className='block text-error'>
|
||||||
|
{JSON.stringify(formik.errors)}
|
||||||
|
</small> */}
|
||||||
|
<MemoizedDeliveryOrderProductTable
|
||||||
formType={formType}
|
formType={formType}
|
||||||
data={memoDeliveryOrder}
|
data={deliveryOrderValues}
|
||||||
salesOrder={memoSalesOrder}
|
salesOrder={memoSalesOrder}
|
||||||
rowSelection={rowDOSelection}
|
rowSelection={rowDOSelection}
|
||||||
setRowSelection={setRowDOSelection}
|
setRowSelection={setRowDOSelection}
|
||||||
@@ -541,6 +627,7 @@ const SalesForm = ({
|
|||||||
onEdit={handleEditDO}
|
onEdit={handleEditDO}
|
||||||
onBulkDelete={handleBulkDeleteDO}
|
onBulkDelete={handleBulkDeleteDO}
|
||||||
onAddProductClick={handleAddDOClick}
|
onAddProductClick={handleAddDOClick}
|
||||||
|
onInputDate={handleInputDate}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
@@ -556,7 +643,7 @@ const SalesForm = ({
|
|||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
isError={formik.touched.notes && Boolean(formik.errors.notes)}
|
isError={formik.touched.notes && Boolean(formik.errors.notes)}
|
||||||
errorMessage={formik.errors.notes}
|
errorMessage={formik.errors.notes}
|
||||||
disabled={formType === 'deliver'}
|
disabled={formType === 'add_deliver' || formType === 'edit_deliver'}
|
||||||
/>
|
/>
|
||||||
<div className='flex flex-col h-full justify-between items-end py-6'>
|
<div className='flex flex-col h-full justify-between items-end py-6'>
|
||||||
<span>Total Penjualan</span>
|
<span>Total Penjualan</span>
|
||||||
@@ -611,7 +698,7 @@ const SalesForm = ({
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<SalesOrderProductForm
|
<MemoizedSalesOrderProductForm
|
||||||
onSubmitForm={handleAddSubmitSO}
|
onSubmitForm={handleAddSubmitSO}
|
||||||
initialValues={selectedMarketingProduct ?? undefined}
|
initialValues={selectedMarketingProduct ?? undefined}
|
||||||
/>
|
/>
|
||||||
@@ -640,7 +727,7 @@ const SalesForm = ({
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<DeliveryOrderProductForm
|
<MemoizedDeliveryOrderProductForm
|
||||||
salesOrders={initialValues?.sales_order ?? []}
|
salesOrders={initialValues?.sales_order ?? []}
|
||||||
onSubmitForm={handleAddSubmitDO}
|
onSubmitForm={handleAddSubmitDO}
|
||||||
initialValues={selectedDeliveryProduct ?? undefined}
|
initialValues={selectedDeliveryProduct ?? undefined}
|
||||||
@@ -667,4 +754,4 @@ const SalesForm = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SalesForm;
|
export default MarketingForm;
|
||||||
|
|||||||
+6
-3
@@ -15,7 +15,7 @@ type DeliveryOrderProductSchemaType = {
|
|||||||
avg_weight: string | number | undefined;
|
avg_weight: string | number | undefined;
|
||||||
total_price: string | number | undefined;
|
total_price: string | number | undefined;
|
||||||
vehicle_number: string | undefined;
|
vehicle_number: string | undefined;
|
||||||
delivery_date: string | undefined;
|
delivery_date: string | undefined | null;
|
||||||
do_number?: string | undefined | null; // Uncertain
|
do_number?: string | undefined | null; // Uncertain
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ export const DeliveryOrderProductSchema: Yup.ObjectSchema<DeliveryOrderProductSc
|
|||||||
.min(1, 'Harga Satuan wajib diisi!')
|
.min(1, 'Harga Satuan wajib diisi!')
|
||||||
.required('Harga Satuan wajib diisi!'),
|
.required('Harga Satuan wajib diisi!'),
|
||||||
total_weight: Yup.number()
|
total_weight: Yup.number()
|
||||||
.min(1, 'Total Bobot wajib diisi!')
|
.min(0, 'Total Bobot wajib diisi!')
|
||||||
.required('Total Bobot wajib diisi!'),
|
.required('Total Bobot wajib diisi!'),
|
||||||
qty: Yup.number()
|
qty: Yup.number()
|
||||||
.min(1, 'Kuantitas wajib diisi!')
|
.min(1, 'Kuantitas wajib diisi!')
|
||||||
@@ -42,7 +42,10 @@ export const DeliveryOrderProductSchema: Yup.ObjectSchema<DeliveryOrderProductSc
|
|||||||
.min(1, 'Total Penjualan wajib diisi!')
|
.min(1, 'Total Penjualan wajib diisi!')
|
||||||
.required('Total Penjualan wajib diisi!'),
|
.required('Total Penjualan wajib diisi!'),
|
||||||
vehicle_number: Yup.string().required('Nomor Kendaraan wajib diisi!'),
|
vehicle_number: Yup.string().required('Nomor Kendaraan wajib diisi!'),
|
||||||
delivery_date: Yup.string().required('Tanggal Pengiriman wajib diisi!'),
|
delivery_date: Yup.string()
|
||||||
|
.required('Tanggal Pengiriman wajib diisi!')
|
||||||
|
.nullable()
|
||||||
|
.optional(),
|
||||||
do_number: Yup.string().nullable().optional(),
|
do_number: Yup.string().nullable().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+43
-34
@@ -49,8 +49,8 @@ const DeliveryOrderProductForm = ({
|
|||||||
marketing_product: initialValues?.marketing_product || undefined,
|
marketing_product: initialValues?.marketing_product || undefined,
|
||||||
},
|
},
|
||||||
validationSchema: DeliveryOrderProductSchema,
|
validationSchema: DeliveryOrderProductSchema,
|
||||||
validateOnBlur: false,
|
validateOnBlur: true,
|
||||||
validateOnChange: true,
|
validateOnChange: false,
|
||||||
onSubmit: async (values) => {
|
onSubmit: async (values) => {
|
||||||
setFormErrorMessage('');
|
setFormErrorMessage('');
|
||||||
if (initialValues?.id) {
|
if (initialValues?.id) {
|
||||||
@@ -172,42 +172,21 @@ const DeliveryOrderProductForm = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className='grid grid-cols-2 gap-4'>
|
<div className='grid grid-cols-2 gap-4'>
|
||||||
<DateInput
|
|
||||||
name='delivery_date'
|
|
||||||
label='Tanggal'
|
|
||||||
value={formik.values.delivery_date}
|
|
||||||
onChange={formik.handleChange}
|
|
||||||
onBlur={formik.handleBlur}
|
|
||||||
isError={
|
|
||||||
formik.touched.delivery_date &&
|
|
||||||
Boolean(formik.errors.delivery_date)
|
|
||||||
}
|
|
||||||
errorMessage={formik.errors.delivery_date}
|
|
||||||
placeholder='Pilih Tanggal'
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
|
|
||||||
<PatternInput
|
|
||||||
name='vehicle_number'
|
|
||||||
label='No. Polisi'
|
|
||||||
format='AA #### AAA'
|
|
||||||
mask='_'
|
|
||||||
inputVehicleNumber
|
|
||||||
required
|
|
||||||
type='text'
|
|
||||||
placeholder='B 1234 CDE'
|
|
||||||
value={formatVechicleNumber(formik.values.vehicle_number ?? '')}
|
|
||||||
onChange={formik.handleChange}
|
|
||||||
onBlur={formik.handleBlur}
|
|
||||||
isError={Boolean(formik.errors.vehicle_number)}
|
|
||||||
errorMessage={formik.errors.vehicle_number}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<SelectInput
|
<SelectInput
|
||||||
options={options}
|
options={options}
|
||||||
label='Produk'
|
label='Produk'
|
||||||
placeholder='Pilih Produk'
|
placeholder='Pilih Produk'
|
||||||
value={selectedProduct}
|
isDisabled
|
||||||
|
value={
|
||||||
|
selectedProduct
|
||||||
|
? ({
|
||||||
|
value: selectedProduct?.value,
|
||||||
|
label: salesOrders.find(
|
||||||
|
(item) => item.id === selectedProduct?.value
|
||||||
|
)?.product_warehouse.product.name,
|
||||||
|
} as OptionType)
|
||||||
|
: null
|
||||||
|
}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
const selected = value as OptionType;
|
const selected = value as OptionType;
|
||||||
setSelectedProduct(selected);
|
setSelectedProduct(selected);
|
||||||
@@ -263,6 +242,36 @@ const DeliveryOrderProductForm = ({
|
|||||||
errorMessage={formik.errors.marketing_product_id}
|
errorMessage={formik.errors.marketing_product_id}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<DateInput
|
||||||
|
name='delivery_date'
|
||||||
|
label='Tanggal'
|
||||||
|
value={formik.values.delivery_date ?? undefined}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
isError={
|
||||||
|
formik.touched.delivery_date &&
|
||||||
|
Boolean(formik.errors.delivery_date)
|
||||||
|
}
|
||||||
|
errorMessage={formik.errors.delivery_date}
|
||||||
|
placeholder='Pilih Tanggal'
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PatternInput
|
||||||
|
name='vehicle_number'
|
||||||
|
label='No. Polisi'
|
||||||
|
format='AA #### AAA'
|
||||||
|
mask='_'
|
||||||
|
inputVehicleNumber
|
||||||
|
required
|
||||||
|
type='text'
|
||||||
|
placeholder='B 1234 CDE'
|
||||||
|
value={formatVechicleNumber(formik.values.vehicle_number ?? '')}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
isError={Boolean(formik.errors.vehicle_number)}
|
||||||
|
errorMessage={formik.errors.vehicle_number}
|
||||||
|
/>
|
||||||
|
|
||||||
<NumberInput
|
<NumberInput
|
||||||
required
|
required
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ export const SalesOrderProductSchema: Yup.ObjectSchema<SalesOrderProductSchemaTy
|
|||||||
.min(1, 'Harga Satuan wajib diisi!')
|
.min(1, 'Harga Satuan wajib diisi!')
|
||||||
.required('Harga Satuan wajib diisi!'),
|
.required('Harga Satuan wajib diisi!'),
|
||||||
total_weight: Yup.number()
|
total_weight: Yup.number()
|
||||||
.min(1, 'Total Bobot wajib diisi!')
|
.min(0, 'Total Bobot wajib diisi!')
|
||||||
.required('Total Bobot wajib diisi!'),
|
.required('Total Bobot wajib diisi!'),
|
||||||
qty: Yup.number()
|
qty: Yup.number()
|
||||||
.min(1, 'Kuantitas wajib diisi!')
|
.min(1, 'Kuantitas wajib diisi!')
|
||||||
|
|||||||
@@ -161,6 +161,9 @@ const SalesOrderProductForm = ({
|
|||||||
</Alert>
|
</Alert>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{/* <small className='block text-rose-500'>
|
||||||
|
{JSON.stringify(formik.errors)}
|
||||||
|
</small> */}
|
||||||
<div className='grid grid-cols-2 gap-4 z-200'>
|
<div className='grid grid-cols-2 gap-4 z-200'>
|
||||||
<PatternInput
|
<PatternInput
|
||||||
name='vehicle_number'
|
name='vehicle_number'
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ import {
|
|||||||
formatVechicleNumber,
|
formatVechicleNumber,
|
||||||
} from '@/lib/helper';
|
} from '@/lib/helper';
|
||||||
import { SalesOrderProductFormValues } from '../repeater/sales-order/SalesOrderProduct.schema';
|
import { SalesOrderProductFormValues } from '../repeater/sales-order/SalesOrderProduct.schema';
|
||||||
|
import DateInput from '@/components/input/DateInput';
|
||||||
|
|
||||||
type DeliveryOrderProductTableProps = {
|
type DeliveryOrderProductTableProps = {
|
||||||
data: DeliveryOrderProductFormValues[];
|
data: DeliveryOrderProductFormValues[];
|
||||||
salesOrder: SalesOrderProductFormValues[];
|
salesOrder: SalesOrderProductFormValues[];
|
||||||
formType?: 'add' | 'edit' | 'deliver';
|
formType?: 'add' | 'edit' | 'add_deliver' | 'edit_deliver';
|
||||||
rowSelection: Record<string, boolean>;
|
rowSelection: Record<string, boolean>;
|
||||||
setRowSelection: React.Dispatch<
|
setRowSelection: React.Dispatch<
|
||||||
React.SetStateAction<Record<string, boolean>>
|
React.SetStateAction<Record<string, boolean>>
|
||||||
@@ -27,6 +28,7 @@ type DeliveryOrderProductTableProps = {
|
|||||||
onEdit: (id: number) => void;
|
onEdit: (id: number) => void;
|
||||||
onBulkDelete: () => void;
|
onBulkDelete: () => void;
|
||||||
onAddProductClick: () => void;
|
onAddProductClick: () => void;
|
||||||
|
onInputDate: (data: DeliveryOrderProductFormValues) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DeliveryOrderProductTable = ({
|
const DeliveryOrderProductTable = ({
|
||||||
@@ -40,6 +42,7 @@ const DeliveryOrderProductTable = ({
|
|||||||
onEdit,
|
onEdit,
|
||||||
onBulkDelete,
|
onBulkDelete,
|
||||||
onAddProductClick,
|
onAddProductClick,
|
||||||
|
onInputDate,
|
||||||
}: DeliveryOrderProductTableProps) => {
|
}: DeliveryOrderProductTableProps) => {
|
||||||
const onDeleteRef = useRef(onDelete);
|
const onDeleteRef = useRef(onDelete);
|
||||||
const onEditRef = useRef(onDelete);
|
const onEditRef = useRef(onDelete);
|
||||||
@@ -53,51 +56,86 @@ const DeliveryOrderProductTable = ({
|
|||||||
return acc && deliveredQty.length != salesOrder.length;
|
return acc && deliveredQty.length != salesOrder.length;
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
const columns = useMemo(
|
const columns = useMemo(() => {
|
||||||
() => [
|
const cols = [
|
||||||
{
|
// {
|
||||||
id: 'select',
|
// id: 'select',
|
||||||
header: ({
|
// header: ({
|
||||||
table,
|
// table,
|
||||||
}: {
|
// }: {
|
||||||
table: TanStack.Table<DeliveryOrderProductFormValues>;
|
// table: TanStack.Table<DeliveryOrderProductFormValues>;
|
||||||
}) => (
|
// }) => (
|
||||||
<div className='w-full flex flex-row justify-center'>
|
// <div className='w-full flex flex-row justify-center'>
|
||||||
<CheckboxInput
|
// <CheckboxInput
|
||||||
name='allRow'
|
// name='allRow'
|
||||||
checked={table.getIsAllRowsSelected()}
|
// checked={table.getIsAllRowsSelected()}
|
||||||
indeterminate={table.getIsSomeRowsSelected()}
|
// indeterminate={table.getIsSomeRowsSelected()}
|
||||||
onChange={table.getToggleAllRowsSelectedHandler()}
|
// onChange={table.getToggleAllRowsSelectedHandler()}
|
||||||
/>
|
// />
|
||||||
</div>
|
// </div>
|
||||||
),
|
// ),
|
||||||
cell: ({
|
// cell: ({
|
||||||
row,
|
// row,
|
||||||
}: {
|
// }: {
|
||||||
row: TanStack.Row<DeliveryOrderProductFormValues>;
|
// row: TanStack.Row<DeliveryOrderProductFormValues>;
|
||||||
}) => (
|
// }) => (
|
||||||
<div>
|
// <div>
|
||||||
<CheckboxInput
|
// <CheckboxInput
|
||||||
name='row'
|
// name='row'
|
||||||
checked={row.getIsSelected()}
|
// checked={row.getIsSelected()}
|
||||||
disabled={!row.getCanSelect()}
|
// disabled={!row.getCanSelect()}
|
||||||
indeterminate={row.getIsSomeSelected()}
|
// indeterminate={row.getIsSomeSelected()}
|
||||||
onChange={row.getToggleSelectedHandler()}
|
// onChange={row.getToggleSelectedHandler()}
|
||||||
/>
|
// />
|
||||||
</div>
|
// </div>
|
||||||
),
|
// ),
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
accessorFn: (row: DeliveryOrderProductFormValues) => row.do_number,
|
accessorFn: (row: DeliveryOrderProductFormValues) => row.do_number,
|
||||||
header: 'No. Pengiriman',
|
header: 'No. Pengiriman',
|
||||||
cell: (
|
cell: (
|
||||||
props: TanStack.CellContext<DeliveryOrderProductFormValues, unknown>
|
props: TanStack.CellContext<DeliveryOrderProductFormValues, unknown>
|
||||||
) => props.row.original.do_number ?? '-',
|
) => <div>{props.row.original.do_number}</div>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorFn: (row: DeliveryOrderProductFormValues) =>
|
accessorFn: (row: DeliveryOrderProductFormValues) =>
|
||||||
formatDate(row.delivery_date as string, 'DD MMM YYYY'),
|
row.delivery_date
|
||||||
|
? formatDate(row.delivery_date as string, 'DD MMM YYYY')
|
||||||
|
: '-',
|
||||||
header: 'Tanggal Delivery',
|
header: 'Tanggal Delivery',
|
||||||
|
cell: (
|
||||||
|
props: TanStack.CellContext<DeliveryOrderProductFormValues, unknown>
|
||||||
|
) => (
|
||||||
|
<>
|
||||||
|
{formType == 'add_deliver' && (
|
||||||
|
<DateInput
|
||||||
|
name={`delivery_date_${props.row.original.marketing_product_id}`}
|
||||||
|
className={{
|
||||||
|
input: 'p-0',
|
||||||
|
inputWrapper: 'py-1 px-3 h-fit w-fit bg-white',
|
||||||
|
wrapper: 'p-0',
|
||||||
|
}}
|
||||||
|
value={
|
||||||
|
props.row.original.delivery_date
|
||||||
|
? formatDate(props.row.original.delivery_date, 'yyyy-MM-DD')
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onChange={(val) => {
|
||||||
|
onInputDate({
|
||||||
|
...props.row.original,
|
||||||
|
delivery_date: val.target.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{formType == 'edit_deliver' &&
|
||||||
|
formatDate(
|
||||||
|
props.row.original.delivery_date as string,
|
||||||
|
'DD MMM YYYY'
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorFn: (row: DeliveryOrderProductFormValues) =>
|
accessorFn: (row: DeliveryOrderProductFormValues) =>
|
||||||
@@ -145,15 +183,18 @@ const DeliveryOrderProductTable = ({
|
|||||||
props: TanStack.CellContext<DeliveryOrderProductFormValues, unknown>
|
props: TanStack.CellContext<DeliveryOrderProductFormValues, unknown>
|
||||||
) => (
|
) => (
|
||||||
<div className='flex flex-row gap-1 items-center justify-end h-full mt-2'>
|
<div className='flex flex-row gap-1 items-center justify-end h-full mt-2'>
|
||||||
|
<>
|
||||||
<Button
|
<Button
|
||||||
color='success'
|
color='warning'
|
||||||
className='p-1'
|
className='px-2 py-1 text-sm'
|
||||||
onClick={() => onEditRef.current(props.row.original.id as number)}
|
onClick={() =>
|
||||||
|
onEditRef.current(props.row.original.id as number)
|
||||||
|
}
|
||||||
type='button'
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:edit' width={16} height={16} />
|
<Icon icon='mdi:edit' width={16} height={16} /> Edit
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
{/* <Button
|
||||||
color='error'
|
color='error'
|
||||||
className='p-1'
|
className='p-1'
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@@ -162,13 +203,19 @@ const DeliveryOrderProductTable = ({
|
|||||||
type='button'
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:trash' width={16} height={16} />
|
<Icon icon='mdi:trash' width={16} height={16} />
|
||||||
</Button>
|
</Button> */}
|
||||||
|
</>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
],
|
];
|
||||||
[]
|
if (formType == 'add_deliver') {
|
||||||
|
return cols.filter(
|
||||||
|
(col) => col.header != 'Aksi' && col.header != 'No. Pengiriman'
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
return cols;
|
||||||
|
}, [formType, onInputDate, onEditRef]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -185,7 +232,7 @@ const DeliveryOrderProductTable = ({
|
|||||||
'px-2 py-2 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end first:flex first:flex-row first:justify-start',
|
'px-2 py-2 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end first:flex first:flex-row first:justify-start',
|
||||||
bodyRowClassName: 'border-b border-b-gray-200',
|
bodyRowClassName: 'border-b border-b-gray-200',
|
||||||
bodyColumnClassName:
|
bodyColumnClassName:
|
||||||
'px-2 py-2 last:flex last:flex-row last:justify-end first:flex first:flex-row first:justify-start',
|
'px-2 py-2 last:flex last:flex-row last:justify-end',
|
||||||
paginationClassName: 'hidden',
|
paginationClassName: 'hidden',
|
||||||
}}
|
}}
|
||||||
emptyContent={
|
emptyContent={
|
||||||
@@ -199,16 +246,16 @@ const DeliveryOrderProductTable = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<div className='flex flex-row gap-3 mt-3'>
|
<div className='flex flex-row gap-3 mt-3'>
|
||||||
<Button
|
{/* <Button
|
||||||
type='button'
|
type='button'
|
||||||
variant='outline'
|
variant='outline'
|
||||||
className='justify-start w-fit py-1 text-sm'
|
className='justify-start w-fit py-1 text-sm'
|
||||||
onClick={onAddProductClick}
|
onClick={onAddProductClick}
|
||||||
disabled={!canAddData}
|
// disabled={!canAddData}
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:plus' width={16} height={16} />
|
<Icon icon='mdi:plus' width={16} height={16} />
|
||||||
Tambah Pengiriman
|
Tambah Pengiriman
|
||||||
</Button>
|
</Button> */}
|
||||||
{selectedRowIds.length > 0 && (
|
{selectedRowIds.length > 0 && (
|
||||||
<Button
|
<Button
|
||||||
type='button'
|
type='button'
|
||||||
|
|||||||
@@ -0,0 +1,227 @@
|
|||||||
|
import Button from '@/components/Button';
|
||||||
|
import { Marketing } from '@/types/api/marketing/marketing';
|
||||||
|
import { Icon } from '@iconify/react';
|
||||||
|
import { Document, Image, Page, pdf, Text, View } from '@react-pdf/renderer';
|
||||||
|
import { useMemo, useState } from 'react';
|
||||||
|
import pdfStyles from './styles/MarketingPDFStyles';
|
||||||
|
import { formatDate, formatNumber } from '@/lib/helper';
|
||||||
|
|
||||||
|
interface SalesOrderExportProps {
|
||||||
|
data?: Marketing;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SalesOrderExport = ({ data }: SalesOrderExportProps) => {
|
||||||
|
const [isGeneratingPDF, setIsGeneratingPDF] = useState(false);
|
||||||
|
const salesData = data;
|
||||||
|
|
||||||
|
const handleDownloadPDF = async () => {
|
||||||
|
if (!salesData) {
|
||||||
|
alert('No sales order data available');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setIsGeneratingPDF(true);
|
||||||
|
try {
|
||||||
|
const blob = await pdf(<PDFDocument data={salesData} />).toBlob();
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = `${salesData?.so_number || 'sales-order'}.pdf`;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error generating PDF:', error);
|
||||||
|
alert('Failed to generate PDF. Please try again.');
|
||||||
|
} finally {
|
||||||
|
setIsGeneratingPDF(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!salesData) {
|
||||||
|
return (
|
||||||
|
<div className='flex items-center justify-center min-h-screen'>
|
||||||
|
<div className='text-gray-500'>No sales order data available</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return salesData?.so_number && salesData.so_number !== 'Belum dibuat' ? (
|
||||||
|
<Button
|
||||||
|
color='primary'
|
||||||
|
className='w-fit min-w-32 flex items-center justify-start gap-1 px-2 py-1 text-sm font-mono'
|
||||||
|
onClick={handleDownloadPDF}
|
||||||
|
isLoading={isGeneratingPDF}
|
||||||
|
>
|
||||||
|
<Icon icon='material-symbols:file-open-outline' width={16} height={16} />
|
||||||
|
{salesData.so_number}
|
||||||
|
</Button>
|
||||||
|
) : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SalesOrderExport;
|
||||||
|
const PDFDocument = ({ data }: { data: Marketing }) => {
|
||||||
|
const grandTotal = useMemo(() => {
|
||||||
|
return data?.sales_order?.reduce((a, b) => a + b.total_price, 0) ?? 0;
|
||||||
|
}, [data?.sales_order]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Document>
|
||||||
|
<Page size='A4' style={pdfStyles.page}>
|
||||||
|
{/* Header Section */}
|
||||||
|
<View style={pdfStyles.header}>
|
||||||
|
<Image
|
||||||
|
src={'https://placehold.co/120x30/png'}
|
||||||
|
style={pdfStyles.logo}
|
||||||
|
id={'mbu-logo'}
|
||||||
|
/>
|
||||||
|
<Text style={pdfStyles.companyInfo}>PT LUMBUNG TELUR INDONESIA</Text>
|
||||||
|
<Text style={pdfStyles.address}>
|
||||||
|
SOHO Building Lt.3 (Paris Van Java), Jalan Karang Tinggal, Kel.
|
||||||
|
Cipedes, Kec. Sukajadi, Kota Bandung 40162
|
||||||
|
</Text>
|
||||||
|
<View style={pdfStyles.divider} />
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Sales Order Title */}
|
||||||
|
<View style={pdfStyles.titleSection}>
|
||||||
|
<Text style={pdfStyles.title}>SALES ORDER</Text>
|
||||||
|
<View style={pdfStyles.poInfo}>
|
||||||
|
<Text>SO Number: {data?.so_number || '-'}</Text>
|
||||||
|
<Text>
|
||||||
|
Date:{' '}
|
||||||
|
{data?.so_date
|
||||||
|
? formatDate(data.so_date, 'DD MMM YYYY')
|
||||||
|
: formatDate(new Date(), 'DD MMM YYYY')}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Customer Table */}
|
||||||
|
<View style={pdfStyles.table}>
|
||||||
|
<View style={[pdfStyles.tableRow, pdfStyles.tableHeader]}>
|
||||||
|
<View style={pdfStyles.tableCellHeader}>
|
||||||
|
<Text>Customer</Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellHeaderLast}>
|
||||||
|
<Text>Sales</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableRow}>
|
||||||
|
<View style={pdfStyles.tableCell}>
|
||||||
|
<Text style={{ fontWeight: 'bold' }}>
|
||||||
|
{data?.customer?.name || '-'} ({data?.customer?.type || '-'})
|
||||||
|
</Text>
|
||||||
|
<Text style={{ marginTop: '2px' }}>
|
||||||
|
{data?.customer.email || ''} - {data?.customer.phone || ''}
|
||||||
|
</Text>
|
||||||
|
<Text></Text>
|
||||||
|
<Text>{data?.customer.address || ''}</Text>
|
||||||
|
<Text style={{ fontSize: '7px', marginTop: '3px' }}></Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellLast}>
|
||||||
|
<Text style={{ fontWeight: 'bold' }}>
|
||||||
|
PT LUMBUNG TELUR INDONESIA
|
||||||
|
</Text>
|
||||||
|
<Text style={{ fontWeight: 'bold', marginTop: '2px' }}>
|
||||||
|
{data?.sales_person?.name || '-'}
|
||||||
|
</Text>
|
||||||
|
<Text>{data?.sales_person.email}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Product Sales Order Table */}
|
||||||
|
<Text style={pdfStyles.sectionTitle}>Product Sold</Text>
|
||||||
|
<View style={pdfStyles.table}>
|
||||||
|
<View style={[pdfStyles.tableRow, pdfStyles.tableHeader]}>
|
||||||
|
<View style={pdfStyles.tableCellHeader}>
|
||||||
|
<Text>Item Description</Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellHeader}>
|
||||||
|
<Text>From</Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellHeader}>
|
||||||
|
<Text>Unit Price</Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellHeader}>
|
||||||
|
<Text>Quantity</Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellHeaderLast}>
|
||||||
|
<Text>Total Amount</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
{data?.sales_order?.map((item, index) => {
|
||||||
|
const isLastItem = index === (data?.sales_order?.length || 0) - 1;
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
key={index}
|
||||||
|
style={[
|
||||||
|
pdfStyles.tableRow,
|
||||||
|
// isLastItem ? {} : pdfStyles.tableBorderBottom,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<View style={pdfStyles.tableCell}>
|
||||||
|
<Text>{item.product_warehouse?.product?.name || '-'}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCell}>
|
||||||
|
<Text>{item.product_warehouse?.warehouse?.name || '-'}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellRight}>
|
||||||
|
<Text>Rp{formatNumber(item.unit_price || 0)}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellRight}>
|
||||||
|
<Text>{formatNumber(item.qty || 0)}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellRightLast}>
|
||||||
|
<Text>Rp{formatNumber(item.total_price || 0)}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}) || []}
|
||||||
|
|
||||||
|
{/* Grand Total Row inside table */}
|
||||||
|
<View style={pdfStyles.grandTotalRow}>
|
||||||
|
<View style={[pdfStyles.tableCell, { borderRightWidth: 0 }]}>
|
||||||
|
<Text></Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCell, { borderRightWidth: 0 }]}>
|
||||||
|
<Text></Text>
|
||||||
|
</View>
|
||||||
|
<View style={[pdfStyles.tableCellRight, { borderRightWidth: 0 }]}>
|
||||||
|
<Text></Text>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableCellRight}>
|
||||||
|
<Text style={{ fontWeight: 'bold' }}>Grand Total</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={[pdfStyles.tableCellRightLast, { fontWeight: 'bold' }]}
|
||||||
|
>
|
||||||
|
<Text>Rp{formatNumber(grandTotal)}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Footer with Special Instructions */}
|
||||||
|
<View style={pdfStyles.footer}>
|
||||||
|
<View style={pdfStyles.specialInstructionTable}>
|
||||||
|
<View style={[pdfStyles.tableRow, pdfStyles.tableHeader]}>
|
||||||
|
<View style={pdfStyles.tableCellHeaderLast}>
|
||||||
|
<Text>Notes</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.tableRow}>
|
||||||
|
<View style={pdfStyles.tableCellLast}>
|
||||||
|
<Text>{data?.notes || '-'}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={pdfStyles.footerCompany}>
|
||||||
|
<Text>PT LUMBUNG TELUR INDONESIA</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Page>
|
||||||
|
</Document>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
import { StyleSheet } from '@react-pdf/renderer';
|
||||||
|
|
||||||
|
const pdfStyles = StyleSheet.create({
|
||||||
|
page: {
|
||||||
|
fontSize: 10,
|
||||||
|
fontFamily: 'Helvetica',
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: '#FFFFFF',
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
logo: {
|
||||||
|
width: 120,
|
||||||
|
height: 30,
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
companyInfo: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: 4,
|
||||||
|
color: '#1f74bf',
|
||||||
|
},
|
||||||
|
address: {
|
||||||
|
fontSize: 8,
|
||||||
|
color: '#666666',
|
||||||
|
maxWidth: 400,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
divider: {
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: '#000000',
|
||||||
|
borderBottomStyle: 'solid',
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
titleSection: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
marginBottom: 20,
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
flex: 3,
|
||||||
|
color: '#1f74bf',
|
||||||
|
},
|
||||||
|
poInfo: {
|
||||||
|
flex: 1,
|
||||||
|
fontSize: 9,
|
||||||
|
textAlign: 'right',
|
||||||
|
},
|
||||||
|
sectionTitle: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: 8,
|
||||||
|
color: '#1f74bf',
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#000000',
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
tableRow: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
},
|
||||||
|
tableHeader: {
|
||||||
|
backgroundColor: '#F5F5F5',
|
||||||
|
},
|
||||||
|
tableCell: {
|
||||||
|
flex: 1,
|
||||||
|
borderRightWidth: 1,
|
||||||
|
borderRightColor: '#000000',
|
||||||
|
borderRightStyle: 'solid',
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
},
|
||||||
|
tableCellLast: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
},
|
||||||
|
tableCellHeader: {
|
||||||
|
flex: 1,
|
||||||
|
borderRightWidth: 1,
|
||||||
|
borderRightColor: '#000000',
|
||||||
|
borderRightStyle: 'solid',
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
backgroundColor: '#F5F5F5',
|
||||||
|
},
|
||||||
|
tableCellHeaderLast: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
backgroundColor: '#F5F5F5',
|
||||||
|
},
|
||||||
|
tableCellRight: {
|
||||||
|
flex: 1,
|
||||||
|
borderRightWidth: 1,
|
||||||
|
borderRightColor: '#000000',
|
||||||
|
borderRightStyle: 'solid',
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
textAlign: 'right',
|
||||||
|
},
|
||||||
|
tableCellRightLast: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
textAlign: 'right',
|
||||||
|
},
|
||||||
|
tableBorderBottom: {
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: '#000000',
|
||||||
|
borderBottomStyle: 'solid',
|
||||||
|
},
|
||||||
|
grandTotalRow: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderTopColor: '#000000',
|
||||||
|
borderTopStyle: 'solid',
|
||||||
|
},
|
||||||
|
grandTotalLabel: {
|
||||||
|
flex: 3,
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
textAlign: 'right',
|
||||||
|
borderRightWidth: 1,
|
||||||
|
borderRightColor: '#000000',
|
||||||
|
borderRightStyle: 'solid',
|
||||||
|
},
|
||||||
|
grandTotalValue: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
textAlign: 'right',
|
||||||
|
borderRightWidth: 0,
|
||||||
|
},
|
||||||
|
allocationSection: {
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
allocationTable: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#000000',
|
||||||
|
},
|
||||||
|
innerTable: {
|
||||||
|
marginTop: 5,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#000000',
|
||||||
|
},
|
||||||
|
innerRow: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: '#000000',
|
||||||
|
borderBottomStyle: 'solid',
|
||||||
|
},
|
||||||
|
innerCell: {
|
||||||
|
flex: 1,
|
||||||
|
borderRightWidth: 1,
|
||||||
|
borderRightColor: '#000000',
|
||||||
|
borderRightStyle: 'solid',
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
},
|
||||||
|
innerCellLast: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
},
|
||||||
|
innerCellRight: {
|
||||||
|
flex: 1,
|
||||||
|
borderRightWidth: 1,
|
||||||
|
borderRightColor: '#000000',
|
||||||
|
borderRightStyle: 'solid',
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
textAlign: 'right',
|
||||||
|
},
|
||||||
|
innerCellRightLast: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 8,
|
||||||
|
fontSize: 9,
|
||||||
|
textAlign: 'right',
|
||||||
|
},
|
||||||
|
footer: {
|
||||||
|
marginTop: 30,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
},
|
||||||
|
footerCompany: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
textAlign: 'right',
|
||||||
|
flex: 1,
|
||||||
|
color: '#1f74bf',
|
||||||
|
},
|
||||||
|
specialInstructionTable: {
|
||||||
|
width: '60%',
|
||||||
|
maxWidth: 300,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#000000',
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default pdfStyles;
|
||||||
@@ -48,7 +48,7 @@ export const MAIN_DRAWER_LINKS: MAIN_DRAWER_MENU[] = [
|
|||||||
|
|
||||||
{
|
{
|
||||||
title: 'Penjualan',
|
title: 'Penjualan',
|
||||||
link: '/marketing/sales-orders',
|
link: '/marketing',
|
||||||
icon: 'mdi:attach-money',
|
icon: 'mdi:attach-money',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user