diff --git a/01-frontend/src/App.tsx b/01-frontend/src/App.tsx index 1408b3d..55cc216 100644 --- a/01-frontend/src/App.tsx +++ b/01-frontend/src/App.tsx @@ -1,7 +1,7 @@ import ReactDOM from 'react-dom/client'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; import './App.css'; -import NavBar from './helper/NavBar'; +import NavBar from './helper/navbar/NavBar'; import Home from './pages/Home'; import NoPage from './pages/NoPage'; import Product from './pages/Product'; diff --git a/01-frontend/src/helper/Ratings.tsx b/01-frontend/src/helper/Ratings.tsx deleted file mode 100644 index 61ab41b..0000000 --- a/01-frontend/src/helper/Ratings.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Box, Button, Divider, Rating, TextField, Typography } from "@mui/material"; -import RatingCard from "./RatingCard"; -import RatingType from "../components/Rating"; - -export default function Ratings() { - - const ratings: RatingType[] = [ - { - id: "1", - rating: 4.5, - text: "Great product!", - date: "2023-10-01", - }, - { - id: "2", - rating: 3.0, - text: "Average quality.", - date: "2023-10-02", - }, - { - id: "3", - rating: 5.0, - text: "Excellent value for money!", - date: "2023-10-03", - }, - ]; - - return ( - <> -
- -
-
- - Rate this product: - - - -
-
- -
- - {ratings.map((ratingType: RatingType) => ( - - ))} - - - ); -} \ No newline at end of file diff --git a/01-frontend/src/helper/FilterItem.tsx b/01-frontend/src/helper/homepage/FilterItem.tsx similarity index 100% rename from 01-frontend/src/helper/FilterItem.tsx rename to 01-frontend/src/helper/homepage/FilterItem.tsx diff --git a/01-frontend/src/helper/ItemCard.tsx b/01-frontend/src/helper/homepage/ItemCard.tsx similarity index 95% rename from 01-frontend/src/helper/ItemCard.tsx rename to 01-frontend/src/helper/homepage/ItemCard.tsx index 03511d7..5597f73 100644 --- a/01-frontend/src/helper/ItemCard.tsx +++ b/01-frontend/src/helper/homepage/ItemCard.tsx @@ -1,9 +1,9 @@ import { AddShoppingCart } from "@mui/icons-material"; import { Card, CardActionArea, CardContent, CardMedia, IconButton, Paper, Rating, Typography } from "@mui/material"; import { useNavigate } from "react-router-dom"; -import Item from "../components/Item"; -import { useBasket } from "./BasketProvider"; -import "./helper.css"; +import Item from "../../components/Item"; +import { useBasket } from "../BasketProvider"; +import "../helper.css"; export default function ItemCard({ item }: { item: Item }) { const navigate = useNavigate() diff --git a/01-frontend/src/helper/NavBar.css b/01-frontend/src/helper/navbar/NavBar.css similarity index 100% rename from 01-frontend/src/helper/NavBar.css rename to 01-frontend/src/helper/navbar/NavBar.css diff --git a/01-frontend/src/helper/NavBar.tsx b/01-frontend/src/helper/navbar/NavBar.tsx similarity index 100% rename from 01-frontend/src/helper/NavBar.tsx rename to 01-frontend/src/helper/navbar/NavBar.tsx diff --git a/01-frontend/src/helper/productpage/ProductInfo.tsx b/01-frontend/src/helper/productpage/ProductInfo.tsx new file mode 100644 index 0000000..a749b63 --- /dev/null +++ b/01-frontend/src/helper/productpage/ProductInfo.tsx @@ -0,0 +1,165 @@ +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 { useBasket } from "../BasketProvider"; + +export default function ProductInfo({ item }: { item: Item }) { + const [quantity, setQuantity] = useState(1); + const [open, setOpen] = useState(false); + const [imageDimensions, setImageDimensions] = useState({ width: 0, height: 0 }); + + + const { addToBasket } = useBasket(); + + const handleClose = ( + event: React.SyntheticEvent | Event, + reason?: SnackbarCloseReason, + ) => { + if (reason === 'clickaway') { + return; + } + + setOpen(false); + }; + + const action = ( + + + + + + ); + + + const handleAddToCart = () => { + addToBasket(item.id, quantity); + setOpen(true); + console.log(`Added {quantity} of €{item.name} to basket`); + }; + + const discountedPrice = item.price * (1 - item.discount / 100); + + const handleImageLoad = (event: React.SyntheticEvent) => { + const { naturalWidth, naturalHeight } = event.currentTarget; + setImageDimensions({ width: naturalWidth, height: naturalHeight }); + }; + + return ( + + {/* Left Column - Image */} + + + imageDimensions.height ? "100%" : "auto", + maxHeight: imageDimensions.height >= imageDimensions.width ? 400 : "auto", + width: "auto", + height: "auto", + objectFit: "contain", + }} + /> + + + + {/* Right Column - Product Details */} + + + + {item.name} + + + + + + ({item.rating} / 5) + + + + + {item.discount > 0 ? ( + <> + + €{discountedPrice.toFixed(2)} + + + €{item.price.toFixed(2)} + + + -{item.discount}% + + + ) : ( + + €{item.price.toFixed(2)} + + )} + + + + + + {item.stock > 10 ? ( + + In Stock ({item.stock} available) + + ) : item.stock > 0 ? ( + Almost sold out ({item.stock} available) + ) : ( + Out of Stock + )} + + + + setQuantity(Math.max(1, parseInt(e.target.value)))} + InputProps={{ inputProps: { min: 1, max: item.stock } }} + sx={{ width: 100 }} + /> + + + + + + + Free shipping on orders over €50 + + + + + + + + ); +} \ No newline at end of file diff --git a/01-frontend/src/helper/RatingCard.tsx b/01-frontend/src/helper/productpage/RatingCard.tsx similarity index 95% rename from 01-frontend/src/helper/RatingCard.tsx rename to 01-frontend/src/helper/productpage/RatingCard.tsx index 53a66ba..307141d 100644 --- a/01-frontend/src/helper/RatingCard.tsx +++ b/01-frontend/src/helper/productpage/RatingCard.tsx @@ -1,5 +1,5 @@ import { Card, CardActionArea, CardContent, Paper, Rating, Typography } from "@mui/material"; -import RatingType from "../components/Rating"; +import RatingType from "../../components/Rating"; export default function RatingCard(ratingType: RatingType) { diff --git a/01-frontend/src/helper/productpage/Ratings.tsx b/01-frontend/src/helper/productpage/Ratings.tsx new file mode 100644 index 0000000..19c413e --- /dev/null +++ b/01-frontend/src/helper/productpage/Ratings.tsx @@ -0,0 +1,99 @@ +import { Box, Button, Divider, IconButton, Rating, Snackbar, SnackbarCloseReason, TextField, Typography } from "@mui/material"; +import RatingCard from "./RatingCard"; +import RatingType from "../../components/Rating"; +import React, { useState } from "react"; +import { Close } from "@mui/icons-material"; + +export default function Ratings() { + + const [open, setOpen] = useState(false); + + const handleClose = ( + event: React.SyntheticEvent | Event, + reason?: SnackbarCloseReason, + ) => { + if (reason === 'clickaway') { + return; + } + + setOpen(false); + }; + + const handleRatingSubmit = () => { + // Handle the rating submission logic here + setOpen(true); + console.log("Rating submitted"); + } + + const action = ( + + + + + + ); + + const ratings: RatingType[] = [ + { + id: "1", + rating: 4.5, + text: "Great product!", + date: "2023-10-01", + }, + { + id: "2", + rating: 3.0, + text: "Average quality.", + date: "2023-10-02", + }, + { + id: "3", + rating: 5.0, + text: "Excellent value for money!", + date: "2023-10-03", + }, + ]; + + return ( + <> +
+ +
+
+ + Rate this product: + + + +
+
+ +
+ + {ratings.map((ratingType: RatingType) => ( + + ))} + + + + ); +} \ No newline at end of file diff --git a/01-frontend/src/pages/Home.tsx b/01-frontend/src/pages/Home.tsx index c1e1776..b718640 100644 --- a/01-frontend/src/pages/Home.tsx +++ b/01-frontend/src/pages/Home.tsx @@ -1,8 +1,8 @@ import { Box, Pagination } from "@mui/material"; import { useEffect, useState } from "react"; import Item from "../components/Item"; -import FilterItem from "../helper/FilterItem"; -import ItemCard from "../helper/ItemCard"; +import FilterItem from "../helper/homepage/FilterItem"; +import ItemCard from "../helper/homepage/ItemCard"; import "./pages.css"; // Import der CSS-Datei export default function Home() { diff --git a/01-frontend/src/pages/Product.tsx b/01-frontend/src/pages/Product.tsx index 10d89d4..535ba9f 100644 --- a/01-frontend/src/pages/Product.tsx +++ b/01-frontend/src/pages/Product.tsx @@ -1,31 +1,19 @@ -import LocalShippingIcon from '@mui/icons-material/LocalShipping'; -import ShoppingCartIcon from '@mui/icons-material/ShoppingCart'; import { - Alert, Box, Button, - Card, Container, Divider, - Grid, - Rating, - Stack, - TextField, - Typography, + Typography } from '@mui/material'; -import { useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import Item from '../components/Item'; -import { useBasket } from '../helper/BasketProvider'; -import Ratings from '../helper/Ratings'; +import ProductInfo from '../helper/productpage/ProductInfo'; +import Ratings from '../helper/productpage/Ratings'; export default function Product() { - const [quantity, setQuantity] = useState(1); - const [imageDimensions, setImageDimensions] = useState({ width: 0, height: 0 }); const location = useLocation(); const item = location.state?.item as Item; - const { addToBasket } = useBasket(); const navigate = useNavigate(); const handleGoHome = () => { @@ -55,125 +43,10 @@ export default function Product() { ); } - - const handleAddToCart = () => { - addToBasket(item.id, quantity); - console.log(`Added {quantity} of €{item.name} to basket`); - }; - - const discountedPrice = item.price * (1 - item.discount / 100); - - const handleImageLoad = (event: React.SyntheticEvent) => { - const { naturalWidth, naturalHeight } = event.currentTarget; - setImageDimensions({ width: naturalWidth, height: naturalHeight }); - }; - return (
- - {/* Left Column - Image */} - - - imageDimensions.height ? "100%" : "auto", - maxHeight: imageDimensions.height >= imageDimensions.width ? 400 : "auto", - width: "auto", - height: "auto", - objectFit: "contain", - }} - /> - - - - {/* Right Column - Product Details */} - - - - {item.name} - - - - - - ({item.rating} / 5) - - - - - {item.discount > 0 ? ( - <> - - €{discountedPrice.toFixed(2)} - - - €{item.price.toFixed(2)} - - - -{item.discount}% - - - ) : ( - - €{item.price.toFixed(2)} - - )} - - - - - - {item.stock > 10 ? ( - - In Stock ({item.stock} available) - - ) : item.stock > 0 ? ( - Almost sold out ({item.stock} available) - ) : ( - Out of Stock - )} - - - - setQuantity(Math.max(1, parseInt(e.target.value)))} - InputProps={{ inputProps: { min: 1, max: item.stock } }} - sx={{ width: 100 }} - /> - - - - - - - Free shipping on orders over €50 - - - - - - +
diff --git a/01-frontend/src/pages/pages.css b/01-frontend/src/pages/pages.css index bc9b0ce..9583664 100644 --- a/01-frontend/src/pages/pages.css +++ b/01-frontend/src/pages/pages.css @@ -128,6 +128,11 @@ display: flex; align-items: center; width: 100%; + overflow: hidden; + height: calc(100vh - 3rem); /* Damit der Hintergrund die gesamte Seite abdeckt */ + min-height: 600px; + padding: 20px 0; /* Abstand oben und unten */ + box-sizing: border-box; } .filter-container {