added logout button to sidebar and updated translations
This commit is contained in:
@@ -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);
|
|
||||||
@@ -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)]">
|
||||||
|
|||||||
@@ -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>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user