Compare commits

...

18 Commits

Author SHA1 Message Date
11b4c723fa
chore(dependencies): upgrade packages in pnpm-lock.yaml
Several dependencies have been upgraded across multiple versions including react-hook-form, lightweight-charts, next elements, sonner, lucide-react, embla-carousel-react and others. Reflecting these changes in the pnpm-lock.yaml file is necessary for functional and up-to-date building of the project. This helps maintain compatibility and introduces performance improvements or new features from the updated packages.
2024-06-17 10:02:36 +02:00
1674664980
build: Update package dependencies
Upgrade multiple dependencies to their newer versions in package.json file. This includes libraries like 'embla-carousel-react', 'lightweight-charts', and 'react' among others. It also includes devDependencies like '@types/node', '@types/react', and 'typescript'.
2024-06-17 10:02:09 +02:00
39fc556aca
refactor(app): move Toaster component position in layout
The Toaster component was relocated in the layout file. It's been moved from below the Providers component to a position above the Footer component. This repositioning is aimed at improving the visual hierarchy and flow of the application.
2024-06-17 10:01:32 +02:00
7426f5f642
feat(component): Update footer styling and structure
The footer's class has been updated to improve page layout. Additionally, unnecessary div containing flex properties has been removed for simplicity and improved readability.
2024-06-17 10:01:15 +02:00
01c073e879
feat(account-info): add disconnect handling and improve info display
The commit enhances the account information component with better data handling. It adds disconnect handling to account for cases when user session is terminated. It also improves information display by adding details like crypto availability and user identity, improving the overall user experience.
2024-06-17 09:50:06 +02:00
e6d37ef600
feat(services): add general.interface.ts
This commit introduces a new interface file named 'general.interface.ts' to standardise return types in the services scope. It includes the IStandardisedReturn interface and the EReturnState enum. These additions enhance the consistency of return types across different services.
2024-06-17 09:49:09 +02:00
cc286462f0
feat(components): add authentication forms
This commit introduces authentication forms for both user login and registration. These forms use zod for data validation and context for state management. Login and registration processes have been implemented as asynchronous functions, handling API requests, and error responses.
2024-06-17 09:48:38 +02:00
4c061dc19c
feat(account-dialog): handle case when userContext not present
This commit updates the account-dialog component to properly handle when there's no userContext. Previously, a default user data was set when no userContext was found, this has been replaced with a simple message saying 'No account'. Also, checks for an authentication token in localStorage have been included. These changes aim towards better handling of edge cases and unauthenticated scenarios.
2024-06-17 09:47:57 +02:00
3b1a3e93e0
feat(layout): add Toaster component and update favicon link
This commit introduces the Toaster component to the main layout. In addition, the link to the favicon has been updated to correct its location.
2024-06-17 09:46:21 +02:00
5c81ad917d
feat(auth): Update auth page layout
The width of the authentication page is adjusted to occupy the full width of the viewport to enhance usability. This layout update ensures consistency for different screen sizes.
2024-06-17 09:45:58 +02:00
b5526e5877
"refactor(service): remove register and login functions in account.handler.ts"
This commit involves a significant refactoring in the account.handler.ts file. Specifically, it removed the `doRegister` and `doLogin` functions. Furthermore, replaced `useEncodedLocalStorage` with `useLocalStorage`. The `doDisconnect` function has been refined to redirect to homepage after removing an item from local storage.
2024-06-17 09:45:25 +02:00
41ba50d417
feat(ui): Change input background color to accent
In the 'input.tsx' component of the UI, the background color property of the input field has been updated from 'bg-background' to 'bg-accent' to enhance visibility.
2024-06-17 09:44:47 +02:00
0504692dfb
feat(auto-form): apply full width to form class
The className of the form in the auto-form component has been updated to include "w-full". This change ensures that the form will occupy the full width of its parent container, enhancing layout and visibility.
2024-06-17 09:44:07 +02:00
15eb7addd0
feat(interface): allow message to be string or array
This update to the api.interface now accepts both strings and arrays for the 'message' field inside the IAbstractApiResponse interface. This provides more flexibility for responses returned by the API.
2024-06-17 09:43:26 +02:00
5a905d0608
refactor: moved favicon to app root 2024-06-17 09:35:31 +02:00
72bbe08de0
feat(components): update layout for responsiveness
This commit enhances the layout in header.tsx for better mobile responsiveness. It adjusts flex properties and classes for optimal rendering across various device sizes. It also rearranges elements within the header component for a better mobile appearance.
2024-06-14 12:48:03 +02:00
48adc8be6c
refactor(interface): modify import statement in userdata.interface.ts
This change adjusts the import statement to correctly import the ICryptoInUserWalletInfo. Previously, the incorrect syntax was causing import errors and this revision resolves that issue.
2024-06-14 12:47:41 +02:00
3a8621735e
feat(auth): Add new authentication page
A new authentication page has been added to the application. It includes an AuthForms component and uses a flex display for layout, with specific height and width properties set.
2024-06-14 12:47:17 +02:00
16 changed files with 514 additions and 217 deletions

View File

@ -44,19 +44,19 @@
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.0.0", "cmdk": "^1.0.0",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"embla-carousel-react": "^8.1.3", "embla-carousel-react": "^8.1.5",
"framer-motion": "^11.2.10", "framer-motion": "^11.2.10",
"input-otp": "^1.2.4", "input-otp": "^1.2.4",
"lightweight-charts": "^4.1.4", "lightweight-charts": "^4.1.5",
"lucide-react": "^0.387.0", "lucide-react": "^0.395.0",
"next": "14.2.3", "next": "14.2.4",
"next-themes": "^0.3.0", "next-themes": "^0.3.0",
"react": "^18", "react": "^18.3.1",
"react-day-picker": "^8.10.1", "react-day-picker": "^8.10.1",
"react-dom": "^18", "react-dom": "^18.3.1",
"react-hook-form": "^7.51.5", "react-hook-form": "^7.52.0",
"react-resizable-panels": "^2.0.19", "react-resizable-panels": "^2.0.19",
"sonner": "^1.4.41", "sonner": "^1.5.0",
"tailwind-merge": "^2.3.0", "tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"vaul": "^0.9.1", "vaul": "^0.9.1",
@ -65,12 +65,12 @@
"devDependencies": { "devDependencies": {
"@biomejs/biome": "1.8.1", "@biomejs/biome": "1.8.1",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/node": "^20", "@types/node": "^20.14.2",
"@types/react": "^18", "@types/react": "^18.3.3",
"@types/react-dom": "^18", "@types/react-dom": "^18.3.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"postcss": "^8", "postcss": "^8.4.38",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.4",
"typescript": "^5" "typescript": "^5.4.5"
} }
} }

234
pnpm-lock.yaml generated
View File

@ -13,7 +13,7 @@ importers:
version: 5.0.3 version: 5.0.3
'@hookform/resolvers': '@hookform/resolvers':
specifier: ^3.6.0 specifier: ^3.6.0
version: 3.6.0(react-hook-form@7.51.5(react@18.3.1)) version: 3.6.0(react-hook-form@7.52.0(react@18.3.1))
'@radix-ui/react-accordion': '@radix-ui/react-accordion':
specifier: ^1.1.2 specifier: ^1.1.2
version: 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -111,8 +111,8 @@ importers:
specifier: ^3.6.0 specifier: ^3.6.0
version: 3.6.0 version: 3.6.0
embla-carousel-react: embla-carousel-react:
specifier: ^8.1.3 specifier: ^8.1.5
version: 8.1.3(react@18.3.1) version: 8.1.5(react@18.3.1)
framer-motion: framer-motion:
specifier: ^11.2.10 specifier: ^11.2.10
version: 11.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 11.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -120,35 +120,35 @@ importers:
specifier: ^1.2.4 specifier: ^1.2.4
version: 1.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 1.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
lightweight-charts: lightweight-charts:
specifier: ^4.1.4 specifier: ^4.1.5
version: 4.1.4 version: 4.1.5
lucide-react: lucide-react:
specifier: ^0.387.0 specifier: ^0.395.0
version: 0.387.0(react@18.3.1) version: 0.395.0(react@18.3.1)
next: next:
specifier: 14.2.3 specifier: 14.2.4
version: 14.2.3(@babel/core@7.24.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 14.2.4(@babel/core@7.24.7)(react-dom@18.3.1(react@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))(react@18.3.1) version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: react:
specifier: ^18 specifier: ^18.3.1
version: 18.3.1 version: 18.3.1
react-day-picker: react-day-picker:
specifier: ^8.10.1 specifier: ^8.10.1
version: 8.10.1(date-fns@3.6.0)(react@18.3.1) version: 8.10.1(date-fns@3.6.0)(react@18.3.1)
react-dom: react-dom:
specifier: ^18 specifier: ^18.3.1
version: 18.3.1(react@18.3.1) version: 18.3.1(react@18.3.1)
react-hook-form: react-hook-form:
specifier: ^7.51.5 specifier: ^7.52.0
version: 7.51.5(react@18.3.1) version: 7.52.0(react@18.3.1)
react-resizable-panels: react-resizable-panels:
specifier: ^2.0.19 specifier: ^2.0.19
version: 2.0.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 2.0.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
sonner: sonner:
specifier: ^1.4.41 specifier: ^1.5.0
version: 1.4.41(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
tailwind-merge: tailwind-merge:
specifier: ^2.3.0 specifier: ^2.3.0
version: 2.3.0 version: 2.3.0
@ -169,25 +169,25 @@ importers:
specifier: ^29.5.12 specifier: ^29.5.12
version: 29.5.12 version: 29.5.12
'@types/node': '@types/node':
specifier: ^20 specifier: ^20.14.2
version: 20.14.2 version: 20.14.2
'@types/react': '@types/react':
specifier: ^18 specifier: ^18.3.3
version: 18.3.3 version: 18.3.3
'@types/react-dom': '@types/react-dom':
specifier: ^18 specifier: ^18.3.0
version: 18.3.0 version: 18.3.0
jest: jest:
specifier: ^29.7.0 specifier: ^29.7.0
version: 29.7.0(@types/node@20.14.2) version: 29.7.0(@types/node@20.14.2)
postcss: postcss:
specifier: ^8 specifier: ^8.4.38
version: 8.4.38 version: 8.4.38
tailwindcss: tailwindcss:
specifier: ^3.4.1 specifier: ^3.4.4
version: 3.4.4 version: 3.4.4
typescript: typescript:
specifier: ^5 specifier: ^5.4.5
version: 5.4.5 version: 5.4.5
packages: packages:
@ -543,59 +543,59 @@ packages:
'@jridgewell/trace-mapping@0.3.25': '@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
'@next/env@14.2.3': '@next/env@14.2.4':
resolution: {integrity: sha512-W7fd7IbkfmeeY2gXrzJYDx8D2lWKbVoTIj1o1ScPHNzvp30s1AuoEFSdr39bC5sjxJaxTtq3OTCZboNp0lNWHA==} resolution: {integrity: sha512-3EtkY5VDkuV2+lNmKlbkibIJxcO4oIHEhBWne6PaAp+76J9KoSsGvNikp6ivzAT8dhhBMYrm6op2pS1ApG0Hzg==}
'@next/swc-darwin-arm64@14.2.3': '@next/swc-darwin-arm64@14.2.4':
resolution: {integrity: sha512-3pEYo/RaGqPP0YzwnlmPN2puaF2WMLM3apt5jLW2fFdXD9+pqcoTzRk+iZsf8ta7+quAe4Q6Ms0nR0SFGFdS1A==} resolution: {integrity: sha512-AH3mO4JlFUqsYcwFUHb1wAKlebHU/Hv2u2kb1pAuRanDZ7pD/A/KPD98RHZmwsJpdHQwfEc/06mgpSzwrJYnNg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@next/swc-darwin-x64@14.2.3': '@next/swc-darwin-x64@14.2.4':
resolution: {integrity: sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==} resolution: {integrity: sha512-QVadW73sWIO6E2VroyUjuAxhWLZWEpiFqHdZdoQ/AMpN9YWGuHV8t2rChr0ahy+irKX5mlDU7OY68k3n4tAZTg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@next/swc-linux-arm64-gnu@14.2.3': '@next/swc-linux-arm64-gnu@14.2.4':
resolution: {integrity: sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==} resolution: {integrity: sha512-KT6GUrb3oyCfcfJ+WliXuJnD6pCpZiosx2X3k66HLR+DMoilRb76LpWPGb4tZprawTtcnyrv75ElD6VncVamUQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@next/swc-linux-arm64-musl@14.2.3': '@next/swc-linux-arm64-musl@14.2.4':
resolution: {integrity: sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==} resolution: {integrity: sha512-Alv8/XGSs/ytwQcbCHwze1HmiIkIVhDHYLjczSVrf0Wi2MvKn/blt7+S6FJitj3yTlMwMxII1gIJ9WepI4aZ/A==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@next/swc-linux-x64-gnu@14.2.3': '@next/swc-linux-x64-gnu@14.2.4':
resolution: {integrity: sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==} resolution: {integrity: sha512-ze0ShQDBPCqxLImzw4sCdfnB3lRmN3qGMB2GWDRlq5Wqy4G36pxtNOo2usu/Nm9+V2Rh/QQnrRc2l94kYFXO6Q==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@next/swc-linux-x64-musl@14.2.3': '@next/swc-linux-x64-musl@14.2.4':
resolution: {integrity: sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==} resolution: {integrity: sha512-8dwC0UJoc6fC7PX70csdaznVMNr16hQrTDAMPvLPloazlcaWfdPogq+UpZX6Drqb1OBlwowz8iG7WR0Tzk/diQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@next/swc-win32-arm64-msvc@14.2.3': '@next/swc-win32-arm64-msvc@14.2.4':
resolution: {integrity: sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==} resolution: {integrity: sha512-jxyg67NbEWkDyvM+O8UDbPAyYRZqGLQDTPwvrBBeOSyVWW/jFQkQKQ70JDqDSYg1ZDdl+E3nkbFbq8xM8E9x8A==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@next/swc-win32-ia32-msvc@14.2.3': '@next/swc-win32-ia32-msvc@14.2.4':
resolution: {integrity: sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==} resolution: {integrity: sha512-twrmN753hjXRdcrZmZttb/m5xaCBFa48Dt3FbeEItpJArxriYDunWxJn+QFXdJ3hPkm4u7CKxncVvnmgQMY1ag==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
'@next/swc-win32-x64-msvc@14.2.3': '@next/swc-win32-x64-msvc@14.2.4':
resolution: {integrity: sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==} resolution: {integrity: sha512-tkLrjBzqFTP8DVrAAQmZelEahfR9OxWpFR++vAI9FBhCiIxtwHwBHC23SBHCTURBtwB4kc/x44imVOnkKGNVGg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@ -1410,8 +1410,8 @@ packages:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'} engines: {node: '>=10'}
caniuse-lite@1.0.30001629: caniuse-lite@1.0.30001636:
resolution: {integrity: sha512-c3dl911slnQhmxUIT4HhYzT7wnBK/XYpGnYLOj4nJBaRiw52Ibe7YxlDaAeRECvA786zCuExhxIUJ2K7nHMrBw==} resolution: {integrity: sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==}
chalk@2.4.2: chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
@ -1559,21 +1559,21 @@ packages:
eastasianwidth@0.2.0: eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
electron-to-chromium@1.4.796: electron-to-chromium@1.4.803:
resolution: {integrity: sha512-NglN/xprcM+SHD2XCli4oC6bWe6kHoytcyLKCWXmRL854F0qhPhaYgUswUsglnPxYaNQIg2uMY4BvaomIf3kLA==} resolution: {integrity: sha512-61H9mLzGOCLLVsnLiRzCbc63uldP0AniRYPV3hbGVtONA1pI7qSGILdbofR7A8TMbOypDocEAjH/e+9k1QIe3g==}
embla-carousel-react@8.1.3: embla-carousel-react@8.1.5:
resolution: {integrity: sha512-YrezDPgxPDKa+OKMhSrwuPEU2OgF5147vFW473EWT3bx9DETV3W/RyWTxq0/2pf3M4VXkjqFNbS/W1xM8lTaVg==} resolution: {integrity: sha512-xFmfxgJd7mpWDHQ4iyK1Qs+5BTTwu4bkn+mSROKiUH9nKpPHTeilQ+rpeQDCHRrAPeshD67aBk0/p6FxWxXsng==}
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17.0.1 || ^18.0.0 react: ^16.8.0 || ^17.0.1 || ^18.0.0
embla-carousel-reactive-utils@8.1.3: embla-carousel-reactive-utils@8.1.5:
resolution: {integrity: sha512-D8tAK6NRQVEubMWb+b/BJ3VvGPsbEeEFOBM6cCCwfiyfLzNlacOAt0q2dtUEA9DbGxeWkB8ExgXzFRxhGV2Hig==} resolution: {integrity: sha512-76uZTrSaEGGta+qpiGkMFlLK0I7N04TdjZ2obrBhyggYIFDWlxk1CriIEmt2lisLNsa1IYXM85kr863JoCMSyg==}
peerDependencies: peerDependencies:
embla-carousel: 8.1.3 embla-carousel: 8.1.5
embla-carousel@8.1.3: embla-carousel@8.1.5:
resolution: {integrity: sha512-GiRpKtzidV3v50oVMly8S+D7iE1r96ttt7fSlvtyKHoSkzrAnVcu8fX3c4j8Ol2hZSQlVfDqDIqdrFPs0u5TWQ==} resolution: {integrity: sha512-R6xTf7cNdR2UTNM6/yUPZlJFRmZSogMiRjJ5vXHO65II5MoUlrVYUAP0fHQei/py82Vf15lj+WI+QdhnzBxA2g==}
emittery@0.13.1: emittery@0.13.1:
resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
@ -1650,8 +1650,8 @@ packages:
debug: debug:
optional: true optional: true
foreground-child@3.1.1: foreground-child@3.2.1:
resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==}
engines: {node: '>=14'} engines: {node: '>=14'}
form-data@4.0.0: form-data@4.0.0:
@ -1965,8 +1965,8 @@ packages:
node-notifier: node-notifier:
optional: true optional: true
jiti@1.21.3: jiti@1.21.6:
resolution: {integrity: sha512-uy2bNX5zQ+tESe+TiC7ilGRz8AtRGmnJH55NC5S0nSUjvvvM2hJHmefHErugGXN4pNv4Qx7vLsnNw9qJ9mtIsw==} resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
hasBin: true hasBin: true
js-tokens@4.0.0: js-tokens@4.0.0:
@ -1997,15 +1997,15 @@ packages:
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
engines: {node: '>=6'} engines: {node: '>=6'}
lightweight-charts@4.1.4: lightweight-charts@4.1.5:
resolution: {integrity: sha512-jsQOK27a3wiw/Db3Eoo3VX93LGovXA/sOWHVEiEosGOOGtxSSuIWTYVebjRKGK0SWkkUwI8AHQ4j7HZSKm7fxA==} resolution: {integrity: sha512-2ML3CgwKGX3FsvLs+ExvIM+C4/cYaa4dsYUy8BHfdqAgYY+bwjIzSDsv5PpTE2a1rDKQBI5LJRtocELcWeXTWw==}
lilconfig@2.1.0: lilconfig@2.1.0:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
lilconfig@3.1.1: lilconfig@3.1.2:
resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==}
engines: {node: '>=14'} engines: {node: '>=14'}
lines-and-columns@1.2.4: lines-and-columns@1.2.4:
@ -2026,8 +2026,8 @@ packages:
lru-cache@5.1.1: lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
lucide-react@0.387.0: lucide-react@0.395.0:
resolution: {integrity: sha512-NyB4oJZ0pzLHT/QgMpgCPbez6yqvz8QPBocMJBXQCInPpXcQVCUpcU1CDlRG8mT2j0KqodLQYp+F5zn8U86sXg==} resolution: {integrity: sha512-6hzdNH5723A4FLaYZWpK50iyZH8iS2Jq5zuPRRotOFkhu6kxxJiebVdJ72tCR5XkiIeYFOU5NUawFZOac+VeYw==}
peerDependencies: peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 react: ^16.5.1 || ^17.0.0 || ^18.0.0
@ -2092,8 +2092,8 @@ packages:
react: ^16.8 || ^17 || ^18 react: ^16.8 || ^17 || ^18
react-dom: ^16.8 || ^17 || ^18 react-dom: ^16.8 || ^17 || ^18
next@14.2.3: next@14.2.4:
resolution: {integrity: sha512-dowFkFTR8v79NPJO4QsBUtxv0g9BrS/phluVpMAt2ku7H+cbcBJlopXjkWlwxrk/xGqMemr7JkGPGemPrLLX7A==} resolution: {integrity: sha512-R8/V7vugY+822rsQGQCjoLhMuC9oFj9SOi4Cl4b2wjDrseD0LRZ10W7R6Czo4w9ZznVSshKjuIomsRjvm9EKJQ==}
engines: {node: '>=18.17.0'} engines: {node: '>=18.17.0'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -2270,11 +2270,11 @@ packages:
peerDependencies: peerDependencies:
react: ^18.3.1 react: ^18.3.1
react-hook-form@7.51.5: react-hook-form@7.52.0:
resolution: {integrity: sha512-J2ILT5gWx1XUIJRETiA7M19iXHlG74+6O3KApzvqB/w8S5NQR7AbU8HVZrMALdmDgWpRPYiZJl0zx8Z4L2mP6Q==} resolution: {integrity: sha512-mJX506Xc6mirzLsmXUJyqlAI3Kj9Ph2RhplYhUVffeOQSnubK2uVqBFOBJmvKikvbFV91pxVXmDiR+QMF19x6A==}
engines: {node: '>=12.22.0'} engines: {node: '>=12.22.0'}
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17 || ^18 react: ^16.8.0 || ^17 || ^18 || ^19
react-is@18.3.1: react-is@18.3.1:
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
@ -2390,8 +2390,8 @@ packages:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'} engines: {node: '>=8'}
sonner@1.4.41: sonner@1.5.0:
resolution: {integrity: sha512-uG511ggnnsw6gcn/X+YKkWPo5ep9il9wYi3QJxHsYe7yTZ4+cOd1wuodOUmOpFuXL+/RE3R04LczdNCDygTDgQ==} resolution: {integrity: sha512-FBjhG/gnnbN6FY0jaNnqZOMmB73R+5IiyYAw8yBj7L54ER7HB3fOSE5OFiQiE2iXWxeXKvg6fIP4LtVppHEdJA==}
peerDependencies: peerDependencies:
react: ^18.0.0 react: ^18.0.0
react-dom: ^18.0.0 react-dom: ^18.0.0
@ -2610,8 +2610,8 @@ packages:
yallist@3.1.1: yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
yaml@2.4.3: yaml@2.4.5:
resolution: {integrity: sha512-sntgmxj8o7DE7g/Qi60cqpLBA3HG3STcDA0kO+WfB05jEKhZMbY7umNm2rBpQvsmZ16/lPXCJGW2672dgOUkrg==} resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==}
engines: {node: '>= 14'} engines: {node: '>= 14'}
hasBin: true hasBin: true
@ -2904,9 +2904,9 @@ snapshots:
'@fontsource-variable/kode-mono@5.0.3': {} '@fontsource-variable/kode-mono@5.0.3': {}
'@hookform/resolvers@3.6.0(react-hook-form@7.51.5(react@18.3.1))': '@hookform/resolvers@3.6.0(react-hook-form@7.52.0(react@18.3.1))':
dependencies: dependencies:
react-hook-form: 7.51.5(react@18.3.1) react-hook-form: 7.52.0(react@18.3.1)
'@isaacs/cliui@8.0.2': '@isaacs/cliui@8.0.2':
dependencies: dependencies:
@ -3106,33 +3106,33 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2 '@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/sourcemap-codec': 1.4.15
'@next/env@14.2.3': {} '@next/env@14.2.4': {}
'@next/swc-darwin-arm64@14.2.3': '@next/swc-darwin-arm64@14.2.4':
optional: true optional: true
'@next/swc-darwin-x64@14.2.3': '@next/swc-darwin-x64@14.2.4':
optional: true optional: true
'@next/swc-linux-arm64-gnu@14.2.3': '@next/swc-linux-arm64-gnu@14.2.4':
optional: true optional: true
'@next/swc-linux-arm64-musl@14.2.3': '@next/swc-linux-arm64-musl@14.2.4':
optional: true optional: true
'@next/swc-linux-x64-gnu@14.2.3': '@next/swc-linux-x64-gnu@14.2.4':
optional: true optional: true
'@next/swc-linux-x64-musl@14.2.3': '@next/swc-linux-x64-musl@14.2.4':
optional: true optional: true
'@next/swc-win32-arm64-msvc@14.2.3': '@next/swc-win32-arm64-msvc@14.2.4':
optional: true optional: true
'@next/swc-win32-ia32-msvc@14.2.3': '@next/swc-win32-ia32-msvc@14.2.4':
optional: true optional: true
'@next/swc-win32-x64-msvc@14.2.3': '@next/swc-win32-x64-msvc@14.2.4':
optional: true optional: true
'@nodelib/fs.scandir@2.1.5': '@nodelib/fs.scandir@2.1.5':
@ -4060,8 +4060,8 @@ snapshots:
browserslist@4.23.1: browserslist@4.23.1:
dependencies: dependencies:
caniuse-lite: 1.0.30001629 caniuse-lite: 1.0.30001636
electron-to-chromium: 1.4.796 electron-to-chromium: 1.4.803
node-releases: 2.0.14 node-releases: 2.0.14
update-browserslist-db: 1.0.16(browserslist@4.23.1) update-browserslist-db: 1.0.16(browserslist@4.23.1)
@ -4083,7 +4083,7 @@ snapshots:
camelcase@6.3.0: {} camelcase@6.3.0: {}
caniuse-lite@1.0.30001629: {} caniuse-lite@1.0.30001636: {}
chalk@2.4.2: chalk@2.4.2:
dependencies: dependencies:
@ -4215,19 +4215,19 @@ snapshots:
eastasianwidth@0.2.0: {} eastasianwidth@0.2.0: {}
electron-to-chromium@1.4.796: {} electron-to-chromium@1.4.803: {}
embla-carousel-react@8.1.3(react@18.3.1): embla-carousel-react@8.1.5(react@18.3.1):
dependencies: dependencies:
embla-carousel: 8.1.3 embla-carousel: 8.1.5
embla-carousel-reactive-utils: 8.1.3(embla-carousel@8.1.3) embla-carousel-reactive-utils: 8.1.5(embla-carousel@8.1.5)
react: 18.3.1 react: 18.3.1
embla-carousel-reactive-utils@8.1.3(embla-carousel@8.1.3): embla-carousel-reactive-utils@8.1.5(embla-carousel@8.1.5):
dependencies: dependencies:
embla-carousel: 8.1.3 embla-carousel: 8.1.5
embla-carousel@8.1.3: {} embla-carousel@8.1.5: {}
emittery@0.13.1: {} emittery@0.13.1: {}
@ -4300,7 +4300,7 @@ snapshots:
follow-redirects@1.15.6: {} follow-redirects@1.15.6: {}
foreground-child@3.1.1: foreground-child@3.2.1:
dependencies: dependencies:
cross-spawn: 7.0.3 cross-spawn: 7.0.3
signal-exit: 4.1.0 signal-exit: 4.1.0
@ -4345,7 +4345,7 @@ snapshots:
glob@10.4.1: glob@10.4.1:
dependencies: dependencies:
foreground-child: 3.1.1 foreground-child: 3.2.1
jackspeak: 3.4.0 jackspeak: 3.4.0
minimatch: 9.0.4 minimatch: 9.0.4
minipass: 7.1.2 minipass: 7.1.2
@ -4780,7 +4780,7 @@ snapshots:
- supports-color - supports-color
- ts-node - ts-node
jiti@1.21.3: {} jiti@1.21.6: {}
js-tokens@4.0.0: {} js-tokens@4.0.0: {}
@ -4799,13 +4799,13 @@ snapshots:
leven@3.1.0: {} leven@3.1.0: {}
lightweight-charts@4.1.4: lightweight-charts@4.1.5:
dependencies: dependencies:
fancy-canvas: 2.1.0 fancy-canvas: 2.1.0
lilconfig@2.1.0: {} lilconfig@2.1.0: {}
lilconfig@3.1.1: {} lilconfig@3.1.2: {}
lines-and-columns@1.2.4: {} lines-and-columns@1.2.4: {}
@ -4823,7 +4823,7 @@ snapshots:
dependencies: dependencies:
yallist: 3.1.1 yallist: 3.1.1
lucide-react@0.387.0(react@18.3.1): lucide-react@0.395.0(react@18.3.1):
dependencies: dependencies:
react: 18.3.1 react: 18.3.1
@ -4879,27 +4879,27 @@ snapshots:
react: 18.3.1 react: 18.3.1
react-dom: 18.3.1(react@18.3.1) react-dom: 18.3.1(react@18.3.1)
next@14.2.3(@babel/core@7.24.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): next@14.2.4(@babel/core@7.24.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies: dependencies:
'@next/env': 14.2.3 '@next/env': 14.2.4
'@swc/helpers': 0.5.5 '@swc/helpers': 0.5.5
busboy: 1.6.0 busboy: 1.6.0
caniuse-lite: 1.0.30001629 caniuse-lite: 1.0.30001636
graceful-fs: 4.2.11 graceful-fs: 4.2.11
postcss: 8.4.31 postcss: 8.4.31
react: 18.3.1 react: 18.3.1
react-dom: 18.3.1(react@18.3.1) react-dom: 18.3.1(react@18.3.1)
styled-jsx: 5.1.1(@babel/core@7.24.7)(react@18.3.1) styled-jsx: 5.1.1(@babel/core@7.24.7)(react@18.3.1)
optionalDependencies: optionalDependencies:
'@next/swc-darwin-arm64': 14.2.3 '@next/swc-darwin-arm64': 14.2.4
'@next/swc-darwin-x64': 14.2.3 '@next/swc-darwin-x64': 14.2.4
'@next/swc-linux-arm64-gnu': 14.2.3 '@next/swc-linux-arm64-gnu': 14.2.4
'@next/swc-linux-arm64-musl': 14.2.3 '@next/swc-linux-arm64-musl': 14.2.4
'@next/swc-linux-x64-gnu': 14.2.3 '@next/swc-linux-x64-gnu': 14.2.4
'@next/swc-linux-x64-musl': 14.2.3 '@next/swc-linux-x64-musl': 14.2.4
'@next/swc-win32-arm64-msvc': 14.2.3 '@next/swc-win32-arm64-msvc': 14.2.4
'@next/swc-win32-ia32-msvc': 14.2.3 '@next/swc-win32-ia32-msvc': 14.2.4
'@next/swc-win32-x64-msvc': 14.2.3 '@next/swc-win32-x64-msvc': 14.2.4
transitivePeerDependencies: transitivePeerDependencies:
- '@babel/core' - '@babel/core'
- babel-plugin-macros - babel-plugin-macros
@ -4986,8 +4986,8 @@ snapshots:
postcss-load-config@4.0.2(postcss@8.4.38): postcss-load-config@4.0.2(postcss@8.4.38):
dependencies: dependencies:
lilconfig: 3.1.1 lilconfig: 3.1.2
yaml: 2.4.3 yaml: 2.4.5
optionalDependencies: optionalDependencies:
postcss: 8.4.38 postcss: 8.4.38
@ -5043,7 +5043,7 @@ snapshots:
react: 18.3.1 react: 18.3.1
scheduler: 0.23.2 scheduler: 0.23.2
react-hook-form@7.51.5(react@18.3.1): react-hook-form@7.52.0(react@18.3.1):
dependencies: dependencies:
react: 18.3.1 react: 18.3.1
@ -5140,7 +5140,7 @@ snapshots:
slash@3.0.0: {} slash@3.0.0: {}
sonner@1.4.41(react-dom@18.3.1(react@18.3.1))(react@18.3.1): sonner@1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies: dependencies:
react: 18.3.1 react: 18.3.1
react-dom: 18.3.1(react@18.3.1) react-dom: 18.3.1(react@18.3.1)
@ -5242,7 +5242,7 @@ snapshots:
fast-glob: 3.3.2 fast-glob: 3.3.2
glob-parent: 6.0.2 glob-parent: 6.0.2
is-glob: 4.0.3 is-glob: 4.0.3
jiti: 1.21.3 jiti: 1.21.6
lilconfig: 2.1.0 lilconfig: 2.1.0
micromatch: 4.0.7 micromatch: 4.0.7
normalize-path: 3.0.0 normalize-path: 3.0.0
@ -5362,7 +5362,7 @@ snapshots:
yallist@3.1.1: {} yallist@3.1.1: {}
yaml@2.4.3: {} yaml@2.4.5: {}
yargs-parser@21.1.1: {} yargs-parser@21.1.1: {}

10
src/app/auth/page.tsx Normal file
View File

@ -0,0 +1,10 @@
import { AuthForms } from "@/components/auth-form";
import Image from "next/image";
export default function AuthPage() {
return (
<main className="flex flex-col items-center justify-start h-full w-full">
<AuthForms />
</main>
);
}

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -7,6 +7,7 @@ import { PrimaryNavigationMenu } from "@/components/primary-nav";
import { Providers } from "@/components/providers/providers"; import { Providers } from "@/components/providers/providers";
import { ThemeProvider } from "@/components/providers/theme-provider"; import { ThemeProvider } from "@/components/providers/theme-provider";
import type React from "react"; import type React from "react";
import {Toaster} from "@/components/ui/toaster";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "YeloBit", title: "YeloBit",
@ -22,7 +23,7 @@ export default function RootLayout({
return ( return (
<html lang="en"> <html lang="en">
<head> <head>
<link rel="icon" href="/public/favicon.ico" sizes="any" /> <link rel="icon" href="/favicon.ico" sizes="any" />
</head> </head>
<body className={"w-full min-h-screen flex flex-col items-center justify-between"}> <body className={"w-full min-h-screen flex flex-col items-center justify-between"}>
<Providers> <Providers>
@ -30,6 +31,7 @@ export default function RootLayout({
<PrimaryNavigationMenu /> <PrimaryNavigationMenu />
</Header> </Header>
{children} {children}
<Toaster />
<Footer /> <Footer />
</Providers> </Providers>
</body> </body>

View File

@ -4,27 +4,29 @@ import { AccountInfo } from "@/components/account-info";
import { UserDataContext } from "@/components/providers/userdata-provider"; import { UserDataContext } from "@/components/providers/userdata-provider";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import type { IUserData } from "@/interfaces/userdata.interface"; import type { IUserData } from "@/interfaces/userdata.interface";
import {Dispatch, SetStateAction, useContext, useEffect, useState} from "react"; import {
type Dispatch,
type SetStateAction,
useContext,
useEffect,
useState,
} from "react";
const localStorage = typeof window !== "undefined" ? window.localStorage : null;
export function AccountDialog() { export function AccountDialog() {
const userContext = useContext(UserDataContext); const userContext = useContext(UserDataContext);
const token = localStorage?.getItem("sub") || "";
const haveToken = token.length >= 16 || false;
console.log(haveToken);
const [isLoaded, setIsLoaded] = useState<boolean>(false); const [isLoaded, setIsLoaded] = useState<boolean>(false);
if (!userContext?.userData) { if (!userContext) {
userContext?.setUserData({ return (
age: 0, <div>
city: "Chambéry", <p>No account</p>
created_at: "jaj", </div>
dollarAvailables: 34, );
email: "mherriot@tutanota.com",
id: "",
isActive: false,
lastName: "Herriot",
pseudo: "Avnyr",
roleId: "",
updated_at: "",
firstName: "Mathis",
});
} }
useEffect(() => { useEffect(() => {
@ -39,7 +41,13 @@ export function AccountDialog() {
return ( return (
<div> <div>
<AccountInfo userData={userContext?.userData as IUserData} setUserData={userContext?.setUserData as Dispatch<SetStateAction<IUserData | undefined>>} /> <AccountInfo
userData={userContext?.userData as IUserData}
setUserData={
userContext?.setUserData as Dispatch<SetStateAction<IUserData | undefined>>
}
isDisconnected={!haveToken}
/>
</div> </div>
); );
} }

View File

@ -13,16 +13,46 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import type { IUserData } from "@/interfaces/userdata.interface"; import type { IUserData } from "@/interfaces/userdata.interface";
import { Landmark, Unplug, User, Wallet } from "lucide-react"; import { CopyButton } from "@/components/ui/copy-button";
import { doDisconnect } from "@/services/account.handler";
import { Bitcoin, Fingerprint, Key, Landmark, Unplug, User, Wallet } from "lucide-react";
import Link from "next/link";
import type React from "react"; import type React from "react";
export function AccountInfo({ export function AccountInfo({
userData, userData,
setUserData, setUserData,
isDisconnected,
}: { }: {
userData: IUserData; userData: IUserData;
setUserData: React.Dispatch<React.SetStateAction<IUserData | undefined>>; setUserData: React.Dispatch<React.SetStateAction<IUserData | undefined>>;
isDisconnected: boolean;
}) { }) {
if (isDisconnected) {
return (
<div className={"flex flex-col justify-center items-center h-10 p-2 text-xs mt-2"}>
<div
className={
"flex flex-row justify-center items-center gap-1 text-destructive to-red-900 animate-pulse"
}
>
<Unplug className={"w-4"} />
<p>Disconnected</p>
</div>
<div>
<Link
href={"/auth"}
className={
"hover:text-primary flex justify-evenly items-center gap-1 p-1 text-nowrap"
}
>
<Key className={"w-3"} /> Link account
</Link>
</div>
</div>
);
}
return ( return (
<Dialog> <Dialog>
<DialogTrigger asChild> <DialogTrigger asChild>
@ -37,12 +67,49 @@ export function AccountInfo({
<DialogDescription>{userData.city}</DialogDescription> <DialogDescription>{userData.city}</DialogDescription>
</DialogHeader> </DialogHeader>
<div className={"flex flex-col items-center justify-center w-full"}> <div className={"flex flex-col items-center justify-center w-full"}>
<div className={"flex flex-row justify-evenly items-center"}> <div className={"flex flex-col justify-evenly items-center gap-2"}>
<div className={"flex flex-row gap-1 justify-center items-center mx-auto"}> <div
<Landmark /> className={
<p>{userData.dollarAvailables} $</p> "flex flex-col md:flex-row gap-2 justify-center md:justify-evenly items-start md:items-center w-full"
}
>
<div
className={
"flex gap-1 justify-start md:justify-center items-center mx-auto w-full md:w-fit"
}
>
<Landmark />
<p className={"rounded bg-accent text-accent-foreground p-1"}>
{userData.dollarAvailables} $
</p>
</div>
<div
className={
"flex gap-1 justify-start md:justify-center items-center mx-auto w-full md:w-fit"
}
>
<Bitcoin />
<p className={"rounded bg-accent text-accent-foreground p-1"}>
You dont have cryptos.
</p>
</div>
</div>
<div
className={"flex flex-col gap-3 justify-center items-start mx-auto mt-4"}
>
<div className={"flex flex-row text-nowrap flex-nowrap gap-1 text-primary"}>
<Fingerprint />
<h2>Your identity</h2>
</div>
<div
className={
"font-light text-xs md:text-sm flex flex-row items-center justify-start gap-1 bg-accent p-2 rounded"
}
>
<p>{userData.id}</p>
<CopyButton value={userData.id} />
</div>
</div> </div>
<div></div>
</div> </div>
</div> </div>
<DialogFooter> <DialogFooter>
@ -50,7 +117,11 @@ export function AccountInfo({
<Wallet /> <Wallet />
<p>My wallet</p> <p>My wallet</p>
</Button> </Button>
<Button variant={"destructive"} className={"gap-2 px-2"}> <Button
variant={"destructive"}
className={"gap-2 px-2"}
onClick={() => doDisconnect()}
>
<Unplug /> <Unplug />
<p>Disconnect</p> <p>Disconnect</p>
</Button> </Button>

View File

@ -0,0 +1,235 @@
"use client";
import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs";
import AutoForm, {AutoFormSubmit} from "@/components/auto-form";
import {UserDataContext} from "@/components/providers/userdata-provider";
import type {IApiLoginReq, IApiLoginRes, IApiRegisterReq, IApiRegisterRes} from "@/interfaces/api.interface";
import type {IUserData} from "@/interfaces/userdata.interface";
import ApiRequest from "@/services/apiRequest";
import {EReturnState, type IStandardisedReturn} from "@/services/general.interface";
import {useLocalStorage} from "@/services/localStorage";
import {Bug, RefreshCw} from "lucide-react";
import Link from "next/link";
import {type Dispatch, type SetStateAction, useContext, useState} from "react";
import * as z from "zod";
import {ToastBox, toastType} from "@/components/ui/toast-box";
import {useToast} from "@/components/ui/use-toast";
const loginSchema = z.object({
email: z
.string({
required_error: "Email is needed.",
})
.email({
message: "Should be a valid email.",
})
.describe("Your account email."),
password: z
.string({
required_error: "Password is needed.",
})
.describe("Your account password."),
});
const registerSchema = z.object({
firstName: z.string({
required_error: "",
}),
lastName: z.string(),
age: z.number().min(18).max(120),
pseudo: z.string({
required_error: "",
}),
city: z.string({
required_error: "",
}),
email: z
.string({
required_error: "Email is needed.",
})
.email("Should be a valid email."),
password: z
.string({
required_error: "Password is needed.",
})
.describe("Your account password."),
});
export function AuthForms() {
const [isLoading, setIsLoading] = useState(false);
const [sub, setSub] = useLocalStorage<string | undefined>("sub", "");
const userContext = useContext(UserDataContext);
const { toast } = useToast()
async function doRegister(
registerData: IApiRegisterReq,
userDataSetter: Dispatch<SetStateAction<IUserData | null>>,
): Promise<IStandardisedReturn<IApiRegisterRes>> {
console.trace(registerData);
try {
const ReqRes = await ApiRequest.standard.post.json<
IApiRegisterReq,
IApiRegisterRes
>("auth/signup", registerData);
console.trace(ReqRes.data);
if (ReqRes.data.user) {
userDataSetter(ReqRes.data.user);
setSub(ReqRes.data.access_token);
}
console.debug(ReqRes.data.message || "Not additional message from request");
return {
state: EReturnState.done,
resolved: ReqRes.data,
};
} catch (error) {
console.error("Error during registration:", error);
return {
state: EReturnState.serverError,
message: error as string,
};
}
}
async function doLogin(
loginData: IApiLoginReq,
): Promise<IStandardisedReturn<IApiLoginRes>> {
try {
const ReqRes = await ApiRequest.standard.post.json<IApiLoginReq, IApiLoginRes>(
"auth/signin",
loginData,
);
console.trace(ReqRes.data);
if (ReqRes.data.access_token) {
setSub(ReqRes.data.access_token);
}
return {
state: EReturnState.done,
};
} catch (err) {
console.error("Error during login:", err);
return {
state: EReturnState.serverError,
message: err as string,
};
}
}
if (!userContext || !userContext.setUserData) {
return (
<div
className={
"bg-destructive text-destructive-foreground p-3 gap-2 border rounded flex flex-row justify-center items-center"
}
>
<Bug />
<p>It seems that the context is missing..</p>
</div>
);
}
return (
<Tabs defaultValue="login" className="w-full p-2 md:w-[400px] my-4">
<TabsList className="grid w-full grid-cols-2">
<TabsTrigger value="login">Login</TabsTrigger>
<TabsTrigger value="register">Register</TabsTrigger>
</TabsList>
<TabsContent value="login">
<AutoForm
// Pass the schema to the form
formSchema={loginSchema}
onSubmit={(data: IApiLoginReq) => {
setIsLoading(true);
doLogin(data).then((res) => {
if (res.state !== EReturnState.done) {
toast({
description: res.message || "An unexpected error occurred..",
variant: "destructive",
})
setIsLoading(false)
return
}
//toast.custom(<ToastBox message={"Login successful ! \n You will be redirected."} type={toastType.success}/>)
toast({
description: "Login successful ! \n You will be redirected."
})
setTimeout(()=>{
setIsLoading(false)
location.href = "/"
console.log('Moving to home.')
}, 3_000)
});
}}
fieldConfig={{
password: {
inputProps: {
type: "password",
placeholder: "••••••••",
},
},
}}
>
<AutoFormSubmit
disabled={!!isLoading}
className={"gap-2 disabled:bg-secondary"}
>
{/* biome-ignore lint/style/useTemplate: <explanation> */}
<RefreshCw className={"animate-spin" + isLoading && "hidden"} />
<p>Login</p>
</AutoFormSubmit>
</AutoForm>
</TabsContent>
<TabsContent value="register">
<AutoForm
// Pass the schema to the form
formSchema={registerSchema}
onSubmit={(data: IApiRegisterReq) => {
setIsLoading(true);
doRegister(
data,
userContext.setUserData as Dispatch<SetStateAction<IUserData | null>>,
).then((res) => {
if (res.state !== EReturnState.done) {
//toast.custom(<ToastBox message={res.message || "An unexpected error occurred.."} type={toastType.error}/>)
setIsLoading(false)
return
}
//toast.custom(<ToastBox message={"Register successful ! \n You will be redirected."} type={toastType.success}/>)
setTimeout(()=>{
setIsLoading(false)
//location.href = "/"
console.log('Moving to home.')
}, 5_000)
});
}}
fieldConfig={{
password: {
inputProps: {
type: "password",
placeholder: "••••••••",
},
},
}}
>
<AutoFormSubmit
disabled={!!isLoading}
className={"gap-2 disabled:bg-secondary"}
>
{/* biome-ignore lint/style/useTemplate: <explanation> */}
<RefreshCw className={"animate-spin" + !isLoading && "hidden"} />
<p>Register</p>
</AutoFormSubmit>
<p className="text-gray-500 text-sm">
By submitting this form, you agree to our{" "}
<Link href="#" className="text-primary underline">
terms and conditions
</Link>
.
</p>
</AutoForm>
</TabsContent>
</Tabs>
);
}

View File

@ -98,7 +98,7 @@ function AutoForm<SchemaType extends ZodObjectOrWrapped>({
onSubmit={(e) => { onSubmit={(e) => {
form.handleSubmit(onSubmit)(e); form.handleSubmit(onSubmit)(e);
}} }}
className={cn("space-y-5", className)} className={cn("space-y-5 w-full", className)}
> >
<AutoFormObject <AutoFormObject
schema={objectFormSchema} schema={objectFormSchema}

View File

@ -5,7 +5,7 @@ export function Footer() {
return ( return (
<footer <footer
className={ className={
"flex flex-col-reverse md:flex-row justify-between gap-2 md:gap-1 items-center p-2 border-t-2 w-full" "flex flex-col-reverse md:flex-row justify-between gap-2 md:gap-1 self-end order-6 items-center p-2 border-t-2 w-full"
} }
> >
<div <div
@ -49,11 +49,7 @@ export function Footer() {
<h3 className={"text-nowrap text-center"}>Support Center</h3> <h3 className={"text-nowrap text-center"}>Support Center</h3>
</Link> </Link>
</div> </div>
<div <div/>
className={
"flex flex-row gap-1 items-center justify-center md:justify-end md:w-1/3"
}
></div>
</footer> </footer>
); );
} }

View File

@ -23,9 +23,15 @@ export function Header({
{title || "YeloBit"} {title || "YeloBit"}
</h1> </h1>
</div> </div>
<div className={"w-1/3 flex flex-row justify-center items-center"}>{children}</div>
<div <div
className={"w-1/3 flex flex-row justify-center md:justify-end gap-2 items-center"} className={"w-1/3 flex flex-col md:flex-row w-full justify-center items-center"}
>
{children}
</div>
<div
className={
"w-1/3 flex flex-row justify-center md:justify-end w-full md:w-fit gap-2 items-center"
}
> >
<AccountDialog /> <AccountDialog />
<ThemeBtnSelector /> <ThemeBtnSelector />

View File

@ -10,7 +10,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
<input <input
type={type} type={type}
className={cn( 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 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", "flex h-10 w-full rounded-md border border-input bg-accent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium 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, className,
)} )}
ref={ref} ref={ref}

View File

@ -21,7 +21,7 @@ export interface IApiLoginReq {
// ----- Response ----- // ----- Response -----
export interface IAbstractApiResponse { export interface IAbstractApiResponse {
message?: Array<string>; message?: Array<string> | string;
error?: string; error?: string;
statusCode?: number; statusCode?: number;
} }

View File

@ -1,5 +1,5 @@
import { import {
ICryptoInUserWalletInfo, type ICryptoInUserWalletInfo,
type ICryptoInWalletInfo, type ICryptoInWalletInfo,
IUserWalletCryptos, IUserWalletCryptos,
} from "@/interfaces/crypto.interface"; } from "@/interfaces/crypto.interface";

View File

@ -8,60 +8,16 @@ import type {
} from "@/interfaces/api.interface"; } from "@/interfaces/api.interface";
import type { IUserData } from "@/interfaces/userdata.interface"; import type { IUserData } from "@/interfaces/userdata.interface";
import ApiRequest from "@/services/apiRequest"; import ApiRequest from "@/services/apiRequest";
import { useEncodedLocalStorage } from "@/services/localStorage"; import { EReturnState, IStandardisedReturn } from "@/services/general.interface";
import { createContext, useContext, useState } from "react"; import { useLocalStorage } from "@/services/localStorage";
import type { Dispatch, SetStateAction } from "react";
const UserDataContext = createContext<IUserData | null>(null);
const [userData, setUserData] = useEncodedLocalStorage<IUserData | null>(
"user_data",
null,
);
//TODO Run register task
export async function doRegister(
registerData: IApiRegisterReq,
): Promise<IApiRegisterRes | null> {
console.trace(registerData);
try {
const ReqRes = await ApiRequest.standard.post.json<IApiRegisterReq, IApiRegisterRes>(
"auth/signup",
registerData,
);
console.trace(ReqRes.data);
if (ReqRes.data.user) {
setUserData(ReqRes.data.user);
}
ReqRes.data.message?.forEach((err) => console.warn(err));
return ReqRes.data;
} catch (error) {
console.error("Error during registration:", error);
return null;
}
}
//TODO Run login task
export async function doLogin(loginData: IApiLoginReq) {
try {
const ReqRes = await ApiRequest.standard.post.json<IApiLoginReq, IApiLoginRes>(
"auth/login",
loginData,
);
console.trace(ReqRes.data);
//if (ReqRes.data.user) {
// setUserData(ReqRes.data.user)
//}
ReqRes.data.message?.forEach((err) => console.warn(err));
return ReqRes.data;
} catch (err) {
console.error("Error during login:", err);
return null;
}
}
//TODO Run disconnect task //TODO Run disconnect task
export function doDisconnect() { export function doDisconnect() {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
window.localStorage.removeItem("sub"); window.localStorage.removeItem("sub");
//Redirect to homepage
window.location.href = "/";
return true; return true;
} }
console.log( console.log(

View File

@ -0,0 +1,13 @@
export interface IStandardisedReturn<T> {
state: EReturnState;
message?: string;
resolved?: T;
}
export enum EReturnState {
unauthorized = 0,
clientError = 1,
serverError = 2,
done = 3,
queued = 4,
}