diff --git a/package.json b/package.json index 7bd657b..7362488 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "embla-carousel-autoplay": "^8.5.2", "embla-carousel-react": "^8.5.2", "i18next": "^24.2.2", + "locomotive-scroll": "^4.1.4", "lucide-react": "^0.473.0", "motion": "^12.0.1", "react": "^18.3.1", @@ -38,12 +39,12 @@ }, "devDependencies": { "@eslint/js": "^9.17.0", + "@types/locomotive-scroll": "^4.1.4", "@types/node": "^22.12.0", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@vitejs/plugin-react-swc": "^3.5.0", "autoprefixer": "^10.4.20", - "eslint": "^9.17.0", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.16", "globals": "^15.14.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 71dc9e6..0d799ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: i18next: specifier: ^24.2.2 version: 24.2.2(typescript@5.6.3) + locomotive-scroll: + specifier: ^4.1.4 + version: 4.1.4 lucide-react: specifier: ^0.473.0 version: 0.473.0(react@18.3.1) @@ -87,6 +90,9 @@ importers: '@eslint/js': specifier: ^9.17.0 version: 9.19.0 + '@types/locomotive-scroll': + specifier: ^4.1.4 + version: 4.1.4 '@types/node': specifier: ^22.12.0 version: 22.12.0 @@ -102,9 +108,6 @@ importers: autoprefixer: specifier: ^10.4.20 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: specifier: ^5.0.0 version: 5.1.0(eslint@9.19.0(jiti@1.21.7)) @@ -881,6 +884,9 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/locomotive-scroll@4.1.4': + resolution: {integrity: sha512-G8GUr/ML/Ssxxl83VYbtFHMFoPNOQh/glzPWi5Z3Jk7Hng26Sl0ckAV11uq1AGKEq40jFMPhyAIuQ6fGPiBmHQ==} + '@types/node@22.12.0': resolution: {integrity: sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==} @@ -1009,10 +1015,16 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bezier-easing@2.1.0: + resolution: {integrity: sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bindall-standalone@1.0.5: + resolution: {integrity: sha512-HDI7YBWXVJk/eoGz+e4lYQQJnYp1ZHcUvAY71lVptLMhQnDm86vD73AGPw2qIlgYR3P0bjmoAcXiA8qhFejBhA==} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -1397,6 +1409,9 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + lethargy@1.0.9: + resolution: {integrity: sha512-nFM8blpCF9rqIL5mRAaTGc78W8oQixVtsD86jbEPvcI13+lDUYJf3R7DZQQL7tCiBpbGpGKMX2gwJFO9hiaOkg==} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1412,6 +1427,9 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + locomotive-scroll@4.1.4: + resolution: {integrity: sha512-6i98cFF2SKg6wIPpwVPuo2FG8qL3USsdDeew78TEYZyLoqleMWNfkSDpWA6mPym4dOfTIBXc678VmGlkgx3fTA==} + lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -1743,6 +1761,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + smoothscroll-polyfill@0.4.4: + resolution: {integrity: sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -1800,6 +1821,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-emitter@1.2.0: + resolution: {integrity: sha512-rWjF00inHeWtT5UbQYAXoMI4hL6TRMqohuKCsODyPYYmfAxqfMnXLsIeNrbdPEkNxlk++rojVilTnI9IVmEBtA==} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -1876,6 +1900,9 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + virtual-scroll@1.5.2: + resolution: {integrity: sha512-7jDHwlKbHUho7CYU/HojE/VKFH8GV9P5fVWP2HCa7dRUOpVvwl93OBOKIIcb2mKd+vqsbVR/0zl0X70+3sUZqA==} + vite@6.0.11: resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -2558,6 +2585,8 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/locomotive-scroll@4.1.4': {} + '@types/node@22.12.0': dependencies: undici-types: 6.20.0 @@ -2717,8 +2746,12 @@ snapshots: balanced-match@1.0.2: {} + bezier-easing@2.1.0: {} + binary-extensions@2.3.0: {} + bindall-standalone@1.0.5: {} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -3101,6 +3134,8 @@ snapshots: dependencies: json-buffer: 3.0.1 + lethargy@1.0.9: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -3114,6 +3149,12 @@ snapshots: dependencies: 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.merge@4.6.2: {} @@ -3405,6 +3446,8 @@ snapshots: signal-exit@4.1.0: {} + smoothscroll-polyfill@0.4.4: {} + source-map-js@1.2.1: {} string-width@4.2.3: @@ -3486,6 +3529,8 @@ snapshots: dependencies: any-promise: 1.3.0 + tiny-emitter@1.2.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -3550,6 +3595,13 @@ snapshots: 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): dependencies: esbuild: 0.24.2 diff --git a/public/impressions/test.png b/public/impressions/test.png new file mode 100644 index 0000000..6dcbe77 Binary files /dev/null and b/public/impressions/test.png differ diff --git a/public/impressions/videos-block-bg.png b/public/impressions/videos-block-bg.png new file mode 100644 index 0000000..93c60f8 Binary files /dev/null and b/public/impressions/videos-block-bg.png differ diff --git a/src/components/layout/smooth-scroll.tsx b/src/components/layout/smooth-scroll.tsx new file mode 100644 index 0000000..10999bf --- /dev/null +++ b/src/components/layout/smooth-scroll.tsx @@ -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) => { + const containerRef = useRef(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 ( +
+ {children} +
+ ); +}; + +export default SmoothScroll; diff --git a/src/components/shared/designer-card.tsx b/src/components/shared/designer-card.tsx index fccfa49..2c3a420 100644 --- a/src/components/shared/designer-card.tsx +++ b/src/components/shared/designer-card.tsx @@ -1,38 +1,132 @@ -import { FC } from "react"; +import { FC, useEffect, useState } from "react"; 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 { - imgUrl: string; name: string; - info: string; + biography: string; className?: string; + achievements: { + ru: string; + en: string; + }[]; + image: { path: string }; + images: { path: string }[]; } -export const DesignerCard: FC = ({ className, ...props }) => { +export const DesignerCard: FC = ({ + 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 ( -
- + + +
+ -
- +
+ {name} -
-

{props.name}

-

{props.info}

+
+

{name}

+
    + {achievements.slice(0, 7).map((item, i) => ( +
  • {item.ru}
  • + ))} +
+
+
+
+
+ + +
+
+ +
+
+
{name}
+
+
+
-
-
+
+ +
+

Работы дизайнера

+
+
+ {canScrollPrev && ( + canScrollPrev && emblaApi?.scrollPrev()} + className={cn( + "cursor-pointer", + !canScrollPrev && "opacity-20" + )} + /> + )} +
+ {images.map((item) => ( + + ))} +
+ {canScrollNext && ( + canScrollPrev && emblaApi?.scrollNext()} + className={cn( + "cursor-pointer", + !canScrollNext && "opacity-20" + )} + /> + )} +
+
+
+ + ); }; diff --git a/src/components/shared/designer-modal.tsx b/src/components/shared/designer-modal.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/shared/impressions/designers.tsx b/src/components/shared/impressions/designers.tsx new file mode 100644 index 0000000..8f2b242 --- /dev/null +++ b/src/components/shared/impressions/designers.tsx @@ -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 ( +
+ +

Дизайнеры одежды

+ +
+
+ {isPending ? ( + + ) : ( + data?.designers?.map((item, i) => ( + + )) + )} +
+
+
+
+ ); +}; + +export default Designers; diff --git a/src/components/shared/impressions/hero.tsx b/src/components/shared/impressions/hero.tsx new file mode 100644 index 0000000..b3e22ad --- /dev/null +++ b/src/components/shared/impressions/hero.tsx @@ -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 ( +
+ +

Показы

+ +
+ +

{title}

+
+ {texts.map((item, i) => ( +

{item}

+ ))} +
+ +
+ + +
+
+
+
+ ); +}; + +export default Hero; diff --git a/src/components/shared/impressions/index.ts b/src/components/shared/impressions/index.ts new file mode 100644 index 0000000..d9710a9 --- /dev/null +++ b/src/components/shared/impressions/index.ts @@ -0,0 +1,3 @@ +export { default as Hero } from "./hero"; +export { default as Videos } from "./videos"; +export { default as Designers } from "./designers"; diff --git a/src/components/shared/impressions/videos.tsx b/src/components/shared/impressions/videos.tsx new file mode 100644 index 0000000..d412daf --- /dev/null +++ b/src/components/shared/impressions/videos.tsx @@ -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 ( +
+ +

{title}

+ +
+ {/* FIRST BLOCK */} +
+
+
+
+

+ Алена Ахмадуллина | 'Царевна-Лебедь' (74 симв.) +

+ 1/10 +
+
+ + {/* SECOND BLOCK */} +
+
+

Смотрите также

+ 1/10 +
+ +
+ {[...Array(10)].map((_, i) => ( +
+
+ +
+

+ Алена Ахмадуллина | 'Царевна-Лебедь' 'Царевна-Лебедь' | + Алена Ахмадуллина +

+
+ ))} +
+
+
+
+
+ ); +}; + +export default Videos; diff --git a/src/hooks/tanstack/use-designers.ts b/src/hooks/tanstack/use-designers.ts new file mode 100644 index 0000000..fa59145 --- /dev/null +++ b/src/hooks/tanstack/use-designers.ts @@ -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 }; +}; diff --git a/src/i18n.ts b/src/i18n.ts index e8af132..e46a36d 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -13,6 +13,9 @@ import homeRu from "./locales/ru/home.json"; import aboutEn from "./locales/en/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 contactsRu from "./locales/ru/contacts.json"; @@ -28,6 +31,7 @@ i18n.use(initReactI18next).init({ home: homeEn, about: aboutEn, contacts: contactsEn, + main: mainEn, }, ru: { nav: navRu, @@ -35,11 +39,12 @@ i18n.use(initReactI18next).init({ home: homeRu, about: aboutRu, contacts: contactsRu, + main: mainRu, }, }, lng: initialLanguage, // Язык по умолчанию fallbackLng: "en", - ns: ["home", "about", "header", "contacts", "nav"], // список namespaces + ns: ["home", "about", "header", "contacts", "nav", "main"], // список namespaces defaultNS: "home", // namespace по умолчанию (можно менять в компонентах) interpolation: { escapeValue: false, // React уже экранирует значения diff --git a/src/index.css b/src/index.css index 9193be0..e44b594 100644 --- a/src/index.css +++ b/src/index.css @@ -35,6 +35,9 @@ font-family: "Gilroy-Medium"; @apply bg-background; } + .c-scrollbar .c-scrollbar_thumb { + background-color: #99101d !important; + } } @layer utilities { diff --git a/src/locales/en/main.json b/src/locales/en/main.json new file mode 100644 index 0000000..52aa371 --- /dev/null +++ b/src/locales/en/main.json @@ -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" + } +} diff --git a/src/locales/ru/main.json b/src/locales/ru/main.json new file mode 100644 index 0000000..52aa371 --- /dev/null +++ b/src/locales/ru/main.json @@ -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" + } +} diff --git a/src/pages/impressions.tsx b/src/pages/impressions.tsx index 0384891..17fc303 100644 --- a/src/pages/impressions.tsx +++ b/src/pages/impressions.tsx @@ -1,80 +1,15 @@ -import { Container } from "@/components/layout"; -import { DesignerCard } from "@/components/shared"; +import { Designers, Hero, Videos } from "@/components/shared/impressions"; import { Button } from "@/components/ui/button"; import { useScrollTop } from "@/hooks/use-scroll-top"; -import useEmblaCarousel from "embla-carousel-react"; export default function Impressions() { useScrollTop(); - const [emblaRef] = useEmblaCarousel({ align: "center" }); - return (
-
- -

Показы

- -
- -
-

- Дефиле туркменской моды на выставке "ТуркменТекстиль" -

-

- В рамках международной выставки "Туркмен текстиль" состоятся - эксклюзивные показы коллекций ведущих туркменских дизайнеров и - Домов моды. Гости мероприятия смогут оценить высокое мастерство - исполнения, богатство национальных традиций в современном - прочтении и актуальные тенденции текстильной индустрии - Туркменистана, воплощенные в уникальных моделях одежды и - аксессуаров. -

-
-
- impression image - - -
-
-
-
- -
- -

Дизайнеры одежды

- -
-
- {[...Array(9)].map((_, i) => ( - - ))} -
-
-
-
- + + +

diff --git a/src/services/service.ts b/src/services/service.ts index 121fb83..83806df 100644 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -14,6 +14,7 @@ import { NewsInnerType, NewsType } from "./types/news.type"; import { ParticipantsType } from "./types/participants.type"; import { PhotoTypes } from "./types/photo.type"; import { VideoTypes } from "./types/videos.type"; +import { DesignersType } from "./types/designers.type"; const axios_url = axios.create({ baseURL: "https://turkmentextile.turkmenexpo.com/app/api/v1/", @@ -160,6 +161,7 @@ export const getVideos = async (id: number) => { return data; }; + export const getSponsors = async (lang: LangState["lang"]) => { const data = axios_url("sponsors_and_partners", { headers: { @@ -169,3 +171,13 @@ export const getSponsors = async (lang: LangState["lang"]) => { return data; }; + +export const getDesigners = async (lang: LangState["lang"], id: number) => { + const data = axios_url("designers/category/" + id, { + headers: { + "Accept-Language": lang, + }, + }); + + return data; +}; diff --git a/src/services/types/designers.type.ts b/src/services/types/designers.type.ts new file mode 100644 index 0000000..fe0ef9b --- /dev/null +++ b/src/services/types/designers.type.ts @@ -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; +} diff --git a/tailwind.config.js b/tailwind.config.js index 3cd6838..81995bf 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -47,6 +47,9 @@ export default { outline_v: "#D0D3D8", background: "#F9F9FA", surface_container: "#EEEDF4", + + gray_10: "#433C3D", + gray_09: "#595051", }, }, },