diff --git a/01-frontend/src/helper/homepage/ItemCard.tsx b/01-frontend/src/helper/homepage/ItemCard.tsx index 735ee78..962f3c0 100644 --- a/01-frontend/src/helper/homepage/ItemCard.tsx +++ b/01-frontend/src/helper/homepage/ItemCard.tsx @@ -5,6 +5,7 @@ import Item from "../../components/Item"; import { useBasket } from "../BasketProvider"; import "../helper.css"; import { useTranslation } from 'react-i18next'; +import { useEffect, useMemo, useRef, useState } from "react"; export default function ItemCard({ item }: { item: Item }) { @@ -20,13 +21,29 @@ export default function ItemCard({ item }: { item: Item }) { const handleClick = () => { navigate(`/product/${item.id}`, { state: { item } }); } + const [imageUrl, setImageUrl] = useState("/src/assets/default.jpg"); // Fallback-Bild + + useEffect(() => { + const fetchImage = async () => { + try { + const response = await fetch(`http://localhost:8085/image?uuid=${item.uuid}`); + const data = await response.json(); + if (data.uri) { + setImageUrl(data.uri); // Bild-URL setzen + } + } catch (error) { + console.error("Fehler beim Laden des Bildes:", error); + } + }; + + fetchImage(); + }, [item.uuid]); - const imageUrl = `http://localhost:8085/image?articleId=${item.id}`; return ( - - + + { event.currentTarget.src = "/src/assets/default.jpg"; // Standardbild setzen }} + sx={{ + objectFit: "contain", // Bild wird skaliert, um vollständig sichtbar zu sein + maxWidth: "100%", // Begrenze die maximale Breite auf den Container + maxHeight: "100%", // Begrenze die maximale Höhe auf den Container + }} /> @@ -43,7 +65,7 @@ export default function ItemCard({ item }: { item: Item }) { - {(item.price100 * (1 - item.discount100 / 100)).toFixed(2)} € + {(item.price100 / 100 * (1 - item.discount100 / 100)).toFixed(2)} € void; }; -export default function PriceSlider({ min = 0, max = 100, onChange }: PriceSliderProps) { - +export default function PriceSlider({ min = 0, max = 10000, onChange }: PriceSliderProps) { const { t } = useTranslation(); const [value, setValue] = useState<[number, number]>([min, max]); + // Synchronisiere den Zustand nur, wenn sich die Props ändern + useEffect(() => { + setValue([min, max]); + onChange?.([min, max]); // Initiale Werte an die übergeordnete Komponente übergeben + }, [min, max]); + const handleChange = (_: Event, newValue: number | number[]) => { if (Array.isArray(newValue)) { setValue([newValue[0], newValue[1]]); @@ -21,27 +26,31 @@ export default function PriceSlider({ min = 0, max = 100, onChange }: PriceSlide const handleCommitted = (_: Event, newValue: number | number[]) => { if (Array.isArray(newValue)) { - onChange?.([newValue[0], newValue[1]]); + onChange?.([newValue[0], newValue[1]]); // Übergebe die neuen Werte an die übergeordnete Komponente } }; + const formatValueToEuro = (value: number) => { + return `${(value / 100).toFixed(2)} €`; // Umrechnung von Cent in Euro + }; + return (

{t('price')}

- + - - - {value[0]?.toFixed(2) ?? "0.00"} € - {value[1]?.toFixed(2) ?? "0.00"} € + + {formatValueToEuro(value[0])} - {formatValueToEuro(value[1])} +
); diff --git a/01-frontend/src/helper/productpage/ProductInfo.tsx b/01-frontend/src/helper/productpage/ProductInfo.tsx index ce6c2c3..00234cc 100644 --- a/01-frontend/src/helper/productpage/ProductInfo.tsx +++ b/01-frontend/src/helper/productpage/ProductInfo.tsx @@ -1,9 +1,9 @@ -import { Alert, Box, Button, Card, Divider, Grid, IconButton, Rating, Snackbar, SnackbarCloseReason, Stack, TextField, Typography } from "@mui/material"; -import Item from "../../components/Item"; -import React, { useState } from "react"; import { Close, LocalShipping, ShoppingCart } from "@mui/icons-material"; +import { Alert, Box, Button, Card, Divider, Grid, IconButton, Rating, Snackbar, SnackbarCloseReason, Stack, TextField, Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import Item from "../../components/Item"; import { useBasket } from "../BasketProvider"; -import {useTranslation} from "react-i18next"; export default function ProductInfo({ item }: { item: Item }) { @@ -53,7 +53,23 @@ export default function ProductInfo({ item }: { item: Item }) { setImageDimensions({ width: naturalWidth, height: naturalHeight }); }; - const imageUrl = `http://localhost:8085/image?articleId=${item.id}`; + const [imageUrl, setImageUrl] = useState("/src/assets/default.jpg"); // Fallback-Bild + + useEffect(() => { + const fetchImage = async () => { + try { + const response = await fetch(`http://localhost:8085/image?uuid=${item.uuid}`); + const data = await response.json(); + if (data.uri) { + setImageUrl(data.uri); // Bild-URL setzen + } + } catch (error) { + console.error("Fehler beim Laden des Bildes:", error); + } + }; + + fetchImage(); + }, [item.uuid]); return ( @@ -89,8 +105,8 @@ export default function ProductInfo({ item }: { item: Item }) { - {item.rating > 0 ? `(${item.rating} / 5)`: t('noRatingsYet')} - + {item.rating > 0 ? `(${item.rating} / 5)` : t('noRatingsYet')} + @@ -98,14 +114,14 @@ export default function ProductInfo({ item }: { item: Item }) { {item.discount100 > 0 ? ( <> - {discountedPrice.toFixed(2)} € + {(discountedPrice / 100).toFixed(2)} € - {item.price100.toFixed(2)} € + {(item.price100 / 100).toFixed(2)} € -{item.discount100} % @@ -113,7 +129,7 @@ export default function ProductInfo({ item }: { item: Item }) { ) : ( - {item.price100.toFixed(2)} € + {(item.price100 / 100).toFixed(2)} € )} diff --git a/01-frontend/src/helper/query/Queries.tsx b/01-frontend/src/helper/query/Queries.tsx index 1fc317d..3ccdc2c 100644 --- a/01-frontend/src/helper/query/Queries.tsx +++ b/01-frontend/src/helper/query/Queries.tsx @@ -3,7 +3,7 @@ import RatingSubmitType from "../../components/RatingSubmit"; export const fetchItemList = async () => { - const response = await fetch('http://localhost:8085/item/all'); + const response = await fetch('http://localhost:8085/article/all'); console.log("API Response:", response); if (!response.ok) { throw new Error('Fehler beim Laden der Items');