Fix TIm Coding. Fix Login CustomerId save in AccountProvider

This commit is contained in:
FlorianSpeicher
2025-06-13 00:17:30 +02:00
parent d767ebbf61
commit dd4a7d08a0
8 changed files with 104 additions and 30 deletions

View File

@@ -18,7 +18,7 @@ public class Account {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@ManyToOne(fetch = FetchType.EAGER, optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "customer_id", nullable = false)
private Customer customer;

View File

@@ -1,6 +1,7 @@
package de.htwsaar.webshop.service.impl;
import de.htwsaar.webshop.repository.AccountRepository;
import de.htwsaar.webshop.repository.CustomerRepository;
import de.htwsaar.webshop.repository.entities.Account;
import de.htwsaar.webshop.service.AccountService;
import de.htwsaar.webshop.service.PasswordService;
@@ -13,11 +14,13 @@ import java.util.List;
public class AccountServiceImpl implements AccountService {
private final AccountRepository accountRepository;
private final PasswordService passwordService;
private final CustomerRepository customerRepository;
@Autowired
public AccountServiceImpl(AccountRepository accountRepository, PasswordService passwordService) {
public AccountServiceImpl(AccountRepository accountRepository, PasswordService passwordService, CustomerRepository customerRepository) {
this.accountRepository = accountRepository;
this.passwordService = passwordService;
this.customerRepository = customerRepository;
}
@Override
@@ -32,6 +35,10 @@ public class AccountServiceImpl implements AccountService {
@Override
public Account saveNew(Account account) {
if (account.getCustomer() != null) {
account.getCustomer().setId(null); // Ensure new customer
customerRepository.save(account.getCustomer());
}
account.setPassword(passwordService.hashPassword(account.getPassword()));
return this.save(account);
}

View File

@@ -97,5 +97,7 @@
"login": "Anmelden",
"total": "Insgesamt",
"admin": "Admin",
"fsmodel": "Indoor-Farming-Station"
"fsmodel": "Indoor-Farming-Station",
"zip": "Postleitzahl",
"surname": "Nachname"
}

View File

@@ -97,5 +97,7 @@
"login": "Login",
"total": "Total",
"admin": "Admin",
"fsmodel": "Indoor farming station"
"fsmodel": "Indoor farming station",
"zip": "Zip code",
"surname": "Surname"
}

View File

@@ -3,8 +3,8 @@ import { useQuery } from "@tanstack/react-query";
import i18next from "i18next";
import React, { useState } from "react";
import AccountType from "../../components/Account";
import { submitLogin, submitRegister } from "../query/Queries"; // Importiere die Funktion für die Registrierung
import { useAccount } from "../AccountProvider";
import { fetchAccount, submitLogin, submitRegister } from "../query/Queries"; // Importiere die Funktion für die Registrierung
type LoginDialogProps = {
open: boolean;
@@ -30,6 +30,14 @@ const LoginDialog: React.FC<LoginDialogProps> = ({ open, onClose, loginData, set
enabled: false,
});
const { refetch: refetchAccount } = useQuery({
queryKey: ["fetchAccount", loginData],
queryFn: () => fetchAccount(loginData),
retry: 0,
retryDelay: 1000,
enabled: false,
});
// useQuery für Registrierung
const { refetch: refetchRegister, isLoading: isLoadingRegister, error: errorRegister } = useQuery({
queryKey: ["submitRegister", registerData],
@@ -45,7 +53,8 @@ const LoginDialog: React.FC<LoginDialogProps> = ({ open, onClose, loginData, set
const response = await refetchLogin(); // Anfrage auslösen
if (response.status === "success") {
const userData = response.data; // Extrahiere die Benutzerdaten aus der Antwort
login({ email: userData.email, customerId: userData.token, password: userData.password }); // Speichere die Benutzerdaten im AccountProvider
const customerData = (await refetchAccount()).data; // Hole die Account-Daten
login({ email: userData.email, customerId: customerData.customer.id, password: userData.password }); // Speichere die Benutzerdaten im AccountProvider
setShowRegister(false); // Zurück zum Login wechseln
onSubmit(); // Dialog schließen
} else {

View File

@@ -11,7 +11,6 @@ export const fetchItemList = async () => {
throw new Error('Fehler beim Laden der Items');
}
const data = await response.json();
console.log("Fetched Items:", data);
return data;
};
@@ -29,7 +28,6 @@ export const submitRating = async (ratingData: RatingSubmitType) => {
}
const data = await response.json();
console.log("Rating Submitted:", data);
return data;
}
@@ -40,7 +38,6 @@ export const fetchRatingList = async (itemId: string) => {
throw new Error('Fehler beim Laden der Items');
}
const data = await response.json();
console.log("Fetched Items:", data);
return data;
};
@@ -106,6 +103,14 @@ export const submitLogin = async (loginData: SubmitLogin) => {
return response.json();
};
export const fetchAccount = async (loginData: SubmitLogin) => {
const response = await fetch("http://localhost:8085/account?email=" + loginData.email + "&password=" + loginData.password);
if (!response.ok) {
throw new Error("Login failed");
}
return response.json();
};
export const submitRegister = async (registerData: AccountType) => {
const response = await fetch("http://localhost:8085/account", {
method: "POST",
@@ -119,3 +124,13 @@ export const submitRegister = async (registerData: AccountType) => {
}
return response.json();
};
export const fetchCustomer = async (userId: number) => {
const response = await fetch('http://localhost:8085/customer?id=' + userId);
console.log("API Response:", response);
if (!response.ok) {
throw new Error('Fehler beim Laden des Customers');
}
const data = await response.json();
return data;
};

View File

@@ -1,25 +1,57 @@
import { Box, Typography, Button, TextField, Paper, Divider, Stack } from "@mui/material";
import { Box, Button, Divider, Paper, Stack, TextField, Typography } from "@mui/material";
import { useQuery } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { CustomerType } from "../components/Account";
import { useAccount } from "../helper/AccountProvider";
import { fetchCustomer } from "../helper/query/Queries";
import "./pages.css";
import { useState } from "react";
import {useTranslation} from "react-i18next";
export default function Account() {
const { t } = useTranslation();
const navigate = useNavigate();
const { user: userData, logout } = useAccount();
// Beispielhafte Userdaten (könnten aus Context/Backend kommen)
const [user, setUser] = useState({
name: "Max Mustermann",
email: "max.mustermann@email.de",
phone: "+49 123 456789",
address: "Musterstraße 1, 12345 Musterstadt"
const [user, setUser] = useState<CustomerType>({
name: "",
surname: "",
address: "",
country: "",
zip: "",
id: userData?.customerId || 0, // Initialwert
});
// Aktualisiere den `user`-State, wenn sich `userData` ändert
useEffect(() => {
console.log("UserData changed:", userData);
if (userData?.customerId) {
setUser((prev) => ({
...prev,
id: userData.customerId, // Aktualisiere die ID
}));
}
}, [userData]);
const [edit, setEdit] = useState(false);
const [form, setForm] = useState(user);
const { data } = useQuery<CustomerType>({
queryKey: ['fetchCustomer', userData?.customerId],
queryFn: () => fetchCustomer(userData?.customerId || 0), // Funktion zum Abrufen der Kundendaten
retry: 3, // Versucht es 3-mal erneut
retryDelay: 1000, // Wartezeit zwischen den Versuchen (in ms)
});
useEffect(() => {
if (data) {
setUser(data); // Aktualisiere den user-State mit den abgerufenen Daten
setForm(data); // Optional: Aktualisiere auch den form-State
}
}, [data]);
const handleEdit = () => setEdit(true);
const handleCancel = () => {
setForm(user);
@@ -33,9 +65,8 @@ export default function Account() {
setEdit(false);
};
const handleDelete = () => {
// Hier ggf. Dialog oder API-Call zum Löschen
alert(t('accountDeleted'));
navigate("/");
logout(); // Logout nach dem Löschen
};
return (
@@ -55,17 +86,9 @@ export default function Account() {
fullWidth
/>
<TextField
label={t('email')}
name="email"
value={edit ? form.email : user.email}
onChange={handleChange}
disabled={!edit}
fullWidth
/>
<TextField
label={t('phone')}
name="phone"
value={edit ? form.phone : user.phone}
label={t('surname')}
name="surname"
value={edit ? form.surname : user.surname}
onChange={handleChange}
disabled={!edit}
fullWidth
@@ -78,6 +101,22 @@ export default function Account() {
disabled={!edit}
fullWidth
/>
<TextField
label={t('country')}
name="country"
value={edit ? form.country : user.country}
onChange={handleChange}
disabled={!edit}
fullWidth
/>
<TextField
label={t('zip')}
name="zip"
value={edit ? form.zip : user.zip}
onChange={handleChange}
disabled={!edit}
fullWidth
/>
</Stack>
<Box sx={{ display: "flex", gap: 2, mt: 4 }}>
{edit ? (