Add dummy Account Provider without backend connection

This commit is contained in:
FlorianSpeicher
2025-06-11 14:19:52 +02:00
parent ab72054820
commit 312363e783
5 changed files with 117 additions and 22 deletions

View File

@@ -93,5 +93,6 @@
"statistics": "Statistiken",
"thanksForRating": "Vielen Dank für die Bewertung!",
"telephone": "Telefon",
"basketEmpty": "Der Warenkorb ist leer."
"basketEmpty": "Der Warenkorb ist leer.",
"login": "Anmelden"
}

View File

@@ -93,5 +93,6 @@
"statistics": "Statistics",
"thanksForRating": "Thank you for rating!",
"telephone": "Telephone",
"basketEmpty": "The shopping cart is empty."
"basketEmpty": "The shopping cart is empty.",
"login": "Login"
}

View File

@@ -14,6 +14,7 @@ import Product from './pages/Product';
import { CustomThemeProvider } from './theme/ThemeContext';
import FSComponents from './pages/FSComponents.tsx';
import AdminPanel from './pages/AdminPanel';
import { AccountProvider } from './helper/AccountProvider.tsx';
export default function App() {
@@ -23,22 +24,24 @@ export default function App() {
<QueryClientProvider client={queryClient}>
<StyledEngineProvider injectFirst>
<CustomThemeProvider>
<BasketProvider>
<BrowserRouter>
<NavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="*" element={<NoPage />} />
<Route path="/product/:id" element={<Product />} />
<Route path="/checkout" element={<Payment />} />
<Route path="/components" element={<FSComponents />} />
<Route path="/contact" element={<Contact />} />
<Route path='/account' element={<Account />} />
<Route path='/orders' element={<Orders />} />
<Route path='/admin' element={<AdminPanel />} />
</Routes>
</BrowserRouter>
</BasketProvider>
<AccountProvider>
<BasketProvider>
<BrowserRouter>
<NavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="*" element={<NoPage />} />
<Route path="/product/:id" element={<Product />} />
<Route path="/checkout" element={<Payment />} />
<Route path="/components" element={<FSComponents />} />
<Route path="/contact" element={<Contact />} />
<Route path='/account' element={<Account />} />
<Route path='/orders' element={<Orders />} />
<Route path='/admin' element={<AdminPanel />} />
</Routes>
</BrowserRouter>
</BasketProvider>
</AccountProvider>
</CustomThemeProvider>
</StyledEngineProvider>
</QueryClientProvider>

View File

@@ -0,0 +1,41 @@
import { createContext, ReactNode, useContext, useState } from "react";
type User = {
password: string;
email: string;
// weitere Felder nach Bedarf
};
type AccountContextType = {
user: User | null;
login: (userData: User) => void;
logout: () => void;
};
const AccountContext = createContext<AccountContextType | undefined>(undefined);
export const AccountProvider = ({ children }: { children: ReactNode }) => {
const [user, setUser] = useState<User | null>(null);
const login = (userData: User) => {
setUser(userData);
};
const logout = () => {
setUser(null);
};
return (
<AccountContext.Provider value={{ user, login, logout }}>
{children}
</AccountContext.Provider>
);
};
export const useAccount = () => {
const context = useContext(AccountContext);
if (!context) {
throw new Error("useAccount must be used within an AccountProvider");
}
return context;
};

View File

@@ -1,7 +1,7 @@
import AdbIcon from '@mui/icons-material/Adb';
import MenuIcon from '@mui/icons-material/Menu';
import SearchIcon from '@mui/icons-material/Search';
import { Autocomplete, TextField } from '@mui/material';
import { Autocomplete, Dialog, DialogActions, DialogContent, DialogTitle, TextField } from '@mui/material';
import AppBar from '@mui/material/AppBar';
import Avatar from '@mui/material/Avatar';
import Box from '@mui/material/Box';
@@ -20,6 +20,7 @@ import Item from '../../components/Item';
import ThemeToggle from '../../theme/ThemeToggle';
import { fetchItemList } from '../query/Queries';
import './NavBar.css';
import { useAccount } from '../AccountProvider';
export default function NavBar() {
const { t } = useTranslation();
@@ -27,10 +28,16 @@ export default function NavBar() {
const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null);
const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null);
const { login } = useAccount();
const [loginOpen, setLoginOpen] = React.useState(false);
const [loginData, setLoginData] = React.useState({ password: '', email: '' });
const [itemNames, setItemNames] = React.useState<string[]>([]); // Für Autocomplete
const pageKeys = ['components', 'checkout', 'contact', 'admin'];
const settingKeys = ['account', 'orders', 'logout'];
const settingKeys = ['account', 'orders', 'login'];
const pages = pageKeys.map(key => ({ key, label: t(key) }));
const settings = settingKeys.map(key => ({ key, label: t(key) }));
@@ -50,7 +57,17 @@ export default function NavBar() {
const handleCloseUserMenu = (link: string) => {
setAnchorElUser(null);
navigate(`/${link.toLowerCase()}`);
if (link === 'login') {
setLoginOpen(true);
} else {
navigate(`/${link.toLowerCase()}`)
}
};
const handleLoginSubmit = () => {
login(loginData);
setLoginOpen(false);
setLoginData({ password: '', email: '' });
};
// useQuery, um die Item-Namen zu laden
@@ -65,7 +82,7 @@ export default function NavBar() {
}, [items]);
const handleSearch = (event: React.SyntheticEvent, value: string | null) => {
if (!value) {
// Wenn der Suchwert leer ist, navigiere zur Homepage ohne Suchparameter
navigate("/");
@@ -76,6 +93,7 @@ export default function NavBar() {
};
return (
<>
<AppBar position="static" color="primary" elevation={4}>
<Toolbar
disableGutters
@@ -202,5 +220,36 @@ export default function NavBar() {
</Box>
</Toolbar>
</AppBar>
<Dialog open={loginOpen} onClose={() => setLoginOpen(false)}>
<DialogTitle>Login</DialogTitle>
<DialogContent>
<TextField
margin="dense"
label="E-Mail"
type="email"
fullWidth
value={loginData.email}
onChange={e => setLoginData({ ...loginData, email: e.target.value })}
/>
<TextField
autoFocus
margin="dense"
label="Passwort"
type="password"
fullWidth
value={loginData.password}
onChange={e => setLoginData({ ...loginData, password: e.target.value })}
/>
</DialogContent>
<DialogActions>
<Button onClick={() => setLoginOpen(false)} color="secondary">
Abbrechen
</Button>
<Button onClick={handleLoginSubmit} color="primary" variant="contained">
Login
</Button>
</DialogActions>
</Dialog>
</>
);
}