fixed fav prod on prod detail page

This commit is contained in:
@jcarymuhammedow
2026-01-14 17:00:05 +05:00
parent 071b45b98a
commit 188df98bbf
4 changed files with 51 additions and 13 deletions

View File

@@ -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>

View File

@@ -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 && (
<> <>

View File

@@ -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}

View File

@@ -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",