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,7 +19,6 @@ import EmptyCart from "@/features/cart/components/EmptyCart";
import ErrorPage from "@/components/ErrorPage"; import ErrorPage from "@/components/ErrorPage";
export default function CartPage() { export default function CartPage() {
const [isClient, setIsClient] = useState(false);
const [paymentType, setPaymentType] = useState<PaymentType | null>(null); const [paymentType, setPaymentType] = useState<PaymentType | null>(null);
const [deliveryType, setDeliveryType] = const [deliveryType, setDeliveryType] =
useState<DeliveryType>("SELECTED_DELIVERY"); useState<DeliveryType>("SELECTED_DELIVERY");
@@ -42,26 +41,35 @@ export default function CartPage() {
const isLoading = cartLoading || provincesLoading || paymentTypesLoading; const isLoading = cartLoading || provincesLoading || paymentTypesLoading;
useEffect(() => { useEffect(() => {
setIsClient(true); if (paymentTypes.length > 0) {
}, []); const defaultType = paymentTypes.find((t) => t.id === 1);
if (defaultType) {
setPaymentType(defaultType);
}
}
}, [paymentTypes]);
const regionGroups = useMemo(() => { const regionGroups = useMemo(() => {
return provinces.reduce((acc, province) => { return provinces.reduce(
(acc, province) => {
if (!acc[province.region]) { if (!acc[province.region]) {
acc[province.region] = []; acc[province.region] = [];
} }
acc[province.region].push(province); acc[province.region].push(province);
return acc; return acc;
}, {} as Record<string, typeof provinces>); },
{} as Record<string, typeof provinces>,
);
}, [provinces]); }, [provinces]);
const availableRegions = useMemo( const availableRegions = useMemo(
() => Object.keys(regionGroups), () => Object.keys(regionGroups),
[regionGroups] [regionGroups],
); );
const itemsBySeller = useMemo(() => { const itemsBySeller = useMemo(() => {
return cartItems.reduce((acc, item) => { return cartItems.reduce(
(acc, item) => {
const sellerId = item.product.channel?.[0]?.id || 0; const sellerId = item.product.channel?.[0]?.id || 0;
const sellerName = item.product.channel?.[0]?.name || "Unknown Seller"; const sellerName = item.product.channel?.[0]?.name || "Unknown Seller";
@@ -73,7 +81,12 @@ export default function CartPage() {
} }
acc[sellerId].items.push(item); acc[sellerId].items.push(item);
return acc; return acc;
}, {} as Record<number, { seller: { id: number; name: string }; items: typeof cartItems }>); },
{} as Record<
number,
{ seller: { id: number; name: string }; items: typeof cartItems }
>,
);
}, [cartItems]); }, [cartItems]);
const totalAmount = useMemo(() => { const totalAmount = useMemo(() => {
@@ -88,14 +101,18 @@ export default function CartPage() {
setSelectedProvince(null); setSelectedProvince(null);
}; };
const formatPhoneForBackend = (phoneNumber: string): string => { const formatPhoneForBackend = (phoneNumber: string): string => {
return phoneNumber.replace(/^\+993\s*/, "").replace(/\s+/g, ""); return phoneNumber.replace(/^\+993\s*/, "").replace(/\s+/g, "");
}; };
const handleCompleteOrder = () => { const handleCompleteOrder = () => {
if (!selectedRegion || !selectedProvince || !paymentType || !phone || !name) { if (
!selectedRegion ||
!selectedProvince ||
!paymentType ||
!phone ||
!name
) {
console.warn("Missing required fields for order"); console.warn("Missing required fields for order");
return; return;
} }
@@ -106,7 +123,9 @@ export default function CartPage() {
return; return;
} }
const selectedProvinceData = provinces.find((p) => p.id === selectedProvince); const selectedProvinceData = provinces.find(
(p) => p.id === selectedProvince,
);
if (!selectedProvinceData) return; if (!selectedProvinceData) return;
createOrder( createOrder(
@@ -123,12 +142,10 @@ export default function CartPage() {
onSuccess: () => { onSuccess: () => {
router.push(`/orders`); router.push(`/orders`);
}, },
} },
); );
}; };
if (!isClient) return null;
if (isLoading) { if (isLoading) {
return ( return (
<div className="mx-auto px-2 md:px-4 lg:px-6 mb-18"> <div className="mx-auto px-2 md:px-4 lg:px-6 mb-18">
@@ -171,12 +188,10 @@ export default function CartPage() {
{Object.entries(itemsBySeller).map( {Object.entries(itemsBySeller).map(
([sellerId, { seller, items }]) => ( ([sellerId, { seller, items }]) => (
<div key={sellerId} className="mb-6"> <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"> <div className="space-y-4">
{items.map((item) => { {items.map((item) => {
const price = parseFloat( const price = parseInt(item.product.price_amount || "0");
item.product.price_amount || "0"
);
const quantity = item.product_quantity; const quantity = item.product_quantity;
const total = price * quantity; const total = price * quantity;
@@ -200,7 +215,7 @@ export default function CartPage() {
item.product.media?.[0]?.thumbnail, item.product.media?.[0]?.thumbnail,
images: images:
item.product.media?.map( 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" /> <Separator className="mt-4" />
)} )}
</div> </div>
) ),
)} )}
</Card> </Card>
</div> </div>

View File

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

View File

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

View File

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

View File

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

View File

@@ -189,46 +189,11 @@ export default function OrderSummary({
}`} }`}
/> />
{showValidation && !isPhoneValid && ( {showValidation && !isPhoneValid && (
<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> <p className="text-xs text-red-500 mt-1">{t("requiredField")}</p>
)} )}
</div> </div>
</div>
</div>
{/* Region Selection */} {/* Region Selection */}
<div className="mb-6"> <div className="mb-6">

View File

@@ -299,21 +299,7 @@ export default function ProductCard({
)} )}
</Carousel> </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 && ( {hasMultipleImages && (
<div className="absolute bottom-2 left-1/2 -translate-x-1/2 z-10 flex gap-1.5"> <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> </p>
</CardContent> </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 && ( {button && !isOutOfStock && (
<div className="px-1"> <div className="px-1 w-full">
{!isInCart ? ( {!isInCart ? (
<Button <Button
onClick={handleAddToCart} onClick={handleAddToCart}
@@ -413,6 +415,7 @@ export default function ProductCard({
)} )}
</div> </div>
)} )}
</div>
</Card> </Card>
</div> </div>

View File

@@ -94,6 +94,7 @@ export default function CollectionSection({ collection, locale }: Props) {
price_color="#0059ff" price_color="#0059ff"
height={360} height={360}
width={250} 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"> <div className="flex justify-between items-center py-2">
<span className="text-gray-500">{t("barcode")}</span> <span className="text-gray-500">{t("barcode")}</span>
@@ -79,7 +56,7 @@ export function ProductInfoCard({
</div> </div>
<Separator /> <Separator />
</> </>
)} )} */}
{colour && ( {colour && (
<> <>

View File

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

View File

@@ -2,7 +2,6 @@ import Link from "next/link";
import { Minus, Plus, Heart, ShoppingCart, Store } from "lucide-react"; import { Minus, Plus, Heart, ShoppingCart, Store } from "lucide-react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card"; import { Card } from "@/components/ui/card";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
interface ProductPurchaseCardProps { interface ProductPurchaseCardProps {
price: string; price: string;
@@ -163,28 +162,7 @@ export function ProductPurchaseCard({
</div> </div>
</Card> </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> </div>
); );
} }

View File

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