change
This commit is contained in:
parent
47f36f7ed3
commit
ed3676a0ec
|
|
@ -23,6 +23,7 @@
|
||||||
"embla-carousel-autoplay": "^8.5.2",
|
"embla-carousel-autoplay": "^8.5.2",
|
||||||
"embla-carousel-react": "^8.5.2",
|
"embla-carousel-react": "^8.5.2",
|
||||||
"i18next": "^24.2.2",
|
"i18next": "^24.2.2",
|
||||||
|
"locomotive-scroll": "^4.1.4",
|
||||||
"lucide-react": "^0.473.0",
|
"lucide-react": "^0.473.0",
|
||||||
"motion": "^12.0.1",
|
"motion": "^12.0.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
|
|
@ -38,12 +39,12 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.17.0",
|
"@eslint/js": "^9.17.0",
|
||||||
|
"@types/locomotive-scroll": "^4.1.4",
|
||||||
"@types/node": "^22.12.0",
|
"@types/node": "^22.12.0",
|
||||||
"@types/react": "^18.3.18",
|
"@types/react": "^18.3.18",
|
||||||
"@types/react-dom": "^18.3.5",
|
"@types/react-dom": "^18.3.5",
|
||||||
"@vitejs/plugin-react-swc": "^3.5.0",
|
"@vitejs/plugin-react-swc": "^3.5.0",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"eslint": "^9.17.0",
|
|
||||||
"eslint-plugin-react-hooks": "^5.0.0",
|
"eslint-plugin-react-hooks": "^5.0.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.16",
|
"eslint-plugin-react-refresh": "^0.4.16",
|
||||||
"globals": "^15.14.0",
|
"globals": "^15.14.0",
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@ importers:
|
||||||
i18next:
|
i18next:
|
||||||
specifier: ^24.2.2
|
specifier: ^24.2.2
|
||||||
version: 24.2.2(typescript@5.6.3)
|
version: 24.2.2(typescript@5.6.3)
|
||||||
|
locomotive-scroll:
|
||||||
|
specifier: ^4.1.4
|
||||||
|
version: 4.1.4
|
||||||
lucide-react:
|
lucide-react:
|
||||||
specifier: ^0.473.0
|
specifier: ^0.473.0
|
||||||
version: 0.473.0(react@18.3.1)
|
version: 0.473.0(react@18.3.1)
|
||||||
|
|
@ -87,6 +90,9 @@ importers:
|
||||||
'@eslint/js':
|
'@eslint/js':
|
||||||
specifier: ^9.17.0
|
specifier: ^9.17.0
|
||||||
version: 9.19.0
|
version: 9.19.0
|
||||||
|
'@types/locomotive-scroll':
|
||||||
|
specifier: ^4.1.4
|
||||||
|
version: 4.1.4
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.12.0
|
specifier: ^22.12.0
|
||||||
version: 22.12.0
|
version: 22.12.0
|
||||||
|
|
@ -102,9 +108,6 @@ importers:
|
||||||
autoprefixer:
|
autoprefixer:
|
||||||
specifier: ^10.4.20
|
specifier: ^10.4.20
|
||||||
version: 10.4.20(postcss@8.5.1)
|
version: 10.4.20(postcss@8.5.1)
|
||||||
eslint:
|
|
||||||
specifier: ^9.17.0
|
|
||||||
version: 9.19.0(jiti@1.21.7)
|
|
||||||
eslint-plugin-react-hooks:
|
eslint-plugin-react-hooks:
|
||||||
specifier: ^5.0.0
|
specifier: ^5.0.0
|
||||||
version: 5.1.0(eslint@9.19.0(jiti@1.21.7))
|
version: 5.1.0(eslint@9.19.0(jiti@1.21.7))
|
||||||
|
|
@ -881,6 +884,9 @@ packages:
|
||||||
'@types/json-schema@7.0.15':
|
'@types/json-schema@7.0.15':
|
||||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||||
|
|
||||||
|
'@types/locomotive-scroll@4.1.4':
|
||||||
|
resolution: {integrity: sha512-G8GUr/ML/Ssxxl83VYbtFHMFoPNOQh/glzPWi5Z3Jk7Hng26Sl0ckAV11uq1AGKEq40jFMPhyAIuQ6fGPiBmHQ==}
|
||||||
|
|
||||||
'@types/node@22.12.0':
|
'@types/node@22.12.0':
|
||||||
resolution: {integrity: sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==}
|
resolution: {integrity: sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==}
|
||||||
|
|
||||||
|
|
@ -1009,10 +1015,16 @@ packages:
|
||||||
balanced-match@1.0.2:
|
balanced-match@1.0.2:
|
||||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||||
|
|
||||||
|
bezier-easing@2.1.0:
|
||||||
|
resolution: {integrity: sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==}
|
||||||
|
|
||||||
binary-extensions@2.3.0:
|
binary-extensions@2.3.0:
|
||||||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
bindall-standalone@1.0.5:
|
||||||
|
resolution: {integrity: sha512-HDI7YBWXVJk/eoGz+e4lYQQJnYp1ZHcUvAY71lVptLMhQnDm86vD73AGPw2qIlgYR3P0bjmoAcXiA8qhFejBhA==}
|
||||||
|
|
||||||
brace-expansion@1.1.11:
|
brace-expansion@1.1.11:
|
||||||
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
||||||
|
|
||||||
|
|
@ -1397,6 +1409,9 @@ packages:
|
||||||
keyv@4.5.4:
|
keyv@4.5.4:
|
||||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||||
|
|
||||||
|
lethargy@1.0.9:
|
||||||
|
resolution: {integrity: sha512-nFM8blpCF9rqIL5mRAaTGc78W8oQixVtsD86jbEPvcI13+lDUYJf3R7DZQQL7tCiBpbGpGKMX2gwJFO9hiaOkg==}
|
||||||
|
|
||||||
levn@0.4.1:
|
levn@0.4.1:
|
||||||
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
@ -1412,6 +1427,9 @@ packages:
|
||||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
locomotive-scroll@4.1.4:
|
||||||
|
resolution: {integrity: sha512-6i98cFF2SKg6wIPpwVPuo2FG8qL3USsdDeew78TEYZyLoqleMWNfkSDpWA6mPym4dOfTIBXc678VmGlkgx3fTA==}
|
||||||
|
|
||||||
lodash.debounce@4.0.8:
|
lodash.debounce@4.0.8:
|
||||||
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||||
|
|
||||||
|
|
@ -1743,6 +1761,9 @@ packages:
|
||||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
|
smoothscroll-polyfill@0.4.4:
|
||||||
|
resolution: {integrity: sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==}
|
||||||
|
|
||||||
source-map-js@1.2.1:
|
source-map-js@1.2.1:
|
||||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
@ -1800,6 +1821,9 @@ packages:
|
||||||
thenify@3.3.1:
|
thenify@3.3.1:
|
||||||
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
||||||
|
|
||||||
|
tiny-emitter@1.2.0:
|
||||||
|
resolution: {integrity: sha512-rWjF00inHeWtT5UbQYAXoMI4hL6TRMqohuKCsODyPYYmfAxqfMnXLsIeNrbdPEkNxlk++rojVilTnI9IVmEBtA==}
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||||
engines: {node: '>=8.0'}
|
engines: {node: '>=8.0'}
|
||||||
|
|
@ -1876,6 +1900,9 @@ packages:
|
||||||
util-deprecate@1.0.2:
|
util-deprecate@1.0.2:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
|
virtual-scroll@1.5.2:
|
||||||
|
resolution: {integrity: sha512-7jDHwlKbHUho7CYU/HojE/VKFH8GV9P5fVWP2HCa7dRUOpVvwl93OBOKIIcb2mKd+vqsbVR/0zl0X70+3sUZqA==}
|
||||||
|
|
||||||
vite@6.0.11:
|
vite@6.0.11:
|
||||||
resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==}
|
resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==}
|
||||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||||
|
|
@ -2558,6 +2585,8 @@ snapshots:
|
||||||
|
|
||||||
'@types/json-schema@7.0.15': {}
|
'@types/json-schema@7.0.15': {}
|
||||||
|
|
||||||
|
'@types/locomotive-scroll@4.1.4': {}
|
||||||
|
|
||||||
'@types/node@22.12.0':
|
'@types/node@22.12.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.20.0
|
undici-types: 6.20.0
|
||||||
|
|
@ -2717,8 +2746,12 @@ snapshots:
|
||||||
|
|
||||||
balanced-match@1.0.2: {}
|
balanced-match@1.0.2: {}
|
||||||
|
|
||||||
|
bezier-easing@2.1.0: {}
|
||||||
|
|
||||||
binary-extensions@2.3.0: {}
|
binary-extensions@2.3.0: {}
|
||||||
|
|
||||||
|
bindall-standalone@1.0.5: {}
|
||||||
|
|
||||||
brace-expansion@1.1.11:
|
brace-expansion@1.1.11:
|
||||||
dependencies:
|
dependencies:
|
||||||
balanced-match: 1.0.2
|
balanced-match: 1.0.2
|
||||||
|
|
@ -3101,6 +3134,8 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
json-buffer: 3.0.1
|
json-buffer: 3.0.1
|
||||||
|
|
||||||
|
lethargy@1.0.9: {}
|
||||||
|
|
||||||
levn@0.4.1:
|
levn@0.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
prelude-ls: 1.2.1
|
prelude-ls: 1.2.1
|
||||||
|
|
@ -3114,6 +3149,12 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
p-locate: 5.0.0
|
p-locate: 5.0.0
|
||||||
|
|
||||||
|
locomotive-scroll@4.1.4:
|
||||||
|
dependencies:
|
||||||
|
bezier-easing: 2.1.0
|
||||||
|
smoothscroll-polyfill: 0.4.4
|
||||||
|
virtual-scroll: 1.5.2
|
||||||
|
|
||||||
lodash.debounce@4.0.8: {}
|
lodash.debounce@4.0.8: {}
|
||||||
|
|
||||||
lodash.merge@4.6.2: {}
|
lodash.merge@4.6.2: {}
|
||||||
|
|
@ -3405,6 +3446,8 @@ snapshots:
|
||||||
|
|
||||||
signal-exit@4.1.0: {}
|
signal-exit@4.1.0: {}
|
||||||
|
|
||||||
|
smoothscroll-polyfill@0.4.4: {}
|
||||||
|
|
||||||
source-map-js@1.2.1: {}
|
source-map-js@1.2.1: {}
|
||||||
|
|
||||||
string-width@4.2.3:
|
string-width@4.2.3:
|
||||||
|
|
@ -3486,6 +3529,8 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
any-promise: 1.3.0
|
any-promise: 1.3.0
|
||||||
|
|
||||||
|
tiny-emitter@1.2.0: {}
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-number: 7.0.0
|
is-number: 7.0.0
|
||||||
|
|
@ -3550,6 +3595,13 @@ snapshots:
|
||||||
|
|
||||||
util-deprecate@1.0.2: {}
|
util-deprecate@1.0.2: {}
|
||||||
|
|
||||||
|
virtual-scroll@1.5.2:
|
||||||
|
dependencies:
|
||||||
|
bindall-standalone: 1.0.5
|
||||||
|
lethargy: 1.0.9
|
||||||
|
object-assign: 4.1.1
|
||||||
|
tiny-emitter: 1.2.0
|
||||||
|
|
||||||
vite@6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0):
|
vite@6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.24.2
|
esbuild: 0.24.2
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { useEffect, useRef, type PropsWithChildren } from "react";
|
||||||
|
import "locomotive-scroll/dist/locomotive-scroll.css";
|
||||||
|
|
||||||
|
type SmoothScrollProps = {
|
||||||
|
className?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SmoothScroll = ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
}: PropsWithChildren<SmoothScrollProps>) => {
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
let locomotiveScroll: any;
|
||||||
|
|
||||||
|
const initScroll = async () => {
|
||||||
|
const LocomotiveScroll = (await import("locomotive-scroll")).default;
|
||||||
|
|
||||||
|
if (containerRef.current) {
|
||||||
|
if (locomotiveScroll) locomotiveScroll.destroy();
|
||||||
|
|
||||||
|
locomotiveScroll = new LocomotiveScroll({
|
||||||
|
el: containerRef.current,
|
||||||
|
smooth: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const scrollbars = document.querySelectorAll(".c-scrollbar");
|
||||||
|
if (scrollbars.length > 1) {
|
||||||
|
scrollbars[1].remove();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
initScroll();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
locomotiveScroll?.destroy();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<main ref={containerRef} className={className} data-scroll-container>
|
||||||
|
{children}
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SmoothScroll;
|
||||||
|
|
@ -1,38 +1,132 @@
|
||||||
import { FC } from "react";
|
import { FC, useEffect, useState } from "react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import { Dialog, DialogContent, DialogTrigger } from "../ui/dialog";
|
||||||
|
import useEmblaCarousel from "embla-carousel-react";
|
||||||
|
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
imgUrl: string;
|
|
||||||
name: string;
|
name: string;
|
||||||
info: string;
|
biography: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
achievements: {
|
||||||
|
ru: string;
|
||||||
|
en: string;
|
||||||
|
}[];
|
||||||
|
image: { path: string };
|
||||||
|
images: { path: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DesignerCard: FC<Props> = ({ className, ...props }) => {
|
export const DesignerCard: FC<Props> = ({
|
||||||
|
className,
|
||||||
|
name,
|
||||||
|
achievements,
|
||||||
|
biography,
|
||||||
|
image,
|
||||||
|
images,
|
||||||
|
}) => {
|
||||||
|
const [emblaRef, emblaApi] = useEmblaCarousel({});
|
||||||
|
const [canScrollPrev, setCanScrollPrev] = useState(false);
|
||||||
|
const [canScrollNext, setCanScrollNext] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!emblaApi) return;
|
||||||
|
|
||||||
|
const onSelect = () => {
|
||||||
|
setCanScrollPrev(emblaApi.canScrollPrev());
|
||||||
|
setCanScrollNext(emblaApi.canScrollNext());
|
||||||
|
};
|
||||||
|
|
||||||
|
emblaApi.on("select", onSelect);
|
||||||
|
onSelect();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
emblaApi.off("select", onSelect);
|
||||||
|
};
|
||||||
|
}, [emblaApi]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article
|
<Dialog>
|
||||||
className={cn(
|
<DialogTrigger
|
||||||
"relative bg-[url('/impressions/card-bg.png')] bg-no-repeat h-[326px] overflow-hidden",
|
className={cn(
|
||||||
className
|
"relative bg-[url('/impressions/card-bg.png')] bg-no-repeat h-[326px] overflow-hidden",
|
||||||
)}
|
className
|
||||||
>
|
)}
|
||||||
<img
|
>
|
||||||
src="/impressions/card-bg-bg.png"
|
<article>
|
||||||
className="absolute top-2.5 left-2.5 -z-10 size-full"
|
<img
|
||||||
/>
|
src="/impressions/card-bg-bg.png"
|
||||||
|
className="absolute top-2.5 left-2.5 -z-10 size-full"
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex gap-4">
|
||||||
<img
|
<img
|
||||||
src={props.imgUrl}
|
src={image?.path}
|
||||||
alt=""
|
alt={name}
|
||||||
className="flex-[0_0_44%] object-contain overflow-hidden"
|
className="flex-[0_0_44%] -mt-2.5 object-contain overflow-hidden"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="flex-auto z-20">
|
<div className="flex-auto text-left text-white z-20 pt-6 pl-4 pr-4">
|
||||||
<h3>{props.name}</h3>
|
<h3 className="text-xl mb-2">{name}</h3>
|
||||||
<p>{props.info}</p>
|
<ul className="text-sm list-disc pl-4 flex flex-col gap-2">
|
||||||
|
{achievements.slice(0, 7).map((item, i) => (
|
||||||
|
<li key={i}>{item.ru}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</DialogTrigger>
|
||||||
|
|
||||||
|
<DialogContent className="p-6 flex flex-col gap-4 xl:!w-[1224px] max-h-[80vh]">
|
||||||
|
<div className="flex gap-4 overflow-y-auto">
|
||||||
|
<div className="flex-1 h-[345px]">
|
||||||
|
<img src={image?.path} alt="" className="size-full object-cover" />
|
||||||
|
</div>
|
||||||
|
<div className="flex-[0_0_70%]">
|
||||||
|
<div className="text-2xl mb-4">{name}</div>
|
||||||
|
<hr />
|
||||||
|
<div
|
||||||
|
className="mt-4 flex flex-col gap-3 normal"
|
||||||
|
dangerouslySetInnerHTML={{ __html: biography }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<hr />
|
||||||
</article>
|
|
||||||
|
<div>
|
||||||
|
<h3 className="text-xl mb-2.5">Работы дизайнера</h3>
|
||||||
|
<div ref={emblaRef} className="embla overflow-hidden">
|
||||||
|
<div className="embla__container items-center flex gap-4">
|
||||||
|
{canScrollPrev && (
|
||||||
|
<ChevronLeftIcon
|
||||||
|
onClick={() => canScrollPrev && emblaApi?.scrollPrev()}
|
||||||
|
className={cn(
|
||||||
|
"cursor-pointer",
|
||||||
|
!canScrollPrev && "opacity-20"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
{images.map((item) => (
|
||||||
|
<img
|
||||||
|
src={item?.path}
|
||||||
|
className="size-[140px] object-cover object-top"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{canScrollNext && (
|
||||||
|
<ChevronRightIcon
|
||||||
|
onClick={() => canScrollPrev && emblaApi?.scrollNext()}
|
||||||
|
className={cn(
|
||||||
|
"cursor-pointer",
|
||||||
|
!canScrollNext && "opacity-20"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { Container } from "@/components/layout";
|
||||||
|
import { DesignerCard, Loader } from "../";
|
||||||
|
import useEmblaCarousel from "embla-carousel-react";
|
||||||
|
import { useDesigners } from "@/hooks/tanstack/use-designers";
|
||||||
|
|
||||||
|
const Designers = () => {
|
||||||
|
const [emblaRef] = useEmblaCarousel({ align: "center" });
|
||||||
|
|
||||||
|
const { data, isPending } = useDesigners(1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="py-[200px]">
|
||||||
|
<Container className="flex flex-col gap-10">
|
||||||
|
<h2 className="text-5xl">Дизайнеры одежды</h2>
|
||||||
|
|
||||||
|
<div ref={emblaRef} className="embla">
|
||||||
|
<div className="flex embla__container">
|
||||||
|
{isPending ? (
|
||||||
|
<Loader />
|
||||||
|
) : (
|
||||||
|
data?.designers?.map((item, i) => (
|
||||||
|
<DesignerCard
|
||||||
|
key={i}
|
||||||
|
{...item}
|
||||||
|
className="embla__slide flex-[0_0_714px] mr-4"
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Designers;
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { Container } from "@/components/layout";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
const Hero = () => {
|
||||||
|
const { t } = useTranslation("main");
|
||||||
|
|
||||||
|
const { title, texts, button, button2 } = t("impressions.hero", {
|
||||||
|
returnObjects: true,
|
||||||
|
}) as { title: string; texts: string[]; button: string; button2: string };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="">
|
||||||
|
<img
|
||||||
|
src="/impressions-cover.png"
|
||||||
|
alt=""
|
||||||
|
className="w-full object-contain max-h-[610px]"
|
||||||
|
/>
|
||||||
|
<h1 className="absolute opacity-0 top-0 left-0">Показы</h1>
|
||||||
|
|
||||||
|
<div className="bg-[url('/impressions-bg.png')]">
|
||||||
|
<Container className="py-20">
|
||||||
|
<h2 className="text-5xl leading-[120%] mb-10">{title}</h2>
|
||||||
|
<div className="text-on_surface_v flex flex-col gap-3">
|
||||||
|
{texts.map((item, i) => (
|
||||||
|
<p key={i}>{item}</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-6 mt-6">
|
||||||
|
<Button size={"sm"} className="w-full">
|
||||||
|
{button}
|
||||||
|
</Button>
|
||||||
|
<Button size={"sm"} className="w-full">
|
||||||
|
{button2}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Hero;
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
export { default as Hero } from "./hero";
|
||||||
|
export { default as Videos } from "./videos";
|
||||||
|
export { default as Designers } from "./designers";
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { Container } from "@/components/layout";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
const Videos = () => {
|
||||||
|
const { t } = useTranslation("main");
|
||||||
|
|
||||||
|
const title = t("impressions.videosTitle");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="bg-[url('/impressions/videos-block-bg.png')] py-20">
|
||||||
|
<Container>
|
||||||
|
<h2 className="mb-10 text-5xl leading-[120%] text-white">{title}</h2>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-[1fr_32.5%] gap-4 text-white overflow-hidden h-auto md:h-[497px]">
|
||||||
|
{/* FIRST BLOCK */}
|
||||||
|
<div className="bg-gray_10 p-2 rounded-[8px] border border-gray_09 flex flex-col h-full">
|
||||||
|
<div className="max-h-[453px]">
|
||||||
|
<video
|
||||||
|
src="https://turkmentextile.turkmenexpo.com/app/storage/app/media/video/Textile2025.mp4"
|
||||||
|
muted
|
||||||
|
controls
|
||||||
|
autoPlay
|
||||||
|
loop
|
||||||
|
className="w-full size-full mb-2 rounded"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-between mt-auto">
|
||||||
|
<h3 className="text-sm">
|
||||||
|
Алена Ахмадуллина | 'Царевна-Лебедь' (74 симв.)
|
||||||
|
</h3>
|
||||||
|
<span className="text-xs normal">1/10</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* SECOND BLOCK */}
|
||||||
|
<div className="bg-gray_10 px-2 pt-2 rounded-[8px] border border-gray_09 flex flex-col h-full min-h-0">
|
||||||
|
<div className="flex items-center justify-between mb-2">
|
||||||
|
<h3 className="text-sm">Смотрите также</h3>
|
||||||
|
<span className="text-xs normal">1/10</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2 overflow-y-auto flex-grow">
|
||||||
|
{[...Array(10)].map((_, i) => (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
className="h-[59px] w-full flex items-center gap-2"
|
||||||
|
>
|
||||||
|
<div className="flex-[0_0_27%]">
|
||||||
|
<img
|
||||||
|
src="/impressions/test.png"
|
||||||
|
alt=""
|
||||||
|
className="object-contain rounded-tl rounded-bl"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<h3 className="text-sm">
|
||||||
|
Алена Ахмадуллина | 'Царевна-Лебедь' 'Царевна-Лебедь' |
|
||||||
|
Алена Ахмадуллина
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Videos;
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { getDesigners } from "@/services/service";
|
||||||
|
import { useLangStore } from "@/store/lang";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
export const useDesigners = (id: number) => {
|
||||||
|
const lang = useLangStore((state) => state.lang);
|
||||||
|
|
||||||
|
const { data, isPending } = useQuery({
|
||||||
|
queryKey: ["designers", lang],
|
||||||
|
queryFn: () => getDesigners(lang, id),
|
||||||
|
select: ({ data }) => data.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { data, isPending };
|
||||||
|
};
|
||||||
|
|
@ -13,6 +13,9 @@ import homeRu from "./locales/ru/home.json";
|
||||||
import aboutEn from "./locales/en/about.json";
|
import aboutEn from "./locales/en/about.json";
|
||||||
import aboutRu from "./locales/ru/about.json";
|
import aboutRu from "./locales/ru/about.json";
|
||||||
|
|
||||||
|
import mainEn from "./locales/en/main.json";
|
||||||
|
import mainRu from "./locales/ru/main.json";
|
||||||
|
|
||||||
import contactsEn from "./locales/en/contacts.json";
|
import contactsEn from "./locales/en/contacts.json";
|
||||||
import contactsRu from "./locales/ru/contacts.json";
|
import contactsRu from "./locales/ru/contacts.json";
|
||||||
|
|
||||||
|
|
@ -28,6 +31,7 @@ i18n.use(initReactI18next).init({
|
||||||
home: homeEn,
|
home: homeEn,
|
||||||
about: aboutEn,
|
about: aboutEn,
|
||||||
contacts: contactsEn,
|
contacts: contactsEn,
|
||||||
|
main: mainEn,
|
||||||
},
|
},
|
||||||
ru: {
|
ru: {
|
||||||
nav: navRu,
|
nav: navRu,
|
||||||
|
|
@ -35,11 +39,12 @@ i18n.use(initReactI18next).init({
|
||||||
home: homeRu,
|
home: homeRu,
|
||||||
about: aboutRu,
|
about: aboutRu,
|
||||||
contacts: contactsRu,
|
contacts: contactsRu,
|
||||||
|
main: mainRu,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
lng: initialLanguage, // Язык по умолчанию
|
lng: initialLanguage, // Язык по умолчанию
|
||||||
fallbackLng: "en",
|
fallbackLng: "en",
|
||||||
ns: ["home", "about", "header", "contacts", "nav"], // список namespaces
|
ns: ["home", "about", "header", "contacts", "nav", "main"], // список namespaces
|
||||||
defaultNS: "home", // namespace по умолчанию (можно менять в компонентах)
|
defaultNS: "home", // namespace по умолчанию (можно менять в компонентах)
|
||||||
interpolation: {
|
interpolation: {
|
||||||
escapeValue: false, // React уже экранирует значения
|
escapeValue: false, // React уже экранирует значения
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@
|
||||||
font-family: "Gilroy-Medium";
|
font-family: "Gilroy-Medium";
|
||||||
@apply bg-background;
|
@apply bg-background;
|
||||||
}
|
}
|
||||||
|
.c-scrollbar .c-scrollbar_thumb {
|
||||||
|
background-color: #99101d !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer utilities {
|
@layer utilities {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"impressions": {
|
||||||
|
"hero": {
|
||||||
|
"title": "TurkmenTextile Expo-2025 – Перекресток стиля на Шелковом Пути!",
|
||||||
|
"texts": [
|
||||||
|
"От самого сердца Великого Шелкового пути — к сияющим вершинам мировой моды!",
|
||||||
|
"TurkmenTextile Expo-2025 приглашает вас в увлекательное путешествие, где встречаются вековые традиции, самые актуальные тренды и безграничный талант дизайнеров со всего мира. Это гармония, созданная вдохновением и мастерством.",
|
||||||
|
"Не упустите возможность стать частью этого грандиозного события! Присоединяйтесь к нам с 11 по 13 июня в Торгово-Промышленной Палате Туркменистана, Ашхабад."
|
||||||
|
],
|
||||||
|
"button": "Добавить в календарь (.ics файл)",
|
||||||
|
"button2": "Скачать программу"
|
||||||
|
},
|
||||||
|
"designers": {
|
||||||
|
"title": "Познакомьтесь с мастерами стиля: известные дизайнеры на TurkmenTextile Expo-2025!!",
|
||||||
|
"text": "С гордостью представляем талантливых дизайнеров из Туркменистана, чьи амбициозные проекты отличаются высочайшим качеством исполнения. Аккуратность пошива и идеально точный крой — это лишь часть того, что делает их коллекции по-настоящему выдающимися. Их смелый взгляд на будущее, органично переплетенный с богатым культурным наследием, создает уникальные произведения, готовые покорить самую широкую аудиторию и продемонстрировать мировой уровень мастерства туркменских модельеров."
|
||||||
|
},
|
||||||
|
"videosTitle": "Погрузитесь в триумф дизайнеров на подиуме TurkmenTextile Expo- 2025"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"impressions": {
|
||||||
|
"hero": {
|
||||||
|
"title": "TurkmenTextile Expo-2025 – Перекресток стиля на Шелковом Пути!",
|
||||||
|
"texts": [
|
||||||
|
"От самого сердца Великого Шелкового пути — к сияющим вершинам мировой моды!",
|
||||||
|
"TurkmenTextile Expo-2025 приглашает вас в увлекательное путешествие, где встречаются вековые традиции, самые актуальные тренды и безграничный талант дизайнеров со всего мира. Это гармония, созданная вдохновением и мастерством.",
|
||||||
|
"Не упустите возможность стать частью этого грандиозного события! Присоединяйтесь к нам с 11 по 13 июня в Торгово-Промышленной Палате Туркменистана, Ашхабад."
|
||||||
|
],
|
||||||
|
"button": "Добавить в календарь (.ics файл)",
|
||||||
|
"button2": "Скачать программу"
|
||||||
|
},
|
||||||
|
"designers": {
|
||||||
|
"title": "Познакомьтесь с мастерами стиля: известные дизайнеры на TurkmenTextile Expo-2025!!",
|
||||||
|
"text": "С гордостью представляем талантливых дизайнеров из Туркменистана, чьи амбициозные проекты отличаются высочайшим качеством исполнения. Аккуратность пошива и идеально точный крой — это лишь часть того, что делает их коллекции по-настоящему выдающимися. Их смелый взгляд на будущее, органично переплетенный с богатым культурным наследием, создает уникальные произведения, готовые покорить самую широкую аудиторию и продемонстрировать мировой уровень мастерства туркменских модельеров."
|
||||||
|
},
|
||||||
|
"videosTitle": "Погрузитесь в триумф дизайнеров на подиуме TurkmenTextile Expo- 2025"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,80 +1,15 @@
|
||||||
import { Container } from "@/components/layout";
|
import { Designers, Hero, Videos } from "@/components/shared/impressions";
|
||||||
import { DesignerCard } from "@/components/shared";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { useScrollTop } from "@/hooks/use-scroll-top";
|
import { useScrollTop } from "@/hooks/use-scroll-top";
|
||||||
import useEmblaCarousel from "embla-carousel-react";
|
|
||||||
|
|
||||||
export default function Impressions() {
|
export default function Impressions() {
|
||||||
useScrollTop();
|
useScrollTop();
|
||||||
|
|
||||||
const [emblaRef] = useEmblaCarousel({ align: "center" });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overflow-x-hidden">
|
<div className="overflow-x-hidden">
|
||||||
<section className="">
|
<Hero />
|
||||||
<img
|
<Videos />
|
||||||
src="/impressions-cover.png"
|
<Designers />
|
||||||
alt=""
|
|
||||||
className="w-full object-contain max-h-[610px]"
|
|
||||||
/>
|
|
||||||
<h1 className="absolute opacity-0 top-0 left-0">Показы</h1>
|
|
||||||
|
|
||||||
<div className="bg-[url('/impressions-bg.png')] py-[200px] ">
|
|
||||||
<Container className="grid grid-cols-2 gap-6 h-[570px]">
|
|
||||||
<div className="flex flex-col gap-6 justify-center">
|
|
||||||
<h2 className="text-5xl leading-[120%]">
|
|
||||||
Дефиле туркменской моды на выставке "ТуркменТекстиль"
|
|
||||||
</h2>
|
|
||||||
<p className="text-on_surface_v normal text-base">
|
|
||||||
В рамках международной выставки "Туркмен текстиль" состоятся
|
|
||||||
эксклюзивные показы коллекций ведущих туркменских дизайнеров и
|
|
||||||
Домов моды. Гости мероприятия смогут оценить высокое мастерство
|
|
||||||
исполнения, богатство национальных традиций в современном
|
|
||||||
прочтении и актуальные тенденции текстильной индустрии
|
|
||||||
Туркменистана, воплощенные в уникальных моделях одежды и
|
|
||||||
аксессуаров.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="relative">
|
|
||||||
<img
|
|
||||||
src="/impressions/gallery-1.png"
|
|
||||||
alt="impression image"
|
|
||||||
className="absolute top-0 right-0 z-10 shadow-xl drop-shadow-sm"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
src="/impressions/gallery-2.png"
|
|
||||||
className="absolute left-0 top-1/4 shadow-xl drop-shadow-sm"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
src="/impressions/gallery-3.png"
|
|
||||||
alt=""
|
|
||||||
className="absolute bottom-0 right-0 z-10 shadow-xl drop-shadow-sm"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Container>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section className="py-[200px]">
|
|
||||||
<Container className="flex flex-col gap-10">
|
|
||||||
<h2 className="text-5xl">Дизайнеры одежды</h2>
|
|
||||||
|
|
||||||
<div ref={emblaRef} className="embla">
|
|
||||||
<div className="flex embla__container">
|
|
||||||
{[...Array(9)].map((_, i) => (
|
|
||||||
<DesignerCard
|
|
||||||
key={i}
|
|
||||||
name="Batyr"
|
|
||||||
info="test tesat tesxt test"
|
|
||||||
imgUrl="/impressions/designer.png"
|
|
||||||
className="embla__slide flex-[0_0_714px] mr-4"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Container>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section className="bg-[url('/CTA.png')] py-20 ">
|
<section className="bg-[url('/CTA.png')] py-20 ">
|
||||||
<div className="flex flex-col gap-6 text-center max-w-[808px] mx-auto">
|
<div className="flex flex-col gap-6 text-center max-w-[808px] mx-auto">
|
||||||
<h3 className="text-white text-3xl">
|
<h3 className="text-white text-3xl">
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import { NewsInnerType, NewsType } from "./types/news.type";
|
||||||
import { ParticipantsType } from "./types/participants.type";
|
import { ParticipantsType } from "./types/participants.type";
|
||||||
import { PhotoTypes } from "./types/photo.type";
|
import { PhotoTypes } from "./types/photo.type";
|
||||||
import { VideoTypes } from "./types/videos.type";
|
import { VideoTypes } from "./types/videos.type";
|
||||||
|
import { DesignersType } from "./types/designers.type";
|
||||||
|
|
||||||
const axios_url = axios.create({
|
const axios_url = axios.create({
|
||||||
baseURL: "https://turkmentextile.turkmenexpo.com/app/api/v1/",
|
baseURL: "https://turkmentextile.turkmenexpo.com/app/api/v1/",
|
||||||
|
|
@ -160,6 +161,7 @@ export const getVideos = async (id: number) => {
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSponsors = async (lang: LangState["lang"]) => {
|
export const getSponsors = async (lang: LangState["lang"]) => {
|
||||||
const data = axios_url<PartnersType>("sponsors_and_partners", {
|
const data = axios_url<PartnersType>("sponsors_and_partners", {
|
||||||
headers: {
|
headers: {
|
||||||
|
|
@ -169,3 +171,13 @@ export const getSponsors = async (lang: LangState["lang"]) => {
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getDesigners = async (lang: LangState["lang"], id: number) => {
|
||||||
|
const data = axios_url<DesignersType>("designers/category/" + id, {
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": lang,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
export interface DesignerImage {
|
||||||
|
id: number;
|
||||||
|
disk_name: string;
|
||||||
|
file_name: string;
|
||||||
|
file_size: number;
|
||||||
|
content_type: string;
|
||||||
|
title: string | null;
|
||||||
|
description: string | null;
|
||||||
|
field: string;
|
||||||
|
sort_order: number;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
path: string;
|
||||||
|
extension: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Achievement {
|
||||||
|
ru: string;
|
||||||
|
en: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Designer {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
biography: string;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
category_designer_id: number;
|
||||||
|
achievements: Achievement[];
|
||||||
|
order_id: number | null;
|
||||||
|
image: DesignerImage;
|
||||||
|
images: DesignerImage[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Datum {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
designers: Designer[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DesignersType {
|
||||||
|
status: string;
|
||||||
|
data: Datum;
|
||||||
|
}
|
||||||
|
|
@ -47,6 +47,9 @@ export default {
|
||||||
outline_v: "#D0D3D8",
|
outline_v: "#D0D3D8",
|
||||||
background: "#F9F9FA",
|
background: "#F9F9FA",
|
||||||
surface_container: "#EEEDF4",
|
surface_container: "#EEEDF4",
|
||||||
|
|
||||||
|
gray_10: "#433C3D",
|
||||||
|
gray_09: "#595051",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue