diff --git a/frontend/src/components/TextField.tsx b/frontend/src/components/TextField.tsx new file mode 100644 index 0000000..c527bb1 --- /dev/null +++ b/frontend/src/components/TextField.tsx @@ -0,0 +1,31 @@ +import type { TextFieldProps } from "../config/interfaces.config"; +import { FormControl, FormLabel, Input } from "@mui/joy"; + +export const TextField = ({ + label, + type = "text", + required, + errors, + value, + onBlur, + onChange, + slotProps, + afterInput, +}: TextFieldProps) => ( + + {label} + onChange(e.target.value)} + type={type} + variant="soft" + sx={{ borderRadius: "10px" }} + slotProps={slotProps} + /> + {afterInput} + {errors[0] ? ( + {errors[0]} + ) : null} + +); diff --git a/frontend/src/config/interfaces.config.ts b/frontend/src/config/interfaces.config.ts index dde4d15..2445779 100644 --- a/frontend/src/config/interfaces.config.ts +++ b/frontend/src/config/interfaces.config.ts @@ -1,5 +1,6 @@ import z from "zod"; import validator from "validator"; +import type { ReactNode } from "react"; export interface FormData { firstName: string; @@ -23,6 +24,18 @@ export interface Message { text: string; } +export type TextFieldProps = { + label: string; + type?: "text" | "email" | "tel" | "number"; + required?: boolean; + errors: string[]; + onBlur: () => void; + onChange: (value: string) => void; + value: string | number | null | undefined; + slotProps?: { input?: Record }; + afterInput?: ReactNode; +}; + export const createFormSchema = ( t: (key: string) => string, invoice: boolean, diff --git a/frontend/src/pages/MainForm.tsx b/frontend/src/pages/MainForm.tsx index 70f0ad4..2c86891 100644 --- a/frontend/src/pages/MainForm.tsx +++ b/frontend/src/pages/MainForm.tsx @@ -28,6 +28,7 @@ import { useForm } from "@tanstack/react-form"; import { changeTranslation } from "../utils/uxFncs"; import { createFormSchema } from "../config/interfaces.config"; import type { ZodObject, ZodRawShape } from "zod"; +import { TextField } from "../components/TextField"; const PAYMENT_METHODS = ["bar", "paypal", "andere"] as const; const PAYMENT_LABELS: Record = { @@ -252,100 +253,64 @@ export const MainForm = () => { name="firstName" validators={makeFieldValidator("firstName")} > - {(field) => { - const errors = getErrors(field); - return ( - - {t("first-name")} - field.handleChange(e.target.value)} - variant="soft" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - - {errors[0]} - - )} - - ); - }} + {(field) => ( + + )} - {(field) => { - const errors = getErrors(field); - return ( - - {t("last-name")} - field.handleChange(e.target.value)} - variant="soft" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - - {errors[0]} - - )} - - ); - }} + {(field) => ( + + )} - {(field) => { - const errors = getErrors(field); - return ( - - {t("email")} - field.handleChange(e.target.value)} - variant="soft" - type="email" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - {errors[0]} - )} - - ); - }} + {(field) => ( + + )} - {(field) => { - const errors = getErrors(field); - return ( - - {t("phone-number")} - field.handleChange(e.target.value)} - variant="soft" - type="tel" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - {errors[0]} - )} - - ); - }} + {(field) => ( + + )} {/* Tickets + Invoice toggle */} @@ -414,26 +379,16 @@ export const MainForm = () => { name="companyName" validators={makeFieldValidator("companyName")} > - {(field) => { - const errors = getErrors(field); - return ( - - {t("company-name")} - field.handleChange(e.target.value)} - variant="soft" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - - {errors[0]} - - )} - - ); - }} + {(field) => ( + + )}
@@ -441,156 +396,96 @@ export const MainForm = () => { name="cmpFirstName" validators={makeFieldValidator("cmpFirstName")} > - {(field) => { - const errors = getErrors(field); - return ( - - {t("first-name")} - field.handleChange(e.target.value)} - variant="soft" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - - {errors[0]} - - )} - - ); - }} + {(field) => ( + + )} - {(field) => { - const errors = getErrors(field); - return ( - - {t("last-name")} - field.handleChange(e.target.value)} - variant="soft" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - - {errors[0]} - - )} - - ); - }} + {(field) => ( + + )}
- {(field) => { - const errors = getErrors(field); - return ( - - {t("street")} - field.handleChange(e.target.value)} - variant="soft" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - - {errors[0]} - - )} - - ); - }} + {(field) => ( + + )} - {(field) => { - const errors = getErrors(field); - return ( - - {t("postal-code")} - field.handleChange(e.target.value)} - variant="soft" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - - {errors[0]} - - )} - - ); - }} + {(field) => ( + + )} - {(field) => { - const errors = getErrors(field); - return ( - - {t("phone-number")} - field.handleChange(e.target.value)} - variant="soft" - type="tel" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - - {errors[0]} - - )} - - ); - }} + {(field) => ( + + )} - {(field) => { - const errors = getErrors(field); - return ( - - {t("email")} - field.handleChange(e.target.value)} - variant="soft" - type="email" - sx={{ borderRadius: "10px" }} - /> - {errors.length > 0 && ( - - {errors[0]} - - )} - - ); - }} + {(field) => ( + + )} )} diff --git a/frontend/src/utils/i18n/locales/en/en.json b/frontend/src/utils/i18n/locales/en/en.json index a5e09fb..24f669e 100644 --- a/frontend/src/utils/i18n/locales/en/en.json +++ b/frontend/src/utils/i18n/locales/en/en.json @@ -33,6 +33,6 @@ "set-username-headline": "No user selected", "set-username-text": "To start the ticket sale, you must select a user first from the top left.", "name-error": "You have to enter a name!", - "email-error": "You have to enter a valid e-mail Adress!", + "email-error": "You have to enter a valid E-Mail adress!", "phone-error": "You have to enter a vaild phone number!" } \ No newline at end of file