mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:11:13 -05:00
feat: Implement Novu Inbox component
This commit is contained in:
433
package-lock.json
generated
433
package-lock.json
generated
@@ -12,6 +12,7 @@
|
||||
"@marsidev/react-turnstile": "^1.3.1",
|
||||
"@novu/headless": "^2.6.6",
|
||||
"@novu/node": "^2.6.6",
|
||||
"@novu/react": "^3.10.1",
|
||||
"@radix-ui/react-accordion": "^1.2.11",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.14",
|
||||
"@radix-ui/react-aspect-ratio": "^1.1.7",
|
||||
@@ -160,6 +161,18 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@corvu/utils": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@corvu/utils/-/utils-0.4.2.tgz",
|
||||
"integrity": "sha512-Ox2kYyxy7NoXdKWdHeDEjZxClwzO4SKM8plAaVwmAJPxHMqA0rLOoAsa+hBDwRLpctf+ZRnAd/ykguuJidnaTA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.6.11"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
|
||||
@@ -852,6 +865,24 @@
|
||||
"url": "https://github.com/sponsors/nzakas"
|
||||
}
|
||||
},
|
||||
"node_modules/@internationalized/date": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.9.0.tgz",
|
||||
"integrity": "sha512-yaN3brAnHRD+4KyyOsJyk49XUvj2wtbNACSqg0bz3u8t2VuzhC8Q5dfRnrSxjnnbDb+ienBnkn1TzQfE154vyg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@swc/helpers": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@internationalized/number": {
|
||||
"version": "3.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.5.tgz",
|
||||
"integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@swc/helpers": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
@@ -923,6 +954,43 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@kobalte/core": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/@kobalte/core/-/core-0.13.11.tgz",
|
||||
"integrity": "sha512-hK7TYpdib/XDb/r/4XDBFaO9O+3ZHz4ZWryV4/3BfES+tSQVgg2IJupDnztKXB0BqbSRy/aWlHKw1SPtNPYCFQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.5.1",
|
||||
"@internationalized/date": "^3.4.0",
|
||||
"@internationalized/number": "^3.2.1",
|
||||
"@kobalte/utils": "^0.9.1",
|
||||
"@solid-primitives/props": "^3.1.8",
|
||||
"@solid-primitives/resize-observer": "^2.0.26",
|
||||
"solid-presence": "^0.1.8",
|
||||
"solid-prevent-scroll": "^0.1.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.8.15"
|
||||
}
|
||||
},
|
||||
"node_modules/@kobalte/utils": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@kobalte/utils/-/utils-0.9.1.tgz",
|
||||
"integrity": "sha512-eeU60A3kprIiBDAfv9gUJX1tXGLuZiKMajUfSQURAF2pk4ZoMYiqIzmrMBvzcxP39xnYttgTyQEVLwiTZnrV4w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/event-listener": "^2.2.14",
|
||||
"@solid-primitives/keyed": "^1.2.0",
|
||||
"@solid-primitives/map": "^0.4.7",
|
||||
"@solid-primitives/media": "^2.2.4",
|
||||
"@solid-primitives/props": "^3.1.8",
|
||||
"@solid-primitives/refs": "^1.0.5",
|
||||
"@solid-primitives/utils": "^6.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.8.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@marsidev/react-turnstile": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@marsidev/react-turnstile/-/react-turnstile-1.3.1.tgz",
|
||||
@@ -933,6 +1001,70 @@
|
||||
"react-dom": "^17.0.2 || ^18.0.0 || ^19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@motionone/animation": {
|
||||
"version": "10.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz",
|
||||
"integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@motionone/easing": "^10.18.0",
|
||||
"@motionone/types": "^10.17.1",
|
||||
"@motionone/utils": "^10.18.0",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@motionone/dom": {
|
||||
"version": "10.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.18.0.tgz",
|
||||
"integrity": "sha512-bKLP7E0eyO4B2UaHBBN55tnppwRnaE3KFfh3Ps9HhnAkar3Cb69kUCJY9as8LrccVYKgHA+JY5dOQqJLOPhF5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@motionone/animation": "^10.18.0",
|
||||
"@motionone/generators": "^10.18.0",
|
||||
"@motionone/types": "^10.17.1",
|
||||
"@motionone/utils": "^10.18.0",
|
||||
"hey-listen": "^1.0.8",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@motionone/easing": {
|
||||
"version": "10.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz",
|
||||
"integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@motionone/utils": "^10.18.0",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@motionone/generators": {
|
||||
"version": "10.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz",
|
||||
"integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@motionone/types": "^10.17.1",
|
||||
"@motionone/utils": "^10.18.0",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@motionone/types": {
|
||||
"version": "10.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz",
|
||||
"integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@motionone/utils": {
|
||||
"version": "10.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz",
|
||||
"integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@motionone/types": "^10.17.1",
|
||||
"hey-listen": "^1.0.8",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -1010,6 +1142,26 @@
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@novu/js": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@novu/js/-/js-3.10.1.tgz",
|
||||
"integrity": "sha512-ht8bwg5vPkmoNxHDbTqBMaAuNzO4bqhVpwxzbWLYUdauj2cPd3taI9yuvXYwln9C6utNe6O1UiEJECdJM8fafg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.6.13",
|
||||
"@kobalte/core": "^0.13.10",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"event-target-polyfill": "^0.0.4",
|
||||
"mitt": "^3.0.1",
|
||||
"partysocket": "^1.1.4",
|
||||
"socket.io-client": "4.7.2",
|
||||
"solid-floating-ui": "^0.3.1",
|
||||
"solid-js": "^1.9.4",
|
||||
"solid-motionone": "^1.0.3",
|
||||
"tailwind-merge": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@novu/node": {
|
||||
"version": "2.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@novu/node/-/node-2.6.6.tgz",
|
||||
@@ -1029,6 +1181,24 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@novu/react": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@novu/react/-/react-3.10.1.tgz",
|
||||
"integrity": "sha512-fG76i7AzNyKWNqXIn1WyFnK7L2l1zVuaONj3tAia/iVjhnt7uNNRv6K46D0JPu34464+fK0/dOSbqqr89Tpk7w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@novu/js": "3.10.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0 || ^19.0.0 || ^19.0.0-0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@novu/shared": {
|
||||
"version": "2.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@novu/shared/-/shared-2.6.6.tgz",
|
||||
@@ -2821,6 +2991,147 @@
|
||||
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@solid-primitives/event-listener": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/event-listener/-/event-listener-2.4.3.tgz",
|
||||
"integrity": "sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/utils": "^6.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/keyed": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/keyed/-/keyed-1.5.2.tgz",
|
||||
"integrity": "sha512-BgoEdqPw48URnI+L5sZIHdF4ua4Las1eWEBBPaoSFs42kkhnHue+rwCBPL2Z9ebOyQ75sUhUfOETdJfmv0D6Kg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/map": {
|
||||
"version": "0.4.13",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/map/-/map-0.4.13.tgz",
|
||||
"integrity": "sha512-B1zyFbsiTQvqPr+cuPCXO72sRuczG9Swncqk5P74NCGw1VE8qa/Ry9GlfI1e/VdeQYHjan+XkbE3rO2GW/qKew==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/trigger": "^1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/media": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/media/-/media-2.3.3.tgz",
|
||||
"integrity": "sha512-hQ4hLOGvfbugQi5Eu1BFWAIJGIAzztq9x0h02xgBGl2l0Jaa3h7tg6bz5tV1NSuNYVGio4rPoa7zVQQLkkx9dA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/event-listener": "^2.4.3",
|
||||
"@solid-primitives/rootless": "^1.5.2",
|
||||
"@solid-primitives/static-store": "^0.1.2",
|
||||
"@solid-primitives/utils": "^6.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/props": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/props/-/props-3.2.2.tgz",
|
||||
"integrity": "sha512-lZOTwFJajBrshSyg14nBMEP0h8MXzPowGO0s3OeiR3z6nXHTfj0FhzDtJMv+VYoRJKQHG2QRnJTgCzK6erARAw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/utils": "^6.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/refs": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/refs/-/refs-1.1.2.tgz",
|
||||
"integrity": "sha512-K7tf2thy7L+YJjdqXspXOg5xvNEOH8tgEWsp0+1mQk3obHBRD6hEjYZk7p7FlJphSZImS35je3UfmWuD7MhDfg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/utils": "^6.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/resize-observer": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/resize-observer/-/resize-observer-2.1.3.tgz",
|
||||
"integrity": "sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/event-listener": "^2.4.3",
|
||||
"@solid-primitives/rootless": "^1.5.2",
|
||||
"@solid-primitives/static-store": "^0.1.2",
|
||||
"@solid-primitives/utils": "^6.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/rootless": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/rootless/-/rootless-1.5.2.tgz",
|
||||
"integrity": "sha512-9HULb0QAzL2r47CCad0M+NKFtQ+LrGGNHZfteX/ThdGvKIg2o2GYhBooZubTCd/RTu2l2+Nw4s+dEfiDGvdrrQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/utils": "^6.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/static-store": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/static-store/-/static-store-0.1.2.tgz",
|
||||
"integrity": "sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/utils": "^6.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/transition-group": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/transition-group/-/transition-group-1.1.2.tgz",
|
||||
"integrity": "sha512-gnHS0OmcdjeoHN9n7Khu8KNrOlRc8a2weETDt2YT6o1zeW/XtUC6Db3Q9pkMU/9cCKdEmN4b0a/41MKAHRhzWA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/trigger": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/trigger/-/trigger-1.2.2.tgz",
|
||||
"integrity": "sha512-IWoptVc0SWYgmpBPpCMehS5b07+tpFcvw15tOQ3QbXedSYn6KP8zCjPkHNzMxcOvOicTneleeZDP7lqmz+PQ6g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solid-primitives/utils": "^6.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@solid-primitives/utils": {
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.3.2.tgz",
|
||||
"integrity": "sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/auth-js": {
|
||||
"version": "2.71.1",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.71.1.tgz",
|
||||
@@ -3111,6 +3422,15 @@
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"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/@swc/types": {
|
||||
"version": "0.1.23",
|
||||
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.23.tgz",
|
||||
@@ -5153,6 +5473,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/event-target-polyfill": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/event-target-polyfill/-/event-target-polyfill-0.0.4.tgz",
|
||||
"integrity": "sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||
@@ -5598,6 +5924,12 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/hey-listen": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
|
||||
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
@@ -6502,6 +6834,12 @@
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/mitt": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@@ -6735,6 +7073,15 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/partysocket": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/partysocket/-/partysocket-1.1.6.tgz",
|
||||
"integrity": "sha512-LkEk8N9hMDDsDT0iDK0zuwUDFVrVMUXFXCeN3850Ng8wtjPqPBeJlwdeY6ROlJSEh3tPoTTasXoSBYH76y118w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"event-target-polyfill": "^0.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
@@ -7443,6 +7790,27 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/seroval": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/seroval/-/seroval-1.3.2.tgz",
|
||||
"integrity": "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/seroval-plugins": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.3.3.tgz",
|
||||
"integrity": "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"seroval": "^1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/shallow-equal": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-3.1.0.tgz",
|
||||
@@ -7513,6 +7881,71 @@
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/solid-floating-ui": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/solid-floating-ui/-/solid-floating-ui-0.3.1.tgz",
|
||||
"integrity": "sha512-o/QmGsWPS2Z3KidAxP0nDvN7alI7Kqy0kU+wd85Fz+au5SYcnYm7I6Fk3M60Za35azsPX0U+5fEtqfOuk6Ao0Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@floating-ui/dom": "^1.5",
|
||||
"solid-js": "^1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/solid-js": {
|
||||
"version": "1.9.9",
|
||||
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.9.tgz",
|
||||
"integrity": "sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"csstype": "^3.1.0",
|
||||
"seroval": "~1.3.0",
|
||||
"seroval-plugins": "~1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/solid-motionone": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/solid-motionone/-/solid-motionone-1.0.4.tgz",
|
||||
"integrity": "sha512-aqEjgecoO9raDFznu/dEci7ORSmA26Kjj9J4Cn1Gyr0GZuOVdvsNxdxClTL9J40Aq/uYFx4GLwC8n70fMLHiuA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@motionone/dom": "^10.17.0",
|
||||
"@motionone/utils": "^10.17.0",
|
||||
"@solid-primitives/props": "^3.1.11",
|
||||
"@solid-primitives/refs": "^1.0.8",
|
||||
"@solid-primitives/transition-group": "^1.0.5",
|
||||
"csstype": "^3.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/solid-presence": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/solid-presence/-/solid-presence-0.1.8.tgz",
|
||||
"integrity": "sha512-pWGtXUFWYYUZNbg5YpG5vkQJyOtzn2KXhxYaMx/4I+lylTLYkITOLevaCwMRN+liCVk0pqB6EayLWojNqBFECA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@corvu/utils": "~0.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/solid-prevent-scroll": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/solid-prevent-scroll/-/solid-prevent-scroll-0.1.10.tgz",
|
||||
"integrity": "sha512-KplGPX2GHiWJLZ6AXYRql4M127PdYzfwvLJJXMkO+CMb8Np4VxqDAg5S8jLdwlEuBis/ia9DKw2M8dFx5u8Mhw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@corvu/utils": "~0.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/sonner": {
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/sonner/-/sonner-1.7.4.tgz",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"@marsidev/react-turnstile": "^1.3.1",
|
||||
"@novu/headless": "^2.6.6",
|
||||
"@novu/node": "^2.6.6",
|
||||
"@novu/react": "^3.10.1",
|
||||
"@radix-ui/react-accordion": "^1.2.11",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.14",
|
||||
"@radix-ui/react-aspect-ratio": "^1.1.7",
|
||||
|
||||
@@ -1,94 +1,30 @@
|
||||
import { useState } from 'react';
|
||||
import { Bell } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@/components/ui/popover';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
import { Inbox } from '@novu/react';
|
||||
import { useNovuNotifications } from '@/hooks/useNovuNotifications';
|
||||
import { Separator } from '@/components/ui/separator';
|
||||
import { useNovuTheme } from '@/hooks/useNovuTheme';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
export function NotificationCenter() {
|
||||
const { notifications, unreadCount, markAsRead, markAllAsRead, isEnabled } = useNovuNotifications();
|
||||
const [open, setOpen] = useState(false);
|
||||
const { applicationIdentifier, subscriberId, isEnabled } = useNovuNotifications();
|
||||
const appearance = useNovuTheme();
|
||||
const navigate = useNavigate();
|
||||
|
||||
if (!isEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleNotificationClick = (notification: any) => {
|
||||
// Handle navigation based on notification payload
|
||||
if (notification.data?.url) {
|
||||
navigate(notification.data.url);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="ghost" size="icon" className="relative">
|
||||
<Bell className="h-5 w-5" />
|
||||
{unreadCount > 0 && (
|
||||
<Badge
|
||||
variant="destructive"
|
||||
className="absolute -top-1 -right-1 h-5 w-5 rounded-full p-0 flex items-center justify-center text-xs"
|
||||
>
|
||||
{unreadCount > 9 ? '9+' : unreadCount}
|
||||
</Badge>
|
||||
)}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-80 p-0" align="end">
|
||||
<div className="flex items-center justify-between p-4 border-b">
|
||||
<h3 className="font-semibold">Notifications</h3>
|
||||
{unreadCount > 0 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={markAllAsRead}
|
||||
className="text-xs"
|
||||
>
|
||||
Mark all as read
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<ScrollArea className="h-[400px]">
|
||||
{notifications.length === 0 ? (
|
||||
<div className="p-8 text-center text-muted-foreground">
|
||||
<Bell className="h-8 w-8 mx-auto mb-2 opacity-50" />
|
||||
<p className="text-sm">No notifications yet</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="divide-y">
|
||||
{notifications.map((notification) => (
|
||||
<div
|
||||
key={notification.id}
|
||||
className={`p-4 cursor-pointer hover:bg-muted/50 transition-colors ${
|
||||
!notification.read ? 'bg-muted/30' : ''
|
||||
}`}
|
||||
onClick={() => {
|
||||
if (!notification.read) {
|
||||
markAsRead(notification.id);
|
||||
}
|
||||
// Handle CTA action if exists
|
||||
if (notification.cta) {
|
||||
// Navigate or perform action based on notification.cta
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
{!notification.read && (
|
||||
<div className="w-2 h-2 rounded-full bg-primary mt-1.5 flex-shrink-0" />
|
||||
)}
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm break-words">{notification.content}</p>
|
||||
<p className="text-xs text-muted-foreground mt-1">
|
||||
{new Date(notification.createdAt).toLocaleString()}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</ScrollArea>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<Inbox
|
||||
applicationIdentifier={applicationIdentifier}
|
||||
subscriberId={subscriberId}
|
||||
appearance={appearance}
|
||||
onNotificationClick={handleNotificationClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,55 +1,15 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
|
||||
export interface NotificationItem {
|
||||
id: string;
|
||||
content: string;
|
||||
read: boolean;
|
||||
createdAt: string;
|
||||
cta?: {
|
||||
type: string;
|
||||
data: any;
|
||||
};
|
||||
}
|
||||
|
||||
export function useNovuNotifications() {
|
||||
const { user } = useAuth();
|
||||
const [notifications, setNotifications] = useState<NotificationItem[]>([]);
|
||||
const [unreadCount, setUnreadCount] = useState(0);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const applicationIdentifier = import.meta.env.VITE_NOVU_APPLICATION_IDENTIFIER;
|
||||
const isEnabled = !!applicationIdentifier && !!user;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isEnabled) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Initialize Novu Headless SDK when configuration is complete
|
||||
// This will require the @novu/headless package to be properly configured
|
||||
setIsLoading(false);
|
||||
}, [isEnabled, user]);
|
||||
|
||||
const markAsRead = async (notificationId: string) => {
|
||||
setNotifications((prev) =>
|
||||
prev.map((n) => (n.id === notificationId ? { ...n, read: true } : n))
|
||||
);
|
||||
setUnreadCount((prev) => Math.max(0, prev - 1));
|
||||
};
|
||||
|
||||
const markAllAsRead = async () => {
|
||||
setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
|
||||
setUnreadCount(0);
|
||||
};
|
||||
const subscriberId = user?.id;
|
||||
const isEnabled = !!applicationIdentifier && !!subscriberId;
|
||||
|
||||
return {
|
||||
notifications,
|
||||
unreadCount,
|
||||
isLoading,
|
||||
markAsRead,
|
||||
markAllAsRead,
|
||||
applicationIdentifier,
|
||||
subscriberId,
|
||||
isEnabled,
|
||||
};
|
||||
}
|
||||
|
||||
131
src/hooks/useNovuTheme.ts
Normal file
131
src/hooks/useNovuTheme.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { useTheme } from '@/components/theme/ThemeProvider';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export function useNovuTheme() {
|
||||
const { theme } = useTheme();
|
||||
|
||||
const appearance = useMemo(() => {
|
||||
// Get computed styles to access CSS variables
|
||||
const root = document.documentElement;
|
||||
const style = getComputedStyle(root);
|
||||
|
||||
return {
|
||||
variables: {
|
||||
// Colors
|
||||
colorBackground: `hsl(var(--background))`,
|
||||
colorForeground: `hsl(var(--foreground))`,
|
||||
colorPrimary: `hsl(var(--primary))`,
|
||||
colorPrimaryForeground: `hsl(var(--primary-foreground))`,
|
||||
colorSecondary: `hsl(var(--secondary))`,
|
||||
colorSecondaryForeground: `hsl(var(--secondary-foreground))`,
|
||||
colorCounter: `hsl(var(--primary))`,
|
||||
colorCounterForeground: `hsl(var(--primary-foreground))`,
|
||||
|
||||
// Notification item colors
|
||||
colorNeutral: `hsl(var(--muted))`,
|
||||
colorNeutralForeground: `hsl(var(--muted-foreground))`,
|
||||
|
||||
// Border and divider
|
||||
colorBorder: `hsl(var(--border))`,
|
||||
|
||||
// Border radius
|
||||
borderRadius: `var(--radius)`,
|
||||
|
||||
// Font
|
||||
fontFamily: style.getPropertyValue('font-family') || 'inherit',
|
||||
fontSize: '14px',
|
||||
},
|
||||
elements: {
|
||||
bellContainer: {
|
||||
width: '40px',
|
||||
height: '40px',
|
||||
},
|
||||
bell: {
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
color: `hsl(var(--foreground))`,
|
||||
},
|
||||
bellDot: {
|
||||
backgroundColor: `hsl(var(--primary))`,
|
||||
},
|
||||
popover: {
|
||||
boxShadow: `var(--shadow-card)`,
|
||||
border: `1px solid hsl(var(--border))`,
|
||||
borderRadius: `calc(var(--radius) + 4px)`,
|
||||
},
|
||||
notificationItem: {
|
||||
transition: 'var(--transition-smooth)',
|
||||
'&:hover': {
|
||||
backgroundColor: `hsl(var(--muted) / 0.5)`,
|
||||
},
|
||||
},
|
||||
notificationItemRead: {
|
||||
opacity: '0.7',
|
||||
},
|
||||
notificationItemUnread: {
|
||||
backgroundColor: `hsl(var(--muted) / 0.3)`,
|
||||
borderLeft: `3px solid hsl(var(--primary))`,
|
||||
},
|
||||
notificationDot: {
|
||||
backgroundColor: `hsl(var(--primary))`,
|
||||
width: '8px',
|
||||
height: '8px',
|
||||
},
|
||||
notificationTitle: {
|
||||
fontWeight: '500',
|
||||
color: `hsl(var(--foreground))`,
|
||||
},
|
||||
notificationDescription: {
|
||||
color: `hsl(var(--muted-foreground))`,
|
||||
},
|
||||
notificationTimestamp: {
|
||||
fontSize: '12px',
|
||||
color: `hsl(var(--muted-foreground))`,
|
||||
},
|
||||
notificationPrimaryAction: {
|
||||
backgroundColor: `hsl(var(--primary))`,
|
||||
color: `hsl(var(--primary-foreground))`,
|
||||
borderRadius: `var(--radius)`,
|
||||
padding: '8px 16px',
|
||||
transition: 'var(--transition-smooth)',
|
||||
'&:hover': {
|
||||
opacity: '0.9',
|
||||
},
|
||||
},
|
||||
notificationSecondaryAction: {
|
||||
backgroundColor: `hsl(var(--secondary))`,
|
||||
color: `hsl(var(--secondary-foreground))`,
|
||||
borderRadius: `var(--radius)`,
|
||||
padding: '8px 16px',
|
||||
transition: 'var(--transition-smooth)',
|
||||
'&:hover': {
|
||||
backgroundColor: `hsl(var(--secondary) / 0.8)`,
|
||||
},
|
||||
},
|
||||
loader: {
|
||||
color: `hsl(var(--primary))`,
|
||||
},
|
||||
emptyNotifications: {
|
||||
color: `hsl(var(--muted-foreground))`,
|
||||
textAlign: 'center',
|
||||
padding: '32px 16px',
|
||||
},
|
||||
header: {
|
||||
borderBottom: `1px solid hsl(var(--border))`,
|
||||
padding: '16px',
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: '16px',
|
||||
fontWeight: '600',
|
||||
color: `hsl(var(--foreground))`,
|
||||
},
|
||||
footer: {
|
||||
borderTop: `1px solid hsl(var(--border))`,
|
||||
padding: '12px 16px',
|
||||
},
|
||||
},
|
||||
};
|
||||
}, [theme]);
|
||||
|
||||
return appearance;
|
||||
}
|
||||
Reference in New Issue
Block a user