mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-19 05:54:06 +01:00
Merge pull request #38 from Sosokker/front-end
Add specific project investment page and several tests with playwright + Refactor invest page code + Add search system
This commit is contained in:
commit
5ad8281d58
27
.github/workflows/playwright.yml
vendored
Normal file
27
.github/workflows/playwright.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# name: Playwright Tests
|
||||||
|
# on:
|
||||||
|
# push:
|
||||||
|
# branches: [ main, master ]
|
||||||
|
# pull_request:
|
||||||
|
# branches: [ main, master ]
|
||||||
|
# jobs:
|
||||||
|
# test:
|
||||||
|
# timeout-minutes: 60
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# - uses: actions/setup-node@v4
|
||||||
|
# with:
|
||||||
|
# node-version: lts/*
|
||||||
|
# - name: Install dependencies
|
||||||
|
# run: npm ci
|
||||||
|
# - name: Install Playwright Browsers
|
||||||
|
# run: npx playwright install --with-deps
|
||||||
|
# - name: Run Playwright tests
|
||||||
|
# run: npx playwright test
|
||||||
|
# - uses: actions/upload-artifact@v4
|
||||||
|
# if: ${{ !cancelled() }}
|
||||||
|
# with:
|
||||||
|
# name: playwright-report
|
||||||
|
# path: playwright-report/
|
||||||
|
# retention-days: 30
|
||||||
10
.gitignore
vendored
10
.gitignore
vendored
@ -38,4 +38,12 @@ next-env.d.ts
|
|||||||
|
|
||||||
.env
|
.env
|
||||||
.env.local
|
.env.local
|
||||||
.vscode
|
.vscode
|
||||||
|
node_modules/
|
||||||
|
/test-results/
|
||||||
|
/playwright-report/
|
||||||
|
/blob-report/
|
||||||
|
/playwright/.cache/
|
||||||
|
|
||||||
|
|
||||||
|
storageState.json
|
||||||
1171
package-lock.json
generated
1171
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -10,19 +10,27 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-avatar": "^1.1.0",
|
"@radix-ui/react-avatar": "^1.1.0",
|
||||||
|
"@radix-ui/react-dialog": "^1.1.2",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-hover-card": "^1.1.1",
|
"@radix-ui/react-hover-card": "^1.1.1",
|
||||||
|
"@radix-ui/react-label": "^2.1.0",
|
||||||
"@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-radio-group": "^1.2.1",
|
||||||
"@radix-ui/react-select": "^2.1.1",
|
"@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",
|
||||||
|
"@radix-ui/react-tabs": "^1.1.0",
|
||||||
"@radix-ui/react-tooltip": "^1.1.2",
|
"@radix-ui/react-tooltip": "^1.1.2",
|
||||||
|
"@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",
|
||||||
|
"@tanstack/react-query": "^5.59.0",
|
||||||
|
"@tanstack/react-query-devtools": "^5.59.0",
|
||||||
"b2d-ventures": "file:",
|
"b2d-ventures": "file:",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"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.5",
|
||||||
@ -31,10 +39,12 @@
|
|||||||
"react-countup": "^6.5.3",
|
"react-countup": "^6.5.3",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
|
"recharts": "^2.12.7",
|
||||||
"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",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
|
|||||||
84
playwright.config.ts
Normal file
84
playwright.config.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { defineConfig, devices } from '@playwright/test';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read environment variables from file.
|
||||||
|
* https://github.com/motdotla/dotenv
|
||||||
|
*/
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
import path from 'path';
|
||||||
|
dotenv.config({ path: path.resolve(__dirname, '.env') });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See https://playwright.dev/docs/test-configuration.
|
||||||
|
*/
|
||||||
|
export default defineConfig({
|
||||||
|
globalSetup: require.resolve('./test_util/global-setup'),
|
||||||
|
testDir: './tests',
|
||||||
|
/* Run tests in files in parallel */
|
||||||
|
fullyParallel: true,
|
||||||
|
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||||
|
forbidOnly: !!process.env.CI,
|
||||||
|
/* Retry on CI only */
|
||||||
|
retries: process.env.CI ? 2 : 0,
|
||||||
|
/* Opt out of parallel tests on CI. */
|
||||||
|
workers: process.env.CI ? 1 : undefined,
|
||||||
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||||
|
reporter: 'html',
|
||||||
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||||
|
use: {
|
||||||
|
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||||
|
baseURL: 'http://127.0.0.1:3000',
|
||||||
|
|
||||||
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||||
|
trace: 'on-first-retry',
|
||||||
|
storageState: './storageState.json',
|
||||||
|
ignoreHTTPSErrors: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Configure projects for major browsers */
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
name: 'chromium',
|
||||||
|
use: { ...devices['Desktop Chrome'] },
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'firefox',
|
||||||
|
use: { ...devices['Desktop Firefox'],
|
||||||
|
storageState:"./storageState.json"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'webkit',
|
||||||
|
use: { ...devices['Desktop Safari'] },
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Test against mobile viewports. */
|
||||||
|
// {
|
||||||
|
// name: 'Mobile Chrome',
|
||||||
|
// use: { ...devices['Pixel 5'] },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'Mobile Safari',
|
||||||
|
// use: { ...devices['iPhone 12'] },
|
||||||
|
// },
|
||||||
|
|
||||||
|
/* Test against branded browsers. */
|
||||||
|
// {
|
||||||
|
// name: 'Microsoft Edge',
|
||||||
|
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'Google Chrome',
|
||||||
|
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
|
||||||
|
/* Run your local dev server before starting the tests */
|
||||||
|
webServer: {
|
||||||
|
command: 'npm run dev',
|
||||||
|
url: 'http://127.0.0.1:3000',
|
||||||
|
reuseExistingServer: !process.env.CI,
|
||||||
|
},
|
||||||
|
});
|
||||||
621
pnpm-lock.yaml
621
pnpm-lock.yaml
@ -1,21 +1,34 @@
|
|||||||
lockfileVersion: '6.0'
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-avatar':
|
'@radix-ui/react-avatar':
|
||||||
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-dialog':
|
||||||
|
specifier: ^1.1.2
|
||||||
|
version: 1.1.2(@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)
|
||||||
'@radix-ui/react-hover-card':
|
'@radix-ui/react-hover-card':
|
||||||
specifier: ^1.1.1
|
specifier: ^1.1.1
|
||||||
version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
version: 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-label':
|
||||||
|
specifier: ^2.1.0
|
||||||
|
version: 2.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-navigation-menu':
|
'@radix-ui/react-navigation-menu':
|
||||||
specifier: ^1.2.0
|
specifier: ^1.2.0
|
||||||
version: 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
version: 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-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-radio-group':
|
||||||
|
specifier: ^1.2.1
|
||||||
|
version: 1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
'@radix-ui/react-select':
|
'@radix-ui/react-select':
|
||||||
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)
|
||||||
@ -25,21 +38,36 @@ dependencies:
|
|||||||
'@radix-ui/react-slot':
|
'@radix-ui/react-slot':
|
||||||
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)
|
||||||
|
'@radix-ui/react-tabs':
|
||||||
|
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-tooltip':
|
'@radix-ui/react-tooltip':
|
||||||
specifier: ^1.1.2
|
specifier: ^1.1.2
|
||||||
version: 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
version: 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@supabase-cache-helpers/postgrest-react-query':
|
||||||
|
specifier: ^1.10.1
|
||||||
|
version: 1.10.1(@supabase/postgrest-js@1.15.8)(@supabase/supabase-js@2.45.2)(@tanstack/react-query@5.59.0)(react@18.3.1)
|
||||||
'@supabase/ssr':
|
'@supabase/ssr':
|
||||||
specifier: ^0.4.1
|
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.2
|
specifier: ^2.45.2
|
||||||
version: 2.45.2
|
version: 2.45.2
|
||||||
|
'@tanstack/react-query':
|
||||||
|
specifier: ^5.59.0
|
||||||
|
version: 5.59.0(react@18.3.1)
|
||||||
|
'@tanstack/react-query-devtools':
|
||||||
|
specifier: ^5.59.0
|
||||||
|
version: 5.59.0(@tanstack/react-query@5.59.0)(react@18.3.1)
|
||||||
class-variance-authority:
|
class-variance-authority:
|
||||||
specifier: ^0.7.0
|
specifier: ^0.7.0
|
||||||
version: 0.7.0
|
version: 0.7.0
|
||||||
clsx:
|
clsx:
|
||||||
specifier: ^2.1.1
|
specifier: ^2.1.1
|
||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
|
dotenv:
|
||||||
|
specifier: ^16.4.5
|
||||||
|
version: 16.4.5
|
||||||
embla-carousel-react:
|
embla-carousel-react:
|
||||||
specifier: ^8.2.0
|
specifier: ^8.2.0
|
||||||
version: 8.2.0(react@18.3.1)
|
version: 8.2.0(react@18.3.1)
|
||||||
@ -48,7 +76,7 @@ dependencies:
|
|||||||
version: 0.428.0(react@18.3.1)
|
version: 0.428.0(react@18.3.1)
|
||||||
next:
|
next:
|
||||||
specifier: 14.2.5
|
specifier: 14.2.5
|
||||||
version: 14.2.5(react-dom@18.3.1)(react@18.3.1)
|
version: 14.2.5(@playwright/test@1.47.2)(react-dom@18.3.1)(react@18.3.1)
|
||||||
next-themes:
|
next-themes:
|
||||||
specifier: ^0.3.0
|
specifier: ^0.3.0
|
||||||
version: 0.3.0(react-dom@18.3.1)(react@18.3.1)
|
version: 0.3.0(react-dom@18.3.1)(react@18.3.1)
|
||||||
@ -64,6 +92,9 @@ dependencies:
|
|||||||
react-hot-toast:
|
react-hot-toast:
|
||||||
specifier: ^2.4.1
|
specifier: ^2.4.1
|
||||||
version: 2.4.1(csstype@3.1.3)(react-dom@18.3.1)(react@18.3.1)
|
version: 2.4.1(csstype@3.1.3)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
recharts:
|
||||||
|
specifier: ^2.12.7
|
||||||
|
version: 2.12.7(react-dom@18.3.1)(react@18.3.1)
|
||||||
tailwind-merge:
|
tailwind-merge:
|
||||||
specifier: ^2.5.2
|
specifier: ^2.5.2
|
||||||
version: 2.5.2
|
version: 2.5.2
|
||||||
@ -72,6 +103,9 @@ dependencies:
|
|||||||
version: 1.0.7(tailwindcss@3.4.10)
|
version: 1.0.7(tailwindcss@3.4.10)
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@playwright/test':
|
||||||
|
specifier: ^1.47.2
|
||||||
|
version: 1.47.2
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20
|
specifier: ^20
|
||||||
version: 20.16.2
|
version: 20.16.2
|
||||||
@ -103,6 +137,21 @@ packages:
|
|||||||
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
/@babel/runtime-corejs3@7.25.7:
|
||||||
|
resolution: {integrity: sha512-gMmIEhg35sXk9Te5qbGp3W9YKrvLt3HV658/d3odWrHSqT0JeG5OzsJWFHRLiOohRyjRsJc/x03DhJm3i8VJxg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
core-js-pure: 3.38.1
|
||||||
|
regenerator-runtime: 0.14.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/runtime@7.25.7:
|
||||||
|
resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime: 0.14.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@eslint-community/eslint-utils@4.4.0(eslint@8.57.0):
|
/@eslint-community/eslint-utils@4.4.0(eslint@8.57.0):
|
||||||
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
@ -346,6 +395,13 @@ packages:
|
|||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
/@playwright/test@1.47.2:
|
||||||
|
resolution: {integrity: sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
playwright: 1.47.2
|
||||||
|
|
||||||
/@radix-ui/number@1.1.0:
|
/@radix-ui/number@1.1.0:
|
||||||
resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
|
resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
|
||||||
dev: false
|
dev: false
|
||||||
@ -446,6 +502,52 @@ packages:
|
|||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-context@1.1.1(@types/react@18.3.4)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@types/react': 18.3.4
|
||||||
|
react: 18.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-dialog@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==}
|
||||||
|
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/primitive': 1.1.0
|
||||||
|
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-context': 1.1.1(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-dismissable-layer': 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-focus-guards': 1.1.1(@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-portal': 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@radix-ui/react-presence': 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-controllable-state': 1.1.0(@types/react@18.3.4)(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.6.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-direction@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):
|
||||||
resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==}
|
resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -483,6 +585,30 @@ 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-dismissable-layer@1.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-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==}
|
||||||
|
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/primitive': 1.1.0
|
||||||
|
'@radix-ui/react-compose-refs': 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-escape-keydown': 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-dropdown-menu@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-dropdown-menu@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-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==}
|
resolution: {integrity: sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -522,6 +648,19 @@ packages:
|
|||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.4)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@types/react': 18.3.4
|
||||||
|
react: 18.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@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-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):
|
||||||
resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==}
|
resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -586,6 +725,26 @@ packages:
|
|||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-label@2.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-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==}
|
||||||
|
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-primitive': 2.0.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
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-menu@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-menu@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-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==}
|
resolution: {integrity: sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -706,6 +865,27 @@ 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-portal@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==}
|
||||||
|
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-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-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-presence@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-presence@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-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==}
|
resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -727,6 +907,27 @@ 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-presence@1.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-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==}
|
||||||
|
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-compose-refs': 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-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-primitive@2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==}
|
resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -768,6 +969,35 @@ 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-radio-group@1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-kdbv54g4vfRjja9DNWPMxKvXblzqbpEC8kspEkZ6dVP7kQksGCn+iZHkcCz2nb00+lPdRvxrqy4WrvvV1cNqrQ==}
|
||||||
|
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/primitive': 1.1.0
|
||||||
|
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-context': 1.1.1(@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-presence': 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-roving-focus': 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-use-controllable-state': 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-use-size': 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-roving-focus@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-roving-focus@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-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==}
|
resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -870,6 +1100,33 @@ packages:
|
|||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-tabs@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-bZgOKB/LtZIij75FSuPzyEti/XBhJH52ExgtdVqjCIh+Nx/FW+LhnbXtbCzIi34ccyMsyOja8T0thCzoHFXNKA==}
|
||||||
|
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/primitive': 1.1.0
|
||||||
|
'@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-id': 1.1.0(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
'@radix-ui/react-presence': 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-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-roving-focus': 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-use-controllable-state': 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-tooltip@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
/@radix-ui/react-tooltip@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==}
|
resolution: {integrity: sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1032,6 +1289,36 @@ packages:
|
|||||||
resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==}
|
resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@supabase-cache-helpers/postgrest-core@0.8.1(@supabase/postgrest-js@1.15.8)(@supabase/supabase-js@2.45.2):
|
||||||
|
resolution: {integrity: sha512-WlmpQBBui54jQPQ9CwE7rdDcdPcMQLRl37aRJ+AEpEm47HMn0lJ/0cTuC8BT0aBMHK8BgOSx0dZ1QjgND1sB6g==}
|
||||||
|
peerDependencies:
|
||||||
|
'@supabase/postgrest-js': ^1.9.0
|
||||||
|
'@supabase/supabase-js': ^2.0.0
|
||||||
|
dependencies:
|
||||||
|
'@supabase/postgrest-js': 1.15.8
|
||||||
|
'@supabase/supabase-js': 2.45.2
|
||||||
|
fast-equals: 5.0.1
|
||||||
|
flat: 6.0.1
|
||||||
|
merge-anything: 5.1.7
|
||||||
|
xregexp: 5.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@supabase-cache-helpers/postgrest-react-query@1.10.1(@supabase/postgrest-js@1.15.8)(@supabase/supabase-js@2.45.2)(@tanstack/react-query@5.59.0)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-BGGrEKue6mSH0el1iO1+iOSuyGqQxsHQ2B8dXWlDvYGmU7rmw5AGqXqDWngMBX68LcoHVJEogdbXP0pH4+1Tuw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@supabase/postgrest-js': ^1.9.0
|
||||||
|
'@tanstack/react-query': ^4.0.0 || ^5.0.0
|
||||||
|
react: ^16.11.0 || ^17.0.0 || ^18.0.0
|
||||||
|
dependencies:
|
||||||
|
'@supabase-cache-helpers/postgrest-core': 0.8.1(@supabase/postgrest-js@1.15.8)(@supabase/supabase-js@2.45.2)
|
||||||
|
'@supabase/postgrest-js': 1.15.8
|
||||||
|
'@tanstack/react-query': 5.59.0(react@18.3.1)
|
||||||
|
flat: 6.0.1
|
||||||
|
react: 18.3.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@supabase/supabase-js'
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@supabase/auth-js@2.64.4:
|
/@supabase/auth-js@2.64.4:
|
||||||
resolution: {integrity: sha512-9ITagy4WP4FLl+mke1rchapOH0RQpf++DI+WSG2sO1OFOZ0rW3cwAM0nCrMOxu+Zw4vJ4zObc08uvQrXx590Tg==}
|
resolution: {integrity: sha512-9ITagy4WP4FLl+mke1rchapOH0RQpf++DI+WSG2sO1OFOZ0rW3cwAM0nCrMOxu+Zw4vJ4zObc08uvQrXx590Tg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1111,6 +1398,76 @@ packages:
|
|||||||
tslib: 2.7.0
|
tslib: 2.7.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@tanstack/query-core@5.59.0:
|
||||||
|
resolution: {integrity: sha512-WGD8uIhX6/deH/tkZqPNcRyAhDUqs729bWKoByYHSogcshXfFbppOdTER5+qY7mFvu8KEFJwT0nxr8RfPTVh0Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@tanstack/query-devtools@5.58.0:
|
||||||
|
resolution: {integrity: sha512-iFdQEFXaYYxqgrv63ots+65FGI+tNp5ZS5PdMU1DWisxk3fez5HG3FyVlbUva+RdYS5hSLbxZ9aw3yEs97GNTw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@tanstack/react-query-devtools@5.59.0(@tanstack/react-query@5.59.0)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-Kz7577FQGU8qmJxROIT/aOwmkTcxfBqgTP6r1AIvuJxVMVHPkp8eQxWQ7BnfBsy/KTJHiV9vMtRVo1+R1tB3vg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tanstack/react-query': ^5.59.0
|
||||||
|
react: ^18 || ^19
|
||||||
|
dependencies:
|
||||||
|
'@tanstack/query-devtools': 5.58.0
|
||||||
|
'@tanstack/react-query': 5.59.0(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@tanstack/react-query@5.59.0(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-YDXp3OORbYR+8HNQx+lf4F73NoiCmCcSvZvgxE29OifmQFk0sBlO26NWLHpcNERo92tVk3w+JQ53/vkcRUY1hA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^18 || ^19
|
||||||
|
dependencies:
|
||||||
|
'@tanstack/query-core': 5.59.0
|
||||||
|
react: 18.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-array@3.2.1:
|
||||||
|
resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-color@3.1.3:
|
||||||
|
resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-ease@3.0.2:
|
||||||
|
resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-interpolate@3.0.4:
|
||||||
|
resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-color': 3.1.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-path@3.1.0:
|
||||||
|
resolution: {integrity: sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-scale@4.0.8:
|
||||||
|
resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-time': 3.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-shape@3.1.6:
|
||||||
|
resolution: {integrity: sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-path': 3.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-time@3.0.3:
|
||||||
|
resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-timer@3.0.2:
|
||||||
|
resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@types/json5@0.0.29:
|
/@types/json5@0.0.29:
|
||||||
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -1519,6 +1876,11 @@ packages:
|
|||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/core-js-pure@3.38.1:
|
||||||
|
resolution: {integrity: sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==}
|
||||||
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/countup.js@2.8.0:
|
/countup.js@2.8.0:
|
||||||
resolution: {integrity: sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ==}
|
resolution: {integrity: sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ==}
|
||||||
dev: false
|
dev: false
|
||||||
@ -1539,6 +1901,77 @@ packages:
|
|||||||
/csstype@3.1.3:
|
/csstype@3.1.3:
|
||||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||||
|
|
||||||
|
/d3-array@3.2.4:
|
||||||
|
resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
internmap: 2.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-color@3.1.0:
|
||||||
|
resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-ease@3.0.1:
|
||||||
|
resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-format@3.1.0:
|
||||||
|
resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-interpolate@3.0.1:
|
||||||
|
resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-color: 3.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-path@3.1.0:
|
||||||
|
resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-scale@4.0.2:
|
||||||
|
resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
d3-format: 3.1.0
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-time: 3.1.0
|
||||||
|
d3-time-format: 4.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-shape@3.2.0:
|
||||||
|
resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-path: 3.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-time-format@4.1.0:
|
||||||
|
resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-time: 3.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-time@3.1.0:
|
||||||
|
resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-timer@3.0.1:
|
||||||
|
resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/damerau-levenshtein@1.0.8:
|
/damerau-levenshtein@1.0.8:
|
||||||
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -1593,6 +2026,10 @@ packages:
|
|||||||
ms: 2.1.2
|
ms: 2.1.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/decimal.js-light@2.5.1:
|
||||||
|
resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/deep-equal@2.2.3:
|
/deep-equal@2.2.3:
|
||||||
resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==}
|
resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -1670,6 +2107,18 @@ packages:
|
|||||||
esutils: 2.0.3
|
esutils: 2.0.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/dom-helpers@5.2.1:
|
||||||
|
resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.25.7
|
||||||
|
csstype: 3.1.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/dotenv@16.4.5:
|
||||||
|
resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/eastasianwidth@0.2.0:
|
/eastasianwidth@0.2.0:
|
||||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||||
|
|
||||||
@ -2128,10 +2577,19 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eventemitter3@4.0.7:
|
||||||
|
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fast-deep-equal@3.1.3:
|
/fast-deep-equal@3.1.3:
|
||||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/fast-equals@5.0.1:
|
||||||
|
resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fast-glob@3.3.2:
|
/fast-glob@3.3.2:
|
||||||
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
|
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
|
||||||
engines: {node: '>=8.6.0'}
|
engines: {node: '>=8.6.0'}
|
||||||
@ -2185,6 +2643,12 @@ packages:
|
|||||||
rimraf: 3.0.2
|
rimraf: 3.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/flat@6.0.1:
|
||||||
|
resolution: {integrity: sha512-/3FfIa8mbrg3xE7+wAhWeV+bd7L2Mof+xtZb5dRDKZ+wDvYJK4WDYeIOuOhre5Yv5aQObZrlbRmk3RTSiuQBtw==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/flatted@3.3.1:
|
/flatted@3.3.1:
|
||||||
resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
|
resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -2206,6 +2670,13 @@ packages:
|
|||||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/fsevents@2.3.2:
|
||||||
|
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||||
|
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||||
|
os: [darwin]
|
||||||
|
requiresBuild: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
/fsevents@2.3.3:
|
/fsevents@2.3.3:
|
||||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||||
@ -2433,6 +2904,11 @@ packages:
|
|||||||
side-channel: 1.0.6
|
side-channel: 1.0.6
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/internmap@2.0.3:
|
||||||
|
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/invariant@2.2.4:
|
/invariant@2.2.4:
|
||||||
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
|
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -2626,6 +3102,11 @@ packages:
|
|||||||
get-intrinsic: 1.2.4
|
get-intrinsic: 1.2.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/is-what@4.1.16:
|
||||||
|
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
|
||||||
|
engines: {node: '>=12.13'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/isarray@2.0.5:
|
/isarray@2.0.5:
|
||||||
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
|
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -2749,6 +3230,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/lodash@4.17.21:
|
||||||
|
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/loose-envify@1.4.0:
|
/loose-envify@1.4.0:
|
||||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@ -2766,6 +3251,13 @@ packages:
|
|||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/merge-anything@5.1.7:
|
||||||
|
resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==}
|
||||||
|
engines: {node: '>=12.13'}
|
||||||
|
dependencies:
|
||||||
|
is-what: 4.1.16
|
||||||
|
dev: false
|
||||||
|
|
||||||
/merge2@1.4.1:
|
/merge2@1.4.1:
|
||||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@ -2838,7 +3330,7 @@ packages:
|
|||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/next@14.2.5(react-dom@18.3.1)(react@18.3.1):
|
/next@14.2.5(@playwright/test@1.47.2)(react-dom@18.3.1)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==}
|
resolution: {integrity: sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==}
|
||||||
engines: {node: '>=18.17.0'}
|
engines: {node: '>=18.17.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@ -2857,6 +3349,7 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@next/env': 14.2.5
|
'@next/env': 14.2.5
|
||||||
|
'@playwright/test': 1.47.2
|
||||||
'@swc/helpers': 0.5.5
|
'@swc/helpers': 0.5.5
|
||||||
busboy: 1.6.0
|
busboy: 1.6.0
|
||||||
caniuse-lite: 1.0.30001653
|
caniuse-lite: 1.0.30001653
|
||||||
@ -3043,6 +3536,20 @@ packages:
|
|||||||
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
|
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
/playwright-core@1.47.2:
|
||||||
|
resolution: {integrity: sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
/playwright@1.47.2:
|
||||||
|
resolution: {integrity: sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
playwright-core: 1.47.2
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents: 2.3.2
|
||||||
|
|
||||||
/possible-typed-array-names@1.0.0:
|
/possible-typed-array-names@1.0.0:
|
||||||
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
|
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -3131,7 +3638,6 @@ packages:
|
|||||||
loose-envify: 1.4.0
|
loose-envify: 1.4.0
|
||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
react-is: 16.13.1
|
react-is: 16.13.1
|
||||||
dev: true
|
|
||||||
|
|
||||||
/punycode@2.3.1:
|
/punycode@2.3.1:
|
||||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||||
@ -3176,7 +3682,6 @@ packages:
|
|||||||
|
|
||||||
/react-is@16.13.1:
|
/react-is@16.13.1:
|
||||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/react-remove-scroll-bar@2.3.6(@types/react@18.3.4)(react@18.3.1):
|
/react-remove-scroll-bar@2.3.6(@types/react@18.3.4)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==}
|
resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==}
|
||||||
@ -3213,6 +3718,38 @@ packages:
|
|||||||
use-sidecar: 1.1.2(@types/react@18.3.4)(react@18.3.1)
|
use-sidecar: 1.1.2(@types/react@18.3.4)(react@18.3.1)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-remove-scroll@2.6.0(@types/react@18.3.4)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@types/react': 18.3.4
|
||||||
|
react: 18.3.1
|
||||||
|
react-remove-scroll-bar: 2.3.6(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
react-style-singleton: 2.2.1(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
tslib: 2.7.0
|
||||||
|
use-callback-ref: 1.3.2(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
use-sidecar: 1.1.2(@types/react@18.3.4)(react@18.3.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/react-smooth@4.0.1(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||||
|
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||||
|
dependencies:
|
||||||
|
fast-equals: 5.0.1
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
react-transition-group: 4.4.5(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-style-singleton@2.2.1(@types/react@18.3.4)(react@18.3.1):
|
/react-style-singleton@2.2.1(@types/react@18.3.4)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
|
resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -3230,6 +3767,20 @@ packages:
|
|||||||
tslib: 2.7.0
|
tslib: 2.7.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-transition-group@4.4.5(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.6.0'
|
||||||
|
react-dom: '>=16.6.0'
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.25.7
|
||||||
|
dom-helpers: 5.2.1
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react@18.3.1:
|
/react@18.3.1:
|
||||||
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
|
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -3248,6 +3799,31 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
|
|
||||||
|
/recharts-scale@0.4.5:
|
||||||
|
resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==}
|
||||||
|
dependencies:
|
||||||
|
decimal.js-light: 2.5.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/recharts@2.12.7(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-hlLJMhPQfv4/3NBSAyq3gzGg4h2v69RJh6KU7b3pXYNNAELs9kEoXOjbkxdXpALqKBoVmVptGfLpxdaVYqjmXQ==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||||
|
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||||
|
dependencies:
|
||||||
|
clsx: 2.1.1
|
||||||
|
eventemitter3: 4.0.7
|
||||||
|
lodash: 4.17.21
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
react-is: 16.13.1
|
||||||
|
react-smooth: 4.0.1(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
recharts-scale: 0.4.5
|
||||||
|
tiny-invariant: 1.3.3
|
||||||
|
victory-vendor: 36.9.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/reflect.getprototypeof@1.0.6:
|
/reflect.getprototypeof@1.0.6:
|
||||||
resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==}
|
resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -3261,6 +3837,10 @@ packages:
|
|||||||
which-builtin-type: 1.1.4
|
which-builtin-type: 1.1.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/regenerator-runtime@0.14.1:
|
||||||
|
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/regexp.prototype.flags@1.5.2:
|
/regexp.prototype.flags@1.5.2:
|
||||||
resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==}
|
resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -3617,6 +4197,10 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
any-promise: 1.3.0
|
any-promise: 1.3.0
|
||||||
|
|
||||||
|
/tiny-invariant@1.3.3:
|
||||||
|
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/to-regex-range@5.0.1:
|
/to-regex-range@5.0.1:
|
||||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||||
engines: {node: '>=8.0'}
|
engines: {node: '>=8.0'}
|
||||||
@ -3766,6 +4350,25 @@ packages:
|
|||||||
/util-deprecate@1.0.2:
|
/util-deprecate@1.0.2:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
|
/victory-vendor@36.9.2:
|
||||||
|
resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-array': 3.2.1
|
||||||
|
'@types/d3-ease': 3.0.2
|
||||||
|
'@types/d3-interpolate': 3.0.4
|
||||||
|
'@types/d3-scale': 4.0.8
|
||||||
|
'@types/d3-shape': 3.1.6
|
||||||
|
'@types/d3-time': 3.0.3
|
||||||
|
'@types/d3-timer': 3.0.2
|
||||||
|
d3-array: 3.2.4
|
||||||
|
d3-ease: 3.0.1
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-scale: 4.0.2
|
||||||
|
d3-shape: 3.2.0
|
||||||
|
d3-time: 3.1.0
|
||||||
|
d3-timer: 3.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/webidl-conversions@3.0.1:
|
/webidl-conversions@3.0.1:
|
||||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
dev: false
|
dev: false
|
||||||
@ -3871,6 +4474,12 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/xregexp@5.1.1:
|
||||||
|
resolution: {integrity: sha512-fKXeVorD+CzWvFs7VBuKTYIW63YD1e1osxwQ8caZ6o1jg6pDAbABDG54LCIq0j5cy7PjRvGIq6sef9DYPXpncg==}
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime-corejs3': 7.25.7
|
||||||
|
dev: false
|
||||||
|
|
||||||
/yaml@2.5.0:
|
/yaml@2.5.0:
|
||||||
resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==}
|
resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==}
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
@ -3880,7 +4489,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
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { Card, CardContent, CardFooter, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardFooter, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
|
||||||
import { LoginButton } from "@/components/auth/loginButton";
|
import { LoginButton } from "@/components/auth/loginButton";
|
||||||
|
import { LoginForm } from "@/components/auth/loginForm";
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
return (
|
return (
|
||||||
@ -18,6 +19,8 @@ export default function Login() {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-col gap-y-2 mx-28">
|
<CardContent className="flex flex-col gap-y-2 mx-28">
|
||||||
<p className="self-center font-semibold text-slate-800 dark:text-slate-200">Continue With</p>
|
<p className="self-center font-semibold text-slate-800 dark:text-slate-200">Continue With</p>
|
||||||
|
<LoginForm />
|
||||||
|
<hr></hr>
|
||||||
<LoginButton />
|
<LoginButton />
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter className="text-xs justify-center">
|
<CardFooter className="text-xs justify-center">
|
||||||
|
|||||||
198
src/app/dashboard/page.tsx
Normal file
198
src/app/dashboard/page.tsx
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
"use client";
|
||||||
|
import Image from "next/image";
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardDescription,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
} from "@/components/ui/card";
|
||||||
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { Overview } from "@/components/ui/overview";
|
||||||
|
import { RecentFunds } from "@/components/recent-funds";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export default function Dashboard() {
|
||||||
|
const [graphType, setGraphType] = useState("line");
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="md:hidden">
|
||||||
|
<Image
|
||||||
|
src="/examples/dashboard-light.png"
|
||||||
|
width={1280}
|
||||||
|
height={866}
|
||||||
|
alt="Dashboard"
|
||||||
|
className="block dark:hidden"
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
src="/examples/dashboard-dark.png"
|
||||||
|
width={1280}
|
||||||
|
height={866}
|
||||||
|
alt="Dashboard"
|
||||||
|
className="hidden dark:block"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="hidden flex-col md:flex">
|
||||||
|
<div className="flex-1 space-y-4 p-8 pt-6">
|
||||||
|
<div className="flex items-center justify-between space-y-2">
|
||||||
|
<h2 className="text-3xl font-bold tracking-tight">Dashboard</h2>
|
||||||
|
</div>
|
||||||
|
<Tabs defaultValue="overview" className="space-y-4">
|
||||||
|
<TabsList>
|
||||||
|
<TabsTrigger value="overview">Overview</TabsTrigger>
|
||||||
|
<TabsTrigger value="analytics">Analytics</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
<TabsContent value="overview" className="space-y-4">
|
||||||
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||||
|
<Card>
|
||||||
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||||
|
<CardTitle className="text-sm font-medium">
|
||||||
|
Total Funds Raised
|
||||||
|
</CardTitle>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
className="h-4 w-4 text-muted-foreground"
|
||||||
|
>
|
||||||
|
<path d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" />
|
||||||
|
</svg>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="text-2xl font-bold">$45,231.89</div>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
+20.1% from last month
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||||
|
<CardTitle className="text-sm font-medium">
|
||||||
|
Profile Views
|
||||||
|
</CardTitle>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
className="h-4 w-4 text-muted-foreground"
|
||||||
|
>
|
||||||
|
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
||||||
|
<circle cx="12" cy="12" r="3"></circle>
|
||||||
|
</svg>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="text-2xl font-bold">+2350</div>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
+180.1% from last month
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||||
|
<CardTitle className="text-sm font-medium">
|
||||||
|
Total Followers
|
||||||
|
</CardTitle>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
className="h-4 w-4 text-muted-foreground"
|
||||||
|
>
|
||||||
|
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" />
|
||||||
|
<circle cx="9" cy="7" r="4" />
|
||||||
|
<path d="M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75" />
|
||||||
|
</svg>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="text-2xl font-bold">+12,234</div>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
+19% from last month
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
{/* <Card>
|
||||||
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||||
|
<CardTitle className="text-sm font-medium">
|
||||||
|
Active Now
|
||||||
|
</CardTitle>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
className="h-4 w-4 text-muted-foreground"
|
||||||
|
>
|
||||||
|
<path d="M22 12h-4l-3 9L9 3l-3 9H2" />
|
||||||
|
</svg>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="text-2xl font-bold">+573</div>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
+201 since last hour
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card> */}
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-7">
|
||||||
|
<Card className="col-span-4">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Overview</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="pl-2">
|
||||||
|
<Overview graphType={graphType} />
|
||||||
|
{/* tab to switch between line and bar graph */}
|
||||||
|
<Tabs
|
||||||
|
defaultValue="line"
|
||||||
|
className="space-y-4 ml-[50%] mt-2"
|
||||||
|
>
|
||||||
|
<TabsList>
|
||||||
|
<TabsTrigger
|
||||||
|
value="line"
|
||||||
|
onClick={() => setGraphType("line")}
|
||||||
|
>
|
||||||
|
Line
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger
|
||||||
|
value="bar"
|
||||||
|
onClick={() => setGraphType("bar")}
|
||||||
|
>
|
||||||
|
Bar
|
||||||
|
</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
</Tabs>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="col-span-3">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Recent Funds</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
You made 265 sales this month.
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<RecentFunds />
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</TabsContent>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,18 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import {
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/components/ui/select";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import {
|
import { Clock3Icon, MessageSquareIcon, UserIcon, UsersIcon } from "lucide-react";
|
||||||
Clock3Icon,
|
|
||||||
MessageSquareIcon,
|
|
||||||
UserIcon,
|
|
||||||
UsersIcon,
|
|
||||||
} from "lucide-react";
|
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
import { ExtendableCard } from "@/components/extendableCard";
|
import { ExtendableCard } from "@/components/extendableCard";
|
||||||
|
|
||||||
@ -21,14 +10,14 @@ export default function Deals() {
|
|||||||
const [contentTypeFilter, setContentTypeFilter] = useState("");
|
const [contentTypeFilter, setContentTypeFilter] = useState("");
|
||||||
const [authorFilter, setAuthorFilter] = useState("");
|
const [authorFilter, setAuthorFilter] = useState("");
|
||||||
const [groupsFilter, setGroupFilter] = useState("");
|
const [groupsFilter, setGroupFilter] = useState("");
|
||||||
|
const [selectedTag, setSelectedTag] = useState("");
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
name: "NVDA",
|
name: "NVDA",
|
||||||
description:
|
description: "Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology",
|
||||||
"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology",
|
|
||||||
joinDate: "December 2021",
|
joinDate: "December 2021",
|
||||||
location: "Bangkok, Thailand",
|
location: "Bangkok, Thailand",
|
||||||
tags: null,
|
tags: ["AI", "Technology"],
|
||||||
minInvestment: 10000,
|
minInvestment: 10000,
|
||||||
totalInvestor: 58400,
|
totalInvestor: 58400,
|
||||||
totalRaised: 9000000,
|
totalRaised: 9000000,
|
||||||
@ -39,7 +28,7 @@ export default function Deals() {
|
|||||||
"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.",
|
||||||
joinDate: "February 2020",
|
joinDate: "February 2020",
|
||||||
location: "Cupertino, California, USA",
|
location: "Cupertino, California, USA",
|
||||||
tags: null,
|
tags: ["Consumer Electronics", "Software"],
|
||||||
minInvestment: 10000,
|
minInvestment: 10000,
|
||||||
totalInvestor: 58400,
|
totalInvestor: 58400,
|
||||||
totalRaised: 9000000,
|
totalRaised: 9000000,
|
||||||
@ -50,30 +39,31 @@ export default function Deals() {
|
|||||||
"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.",
|
||||||
joinDate: "April 2019",
|
joinDate: "April 2019",
|
||||||
location: "Mountain View, California, USA",
|
location: "Mountain View, California, USA",
|
||||||
tags: null,
|
tags: ["Internet", "Search Engine"],
|
||||||
minInvestment: 10000,
|
minInvestment: 10000,
|
||||||
totalInvestor: 5000,
|
totalInvestor: 5000,
|
||||||
totalRaised: 1500000000,
|
totalRaised: 1500000000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Microsoft Corporation",
|
name: "Microsoft Corporation",
|
||||||
description:
|
description: "Microsoft Corporation is a multinational technology company.",
|
||||||
"Microsoft Corporation is a multinational technology company.",
|
|
||||||
joinDate: "January 2018",
|
joinDate: "January 2018",
|
||||||
location: "California, USA",
|
location: "California, USA",
|
||||||
tags: null,
|
tags: ["Technology", "Software"],
|
||||||
minInvestment: 250,
|
minInvestment: 250,
|
||||||
totalInvestor: 5000,
|
totalInvestor: 5000,
|
||||||
totalRaised: 1500000,
|
totalRaised: 1500000,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const filteredData = selectedTag ? data.filter((item) => item.tags.includes(selectedTag)) : data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className=" w-1/2 h-[250px] mt-10 ml-[15%]">
|
<div className=" w-1/2 h-[250px] mt-10 ml-[15%]">
|
||||||
<h1 className="text-4xl font-bold">Investment Opportunities </h1>
|
<h1 className="text-4xl font-bold">Investment Opportunities</h1>
|
||||||
<br />
|
<br />
|
||||||
<p>Browse current investment opportunities on Republic. </p>
|
<p>Browse current investment opportunities on B2DVenture.</p>
|
||||||
<p>
|
<p>
|
||||||
All companies are <u>vetted & pass due diligence.</u>
|
All companies are <u>vetted & pass due diligence.</u>
|
||||||
</p>
|
</p>
|
||||||
@ -89,40 +79,22 @@ export default function Deals() {
|
|||||||
<SelectItem value="Yesterday">Yesterday</SelectItem>
|
<SelectItem value="Yesterday">Yesterday</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<Select onValueChange={(value) => setContentTypeFilter(value)}>
|
<Select onValueChange={(value) => setSelectedTag(value)}>
|
||||||
|
{" "}
|
||||||
|
{/* Tag filtering */}
|
||||||
<SelectTrigger className="w-[180px]">
|
<SelectTrigger className="w-[180px]">
|
||||||
<MessageSquareIcon className="ml-2" />
|
<MessageSquareIcon className="ml-2" />
|
||||||
<SelectValue placeholder="Content type" />
|
<SelectValue placeholder="Tags" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="Blog">Blog</SelectItem>
|
<SelectItem value="_">All Tags</SelectItem> {/* Reset filter */}
|
||||||
<SelectItem value="Youtube">Youtube</SelectItem>
|
<SelectItem value="AI">AI</SelectItem>
|
||||||
|
<SelectItem value="Technology">Technology</SelectItem>
|
||||||
|
<SelectItem value="Consumer Electronics">Consumer Electronics</SelectItem>
|
||||||
|
<SelectItem value="Software">Software</SelectItem>
|
||||||
|
<SelectItem value="Internet">Internet</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</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>
|
</div>
|
||||||
<Separator className="mt-10" />
|
<Separator className="mt-10" />
|
||||||
</div>
|
</div>
|
||||||
@ -133,7 +105,7 @@ export default function Deals() {
|
|||||||
</div>
|
</div>
|
||||||
{/* block for all the deals */}
|
{/* block for all the deals */}
|
||||||
<div className="ml-[15%] mt-10 grid grid-cols-3">
|
<div className="ml-[15%] mt-10 grid grid-cols-3">
|
||||||
{data.map((item, index) => (
|
{filteredData.map((item, index) => (
|
||||||
<ExtendableCard
|
<ExtendableCard
|
||||||
key={index}
|
key={index}
|
||||||
name={item.name}
|
name={item.name}
|
||||||
|
|||||||
180
src/app/find/page.tsx
Normal file
180
src/app/find/page.tsx
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useSearchParams } from "next/navigation";
|
||||||
|
import { SupabaseClient } from "@supabase/supabase-js";
|
||||||
|
import { createSupabaseClient } from "@/lib/supabase/clientComponentClient";
|
||||||
|
import { dehydrate, HydrationBoundary, QueryClient } from "@tanstack/react-query";
|
||||||
|
import { useQuery } from "@supabase-cache-helpers/postgrest-react-query";
|
||||||
|
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||||
|
import { ExtendableCard } from "@/components/extendableCard";
|
||||||
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
|
||||||
|
interface ProjectInvestmentDetail {
|
||||||
|
minInvestment: number;
|
||||||
|
totalInvestment: number;
|
||||||
|
targetInvestment: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Project {
|
||||||
|
id: string;
|
||||||
|
projectName: string;
|
||||||
|
businessId: string;
|
||||||
|
investmentCount: number;
|
||||||
|
projectShortDescription: string;
|
||||||
|
publishedTime: string;
|
||||||
|
ProjectInvestmentDetail: ProjectInvestmentDetail[];
|
||||||
|
tags: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Business {
|
||||||
|
id: string;
|
||||||
|
businessName: string;
|
||||||
|
joinedDate: string;
|
||||||
|
Projects: Project[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBusinesses(client: SupabaseClient, query: string | null) {
|
||||||
|
return client.from("Business").select("id, businessName, joinedDate").ilike("businessName", `%${query}%`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProjects(client: SupabaseClient, businessIds: string[]) {
|
||||||
|
return client
|
||||||
|
.from("Project")
|
||||||
|
.select(
|
||||||
|
`
|
||||||
|
id,
|
||||||
|
projectName,
|
||||||
|
businessId,
|
||||||
|
publishedTime,
|
||||||
|
projectShortDescription,
|
||||||
|
ProjectInvestmentDetail (
|
||||||
|
minInvestment,
|
||||||
|
totalInvestment,
|
||||||
|
targetInvestment
|
||||||
|
)
|
||||||
|
`
|
||||||
|
)
|
||||||
|
.in("businessId", businessIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTags(client: SupabaseClient, projectIds: string[]) {
|
||||||
|
return client.from("ItemTag").select("itemId, Tag (value)").in("itemId", projectIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInvestmentCounts(client: SupabaseClient, projectIds: string[]) {
|
||||||
|
return client.from("InvestmentDeal").select("*", { count: "exact", head: true }).in("projectId", projectIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Find() {
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const query = searchParams.get("query");
|
||||||
|
// const query = "neon";
|
||||||
|
|
||||||
|
let supabase = createSupabaseClient();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: businesses,
|
||||||
|
isLoading: isLoadingBusinesses,
|
||||||
|
error: businessError,
|
||||||
|
} = useQuery(getBusinesses(supabase, query));
|
||||||
|
|
||||||
|
const businessIds = businesses?.map((b) => b.id) || [];
|
||||||
|
const {
|
||||||
|
data: projects,
|
||||||
|
isLoading: isLoadingProjects,
|
||||||
|
error: projectError,
|
||||||
|
} = useQuery(getProjects(supabase, businessIds), { enabled: businessIds.length > 0 });
|
||||||
|
|
||||||
|
const projectIds = projects?.map((p) => p.id) || [];
|
||||||
|
const {
|
||||||
|
data: tags,
|
||||||
|
isLoading: isLoadingTags,
|
||||||
|
error: tagError,
|
||||||
|
} = useQuery(getTags(supabase, projectIds), { enabled: projectIds.length > 0 });
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: investmentCounts,
|
||||||
|
isLoading: isLoadingInvestments,
|
||||||
|
error: investmentError,
|
||||||
|
} = useQuery(getInvestmentCounts(supabase, projectIds), { enabled: projectIds.length > 0 });
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
|
const isLoading = isLoadingBusinesses || isLoadingProjects || isLoadingTags || isLoadingInvestments;
|
||||||
|
const error = businessError || projectError || tagError || investmentError;
|
||||||
|
|
||||||
|
const results: Business[] =
|
||||||
|
businesses?.map((business) => ({
|
||||||
|
...business,
|
||||||
|
Projects:
|
||||||
|
projects
|
||||||
|
?.filter((project) => project.businessId === business.id)
|
||||||
|
.map((project) => ({
|
||||||
|
...project,
|
||||||
|
tags: tags?.filter((tag) => tag.itemId === project.id).map((tag) => tag.Tag.value) || [],
|
||||||
|
investmentCount: investmentCounts?.find((ic) => ic.projectId === project.id)?.count || 0,
|
||||||
|
})) || [],
|
||||||
|
})) || [];
|
||||||
|
|
||||||
|
if (isLoading) return <p>Loading...</p>;
|
||||||
|
if (error) return <p>Error fetching data: {error.message}</p>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="mt-10 mx-[15%]">
|
||||||
|
<h1 className="text-4xl font-bold">Result</h1>
|
||||||
|
|
||||||
|
<Separator className="my-4" />
|
||||||
|
|
||||||
|
{results.length === 0 && <p>No results found.</p>}
|
||||||
|
{results.length > 0 && (
|
||||||
|
<ul>
|
||||||
|
{results.map((business) => (
|
||||||
|
<li key={business.id}>
|
||||||
|
{/* <h2>{business.businessName}</h2>
|
||||||
|
<p>Joined Date: {new Date(business.joinedDate).toLocaleDateString()}</p>
|
||||||
|
{business.Projects.map((project) => (
|
||||||
|
<ExtendableCard
|
||||||
|
key={project.id}
|
||||||
|
name={project.projectName}
|
||||||
|
description={project.projectName}
|
||||||
|
joinDate={project.projectName}
|
||||||
|
location={"Bangkok"}
|
||||||
|
minInvestment={project.ProjectInvestmentDetail[0]?.minInvestment}
|
||||||
|
totalInvestor={project.ProjectInvestmentDetail[0]?.totalInvestment}
|
||||||
|
totalRaised={project.ProjectInvestmentDetail[0]?.targetInvestment}
|
||||||
|
tags={null}
|
||||||
|
/>
|
||||||
|
))} */}
|
||||||
|
|
||||||
|
<Card className="w-full">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>{business.businessName}</CardTitle>
|
||||||
|
<CardDescription>Joined Date: {new Date(business.joinedDate).toLocaleDateString()}</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
{business.Projects.map((project) => (
|
||||||
|
<ExtendableCard
|
||||||
|
key={project.id}
|
||||||
|
name={project.projectName}
|
||||||
|
description={project.projectName}
|
||||||
|
joinDate={project.projectName}
|
||||||
|
location={"Bangkok"}
|
||||||
|
minInvestment={project.ProjectInvestmentDetail[0]?.minInvestment}
|
||||||
|
totalInvestor={project.ProjectInvestmentDetail[0]?.totalInvestment}
|
||||||
|
totalRaised={project.ProjectInvestmentDetail[0]?.targetInvestment}
|
||||||
|
tags={[]}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
<ReactQueryDevtools initialIsOpen={false} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
144
src/app/invest/1/page.tsx
Normal file
144
src/app/invest/1/page.tsx
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
"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) => {
|
||||||
|
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-40 my-10">
|
||||||
|
<h1 className="text-4xl font-bold">Invest on NVIDIA</h1>
|
||||||
|
<Separator className="my-4" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div className="w-1/2 space-y-2">
|
||||||
|
<h2 className="text-2xl">Investment Amount</h2>
|
||||||
|
<Input type="number" placeholder="min $500" />
|
||||||
|
</div>
|
||||||
|
<Separator className="my-4" />
|
||||||
|
|
||||||
|
<div className="w-1/2 space-y-2">
|
||||||
|
<h2 className="text-2xl">Payment Information</h2>
|
||||||
|
<CardsPaymentMethod />
|
||||||
|
</div>
|
||||||
|
<Separator className="my-4" />
|
||||||
|
|
||||||
|
<div className="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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -2,13 +2,7 @@
|
|||||||
|
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import {
|
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
||||||
Carousel,
|
|
||||||
CarouselContent,
|
|
||||||
CarouselItem,
|
|
||||||
CarouselNext,
|
|
||||||
CarouselPrevious,
|
|
||||||
} from "@/components/ui/carousel";
|
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
import CountUp from "react-countup";
|
import CountUp from "react-countup";
|
||||||
import { Progress } from "@/components/ui/progress";
|
import { Progress } from "@/components/ui/progress";
|
||||||
@ -18,12 +12,8 @@ import { ShareIcon, StarIcon } from "lucide-react";
|
|||||||
import { Toaster, toast } from "react-hot-toast";
|
import { Toaster, toast } from "react-hot-toast";
|
||||||
import useSession from "@/lib/supabase/useSession";
|
import useSession from "@/lib/supabase/useSession";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
import {
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
Tooltip,
|
import Link from "next/link";
|
||||||
TooltipContent,
|
|
||||||
TooltipProvider,
|
|
||||||
TooltipTrigger,
|
|
||||||
} from "@/components/ui/tooltip";
|
|
||||||
|
|
||||||
export default function Invest() {
|
export default function Invest() {
|
||||||
const [progress, setProgress] = useState(0);
|
const [progress, setProgress] = useState(0);
|
||||||
@ -69,21 +59,20 @@ export default function Invest() {
|
|||||||
<div>
|
<div>
|
||||||
<Toaster position="top-right" reverseOrder={false} />
|
<Toaster position="top-right" reverseOrder={false} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-[90%] h-[45w0px]-500 m-auto mt-12 pl-24">
|
<div className="w-[90%] h-[450px]-500 md:m-auto mt-12 md:mt-12 pl-14 md:pl-24">
|
||||||
<div>
|
<div>
|
||||||
<div className="flex ">
|
{/* Name, star and share button packed */}
|
||||||
<Image src="./logo.svg" alt="logo" width={50} height={50} />
|
<div className="grid grid-cols-4">
|
||||||
<h1 className="mt-3 font-bold text-3xl">NVIDIA</h1>
|
<div className="flex col-span-2">
|
||||||
<div className="grid grid-cols-2 gap-5 ml-[850px] ">
|
<Image src="./logo.svg" alt="logo" width={50} height={50} className="sm:scale-75" />
|
||||||
|
<div className="mt-3 font-bold text-lg md:text-3xl">NVIDIA</div>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-5 justify-self-end ">
|
||||||
<div className="mt-2 cursor-pointer" onClick={handleFollow}>
|
<div className="mt-2 cursor-pointer" onClick={handleFollow}>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<StarIcon
|
<StarIcon id="follow" fill={isFollow ? "#FFFF00" : "#fff"} strokeWidth={2} />
|
||||||
id="follow"
|
|
||||||
fill={isFollow ? "#FFFF00" : "#fff"}
|
|
||||||
strokeWidth={2}
|
|
||||||
/>
|
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<p>Follow NIVIDIA</p>
|
<p>Follow NIVIDIA</p>
|
||||||
@ -96,104 +85,90 @@ export default function Invest() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-2"> World's first non-metal sustainable battery</p>
|
{/* end of pack */}
|
||||||
|
<p className="mt-2 sm:text-sm"> World's first non-metal sustainable battery</p>
|
||||||
<div className="flex flex-wrap mt-3">
|
<div className="flex flex-wrap mt-3">
|
||||||
{["Technology", "Gaming"].map((tag) => (
|
{["Technology", "Gaming"].map((tag) => (
|
||||||
<span
|
<span key={tag} className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1">
|
||||||
key={tag}
|
|
||||||
className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1"
|
|
||||||
>
|
|
||||||
{tag}
|
{tag}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex">
|
<div className="grid grid-cols-2 mt-5">
|
||||||
{/* image carousel */}
|
{/* image carousel */}
|
||||||
<Carousel className="w-[55%] mt-4">
|
<div>
|
||||||
<CarouselContent className="h-[450px]">
|
<Carousel className="w-full mt-20 md:mt-0">
|
||||||
{Array.from({ length: 5 }).map((_, index) => (
|
<CarouselContent className="h-[400px] flex h-full">
|
||||||
<CarouselItem key={index}>
|
{Array.from({ length: 5 }).map((_, index) => (
|
||||||
|
<CarouselItem key={index}>
|
||||||
|
<img src="./boiler1.jpg" alt="" className="rounded-lg self-center" />
|
||||||
|
</CarouselItem>
|
||||||
|
))}
|
||||||
|
</CarouselContent>{" "}
|
||||||
|
<CarouselPrevious />
|
||||||
|
<CarouselNext />
|
||||||
|
</Carousel>
|
||||||
|
<Carousel className="w-2/3 md:w-full ml-10 md:ml-0 mt-5 md:mt-10 ">
|
||||||
|
<CarouselContent>
|
||||||
|
{/* boiler plate for an actual pictures */}
|
||||||
|
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
||||||
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
||||||
</CarouselItem>
|
</CarouselItem>
|
||||||
))}
|
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
||||||
</CarouselContent>{" "}
|
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
||||||
<CarouselPrevious />
|
</CarouselItem>
|
||||||
<CarouselNext />
|
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
||||||
</Carousel>
|
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
||||||
<div className=" w-1/3 mt-4 h-[400px] ml-[8%] ">
|
</CarouselItem>
|
||||||
|
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
||||||
|
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
||||||
|
</CarouselItem>
|
||||||
|
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
||||||
|
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
||||||
|
</CarouselItem>
|
||||||
|
</CarouselContent>
|
||||||
|
</Carousel>
|
||||||
|
</div>
|
||||||
|
<div className=" w-2/3 mt-4 m-auto grid-rows-5">
|
||||||
<div className="pl-5">
|
<div className="pl-5">
|
||||||
<h1 className="font-semibold text-4xl mt-8">
|
<h1 className="font-semibold text-xl md:text-4xl mt-8">
|
||||||
<CountUp
|
<CountUp start={0} end={100000} duration={2} prefix="$" className="" />
|
||||||
start={0}
|
|
||||||
end={100000}
|
|
||||||
duration={2}
|
|
||||||
prefix="$"
|
|
||||||
className=""
|
|
||||||
/>
|
|
||||||
</h1>
|
</h1>
|
||||||
<p className=""> 5% raised of $5M max goal</p>
|
<p className="text-sm md:text-lg"> 5% raised of $5M max goal</p>
|
||||||
<Progress value={progress} className="w-[60%] h-3 mt-3" />
|
<Progress value={progress} className="w-[60%] h-3 mt-3" />
|
||||||
<h1 className="font-semibold text-4xl mt-8">
|
<h1 className="font-semibold text-4xl md:mt-8">
|
||||||
{" "}
|
{" "}
|
||||||
<CountUp start={0} end={1000} duration={2} className="" />
|
<CountUp start={0} end={1000} duration={2} className="text-xl md:text-4xl" />
|
||||||
</h1>
|
</h1>
|
||||||
<p className=""> Investors</p>
|
<p className="text-sm md:text-lg"> Investors</p>
|
||||||
</div>
|
</div>
|
||||||
<Separator decorative className="mt-3 w-3/4 ml-5" />
|
<Separator decorative className="mt-3 w-3/4 ml-5" />
|
||||||
<h1 className="font-semibold text-4xl mt-8 ml-5">
|
<h1 className="font-semibold text-xl md:text-4xl mt-8 ml-5">
|
||||||
{" "}
|
<CountUp start={0} end={5800} duration={2} className="text-xl md:text-4xl" /> hours
|
||||||
<CountUp start={0} end={5800} duration={2} className="" /> hours
|
|
||||||
</h1>
|
</h1>
|
||||||
<p className="ml-5"> Left to invest</p>
|
<p className="ml-5"> Left to invest</p>
|
||||||
<Button className="mt-10 ml-[25%]">Invest in NVIDIA</Button>
|
<Button className="mt-5 md:mt-10 ml-0 md:ml-[25%] scale-75 md:scale-100">
|
||||||
|
<Link href="/invest/1">Invest in NVIDIA</Link>
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Carousel className="w-1/2 ml-10">
|
|
||||||
<CarouselContent>
|
|
||||||
{/* boiler plate for an actual pictures */}
|
|
||||||
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
|
||||||
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
|
||||||
</CarouselItem>
|
|
||||||
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
|
||||||
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
|
||||||
</CarouselItem>
|
|
||||||
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
|
||||||
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
|
||||||
</CarouselItem>
|
|
||||||
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
|
||||||
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
|
||||||
</CarouselItem>
|
|
||||||
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
|
|
||||||
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
|
|
||||||
</CarouselItem>
|
|
||||||
</CarouselContent>
|
|
||||||
</Carousel>
|
|
||||||
</div>
|
</div>
|
||||||
{/* menu */}
|
{/* menu */}
|
||||||
<div className="flex w-[90%] mt-24 m-auto ml-32">
|
<div className="flex w-[90%] mt-24 m-auto ml-10 md:ml-32">
|
||||||
<ul className="list-none flex gap-10 text-xl ">
|
<ul className="list-none flex gap-10 text-lg md:text-xl ">
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a onClick={() => handleClick("Pitch")} className={tab === "Pitch" ? "text-blue-600" : ""}>
|
||||||
onClick={() => handleClick("Pitch")}
|
|
||||||
className={tab === "Pitch" ? "text-blue-600" : ""}
|
|
||||||
>
|
|
||||||
Pitch
|
Pitch
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a onClick={() => handleClick("General Data")} className={tab === "General Data" ? "text-blue-600" : ""}>
|
||||||
onClick={() => handleClick("General Data")}
|
|
||||||
className={tab === "General Data" ? "text-blue-600" : ""}
|
|
||||||
>
|
|
||||||
General Data
|
General Data
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a onClick={() => handleClick("Updates")} className={tab === "Updates" ? "text-blue-600" : ""}>
|
||||||
onClick={() => handleClick("Updates")}
|
|
||||||
className={tab === "Updates" ? "text-blue-600" : ""}
|
|
||||||
>
|
|
||||||
Updates
|
Updates
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Montserrat } from "next/font/google";
|
import { Montserrat } from "next/font/google";
|
||||||
import { ThemeProvider } from "@/components/theme-provider";
|
import { ThemeProvider } from "@/components/theme-provider";
|
||||||
|
import { ReactQueryClientProvider } from "@/components/ReactQueryClientProvider";
|
||||||
import "@/app/globals.css";
|
import "@/app/globals.css";
|
||||||
|
|
||||||
import { NavigationBar } from "@/components/navigationBar/nav";
|
import { NavigationBar } from "@/components/navigationBar/nav";
|
||||||
|
import { Toaster } from "react-hot-toast";
|
||||||
|
|
||||||
const montserrat = Montserrat({
|
const montserrat = Montserrat({
|
||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
@ -24,16 +26,21 @@ interface RootLayoutProps {
|
|||||||
|
|
||||||
export default function RootLayout({ children }: RootLayoutProps) {
|
export default function RootLayout({ children }: RootLayoutProps) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<ReactQueryClientProvider>
|
||||||
<head />
|
<html lang="en">
|
||||||
<body className={`${montserrat.className}`}>
|
<head />
|
||||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
<body className={`${montserrat.className}`}>
|
||||||
<div className="relative flex min-h-screen flex-col">
|
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||||
<NavigationBar />
|
<div className="relative flex min-h-screen flex-col">
|
||||||
<div className="flex-1 bg-background">{children}</div>
|
<div>
|
||||||
</div>
|
<Toaster position="top-center" reverseOrder={false} toastOptions={{ duration: 1000 }} />
|
||||||
</ThemeProvider>
|
</div>
|
||||||
</body>
|
<NavigationBar />
|
||||||
</html>
|
<div className="flex-1 bg-background">{children}</div>
|
||||||
|
</div>
|
||||||
|
</ThemeProvider>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</ReactQueryClientProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,8 @@ export default function Notification() {
|
|||||||
];
|
];
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="ml-56 mt-16 ">
|
<div className="ml-24 md:ml-56 mt-16 ">
|
||||||
<h1 className="font-bold text-3xl h-0">Notifications</h1>
|
<h1 className="font-bold text-2xl md:text-3xl h-0">Notifications</h1>
|
||||||
<div className=" w-full mt-20 ">
|
<div className=" w-full mt-20 ">
|
||||||
{/* Cards */}
|
{/* Cards */}
|
||||||
<Card className=" border-slate-800 w-3/4 p-6">
|
<Card className=" border-slate-800 w-3/4 p-6">
|
||||||
|
|||||||
@ -1,13 +1,7 @@
|
|||||||
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 {
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
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";
|
import { ExtendableCard } from "@/components/extendableCard";
|
||||||
|
|
||||||
@ -16,16 +10,14 @@ export default function Home() {
|
|||||||
<main>
|
<main>
|
||||||
<div className="flex flex-row bg-slate-100 dark:bg-gray-800">
|
<div className="flex flex-row bg-slate-100 dark:bg-gray-800">
|
||||||
<div className="flex flex-col w-3/5">
|
<div className="flex flex-col w-3/5">
|
||||||
<span className="px-28 py-20">
|
<span className="px-10 md:px-28 py-10 md:py-20">
|
||||||
<p className="text-4xl font-bold">Explore the world of ventures</p>
|
<p className="text-lg md:text-4xl font-bold">Explore the world of ventures</p>
|
||||||
<span className="text-lg">
|
<span className="text-sm md:text-lg">
|
||||||
<p>
|
<p>Unlock opportunities and connect with a community of passionate</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="scale-75 md:scale-100 font-bold mt-4">
|
||||||
<Link href="/deals">Start Investing</Link>
|
<Link href="/deals">Start Investing</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
@ -42,36 +34,36 @@ export default function Home() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-row gap-10 justify-center mt-5">
|
<div className="flex flex-row gap-0 md:gap-10 justify-start md:justify-center mt-3 md:mt-5">
|
||||||
<Card className="border-0 shadow-none">
|
<Card className="border-0 shadow-none">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>100M+</CardTitle>
|
<CardTitle className="text-lg md:text-2xl">100M+</CardTitle>
|
||||||
<CardDescription>Global investor community</CardDescription>
|
<CardDescription>Global investor community</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
</Card>
|
</Card>
|
||||||
<Card className="border-0 shadow-none">
|
<Card className="border-0 shadow-none">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>2,500+</CardTitle>
|
<CardTitle className="text-lg md:text-2xl">2,500+</CardTitle>
|
||||||
<CardDescription>Ventures supported</CardDescription>
|
<CardDescription>Ventures supported</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
</Card>
|
</Card>
|
||||||
<Card className="border-0 shadow-none">
|
<Card className="border-0 shadow-none">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>$2.6B+</CardTitle>
|
<CardTitle className="text-lg md:text-2xl">$2.6B+</CardTitle>
|
||||||
<CardDescription>Capital raised</CardDescription>
|
<CardDescription>Capital raised</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
</Card>
|
</Card>
|
||||||
<Card className="border-0 shadow-none">
|
<Card className="border-0 shadow-none">
|
||||||
<CardHeader className="pb-2">
|
<CardHeader className="pb-2">
|
||||||
<CardTitle>Follow Us</CardTitle>
|
<CardTitle className="text-lg md:text-2xl">Follow Us</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex gap-2">
|
<CardContent className="flex gap-2">
|
||||||
<Button className="flex gap-1 border-2 border-border rounded-md p-1 bg-background text-foreground">
|
<Button className="flex gap-1 border-2 border-border rounded-md p-1 bg-background text-foreground scale-75 md:scale-100">
|
||||||
<Image src={"/github.svg"} width={20} height={20} alt="github" />
|
<Image src={"/github.svg"} width={20} height={20} alt="github" className="scale-75 md:scale-100" />
|
||||||
Github
|
Github
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="flex gap-1 border-2 border-border rounded-md p-1 bg-background text-foreground">
|
<Button className="flex gap-1 border-2 border-border rounded-md p-1 bg-background text-foreground scale-75 md:scale-100">
|
||||||
<Image src={"/github.svg"} width={20} height={20} alt="github" />
|
<Image src={"/github.svg"} width={20} height={20} alt="github" className="scale-75 md:scale-100" />
|
||||||
Github
|
Github
|
||||||
</Button>
|
</Button>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@ -80,23 +72,19 @@ export default function Home() {
|
|||||||
|
|
||||||
<Separator className="mb-6" />
|
<Separator className="mb-6" />
|
||||||
|
|
||||||
<div className="flex flex-col px-28">
|
<div className="flex flex-col px-10 md:px-28">
|
||||||
<span className="pb-5">
|
<span className="pb-5">
|
||||||
<p className="text-2xl font-bold">Hottest Deals</p>
|
<p className="text-xl md:text-2xl font-bold">Hottest Deals</p>
|
||||||
<p className="text-lg">
|
<p className="text-md md:text-lg">The deals attracting the most interest right now</p>
|
||||||
The deals attracting the most interest right now
|
|
||||||
</p>
|
|
||||||
</span>
|
</span>
|
||||||
<div className="grid grid-cols-4 gap-4">
|
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
<Link href={"/invest"}>
|
<Link href={"/invest"}>
|
||||||
<ExtendableCard
|
<ExtendableCard
|
||||||
name={"NVDA"}
|
name={"NVDA"}
|
||||||
description={
|
description={"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology"}
|
||||||
"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology"
|
|
||||||
}
|
|
||||||
joinDate={"December 2021"}
|
joinDate={"December 2021"}
|
||||||
location={"Bangkok, Thailand"}
|
location={"Bangkok, Thailand"}
|
||||||
tags={null}
|
tags={[]}
|
||||||
minInvestment={10000}
|
minInvestment={10000}
|
||||||
totalInvestor={58400}
|
totalInvestor={58400}
|
||||||
totalRaised={9000000}
|
totalRaised={9000000}
|
||||||
@ -109,7 +97,7 @@ export default function Home() {
|
|||||||
}
|
}
|
||||||
joinDate={"February 2020"}
|
joinDate={"February 2020"}
|
||||||
location={"Cupertino, California, USA"}
|
location={"Cupertino, California, USA"}
|
||||||
tags={null}
|
tags={[]}
|
||||||
minInvestment={10000}
|
minInvestment={10000}
|
||||||
totalInvestor={58400}
|
totalInvestor={58400}
|
||||||
totalRaised={9000000}
|
totalRaised={9000000}
|
||||||
@ -121,25 +109,23 @@ export default function Home() {
|
|||||||
}
|
}
|
||||||
joinDate={"April 2019"}
|
joinDate={"April 2019"}
|
||||||
location={"Mountain View, California, USA"}
|
location={"Mountain View, California, USA"}
|
||||||
tags={null}
|
tags={[]}
|
||||||
minInvestment={10000}
|
minInvestment={10000}
|
||||||
totalInvestor={5000}
|
totalInvestor={5000}
|
||||||
totalRaised={1500000000}
|
totalRaised={1500000000}
|
||||||
/>
|
/>
|
||||||
<ExtendableCard
|
<ExtendableCard
|
||||||
name={"Microsoft Corporation"}
|
name={"Microsoft Corporation"}
|
||||||
description={
|
description={"Microsoft Corporation is a multinational technology company."}
|
||||||
"Microsoft Corporation is a multinational technology company."
|
|
||||||
}
|
|
||||||
joinDate={"January 2018"}
|
joinDate={"January 2018"}
|
||||||
location={"California, USA"}
|
location={"California, USA"}
|
||||||
tags={null}
|
tags={[]}
|
||||||
minInvestment={250}
|
minInvestment={250}
|
||||||
totalInvestor={5000}
|
totalInvestor={5000}
|
||||||
totalRaised={1500000}
|
totalRaised={1500000}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="self-center py-5">
|
<div className="self-center py-5 scale-75 md:scale-100">
|
||||||
<Button>
|
<Button>
|
||||||
<Link href={"/deals"}>View all</Link>
|
<Link href={"/deals"}>View all</Link>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
20
src/components/ReactQueryClientProvider.tsx
Normal file
20
src/components/ReactQueryClientProvider.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export const ReactQueryClientProvider = ({ children }: { children: React.ReactNode }) => {
|
||||||
|
const [queryClient] = useState(
|
||||||
|
() =>
|
||||||
|
new QueryClient({
|
||||||
|
defaultOptions: {
|
||||||
|
queries: {
|
||||||
|
// With SSR, we usually want to set some default staleTime
|
||||||
|
// above 0 to avoid refetching immediately on the client
|
||||||
|
staleTime: 60 * 1000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
|
||||||
|
};
|
||||||
39
src/components/auth/loginForm.tsx
Normal file
39
src/components/auth/loginForm.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { createSupabaseClient } from "@/lib/supabase/clientComponentClient";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
|
export function LoginForm() {
|
||||||
|
const router = useRouter();
|
||||||
|
const supabase = createSupabaseClient();
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
|
||||||
|
const handleLogin = async (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
event.preventDefault();
|
||||||
|
await supabase.auth.signInWithPassword({
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
});
|
||||||
|
router.push("/");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col space-y-2">
|
||||||
|
<Input id="email" type="text" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" />
|
||||||
|
<Input
|
||||||
|
id="password"
|
||||||
|
type="password"
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
placeholder="Password"
|
||||||
|
/>
|
||||||
|
<Button id="login" onClick={handleLogin}>
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -11,7 +11,7 @@ interface ExtendableCardProps {
|
|||||||
description: string;
|
description: string;
|
||||||
joinDate: string;
|
joinDate: string;
|
||||||
location: string;
|
location: string;
|
||||||
tags: XMap | null;
|
tags: XMap | null | never[] | string[];
|
||||||
minInvestment: number;
|
minInvestment: number;
|
||||||
totalInvestor: number;
|
totalInvestor: number;
|
||||||
totalRaised: number;
|
totalRaised: number;
|
||||||
@ -19,7 +19,7 @@ interface ExtendableCardProps {
|
|||||||
|
|
||||||
export function ExtendableCard(props: ExtendableCardProps) {
|
export function ExtendableCard(props: ExtendableCardProps) {
|
||||||
return (
|
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="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">
|
<div className="aspect-[4/3] overflow-hidden">
|
||||||
<img
|
<img
|
||||||
src="/money.png"
|
src="/money.png"
|
||||||
@ -30,27 +30,27 @@ export function ExtendableCard(props: ExtendableCardProps) {
|
|||||||
style={{ aspectRatio: "400/300", objectFit: "cover" }}
|
style={{ aspectRatio: "400/300", objectFit: "cover" }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4">
|
<div className="p-1 md:p-4">
|
||||||
<h3 className="text-lg font-semibold text-card-foreground transition-colors duration-500 group-hover:text-primary">
|
<div className="text-sm md:text-lg font-semibold text-card-foreground transition-colors duration-500 group-hover:text-primary">
|
||||||
{props.name}
|
{props.name}
|
||||||
</h3>
|
</div>
|
||||||
|
|
||||||
{/* Default content (visible when not hovered) */}
|
{/* Default content (visible when not hovered) */}
|
||||||
<div className="mt-2 flex items-center text-muted-foreground group-hover:hidden">
|
<div className="mt-2 flex items-center text-muted-foreground group-hover:hidden">
|
||||||
<span className="flex items-center pt-2 gap-1">
|
<span className="flex items-center pt-2 gap-1">
|
||||||
<CalendarDaysIcon width={20} />
|
<CalendarDaysIcon width={20} />
|
||||||
Joined {props.joinDate}
|
<div className="text-xs md:text-lg">Joined {props.joinDate}</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex items-center text-muted-foreground group-hover:hidden">
|
<div className="mt-2 flex items-center text-muted-foreground group-hover:hidden">
|
||||||
<span className="text-sm">{props.location}</span>
|
<span className="text-xs md:text-sm">{props.location}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex flex-wrap items-center text-muted-foreground group-hover:hidden">
|
<div className="mt-2 flex flex-wrap items-center text-muted-foreground group-hover:hidden">
|
||||||
{["Technology", "Gaming"].map((tag) => (
|
{props.tags.map((tag) => (
|
||||||
<span
|
<span
|
||||||
|
id="tag"
|
||||||
key={tag}
|
key={tag}
|
||||||
className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1"
|
className="text-[10px] md:text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1">
|
||||||
>
|
|
||||||
{tag}
|
{tag}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
@ -58,24 +58,21 @@ export function ExtendableCard(props: ExtendableCardProps) {
|
|||||||
|
|
||||||
{/* Hover content (appears when hovered) */}
|
{/* 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-1000 ease-in-out">
|
<div className="mt-4 max-h-0 overflow-hidden opacity-0 group-hover:max-h-[500px] group-hover:opacity-100 transition-all duration-1000 ease-in-out">
|
||||||
<p className="text-sm text-muted-foreground">{props.description}</p>
|
<p className="text-xs md:text-sm text-muted-foreground">{props.description}</p>
|
||||||
<div className="mt-4 flex items-center justify-between">
|
<div className="mt-4 flex items-center justify-between">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<div>
|
<div>
|
||||||
<hr className="w-screen -ml-4 mb-2" />
|
<hr className="w-screen -ml-4 mb-2" />
|
||||||
<p>
|
<p className="text-xs md:text-base">
|
||||||
<strong>${props.totalRaised.toLocaleString()}</strong>{" "}
|
<strong>${props.totalRaised.toLocaleString()}</strong> committed and reserved
|
||||||
committed and reserved
|
|
||||||
</p>
|
</p>
|
||||||
<hr className="w-screen -ml-4 mb-2 mt-2" />
|
<hr className="w-screen -ml-4 mb-2 mt-2" />
|
||||||
<p className="mb-2">
|
<p className="mb-2 text-xs md:text-base">
|
||||||
<strong>{props.totalInvestor.toLocaleString()}</strong>{" "}
|
<strong>{props.totalInvestor.toLocaleString()}</strong> investors
|
||||||
investors
|
|
||||||
</p>
|
</p>
|
||||||
<hr className="w-screen -ml-4 mb-2" />
|
<hr className="w-screen -ml-4 mb-2" />
|
||||||
<p>
|
<p className="text-xs md:text-base">
|
||||||
<strong>${props.minInvestment.toLocaleString()}</strong> min.
|
<strong>${props.minInvestment.toLocaleString()}</strong> min. investment
|
||||||
investment
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { cn } from "@/lib/utils";
|
|||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
import { ThemeToggle } from "@/components/theme-toggle";
|
import { ThemeToggle } from "@/components/theme-toggle";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
import {
|
import {
|
||||||
NavigationMenu,
|
NavigationMenu,
|
||||||
NavigationMenuContent,
|
NavigationMenuContent,
|
||||||
@ -133,6 +134,8 @@ export function NavigationBar() {
|
|||||||
const { session, loading } = useSession();
|
const { session, loading } = useSession();
|
||||||
const user = session?.user;
|
const user = session?.user;
|
||||||
const [sessionLoaded, setSessionLoaded] = React.useState(false);
|
const [sessionLoaded, setSessionLoaded] = React.useState(false);
|
||||||
|
const [searchActive, setSearchActive] = React.useState(false);
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!loading) {
|
if (!loading) {
|
||||||
@ -140,6 +143,15 @@ export function NavigationBar() {
|
|||||||
}
|
}
|
||||||
}, [loading]);
|
}, [loading]);
|
||||||
|
|
||||||
|
const handleKeyDown = async (k: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
|
if (k.key === 'Enter') {
|
||||||
|
const query = (k.target as HTMLInputElement).value.trim();
|
||||||
|
if (query) {
|
||||||
|
router.push(`/find?query=${encodeURIComponent(query)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const businessComponents = [
|
const businessComponents = [
|
||||||
{
|
{
|
||||||
title: "Businesses",
|
title: "Businesses",
|
||||||
@ -249,8 +261,21 @@ export function NavigationBar() {
|
|||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
</NavigationMenuItem>
|
</NavigationMenuItem>
|
||||||
|
|
||||||
<NavigationMenuItem className="pl-5">
|
<NavigationMenuItem className="pl-5 flex">
|
||||||
<Search />
|
<Search
|
||||||
|
onClick={() => setSearchActive(!searchActive)}
|
||||||
|
className="cursor-pointer"
|
||||||
|
/>
|
||||||
|
{/* search bar's input */}
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter business name..."
|
||||||
|
className={cn(
|
||||||
|
"ml-2 border rounded-md px-2 py-1 transition-all duration-300 ease-in-out ",
|
||||||
|
searchActive ? "w-48 opacity-100" : "w-0 opacity-0"
|
||||||
|
)}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
/>
|
||||||
</NavigationMenuItem>
|
</NavigationMenuItem>
|
||||||
</NavigationMenuList>
|
</NavigationMenuList>
|
||||||
</NavigationMenu>
|
</NavigationMenu>
|
||||||
|
|||||||
122
src/components/paymentMethod.tsx
Normal file
122
src/components/paymentMethod.tsx
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Icons } from "./ui/icons";
|
||||||
|
import { Button } from "./ui/button";
|
||||||
|
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./ui/card";
|
||||||
|
import { Input } from "./ui/input";
|
||||||
|
import { Label } from "./ui/label";
|
||||||
|
import { RadioGroup, RadioGroupItem } from "./ui/radio-group";
|
||||||
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
|
||||||
|
|
||||||
|
export function CardsPaymentMethod() {
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Payment Method</CardTitle>
|
||||||
|
<CardDescription>Add a new payment method to your account.</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="grid gap-6">
|
||||||
|
<RadioGroup defaultValue="card" className="grid grid-cols-3 gap-4">
|
||||||
|
<div>
|
||||||
|
<RadioGroupItem value="card" id="card" className="peer sr-only" aria-label="Card" />
|
||||||
|
<Label
|
||||||
|
htmlFor="card"
|
||||||
|
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
className="mb-3 h-6 w-6">
|
||||||
|
<rect width="20" height="14" x="2" y="5" rx="2" />
|
||||||
|
<path d="M2 10h20" />
|
||||||
|
</svg>
|
||||||
|
Card
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<RadioGroupItem value="paypal" id="paypal" className="peer sr-only" aria-label="Paypal" />
|
||||||
|
<Label
|
||||||
|
htmlFor="paypal"
|
||||||
|
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary">
|
||||||
|
<Icons.paypal className="mb-3 h-6 w-6" />
|
||||||
|
Paypal
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<RadioGroupItem value="apple" id="apple" className="peer sr-only" aria-label="Apple" />
|
||||||
|
<Label
|
||||||
|
htmlFor="apple"
|
||||||
|
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary">
|
||||||
|
<Icons.apple className="mb-3 h-6 w-6" />
|
||||||
|
Apple
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
</RadioGroup>
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="name">Name</Label>
|
||||||
|
<Input id="name" placeholder="First Last" />
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="city">City</Label>
|
||||||
|
<Input id="city" placeholder="" />
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="number">Card number</Label>
|
||||||
|
<Input id="number" placeholder="" />
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-3 gap-4">
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="month">Expires</Label>
|
||||||
|
<Select>
|
||||||
|
<SelectTrigger id="month" aria-label="Month">
|
||||||
|
<SelectValue placeholder="Month" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="1">January</SelectItem>
|
||||||
|
<SelectItem value="2">February</SelectItem>
|
||||||
|
<SelectItem value="3">March</SelectItem>
|
||||||
|
<SelectItem value="4">April</SelectItem>
|
||||||
|
<SelectItem value="5">May</SelectItem>
|
||||||
|
<SelectItem value="6">June</SelectItem>
|
||||||
|
<SelectItem value="7">July</SelectItem>
|
||||||
|
<SelectItem value="8">August</SelectItem>
|
||||||
|
<SelectItem value="9">September</SelectItem>
|
||||||
|
<SelectItem value="10">October</SelectItem>
|
||||||
|
<SelectItem value="11">November</SelectItem>
|
||||||
|
<SelectItem value="12">December</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="year">Year</Label>
|
||||||
|
<Select>
|
||||||
|
<SelectTrigger id="year" aria-label="Year">
|
||||||
|
<SelectValue placeholder="Year" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{Array.from({ length: 10 }, (_, i) => (
|
||||||
|
<SelectItem key={i} value={`${new Date().getFullYear() + i}`}>
|
||||||
|
{new Date().getFullYear() + i}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="cvc">CVC</Label>
|
||||||
|
<Input id="cvc" placeholder="CVC" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
{/* <CardFooter>
|
||||||
|
<Button className="w-full">Continue</Button>
|
||||||
|
</CardFooter> */}
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
59
src/components/recent-funds.tsx
Normal file
59
src/components/recent-funds.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
name: "Olivia Martin",
|
||||||
|
email: "olivia.martin@email.com",
|
||||||
|
amount: "1900.00",
|
||||||
|
avatar: "/avatars/01.png", // psuedo avatar image
|
||||||
|
initials: "OM",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Jackson Lee",
|
||||||
|
email: "jackson.lee@email.com",
|
||||||
|
amount: "39.00",
|
||||||
|
avatar: "/avatars/02.png",
|
||||||
|
initials: "JL",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Isabella Nguyen",
|
||||||
|
email: "isabella.nguyen@email.com",
|
||||||
|
amount: "299.00",
|
||||||
|
avatar: "/avatars/03.png",
|
||||||
|
initials: "IN",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "William Kim",
|
||||||
|
email: "will@email.com",
|
||||||
|
amount: "99.00",
|
||||||
|
avatar: "/avatars/04.png",
|
||||||
|
initials: "WK",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sofia Davis",
|
||||||
|
email: "sofia.davis@email.com",
|
||||||
|
amount: "39.00",
|
||||||
|
avatar: "/avatars/05.png",
|
||||||
|
initials: "SD",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export function RecentFunds() {
|
||||||
|
return (
|
||||||
|
<div className="space-y-8">
|
||||||
|
{data.map((person, index) => (
|
||||||
|
<div className="flex items-center" key={index}>
|
||||||
|
<Avatar className="h-9 w-9">
|
||||||
|
<AvatarImage src={person.avatar} alt={person.name} />
|
||||||
|
<AvatarFallback>{person.initials}</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<div className="ml-4 space-y-1">
|
||||||
|
<p className="text-sm font-medium leading-none">{person.name}</p>
|
||||||
|
<p className="text-sm text-muted-foreground">{person.email}</p>
|
||||||
|
</div>
|
||||||
|
<div className="ml-auto font-medium">+${person.amount}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
122
src/components/ui/dialog.tsx
Normal file
122
src/components/ui/dialog.tsx
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
||||||
|
import { X } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Dialog = DialogPrimitive.Root
|
||||||
|
|
||||||
|
const DialogTrigger = DialogPrimitive.Trigger
|
||||||
|
|
||||||
|
const DialogPortal = DialogPrimitive.Portal
|
||||||
|
|
||||||
|
const DialogClose = DialogPrimitive.Close
|
||||||
|
|
||||||
|
const DialogOverlay = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Overlay
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
|
||||||
|
|
||||||
|
const DialogContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<DialogPortal>
|
||||||
|
<DialogOverlay />
|
||||||
|
<DialogPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||||
|
<X className="h-4 w-4" />
|
||||||
|
<span className="sr-only">Close</span>
|
||||||
|
</DialogPrimitive.Close>
|
||||||
|
</DialogPrimitive.Content>
|
||||||
|
</DialogPortal>
|
||||||
|
))
|
||||||
|
DialogContent.displayName = DialogPrimitive.Content.displayName
|
||||||
|
|
||||||
|
const DialogHeader = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col space-y-1.5 text-center sm:text-left",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
DialogHeader.displayName = "DialogHeader"
|
||||||
|
|
||||||
|
const DialogFooter = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
DialogFooter.displayName = "DialogFooter"
|
||||||
|
|
||||||
|
const DialogTitle = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Title>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Title
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-lg font-semibold leading-none tracking-tight",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DialogTitle.displayName = DialogPrimitive.Title.displayName
|
||||||
|
|
||||||
|
const DialogDescription = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Description>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DialogDescription.displayName = DialogPrimitive.Description.displayName
|
||||||
|
|
||||||
|
export {
|
||||||
|
Dialog,
|
||||||
|
DialogPortal,
|
||||||
|
DialogOverlay,
|
||||||
|
DialogClose,
|
||||||
|
DialogTrigger,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogFooter,
|
||||||
|
DialogTitle,
|
||||||
|
DialogDescription,
|
||||||
|
}
|
||||||
136
src/components/ui/icons.tsx
Normal file
136
src/components/ui/icons.tsx
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
type IconProps = React.HTMLAttributes<SVGElement>;
|
||||||
|
|
||||||
|
export const Icons = {
|
||||||
|
logo: (props: IconProps) => (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" {...props}>
|
||||||
|
<rect width="256" height="256" fill="none" />
|
||||||
|
<line
|
||||||
|
x1="208"
|
||||||
|
y1="128"
|
||||||
|
x2="128"
|
||||||
|
y2="208"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="16"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
x1="192"
|
||||||
|
y1="40"
|
||||||
|
x2="40"
|
||||||
|
y2="192"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="16"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
twitter: (props: IconProps) => (
|
||||||
|
<svg {...props} height="23" viewBox="0 0 1200 1227" width="23" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" />
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
gitHub: (props: IconProps) => (
|
||||||
|
<svg viewBox="0 0 438.549 438.549" {...props}>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"></path>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
radix: (props: IconProps) => (
|
||||||
|
<svg viewBox="0 0 25 25" fill="none" {...props}>
|
||||||
|
<path d="M12 25C7.58173 25 4 21.4183 4 17C4 12.5817 7.58173 9 12 9V25Z" fill="currentcolor"></path>
|
||||||
|
<path d="M12 0H4V8H12V0Z" fill="currentcolor"></path>
|
||||||
|
<path
|
||||||
|
d="M17 8C19.2091 8 21 6.20914 21 4C21 1.79086 19.2091 0 17 0C14.7909 0 13 1.79086 13 4C13 6.20914 14.7909 8 17 8Z"
|
||||||
|
fill="currentcolor"></path>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
aria: (props: IconProps) => (
|
||||||
|
<svg role="img" viewBox="0 0 24 24" fill="currentColor" {...props}>
|
||||||
|
<path d="M13.966 22.624l-1.69-4.281H8.122l3.892-9.144 5.662 13.425zM8.884 1.376H0v21.248zm15.116 0h-8.884L24 22.624Z" />
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
npm: (props: IconProps) => (
|
||||||
|
<svg viewBox="0 0 24 24" {...props}>
|
||||||
|
<path
|
||||||
|
d="M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
yarn: (props: IconProps) => (
|
||||||
|
<svg viewBox="0 0 24 24" {...props}>
|
||||||
|
<path
|
||||||
|
d="M12 0C5.375 0 0 5.375 0 12s5.375 12 12 12 12-5.375 12-12S18.625 0 12 0zm.768 4.105c.183 0 .363.053.525.157.125.083.287.185.755 1.154.31-.088.468-.042.551-.019.204.056.366.19.463.375.477.917.542 2.553.334 3.605-.241 1.232-.755 2.029-1.131 2.576.324.329.778.899 1.117 1.825.278.774.31 1.478.273 2.015a5.51 5.51 0 0 0 .602-.329c.593-.366 1.487-.917 2.553-.931.714-.009 1.269.445 1.353 1.103a1.23 1.23 0 0 1-.945 1.362c-.649.158-.95.278-1.821.843-1.232.797-2.539 1.242-3.012 1.39a1.686 1.686 0 0 1-.704.343c-.737.181-3.266.315-3.466.315h-.046c-.783 0-1.214-.241-1.45-.491-.658.329-1.51.19-2.122-.134a1.078 1.078 0 0 1-.58-1.153 1.243 1.243 0 0 1-.153-.195c-.162-.25-.528-.936-.454-1.946.056-.723.556-1.367.88-1.71a5.522 5.522 0 0 1 .408-2.256c.306-.727.885-1.348 1.32-1.737-.32-.537-.644-1.367-.329-2.21.227-.602.412-.936.82-1.08h-.005c.199-.074.389-.153.486-.259a3.418 3.418 0 0 1 2.298-1.103c.037-.093.079-.185.125-.283.31-.658.639-1.029 1.024-1.168a.94.94 0 0 1 .328-.06zm.006.7c-.507.016-1.001 1.519-1.001 1.519s-1.27-.204-2.266.871c-.199.218-.468.334-.746.44-.079.028-.176.023-.417.672-.371.991.625 2.094.625 2.094s-1.186.839-1.626 1.881c-.486 1.144-.338 2.261-.338 2.261s-.843.732-.899 1.487c-.051.663.139 1.2.343 1.515.227.343.51.176.51.176s-.561.653-.037.931c.477.25 1.283.394 1.71-.037.31-.31.371-1.001.486-1.283.028-.065.12.111.209.199.097.093.264.195.264.195s-.755.324-.445 1.066c.102.246.468.403 1.066.398.222-.005 2.664-.139 3.313-.296.375-.088.505-.283.505-.283s1.566-.431 2.998-1.357c.917-.598 1.293-.76 2.034-.936.612-.148.57-1.098-.241-1.084-.839.009-1.575.44-2.196.825-1.163.718-1.742.672-1.742.672l-.018-.032c-.079-.13.371-1.293-.134-2.678-.547-1.515-1.413-1.881-1.344-1.997.297-.5 1.038-1.297 1.334-2.78.176-.899.13-2.377-.269-3.151-.074-.144-.732.241-.732.241s-.616-1.371-.788-1.483a.271.271 0 0 0-.157-.046z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
pnpm: (props: IconProps) => (
|
||||||
|
<svg viewBox="0 0 24 24" {...props}>
|
||||||
|
<path
|
||||||
|
d="M0 0v7.5h7.5V0zm8.25 0v7.5h7.498V0zm8.25 0v7.5H24V0zM8.25 8.25v7.5h7.498v-7.5zm8.25 0v7.5H24v-7.5zM0 16.5V24h7.5v-7.5zm8.25 0V24h7.498v-7.5zm8.25 0V24H24v-7.5z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
react: (props: IconProps) => (
|
||||||
|
<svg viewBox="0 0 24 24" {...props}>
|
||||||
|
<path
|
||||||
|
d="M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236 2.236 2.236 0 0 1-2.236-2.236 2.236 2.236 0 0 1 2.235-2.236 2.236 2.236 0 0 1 2.236 2.236zm2.648-10.69c-1.346 0-3.107.96-4.888 2.622-1.78-1.653-3.542-2.602-4.887-2.602-.41 0-.783.093-1.106.278-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03-.704 3.113-.39 5.588.988 6.38.32.187.69.275 1.102.275 1.345 0 3.107-.96 4.888-2.624 1.78 1.654 3.542 2.603 4.887 2.603.41 0 .783-.09 1.106-.275 1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032.704-3.11.39-5.587-.988-6.38-.318-.184-.688-.277-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127.666.382.955 1.835.73 3.704-.054.46-.142.945-.25 1.44-.96-.236-2.006-.417-3.107-.534-.66-.905-1.345-1.727-2.035-2.447 1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28-.686.72-1.37 1.537-2.02 2.442-1.107.117-2.154.298-3.113.538-.112-.49-.195-.964-.254-1.42-.23-1.868.054-3.32.714-3.707.19-.09.4-.127.563-.132zm4.882 3.05c.455.468.91.992 1.36 1.564-.44-.02-.89-.034-1.345-.034-.46 0-.915.01-1.36.034.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093.406.582.802 1.203 1.183 1.86.372.64.71 1.29 1.018 1.946-.308.655-.646 1.31-1.013 1.95-.38.66-.773 1.288-1.18 1.87-.728.063-1.466.098-2.21.098-.74 0-1.477-.035-2.202-.093-.406-.582-.802-1.204-1.183-1.86-.372-.64-.71-1.29-1.018-1.946.303-.657.646-1.313 1.013-1.954.38-.66.773-1.286 1.18-1.868.728-.064 1.466-.098 2.21-.098zm-3.635.254c-.24.377-.48.763-.704 1.16-.225.39-.435.782-.635 1.174-.265-.656-.49-1.31-.676-1.947.64-.15 1.315-.283 2.015-.386zm7.26 0c.695.103 1.365.23 2.006.387-.18.632-.405 1.282-.66 1.933-.2-.39-.41-.783-.64-1.174-.225-.392-.465-.774-.705-1.146zm3.063.675c.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98-.45 1.017-.812 2.01-1.086 2.964-.484-.15-.944-.318-1.37-.5-1.732-.737-2.852-1.706-2.852-2.474 0-.768 1.12-1.742 2.852-2.476.42-.18.88-.342 1.356-.494zm11.678 4.28c.265.657.49 1.312.676 1.948-.64.157-1.316.29-2.016.39.24-.375.48-.762.705-1.158.225-.39.435-.788.636-1.18zm-9.945.02c.2.392.41.783.64 1.175.23.39.465.772.705 1.143-.695-.102-1.365-.23-2.006-.386.18-.63.406-1.282.66-1.933zM17.92 16.32c.112.493.2.968.254 1.423.23 1.868-.054 3.32-.714 3.708-.147.09-.338.128-.563.128-1.012 0-2.514-.807-4.11-2.28.686-.72 1.37-1.536 2.02-2.44 1.107-.118 2.154-.3 3.113-.54zm-11.83.01c.96.234 2.006.415 3.107.532.66.905 1.345 1.727 2.035 2.446-1.595 1.483-3.092 2.295-4.11 2.295-.22-.005-.406-.05-.553-.132-.666-.38-.955-1.834-.73-3.703.054-.46.142-.944.25-1.438zm4.56.64c.44.02.89.034 1.345.034.46 0 .915-.01 1.36-.034-.44.572-.895 1.095-1.345 1.565-.455-.47-.91-.993-1.36-1.565z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
tailwind: (props: IconProps) => (
|
||||||
|
<svg viewBox="0 0 24 24" {...props}>
|
||||||
|
<path
|
||||||
|
d="M12.001,4.8c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 C13.666,10.618,15.027,12,18.001,12c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C16.337,6.182,14.976,4.8,12.001,4.8z M6.001,12c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 c1.177,1.194,2.538,2.576,5.512,2.576c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C10.337,13.382,8.976,12,6.001,12z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
google: (props: IconProps) => (
|
||||||
|
<svg role="img" viewBox="0 0 24 24" {...props}>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
apple: (props: IconProps) => (
|
||||||
|
<svg role="img" viewBox="0 0 24 24" {...props}>
|
||||||
|
<path
|
||||||
|
d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
paypal: (props: IconProps) => (
|
||||||
|
<svg role="img" viewBox="0 0 24 24" {...props}>
|
||||||
|
<path
|
||||||
|
d="M7.076 21.337H2.47a.641.641 0 0 1-.633-.74L4.944.901C5.026.382 5.474 0 5.998 0h7.46c2.57 0 4.578.543 5.69 1.81 1.01 1.15 1.304 2.42 1.012 4.287-.023.143-.047.288-.077.437-.983 5.05-4.349 6.797-8.647 6.797h-2.19c-.524 0-.968.382-1.05.9l-1.12 7.106zm14.146-14.42a3.35 3.35 0 0 0-.607-.541c-.013.076-.026.175-.041.254-.93 4.778-4.005 7.201-9.138 7.201h-2.19a.563.563 0 0 0-.556.479l-1.187 7.527h-.506l-.24 1.516a.56.56 0 0 0 .554.647h3.882c.46 0 .85-.334.922-.788.06-.26.76-4.852.816-5.09a.932.932 0 0 1 .923-.788h.58c3.76 0 6.705-1.528 7.565-5.946.36-1.847.174-3.388-.777-4.471z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
spinner: (props: IconProps) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
{...props}>
|
||||||
|
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
};
|
||||||
25
src/components/ui/input.tsx
Normal file
25
src/components/ui/input.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export interface InputProps
|
||||||
|
extends React.InputHTMLAttributes<HTMLInputElement> {}
|
||||||
|
|
||||||
|
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||||
|
({ className, type, ...props }, ref) => {
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
type={type}
|
||||||
|
className={cn(
|
||||||
|
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Input.displayName = "Input"
|
||||||
|
|
||||||
|
export { Input }
|
||||||
26
src/components/ui/label.tsx
Normal file
26
src/components/ui/label.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as LabelPrimitive from "@radix-ui/react-label"
|
||||||
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const labelVariants = cva(
|
||||||
|
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Label = React.forwardRef<
|
||||||
|
React.ElementRef<typeof LabelPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
|
||||||
|
VariantProps<typeof labelVariants>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<LabelPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(labelVariants(), className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
Label.displayName = LabelPrimitive.Root.displayName
|
||||||
|
|
||||||
|
export { Label }
|
||||||
110
src/components/ui/overview.tsx
Normal file
110
src/components/ui/overview.tsx
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Bar, BarChart, ResponsiveContainer, XAxis, YAxis, LineChart, Line } from "recharts";
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
name: "Jan",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Feb",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Mar",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Apr",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "May",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Jun",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Jul",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Aug",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sep",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Oct",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Nov",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Dec",
|
||||||
|
total: Math.floor(Math.random() * 5000) + 1000,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
interface OverViewProps{
|
||||||
|
graphType:string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Overview(props: OverViewProps) {
|
||||||
|
return (
|
||||||
|
<ResponsiveContainer width="100%" height={350}>
|
||||||
|
{props.graphType === 'line' ? (
|
||||||
|
<LineChart data={data}>
|
||||||
|
<XAxis
|
||||||
|
dataKey="name"
|
||||||
|
stroke="#888888"
|
||||||
|
fontSize={12}
|
||||||
|
tickLine={false}
|
||||||
|
axisLine={false}
|
||||||
|
/>
|
||||||
|
<YAxis
|
||||||
|
stroke="#888888"
|
||||||
|
fontSize={12}
|
||||||
|
tickLine={false}
|
||||||
|
axisLine={false}
|
||||||
|
tickFormatter={(value) => `$${value}`}
|
||||||
|
/>
|
||||||
|
<Line
|
||||||
|
dataKey="total"
|
||||||
|
fill="currentColor"
|
||||||
|
className="fill-primary"
|
||||||
|
/>
|
||||||
|
</LineChart>
|
||||||
|
) : (
|
||||||
|
<BarChart data={data}>
|
||||||
|
<XAxis
|
||||||
|
dataKey="name"
|
||||||
|
stroke="#888888"
|
||||||
|
fontSize={12}
|
||||||
|
tickLine={false}
|
||||||
|
axisLine={false}
|
||||||
|
/>
|
||||||
|
<YAxis
|
||||||
|
stroke="#888888"
|
||||||
|
fontSize={12}
|
||||||
|
tickLine={false}
|
||||||
|
axisLine={false}
|
||||||
|
tickFormatter={(value) => `$${value}`}
|
||||||
|
/>
|
||||||
|
<Bar
|
||||||
|
dataKey="total"
|
||||||
|
fill="currentColor"
|
||||||
|
className="fill-primary"
|
||||||
|
/>
|
||||||
|
</BarChart>
|
||||||
|
)}
|
||||||
|
</ResponsiveContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
44
src/components/ui/radio-group.tsx
Normal file
44
src/components/ui/radio-group.tsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
|
||||||
|
import { Circle } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const RadioGroup = React.forwardRef<
|
||||||
|
React.ElementRef<typeof RadioGroupPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
|
||||||
|
>(({ className, ...props }, ref) => {
|
||||||
|
return (
|
||||||
|
<RadioGroupPrimitive.Root
|
||||||
|
className={cn("grid gap-2", className)}
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
|
||||||
|
|
||||||
|
const RadioGroupItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof RadioGroupPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
|
||||||
|
>(({ className, ...props }, ref) => {
|
||||||
|
return (
|
||||||
|
<RadioGroupPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
|
||||||
|
<Circle className="h-2.5 w-2.5 fill-current text-current" />
|
||||||
|
</RadioGroupPrimitive.Indicator>
|
||||||
|
</RadioGroupPrimitive.Item>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
|
||||||
|
|
||||||
|
export { RadioGroup, RadioGroupItem }
|
||||||
117
src/components/ui/table.tsx
Normal file
117
src/components/ui/table.tsx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Table = React.forwardRef<
|
||||||
|
HTMLTableElement,
|
||||||
|
React.HTMLAttributes<HTMLTableElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div className="relative w-full overflow-auto">
|
||||||
|
<table
|
||||||
|
ref={ref}
|
||||||
|
className={cn("w-full caption-bottom text-sm", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
Table.displayName = "Table"
|
||||||
|
|
||||||
|
const TableHeader = React.forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
|
||||||
|
))
|
||||||
|
TableHeader.displayName = "TableHeader"
|
||||||
|
|
||||||
|
const TableBody = React.forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tbody
|
||||||
|
ref={ref}
|
||||||
|
className={cn("[&_tr:last-child]:border-0", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableBody.displayName = "TableBody"
|
||||||
|
|
||||||
|
const TableFooter = React.forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tfoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableFooter.displayName = "TableFooter"
|
||||||
|
|
||||||
|
const TableRow = React.forwardRef<
|
||||||
|
HTMLTableRowElement,
|
||||||
|
React.HTMLAttributes<HTMLTableRowElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tr
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableRow.displayName = "TableRow"
|
||||||
|
|
||||||
|
const TableHead = React.forwardRef<
|
||||||
|
HTMLTableCellElement,
|
||||||
|
React.ThHTMLAttributes<HTMLTableCellElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<th
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableHead.displayName = "TableHead"
|
||||||
|
|
||||||
|
const TableCell = React.forwardRef<
|
||||||
|
HTMLTableCellElement,
|
||||||
|
React.TdHTMLAttributes<HTMLTableCellElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<td
|
||||||
|
ref={ref}
|
||||||
|
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableCell.displayName = "TableCell"
|
||||||
|
|
||||||
|
const TableCaption = React.forwardRef<
|
||||||
|
HTMLTableCaptionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableCaptionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<caption
|
||||||
|
ref={ref}
|
||||||
|
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableCaption.displayName = "TableCaption"
|
||||||
|
|
||||||
|
export {
|
||||||
|
Table,
|
||||||
|
TableHeader,
|
||||||
|
TableBody,
|
||||||
|
TableFooter,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
TableCell,
|
||||||
|
TableCaption,
|
||||||
|
}
|
||||||
55
src/components/ui/tabs.tsx
Normal file
55
src/components/ui/tabs.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as TabsPrimitive from "@radix-ui/react-tabs"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Tabs = TabsPrimitive.Root
|
||||||
|
|
||||||
|
const TabsList = React.forwardRef<
|
||||||
|
React.ElementRef<typeof TabsPrimitive.List>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<TabsPrimitive.List
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TabsList.displayName = TabsPrimitive.List.displayName
|
||||||
|
|
||||||
|
const TabsTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<TabsPrimitive.Trigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
|
||||||
|
|
||||||
|
const TabsContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof TabsPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<TabsPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TabsContent.displayName = TabsPrimitive.Content.displayName
|
||||||
|
|
||||||
|
export { Tabs, TabsList, TabsTrigger, TabsContent }
|
||||||
25
test_util/global-setup.ts
Normal file
25
test_util/global-setup.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { firefox, FullConfig } from '@playwright/test';
|
||||||
|
|
||||||
|
async function globalSetup(config: FullConfig) {
|
||||||
|
const email = process.env.NEXT_PUBLIC_DUMMY_EMAIL;
|
||||||
|
const password = process.env.NEXT_PUBLIC_DUMMY_PASSWORD;
|
||||||
|
const baseUrl = 'http://127.0.0.1:3000';
|
||||||
|
|
||||||
|
if (!email || !password) {
|
||||||
|
throw new Error('NEXT_PUBLIC_DUMMY_EMAIL and NEXT_PUBLIC_DUMMY_PASSWORD must be set');
|
||||||
|
}
|
||||||
|
|
||||||
|
const browser = await firefox.launch();
|
||||||
|
const page = await browser.newPage();
|
||||||
|
await page.goto(baseUrl + '/auth');
|
||||||
|
await page.fill('id=email', email);
|
||||||
|
await page.fill('id=password', password);
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForURL(baseUrl),
|
||||||
|
page.click('id=login')
|
||||||
|
]);
|
||||||
|
await page.context().storageState({ path: 'storageState.json' });
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
export default globalSetup;
|
||||||
23
tests/test-1.spec.ts
Normal file
23
tests/test-1.spec.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test.use({
|
||||||
|
storageState: './storageState.json'
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test search businesses', async ({ page }) => {
|
||||||
|
await page.goto('http://127.0.0.1:3000/');
|
||||||
|
await page.getByLabel('Main').getByRole('img').click();
|
||||||
|
|
||||||
|
const businessInput = page.getByPlaceholder('Enter business name...');
|
||||||
|
await expect(businessInput).toBeVisible();
|
||||||
|
await businessInput.fill('neon');
|
||||||
|
await businessInput.press('Enter');
|
||||||
|
|
||||||
|
const heading = page.getByRole('heading', { name: 'Neon Solution, A dummy company' });
|
||||||
|
await expect(heading).toBeVisible();
|
||||||
|
await heading.click();
|
||||||
|
|
||||||
|
const fundSection = page.locator('div').filter({ hasText: /^Neon raising fund #1$/ });
|
||||||
|
await expect(fundSection).toBeVisible();
|
||||||
|
await fundSection.click();
|
||||||
|
});
|
||||||
30
tests/test-2.spec.ts
Normal file
30
tests/test-2.spec.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test.use({
|
||||||
|
storageState: './storageState.json'
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test filter with tags', async ({ page }) => {
|
||||||
|
await page.goto('http://127.0.0.1:3000/');
|
||||||
|
await page.getByRole('button', { name: 'Start Investing' }).click();
|
||||||
|
|
||||||
|
await page.locator('button').filter({ hasText: 'Tags' }).click();
|
||||||
|
await page.getByLabel('AI', { exact: true }).click();
|
||||||
|
await page.locator('span#tag', { hasText: 'AI' });
|
||||||
|
|
||||||
|
await page.locator('button').filter({ hasText: 'AI' }).click();
|
||||||
|
await page.getByLabel('Technology').click();
|
||||||
|
await page.locator('span#tag', { hasText: 'Technology' });
|
||||||
|
|
||||||
|
await page.locator('button').filter({ hasText: 'Technology' }).click();
|
||||||
|
await page.getByText('Consumer Electronics').click();
|
||||||
|
await page.locator('span#tag', { hasText: 'Consumer Electronics' });
|
||||||
|
|
||||||
|
await page.locator('button').filter({ hasText: 'Consumer Electronics' }).click();
|
||||||
|
await page.getByLabel('Software').click();
|
||||||
|
await page.locator('span#tag', { hasText: 'Software' });
|
||||||
|
|
||||||
|
await page.locator('button').filter({ hasText: 'Software' }).click();
|
||||||
|
await page.getByLabel('Internet').click();
|
||||||
|
await page.locator('span#tag', { hasText: 'Internet' });
|
||||||
|
});
|
||||||
26
tests/test-3.spec.ts
Normal file
26
tests/test-3.spec.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
test.use({
|
||||||
|
storageState: './storageState.json'
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test dashboard visibility', async ({ page }) => {
|
||||||
|
await page.goto('http://127.0.0.1:3000/dashboard');
|
||||||
|
|
||||||
|
const dashboardHeading = page.locator('h2', { hasText: 'Dashboard' });
|
||||||
|
await expect(dashboardHeading).toBeVisible();
|
||||||
|
|
||||||
|
const profileViewHeading = page.locator('h3', { hasText: 'Profile Views' });
|
||||||
|
await expect(profileViewHeading).toBeVisible();
|
||||||
|
|
||||||
|
const totalFollowerHeading = page.locator('h3', { hasText: 'Total Followers' });
|
||||||
|
await expect(totalFollowerHeading).toBeVisible();
|
||||||
|
|
||||||
|
const fundsRaisedHeading = page.locator('h3', { hasText: 'Total Funds Raised' });
|
||||||
|
await expect(fundsRaisedHeading).toBeVisible();
|
||||||
|
|
||||||
|
const overviewHeading = page.locator('h3', { hasText: 'Overview' });
|
||||||
|
await expect(overviewHeading).toBeVisible();
|
||||||
|
|
||||||
|
const recentFundHeading = page.locator('h3', { hasText: 'Recent Funds' });
|
||||||
|
await expect(recentFundHeading).toBeVisible();
|
||||||
|
});
|
||||||
107
tests/test-4.spec.ts
Normal file
107
tests/test-4.spec.ts
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import { test, expect, Page } from '@playwright/test';
|
||||||
|
|
||||||
|
test.use({
|
||||||
|
storageState: './storageState.json',
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Investment process test', async ({ page }) => {
|
||||||
|
await page.goto('http://127.0.0.1:3000/');
|
||||||
|
|
||||||
|
// Navigate to the investment page
|
||||||
|
// await page.getByRole('link', { name: 'Card image NVDA Founded in' }).click();
|
||||||
|
await page.click('a[href="/invest"]');
|
||||||
|
await page.getByRole('button', { name: 'Invest in NVIDIA' }).click();
|
||||||
|
|
||||||
|
// Fill investment amount
|
||||||
|
await fillInvestmentAmount(page, '10000');
|
||||||
|
|
||||||
|
// Fill card information
|
||||||
|
await fillCardInformation(page, {
|
||||||
|
name: 'Dummy',
|
||||||
|
city: 'Bangkok',
|
||||||
|
cardNumber: '4111 1111 1111 1111',
|
||||||
|
expirationMonth: 'August',
|
||||||
|
expirationYear: '2032',
|
||||||
|
cvc: '111',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Accept terms
|
||||||
|
await acceptTerms(page, [
|
||||||
|
'Minimum Investment',
|
||||||
|
'Investment Horizon',
|
||||||
|
'Fees',
|
||||||
|
'Returns',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Click Invest button and confirm
|
||||||
|
await page.getByRole('button', { name: 'Invest' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||||
|
|
||||||
|
// Ensure error message is displayed when not all terms are accepted
|
||||||
|
await ensureErrorMessageDisplayed(page, 'Please accept all terms');
|
||||||
|
|
||||||
|
// Close the error dialog
|
||||||
|
await closeErrorDialog(page);
|
||||||
|
|
||||||
|
// Accept remaining terms
|
||||||
|
await acceptTerms(page, [
|
||||||
|
'Risk Disclosure',
|
||||||
|
'Withdrawal Policy',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Click Invest button and confirm again
|
||||||
|
await page.getByRole('button', { name: 'Invest' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||||
|
|
||||||
|
// Ensure that success toast is displayed when investment is successful
|
||||||
|
await expect(
|
||||||
|
page.locator('div[role="status"][aria-live="polite"]').filter({ hasText: /^You successfully invested!$/ })
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
async function fillInvestmentAmount(page: Page, amount: string): Promise<void> {
|
||||||
|
await page.getByPlaceholder('min $').click();
|
||||||
|
await page.getByPlaceholder('min $').fill(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CardInfo {
|
||||||
|
name: string;
|
||||||
|
city: string;
|
||||||
|
cardNumber: string;
|
||||||
|
expirationMonth: string;
|
||||||
|
expirationYear: string;
|
||||||
|
cvc: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fillCardInformation(
|
||||||
|
page: Page,
|
||||||
|
{ name, city, cardNumber, expirationMonth, expirationYear, cvc }: CardInfo
|
||||||
|
): Promise<void> {
|
||||||
|
await page.getByPlaceholder('First Last').click();
|
||||||
|
await page.getByPlaceholder('First Last').fill(name);
|
||||||
|
await page.getByLabel('City').click();
|
||||||
|
await page.getByLabel('City').fill(city);
|
||||||
|
await page.getByLabel('Card number').click();
|
||||||
|
await page.getByLabel('Card number').fill(cardNumber);
|
||||||
|
await page.getByLabel('Month').click();
|
||||||
|
await page.getByText(expirationMonth).click();
|
||||||
|
await page.getByLabel('Year').click();
|
||||||
|
await page.getByLabel(expirationYear).click();
|
||||||
|
await page.getByPlaceholder('CVC').click();
|
||||||
|
await page.getByPlaceholder('CVC').fill(cvc);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function acceptTerms(page: Page, terms: string[]): Promise<void> {
|
||||||
|
for (const term of terms) {
|
||||||
|
await page.getByRole('row', { name: new RegExp(term) }).getByRole('checkbox').check();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ensureErrorMessageDisplayed(page: Page, message: string): Promise<void> {
|
||||||
|
await expect(page.getByText(message)).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function closeErrorDialog(page: Page): Promise<void> {
|
||||||
|
await page.getByRole('button', { name: 'Close' }).first().click();
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user