card editing
This commit is contained in:
BIN
public/7up-bottle.png
Normal file
BIN
public/7up-bottle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
BIN
public/logos/logo-white.png
Normal file
BIN
public/logos/logo-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
BIN
public/mirinda-orange.png
Normal file
BIN
public/mirinda-orange.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
BIN
public/mountain-dew.png
Normal file
BIN
public/mountain-dew.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
public/red-bull-cola.png
Normal file
BIN
public/red-bull-cola.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 215 KiB |
BIN
public/schweppes-tonic.png
Normal file
BIN
public/schweppes-tonic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
@@ -155,7 +155,7 @@ const Login = () => {
|
|||||||
{step === 'phone' ? (
|
{step === 'phone' ? (
|
||||||
<Phone className="w-10 h-10 text-blue-500" />
|
<Phone className="w-10 h-10 text-blue-500" />
|
||||||
) : (
|
) : (
|
||||||
<Lock className="w-10 h-10" />
|
<Lock className="w-10 h-10 text-blue-500" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-2xl font-bold mb-2">
|
<h1 className="text-2xl font-bold mb-2">
|
||||||
|
|||||||
@@ -116,6 +116,66 @@ export const subCategoriesData: SubCategory[] = [
|
|||||||
inStock: true,
|
inStock: true,
|
||||||
liked: false,
|
liked: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
name: '7UP 1.5L',
|
||||||
|
price: 9800,
|
||||||
|
oldPrice: 11500,
|
||||||
|
image: '/7up-bottle.png',
|
||||||
|
rating: 4.3,
|
||||||
|
reviews: 124,
|
||||||
|
discount: 15,
|
||||||
|
inStock: true,
|
||||||
|
liked: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10,
|
||||||
|
name: 'Mirinda Orange 1.5L',
|
||||||
|
price: 9500,
|
||||||
|
oldPrice: 11000,
|
||||||
|
image: '/mirinda-orange.png',
|
||||||
|
rating: 4.4,
|
||||||
|
reviews: 139,
|
||||||
|
discount: 14,
|
||||||
|
inStock: true,
|
||||||
|
liked: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 11,
|
||||||
|
name: 'Schweppes Tonic 1L',
|
||||||
|
price: 13500,
|
||||||
|
oldPrice: 15500,
|
||||||
|
image: '/schweppes-tonic.png',
|
||||||
|
rating: 4.6,
|
||||||
|
reviews: 98,
|
||||||
|
discount: 13,
|
||||||
|
inStock: true,
|
||||||
|
liked: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 12,
|
||||||
|
name: 'Mountain Dew 1.5L',
|
||||||
|
price: 12500,
|
||||||
|
oldPrice: 14500,
|
||||||
|
image: '/mountain-dew.png',
|
||||||
|
rating: 4.5,
|
||||||
|
reviews: 187,
|
||||||
|
discount: 14,
|
||||||
|
inStock: true,
|
||||||
|
liked: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 13,
|
||||||
|
name: 'Red Bull Cola 0.33L',
|
||||||
|
price: 16000,
|
||||||
|
oldPrice: 18000,
|
||||||
|
image: '/red-bull-cola.png',
|
||||||
|
rating: 4.2,
|
||||||
|
reviews: 76,
|
||||||
|
discount: 11,
|
||||||
|
inStock: false,
|
||||||
|
liked: false,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const Product = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-3">
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3">
|
||||||
{products.map((product) => (
|
{products.map((product) => (
|
||||||
<ProductCard
|
<ProductCard
|
||||||
key={product.id}
|
key={product.id}
|
||||||
|
|||||||
@@ -119,9 +119,9 @@ export default function Favourite() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-slate-50 py-8">
|
<div className="custom-container">
|
||||||
<div className="container mx-auto px-4">
|
<>
|
||||||
<div className="flex items-center justify-between mb-8">
|
<div className="mb-8">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold text-slate-800 mb-2">
|
<h1 className="text-3xl font-bold text-slate-800 mb-2">
|
||||||
Sevimli mahsulotlar
|
Sevimli mahsulotlar
|
||||||
@@ -130,7 +130,7 @@ export default function Favourite() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4 mb-30">
|
||||||
{likedProducts.map((product) => (
|
{likedProducts.map((product) => (
|
||||||
<ProductCard
|
<ProductCard
|
||||||
key={product.id}
|
key={product.id}
|
||||||
@@ -139,7 +139,7 @@ export default function Favourite() {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Carousel, CarouselContent, CarouselItem } from '@/shared/ui/carousel';
|
import {
|
||||||
|
Carousel,
|
||||||
|
CarouselContent,
|
||||||
|
CarouselItem,
|
||||||
|
CarouselNext,
|
||||||
|
CarouselPrevious,
|
||||||
|
} from '@/shared/ui/carousel';
|
||||||
import { ProductCard } from '@/widgets/categories/ui/product-card';
|
import { ProductCard } from '@/widgets/categories/ui/product-card';
|
||||||
import {
|
import {
|
||||||
Heart,
|
Heart,
|
||||||
@@ -166,7 +172,7 @@ const ProductDetail = () => {
|
|||||||
}}
|
}}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<CarouselContent className="-ml-2">
|
<CarouselContent className="-ml-2 pr-[15%] sm:pr-0">
|
||||||
{product.images.map((img, index) => (
|
{product.images.map((img, index) => (
|
||||||
<CarouselItem
|
<CarouselItem
|
||||||
key={index}
|
key={index}
|
||||||
@@ -219,7 +225,7 @@ const ProductDetail = () => {
|
|||||||
|
|
||||||
{/* Price */}
|
{/* Price */}
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3 max-lg:flex-col max-lg:items-start">
|
||||||
<span className="text-4xl font-bold text-blue-600">
|
<span className="text-4xl font-bold text-blue-600">
|
||||||
{product.price.toLocaleString()} {"so'm"}
|
{product.price.toLocaleString()} {"so'm"}
|
||||||
</span>
|
</span>
|
||||||
@@ -235,7 +241,7 @@ const ProductDetail = () => {
|
|||||||
<p className="text-gray-600 mb-6">{product.description}</p>
|
<p className="text-gray-600 mb-6">{product.description}</p>
|
||||||
|
|
||||||
{/* Brand and Category */}
|
{/* Brand and Category */}
|
||||||
<div className="grid grid-cols-2 gap-4 mb-6">
|
<div className="grid grid-cols-2 gap-4 mb-6 max-md:grid-cols-1">
|
||||||
<div>
|
<div>
|
||||||
<span className="text-gray-500">Brand:</span>
|
<span className="text-gray-500">Brand:</span>
|
||||||
<p className="font-semibold">{product.brand}</p>
|
<p className="font-semibold">{product.brand}</p>
|
||||||
@@ -259,7 +265,7 @@ const ProductDetail = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<h4 className="font-bold text-gray-800 text-lg mb-1">
|
<h4 className="font-bold text-gray-800 text-lg mb-1 line-clamp-1">
|
||||||
{product.supplier.name}
|
{product.supplier.name}
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
@@ -271,7 +277,7 @@ const ProductDetail = () => {
|
|||||||
<label className="text-gray-700 font-medium mb-2 block">
|
<label className="text-gray-700 font-medium mb-2 block">
|
||||||
Miqdor:
|
Miqdor:
|
||||||
</label>
|
</label>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4 max-lg:flex-col max-lg:items-start">
|
||||||
<div className="flex items-center border border-gray-300 rounded-lg">
|
<div className="flex items-center border border-gray-300 rounded-lg">
|
||||||
<button
|
<button
|
||||||
onClick={() => handleQuantityChange('decrease')}
|
onClick={() => handleQuantityChange('decrease')}
|
||||||
@@ -311,7 +317,7 @@ const ProductDetail = () => {
|
|||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<ShoppingCart className="w-5 h-5" />
|
<ShoppingCart className="w-5 h-5" />
|
||||||
{"Savatchaga qo'shish"}
|
{'Savatga'}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setLiked(!liked)}
|
onClick={() => setLiked(!liked)}
|
||||||
@@ -355,9 +361,12 @@ const ProductDetail = () => {
|
|||||||
<h2 className="text-2xl font-bold mb-4">Xususiyatlari</h2>
|
<h2 className="text-2xl font-bold mb-4">Xususiyatlari</h2>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
{Object.entries(product.specifications).map(([key, value]) => (
|
{Object.entries(product.specifications).map(([key, value]) => (
|
||||||
<div key={key} className="flex justify-between border-b pb-2">
|
<div
|
||||||
|
key={key}
|
||||||
|
className="flex justify-between border-b pb-2 gap-4"
|
||||||
|
>
|
||||||
<span className="text-gray-600">{key}:</span>
|
<span className="text-gray-600">{key}:</span>
|
||||||
<span className="font-semibold">{value}</span>
|
<span className="font-semibold text-right">{value}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -366,16 +375,25 @@ const ProductDetail = () => {
|
|||||||
{/* Related Products */}
|
{/* Related Products */}
|
||||||
<div className="bg-white rounded-lg shadow-md p-6">
|
<div className="bg-white rounded-lg shadow-md p-6">
|
||||||
<h2 className="text-2xl font-bold mb-6">{"O'xshash mahsulotlar"}</h2>
|
<h2 className="text-2xl font-bold mb-6">{"O'xshash mahsulotlar"}</h2>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-6">
|
<Carousel className="w-full">
|
||||||
{relatedProducts.map((item) => (
|
<CarouselContent className="pr-[12%] sm:pr-0">
|
||||||
|
{relatedProducts.slice(0, 12).map((product) => (
|
||||||
|
<CarouselItem
|
||||||
|
key={product.id}
|
||||||
|
className="basis-1/2 sm:basis-1/3 md:basis-1/4 lg:basis-1/6 pb-2"
|
||||||
|
>
|
||||||
<ProductCard
|
<ProductCard
|
||||||
key={item.id}
|
product={product}
|
||||||
product={item}
|
|
||||||
handleRemove={handleRemove}
|
handleRemove={handleRemove}
|
||||||
handleLiked={handleLiked}
|
handleLiked={handleLiked}
|
||||||
/>
|
/>
|
||||||
|
</CarouselItem>
|
||||||
))}
|
))}
|
||||||
</div>
|
</CarouselContent>
|
||||||
|
|
||||||
|
<CarouselPrevious className="hidden lg:flex -top-12 right-12 w-9 h-9 bg-blue-600 text-white border-0" />
|
||||||
|
<CarouselNext className="hidden lg:flex -top-12 right-0 w-9 h-9 bg-blue-600 text-white border-0" />
|
||||||
|
</Carousel>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { Badge } from '@/shared/ui/badge';
|
|||||||
import { Button } from '@/shared/ui/button';
|
import { Button } from '@/shared/ui/button';
|
||||||
import { Card, CardContent } from '@/shared/ui/card';
|
import { Card, CardContent } from '@/shared/ui/card';
|
||||||
import {
|
import {
|
||||||
Bell,
|
|
||||||
CheckCircle,
|
CheckCircle,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
Handshake,
|
Handshake,
|
||||||
@@ -22,7 +21,6 @@ import {
|
|||||||
Package,
|
Package,
|
||||||
RefreshCw,
|
RefreshCw,
|
||||||
ShoppingBag,
|
ShoppingBag,
|
||||||
Star,
|
|
||||||
TrendingUp,
|
TrendingUp,
|
||||||
Truck,
|
Truck,
|
||||||
Wallet,
|
Wallet,
|
||||||
@@ -335,14 +333,6 @@ const Profile = () => {
|
|||||||
<RefreshCw className="w-3 h-3 md:w-4 md:h-4" />
|
<RefreshCw className="w-3 h-3 md:w-4 md:h-4" />
|
||||||
Qayta
|
Qayta
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
className="gap-1 md:gap-2 h-8 md:h-9 text-xs md:text-sm"
|
|
||||||
>
|
|
||||||
<Star className="w-3 h-3 md:w-4 md:h-4" />
|
|
||||||
Baholash
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -451,9 +441,13 @@ const Profile = () => {
|
|||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
|
onClick={() => {
|
||||||
|
localStorage.removeItem('user');
|
||||||
|
router.push('/');
|
||||||
|
}}
|
||||||
className="w-9 h-9 md:w-10 md:h-10"
|
className="w-9 h-9 md:w-10 md:h-10"
|
||||||
>
|
>
|
||||||
<Bell className="w-4 h-4 md:w-5 md:h-5" />
|
<LogOut className="w-4 text-red-500 h-4 md:w-5 md:h-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -65,13 +65,13 @@ export default function CustomerSupport() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="custom-sontainer">
|
<div className="custom-sontainer mt-5">
|
||||||
<>
|
<>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="mb-8">
|
<div className="mb-8">
|
||||||
<div className="flex items-center gap-3 mb-2">
|
<div className="flex items-center gap-3 mb-2">
|
||||||
<MessageCircle className="w-8 h-8 text-gray-700" />
|
<MessageCircle className="w-8 h-8 text-gray-700" />
|
||||||
<h1 className="text-3xl font-bold text-gray-800">
|
<h1 className="text-2xl font-bold text-gray-800">
|
||||||
{"Qo'llab-quvvatlash"}
|
{"Qo'llab-quvvatlash"}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ const SearchResult: React.FC = () => {
|
|||||||
<div className="text-center py-20">Yuklanmoqda...</div>
|
<div className="text-center py-20">Yuklanmoqda...</div>
|
||||||
) : query ? (
|
) : query ? (
|
||||||
results.length ? (
|
results.length ? (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-6 gap-4">
|
||||||
{results.map((product) => (
|
{results.map((product) => (
|
||||||
<ProductCard
|
<ProductCard
|
||||||
key={product.id}
|
key={product.id}
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ export function CategoryCarousel({ category }: { category: SubCategory }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Carousel className="w-full">
|
<Carousel className="w-full">
|
||||||
<CarouselContent className="flex">
|
<CarouselContent className="pr-[12%] sm:pr-0">
|
||||||
{products.slice(0, 12).map((product) => (
|
{products.slice(0, 12).map((product) => (
|
||||||
<CarouselItem
|
<CarouselItem
|
||||||
key={product.id}
|
key={product.id}
|
||||||
className="basis-1/1 md:basis-1/2 lg:basis-1/4 pb-2"
|
className="basis-1/2 sm:basis-1/3 md:basis-1/4 lg:basis-1/6 pb-2"
|
||||||
>
|
>
|
||||||
<ProductCard
|
<ProductCard
|
||||||
product={product}
|
product={product}
|
||||||
@@ -66,8 +66,9 @@ export function CategoryCarousel({ category }: { category: SubCategory }) {
|
|||||||
</CarouselItem>
|
</CarouselItem>
|
||||||
))}
|
))}
|
||||||
</CarouselContent>
|
</CarouselContent>
|
||||||
<CarouselNext className="-top-12 right-0 rounded-lg w-10 h-10 max-lg:hidden bg-blue-600 hover:bg-blue-600 cursor-pointer text-white border-0" />
|
|
||||||
<CarouselPrevious className="-top-12 right-12 rounded-lg w-10 h-10 max-lg:hidden bg-blue-600 hover:bg-blue-600 cursor-pointer text-white border-0" />
|
<CarouselPrevious className="hidden lg:flex -top-12 right-12 w-9 h-9 bg-blue-600 text-white border-0" />
|
||||||
|
<CarouselNext className="hidden lg:flex -top-12 right-0 w-9 h-9 bg-blue-600 text-white border-0" />
|
||||||
</Carousel>
|
</Carousel>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -46,12 +46,12 @@ export function ProductCard({
|
|||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
onClick={() => router.push(`/product/${product.id}`)}
|
onClick={() => router.push(`/product/${product.id}`)}
|
||||||
className="group relative p-0 overflow-hidden border border-slate-200 bg-white shadow-sm hover:shadow-xl transition-all duration-300 rounded-2xl hover:border-blue-400"
|
className="group relative p-0 overflow-hidden border border-slate-200 bg-white shadow-sm hover:shadow-lg transition-all rounded-xl sm:rounded-2xl hover:border-blue-400"
|
||||||
>
|
>
|
||||||
<CardContent className="p-0">
|
<CardContent className="p-0">
|
||||||
<div className="relative overflow-hidden">
|
<div className="relative overflow-hidden">
|
||||||
{product.discount > 0 && (
|
{product.discount > 0 && (
|
||||||
<div className="absolute top-3 left-3 z-10 bg-orange-500 text-white px-2.5 py-1 rounded-full text-sm font-bold">
|
<div className="absolute top-2 left-2 z-10 bg-orange-500 text-white px-2 py-0.5 rounded-full text-xs sm:text-sm font-bold">
|
||||||
-{product.discount}%
|
-{product.discount}%
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -59,61 +59,54 @@ export function ProductCard({
|
|||||||
<Button
|
<Button
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
if (product.liked) {
|
if (product.liked) {
|
||||||
handleRemove(product.id);
|
handleRemove(product.id);
|
||||||
} else if (handleLiked && !product.liked) {
|
} else if (handleLiked) {
|
||||||
handleLiked(product.id);
|
handleLiked(product.id);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="absolute hover:bg-white cursor-pointer top-3 right-3 z-10 bg-white rounded-full p-2 shadow-md hover:scale-110 transition-all duration-300"
|
className="absolute top-2 right-2 z-10 bg-white rounded-full p-1.5 sm:p-2 shadow hover:scale-110"
|
||||||
>
|
>
|
||||||
<Heart
|
<Heart
|
||||||
className={`w-5 h-5 transition-colors ${product.liked ? 'fill-red-500 text-red-500' : 'text-slate-400 hover:text-red-400'}`}
|
className={`w-4 h-4 sm:w-5 sm:h-5 ${
|
||||||
|
product.liked
|
||||||
|
? 'fill-red-500 text-red-500'
|
||||||
|
: 'text-slate-400 hover:text-red-400'
|
||||||
|
}`}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div className="relative h-96 bg-slate-50 overflow-hidden">
|
<div className="relative h-40 sm:h-48 md:h-56 bg-slate-50">
|
||||||
<Image
|
<Image
|
||||||
width={500}
|
fill
|
||||||
height={500}
|
|
||||||
src={product.image || '/placeholder.svg'}
|
src={product.image || '/placeholder.svg'}
|
||||||
alt={product.name}
|
alt={product.name}
|
||||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
className="object-cover group-hover:scale-105 transition-transform"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="p-4 space-y-3">
|
<div className="p-3 sm:p-4 space-y-2 sm:space-y-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div className="flex items-center gap-1 bg-orange-50 px-2 py-1 rounded-full">
|
<Star className="w-3.5 h-3.5 sm:w-4 sm:h-4 fill-orange-400 text-orange-400" />
|
||||||
<Star className="w-4 h-4 fill-orange-400 text-orange-400" />
|
<span className="text-xs sm:text-sm font-semibold text-orange-600">
|
||||||
<span className="text-sm font-semibold text-orange-600">
|
|
||||||
{product.rating}
|
{product.rating}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-slate-500 text-sm">
|
|
||||||
({product.reviews} ta sharh)
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 className="font-semibold text-base text-slate-800 line-clamp-2 leading-snug hover:text-blue-600 transition-colors">
|
<h3 className="text-sm sm:text-base font-semibold text-slate-800 line-clamp-1">
|
||||||
{product.name}
|
{product.name}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className="space-y-1">
|
<div>
|
||||||
<div className="flex items-baseline gap-2">
|
<span className="text-lg sm:text-xl font-bold text-blue-600">
|
||||||
<span className="text-2xl font-bold text-blue-600">
|
|
||||||
{formatPrice(product.price)}
|
{formatPrice(product.price)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
{product.oldPrice && (
|
{product.oldPrice && (
|
||||||
<div className="flex items-center gap-2">
|
<div className="text-xs sm:text-sm text-slate-400 line-through">
|
||||||
<span className="text-sm text-slate-400 line-through">
|
|
||||||
{formatPrice(product.oldPrice)}
|
{formatPrice(product.oldPrice)}
|
||||||
</span>
|
|
||||||
<span className="text-xs bg-orange-100 text-orange-600 px-2 py-0.5 rounded-full font-semibold">
|
|
||||||
Tejang!
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -122,40 +115,34 @@ export function ProductCard({
|
|||||||
<Button
|
<Button
|
||||||
disabled={!product.inStock}
|
disabled={!product.inStock}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
setQuantity(1);
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
setQuantity(1);
|
||||||
}}
|
}}
|
||||||
className="w-full h-11 rounded-xl bg-blue-600 text-white"
|
className="w-full h-9 sm:h-11 text-sm"
|
||||||
>
|
>
|
||||||
<ShoppingCart className="w-5 h-5 mr-2" />
|
<ShoppingCart className="w-4 h-4 mr-1" />
|
||||||
Savatga qo‘shish
|
Savatga
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center justify-between border border-blue-500 rounded-xl h-11 px-2">
|
<div
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
className="flex items-center justify-between border border-blue-500 rounded-lg h-9 sm:h-11"
|
||||||
|
>
|
||||||
<Button size="icon" variant="ghost" onClick={decrease}>
|
<Button size="icon" variant="ghost" onClick={decrease}>
|
||||||
<Minus />
|
<Minus className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
|
||||||
value={quantity}
|
value={quantity}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const value = e.target.value;
|
const v = e.target.value;
|
||||||
|
if (/^\d*$/.test(v)) setQuantity(v === '' ? '' : +v);
|
||||||
if (/^\d*$/.test(value)) {
|
|
||||||
setQuantity(value === '' ? '' : Number(value));
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
onBlur={() => {
|
className="w-full border-none text-sm !p-0 focus-visible:ring-0"
|
||||||
if (quantity === '' || quantity < 1) {
|
|
||||||
setQuantity(1);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="w-full text-center outline-none ring-0 focus-visible:ring-0 border-none font-semibold"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button size="icon" variant="ghost" onClick={increase}>
|
<Button size="icon" variant="ghost" onClick={increase}>
|
||||||
<Plus />
|
<Plus className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { Fragment } from 'react';
|
|||||||
|
|
||||||
const Footer = () => {
|
const Footer = () => {
|
||||||
return (
|
return (
|
||||||
<section className="max-lg:py-9 py-12 z-50 w-full bg-slate-50 border-t border-slate-200">
|
<section className="max-lg:py-9 max-lg:bg-white max-lg:border-none py-12 z-50 w-full bg-[#57A595] border-t border-slate-200">
|
||||||
<div className="custom-container max-lg:hidden">
|
<div className="custom-container max-lg:hidden">
|
||||||
<div className="flex w-full gap-10 flex-col items-center justify-between text-center lg:flex-row lg:items-start lg:text-left">
|
<div className="flex w-full gap-10 flex-col items-center justify-between text-center lg:flex-row lg:items-start lg:text-left">
|
||||||
<div className="flex w-fit flex-col items-center justify-between gap-4 lg:items-start mb-8 lg:mb-0">
|
<div className="flex w-fit flex-col items-center justify-between gap-4 lg:items-start mb-8 lg:mb-0">
|
||||||
@@ -17,24 +17,24 @@ const Footer = () => {
|
|||||||
<Image
|
<Image
|
||||||
width={500}
|
width={500}
|
||||||
height={500}
|
height={500}
|
||||||
src={PRODUCT_INFO.logo || '/placeholder.svg'}
|
src={'/logos/logo-white.png'}
|
||||||
alt={PRODUCT_INFO.name}
|
alt={PRODUCT_INFO.name}
|
||||||
title={PRODUCT_INFO.name}
|
title={PRODUCT_INFO.name}
|
||||||
className="h-10 w-10"
|
className="h-10 w-10"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-xl font-bold text-slate-800">
|
<h2 className="text-xl font-bold text-white">
|
||||||
{PRODUCT_INFO.name}
|
{PRODUCT_INFO.name}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-slate-600 max-w-xs leading-relaxed text-sm">
|
<p className="text-white max-w-xs leading-relaxed text-sm">
|
||||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Est,
|
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Est,
|
||||||
totam?
|
totam?
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full grid-cols-1 md:grid-cols-3 gap-8 lg:gap-16">
|
<div className="grid w-full grid-cols-1 md:grid-cols-3 gap-8 lg:gap-16">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="mb-4 font-bold text-base text-black">
|
<h3 className="mb-2 font-bold text-lg text-muted">
|
||||||
Kategoriyalar
|
Kategoriyalar
|
||||||
</h3>
|
</h3>
|
||||||
<ul className="space-y-2 text-sm">
|
<ul className="space-y-2 text-sm">
|
||||||
@@ -43,7 +43,7 @@ const Footer = () => {
|
|||||||
{link.subCategories.slice(0, 2).map((e, linkIdx) => (
|
{link.subCategories.slice(0, 2).map((e, linkIdx) => (
|
||||||
<li
|
<li
|
||||||
key={linkIdx}
|
key={linkIdx}
|
||||||
className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer"
|
className="text-white hover:text-gray-300 transition-colors cursor-pointer"
|
||||||
>
|
>
|
||||||
<Link href={`/category/${link.name}/${e.name}`}>
|
<Link href={`/category/${link.name}/${e.name}`}>
|
||||||
{e.name}
|
{e.name}
|
||||||
@@ -55,53 +55,53 @@ const Footer = () => {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 className="mb-4 font-bold text-base text-black">Sahifalar</h3>
|
<h3 className="mb-2 font-bold text-base text-muted">Sahifalar</h3>
|
||||||
<ul className="space-y-2 text-sm">
|
<ul className="space-y-2 text-sm">
|
||||||
<li className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer">
|
<li className="text-muted hover:text-gray-300 transition-colors cursor-pointer">
|
||||||
<Link href={'/about'}>Biz haqimizda</Link>
|
<Link href={'/about'}>Biz haqimizda</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer">
|
<li className="text-muted hover:text-gray-300 transition-colors cursor-pointer">
|
||||||
<Link href={'/privacy-policy'}>Maxfiylik siyosati</Link>
|
<Link href={'/privacy-policy'}>Maxfiylik siyosati</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer">
|
<li className="text-muted hover:text-gray-300 transition-colors cursor-pointer">
|
||||||
<Link href={'/faq'}>Savol va javoblar</Link>
|
<Link href={'/faq'}>Savol va javoblar</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 className="mb-4 font-bold text-base text-black">Aloqa</h3>
|
<h3 className="mb-2 font-bold text-base text-muted">Aloqa</h3>
|
||||||
<ul className="space-y-2 text-sm">
|
<ul className="space-y-2 text-sm">
|
||||||
<li className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer">
|
<li className="text-muted hover:text-gray-300 transition-colors cursor-pointer">
|
||||||
<a href={'#'} className="flex items-center gap-2">
|
<a href={'#'} className="flex items-center gap-2">
|
||||||
<Send className="size-4" />
|
<Send className="size-4" />
|
||||||
<p>Telegram</p>
|
<p>Telegram</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer">
|
<li className="text-muted hover:text-gray-300 transition-colors cursor-pointer">
|
||||||
<a href={'#'} className="flex items-center gap-2">
|
<a href={'#'} className="flex items-center gap-2">
|
||||||
<Instagram className="size-4" />
|
<Instagram className="size-4" />
|
||||||
<p>Instagram</p>
|
<p>Instagram</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer">
|
<li className="text-muted hover:text-gray-300 transition-colors cursor-pointer">
|
||||||
<a href={'#'} className="flex items-center gap-2">
|
<a href={'#'} className="flex items-center gap-2">
|
||||||
<Facebook className="size-4" />
|
<Facebook className="size-4" />
|
||||||
<p>Facebook</p>
|
<p>Facebook</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer">
|
<li className="text-muted hover:text-gray-300 transition-colors cursor-pointer">
|
||||||
<a href={'#'} className="flex items-center gap-2">
|
<a href={'#'} className="flex items-center gap-2">
|
||||||
<Twitter className="size-4" />
|
<Twitter className="size-4" />
|
||||||
<p>Twitter</p>
|
<p>Twitter</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer">
|
<li className="text-muted hover:text-gray-300 transition-colors cursor-pointer">
|
||||||
<a href={'#'} className="flex items-center gap-2">
|
<a href={'#'} className="flex items-center gap-2">
|
||||||
<Mail className="size-4" />
|
<Mail className="size-4" />
|
||||||
<p>e-mail</p>
|
<p>e-mail</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li className="text-muted-foreground hover:text-blue-600 transition-colors cursor-pointer">
|
<li className="text-muted hover:text-gray-300 transition-colors cursor-pointer">
|
||||||
<a href={'#'} className="flex items-center gap-2">
|
<a href={'#'} className="flex items-center gap-2">
|
||||||
<Phone className="size-4" />
|
<Phone className="size-4" />
|
||||||
<p>{formatPhone('+998901234567')}</p>
|
<p>{formatPhone('+998901234567')}</p>
|
||||||
|
|||||||
@@ -9,12 +9,16 @@ import { useEffect, useState } from 'react';
|
|||||||
|
|
||||||
const NavbarMobile = () => {
|
const NavbarMobile = () => {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const [profile, setProfile] = useState<string | null>(null);
|
const [profile, setProfile] = useState<boolean>(false);
|
||||||
|
const user = localStorage.getItem('user');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const user = localStorage.getItem('user');
|
if (user && user === 'true') {
|
||||||
setProfile(user);
|
setProfile(true);
|
||||||
}, []);
|
} else {
|
||||||
|
setProfile(false);
|
||||||
|
}
|
||||||
|
}, [user]);
|
||||||
|
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{ label: 'Asosiy', icon: Home, href: '/' },
|
{ label: 'Asosiy', icon: Home, href: '/' },
|
||||||
@@ -24,7 +28,7 @@ const NavbarMobile = () => {
|
|||||||
{
|
{
|
||||||
label: 'Profil',
|
label: 'Profil',
|
||||||
icon: User,
|
icon: User,
|
||||||
href: profile === 'true' ? '/profile' : '/auth',
|
href: profile ? '/profile' : '/auth',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,16 @@ const Navbar = () => {
|
|||||||
const [isSticky, setIsSticky] = useState(false);
|
const [isSticky, setIsSticky] = useState(false);
|
||||||
const [query, setQuery] = useState('');
|
const [query, setQuery] = useState('');
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
const [user, setUser] = useState<boolean>(false);
|
||||||
|
const users = localStorage.getItem('user');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (users && users === 'true') {
|
||||||
|
setUser(true);
|
||||||
|
} else {
|
||||||
|
setUser(false);
|
||||||
|
}
|
||||||
|
}, [users]);
|
||||||
|
|
||||||
const queryFromUrl = searchParams.get('q') ?? '';
|
const queryFromUrl = searchParams.get('q') ?? '';
|
||||||
|
|
||||||
@@ -61,7 +71,7 @@ const Navbar = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="w-full bg-blue-600 h-10 max-lg:hidden">
|
<div className="w-full bg-[#57A595] h-10 max-lg:hidden">
|
||||||
<div className="custom-container h-full flex justify-between items-center">
|
<div className="custom-container h-full flex justify-between items-center">
|
||||||
<ul className="text-sm flex items-center justify-center gap-4">
|
<ul className="text-sm flex items-center justify-center gap-4">
|
||||||
<li className="text-white transition-colors cursor-pointer">
|
<li className="text-white transition-colors cursor-pointer">
|
||||||
@@ -195,8 +205,7 @@ const Navbar = () => {
|
|||||||
<Button
|
<Button
|
||||||
variant={'ghost'}
|
variant={'ghost'}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const user = localStorage.getItem('user');
|
if (user) {
|
||||||
if (user === 'true') {
|
|
||||||
router.push('/profile');
|
router.push('/profile');
|
||||||
} else {
|
} else {
|
||||||
router.push('/auth');
|
router.push('/auth');
|
||||||
|
|||||||
Reference in New Issue
Block a user