diff --git a/app/globals.css b/app/globals.css
index cda3071..22e2cd9 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -14,7 +14,7 @@
--font-mono: var(--font-geist-mono);
--font-roboto: "Roboto", sans-serif;
--font-almarai: "Almarai", sans-serif;
- --font-unbounded:"Unbounded",sans-serif;
+ --font-unbounded: "Unbounded", sans-serif;
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
@@ -135,6 +135,25 @@ body {
background: #1e1d1c;
}
-.loio{
- color:#8b1515, #c91d1d
+.loio {
+ color: #8b1515, #c91d1d;
+}
+
+/* globals.css ga qo'shing */
+@keyframes shimmer {
+ 100% {
+ transform: translateX(100%);
+ }
+}
+
+.animate-shimmer {
+ animation: shimmer 2s infinite;
+}
+
+.delay-150 {
+ animation-delay: 150ms;
+}
+
+.delay-300 {
+ animation-delay: 300ms;
}
diff --git a/components/EmptyData.tsx b/components/EmptyData.tsx
new file mode 100644
index 0000000..114680d
--- /dev/null
+++ b/components/EmptyData.tsx
@@ -0,0 +1,48 @@
+// components/EmptyData.tsx
+import { PackageOpen, ShoppingBag } from "lucide-react";
+import { useTranslations } from "next-intl";
+
+interface EmptyDataProps {
+ title?: string;
+ description?: string;
+ icon?: "package" | "shopping";
+}
+
+export default function EmptyData({
+ title,
+ description,
+ icon = "package",
+}: EmptyDataProps) {
+ const t = useTranslations();
+
+ const Icon = icon === "package" ? PackageOpen : ShoppingBag;
+
+ return (
+
+ {/* Animated background circles */}
+
+
+ {/* Text content */}
+
+
+ {title || t("no_data_title")}
+
+
+ {description || t("no_data_description")}
+
+
+
+ {/* Decorative elements */}
+
+
+ );
+}
diff --git a/components/loadingSkleton.tsx b/components/loadingSkleton.tsx
new file mode 100644
index 0000000..796e31c
--- /dev/null
+++ b/components/loadingSkleton.tsx
@@ -0,0 +1,41 @@
+// components/CatalogCardSkeleton.tsx
+export default function CatalogCardSkeleton() {
+ return (
+
+ {/* Content container */}
+
+ {/* Title section */}
+
+
+ {/* Title skeleton */}
+
+ {/* Icon skeleton */}
+
+
+
+ {/* Description skeleton */}
+
+
+
+ {/* Image container skeleton */}
+
+
+ {/* Bottom accent bar skeleton */}
+
+
+
+ {/* Shimmer effect */}
+
+
+ );
+}
\ No newline at end of file
diff --git a/components/pages/home/blog.tsx b/components/pages/home/blog/blog.tsx
similarity index 67%
rename from components/pages/home/blog.tsx
rename to components/pages/home/blog/blog.tsx
index 190d1b9..9f2273f 100644
--- a/components/pages/home/blog.tsx
+++ b/components/pages/home/blog/blog.tsx
@@ -1,7 +1,6 @@
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
import { useTranslations } from "next-intl";
-import { ProductCatalog } from "@/lib/demoData";
-import CatalogCard from "../products/catalog";
+import Catalog from "./catalog";
export function Blog() {
const t = useTranslations();
@@ -26,17 +25,7 @@ export function Blog() {
{/* Blog Cards Grid */}
-
- {ProductCatalog.map((item, index) => (
-
- ))}
-
+
);
diff --git a/components/pages/home/blog/catalog.tsx b/components/pages/home/blog/catalog.tsx
new file mode 100644
index 0000000..d64ae7b
--- /dev/null
+++ b/components/pages/home/blog/catalog.tsx
@@ -0,0 +1,57 @@
+"use client";
+import { useQuery } from "@tanstack/react-query";
+import httpClient from "@/request/api";
+import { endPoints } from "@/request/links";
+import { useEffect } from "react";
+import CatalogCard from "../../products/catalog";
+import CatalogCardSkeleton from "@/components/loadingSkleton";
+import EmptyData from "@/components/EmptyData";
+import { getRouteLang } from "@/request/getLang";
+import { CategoryType } from "@/lib/types";
+
+export default function Catalog() {
+ const language = getRouteLang();
+ const { data, isLoading } = useQuery({
+ queryKey: ["categorycasd", language],
+ queryFn: () => httpClient(endPoints.category.all),
+ select: (data): CategoryType[] => data?.data?.results,
+ });
+ useEffect(() => {
+ console.log("product catalog data: ", data);
+ }, [data]);
+
+ if (isLoading) {
+ return (
+
+ {[...Array(3)].map((_, index) => (
+
+ ))}
+
+ );
+ }
+
+ // Ma'lumot yo'q holati
+ if (!data || data.length === 0) {
+ return (
+
+ );
+ }
+
+ return (
+
+ {data.map((item, index) => (
+
+ ))}
+
+ );
+}
diff --git a/components/pages/home/index.ts b/components/pages/home/index.ts
index 167d23a..082d0bd 100644
--- a/components/pages/home/index.ts
+++ b/components/pages/home/index.ts
@@ -5,4 +5,4 @@ export { Video } from "./video";
export { OurService } from "./ourService";
export { Testimonial } from "./testimonal";
export { Line } from "./line";
-export { Blog } from "./blog";
+export { Blog } from "./blog/blog";
diff --git a/components/pages/products/catalog.tsx b/components/pages/products/catalog.tsx
index 5ed6b99..c825d7b 100644
--- a/components/pages/products/catalog.tsx
+++ b/components/pages/products/catalog.tsx
@@ -50,7 +50,7 @@ import Link from "next/link";
import { ArrowUpRight } from "lucide-react";
interface CatalogProps {
- id: string;
+ id: number;
image: string;
title: string;
description: string;
diff --git a/lib/types.ts b/lib/types.ts
new file mode 100644
index 0000000..5b1de65
--- /dev/null
+++ b/lib/types.ts
@@ -0,0 +1,39 @@
+export interface CategoryType {
+ id: number;
+ name: string;
+ image: string;
+ description: string;
+}
+
+export interface SubCategoryType {
+ id: number;
+ name: string;
+ category: number;
+ image: string;
+}
+
+export interface ProductsPageTypes {
+ id: number;
+ name: string;
+ image: string;
+}
+
+export interface ProductImage {
+ id: number;
+ product: number;
+ image: string;
+ is_main: boolean;
+ order: number;
+}
+
+export interface ProductDetail {
+ id: number;
+ name: string;
+ articular: string;
+ status: string;
+ description: string;
+ size: number;
+ price: string;
+ features: string[];
+ images: ProductImage[];
+}
diff --git a/request/links.ts b/request/links.ts
index bc13c6c..d6abfc6 100644
--- a/request/links.ts
+++ b/request/links.ts
@@ -12,7 +12,7 @@ export const endPoints = {
detail: (id: number) => `product/${id}/`,
},
faq: "faq/",
- gallery: "gallery/",
+ gallery: "gallery/?page_size=500",
contact: "contact/",
statistics: "statistics/",
filter: {
diff --git a/store/useCategory.ts b/store/useCategory.ts
new file mode 100644
index 0000000..af27552
--- /dev/null
+++ b/store/useCategory.ts
@@ -0,0 +1,19 @@
+import { CategoryType } from "@/lib/types";
+import { create } from "zustand";
+
+interface CategoryZustandType {
+ category: CategoryType;
+ setCategory: (category: CategoryType) => void;
+}
+
+const demoCategory: CategoryType = {
+ id: 0,
+ name: "",
+ description: "",
+ image: "",
+};
+
+export const useCategory = create((set) => ({
+ category: demoCategory,
+ setCategory: (data) => set({ category: data }),
+}));
diff --git a/store/useProduct.ts b/store/useProduct.ts
new file mode 100644
index 0000000..e69de29
diff --git a/store/useSubCategory.ts b/store/useSubCategory.ts
new file mode 100644
index 0000000..ce229dc
--- /dev/null
+++ b/store/useSubCategory.ts
@@ -0,0 +1,18 @@
+import { SubCategoryType } from "@/lib/types";
+import { create } from "zustand";
+
+interface SubCategoryZustandType {
+ subCategory: SubCategoryType;
+ setSubCategory: (subCategory: SubCategoryType) => void;
+}
+
+const demoSubCategory = {
+ id: 0,
+ name: "",
+ category: 0,
+ image: "",
+};
+export const useSubCategory = create((set) => ({
+ subCategory: demoSubCategory,
+ setSubCategory: (data) => set({}),
+}));