removed some unnecessary ui elements

This commit is contained in:
Jelaletdin12
2026-02-02 16:22:27 +05:00
parent b8c871750a
commit c68ac335c6
12 changed files with 120 additions and 205 deletions

View File

@@ -19,14 +19,13 @@ import EmptyCart from "@/features/cart/components/EmptyCart";
import ErrorPage from "@/components/ErrorPage";
export default function CartPage() {
const [isClient, setIsClient] = useState(false);
const [paymentType, setPaymentType] = useState<PaymentType | null>(null);
const [deliveryType, setDeliveryType] =
useState<DeliveryType>("SELECTED_DELIVERY");
const [selectedRegion, setSelectedRegion] = useState<string>("");
const [selectedProvince, setSelectedProvince] = useState<number | null>(null);
const [note, setNote] = useState<string>("");
const [phone, setPhone] = useState<string>("+993 ");
const [phone, setPhone] = useState<string>("+993 ");
const [name, setName] = useState<string>("");
const [lastName, setLastName] = useState<string>("");
const router = useRouter();
@@ -42,38 +41,52 @@ export default function CartPage() {
const isLoading = cartLoading || provincesLoading || paymentTypesLoading;
useEffect(() => {
setIsClient(true);
}, []);
if (paymentTypes.length > 0) {
const defaultType = paymentTypes.find((t) => t.id === 1);
if (defaultType) {
setPaymentType(defaultType);
}
}
}, [paymentTypes]);
const regionGroups = useMemo(() => {
return provinces.reduce((acc, province) => {
if (!acc[province.region]) {
acc[province.region] = [];
}
acc[province.region].push(province);
return acc;
}, {} as Record<string, typeof provinces>);
return provinces.reduce(
(acc, province) => {
if (!acc[province.region]) {
acc[province.region] = [];
}
acc[province.region].push(province);
return acc;
},
{} as Record<string, typeof provinces>,
);
}, [provinces]);
const availableRegions = useMemo(
() => Object.keys(regionGroups),
[regionGroups]
[regionGroups],
);
const itemsBySeller = useMemo(() => {
return cartItems.reduce((acc, item) => {
const sellerId = item.product.channel?.[0]?.id || 0;
const sellerName = item.product.channel?.[0]?.name || "Unknown Seller";
return cartItems.reduce(
(acc, item) => {
const sellerId = item.product.channel?.[0]?.id || 0;
const sellerName = item.product.channel?.[0]?.name || "Unknown Seller";
if (!acc[sellerId]) {
acc[sellerId] = {
seller: { id: sellerId, name: sellerName },
items: [],
};
}
acc[sellerId].items.push(item);
return acc;
}, {} as Record<number, { seller: { id: number; name: string }; items: typeof cartItems }>);
if (!acc[sellerId]) {
acc[sellerId] = {
seller: { id: sellerId, name: sellerName },
items: [],
};
}
acc[sellerId].items.push(item);
return acc;
},
{} as Record<
number,
{ seller: { id: number; name: string }; items: typeof cartItems }
>,
);
}, [cartItems]);
const totalAmount = useMemo(() => {
@@ -88,46 +101,50 @@ export default function CartPage() {
setSelectedProvince(null);
};
const formatPhoneForBackend = (phoneNumber: string): string => {
return phoneNumber.replace(/^\+993\s*/, "").replace(/\s+/g, "");
};
const handleCompleteOrder = () => {
if (!selectedRegion || !selectedProvince || !paymentType || !phone || !name) {
console.warn("Missing required fields for order");
return;
}
const phoneDigits = formatPhoneForBackend(phone);
if (phoneDigits.length !== 8) {
console.warn("Phone number must be exactly 8 digits");
return;
}
const selectedProvinceData = provinces.find((p) => p.id === selectedProvince);
if (!selectedProvinceData) return;
createOrder(
{
customer_name: `${name} ${lastName}`.trim(),
customer_phone: parseInt(phoneDigits, 10),
customer_address: selectedProvinceData.name,
shipping_method: "standart",
payment_type_id: paymentType.id,
region: selectedRegion,
note: note || undefined,
},
{
onSuccess: () => {
router.push(`/orders`);
},
if (
!selectedRegion ||
!selectedProvince ||
!paymentType ||
!phone ||
!name
) {
console.warn("Missing required fields for order");
return;
}
);
};
if (!isClient) return null;
const phoneDigits = formatPhoneForBackend(phone);
if (phoneDigits.length !== 8) {
console.warn("Phone number must be exactly 8 digits");
return;
}
const selectedProvinceData = provinces.find(
(p) => p.id === selectedProvince,
);
if (!selectedProvinceData) return;
createOrder(
{
customer_name: `${name} ${lastName}`.trim(),
customer_phone: parseInt(phoneDigits, 10),
customer_address: selectedProvinceData.name,
shipping_method: "standart",
payment_type_id: paymentType.id,
region: selectedRegion,
note: note || undefined,
},
{
onSuccess: () => {
router.push(`/orders`);
},
},
);
};
if (isLoading) {
return (
@@ -151,8 +168,8 @@ export default function CartPage() {
</div>
);
}
if (isError ) {
if (isError) {
return <ErrorPage />;
}
if (cartItems.length === 0) {
@@ -171,12 +188,10 @@ export default function CartPage() {
{Object.entries(itemsBySeller).map(
([sellerId, { seller, items }]) => (
<div key={sellerId} className="mb-6">
<p className="text-base font-semibold mb-3">{seller.name}</p>
{/* <p className="text-base font-semibold mb-3">{seller.name}</p> */}
<div className="space-y-4">
{items.map((item) => {
const price = parseFloat(
item.product.price_amount || "0"
);
const price = parseInt(item.product.price_amount || "0");
const quantity = item.product_quantity;
const total = price * quantity;
@@ -200,7 +215,7 @@ export default function CartPage() {
item.product.media?.[0]?.thumbnail,
images:
item.product.media?.map(
(m) => m.images_800x800 || m.thumbnail
(m) => m.images_800x800 || m.thumbnail,
) || [],
},
}}
@@ -212,7 +227,7 @@ export default function CartPage() {
<Separator className="mt-4" />
)}
</div>
)
),
)}
</Card>
</div>
@@ -258,4 +273,4 @@ export default function CartPage() {
</div>
</div>
);
}
}

View File

@@ -80,8 +80,9 @@ export default function FavoritesPage() {
price_color="#0059ff"
height={360}
width={250}
button={false}
button={true}
stock={product.stock}
/>
);
})}

View File

@@ -11,12 +11,12 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { locale, slug } = await params;
return {
title: `Product ${slug} | E-Commerce`,
title: `Product ${slug} | Smart-Electronics`,
description: `View details for product ${slug}`,
openGraph: {
locale,
type: "website",
title: `Product ${slug} | E-Commerce`,
title: `Product ${slug} | Smart-Electronics`,
description: `View details for product ${slug}`,
},
};

View File

@@ -3,15 +3,8 @@ import { useRouter } from "next/navigation";
import { useMemo } from "react";
import type React from "react";
import Link from "next/link";
import { User, Truck, Heart, Store, LogOut } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useCart, useFavorites, useOrders, useCartCount } from "@/lib/hooks";
import { Skeleton } from "@/components/ui/skeleton";
import { useTranslations } from "next-intl";
@@ -20,7 +13,6 @@ import {
CartIcon,
FavoriteIcon,
OrderIcon,
ProfileIcon,
} from "@/components/icons";
interface ActionButtonsProps {
@@ -78,11 +70,6 @@ const cartCount = useCartCount()
const buttons: ActionButtonData[] = useMemo(
() => [
{
icon: <Store />,
label: t("common.openStore"),
href: "/openStore",
},
{
icon: <OrderIcon />,
label: t("common.orders"),
@@ -119,7 +106,7 @@ const cartCount = useCartCount()
return (
<div className="hidden items-center gap-1 lg:flex">
{/* Profile/Login Button with Dropdown */}
{authLoading ? (
{/* {authLoading ? (
<div className="h-10 w-24 animate-pulse bg-gray-200 rounded" />
) : isAuthenticated ? (
<DropdownMenu>
@@ -154,7 +141,7 @@ const cartCount = useCartCount()
<ProfileIcon />
<span className="text-xs text-gray-700">{t("common.login")}</span>
</Button>
)}
)} */}
{/* Other Action Buttons */}
{buttons.map((button, index) => (

View File

@@ -81,13 +81,13 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) {
sessionStorage.setItem(
PENDING_CART_UPDATES_KEY,
JSON.stringify(pending)
JSON.stringify(pending),
);
} catch (error) {
console.error("Failed to save pending update:", error);
}
},
[item.product_id]
[item.product_id],
);
// Remove from sessionStorage
@@ -103,7 +103,7 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) {
} else {
sessionStorage.setItem(
PENDING_CART_UPDATES_KEY,
JSON.stringify(pending)
JSON.stringify(pending),
);
}
}
@@ -200,7 +200,7 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) {
retrySyncRef.current?.(quantity);
},
}
},
);
}
},
@@ -211,7 +211,7 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) {
removeItem,
onUpdate,
clearPendingUpdate,
]
],
);
// Update ref
@@ -235,7 +235,7 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) {
// Trigger sync after a short delay
setTimeout(
() => syncToServerRef.current?.(productPending.quantity),
500
500,
);
}
}
@@ -336,14 +336,6 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) {
</div>
<div className="flex flex-col gap-2">
<h3 className="font-semibold text-base">{item.product.name}</h3>
<p className="text-sm text-gray-600">
{item.seller?.name || "Store"}
</p>
{availableStock <= 5 && (
<p className="text-xs text-orange-600 font-medium">
{t("only_left", { count: availableStock })}
</p>
)}
<Button
variant="ghost"
size="sm"

View File

@@ -189,47 +189,12 @@ export default function OrderSummary({
}`}
/>
{showValidation && !isPhoneValid && (
<p className="text-xs text-red-500 mt-1">
{t("requiredField")}
</p>
<p className="text-xs text-red-500 mt-1">{t("requiredField")}</p>
)}
</div>
</div>
</div>
{/* Payment Type */}
<div className="mb-6">
<h3 className="text-lg font-semibold mb-3">{t("payment_type")}</h3>
<div className="flex gap-2">
{paymentTypes.map((type) => (
<Card
key={type.id}
className={`flex-1 cursor-pointer transition-all ${
paymentType?.id === type.id
? "border-2 border-[#005bff] bg-blue-50"
: showValidation && !paymentType
? "border-2 border-red-500"
: "border-2 border-gray-200"
}`}
onClick={() => onPaymentTypeChange(type)}
>
<div className="flex flex-col items-center justify-center p-4 gap-2">
<span
className={`text-xs font-medium ${
paymentType?.id === type.id ? "text-[#005bff]" : ""
}`}
>
{type.name}
</span>
</div>
</Card>
))}
</div>
{showValidation && !paymentType && (
<p className="text-xs text-red-500 mt-1">{t("requiredField")}</p>
)}
</div>
{/* Region Selection */}
<div className="mb-6">
<Label className="text-lg font-semibold mb-3 block">

View File

@@ -299,21 +299,7 @@ export default function ProductCard({
)}
</Carousel>
<button
onClick={handleFavorite}
disabled={isFavoriteToggling || isFavoriteLoading}
className="absolute top-3 cursor-pointer right-3 z-10 rounded-full bg-white/80 p-2 hover:bg-white transition-all disabled:opacity-50"
>
{isFavoriteLoading ? (
<div className="w-5 h-5 border-2 border-gray-300 border-t-gray-600 rounded-full animate-spin" />
) : (
<Heart
className={`w-5 h-5 ${
isFavorite ? "text-[#005bff] fill-[#005bff]" : "text-gray-700"
}`}
/>
)}
</button>
{hasMultipleImages && (
<div className="absolute bottom-2 left-1/2 -translate-x-1/2 z-10 flex gap-1.5">
@@ -365,8 +351,24 @@ export default function ProductCard({
</p>
</CardContent>
<div className="flex">
<button
onClick={handleFavorite}
disabled={isFavoriteToggling || isFavoriteLoading}
className=" cursor-pointer z-10 rounded-full bg-white/80 p-2 hover:bg-white transition-all disabled:opacity-50"
>
{isFavoriteLoading ? (
<div className="w-5 h-5 border-2 border-gray-300 border-t-gray-600 rounded-full animate-spin" />
) : (
<Heart
className={`w-5 h-5 ${
isFavorite ? "text-[#005bff] fill-[#005bff]" : "text-gray-700"
}`}
/>
)}
</button>
{button && !isOutOfStock && (
<div className="px-1">
<div className="px-1 w-full">
{!isInCart ? (
<Button
onClick={handleAddToCart}
@@ -413,6 +415,7 @@ export default function ProductCard({
)}
</div>
)}
</div>
</Card>
</div>

View File

@@ -94,6 +94,7 @@ export default function CollectionSection({ collection, locale }: Props) {
price_color="#0059ff"
height={360}
width={250}
button={true}
/>
);
})}

View File

@@ -47,31 +47,8 @@ export function ProductInfoCard({
</>
)}
{stock !== undefined && (
<>
<div className="flex justify-between items-center py-2">
<span className="text-gray-500">{t("stock")}</span>
<span
className={`font-medium ${
stock === 0
? "text-red-500"
: stock <= 5
? "text-orange-600"
: "text-green-600"
}`}
>
{stock === 0
? t("out_of_stock")
: stock <= 5
? `${t("only_left", { count: stock })}`
: stock}
</span>
</div>
<Separator />
</>
)}
{barcode && (
{/* {barcode && (
<>
<div className="flex justify-between items-center py-2">
<span className="text-gray-500">{t("barcode")}</span>
@@ -79,7 +56,7 @@ export function ProductInfoCard({
</div>
<Separator />
</>
)}
)} */}
{colour && (
<>

View File

@@ -39,10 +39,6 @@ interface PendingUpdate {
retryCount: number;
}
// const DEBUG = true
// const log = (...args: any[]) => {
// if (DEBUG) console.log("[ProductPage]", ...args)
// }
export default function ProductPageContent({ slug }: ProductDetailProps) {
const [localQuantity, setLocalQuantity] = useState(1);
@@ -524,14 +520,14 @@ export default function ProductPageContent({ slug }: ProductDetailProps) {
/>
</div>
<ProductReviewsSection
{/* <ProductReviewsSection
reviews={reviews}
averageRating={averageRating}
isLoading={false}
onWriteReview={() => setShowReviewModal(true)}
/>
<RelatedProductsSection products={transformedRelatedProducts} />
<RelatedProductsSection products={transformedRelatedProducts} /> */}
</div>
<StockLimitModal

View File

@@ -2,7 +2,6 @@ import Link from "next/link";
import { Minus, Plus, Heart, ShoppingCart, Store } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
interface ProductPurchaseCardProps {
price: string;
@@ -163,28 +162,7 @@ export function ProductPurchaseCard({
</div>
</Card>
{channelName && (
<Card className="p-6 rounded-xl">
<div className="flex items-center gap-4 mb-4">
<Avatar className="w-14 h-14 bg-primary/10">
<AvatarFallback className="bg-transparent">
<Store className="h-6 w-6 text-primary" />
</AvatarFallback>
</Avatar>
<div>
<p className="text-sm text-gray-500">{t("store")}</p>
<h4 className="text-lg font-bold">{channelName}</h4>
</div>
</div>
<Button
variant="outline"
size="lg"
className="w-full cursor-pointer rounded-lg"
>
{t("write_to_store")}
</Button>
</Card>
)}
</div>
);
}

View File

@@ -1,5 +1,5 @@
{
"name": "ecommerce",
"name": "Smart-Electronics",
"version": "0.1.0",
"private": true,
"scripts": {