bug fixed

This commit is contained in:
Samandar Turgunboyev
2026-02-03 18:57:14 +05:00
parent b7846c7bc9
commit 8a4682212f
10 changed files with 66 additions and 46 deletions

View File

@@ -29,16 +29,13 @@ export async function generateMetadata({
res.data.short_name || `Gastro Market mahsuloti: ${res.data.name}`, res.data.short_name || `Gastro Market mahsuloti: ${res.data.name}`,
type: 'website', type: 'website',
images: [ images: [
{ res.data.images && res.data.images.length > 0
url: ? {
res.data.images && res.data.images.length > 0 url: res.data.images[0].image?.includes(BASE_URL)
? res.data.images[0].image.includes(BASE_URL)
? res.data.images[0].image ? res.data.images[0].image
: BASE_URL + res.data.images[0].image : BASE_URL + res.data.images[0].image,
: '/placeholder.svg', }
width: 800, : { url: '/placeholder.svg' },
height: 600,
},
], ],
}, },
twitter: { twitter: {
@@ -46,14 +43,15 @@ export async function generateMetadata({
title: `${res.data.name} - Gastro Market`, title: `${res.data.name} - Gastro Market`,
description: description:
res.data.short_name || `Gastro Market mahsuloti: ${res.data.name}`, res.data.short_name || `Gastro Market mahsuloti: ${res.data.name}`,
images: images: [
res.data.images && res.data.images.length > 0 res.data.images && res.data.images.length > 0
? [ ? {
res.data.images[0].image.includes(BASE_URL) url: res.data.images[0].image?.includes(BASE_URL)
? res.data.images[0].image ? res.data.images[0].image
: BASE_URL + res.data.images[0].image, : BASE_URL + res.data.images[0].image,
] }
: ['/placeholder.svg'], : { url: '/placeholder.svg' },
],
}, },
}; };
} catch { } catch {

View File

@@ -289,11 +289,11 @@ const OrderPage = () => {
{ {
filial_code: 'dodge', filial_code: 'dodge',
delivery_date: formatDate.format(deliveryDate, 'DD.MM.YYYY'), delivery_date: formatDate.format(deliveryDate, 'DD.MM.YYYY'),
room_code: '100', room_code: process.env.NEXT_ROOM_CODE!,
deal_time: formatDate.format(deliveryDate, 'DD.MM.YYYY'), deal_time: formatDate.format(deliveryDate, 'DD.MM.YYYY'),
robot_code: 'r2', robot_code: process.env.NEXT_ROBOT_CODE!,
status: 'B#N', status: 'B#N',
sales_manager_code: '1', sales_manager_code: process.env.NEXT_SALES_MANAGER_CODE!,
person_code: user?.username, person_code: user?.username,
currency_code: '860', currency_code: '860',
owner_person_code: user?.username, owner_person_code: user?.username,

View File

@@ -1,4 +1,5 @@
'use client'; 'use client';
import CategoryImage from '@/assets/water-bottle.png';
import { category_api } from '@/shared/config/api/category/api'; import { category_api } from '@/shared/config/api/category/api';
import { BASE_URL } from '@/shared/config/api/URLs'; import { BASE_URL } from '@/shared/config/api/URLs';
import { Link } from '@/shared/config/i18n/navigation'; import { Link } from '@/shared/config/i18n/navigation';
@@ -34,7 +35,11 @@ const Category = () => {
> >
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<Image <Image
src={BASE_URL + category.image} src={
category.image === null
? CategoryImage
: BASE_URL + category.image
}
alt={category.name} alt={category.name}
width={70} width={70}
unoptimized unoptimized

View File

@@ -56,9 +56,11 @@ const ProductDetail = () => {
select: (res) => res.data.results, select: (res) => res.data.results,
}); });
/* ---------------- PRICE ---------------- */ /* ---------------- DERIVED DATA ---------------- */
const price = Number(data?.prices?.[0]?.price || 0); const price = Number(data?.prices?.[0]?.price || 0);
const category = 'Ichimliklar'; // default category
/* ---------------- SYNC CART QUANTITY ---------------- */ /* ---------------- SYNC CART QUANTITY ---------------- */
useEffect(() => { useEffect(() => {
if (!data || !cartItems) return; if (!data || !cartItems) return;
@@ -103,8 +105,8 @@ const ProductDetail = () => {
toast.success(t("Mahsulot savatga qo'shildi"), { richColors: true }); toast.success(t("Mahsulot savatga qo'shildi"), { richColors: true });
}, },
onError: (err: AxiosError) => { onError: (err: AxiosError) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any const msg =
const msg = (err.response?.data as any)?.detail || err.message; (err.response?.data as { detail: string })?.detail || err.message;
toast.error(msg, { richColors: true }); toast.error(msg, { richColors: true });
}, },
}); });
@@ -124,6 +126,12 @@ const ProductDetail = () => {
queryClient.invalidateQueries({ queryKey: ['product_detail'] }); queryClient.invalidateQueries({ queryKey: ['product_detail'] });
queryClient.invalidateQueries({ queryKey: ['product_list'] }); queryClient.invalidateQueries({ queryKey: ['product_list'] });
}, },
onError: () => {
toast.error(t('Tizimga kirilmagan'), {
richColors: true,
position: 'top-center',
});
},
}); });
/* ---------------- HANDLERS ---------------- */ /* ---------------- HANDLERS ---------------- */
@@ -168,20 +176,20 @@ const ProductDetail = () => {
unoptimized unoptimized
height={500} height={500}
src={ src={
data && data?.images?.length !== 0 data?.images?.length
? BASE_URL + data.images[selectedImage]?.image ? BASE_URL + data.images[selectedImage]?.image
: data?.images[selectedImage]?.image : '/placeholder.svg'
? BASE_URL + data.images[selectedImage]?.image
: '/placeholder.svg'
} }
alt={data?.name || 'logo'} alt={data?.name || 'logo'}
className="w-full h-[400px] object-contain" className="w-full h-[400px] object-contain"
/> />
<Carousel className="mt-4"> <Carousel className="mt-4">
<CarouselContent> <CarouselContent>
{data?.images?.map((img, i) => ( {(data?.images?.length
<CarouselItem key={img.id} className="basis-1/4"> ? data.images
: [{ id: 0, image: '/placeholder.svg' }]
).map((img, i) => (
<CarouselItem key={i} className="basis-1/4">
<button <button
onClick={() => setSelectedImage(i)} onClick={() => setSelectedImage(i)}
className={`border rounded-lg p-1 ${ className={`border rounded-lg p-1 ${
@@ -191,12 +199,12 @@ const ProductDetail = () => {
}`} }`}
> >
<Image <Image
src={BASE_URL + img.image} src={img.image!}
alt="" alt={data?.name || 'Mahsulot rasmi'}
unoptimized
width={120} width={120}
height={120} height={120}
className="object-contain" className="object-contain"
unoptimized
/> />
</button> </button>
</CarouselItem> </CarouselItem>
@@ -215,7 +223,13 @@ const ProductDetail = () => {
<p className="text-gray-600 mb-6">{data?.short_name}</p> <p className="text-gray-600 mb-6">{data?.short_name}</p>
{/* QUANTITY */} <div className="grid grid-cols-2 gap-4 mb-6">
<div>
<span className="text-gray-500">Kategoriya:</span>
<p className="font-semibold">{category}</p>
</div>
</div>
<div className="flex items-center gap-4 mb-6"> <div className="flex items-center gap-4 mb-6">
<button <button
onClick={() => setQuantity((q) => Math.max(1, q - 1))} onClick={() => setQuantity((q) => Math.max(1, q - 1))}
@@ -246,7 +260,7 @@ const ProductDetail = () => {
</div> </div>
{/* ACTIONS */} {/* ACTIONS */}
<div className="flex gap-3"> <div className="flex gap-3 mb-6">
<button <button
onClick={handleAddToCart} onClick={handleAddToCart}
className="flex-1 bg-green-600 hover:bg-green-700 text-white py-3 rounded-lg flex justify-center items-center gap-2" className="flex-1 bg-green-600 hover:bg-green-700 text-white py-3 rounded-lg flex justify-center items-center gap-2"
@@ -256,7 +270,7 @@ const ProductDetail = () => {
</button> </button>
<button <button
onClick={() => favouriteMutation.mutate(product)} onClick={() => favouriteMutation.mutate(String(data?.id))}
className={`p-3 rounded-lg border ${ className={`p-3 rounded-lg border ${
data?.liked ? 'border-red-500 bg-red-50' : 'border-gray-300' data?.liked ? 'border-red-500 bg-red-50' : 'border-gray-300'
}`} }`}

View File

@@ -73,14 +73,14 @@ const Profile = () => {
<Avatar className="w-14 h-14 ring-2 ring-emerald-500 ring-offset-2 flex items-center justify-center"> <Avatar className="w-14 h-14 ring-2 ring-emerald-500 ring-offset-2 flex items-center justify-center">
<AvatarImage /> <AvatarImage />
<AvatarFallback className="text-muted-foreground font-semibold"> <AvatarFallback className="text-muted-foreground font-semibold">
{user?.username.slice(0, 1).toUpperCase()} {user?.first_name.slice(0, 1).toUpperCase()}
</AvatarFallback> </AvatarFallback>
</Avatar> </Avatar>
<div> <div>
<p className="text-lg text-muted-foreground font-medium"> <p className="text-lg text-muted-foreground font-medium">
{user && {user &&
user.username.charAt(0).toUpperCase() + user.first_name.charAt(0).toUpperCase() +
user.username.slice(1)} user.first_name.slice(1)}
</p> </p>
</div> </div>
</div> </div>
@@ -129,14 +129,14 @@ const Profile = () => {
<Avatar className="w-10 h-10 md:w-12 md:h-12 ring-2 ring-emerald-500 ring-offset-2"> <Avatar className="w-10 h-10 md:w-12 md:h-12 ring-2 ring-emerald-500 ring-offset-2">
<AvatarImage /> <AvatarImage />
<AvatarFallback className="text-muted-foreground font-semibold"> <AvatarFallback className="text-muted-foreground font-semibold">
{user?.username?.slice(0, 1).toUpperCase()} {user?.first_name?.slice(0, 1).toUpperCase()}
</AvatarFallback> </AvatarFallback>
</Avatar> </Avatar>
<div> <div>
<p className="text-md md:text-xl text-muted-foreground"> <p className="text-md md:text-xl text-muted-foreground">
{user && {user &&
user.username.charAt(0).toUpperCase() + user.first_name.charAt(0).toUpperCase() +
user.username.slice(1)} user.first_name.slice(1)}
</p> </p>
</div> </div>
</div> </div>

View File

@@ -11,5 +11,5 @@ export interface Category {
export interface CategoryResult { export interface CategoryResult {
id: string; id: string;
name: string; name: string;
image: string; image: string | null;
} }

View File

@@ -42,9 +42,9 @@ export interface ProductListResult {
export interface ProductDetail { export interface ProductDetail {
id: number; id: number;
images: { id: number; image: string }[]; images: { id: number; image: string | null }[];
liked: boolean; liked: boolean;
meansurement: null | string; meansurement: null | { id: number; name: string };
inventory_id: null | string; inventory_id: null | string;
product_id: string; product_id: string;
code: string; code: string;

View File

@@ -245,6 +245,7 @@ export function ProductCard({
<span className="text-lg sm:text-xl font-bold text-green-600"> <span className="text-lg sm:text-xl font-bold text-green-600">
{formatPrice( {formatPrice(
Math.max(...product.prices.map((p) => Number(p.price))), Math.max(...product.prices.map((p) => Number(p.price))),
true,
)} )}
</span> </span>
)} )}

View File

@@ -74,7 +74,7 @@ const NavbarMobile = () => {
isActive && 'text-green-500', isActive && 'text-green-500',
)} )}
> >
<div className="relative w-full flex justify-center items-center"> <div className="relative w-fit flex justify-center items-center ">
<item.icon <item.icon
className={cn( className={cn(
'size-6 transition-colors', 'size-6 transition-colors',
@@ -82,7 +82,7 @@ const NavbarMobile = () => {
)} )}
/> />
{item.href === '/cart' && ( {item.href === '/cart' && (
<Badge className="absolute -top-2 right-2 line-clamp-1 w-5 h-5 flex justify-center items-center"> <Badge className="absolute -top-2.5 -right-2.5 line-clamp-1 w-5 h-5 flex justify-center items-center">
{cartQuenty === 9 ? cartQuenty + '+' : cartQuenty} {cartQuenty === 9 ? cartQuenty + '+' : cartQuenty}
</Badge> </Badge>
)} )}

View File

@@ -20,6 +20,7 @@ import { CategoryCarousel } from '@/widgets/categories/ui/category-carousel';
import { ProductCard } from '@/widgets/categories/ui/product-card'; import { ProductCard } from '@/widgets/categories/ui/product-card';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { AlertCircle, ChevronLeft, ChevronRight } from 'lucide-react'; import { AlertCircle, ChevronLeft, ChevronRight } from 'lucide-react';
import { useTranslations } from 'next-intl';
import Image from 'next/image'; import Image from 'next/image';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import 'swiper/css'; import 'swiper/css';
@@ -32,6 +33,7 @@ const Welcome = () => {
const [canScrollNext, setCanScrollNext] = useState(false); const [canScrollNext, setCanScrollNext] = useState(false);
const [apiCat, setApiCat] = useState<CarouselApi>(); const [apiCat, setApiCat] = useState<CarouselApi>();
const router = useRouter(); const router = useRouter();
const t = useTranslations();
const { data, isLoading, isError } = useQuery({ const { data, isLoading, isError } = useQuery({
queryKey: ['banner_list'], queryKey: ['banner_list'],
@@ -225,7 +227,7 @@ const Welcome = () => {
onClick={() => router.push(`/all-product/`)} onClick={() => router.push(`/all-product/`)}
> >
<h2 className="text-2xl font-bold text-slate-800 group-hover:text-blue-600 transition-colors"> <h2 className="text-2xl font-bold text-slate-800 group-hover:text-blue-600 transition-colors">
Barcha mahsulotlar {t('Barcha mahsulotlar')}
</h2> </h2>
<div className="p-1.5 bg-slate-100 rounded-full group-hover:bg-blue-100 transition-all"> <div className="p-1.5 bg-slate-100 rounded-full group-hover:bg-blue-100 transition-all">
<ChevronRight className="text-slate-600 group-hover:text-blue-600 group-hover:translate-x-0.5 transition-all" /> <ChevronRight className="text-slate-600 group-hover:text-blue-600 group-hover:translate-x-0.5 transition-all" />