mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-19 05:54:06 +01:00
Merge pull request #53 from Sosokker/back-end
feat: add payment system and base code in business application
This commit is contained in:
commit
a4ae54127a
603
package-lock.json
generated
603
package-lock.json
generated
@ -21,6 +21,8 @@
|
|||||||
"@radix-ui/react-slot": "^1.1.0",
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"@radix-ui/react-tabs": "^1.1.0",
|
"@radix-ui/react-tabs": "^1.1.0",
|
||||||
"@radix-ui/react-tooltip": "^1.1.2",
|
"@radix-ui/react-tooltip": "^1.1.2",
|
||||||
|
"@stripe/react-stripe-js": "^2.8.1",
|
||||||
|
"@stripe/stripe-js": "^4.7.0",
|
||||||
"@supabase-cache-helpers/postgrest-react-query": "^1.10.1",
|
"@supabase-cache-helpers/postgrest-react-query": "^1.10.1",
|
||||||
"@supabase/ssr": "^0.4.1",
|
"@supabase/ssr": "^0.4.1",
|
||||||
"@supabase/supabase-js": "^2.45.2",
|
"@supabase/supabase-js": "^2.45.2",
|
||||||
@ -33,7 +35,7 @@
|
|||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"embla-carousel-react": "^8.2.0",
|
"embla-carousel-react": "^8.2.0",
|
||||||
"lucide-react": "^0.428.0",
|
"lucide-react": "^0.428.0",
|
||||||
"next": "14.2.5",
|
"next": "^14.2.15",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-countup": "^6.5.3",
|
"react-countup": "^6.5.3",
|
||||||
@ -41,18 +43,21 @@
|
|||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
"react-markdown": "^9.0.1",
|
"react-markdown": "^9.0.1",
|
||||||
"recharts": "^2.12.7",
|
"recharts": "^2.12.7",
|
||||||
|
"stripe": "^17.1.0",
|
||||||
"tailwind-merge": "^2.5.2",
|
"tailwind-merge": "^2.5.2",
|
||||||
"tailwindcss-animate": "^1.0.7"
|
"tailwindcss-animate": "^1.0.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.47.2",
|
"@playwright/test": "^1.47.2",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.15",
|
||||||
|
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "14.2.5",
|
"eslint-config-next": "14.2.5",
|
||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
"supabase": "^1.200.3",
|
"supabase": "^1.200.3",
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
@ -69,6 +74,271 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/code-frame": {
|
||||||
|
"version": "7.25.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz",
|
||||||
|
"integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/highlight": "^7.25.7",
|
||||||
|
"picocolors": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/generator": {
|
||||||
|
"version": "7.17.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz",
|
||||||
|
"integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.17.0",
|
||||||
|
"jsesc": "^2.5.1",
|
||||||
|
"source-map": "^0.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-environment-visitor": {
|
||||||
|
"version": "7.24.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
|
||||||
|
"integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.24.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-environment-visitor/node_modules/@babel/types": {
|
||||||
|
"version": "7.25.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
|
||||||
|
"integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": "^7.25.7",
|
||||||
|
"@babel/helper-validator-identifier": "^7.25.7",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-function-name": {
|
||||||
|
"version": "7.24.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
|
||||||
|
"integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/template": "^7.24.7",
|
||||||
|
"@babel/types": "^7.24.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-function-name/node_modules/@babel/types": {
|
||||||
|
"version": "7.25.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
|
||||||
|
"integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": "^7.25.7",
|
||||||
|
"@babel/helper-validator-identifier": "^7.25.7",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-hoist-variables": {
|
||||||
|
"version": "7.24.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz",
|
||||||
|
"integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.24.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-hoist-variables/node_modules/@babel/types": {
|
||||||
|
"version": "7.25.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
|
||||||
|
"integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": "^7.25.7",
|
||||||
|
"@babel/helper-validator-identifier": "^7.25.7",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-split-export-declaration": {
|
||||||
|
"version": "7.24.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
|
||||||
|
"integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.24.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-split-export-declaration/node_modules/@babel/types": {
|
||||||
|
"version": "7.25.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
|
||||||
|
"integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": "^7.25.7",
|
||||||
|
"@babel/helper-validator-identifier": "^7.25.7",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-string-parser": {
|
||||||
|
"version": "7.25.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz",
|
||||||
|
"integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-validator-identifier": {
|
||||||
|
"version": "7.25.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz",
|
||||||
|
"integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight": {
|
||||||
|
"version": "7.25.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz",
|
||||||
|
"integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-validator-identifier": "^7.25.7",
|
||||||
|
"chalk": "^2.4.2",
|
||||||
|
"js-tokens": "^4.0.0",
|
||||||
|
"picocolors": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^1.9.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/chalk": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^3.2.1",
|
||||||
|
"escape-string-regexp": "^1.0.5",
|
||||||
|
"supports-color": "^5.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/color-convert": {
|
||||||
|
"version": "1.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
|
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/color-name": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/parser": {
|
||||||
|
"version": "7.25.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz",
|
||||||
|
"integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.25.8"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"parser": "bin/babel-parser.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/parser/node_modules/@babel/types": {
|
||||||
|
"version": "7.25.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
|
||||||
|
"integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": "^7.25.7",
|
||||||
|
"@babel/helper-validator-identifier": "^7.25.7",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.25.6",
|
"version": "7.25.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
|
||||||
@ -92,6 +362,118 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/template": {
|
||||||
|
"version": "7.25.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz",
|
||||||
|
"integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/code-frame": "^7.25.7",
|
||||||
|
"@babel/parser": "^7.25.7",
|
||||||
|
"@babel/types": "^7.25.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/template/node_modules/@babel/types": {
|
||||||
|
"version": "7.25.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
|
||||||
|
"integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": "^7.25.7",
|
||||||
|
"@babel/helper-validator-identifier": "^7.25.7",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/traverse": {
|
||||||
|
"version": "7.23.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
|
||||||
|
"integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/code-frame": "^7.22.13",
|
||||||
|
"@babel/generator": "^7.23.0",
|
||||||
|
"@babel/helper-environment-visitor": "^7.22.20",
|
||||||
|
"@babel/helper-function-name": "^7.23.0",
|
||||||
|
"@babel/helper-hoist-variables": "^7.22.5",
|
||||||
|
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||||
|
"@babel/parser": "^7.23.0",
|
||||||
|
"@babel/types": "^7.23.0",
|
||||||
|
"debug": "^4.1.0",
|
||||||
|
"globals": "^11.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/traverse/node_modules/@babel/generator": {
|
||||||
|
"version": "7.25.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz",
|
||||||
|
"integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.25.7",
|
||||||
|
"@jridgewell/gen-mapping": "^0.3.5",
|
||||||
|
"@jridgewell/trace-mapping": "^0.3.25",
|
||||||
|
"jsesc": "^3.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/traverse/node_modules/@babel/types": {
|
||||||
|
"version": "7.25.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
|
||||||
|
"integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": "^7.25.7",
|
||||||
|
"@babel/helper-validator-identifier": "^7.25.7",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/traverse/node_modules/globals": {
|
||||||
|
"version": "11.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||||
|
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/traverse/node_modules/jsesc": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"jsesc": "bin/jsesc"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/types": {
|
||||||
|
"version": "7.17.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz",
|
||||||
|
"integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-validator-identifier": "^7.16.7",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||||
@ -314,9 +696,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/env": {
|
"node_modules/@next/env": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.15.tgz",
|
||||||
"integrity": "sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA=="
|
"integrity": "sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@next/eslint-plugin-next": {
|
"node_modules/@next/eslint-plugin-next": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.5",
|
||||||
@ -328,9 +710,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-darwin-arm64": {
|
"node_modules/@next/swc-darwin-arm64": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.15.tgz",
|
||||||
"integrity": "sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==",
|
"integrity": "sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -343,9 +725,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-darwin-x64": {
|
"node_modules/@next/swc-darwin-x64": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.15.tgz",
|
||||||
"integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==",
|
"integrity": "sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -358,9 +740,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.15.tgz",
|
||||||
"integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==",
|
"integrity": "sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -373,9 +755,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-arm64-musl": {
|
"node_modules/@next/swc-linux-arm64-musl": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.15.tgz",
|
||||||
"integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==",
|
"integrity": "sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -388,9 +770,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-x64-gnu": {
|
"node_modules/@next/swc-linux-x64-gnu": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.15.tgz",
|
||||||
"integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==",
|
"integrity": "sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -403,9 +785,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-x64-musl": {
|
"node_modules/@next/swc-linux-x64-musl": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.15.tgz",
|
||||||
"integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==",
|
"integrity": "sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -418,9 +800,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.15.tgz",
|
||||||
"integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==",
|
"integrity": "sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -433,9 +815,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-ia32-msvc": {
|
"node_modules/@next/swc-win32-ia32-msvc": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.15.tgz",
|
||||||
"integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==",
|
"integrity": "sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@ -448,9 +830,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-x64-msvc": {
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.15.tgz",
|
||||||
"integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==",
|
"integrity": "sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -1464,6 +1846,27 @@
|
|||||||
"integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==",
|
"integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@stripe/react-stripe-js": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-C410jVKOATinXLalWotab6E6jlWAlbqUDWL9q1km0p5UHrvnihjjYzA8imYXc4xc4Euf9GeKDQc4n35HKZvgwg==",
|
||||||
|
"dependencies": {
|
||||||
|
"prop-types": "^15.7.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@stripe/stripe-js": "^1.44.1 || ^2.0.0 || ^3.0.0 || ^4.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@stripe/stripe-js": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-Dfdg8UumBu+zDnBgGw30zEE9PIm8lunDUuwy2Bois9bb2sxCohVbD1PpAnasPIZhYfIbigmTHEr/Hg+56Vue6A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@supabase-cache-helpers/postgrest-core": {
|
"node_modules/@supabase-cache-helpers/postgrest-core": {
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@supabase-cache-helpers/postgrest-core/-/postgrest-core-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@supabase-cache-helpers/postgrest-core/-/postgrest-core-0.8.1.tgz",
|
||||||
@ -1665,6 +2068,29 @@
|
|||||||
"react": "^18 || ^19"
|
"react": "^18 || ^19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@trivago/prettier-plugin-sort-imports": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/generator": "7.17.7",
|
||||||
|
"@babel/parser": "^7.20.5",
|
||||||
|
"@babel/traverse": "7.23.2",
|
||||||
|
"@babel/types": "7.17.0",
|
||||||
|
"javascript-natural-sort": "0.7.1",
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vue/compiler-sfc": "3.x",
|
||||||
|
"prettier": "2.x - 3.x"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@vue/compiler-sfc": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/d3-array": {
|
"node_modules/@types/d3-array": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
|
||||||
@ -2345,7 +2771,6 @@
|
|||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-define-property": "^1.0.0",
|
"es-define-property": "^1.0.0",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@ -2892,7 +3317,6 @@
|
|||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-define-property": "^1.0.0",
|
"es-define-property": "^1.0.0",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@ -3113,7 +3537,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
|
||||||
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"get-intrinsic": "^1.2.4"
|
"get-intrinsic": "^1.2.4"
|
||||||
},
|
},
|
||||||
@ -3125,7 +3548,6 @@
|
|||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
@ -3928,7 +4350,6 @@
|
|||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
"function-bind": "^1.1.2",
|
"function-bind": "^1.1.2",
|
||||||
@ -4097,7 +4518,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||||
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"get-intrinsic": "^1.1.3"
|
"get-intrinsic": "^1.1.3"
|
||||||
},
|
},
|
||||||
@ -4138,7 +4558,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-define-property": "^1.0.0"
|
"es-define-property": "^1.0.0"
|
||||||
},
|
},
|
||||||
@ -4150,7 +4569,6 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
|
||||||
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
|
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@ -4162,7 +4580,6 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@ -4834,6 +5251,12 @@
|
|||||||
"@pkgjs/parseargs": "^0.11.0"
|
"@pkgjs/parseargs": "^0.11.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/javascript-natural-sort": {
|
||||||
|
"version": "0.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
|
||||||
|
"integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/jiti": {
|
"node_modules/jiti": {
|
||||||
"version": "1.21.6",
|
"version": "1.21.6",
|
||||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
|
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
|
||||||
@ -4859,6 +5282,18 @@
|
|||||||
"js-yaml": "bin/js-yaml.js"
|
"js-yaml": "bin/js-yaml.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jsesc": {
|
||||||
|
"version": "2.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
||||||
|
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"jsesc": "bin/jsesc"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/json-buffer": {
|
"node_modules/json-buffer": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||||
@ -5738,11 +6173,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/next": {
|
"node_modules/next": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/next/-/next-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/next/-/next-14.2.15.tgz",
|
||||||
"integrity": "sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==",
|
"integrity": "sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next/env": "14.2.5",
|
"@next/env": "14.2.15",
|
||||||
"@swc/helpers": "0.5.5",
|
"@swc/helpers": "0.5.5",
|
||||||
"busboy": "1.6.0",
|
"busboy": "1.6.0",
|
||||||
"caniuse-lite": "^1.0.30001579",
|
"caniuse-lite": "^1.0.30001579",
|
||||||
@ -5757,15 +6192,15 @@
|
|||||||
"node": ">=18.17.0"
|
"node": ">=18.17.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@next/swc-darwin-arm64": "14.2.5",
|
"@next/swc-darwin-arm64": "14.2.15",
|
||||||
"@next/swc-darwin-x64": "14.2.5",
|
"@next/swc-darwin-x64": "14.2.15",
|
||||||
"@next/swc-linux-arm64-gnu": "14.2.5",
|
"@next/swc-linux-arm64-gnu": "14.2.15",
|
||||||
"@next/swc-linux-arm64-musl": "14.2.5",
|
"@next/swc-linux-arm64-musl": "14.2.15",
|
||||||
"@next/swc-linux-x64-gnu": "14.2.5",
|
"@next/swc-linux-x64-gnu": "14.2.15",
|
||||||
"@next/swc-linux-x64-musl": "14.2.5",
|
"@next/swc-linux-x64-musl": "14.2.15",
|
||||||
"@next/swc-win32-arm64-msvc": "14.2.5",
|
"@next/swc-win32-arm64-msvc": "14.2.15",
|
||||||
"@next/swc-win32-ia32-msvc": "14.2.5",
|
"@next/swc-win32-ia32-msvc": "14.2.15",
|
||||||
"@next/swc-win32-x64-msvc": "14.2.5"
|
"@next/swc-win32-x64-msvc": "14.2.15"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@opentelemetry/api": "^1.1.0",
|
"@opentelemetry/api": "^1.1.0",
|
||||||
@ -5896,7 +6331,6 @@
|
|||||||
"version": "1.13.2",
|
"version": "1.13.2",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
|
||||||
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
|
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@ -6384,6 +6818,21 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prettier": {
|
||||||
|
"version": "3.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
|
||||||
|
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"prettier": "bin/prettier.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prop-types": {
|
"node_modules/prop-types": {
|
||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
@ -6412,6 +6861,20 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||||
|
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.0.6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
@ -6900,7 +7363,6 @@
|
|||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"define-data-property": "^1.1.4",
|
"define-data-property": "^1.1.4",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@ -6951,7 +7413,6 @@
|
|||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
||||||
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
|
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.7",
|
"call-bind": "^1.0.7",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@ -6985,6 +7446,15 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/source-map": {
|
||||||
|
"version": "0.5.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||||
|
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
@ -7234,6 +7704,18 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/stripe": {
|
||||||
|
"version": "17.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/stripe/-/stripe-17.1.0.tgz",
|
||||||
|
"integrity": "sha512-sNRsJx7LPP2Gg6cBJoHJqhr+UoBVZZRes2BDqbrg+1FDBxJc4Yn+LkrpJ/VnL3XQ3+6I5GrOUnSSFfE/joDFjw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": ">=8.1.0",
|
||||||
|
"qs": "^6.11.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/style-to-object": {
|
"node_modules/style-to-object": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz",
|
||||||
@ -7436,6 +7918,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
|
||||||
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
|
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/to-fast-properties": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
|||||||
@ -22,6 +22,8 @@
|
|||||||
"@radix-ui/react-slot": "^1.1.0",
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"@radix-ui/react-tabs": "^1.1.0",
|
"@radix-ui/react-tabs": "^1.1.0",
|
||||||
"@radix-ui/react-tooltip": "^1.1.2",
|
"@radix-ui/react-tooltip": "^1.1.2",
|
||||||
|
"@stripe/react-stripe-js": "^2.8.1",
|
||||||
|
"@stripe/stripe-js": "^4.7.0",
|
||||||
"@supabase-cache-helpers/postgrest-react-query": "^1.10.1",
|
"@supabase-cache-helpers/postgrest-react-query": "^1.10.1",
|
||||||
"@supabase/ssr": "^0.4.1",
|
"@supabase/ssr": "^0.4.1",
|
||||||
"@supabase/supabase-js": "^2.45.2",
|
"@supabase/supabase-js": "^2.45.2",
|
||||||
@ -34,7 +36,7 @@
|
|||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"embla-carousel-react": "^8.2.0",
|
"embla-carousel-react": "^8.2.0",
|
||||||
"lucide-react": "^0.428.0",
|
"lucide-react": "^0.428.0",
|
||||||
"next": "14.2.5",
|
"next": "^14.2.15",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-countup": "^6.5.3",
|
"react-countup": "^6.5.3",
|
||||||
@ -42,18 +44,21 @@
|
|||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
"react-markdown": "^9.0.1",
|
"react-markdown": "^9.0.1",
|
||||||
"recharts": "^2.12.7",
|
"recharts": "^2.12.7",
|
||||||
|
"stripe": "^17.1.0",
|
||||||
"tailwind-merge": "^2.5.2",
|
"tailwind-merge": "^2.5.2",
|
||||||
"tailwindcss-animate": "^1.0.7"
|
"tailwindcss-animate": "^1.0.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.47.2",
|
"@playwright/test": "^1.47.2",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.15",
|
||||||
|
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "14.2.5",
|
"eslint-config-next": "14.2.5",
|
||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
"supabase": "^1.200.3",
|
"supabase": "^1.200.3",
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
|
|||||||
161
src/app/(investment)/invest/[id]/checkoutPage.tsx
Normal file
161
src/app/(investment)/invest/[id]/checkoutPage.tsx
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { useStripe, useElements, CardElement } from "@stripe/react-stripe-js";
|
||||||
|
import convertToSubcurrency from "@/lib/convertToSubcurrency";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
DialogFooter,
|
||||||
|
DialogClose,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import useSession from "@/lib/supabase/useSession";
|
||||||
|
import { createSupabaseClient } from "@/lib/supabase/clientComponentClient";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
|
const CheckoutPage = ({
|
||||||
|
amount,
|
||||||
|
project_id,
|
||||||
|
investor_id,
|
||||||
|
isAcceptTermAndService,
|
||||||
|
}: {
|
||||||
|
amount: number;
|
||||||
|
project_id: number;
|
||||||
|
investor_id: string;
|
||||||
|
isAcceptTermAndService: () => boolean;
|
||||||
|
}) => {
|
||||||
|
const stripe = useStripe();
|
||||||
|
const elements = useElements();
|
||||||
|
const [errorMessage, setErrorMessage] = useState<string>();
|
||||||
|
const [clientSecret, setClientSecret] = useState("");
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||||
|
const isAcceptTerm = isAcceptTermAndService();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const { session } = useSession();
|
||||||
|
const user = session?.user;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch("/api/create-payment-intent", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ amount: convertToSubcurrency(amount) }),
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => setClientSecret(data.clientSecret));
|
||||||
|
}, [amount]);
|
||||||
|
|
||||||
|
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
event.preventDefault();
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
if (!stripe || !elements) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { error: submitError } = await elements.submit();
|
||||||
|
|
||||||
|
if (submitError) {
|
||||||
|
setErrorMessage(submitError.message);
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await stripe
|
||||||
|
.confirmCardPayment(clientSecret, {
|
||||||
|
payment_method: {
|
||||||
|
card: elements.getElement(CardElement)!,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(async (result) => {
|
||||||
|
if (result.error) {
|
||||||
|
setErrorMessage(result.error.message);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const supabase = createSupabaseClient();
|
||||||
|
const { data, error } = await supabase.from("investment_deal").insert([
|
||||||
|
{
|
||||||
|
investor_id: investor_id,
|
||||||
|
project_id: project_id,
|
||||||
|
deal_amount: amount,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error("Supabase Insert Error:", error.message);
|
||||||
|
} else {
|
||||||
|
console.log("Insert successful:", data);
|
||||||
|
router.push(`http://www.localhost:3000/payment-success?amount=${amount}`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Unexpected error during Supabase insert:", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!clientSecret || !stripe || !elements) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center">
|
||||||
|
<div
|
||||||
|
className="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-e-transparent align-[-0.125em] text-surface motion-reduce:animate-[spin_1.5s_linear_infinite] dark:text-white"
|
||||||
|
role="status">
|
||||||
|
<span className="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]">
|
||||||
|
Loading...
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{clientSecret && <CardElement />}
|
||||||
|
|
||||||
|
{errorMessage && <div>{errorMessage}</div>}
|
||||||
|
|
||||||
|
{/* Trigger the dialog when the "Pay" button is clicked */}
|
||||||
|
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setIsDialogOpen(true)}
|
||||||
|
disabled={!stripe || loading}
|
||||||
|
className="text-white w-full p-5 bg-black mt-2 rounded-md font-bold disabled:opacity-50 disabled:animate-pulse">
|
||||||
|
{!loading ? `Pay $${amount}` : "Processing..."}
|
||||||
|
</button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Are you sure you want to proceed with the investment?</DialogTitle>
|
||||||
|
<DialogDescription>This action cannot be undone, and the investment will be confirmed.</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<DialogFooter>
|
||||||
|
<form onSubmit={handleSubmit} className="bg-white p-2 rounded-md">
|
||||||
|
<Button type="submit" disabled={!isAcceptTerm}>
|
||||||
|
Confirm Payment
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
<DialogClose asChild>
|
||||||
|
<Button type="button" variant="secondary">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DialogClose>
|
||||||
|
</DialogFooter>
|
||||||
|
{errorMessage && <p className="text-red-500 mt-2 text-lg font-bold">{errorMessage}</p>}
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CheckoutPage;
|
||||||
155
src/app/(investment)/invest/[id]/page.tsx
Normal file
155
src/app/(investment)/invest/[id]/page.tsx
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useParams } from "next/navigation";
|
||||||
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
|
import { useQuery } from "@supabase-cache-helpers/postgrest-react-query";
|
||||||
|
|
||||||
|
import convertToSubcurrency from "@/lib/convertToSubcurrency";
|
||||||
|
import CheckoutPage from "./checkoutPage";
|
||||||
|
import { Elements } from "@stripe/react-stripe-js";
|
||||||
|
import { loadStripe } from "@stripe/stripe-js";
|
||||||
|
|
||||||
|
import { getProjectDataQuery } from "@/lib/data/projectQuery";
|
||||||
|
import { createSupabaseClient } from "@/lib/supabase/clientComponentClient";
|
||||||
|
import useSession from "@/lib/supabase/useSession";
|
||||||
|
|
||||||
|
if (process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY === undefined) {
|
||||||
|
throw new Error("NEXT_PUBLIC_STRIPE_PUBLIC_KEY is not defined");
|
||||||
|
}
|
||||||
|
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY);
|
||||||
|
|
||||||
|
const term_data = [
|
||||||
|
{
|
||||||
|
term: "Minimum Investment",
|
||||||
|
description: "The minimum investment amount is $500.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
term: "Investment Horizon",
|
||||||
|
description: "Investments are typically locked for a minimum of 12 months.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
term: "Fees",
|
||||||
|
description: "A management fee of 2% will be applied annually.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
term: "Returns",
|
||||||
|
description: "Expected annual returns are between 8% and 12%.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
term: "Risk Disclosure",
|
||||||
|
description: "Investments carry risks, including the loss of principal.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
term: "Withdrawal Policy",
|
||||||
|
description: "Withdrawals can be made after the lock-in period.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function InvestPage() {
|
||||||
|
const [checkedTerms, setCheckedTerms] = useState(Array(term_data.length).fill(false));
|
||||||
|
const [investAmount, setInvestAmount] = useState(10);
|
||||||
|
const [investor_id, setInvestorId] = useState<string>("");
|
||||||
|
|
||||||
|
const params = useParams<{ id: string }>();
|
||||||
|
const supabase = createSupabaseClient();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchInvestorData = async () => {
|
||||||
|
const { data, error } = await supabase.auth.getSession();
|
||||||
|
if (error) {
|
||||||
|
console.error("Error fetching session:", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.session) {
|
||||||
|
setInvestorId(data.session.user.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchInvestorData();
|
||||||
|
}, [supabase]);
|
||||||
|
|
||||||
|
const { data: projectData, isLoading: isLoadingProject } = useQuery(getProjectDataQuery(supabase, Number(params.id)));
|
||||||
|
|
||||||
|
const handleCheckboxChange = (index: number) => {
|
||||||
|
const updatedCheckedTerms = [...checkedTerms];
|
||||||
|
updatedCheckedTerms[index] = !updatedCheckedTerms[index];
|
||||||
|
setCheckedTerms(updatedCheckedTerms);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isAcceptTermAndService = () => {
|
||||||
|
if (checkedTerms.some((checked) => !checked)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mx-10 md:mx-40 my-10">
|
||||||
|
<h1 className="text-2xl md:text-4xl font-bold">Invest on ${projectData?.project_name}</h1>
|
||||||
|
<Separator className="my-4" />
|
||||||
|
<div></div>
|
||||||
|
<div>
|
||||||
|
<div className="w-1/2 space-y-2">
|
||||||
|
<h2 className="text:base md:text-2xl">Investment Amount</h2>
|
||||||
|
<Input
|
||||||
|
className="w-52"
|
||||||
|
type="number"
|
||||||
|
placeholder="min $10"
|
||||||
|
min={10}
|
||||||
|
onChangeCapture={(e) => setInvestAmount(Number(e.currentTarget.value))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Separator className="my-4" />
|
||||||
|
|
||||||
|
<div className=" md:w-2/3 space-y-2">
|
||||||
|
<h2 className="text-2xl">Terms and Services</h2>
|
||||||
|
<Table>
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
<TableHead>Select</TableHead>
|
||||||
|
<TableHead>Term</TableHead>
|
||||||
|
<TableHead>Description</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{term_data.map((item, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
<TableCell>
|
||||||
|
<input type="checkbox" checked={checkedTerms[index]} onChange={() => handleCheckboxChange(index)} />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>{item.term}</TableCell>
|
||||||
|
<TableCell>{item.description}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
<Separator className="my-4" />
|
||||||
|
|
||||||
|
<div className="w-full space-y-2">
|
||||||
|
<h2 className="text:base md:text-2xl">Payment Information</h2>
|
||||||
|
<div>
|
||||||
|
<Elements
|
||||||
|
stripe={stripePromise}
|
||||||
|
options={{
|
||||||
|
mode: "payment",
|
||||||
|
amount: convertToSubcurrency(investAmount),
|
||||||
|
currency: "usd",
|
||||||
|
}}>
|
||||||
|
<CheckoutPage
|
||||||
|
amount={investAmount}
|
||||||
|
isAcceptTermAndService={isAcceptTermAndService}
|
||||||
|
project_id={Number(params.id)}
|
||||||
|
investor_id={investor_id}
|
||||||
|
/>
|
||||||
|
</Elements>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,168 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Separator } from "@/components/ui/separator";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { CardsPaymentMethod } from "@/components/paymentMethod";
|
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "@/components/ui/table";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { useState } from "react";
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
DialogFooter,
|
|
||||||
DialogClose,
|
|
||||||
} from "@/components/ui/dialog";
|
|
||||||
import { useRouter } from "next/navigation";
|
|
||||||
import { toast } from "react-hot-toast";
|
|
||||||
|
|
||||||
const term_data = [
|
|
||||||
{
|
|
||||||
term: "Minimum Investment",
|
|
||||||
description: "The minimum investment amount is $500.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
term: "Investment Horizon",
|
|
||||||
description: "Investments are typically locked for a minimum of 12 months.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
term: "Fees",
|
|
||||||
description: "A management fee of 2% will be applied annually.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
term: "Returns",
|
|
||||||
description: "Expected annual returns are between 8% and 12%.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
term: "Risk Disclosure",
|
|
||||||
description: "Investments carry risks, including the loss of principal.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
term: "Withdrawal Policy",
|
|
||||||
description: "Withdrawals can be made after the lock-in period.",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function Invest() {
|
|
||||||
const [checkedTerms, setCheckedTerms] = useState(
|
|
||||||
Array(term_data.length).fill(false)
|
|
||||||
);
|
|
||||||
const [error, setError] = useState("");
|
|
||||||
const router = useRouter(); // Initialize the router
|
|
||||||
|
|
||||||
const handleCheckboxChange = (index: number) => {
|
|
||||||
const updatedCheckedTerms = [...checkedTerms];
|
|
||||||
updatedCheckedTerms[index] = !updatedCheckedTerms[index];
|
|
||||||
setCheckedTerms(updatedCheckedTerms);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleTermServiceClick = () => {
|
|
||||||
if (checkedTerms.some((checked) => !checked)) {
|
|
||||||
setError(
|
|
||||||
"Please accept all terms before proceeding with the investment."
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
setError("");
|
|
||||||
handleInvestmentSuccess();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleInvestmentSuccess = () => {
|
|
||||||
toast.success("You successfully invested!");
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
router.push("/");
|
|
||||||
}, 1000);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mx-10 md:mx-40 my-10">
|
|
||||||
<h1 className="text-2xl md:text-4xl font-bold">Invest on NVIDIA</h1>
|
|
||||||
<Separator className="my-4" />
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div className="w-1/2 space-y-2">
|
|
||||||
<h2 className="text:base md:text-2xl">Investment Amount</h2>
|
|
||||||
<Input
|
|
||||||
className="w-52"
|
|
||||||
type="number"
|
|
||||||
placeholder="min $500"
|
|
||||||
min={500}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Separator className="my-4" />
|
|
||||||
|
|
||||||
<div className="w-full space-y-2">
|
|
||||||
<h2 className="text:base md:text-2xl">Payment Information</h2>
|
|
||||||
<CardsPaymentMethod />
|
|
||||||
</div>
|
|
||||||
<Separator className="my-4" />
|
|
||||||
|
|
||||||
<div className=" md:w-2/3 space-y-2">
|
|
||||||
<h2 className="text-2xl">Terms and Services</h2>
|
|
||||||
<Table>
|
|
||||||
<TableHeader>
|
|
||||||
<TableRow>
|
|
||||||
<TableHead>Select</TableHead>
|
|
||||||
<TableHead>Term</TableHead>
|
|
||||||
<TableHead>Description</TableHead>
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
{term_data.map((item, index) => (
|
|
||||||
<TableRow key={index}>
|
|
||||||
<TableCell>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
checked={checkedTerms[index]}
|
|
||||||
onChange={() => handleCheckboxChange(index)}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell>{item.term}</TableCell>
|
|
||||||
<TableCell>{item.description}</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Dialog>
|
|
||||||
<DialogTrigger asChild>
|
|
||||||
<Button className="mt-4">Invest</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Are you absolutely sure?</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
This action cannot be undone. This will permanently!
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<DialogFooter className="sm:justify-start">
|
|
||||||
<Button type="submit" onClick={handleTermServiceClick}>
|
|
||||||
Confirm
|
|
||||||
</Button>
|
|
||||||
<DialogClose asChild>
|
|
||||||
<Button type="button" variant="secondary">
|
|
||||||
Close
|
|
||||||
</Button>
|
|
||||||
</DialogClose>
|
|
||||||
</DialogFooter>
|
|
||||||
{error && (
|
|
||||||
<p className="text-red-500 mt-2 text-lg font-bold">{error}</p>
|
|
||||||
)}
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
18
src/app/(investment)/payment-success/page.tsx
Normal file
18
src/app/(investment)/payment-success/page.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
export default function PaymentSuccess({ searchParams: { amount } }: { searchParams: { amount: string } }) {
|
||||||
|
if (!amount) {
|
||||||
|
redirect("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className="max-w-6xl mx-auto p-10 text-white text-center border m-10 rounded-md bg-gradient-to-tr from-blue-500 to-purple-500">
|
||||||
|
<div className="mb-10">
|
||||||
|
<h1 className="text-4xl font-extrabold mb-2">Thank you!</h1>
|
||||||
|
<h2 className="text-2xl">You successfully sent</h2>
|
||||||
|
|
||||||
|
<div className="bg-white p-2 rounded-md text-purple-500 mt-5 text-4xl font-bold">${amount}</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
src/app/api/create-payment-intent/route.ts
Normal file
25
src/app/api/create-payment-intent/route.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
|
||||||
|
|
||||||
|
// POST 127.0.0.1:8000/api/create-payment-intetnt
|
||||||
|
|
||||||
|
export async function POST(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const { amount } = await request.json();
|
||||||
|
|
||||||
|
const paymentIntent = await stripe.paymentIntents.create({
|
||||||
|
amount: amount,
|
||||||
|
currency: "usd",
|
||||||
|
automatic_payment_methods: { enabled: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({ clientSecret: paymentIntent.client_secret });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Internal Error:", error);
|
||||||
|
// Handle other errors (e.g., network issues, parsing errors)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: `Internal Server Error: ${error}` },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,11 +16,17 @@ import { useEffect, useState } from "react";
|
|||||||
|
|
||||||
export default function Apply() {
|
export default function Apply() {
|
||||||
let supabase = createSupabaseClient();
|
let supabase = createSupabaseClient();
|
||||||
const [industry, setIndustry] = useState<string[]>([]);
|
|
||||||
|
const [companyName, setCompanyName] = useState("");
|
||||||
|
const [selectedIndustry, setSelectedIndustry] = useState("");
|
||||||
|
const [moneyRaisedToDate, setMoneyRaisedToDate] = useState("");
|
||||||
const [isInUS, setIsInUS] = useState("");
|
const [isInUS, setIsInUS] = useState("");
|
||||||
const [isForSale, setIsForSale] = useState("");
|
const [isForSale, setIsForSale] = useState("");
|
||||||
const [isGenerating, setIsGenarting] = useState("");
|
const [isGeneratingRevenue, setIsGeneratingRevenue] = useState("");
|
||||||
const [pitch, setPitch] = useState("");
|
const [businessPitch, setBusinessPitch] = useState("");
|
||||||
|
const [selectedCommunitySize, setSelectedCommunitySize] = useState("");
|
||||||
|
|
||||||
|
const [industry, setIndustry] = useState<string[]>([]);
|
||||||
const communitySize = [
|
const communitySize = [
|
||||||
"N/A",
|
"N/A",
|
||||||
"0-5K",
|
"0-5K",
|
||||||
@ -31,23 +37,84 @@ export default function Apply() {
|
|||||||
"100K+",
|
"100K+",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// get industry list to display in dropdown
|
||||||
const fetchIndustry = async () => {
|
const fetchIndustry = async () => {
|
||||||
let { data: BusinessType, error } = await supabase
|
let { data: businessType, error } = await supabase
|
||||||
.from("BusinessType")
|
.from("business_type")
|
||||||
.select("value");
|
.select("value");
|
||||||
|
|
||||||
if (error) {
|
if (!businessType) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} else {
|
} else {
|
||||||
if (BusinessType) {
|
setIndustry(businessType.map((item) => item.value));
|
||||||
console.table();
|
|
||||||
setIndustry(BusinessType.map((item) => item.value));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchIndustry();
|
fetchIndustry();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// get business id from business type
|
||||||
|
const getBusinessTypeID = async () => {
|
||||||
|
const { data, error } = await supabase
|
||||||
|
.from('business_type')
|
||||||
|
.select('id')
|
||||||
|
.eq('value', selectedIndustry)
|
||||||
|
.single();
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error('Error fetching business ID:', error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
// get current user id
|
||||||
|
const getUserID = async () => {
|
||||||
|
const { data: { user }, error } = await supabase.auth.getUser();
|
||||||
|
|
||||||
|
if (error || !user) {
|
||||||
|
console.error('Error fetching user:', error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return user.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// format input data as json
|
||||||
|
const createFormat = async () => {
|
||||||
|
return {
|
||||||
|
"company_name": companyName,
|
||||||
|
"business_type_id": await getBusinessTypeID(),
|
||||||
|
"raise_to_date": moneyRaisedToDate, //TODO change to money_raised_to_date in database and change type to number
|
||||||
|
"is_in_us": isInUS,
|
||||||
|
"is_for_sale": isForSale,
|
||||||
|
"is_generating_revenue": isGeneratingRevenue,
|
||||||
|
"pitch_deck_url": businessPitch,
|
||||||
|
"community_size": selectedCommunitySize,
|
||||||
|
"created_at": new Date(),
|
||||||
|
"user_id": await getUserID()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// insert into business_application database
|
||||||
|
const submitApplication = async () => {
|
||||||
|
let format = await createFormat();
|
||||||
|
// alert(JSON.stringify(format)) // debug message
|
||||||
|
|
||||||
|
const { data, error } = await supabase
|
||||||
|
.from('business_application')
|
||||||
|
.insert([format]);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
// return div error here
|
||||||
|
console.error('Error inserting data:', error);
|
||||||
|
// alert("Error" + JSON.stringify(error));
|
||||||
|
} else {
|
||||||
|
alert("Data successfully submitted!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="grid grid-flow-row auto-rows-max w-full h-52 md:h-92 bg-gray-100 dark:bg-gray-800 p-5">
|
<div className="grid grid-flow-row auto-rows-max w-full h-52 md:h-92 bg-gray-100 dark:bg-gray-800 p-5">
|
||||||
@ -57,9 +124,7 @@ export default function Apply() {
|
|||||||
<div className="mt-5 justify-self-center">
|
<div className="mt-5 justify-self-center">
|
||||||
<p className="text-sm md:text-base text-neutral-500">
|
<p className="text-sm md:text-base text-neutral-500">
|
||||||
All information submitted in this application is for internal use
|
All information submitted in this application is for internal use
|
||||||
only and is treated with the utmost{" "}
|
only and is treated with the utmost {" "}<br />
|
||||||
</p>
|
|
||||||
<p className="text-sm md:text-base text-neutral-500">
|
|
||||||
confidentiality. Companies may apply to raise with B2DVentures more
|
confidentiality. Companies may apply to raise with B2DVentures more
|
||||||
than once.
|
than once.
|
||||||
</p>
|
</p>
|
||||||
@ -68,7 +133,7 @@ export default function Apply() {
|
|||||||
<div className="grid grid-flow-row auto-rows-max w-full ml-48">
|
<div className="grid grid-flow-row auto-rows-max w-full ml-48">
|
||||||
<h1 className="text-3xl font-bold mt-10 ml-96">About your company</h1>
|
<h1 className="text-3xl font-bold mt-10 ml-96">About your company</h1>
|
||||||
<p className="ml-96 mt-5 text-neutral-500">
|
<p className="ml-96 mt-5 text-neutral-500">
|
||||||
All requested information in this section is required.
|
All requested information in this section are required.
|
||||||
</p>
|
</p>
|
||||||
{/* form */}
|
{/* form */}
|
||||||
|
|
||||||
@ -76,10 +141,10 @@ export default function Apply() {
|
|||||||
<div className="ml-96 mt-5 space-y-10">
|
<div className="ml-96 mt-5 space-y-10">
|
||||||
<div className="mt-10 space-y-5">
|
<div className="mt-10 space-y-5">
|
||||||
<Label htmlFor="companyName" className="font-bold text-lg">
|
<Label htmlFor="companyName" className="font-bold text-lg">
|
||||||
Company name
|
Company Name
|
||||||
</Label>
|
</Label>
|
||||||
<div className="flex space-x-5">
|
<div className="flex space-x-5">
|
||||||
<Input type="text" id="companyName" className="w-96" />
|
<Input onChange={(event) => setCompanyName(event.target.value)} type="text" id="companyName" className="w-96" />
|
||||||
<span className="text-[12px] text-neutral-500 self-center">
|
<span className="text-[12px] text-neutral-500 self-center">
|
||||||
This should be the name your company uses on your <br />
|
This should be the name your company uses on your <br />
|
||||||
website and in the market.
|
website and in the market.
|
||||||
@ -92,7 +157,7 @@ export default function Apply() {
|
|||||||
Industry
|
Industry
|
||||||
</Label>
|
</Label>
|
||||||
<div className="flex space-x-5">
|
<div className="flex space-x-5">
|
||||||
<Select>
|
<Select onValueChange={(value) => setSelectedIndustry(value)}>
|
||||||
<SelectTrigger className="w-96">
|
<SelectTrigger className="w-96">
|
||||||
<SelectValue placeholder="Select an industry" />
|
<SelectValue placeholder="Select an industry" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@ -100,7 +165,7 @@ export default function Apply() {
|
|||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectLabel>Industry</SelectLabel>
|
<SelectLabel>Industry</SelectLabel>
|
||||||
{industry.map((i) => (
|
{industry.map((i) => (
|
||||||
<SelectItem value={i}>{i}</SelectItem>
|
<SelectItem key={i} value={i}>{i}</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectGroup>
|
</SelectGroup>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
@ -117,6 +182,7 @@ export default function Apply() {
|
|||||||
</Label>
|
</Label>
|
||||||
<div className="flex space-x-5">
|
<div className="flex space-x-5">
|
||||||
<Input
|
<Input
|
||||||
|
onChange={(event) => setMoneyRaisedToDate(event.target.value)}
|
||||||
type="text"
|
type="text"
|
||||||
id="companyName"
|
id="companyName"
|
||||||
className="w-96"
|
className="w-96"
|
||||||
@ -201,15 +267,15 @@ export default function Apply() {
|
|||||||
<div className="flex space-x-5">
|
<div className="flex space-x-5">
|
||||||
<div className="flex space-x-2 w-96">
|
<div className="flex space-x-2 w-96">
|
||||||
<Button
|
<Button
|
||||||
variant={isGenerating === "Yes" ? "default" : "outline"}
|
variant={isGeneratingRevenue === "Yes" ? "default" : "outline"}
|
||||||
onClick={() => setIsGenarting("Yes")}
|
onClick={() => setIsGeneratingRevenue("Yes")}
|
||||||
className="w-20 h-12 text-base"
|
className="w-20 h-12 text-base"
|
||||||
>
|
>
|
||||||
Yes
|
Yes
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant={isGenerating === "No" ? "default" : "outline"}
|
variant={isGeneratingRevenue === "No" ? "default" : "outline"}
|
||||||
onClick={() => setIsGenarting("No")}
|
onClick={() => setIsGeneratingRevenue("No")}
|
||||||
className="w-20 h-12 text-base"
|
className="w-20 h-12 text-base"
|
||||||
>
|
>
|
||||||
No
|
No
|
||||||
@ -225,19 +291,19 @@ export default function Apply() {
|
|||||||
{/* Pitch deck */}
|
{/* Pitch deck */}
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<Label htmlFor="companyName" className="font-bold text-lg">
|
<Label htmlFor="companyName" className="font-bold text-lg">
|
||||||
Pitch deck
|
Pitch Deck
|
||||||
</Label>
|
</Label>
|
||||||
<div className="flex space-x-2 w-96">
|
<div className="flex space-x-2 w-96">
|
||||||
<Button
|
<Button
|
||||||
variant={pitch === "text" ? "default" : "outline"}
|
variant={businessPitch === "text" ? "default" : "outline"}
|
||||||
onClick={() => setPitch("text")}
|
onClick={() => setBusinessPitch("text")}
|
||||||
className="w-32 h-12 text-base"
|
className="w-32 h-12 text-base"
|
||||||
>
|
>
|
||||||
Paste URL
|
Paste URL
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant={pitch === "file" ? "default" : "outline"}
|
variant={businessPitch === "file" ? "default" : "outline"}
|
||||||
onClick={() => setPitch("file")}
|
onClick={() => setBusinessPitch("file")}
|
||||||
className="w-32 h-12 text-base"
|
className="w-32 h-12 text-base"
|
||||||
>
|
>
|
||||||
Upload a file
|
Upload a file
|
||||||
@ -245,7 +311,7 @@ export default function Apply() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex space-x-5">
|
<div className="flex space-x-5">
|
||||||
<Input
|
<Input
|
||||||
type={pitch}
|
type={businessPitch}
|
||||||
id="companyName"
|
id="companyName"
|
||||||
className="w-96"
|
className="w-96"
|
||||||
placeholder="https:// "
|
placeholder="https:// "
|
||||||
@ -264,10 +330,10 @@ export default function Apply() {
|
|||||||
{/* What's the rough size of your community? */}
|
{/* What's the rough size of your community? */}
|
||||||
<div className="mt-10 space-y-5">
|
<div className="mt-10 space-y-5">
|
||||||
<Label htmlFor="industry" className="font-bold text-lg mt-10">
|
<Label htmlFor="industry" className="font-bold text-lg mt-10">
|
||||||
What's the rough size of your <br /> community?
|
What{"'"}s the rough size of your <br /> community?
|
||||||
</Label>
|
</Label>
|
||||||
<div className="flex space-x-5">
|
<div className="flex space-x-5">
|
||||||
<Select>
|
<Select onValueChange={(value) => setSelectedCommunitySize(value)}>
|
||||||
<SelectTrigger className="w-96">
|
<SelectTrigger className="w-96">
|
||||||
<SelectValue placeholder="Select" />
|
<SelectValue placeholder="Select" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@ -275,7 +341,7 @@ export default function Apply() {
|
|||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectLabel>Select</SelectLabel>
|
<SelectLabel>Select</SelectLabel>
|
||||||
{communitySize.map((i) => (
|
{communitySize.map((i) => (
|
||||||
<SelectItem value={i}>{i}</SelectItem>
|
<SelectItem key={i} value={i}>{i}</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectGroup>
|
</SelectGroup>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
@ -291,8 +357,8 @@ export default function Apply() {
|
|||||||
</div>
|
</div>
|
||||||
{/* Submit */}
|
{/* Submit */}
|
||||||
<center>
|
<center>
|
||||||
<Button className="mt-12 mb-20 h-10 text-base font-bold py-6 px-5">
|
<Button onClick={submitApplication} className="mt-12 mb-20 h-10 text-base font-bold py-6 px-5">
|
||||||
Submit application
|
Submit Application
|
||||||
</Button>
|
</Button>
|
||||||
</center>
|
</center>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -25,15 +25,15 @@ const TopProjects = async () => {
|
|||||||
{topProjectsData.map((project) => (
|
{topProjectsData.map((project) => (
|
||||||
<Link href={`/deals/${project.id}`} key={project.id}>
|
<Link href={`/deals/${project.id}`} key={project.id}>
|
||||||
<ProjectCard
|
<ProjectCard
|
||||||
name={project.projectName}
|
name={project.project_name}
|
||||||
description={project.projectShortDescription}
|
description={project.project_short_description}
|
||||||
imageUri={project.cardImage}
|
imageUri={project.card_image_url}
|
||||||
joinDate={new Date(project.publishedTime).toLocaleDateString()}
|
joinDate={new Date(project.published_time).toLocaleDateString()}
|
||||||
location={project.Business.location}
|
location={project.business.location}
|
||||||
tags={project.ItemTag.map((item) => item.Tag.value)}
|
tags={project.item_tag.map((item) => item.tag.value)}
|
||||||
minInvestment={project.ProjectInvestmentDetail[0]?.minInvestment || 0}
|
minInvestment={project.project_investment_detail[0]?.min_investment || 0}
|
||||||
totalInvestor={0}
|
totalInvestor={0}
|
||||||
totalRaised={project.ProjectInvestmentDetail[0]?.totalInvestment || 0}
|
totalRaised={project.project_investment_detail[0]?.total_investment || 0}
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
|
|||||||
5
src/lib/convertToSubcurrency.tsx
Normal file
5
src/lib/convertToSubcurrency.tsx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
function convertToSubcurrency(amount: number, factor = 100) {
|
||||||
|
return Math.round(amount * factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default convertToSubcurrency;
|
||||||
@ -1,16 +1,15 @@
|
|||||||
import { SupabaseClient } from "@supabase/supabase-js";
|
import { SupabaseClient } from "@supabase/supabase-js";
|
||||||
|
|
||||||
|
|
||||||
function getAllTagsQuery(client: SupabaseClient) {
|
function getAllTagsQuery(client: SupabaseClient) {
|
||||||
return client.from("Tag").select("id, value");
|
return client.from("tag").select("id, value");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getALlFundedStatusQuery(client: SupabaseClient) {
|
function getALlFundedStatusQuery(client: SupabaseClient) {
|
||||||
return client.from("FundedStatus").select("id, value, description");
|
return client.from("funded_status").select("id, value, description");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllBusinessTypeQuery(client: SupabaseClient) {
|
function getAllBusinessTypeQuery(client: SupabaseClient) {
|
||||||
return client.from("BusinessType").select("id, value, description");
|
return client.from("business_type").select("id, value, description");
|
||||||
}
|
}
|
||||||
|
|
||||||
export { getAllTagsQuery, getALlFundedStatusQuery, getAllBusinessTypeQuery };
|
export { getAllBusinessTypeQuery, getALlFundedStatusQuery, getAllTagsQuery };
|
||||||
|
|||||||
@ -1,72 +1,97 @@
|
|||||||
import { SupabaseClient } from "@supabase/supabase-js";
|
import { SupabaseClient } from "@supabase/supabase-js";
|
||||||
|
|
||||||
async function getTopProjects(client: SupabaseClient, numberOfRecords: number = 4) {
|
async function getTopProjects(
|
||||||
try {
|
client: SupabaseClient,
|
||||||
const { data, error } = await client
|
numberOfRecords: number = 4,
|
||||||
.from("Project")
|
) {
|
||||||
.select(
|
try {
|
||||||
`
|
const { data, error } = await client
|
||||||
|
.from("project")
|
||||||
|
.select(
|
||||||
|
`
|
||||||
id,
|
id,
|
||||||
projectName,
|
project_name,
|
||||||
businessId,
|
business_id,
|
||||||
publishedTime,
|
published_time,
|
||||||
projectShortDescription,
|
project_short_description,
|
||||||
cardImage,
|
card_image_url,
|
||||||
ProjectInvestmentDetail (
|
project_investment_detail (
|
||||||
minInvestment,
|
min_investment,
|
||||||
totalInvestment,
|
total_investment,
|
||||||
targetInvestment,
|
target_investment,
|
||||||
investmentDeadline
|
investment_deadline
|
||||||
),
|
),
|
||||||
ItemTag (
|
item_tag (
|
||||||
Tag (
|
tag (
|
||||||
id,
|
id,
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Business (
|
business (
|
||||||
location
|
location
|
||||||
)
|
)
|
||||||
`
|
`,
|
||||||
)
|
)
|
||||||
.order("publishedTime", { ascending: false })
|
.order("published_time", { ascending: false })
|
||||||
.limit(numberOfRecords);
|
.limit(numberOfRecords);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error("Error fetching top projects:", error.message);
|
console.error("Error fetching top projects:", error.message);
|
||||||
return { data: null, error: error.message };
|
return { data: null, error: error.message };
|
||||||
}
|
|
||||||
|
|
||||||
return { data, error: null };
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Unexpected error:", err);
|
|
||||||
return { data: null, error: "An unexpected error occurred." };
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async function getProjectData(client: SupabaseClient, projectId: number) {
|
return { data, error: null };
|
||||||
const query = client.from("Project").select(
|
} catch (err) {
|
||||||
|
console.error("Unexpected error:", err);
|
||||||
|
return { data: null, error: "An unexpected error occurred." };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProjectDataQuery(client: SupabaseClient, projectId: number) {
|
||||||
|
return client.from("project").select(
|
||||||
`
|
`
|
||||||
project_name:projectName,
|
project_name,
|
||||||
project_short_description:projectShortDescription,
|
project_short_description,
|
||||||
project_description:projectDescription,
|
project_description,
|
||||||
published_time:publishedTime,
|
published_time,
|
||||||
...ProjectInvestmentDetail!inner (
|
...project_investment_detail!inner (
|
||||||
min_investment:minInvestment,
|
min_investment,
|
||||||
total_investment:totalInvestment,
|
total_investment,
|
||||||
target_investment:targetInvestment,
|
target_investment,
|
||||||
investment_deadline:investmentDeadline
|
investment_deadline
|
||||||
),
|
),
|
||||||
tags:ItemTag!inner (
|
tags:item_tag!inner (
|
||||||
...Tag!inner (
|
...tag!inner (
|
||||||
tag_name:value
|
tag_name:value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
`
|
`,
|
||||||
).eq("id", projectId).single()
|
).eq("id", projectId).single();
|
||||||
|
}
|
||||||
|
|
||||||
const {data, error} = await query;
|
async function getProjectData(client: SupabaseClient, projectId: number) {
|
||||||
return { data, error }
|
const query = client.from("project").select(
|
||||||
|
`
|
||||||
|
project_name,
|
||||||
|
project_short_description,
|
||||||
|
project_description,
|
||||||
|
published_time,
|
||||||
|
...project_investment_detail!inner (
|
||||||
|
min_investment,
|
||||||
|
total_investment,
|
||||||
|
target_investment,
|
||||||
|
investment_deadline
|
||||||
|
),
|
||||||
|
tags:item_tag!inner (
|
||||||
|
...tag!inner (
|
||||||
|
tag_name:value
|
||||||
|
)
|
||||||
|
)
|
||||||
|
`,
|
||||||
|
).eq("id", projectId).single();
|
||||||
|
|
||||||
|
const { data, error } = await query;
|
||||||
|
return { data, error };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FilterParams {
|
export interface FilterParams {
|
||||||
@ -79,43 +104,54 @@ export interface FilterParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FilterProjectQueryParams extends FilterParams {
|
export interface FilterProjectQueryParams extends FilterParams {
|
||||||
page: number,
|
page: number;
|
||||||
pageSize: number
|
pageSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchProjectsQuery(client: SupabaseClient, {searchTerm, tagsFilter, projectStatus, businessTypeFilter, sortByTimeFilter, page = 1, pageSize = 4}: FilterProjectQueryParams) {
|
function searchProjectsQuery(
|
||||||
|
client: SupabaseClient,
|
||||||
|
{
|
||||||
|
searchTerm,
|
||||||
|
tagsFilter,
|
||||||
|
projectStatus,
|
||||||
|
businessTypeFilter,
|
||||||
|
sortByTimeFilter,
|
||||||
|
page = 1,
|
||||||
|
pageSize = 4,
|
||||||
|
}: FilterProjectQueryParams,
|
||||||
|
) {
|
||||||
const start = (page - 1) * pageSize;
|
const start = (page - 1) * pageSize;
|
||||||
const end = start + pageSize - 1;
|
const end = start + pageSize - 1;
|
||||||
|
|
||||||
let query = client.from("Project").select(
|
let query = client.from("project").select(
|
||||||
`
|
`
|
||||||
project_id:id,
|
project_id:id,
|
||||||
project_name:projectName,
|
project_name,
|
||||||
published_time:publishedTime,
|
published_time,
|
||||||
project_short_description:projectShortDescription,
|
project_short_description,
|
||||||
card_image_url:cardImage,
|
card_image_url,
|
||||||
...ProjectStatus!Project_projectStatusId_fkey!inner (
|
...project_status!project_project_status_id_fkey!inner (
|
||||||
project_status:value
|
project_status:value
|
||||||
),
|
),
|
||||||
...ProjectInvestmentDetail!inner (
|
...project_investment_detail!inner (
|
||||||
min_investment:minInvestment,
|
min_investment,
|
||||||
total_investment:totalInvestment,
|
total_investment,
|
||||||
target_investment:targetInvestment,
|
target_investment,
|
||||||
investment_deadline:investmentDeadline
|
investment_deadline
|
||||||
),
|
),
|
||||||
tags:ItemTag!inner (
|
tags:item_tag!inner (
|
||||||
...Tag!inner (
|
...tag!inner (
|
||||||
tag_name:value
|
tag_name:value
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
...Business!inner (
|
...business!inner (
|
||||||
...businessType!inner (
|
...business_type!inner (
|
||||||
business_type:value
|
business_type:value
|
||||||
),
|
),
|
||||||
business_location:location
|
business_location:location
|
||||||
)
|
)
|
||||||
`
|
`,
|
||||||
).order("publishedTime", { ascending: false }).range(start, end)
|
).order("published_time", { ascending: false }).range(start, end);
|
||||||
|
|
||||||
if (sortByTimeFilter === "all") {
|
if (sortByTimeFilter === "all") {
|
||||||
sortByTimeFilter = undefined;
|
sortByTimeFilter = undefined;
|
||||||
@ -134,24 +170,27 @@ function searchProjectsQuery(client: SupabaseClient, {searchTerm, tagsFilter, pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (searchTerm) {
|
if (searchTerm) {
|
||||||
query = query.ilike('projectName', `%${searchTerm}%`)
|
query = query.ilike("project_name", `%${searchTerm}%`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tagsFilter) {
|
if (tagsFilter) {
|
||||||
query = query.in('ItemTag.Tag.value', tagsFilter)
|
query = query.in("item_tag.tag.value", tagsFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (projectStatus) {
|
if (projectStatus) {
|
||||||
query = query.eq("ProjectStatus.value", projectStatus)
|
query = query.eq("project_status.value", projectStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (businessTypeFilter) {
|
if (businessTypeFilter) {
|
||||||
query = query.eq("Business.businessType.value", businessTypeFilter)
|
query = query.eq("business.business_type.value", businessTypeFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
export { getTopProjects, getProjectData, searchProjectsQuery };
|
getProjectData,
|
||||||
|
getProjectDataQuery,
|
||||||
|
getTopProjects,
|
||||||
|
searchProjectsQuery,
|
||||||
|
};
|
||||||
|
|||||||
@ -1,35 +1,44 @@
|
|||||||
import { SupabaseClient } from "@supabase/supabase-js";
|
import { SupabaseClient } from "@supabase/supabase-js";
|
||||||
|
|
||||||
function getBusinesses(client: SupabaseClient, query: string | null) {
|
function getBusinesses(client: SupabaseClient, query: string | null) {
|
||||||
return client.from("Business").select("id, businessName, joinedDate").ilike("businessName", `%${query}%`);
|
return client.from("business").select("id, business_name, joined_date").ilike(
|
||||||
|
"business_name",
|
||||||
|
`%${query}%`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProjects(client: SupabaseClient, businessIds: string[]) {
|
function getProjects(client: SupabaseClient, businessIds: string[]) {
|
||||||
return client
|
return client
|
||||||
.from("Project")
|
.from("project")
|
||||||
.select(
|
.select(
|
||||||
`
|
`
|
||||||
id,
|
id,
|
||||||
projectName,
|
project_name,
|
||||||
businessId,
|
business_id,
|
||||||
publishedTime,
|
published_time,
|
||||||
projectShortDescription,
|
project_short_description,
|
||||||
ProjectInvestmentDetail (
|
project_investment_detail (
|
||||||
minInvestment,
|
min_investment,
|
||||||
totalInvestment,
|
total_investment,
|
||||||
targetInvestment
|
target_investment
|
||||||
)
|
)
|
||||||
`
|
`,
|
||||||
)
|
)
|
||||||
.in("businessId", businessIds);
|
.in("business_id", businessIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTags(client: SupabaseClient, projectIds: string[]) {
|
function getTags(client: SupabaseClient, projectIds: string[]) {
|
||||||
return client.from("ItemTag").select("itemId, Tag (value)").in("itemId", projectIds);
|
return client.from("item_tag").select("item_id, tag (value)").in(
|
||||||
|
"item_id",
|
||||||
|
projectIds,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInvestmentCounts(client: SupabaseClient, projectIds: string[]) {
|
function getInvestmentCounts(client: SupabaseClient, projectIds: string[]) {
|
||||||
return client.from("InvestmentDeal").select("*", { count: "exact", head: true }).in("projectId", projectIds);
|
return client.from("investment_deal").select("*", {
|
||||||
|
count: "exact",
|
||||||
|
head: true,
|
||||||
|
}).in("project_id", projectIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { getBusinesses, getProjects, getTags, getInvestmentCounts };
|
export { getBusinesses, getInvestmentCounts, getProjects, getTags };
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { SupabaseClient } from "@supabase/supabase-js";
|
|||||||
async function getUserProfile(client: SupabaseClient, userId: string) {
|
async function getUserProfile(client: SupabaseClient, userId: string) {
|
||||||
try {
|
try {
|
||||||
const { data, error } = await client
|
const { data, error } = await client
|
||||||
.from("Profiles")
|
.from("profiles")
|
||||||
.select("updated_at, username, full_name, avatar_url, website, bio")
|
.select("updated_at, username, full_name, avatar_url, website, bio")
|
||||||
.eq("id", userId)
|
.eq("id", userId)
|
||||||
.single();
|
.single();
|
||||||
|
|||||||
11
src/lib/stripe/config.ts
Normal file
11
src/lib/stripe/config.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Stripe, loadStripe } from '@stripe/stripe-js';
|
||||||
|
|
||||||
|
let stripePromise: Promise<Stripe | null>;
|
||||||
|
const getStripe = () => {
|
||||||
|
if (!stripePromise) {
|
||||||
|
stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);
|
||||||
|
}
|
||||||
|
return stripePromise;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getStripe;
|
||||||
@ -14,6 +14,6 @@ export const config = {
|
|||||||
* - favicon.ico (favicon file)
|
* - favicon.ico (favicon file)
|
||||||
* Feel free to modify this pattern to include more paths.
|
* Feel free to modify this pattern to include more paths.
|
||||||
*/
|
*/
|
||||||
"/((?!_next/static|_next/image|$|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
|
"/((?!_next/static|_next/image|$|favicon.ico|payment-success|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user