Added Rating Backend Connection and Rating Submit working.
This commit is contained in:
Binary file not shown.
@@ -1,8 +1,7 @@
|
||||
type RatingType = {
|
||||
id: string;
|
||||
rating: number;
|
||||
text: string;
|
||||
date: string;
|
||||
content: string;
|
||||
timestamp: number;
|
||||
};
|
||||
|
||||
export default RatingType;
|
||||
10
01-frontend/src/helper/adminpanel/ItemsInfo.tsx
Normal file
10
01-frontend/src/helper/adminpanel/ItemsInfo.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Typography } from "@mui/material";
|
||||
|
||||
export default function ItemInfo() {
|
||||
|
||||
return (
|
||||
<Typography >
|
||||
Under construction...
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ export default function ItemCard({ item }: { item: Item }) {
|
||||
<Typography gutterBottom variant="h5" component="div">
|
||||
{item.name}
|
||||
</Typography>
|
||||
<Rating name="half-rating" readOnly defaultValue={item.rating} precision={0.5} />
|
||||
<Rating name="half-rating" readOnly defaultValue={item.rating /2} precision={0.01} />
|
||||
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end" }}>
|
||||
<Typography variant="body2" sx={{ color: 'text.secondary' }} className="item-description">
|
||||
{(item.price100 / 100 * (1 - item.discount100 / 100)).toFixed(2)} €
|
||||
|
||||
@@ -104,9 +104,9 @@ export default function ProductInfo({ item }: { item: Item }) {
|
||||
</Typography>
|
||||
|
||||
<Box display="flex" alignItems="center" gap={1}>
|
||||
<Rating value={item.rating} precision={0.5} readOnly />
|
||||
<Rating value={item.rating /2} precision={0.01} readOnly />
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{item.rating > 0 ? `(${item.rating} / 5)` : t('noRatingsYet')}
|
||||
{item.rating > 0 ? `(${item.rating / 2} / 5)` : t('noRatingsYet')}
|
||||
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function RatingCard(ratingType: RatingType) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleClick = () => {
|
||||
console.log(`Clicked on rating with id: ${ratingType.id}`);
|
||||
console.log(`Clicked on rating`);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -16,11 +16,11 @@ export default function RatingCard(ratingType: RatingType) {
|
||||
<CardActionArea onClick={handleClick}>
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="h5" component="div">
|
||||
{t('ratingFrom')} {ratingType.date}
|
||||
{t('ratingFrom')} {new Date(ratingType.timestamp).toLocaleDateString('de-DE')}
|
||||
</Typography>
|
||||
<Rating name="half-rating" readOnly defaultValue={ratingType.rating} precision={0.5} />
|
||||
<Rating name="half-rating" readOnly defaultValue={ratingType.rating / 2} precision={0.01} />
|
||||
<Typography variant="body2" sx={{ color: 'text.secondary' }} className="item-description">
|
||||
{ratingType.text}
|
||||
{ratingType.content}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</CardActionArea>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Close } from "@mui/icons-material";
|
||||
import { Box, Button, Divider, IconButton, Rating, Snackbar, SnackbarCloseReason, TextField, Typography } from "@mui/material";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import React, { useState } from "react";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import RatingType from "../../components/Rating";
|
||||
import { submitRating } from "../query/Queries";
|
||||
import { fetchRatingList, submitRating } from "../query/Queries";
|
||||
import RatingCard from "./RatingCard";
|
||||
import RatingSubmitType from "../../components/RatingSubmit";
|
||||
|
||||
@@ -58,26 +58,22 @@ export default function Ratings({itemId}: {itemId: string}) {
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
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",
|
||||
},
|
||||
];
|
||||
const { data = [] } = useQuery<RatingType[]>({
|
||||
queryKey: ['fetchRatingList', itemId],
|
||||
queryFn: () => fetchRatingList(itemId),
|
||||
retry: 3, // Versucht es 3-mal erneut
|
||||
retryDelay: 1000, // Wartezeit zwischen den Versuchen (in ms)
|
||||
});
|
||||
|
||||
const ratings:RatingType[] = useMemo(() => data || [], [data]);
|
||||
|
||||
const getRatings = () => {
|
||||
if (ratings.length === 0)
|
||||
return <Typography variant="body1" className="no-ratings">{t('noRatingsYet')}</Typography>;
|
||||
return ratings.map((ratingType: RatingType) => (
|
||||
<RatingCard {...ratingType} />
|
||||
))
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -105,9 +101,7 @@ export default function Ratings({itemId}: {itemId: string}) {
|
||||
<Divider className='contact-divider' />
|
||||
</div>
|
||||
<Box className="rating-card-box">
|
||||
{ratings.map((ratingType: RatingType) => (
|
||||
<RatingCard key={ratingType.id} {...ratingType} />
|
||||
))}
|
||||
{getRatings()}
|
||||
</Box>
|
||||
<Snackbar
|
||||
open={open}
|
||||
|
||||
@@ -14,12 +14,12 @@ export const fetchItemList = async () => {
|
||||
};
|
||||
|
||||
export const submitRating = async (ratingData: RatingSubmitType) => {
|
||||
const response = await fetch('http://localhost:8085/rating', {
|
||||
const response = await fetch('http://localhost:8085/review?uuid=' + ratingData.articleId + '&rating=' + ratingData.rating * 2, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Type': 'text/plain',
|
||||
},
|
||||
body: JSON.stringify(ratingData),
|
||||
body: ratingData.content,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -29,4 +29,15 @@ export const submitRating = async (ratingData: RatingSubmitType) => {
|
||||
const data = await response.json();
|
||||
console.log("Rating Submitted:", data);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
export const fetchRatingList = async (itemId: string) => {
|
||||
const response = await fetch('http://localhost:8085/review/all?uuid=' + itemId);
|
||||
console.log("API Response:", response);
|
||||
if (!response.ok) {
|
||||
throw new Error('Fehler beim Laden der Items');
|
||||
}
|
||||
const data = await response.json();
|
||||
console.log("Fetched Items:", data);
|
||||
return data;
|
||||
};
|
||||
@@ -1,10 +1,11 @@
|
||||
import { AccountCircle, QueryStats, ReceiptLong } from "@mui/icons-material";
|
||||
import { AccountCircle, Category, QueryStats, ReceiptLong } from "@mui/icons-material";
|
||||
import { Box, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Typography } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import AccountsInfo from "../helper/adminpanel/AccountsInfo";
|
||||
import OrdersInfo from "../helper/adminpanel/OrdersInfo";
|
||||
import StatisticsInfo from "../helper/adminpanel/StatisticsInfo";
|
||||
import ItemInfo from "../helper/adminpanel/ItemsInfo";
|
||||
|
||||
export default function AdminPanel() {
|
||||
const { t } = useTranslation();
|
||||
@@ -24,6 +25,8 @@ export default function AdminPanel() {
|
||||
return <OrdersInfo />;
|
||||
case "accounts":
|
||||
return <AccountsInfo />;
|
||||
case "items":
|
||||
return <ItemInfo />;
|
||||
default:
|
||||
return <StatisticsInfo />; // Fallback, falls kein gültiger Status
|
||||
}
|
||||
@@ -68,6 +71,14 @@ export default function AdminPanel() {
|
||||
<ListItemText primary={t("accounts")} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
<ListItem disablePadding>
|
||||
<ListItemButton onClick={() => handleInfoStatus("items")}>
|
||||
<ListItemIcon>
|
||||
<Category />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={t("items")} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
</List>
|
||||
</nav>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user