From 95aae1c05093e73d123bba49ee9cab3e899d9044 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Fri, 1 May 2026 13:41:30 +0200 Subject: [PATCH 1/8] cleaned changelog --- changelog.md | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/changelog.md b/changelog.md index 24e18f0..0882940 100644 --- a/changelog.md +++ b/changelog.md @@ -1,37 +1,28 @@ -# Changelog for upcoming version: v2.2 +# Changelog for upcoming version: vX.X -This update provides some new features for the design. It also contains some improvements and I have also fixed some bugs. +Introduction ## New features -- **Deactivatable services:** I have added the ability to deactivate services, which can be useful for maintenance or other purposes. The admin can activate and deactivate services in the admin panel. If a service is deactivated, it will not be available for users and they will get an error message if they try to use it. They will also get an warning banner on the homepage. -- **New Animations:** I have added some new animations to the frontend, which make the user experience more enjoyable. -- **New Icon:** I have added a new icon for the frontend, which is now also used in the header and the favicon. It is a dark version of the old icon, which fits better to the overall design. I have made it with Icon Composer. The old icon is still used for the admin panel, which has a light design. (Maybe I will change the admin panel design in the future...) -- **New Button:** When you go to your user card (over the user icon in the header) you have a new button "Click me". If you click it, you will get an message... _I am just saying: I have implemented the no-as-a-service code in to my Backend._ +- ## Improvements -- The overview page now shows the note column and is overall better organised. -- Improved error logging -- If you try to delete a loan that has not been returned yet, you will get an 507 error code. -- When the admin deletes a loan, the loan will be still visible in the database, but it will be marked as deleted. This is to prevent data loss and to keep track of deleted loans. -- Mailer improvements: The mailer is now more clearly organised. Two large code files are now split into five smaller code files which are easier to maintain. Also the design of the mails has improved. +- ## Fixed bugs -- Fixed bug: #13 -- Fixed bug for messaging when server has an error -- Fixed footer height +- --- ## New version numbers -**Backend:** v2.2 +**Backend:** vX.X -**Frontend:** v2.2 +**Frontend:** vX.X -**Admin panel:** v1.4 +**Admin panel:** vX.X --- From 8e35e81e8f0f504813bc1231e385a076f596032e Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Sat, 9 May 2026 11:35:13 +0200 Subject: [PATCH 2/8] Fixed bug: #16 --- FrontendV2/src/pages/MyLoansPage.tsx | 30 ++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/FrontendV2/src/pages/MyLoansPage.tsx b/FrontendV2/src/pages/MyLoansPage.tsx index 5cca95d..8377727 100644 --- a/FrontendV2/src/pages/MyLoansPage.tsx +++ b/FrontendV2/src/pages/MyLoansPage.tsx @@ -121,10 +121,28 @@ export const MyLoansPage = () => { const formatDate = (iso: string | null) => { if (!iso) return "-"; - const m = iso.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})/); - if (!m) return iso; - const [, y, M, d, h, min] = m; - return `${d}.${M}.${y} ${h}:${min}`; + const date = new Date(iso); + if (isNaN(date.getTime())) return iso; + return date.toLocaleString("de-DE", { + timeZone: "Europe/Berlin", + day: "2-digit", + month: "2-digit", + year: "numeric", + hour: "2-digit", + minute: "2-digit", + }); + }; + + const dateAndTime = (isISO: boolean) => { + const date = new Date(); + + if (isISO) { + return date.toISOString(); + } + + if (!isISO) { + return date; + } }; const handleTakeAction = async (loanCode: string) => { @@ -151,7 +169,7 @@ export const MyLoansPage = () => { setLoans((prev) => prev.map((loan) => loan.loan_code === loanCode - ? { ...loan, take_date: new Date().toISOString() } + ? { ...loan, take_date: dateAndTime(true) } : loan, ), ); @@ -191,7 +209,7 @@ export const MyLoansPage = () => { setLoans((prev) => prev.map((loan) => loan.loan_code === loanCode - ? { ...loan, returned_date: new Date().toISOString() } + ? { ...loan, returned_date: dateAndTime(true) } : loan, ), ); From c48da71cd54cf486eee1095d111358671af11f4d Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Sat, 9 May 2026 11:37:44 +0200 Subject: [PATCH 3/8] improved translation --- FrontendV2/src/utils/i18n/locales/de/de.json | 2 +- FrontendV2/src/utils/i18n/locales/en/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FrontendV2/src/utils/i18n/locales/de/de.json b/FrontendV2/src/utils/i18n/locales/de/de.json index e385379..e2cb489 100644 --- a/FrontendV2/src/utils/i18n/locales/de/de.json +++ b/FrontendV2/src/utils/i18n/locales/de/de.json @@ -60,7 +60,7 @@ "sure-delete-loan-2": "Für den Admin bleibt sie weiterhin sichtbar.", "delete": "Löschen", "change-language": "Sprache ändern", - "timezone-info": "Die angezeigten Daten und Uhrzeiten werden in deutscher Zeitzone dargestellt und müssen auch so eingegeben werden.", + "timezone-info": "Die angezeigten Daten und Uhrzeiten werden in deutscher Zeitzone dargestellt und müssen auch so eingegeben werden. Das gesamte System ist auf die deutsche Zeitzone eingestellt.", "optional-note": "Optionale Notiz", "note": "Notiz", "user-info-desc": "Hier können Sie Ihre persönlichen Informationen einsehen und das Passwort ändern. Falls Sie weitere Änderungen benötigen, wenden Sie sich bitte an einen Administrator.", diff --git a/FrontendV2/src/utils/i18n/locales/en/en.json b/FrontendV2/src/utils/i18n/locales/en/en.json index 33a99d9..2fd63f8 100644 --- a/FrontendV2/src/utils/i18n/locales/en/en.json +++ b/FrontendV2/src/utils/i18n/locales/en/en.json @@ -60,7 +60,7 @@ "sure-delete-loan-2": "It will remain visible to the admin.", "delete": "Delete", "change-language": "Change language", - "timezone-info": "The displayed dates and times are shown in Berlin timezone and must also be entered as such.", + "timezone-info": "The displayed dates and times are shown in Berlin timezone and must also be entered as such. The entire system is set to Berlin timezone.", "optional-note": "Optional note", "note": "Note", "user-info-desc": "Here you can view your personal information and change your password. If you need to make further changes, please contact an administrator.", From 1ce8d33b0d7eb9e78cf0c21ddb24f67f19cb8c71 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Sat, 9 May 2026 23:32:12 +0200 Subject: [PATCH 4/8] pulled naas --- no-as-a-service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/no-as-a-service b/no-as-a-service index 764062a..e6b4218 160000 --- a/no-as-a-service +++ b/no-as-a-service @@ -1 +1 @@ -Subproject commit 764062a307c725cb55f56308ee842f5e42529dd1 +Subproject commit e6b4218394f3ab6c513caaf2ec2e3e88d03d124c From fd43e84c0c45c3af6266420caf4498643773e09b Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Mon, 11 May 2026 22:40:34 +0200 Subject: [PATCH 5/8] refactored code --- backendV2/routes/app/database/loansMgmt.database.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/backendV2/routes/app/database/loansMgmt.database.js b/backendV2/routes/app/database/loansMgmt.database.js index aa9a261..34b8c72 100644 --- a/backendV2/routes/app/database/loansMgmt.database.js +++ b/backendV2/routes/app/database/loansMgmt.database.js @@ -63,11 +63,9 @@ export const createLoanInDatabase = async ( }; } - const itemNames = itemIds - .map( - (id) => itemsRows.find((r) => Number(r.id) === Number(id))?.item_name, - ) - .filter(Boolean); + const itemNames = itemIds.map( + (id) => itemsRows.find((r) => Number(r.id) === Number(id)).item_name, + ); // Build lockers array (unique, only 2-digit numbers from safe_nr) const lockers = [ From 831de8b6101a63fbb33d71b20d0aa85abe1fa6e2 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Wed, 13 May 2026 14:04:12 +0200 Subject: [PATCH 6/8] added new loan code function - NOT TESTED YET --- .../routes/app/database/loansMgmt.database.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/backendV2/routes/app/database/loansMgmt.database.js b/backendV2/routes/app/database/loansMgmt.database.js index 34b8c72..1b48d41 100644 --- a/backendV2/routes/app/database/loansMgmt.database.js +++ b/backendV2/routes/app/database/loansMgmt.database.js @@ -107,6 +107,32 @@ export const createLoanInDatabase = async ( }; } + let index = false; + let candidate = Math.floor(100000 + Math.random() * 899999); // 6 digits + + try { + const [exists] = await conn.query( + "SELECT 1 FROM loans WHERE loan_code = ? LIMIT 1", + [candidate], + ); + } catch (error) { + while ((i = false)) { + candidate = Math.floor(100000 + Math.random() * 899999); // 6 digits + + const [exists] = await conn.query( + "SELECT 1 FROM loans WHERE loan_code = ? LIMIT 1", + [candidate], + ); + + // sets index to true if the 6 digit code does not exist + if (exists.length == 0) { + index = true; + } + } + } + + /* + // Generate unique loan_code (retry a few times) let loanCode = null; for (let i = 0; i < 6; i++) { @@ -128,6 +154,8 @@ export const createLoanInDatabase = async ( message: "Failed to generate unique loan code", }; } + + */ // Insert loan (now includes lockers) const [insertRes] = await conn.query( From 67c704009e3fd9fd5e1721880faac8f5a6fcb289 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Wed, 13 May 2026 19:42:54 +0200 Subject: [PATCH 7/8] refactored loan code creation function --- .../routes/app/database/loansMgmt.database.js | 53 ++++--------------- 1 file changed, 11 insertions(+), 42 deletions(-) diff --git a/backendV2/routes/app/database/loansMgmt.database.js b/backendV2/routes/app/database/loansMgmt.database.js index 1b48d41..f02ea65 100644 --- a/backendV2/routes/app/database/loansMgmt.database.js +++ b/backendV2/routes/app/database/loansMgmt.database.js @@ -108,54 +108,23 @@ export const createLoanInDatabase = async ( } let index = false; - let candidate = Math.floor(100000 + Math.random() * 899999); // 6 digits + let candidate; + let loanCode; - try { - const [exists] = await conn.query( - "SELECT 1 FROM loans WHERE loan_code = ? LIMIT 1", + // Generates 6-digit loan code + do { + candidate = Math.floor(100000 + Math.random() * 899999); + + const [rows] = await conn.query( + "SELECT 1 FROM loans where loan_code = ? LIMIT 1", [candidate], ); - } catch (error) { - while ((i = false)) { - candidate = Math.floor(100000 + Math.random() * 899999); // 6 digits - const [exists] = await conn.query( - "SELECT 1 FROM loans WHERE loan_code = ? LIMIT 1", - [candidate], - ); - - // sets index to true if the 6 digit code does not exist - if (exists.length == 0) { - index = true; - } - } - } - - /* - - // Generate unique loan_code (retry a few times) - let loanCode = null; - for (let i = 0; i < 6; i++) { - const candidate = Math.floor(100000 + Math.random() * 899999); // 6 digits - const [exists] = await conn.query( - "SELECT 1 FROM loans WHERE loan_code = ? LIMIT 1", - [candidate], - ); - if (exists.length === 0) { + if (rows.length == 0) { + index = true; loanCode = candidate; - break; } - } - if (!loanCode) { - await conn.rollback(); - return { - success: false, - code: "SERVER_ERROR", - message: "Failed to generate unique loan code", - }; - } - - */ + } while (index === false); // Insert loan (now includes lockers) const [insertRes] = await conn.query( From 929ec5ef10b098c74587afeb21d7b8d8056e48d8 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Wed, 15 Jul 2026 15:40:08 +0200 Subject: [PATCH 8/8] fix: Fix issue/ticket #17 --- backendV2/routes/admin/database/loanDataMgmt.database.js | 2 +- backendV2/routes/api/api.database.js | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/backendV2/routes/admin/database/loanDataMgmt.database.js b/backendV2/routes/admin/database/loanDataMgmt.database.js index 776e41f..81d2c55 100644 --- a/backendV2/routes/admin/database/loanDataMgmt.database.js +++ b/backendV2/routes/admin/database/loanDataMgmt.database.js @@ -12,7 +12,7 @@ const pool = mysql .promise(); export const getAllLoans = async () => { - const [rows] = await pool.query("SELECT * FROM loans"); + const [rows] = await pool.query("SELECT * FROM loans WHERE deleted_admin = 0;"); return { success: true, data: rows }; }; diff --git a/backendV2/routes/api/api.database.js b/backendV2/routes/api/api.database.js index d0a13d3..f42f417 100644 --- a/backendV2/routes/api/api.database.js +++ b/backendV2/routes/api/api.database.js @@ -119,14 +119,6 @@ export const setTakeDateV2 = async (loanCode) => { return { message: "Failed to set take date", success: false }; }; -export const getAllLoansV2 = async () => { - const [result] = await pool.query("SELECT * FROM loans;"); - if (result.length > 0) { - return { success: true, data: result }; - } - return { success: false }; -}; - export const openDoor = async (doorKey) => { const [result] = await pool.query( "SELECT safe_nr, id FROM items WHERE door_key = ?;",