s22
parent
10a2c0c2c3
commit
5a32c1a7d2
|
@ -14,6 +14,7 @@
|
|||
"@radix-ui/react-select": "^2.1.6",
|
||||
"@radix-ui/react-tabs": "^1.1.3",
|
||||
"@radix-ui/react-toast": "^1.2.6",
|
||||
"@react-pdf/renderer": "^4.3.0",
|
||||
"@shadcn/ui": "^0.0.4",
|
||||
"@types/date-fns": "^2.5.3",
|
||||
"@types/react": "^19.0.12",
|
||||
|
@ -2812,6 +2813,180 @@
|
|||
"integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"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.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-pdf/font/-/font-4.0.2.tgz",
|
||||
"integrity": "sha512-/dAWu7Y2RD1RxarDZ9SkYPHgBYOhmcDnet4W/qN/m8k+A2Hr3ja54GymSR7GGxWBtxjKtNauVKrTa9LS1n8WUw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@react-pdf/pdfkit": "^4.0.3",
|
||||
"@react-pdf/types": "^2.9.0",
|
||||
"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.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-pdf/layout/-/layout-4.4.0.tgz",
|
||||
"integrity": "sha512-Aq+Cc6JYausWLoks2FvHe3PwK9cTuvksB2uJ0AnkKJEUtQbvCq8eCRb1bjbbwIji9OzFRTTzZij7LzkpKHjIeA==",
|
||||
"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.0",
|
||||
"@react-pdf/textkit": "^6.0.0",
|
||||
"@react-pdf/types": "^2.9.0",
|
||||
"emoji-regex": "^10.3.0",
|
||||
"queue": "^6.0.1",
|
||||
"yoga-layout": "^3.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-pdf/pdfkit": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@react-pdf/pdfkit/-/pdfkit-4.0.3.tgz",
|
||||
"integrity": "sha512-k+Lsuq8vTwWsCqTp+CCB4+2N+sOTFrzwGA7aw3H9ix/PDWR9QksbmNg0YkzGbLAPI6CeawmiLHcf4trZ5ecLPQ==",
|
||||
"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.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-pdf/render/-/render-4.3.0.tgz",
|
||||
"integrity": "sha512-MdWfWaqO6d7SZD75TZ2z5L35V+cHpyA43YNRlJNG0RJ7/MeVGDQv12y/BXOJgonZKkeEGdzM3EpAt9/g4E22WA==",
|
||||
"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.0",
|
||||
"abs-svg-path": "^0.1.1",
|
||||
"color-string": "^1.9.1",
|
||||
"normalize-svg-path": "^1.1.0",
|
||||
"parse-svg-path": "^0.1.2",
|
||||
"svg-arc-to-cubic-bezier": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-pdf/renderer": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-pdf/renderer/-/renderer-4.3.0.tgz",
|
||||
"integrity": "sha512-28gpA69fU9ZQrDzmd5xMJa1bDf8t0PT3ApUKBl2PUpoE/x4JlvCB5X66nMXrfFrgF2EZrA72zWQAkvbg7TE8zw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"@react-pdf/fns": "3.1.2",
|
||||
"@react-pdf/font": "^4.0.2",
|
||||
"@react-pdf/layout": "^4.4.0",
|
||||
"@react-pdf/pdfkit": "^4.0.3",
|
||||
"@react-pdf/primitives": "^4.1.1",
|
||||
"@react-pdf/reconciler": "^1.1.4",
|
||||
"@react-pdf/render": "^4.3.0",
|
||||
"@react-pdf/types": "^2.9.0",
|
||||
"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.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-pdf/stylesheet/-/stylesheet-6.1.0.tgz",
|
||||
"integrity": "sha512-BGZ2sYNUp38VJUegjva/jsri3iiRGnVNjWI+G9dTwAvLNOmwFvSJzqaCsEnqQ/DW5mrTBk/577FhDY7pv6AidA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@react-pdf/fns": "3.1.2",
|
||||
"@react-pdf/types": "^2.9.0",
|
||||
"color-string": "^1.9.1",
|
||||
"hsl-to-hex": "^1.0.0",
|
||||
"media-engine": "^1.0.3",
|
||||
"postcss-value-parser": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-pdf/textkit": {
|
||||
"version": "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.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-pdf/types/-/types-2.9.0.tgz",
|
||||
"integrity": "sha512-ckj80vZLlvl9oYrQ4tovEaqKWP3O06Eb1D48/jQWbdwz1Yh7Y9v1cEmwlP8ET+a1Whp8xfdM0xduMexkuPANCQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@react-pdf/font": "^4.0.2",
|
||||
"@react-pdf/primitives": "^4.1.1",
|
||||
"@react-pdf/stylesheet": "^6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
|
||||
|
@ -3175,6 +3350,15 @@
|
|||
"integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
|
||||
"integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
|
@ -3775,6 +3959,12 @@
|
|||
"license": "(Unlicense OR Apache-2.0)",
|
||||
"optional": true
|
||||
},
|
||||
"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": {
|
||||
"version": "8.14.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||
|
@ -4206,6 +4396,15 @@
|
|||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"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/binary-extensions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
|
@ -4299,12 +4498,30 @@
|
|||
"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/browser-or-node": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz",
|
||||
"integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"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/browserslist": {
|
||||
"version": "4.24.4",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
|
||||
|
@ -4682,7 +4899,6 @@
|
|||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
|
||||
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"color-name": "^1.0.0",
|
||||
"simple-swizzle": "^0.2.2"
|
||||
|
@ -4757,6 +4973,12 @@
|
|||
"uncrypto": "^0.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/css-selector-parser": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.1.2.tgz",
|
||||
|
@ -4956,6 +5178,12 @@
|
|||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"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/didyoumean": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||
|
@ -5198,6 +5426,15 @@
|
|||
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"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/execa": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz",
|
||||
|
@ -5227,6 +5464,12 @@
|
|||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||
|
@ -5349,6 +5592,32 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"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/fontkit/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/for-each": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
|
||||
|
@ -6186,6 +6455,21 @@
|
|||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"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/html-escaper": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz",
|
||||
|
@ -6227,6 +6511,12 @@
|
|||
"node": ">=14.18.0"
|
||||
}
|
||||
},
|
||||
"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/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
|
@ -6331,8 +6621,7 @@
|
|||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
|
@ -6587,6 +6876,12 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"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-wsl": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
|
||||
|
@ -6623,6 +6918,15 @@
|
|||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "1.21.7",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
|
||||
|
@ -6707,6 +7011,25 @@
|
|||
"url": "https://github.com/sponsors/antonk52"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||
|
@ -9301,6 +9624,12 @@
|
|||
"integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"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/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
|
@ -11358,6 +11687,15 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-svg-path": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz",
|
||||
"integrity": "sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"svg-arc-to-cubic-bezier": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/not": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz",
|
||||
|
@ -11535,6 +11873,12 @@
|
|||
"integrity": "sha512-Y8f9qUlBzW8qauJjd/eu6jlpJZsuPJm2ZAV0cDVd420o4EdpH5RPdoCv+60/TdJflGatr4sDfpAL6ArWZbM5tA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"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/parse-entities": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
|
||||
|
@ -11584,6 +11928,12 @@
|
|||
"integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"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/parse5": {
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
|
||||
|
@ -11909,6 +12259,15 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
|
@ -13880,6 +14239,15 @@
|
|||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||
|
@ -13940,6 +14308,12 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"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/retext": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz",
|
||||
|
@ -14295,7 +14669,6 @@
|
|||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"is-arrayish": "^0.3.1"
|
||||
}
|
||||
|
@ -14600,6 +14973,12 @@
|
|||
"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/tailwind-merge": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.0.2.tgz",
|
||||
|
@ -14686,6 +15065,12 @@
|
|||
"readable-stream": "3"
|
||||
}
|
||||
},
|
||||
"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/tinyexec": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
|
||||
|
@ -14828,6 +15213,32 @@
|
|||
"integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==",
|
||||
"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/unified": {
|
||||
"version": "11.0.5",
|
||||
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
|
||||
|
@ -15474,6 +15885,20 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"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/vitefu": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.0.6.tgz",
|
||||
|
@ -15777,6 +16202,12 @@
|
|||
"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/zod": {
|
||||
"version": "3.24.2",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"@radix-ui/react-select": "^2.1.6",
|
||||
"@radix-ui/react-tabs": "^1.1.3",
|
||||
"@radix-ui/react-toast": "^1.2.6",
|
||||
"@react-pdf/renderer": "^4.3.0",
|
||||
"@shadcn/ui": "^0.0.4",
|
||||
"@types/date-fns": "^2.5.3",
|
||||
"@types/react": "^19.0.12",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -8,6 +8,7 @@ import { Eye, EyeOff, Loader2 } from "lucide-react";
|
|||
import { Separator } from "./ui/separator";
|
||||
import { Label } from "./ui/label";
|
||||
import { useIsLoggedIn } from '../lib/isLoggedIn';
|
||||
import Loader from "./ui/loader";
|
||||
interface AuthStatus {
|
||||
message: string;
|
||||
isError: boolean;
|
||||
|
@ -17,6 +18,7 @@ interface UserRecord {
|
|||
id: string;
|
||||
email: string;
|
||||
name?: string;
|
||||
type?: string;
|
||||
avatar?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
@ -43,6 +45,7 @@ const LoginPage = () => {
|
|||
id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
type: string;
|
||||
avatar: string;
|
||||
};
|
||||
}
|
||||
|
@ -54,6 +57,10 @@ const LoginPage = () => {
|
|||
|
||||
try {
|
||||
const authData = await pb.collection("users").authWithPassword(email, password);
|
||||
if (!authData?.token || !authData?.record) {
|
||||
throw new Error("Authentication failed: No token or user record received");
|
||||
}
|
||||
|
||||
const avatarUrl = authData.record.avatar ? pb.files.getUrl(authData.record, authData.record.avatar) : '';
|
||||
|
||||
const authResponse: AuthResponse = {
|
||||
|
@ -62,17 +69,18 @@ const LoginPage = () => {
|
|||
query: 'new',
|
||||
id: authData.record.id,
|
||||
email: authData.record.email,
|
||||
name: authData.record.name || '',
|
||||
name: authData.record.name || authData.record.email.split('@')[0], // Fallback name
|
||||
type: authData.record.type || 'user',
|
||||
avatar: authData.record.avatar || ''
|
||||
}
|
||||
};
|
||||
|
||||
await syncSessionWithBackend(authResponse, avatarUrl);
|
||||
window.location.href = '/profile';
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
console.error("Login failed:", error);
|
||||
setStatus({
|
||||
message: "Login failed. Please check your credentials.",
|
||||
message: error.message || "Login failed. Please check your credentials.",
|
||||
isError: true
|
||||
});
|
||||
} finally {
|
||||
|
@ -99,6 +107,7 @@ const LoginPage = () => {
|
|||
id: authData.record.id,
|
||||
email: authData.record.email || '',
|
||||
name: authData.record.name || '',
|
||||
type: authData.record.type || '',
|
||||
avatar: authData.record.avatar || ''
|
||||
}
|
||||
};
|
||||
|
@ -120,13 +129,14 @@ const LoginPage = () => {
|
|||
try {
|
||||
const response = await fetch('https://host-api.cs1.hz.siliconpin.com/v1/users/?query=login', {
|
||||
method: 'POST',
|
||||
credentials: 'include', // Important for cookies
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
query: 'new',
|
||||
accessToken: authData.token,
|
||||
email: authData.record.email,
|
||||
name: authData.record.name,
|
||||
type: authData.record.type,
|
||||
avatar: avatarUrl,
|
||||
isAuthenticated: true,
|
||||
id: authData.record.id
|
||||
|
@ -134,20 +144,22 @@ const LoginPage = () => {
|
|||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to sync session');
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('Session synced with backend:', data);
|
||||
} catch (error) {
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
console.error('Error syncing session:', error);
|
||||
throw error; // Re-throw the error if you want calling functions to handle it
|
||||
throw new Error(`Session sync failed: ${error.message}`);
|
||||
}
|
||||
};
|
||||
const { isLoggedIn, loading, error } = useIsLoggedIn();
|
||||
// console.log(isLoggedIn)
|
||||
if(loading){
|
||||
return <p>Loading...</p>
|
||||
return <Loader />
|
||||
}
|
||||
if(isLoggedIn){
|
||||
return (
|
||||
|
|
|
@ -0,0 +1,422 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { useIsLoggedIn } from '../../lib/isLoggedIn';
|
||||
import Loader from "../../components/ui/loader";
|
||||
import { PDFDownloadLink, PDFViewer } from '@react-pdf/renderer';
|
||||
import InvoicePDF from "../../lib/InvoicePDF"; // We'll create this component next
|
||||
|
||||
export default function AllSellingList() {
|
||||
const { isLoggedIn, loading, error, sessionData } = useIsLoggedIn();
|
||||
const [billingData, setBillingData] = useState([]);
|
||||
const [dataLoading, setDataLoading] = useState(true);
|
||||
const [apiError, setApiError] = useState(null);
|
||||
const [selectedItem, setSelectedItem] = useState(null);
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [editMode, setEditMode] = useState(false);
|
||||
const [formData, setFormData] = useState({
|
||||
service: '',
|
||||
tenure: 'monthly',
|
||||
amount: '',
|
||||
user: '',
|
||||
status: 'pending'
|
||||
});
|
||||
const INVOICE_API_URL = 'https://host-api.cs1.hz.siliconpin.com/v1/users/';
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoggedIn && sessionData?.user_type === 'admin') {
|
||||
fetchBillingData();
|
||||
}
|
||||
}, [isLoggedIn, sessionData]);
|
||||
|
||||
const fetchBillingData = async () => {
|
||||
try {
|
||||
const res = await fetch(`${INVOICE_API_URL}?query=all-selling-list`, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
|
||||
const data = await res.json();
|
||||
setBillingData(data.data || []);
|
||||
} catch (err) {
|
||||
setApiError(err.message);
|
||||
} finally {
|
||||
setDataLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleViewItem = (item) => {
|
||||
setSelectedItem(item);
|
||||
setShowModal(true);
|
||||
setEditMode(false);
|
||||
};
|
||||
|
||||
const handleEditItem = (item) => {
|
||||
setSelectedItem(item);
|
||||
setFormData({
|
||||
service: item.service,
|
||||
tenure: item.tenure,
|
||||
amount: item.amount,
|
||||
user: item.user,
|
||||
status: item.status
|
||||
});
|
||||
setEditMode(true);
|
||||
setShowModal(true);
|
||||
};
|
||||
|
||||
const handleDeleteItem = async (id) => {
|
||||
if (!window.confirm('Are you sure you want to delete this billing record?')) return;
|
||||
|
||||
try {
|
||||
const res = await fetch(`${INVOICE_API_URL}?query=delete-billing&id=${id}`, {
|
||||
method: 'DELETE',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
|
||||
fetchBillingData();
|
||||
} catch (err) {
|
||||
setApiError(err.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCreateNew = () => {
|
||||
setSelectedItem(null);
|
||||
setFormData({
|
||||
service: '',
|
||||
tenure: 'monthly',
|
||||
amount: '',
|
||||
user: '',
|
||||
status: 'pending'
|
||||
});
|
||||
setEditMode(true);
|
||||
setShowModal(true);
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
const url = selectedItem
|
||||
? `${INVOICE_API_URL}?query=update-billing&id=${selectedItem.id}`
|
||||
: `${INVOICE_API_URL}?query=create-billing`;
|
||||
|
||||
const method = selectedItem ? 'PUT' : 'POST';
|
||||
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(formData)
|
||||
});
|
||||
|
||||
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
|
||||
fetchBillingData();
|
||||
setShowModal(false);
|
||||
} catch (err) {
|
||||
setApiError(err.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleInputChange = (e) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
[name]: value
|
||||
}));
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
setShowModal(false);
|
||||
setSelectedItem(null);
|
||||
setEditMode(false);
|
||||
};
|
||||
|
||||
const getStatusColor = (status) => {
|
||||
switch (status) {
|
||||
case 'completed': return 'bg-green-100 text-green-800';
|
||||
case 'pending': return 'bg-yellow-100 text-yellow-800';
|
||||
case 'failed': return 'bg-red-100 text-red-800';
|
||||
default: return 'bg-gray-100 text-gray-800';
|
||||
}
|
||||
};
|
||||
|
||||
const formatDate = (dateString) => {
|
||||
if (!dateString) return 'N/A';
|
||||
const options = { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' };
|
||||
return new Date(dateString).toLocaleDateString(undefined, options);
|
||||
};
|
||||
|
||||
const formatCurrency = (amount) => {
|
||||
if (!amount) return '$0.00';
|
||||
return new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD'
|
||||
}).format(parseFloat(amount));
|
||||
};
|
||||
|
||||
if (loading || dataLoading) return <Loader />;
|
||||
if (error || apiError) return <p>Error: {error?.message || apiError}</p>;
|
||||
if (!isLoggedIn || sessionData?.user_type !== 'admin') {
|
||||
return <p className="text-center mt-8">You are not authorized to view this page. <a href="/" className="text-[#6d9e37]">Click Here</a> to go to the homepage.</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="container mx-auto px-4 py-8">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h1 className="text-2xl font-bold">Billing Management</h1>
|
||||
<button
|
||||
onClick={handleCreateNew}
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
|
||||
>
|
||||
Create New
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow overflow-hidden">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="min-w-full divide-y divide-gray-200">
|
||||
<thead className="bg-gray-50">
|
||||
<tr>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Billing ID</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Service</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">User</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Amount</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Created At</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-white divide-y divide-gray-200">
|
||||
{billingData.map((item) => (
|
||||
<tr key={item.id} className="hover:bg-gray-50">
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
{item.billing_id}
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{item.service}
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{item.user}
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 font-medium">
|
||||
{formatCurrency(item.amount)}
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap">
|
||||
<span className={`px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${getStatusColor(item.status)}`}>
|
||||
{item.status.charAt(0).toUpperCase() + item.status.slice(1)}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{formatDate(item.created_at)}
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||
<button
|
||||
onClick={() => handleViewItem(item)}
|
||||
className="text-indigo-600 hover:text-indigo-900 mr-2"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleEditItem(item)}
|
||||
className="text-yellow-600 hover:text-yellow-900 mr-2"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleDeleteItem(item.id)}
|
||||
className="text-red-600 hover:text-red-900 mr-2"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
<PDFDownloadLink
|
||||
document={<InvoicePDF data={item} />}
|
||||
fileName={`invoice_${item.billing_id}.pdf`}
|
||||
className="text-green-600 hover:text-green-900"
|
||||
>
|
||||
{({ loading }) => (loading ? 'Preparing...' : 'PDF')}
|
||||
</PDFDownloadLink>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Modal for View/Edit */}
|
||||
{showModal && (
|
||||
<div className="fixed inset-0 bg-gray-600 bg-opacity-50 flex items-center justify-center p-4 z-50">
|
||||
<div className="bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto">
|
||||
<div className="p-6">
|
||||
<div className="flex justify-between items-start">
|
||||
<h2 className="text-xl font-bold mb-4">
|
||||
{editMode ? (selectedItem ? 'Edit Billing' : 'Create New Billing') : 'Billing Details'}
|
||||
</h2>
|
||||
<button
|
||||
onClick={closeModal}
|
||||
className="text-gray-500 hover:text-gray-700"
|
||||
>
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{editMode ? (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Service</label>
|
||||
<input
|
||||
type="text"
|
||||
name="service"
|
||||
value={formData.service}
|
||||
onChange={handleInputChange}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Tenure</label>
|
||||
<select
|
||||
name="tenure"
|
||||
value={formData.tenure}
|
||||
onChange={handleInputChange}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md"
|
||||
>
|
||||
<option value="monthly">Monthly</option>
|
||||
<option value="yearly">Yearly</option>
|
||||
<option value="one-time">One-time</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Amount</label>
|
||||
<input
|
||||
type="number"
|
||||
name="amount"
|
||||
value={formData.amount}
|
||||
onChange={handleInputChange}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md"
|
||||
step="0.01"
|
||||
min="0"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">User Email</label>
|
||||
<input
|
||||
type="email"
|
||||
name="user"
|
||||
value={formData.user}
|
||||
onChange={handleInputChange}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Status</label>
|
||||
<select
|
||||
name="status"
|
||||
value={formData.status}
|
||||
onChange={handleInputChange}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md"
|
||||
>
|
||||
<option value="pending">Pending</option>
|
||||
<option value="completed">Completed</option>
|
||||
<option value="failed">Failed</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex justify-end space-x-4">
|
||||
<button
|
||||
type="submit"
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
|
||||
>
|
||||
{selectedItem ? 'Update' : 'Create'}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={closeModal}
|
||||
className="px-4 py-2 bg-gray-200 text-gray-800 rounded hover:bg-gray-300"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
) : (
|
||||
<>
|
||||
<div className="grid grid-cols-2 gap-4 mb-6">
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-700">Billing ID</h3>
|
||||
<p>{selectedItem.billing_id}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-700">Service</h3>
|
||||
<p>{selectedItem.service}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-700">User</h3>
|
||||
<p>{selectedItem.user}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-700">Tenure</h3>
|
||||
<p>{selectedItem.tenure}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-700">Amount</h3>
|
||||
<p>{formatCurrency(selectedItem.amount)}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-700">Status</h3>
|
||||
<span className={`px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${getStatusColor(selectedItem.status)}`}>
|
||||
{selectedItem.status.charAt(0).toUpperCase() + selectedItem.status.slice(1)}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-700">Created At</h3>
|
||||
<p>{formatDate(selectedItem.created_at)}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-700">Updated At</h3>
|
||||
<p>{formatDate(selectedItem.updated_at)}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex justify-end space-x-4">
|
||||
<PDFDownloadLink
|
||||
document={<InvoicePDF data={selectedItem} />}
|
||||
fileName={`invoice_${selectedItem.billing_id}.pdf`}
|
||||
className="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
|
||||
>
|
||||
{({ loading }) => (loading ? 'Preparing PDF...' : 'Download PDF')}
|
||||
</PDFDownloadLink>
|
||||
<button
|
||||
onClick={() => handleEditItem(selectedItem)}
|
||||
className="px-4 py-2 bg-yellow-600 text-white rounded hover:bg-yellow-700"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
onClick={closeModal}
|
||||
className="px-4 py-2 bg-gray-200 text-gray-800 rounded hover:bg-gray-300"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import TopicItems from "./TopicItem";
|
||||
import { useIsLoggedIn } from '../lib/isLoggedIn';
|
||||
|
||||
import Loader from "./ui/loader";
|
||||
const topicPageDesc = 'Cutting-edge discussions on tech, digital services, news, and digital freedom. Stay informed on AI, cybersecurity, privacy, and the future of innovation.';
|
||||
|
||||
export default function TopicCreation(props) {
|
||||
|
@ -38,7 +38,7 @@ export default function TopicCreation(props) {
|
|||
}, []);
|
||||
|
||||
if (authLoading || loading) {
|
||||
return <div className="loading-indicator">Loading...</div>;
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
if (authError || error) {
|
||||
|
|
|
@ -11,7 +11,11 @@ export default function TopicDetail(props) {
|
|||
return (
|
||||
<div className="container mx-auto px-4 py-12">
|
||||
<article className="max-w-4xl mx-auto">
|
||||
{
|
||||
props.topic.img && (
|
||||
<img src={props.topic.img} alt={props.topic.title} className="w-full h-96 object-cover rounded-lg mb-8" />
|
||||
)
|
||||
}
|
||||
<h1 className="text-4xl font-bold text-[#6d9e37] mb-4">{props.topic.title}</h1>
|
||||
<div className="font-light mb-8 text-justify prose max-w-none" dangerouslySetInnerHTML={{ __html: marked.parse(props.topic.content || '') }}></div>
|
||||
</article>
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Button } from './ui/button';
|
|||
import { Separator } from './ui/separator';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from './ui/dialog';
|
||||
import { CustomTabs } from './ui/tabs';
|
||||
|
||||
import Loader from "./ui/loader";
|
||||
|
||||
const TOPIC_API_URL = 'https://host-api.cs1.hz.siliconpin.com/v1/topics/';
|
||||
const MINIO_UPLOAD_URL = 'https://your-minio-api-endpoint/upload';
|
||||
|
@ -269,10 +269,7 @@ export default function EditTopic (){
|
|||
// Loading state
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="container mx-auto px-4 py-8 text-center">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-[#6d9e37] mx-auto"></div>
|
||||
<p className="mt-4 text-gray-600">Topic Loading...</p>
|
||||
</div>
|
||||
<Loader />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -280,10 +277,10 @@ export default function EditTopic (){
|
|||
if (success) {
|
||||
return (
|
||||
<div className="container mx-auto px-4 text-center py-8">
|
||||
<h3 className="text-xl font-semibold text-green-600 mb-4">Topic has been successfully updated!</h3>
|
||||
<h3 className="text-xl font-semibold mb-4">Topic has been successfully updated!</h3>
|
||||
<p className="mb-4">You are being automatically redirected to the topic page...</p>
|
||||
<div className="flex justify-center gap-4">
|
||||
<Button onClick={() => navigate(`/topic/${formData.slug}`)}>Preview this Topic</Button>
|
||||
<Button onClick={() => window.location.href = `/topic/${formData.slug}`}>Preview this Topic</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import React from "react";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./ui/card";
|
||||
import { Button } from "./ui/button";
|
||||
import { Input } from "./ui/input";
|
||||
import { useIsLoggedIn } from '../lib/isLoggedIn';
|
||||
import { Pencil, Trash2 } from "lucide-react"; // Import icons for better visual
|
||||
|
||||
import { Pencil, Trash2, Search } from "lucide-react";
|
||||
import { marked } from 'marked';
|
||||
export default function TopicItems(props) {
|
||||
const { isLoggedIn, loading, error, sessionData } = useIsLoggedIn();
|
||||
const [localSearchTerm, setLocalSearchTerm] = React.useState(props.searchTerm || '');
|
||||
|
||||
if (loading) {
|
||||
return <div className="loading-indicator">Loading...</div>;
|
||||
|
@ -15,11 +17,33 @@ export default function TopicItems(props) {
|
|||
return <div className="error-message">Error loading authentication status</div>;
|
||||
}
|
||||
|
||||
const handleSearchChange = (e) => {
|
||||
setLocalSearchTerm(e.target.value);
|
||||
};
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
props.onSearch(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="container mx-auto px-4">
|
||||
<div className="py-8 text-center">
|
||||
<h2 className="text-3xl sm:text-4xl font-bold text-[#6d9e37] mb-3 sm:mb-4">{props.title}</h2>
|
||||
<p className="text-lg sm:text-xl max-w-3xl mx-auto text-neutral-300">{props.description}</p>
|
||||
<form onSubmit={handleSubmit} className="flex gap-2 max-w-xl mx-auto mt-4">
|
||||
<Input
|
||||
type="text"
|
||||
name="search"
|
||||
placeholder="Search Topic..."
|
||||
value={localSearchTerm}
|
||||
onChange={handleSearchChange}
|
||||
/>
|
||||
<Button type="submit">
|
||||
<Search className="h-4 w-4 mr-2" />
|
||||
Search
|
||||
</Button>
|
||||
</form>
|
||||
</div>
|
||||
{
|
||||
props.topics.length > 0 ? (
|
||||
|
@ -28,17 +52,13 @@ export default function TopicItems(props) {
|
|||
props.topics.map((topic) => (
|
||||
<a href={`/topic/${topic.slug}`} key={topic.id} className="hover:scale-[1.02] transition-transform duration-200 ">
|
||||
<Card className="h-full flex flex-col group relative">
|
||||
<div className="relative">
|
||||
<img src={topic.img} alt={topic.title} className="aspect-video object-cover rounded-t-lg relative" loading="lazy" />
|
||||
<div className="">
|
||||
<img src={topic.img ? topic.img : '/assets/images/thumb-place.jpg'} alt={topic.title} className="aspect-video object-cover rounded-t-lg" loading="lazy" />
|
||||
</div>
|
||||
<CardContent className="flex-1 p-6">
|
||||
<CardTitle className="mb-2 line-clamp-1">{topic.title}</CardTitle>
|
||||
<CardDescription className="line-clamp-3 mb-4">
|
||||
{topic.description}
|
||||
<CardDescription className="line-clamp-4 mb-4" dangerouslySetInnerHTML={{ __html: marked.parse(topic.content || '') }}>
|
||||
</CardDescription>
|
||||
{
|
||||
// console.log('props.mytopic', props.mytopic)
|
||||
}
|
||||
{isLoggedIn && sessionData.user_email === topic.user && props.mytopic === true && (
|
||||
<div className="flex justify-end gap-2 mt-4 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
||||
<Button variant="outline" size="sm" className="gap-1"
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import TopicItems from "./TopicItem";
|
||||
import { useIsLoggedIn } from '../lib/isLoggedIn';
|
||||
import { Button } from "./ui/button";
|
||||
|
||||
const topicPageDesc = 'Cutting-edge discussions on tech, digital services, news, and digital freedom. Stay informed on AI, cybersecurity, privacy, and the future of innovation.';
|
||||
|
||||
export default function TopicCreation() {
|
||||
const { isLoggedIn, loading: authLoading, error: authError } = useIsLoggedIn();
|
||||
const [topics, setTopics] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [pagination, setPagination] = useState({
|
||||
current_page: 1,
|
||||
last_page: 1,
|
||||
per_page: 10,
|
||||
total: 0
|
||||
});
|
||||
|
||||
// Get current page from URL or default to 1
|
||||
const getCurrentPage = () => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const page = parseInt(params.get('page')) || 1;
|
||||
return Math.max(1, Math.min(page, pagination.last_page));
|
||||
};
|
||||
|
||||
// Fetch topics data with abort controller
|
||||
const fetchTopics = async (page) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await fetch(
|
||||
`https://host-api.cs1.hz.siliconpin.com/v1/topics/?query=get-all-topics&page=${page}`,
|
||||
{
|
||||
method: 'GET',
|
||||
credentials: 'include'
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
setTopics(data.data || []);
|
||||
setPagination(prev => ({
|
||||
...data.pagination,
|
||||
current_page: Math.min(data.pagination.current_page, data.pagination.last_page)
|
||||
}));
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
console.error('Fetch error:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle page change
|
||||
const handlePageChange = (newPage) => {
|
||||
const validatedPage = Math.max(1, Math.min(newPage, pagination.last_page));
|
||||
window.history.pushState({}, '', `?page=${validatedPage}`);
|
||||
fetchTopics(validatedPage);
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
};
|
||||
|
||||
// Initial load and URL change handling
|
||||
useEffect(() => {
|
||||
fetchTopics(getCurrentPage());
|
||||
|
||||
const handlePopState = () => {
|
||||
fetchTopics(getCurrentPage());
|
||||
};
|
||||
|
||||
window.addEventListener('popstate', handlePopState);
|
||||
return () => {
|
||||
window.removeEventListener('popstate', handlePopState);
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (authLoading) {
|
||||
return <div className="flex justify-center items-center h-64">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
if (authError) {
|
||||
return <div className="error-message p-4 bg-red-100 text-red-700 rounded">Error loading authentication status</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoggedIn && (
|
||||
<div className="container mx-auto flex justify-end gap-x-4 mb-4">
|
||||
<a href="/topic/new" className="create-new-link">Create New</a>
|
||||
<a href="/topic/my-topic">My Topics</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loading && !topics.length ? (
|
||||
<div className="flex justify-center items-center h-64">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="error-message p-4 bg-red-100 text-red-700 rounded">Error loading topics: {error}</div>
|
||||
) : (
|
||||
<>
|
||||
<TopicItems topics={topics} title="SoliconPin Topics" description={topicPageDesc} />
|
||||
|
||||
{pagination.last_page > 1 && (
|
||||
<div className="flex flex-col justify-between items-center mt-8 gap-4">
|
||||
<div className="text-sm text-gray-600">
|
||||
Showing {(pagination.current_page - 1) * pagination.per_page + 1}-
|
||||
{Math.min(pagination.current_page * pagination.per_page, pagination.total)} of {pagination.total} topics
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
{
|
||||
pagination.current_page > 1 && (
|
||||
<>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handlePageChange(1)}
|
||||
disabled={pagination.current_page <= 1}
|
||||
className="hidden sm:inline-flex"
|
||||
>
|
||||
First
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handlePageChange(pagination.current_page - 1)}
|
||||
disabled={pagination.current_page <= 1}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
{generatePageNumbers(pagination.current_page, pagination.last_page).map((page, i) => (
|
||||
page === '...' ? (
|
||||
<span key={i} className="px-2">...</span>
|
||||
) : (
|
||||
<Button
|
||||
key={i}
|
||||
variant={page === pagination.current_page ? "default" : "outline"}
|
||||
onClick={() => handlePageChange(page)}
|
||||
className="min-w-10"
|
||||
>
|
||||
{page}
|
||||
</Button>
|
||||
)
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handlePageChange(pagination.current_page + 1)}
|
||||
disabled={pagination.current_page >= pagination.last_page}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handlePageChange(pagination.last_page)}
|
||||
disabled={pagination.current_page >= pagination.last_page}
|
||||
className="hidden sm:inline-flex"
|
||||
>
|
||||
Last
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// Helper function to generate smart page numbers
|
||||
function generatePageNumbers(currentPage, lastPage) {
|
||||
const pages = [];
|
||||
const maxVisible = 5; // Maximum visible page numbers
|
||||
|
||||
if (lastPage <= maxVisible) {
|
||||
for (let i = 1; i <= lastPage; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
} else {
|
||||
// Always show first page
|
||||
pages.push(1);
|
||||
|
||||
// Calculate start and end of middle pages
|
||||
let start = Math.max(2, currentPage - 1);
|
||||
let end = Math.min(lastPage - 1, currentPage + 1);
|
||||
|
||||
// Adjust if we're at the beginning
|
||||
if (currentPage <= 3) {
|
||||
end = maxVisible - 2;
|
||||
}
|
||||
|
||||
// Adjust if we're at the end
|
||||
if (currentPage >= lastPage - 2) {
|
||||
start = lastPage - (maxVisible - 2);
|
||||
}
|
||||
|
||||
// Add ellipsis if needed
|
||||
if (start > 2) {
|
||||
pages.push('...');
|
||||
}
|
||||
|
||||
// Add middle pages
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
|
||||
// Add ellipsis if needed
|
||||
if (end < lastPage - 1) {
|
||||
pages.push('...');
|
||||
}
|
||||
|
||||
// Always show last page
|
||||
pages.push(lastPage);
|
||||
}
|
||||
|
||||
return pages;
|
||||
}
|
|
@ -1,29 +1,262 @@
|
|||
import React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import TopicItems from "./TopicItem";
|
||||
import { useIsLoggedIn } from '../lib/isLoggedIn';
|
||||
|
||||
import { Button } from "./ui/button";
|
||||
import Loader from "./ui/loader";
|
||||
const topicPageDesc = 'Cutting-edge discussions on tech, digital services, news, and digital freedom. Stay informed on AI, cybersecurity, privacy, and the future of innovation.';
|
||||
|
||||
export default function TopicCreation(props) {
|
||||
const { isLoggedIn, loading, error } = useIsLoggedIn();
|
||||
export default function TopicCreation() {
|
||||
const { isLoggedIn, loading: authLoading, error: authError } = useIsLoggedIn();
|
||||
const [topics, setTopics] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [pagination, setPagination] = useState({
|
||||
current_page: 1,
|
||||
last_page: 1,
|
||||
per_page: 10,
|
||||
total: 0
|
||||
});
|
||||
|
||||
if (loading) {
|
||||
return <div className="loading-indicator">Loading...</div>;
|
||||
// Get current page from URL or default to 1
|
||||
const getCurrentPage = () => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const page = parseInt(params.get('page')) || 1;
|
||||
return Math.max(1, Math.min(page, pagination.last_page));
|
||||
};
|
||||
|
||||
// Fetch topics data
|
||||
const fetchTopics = async (page, search = '') => {
|
||||
setLoading(true);
|
||||
try {
|
||||
let url = `https://host-api.cs1.hz.siliconpin.com/v1/topics/?query=get-all-topics&page=${page}`;
|
||||
|
||||
if (search) {
|
||||
url += `&search=${encodeURIComponent(search)}`;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <div className="error-message">Error loading authentication status</div>;
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
credentials: 'include'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
setTopics(data.data || []);
|
||||
setPagination(prev => ({
|
||||
...data.pagination,
|
||||
current_page: Math.min(data.pagination.current_page, data.pagination.last_page)
|
||||
}));
|
||||
setSearchTerm(data.search_term || '');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
console.error('Fetch error:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle page change
|
||||
const handlePageChange = (newPage) => {
|
||||
const validatedPage = Math.max(1, Math.min(newPage, pagination.last_page));
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
params.set('page', validatedPage);
|
||||
window.history.pushState({}, '', `?${params.toString()}`);
|
||||
fetchTopics(validatedPage, searchTerm);
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
};
|
||||
|
||||
// Handle search
|
||||
const handleSearch = (e) => {
|
||||
e.preventDefault();
|
||||
const newSearchTerm = e.target.elements.search.value.trim();
|
||||
setSearchTerm(newSearchTerm);
|
||||
|
||||
// Reset to page 1 when searching
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
params.set('page', 1);
|
||||
if (newSearchTerm) {
|
||||
params.set('search', newSearchTerm);
|
||||
} else {
|
||||
params.delete('search');
|
||||
}
|
||||
window.history.pushState({}, '', `?${params.toString()}`);
|
||||
fetchTopics(1, newSearchTerm);
|
||||
};
|
||||
|
||||
// Initial load and URL change handling
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const initialSearch = params.get('search') || '';
|
||||
setSearchTerm(initialSearch);
|
||||
fetchTopics(getCurrentPage(), initialSearch);
|
||||
|
||||
const handlePopState = () => {
|
||||
const newParams = new URLSearchParams(window.location.search);
|
||||
const newSearch = newParams.get('search') || '';
|
||||
setSearchTerm(newSearch);
|
||||
fetchTopics(getCurrentPage(), newSearch);
|
||||
};
|
||||
|
||||
window.addEventListener('popstate', handlePopState);
|
||||
return () => {
|
||||
window.removeEventListener('popstate', handlePopState);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// ... (keep existing authLoading and authError checks)
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoggedIn && (
|
||||
<div className="container mx-auto flex justify-end gap-x-4">
|
||||
<div className="container mx-auto flex justify-end gap-x-4 mb-4">
|
||||
<a href="/topic/new" className="create-new-link">Create New</a>
|
||||
<a href="/topic/my-topic">My Topics</a>
|
||||
</div>
|
||||
)}
|
||||
<TopicItems topics={props.topics} title="SoliconPin Topics" description={topicPageDesc} />
|
||||
|
||||
{loading && !topics.length ? (
|
||||
<Loader />
|
||||
) : error ? (
|
||||
<div className="error-message p-4 bg-red-100 text-red-700 rounded">Error loading topics: {error}</div>
|
||||
) : (
|
||||
<>
|
||||
<TopicItems
|
||||
topics={topics}
|
||||
title="SoliconPin Topics"
|
||||
description={topicPageDesc}
|
||||
onSearch={handleSearch}
|
||||
searchTerm={searchTerm}
|
||||
/>
|
||||
|
||||
{pagination.last_page > 1 && (
|
||||
<div className="flex flex-col justify-between items-center mt-8 gap-4">
|
||||
<div className="text-sm text-gray-600">
|
||||
Showing {(pagination.current_page - 1) * pagination.per_page + 1}-
|
||||
{Math.min(pagination.current_page * pagination.per_page, pagination.total)} of {pagination.total} topics
|
||||
{searchTerm && (
|
||||
<span className="ml-2">matching "{searchTerm}"</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
{
|
||||
pagination.current_page > 1 && (
|
||||
<>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handlePageChange(1)}
|
||||
disabled={pagination.current_page <= 1}
|
||||
className="hidden sm:inline-flex"
|
||||
>
|
||||
First
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handlePageChange(pagination.current_page - 1)}
|
||||
disabled={pagination.current_page <= 1}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
{generatePageNumbers(pagination.current_page, pagination.last_page).map((page, i) => (
|
||||
page === '...' ? (
|
||||
<span key={i} className="px-2">...</span>
|
||||
) : (
|
||||
<Button
|
||||
key={i}
|
||||
variant={page === pagination.current_page ? "default" : "outline"}
|
||||
onClick={() => handlePageChange(page)}
|
||||
className="min-w-10"
|
||||
>
|
||||
{page}
|
||||
</Button>
|
||||
)
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handlePageChange(pagination.current_page + 1)}
|
||||
disabled={pagination.current_page >= pagination.last_page}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handlePageChange(pagination.last_page)}
|
||||
disabled={pagination.current_page >= pagination.last_page}
|
||||
className="hidden sm:inline-flex"
|
||||
>
|
||||
Last
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// Helper function to generate smart page numbers
|
||||
function generatePageNumbers(currentPage, lastPage) {
|
||||
const pages = [];
|
||||
const maxVisible = 5; // Maximum visible page numbers
|
||||
|
||||
if (lastPage <= maxVisible) {
|
||||
for (let i = 1; i <= lastPage; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
} else {
|
||||
// Always show first page
|
||||
pages.push(1);
|
||||
|
||||
// Calculate start and end of middle pages
|
||||
let start = Math.max(2, currentPage - 1);
|
||||
let end = Math.min(lastPage - 1, currentPage + 1);
|
||||
|
||||
// Adjust if we're at the beginning
|
||||
if (currentPage <= 3) {
|
||||
end = maxVisible - 2;
|
||||
}
|
||||
|
||||
// Adjust if we're at the end
|
||||
if (currentPage >= lastPage - 2) {
|
||||
start = lastPage - (maxVisible - 2);
|
||||
}
|
||||
|
||||
// Add ellipsis if needed
|
||||
if (start > 2) {
|
||||
pages.push('...');
|
||||
}
|
||||
|
||||
// Add middle pages
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
|
||||
// Add ellipsis if needed
|
||||
if (end < lastPage - 1) {
|
||||
pages.push('...');
|
||||
}
|
||||
|
||||
// Always show last page
|
||||
pages.push(lastPage);
|
||||
}
|
||||
|
||||
return pages;
|
||||
}
|
|
@ -9,7 +9,7 @@ import { Textarea } from "./ui/textarea";
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import UpdateAvatar from './UpdateAvatar';
|
||||
import {localizeTime} from "../lib/localizeTime";
|
||||
|
||||
import Loader from "./ui/loader";
|
||||
interface SessionData {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ export default function ProfilePage() {
|
|||
}
|
||||
|
||||
if (!userData) {
|
||||
return (<div>Loading profile data...</div>);
|
||||
return (<Loader />);
|
||||
}
|
||||
return (
|
||||
<div className="space-y-6 container mx-auto">
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
import React, { useEffect } from 'react';
|
||||
|
||||
const Loader = () => {
|
||||
// CSS styles object
|
||||
const styles = {
|
||||
container: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: '100vh',
|
||||
width: '100%',
|
||||
},
|
||||
loader: {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginBottom: '16px',
|
||||
},
|
||||
dot: {
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
margin: '0 4px',
|
||||
backgroundColor: '#6d9e37',
|
||||
borderRadius: '50%',
|
||||
display: 'inline-block',
|
||||
animation: 'bounce 1.4s infinite ease-in-out both',
|
||||
},
|
||||
dot1: {
|
||||
animationDelay: '-0.32s',
|
||||
},
|
||||
dot2: {
|
||||
animationDelay: '-0.16s',
|
||||
},
|
||||
text: {
|
||||
color: '#6d9e37',
|
||||
fontSize: '1rem',
|
||||
fontWeight: '500',
|
||||
},
|
||||
// Keyframes as a string to be injected
|
||||
keyframes: `
|
||||
@keyframes bounce {
|
||||
0%, 80%, 100% {
|
||||
transform: scale(0);
|
||||
}
|
||||
40% {
|
||||
transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Only run on client-side where document is available
|
||||
if (typeof document !== 'undefined') {
|
||||
const styleSheet = document.styleSheets[0];
|
||||
try {
|
||||
styleSheet.insertRule(styles.keyframes, styleSheet.cssRules.length);
|
||||
} catch (e) {
|
||||
// Fallback for browsers that might not support this
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.innerHTML = styles.keyframes;
|
||||
document.head.appendChild(styleElement);
|
||||
}
|
||||
}
|
||||
}, []); // Empty dependency array means this runs once on mount
|
||||
|
||||
return (
|
||||
<div style={styles.container}>
|
||||
<div style={styles.loader}>
|
||||
<div style={{ ...styles.dot, ...styles.dot1 }}></div>
|
||||
<div style={{ ...styles.dot, ...styles.dot2 }}></div>
|
||||
<div style={styles.dot}></div>
|
||||
</div>
|
||||
<p style={styles.text}>Loading...</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Loader;
|
|
@ -0,0 +1,187 @@
|
|||
import React from 'react';
|
||||
import { Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';
|
||||
|
||||
// Create styles
|
||||
const styles = StyleSheet.create({
|
||||
page: {
|
||||
flexDirection: 'column',
|
||||
backgroundColor: '#FFFFFF',
|
||||
padding: 40
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 20,
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: '#6d9e37',
|
||||
paddingBottom: 10
|
||||
},
|
||||
title: {
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
color: '#6d9e37'
|
||||
},
|
||||
section: {
|
||||
marginBottom: 20
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 5
|
||||
},
|
||||
label: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
value: {
|
||||
fontSize: 12
|
||||
},
|
||||
divider: {
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#EEEEEE',
|
||||
marginVertical: 10
|
||||
},
|
||||
tableHeader: {
|
||||
flexDirection: 'row',
|
||||
backgroundColor: '#F5F5F5',
|
||||
padding: 5,
|
||||
marginBottom: 5
|
||||
},
|
||||
tableRow: {
|
||||
flexDirection: 'row',
|
||||
padding: 5,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#EEEEEE'
|
||||
},
|
||||
col1: {
|
||||
width: '40%'
|
||||
},
|
||||
col2: {
|
||||
width: '30%',
|
||||
textAlign: 'right'
|
||||
},
|
||||
col3: {
|
||||
width: '30%',
|
||||
textAlign: 'right'
|
||||
},
|
||||
total: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
marginTop: 10
|
||||
},
|
||||
totalText: {
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
footer: {
|
||||
position: 'absolute',
|
||||
bottom: 30,
|
||||
left: 40,
|
||||
right: 40,
|
||||
textAlign: 'center',
|
||||
fontSize: 10,
|
||||
color: '#999999'
|
||||
},
|
||||
status: {
|
||||
padding: 3,
|
||||
borderRadius: 3,
|
||||
fontSize: 10,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
});
|
||||
|
||||
const InvoicePDF = ({ data }) => {
|
||||
const statusColor = data.status === 'completed' ? '#10B981' : '#EF4444';
|
||||
|
||||
return (
|
||||
<Document>
|
||||
<Page size="A4" style={styles.page}>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<View>
|
||||
<Text style={styles.title}>INVOICE</Text>
|
||||
<Text style={styles.label}>Invoice #: {data.billing_id}</Text>
|
||||
<Text style={styles.label}>Date: {new Date(data.created_at).toLocaleDateString()}</Text>
|
||||
</View>
|
||||
<View>
|
||||
<Text style={styles.label}>Your Company</Text>
|
||||
<Text style={styles.value}>123 Business Street</Text>
|
||||
<Text style={styles.value}>City, Country</Text>
|
||||
<Text style={styles.value}>contact@yourcompany.com</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Bill To */}
|
||||
<View style={styles.section}>
|
||||
<View style={styles.row}>
|
||||
<View>
|
||||
<Text style={styles.label}>BILL TO:</Text>
|
||||
<Text style={styles.value}>{data.user}</Text>
|
||||
</View>
|
||||
<View>
|
||||
<Text style={styles.label}>STATUS:</Text>
|
||||
<Text style={[styles.value, { color: statusColor }]}>
|
||||
{data.status.toUpperCase()}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.divider} />
|
||||
|
||||
{/* Items Table */}
|
||||
<View style={styles.section}>
|
||||
<View style={styles.tableHeader}>
|
||||
<Text style={styles.col1}>DESCRIPTION</Text>
|
||||
<Text style={styles.col2}>TENURE</Text>
|
||||
<Text style={styles.col3}>AMOUNT</Text>
|
||||
</View>
|
||||
<View style={styles.tableRow}>
|
||||
<Text style={styles.col1}>{data.service}</Text>
|
||||
<Text style={styles.col2}>{data.tenure}</Text>
|
||||
<Text style={styles.col3}>
|
||||
{new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD'
|
||||
}).format(parseFloat(data.amount))}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.divider} />
|
||||
|
||||
{/* Total */}
|
||||
<View style={styles.total}>
|
||||
<View style={{width: '30%'}}>
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.label}>SUBTOTAL:</Text>
|
||||
<Text style={styles.value}>
|
||||
{new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD'
|
||||
}).format(parseFloat(data.amount))}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.label}>TOTAL:</Text>
|
||||
<Text style={styles.totalText}>
|
||||
{new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD'
|
||||
}).format(parseFloat(data.amount))}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Footer */}
|
||||
<View style={styles.footer}>
|
||||
<Text>Thank you for your business!</Text>
|
||||
<Text>Please make payments payable to Your Company</Text>
|
||||
</View>
|
||||
</Page>
|
||||
</Document>
|
||||
);
|
||||
};
|
||||
|
||||
export default InvoicePDF;
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import AllSellingList from "../../components/Manager/AllSellingList"
|
||||
---
|
||||
<Layout title="All Selling List | SiliconPin" >
|
||||
<AllSellingList client:load />
|
||||
</Layout>
|
|
@ -19,7 +19,7 @@ try {
|
|||
|
||||
const data = await response.json();
|
||||
topic = data.data[0]; // Assuming single result
|
||||
console.log('Single Topic:', topic);
|
||||
// console.log('Single Topic:', topic);
|
||||
} catch (error) {
|
||||
console.error('Error fetching single topic:', error);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ export async function getStaticPaths() {
|
|||
const TOPIC_API_URL = 'https://host-api.cs1.hz.siliconpin.com/v1/topics/';
|
||||
|
||||
try {
|
||||
const response = await fetch(`${TOPIC_API_URL}?query=get-all-topics`, {
|
||||
const response = await fetch(`${TOPIC_API_URL}?query=get-all-topics-for-slug`, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ const TOPIC_API_URL = 'https://host-api.cs1.hz.siliconpin.com/v1/topics/';
|
|||
let topics = [];
|
||||
|
||||
try {
|
||||
const response = await fetch(`${TOPIC_API_URL}?query=get-all-topics`, {
|
||||
const response = await fetch(`${TOPIC_API_URL}?query=get-all-topics-for-slug`, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
});
|
||||
|
@ -16,13 +16,13 @@ try {
|
|||
}
|
||||
|
||||
const data = await response.json();
|
||||
// console.log('Topic Data', data)
|
||||
topics = data.data || [];
|
||||
// console.log('Topic Data', data);
|
||||
} catch (error) {
|
||||
console.error('An error occurred', error);
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title="Topics">
|
||||
<TopicsList client:load topics={topics} />
|
||||
<TopicsList client:load />
|
||||
</Layout>
|
||||
|
|
356
yarn.lock
356
yarn.lock
|
@ -213,7 +213,7 @@
|
|||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.25.9"
|
||||
|
||||
"@babel/runtime@^7.14.6", "@babel/runtime@^7.17.2":
|
||||
"@babel/runtime@^7.14.6", "@babel/runtime@^7.17.2", "@babel/runtime@^7.20.13":
|
||||
version "7.27.0"
|
||||
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz"
|
||||
integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==
|
||||
|
@ -650,6 +650,144 @@
|
|||
resolved "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz"
|
||||
integrity sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==
|
||||
|
||||
"@react-pdf/fns@3.1.2":
|
||||
version "3.1.2"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/fns/-/fns-3.1.2.tgz"
|
||||
integrity sha512-qTKGUf0iAMGg2+OsUcp9ffKnKi41RukM/zYIWMDJ4hRVYSr89Q7e3wSDW/Koqx3ea3Uy/z3h2y3wPX6Bdfxk6g==
|
||||
|
||||
"@react-pdf/font@^4.0.2":
|
||||
version "4.0.2"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/font/-/font-4.0.2.tgz"
|
||||
integrity sha512-/dAWu7Y2RD1RxarDZ9SkYPHgBYOhmcDnet4W/qN/m8k+A2Hr3ja54GymSR7GGxWBtxjKtNauVKrTa9LS1n8WUw==
|
||||
dependencies:
|
||||
"@react-pdf/pdfkit" "^4.0.3"
|
||||
"@react-pdf/types" "^2.9.0"
|
||||
fontkit "^2.0.2"
|
||||
is-url "^1.2.4"
|
||||
|
||||
"@react-pdf/image@^3.0.3":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/image/-/image-3.0.3.tgz"
|
||||
integrity sha512-lvP5ryzYM3wpbO9bvqLZYwEr5XBDX9jcaRICvtnoRqdJOo7PRrMnmB4MMScyb+Xw10mGeIubZAAomNAG5ONQZQ==
|
||||
dependencies:
|
||||
"@react-pdf/png-js" "^3.0.0"
|
||||
jay-peg "^1.1.1"
|
||||
|
||||
"@react-pdf/layout@^4.4.0":
|
||||
version "4.4.0"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/layout/-/layout-4.4.0.tgz"
|
||||
integrity sha512-Aq+Cc6JYausWLoks2FvHe3PwK9cTuvksB2uJ0AnkKJEUtQbvCq8eCRb1bjbbwIji9OzFRTTzZij7LzkpKHjIeA==
|
||||
dependencies:
|
||||
"@react-pdf/fns" "3.1.2"
|
||||
"@react-pdf/image" "^3.0.3"
|
||||
"@react-pdf/primitives" "^4.1.1"
|
||||
"@react-pdf/stylesheet" "^6.1.0"
|
||||
"@react-pdf/textkit" "^6.0.0"
|
||||
"@react-pdf/types" "^2.9.0"
|
||||
emoji-regex "^10.3.0"
|
||||
queue "^6.0.1"
|
||||
yoga-layout "^3.2.1"
|
||||
|
||||
"@react-pdf/pdfkit@^4.0.3":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/pdfkit/-/pdfkit-4.0.3.tgz"
|
||||
integrity sha512-k+Lsuq8vTwWsCqTp+CCB4+2N+sOTFrzwGA7aw3H9ix/PDWR9QksbmNg0YkzGbLAPI6CeawmiLHcf4trZ5ecLPQ==
|
||||
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"
|
||||
|
||||
"@react-pdf/png-js@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/png-js/-/png-js-3.0.0.tgz"
|
||||
integrity sha512-eSJnEItZ37WPt6Qv5pncQDxLJRK15eaRwPT+gZoujP548CodenOVp49GST8XJvKMFt9YqIBzGBV/j9AgrOQzVA==
|
||||
dependencies:
|
||||
browserify-zlib "^0.2.0"
|
||||
|
||||
"@react-pdf/primitives@^4.1.1":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/primitives/-/primitives-4.1.1.tgz"
|
||||
integrity sha512-IuhxYls1luJb7NUWy6q5avb1XrNaVj9bTNI40U9qGRuS6n7Hje/8H8Qi99Z9UKFV74bBP3DOf3L1wV2qZVgVrQ==
|
||||
|
||||
"@react-pdf/reconciler@^1.1.4":
|
||||
version "1.1.4"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/reconciler/-/reconciler-1.1.4.tgz"
|
||||
integrity sha512-oTQDiR/t4Z/Guxac88IavpU2UgN7eR0RMI9DRKvKnvPz2DUasGjXfChAdMqDNmJJxxV26mMy9xQOUV2UU5/okg==
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
scheduler "0.25.0-rc-603e6108-20241029"
|
||||
|
||||
"@react-pdf/render@^4.3.0":
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/render/-/render-4.3.0.tgz"
|
||||
integrity sha512-MdWfWaqO6d7SZD75TZ2z5L35V+cHpyA43YNRlJNG0RJ7/MeVGDQv12y/BXOJgonZKkeEGdzM3EpAt9/g4E22WA==
|
||||
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.0"
|
||||
abs-svg-path "^0.1.1"
|
||||
color-string "^1.9.1"
|
||||
normalize-svg-path "^1.1.0"
|
||||
parse-svg-path "^0.1.2"
|
||||
svg-arc-to-cubic-bezier "^3.2.0"
|
||||
|
||||
"@react-pdf/renderer@^4.3.0":
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/renderer/-/renderer-4.3.0.tgz"
|
||||
integrity sha512-28gpA69fU9ZQrDzmd5xMJa1bDf8t0PT3ApUKBl2PUpoE/x4JlvCB5X66nMXrfFrgF2EZrA72zWQAkvbg7TE8zw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.20.13"
|
||||
"@react-pdf/fns" "3.1.2"
|
||||
"@react-pdf/font" "^4.0.2"
|
||||
"@react-pdf/layout" "^4.4.0"
|
||||
"@react-pdf/pdfkit" "^4.0.3"
|
||||
"@react-pdf/primitives" "^4.1.1"
|
||||
"@react-pdf/reconciler" "^1.1.4"
|
||||
"@react-pdf/render" "^4.3.0"
|
||||
"@react-pdf/types" "^2.9.0"
|
||||
events "^3.3.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
queue "^6.0.1"
|
||||
|
||||
"@react-pdf/stylesheet@^6.1.0":
|
||||
version "6.1.0"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/stylesheet/-/stylesheet-6.1.0.tgz"
|
||||
integrity sha512-BGZ2sYNUp38VJUegjva/jsri3iiRGnVNjWI+G9dTwAvLNOmwFvSJzqaCsEnqQ/DW5mrTBk/577FhDY7pv6AidA==
|
||||
dependencies:
|
||||
"@react-pdf/fns" "3.1.2"
|
||||
"@react-pdf/types" "^2.9.0"
|
||||
color-string "^1.9.1"
|
||||
hsl-to-hex "^1.0.0"
|
||||
media-engine "^1.0.3"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
"@react-pdf/textkit@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/textkit/-/textkit-6.0.0.tgz"
|
||||
integrity sha512-fDt19KWaJRK/n2AaFoVm31hgGmpygmTV7LsHGJNGZkgzXcFyLsx+XUl63DTDPH3iqxj3xUX128t104GtOz8tTw==
|
||||
dependencies:
|
||||
"@react-pdf/fns" "3.1.2"
|
||||
bidi-js "^1.0.2"
|
||||
hyphen "^1.6.4"
|
||||
unicode-properties "^1.4.1"
|
||||
|
||||
"@react-pdf/types@^2.9.0":
|
||||
version "2.9.0"
|
||||
resolved "https://registry.npmjs.org/@react-pdf/types/-/types-2.9.0.tgz"
|
||||
integrity sha512-ckj80vZLlvl9oYrQ4tovEaqKWP3O06Eb1D48/jQWbdwz1Yh7Y9v1cEmwlP8ET+a1Whp8xfdM0xduMexkuPANCQ==
|
||||
dependencies:
|
||||
"@react-pdf/font" "^4.0.2"
|
||||
"@react-pdf/primitives" "^4.1.1"
|
||||
"@react-pdf/stylesheet" "^6.1.0"
|
||||
|
||||
"@rollup/pluginutils@^5.1.4":
|
||||
version "5.1.4"
|
||||
resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz"
|
||||
|
@ -739,6 +877,13 @@
|
|||
resolved "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz"
|
||||
integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==
|
||||
|
||||
"@swc/helpers@^0.5.12":
|
||||
version "0.5.17"
|
||||
resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz"
|
||||
integrity sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==
|
||||
dependencies:
|
||||
tslib "^2.8.0"
|
||||
|
||||
"@types/babel__core@^7.20.5":
|
||||
version "7.20.5"
|
||||
resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz"
|
||||
|
@ -951,6 +1096,11 @@
|
|||
resolved "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz"
|
||||
integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==
|
||||
|
||||
abs-svg-path@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz"
|
||||
integrity sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==
|
||||
|
||||
acorn@^8.14.1:
|
||||
version "8.14.1"
|
||||
resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz"
|
||||
|
@ -1135,16 +1285,28 @@ base-64@^1.0.0:
|
|||
resolved "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz"
|
||||
integrity sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==
|
||||
|
||||
base64-js@^1.3.1:
|
||||
base64-js@^1.1.2, base64-js@^1.3.0, base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
base64-js@0.0.8:
|
||||
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==
|
||||
|
||||
bcp-47-match@^2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz"
|
||||
integrity sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==
|
||||
|
||||
bidi-js@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz"
|
||||
integrity sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==
|
||||
dependencies:
|
||||
require-from-string "^2.0.2"
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz"
|
||||
|
@ -1199,11 +1361,25 @@ braces@^3.0.3, braces@~3.0.2:
|
|||
dependencies:
|
||||
fill-range "^7.1.1"
|
||||
|
||||
brotli@^1.3.2:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz"
|
||||
integrity sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==
|
||||
dependencies:
|
||||
base64-js "^1.1.2"
|
||||
|
||||
browser-or-node@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz"
|
||||
integrity sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==
|
||||
|
||||
browserify-zlib@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz"
|
||||
integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==
|
||||
dependencies:
|
||||
pako "~1.0.5"
|
||||
|
||||
browserslist@^4.24.0, browserslist@^4.24.4, "browserslist@>= 4.21.0":
|
||||
version "4.24.4"
|
||||
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz"
|
||||
|
@ -1359,6 +1535,11 @@ clone@^1.0.2:
|
|||
resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz"
|
||||
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
|
||||
|
||||
clone@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
|
||||
integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==
|
||||
|
||||
clsx@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz"
|
||||
|
@ -1388,7 +1569,7 @@ color-name@^1.0.0, color-name@~1.1.4:
|
|||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
color-string@^1.9.0:
|
||||
color-string@^1.9.0, color-string@^1.9.1:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz"
|
||||
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
|
||||
|
@ -1460,6 +1641,11 @@ crossws@^0.3.3:
|
|||
dependencies:
|
||||
uncrypto "^0.1.3"
|
||||
|
||||
crypto-js@^4.2.0:
|
||||
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==
|
||||
|
||||
css-selector-parser@^1.0.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz"
|
||||
|
@ -1569,6 +1755,11 @@ devlop@^1.0.0, devlop@^1.1.0:
|
|||
dependencies:
|
||||
dequal "^2.0.0"
|
||||
|
||||
dfa@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz"
|
||||
integrity sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==
|
||||
|
||||
didyoumean@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz"
|
||||
|
@ -1734,6 +1925,11 @@ eventemitter3@^5.0.1:
|
|||
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz"
|
||||
integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
|
||||
|
||||
events@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
|
||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||
|
||||
execa@^7.0.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz"
|
||||
|
@ -1754,6 +1950,11 @@ extend@^3.0.0:
|
|||
resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-glob@^3.3.2:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz"
|
||||
|
@ -1809,6 +2010,21 @@ flattie@^1.1.1:
|
|||
resolved "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz"
|
||||
integrity sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==
|
||||
|
||||
fontkit@^2.0.2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.npmjs.org/fontkit/-/fontkit-2.0.4.tgz"
|
||||
integrity sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==
|
||||
dependencies:
|
||||
"@swc/helpers" "^0.5.12"
|
||||
brotli "^1.3.2"
|
||||
clone "^2.1.2"
|
||||
dfa "^1.2.0"
|
||||
fast-deep-equal "^3.1.3"
|
||||
restructure "^3.0.0"
|
||||
tiny-inflate "^1.0.3"
|
||||
unicode-properties "^1.4.0"
|
||||
unicode-trie "^2.0.0"
|
||||
|
||||
for-each@^0.3.5:
|
||||
version "0.3.5"
|
||||
resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz"
|
||||
|
@ -2312,6 +2528,18 @@ hastscript@^9.0.0:
|
|||
property-information "^7.0.0"
|
||||
space-separated-tokens "^2.0.0"
|
||||
|
||||
hsl-to-hex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/hsl-to-hex/-/hsl-to-hex-1.0.0.tgz"
|
||||
integrity sha512-K6GVpucS5wFf44X0h2bLVRDsycgJmf9FF2elg+CrqD8GcFU8c6vYhgXn8NjUkFCwj+xDFb70qgLbTUm6sxwPmA==
|
||||
dependencies:
|
||||
hsl-to-rgb-for-reals "^1.1.0"
|
||||
|
||||
hsl-to-rgb-for-reals@^1.1.0:
|
||||
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==
|
||||
|
||||
html-escaper@3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz"
|
||||
|
@ -2342,6 +2570,11 @@ human-signals@^4.3.0:
|
|||
resolved "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz"
|
||||
integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==
|
||||
|
||||
hyphen@^1.6.4:
|
||||
version "1.10.6"
|
||||
resolved "https://registry.npmjs.org/hyphen/-/hyphen-1.10.6.tgz"
|
||||
integrity sha512-fXHXcGFTXOvZTSkPJuGOQf5Lv5T/R2itiiCVPg9LxAje5D00O0pP83yJShFq5V89Ly//Gt6acj7z8pbBr34stw==
|
||||
|
||||
ieee754@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
|
||||
|
@ -2352,7 +2585,7 @@ import-meta-resolve@^4.1.0:
|
|||
resolved "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz"
|
||||
integrity sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==
|
||||
|
||||
inherits@^2.0.3, inherits@^2.0.4:
|
||||
inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
@ -2518,6 +2751,11 @@ is-unicode-supported@^1.1.0:
|
|||
resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz"
|
||||
integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==
|
||||
|
||||
is-url@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz"
|
||||
integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
|
||||
|
||||
is-wsl@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz"
|
||||
|
@ -2539,6 +2777,13 @@ jackspeak@^3.1.2:
|
|||
optionalDependencies:
|
||||
"@pkgjs/parseargs" "^0.11.0"
|
||||
|
||||
jay-peg@^1.1.1:
|
||||
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==
|
||||
dependencies:
|
||||
restructure "^3.0.0"
|
||||
|
||||
jiti@^1.21.6, jiti@>=1.21.0:
|
||||
version "1.21.7"
|
||||
resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz"
|
||||
|
@ -2590,6 +2835,14 @@ lilconfig@^3.0.0, lilconfig@^3.1.3:
|
|||
resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz"
|
||||
integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==
|
||||
|
||||
linebreak@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz"
|
||||
integrity sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==
|
||||
dependencies:
|
||||
base64-js "0.0.8"
|
||||
unicode-trie "^2.0.0"
|
||||
|
||||
lines-and-columns@^1.1.6:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz"
|
||||
|
@ -3005,6 +3258,11 @@ mdast-util-to-string@^4.0.0:
|
|||
dependencies:
|
||||
"@types/mdast" "^4.0.0"
|
||||
|
||||
media-engine@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/media-engine/-/media-engine-1.0.3.tgz"
|
||||
integrity sha512-aa5tG6sDoK+k70B9iEX1NeyfT8ObCKhNDs6lJVpwF6r8vhUfuKMslIcirq6HIUYuuUYLefcEQOn9bSBOvawtwg==
|
||||
|
||||
merge-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
|
||||
|
@ -3712,6 +3970,13 @@ normalize-range@^0.1.2:
|
|||
resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
|
||||
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
|
||||
|
||||
normalize-svg-path@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz"
|
||||
integrity sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==
|
||||
dependencies:
|
||||
svg-arc-to-cubic-bezier "^3.0.0"
|
||||
|
||||
not@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmjs.org/not/-/not-0.1.0.tgz"
|
||||
|
@ -3818,6 +4083,16 @@ package-manager-detector@^1.0.0:
|
|||
resolved "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.1.0.tgz"
|
||||
integrity sha512-Y8f9qUlBzW8qauJjd/eu6jlpJZsuPJm2ZAV0cDVd420o4EdpH5RPdoCv+60/TdJflGatr4sDfpAL6ArWZbM5tA==
|
||||
|
||||
pako@^0.2.5:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz"
|
||||
integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==
|
||||
|
||||
pako@~1.0.5:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz"
|
||||
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
|
||||
|
||||
parse-entities@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz"
|
||||
|
@ -3848,6 +4123,11 @@ parse-numeric-range@^1.3.0:
|
|||
resolved "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz"
|
||||
integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==
|
||||
|
||||
parse-svg-path@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz"
|
||||
integrity sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==
|
||||
|
||||
parse5@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz"
|
||||
|
@ -3967,7 +4247,7 @@ postcss-selector-parser@^6.1.1, postcss-selector-parser@^6.1.2:
|
|||
cssesc "^3.0.0"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
|
||||
postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
|
||||
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
|
||||
|
@ -3994,7 +4274,7 @@ prompts@^2.4.2:
|
|||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.0.0, prop-types@^15.8.1:
|
||||
prop-types@^15.0.0, prop-types@^15.6.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
|
@ -4033,6 +4313,13 @@ queue-microtask@^1.2.2:
|
|||
resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
|
||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||
|
||||
queue@^6.0.1:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz"
|
||||
integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==
|
||||
dependencies:
|
||||
inherits "~2.0.3"
|
||||
|
||||
radix3@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz"
|
||||
|
@ -4463,6 +4750,11 @@ remark-stringify@^11.0.0:
|
|||
mdast-util-to-markdown "^2.0.0"
|
||||
unified "^11.0.0"
|
||||
|
||||
require-from-string@^2.0.2:
|
||||
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==
|
||||
|
||||
resolve@^1.1.7, resolve@^1.22.8:
|
||||
version "1.22.10"
|
||||
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz"
|
||||
|
@ -4480,6 +4772,11 @@ restore-cursor@^4.0.0:
|
|||
onetime "^5.1.0"
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
restructure@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz"
|
||||
integrity sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==
|
||||
|
||||
retext-latin@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz"
|
||||
|
@ -4588,6 +4885,11 @@ scheduler@^0.25.0:
|
|||
resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz"
|
||||
integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==
|
||||
|
||||
scheduler@0.25.0-rc-603e6108-20241029:
|
||||
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==
|
||||
|
||||
semver@^6.3.1:
|
||||
version "6.3.1"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
|
||||
|
@ -4871,6 +5173,11 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
svg-arc-to-cubic-bezier@^3.0.0, svg-arc-to-cubic-bezier@^3.2.0:
|
||||
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==
|
||||
|
||||
tailwind-merge@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.0.2.tgz"
|
||||
|
@ -4930,6 +5237,11 @@ through2@^4.0.2:
|
|||
dependencies:
|
||||
readable-stream "3"
|
||||
|
||||
tiny-inflate@^1.0.0, tiny-inflate@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz"
|
||||
integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==
|
||||
|
||||
tinyexec@^0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz"
|
||||
|
@ -4970,7 +5282,7 @@ tsconfck@^3.1.5:
|
|||
resolved "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.5.tgz"
|
||||
integrity sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.1.0:
|
||||
tslib@^2.0.0, tslib@^2.1.0, tslib@^2.8.0:
|
||||
version "2.8.1"
|
||||
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
|
||||
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
|
||||
|
@ -5010,6 +5322,22 @@ uncrypto@^0.1.3:
|
|||
resolved "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz"
|
||||
integrity sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==
|
||||
|
||||
unicode-properties@^1.4.0, unicode-properties@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz"
|
||||
integrity sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==
|
||||
dependencies:
|
||||
base64-js "^1.3.0"
|
||||
unicode-trie "^2.0.0"
|
||||
|
||||
unicode-trie@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz"
|
||||
integrity sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==
|
||||
dependencies:
|
||||
pako "^0.2.5"
|
||||
tiny-inflate "^1.0.0"
|
||||
|
||||
unified@^10.0.0, unified@~10.1.1:
|
||||
version "10.1.2"
|
||||
resolved "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz"
|
||||
|
@ -5296,6 +5624,15 @@ vfile@^6.0.0, vfile@^6.0.3:
|
|||
"@types/unist" "^3.0.0"
|
||||
vfile-message "^4.0.0"
|
||||
|
||||
vite-compatible-readable-stream@^3.6.1:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.npmjs.org/vite-compatible-readable-stream/-/vite-compatible-readable-stream-3.6.1.tgz"
|
||||
integrity sha512-t20zYkrSf868+j/p31cRIGN28Phrjm3nRSLR2fyc2tiWi4cZGVdv68yNlwnIINTkMTmPoMiSlc0OadaO7DXZaQ==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
"vite@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^4.2.0 || ^5.0.0 || ^6.0.0", vite@^6.2.0, vite@^6.2.1:
|
||||
version "6.2.2"
|
||||
resolved "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz"
|
||||
|
@ -5447,6 +5784,11 @@ yoctocolors@^2.1.1:
|
|||
resolved "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz"
|
||||
integrity sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==
|
||||
|
||||
yoga-layout@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz"
|
||||
integrity sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==
|
||||
|
||||
zod-to-json-schema@^3.24.3:
|
||||
version "3.24.4"
|
||||
resolved "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.4.tgz"
|
||||
|
|
Loading…
Reference in New Issue