Compare commits

..

No commits in common. "e2e13129eda4f990c639f5000548979dddab9e34" and "a76b68730ba04e48e26407a27f77c2c42845cc4c" have entirely different histories.

20 changed files with 33 additions and 652 deletions

View File

@ -14,12 +14,10 @@
"@radix-ui/react-collapsible": "^1.1.8", "@radix-ui/react-collapsible": "^1.1.8",
"@radix-ui/react-dialog": "^1.1.11", "@radix-ui/react-dialog": "^1.1.11",
"@radix-ui/react-dropdown-menu": "^2.1.11", "@radix-ui/react-dropdown-menu": "^2.1.11",
"@radix-ui/react-label": "^2.1.4",
"@radix-ui/react-navigation-menu": "^1.2.10", "@radix-ui/react-navigation-menu": "^1.2.10",
"@radix-ui/react-select": "^2.2.2", "@radix-ui/react-select": "^2.2.2",
"@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-slot": "^1.2.0",
"@radix-ui/react-tabs": "^1.1.8", "@radix-ui/react-tabs": "^1.1.8",
"@radix-ui/react-toast": "^1.2.11",
"@reduxjs/toolkit": "^2.7.0", "@reduxjs/toolkit": "^2.7.0",
"aos": "^2.3.4", "aos": "^2.3.4",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
@ -31,9 +29,7 @@
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-hook-form": "^7.56.1",
"react-redux": "^9.2.0", "react-redux": "^9.2.0",
"sonner": "^2.0.3",
"tailwind-merge": "^3.2.0", "tailwind-merge": "^3.2.0",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"tw-animate-css": "^1.2.6", "tw-animate-css": "^1.2.6",

90
pnpm-lock.yaml generated
View File

@ -10,7 +10,7 @@ importers:
dependencies: dependencies:
'@hookform/resolvers': '@hookform/resolvers':
specifier: ^5.0.1 specifier: ^5.0.1
version: 5.0.1(react-hook-form@7.56.1(react@19.1.0)) version: 5.0.1(react-hook-form@7.56.0(react@19.1.0))
'@radix-ui/react-collapsible': '@radix-ui/react-collapsible':
specifier: ^1.1.8 specifier: ^1.1.8
version: 1.1.8(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) version: 1.1.8(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@ -20,9 +20,6 @@ importers:
'@radix-ui/react-dropdown-menu': '@radix-ui/react-dropdown-menu':
specifier: ^2.1.11 specifier: ^2.1.11
version: 2.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) version: 2.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-label':
specifier: ^2.1.4
version: 2.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-navigation-menu': '@radix-ui/react-navigation-menu':
specifier: ^1.2.10 specifier: ^1.2.10
version: 1.2.10(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) version: 1.2.10(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@ -35,9 +32,6 @@ importers:
'@radix-ui/react-tabs': '@radix-ui/react-tabs':
specifier: ^1.1.8 specifier: ^1.1.8
version: 1.1.8(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) version: 1.1.8(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-toast':
specifier: ^1.2.11
version: 1.2.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@reduxjs/toolkit': '@reduxjs/toolkit':
specifier: ^2.7.0 specifier: ^2.7.0
version: 2.7.0(react-redux@9.2.0(@types/react@19.1.2)(react@19.1.0)(redux@5.0.1))(react@19.1.0) version: 2.7.0(react-redux@9.2.0(@types/react@19.1.2)(react@19.1.0)(redux@5.0.1))(react@19.1.0)
@ -71,15 +65,9 @@ importers:
react-dom: react-dom:
specifier: ^19.0.0 specifier: ^19.0.0
version: 19.1.0(react@19.1.0) version: 19.1.0(react@19.1.0)
react-hook-form:
specifier: ^7.56.1
version: 7.56.1(react@19.1.0)
react-redux: react-redux:
specifier: ^9.2.0 specifier: ^9.2.0
version: 9.2.0(@types/react@19.1.2)(react@19.1.0)(redux@5.0.1) version: 9.2.0(@types/react@19.1.2)(react@19.1.0)(redux@5.0.1)
sonner:
specifier: ^2.0.3
version: 2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
tailwind-merge: tailwind-merge:
specifier: ^3.2.0 specifier: ^3.2.0
version: 3.2.0 version: 3.2.0
@ -642,19 +630,6 @@ packages:
'@types/react': '@types/react':
optional: true optional: true
'@radix-ui/react-label@2.1.4':
resolution: {integrity: sha512-wy3dqizZnZVV4ja0FNnUhIWNwWdoldXrneEyUcVtLYDAt8ovGS4ridtMAOGgXBBIfggL4BOveVWsjXDORdGEQg==}
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
'@radix-ui/react-menu@2.1.11': '@radix-ui/react-menu@2.1.11':
resolution: {integrity: sha512-sbFI4Qaw02J0ogmR9tOMsSqsdrGNpUanlPYAqTE2JJafow8ecHtykg4fSTjNHBdDl4deiKMK+RhTEwyVhP7UDA==} resolution: {integrity: sha512-sbFI4Qaw02J0ogmR9tOMsSqsdrGNpUanlPYAqTE2JJafow8ecHtykg4fSTjNHBdDl4deiKMK+RhTEwyVhP7UDA==}
peerDependencies: peerDependencies:
@ -794,19 +769,6 @@ packages:
'@types/react-dom': '@types/react-dom':
optional: true optional: true
'@radix-ui/react-toast@1.2.11':
resolution: {integrity: sha512-Ed2mlOmT+tktOsu2NZBK1bCSHh/uqULu1vWOkpQTVq53EoOuZUZw7FInQoDB3uil5wZc2oe0XN9a7uVZB7/6AQ==}
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
'@radix-ui/react-use-callback-ref@1.1.1': '@radix-ui/react-use-callback-ref@1.1.1':
resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==}
peerDependencies: peerDependencies:
@ -2266,8 +2228,8 @@ packages:
peerDependencies: peerDependencies:
react: ^19.1.0 react: ^19.1.0
react-hook-form@7.56.1: react-hook-form@7.56.0:
resolution: {integrity: sha512-qWAVokhSpshhcEuQDSANHx3jiAEFzu2HAaaQIzi/r9FNPm1ioAvuJSD4EuZzWd7Al7nTRKcKPnBKO7sRn+zavQ==} resolution: {integrity: sha512-U2QQgx5z2Y8Z0qlXv3W19hWHJgfKdWMz0O/osuY+o+CYq568V2R/JhzC6OAXfR8k24rIN0Muan2Qliaq9eKs/g==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17 || ^18 || ^19 react: ^16.8.0 || ^17 || ^18 || ^19
@ -2430,12 +2392,6 @@ packages:
simple-swizzle@0.2.2: simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
sonner@2.0.3:
resolution: {integrity: sha512-njQ4Hht92m0sMqqHVDL32V2Oun9W1+PHO9NDv9FHfJjT3JT22IG4Jpo3FPQy+mouRKCXFWO+r67v6MrHX2zeIA==}
peerDependencies:
react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
source-map-js@1.2.1: source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -2765,10 +2721,10 @@ snapshots:
'@floating-ui/utils@0.2.9': {} '@floating-ui/utils@0.2.9': {}
'@hookform/resolvers@5.0.1(react-hook-form@7.56.1(react@19.1.0))': '@hookform/resolvers@5.0.1(react-hook-form@7.56.0(react@19.1.0))':
dependencies: dependencies:
'@standard-schema/utils': 0.3.0 '@standard-schema/utils': 0.3.0
react-hook-form: 7.56.1(react@19.1.0) react-hook-form: 7.56.0(react@19.1.0)
'@humanfs/core@0.19.1': {} '@humanfs/core@0.19.1': {}
@ -3064,15 +3020,6 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/react': 19.1.2 '@types/react': 19.1.2
'@radix-ui/react-label@2.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
optionalDependencies:
'@types/react': 19.1.2
'@types/react-dom': 19.1.2(@types/react@19.1.2)
'@radix-ui/react-menu@2.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': '@radix-ui/react-menu@2.1.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies: dependencies:
'@radix-ui/primitive': 1.1.2 '@radix-ui/primitive': 1.1.2
@ -3247,26 +3194,6 @@ snapshots:
'@types/react': 19.1.2 '@types/react': 19.1.2
'@types/react-dom': 19.1.2(@types/react@19.1.2) '@types/react-dom': 19.1.2(@types/react@19.1.2)
'@radix-ui/react-toast@1.2.11(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@radix-ui/primitive': 1.1.2
'@radix-ui/react-collection': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-dismissable-layer': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-portal': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-primitive': 2.1.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0)
'@radix-ui/react-visually-hidden': 1.2.0(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
optionalDependencies:
'@types/react': 19.1.2
'@types/react-dom': 19.1.2(@types/react@19.1.2)
'@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.2)(react@19.1.0)': '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.2)(react@19.1.0)':
dependencies: dependencies:
react: 19.1.0 react: 19.1.0
@ -4787,7 +4714,7 @@ snapshots:
react: 19.1.0 react: 19.1.0
scheduler: 0.26.0 scheduler: 0.26.0
react-hook-form@7.56.1(react@19.1.0): react-hook-form@7.56.0(react@19.1.0):
dependencies: dependencies:
react: 19.1.0 react: 19.1.0
@ -4995,11 +4922,6 @@ snapshots:
is-arrayish: 0.3.2 is-arrayish: 0.3.2
optional: true optional: true
sonner@2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
dependencies:
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
source-map-js@1.2.1: {} source-map-js@1.2.1: {}
stable-hash@0.0.5: {} stable-hash@0.0.5: {}

1
public/file.svg Normal file
View File

@ -0,0 +1 @@
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 391 B

1
public/globe.svg Normal file
View File

@ -0,0 +1 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,44 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="150.000000pt" height="200.000000pt" viewBox="0 0 150.000000 200.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,200.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M695 1825 c-33 -36 -72 -104 -81 -141 -3 -16 10 3 29 41 55 108 107
145 107 77 1 -90 56 -208 172 -363 100 -134 131 -186 157 -260 10 -30 35 -81
55 -114 102 -167 110 -375 23 -560 -53 -111 -166 -222 -265 -261 -30 -11 -31
-13 -8 -9 86 17 213 135 274 253 98 188 92 399 -17 584 -21 37 -46 88 -55 115
-23 68 -61 131 -159 263 -100 134 -141 212 -157 301 -19 103 -34 118 -75 74z"/>
<path d="M686 1715 c-10 -20 -22 -60 -28 -89 -15 -68 5 -147 70 -279 81 -166
88 -211 48 -290 -13 -26 -20 -47 -16 -47 15 0 125 87 157 123 37 43 57 105 47
150 -3 18 -36 73 -73 122 -98 131 -139 202 -162 278 -12 37 -22 67 -24 67 -1
0 -10 -16 -19 -35z"/>
<path d="M603 1580 c0 -41 2 -58 4 -37 2 20 2 54 0 75 -2 20 -4 3 -4 -38z"/>
<path d="M610 1490 c0 -12 21 -66 57 -147 4 -10 -6 -12 -38 -9 -24 2 -35 2
-24 -1 11 -2 35 -8 53 -13 25 -7 32 -6 29 3 -3 7 -22 50 -41 97 -20 47 -36 78
-36 70z"/>
<path d="M434 1321 c-115 -41 -229 -132 -296 -235 -43 -67 -82 -182 -93 -271
-12 -109 23 -256 84 -355 36 -58 212 -230 234 -229 7 0 1 8 -13 17 -52 34
-191 179 -219 227 -189 325 -12 752 352 850 30 8 41 14 27 14 -14 0 -48 -8
-76 -18z"/>
<path d="M475 1275 c-157 -49 -276 -161 -341 -320 -26 -64 -29 -80 -28 -190 0
-104 3 -128 24 -180 l25 -60 5 70 c12 148 116 270 331 389 169 93 233 237 129
291 -34 18 -89 18 -145 0z"/>
<path d="M1005 1178 c-6 -34 -20 -55 -69 -103 -53 -53 -85 -73 -241 -150 -204
-100 -258 -132 -331 -198 -57 -51 -101 -133 -111 -203 -22 -159 136 -293 347
-294 l64 0 -44 23 c-58 29 -90 77 -90 134 0 111 80 204 255 298 228 122 313
276 256 464 -12 39 -23 71 -25 71 -3 0 -7 -19 -11 -42z"/>
<path d="M1107 965 c-5 -21 -18 -57 -29 -78 -19 -38 -18 -95 2 -82 17 11 41
105 38 152 l-3 48 -8 -40z"/>
<path d="M1136 845 c-33 -113 -104 -205 -208 -272 -128 -81 -188 -151 -188
-219 0 -63 19 -78 93 -71 47 4 71 13 114 43 100 69 176 179 208 299 15 61 19
210 6 255 -7 22 -10 18 -25 -35z"/>
<path d="M210 663 c-17 -53 -20 -80 -14 -123 l7 -55 12 60 c6 33 19 75 28 92
17 32 15 77 -4 88 -4 3 -18 -25 -29 -62z"/>
<path d="M415 211 c110 -54 365 -51 425 6 12 11 8 10 -16 -2 -78 -38 -262 -44
-364 -12 -25 8 -54 17 -65 21 -11 3 -2 -3 20 -13z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

1
public/next.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

1
public/vercel.svg Normal file
View File

@ -0,0 +1 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 128 B

1
public/window.svg Normal file
View File

@ -0,0 +1 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>

After

Width:  |  Height:  |  Size: 385 B

View File

@ -1,93 +0,0 @@
import { Building2, Fuel, User } from 'lucide-react';
import Link from 'next/link';
import { LoginForm } from '@/features/auth/login-form';
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/shared/shadcn-ui/card';
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from '@/shared/shadcn-ui/tabs';
export default function LoginPage() {
return (
<div className='flex min-h-screen flex-col'>
<main className='flex-1'>
<div className='container max-w-6xl py-16'>
<div className='mb-12 flex flex-col items-center text-center'>
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
<Fuel className='h-6 w-6 text-red-600' />
</div>
<h1 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Вход в личный кабинет
</h1>
<p className='max-w-2xl text-gray-600'>
Войдите в личный кабинет, чтобы получить доступ к информации о
ваших бонусах, истории операций и другим возможностям.
</p>
</div>
<div className='mx-auto max-w-md'>
<Tabs defaultValue='bonus' className='w-full'>
<TabsList className='mb-8 grid w-full grid-cols-2'>
<TabsTrigger value='bonus' className='text-base'>
<User className='mr-2 h-4 w-4' /> Бонусный клиент
</TabsTrigger>
<TabsTrigger value='corporate' className='text-base'>
<Building2 className='mr-2 h-4 w-4' /> Корпоративный клиент
</TabsTrigger>
</TabsList>
<TabsContent value='bonus'>
<Card>
<CardHeader>
<CardTitle>Вход для бонусных клиентов</CardTitle>
<CardDescription>
Введите номер телефона и номер бонусной карты для входа в
личный кабинет.
</CardDescription>
</CardHeader>
<CardContent className='space-y-4'>
<LoginForm />
</CardContent>
</Card>
</TabsContent>
<TabsContent value='corporate'>
<Card>
<CardHeader>
<CardTitle>Вход для корпоративных клиентов</CardTitle>
<CardDescription>
Введите номер телефона и номер корпоративной карты для
входа в личный кабинет.
</CardDescription>
</CardHeader>
<CardContent className='space-y-4'>
<LoginForm />
</CardContent>
</Card>
</TabsContent>
</Tabs>
<div className='mt-8 text-center text-sm text-gray-500'>
<p>
Возникли проблемы со входом?{' '}
<Link href='/contact' className='text-red-600 hover:underline'>
Свяжитесь с нами
</Link>
</p>
</div>
</div>
</div>
</main>
</div>
);
}

View File

@ -1 +0,0 @@
export { LoginForm } from './ui/login-form';

View File

@ -1,18 +0,0 @@
import { z } from 'zod';
export const loginFormSchema = z.object({
phoneNumber: z
.string()
.trim()
.regex(/^[0-9+\-() ]*$/, {
message:
'Phone number can only contain numbers, spaces, and the following symbols: + - ( )',
})
.refine((val) => !val || val.length >= 5, {
message:
'Phone number is too short. Please enter a complete phone number',
}),
cardNumber: z.string().min(16).trim(),
});
export type LoginFormData = z.infer<typeof loginFormSchema>;

View File

@ -1,108 +0,0 @@
'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import { useRouter } from 'next/navigation';
import { useForm } from 'react-hook-form';
import { toast } from 'sonner';
import { Button } from '@/shared/shadcn-ui/button';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/shared/shadcn-ui/form';
import { Input } from '@/shared/shadcn-ui/input';
import { LoginFormData, loginFormSchema } from '../model/login-form.schema';
interface LoginFormProps {
// onSubmit: (data: any) => Promise<void>;
}
export const LoginForm = ({}: LoginFormProps) => {
const router = useRouter();
// const [login, results] = useLoginMutation();
const form = useForm<LoginFormData>({
resolver: zodResolver(loginFormSchema),
defaultValues: {
phoneNumber: '',
cardNumber: '',
},
});
const onSubmit = async (data: LoginFormData) => {
// const response = await login(data).unwrap();
// const user = response.data;
// dispatch(
// setCredentials({
// user: {
// accessToken: user.accessToken,
// affiliateId: user.affiliateId,
// email: user.email,
// id: user.id,
// role: user.role,
// username: user.username,
// },
// }),
// );
toast.success('Logged in successfully!');
router.push('/customer-dashboard');
};
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className='space-y-4'>
<FormField
control={form.control}
name='phoneNumber'
render={({ field }) => (
<FormItem>
<FormLabel>Номер телефона</FormLabel>
<FormControl>
<Input
type='tel'
placeholder='+992 XXX XX XX XX'
{...field}
inputMode='tel'
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='cardNumber'
render={({ field }) => (
<FormItem>
<FormLabel>Номер карты</FormLabel>
<FormControl>
<Input
type='text'
placeholder='XXXX-XXXX-XXXX-XXXX'
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button
// isLoading={results.isLoading}
// title='Login'
type='submit'
className='w-full'
// variant={'default'}
// disabled={loading}
>
Войти
</Button>
</form>
</Form>
);
};

View File

@ -1,10 +1,10 @@
import Image from 'next/image'; import { Fuel } from 'lucide-react';
import Link from 'next/link'; import Link from 'next/link';
export const Logo = () => { export const Logo = () => {
return ( return (
<Link className='flex items-center gap-2' href={'/'}> <Link className='flex items-center gap-2' href={'/'}>
<Image src='/logo.svg' alt='oriyo-logo' width={24} height={24} /> <Fuel className='h-6 w-6 text-red-600' />
<span className='text-xl font-bold'>Ориё</span> <span className='text-xl font-bold'>Ориё</span>
</Link> </Link>
); );

View File

@ -5,7 +5,6 @@ import { Provider } from 'react-redux';
import { store } from '../store'; import { store } from '../store';
import { ThemeProvider } from '../theme/theme-provider'; import { ThemeProvider } from '../theme/theme-provider';
import { AosProvider } from './aos-provider'; import { AosProvider } from './aos-provider';
import { Toaster } from './toaster';
type ProvidersProps = { type ProvidersProps = {
children: React.ReactNode; children: React.ReactNode;
@ -20,10 +19,7 @@ export const Providers = ({ children }: ProvidersProps) => {
enableSystem enableSystem
disableTransitionOnChange disableTransitionOnChange
> >
<AosProvider> <AosProvider>{children}</AosProvider>
{children}
<Toaster />
</AosProvider>
</ThemeProvider> </ThemeProvider>
</Provider> </Provider>
); );

View File

@ -1,31 +0,0 @@
'use client';
import { useTheme } from 'next-themes';
import { Toaster as Sonner } from 'sonner';
type ToasterProps = React.ComponentProps<typeof Sonner>;
const Toaster = ({ ...props }: ToasterProps) => {
const { theme = 'system' } = useTheme();
return (
<Sonner
theme={theme as ToasterProps['theme']}
className='toaster group'
toastOptions={{
classNames: {
toast:
'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',
description: 'group-[.toast]:text-muted-foreground',
actionButton:
'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',
cancelButton:
'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',
},
}}
{...props}
/>
);
};
export { Toaster };

View File

@ -1,179 +0,0 @@
'use client';
import * as LabelPrimitive from '@radix-ui/react-label';
import { Slot } from '@radix-ui/react-slot';
import * as React from 'react';
import {
Controller,
type ControllerProps,
type FieldPath,
type FieldValues,
FormProvider,
useFormContext,
} from 'react-hook-form';
import { cn } from '@/shared/lib/utils';
import { Label } from '@/shared/shadcn-ui/label';
const Form = FormProvider;
type FormFieldContextValue<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
> = {
name: TName;
};
const FormFieldContext = React.createContext<FormFieldContextValue>(
{} as FormFieldContextValue,
);
const FormField = <
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
>({
...props
}: ControllerProps<TFieldValues, TName>) => {
return (
<FormFieldContext.Provider value={{ name: props.name }}>
<Controller {...props} />
</FormFieldContext.Provider>
);
};
const useFormField = () => {
const fieldContext = React.useContext(FormFieldContext);
const itemContext = React.useContext(FormItemContext);
const { getFieldState, formState } = useFormContext();
const fieldState = getFieldState(fieldContext.name, formState);
if (!fieldContext) {
throw new Error('useFormField should be used within <FormField>');
}
const { id } = itemContext;
return {
id,
name: fieldContext.name,
formItemId: `${id}-form-item`,
formDescriptionId: `${id}-form-item-description`,
formMessageId: `${id}-form-item-message`,
...fieldState,
};
};
type FormItemContextValue = {
id: string;
};
const FormItemContext = React.createContext<FormItemContextValue>(
{} as FormItemContextValue,
);
const FormItem = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
const id = React.useId();
return (
<FormItemContext.Provider value={{ id }}>
<div ref={ref} className={cn('space-y-2', className)} {...props} />
</FormItemContext.Provider>
);
});
FormItem.displayName = 'FormItem';
const FormLabel = React.forwardRef<
React.ComponentRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => {
const { error, formItemId } = useFormField();
return (
<Label
ref={ref}
className={cn(error && 'text-destructive', className)}
htmlFor={formItemId}
{...props}
/>
);
});
FormLabel.displayName = 'FormLabel';
const FormControl = React.forwardRef<
React.ComponentRef<typeof Slot>,
React.ComponentPropsWithoutRef<typeof Slot>
>(({ ...props }, ref) => {
const { error, formItemId, formDescriptionId, formMessageId } =
useFormField();
return (
<Slot
ref={ref}
id={formItemId}
aria-describedby={
!error
? `${formDescriptionId}`
: `${formDescriptionId} ${formMessageId}`
}
aria-invalid={!!error}
{...props}
/>
);
});
FormControl.displayName = 'FormControl';
const FormDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => {
const { formDescriptionId } = useFormField();
return (
<p
ref={ref}
id={formDescriptionId}
className={cn('text-muted-foreground text-sm', className)}
{...props}
/>
);
});
FormDescription.displayName = 'FormDescription';
const FormMessage = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, children, ...props }, ref) => {
const { error, formMessageId } = useFormField();
const body = error ? String(error?.message ?? '') : children;
if (!body) {
return null;
}
return (
<p
ref={ref}
id={formMessageId}
className={cn('text-destructive text-sm font-medium', className)}
{...props}
>
{body}
</p>
);
});
FormMessage.displayName = 'FormMessage';
export {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
useFormField,
};

View File

@ -1,22 +0,0 @@
import * as React from 'react';
import { cn } from '@/shared/lib/utils';
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<'input'>>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
'border-input bg-background ring-offset-background file:text-foreground placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-base file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
className,
)}
ref={ref}
{...props}
/>
);
},
);
Input.displayName = 'Input';
export { Input };

View File

@ -1,26 +0,0 @@
'use client';
import * as LabelPrimitive from '@radix-ui/react-label';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { cn } from '@/shared/lib/utils';
const labelVariants = cva(
'text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
);
const Label = React.forwardRef<
React.ComponentRef<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 };

View File

@ -1,6 +1,9 @@
'use client';
import Link from 'next/link'; import Link from 'next/link';
import React from 'react'; import React from 'react';
import { Logo } from '@/shared/assets/logo';
import { cn } from '@/shared/lib/utils'; import { cn } from '@/shared/lib/utils';
import { import {
NavigationMenu, NavigationMenu,
@ -17,22 +20,16 @@ export function DesktopNav() {
<NavigationMenu className='hidden md:flex'> <NavigationMenu className='hidden md:flex'>
<NavigationMenuList> <NavigationMenuList>
<NavigationMenuItem> <NavigationMenuItem>
<Link href='/' scroll> <Link href='/' legacyBehavior passHref>
<NavigationMenuLink <NavigationMenuLink className={navigationMenuTriggerStyle()}>
asChild Главная
className={navigationMenuTriggerStyle()}
>
<span>Главная</span>
</NavigationMenuLink> </NavigationMenuLink>
</Link> </Link>
</NavigationMenuItem> </NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuItem>
<Link href='/about' scroll> <Link href='/about' legacyBehavior passHref>
<NavigationMenuLink <NavigationMenuLink className={navigationMenuTriggerStyle()}>
asChild О нас
className={navigationMenuTriggerStyle()}
>
<span>О нас</span>
</NavigationMenuLink> </NavigationMenuLink>
</Link> </Link>
</NavigationMenuItem> </NavigationMenuItem>
@ -72,32 +69,23 @@ export function DesktopNav() {
</NavigationMenuContent> </NavigationMenuContent>
</NavigationMenuItem> </NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuItem>
<Link href='/#stations' scroll> <Link href='/#stations' legacyBehavior passHref>
<NavigationMenuLink <NavigationMenuLink className={navigationMenuTriggerStyle()}>
asChild Наши заправки
className={navigationMenuTriggerStyle()}
>
<span>Наши заправки</span>
</NavigationMenuLink> </NavigationMenuLink>
</Link> </Link>
</NavigationMenuItem> </NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuItem>
<Link href='/#vacancies' scroll={true}> <Link href='/#vacancies' legacyBehavior passHref>
<NavigationMenuLink <NavigationMenuLink className={navigationMenuTriggerStyle()}>
asChild Вакансии
className={navigationMenuTriggerStyle()}
>
<span>Вакансии</span>
</NavigationMenuLink> </NavigationMenuLink>
</Link> </Link>
</NavigationMenuItem> </NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuItem>
<Link href='/#promotions' scroll> <Link href='/#promotions' legacyBehavior passHref>
<NavigationMenuLink <NavigationMenuLink className={navigationMenuTriggerStyle()}>
asChild Акции
className={navigationMenuTriggerStyle()}
>
<span>Акции</span>
</NavigationMenuLink> </NavigationMenuLink>
</Link> </Link>
</NavigationMenuItem> </NavigationMenuItem>

View File

@ -1,5 +1,3 @@
import Link from 'next/link';
import { Logo } from '@/shared/assets/logo'; import { Logo } from '@/shared/assets/logo';
import { Button } from '@/shared/shadcn-ui/button'; import { Button } from '@/shared/shadcn-ui/button';
@ -14,9 +12,7 @@ export function Header() {
<DesktopNav /> <DesktopNav />
<div className='flex items-center gap-6 md:contents'> <div className='flex items-center gap-6 md:contents'>
<MobileNav /> <MobileNav />
<Link href={'/login'}> <Button>Вход</Button>
<Button>Вход</Button>
</Link>
</div> </div>
</div> </div>
</header> </header>