From 35df9c9093b4c3feff0d4e1aef1773a75f412ae5 Mon Sep 17 00:00:00 2001 From: Batyr Date: Wed, 26 Feb 2025 17:14:27 +0500 Subject: [PATCH] added partners --- package.json | 1 + pnpm-lock.yaml | 12 ++ src/components/shared/home/home-partners.tsx | 170 +++++++++++-------- src/hooks/tanstack/use-partners.ts | 31 ++++ src/locales/en/home.json | 5 + src/locales/ru/home.json | 4 + src/pages/home.tsx | 2 + src/services/service.ts | 33 ++-- 8 files changed, 177 insertions(+), 81 deletions(-) create mode 100644 src/hooks/tanstack/use-partners.ts diff --git a/package.json b/package.json index 55be306..7bd657b 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "axios": "^1.7.9", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "embla-carousel-autoplay": "^8.5.2", "embla-carousel-react": "^8.5.2", "i18next": "^24.2.2", "lucide-react": "^0.473.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8636bd0..71dc9e6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 + embla-carousel-autoplay: + specifier: ^8.5.2 + version: 8.5.2(embla-carousel@8.5.2) embla-carousel-react: specifier: ^8.5.2 version: 8.5.2(react@18.3.1) @@ -1116,6 +1119,11 @@ packages: electron-to-chromium@1.5.88: resolution: {integrity: sha512-K3C2qf1o+bGzbilTDCTBhTQcMS9KW60yTAaTeeXsfvQuTDDwlokLam/AdqlqcSy9u4UainDgsHV23ksXAOgamw==} + embla-carousel-autoplay@8.5.2: + resolution: {integrity: sha512-27emJ0px3q/c0kCHCjwRrEbYcyYUPfGO3g5IBWF1i7714TTzE6L9P81V6PHLoSMAKJ1aHoT2e7YFOsuFKCbyag==} + peerDependencies: + embla-carousel: 8.5.2 + embla-carousel-react@8.5.2: resolution: {integrity: sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA==} peerDependencies: @@ -2804,6 +2812,10 @@ snapshots: electron-to-chromium@1.5.88: {} + embla-carousel-autoplay@8.5.2(embla-carousel@8.5.2): + dependencies: + embla-carousel: 8.5.2 + embla-carousel-react@8.5.2(react@18.3.1): dependencies: embla-carousel: 8.5.2 diff --git a/src/components/shared/home/home-partners.tsx b/src/components/shared/home/home-partners.tsx index d0155ab..f9e4fdd 100644 --- a/src/components/shared/home/home-partners.tsx +++ b/src/components/shared/home/home-partners.tsx @@ -1,83 +1,115 @@ -// import { Button } from "@/components/ui/button"; -// import { cn } from "@/lib/utils"; -// import { FC, useCallback, useEffect, useState } from "react"; -// import useEmblaCarousel from "embla-carousel-react"; -// import { ArrowLeft, ArrowRight } from "lucide-react"; -// import { Container } from "@/components/layout"; +import { cn } from "@/lib/utils"; +import { FC, useCallback } from "react"; +import useEmblaCarousel from "embla-carousel-react"; +import { ArrowLeft, ArrowRight } from "lucide-react"; +import { Container } from "@/components/layout"; +import Autoplay from "embla-carousel-autoplay"; +import { usePartners } from "@/hooks/tanstack/use-partners"; +import { Link } from "react-router-dom"; +import { useTranslation } from "react-i18next"; -// interface Props { -// className?: string; -// } +interface Props { + className?: string; +} -// export const HomePartners: FC = ({ className }) => { -// const [emblaRef, emblaApi] = useEmblaCarousel(); -// const [selectedIndex, setSelectedIndex] = useState(0); +export const HomePartners: FC = ({ className }) => { + const [emblaRef] = useEmblaCarousel({ loop: true, align: "start" }, [ + Autoplay({ delay: 2000, stopOnInteraction: false }), + ]); + // const [selectedIndex, setSelectedIndex] = useState(0); -// useEffect(() => { -// if (!emblaApi) return; + // useEffect(() => { + // if (!emblaApi) return; -// const onSelect = () => setSelectedIndex(emblaApi.selectedScrollSnap()); -// emblaApi.on("select", onSelect); -// onSelect(); + // const onSelect = () => setSelectedIndex(emblaApi.selectedScrollSnap()); + // emblaApi.on("select", onSelect); + // onSelect(); -// return () => { -// emblaApi.off("select", onSelect); -// }; -// }, [emblaApi]); + // return () => { + // emblaApi.off("select", onSelect); + // }; + // }, [emblaApi]); -// const scrollTo = useCallback( -// (index: number) => { -// if (emblaApi) emblaApi.scrollTo(index); -// }, -// [emblaApi] -// ); + // const scrollTo = useCallback( + // (index: number) => { + // if (emblaApi) emblaApi.scrollTo(index); + // }, + // [emblaApi] + // ); -// const scrollPrev = useCallback(() => { -// if (emblaApi) emblaApi.scrollPrev(); -// }, [emblaApi]); + // const scrollPrev = useCallback(() => { + // if (emblaApi) emblaApi.scrollPrev(); + // }, [emblaApi]); -// const scrollNext = useCallback(() => { -// if (emblaApi) emblaApi.scrollNext(); -// }, [emblaApi]); + // const scrollNext = useCallback(() => { + // if (emblaApi) emblaApi.scrollNext(); + // }, [emblaApi]); -// return ( -//
-// -//
-//

Участники выставки ITSE 2025

+ const { data } = usePartners(); -// -//
+ const { t } = useTranslation("home"); -// + const { title } = t("partners", { returnObjects: true }) as { title: string }; -// + return ( +
+ +
+

{title}

-//
-//
-// {Array.from({ length: 12 }).map((_, i) => ( -//
-// ))} -//
-//
+ {/* */} +
-// {/* */} -// -//
-// ); -// }; + {/* + + + */} +
+
+ {data?.map((item, i) => + item.link ? ( + + logo + + ) : ( +
+ logo +
+ ) + )} +
+
+ + {/* */} +
+
+ ); +}; diff --git a/src/hooks/tanstack/use-partners.ts b/src/hooks/tanstack/use-partners.ts new file mode 100644 index 0000000..d30d1ad --- /dev/null +++ b/src/hooks/tanstack/use-partners.ts @@ -0,0 +1,31 @@ +import { getPartners } from "@/services/service"; +import { useLangStore } from "@/store/lang"; +import { useQuery } from "@tanstack/react-query"; + +export interface PartnersType { + status: string; + data: Datum[]; +} + +export interface Datum { + id: number; + name: string; + link: string; + image: Image; +} + +export interface Image { + path: string; +} + +export const usePartners = () => { + const lang = useLangStore((state) => state.lang); + + const { data, isPending } = useQuery({ + queryKey: ["partners", lang], + queryFn: () => getPartners(lang), + select: ({ data }) => data.data, + }); + + return { data, isPending }; +}; diff --git a/src/locales/en/home.json b/src/locales/en/home.json index 04f576b..19271ad 100644 --- a/src/locales/en/home.json +++ b/src/locales/en/home.json @@ -5,6 +5,11 @@ "sm": "https://turkmentextile.turkmenexpo.com/app/storage/app/media/banners/en/s.jpg" }, + "partners": { + "title": "Partners", + "button": "" + }, + "about": { "buttons": [ { diff --git a/src/locales/ru/home.json b/src/locales/ru/home.json index 3a5d99d..1fc38d8 100644 --- a/src/locales/ru/home.json +++ b/src/locales/ru/home.json @@ -5,6 +5,10 @@ "sm": "https://turkmentextile.turkmenexpo.com/app/storage/app/media/banners/ru/s.jpg" }, + "partners": { + "title": "Партнёры", + "button": "" + }, "about": { "buttons": [ { diff --git a/src/pages/home.tsx b/src/pages/home.tsx index 233d2f5..733d72c 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -5,6 +5,7 @@ import { HomeTheme, HomeTime, } from "@/components/shared"; +import { HomePartners } from "@/components/shared/home/home-partners"; export default function Home() { return ( @@ -13,6 +14,7 @@ export default function Home() { + ); diff --git a/src/services/service.ts b/src/services/service.ts index b2afaf1..2733f2e 100644 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -9,33 +9,32 @@ import { HomeContactsType } from "./types/home-contacts.type"; import { StaticType } from "@/hooks/tanstack/use-static-words"; import { IndustriesType } from "@/hooks/tanstack/use-industries"; import { TimeType } from "@/hooks/tanstack/use-exhibition-time"; - -const URL = "https://turkmentextile.turkmenexpo.com/app/api/v1"; +import { PartnersType } from "@/hooks/tanstack/use-partners"; const axios_url = axios.create({ baseURL: "https://turkmentextile.turkmenexpo.com/app/api/v1/", }); export const postStend = async (data: StandFormType): Promise => { - const res = axios.post(`${URL}/book_stand_form`, data); + const res = axios_url.post(`book_stand_form`, data); return (await res).status === 201; }; export const postB2b = async (data: FormData): Promise => { - const res = axios.post(`${URL}/form`, data); + const res = axios_url.post(`form`, data); return (await res).status === 201; }; export const postSponsor = async (data: SponsorFormType): Promise => { - const res = axios.post(`${URL}/become_sponsor_form`, data); + const res = axios_url.post(`become_sponsor_form`, data); return (await res).status === 201; }; export const postContact = async (data: ContactsFormType): Promise => { - const res = axios.post(`${URL}/contact_form`, data); + const res = axios_url.post(`contact_form`, data); return (await res).status === 201; }; @@ -47,7 +46,17 @@ export const postSubscribe = async (data: { email: string }) => { }; export const getStaticWords = async (lang: LangState["lang"], id: string) => { - const data = axios.get(`${URL}/pages/${id}`, { + const data = axios_url.get(`pages/${id}`, { + headers: { + "Accept-Language": lang, + }, + }); + + return data; +}; + +export const getPartners = async (lang: LangState["lang"]) => { + const data = axios_url.get("partners", { headers: { "Accept-Language": lang, }, @@ -57,7 +66,7 @@ export const getStaticWords = async (lang: LangState["lang"], id: string) => { }; export const getStats = async (lang: LangState["lang"]) => { - const data = axios_url.get("/stats", { + const data = axios_url.get("stats", { headers: { "Accept-Language": lang, }, @@ -67,7 +76,7 @@ export const getStats = async (lang: LangState["lang"]) => { }; export const getContacts = async (lang: LangState["lang"]) => { - const data = axios_url("contact_info", { + const data = axios_url.get("contact_info", { headers: { "Accept-Language": lang, }, @@ -77,7 +86,7 @@ export const getContacts = async (lang: LangState["lang"]) => { }; export const getHomeContacts = async (lang: LangState["lang"]) => { - const data = axios_url("contact_data", { + const data = axios_url.get("contact_data", { headers: { "Accept-Language": lang, }, @@ -87,7 +96,7 @@ export const getHomeContacts = async (lang: LangState["lang"]) => { }; export const getIndustries = async (lang: LangState["lang"]) => { - const data = axios.get(`${URL}/industries`, { + const data = axios_url.get(`industries`, { headers: { "Accept-Language": lang, }, @@ -97,7 +106,7 @@ export const getIndustries = async (lang: LangState["lang"]) => { }; export const getExhibitionTime = async (lang: LangState["lang"]) => { - const data = axios.get(`${URL}/exhibition_time`, { + const data = axios_url.get(`exhibition_time`, { headers: { "Accept-Language": lang, },