@@ -388,12 +390,16 @@ const CategoryPage = () => {
next={loadMoreData}
hasMore={hasMore}
scrollThreshold={0.8}
+ scrollableTarget={null}
+ style={{ overflow: "hidden" }}
loader={
-
+
}
- className={`${styles.productGrid} ${
+ className={`${styles.productGrid} ${
isMobilePhoneView ? styles.mobilePhoneGrid : ""
}`}
>
@@ -412,7 +418,7 @@ const CategoryPage = () => {
showFavoriteButton
showAddToCart
/>
- )
+ ),
)}
) : (
diff --git a/src/pages/ProductDetail/ProductPage.module.scss b/src/pages/ProductDetail/ProductPage.module.scss
index 33bc94f..e396221 100644
--- a/src/pages/ProductDetail/ProductPage.module.scss
+++ b/src/pages/ProductDetail/ProductPage.module.scss
@@ -7,6 +7,7 @@
box-sizing: border-box;
}
+// ─── Breadcrumb ───────────────────────────────────────────────────
.breadcrumb {
margin-bottom: 15px;
color: #666;
@@ -19,70 +20,255 @@
}
}
+// ─── Product section: 3 kolon ─────────────────────────────────────
+// desktop: [image 35%] | [info+description flex:1] | [purchase 260px]
+// tablet: [image 45%] [info 55%] / [purchase full-width]
+// mobile: tek kolon
.productSection {
display: flex;
gap: 24px;
- background-color: rgb(255, 255, 255);
+ align-items: flex-start;
+ background-color: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border-radius: 4px;
padding: 1.25rem;
box-sizing: border-box;
+
+ @media screen and (max-width: 900px) {
+ flex-wrap: wrap;
+ }
+
@media screen and (max-width: 639px) {
flex-direction: column;
padding: 0.75rem;
}
}
+// ─── Sol: resim kolonu ────────────────────────────────────────────
.productImage {
background: #fff;
padding: 20px;
border-radius: 8px;
- width: 40%;
+ width: 35%;
+ flex-shrink: 0;
+
@media screen and (max-width: 900px) {
+ width: 45%;
padding: 5px;
}
+
@media screen and (max-width: 639px) {
width: 100%;
+ padding: 0;
}
img {
width: 99%;
height: auto;
object-fit: contain;
- // border: 1px solid #eee;
- @media screen and (max-width: 900px) {
- height: 100%;
+ }
+}
+
+// ─── Orta: isim + meta + description kolonu ───────────────────────
+.productInfo {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ min-width: 0;
+
+ @media screen and (max-width: 900px) {
+ // tablet: image(45%) + info yan yana, purchase wrap ile alta iner
+ width: calc(55% - 24px);
+ flex: none;
+ }
+
+ @media screen and (max-width: 639px) {
+ width: 100%;
+
+ // mobile'da purchase card orta kolona taşınır (sticky bar var)
+ border-bottom: 1px solid #e5e7eb;
+ }
+
+ .productTitle {
+ font-size: 24px;
+ font-weight: 600;
+ margin: 0 0 4px;
+ color: #000;
+ line-height: 1.3;
+ }
+}
+
+// ─── Sağ: satın alma kartı kolonu ────────────────────────────────
+.purchaseCol {
+ width: 260px;
+ flex-shrink: 0;
+
+ @media screen and (max-width: 900px) {
+ width: 100%;
+ }
+
+ @media screen and (max-width: 639px) {
+ display: none; // mobile'da sticky bar devreye girer
+ }
+}
+
+.purchaseCard {
+ border: 1px solid #e5e7eb;
+ border-radius: 8px;
+ padding: 16px;
+ background: #fff;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
+}
+
+// ─── Fiyat satırı ─────────────────────────────────────────────────
+.priceRow {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ margin-bottom: 14px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid #f3f4f6;
+}
+
+.priceLabel {
+ font-size: 15px;
+ color: #666;
+}
+
+.priceRight {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ gap: 2px;
+}
+
+.price {
+ font-size: 28px;
+ font-weight: 700;
+ color: #000;
+}
+
+.oldPrice {
+ font-size: 14px;
+ color: #d32824;
+ text-decoration: line-through;
+ font-weight: 500;
+}
+
+// ─── Aksiyon butonları satırı ─────────────────────────────────────
+.Btn {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+}
+
+.addToCartButton {
+ flex: 1;
+ height: 42px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 8px;
+ border-radius: 6px;
+ border: none;
+ background-color: #d32824;
+ color: #fff;
+ font-size: 15px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: background-color 150ms ease;
+ white-space: nowrap;
+
+ svg {
+ fill: #fff;
+ width: 18px;
+ height: 18px;
+ flex-shrink: 0;
+ }
+
+ &:hover {
+ background-color: #e86064;
+ }
+}
+
+.favoriteButton {
+ width: 42px;
+ height: 42px;
+ flex-shrink: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 6px;
+ background-color: #fff;
+ border: 1px solid #e5e7eb;
+ cursor: pointer;
+ transition: border-color 150ms ease;
+
+ svg {
+ fill: #888;
+ height: 20px;
+ width: 20px;
+ }
+
+ &:hover {
+ border-color: #d32824;
+
+ svg {
+ fill: #d32824;
}
}
}
-.productInfo {
- width: 60%;
- @media screen and (max-width: 639px) {
- width: 100%;
- }
- @media screen and (max-width: 520px) {
- border-bottom: 1px solid #e5e7eb;
- }
- .productTitle {
- font-size: 30px;
- font-weight: 600;
- margin-bottom: 12px;
- color: #000000;
+// ─── Quantity controls ────────────────────────────────────────────
+.quantityControls {
+ flex: 1;
+ height: 42px;
+ display: flex;
+ align-items: center;
+ background-color: #d32824;
+ border-radius: 6px;
+ overflow: hidden;
+
+ span {
+ color: #fff;
+ font-weight: 700;
+ font-size: 16px;
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
- .productDescription {
- font-size: 14px;
- color: #000;
- margin-bottom: 24px;
+ .quantityBtn {
+ width: 42px;
+ height: 42px;
+ border: none;
+ background: transparent;
+ cursor: pointer;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-shrink: 0;
+
+ svg {
+ fill: #fff;
+ width: 18px;
+ height: 18px;
+ }
+
+ &:hover {
+ background: #e86064;
+ }
}
}
+// ─── Meta tablo ───────────────────────────────────────────────────
.productMeta {
- background: #f5f5f5;
- // padding: 16px;
+ border: 1px solid #e5e7eb;
border-radius: 8px;
- margin-bottom: 24px;
+ overflow: hidden;
+ background: #f5f5f5;
.metaItem {
display: flex;
@@ -105,105 +291,103 @@
font-weight: 500;
}
}
-.Btn {
- display: flex;
- gap: 10px;
- @media screen and (max-width: 639px) {
- width: 65%;
- }
-}
-.priceContainer {
- display: flex;
- align-items: baseline;
- gap: 10px;
- @media screen and (max-width: 639px) {
- flex-direction: column;
- gap: 5px;
- width: 35%;
- align-items: center;
- }
+
+// ─── Description card ─────────────────────────────────────────────
+.descriptionCard {
+ border: 1px solid #e5e7eb;
+ border-radius: 8px;
+ padding: 16px 20px;
+ background: #fff;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}
-.productActions {
- @media screen and (max-width: 639px) {
- display: none !important;
- }
-}
-.productActionsMobile {
- @media screen and (min-width: 639px) {
- background-color: #fff;
- display: none !important;
- position: sticky !important;
- bottom: 60px !important;
- }
-}
-.productActions,
-.productActionsMobile {
+.descriptionHeader {
display: flex;
align-items: center;
- justify-content: space-between;
- border-bottom: 1px solid #e5e7eb;
- border-top: 1px solid #e5e7eb;
- background-color: #fff;
- padding: 15px 16px;
- @media screen and (max-width: 520px) {
- border-bottom: none;
- border-top: none;
- padding: 0;
+ gap: 10px;
+ margin-bottom: 12px;
+
+ .descriptionIcon {
+ width: 32px;
+ height: 32px;
+ border-radius: 6px;
+ background: #1a1a2e;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+
+ svg {
+ width: 16px;
+ height: 16px;
+ stroke: #fff;
+ fill: none;
+ }
}
- .price {
- font-size: 24px;
+ .descriptionTitle {
+ font-size: 16px;
font-weight: 700;
color: #000;
- @media screen and (max-width: 520px) {
- font-size: 20px;
- }
+ margin: 0;
}
+}
+
+.productDescription {
+ font-size: 14px;
+ color: #000;
+ line-height: 1.7;
+}
+
+// ─── Mobile sticky bar ────────────────────────────────────────────
+.productActionsMobile {
+ display: none;
+
+ @media screen and (max-width: 639px) {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ position: sticky;
+ bottom: 59px;
+ z-index: 50;
+ background: #fff;
+ border-top: 1px solid #e5e7eb;
+ border-bottom: 1px solid #e5e7eb;
+ padding: 10px 16px;
+ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08);
+ gap: 12px;
+ }
+}
+
+.mobilePriceContainer {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ width: 35%;
+
+ .price {
+ font-size: 20px;
+ font-weight: 700;
+ color: #000;
+ }
+
.oldPrice {
- font-size: 16px;
+ font-size: 13px;
color: #d32824;
text-decoration: line-through;
- font-weight: 600;
- @media screen and (max-width: 520px) {
- font-size: 14px;
- }
+ font-weight: 500;
}
}
-.favoriteButton {
- height: 36px;
+.mobileBtnContainer {
display: flex;
- // margin-right: 0.5rem;
- justify-content: center;
- align-items: center;
- border-radius: 0.375rem;
- background-color: rgb(255 255 255);
- border: 1px solid rgb(237 228 255);
- svg {
- fill: #888888;
- height: 20px;
- width: 20px;
- }
-}
-
-.wishlistButton {
- background: #fff;
- border: 1px solid #ddd;
-
- &:hover {
- background: #f5f5f5;
- }
-}
-
-@media (max-width: 768px) {
- .productGrid {
- grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
- }
+ gap: 8px;
+ width: 65%;
}
+// ─── Similar products ─────────────────────────────────────────────
.similarProducts {
- margin-top: 48px;
+ margin-top: 40px;
.sectionTitle {
font-size: 20px;
@@ -216,117 +400,27 @@
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 24px;
+
@media screen and (max-width: 1230px) {
grid-template-columns: repeat(auto-fill, minmax(225px, 1fr));
}
+
@media screen and (max-width: 1023px) {
grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
}
+
@media screen and (max-width: 768px) {
grid-template-columns: repeat(auto-fill, minmax(234px, 1fr));
gap: 10px;
}
- @media screen and (max-width: 767px) {
- grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
- }
+
@media screen and (max-width: 510px) {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
}
-@media (max-width: 768px) {
- .productSection {
- grid-template-columns: 1fr;
- }
-}
-
-.addToCartButton {
- // height: 40px;
- display: flex;
- padding-left: 0.5rem;
- padding-right: 0.5rem;
- justify-content: center;
- align-items: center;
- border-radius: 0.25rem;
- border-width: 1px;
- width: 100%;
- min-width: 158px;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 300ms;
- transition-duration: 150ms;
- background-color: #d32824;
- border: none;
- @media screen and (max-width: 639px) {
- min-width: auto;
- }
- svg {
- fill: #fff;
- width: 20px;
- height: 20px;
- }
-
- &:hover {
- background-color: #e86064;
- cursor: pointer;
- }
-}
-
-.quantityControls {
- min-width: 158px;
- display: flex;
- align-items: center;
- gap: 2.5rem;
- background-color: #d32824;
- // width: 10rem;
- // justify-content: center;
- border-radius: 5px;
- width: 100%;
- @media screen and (max-width: 520px) {
- min-width: auto;
- gap: 0;
- }
- span {
- color: #fff;
- font-weight: 700;
- font-size: 16px;
- display: flex;
- width: 100%;
- justify-content: center;
- }
-
- .quantityBtn {
- width: 100%;
- height: 100%;
- border: none;
- background: transparent;
- border-radius: 4px;
- cursor: pointer;
- display: flex;
- justify-content: center;
- align-items: center;
- svg {
- fill: #fff;
- width: 20px;
- height: 20px;
- }
-
- &:hover {
- background: #e86064;
- }
- }
-}
-
-.outOfStock {
- background-color: #ff4d4f;
-}
-
-.disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
+// ─── Misc ─────────────────────────────────────────────────────────
.modalButton {
- // Style for modal buttons
padding: 6px 15px;
background-color: #1890ff;
color: white;
@@ -334,3 +428,21 @@
border-radius: 8px;
cursor: pointer;
}
+
+.wishlistButton {
+ background: #fff;
+ border: 1px solid #ddd;
+
+ &:hover {
+ background: #f5f5f5;
+ }
+}
+
+.disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.outOfStock {
+ background-color: #ff4d4f;
+}
\ No newline at end of file
diff --git a/src/pages/ProductDetail/index.jsx b/src/pages/ProductDetail/index.jsx
index 7f8647f..68cfbe2 100644
--- a/src/pages/ProductDetail/index.jsx
+++ b/src/pages/ProductDetail/index.jsx
@@ -38,18 +38,22 @@ const ProductPage = ({
const navigate = useNavigate();
const { productId } = useParams();
const { t } = useTranslation();
+
const {
data: productResponse,
error: productError,
isLoading: productLoading,
} = useGetProductByIdQuery(productId);
+
const {
data: similarProductsResponse,
error: similarProductsError,
isLoading: similarProductsLoading,
} = useGetRelatedProductsQuery(productId);
+
const product = productResponse?.data;
const similarProducts = similarProductsResponse?.data;
+
const [stockErrorModalVisible, setStockErrorModalVisible] = useState(false);
const [addFavorite] = useAddFavoriteMutation();
const [removeFavorite] = useRemoveFavoriteMutation();
@@ -183,7 +187,6 @@ const ProductPage = ({
10
);
- // Sadece miktar değiştiyse ve 0'dan büyükse güncelle (0 ise Remove triggerlanır)
if (pendingQuantity === serverQty || pendingQuantity <= 0) {
return;
}
@@ -197,7 +200,6 @@ const ProductPage = ({
}).unwrap();
} catch (error) {
console.error("Failed to update cart item:", error);
- // Hata durumunda geri al
setLocalQuantity(serverQty);
setPendingQuantity(serverQty);
} finally {
@@ -225,12 +227,74 @@ const ProductPage = ({
if (!product) return
Can not find product
;
- const imageUrl = product.media?.[0]?.thumbnail || "";
const categoryName = product.categories?.[0]?.name || "Category";
const categoryId = product.categories?.[0]?.id;
+
const handleCategoryClick = (categoryId) => {
navigate(`/category/${categoryId}`);
};
+
+ // ── Cart + favorite butonları (desktop purchase card + mobile bar'da ortak) ──
+ const CartButtons = () => (
+
+ {showFavoriteButton && (
+
+ )}
+
+ {showAddToCart && (
+ <>
+ {localQuantity > 0 ? (
+
+
+
{localQuantity}
+
+
+ ) : (
+
+ )}
+ >
+ )}
+
+ );
+
return (
{/* Breadcrumb */}
@@ -242,8 +306,10 @@ const ProductPage = ({
{product?.name || "Product"}
- {/* Product Details */}
+ {/* ── 3 kolon ana section ── */}
+
+ {/* KOLON 1: Resim */}
+
+ {/* KOLON 2: İsim + Meta + Description */}
{product.name}
-
+ {/* Meta tablo */}
@@ -266,12 +331,14 @@ const ProductPage = ({
{product.id}
+
{product.barcode && (
{t("product.barCode")}
{product.barcode}
)}
+
{product.brand?.name && (
{t("order.brand")}
@@ -288,145 +355,73 @@ const ProductPage = ({
)}
-
-
-
{product.price_amount} m.
- {product.old_price_amount && (
-
- {product.old_price_amount} m.
+ {/* Description card */}
+ {product.description && (
+
+
+
+
+ {t("product.description")}
+
+
+
+
+ )}
+
+
+ {/* KOLON 3: Satın alma kartı (sadece desktop/tablet) */}
+
+
+ {/* Fiyat */}
+
+
{t("product.price")}:
+
+
+ {product.price_amount} m.
- )}
+ {product.old_price_amount && (
+
+ {product.old_price_amount} m.
+
+ )}
+
-
- {showFavoriteButton && (
-
- )}
- {showAddToCart && (
- <>
- {localQuantity > 0 ? (
-
-
-
{localQuantity}
-
-
- ) : (
-
- )}
- >
- )}
-
-
-
-
- {" "}
- {product.price_amount} m.
-
- {product.old_price_amount} m.
-
-
-
- {showFavoriteButton && (
-
- )}
-
- {showAddToCart && (
- <>
- {localQuantity > 0 ? (
-
-
-
{localQuantity}
-
-
- ) : (
-
- )}
- >
- )}
-
+ {/* Butonlar */}
+
+
+ {/* ── Mobile sticky bar ── */}
+
+
+ {product.price_amount} m.
+ {product.old_price_amount && (
+
+ {product.old_price_amount} m.
+
+ )}
+
+
+
+
+
+
+ {/* Reviews */}
+ {/* Stock modal */}