fixed fav prod on prod detail page
This commit is contained in:
@@ -160,7 +160,7 @@ export default function CartPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto px-2 md:px-4 lg:px-6 mb-18">
|
<div className="flex flex-col mx-auto max-w-[1504px] px-2 md:px-4 lg:px-6 mb-18">
|
||||||
<h1 className="text-xl md:text-2xl lg:text-3xl font-bold mb-4 md:mb-6 pt-3">
|
<h1 className="text-xl md:text-2xl lg:text-3xl font-bold mb-4 md:mb-6 pt-3">
|
||||||
{t("cart")}
|
{t("cart")}
|
||||||
</h1>
|
</h1>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ interface ProductProperty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ProductInfoCardProps {
|
interface ProductInfoCardProps {
|
||||||
|
name: string;
|
||||||
brandName?: string;
|
brandName?: string;
|
||||||
stock?: number;
|
stock?: number;
|
||||||
barcode?: string;
|
barcode?: string;
|
||||||
@@ -20,6 +21,7 @@ interface ProductInfoCardProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ProductInfoCard({
|
export function ProductInfoCard({
|
||||||
|
name,
|
||||||
brandName,
|
brandName,
|
||||||
stock,
|
stock,
|
||||||
barcode,
|
barcode,
|
||||||
@@ -30,12 +32,10 @@ export function ProductInfoCard({
|
|||||||
reviewsCount,
|
reviewsCount,
|
||||||
t,
|
t,
|
||||||
}: ProductInfoCardProps) {
|
}: ProductInfoCardProps) {
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 space-y-6 bg-white">
|
<div className="flex-1 space-y-6 bg-white">
|
||||||
<Card className="p-4 rounded-xl border-gray-200">
|
<Card className="p-4 rounded-xl border-gray-200">
|
||||||
<h3 className="text-xl font-semibold mb-4">{t("about_product")}</h3>
|
<h3 className="text-xl font-semibold mb-4">{name}</h3>
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{brandName && (
|
{brandName && (
|
||||||
<>
|
<>
|
||||||
@@ -123,4 +123,4 @@ export function ProductInfoCard({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,10 @@ import { ProductReviewsSection } from "./ProductReviewsSection";
|
|||||||
import { RelatedProductsSection } from "./RelatedProductsSection";
|
import { RelatedProductsSection } from "./RelatedProductsSection";
|
||||||
import { ReviewModal } from "./ReviewModal";
|
import { ReviewModal } from "./ReviewModal";
|
||||||
import { StockLimitModal } from "./StockLimitModal";
|
import { StockLimitModal } from "./StockLimitModal";
|
||||||
|
import {
|
||||||
|
useIsFavorite,
|
||||||
|
useToggleFavorite,
|
||||||
|
} from "@/features/favorites/hooks/useFavorites";
|
||||||
interface ProductDetailProps {
|
interface ProductDetailProps {
|
||||||
slug: string;
|
slug: string;
|
||||||
}
|
}
|
||||||
@@ -43,7 +46,7 @@ interface PendingUpdate {
|
|||||||
|
|
||||||
export default function ProductPageContent({ slug }: ProductDetailProps) {
|
export default function ProductPageContent({ slug }: ProductDetailProps) {
|
||||||
const [localQuantity, setLocalQuantity] = useState(1);
|
const [localQuantity, setLocalQuantity] = useState(1);
|
||||||
const [isFavorite, setIsFavorite] = useState(false);
|
|
||||||
const [isSyncing, setIsSyncing] = useState(false);
|
const [isSyncing, setIsSyncing] = useState(false);
|
||||||
const [syncError, setSyncError] = useState(false);
|
const [syncError, setSyncError] = useState(false);
|
||||||
const [showStockModal, setShowStockModal] = useState(false);
|
const [showStockModal, setShowStockModal] = useState(false);
|
||||||
@@ -68,7 +71,9 @@ export default function ProductPageContent({ slug }: ProductDetailProps) {
|
|||||||
error,
|
error,
|
||||||
refetch: refetchProduct,
|
refetch: refetchProduct,
|
||||||
} = useProductsBySlug(slug);
|
} = useProductsBySlug(slug);
|
||||||
|
const { isFavorite, isLoading: isFavLoading } = useIsFavorite(
|
||||||
|
product?.id || 0
|
||||||
|
);
|
||||||
const cartOptions = useMemo(
|
const cartOptions = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
refetchOnMount: true,
|
refetchOnMount: true,
|
||||||
@@ -77,7 +82,7 @@ export default function ProductPageContent({ slug }: ProductDetailProps) {
|
|||||||
}),
|
}),
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
const { mutate: toggleFavoriteMutation } = useToggleFavorite();
|
||||||
const {
|
const {
|
||||||
data: cartData,
|
data: cartData,
|
||||||
refetch: refetchCart,
|
refetch: refetchCart,
|
||||||
@@ -374,9 +379,41 @@ export default function ProductPageContent({ slug }: ProductDetailProps) {
|
|||||||
});
|
});
|
||||||
}, [localQuantity]);
|
}, [localQuantity]);
|
||||||
|
|
||||||
const handleToggleFavorite = useCallback(() => {
|
const handleToggleFavorite = useCallback(
|
||||||
setIsFavorite(!isFavorite);
|
(e?: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
}, [isFavorite]);
|
e?.preventDefault();
|
||||||
|
e?.stopPropagation();
|
||||||
|
|
||||||
|
if (!product?.id) {
|
||||||
|
toast.error(t("error"), {
|
||||||
|
description: "Product ID not found",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFavoriteMutation(
|
||||||
|
{
|
||||||
|
productId: product.id,
|
||||||
|
isFavorite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
toast.success(
|
||||||
|
data?.wasAdded
|
||||||
|
? t("added_to_favorites")
|
||||||
|
: t("removed_from_favorites")
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
toast.error(t("error"), {
|
||||||
|
description: "Try again later",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[product?.id, isFavorite, toggleFavoriteMutation, t]
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmitReview = useCallback(
|
const handleSubmitReview = useCallback(
|
||||||
async (rating: number, text: string) => {
|
async (rating: number, text: string) => {
|
||||||
@@ -456,6 +493,7 @@ export default function ProductPageContent({ slug }: ProductDetailProps) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<ProductInfoCard
|
<ProductInfoCard
|
||||||
|
name={product.name}
|
||||||
brandName={product.brand?.name ?? undefined}
|
brandName={product.brand?.name ?? undefined}
|
||||||
stock={product.stock}
|
stock={product.stock}
|
||||||
barcode={product.barcode}
|
barcode={product.barcode}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@
|
|||||||
"share_experience": "Bu haryt barada öz teswiriňizi ýazyň",
|
"share_experience": "Bu haryt barada öz teswiriňizi ýazyň",
|
||||||
"rating": "Reýting",
|
"rating": "Reýting",
|
||||||
"your_review": "Teswiriňiz",
|
"your_review": "Teswiriňiz",
|
||||||
"sumbit": "Ugratmak",
|
"submit": "Ugratmak",
|
||||||
"submitting": "Ugradylýar...",
|
"submitting": "Ugradylýar...",
|
||||||
"submit_review": "Teswiri ugrat",
|
"submit_review": "Teswiri ugrat",
|
||||||
"characters": "simbol",
|
"characters": "simbol",
|
||||||
|
|||||||
Reference in New Issue
Block a user