Compare commits
4 Commits
422ad9042a
...
a76b68730b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a76b68730b | ||
|
|
aa47cbbe11 | ||
|
|
b9b19c002d | ||
|
|
a9957ee471 |
@ -11,7 +11,10 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^5.0.1",
|
"@hookform/resolvers": "^5.0.1",
|
||||||
|
"@radix-ui/react-collapsible": "^1.1.8",
|
||||||
|
"@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-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",
|
||||||
|
|||||||
131
pnpm-lock.yaml
generated
131
pnpm-lock.yaml
generated
@ -11,9 +11,18 @@ importers:
|
|||||||
'@hookform/resolvers':
|
'@hookform/resolvers':
|
||||||
specifier: ^5.0.1
|
specifier: ^5.0.1
|
||||||
version: 5.0.1(react-hook-form@7.56.0(react@19.1.0))
|
version: 5.0.1(react-hook-form@7.56.0(react@19.1.0))
|
||||||
|
'@radix-ui/react-collapsible':
|
||||||
|
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)
|
||||||
|
'@radix-ui/react-dialog':
|
||||||
|
specifier: ^1.1.11
|
||||||
|
version: 1.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-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-navigation-menu':
|
||||||
|
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)
|
||||||
'@radix-ui/react-select':
|
'@radix-ui/react-select':
|
||||||
specifier: ^2.2.2
|
specifier: ^2.2.2
|
||||||
version: 2.2.2(@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.2.2(@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)
|
||||||
@ -498,6 +507,19 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-collapsible@1.1.8':
|
||||||
|
resolution: {integrity: sha512-hxEsLvK9WxIAPyxdDRULL4hcaSjMZCfP7fHB0Z1uUnDoDBat1Zh46hwYfa69DeZAbJrPckjf0AGAtEZyvDyJbw==}
|
||||||
|
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-collection@1.1.4':
|
'@radix-ui/react-collection@1.1.4':
|
||||||
resolution: {integrity: sha512-cv4vSf7HttqXilDnAnvINd53OTl1/bjUYVZrkFnA7nwmY9Ob2POUy0WY0sfqBAe1s5FyKsyceQlqiEGPYNTadg==}
|
resolution: {integrity: sha512-cv4vSf7HttqXilDnAnvINd53OTl1/bjUYVZrkFnA7nwmY9Ob2POUy0WY0sfqBAe1s5FyKsyceQlqiEGPYNTadg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -529,6 +551,19 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-dialog@1.1.11':
|
||||||
|
resolution: {integrity: sha512-yI7S1ipkP5/+99qhSI6nthfo/tR6bL6Zgxi/+1UO6qPa6UeM6nlafWcQ65vB4rU2XjgjMfMhI3k9Y5MztA62VQ==}
|
||||||
|
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-direction@1.1.1':
|
'@radix-ui/react-direction@1.1.1':
|
||||||
resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
|
resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -608,6 +643,19 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-navigation-menu@1.2.10':
|
||||||
|
resolution: {integrity: sha512-kGDqMVPj2SRB1vJmXN/jnhC66REAXNyDmDRubbbmJ+360zSIJUDmWGMKIJOf72PHMwPENrbtJVb3CMAUJDjEIA==}
|
||||||
|
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-popper@1.2.4':
|
'@radix-ui/react-popper@1.2.4':
|
||||||
resolution: {integrity: sha512-3p2Rgm/a1cK0r/UVkx5F/K9v/EplfjAeIFCGOPYPO4lZ0jtg4iSQXt/YGTSLWaf4x7NG6Z4+uKFcylcTZjeqDA==}
|
resolution: {integrity: sha512-3p2Rgm/a1cK0r/UVkx5F/K9v/EplfjAeIFCGOPYPO4lZ0jtg4iSQXt/YGTSLWaf4x7NG6Z4+uKFcylcTZjeqDA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -647,6 +695,19 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-presence@1.1.4':
|
||||||
|
resolution: {integrity: sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==}
|
||||||
|
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-primitive@2.1.0':
|
'@radix-ui/react-primitive@2.1.0':
|
||||||
resolution: {integrity: sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw==}
|
resolution: {integrity: sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2839,6 +2900,22 @@ 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-collapsible@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)':
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/primitive': 1.1.2
|
||||||
|
'@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-id': 1.1.1(@types/react@19.1.2)(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-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)
|
||||||
|
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-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-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)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0)
|
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
@ -2863,6 +2940,28 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 19.1.2
|
'@types/react': 19.1.2
|
||||||
|
|
||||||
|
'@radix-ui/react-dialog@1.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:
|
||||||
|
'@radix-ui/primitive': 1.1.2
|
||||||
|
'@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-focus-guards': 1.1.2(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
'@radix-ui/react-focus-scope': 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-id': 1.1.1(@types/react@19.1.2)(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-slot': 1.2.0(@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)
|
||||||
|
aria-hidden: 1.2.4
|
||||||
|
react: 19.1.0
|
||||||
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
|
react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 19.1.2
|
||||||
|
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||||
|
|
||||||
'@radix-ui/react-direction@1.1.1(@types/react@19.1.2)(react@19.1.0)':
|
'@radix-ui/react-direction@1.1.1(@types/react@19.1.2)(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
@ -2947,6 +3046,28 @@ 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-navigation-menu@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)':
|
||||||
|
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-direction': 1.1.1(@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-id': 1.1.1(@types/react@19.1.2)(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-use-previous': 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-popper@1.2.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-popper@1.2.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:
|
dependencies:
|
||||||
'@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
'@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
@ -2985,6 +3106,16 @@ 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-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)':
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/react-compose-refs': 1.1.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)
|
||||||
|
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-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-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)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0)
|
'@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0)
|
||||||
|
|||||||
404
src/app/about/page.tsx
Normal file
404
src/app/about/page.tsx
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
import {
|
||||||
|
Award,
|
||||||
|
Fuel,
|
||||||
|
History,
|
||||||
|
MapPin,
|
||||||
|
Star,
|
||||||
|
Target,
|
||||||
|
Users,
|
||||||
|
} from 'lucide-react';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
import AnimatedCounter from '@/shared/components/animated-counter';
|
||||||
|
import { Button } from '@/shared/shadcn-ui/button';
|
||||||
|
import { Card, CardContent } from '@/shared/shadcn-ui/card';
|
||||||
|
|
||||||
|
import { CompanyTimeline } from '@/widgets/about-page/company-timeline';
|
||||||
|
import { StationGallery } from '@/widgets/about-page/station-gallery';
|
||||||
|
import { CtaSection } from '@/widgets/cta-section';
|
||||||
|
|
||||||
|
export const metadata = {
|
||||||
|
title: 'О нас | GasNetwork - Сеть заправок в Таджикистане',
|
||||||
|
description:
|
||||||
|
'Узнайте больше о нашей компании, истории и ценностях. Качественное топливо и отличный сервис.',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function AboutPage() {
|
||||||
|
return (
|
||||||
|
<div className='flex min-h-screen flex-col'>
|
||||||
|
<main className='flex-1'>
|
||||||
|
{/* Hero Section */}
|
||||||
|
<section className='relative'>
|
||||||
|
<div className='relative h-[400px] w-full overflow-hidden'>
|
||||||
|
<Image
|
||||||
|
src='/placeholder.svg?height=400&width=1920&text=Наша+История'
|
||||||
|
alt='О нашей компании'
|
||||||
|
width={1920}
|
||||||
|
height={400}
|
||||||
|
className='object-cover'
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='max-w-2xl space-y-4 text-white'>
|
||||||
|
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
|
||||||
|
О нашей компании
|
||||||
|
</h1>
|
||||||
|
<p className='text-lg text-gray-200'>
|
||||||
|
Узнайте больше о нашей истории, ценностях и миссии. Мы
|
||||||
|
стремимся предоставлять лучший сервис и качественное топливо
|
||||||
|
для наших клиентов.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Company Overview */}
|
||||||
|
<section className='py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='grid items-center gap-12 md:grid-cols-2'>
|
||||||
|
<div>
|
||||||
|
<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>
|
||||||
|
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Лидер на рынке Таджикистана
|
||||||
|
</h2>
|
||||||
|
<p className='mb-6 text-gray-600'>
|
||||||
|
GasNetwork - ведущая сеть автозаправочных станций в
|
||||||
|
Таджикистане, предоставляющая высококачественное топливо и
|
||||||
|
превосходный сервис. Наша компания была основана в 2008 году и
|
||||||
|
с тех пор стала символом надежности и качества в
|
||||||
|
энергетическом секторе страны.
|
||||||
|
</p>
|
||||||
|
<p className='mb-6 text-gray-600'>
|
||||||
|
Мы гордимся тем, что предлагаем нашим клиентам только лучшее
|
||||||
|
топливо, соответствующее международным стандартам качества.
|
||||||
|
Наши заправочные станции оснащены современным оборудованием,
|
||||||
|
которое обеспечивает быстрое и безопасное обслуживание.
|
||||||
|
</p>
|
||||||
|
<p className='mb-6 text-gray-600'>
|
||||||
|
Наша миссия - сделать поездки наших клиентов комфортными и
|
||||||
|
безопасными, предоставляя качественное топливо и отличный
|
||||||
|
сервис по всей стране.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className='mb-6 grid grid-cols-2 gap-4'>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>Качество</h3>
|
||||||
|
<p className='text-gray-600'>Топливо высшего стандарта</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>Сервис</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Профессиональное обслуживание
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>Инновации</h3>
|
||||||
|
<p className='text-gray-600'>Современные технологии</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>Доступность</h3>
|
||||||
|
<p className='text-gray-600'>Станции по всей стране</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='relative h-[500px] overflow-hidden rounded-xl shadow-xl'>
|
||||||
|
<Image
|
||||||
|
src='/placeholder.svg?height=500&width=600&text=Главный+офис'
|
||||||
|
alt='Главный офис GasNetwork'
|
||||||
|
fill
|
||||||
|
className='object-cover'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Stats Section */}
|
||||||
|
<section className='bg-red-600 py-16 text-white'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='mb-12 text-center'>
|
||||||
|
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
GasNetwork в цифрах
|
||||||
|
</h2>
|
||||||
|
<p className='mx-auto max-w-2xl text-white/80'>
|
||||||
|
Наши достижения и рост за годы работы на рынке Таджикистана
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='grid grid-cols-2 gap-8 text-center md:grid-cols-4'>
|
||||||
|
<div className='space-y-2'>
|
||||||
|
<h3 className='text-4xl font-bold'>
|
||||||
|
<AnimatedCounter end={25} suffix='+' />
|
||||||
|
</h3>
|
||||||
|
<p className='text-sm text-white/80'>Заправок по стране</p>
|
||||||
|
</div>
|
||||||
|
<div className='space-y-2'>
|
||||||
|
<h3 className='text-4xl font-bold'>
|
||||||
|
<AnimatedCounter end={15} />
|
||||||
|
</h3>
|
||||||
|
<p className='text-sm text-white/80'>Лет на рынке</p>
|
||||||
|
</div>
|
||||||
|
<div className='space-y-2'>
|
||||||
|
<h3 className='text-4xl font-bold'>
|
||||||
|
<AnimatedCounter end={150} suffix='+' />
|
||||||
|
</h3>
|
||||||
|
<p className='text-sm text-white/80'>Сотрудников</p>
|
||||||
|
</div>
|
||||||
|
<div className='space-y-2'>
|
||||||
|
<h3 className='text-4xl font-bold'>
|
||||||
|
<AnimatedCounter end={1000000} suffix='+' />
|
||||||
|
</h3>
|
||||||
|
<p className='text-sm text-white/80'>Клиентов в год</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Our History */}
|
||||||
|
<section className='py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='mb-12 flex flex-col items-center justify-center text-center'>
|
||||||
|
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
|
||||||
|
<History className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Наша история
|
||||||
|
</h2>
|
||||||
|
<p className='max-w-2xl text-gray-600'>
|
||||||
|
История развития нашей компании от небольшой сети до лидера
|
||||||
|
рынка
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<CompanyTimeline />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Our Stations */}
|
||||||
|
<section className='bg-gray-50 py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='mb-12 flex flex-col items-center justify-center text-center'>
|
||||||
|
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
|
||||||
|
<MapPin className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Наши заправочные станции
|
||||||
|
</h2>
|
||||||
|
<p className='max-w-2xl text-gray-600'>
|
||||||
|
Современные заправочные станции, оснащенные по последнему слову
|
||||||
|
техники
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<StationGallery />
|
||||||
|
|
||||||
|
<div className='mt-12 text-center'>
|
||||||
|
<p className='mx-auto mb-6 max-w-2xl text-gray-600'>
|
||||||
|
Наши заправочные станции расположены в стратегически важных
|
||||||
|
точках по всему Таджикистану, обеспечивая удобный доступ для
|
||||||
|
всех наших клиентов.
|
||||||
|
</p>
|
||||||
|
<Button className='bg-red-600 hover:bg-red-700'>
|
||||||
|
Найти ближайшую заправку <MapPin className='ml-2 h-4 w-4' />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Our Values */}
|
||||||
|
<section className='py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='mb-12 flex flex-col items-center justify-center text-center'>
|
||||||
|
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
|
||||||
|
<Target className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Наши ценности
|
||||||
|
</h2>
|
||||||
|
<p className='max-w-2xl text-gray-600'>
|
||||||
|
Принципы, которыми мы руководствуемся в нашей работе
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='grid gap-8 md:grid-cols-3'>
|
||||||
|
<Card className='overflow-hidden transition-all hover:shadow-lg'>
|
||||||
|
<CardContent className='p-6'>
|
||||||
|
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
|
||||||
|
<Star className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h3 className='mb-2 text-xl font-bold'>Качество</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Мы предлагаем только высококачественное топливо,
|
||||||
|
соответствующее международным стандартам. Регулярные
|
||||||
|
проверки и контроль качества гарантируют, что наши клиенты
|
||||||
|
получают лучшее.
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className='overflow-hidden transition-all hover:shadow-lg'>
|
||||||
|
<CardContent className='p-6'>
|
||||||
|
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
|
||||||
|
<Users className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h3 className='mb-2 text-xl font-bold'>
|
||||||
|
Клиентоориентированность
|
||||||
|
</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Наши клиенты - наш главный приоритет. Мы стремимся
|
||||||
|
предоставить лучший сервис, удобные условия и приятную
|
||||||
|
атмосферу на каждой нашей заправке.
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className='overflow-hidden transition-all hover:shadow-lg'>
|
||||||
|
<CardContent className='p-6'>
|
||||||
|
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
|
||||||
|
<Award className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h3 className='mb-2 text-xl font-bold'>Профессионализм</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Наши сотрудники - профессионалы своего дела. Мы постоянно
|
||||||
|
инвестируем в их обучение и развитие, чтобы обеспечить
|
||||||
|
высокий уровень обслуживания.
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Our Team */}
|
||||||
|
<section className='bg-gray-50 py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='mb-12 flex flex-col items-center justify-center text-center'>
|
||||||
|
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
|
||||||
|
<Users className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Наша команда
|
||||||
|
</h2>
|
||||||
|
<p className='max-w-2xl text-gray-600'>
|
||||||
|
Познакомьтесь с профессионалами, которые делают GasNetwork
|
||||||
|
лучшей сетью заправок в Таджикистане
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-4'>
|
||||||
|
{[
|
||||||
|
{ name: 'Алишер Рахмонов', position: 'Генеральный директор' },
|
||||||
|
{ name: 'Фарида Каримова', position: 'Финансовый директор' },
|
||||||
|
{ name: 'Рустам Назаров', position: 'Технический директор' },
|
||||||
|
{ name: 'Зарина Шарипова', position: 'Директор по маркетингу' },
|
||||||
|
].map((person, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className='overflow-hidden rounded-lg bg-white shadow-md transition-transform hover:scale-105'
|
||||||
|
>
|
||||||
|
<div className='relative h-64 w-full'>
|
||||||
|
<Image
|
||||||
|
src={`/placeholder.svg?height=300&width=300&text=${person.name}`}
|
||||||
|
alt={person.name}
|
||||||
|
fill
|
||||||
|
className='object-cover'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='p-4 text-center'>
|
||||||
|
<h3 className='text-lg font-bold'>{person.name}</h3>
|
||||||
|
<p className='text-gray-600'>{person.position}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Testimonials */}
|
||||||
|
<section className='py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='mb-12 flex flex-col items-center justify-center text-center'>
|
||||||
|
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
|
||||||
|
<Star className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Отзывы клиентов
|
||||||
|
</h2>
|
||||||
|
<p className='max-w-2xl text-gray-600'>
|
||||||
|
Что говорят о нас наши клиенты
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='grid gap-8 md:grid-cols-3'>
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
name: 'Фархад К.',
|
||||||
|
text: 'Я всегда заправляюсь только на GasNetwork. Качество топлива на высоте, а обслуживание всегда приветливое и быстрое.',
|
||||||
|
rating: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Нигина М.',
|
||||||
|
text: 'Очень удобно, что заправки расположены по всему городу. Всегда чисто, есть кафе и магазин. Рекомендую!',
|
||||||
|
rating: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Джамшед Р.',
|
||||||
|
text: 'Пользуюсь картой лояльности GasNetwork уже 3 года. Накопил много бонусов и получил немало приятных подарков. Отличный сервис!',
|
||||||
|
rating: 4,
|
||||||
|
},
|
||||||
|
].map((testimonial, index) => (
|
||||||
|
<Card
|
||||||
|
key={index}
|
||||||
|
className='overflow-hidden transition-all hover:shadow-lg'
|
||||||
|
>
|
||||||
|
<CardContent className='p-6'>
|
||||||
|
<div className='mb-4 flex'>
|
||||||
|
{Array(5)
|
||||||
|
.fill(0)
|
||||||
|
.map((_, i) => (
|
||||||
|
<Star
|
||||||
|
key={i}
|
||||||
|
className={`h-5 w-5 ${i < testimonial.rating ? 'fill-yellow-400 text-yellow-400' : 'text-gray-300'}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<p className='mb-4 text-gray-600 italic'>
|
||||||
|
"{testimonial.text}"
|
||||||
|
</p>
|
||||||
|
<p className='font-semibold'>{testimonial.name}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<CtaSection />
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
285
src/app/clients/loyalty/page.tsx
Normal file
285
src/app/clients/loyalty/page.tsx
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
import { Check, Percent } from 'lucide-react';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
import { Card, CardContent } from '@/shared/shadcn-ui/card';
|
||||||
|
|
||||||
|
import { CtaSection } from '@/widgets/cta-section';
|
||||||
|
|
||||||
|
export const metadata = {
|
||||||
|
title: 'Программа лояльности | GasNetwork - Сеть заправок в Таджикистане',
|
||||||
|
description:
|
||||||
|
'Программа лояльности GasNetwork: накапливайте баллы и получайте скидки на топливо и услуги.',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function LoyaltyPage() {
|
||||||
|
return (
|
||||||
|
<div className='flex min-h-screen flex-col'>
|
||||||
|
<main className='flex-1'>
|
||||||
|
{/* Hero Section */}
|
||||||
|
<section className='relative'>
|
||||||
|
<div className='relative h-[400px] w-full overflow-hidden'>
|
||||||
|
<Image
|
||||||
|
src='/placeholder.svg?height=400&width=1920&text=Программа+лояльности'
|
||||||
|
alt='Программа лояльности'
|
||||||
|
width={1920}
|
||||||
|
height={400}
|
||||||
|
className='object-cover'
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='max-w-2xl space-y-4 text-white'>
|
||||||
|
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
|
||||||
|
Программа лояльности
|
||||||
|
</h1>
|
||||||
|
<p className='text-lg text-gray-200'>
|
||||||
|
Накапливайте баллы и получайте скидки на топливо и услуги
|
||||||
|
нашей сети
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Program Overview */}
|
||||||
|
<section className='py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='grid items-center gap-12 md:grid-cols-2'>
|
||||||
|
<div>
|
||||||
|
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
|
||||||
|
<Percent className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
О программе лояльности
|
||||||
|
</h2>
|
||||||
|
<p className='mb-6 text-gray-600'>
|
||||||
|
Программа лояльности GasNetwork — это возможность получать
|
||||||
|
баллы за каждую покупку топлива и услуг на наших заправочных
|
||||||
|
станциях. Накопленные баллы можно обменять на скидки, подарки
|
||||||
|
или дополнительные услуги.
|
||||||
|
</p>
|
||||||
|
<p className='mb-6 text-gray-600'>
|
||||||
|
Участие в программе абсолютно бесплатное. Вам нужно только
|
||||||
|
получить карту лояльности в любой нашей заправочной станции
|
||||||
|
или зарегистрироваться в мобильном приложении.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className='space-y-4'>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>1 литр = 1 балл</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
За каждый литр топлива вы получаете 1 балл
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>
|
||||||
|
Дополнительные баллы
|
||||||
|
</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
За покупки в магазине и кафе на заправке
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>Специальные акции</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Удвоенные и утроенные баллы в праздничные дни
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='relative h-[400px] overflow-hidden rounded-xl shadow-xl'>
|
||||||
|
<Image
|
||||||
|
src='/placeholder.svg?height=400&width=600&text=Программа+лояльности'
|
||||||
|
alt='Программа лояльности'
|
||||||
|
fill
|
||||||
|
className='object-cover'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* How It Works */}
|
||||||
|
<section className='bg-gray-50 py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='mb-12 text-center'>
|
||||||
|
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Как это работает
|
||||||
|
</h2>
|
||||||
|
<p className='mx-auto max-w-2xl text-gray-600'>
|
||||||
|
Простые шаги для участия в программе лояльности GasNetwork
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='grid gap-8 md:grid-cols-4'>
|
||||||
|
<div className='text-center'>
|
||||||
|
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
|
||||||
|
1
|
||||||
|
</div>
|
||||||
|
<h3 className='mb-2 text-xl font-bold'>Получите карту</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Получите карту лояльности на любой заправке GasNetwork или
|
||||||
|
зарегистрируйтесь в мобильном приложении
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='text-center'>
|
||||||
|
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
|
||||||
|
2
|
||||||
|
</div>
|
||||||
|
<h3 className='mb-2 text-xl font-bold'>Заправляйтесь</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Используйте карту при каждой заправке и покупке в магазинах на
|
||||||
|
наших АЗС
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='text-center'>
|
||||||
|
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
|
||||||
|
3
|
||||||
|
</div>
|
||||||
|
<h3 className='mb-2 text-xl font-bold'>Накапливайте баллы</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Получайте баллы за каждую покупку и следите за их накоплением
|
||||||
|
в приложении
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='text-center'>
|
||||||
|
<div className='mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-600 text-2xl font-bold text-white'>
|
||||||
|
4
|
||||||
|
</div>
|
||||||
|
<h3 className='mb-2 text-xl font-bold'>Получайте выгоду</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Обменивайте накопленные баллы на скидки, подарки или
|
||||||
|
дополнительные услуги
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Loyalty Levels */}
|
||||||
|
<section className='py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='mb-12 text-center'>
|
||||||
|
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Уровни лояльности
|
||||||
|
</h2>
|
||||||
|
<p className='mx-auto max-w-2xl text-gray-600'>
|
||||||
|
Чем больше вы заправляетесь, тем больше преимуществ получаете
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='grid gap-8 md:grid-cols-3'>
|
||||||
|
<Card className='overflow-hidden border-t-4 border-t-gray-400 transition-all hover:shadow-lg'>
|
||||||
|
<CardContent className='p-6'>
|
||||||
|
<h3 className='mb-4 text-center text-2xl font-bold'>
|
||||||
|
Стандарт
|
||||||
|
</h3>
|
||||||
|
<div className='mb-6 text-center'>
|
||||||
|
<span className='text-4xl font-bold'>1%</span>
|
||||||
|
<p className='text-sm text-gray-600'>возврат баллами</p>
|
||||||
|
</div>
|
||||||
|
<ul className='space-y-2'>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>1 балл за каждый литр топлива</span>
|
||||||
|
</li>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>Участие в акциях</span>
|
||||||
|
</li>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>Доступ к мобильному приложению</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className='overflow-hidden border-t-4 border-t-yellow-500 transition-all hover:shadow-lg'>
|
||||||
|
<CardContent className='p-6'>
|
||||||
|
<h3 className='mb-4 text-center text-2xl font-bold'>
|
||||||
|
Золотой
|
||||||
|
</h3>
|
||||||
|
<div className='mb-6 text-center'>
|
||||||
|
<span className='text-4xl font-bold'>2%</span>
|
||||||
|
<p className='text-sm text-gray-600'>возврат баллами</p>
|
||||||
|
</div>
|
||||||
|
<ul className='space-y-2'>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>2 балла за каждый литр топлива</span>
|
||||||
|
</li>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>Скидка 5% в кафе на заправках</span>
|
||||||
|
</li>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>Приоритетное обслуживание</span>
|
||||||
|
</li>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>Эксклюзивные акции</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className='overflow-hidden border-t-4 border-t-red-600 transition-all hover:shadow-lg'>
|
||||||
|
<CardContent className='p-6'>
|
||||||
|
<h3 className='mb-4 text-center text-2xl font-bold'>
|
||||||
|
Платиновый
|
||||||
|
</h3>
|
||||||
|
<div className='mb-6 text-center'>
|
||||||
|
<span className='text-4xl font-bold'>3%</span>
|
||||||
|
<p className='text-sm text-gray-600'>возврат баллами</p>
|
||||||
|
</div>
|
||||||
|
<ul className='space-y-2'>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>3 балла за каждый литр топлива</span>
|
||||||
|
</li>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>Скидка 10% в кафе на заправках</span>
|
||||||
|
</li>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>Бесплатная мойка раз в месяц</span>
|
||||||
|
</li>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>Персональный менеджер</span>
|
||||||
|
</li>
|
||||||
|
<li className='flex items-center'>
|
||||||
|
<Check className='mr-2 h-5 w-5 text-green-500' />
|
||||||
|
<span>VIP-обслуживание</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<CtaSection />
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
254
src/app/clients/page.tsx
Normal file
254
src/app/clients/page.tsx
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
import { ArrowRight, CreditCard, Gift, Percent, Wallet } from 'lucide-react';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
import { Button } from '@/shared/shadcn-ui/button';
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardDescription,
|
||||||
|
CardFooter,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
} from '@/shared/shadcn-ui/card';
|
||||||
|
|
||||||
|
import { CtaSection } from '@/widgets/cta-section';
|
||||||
|
|
||||||
|
export const metadata = {
|
||||||
|
title: 'Клиентам | GasNetwork - Сеть заправок в Таджикистане',
|
||||||
|
description:
|
||||||
|
'Информация для клиентов: программа лояльности, топливные карты, сертификаты и способы оплаты.',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ClientsPage() {
|
||||||
|
return (
|
||||||
|
<div className='flex min-h-screen flex-col'>
|
||||||
|
<main className='flex-1'>
|
||||||
|
{/* Hero Section */}
|
||||||
|
<section className='relative'>
|
||||||
|
<div className='relative h-[400px] w-full overflow-hidden'>
|
||||||
|
<Image
|
||||||
|
src='/placeholder.svg?height=400&width=1920&text=Для+наших+клиентов'
|
||||||
|
alt='Для наших клиентов'
|
||||||
|
width={1920}
|
||||||
|
height={400}
|
||||||
|
className='object-cover'
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
<div className='absolute inset-0 flex items-center bg-gradient-to-r from-black/70 to-black/30'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='max-w-2xl space-y-4 text-white'>
|
||||||
|
<h1 className='text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl'>
|
||||||
|
Для наших клиентов
|
||||||
|
</h1>
|
||||||
|
<p className='text-lg text-gray-200'>
|
||||||
|
Специальные предложения, программы лояльности и удобные
|
||||||
|
способы оплаты для наших клиентов
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Services Overview */}
|
||||||
|
<section className='py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='mb-12 text-center'>
|
||||||
|
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Наши услуги для клиентов
|
||||||
|
</h2>
|
||||||
|
<p className='mx-auto max-w-2xl text-gray-600'>
|
||||||
|
Мы стремимся сделать обслуживание на наших заправках максимально
|
||||||
|
удобным и выгодным для вас
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='grid gap-6 md:grid-cols-2 lg:grid-cols-4'>
|
||||||
|
<Card className='overflow-hidden transition-all hover:shadow-lg'>
|
||||||
|
<CardHeader className='pb-3'>
|
||||||
|
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
|
||||||
|
<Percent className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<CardTitle>Программа лояльности</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Накапливайте баллы и получайте скидки
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className='text-sm text-gray-600'>
|
||||||
|
<p>
|
||||||
|
Наша программа лояльности позволяет накапливать баллы за
|
||||||
|
каждую покупку и обменивать их на скидки и подарки.
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
<CardFooter>
|
||||||
|
<Link href='/clients/loyalty'>
|
||||||
|
<Button variant='outline' className='w-full'>
|
||||||
|
Подробнее <ArrowRight className='ml-2 h-4 w-4' />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className='overflow-hidden transition-all hover:shadow-lg'>
|
||||||
|
<CardHeader className='pb-3'>
|
||||||
|
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
|
||||||
|
<CreditCard className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<CardTitle>Топливная карта</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Удобный способ оплаты топлива
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className='text-sm text-gray-600'>
|
||||||
|
<p>
|
||||||
|
Топливные карты для физических и юридических лиц.
|
||||||
|
Контролируйте расходы и получайте дополнительные
|
||||||
|
преимущества.
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
<CardFooter>
|
||||||
|
<Link href='/clients/fuel-card'>
|
||||||
|
<Button variant='outline' className='w-full'>
|
||||||
|
Подробнее <ArrowRight className='ml-2 h-4 w-4' />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className='overflow-hidden transition-all hover:shadow-lg'>
|
||||||
|
<CardHeader className='pb-3'>
|
||||||
|
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
|
||||||
|
<Gift className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<CardTitle>Сертификаты</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Подарочные сертификаты на топливо и услуги
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className='text-sm text-gray-600'>
|
||||||
|
<p>
|
||||||
|
Подарите близким или партнерам сертификат на топливо или
|
||||||
|
услуги нашей сети. Идеальный подарок для автовладельцев.
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
<CardFooter>
|
||||||
|
<Link href='/clients/certificates'>
|
||||||
|
<Button variant='outline' className='w-full'>
|
||||||
|
Подробнее <ArrowRight className='ml-2 h-4 w-4' />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className='overflow-hidden transition-all hover:shadow-lg'>
|
||||||
|
<CardHeader className='pb-3'>
|
||||||
|
<div className='mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
|
||||||
|
<Wallet className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<CardTitle>Способы оплаты</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Различные способы оплаты на наших заправках
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className='text-sm text-gray-600'>
|
||||||
|
<p>
|
||||||
|
Мы предлагаем различные способы оплаты: наличные, банковские
|
||||||
|
карты, мобильные платежи и топливные карты.
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
<CardFooter>
|
||||||
|
<Link href='/clients/payment'>
|
||||||
|
<Button variant='outline' className='w-full'>
|
||||||
|
Подробнее <ArrowRight className='ml-2 h-4 w-4' />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Benefits Section */}
|
||||||
|
<section className='bg-gray-50 py-16'>
|
||||||
|
<div className='container mx-auto'>
|
||||||
|
<div className='grid items-center gap-12 md:grid-cols-2'>
|
||||||
|
<div className='order-2 md:order-1'>
|
||||||
|
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
|
||||||
|
<Percent className='h-6 w-6 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h2 className='mb-6 text-3xl font-bold tracking-tight sm:text-4xl'>
|
||||||
|
Преимущества для клиентов
|
||||||
|
</h2>
|
||||||
|
<p className='mb-6 text-gray-600'>
|
||||||
|
Став клиентом GasNetwork, вы получаете множество преимуществ,
|
||||||
|
которые делают заправку вашего автомобиля более выгодной и
|
||||||
|
удобной.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className='space-y-4'>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>Экономия</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Скидки и бонусы для постоянных клиентов
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>Удобство</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Быстрая оплата и обслуживание
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>Качество</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Гарантированно высокое качество топлива
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-start'>
|
||||||
|
<div className='mt-1 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-red-600'>
|
||||||
|
<span className='text-xs text-white'>✓</span>
|
||||||
|
</div>
|
||||||
|
<div className='ml-3'>
|
||||||
|
<h3 className='text-lg font-medium'>
|
||||||
|
Дополнительные услуги
|
||||||
|
</h3>
|
||||||
|
<p className='text-gray-600'>
|
||||||
|
Кафе, магазины и другие услуги на наших заправках
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='relative order-1 h-[400px] overflow-hidden rounded-xl shadow-xl md:order-2'>
|
||||||
|
<Image
|
||||||
|
src='/placeholder.svg?height=400&width=600&text=Преимущества+для+клиентов'
|
||||||
|
alt='Преимущества для клиентов'
|
||||||
|
fill
|
||||||
|
className='object-cover'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<CtaSection />
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -49,7 +49,7 @@
|
|||||||
--card-foreground: oklch(0.145 0 0);
|
--card-foreground: oklch(0.145 0 0);
|
||||||
--popover: oklch(1 0 0);
|
--popover: oklch(1 0 0);
|
||||||
--popover-foreground: oklch(0.145 0 0);
|
--popover-foreground: oklch(0.145 0 0);
|
||||||
--primary: oklch(0.205 0 0);
|
--primary: oklch(0.577 0.245 27.325) ;
|
||||||
--primary-foreground: oklch(0.985 0 0);
|
--primary-foreground: oklch(0.985 0 0);
|
||||||
--secondary: oklch(0.97 0 0);
|
--secondary: oklch(0.97 0 0);
|
||||||
--secondary-foreground: oklch(0.205 0 0);
|
--secondary-foreground: oklch(0.205 0 0);
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import { cn } from '@/shared/lib/utils';
|
|
||||||
import { Slot } from '@radix-ui/react-slot';
|
import { Slot } from '@radix-ui/react-slot';
|
||||||
import { cva, type VariantProps } from 'class-variance-authority';
|
import { cva, type VariantProps } from 'class-variance-authority';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { cn } from '@/shared/lib/utils';
|
||||||
|
|
||||||
const buttonVariants = cva(
|
const buttonVariants = cva(
|
||||||
'ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
'ring-offset-background focus-visible:ring-ring inline-flex cursor-pointer items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||||
{
|
{
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
@ -12,7 +13,7 @@ const buttonVariants = cva(
|
|||||||
destructive:
|
destructive:
|
||||||
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
||||||
outline:
|
outline:
|
||||||
'border-input bg-background hover:bg-accent hover:text-accent-foreground border',
|
'border-input bg-background hover:bg-accent text-accent-foreground border',
|
||||||
secondary:
|
secondary:
|
||||||
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
||||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||||
|
|||||||
11
src/shared/shadcn-ui/collapsible.tsx
Normal file
11
src/shared/shadcn-ui/collapsible.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
|
||||||
|
|
||||||
|
const Collapsible = CollapsiblePrimitive.Root;
|
||||||
|
|
||||||
|
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
||||||
|
|
||||||
|
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
|
||||||
|
|
||||||
|
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
||||||
123
src/shared/shadcn-ui/dialog.tsx
Normal file
123
src/shared/shadcn-ui/dialog.tsx
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
||||||
|
import { X } from 'lucide-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { cn } from '@/shared/lib/utils';
|
||||||
|
|
||||||
|
const Dialog = DialogPrimitive.Root;
|
||||||
|
|
||||||
|
const DialogTrigger = DialogPrimitive.Trigger;
|
||||||
|
|
||||||
|
const DialogPortal = DialogPrimitive.Portal;
|
||||||
|
|
||||||
|
const DialogClose = DialogPrimitive.Close;
|
||||||
|
|
||||||
|
const DialogOverlay = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof DialogPrimitive.Overlay>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Overlay
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
||||||
|
|
||||||
|
const DialogContent = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof DialogPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<DialogPortal>
|
||||||
|
<DialogOverlay />
|
||||||
|
<DialogPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'bg-background 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%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<DialogPrimitive.Close className='ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none'>
|
||||||
|
<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.ComponentRef<typeof DialogPrimitive.Title>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Title
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'text-lg leading-none font-semibold tracking-tight',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
||||||
|
|
||||||
|
const DialogDescription = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof DialogPrimitive.Description>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn('text-muted-foreground text-sm', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
||||||
|
|
||||||
|
export {
|
||||||
|
Dialog,
|
||||||
|
DialogClose,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogOverlay,
|
||||||
|
DialogPortal,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger
|
||||||
|
};
|
||||||
|
|
||||||
128
src/shared/shadcn-ui/navigation-menu.tsx
Normal file
128
src/shared/shadcn-ui/navigation-menu.tsx
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
|
||||||
|
import { cva } from 'class-variance-authority';
|
||||||
|
import { ChevronDown } from 'lucide-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { cn } from '@/shared/lib/utils';
|
||||||
|
|
||||||
|
const NavigationMenu = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof NavigationMenuPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<NavigationMenuPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'relative z-10 flex max-w-max flex-1 items-center justify-center',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<NavigationMenuViewport />
|
||||||
|
</NavigationMenuPrimitive.Root>
|
||||||
|
));
|
||||||
|
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
|
||||||
|
|
||||||
|
const NavigationMenuList = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof NavigationMenuPrimitive.List>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<NavigationMenuPrimitive.List
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'group flex flex-1 list-none items-center justify-center space-x-1',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
|
||||||
|
|
||||||
|
const NavigationMenuItem = NavigationMenuPrimitive.Item;
|
||||||
|
|
||||||
|
const navigationMenuTriggerStyle = cva(
|
||||||
|
'group bg-background hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground data-[state=open]:text-accent-foreground data-[state=open]:bg-accent/50 data-[state=open]:hover:bg-accent data-[state=open]:focus:bg-accent inline-flex h-10 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-colors focus:outline-none disabled:pointer-events-none disabled:opacity-50',
|
||||||
|
);
|
||||||
|
|
||||||
|
const NavigationMenuTrigger = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof NavigationMenuPrimitive.Trigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<NavigationMenuPrimitive.Trigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(navigationMenuTriggerStyle(), 'group', className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}{' '}
|
||||||
|
<ChevronDown
|
||||||
|
className='relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180'
|
||||||
|
aria-hidden='true'
|
||||||
|
/>
|
||||||
|
</NavigationMenuPrimitive.Trigger>
|
||||||
|
));
|
||||||
|
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
|
||||||
|
|
||||||
|
const NavigationMenuContent = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof NavigationMenuPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<NavigationMenuPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 left-0 w-full md:absolute md:w-auto',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
|
||||||
|
|
||||||
|
const NavigationMenuLink = NavigationMenuPrimitive.Link;
|
||||||
|
|
||||||
|
const NavigationMenuViewport = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof NavigationMenuPrimitive.Viewport>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div className={cn('absolute top-full left-0 flex justify-center')}>
|
||||||
|
<NavigationMenuPrimitive.Viewport
|
||||||
|
className={cn(
|
||||||
|
'origin-top-center bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow-lg md:w-[var(--radix-navigation-menu-viewport-width)]',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
NavigationMenuViewport.displayName =
|
||||||
|
NavigationMenuPrimitive.Viewport.displayName;
|
||||||
|
|
||||||
|
const NavigationMenuIndicator = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof NavigationMenuPrimitive.Indicator>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<NavigationMenuPrimitive.Indicator
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<div className='bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md' />
|
||||||
|
</NavigationMenuPrimitive.Indicator>
|
||||||
|
));
|
||||||
|
NavigationMenuIndicator.displayName =
|
||||||
|
NavigationMenuPrimitive.Indicator.displayName;
|
||||||
|
|
||||||
|
export {
|
||||||
|
NavigationMenu,
|
||||||
|
NavigationMenuContent,
|
||||||
|
NavigationMenuIndicator,
|
||||||
|
NavigationMenuItem,
|
||||||
|
NavigationMenuLink,
|
||||||
|
NavigationMenuList,
|
||||||
|
NavigationMenuTrigger,
|
||||||
|
navigationMenuTriggerStyle,
|
||||||
|
NavigationMenuViewport,
|
||||||
|
};
|
||||||
140
src/shared/shadcn-ui/sheet.tsx
Normal file
140
src/shared/shadcn-ui/sheet.tsx
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as SheetPrimitive from '@radix-ui/react-dialog';
|
||||||
|
import { cva, type VariantProps } from 'class-variance-authority';
|
||||||
|
import { X } from 'lucide-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { cn } from '@/shared/lib/utils';
|
||||||
|
|
||||||
|
const Sheet = SheetPrimitive.Root;
|
||||||
|
|
||||||
|
const SheetTrigger = SheetPrimitive.Trigger;
|
||||||
|
|
||||||
|
const SheetClose = SheetPrimitive.Close;
|
||||||
|
|
||||||
|
const SheetPortal = SheetPrimitive.Portal;
|
||||||
|
|
||||||
|
const SheetOverlay = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof SheetPrimitive.Overlay>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SheetPrimitive.Overlay
|
||||||
|
className={cn(
|
||||||
|
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
|
||||||
|
|
||||||
|
const sheetVariants = cva(
|
||||||
|
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 gap-4 p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
side: {
|
||||||
|
top: 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 border-b',
|
||||||
|
bottom:
|
||||||
|
'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 border-t',
|
||||||
|
left: 'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
|
||||||
|
right:
|
||||||
|
'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
side: 'right',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
interface SheetContentProps
|
||||||
|
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
|
||||||
|
VariantProps<typeof sheetVariants> {}
|
||||||
|
|
||||||
|
const SheetContent = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof SheetPrimitive.Content>,
|
||||||
|
SheetContentProps
|
||||||
|
>(({ side = 'right', className, children, ...props }, ref) => (
|
||||||
|
<SheetPortal>
|
||||||
|
<SheetOverlay />
|
||||||
|
<SheetPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(sheetVariants({ side }), className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<SheetPrimitive.Close className='ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none'>
|
||||||
|
<X className='h-4 w-4' />
|
||||||
|
<span className='sr-only'>Close</span>
|
||||||
|
</SheetPrimitive.Close>
|
||||||
|
</SheetPrimitive.Content>
|
||||||
|
</SheetPortal>
|
||||||
|
));
|
||||||
|
SheetContent.displayName = SheetPrimitive.Content.displayName;
|
||||||
|
|
||||||
|
const SheetHeader = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex flex-col space-y-2 text-center sm:text-left',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
SheetHeader.displayName = 'SheetHeader';
|
||||||
|
|
||||||
|
const SheetFooter = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
SheetFooter.displayName = 'SheetFooter';
|
||||||
|
|
||||||
|
const SheetTitle = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof SheetPrimitive.Title>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SheetPrimitive.Title
|
||||||
|
ref={ref}
|
||||||
|
className={cn('text-foreground text-lg font-semibold', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
SheetTitle.displayName = SheetPrimitive.Title.displayName;
|
||||||
|
|
||||||
|
const SheetDescription = React.forwardRef<
|
||||||
|
React.ComponentRef<typeof SheetPrimitive.Description>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SheetPrimitive.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn('text-muted-foreground text-sm', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
SheetDescription.displayName = SheetPrimitive.Description.displayName;
|
||||||
|
|
||||||
|
export {
|
||||||
|
Sheet,
|
||||||
|
SheetClose,
|
||||||
|
SheetContent,
|
||||||
|
SheetDescription,
|
||||||
|
SheetFooter,
|
||||||
|
SheetHeader,
|
||||||
|
SheetOverlay,
|
||||||
|
SheetPortal,
|
||||||
|
SheetTitle,
|
||||||
|
SheetTrigger,
|
||||||
|
};
|
||||||
125
src/widgets/about-page/company-timeline.tsx
Normal file
125
src/widgets/about-page/company-timeline.tsx
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { Calendar, ChevronDown, ChevronUp } from 'lucide-react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@/shared/shadcn-ui/button';
|
||||||
|
import { Card, CardContent } from '@/shared/shadcn-ui/card';
|
||||||
|
|
||||||
|
const timelineEvents = [
|
||||||
|
{
|
||||||
|
year: '2008',
|
||||||
|
title: 'Основание компании',
|
||||||
|
description:
|
||||||
|
'GasNetwork была основана с открытием первых трех заправочных станций в Душанбе. С самого начала компания поставила перед собой цель предоставлять качественное топливо и отличный сервис.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: '2010',
|
||||||
|
title: 'Расширение сети',
|
||||||
|
description:
|
||||||
|
'Открытие еще пяти заправочных станций в различных регионах Таджикистана. Начало формирования единого стандарта обслуживания на всех станциях сети.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: '2012',
|
||||||
|
title: 'Внедрение программы лояльности',
|
||||||
|
description:
|
||||||
|
'Запуск первой в Таджикистане программы лояльности для клиентов сети заправок. Введение карт постоянного клиента с накопительной системой бонусов.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: '2014',
|
||||||
|
title: 'Модернизация оборудования',
|
||||||
|
description:
|
||||||
|
'Масштабная программа по обновлению оборудования на всех заправочных станциях сети. Внедрение современных технологий для повышения качества обслуживания.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: '2016',
|
||||||
|
title: 'Открытие 15-й заправки',
|
||||||
|
description:
|
||||||
|
'Значительное расширение сети с открытием юбилейной 15-й заправочной станции. GasNetwork становится одной из крупнейших сетей заправок в Таджикистане.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: '2018',
|
||||||
|
title: 'Запуск мобильного приложения',
|
||||||
|
description:
|
||||||
|
'Разработка и запуск мобильного приложения для клиентов сети. Возможность отслеживать бонусы, находить ближайшие заправки и получать специальные предложения.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: '2020',
|
||||||
|
title: 'Создание благотворительного фонда',
|
||||||
|
description:
|
||||||
|
'Основание благотворительного фонда GasNetwork для поддержки социальных проектов в Таджикистане. Начало активной социальной деятельности компании.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: '2023',
|
||||||
|
title: 'Современное развитие',
|
||||||
|
description:
|
||||||
|
'Сегодня GasNetwork - это 25+ современных заправочных станций по всему Таджикистану, более 150 сотрудников и тысячи довольных клиентов ежедневно.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export function CompanyTimeline() {
|
||||||
|
const [expanded, setExpanded] = useState(false);
|
||||||
|
const displayEvents = expanded ? timelineEvents : timelineEvents.slice(0, 4);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='relative'>
|
||||||
|
<div className='absolute left-1/2 -z-10 -ml-0.5 hidden h-full w-0.5 bg-gradient-to-b from-red-200 via-red-200 to-transparent md:block' />
|
||||||
|
|
||||||
|
<div className='space-y-8'>
|
||||||
|
{displayEvents.map((event, index) => (
|
||||||
|
<div key={index} className='relative'>
|
||||||
|
<div className='items-center md:grid md:grid-cols-2 md:gap-8'>
|
||||||
|
<div
|
||||||
|
className={`mb-4 md:mb-0 ${index % 2 === 0 ? 'md:pr-10 md:text-right' : 'md:order-last md:pl-10'}`}
|
||||||
|
data-aos='zoom-in-down'
|
||||||
|
>
|
||||||
|
<div className='mb-2 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
|
||||||
|
<Calendar className='h-5 w-5 text-red-600' />
|
||||||
|
</div>
|
||||||
|
<h3 className='text-xl font-bold'>{event.year}</h3>
|
||||||
|
<h4 className='mb-2 text-lg font-semibold'>{event.title}</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={`${index % 2 === 0 ? 'md:pl-10' : 'md:order-first md:pr-10 md:text-right'}`}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
className='overflow-hidden transition-all hover:shadow-md'
|
||||||
|
data-aos={index % 2 === 0 ? 'fade-left' : 'fade-right'}
|
||||||
|
>
|
||||||
|
<CardContent className='p-4'>
|
||||||
|
<p className='text-gray-600'>{event.description}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='absolute top-5 left-1/2 -ml-3 hidden h-6 w-6 items-center justify-center rounded-full bg-red-600 md:flex'>
|
||||||
|
<div className='h-3 w-3 rounded-full bg-white'></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{timelineEvents.length > 4 && (
|
||||||
|
<div className='mt-8 text-center'>
|
||||||
|
<Button
|
||||||
|
variant='outline'
|
||||||
|
onClick={() => setExpanded(!expanded)}
|
||||||
|
className='inline-flex items-center'
|
||||||
|
>
|
||||||
|
{expanded ? (
|
||||||
|
<>
|
||||||
|
Свернуть <ChevronUp className='ml-2 h-4 w-4' />
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
Показать больше <ChevronDown className='ml-2 h-4 w-4' />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
162
src/widgets/about-page/station-gallery.tsx
Normal file
162
src/widgets/about-page/station-gallery.tsx
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { ChevronLeft, ChevronRight, Maximize } from 'lucide-react';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@/shared/shadcn-ui/button';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '@/shared/shadcn-ui/dialog';
|
||||||
|
|
||||||
|
interface Station {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
image: string;
|
||||||
|
location: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stations: Array<Station> = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'АЗС Душанбе-Центр',
|
||||||
|
image: '/placeholder.svg?height=400&width=600&text=АЗС+Душанбе-Центр',
|
||||||
|
location: 'ул. Рудаки 150, Душанбе',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'АЗС Худжанд',
|
||||||
|
image: '/placeholder.svg?height=400&width=600&text=АЗС+Худжанд',
|
||||||
|
location: 'ул. Ленина 45, Худжанд',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'АЗС Куляб',
|
||||||
|
image: '/placeholder.svg?height=400&width=600&text=АЗС+Куляб',
|
||||||
|
location: 'ул. Сомони 78, Куляб',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: 'АЗС Бохтар',
|
||||||
|
image: '/placeholder.svg?height=400&width=600&text=АЗС+Бохтар',
|
||||||
|
location: 'ул. Айни 23, Бохтар',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
name: 'АЗС Хорог',
|
||||||
|
image: '/placeholder.svg?height=400&width=600&text=АЗС+Хорог',
|
||||||
|
location: 'ул. Горная 12, Хорог',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
name: 'АЗС Истаравшан',
|
||||||
|
image: '/placeholder.svg?height=400&width=600&text=АЗС+Истаравшан',
|
||||||
|
location: 'ул. Исмоили Сомони 34, Истаравшан',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export function StationGallery() {
|
||||||
|
const [currentImage, setCurrentImage] = useState(0);
|
||||||
|
const [selectedStation, setSelectedStation] = useState<Station | null>(null);
|
||||||
|
|
||||||
|
const nextImage = () => {
|
||||||
|
setCurrentImage((prev) => (prev === stations.length - 1 ? 0 : prev + 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
const prevImage = () => {
|
||||||
|
setCurrentImage((prev) => (prev === 0 ? stations.length - 1 : prev - 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='space-y-8'>
|
||||||
|
<div className='relative h-[400px] overflow-hidden rounded-xl shadow-xl md:h-[500px]'>
|
||||||
|
<Image
|
||||||
|
src={stations[currentImage].image || '/placeholder.svg'}
|
||||||
|
alt={stations[currentImage].name}
|
||||||
|
fill
|
||||||
|
className='object-cover'
|
||||||
|
/>
|
||||||
|
<div className='absolute inset-0 flex flex-col justify-end bg-gradient-to-t from-black/70 to-transparent p-6 text-white'>
|
||||||
|
<h3 className='text-2xl font-bold'>{stations[currentImage].name}</h3>
|
||||||
|
<p className='text-white/80'>{stations[currentImage].location}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant='outline'
|
||||||
|
size='icon'
|
||||||
|
className='absolute top-1/2 left-4 -translate-y-1/2 bg-white/80 hover:bg-white'
|
||||||
|
onClick={prevImage}
|
||||||
|
>
|
||||||
|
<ChevronLeft className='h-6 w-6' />
|
||||||
|
<span className='sr-only'>Предыдущая</span>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant='outline'
|
||||||
|
size='icon'
|
||||||
|
className='absolute top-1/2 right-4 -translate-y-1/2 bg-white/80 hover:bg-white'
|
||||||
|
onClick={nextImage}
|
||||||
|
>
|
||||||
|
<ChevronRight className='h-6 w-6' />
|
||||||
|
<span className='sr-only'>Следующая</span>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant='outline'
|
||||||
|
size='icon'
|
||||||
|
className='absolute top-4 right-4 bg-white/80 hover:bg-white'
|
||||||
|
onClick={() => setSelectedStation(stations[currentImage])}
|
||||||
|
>
|
||||||
|
<Maximize className='h-5 w-5' />
|
||||||
|
<span className='sr-only'>Увеличить</span>
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className='max-w-4xl'>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>{stations[currentImage].name}</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
{stations[currentImage].location}
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<div className='relative h-[60vh] w-full'>
|
||||||
|
<Image
|
||||||
|
src={stations[currentImage].image || '/placeholder.svg'}
|
||||||
|
alt={stations[currentImage].name}
|
||||||
|
fill
|
||||||
|
className='object-contain'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='grid grid-cols-3 gap-4 md:grid-cols-6'>
|
||||||
|
{stations.map((station, index) => (
|
||||||
|
<div
|
||||||
|
key={station.id}
|
||||||
|
className={`relative h-20 cursor-pointer overflow-hidden rounded-md transition-all ${
|
||||||
|
index === currentImage
|
||||||
|
? 'ring-2 ring-red-600 ring-offset-2'
|
||||||
|
: 'opacity-70 hover:opacity-100'
|
||||||
|
}`}
|
||||||
|
onClick={() => setCurrentImage(index)}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={station.image || '/placeholder.svg'}
|
||||||
|
alt={station.name}
|
||||||
|
fill
|
||||||
|
className='object-cover'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -13,12 +13,7 @@ export const CtaSection = () => {
|
|||||||
и скидки.
|
и скидки.
|
||||||
</p>
|
</p>
|
||||||
<div className='flex flex-col gap-4 sm:flex-row'>
|
<div className='flex flex-col gap-4 sm:flex-row'>
|
||||||
<Button
|
<Button variant='outline'>Скачать приложение</Button>
|
||||||
variant='outline'
|
|
||||||
className='border-white text-white hover:bg-white/10'
|
|
||||||
>
|
|
||||||
Скачать приложение
|
|
||||||
</Button>
|
|
||||||
<Button className='bg-white text-red-600 hover:bg-gray-100'>
|
<Button className='bg-white text-red-600 hover:bg-gray-100'>
|
||||||
Получить карту лояльности
|
Получить карту лояльности
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
126
src/widgets/header/ui/desktop-nav.tsx
Normal file
126
src/widgets/header/ui/desktop-nav.tsx
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import Link from 'next/link';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { Logo } from '@/shared/assets/logo';
|
||||||
|
import { cn } from '@/shared/lib/utils';
|
||||||
|
import {
|
||||||
|
NavigationMenu,
|
||||||
|
NavigationMenuContent,
|
||||||
|
NavigationMenuItem,
|
||||||
|
NavigationMenuLink,
|
||||||
|
NavigationMenuList,
|
||||||
|
NavigationMenuTrigger,
|
||||||
|
navigationMenuTriggerStyle,
|
||||||
|
} from '@/shared/shadcn-ui/navigation-menu';
|
||||||
|
|
||||||
|
export function DesktopNav() {
|
||||||
|
return (
|
||||||
|
<NavigationMenu className='hidden md:flex'>
|
||||||
|
<NavigationMenuList>
|
||||||
|
<NavigationMenuItem>
|
||||||
|
<Link href='/' legacyBehavior passHref>
|
||||||
|
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
||||||
|
Главная
|
||||||
|
</NavigationMenuLink>
|
||||||
|
</Link>
|
||||||
|
</NavigationMenuItem>
|
||||||
|
<NavigationMenuItem>
|
||||||
|
<Link href='/about' legacyBehavior passHref>
|
||||||
|
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
||||||
|
О нас
|
||||||
|
</NavigationMenuLink>
|
||||||
|
</Link>
|
||||||
|
</NavigationMenuItem>
|
||||||
|
<NavigationMenuItem>
|
||||||
|
<NavigationMenuTrigger>Клиентам</NavigationMenuTrigger>
|
||||||
|
<NavigationMenuContent>
|
||||||
|
<ul className='grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px]'>
|
||||||
|
<li className='row-span-4'>
|
||||||
|
<NavigationMenuLink asChild>
|
||||||
|
<a
|
||||||
|
className='flex h-full w-full flex-col justify-end rounded-md bg-gradient-to-b from-red-500 to-red-700 p-6 no-underline outline-none select-none focus:shadow-md'
|
||||||
|
href='/clients'
|
||||||
|
>
|
||||||
|
<div className='mt-4 mb-2 text-lg font-medium text-white'>
|
||||||
|
Для наших клиентов
|
||||||
|
</div>
|
||||||
|
<p className='text-sm leading-tight text-white/90'>
|
||||||
|
Специальные предложения, программы лояльности и удобные
|
||||||
|
способы оплаты для наших клиентов
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</NavigationMenuLink>
|
||||||
|
</li>
|
||||||
|
<ListItem href='/clients/loyalty' title='Программа лояльности'>
|
||||||
|
Накапливайте баллы и получайте скидки на топливо и услуги
|
||||||
|
</ListItem>
|
||||||
|
<ListItem href='/clients/fuel-card' title='Топливная карта'>
|
||||||
|
Удобный способ оплаты топлива для физических и юридических лиц
|
||||||
|
</ListItem>
|
||||||
|
<ListItem href='/clients/certificates' title='Сертификаты'>
|
||||||
|
Подарочные сертификаты на топливо и услуги нашей сети
|
||||||
|
</ListItem>
|
||||||
|
<ListItem href='/clients/payment' title='Способы оплаты'>
|
||||||
|
Различные способы оплаты на наших заправочных станциях
|
||||||
|
</ListItem>
|
||||||
|
</ul>
|
||||||
|
</NavigationMenuContent>
|
||||||
|
</NavigationMenuItem>
|
||||||
|
<NavigationMenuItem>
|
||||||
|
<Link href='/#stations' legacyBehavior passHref>
|
||||||
|
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
||||||
|
Наши заправки
|
||||||
|
</NavigationMenuLink>
|
||||||
|
</Link>
|
||||||
|
</NavigationMenuItem>
|
||||||
|
<NavigationMenuItem>
|
||||||
|
<Link href='/#vacancies' legacyBehavior passHref>
|
||||||
|
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
||||||
|
Вакансии
|
||||||
|
</NavigationMenuLink>
|
||||||
|
</Link>
|
||||||
|
</NavigationMenuItem>
|
||||||
|
<NavigationMenuItem>
|
||||||
|
<Link href='/#promotions' legacyBehavior passHref>
|
||||||
|
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
||||||
|
Акции
|
||||||
|
</NavigationMenuLink>
|
||||||
|
</Link>
|
||||||
|
</NavigationMenuItem>
|
||||||
|
</NavigationMenuList>
|
||||||
|
</NavigationMenu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ListItemProps extends React.ComponentPropsWithoutRef<'a'> {
|
||||||
|
title: string;
|
||||||
|
href: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListItem = React.forwardRef<React.ComponentRef<'a'>, ListItemProps>(
|
||||||
|
({ className, title, children, href, ...props }, ref) => {
|
||||||
|
return (
|
||||||
|
<li>
|
||||||
|
<NavigationMenuLink asChild>
|
||||||
|
<a
|
||||||
|
ref={ref}
|
||||||
|
href={href}
|
||||||
|
className={cn(
|
||||||
|
'hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground block space-y-1 rounded-md p-3 leading-none no-underline transition-colors outline-none select-none',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<div className='text-sm leading-none font-medium'>{title}</div>
|
||||||
|
<p className='text-muted-foreground line-clamp-2 text-sm leading-snug'>
|
||||||
|
{children}
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</NavigationMenuLink>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
ListItem.displayName = 'ListItem';
|
||||||
@ -1,21 +0,0 @@
|
|||||||
import Link from 'next/link';
|
|
||||||
import { Fragment } from 'react';
|
|
||||||
|
|
||||||
import { navLinks } from '../lib/nav-links';
|
|
||||||
|
|
||||||
export const HeaderNav = () => {
|
|
||||||
return (
|
|
||||||
<nav className='hidden items-center gap-6 md:flex'>
|
|
||||||
{navLinks.map(({ label, href }) => (
|
|
||||||
<Fragment key={href}>
|
|
||||||
<Link
|
|
||||||
href={href}
|
|
||||||
className='text-sm font-medium transition-colors hover:text-red-600'
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</Link>
|
|
||||||
</Fragment>
|
|
||||||
))}
|
|
||||||
</nav>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,14 +1,20 @@
|
|||||||
import { Logo } from '@/shared/assets/logo';
|
import { Logo } from '@/shared/assets/logo';
|
||||||
|
import { Button } from '@/shared/shadcn-ui/button';
|
||||||
|
|
||||||
import { HeaderNav } from './header-nav';
|
import { DesktopNav } from './desktop-nav';
|
||||||
|
import { MobileNav } from './mobile-nav';
|
||||||
|
|
||||||
export const Header = () => {
|
export function Header() {
|
||||||
return (
|
return (
|
||||||
<header className='sticky top-0 z-40 w-full border-b bg-white'>
|
<header className='sticky top-0 z-40 w-full border-b bg-white'>
|
||||||
<div className='container mx-auto flex h-16 items-center justify-between py-4'>
|
<div className='container mx-auto flex h-16 items-center justify-between p-4'>
|
||||||
<Logo />
|
<Logo />
|
||||||
<HeaderNav />
|
<DesktopNav />
|
||||||
|
<div className='flex items-center gap-6 md:contents'>
|
||||||
|
<MobileNav />
|
||||||
|
<Button>Вход</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|||||||
124
src/widgets/header/ui/mobile-nav.tsx
Normal file
124
src/widgets/header/ui/mobile-nav.tsx
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { ChevronDown, ChevronRight, Menu } from 'lucide-react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@/shared/shadcn-ui/button';
|
||||||
|
import {
|
||||||
|
Collapsible,
|
||||||
|
CollapsibleContent,
|
||||||
|
CollapsibleTrigger,
|
||||||
|
} from '@/shared/shadcn-ui/collapsible';
|
||||||
|
import { Sheet, SheetContent, SheetTrigger } from '@/shared/shadcn-ui/sheet';
|
||||||
|
|
||||||
|
export function MobileNav() {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [clientsOpen, setClientsOpen] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Sheet open={open} onOpenChange={setOpen}>
|
||||||
|
<SheetTrigger asChild>
|
||||||
|
<Button variant='ghost' className='md:hidden' size='icon'>
|
||||||
|
<Menu className='h-6 w-6' />
|
||||||
|
<span className='sr-only'>Открыть меню</span>
|
||||||
|
</Button>
|
||||||
|
</SheetTrigger>
|
||||||
|
<SheetContent side='left' className='w-[300px] sm:w-[400px]'>
|
||||||
|
<nav className='mt-8 flex flex-col gap-4'>
|
||||||
|
<Link
|
||||||
|
href='/'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='text-lg font-medium transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Главная
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/about'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='text-lg font-medium transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
О нас
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Collapsible open={clientsOpen} onOpenChange={setClientsOpen}>
|
||||||
|
<CollapsibleTrigger className='data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up flex w-full items-center justify-between text-lg font-medium transition-all hover:text-red-600'>
|
||||||
|
<span>Клиентам</span>
|
||||||
|
{clientsOpen ? (
|
||||||
|
<ChevronDown className='h-5 w-5' />
|
||||||
|
) : (
|
||||||
|
<ChevronRight className='h-5 w-5' />
|
||||||
|
)}
|
||||||
|
</CollapsibleTrigger>
|
||||||
|
<CollapsibleContent className='mt-2 space-y-2 border-l-2 border-gray-200 pl-4'>
|
||||||
|
<Link
|
||||||
|
href='/clients/loyalty'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='block py-1 text-base transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Программа лояльности
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/clients/fuel-card'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='block py-1 text-base transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Топливная карта
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/clients/certificates'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='block py-1 text-base transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Сертификаты
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/clients/payment'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='block py-1 text-base transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Способы оплаты
|
||||||
|
</Link>
|
||||||
|
</CollapsibleContent>
|
||||||
|
</Collapsible>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
href='/#stations'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='text-lg font-medium transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Наши заправки
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/#vacancies'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='text-lg font-medium transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Вакансии
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/#promotions'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='text-lg font-medium transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Акции
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/#partners'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='text-lg font-medium transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Партнеры
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/#charity'
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
className='text-lg font-medium transition-colors hover:text-red-600'
|
||||||
|
>
|
||||||
|
Благотворительность
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
</SheetContent>
|
||||||
|
</Sheet>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -28,7 +28,7 @@ module.exports = {
|
|||||||
background: 'hsl(var(--background))',
|
background: 'hsl(var(--background))',
|
||||||
foreground: 'hsl(var(--foreground))',
|
foreground: 'hsl(var(--foreground))',
|
||||||
primary: {
|
primary: {
|
||||||
DEFAULT: '#e11d48', // Red-600 for primary // hsl(var(--primary))
|
DEFAULT: 'hsl(var(--primary))',
|
||||||
foreground: 'hsl(var(--primary-foreground))',
|
foreground: 'hsl(var(--primary-foreground))',
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user