added partners
This commit is contained in:
parent
c5de7bec9d
commit
35df9c9093
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -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 };
|
||||||
|
};
|
||||||
|
|
@ -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": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue