Compare commits

..
18 Commits
11 changed files with 162 additions and 98 deletions
+9 -17
View File
@@ -1,23 +1,15 @@
"use client"; "use client"
import { ChakraProvider, defaultSystem } from "@chakra-ui/react"; import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
import * as React from "react"; import {
import type { ReactNode } from "react"; ColorModeProvider,
import { ColorModeProvider as ThemeColorModeProvider } from "./color-mode"; type ColorModeProviderProps,
} from "./color-mode"
export interface ColorModeProviderProps { export function Provider(props: ColorModeProviderProps) {
children: React.ReactNode;
}
export function ColorModeProvider({ children }: ColorModeProviderProps) {
// Wrap children with the real color-mode provider
return <ThemeColorModeProvider>{children}</ThemeColorModeProvider>;
}
export function Provider({ children }: { children: ReactNode }) {
return ( return (
<ChakraProvider value={defaultSystem}> <ChakraProvider value={defaultSystem}>
<ColorModeProvider>{children}</ColorModeProvider> <ColorModeProvider {...props} />
</ChakraProvider> </ChakraProvider>
); )
} }
+7 -14
View File
@@ -1,23 +1,16 @@
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import svgr from "vite-plugin-svgr";
import tailwindcss from "@tailwindcss/vite"; import tailwindcss from "@tailwindcss/vite";
import path from "node:path"; import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({ export default defineConfig({
plugins: [tailwindcss()], plugins: [react(), svgr(), tailwindcss(), tsconfigPaths()],
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
server: { server: {
host: "0.0.0.0", host: "0.0.0.0",
allowedHosts: ["insta.the1s.de"], port: 8001,
port: 8101, watch: {
watch: { usePolling: true }, usePolling: true,
hmr: {
host: "insta.the1s.de",
port: 8101,
protocol: "wss",
}, },
}, },
}); });
+1 -1
View File
@@ -14,7 +14,7 @@ server {
} }
location /backend/ { location /backend/ {
proxy_pass http://borrow_system-backend_v2:8102/; proxy_pass http://borrow_system-backend_v2:8004/;
} }
location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ { location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
+3 -7
View File
@@ -8,13 +8,9 @@ export default defineConfig({
plugins: [react(), svgr(), tailwindcss(), tsconfigPaths()], plugins: [react(), svgr(), tailwindcss(), tsconfigPaths()],
server: { server: {
host: "0.0.0.0", host: "0.0.0.0",
allowedHosts: ["admin.insta.the1s.de"], port: 8003,
port: 8103, watch: {
watch: { usePolling: true }, usePolling: true,
hmr: {
host: "admin.insta.the1s.de",
port: 8103,
protocol: "wss",
}, },
}, },
}); });
+3 -3
View File
@@ -1,11 +1,11 @@
{ {
"backend-info": { "backend-info": {
"version": "v2.2" "version": "v2.2 (demo)"
}, },
"frontend-info": { "frontend-info": {
"version": "v2.2" "version": "v2.2 (demo)"
}, },
"admin-panel-info": { "admin-panel-info": {
"version": "v1.4" "version": "v1.4 (demo)"
} }
} }
@@ -12,7 +12,7 @@ const pool = mysql
.promise(); .promise();
export const getAllLoans = async () => { 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 }; return { success: true, data: rows };
}; };
-8
View File
@@ -119,14 +119,6 @@ export const setTakeDateV2 = async (loanCode) => {
return { message: "Failed to set take date", success: false }; 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) => { export const openDoor = async (doorKey) => {
const [result] = await pool.query( const [result] = await pool.query(
"SELECT safe_nr, id FROM items WHERE door_key = ?;", "SELECT safe_nr, id FROM items WHERE door_key = ?;",
@@ -63,11 +63,9 @@ export const createLoanInDatabase = async (
}; };
} }
const itemNames = itemIds const itemNames = itemIds.map(
.map( (id) => itemsRows.find((r) => Number(r.id) === Number(id)).item_name,
(id) => itemsRows.find((r) => Number(r.id) === Number(id))?.item_name, );
)
.filter(Boolean);
// Build lockers array (unique, only 2-digit numbers from safe_nr) // Build lockers array (unique, only 2-digit numbers from safe_nr)
const lockers = [ const lockers = [
@@ -109,27 +107,24 @@ export const createLoanInDatabase = async (
}; };
} }
// Generate unique loan_code (retry a few times) let index = false;
let loanCode = null; let candidate;
for (let i = 0; i < 6; i++) { let loanCode;
const candidate = Math.floor(100000 + Math.random() * 899999); // 6 digits
const [exists] = await conn.query( // Generates 6-digit loan code
"SELECT 1 FROM loans WHERE loan_code = ? LIMIT 1", do {
candidate = Math.floor(100000 + Math.random() * 899999);
const [rows] = await conn.query(
"SELECT 1 FROM loans where loan_code = ? LIMIT 1",
[candidate], [candidate],
); );
if (exists.length === 0) {
if (rows.length == 0) {
index = true;
loanCode = candidate; 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) // Insert loan (now includes lockers)
const [insertRes] = await conn.query( const [insertRes] = await conn.query(
+100
View File
@@ -0,0 +1,100 @@
USE borrow_system_new;
-- USERS
INSERT INTO users (username, password, email, first_name, last_name, role, is_admin)
VALUES
('user1', 'passwordhash1', 'user1@example.com', 'First1', 'Last1', 1, false),
('user2', 'passwordhash2', 'user2@example.com', 'First2', 'Last2', 1, false),
('user3', 'passwordhash3', 'user3@example.com', 'First3', 'Last3', 2, false),
('admin1', 'passwordhash4', 'admin1@example.com', 'Admin', 'One', 9, true),
('admin2', 'passwordhash5', 'admin2@example.com', 'Admin', 'Two', 9, true);
-- ITEMS
INSERT INTO items (item_name, can_borrow_role, in_safe, safe_nr, door_key, last_borrowed_person, currently_borrowing)
VALUES
('Item1', 1, true, 1, 101, NULL, NULL),
('Item2', 1, true, 2, 102, 'user1', 'user1'),
('Item3', 2, true, 3, 103, 'user2', NULL),
('Item4', 1, false, NULL, NULL, NULL, NULL),
('Item5', 2, false, NULL, NULL, 'user3', 'user3');
-- LOANS
INSERT INTO loans (
username,
lockers,
loan_code,
start_date,
end_date,
take_date,
returned_date,
created_at,
loaned_items_id,
loaned_items_name,
deleted,
note
)
VALUES
(
'user1',
JSON_ARRAY('Locker1', 'Locker2'),
'123456',
'2026-02-01 09:00:00',
'2026-02-10 17:00:00',
'2026-02-01 09:15:00',
NULL,
'2026-02-01 09:00:00',
JSON_ARRAY(1, 2),
JSON_ARRAY('Item1', 'Item2'),
false,
'Erste allgemeine Ausleihe'
),
(
'user2',
JSON_ARRAY('Locker3'),
'234567',
'2026-02-02 10:00:00',
'2026-02-05 16:00:00',
'2026-02-02 10:05:00',
'2026-02-05 15:30:00',
'2026-02-02 10:00:00',
JSON_ARRAY(3),
JSON_ARRAY('Item3'),
false,
'Zurückgegeben vor Enddatum'
),
(
'user3',
JSON_ARRAY(),
'345678',
'2026-02-03 08:30:00',
'2026-02-15 18:00:00',
NULL,
NULL,
'2026-02-03 08:30:00',
JSON_ARRAY(5),
JSON_ARRAY('Item5'),
false,
'Noch ausgeliehen'
),
(
'user1',
JSON_ARRAY('Locker4'),
'456789',
'2025-12-01 09:00:00',
'2025-12-03 17:00:00',
'2025-12-01 09:10:00',
'2025-12-03 16:45:00',
'2025-12-01 09:00:00',
JSON_ARRAY(1),
JSON_ARRAY('Item1'),
true,
'Alte, gelöschte Ausleihe'
);
-- API KEYS
INSERT INTO apiKeys (api_key, entry_name)
VALUES
('10000001', 'Entry1'),
('10000002', 'Entry2'),
('10000003', 'Entry3'),
('10000004', 'Entry4');
+20 -24
View File
@@ -1,23 +1,23 @@
services: services:
usr-frontend_v2: # usr-frontend_v2:
container_name: borrow_system-usr-frontend # container_name: borrow_system-usr-frontend
networks: # build: ./FrontendV2
- proxynet # ports:
build: ./FrontendV2 # - "8001:80"
restart: unless-stopped # restart: always
admin-frontend: # admin-frontend:
container_name: borrow_system-admin-frontend # container_name: borrow_system-admin-frontend
networks: # build: ./admin
- proxynet # ports:
build: ./admin # - "8003:80"
restart: unless-stopped # restart: always
backend_v2: backend_v2:
container_name: borrow_system-backend_v2 container_name: borrow_system-backend_v2
networks:
- proxynet
build: ./backendV2 build: ./backendV2
ports:
- "8004:8004"
environment: environment:
NODE_ENV: production NODE_ENV: production
DB_HOST: mysql_v2 DB_HOST: mysql_v2
@@ -26,14 +26,12 @@ services:
DB_NAME: borrow_system_new DB_NAME: borrow_system_new
depends_on: depends_on:
- mysql_v2 - mysql_v2
restart: unless-stopped restart: always
mysql_v2: mysql_v2:
container_name: borrow_system-mysql-v2 container_name: borrow_system-mysql-v2
networks:
- proxynet
image: mysql:8.0 image: mysql:8.0
restart: unless-stopped restart: always
environment: environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD_V2} MYSQL_ROOT_PASSWORD: ${DB_PASSWORD_V2}
MYSQL_DATABASE: borrow_system_new MYSQL_DATABASE: borrow_system_new
@@ -41,11 +39,13 @@ services:
volumes: volumes:
- mysql-v2-data:/var/lib/mysql - mysql-v2-data:/var/lib/mysql
- ./mysql-timezone.cnf:/etc/mysql/conf.d/timezone.cnf:ro - ./mysql-timezone.cnf:/etc/mysql/conf.d/timezone.cnf:ro
ports:
- "3310:3306"
no-as-a-service: no-as-a-service:
container_name: borrow_system-naas container_name: borrow_system-naas
networks: ports:
- proxynet - "3000:3000"
build: build:
context: ./no-as-a-service context: ./no-as-a-service
dockerfile: Dockerfile dockerfile: Dockerfile
@@ -54,7 +54,3 @@ services:
volumes: volumes:
mysql-data: mysql-data:
mysql-v2-data: mysql-v2-data:
networks:
proxynet:
external: true