added partners

This commit is contained in:
Batyr 2025-02-26 17:14:27 +05:00
parent c5de7bec9d
commit 35df9c9093
8 changed files with 177 additions and 81 deletions

View File

@ -20,6 +20,7 @@
"axios": "^1.7.9", "axios": "^1.7.9",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"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",
"lucide-react": "^0.473.0", "lucide-react": "^0.473.0",

View File

@ -38,6 +38,9 @@ importers:
clsx: clsx:
specifier: ^2.1.1 specifier: ^2.1.1
version: 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: embla-carousel-react:
specifier: ^8.5.2 specifier: ^8.5.2
version: 8.5.2(react@18.3.1) version: 8.5.2(react@18.3.1)
@ -1116,6 +1119,11 @@ packages:
electron-to-chromium@1.5.88: electron-to-chromium@1.5.88:
resolution: {integrity: sha512-K3C2qf1o+bGzbilTDCTBhTQcMS9KW60yTAaTeeXsfvQuTDDwlokLam/AdqlqcSy9u4UainDgsHV23ksXAOgamw==} 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: embla-carousel-react@8.5.2:
resolution: {integrity: sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA==} resolution: {integrity: sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA==}
peerDependencies: peerDependencies:
@ -2804,6 +2812,10 @@ snapshots:
electron-to-chromium@1.5.88: {} 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): embla-carousel-react@8.5.2(react@18.3.1):
dependencies: dependencies:
embla-carousel: 8.5.2 embla-carousel: 8.5.2

View File

@ -1,83 +1,115 @@
// import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils";
// import { cn } from "@/lib/utils"; import { FC, useCallback } from "react";
// import { FC, useCallback, useEffect, useState } from "react"; import useEmblaCarousel from "embla-carousel-react";
// import useEmblaCarousel from "embla-carousel-react"; import { ArrowLeft, ArrowRight } from "lucide-react";
// import { ArrowLeft, ArrowRight } from "lucide-react"; import { Container } from "@/components/layout";
// 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 { interface Props {
// className?: string; className?: string;
// } }
// export const HomePartners: FC<Props> = ({ className }) => { export const HomePartners: FC<Props> = ({ className }) => {
// const [emblaRef, emblaApi] = useEmblaCarousel(); const [emblaRef] = useEmblaCarousel({ loop: true, align: "start" }, [
// const [selectedIndex, setSelectedIndex] = useState(0); Autoplay({ delay: 2000, stopOnInteraction: false }),
]);
// const [selectedIndex, setSelectedIndex] = useState(0);
// useEffect(() => { // useEffect(() => {
// if (!emblaApi) return; // if (!emblaApi) return;
// const onSelect = () => setSelectedIndex(emblaApi.selectedScrollSnap()); // const onSelect = () => setSelectedIndex(emblaApi.selectedScrollSnap());
// emblaApi.on("select", onSelect); // emblaApi.on("select", onSelect);
// onSelect(); // onSelect();
// return () => { // return () => {
// emblaApi.off("select", onSelect); // emblaApi.off("select", onSelect);
// }; // };
// }, [emblaApi]); // }, [emblaApi]);
// const scrollTo = useCallback( // const scrollTo = useCallback(
// (index: number) => { // (index: number) => {
// if (emblaApi) emblaApi.scrollTo(index); // if (emblaApi) emblaApi.scrollTo(index);
// }, // },
// [emblaApi] // [emblaApi]
// ); // );
// const scrollPrev = useCallback(() => { // const scrollPrev = useCallback(() => {
// if (emblaApi) emblaApi.scrollPrev(); // if (emblaApi) emblaApi.scrollPrev();
// }, [emblaApi]); // }, [emblaApi]);
// const scrollNext = useCallback(() => { // const scrollNext = useCallback(() => {
// if (emblaApi) emblaApi.scrollNext(); // if (emblaApi) emblaApi.scrollNext();
// }, [emblaApi]); // }, [emblaApi]);
// return ( const { data } = usePartners();
// <section className={cn("", className)}>
// <Container className="flex flex-col gap-10 relative w-full">
// <div className="flex item-center justify-between">
// <h2 className="h2">Участники выставки ITSE 2025</h2>
// <Button variant="outline" size={"sm"}> const { t } = useTranslation("home");
// Все экспоненты
// </Button>
// </div>
// <button const { title } = t("partners", { returnObjects: true }) as { title: string };
// onClick={scrollPrev}
// className="nav-btn absolute top-[55%] -translate-y-1/2 -left-12"
// >
// <ArrowLeft />
// </button>
// <button return (
// onClick={scrollNext} <section className={cn("", className)}>
// className="nav-btn absolute top-[55%] -translate-y-1/2 -right-12" <Container className="flex flex-col gap-10 relative w-full">
// > <div className="flex item-center justify-between">
// <ArrowRight /> <h2 className="h2">{title}</h2>
// </button>
// <div ref={emblaRef} className="embla overflow-hidden"> {/* <Button variant="outline" size={"sm"}>
// <div className="embla__container gap-6 flex"> Все экспоненты
// {Array.from({ length: 12 }).map((_, i) => ( </Button> */}
// <div </div>
// key={i}
// className="embla__slide size-[184px] flex-[0_0_184px] bg-[#D9D9D9]"
// />
// ))}
// </div>
// </div>
// {/* <EmblaDots scrollTo={scrollTo} slides={4} active={selectedIndex} /> */} {/* <button
// </Container> onClick={scrollPrev}
// </section> className="nav-btn absolute top-[55%] -translate-y-1/2 -left-12"
// ); >
// }; <ArrowLeft />
</button>
<button
onClick={scrollNext}
className="nav-btn absolute top-[55%] -translate-y-1/2 -right-12"
>
<ArrowRight />
</button>
*/}
<div ref={emblaRef} className="embla overflow-hidden">
<div className="embla__container flex">
{data?.map((item, i) =>
item.link ? (
<Link
target="_blank"
to={item.link}
key={i}
className="bg-[#E0E6EB] flex embla__slide mr-6 min-w-0 flex-[0_0_288px] items-center justify-center h-[128px] w-full"
>
<img
src={item?.image?.path}
alt="logo"
className="object-contain"
/>
</Link>
) : (
<div
key={i}
className="bg-[#E0E6EB] flex embla__slide mr-6 min-w-0 flex-[0_0_288px] items-center justify-center h-[128px] w-full"
>
<img
src={item?.image?.path}
alt="logo"
className="object-contain"
/>
</div>
)
)}
</div>
</div>
{/* <EmblaDots scrollTo={scrollTo} slides={4} active={selectedIndex} /> */}
</Container>
</section>
);
};

View File

@ -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 };
};

View File

@ -5,6 +5,11 @@
"sm": "https://turkmentextile.turkmenexpo.com/app/storage/app/media/banners/en/s.jpg" "sm": "https://turkmentextile.turkmenexpo.com/app/storage/app/media/banners/en/s.jpg"
}, },
"partners": {
"title": "Partners",
"button": ""
},
"about": { "about": {
"buttons": [ "buttons": [
{ {

View File

@ -5,6 +5,10 @@
"sm": "https://turkmentextile.turkmenexpo.com/app/storage/app/media/banners/ru/s.jpg" "sm": "https://turkmentextile.turkmenexpo.com/app/storage/app/media/banners/ru/s.jpg"
}, },
"partners": {
"title": "Партнёры",
"button": ""
},
"about": { "about": {
"buttons": [ "buttons": [
{ {

View File

@ -5,6 +5,7 @@ import {
HomeTheme, HomeTheme,
HomeTime, HomeTime,
} from "@/components/shared"; } from "@/components/shared";
import { HomePartners } from "@/components/shared/home/home-partners";
export default function Home() { export default function Home() {
return ( return (
@ -13,6 +14,7 @@ export default function Home() {
<HomeAbout /> <HomeAbout />
<HomeOffers /> <HomeOffers />
<HomeTheme /> <HomeTheme />
<HomePartners />
<HomeTime /> <HomeTime />
</div> </div>
); );

View File

@ -9,33 +9,32 @@ import { HomeContactsType } from "./types/home-contacts.type";
import { StaticType } from "@/hooks/tanstack/use-static-words"; import { StaticType } from "@/hooks/tanstack/use-static-words";
import { IndustriesType } from "@/hooks/tanstack/use-industries"; import { IndustriesType } from "@/hooks/tanstack/use-industries";
import { TimeType } from "@/hooks/tanstack/use-exhibition-time"; import { TimeType } from "@/hooks/tanstack/use-exhibition-time";
import { PartnersType } from "@/hooks/tanstack/use-partners";
const URL = "https://turkmentextile.turkmenexpo.com/app/api/v1";
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/",
}); });
export const postStend = async (data: StandFormType): Promise<boolean> => { export const postStend = async (data: StandFormType): Promise<boolean> => {
const res = axios.post(`${URL}/book_stand_form`, data); const res = axios_url.post(`book_stand_form`, data);
return (await res).status === 201; return (await res).status === 201;
}; };
export const postB2b = async (data: FormData): Promise<boolean> => { export const postB2b = async (data: FormData): Promise<boolean> => {
const res = axios.post(`${URL}/form`, data); const res = axios_url.post(`form`, data);
return (await res).status === 201; return (await res).status === 201;
}; };
export const postSponsor = async (data: SponsorFormType): Promise<boolean> => { export const postSponsor = async (data: SponsorFormType): Promise<boolean> => {
const res = axios.post(`${URL}/become_sponsor_form`, data); const res = axios_url.post(`become_sponsor_form`, data);
return (await res).status === 201; return (await res).status === 201;
}; };
export const postContact = async (data: ContactsFormType): Promise<boolean> => { export const postContact = async (data: ContactsFormType): Promise<boolean> => {
const res = axios.post(`${URL}/contact_form`, data); const res = axios_url.post(`contact_form`, data);
return (await res).status === 201; 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) => { export const getStaticWords = async (lang: LangState["lang"], id: string) => {
const data = axios.get<StaticType>(`${URL}/pages/${id}`, { const data = axios_url.get<StaticType>(`pages/${id}`, {
headers: {
"Accept-Language": lang,
},
});
return data;
};
export const getPartners = async (lang: LangState["lang"]) => {
const data = axios_url.get<PartnersType>("partners", {
headers: { headers: {
"Accept-Language": lang, "Accept-Language": lang,
}, },
@ -57,7 +66,7 @@ export const getStaticWords = async (lang: LangState["lang"], id: string) => {
}; };
export const getStats = async (lang: LangState["lang"]) => { export const getStats = async (lang: LangState["lang"]) => {
const data = axios_url.get<StatsType>("/stats", { const data = axios_url.get<StatsType>("stats", {
headers: { headers: {
"Accept-Language": lang, "Accept-Language": lang,
}, },
@ -67,7 +76,7 @@ export const getStats = async (lang: LangState["lang"]) => {
}; };
export const getContacts = async (lang: LangState["lang"]) => { export const getContacts = async (lang: LangState["lang"]) => {
const data = axios_url<ContactsPageType>("contact_info", { const data = axios_url.get<ContactsPageType>("contact_info", {
headers: { headers: {
"Accept-Language": lang, "Accept-Language": lang,
}, },
@ -77,7 +86,7 @@ export const getContacts = async (lang: LangState["lang"]) => {
}; };
export const getHomeContacts = async (lang: LangState["lang"]) => { export const getHomeContacts = async (lang: LangState["lang"]) => {
const data = axios_url<HomeContactsType>("contact_data", { const data = axios_url.get<HomeContactsType>("contact_data", {
headers: { headers: {
"Accept-Language": lang, "Accept-Language": lang,
}, },
@ -87,7 +96,7 @@ export const getHomeContacts = async (lang: LangState["lang"]) => {
}; };
export const getIndustries = async (lang: LangState["lang"]) => { export const getIndustries = async (lang: LangState["lang"]) => {
const data = axios.get<IndustriesType>(`${URL}/industries`, { const data = axios_url.get<IndustriesType>(`industries`, {
headers: { headers: {
"Accept-Language": lang, "Accept-Language": lang,
}, },
@ -97,7 +106,7 @@ export const getIndustries = async (lang: LangState["lang"]) => {
}; };
export const getExhibitionTime = async (lang: LangState["lang"]) => { export const getExhibitionTime = async (lang: LangState["lang"]) => {
const data = axios.get<TimeType>(`${URL}/exhibition_time`, { const data = axios_url.get<TimeType>(`exhibition_time`, {
headers: { headers: {
"Accept-Language": lang, "Accept-Language": lang,
}, },