mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-19 05:54:06 +01:00
Merge pull request #19 from Sosokker/front-end
Finished the deals page.
This commit is contained in:
commit
c67397ad55
3
.gitignore
vendored
3
.gitignore
vendored
@ -26,7 +26,8 @@ yarn-debug.log*
|
|||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
# local env files
|
# local env files
|
||||||
.env*.local
|
.env*.
|
||||||
|
.env
|
||||||
|
|
||||||
# vercel
|
# vercel
|
||||||
.vercel
|
.vercel
|
||||||
|
|||||||
26
package-lock.json
generated
26
package-lock.json
generated
@ -8,6 +8,7 @@
|
|||||||
"name": "b2d-ventures",
|
"name": "b2d-ventures",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@radix-ui/react-avatar": "^1.1.0",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-navigation-menu": "^1.2.0",
|
"@radix-ui/react-navigation-menu": "^1.2.0",
|
||||||
"@radix-ui/react-progress": "^1.1.0",
|
"@radix-ui/react-progress": "^1.1.0",
|
||||||
@ -475,6 +476,31 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-avatar": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-Q/PbuSMk/vyAd/UoIShVGZ7StHHeRFYU7wXmi5GV+8cLXflZAEpHL/F697H1klrzxKXNtZ97vWiC0q3RKUH8UA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-context": "1.1.0",
|
||||||
|
"@radix-ui/react-primitive": "2.0.0",
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||||
|
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-collection": {
|
"node_modules/@radix-ui/react-collection": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
|
||||||
|
|||||||
@ -9,9 +9,11 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@radix-ui/react-avatar": "^1.1.0",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-navigation-menu": "^1.2.0",
|
"@radix-ui/react-navigation-menu": "^1.2.0",
|
||||||
"@radix-ui/react-progress": "^1.1.0",
|
"@radix-ui/react-progress": "^1.1.0",
|
||||||
|
"@radix-ui/react-select": "^2.1.1",
|
||||||
"@radix-ui/react-separator": "^1.1.0",
|
"@radix-ui/react-separator": "^1.1.0",
|
||||||
"@radix-ui/react-slot": "^1.1.0",
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"@supabase/ssr": "^0.4.1",
|
"@supabase/ssr": "^0.4.1",
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
lockfileVersion: '6.0'
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@radix-ui/react-avatar':
|
||||||
|
specifier: ^1.1.0
|
||||||
|
version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
'@radix-ui/react-dropdown-menu':
|
'@radix-ui/react-dropdown-menu':
|
||||||
specifier: ^2.1.1
|
specifier: ^2.1.1
|
||||||
version: 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
version: 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
@ -10,6 +17,9 @@ dependencies:
|
|||||||
'@radix-ui/react-progress':
|
'@radix-ui/react-progress':
|
||||||
specifier: ^1.1.0
|
specifier: ^1.1.0
|
||||||
version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@radix-ui/react-select':
|
||||||
|
specifier: ^2.1.1
|
||||||
|
version: 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
'@radix-ui/react-separator':
|
'@radix-ui/react-separator':
|
||||||
specifier: ^1.1.0
|
specifier: ^1.1.0
|
||||||
version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
@ -17,10 +27,10 @@ dependencies:
|
|||||||
specifier: ^1.1.0
|
specifier: ^1.1.0
|
||||||
version: 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
version: 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
'@supabase/ssr':
|
'@supabase/ssr':
|
||||||
specifier: ^0.4.0
|
specifier: ^0.4.1
|
||||||
version: 0.4.1(@supabase/supabase-js@2.45.2)
|
version: 0.4.1(@supabase/supabase-js@2.45.2)
|
||||||
'@supabase/supabase-js':
|
'@supabase/supabase-js':
|
||||||
specifier: ^2.45.1
|
specifier: ^2.45.2
|
||||||
version: 2.45.2
|
version: 2.45.2
|
||||||
class-variance-authority:
|
class-variance-authority:
|
||||||
specifier: ^0.7.0
|
specifier: ^0.7.0
|
||||||
@ -331,6 +341,10 @@ packages:
|
|||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
/@radix-ui/number@1.1.0:
|
||||||
|
resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/primitive@1.1.0:
|
/@radix-ui/primitive@1.1.0:
|
||||||
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
|
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
|
||||||
dev: false
|
dev: false
|
||||||
@ -355,6 +369,29 @@ packages:
|
|||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-avatar@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-Q/PbuSMk/vyAd/UoIShVGZ7StHHeRFYU7wXmi5GV+8cLXflZAEpHL/F697H1klrzxKXNtZ97vWiC0q3RKUH8UA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/react-context': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@types/react': 18.3.4
|
||||||
|
'@types/react-dom': 18.3.0
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
/@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==}
|
resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -726,6 +763,46 @@ packages:
|
|||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-select@2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-8iRDfyLtzxlprOo9IicnzvpsO1wNCkuwzzCM+Z5Rb5tNOpCdMvcc2AkzX0Fz+Tz9v6NJ5B/7EEgyZveo4FBRfQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/number': 1.1.0
|
||||||
|
'@radix-ui/primitive': 1.1.0
|
||||||
|
'@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-context': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-direction': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@radix-ui/react-focus-guards': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@radix-ui/react-id': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@radix-ui/react-slot': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@types/react': 18.3.4
|
||||||
|
'@types/react-dom': 18.3.0
|
||||||
|
aria-hidden: 1.2.4
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
react-remove-scroll: 2.5.7(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-separator@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
/@radix-ui/react-separator@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==}
|
resolution: {integrity: sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -3717,7 +3794,3 @@ packages:
|
|||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
settings:
|
|
||||||
autoInstallPeers: true
|
|
||||||
excludeLinksFromLockfile: false
|
|
||||||
|
|||||||
BIN
public/placeholder-user.jpg
Normal file
BIN
public/placeholder-user.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
1
public/placeholder.svg
Normal file
1
public/placeholder.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>
|
||||||
|
After Width: | Height: | Size: 3.2 KiB |
152
src/app/deals/page.tsx
Normal file
152
src/app/deals/page.tsx
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
"use client";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
|
import { useState } from "react";
|
||||||
|
import {
|
||||||
|
Clock3Icon,
|
||||||
|
MessageSquareIcon,
|
||||||
|
UserIcon,
|
||||||
|
UsersIcon,
|
||||||
|
} from "lucide-react";
|
||||||
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import { ExtendableCard } from "@/components/extendableCard";
|
||||||
|
|
||||||
|
export default function Deals() {
|
||||||
|
const [postAtFilter, setPostAtFilter] = useState("");
|
||||||
|
const [contentTypeFilter, setContentTypeFilter] = useState("");
|
||||||
|
const [authorFilter, setAuthorFilter] = useState("");
|
||||||
|
const [groupsFilter, setGroupFilter] = useState("");
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
name: "NVDA",
|
||||||
|
description:
|
||||||
|
"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology",
|
||||||
|
joinDate: "December 2021",
|
||||||
|
location: "Bangkok, Thailand",
|
||||||
|
tags: null,
|
||||||
|
minInvestment: 10000,
|
||||||
|
totalInvestor: 58400,
|
||||||
|
totalRaised: 9000000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Apple Inc.",
|
||||||
|
description:
|
||||||
|
"Founded in 1976, Apple Inc. is a leading innovator in consumer electronics, software, and online services, known for products like the iPhone, MacBook, and the App Store.",
|
||||||
|
joinDate: "February 2020",
|
||||||
|
location: "Cupertino, California, USA",
|
||||||
|
tags: null,
|
||||||
|
minInvestment: 10000,
|
||||||
|
totalInvestor: 58400,
|
||||||
|
totalRaised: 9000000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Google LLC",
|
||||||
|
description:
|
||||||
|
"Founded in 1998, Google LLC specializes in internet-related services and products, including search engines, online advertising, cloud computing, and the Android operating system.",
|
||||||
|
joinDate: "April 2019",
|
||||||
|
location: "Mountain View, California, USA",
|
||||||
|
tags: null,
|
||||||
|
minInvestment: 10000,
|
||||||
|
totalInvestor: 5000,
|
||||||
|
totalRaised: 1500000000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Microsoft Corporation",
|
||||||
|
description:
|
||||||
|
"Microsoft Corporation is a multinational technology company.",
|
||||||
|
joinDate: "January 2018",
|
||||||
|
location: "California, USA",
|
||||||
|
tags: null,
|
||||||
|
minInvestment: 250,
|
||||||
|
totalInvestor: 5000,
|
||||||
|
totalRaised: 1500000,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className=" w-1/2 h-[250px] mt-10 ml-[15%]">
|
||||||
|
<h1 className="text-4xl font-bold">Investment Opportunities </h1>
|
||||||
|
<br />
|
||||||
|
<p>Browse current investment opportunities on Republic. </p>
|
||||||
|
<p>
|
||||||
|
All companies are <u>vetted & pass due diligence.</u>
|
||||||
|
</p>
|
||||||
|
{/* filters */}
|
||||||
|
<div className="flex mt-10 gap-3">
|
||||||
|
<Select onValueChange={(value) => setPostAtFilter(value)}>
|
||||||
|
<SelectTrigger className="w-[180px]">
|
||||||
|
<Clock3Icon className="ml-2" />
|
||||||
|
<SelectValue placeholder="Posted at" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="Today">Today</SelectItem>
|
||||||
|
<SelectItem value="Yesterday">Yesterday</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<Select onValueChange={(value) => setContentTypeFilter(value)}>
|
||||||
|
<SelectTrigger className="w-[180px]">
|
||||||
|
<MessageSquareIcon className="ml-2" />
|
||||||
|
<SelectValue placeholder="Content type" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="Blog">Blog</SelectItem>
|
||||||
|
<SelectItem value="Youtube">Youtube</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<Select onValueChange={(value) => setAuthorFilter(value)}>
|
||||||
|
<SelectTrigger className="w-[180px]">
|
||||||
|
<UserIcon className="ml-2" />
|
||||||
|
<SelectValue placeholder="Author" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="Me">Me</SelectItem>
|
||||||
|
<SelectItem value="Charlie Puth">Charlie Puth</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<Select onValueChange={(value) => setGroupFilter(value)}>
|
||||||
|
<SelectTrigger className="w-[180px]">
|
||||||
|
<UsersIcon />
|
||||||
|
<SelectValue placeholder="Sent to groups" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="Group1">Group1</SelectItem>
|
||||||
|
<SelectItem value="Group2">Group2</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
{/* {postAtFilter}
|
||||||
|
{contentTypeFilter}
|
||||||
|
{authorFilter}
|
||||||
|
{groupsFilter} */}
|
||||||
|
</div>
|
||||||
|
<Separator className="mt-10" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="ml-[15%]">
|
||||||
|
<h2 className="text-2xl">Deals</h2>
|
||||||
|
<p className="mt-3">The deals attracting the most interest right now</p>
|
||||||
|
</div>
|
||||||
|
{/* block for all the deals */}
|
||||||
|
<div className="ml-[15%] mt-10 grid grid-cols-3">
|
||||||
|
{data.map((item, index) => (
|
||||||
|
<ExtendableCard
|
||||||
|
key={index}
|
||||||
|
name={item.name}
|
||||||
|
description={item.description}
|
||||||
|
joinDate={item.joinDate}
|
||||||
|
location={item.location}
|
||||||
|
minInvestment={item.minInvestment}
|
||||||
|
totalInvestor={item.totalInvestor}
|
||||||
|
totalRaised={item.totalRaised}
|
||||||
|
tags={item.tags}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -28,18 +28,18 @@ export default function Invest() {
|
|||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="w-[90%] h-[500px]-500 m-auto mt-12">
|
<div className="w-[90%] h-[500px]-500 m-auto mt-12 pl-24">
|
||||||
<div>
|
<div>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<Image src="./logo.svg" alt="logo" width={50} height={50} />
|
<Image src="./logo.svg" alt="logo" width={50} height={50} />
|
||||||
<h1 className="mt-3 font-bold text-3xl">NVIDIA</h1>
|
<h1 className="mt-3 font-bold text-3xl">NVIDIA</h1>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-2"> World's first non-metal sustainable battery</p>
|
<p className="mt-2"> World's first non-metal sustainable battery</p>
|
||||||
<div className="flex mt-3">
|
<div className="flex flex-wrap mt-3">
|
||||||
{["Technology", "Gaming"].map((tag) => (
|
{["Technology", "Gaming"].map((tag) => (
|
||||||
<span
|
<span
|
||||||
key={tag}
|
key={tag}
|
||||||
className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1"
|
className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1"
|
||||||
>
|
>
|
||||||
{tag}
|
{tag}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Montserrat } from "next/font/google";
|
|||||||
import { ThemeProvider } from "@/components/theme-provider";
|
import { ThemeProvider } from "@/components/theme-provider";
|
||||||
import "@/app/globals.css";
|
import "@/app/globals.css";
|
||||||
|
|
||||||
import { UnsignedNav } from "@/components/navigationBar/Unsigned";
|
import { NavigationBar } from "@/components/navigationBar/nav";
|
||||||
|
|
||||||
const montserrat = Montserrat({
|
const montserrat = Montserrat({
|
||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
@ -29,7 +29,7 @@ export default function RootLayout({ children }: RootLayoutProps) {
|
|||||||
<body className={`${montserrat.className}`}>
|
<body className={`${montserrat.className}`}>
|
||||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||||
<div className="relative flex min-h-screen flex-col">
|
<div className="relative flex min-h-screen flex-col">
|
||||||
<UnsignedNav />
|
<NavigationBar />
|
||||||
<div className="flex-1 bg-background">{children}</div>
|
<div className="flex-1 bg-background">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
|||||||
@ -1,9 +1,15 @@
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import {
|
||||||
import { BusinessCard } from "@/components/businessCard";
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardDescription,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
} from "@/components/ui/card";
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import { ExtendableCard } from "@/components/extendableCard";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
@ -13,12 +19,14 @@ export default function Home() {
|
|||||||
<span className="px-28 py-20">
|
<span className="px-28 py-20">
|
||||||
<p className="text-4xl font-bold">Explore the world of ventures</p>
|
<p className="text-4xl font-bold">Explore the world of ventures</p>
|
||||||
<span className="text-lg">
|
<span className="text-lg">
|
||||||
<p>Unlock opportunities and connect with a community of passionate</p>
|
<p>
|
||||||
|
Unlock opportunities and connect with a community of passionate
|
||||||
|
</p>
|
||||||
<p>investors and innovators.</p>
|
<p>investors and innovators.</p>
|
||||||
<p>Together, we turn ideas into impact.</p>
|
<p>Together, we turn ideas into impact.</p>
|
||||||
</span>
|
</span>
|
||||||
<Button className="font-bold mt-4">
|
<Button className="font-bold mt-4">
|
||||||
<Link href="/">Start Investing</Link>
|
<Link href="/deals">Start Investing</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -75,17 +83,26 @@ export default function Home() {
|
|||||||
<div className="flex flex-col px-28">
|
<div className="flex flex-col px-28">
|
||||||
<span className="pb-5">
|
<span className="pb-5">
|
||||||
<p className="text-2xl font-bold">Hottest Deals</p>
|
<p className="text-2xl font-bold">Hottest Deals</p>
|
||||||
<p className="text-lg">The deals attracting the most interest right now</p>
|
<p className="text-lg">
|
||||||
|
The deals attracting the most interest right now
|
||||||
|
</p>
|
||||||
</span>
|
</span>
|
||||||
<div className="grid grid-cols-4 gap-4">
|
<div className="grid grid-cols-4 gap-4">
|
||||||
<BusinessCard
|
<Link href={"/invest"}>
|
||||||
name={"NVDA"}
|
<ExtendableCard
|
||||||
description={"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology"}
|
name={"NVDA"}
|
||||||
joinDate={"December 2021"}
|
description={
|
||||||
location={"Bangkok, Thailand"}
|
"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology"
|
||||||
tags={null}
|
}
|
||||||
/>
|
joinDate={"December 2021"}
|
||||||
<BusinessCard
|
location={"Bangkok, Thailand"}
|
||||||
|
tags={null}
|
||||||
|
minInvestment={10000}
|
||||||
|
totalInvestor={58400}
|
||||||
|
totalRaised={9000000}
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
<ExtendableCard
|
||||||
name={"Apple Inc."}
|
name={"Apple Inc."}
|
||||||
description={
|
description={
|
||||||
"Founded in 1976, Apple Inc. is a leading innovator in consumer electronics, software, and online services, known for products like the iPhone, MacBook, and the App Store."
|
"Founded in 1976, Apple Inc. is a leading innovator in consumer electronics, software, and online services, known for products like the iPhone, MacBook, and the App Store."
|
||||||
@ -93,8 +110,11 @@ export default function Home() {
|
|||||||
joinDate={"February 2020"}
|
joinDate={"February 2020"}
|
||||||
location={"Cupertino, California, USA"}
|
location={"Cupertino, California, USA"}
|
||||||
tags={null}
|
tags={null}
|
||||||
|
minInvestment={10000}
|
||||||
|
totalInvestor={58400}
|
||||||
|
totalRaised={9000000}
|
||||||
/>
|
/>
|
||||||
<BusinessCard
|
<ExtendableCard
|
||||||
name={"Google LLC"}
|
name={"Google LLC"}
|
||||||
description={
|
description={
|
||||||
"Founded in 1998, Google LLC specializes in internet-related services and products, including search engines, online advertising, cloud computing, and the Android operating system."
|
"Founded in 1998, Google LLC specializes in internet-related services and products, including search engines, online advertising, cloud computing, and the Android operating system."
|
||||||
@ -102,20 +122,26 @@ export default function Home() {
|
|||||||
joinDate={"April 2019"}
|
joinDate={"April 2019"}
|
||||||
location={"Mountain View, California, USA"}
|
location={"Mountain View, California, USA"}
|
||||||
tags={null}
|
tags={null}
|
||||||
|
minInvestment={10000}
|
||||||
|
totalInvestor={5000}
|
||||||
|
totalRaised={1500000000}
|
||||||
/>
|
/>
|
||||||
<BusinessCard
|
<ExtendableCard
|
||||||
name={"Microsoft Corporation"}
|
name={"Microsoft Corporation"}
|
||||||
description={
|
description={
|
||||||
"Founded in 1975, Microsoft Corporation is a multinational technology company that develops, manufactures, and licenses software, hardware, and services, including Windows, Office, and Azure."
|
"Microsoft Corporation is a multinational technology company."
|
||||||
}
|
}
|
||||||
joinDate={"January 2018"}
|
joinDate={"January 2018"}
|
||||||
location={""}
|
location={"California, USA"}
|
||||||
tags={null}
|
tags={null}
|
||||||
|
minInvestment={250}
|
||||||
|
totalInvestor={5000}
|
||||||
|
totalRaised={1500000}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="self-center py-5">
|
<div className="self-center py-5">
|
||||||
<Button>
|
<Button>
|
||||||
<Link href={"/invest"}>View all</Link>
|
<Link href={"/deals"}>View all</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
87
src/components/extendableCard.tsx
Normal file
87
src/components/extendableCard.tsx
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
"use client";
|
||||||
|
import { CalendarDaysIcon } from "lucide-react";
|
||||||
|
|
||||||
|
interface XMap {
|
||||||
|
// tagName: colorCode
|
||||||
|
[tag: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExtendableCardProps {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
joinDate: string;
|
||||||
|
location: string;
|
||||||
|
tags: XMap | null;
|
||||||
|
minInvestment: number;
|
||||||
|
totalInvestor: number;
|
||||||
|
totalRaised: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ExtendableCard(props: ExtendableCardProps) {
|
||||||
|
return (
|
||||||
|
<div className="group relative w-full max-w-sm overflow-hidden rounded-lg bg-card shadow-md transition-all duration-500 hover:shadow-lg">
|
||||||
|
<div className="aspect-[4/3] overflow-hidden">
|
||||||
|
<img
|
||||||
|
src="/money.png"
|
||||||
|
alt="Card image"
|
||||||
|
width="400"
|
||||||
|
height="300"
|
||||||
|
className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
|
||||||
|
style={{ aspectRatio: "400/300", objectFit: "cover" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="p-4">
|
||||||
|
<h3 className="text-lg font-semibold text-card-foreground transition-colors duration-500 group-hover:text-primary">
|
||||||
|
{props.name}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
{/* Default content (visible when not hovered) */}
|
||||||
|
<div className="mt-2 flex items-center text-muted-foreground group-hover:hidden">
|
||||||
|
<span className="flex items-center pt-2 gap-1">
|
||||||
|
<CalendarDaysIcon width={20} />
|
||||||
|
Joined {props.joinDate}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 flex items-center text-muted-foreground group-hover:hidden">
|
||||||
|
<span className="text-sm">{props.location}</span>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 flex flex-wrap items-center text-muted-foreground group-hover:hidden">
|
||||||
|
{["Technology", "Gaming"].map((tag) => (
|
||||||
|
<span
|
||||||
|
key={tag}
|
||||||
|
className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1"
|
||||||
|
>
|
||||||
|
{tag}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Hover content (appears when hovered) */}
|
||||||
|
<div className="mt-4 max-h-0 overflow-hidden opacity-0 group-hover:max-h-[500px] group-hover:opacity-100 transition-all duration-500 ease-in-out">
|
||||||
|
<p className="text-sm text-muted-foreground">{props.description}</p>
|
||||||
|
<div className="mt-4 flex items-center justify-between">
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<div>
|
||||||
|
<hr className="w-screen -ml-4 mb-2" />
|
||||||
|
<p>
|
||||||
|
<strong>${props.totalRaised.toLocaleString()}</strong>{" "}
|
||||||
|
committed and reserved
|
||||||
|
</p>
|
||||||
|
<hr className="w-screen -ml-4 mb-2 mt-2" />
|
||||||
|
<p className="mb-2">
|
||||||
|
<strong>{props.totalInvestor.toLocaleString()}</strong>{" "}
|
||||||
|
investors
|
||||||
|
</p>
|
||||||
|
<hr className="w-screen -ml-4 mb-2" />
|
||||||
|
<p>
|
||||||
|
<strong>${props.minInvestment.toLocaleString()}</strong> min.
|
||||||
|
investment
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -17,7 +17,11 @@ import {
|
|||||||
NavigationMenuTrigger,
|
NavigationMenuTrigger,
|
||||||
navigationMenuTriggerStyle,
|
navigationMenuTriggerStyle,
|
||||||
} from "@/components/ui/navigation-menu";
|
} from "@/components/ui/navigation-menu";
|
||||||
import { Search } from "lucide-react";
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
|
import { Search, Bell, Heart, Wallet } from "lucide-react";
|
||||||
|
|
||||||
|
import useSession from "@/lib/supabase/useSession";
|
||||||
|
|
||||||
const landings = [
|
const landings = [
|
||||||
{
|
{
|
||||||
@ -54,7 +58,44 @@ const ListItem = React.forwardRef<React.ElementRef<"a">, React.ComponentPropsWit
|
|||||||
);
|
);
|
||||||
ListItem.displayName = "ListItem";
|
ListItem.displayName = "ListItem";
|
||||||
|
|
||||||
export function UnsignedNav() {
|
const unAuthenticatedComponents = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex gap-2 pl-2">
|
||||||
|
<Link href="/auth">
|
||||||
|
<Button variant="secondary" className="border-2 border-border">
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<Button>Sign up</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const authenticatedComponents = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex gap-3 pl-2 items-center">
|
||||||
|
<Bell />
|
||||||
|
<Heart />
|
||||||
|
<Wallet />
|
||||||
|
<Avatar className="ml-2">
|
||||||
|
<AvatarImage src="https://api.dicebear.com/9.x/pixel-art/svg" />
|
||||||
|
<AvatarFallback>1</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function NavigationBar() {
|
||||||
|
const { session, loading } = useSession();
|
||||||
|
const user = session?.user;
|
||||||
|
const [sessionLoaded, setSessionLoaded] = React.useState(false);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!loading) {
|
||||||
|
setSessionLoaded(true);
|
||||||
|
}
|
||||||
|
}, [loading]);
|
||||||
|
|
||||||
const businessComponents = [
|
const businessComponents = [
|
||||||
{
|
{
|
||||||
title: "Businesses",
|
title: "Businesses",
|
||||||
@ -151,12 +192,17 @@ export function UnsignedNav() {
|
|||||||
<div className="flex gap-2 pl-2">
|
<div className="flex gap-2 pl-2">
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
<Separator orientation="vertical" className="mx-3" />
|
<Separator orientation="vertical" className="mx-3" />
|
||||||
<Link href="/auth">
|
{sessionLoaded ? (
|
||||||
<Button variant="secondary" className="border-2 border-border">
|
user ? (
|
||||||
Login
|
authenticatedComponents()
|
||||||
</Button>
|
) : (
|
||||||
</Link>
|
unAuthenticatedComponents()
|
||||||
<Button>Sign up</Button>
|
)
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<Skeleton className="rounded-lg h-full w-[160px]" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
50
src/components/ui/avatar.tsx
Normal file
50
src/components/ui/avatar.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as AvatarPrimitive from "@radix-ui/react-avatar"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Avatar = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AvatarPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<AvatarPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
Avatar.displayName = AvatarPrimitive.Root.displayName
|
||||||
|
|
||||||
|
const AvatarImage = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AvatarPrimitive.Image>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<AvatarPrimitive.Image
|
||||||
|
ref={ref}
|
||||||
|
className={cn("aspect-square h-full w-full", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
AvatarImage.displayName = AvatarPrimitive.Image.displayName
|
||||||
|
|
||||||
|
const AvatarFallback = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<AvatarPrimitive.Fallback
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-full w-full items-center justify-center rounded-full bg-muted",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
|
||||||
|
|
||||||
|
export { Avatar, AvatarImage, AvatarFallback }
|
||||||
160
src/components/ui/select.tsx
Normal file
160
src/components/ui/select.tsx
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as SelectPrimitive from "@radix-ui/react-select"
|
||||||
|
import { Check, ChevronDown, ChevronUp } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Select = SelectPrimitive.Root
|
||||||
|
|
||||||
|
const SelectGroup = SelectPrimitive.Group
|
||||||
|
|
||||||
|
const SelectValue = SelectPrimitive.Value
|
||||||
|
|
||||||
|
const SelectTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Trigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<SelectPrimitive.Icon asChild>
|
||||||
|
<ChevronDown className="h-4 w-4 opacity-50" />
|
||||||
|
</SelectPrimitive.Icon>
|
||||||
|
</SelectPrimitive.Trigger>
|
||||||
|
))
|
||||||
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
|
||||||
|
|
||||||
|
const SelectScrollUpButton = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.ScrollUpButton
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default items-center justify-center py-1",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ChevronUp className="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ScrollUpButton>
|
||||||
|
))
|
||||||
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
|
||||||
|
|
||||||
|
const SelectScrollDownButton = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.ScrollDownButton
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default items-center justify-center py-1",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ChevronDown className="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ScrollDownButton>
|
||||||
|
))
|
||||||
|
SelectScrollDownButton.displayName =
|
||||||
|
SelectPrimitive.ScrollDownButton.displayName
|
||||||
|
|
||||||
|
const SelectContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
||||||
|
>(({ className, children, position = "popper", ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Portal>
|
||||||
|
<SelectPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
|
position === "popper" &&
|
||||||
|
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
position={position}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<SelectScrollUpButton />
|
||||||
|
<SelectPrimitive.Viewport
|
||||||
|
className={cn(
|
||||||
|
"p-1",
|
||||||
|
position === "popper" &&
|
||||||
|
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</SelectPrimitive.Viewport>
|
||||||
|
<SelectScrollDownButton />
|
||||||
|
</SelectPrimitive.Content>
|
||||||
|
</SelectPrimitive.Portal>
|
||||||
|
))
|
||||||
|
SelectContent.displayName = SelectPrimitive.Content.displayName
|
||||||
|
|
||||||
|
const SelectLabel = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Label>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Label
|
||||||
|
ref={ref}
|
||||||
|
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
SelectLabel.displayName = SelectPrimitive.Label.displayName
|
||||||
|
|
||||||
|
const SelectItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||||
|
<SelectPrimitive.ItemIndicator>
|
||||||
|
<Check className="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ItemIndicator>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
||||||
|
</SelectPrimitive.Item>
|
||||||
|
))
|
||||||
|
SelectItem.displayName = SelectPrimitive.Item.displayName
|
||||||
|
|
||||||
|
const SelectSeparator = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Separator>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Separator
|
||||||
|
ref={ref}
|
||||||
|
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName
|
||||||
|
|
||||||
|
export {
|
||||||
|
Select,
|
||||||
|
SelectGroup,
|
||||||
|
SelectValue,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectContent,
|
||||||
|
SelectLabel,
|
||||||
|
SelectItem,
|
||||||
|
SelectSeparator,
|
||||||
|
SelectScrollUpButton,
|
||||||
|
SelectScrollDownButton,
|
||||||
|
}
|
||||||
15
src/components/ui/skeleton.tsx
Normal file
15
src/components/ui/skeleton.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
function Skeleton({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn("animate-pulse rounded-md bg-muted", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Skeleton }
|
||||||
27
src/lib/supabase/useSession.ts
Normal file
27
src/lib/supabase/useSession.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { createSupabaseClient } from "./clientComponentClient";
|
||||||
|
import { Session } from "@supabase/supabase-js";
|
||||||
|
|
||||||
|
export default function useSession() {
|
||||||
|
const [session, setSession] = useState<Session | null>(null);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const supabase = createSupabaseClient();
|
||||||
|
|
||||||
|
const getSession = async () => {
|
||||||
|
const {
|
||||||
|
data: { session },
|
||||||
|
} = await supabase.auth.getSession();
|
||||||
|
|
||||||
|
setSession(session);
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
getSession();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { session, loading };
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user