added prize draw name to tables
This commit is contained in:
@@ -158,6 +158,7 @@ keys/
|
||||
# Own files
|
||||
ToDo.txt
|
||||
PayPal-QR-Code.png
|
||||
.docker/volumes
|
||||
|
||||
# only in development branch
|
||||
next-env.d.ts
|
||||
@@ -11,14 +11,16 @@ const pool = mysql
|
||||
})
|
||||
.promise();
|
||||
|
||||
export const getUser = async () => {
|
||||
const [rows] = await pool.query("SELECT username FROM users");
|
||||
export const getInfo = async () => {
|
||||
const [rows] = await pool.query("SELECT username FROM users;");
|
||||
const [rows2] = await pool.query("SELECT name FROM prize_draws;");
|
||||
|
||||
if (rows.length > 0) {
|
||||
if (rows.length > 0 && rows2.length > 0) {
|
||||
const users = rows.map((r) => r.username);
|
||||
return { users };
|
||||
const prize_draws = rows2.map((n) => n.name);
|
||||
return { users, prize_draws };
|
||||
} else {
|
||||
return { users: [], message: "No data found" };
|
||||
return { message: "No data found" };
|
||||
}
|
||||
};
|
||||
|
||||
@@ -43,6 +45,7 @@ export const confirmUser = async (username) => {
|
||||
const [createTable] = await pool.query(
|
||||
`CREATE TABLE IF NOT EXISTS ?? (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
Verlosung VARCHAR(100) NOT NULL,
|
||||
Vorname VARCHAR(100) NOT NULL,
|
||||
Nachname Varchar(100) NOT NULL,
|
||||
EMail Varchar(100) NOT NULL,
|
||||
@@ -80,7 +83,7 @@ export const confirmUser = async (username) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const newEntry = async (formData, username) => {
|
||||
export const newEntry = async (formData, username, prizeDraw) => {
|
||||
const confirmation = await confirmUser(username);
|
||||
|
||||
if (!confirmation || !confirmation.success) {
|
||||
@@ -90,9 +93,10 @@ export const newEntry = async (formData, username) => {
|
||||
const tableName = confirmation.tableName;
|
||||
|
||||
const [result] = await pool.query(
|
||||
`INSERT INTO ?? (Vorname, Nachname, EMail, Telefonnummer, Lose, Firmenname, Vorname_Geschaeftlich, Nachname_Geschaeftlich, EMail_Geschaeftlich, Telefonnummer_Geschaeftlich, Strasse_Hausnr, Plz_Ort, Zahlungsmethode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
`INSERT INTO ?? (Verlosung, Vorname, Nachname, EMail, Telefonnummer, Lose, Firmenname, Vorname_Geschaeftlich, Nachname_Geschaeftlich, EMail_Geschaeftlich, Telefonnummer_Geschaeftlich, Strasse_Hausnr, Plz_Ort, Zahlungsmethode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
tableName,
|
||||
prizeDraw,
|
||||
formData.firstName,
|
||||
formData.lastName,
|
||||
formData.email,
|
||||
|
||||
@@ -3,24 +3,33 @@ import dotenv from "dotenv";
|
||||
const router = express.Router();
|
||||
dotenv.config();
|
||||
|
||||
import { getUser, newEntry, confirmUser } from "./frontend.data.js";
|
||||
import { getInfo, newEntry, confirmUser } from "./frontend.data.js";
|
||||
|
||||
router.post("/new-entry", async (req, res) => {
|
||||
const username = req.query.username;
|
||||
const result = await newEntry(req.body, username);
|
||||
const draw = req.query.draw;
|
||||
|
||||
const result = await newEntry(req.body, username, draw);
|
||||
|
||||
if (!result.success) {
|
||||
return res.status(500).json({ message: "Form Data Invalid" });
|
||||
}
|
||||
res.sendStatus(204);
|
||||
});
|
||||
|
||||
router.get("/users", async (req, res) => {
|
||||
const users = await getUser();
|
||||
res.json(users);
|
||||
router.get("/info", async (req, res) => {
|
||||
const info = await getInfo();
|
||||
|
||||
if (!info) {
|
||||
return res.status(500).json({ message: "Server error" });
|
||||
}
|
||||
|
||||
res.json(info);
|
||||
});
|
||||
|
||||
router.get("/confirm-user", async (req, res) => {
|
||||
const username = req.query.username;
|
||||
|
||||
if (!username) {
|
||||
return res.status(400).json({ message: "Username is required" });
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
USE ca_lose;
|
||||
|
||||
CREATE TABLE users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(100) NOT NULL UNIQUE,
|
||||
@@ -6,9 +8,16 @@ CREATE TABLE users (
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE prize_draws (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL UNIQUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
/* This scheme does not have to be implemented manually. It always will be generated by the backend */
|
||||
CREATE TABLE xx_DD_MM_YYYY (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
Verlosung VARCHAR(100) NOT NULL,
|
||||
Vorname VARCHAR(100) NOT NULL,
|
||||
Nachname Varchar(100) NOT NULL,
|
||||
EMail Varchar(100) NOT NULL,
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ services:
|
||||
MYSQL_DATABASE: ca_lose
|
||||
TZ: Europe/Berlin
|
||||
volumes:
|
||||
- ca-lose_mysql:/var/lib/mysql
|
||||
- ./.docker/volumes/ca-lose_mysql:/var/lib/mysql
|
||||
- ./mysql-timezone.cnf:/etc/mysql/conf.d/timezone.cnf:ro
|
||||
|
||||
volumes:
|
||||
|
||||
@@ -10,10 +10,12 @@ import { useTranslation } from "react-i18next";
|
||||
interface SelectUserModalProps {
|
||||
showSelectUser: boolean;
|
||||
setShowSelectUser: (value: boolean) => void;
|
||||
usernameData: { users: string[] };
|
||||
usernameDataIsLoading: boolean;
|
||||
info: { users: string[]; prize_draws: string[] };
|
||||
infoIsLoading: boolean;
|
||||
selectedUser: string | null;
|
||||
selectedDraw: string | null;
|
||||
handleUserSelection: (value: string | null) => void;
|
||||
handleDrawSelection: (value: string | null) => void;
|
||||
}
|
||||
|
||||
export const SelectUserModal = (props: SelectUserModalProps) => {
|
||||
@@ -25,8 +27,8 @@ export const SelectUserModal = (props: SelectUserModalProps) => {
|
||||
<Typography>{t("user")}</Typography>
|
||||
{/* User selection */}
|
||||
<Autocomplete
|
||||
options={props.usernameData?.users ?? []}
|
||||
loading={props.usernameDataIsLoading}
|
||||
options={props.info?.users ?? []}
|
||||
loading={props.infoIsLoading}
|
||||
loadingText={t("loading")}
|
||||
value={props.selectedUser}
|
||||
onChange={(_, value) => props.handleUserSelection(value)}
|
||||
@@ -34,6 +36,17 @@ export const SelectUserModal = (props: SelectUserModalProps) => {
|
||||
variant="soft"
|
||||
sx={{ borderRadius: "10px" }}
|
||||
/>
|
||||
{/* Prize selection */}
|
||||
<Autocomplete
|
||||
options={props.info?.prize_draws ?? []}
|
||||
loading={props.infoIsLoading}
|
||||
loadingText={t("loading")}
|
||||
value={props.selectedDraw}
|
||||
onChange={(_, value) => props.handleDrawSelection(value)}
|
||||
placeholder={t("prize_draws")}
|
||||
variant="soft"
|
||||
sx={{ borderRadius: "10px" }}
|
||||
/>
|
||||
</ModalDialog>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -21,7 +21,7 @@ import PersonIcon from "@mui/icons-material/Person";
|
||||
import QrCodeIcon from "@mui/icons-material/QrCode";
|
||||
import TranslateIcon from "@mui/icons-material/Translate";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { confirmUser, fetchUsers } from "../utils/api/users";
|
||||
import { confirmUser, fetchInfo } from "../utils/api/users";
|
||||
import { QRcodeModal } from "../components/modals/QR-CodeModal";
|
||||
import { SelectUserModal } from "../components/modals/SelectUserModal";
|
||||
import { useForm } from "@tanstack/react-form";
|
||||
@@ -39,6 +39,7 @@ export const MainForm = () => {
|
||||
const [invoice, setInvoice] = useState(false);
|
||||
const [msg, setMsg] = useState<Message | null>(null);
|
||||
const [selectedUser, setSelectedUser] = useState<string | null>(null);
|
||||
const [selectedDraw, setSelectedDraw] = useState<string | null>(null);
|
||||
const [showSelectUser, setShowSelectUser] = useState(false);
|
||||
const [QRmodal, setQRmodal] = useState(false);
|
||||
|
||||
@@ -106,6 +107,11 @@ export const MainForm = () => {
|
||||
// useEffect that only executes on mount and is checking if there is a user selcted in the cookies
|
||||
useEffect(() => {
|
||||
const savedUser = Cookies.get("selectedUser");
|
||||
const savedDraw = Cookies.get("selectedDraw");
|
||||
if (savedDraw) {
|
||||
setSelectedDraw(savedDraw);
|
||||
}
|
||||
|
||||
if (savedUser) {
|
||||
setSelectedUser(savedUser);
|
||||
} else {
|
||||
@@ -118,9 +124,9 @@ export const MainForm = () => {
|
||||
}, []);
|
||||
|
||||
// Fetch users tanstack query
|
||||
const { data: usernameData, isLoading: usernameDataIsLoading } = useQuery({
|
||||
queryKey: ["users"],
|
||||
queryFn: fetchUsers,
|
||||
const { data: info, isLoading: infoIsLoading } = useQuery({
|
||||
queryKey: ["info"],
|
||||
queryFn: fetchInfo,
|
||||
});
|
||||
|
||||
// Query for validating selcted user
|
||||
@@ -157,15 +163,26 @@ export const MainForm = () => {
|
||||
setSelectedUser(username);
|
||||
};
|
||||
|
||||
// function for selecting draw
|
||||
const handleDrawSelection = (draw: string | null) => {
|
||||
if (draw == null || draw == "") {
|
||||
return;
|
||||
}
|
||||
setSelectedDraw(draw);
|
||||
Cookies.set("selectedDraw", draw);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<SelectUserModal
|
||||
showSelectUser={showSelectUser}
|
||||
setShowSelectUser={setShowSelectUser}
|
||||
usernameData={usernameData}
|
||||
usernameDataIsLoading={usernameDataIsLoading}
|
||||
info={info}
|
||||
infoIsLoading={infoIsLoading}
|
||||
selectedUser={selectedUser}
|
||||
selectedDraw={selectedDraw}
|
||||
handleUserSelection={handleUserSelection}
|
||||
handleDrawSelection={handleDrawSelection}
|
||||
/>
|
||||
|
||||
<QRcodeModal setQRmodal={setQRmodal} QRmodal={QRmodal} />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { API_BASE } from "../../config/api.config";
|
||||
import type { FormData } from "../../config/interfaces.config";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
export const submitFormData = async (
|
||||
data: FormData,
|
||||
@@ -7,10 +8,16 @@ export const submitFormData = async (
|
||||
) => {
|
||||
console.warn("submitFormData is fetching!");
|
||||
|
||||
const draw = Cookies.get("selectedDraw");
|
||||
|
||||
if (!draw) {
|
||||
throw new Error("You need to set an prize draw!");
|
||||
}
|
||||
|
||||
// await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait 3 seconds
|
||||
|
||||
const response = await fetch(
|
||||
`${API_BASE}/default/new-entry?username=${username}`,
|
||||
`${API_BASE}/default/new-entry?username=${username}&draw=${draw}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { API_BASE } from "../../config/api.config";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
export const fetchUsers = async () => {
|
||||
console.warn("fetchUsers is fetching!");
|
||||
export const fetchInfo = async () => {
|
||||
console.warn("fetchInfo is fetching!");
|
||||
|
||||
const response = await fetch(`${API_BASE}/default/users`);
|
||||
const response = await fetch(`${API_BASE}/default/info`);
|
||||
const data = await response.json();
|
||||
|
||||
return data;
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
"user": "Benutzer",
|
||||
"next-id": "Nächste Eintragsnummer: ",
|
||||
"form-submitted-successfully": "Formular erfolgreich übermittelt!",
|
||||
"form-submission-failed": "Formularübermittlung fehlgeschlagen.",
|
||||
"form-submission-failed": "Formularübermittlung fehlgeschlagen. Haben Sie eine Verlosung ausgewählt?",
|
||||
"success": "Erfolg",
|
||||
"error": "Fehler",
|
||||
"cash": "Bar",
|
||||
"paypal": "PayPal",
|
||||
"prize_draws": "Verlosungen",
|
||||
"transfer": "Andere (notieren)",
|
||||
"ticket-payment_one": "Sie haben erfolgreich {{count}} Los gekauft.",
|
||||
"ticket-payment_other": "Sie haben erfolgreich {{count}} Lose gekauft.",
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
"user": "User",
|
||||
"next-id": "Next Entry Number: ",
|
||||
"form-submitted-successfully": "Form submitted successfully!",
|
||||
"orm-submission-failed": "Form submission failed.",
|
||||
"form-submission-failed": "Form submission failed. Have you set an prize draw?",
|
||||
"prize_draws": "Prize draws",
|
||||
"success": "Success",
|
||||
"error": "Error",
|
||||
"cash": "Cash",
|
||||
|
||||
Reference in New Issue
Block a user