feat: implement MainForm component and set up routing; add user table schema and trigger in SQL

This commit is contained in:
2026-01-13 19:01:06 +01:00
parent 8a915ea5f5
commit ba1a221ef3
8 changed files with 151 additions and 23 deletions

View File

@@ -0,0 +1,4 @@
import express from "express";
import dotenv from "dotenv";
const router = express.Router();
dotenv.config();

24
backend/scheme.sql Normal file
View File

@@ -0,0 +1,24 @@
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100) NOT NULL,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
unique_key CHAR(25) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Trigger zur automatischen Generierung eines 25stelligen Keys
DELIMITER $
CREATE TRIGGER before_user_insert
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
SET NEW.unique_key = SUBSTRING(
REPLACE(UUID(), '-', '')
-- UUID = 32 Zeichen, wir nehmen 25 davon
, 1, 25);
END$
DELIMITER ;

View File

@@ -1,5 +1,8 @@
import express from "express";
import cors from "cors";
import defaultRouter from "./routes/default/frontend.route.js";
import dotenv from "dotenv";
dotenv.config();
const app = express();
const PORT = process.env.PORT;
@@ -9,6 +12,8 @@ app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use("/default", defaultRouter);
app.get("/", (req, res) => {
res.render("index");
});

View File

@@ -1,10 +1,10 @@
services:
frontend:
container_name: ca-lose-frontend
build: ./frontend
ports:
- "8002:80"
restart: unless-stopped
# frontend:
# container_name: ca-lose-frontend
# build: ./frontend
# ports:
# - "8002:80"
# restart: unless-stopped
backend:
container_name: ca-lose-backend
@@ -13,21 +13,23 @@ services:
- "8004:8004"
environment:
NODE_ENV: production
DB_HOST: ca-lose
DB_HOST: ca_lose
DB_USER: root
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ca-lose
DB_NAME: ca_lose
depends_on:
- ca-lose
- database
restart: unless-stopped
database:
container_name: ca-lose
container_name: ca-lose-mysql
image: mysql:8.0
restart: unless-stopped
ports:
- "3311:3306"
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_DATABASE: ca-lose
MYSQL_DATABASE: ca_lose
TZ: Europe/Berlin
volumes:
- ca-lose_mysql:/var/lib/mysql

View File

@@ -1,12 +1,12 @@
import "./App.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { Inputs } from "./pages/Inputs";
import { MainForm } from "./pages/MainForm";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Inputs />} />
<Route path="/" element={<MainForm />} />
</Routes>
</BrowserRouter>
);

View File

@@ -1,10 +1,10 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";
createRoot(document.getElementById('root')!).render(
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
)
</StrictMode>
);

View File

@@ -1,3 +0,0 @@
export const Inputs = () => {
return <div>Inputs Page</div>;
};

View File

@@ -0,0 +1,96 @@
import { TextField, FormControlLabel, Checkbox, Button } from "@mui/material";
import { useTranslation } from "react-i18next";
import { useState } from "react";
export const MainForm = () => {
const { t } = useTranslation();
const [invoice, setInvoice] = useState(false);
return (
<>
<form action="" method="post">
<TextField
required
id="first-name"
label={t("first_name")}
variant="filled"
/>
<TextField
required
id="last-name"
label={t("last_name")}
variant="filled"
/>
<TextField required id="email" label={t("email")} variant="filled" />
<TextField
required
id="phone-number"
label={t("phone_number")}
variant="filled"
/>
<TextField
required
id="tickets"
label={t("tickets")}
variant="filled"
/>
<FormControlLabel control={<Checkbox />} label={t("invoice")} />
{invoice && (
<>
<TextField
required
id="company-name"
label={t("company_name")}
variant="filled"
/>
<TextField
required
id="first-name_invoice"
label={t("first_name")}
variant="filled"
/>
<TextField
required
id="last-name_invoice"
label={t("last_name")}
variant="filled"
/>
<TextField
required
id="street"
label={t("street")}
variant="filled"
/>
<TextField
required
id="postal-code"
label={t("postal_code")}
variant="filled"
/>
<TextField
required
id="phone-number_invoice"
label={t("phone_number")}
variant="filled"
/>
<TextField
required
id="email_invoice"
label={t("email")}
variant="filled"
/>
</>
)}
{/* Payment methods - only one must be selected */}
<FormControlLabel control={<Checkbox />} label={t("cash")} />
<FormControlLabel control={<Checkbox />} label={t("paypal")} />
<FormControlLabel control={<Checkbox />} label={t("transfer")} />
<TextField required id="code" label={t("code")} variant="filled" />
<Button variant="contained">{t("submit")}</Button>
</form>
</>
);
};