feat: add door_key field to items and update related logic in forms and database

This commit is contained in:
2025-11-24 17:12:37 +01:00
parent df6b5eac59
commit fd2ccaa747
8 changed files with 45 additions and 19 deletions

View File

@@ -29,8 +29,8 @@ const AddItemForm: React.FC<AddItemFormProps> = ({ onClose, alert }) => {
<Input id="item_name" placeholder="z.B. Laptop" /> <Input id="item_name" placeholder="z.B. Laptop" />
</Field.Root> </Field.Root>
<Field.Root> <Field.Root>
<Field.Label>Schließfachnummer (immer zwei Zahlen)</Field.Label> <Field.Label>Schließfachnummer</Field.Label>
<Input id="safe_nr" placeholder="Nummer 01 - 06" /> <Input id="safe_nr" placeholder="Nummer 1 - 6" />
</Field.Root> </Field.Root>
<Field.Root> <Field.Root>
<Field.Label>Ausleih-Berechtigung (Rolle)</Field.Label> <Field.Label>Ausleih-Berechtigung (Rolle)</Field.Label>
@@ -64,7 +64,6 @@ const AddItemForm: React.FC<AddItemFormProps> = ({ onClose, alert }) => {
const safeNr = safeNrValue === "" ? null : safeNrValue; const safeNr = safeNrValue === "" ? null : safeNrValue;
if (!name || Number.isNaN(role)) return; if (!name || Number.isNaN(role)) return;
if (safeNr !== null && !/^\d{2}$/.test(safeNr)) return;
const res = await createItem(name, role, safeNr); const res = await createItem(name, role, safeNr);
if (res.success) { if (res.success) {

View File

@@ -38,6 +38,7 @@ type Items = {
can_borrow_role: string; can_borrow_role: string;
in_safe: boolean; in_safe: boolean;
safe_nr: string; safe_nr: string;
door_key: string;
entry_created_at: string; entry_created_at: string;
entry_updated_at: string; entry_updated_at: string;
last_borrowed_person: string | null; last_borrowed_person: string | null;
@@ -72,6 +73,12 @@ const ItemTable: React.FC = () => {
); );
}; };
const handleDoorKeyChange = (id: number, value: string) => {
setItems((prev) =>
prev.map((it) => (it.id === id ? { ...it, door_key: value } : it))
);
};
const setError = ( const setError = (
status: "error" | "success", status: "error" | "success",
message: string, message: string,
@@ -204,6 +211,9 @@ const ItemTable: React.FC = () => {
<Table.ColumnHeader> <Table.ColumnHeader>
<strong>Schließfachnummer</strong> <strong>Schließfachnummer</strong>
</Table.ColumnHeader> </Table.ColumnHeader>
<Table.ColumnHeader>
<strong>Schlüssel</strong>
</Table.ColumnHeader>
<Table.ColumnHeader> <Table.ColumnHeader>
<strong>Eintrag erstellt am</strong> <strong>Eintrag erstellt am</strong>
</Table.ColumnHeader> </Table.ColumnHeader>
@@ -290,6 +300,16 @@ const ItemTable: React.FC = () => {
value={item.safe_nr} value={item.safe_nr}
/> />
</Table.Cell> </Table.Cell>
<Table.Cell>
<Input
size="sm"
w="max-content"
onChange={(e) =>
handleDoorKeyChange(item.id, e.target.value)
}
value={item.door_key}
/>
</Table.Cell>
<Table.Cell>{formatDateTime(item.entry_created_at)}</Table.Cell> <Table.Cell>{formatDateTime(item.entry_created_at)}</Table.Cell>
<Table.Cell>{formatDateTime(item.entry_updated_at)}</Table.Cell> <Table.Cell>{formatDateTime(item.entry_updated_at)}</Table.Cell>
<Table.Cell>{item.last_borrowed_person}</Table.Cell> <Table.Cell>{item.last_borrowed_person}</Table.Cell>
@@ -301,6 +321,7 @@ const ItemTable: React.FC = () => {
item.id, item.id,
item.item_name, item.item_name,
item.safe_nr, item.safe_nr,
item.door_key,
item.can_borrow_role item.can_borrow_role
).then((response) => { ).then((response) => {
if (response.success) { if (response.success) {

View File

@@ -184,7 +184,7 @@ export const createItem = async (
return { return {
success: false, success: false,
message: message:
"Fehler beim Erstellen des Gegenstands. Der Name des Gegenstandes darf nicht mehrmals vergeben werden.", "Fehler beim Erstellen des Gegenstands. Der Name des Gegenstandes und die Schließfachnummer dürfen nicht mehrmals vergeben werden.",
}; };
} }
return { success: true }; return { success: true };
@@ -198,6 +198,7 @@ export const handleEditItems = async (
itemId: number, itemId: number,
item_name: string, item_name: string,
safe_nr: string | null, safe_nr: string | null,
door_key: string | null,
can_borrow_role: string can_borrow_role: string
) => { ) => {
try { try {
@@ -209,7 +210,7 @@ export const handleEditItems = async (
"Content-Type": "application/json", "Content-Type": "application/json",
Authorization: `Bearer ${Cookies.get("token")}`, Authorization: `Bearer ${Cookies.get("token")}`,
}, },
body: JSON.stringify({ item_name, safe_nr, can_borrow_role }), body: JSON.stringify({ item_name, safe_nr, door_key, can_borrow_role }),
} }
); );
if (!response.ok) { if (!response.ok) {

View File

@@ -36,7 +36,8 @@ export const editItemById = async (
itemId, itemId,
item_name, item_name,
can_borrow_role, can_borrow_role,
safe_nr safe_nr,
door_key
) => { ) => {
let newSafeNr; let newSafeNr;
if (safe_nr === null || safe_nr === "") { if (safe_nr === null || safe_nr === "") {
@@ -45,8 +46,8 @@ export const editItemById = async (
newSafeNr = safe_nr; newSafeNr = safe_nr;
} }
const [result] = await pool.query( const [result] = await pool.query(
"UPDATE items SET item_name = ?, can_borrow_role = ?, safe_nr = ?, entry_updated_at = NOW() WHERE id = ?", "UPDATE items SET item_name = ?, can_borrow_role = ?, safe_nr = ?, door_key = ?, entry_updated_at = NOW() WHERE id = ?",
[item_name, can_borrow_role, newSafeNr, itemId] [item_name, can_borrow_role, newSafeNr, door_key, itemId]
); );
if (result.affectedRows > 0) return { success: true }; if (result.affectedRows > 0) return { success: true };
return { success: false }; return { success: false };

View File

@@ -41,13 +41,14 @@ router.post("/create-item", authenticateAdmin, async (req, res) => {
router.post("/edit-item/:id", authenticateAdmin, async (req, res) => { router.post("/edit-item/:id", authenticateAdmin, async (req, res) => {
const itemId = req.params.id; const itemId = req.params.id;
const { item_name, can_borrow_role, safe_nr } = req.body; const { item_name, can_borrow_role, safe_nr, door_key } = req.body;
const result = await editItemById( const result = await editItemById(
itemId, itemId,
item_name, item_name,
can_borrow_role, can_borrow_role,
safe_nr safe_nr,
door_key
); );
if (result.success) { if (result.success) {
return res.status(200).json({ message: "Item edited successfully" }); return res.status(200).json({ message: "Item edited successfully" });

View File

@@ -117,11 +117,19 @@ export const getAllLoansV2 = async () => {
export const openDoor = async (doorKey) => { export const openDoor = async (doorKey) => {
const [result] = await pool.query( const [result] = await pool.query(
"SELECT lockers FROM doorKeys WHERE door_key = ?;", "SELECT safe_nr, id FROM items WHERE door_key = ?;",
[doorKey] [doorKey]
); );
if (result.length > 0) { if (result.length > 0) {
const [changeItemSate] = await pool.query(
"UPDATE items SET in_safe = NOT in_safe WHERE id = ?",
[result[0].id]
);
if (changeItemSate.affectedRows > 0) {
return { success: true, data: result[0] }; return { success: true, data: result[0] };
} else {
return { success: false };
}
} }
return { success: false }; return { success: false };
}; };

View File

@@ -80,6 +80,7 @@ router.post(
} }
); );
// Route for API to open a door
router.get("/open-door/:key/:doorKey", authenticate, async (req, res) => { router.get("/open-door/:key/:doorKey", authenticate, async (req, res) => {
const doorKey = req.params.doorKey; const doorKey = req.params.doorKey;

View File

@@ -38,6 +38,7 @@ CREATE TABLE items (
can_borrow_role INT NOT NULL, can_borrow_role INT NOT NULL,
in_safe bool NOT NULL DEFAULT true, in_safe bool NOT NULL DEFAULT true,
safe_nr INT DEFAULT NULL UNIQUE, safe_nr INT DEFAULT NULL UNIQUE,
door_key INT DEFAULT NULL UNIQUE,
entry_created_at timestamp NULL DEFAULT CURRENT_TIMESTAMP, entry_created_at timestamp NULL DEFAULT CURRENT_TIMESTAMP,
entry_updated_at timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, entry_updated_at timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
last_borrowed_person varchar(255) DEFAULT NULL, last_borrowed_person varchar(255) DEFAULT NULL,
@@ -54,10 +55,3 @@ CREATE TABLE apiKeys (
PRIMARY KEY (id), PRIMARY KEY (id),
CHECK (api_key REGEXP '^[0-9]{8}$') CHECK (api_key REGEXP '^[0-9]{8}$')
) ENGINE=InnoDB; ) ENGINE=InnoDB;
CREATE TABLE doorKeys (
id int NOT NULL AUTO_INCREMENT,
door_key INT NOT NULL,
lockers INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;