classify web

This commit is contained in:
Husanjonazamov
2026-02-24 12:52:49 +05:00
commit 64af77101f
310 changed files with 45449 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
"use client";
import { t } from "@/utils";
import { useEffect, useState } from "react";
import { IoSearchOutline } from "react-icons/io5";
import Img1 from "../../../public/assets/Image1.png";
import Img2 from "../../../public/assets/Image2.png";
import Img3 from "../../../public/assets/Image3.png";
import Img4 from "../../../public/assets/Image4.png";
import Img5 from "../../../public/assets/Image5.png";
import Img6 from "../../../public/assets/Image6.png";
import {
getCityData,
getIsBrowserSupported,
getKilometerRange,
saveCity,
} from "@/redux/reducer/locationSlice";
import { useDispatch, useSelector } from "react-redux";
import { CurrentLanguageData } from "@/redux/reducer/languageSlice";
import LocationModal from "../../Location/LocationModal";
import { toast } from "sonner";
import { FaLocationCrosshairs } from "react-icons/fa6";
import { getCompanyName } from "@/redux/reducer/settingSlice";
import CustomLink from "@/components/Common/CustomLink";
import { ArrowRight } from "lucide-react";
import { setIsVisitedLandingPage } from "@/redux/reducer/globalStateSlice";
import CustomImage from "@/components/Common/CustomImage";
import { useNavigate } from "@/components/Common/useNavigate";
import LandingAdEditSearchAutocomplete from "@/components/Location/LandingAdEditSearchAutocomplete";
const AnythingYouWant = () => {
const dispatch = useDispatch();
const { navigate } = useNavigate();
const CurrentLanguage = useSelector(CurrentLanguageData);
const LocationData = useSelector(getCityData);
const companyName = useSelector(getCompanyName);
const [selectedCity, setSelectedCity] = useState(LocationData);
const IsBrowserSupported = useSelector(getIsBrowserSupported);
const [IsLocationModalOpen, setIsLocationModalOpen] = useState(false);
const KmRange = useSelector(getKilometerRange);
useEffect(() => {
dispatch(setIsVisitedLandingPage(true));
}, []);
const handleSearchLocation = () => {
const isInvalidLocation =
KmRange > 0
? !selectedCity?.lat || !selectedCity?.long
: !selectedCity?.areaId &&
!selectedCity?.city &&
!selectedCity?.state &&
!selectedCity?.country;
if (isInvalidLocation) {
toast.error(t("pleaseSelectLocation"));
return;
}
saveCity(selectedCity);
navigate("/");
};
return (
<>
<section
id="anythingYouWant"
className="py-28 bg-muted flex items-center justify-center"
>
<div className="container relative">
<div className="flex flex-col items-center gap-6 text-center">
<div className="flex flex-col items-center font-bold text-4xl lg:text-5xl gap-3 relative">
<h1 className="flex flex-column items-center relative z-10 after:content-[''] after:absolute after:bg-[#00b2ca] after:h-[40%] after:w-full after:z-[-1] after:bottom-0">
{t("buySell")}
</h1>
<h1>{t("anythingYouWant")}</h1>
</div>
<p className="text-sm font-light md:w-1/2">
{t("discoverEndlessPossibilitiesAt")} {companyName}{" "}
{t("goToMarketplace")}
</p>
<div className="space-between gap-3 rounded border w-full lg:w-[60%] bg-white py-2 ltr:pr-2 rtl:pl-2 relative">
<LandingAdEditSearchAutocomplete
saveOnSuggestionClick={false}
setSelectedLocation={setSelectedCity}
/>
<div className="flex items-center gap-3">
{IsBrowserSupported && (
<button
className="flex items-center gap-2"
onClick={() => setIsLocationModalOpen(true)}
>
<FaLocationCrosshairs size={22} />
</button>
)}
<button
className="flex items-center gap-2 bg-primary px-3 py-[6px] rounded text-white"
onClick={handleSearchLocation}
>
<IoSearchOutline size={22} />
<span className="hidden md:block">{t("search")}</span>
</button>
</div>
<CustomLink
href="/"
className="hidden sm:flex items-center gap-2 text-destructive"
>
<span className="whitespace-nowrap">{t("skip")}</span>
<ArrowRight size={16} className="rtl:scale-x-[-1]" />
</CustomLink>
</div>
<CustomLink
href="/"
className="sm:hidden flex items-center gap-2 text-destructive"
>
<span className="whitespace-nowrap">{t("skip")}</span>
<ArrowRight size={16} className="rtl:scale-x-[-1]" />
</CustomLink>
</div>
<CustomImage
src={Img1}
className="hidden xl:block absolute xl:-top-[38%] ltr:xl:left-[3%] rtl:xl:right-[3%] xl:w-[110px] rounded-full"
height={135}
width={90}
alt="landing page image 1"
/>
<CustomImage
src={Img2}
className="hidden xl:block absolute xl:top-[38%] ltr:xl:left-[9%] rtl:xl:right-[9%] xl:w-[110px] rounded-full"
height={135}
width={90}
alt="landing page image 2"
/>
<CustomImage
src={Img3}
className="hidden xl:block absolute xl:top-[120%] ltr:xl:left-[3%] rtl:xl:right-[3%] xl:w-[110px] rounded-full"
height={90}
width={90}
alt="landing page image 3"
/>
<CustomImage
src={Img4}
className="hidden xl:block absolute xl:-top-[38%] ltr:xl:right-[3%] rtl:xl:left-[3%] xl:w-[110px] rounded-full"
height={135}
width={90}
alt="landing page image 4"
/>
<CustomImage
src={Img5}
className="hidden xl:block absolute xl:top-[38%] ltr:xl:right-[9%] rtl:xl:left-[9%] xl:w-[110px] rounded-full"
height={90}
width={90}
alt="landing page image 5"
/>
<CustomImage
src={Img6}
className="hidden xl:block absolute xl:top-[109%] ltr:xl:right-[3%] rtl:xl:left-[3%] xl:w-[110px] rounded-full"
height={0}
width={0}
alt="landing page image 6"
/>
</div>
</section>
<LocationModal
key={`${IsLocationModalOpen}-location-modal`}
IsLocationModalOpen={IsLocationModalOpen}
setIsLocationModalOpen={setIsLocationModalOpen}
/>
</>
);
};
export default AnythingYouWant;

View File

@@ -0,0 +1,37 @@
"use client";
import { FaArrowRight } from "react-icons/fa";
import CustomLink from "@/components/Common/CustomLink";
import { t } from "@/utils";
import CustomImage from "@/components/Common/CustomImage";
const BlogCard = ({ blog }) => {
return (
<div className="p-4 rounded-3xl flex flex-col gap-4 border h-100 bg-white h-full">
<CustomImage
src={blog?.image}
alt="Blog image"
className="w-full object-cover rounded-[8px] aspect-[388/200]"
width={378}
height={195}
/>
<h5 className="text-lg font-semibold truncate">
{blog?.translated_title || blog?.title}
</h5>
<p
className="opacity-65 line-clamp-2"
dangerouslySetInnerHTML={{
__html: blog?.translated_description || blog?.description,
}}
></p>
<CustomLink
href={`/blogs/${blog?.slug}`}
className="flex items-center gap-3 text-primary text-lg mt-auto"
>
<span>{t("readArticle")}</span>
<FaArrowRight className="rtl:scale-x-[-1]" size={20} />
</CustomLink>
</div>
);
};
export default BlogCard;

View File

@@ -0,0 +1,141 @@
"use client";
import { t } from "@/utils";
import { useSelector } from "react-redux";
import { CurrentLanguageData } from "@/redux/reducer/languageSlice";
import { settingsData } from "@/redux/reducer/settingSlice";
import LanguageDropdown from "../../Common/LanguageDropdown";
import LandingMobileMenu from "@/components/PagesComponent/LandingPage/LandingMobileMenu";
import { useState, useEffect } from "react";
import CustomImage from "@/components/Common/CustomImage";
import CustomLink from "@/components/Common/CustomLink";
const LandingHeader = () => {
const CurrentLanguage = useSelector(CurrentLanguageData);
const settings = useSelector(settingsData);
const [isShowMobileMenu, setIsShowMobileMenu] = useState(false);
const [activeSection, setActiveSection] = useState("anythingYouWant");
const handleMobileMenuClose = () => {
if (isShowMobileMenu) {
setIsShowMobileMenu(false);
}
};
// Intersection Observer to track which section is currently visible
useEffect(() => {
const sections = ["anythingYouWant", "work_process", "faq", "ourBlogs"];
const observerOptions = {
root: null,
rootMargin: "0px", // Trigger when section is 20% from top
threshold: 0.7,
};
const observerCallback = (entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setActiveSection(entry.target.id);
}
});
};
const observer = new IntersectionObserver(
observerCallback,
observerOptions
);
// Observe all sections
sections.forEach((sectionId) => {
const element = document.getElementById(sectionId);
if (element) {
observer.observe(element);
}
});
// Cleanup observer on component unmount
return () => {
observer.disconnect();
};
}, []);
return (
<>
<header className="sticky top-0 z-50 bg-white shadow-xs">
<nav className="shadow-md">
<div className="container py-5 lg:flex lg:items-center lg:justify-between">
<div className="flex w-100 items-center justify-between">
<CustomImage
src={settings?.header_logo}
className="w-full h-[52px] object-contain ltr:object-left rtl:object-right max-w-[195px]"
alt="logo"
width={195}
height={52}
/>
<LandingMobileMenu
isOpen={isShowMobileMenu}
setIsOpen={setIsShowMobileMenu}
activeSection={activeSection}
/>
</div>
<div className="hidden lg:flex gap-6">
<ul className="flex items-center gap-6">
<li>
<CustomLink
href="#anythingYouWant"
className={`cursor-pointer transition-all duration-200 ${
activeSection === "anythingYouWant"
? "text-primary"
: "hover:text-primary"
}`}
>
{t("home")}
</CustomLink>
</li>
<li>
<CustomLink
href="#work_process"
className={`cursor-pointer transition-all duration-200 ${
activeSection === "work_process"
? "text-primary"
: "hover:text-primary"
}`}
onClick={handleMobileMenuClose}
>
{t("whyChooseUs")}
</CustomLink>
</li>
<li>
<CustomLink
href="#faq"
className={`cursor-pointer transition-all duration-200 ${
activeSection === "faq"
? "text-primary"
: "hover:text-primary"
}`}
onClick={handleMobileMenuClose}
>
{t("faqs")}
</CustomLink>
</li>
<li>
<CustomLink
href="#ourBlogs"
className={`cursor-pointer transition-all duration-200 ${
activeSection === "ourBlogs"
? "text-primary"
: "hover:text-primary"
}`}
onClick={handleMobileMenuClose}
>
{t("blog")}
</CustomLink>
</li>
</ul>
</div>
<div className="hidden lg:flex">
<LanguageDropdown />
</div>
</div>
</nav>
</header>
</>
);
};
export default LandingHeader;

View File

@@ -0,0 +1,103 @@
"use client";
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
import { settingsData } from "@/redux/reducer/settingSlice";
import { t } from "@/utils";
import { GiHamburgerMenu } from "react-icons/gi";
import { useSelector } from "react-redux";
import LanguageDropdown from "../../Common/LanguageDropdown";
import { CurrentLanguageData } from "@/redux/reducer/languageSlice";
import CustomImage from "@/components/Common/CustomImage";
const LandingMobileMenu = ({ isOpen, setIsOpen, activeSection }) => {
const CurrentLanguage = useSelector(CurrentLanguageData);
const settings = useSelector(settingsData);
const scrollToSection = (id) => {
const section = document.getElementById(id);
if (section) {
setIsOpen(false);
section.scrollIntoView({ behavior: "smooth" });
}
};
return (
<Sheet open={isOpen} onOpenChange={setIsOpen} className="lg:hidden">
<SheetTrigger asChild className="lg:hidden">
<button
id="hamburg"
className="text-2xl cursor-pointer border rounded-lg p-1"
>
<GiHamburgerMenu size={25} className="text-primary" />
</button>
</SheetTrigger>
<SheetContent className="[&>button:first-child]:hidden] p-0">
<SheetHeader className="py-4 px-6 border-b border">
<SheetTitle>
<CustomImage
src={settings?.header_logo}
width={195}
height={52}
alt="Logo"
className="w-full h-[52px] object-contain ltr:object-left rtl:object-right max-w-[195px]"
/>
</SheetTitle>
</SheetHeader>
<div className="p-6">
<div className="flex flex-col list-none">
<li
className={`cursor-pointer py-3 border-b border-dashed transition-all duration-200 ${
activeSection === "anythingYouWant"
? "text-primary"
: "hover:text-primary"
}`}
onClick={() => scrollToSection("anythingYouWant")}
>
{t("home")}
</li>
<li
className={`cursor-pointer py-3 border-b border-dashed transition-all duration-200 ${
activeSection === "work_process"
? "text-primary"
: "hover:text-primary"
}`}
onClick={() => scrollToSection("work_process")}
>
{t("whyChooseUs")}
</li>
<li
className={`cursor-pointer py-3 border-b border-dashed transition-all duration-200 ${
activeSection === "faq"
? "text-primary font-semibold bg-primary/5"
: "hover:text-primary"
}`}
onClick={() => scrollToSection("faq")}
>
{t("faqs")}
</li>
<li
className={`cursor-pointer py-3 border-b border-dashed transition-all duration-200 ${
activeSection === "ourBlogs"
? "text-primary font-semibold bg-primary/5"
: "hover:text-primary"
}`}
onClick={() => scrollToSection("ourBlogs")}
>
{t("blog")}
</li>
<li className="py-3">
<LanguageDropdown />
</li>
</div>
</div>
</SheetContent>
</Sheet>
);
};
export default LandingMobileMenu;

View File

@@ -0,0 +1,122 @@
"use client";
import { t } from "@/utils";
import {
Carousel,
CarouselContent,
CarouselItem,
} from "@/components/ui/carousel";
import { useEffect, useState } from "react";
import { RiArrowLeftLine, RiArrowRightLine } from "react-icons/ri";
import { getBlogsApi } from "@/utils/api";
import BlogCardSkeleton from "../../Skeletons/BlogCardSkeleton.jsx";
import BlogCard from "./BlogCard.jsx";
import { CurrentLanguageData } from "@/redux/reducer/languageSlice.js";
import { useSelector } from "react-redux";
const OurBlogs = () => {
const CurrentLanguage = useSelector(CurrentLanguageData);
const isRTL = CurrentLanguage?.rtl;
const [api, setApi] = useState();
const [current, setCurrent] = useState(0);
const [Blogs, setBlogs] = useState([]);
const [IsLoading, setIsLoading] = useState(true);
const getBlogsData = async () => {
try {
const res = await getBlogsApi.getBlogs();
setBlogs(res?.data?.data?.data);
} catch (error) {
console.log(error);
} finally {
setIsLoading(false);
}
};
useEffect(() => {
getBlogsData();
}, [CurrentLanguage.id]);
useEffect(() => {
if (!api) {
return;
}
setCurrent(api.selectedScrollSnap());
api.on("select", () => {
setCurrent(api.selectedScrollSnap());
});
}, [api]);
return (
<section className="py-28 bg-muted" id="ourBlogs">
<div className="container">
<div className="flex items-center flex-col gap-6">
<p className="outlinedSecHead">{t("ourBlog")}</p>
<h1 className="landingSecHeader">
{t("masteringMarketplace")}
<br />
{t("withOurBlog")}
</h1>
</div>
<Carousel
key={isRTL ? "rtl" : "ltr"}
className="w-full mt-20"
setApi={setApi}
opts={{ align: "start", direction: isRTL ? "rtl" : "ltr" }}
>
<CarouselContent className="-ml-3 md:-ml-[30px]">
{IsLoading
? Array.from({ length: 6 }).map((_, i) => (
<CarouselItem
key={i}
className="sm:basis-1/2 xl:basis-1/3 pl-3 md:pl-[30px]"
>
<BlogCardSkeleton />
</CarouselItem>
))
: Blogs &&
Blogs.length > 0 &&
Blogs.map((blog) => (
<CarouselItem
key={blog?.id}
className="sm:basis-1/2 xl:basis-1/3 pl-3 md:pl-[30px]"
>
<BlogCard blog={blog} />
</CarouselItem>
))}
</CarouselContent>
</Carousel>
<div className="flex items-center justify-center mt-[30px] gap-4">
<button
onClick={() => api?.scrollTo(current - 1)}
className={`bg-primary p-2 rounded ${
!api?.canScrollPrev() ? "opacity-65 cursor-default" : ""
}`}
disabled={!api?.canScrollPrev()}
>
<RiArrowLeftLine
size={24}
color="white"
className={isRTL ? "rotate-180" : ""}
/>
</button>
<button
onClick={() => api?.scrollTo(current + 1)}
className={`bg-primary p-2 rounded ${
!api?.canScrollNext() ? "opacity-65 cursor-default" : ""
}`}
disabled={!api?.canScrollNext()}
>
<RiArrowRightLine
size={24}
color="white"
className={isRTL ? "rotate-180" : ""}
/>
</button>
</div>
</div>
</section>
);
};
export default OurBlogs;

View File

@@ -0,0 +1,70 @@
"use client";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
import { CurrentLanguageData } from "@/redux/reducer/languageSlice";
import { t } from "@/utils";
import { getFaqApi } from "@/utils/api";
import { useEffect, useState } from "react";
import { useSelector } from "react-redux";
const QuickAnswers = () => {
const CurrentLanguage = useSelector(CurrentLanguageData);
const [Faqs, setFaqs] = useState([]);
const getFaqData = async () => {
try {
const res = await getFaqApi.getFaq();
setFaqs(res?.data?.data);
} catch (error) {
console.log(error);
}
};
useEffect(() => {
getFaqData();
}, [CurrentLanguage.id]);
return (
<section className="py-28" id="faq">
<div className="container">
<div className="flex items-center flex-col gap-6">
<p className="outlinedSecHead">{t("navigating")}</p>
<h1 className="landingSecHeader">{t("quickAnswers")}</h1>
</div>
<div className="flex flex-col gap-4 md:gap-8 mt-20">
{Faqs &&
Faqs.length > 0 &&
Faqs.map((faq) => (
<Accordion
type="single"
collapsible
className="border rounded-md overflow-hidden"
key={faq?.id}
>
<AccordionItem value={faq?.id} className="border-none group">
<AccordionTrigger
className="text-start font-bold text-base px-4 hover:no-underline bg-transparent
group-data-[state=open]:bg-muted group-data-[state=open]:text-primary
group-data-[state=open]:border-b"
>
{faq?.translated_question || faq?.question}
</AccordionTrigger>
<AccordionContent className="bg-muted p-4">
<p className="text-base">
{faq?.translated_answer || faq?.answer}
</p>
</AccordionContent>
</AccordionItem>
</Accordion>
))}
</div>
</div>
</section>
);
};
export default QuickAnswers;

View File

@@ -0,0 +1,56 @@
"use client";
import { t } from "@/utils";
import Arrow from "../../../public/assets/Arrow.svg";
import { workProcessSteps } from "@/utils/constants";
import { useSelector } from "react-redux";
import { settingsData } from "@/redux/reducer/settingSlice";
import { CurrentLanguageData } from "@/redux/reducer/languageSlice";
import CustomImage from "@/components/Common/CustomImage";
const WorkProcess = () => {
const CurrentLanguage = useSelector(CurrentLanguageData);
const settings = useSelector(settingsData);
return (
<section className="py-28" id="work_process">
<div className="container">
<div className="flex items-center flex-col gap-6">
<p className="outlinedSecHead">
{t("how")} {settings?.company_name} {t("getsYouResults")}
</p>
<h1 className="landingSecHeader">
{t("unravelingThe")} {settings?.company_name} <br />{" "}
{t("workProcess")}
</h1>
</div>
<div className="mt-20">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 text-center">
{workProcessSteps.map((step, index) => (
<div
key={step.id}
className="flex flex-col items-center gap-4 relative"
>
{index !== workProcessSteps.length - 1 && (
<CustomImage
src={Arrow}
alt="arrow"
width={128}
height={22}
className="absolute hidden w-32 top-[5%] lg:block lg:-right-[34%] xl:-right-[30%] 2xl:-right-[25%] rtl:right-auto rtl:lg:-left-[34%] rtl:xl:-left-[30%] rtl:2xl:-left-[25%] rtl:scale-x-[-1]"
/>
)}
<span className="flex items-center justify-center text-white font-bold w-[40px] h-[40px] bg-primary rounded-full">
{step.id}
</span>
<h5 className="font-bold">{t(step.title)}</h5>
<p>{t(step.description)}</p>
</div>
))}
</div>
</div>
</div>
</section>
);
};
export default WorkProcess;