Compare commits

..

2 Commits

Author SHA1 Message Date
a910320b16 delted unused imports 2025-08-16 21:03:35 +02:00
b8d609ac28 Added export button, but without any function
- The function comes later...
2025-08-16 21:03:12 +02:00
13 changed files with 62 additions and 62 deletions

View File

@@ -7,6 +7,6 @@ RUN npm install
COPY . . COPY . .
EXPOSE 8502 EXPOSE 8002
CMD ["npm", "start"] CMD ["npm", "start"]

View File

@@ -1,7 +1,6 @@
{ {
"name": "backend", "name": "backend",
"version": "1.0.0", "version": "1.0.0",
"type": "module",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",

View File

@@ -13,7 +13,7 @@ import {
import { generateToken, authenticate } from "./services/tokenService.js"; import { generateToken, authenticate } from "./services/tokenService.js";
env.config(); env.config();
const app = express(); const app = express();
const port = 8502; const port = 8002;
app.use(cors()); app.use(cors());
// Increase body size limits to support large CSV JSON payloads // Increase body size limits to support large CSV JSON payloads
@@ -34,6 +34,8 @@ app.post("/lose", async (req, res) => {
} }
}); });
// !!!!!!! AUTHORISATION HINZUFÜGEN - DENN GEHT NICHT !!!!!!!!
app.get("/table-data", authenticate, async (req, res) => { app.get("/table-data", authenticate, async (req, res) => {
const result = await getTableData(); const result = await getTableData();
if (result.success && result.data) { if (result.success && result.data) {

View File

@@ -1,12 +1,11 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Backend</title> <title>Backend</title>
</head> </head>
<body> <body>
<h1>You have reached the backend views index page!</h1> Backend
<p>Currently, there is nothing to display!</p>
</body> </body>
</html> </html>

View File

@@ -1,27 +1,21 @@
services: services:
mcs_lose-frontend: # mcs_lose-frontend:
container_name: mcs_lose-frontend # container_name: mcs_lose-frontend
build: ./frontend # build: ./frontend
ports: # ports:
- "8501:8501" # - "8001:8001"
environment: # environment:
- CHOKIDAR_USEPOLLING=true # - CHOKIDAR_USEPOLLING=true
networks: # volumes:
- proxynet # - ./frontend:/app
- lose-local # - /app/node_modules
volumes: # restart: unless-stopped
- ./frontend:/app
- /app/node_modules
restart: unless-stopped
mcs_lose-backend: mcs_lose-backend:
container_name: mcs_lose-backend_express container_name: mcs_lose-backend_express
build: ./backend build: ./backend
ports: ports:
- "8502:8502" - "8002:8002"
networks:
- proxynet
- lose-local
environment: environment:
DB_HOST: mysql DB_HOST: mysql
DB_USER: root DB_USER: root
@@ -37,21 +31,13 @@ services:
container_name: mcs_lose-mysql container_name: mcs_lose-mysql
image: mysql:8.0 image: mysql:8.0
restart: unless-stopped restart: unless-stopped
networks:
- lose-local
environment: environment:
MYSQL_ROOT_PASSWORD: D7Ze0lwV9hMrNQHdz1Q8yi0MIQuOO8 MYSQL_ROOT_PASSWORD: D7Ze0lwV9hMrNQHdz1Q8yi0MIQuOO8
MYSQL_DATABASE: mcs_lose MYSQL_DATABASE: mcs_lose
volumes: volumes:
- mysql-data:/var/lib/mysql - mysql-data:/var/lib/mysql
ports: ports:
- "8500:3306" - "3308:3306"
volumes: volumes:
mysql-data: mysql-data:
networks:
proxynet:
external: true
lose-local:
external: false

View File

@@ -7,6 +7,6 @@ RUN npm install
COPY . . COPY . .
EXPOSE 8501 EXPOSE 8001
CMD ["npm", "run", "dev"] CMD ["npm", "run", "dev"]

View File

@@ -1,10 +1,11 @@
import React from "react"; import React, { useEffect } from "react";
import { Sheet, WholeWord, Search, DatabaseZap } from "lucide-react"; import { Sheet, WholeWord, Search, DatabaseZap, FileDown } from "lucide-react";
import { useState } from "react"; import { useState } from "react";
import ImportGUI from "./ImportGUI"; import ImportGUI from "./ImportGUI";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { removeSelection } from "../utils/tableActions"; import { removeSelection } from "../utils/tableActions";
import DangerZone from "./DangerZone"; import DangerZone from "./DangerZone";
import { myToast } from "../utils/toastify";
type SubHeaderAdminProps = { type SubHeaderAdminProps = {
setFiles: (files: File[]) => void; setFiles: (files: File[]) => void;
@@ -22,6 +23,13 @@ const SubHeaderAdmin: React.FC<SubHeaderAdminProps> = ({
}) => { }) => {
const [showImport, setShowImport] = useState(false); const [showImport, setShowImport] = useState(false);
const [showDanger, setShowDanger] = useState(false); const [showDanger, setShowDanger] = useState(false);
const [exporting, setExporting] = useState(false);
useEffect(() => {
if (exporting) {
myToast("Export in Bearbeitung...", "info");
}
}, [exporting]);
return ( return (
<> <>
@@ -62,6 +70,17 @@ const SubHeaderAdmin: React.FC<SubHeaderAdminProps> = ({
/> />
<span className="whitespace-nowrap">Losnummern importieren</span> <span className="whitespace-nowrap">Losnummern importieren</span>
</button> </button>
<button
onClick={() => setExporting(true)}
type="button"
className="group inline-flex items-center gap-2 rounded-md border border-gray-300 bg-white px-3.5 py-2 text-sm font-medium text-gray-700 shadow-sm transition hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/60 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
>
<FileDown
className="h-4 w-4 shrink-0 text-gray-500 transition group-hover:text-gray-600"
strokeWidth={1.75}
/>
<span className="whitespace-nowrap">Losnummern exportieren</span>
</button>
<button <button
onClick={() => { onClick={() => {
removeSelection(Cookies.get("token") || ""); removeSelection(Cookies.get("token") || "");
@@ -99,9 +118,7 @@ const SubHeaderAdmin: React.FC<SubHeaderAdminProps> = ({
/> />
)} )}
{showDanger && ( {showDanger && <DangerZone onClose={() => setShowDanger(false)} />}
<DangerZone onClose={() => setShowDanger(false)} />
)}
</> </>
); );
}; };

View File

@@ -55,7 +55,7 @@ export async function postCSV(file: File): Promise<boolean> {
const chunkSize = 2000; // ~2k per request => 25 requests for 50k const chunkSize = 2000; // ~2k per request => 25 requests for 50k
for (let i = 0; i < lines.length; i += chunkSize) { for (let i = 0; i < lines.length; i += chunkSize) {
const chunk = lines.slice(i, i + chunkSize); const chunk = lines.slice(i, i + chunkSize);
const res = await fetch("https://backend.lose.the1s.de/create-entry", { const res = await fetch("http://localhost:8002/create-entry", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",

View File

@@ -20,7 +20,7 @@ export const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
let response: Response; let response: Response;
try { try {
response = await fetch("https://backend.lose.the1s.de/login", { response = await fetch("http://localhost:8002/login", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password }), body: JSON.stringify({ username, password }),

View File

@@ -1,7 +1,7 @@
import { myToast } from "./toastify"; import { myToast } from "./toastify";
export const registerLos = async (data: any) => { export const registerLos = async (data: any) => {
await fetch("https://backend.lose.the1s.de/lose", { await fetch("http://localhost:8002/lose", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",

View File

@@ -30,7 +30,7 @@ function createHeaders(token: string) {
export const removeSelection = (token: string) => { export const removeSelection = (token: string) => {
const selection = Cookies.get("removeArr"); const selection = Cookies.get("removeArr");
if (selection && selection !== "[]") { if (selection && selection !== "[]") {
fetch("https://backend.lose.the1s.de/remove-entries", { fetch("http://localhost:8002/remove-entries", {
method: "DELETE", method: "DELETE",
headers: createHeaders(token), headers: createHeaders(token),
body: `{ body: `{
@@ -50,7 +50,7 @@ export const removeSelection = (token: string) => {
}; };
export const saveRow = (data: any, token: string) => { export const saveRow = (data: any, token: string) => {
fetch("https://backend.lose.the1s.de/save-row", { fetch("http://localhost:8002/save-row", {
method: "PUT", method: "PUT",
headers: createHeaders(token), headers: createHeaders(token),
body: JSON.stringify(data), body: JSON.stringify(data),
@@ -64,7 +64,7 @@ export const saveRow = (data: any, token: string) => {
}; };
export const resetData = (token: string) => { export const resetData = (token: string) => {
fetch("https://backend.lose.the1s.de/reset-data", { fetch("http://localhost:8002/reset-data", {
method: "DELETE", method: "DELETE",
headers: createHeaders(token), headers: createHeaders(token),
}).then((response) => { }).then((response) => {

View File

@@ -10,7 +10,7 @@ export const logoutAdmin = () => {
// Fetch table data and store it in localStorage. Returns the parsed data or null on failure. // Fetch table data and store it in localStorage. Returns the parsed data or null on failure.
export const getTableData = async (token: string) => { export const getTableData = async (token: string) => {
try { try {
const response = await fetch("https://backend.lose.the1s.de/table-data", { const response = await fetch("http://localhost:8002/table-data", {
method: "GET", method: "GET",
headers: { headers: {
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,

View File

@@ -1,18 +1,15 @@
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";
export default defineConfig({ export default defineConfig({
plugins: [tailwindcss()], plugins: [react(), svgr(), tailwindcss()],
server: { server: {
host: "0.0.0.0", host: "0.0.0.0",
allowedHosts: ["lose.the1s.de"], port: 8001,
port: 8501, watch: {
https: false, usePolling: true,
watch: { usePolling: true },
hmr: {
host: "lose.the1s.de",
port: 8501,
protocol: "wss",
}, },
}, },
}); });