Compare commits

..
13 Commits
104 changed files with 3401 additions and 9140 deletions
+14
View File
@@ -0,0 +1,14 @@
**/node_modules
**/dist
**/dist-ssr
.git
.idea
.vscode
**/.env
**/.env.*
**/.DS_Store
**/*.log
docs
pics
icon
no-as-a-service
+10
View File
@@ -0,0 +1,10 @@
DB_PASSWORD=
BACKEND_URL=
MAIL_HOST=
MAIL_PORT=
MAIL_USER=
MAIL_PASSWORD=
MAIL_SENDEES_CONTACT=
MAIL_SENDEES=
NAAS_URL=
SECRET_KEY=
+3 -1
View File
@@ -11,6 +11,8 @@ dist/
build/ build/
out/ out/
docker-compose.override.yml
# Environment variables # Environment variables
.env .env
.env.local .env.local
@@ -119,6 +121,6 @@ ToDo.txt
next-env.d.ts next-env.d.ts
# psd files from footage # psd files from footage
footage/*.psd pics/*.psd
icon/ icon/
+7
View File
@@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": false,
"trailingComma": "all",
"printWidth": 80,
"tabWidth": 2
}
+78
View File
@@ -0,0 +1,78 @@
# Docker
## Prerequisites
You have created an empty `docker-compose.override.yml` file in the root directory of this repository.
## Docker Network
If you want to run the stack in a docker network, you need to change the `BACKEND_HOST` variable in the root `.env` file
to `stockhome-backend`. To add a docker network, create a `docker-compose.override.yml` file in the root directory of
this repository with the following content:
```yaml
services:
admin-frontend:
networks:
- proxynet
backend:
networks:
- proxynet
usr-frontend:
networks:
- proxynet
no-as-a-service:
networks:
- proxynet
mysql:
networks:
- proxynet
networks:
proxynet:
external: true
```
To start off I recommend to set the `BACKEND_HOST` variable to `localhost` and start the stack without a docker network.
After you have started the stack and everything is working, you can add a docker network.
## Ports
### Change Exposed Ports
If you want to change the exposed ports, you can do this in the `docker-compose.yml` file like so:
```yaml
services:
mysql:
ports:
- "3306:3306"
backend:
ports:
- "8004:8004"
usr-frontend:
ports:
- "80:80"
```
### Remove Exposed Ports
If you want to remove the exposed ports, you can do this in the `docker-compose.override.yml` file like so:
```yaml
services:
mysql:
ports: !override [ ]
backend:
ports: !override [ ]
usr-frontend:
ports: !override [ ]
```
-19
View File
@@ -1,19 +0,0 @@
FROM node:22-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine AS runner
WORKDIR /usr/share/nginx/html
COPY --from=builder /app/dist .
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
-23
View File
@@ -1,23 +0,0 @@
"use client";
import { ChakraProvider, defaultSystem } from "@chakra-ui/react";
import * as React from "react";
import type { ReactNode } from "react";
import { ColorModeProvider as ThemeColorModeProvider } from "./color-mode";
export interface 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 (
<ChakraProvider value={defaultSystem}>
<ColorModeProvider>{children}</ColorModeProvider>
</ChakraProvider>
);
}
-23
View File
@@ -1,23 +0,0 @@
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
import path from "node:path";
export default defineConfig({
plugins: [tailwindcss()],
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
server: {
host: "0.0.0.0",
allowedHosts: ["insta.the1s.de"],
port: 8101,
watch: { usePolling: true },
hmr: {
host: "insta.the1s.de",
port: 8101,
protocol: "wss",
},
},
});
+23 -20
View File
@@ -19,17 +19,21 @@ A small full‑stack system to log in, view available items, reserve them for a
## Contents ## Contents
- Frontend: [frontend/](frontend) - Frontend: [frontend/](frontend)
- Vite/Tailwind config: [frontend/vite.config.ts](frontend/vite.config.ts), [frontend/tailwind.config.js](frontend/tailwind.config.js) - Vite/Tailwind
- App entry: [frontend/src/main.tsx](frontend/src/main.tsx), [frontend/src/App.tsx](frontend/src/App.tsx) config: [frontend/vite.config.ts](frontend/vite.config.ts), [frontend/tailwind.config.js](frontend/tailwind.config.js)
- UI: [frontend/src/layout/Layout.tsx](frontend/src/layout/Layout.tsx), [frontend/src/components](frontend/src/components) - App entry: [frontend/src/main.tsx](frontend/src/main.tsx), [frontend/src/App.tsx](frontend/src/App.tsx)
- Data/utilities: [frontend/src/utils/fetchData.ts](frontend/src/utils/fetchData.ts), [frontend/src/utils/userHandler.ts](frontend/src/utils/userHandler.ts), [frontend/src/utils/toastify.ts](frontend/src/utils/toastify.ts) -
UI: [frontend/src/layout/Layout.tsx](frontend/src/layout/Layout.tsx), [frontend/src/components](frontend/src/components)
-
Data/utilities: [frontend/src/utils/fetchData.ts](frontend/src/utils/fetchData.ts), [frontend/src/utils/userHandler.ts](frontend/src/utils/userHandler.ts), [frontend/src/utils/toastify.ts](frontend/src/utils/toastify.ts)
- Backend: [backend/](backend) - Backend: [backend/](backend)
- Server: [backend/server.js](backend/server.js) - Server: [backend/server.js](backend/server.js)
- Routes: [backend/routes/api.js](backend/routes/api.js), [backend/routes/apiV2.js](backend/routes/apiV2.js) - Routes: [backend/routes/api.js](backend/routes/api.js), [backend/routes/apiV2.js](backend/routes/apiV2.js)
- DB + services: [backend/services/database.js](backend/services/database.js), [backend/services/tokenService.js](backend/services/tokenService.js) - DB +
- Schema/seed: [backend/scheme.sql](backend/scheme.sql) services: [backend/services/database.js](backend/services/database.js), [backend/services/tokenService.js](backend/services/tokenService.js)
- Schema/seed: [backend/scheme.sql](backend/scheme.sql)
- Docs: [docs/](docs) - Docs: [docs/](docs)
- API docs (see below): [docs/backend_API_docs/README.md](docs/backend_API_docs/README.md) - API docs (see below): [docs/backend_API_docs/README.md](docs/backend_API_docs/README.md)
## Features (high‑level) ## Features (high‑level)
@@ -41,7 +45,8 @@ A small full‑stack system to log in, view available items, reserve them for a
Key frontend utilities: Key frontend utilities:
- [`utils.fetchData.fetchAllData`](frontend/src/utils/fetchData.ts): loads items, loans, and user loans after login. - [`utils.fetchData.fetchAllData`](frontend/src/utils/fetchData.ts): loads items, loans, and user loans after login.
- [`utils.fetchData.getBorrowableItems`](frontend/src/utils/fetchData.ts): fetches borrowable items for the selected time range. - [`utils.fetchData.getBorrowableItems`](frontend/src/utils/fetchData.ts): fetches borrowable items for the selected
time range.
- [`utils.userHandler.createLoan`](frontend/src/utils/userHandler.ts): creates a new loan for selected items. - [`utils.userHandler.createLoan`](frontend/src/utils/userHandler.ts): creates a new loan for selected items.
- [`utils.userHandler.handleDeleteLoan`](frontend/src/utils/userHandler.ts): deletes a loan and syncs local state. - [`utils.userHandler.handleDeleteLoan`](frontend/src/utils/userHandler.ts): deletes a loan and syncs local state.
- [`utils.toastify.myToast`](frontend/src/utils/toastify.ts): toast notifications. - [`utils.toastify.myToast`](frontend/src/utils/toastify.ts): toast notifications.
@@ -54,20 +59,18 @@ UI flow (main screens):
## Development ## Development
- Scripts: see [frontend/package.json](frontend/package.json) and [backend/package.json](backend/package.json) - The NAAS (no-as-a-service) and the mysql database are running in a docker container
- Frontend: `npm run dev`, `npm run build`, `npm run preview`, `npm run lint` - `frontend`, `backend` and `admin` are both in a vite dev server and can be started by `npm run dev` in the root
- Backend: `npm start` directory.
- Linting: ESLint configured via [frontend/eslint.config.js](frontend/eslint.config.js)
- TypeScript configs: [frontend/tsconfig.app.json](frontend/tsconfig.app.json), [frontend/tsconfig.node.json](frontend/tsconfig.node.json)
## Configuration notes ## Configuration notes
- Vite/Tailwind integration via [frontend/vite.config.ts](frontend/vite.config.ts) and `@tailwindcss/vite`; CSS entry uses `@import "tailwindcss"` in [frontend/src/index.css](frontend/src/index.css). - Vite/Tailwind integration via [frontend/vite.config.ts](frontend/vite.config.ts) and `@tailwindcss/vite`; CSS entry
uses `@import "tailwindcss"` in [frontend/src/index.css](frontend/src/index.css).
- Toasts wired in [frontend/src/main.tsx](frontend/src/main.tsx) with `react-toastify`. - Toasts wired in [frontend/src/main.tsx](frontend/src/main.tsx) with `react-toastify`.
- Local state is stored in `localStorage` keys: `allItems`, `allLoans`, `userLoans`, `borrowableItems`. Cross‑component updates are signaled via window events from [`utils.fetchData`](frontend/src/utils/fetchData.ts). - Local state is stored in `localStorage` keys: `allItems`, `allLoans`, `userLoans`, `borrowableItems`. Cross‑component
updates are signaled via window events from [`utils.fetchData`](frontend/src/utils/fetchData.ts).
## API documentation ## API documentation
Refer to the dedicated API docs: Refer to the dedicated [API-Docs](docs/backend_API_docs/README.md)
`docs/backend_API_docs/README.md`
+14 -7
View File
@@ -1,19 +1,26 @@
FROM node:18 as builder # Build context is the repo root (npm workspaces share one root package-lock.json)
FROM node:22-alpine AS builder
WORKDIR /app WORKDIR /app
COPY package.json package-lock.json ./ COPY package.json package-lock.json ./
RUN npm ci COPY frontend/package.json frontend/
COPY admin/package.json admin/
COPY backend/package.json backend/
RUN npm ci -w admin
COPY . . ARG VITE_BACKEND_URL
RUN npm run build ENV VITE_BACKEND_URL=$VITE_BACKEND_URL
COPY admin/ admin/
RUN npm run build -w admin
FROM nginx:alpine AS runner FROM nginx:alpine AS runner
WORKDIR /usr/share/nginx/html WORKDIR /usr/share/nginx/html
COPY --from=builder /app/dist . COPY --from=builder /app/admin/dist .
COPY nginx.conf /etc/nginx/conf.d/default.conf COPY admin/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80 EXPOSE 80
CMD ["nginx", "-g", "daemon off;"] CMD ["nginx", "-g", "daemon off;"]
+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:8004/;
} }
location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ { location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
-6066
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "admin", "name": "admin",
"private": true, "private": true,
"version": "v1.3.2 (dev)", "version": "1.3.2-dev",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
+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",
}, },
}, },
}); });
+28
View File
@@ -0,0 +1,28 @@
# Build context is the repo root (npm workspaces share one root package-lock.json)
FROM node:20-alpine
ENV NODE_ENV=production
WORKDIR /app
COPY package.json package-lock.json ./
COPY frontend/package.json frontend/
COPY admin/package.json admin/
COPY backend/package.json backend/
RUN npm ci -w backend --omit=dev
COPY backend/ backend/
# Generate info.json from the workspace package.json versions, without the "-dev" suffix
RUN node -e ' \
const fs = require("fs"); \
const v = (p) => "v" + JSON.parse(fs.readFileSync(p + "/package.json")).version.replace(/-dev$/, ""); \
fs.writeFileSync("backend/info.json", JSON.stringify({ \
"backend-info": { version: v("backend") }, \
"frontend-info": { version: v("frontend") }, \
"admin-panel-info": { version: v("admin") } \
}, null, 4)); \
'
WORKDIR /app/backend
EXPOSE 8004
CMD ["npm", "start"]
+11
View File
@@ -0,0 +1,11 @@
{
"backend-info": {
"version": "v2.2 (dev)"
},
"frontend-info": {
"version": "v2.2 (dev)"
},
"admin-panel-info": {
"version": "v1.4 (dev)"
}
}
@@ -1,10 +1,11 @@
{ {
"name": "backendv2", "name": "backend",
"version": "v2.1.1 (dev)", "version": "2.1.1-dev",
"private": true,
"main": "server.js", "main": "server.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "dev": "node --watch server.js",
"start": "node server.js" "start": "NODE_ENV=production node server.js"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
@@ -18,6 +19,6 @@
"express-rate-limit": "^8.4.1", "express-rate-limit": "^8.4.1",
"jose": "^6.0.12", "jose": "^6.0.12",
"mysql2": "^3.14.3", "mysql2": "^3.14.3",
"nodemailer": "^8.0.6" "nodemailer": "^10.2.1"
} }
} }
@@ -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 };
}; };
@@ -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;
} }
} } while (index === false);
if (!loanCode) {
await conn.rollback();
return {
success: false,
code: "SERVER_ERROR",
message: "Failed to generate unique loan code",
};
}
// Insert loan (now includes lockers) // Insert loan (now includes lockers)
const [insertRes] = await conn.query( const [insertRes] = await conn.query(
+1 -1
View File
@@ -1,7 +1,7 @@
import express from "express"; import express from "express";
import cors from "cors"; import cors from "cors";
import dotenv from "dotenv"; import dotenv from "dotenv";
import info from "./info.json" assert { type: "json" }; import info from "./info.json" with { type: "json" };
import { authenticate } from "./services/authentication.js"; import { authenticate } from "./services/authentication.js";
import { rateLimit } from "express-rate-limit"; import { rateLimit } from "express-rate-limit";
-12
View File
@@ -1,12 +0,0 @@
FROM node:20-alpine
ENV NODE_ENV=production
WORKDIR /backend
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 8004
CMD ["npm", "start"]
-11
View File
@@ -1,11 +0,0 @@
{
"backend-info": {
"version": "v2.2"
},
"frontend-info": {
"version": "v2.2"
},
"admin-panel-info": {
"version": "v1.4"
}
}
-1141
View File
File diff suppressed because it is too large Load Diff
-29
View File
@@ -1,29 +0,0 @@
# Changelog for upcoming version: vX.X
Introduction
## New features
-
## Improvements
-
## Fixed bugs
-
---
## New version numbers
**Backend:** vX.X
**Frontend:** vX.X
**Admin panel:** vX.X
---
-[Theis](https://portfolio-theis.de)
+56
View File
@@ -0,0 +1,56 @@
services:
# usr-frontend_v2:
# container_name: borrow_system-usr-frontend
# build: ./FrontendV2
# ports:
# - "8001:80"
# restart: always
# admin-frontend:
# container_name: borrow_system-admin-frontend
# build: ./admin
# ports:
# - "8003:80"
# restart: always
# backend_v2:
# container_name: borrow_system-backend_v2
# build: ./backend
# ports:
# - "8004:8004"
# environment:
# NODE_ENV: production
# DB_HOST: mysql_v2
# DB_USER: root
# DB_PASSWORD: ${DB_PASSWORD_V2}
# DB_NAME: borrow_system_new
# depends_on:
# - mysql_v2
# restart: always
mysql:
container_name: borrow-system_mysql
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD_V2}
MYSQL_DATABASE: borrow_system_new
TZ: Europe/Berlin
volumes:
- mysql-v2-data:/var/lib/mysql
- ./mysql-timezone.cnf:/etc/mysql/conf.d/timezone.cnf:ro
ports:
- "3310:3306"
no-as-a-service:
container_name: borrow-system_naas
ports:
- "3000:3000"
build:
context: ./no-as-a-service
dockerfile: Dockerfile
restart: always
volumes:
mysql-data:
mysql-v2-data:
+38 -34
View File
@@ -1,41 +1,51 @@
services: services:
usr-frontend_v2: usr-frontend:
container_name: borrow_system-usr-frontend container_name: borrow-system_usr-frontend
networks: build:
- proxynet context: .
build: ./FrontendV2 dockerfile: frontend/Dockerfile
restart: unless-stopped args:
VITE_BACKEND_URL: ${BACKEND_URL}
restart: always
admin-frontend: admin-frontend:
container_name: borrow_system-admin-frontend container_name: borrow-system_admin-frontend
networks: build:
- proxynet context: .
build: ./admin dockerfile: admin/Dockerfile
restart: unless-stopped args:
VITE_BACKEND_URL: ${BACKEND_URL}
restart: always
backend_v2: backend:
container_name: borrow_system-backend_v2 container_name: borrow-system_backend
networks: build:
- proxynet context: .
build: ./backendV2 dockerfile: backend/Dockerfile
environment: environment:
NODE_ENV: production NODE_ENV: production
DB_HOST: mysql_v2 DB_HOST: borrow-system_mysql
DB_USER: root DB_USER: root
DB_PASSWORD: ${DB_PASSWORD_V2} DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: borrow_system_new DB_NAME: borrow_system_new
MAIL_HOST: ${MAIL_HOST}
MAIL_PORT: ${MAIL_PORT}
MAIL_USER: ${MAIL_USER}
MAIL_PASSWORD: ${MAIL_PASSWORD}
MAIL_SENDEES_CONTACT: ${MAIL_SENDEES_CONTACT}
MAIL_SENDEES: ${MAIL_SENDEES}
NAAS_URL: ${NAAS_URL}
SECRET_KEY: ${SECRET_KEY}
depends_on: depends_on:
- mysql_v2 - mysql
restart: unless-stopped restart: always
mysql_v2: mysql:
container_name: borrow_system-mysql-v2 container_name: borrow-system_mysql
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}
MYSQL_DATABASE: borrow_system_new MYSQL_DATABASE: borrow_system_new
TZ: Europe/Berlin TZ: Europe/Berlin
volumes: volumes:
@@ -43,9 +53,7 @@ services:
- ./mysql-timezone.cnf:/etc/mysql/conf.d/timezone.cnf:ro - ./mysql-timezone.cnf:/etc/mysql/conf.d/timezone.cnf:ro
no-as-a-service: no-as-a-service:
container_name: borrow_system-naas container_name: borrow-system_naas
networks:
- proxynet
build: build:
context: ./no-as-a-service context: ./no-as-a-service
dockerfile: Dockerfile dockerfile: Dockerfile
@@ -53,8 +61,4 @@ services:
volumes: volumes:
mysql-data: mysql-data:
mysql-v2-data: mysql-v2-data:
networks:
proxynet:
external: true
+26
View File
@@ -0,0 +1,26 @@
# Build context is the repo root (npm workspaces share one root package-lock.json)
FROM node:22-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
COPY frontend/package.json frontend/
COPY admin/package.json admin/
COPY backend/package.json backend/
RUN npm ci -w frontend
ARG VITE_BACKEND_URL
ENV VITE_BACKEND_URL=$VITE_BACKEND_URL
COPY frontend/ frontend/
RUN npm run build -w frontend
FROM nginx:alpine AS runner
WORKDIR /usr/share/nginx/html
COPY --from=builder /app/frontend/dist .
COPY frontend/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
@@ -14,7 +14,7 @@ server {
} }
location /backend/ { location /backend/ {
proxy_pass http://borrow_system-backend_v2:8004/; proxy_pass http://borrow-system_backend:8004/;
} }
location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ { location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
@@ -1,7 +1,7 @@
{ {
"name": "admin", "name": "frontend",
"private": true, "private": true,
"version": "v2.1.2 (dev)", "version": "2.1.2-dev",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -45,6 +45,7 @@
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.3.0", "globals": "^16.3.0",
"prettier": "^3.9.10",
"typescript": "~5.8.3", "typescript": "~5.8.3",
"typescript-eslint": "^8.39.0", "typescript-eslint": "^8.39.0",
"vite": "^7.1.0", "vite": "^7.1.0",

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

+15
View File
@@ -0,0 +1,15 @@
"use client"
import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
import {
ColorModeProvider,
type ColorModeProviderProps,
} from "./color-mode"
export function Provider(props: ColorModeProviderProps) {
return (
<ChakraProvider value={defaultSystem}>
<ColorModeProvider {...props} />
</ChakraProvider>
)
}
@@ -14,5 +14,5 @@ createRoot(document.getElementById("root")!).render(
<Provider> <Provider>
<App /> <App />
</Provider> </Provider>
</StrictMode> </StrictMode>,
); );
+16
View File
@@ -0,0 +1,16 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import svgr from "vite-plugin-svgr";
import tailwindcss from "@tailwindcss/vite";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [react(), svgr(), tailwindcss(), tsconfigPaths()],
server: {
host: "0.0.0.0",
port: 8001,
watch: {
usePolling: true,
},
},
});
+2
View File
@@ -0,0 +1,2 @@
[mysqld]
default-time-zone = Europe/Berlin
File diff suppressed because it is too large Load Diff
+35
View File
@@ -0,0 +1,35 @@
{
"name": "borrow-system",
"version": "2.3.0",
"private": true,
"workspaces": [
"backend",
"frontend",
"admin"
],
"description": "",
"main": "index.js",
"directories": {
"doc": "docs"
},
"devDependencies": {
"concurrently": "^10.0.6",
"prettier": "^3.9.6"
},
"scripts": {
"dev:docker": "docker compose -f docker-compose.dev.yml up -d",
"dev": "npm run dev:docker && concurrently --kill-others \"npm:dev:frontend\" \"npm:dev:backend\" \"npm:dev:admin\"",
"dev:frontend": "npm run dev -w frontend",
"dev:backend": "npm run dev -w backend",
"dev:admin": "npm run dev -w admin",
"dev:stop": "docker compose -f docker-compose.dev.yml down"
},
"repository": {
"type": "git",
"url": "https://git.the1s.de/theis.gaedigk/borrow-system.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}

Some files were not shown because too many files have changed in this diff Show More