added logout button to sidebar and updated translations

This commit is contained in:
2026-05-29 23:15:40 +02:00
parent 9cab32ddea
commit e006aa44ae
4 changed files with 47 additions and 132 deletions
-83
View File
@@ -1,83 +0,0 @@
-- ============================================================
-- StockHome Mock Data
-- Run against the stockhome schema before executing this.
-- Passwords are stored in plain text (development only).
-- ============================================================
USE stockhome;
SET FOREIGN_KEY_CHECKS = 0;
DELETE FROM products;
DELETE FROM storage_locations;
DELETE FROM users;
SET FOREIGN_KEY_CHECKS = 1;
-- ============================================================
-- USERS
-- ============================================================
INSERT INTO users (username, first_name, last_name, email, password, is_admin, is_active, last_login) VALUES
('thomas.mueller', 'Thomas', 'Müller', 'thomas.mueller@example.com', 'Password123!', TRUE, TRUE, '2025-05-25 08:30:00'),
('sarah.mueller', 'Sarah', 'Müller', 'sarah.mueller@example.com', 'Password123!', FALSE, TRUE, '2025-05-24 19:15:00'),
('max.schmidt', 'Max', 'Schmidt', 'max.schmidt@example.com', 'Password123!', FALSE, FALSE, '2025-03-10 11:00:00');
-- ============================================================
-- STORAGE LOCATIONS
-- ============================================================
INSERT INTO storage_locations (name, description) VALUES
('Kühlschrank', 'Kühlschrank in der Küche'),
('Gefrierfach 1', 'Oberes Gefrierfach Fleisch und Fisch'),
('Gefrierfach 2', 'Unteres Gefrierfach Gemüse und Fertiggerichte'),
('Vorratskammer', 'Regal im Flur, Trockenware und Konserven'),
('Keller Regal A', 'Keller links Getränke und Eingemachtes'),
('Keller Regal B', 'Keller rechts Hygieneartikel und Reinigungsmittel'),
('Garage Regal', 'Garage Werkzeug, Öle, Autopflege');
-- ============================================================
-- PRODUCTS
-- Storage locations are looked up by name since UUIDs are
-- auto-generated above and not known at insert time.
-- ============================================================
-- Gefrierfach 1
INSERT INTO products (name, description, price, amount, storage_location, expiry_date, bottling_date) VALUES
('Hähnchenbrust', 'Tiefgekühlte Hähnchenbrustfilets, vakuumverpackt', '6.49', 5, (SELECT uuid FROM storage_locations WHERE name = 'Gefrierfach 1'), '2026-01-10', '2025-01-10'),
('Lachs Filet', 'Tiefgefrorenes Lachsfilet, Atlantic, 500g', '12.99', 1, (SELECT uuid FROM storage_locations WHERE name = 'Gefrierfach 1'), '2025-12-31', '2025-02-20'),
('Hackfleisch', 'Rind und Schwein gemischt, 500g Portion', '3.99', 3, (SELECT uuid FROM storage_locations WHERE name = 'Gefrierfach 1'), '2026-02-15', '2025-01-28');
-- Gefrierfach 2
INSERT INTO products (name, description, price, amount, storage_location, expiry_date, bottling_date) VALUES
('Erbsen TK', 'Tiefkühlerbsen, 750g Packung', '1.99', 3, (SELECT uuid FROM storage_locations WHERE name = 'Gefrierfach 2'), '2026-06-01', '2025-03-05'),
('Spinat TK', 'Blattspinat tiefgefroren, 450g', '1.49', 2, (SELECT uuid FROM storage_locations WHERE name = 'Gefrierfach 2'), '2026-04-01', '2025-02-10'),
('Pizza Margherita', 'Tiefkühlpizza, 350g', '2.29', 4, (SELECT uuid FROM storage_locations WHERE name = 'Gefrierfach 2'), '2025-11-30', NULL);
-- Kühlschrank
INSERT INTO products (name, description, price, amount, storage_location, expiry_date, bottling_date) VALUES
('Vollmilch', '3,5% Fett, 1 Liter', '1.09', 2, (SELECT uuid FROM storage_locations WHERE name = 'Kühlschrank'), '2025-05-29', NULL),
('Butter', 'Deutsche Markenbutter, 250g', '1.89', 3, (SELECT uuid FROM storage_locations WHERE name = 'Kühlschrank'), '2025-07-01', NULL),
('Gouda am Stück', 'Junger Gouda, ca. 400g', '3.29', 1, (SELECT uuid FROM storage_locations WHERE name = 'Kühlschrank'), '2025-06-15', NULL);
-- Vorratskammer
INSERT INTO products (name, description, price, amount, storage_location, expiry_date, bottling_date) VALUES
('Spaghetti', 'Barilla Nr. 5, 500g', '1.29', 5, (SELECT uuid FROM storage_locations WHERE name = 'Vorratskammer'), '2027-02-01', NULL),
('Basmatireis', 'Uncle Ben''s, 1kg', '2.49', 2, (SELECT uuid FROM storage_locations WHERE name = 'Vorratskammer'), '2027-01-05', NULL),
('Tomaten gehackt', 'Mutti, 400g Dose', '0.89', 8, (SELECT uuid FROM storage_locations WHERE name = 'Vorratskammer'), '2027-01-01', '2024-11-01'),
('Kichererbsen', 'ja!, 400g Dose in Lake', '0.79', 4, (SELECT uuid FROM storage_locations WHERE name = 'Vorratskammer'), '2027-06-01', '2024-12-01'),
('Haferflocken', 'Kölln, zarte Haferflocken, 500g', '1.49', 2, (SELECT uuid FROM storage_locations WHERE name = 'Vorratskammer'), '2026-09-10', NULL),
('Thunfisch in Öl', 'Rio Mare, 3er Pack in Olivenöl', '3.49', 2, (SELECT uuid FROM storage_locations WHERE name = 'Vorratskammer'), '2026-08-01', '2025-01-20');
-- Keller Regal A
INSERT INTO products (name, description, price, amount, storage_location, expiry_date, bottling_date) VALUES
('Mineralwasser', 'Volvic still, 1,5L Flasche', '0.79', 12, (SELECT uuid FROM storage_locations WHERE name = 'Keller Regal A'), '2027-02-15', NULL),
('Apfelsaft', 'Valensina naturtrüb, 1L', '1.99', 3, (SELECT uuid FROM storage_locations WHERE name = 'Keller Regal A'), '2026-03-01', '2025-03-01'),
('Erdbeerkonfitüre', 'Selbst eingemacht, 250ml Glas', NULL, 6, (SELECT uuid FROM storage_locations WHERE name = 'Keller Regal A'), '2026-07-01', '2025-07-15');
-- Keller Regal B
INSERT INTO products (name, description, price, amount, storage_location, expiry_date, bottling_date) VALUES
('Toilettenpapier', 'Zewa, 3-lagig, 16 Rollen', '4.99', 3, (SELECT uuid FROM storage_locations WHERE name = 'Keller Regal B'), NULL, NULL),
('Handseife', 'Dove, pflegend, 250ml', '2.29', 0, (SELECT uuid FROM storage_locations WHERE name = 'Keller Regal B'), '2026-02-10', '2025-02-10'),
('Waschmittel', 'Persil Color, 20 Waschladungen', '8.99', 1, (SELECT uuid FROM storage_locations WHERE name = 'Keller Regal B'), NULL, NULL);
-- Garage Regal
INSERT INTO products (name, description, price, amount, storage_location, expiry_date, bottling_date) VALUES
('Motoröl 5W-30', 'Castrol EDGE, 1L Flasche', '14.99', 2, (SELECT uuid FROM storage_locations WHERE name = 'Garage Regal'), NULL, NULL),
('Fahrradkette', 'Shimano HG-54, 11-fach', '18.50', 1, (SELECT uuid FROM storage_locations WHERE name = 'Garage Regal'), NULL, NULL);
+12
View File
@@ -4,6 +4,7 @@ import InventoryIcon from "@mui/icons-material/Inventory";
import AddBoxIcon from "@mui/icons-material/AddBox"; import AddBoxIcon from "@mui/icons-material/AddBox";
import StorageIcon from "@mui/icons-material/Storage"; import StorageIcon from "@mui/icons-material/Storage";
import SettingsIcon from "@mui/icons-material/Settings"; import SettingsIcon from "@mui/icons-material/Settings";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import { useNavigate, useMatchRoute } from "@tanstack/react-router"; import { useNavigate, useMatchRoute } from "@tanstack/react-router";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
@@ -68,6 +69,17 @@ export const Sidebar = () => {
> >
{t("settings")} {t("settings")}
</Button> </Button>
<Button
onClick={() => {
Cookies.remove("token");
navigate({ to: "/login" });
}}
variant={variant("/login")}
startDecorator={<ExitToAppIcon />}
className={btnClass}
>
{t("logout")}
</Button>
</div> </div>
<div className="rounded-2xl border border-white/70 bg-white/80 px-4 py-3 text-xs font-semibold uppercase tracking-[0.2em] text-[#0b6bcb] shadow-[0_12px_30px_rgba(12,38,78,0.12)]"> <div className="rounded-2xl border border-white/70 bg-white/80 px-4 py-3 text-xs font-semibold uppercase tracking-[0.2em] text-[#0b6bcb] shadow-[0_12px_30px_rgba(12,38,78,0.12)]">
+33 -48
View File
@@ -6,7 +6,7 @@ import type { Storage } from "../misc/interfaces";
import { StorageRow } from "../components/StorageRow"; import { StorageRow } from "../components/StorageRow";
import { useState } from "react"; import { useState } from "react";
import { AddStorageModal } from "../components/modals/AddStorageModal"; import { AddStorageModal } from "../components/modals/AddStorageModal";
import AddBoxIcon from "@mui/icons-material/AddBox"; import AddIcon from "@mui/icons-material/Add";
export const Storages = () => { export const Storages = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -19,67 +19,52 @@ export const Storages = () => {
return ( return (
<> <>
<div className="space-y-6"> <div className="flex flex-col gap-4">
<div className="flex flex-wrap items-center gap-3"> <div className="min-w-65 space-y-2">
<div className="space-y-1"> <Typography level="h2" className="text-slate-900">
<Typography level="h2" className="text-slate-900"> {t("storages")}
{t("storages")} </Typography>
</Typography> <Typography level="body-lg" className="text-slate-500">
<Typography level="body-lg" className="text-slate-500"> {t("storage-delete-info")}
{t("storage-delete-info")} </Typography>
</Typography> </div>
</div> <div className="flex items-center gap-3">
<Button <Button
startDecorator={<AddIcon />}
onClick={() => setModal(true)} onClick={() => setModal(true)}
size="lg" variant="solid"
startDecorator={<AddBoxIcon />} className="rounded-full px-5 py-2 text-base font-semibold shadow-sm"
className="ml-auto rounded-2xl bg-[#0b6bcb] px-5 text-white shadow-[0_16px_36px_rgba(11,107,203,0.35)] transition hover:-translate-y-0.5 hover:bg-[#095aa7]"
> >
{t("add")} {t("add")}
</Button> </Button>
</div> </div>
</div> </div>
<Sheet className="mt-6 rounded-3xl border border-white/70 bg-white/80 p-6 shadow-[0_24px_60px_rgba(12,38,78,0.12)] backdrop-blur"> <Sheet className="mt-6 rounded-3xl border border-slate-200/70 bg-white/90 p-6 shadow-[0_24px_60px_rgba(12,38,78,0.12)] backdrop-blur">
<AddStorageModal isOpen={modal} setOpen={setModal} /> <AddStorageModal isOpen={modal} setOpen={setModal} />
{isLoading ? ( {isLoading ? (
<div className="flex items-center justify-center py-16"> <div className="flex items-center justify-center py-16">
<CircularProgress size="lg" /> <CircularProgress size="lg" />
</div> </div>
) : ( ) : (
<Table <div className="overflow-hidden rounded-2xl border border-slate-200/80 bg-white">
hoverRow <Table hoverRow className="min-w-240 text-slate-700">
className="min-w-240 text-slate-700" <thead className="bg-slate-50/80 text-slate-500">
sx={{ <tr className="text-sm uppercase tracking-wide">
"--TableCell-headBackground": "transparent", <th className="px-5 py-3 text-left">{t("storage-name")}</th>
"& thead th": { <th className="px-5 py-3 text-left">{t("description")}</th>
fontWeight: "lg", <th className="px-5 py-3 text-left">{t("created-at")}</th>
color: "#475569", <th className="px-5 py-3 text-left">{t("updated-at")}</th>
padding: "16px 20px", <th className="px-5 py-3 text-right"></th>
}, </tr>
"& tbody td": { </thead>
padding: "18px 20px", <tbody className="divide-y divide-slate-200">
}, {storages?.map((storage: Storage) => (
"& tbody tr": { <StorageRow key={storage.uuid} storage={storage} />
borderTop: "1px solid #e2e8f0", ))}
}, </tbody>
}} </Table>
> </div>
<thead>
<tr>
<th>{t("storage-name")}</th>
<th>{t("description")}</th>
<th>{t("created-at")}</th>
<th>{t("updated-at")}</th>
<th className="text-right"></th>
</tr>
</thead>
<tbody>
{storages?.map((storage: Storage) => (
<StorageRow key={storage.uuid} storage={storage} />
))}
</tbody>
</Table>
)} )}
</Sheet> </Sheet>
</> </>
+2 -1
View File
@@ -39,5 +39,6 @@
"quick-tips-2": "Choose a currency code that matches your pricing display, e.g. EUR, CHF, or USD.", "quick-tips-2": "Choose a currency code that matches your pricing display, e.g. EUR, CHF, or USD.",
"settings-sub": "Manage your app preferences and store defaults.", "settings-sub": "Manage your app preferences and store defaults.",
"preferences": "Preferences", "preferences": "Preferences",
"selected": "selected" "selected": "selected",
"logout": "Logout"
} }