refactor: update FormInput and FormSelect components to accept props directly; add FieldsWrapper for improved layout
This commit is contained in:
parent
abad63787b
commit
bb108f809f
12
src/components/FieldsWrapper.jsx
Normal file
12
src/components/FieldsWrapper.jsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
function FieldsWrapper({ children, className = "" }) {
|
||||||
|
return <div className={`flex flex-col gap-4 m-2 my-7 ${className}`}>{children}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldsWrapper.propTypes = {
|
||||||
|
children: PropTypes.node,
|
||||||
|
className: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FieldsWrapper;
|
@ -1,7 +1,7 @@
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
function FormHeader({ text }) {
|
function FormHeader({ text }) {
|
||||||
return <h1 className="text-2xl font-medium text-primary py-2">{text}</h1>;
|
return <h1 className="text-2xl font-medium text-primary mt-5">{text}</h1>;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormHeader.propTypes = {
|
FormHeader.propTypes = {
|
||||||
|
@ -2,29 +2,15 @@ import PropTypes from "prop-types";
|
|||||||
import { motion, AnimatePresence } from "motion/react";
|
import { motion, AnimatePresence } from "motion/react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
function FormInput({
|
function FormInput({ props, valid = true, className = "" }) {
|
||||||
value,
|
|
||||||
onChange,
|
|
||||||
placeholder,
|
|
||||||
valid = true,
|
|
||||||
maxLength = 17,
|
|
||||||
readOnly = false,
|
|
||||||
className = "",
|
|
||||||
type = "text",
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
readOnly={readOnly}
|
{...props}
|
||||||
value={value}
|
|
||||||
className={clsx(
|
className={clsx(
|
||||||
`w-72 h-10 px-2 rounded-full dark:bg-white dark:text-grey border-2 text-grey focus:outline-grey ${className}`,
|
`w-72 h-10 px-2 rounded-full dark:bg-white dark:text-grey border-2 text-grey focus:outline-grey ${className}`,
|
||||||
!valid && "border-error"
|
!valid && "border-error"
|
||||||
)}
|
)}
|
||||||
onChange={onChange}
|
|
||||||
type={type}
|
|
||||||
maxLength={maxLength}
|
|
||||||
placeholder={placeholder}
|
|
||||||
/>
|
/>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{!valid && (
|
{!valid && (
|
||||||
@ -44,14 +30,9 @@ function FormInput({
|
|||||||
}
|
}
|
||||||
|
|
||||||
FormInput.propTypes = {
|
FormInput.propTypes = {
|
||||||
value: PropTypes.string.isRequired,
|
props: PropTypes.object,
|
||||||
onChange: PropTypes.func.isRequired,
|
|
||||||
readOnly: PropTypes.bool,
|
|
||||||
className: PropTypes.string,
|
|
||||||
type: PropTypes.string,
|
|
||||||
maxLength: PropTypes.number,
|
|
||||||
valid: PropTypes.bool,
|
valid: PropTypes.bool,
|
||||||
placeholder: PropTypes.string,
|
className: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FormInput;
|
export default FormInput;
|
||||||
|
@ -3,21 +3,20 @@ import { AnimatePresence } from "motion/react";
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import FieldError from "./FieldError";
|
import FieldError from "./FieldError";
|
||||||
|
|
||||||
function FormSelect({ value, onChange, options, className, valid = true }) {
|
function FormSelect({ props, valid = true, className = "", options }) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
value={value}
|
{...props}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
`w-72 h-10 px-2 rounded-full dark:bg-white dark:text-grey border-2 text-grey focus:outline-grey ${className}`,
|
`w-72 h-10 px-2 rounded-full dark:bg-white dark:text-grey border-2 text-grey focus:outline-grey ${className}`,
|
||||||
!valid && "border-error"
|
!valid && "border-error"
|
||||||
)}
|
)}
|
||||||
onChange={onChange}
|
|
||||||
>
|
>
|
||||||
<option disabled value="">
|
<option disabled value="">
|
||||||
Select
|
Select
|
||||||
</option>
|
</option>
|
||||||
{options.map(({ value, label }) => (
|
{options?.map(({ value, label }) => (
|
||||||
<option key={value} value={value}>
|
<option key={value} value={value}>
|
||||||
{label}
|
{label}
|
||||||
</option>
|
</option>
|
||||||
@ -31,8 +30,7 @@ function FormSelect({ value, onChange, options, className, valid = true }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FormSelect.propTypes = {
|
FormSelect.propTypes = {
|
||||||
value: PropTypes.string.isRequired,
|
props: PropTypes.object,
|
||||||
onChange: PropTypes.func.isRequired,
|
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
valid: PropTypes.bool,
|
valid: PropTypes.bool,
|
||||||
options: PropTypes.arrayOf(
|
options: PropTypes.arrayOf(
|
||||||
|
@ -11,6 +11,7 @@ import productInfo from "../util/productList";
|
|||||||
import Notification from "../components/Notification";
|
import Notification from "../components/Notification";
|
||||||
import ProductModal from "../components/ProductModal";
|
import ProductModal from "../components/ProductModal";
|
||||||
import FormHeader from "../components/FormHeader";
|
import FormHeader from "../components/FormHeader";
|
||||||
|
import FieldsWrapper from "../components/FieldsWrapper";
|
||||||
|
|
||||||
function AccountCreation() {
|
function AccountCreation() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -182,7 +183,6 @@ function AccountCreation() {
|
|||||||
const renderField = (field) => {
|
const renderField = (field) => {
|
||||||
const commonProps = {
|
const commonProps = {
|
||||||
value: accountDetails[field.name],
|
value: accountDetails[field.name],
|
||||||
valid: accountDetails[`${field.name}Valid`],
|
|
||||||
onChange: (e) => {
|
onChange: (e) => {
|
||||||
const newAccountDetails = { ...accountDetails };
|
const newAccountDetails = { ...accountDetails };
|
||||||
newAccountDetails[field.name] = e.target.value;
|
newAccountDetails[field.name] = e.target.value;
|
||||||
@ -190,18 +190,21 @@ function AccountCreation() {
|
|||||||
setAccountDetails(newAccountDetails);
|
setAccountDetails(newAccountDetails);
|
||||||
},
|
},
|
||||||
maxLength: field.maxLength,
|
maxLength: field.maxLength,
|
||||||
|
type: field.subType,
|
||||||
|
readOnly: field.readOnly,
|
||||||
};
|
};
|
||||||
|
const valid = accountDetails[`${field.name}Valid`];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === "input" ? (
|
||||||
<FormInput
|
<FormInput props={commonProps} valid={valid} />
|
||||||
{...commonProps}
|
|
||||||
type={field.subType}
|
|
||||||
readOnly={field.readOnly}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<FormSelect {...commonProps} options={field.options} />
|
<FormSelect
|
||||||
|
props={commonProps}
|
||||||
|
valid={valid}
|
||||||
|
options={field.options}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
@ -222,20 +225,15 @@ function AccountCreation() {
|
|||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
||||||
<FormBox title="Account Creation" >
|
<FormBox title="Account Creation">
|
||||||
<div className="p-2 pt-7 ">
|
<FieldsWrapper>
|
||||||
<div className="flex flex-col gap-4">
|
<FormHeader text={"Account Details"} />
|
||||||
<FormHeader text={"Account Details"}/>
|
{accountDetailsFields.map(renderField)}
|
||||||
{accountDetailsFields.map(renderField)}
|
<FormHeader text={"Additional Details"} />
|
||||||
</div>
|
{additionalDetailsFields.map(renderField)}
|
||||||
<div className="flex flex-col gap-4">
|
</FieldsWrapper>
|
||||||
<FormHeader text={"Additional Details"}/>
|
|
||||||
{additionalDetailsFields.map(renderField)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Button text={t("submit")} onClick={handleSubmit} />
|
<Button text={t("submit")} onClick={handleSubmit} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import { lockerService } from "../services/locker.service";
|
|||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from "motion/react";
|
||||||
import { Pencil } from "lucide-react";
|
import { Pencil } from "lucide-react";
|
||||||
import Notification from "../components/Notification";
|
import Notification from "../components/Notification";
|
||||||
|
import FieldsWrapper from "../components/FieldsWrapper";
|
||||||
|
|
||||||
function ChargeEdit() {
|
function ChargeEdit() {
|
||||||
const [chargeDetails, setChargeDetails] = useState({
|
const [chargeDetails, setChargeDetails] = useState({
|
||||||
@ -141,18 +142,20 @@ function ChargeEdit() {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
readOnly: field.readOnly,
|
readOnly: field.readOnly,
|
||||||
className: field.readOnly ? "bg-grey/[0.3]" : "",
|
|
||||||
|
type: field.subType,
|
||||||
};
|
};
|
||||||
|
const className = field.readOnly ? "bg-grey/[0.3]" : "";
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === "input" ? (
|
||||||
<FormInput
|
<FormInput props={commonProps} className={className} />
|
||||||
{...commonProps}
|
|
||||||
type={field.subType}
|
|
||||||
readOnly={field.readOnly}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<FormSelect {...commonProps} options={field.options} />
|
<FormSelect
|
||||||
|
props={commonProps}
|
||||||
|
options={field.options}
|
||||||
|
className={className}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
@ -168,9 +171,7 @@ function ChargeEdit() {
|
|||||||
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
||||||
)}
|
)}
|
||||||
<FormBox title={t("chargeEdit")}>
|
<FormBox title={t("chargeEdit")}>
|
||||||
<div className="p-2 pt-7 flex flex-col gap-4">
|
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
||||||
{formFields.map(renderField)}
|
|
||||||
</div>
|
|
||||||
<Button
|
<Button
|
||||||
text={t("submit")}
|
text={t("submit")}
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import clsx from "clsx";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import FormField from "../components/FormField";
|
import FormField from "../components/FormField";
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from "../components/FormInput";
|
||||||
@ -8,6 +7,7 @@ import FormBox from "../components/FormBox";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useToast } from "../hooks/useToast";
|
import { useToast } from "../hooks/useToast";
|
||||||
|
import FieldsWrapper from "../components/FieldsWrapper";
|
||||||
|
|
||||||
function ChargeManagement() {
|
function ChargeManagement() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -83,19 +83,19 @@ function ChargeManagement() {
|
|||||||
setProductDetails(newLockerDetails);
|
setProductDetails(newLockerDetails);
|
||||||
},
|
},
|
||||||
maxLength: field.maxLength,
|
maxLength: field.maxLength,
|
||||||
className: clsx(!productDetails[`${field.name}Valid`] && "border-error"),
|
type: field.subType,
|
||||||
|
readOnly: field.readOnly,
|
||||||
};
|
};
|
||||||
|
const valid = productDetails[`${field.name}Valid`];
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === "input" ? (
|
||||||
<FormInput
|
<FormInput
|
||||||
{...commonProps}
|
props={commonProps}
|
||||||
type={field.subType}
|
valid={valid}
|
||||||
readOnly={field.readOnly}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<FormSelect {...commonProps} options={field.options} />
|
<FormSelect props={commonProps} valid={valid} options={field.options} />
|
||||||
)}
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
@ -103,9 +103,9 @@ function ChargeManagement() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FormBox title={t("chargeManagement")}>
|
<FormBox title={t("chargeManagement")}>
|
||||||
<div className="p-2 pt-7 flex flex-col gap-4">
|
<FieldsWrapper>
|
||||||
{formFields.map(renderField)}
|
{formFields.map(renderField)}
|
||||||
</div>
|
</FieldsWrapper>
|
||||||
<Button text={t("submit")} onClick={handleSubmit} />
|
<Button text={t("submit")} onClick={handleSubmit} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
);
|
);
|
||||||
|
@ -10,6 +10,7 @@ import { useToast } from "../hooks/useToast";
|
|||||||
import { lockerService } from "../services/locker.service";
|
import { lockerService } from "../services/locker.service";
|
||||||
import { useLoading } from "../hooks/useLoading";
|
import { useLoading } from "../hooks/useLoading";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import FieldsWrapper from "../components/FieldsWrapper";
|
||||||
|
|
||||||
function CheckInOutManagement() {
|
function CheckInOutManagement() {
|
||||||
const [accountNumber, setAccountNumber] = useState("");
|
const [accountNumber, setAccountNumber] = useState("");
|
||||||
@ -66,18 +67,20 @@ function CheckInOutManagement() {
|
|||||||
{notification.visible && <Notification notification={notification} />}
|
{notification.visible && <Notification notification={notification} />}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
<FormBox title="Check In/Out">
|
<FormBox title="Check In/Out">
|
||||||
<div className="p-2 pt-7">
|
<FieldsWrapper>
|
||||||
<FormField
|
<FormField
|
||||||
label="Account Number"
|
label="Account Number"
|
||||||
icon={{ icon: <Search size={17} />, onClick: () => {} }}
|
icon={{ icon: <Search size={17} />, onClick: () => {} }}
|
||||||
>
|
>
|
||||||
<FormInput
|
<FormInput
|
||||||
type="text"
|
props={{
|
||||||
value={accountNumber}
|
type: "text",
|
||||||
onChange={(e) => setAccountNumber(e.target.value)}
|
value: accountNumber,
|
||||||
|
onChange: (e) => setAccountNumber(e.target.value),
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</FormField>
|
</FormField>
|
||||||
</div>
|
</FieldsWrapper>
|
||||||
<Button text="Next" onClick={handleNext} />
|
<Button text="Next" onClick={handleNext} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,9 +8,9 @@ import FormInput from "../components/FormInput";
|
|||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from "../components/FormSelect";
|
||||||
import Button from "../components/Button";
|
import Button from "../components/Button";
|
||||||
import { lockerService } from "../services/locker.service";
|
import { lockerService } from "../services/locker.service";
|
||||||
import clsx from "clsx";
|
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from "../components/FormBox";
|
||||||
import Notification from "../components/Notification";
|
import Notification from "../components/Notification";
|
||||||
|
import FieldsWrapper from "../components/FieldsWrapper";
|
||||||
|
|
||||||
function KeySwap() {
|
function KeySwap() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -142,19 +142,20 @@ function KeySwap() {
|
|||||||
setKeySwapDetails(newLockerDetails);
|
setKeySwapDetails(newLockerDetails);
|
||||||
},
|
},
|
||||||
maxLength: field.maxLength,
|
maxLength: field.maxLength,
|
||||||
className: clsx(!keySwapDetails[`${field.name}Valid`] && "border-error"),
|
type: field.subType,
|
||||||
|
readOnly: field.readOnly,
|
||||||
};
|
};
|
||||||
|
const valid = keySwapDetails[`${field.name}Valid`];
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === "input" ? (
|
||||||
<FormInput
|
<FormInput props={commonProps} valid={valid} />
|
||||||
{...commonProps}
|
|
||||||
type={field.subType}
|
|
||||||
readOnly={field.readOnly}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<FormSelect {...commonProps} options={field.options} />
|
<FormSelect
|
||||||
|
props={commonProps}
|
||||||
|
valid={valid}
|
||||||
|
options={field.options}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
@ -170,9 +171,7 @@ function KeySwap() {
|
|||||||
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
||||||
)}
|
)}
|
||||||
<FormBox title={t("lockerStatus")}>
|
<FormBox title={t("lockerStatus")}>
|
||||||
<div className="p-2 pt-7 flex flex-col gap-4">
|
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
||||||
{formFields.map(renderField)}
|
|
||||||
</div>
|
|
||||||
<Button text={t("submit")} onClick={handleKeySwap} />
|
<Button text={t("submit")} onClick={handleKeySwap} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,12 +4,12 @@ import FormInput from "../components/FormInput";
|
|||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from "../components/FormSelect";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import clsx from "clsx";
|
|
||||||
import Button from "../components/Button";
|
import Button from "../components/Button";
|
||||||
import { lockerService } from "../services/locker.service";
|
import { lockerService } from "../services/locker.service";
|
||||||
import { useLoading } from "../hooks/useLoading";
|
import { useLoading } from "../hooks/useLoading";
|
||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from "motion/react";
|
||||||
import Notification from "../components/Notification";
|
import Notification from "../components/Notification";
|
||||||
|
import FieldsWrapper from "../components/FieldsWrapper";
|
||||||
|
|
||||||
function LockerStatus() {
|
function LockerStatus() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -98,7 +98,6 @@ function LockerStatus() {
|
|||||||
const renderField = (field) => {
|
const renderField = (field) => {
|
||||||
const commonProps = {
|
const commonProps = {
|
||||||
value: lockerDetails[field.name],
|
value: lockerDetails[field.name],
|
||||||
valid: lockerDetails[`${field.name}Valid`],
|
|
||||||
onChange: (e) => {
|
onChange: (e) => {
|
||||||
const newLockerDetails = { ...lockerDetails };
|
const newLockerDetails = { ...lockerDetails };
|
||||||
newLockerDetails[field.name] = e.target.value.toUpperCase();
|
newLockerDetails[field.name] = e.target.value.toUpperCase();
|
||||||
@ -106,19 +105,16 @@ function LockerStatus() {
|
|||||||
setLockerDetails(newLockerDetails);
|
setLockerDetails(newLockerDetails);
|
||||||
},
|
},
|
||||||
maxLength: field.maxLength,
|
maxLength: field.maxLength,
|
||||||
className: clsx(!lockerDetails[`${field.name}Valid`] && "border-error"),
|
type: field.subType,
|
||||||
|
readOnly: field.readOnly,
|
||||||
};
|
};
|
||||||
|
const valid = lockerDetails[`${field.name}Valid`];
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === "input" ? (
|
||||||
<FormInput
|
<FormInput props={commonProps} valid={valid} />
|
||||||
{...commonProps}
|
|
||||||
type={field.subType}
|
|
||||||
readOnly={field.readOnly}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<FormSelect {...commonProps} options={field.options} />
|
<FormSelect props={commonProps} options={field.options} />
|
||||||
)}
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
@ -134,9 +130,9 @@ function LockerStatus() {
|
|||||||
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
||||||
)}
|
)}
|
||||||
<FormBox title={t("lockerStatus")}>
|
<FormBox title={t("lockerStatus")}>
|
||||||
<div className="p-2 pt-7 flex flex-col gap-4">
|
<FieldsWrapper>
|
||||||
{formFields.map(renderField)}
|
{formFields.map(renderField)}
|
||||||
</div>
|
</FieldsWrapper>
|
||||||
<Button text={t("submit")} onClick={handleSubmit} />
|
<Button text={t("submit")} onClick={handleSubmit} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,6 +9,8 @@ import Notification from "../components/Notification";
|
|||||||
import FormField from "../components/FormField";
|
import FormField from "../components/FormField";
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from "../components/FormInput";
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from "../components/FormSelect";
|
||||||
|
import FormHeader from "../components/FormHeader";
|
||||||
|
import FieldsWrapper from "../components/FieldsWrapper";
|
||||||
|
|
||||||
function LockersRegistration() {
|
function LockersRegistration() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@ -116,49 +118,65 @@ function LockersRegistration() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const lockerDetails = lockerValues.map((locker, index) => {
|
const formRow = [
|
||||||
|
{
|
||||||
|
label: "Locker ID",
|
||||||
|
type: "input",
|
||||||
|
subType: "text",
|
||||||
|
name: "id",
|
||||||
|
maxLength: 6,
|
||||||
|
validate: (value) => /^[A-Z]{2}[0-9]{4}$/.test(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Size",
|
||||||
|
type: "select",
|
||||||
|
subType: "text",
|
||||||
|
name: "size",
|
||||||
|
options: [
|
||||||
|
{ label: "Small", value: "1" },
|
||||||
|
{ label: "Medium", value: "2" },
|
||||||
|
{ label: "Large", value: "3" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Key ID",
|
||||||
|
type: "input",
|
||||||
|
subType: "text",
|
||||||
|
name: "keyId",
|
||||||
|
maxLength: 6,
|
||||||
|
validate: (value) => /^[A-Z]{2}[0-9]{4}$/.test(value),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const renderFormRow = (field) => {
|
||||||
|
const commonProps = {
|
||||||
|
value: lockerValues[field.name],
|
||||||
|
onChange: (e) => {
|
||||||
|
const newLockerValues = [...lockerValues];
|
||||||
|
newLockerValues[field.name] = e.target.value;
|
||||||
|
newLockerValues[`${field.name}Valid`] = true;
|
||||||
|
setLockerValues(newLockerValues);
|
||||||
|
},
|
||||||
|
maxLength: field.maxLength,
|
||||||
|
type: field.subType,
|
||||||
|
};
|
||||||
|
|
||||||
|
const valid = lockerValues[`${field.name}Valid`];
|
||||||
|
|
||||||
|
return field.type === "input" ? (
|
||||||
|
<FormInput props={commonProps} valid={valid} />
|
||||||
|
) : (
|
||||||
|
<FormSelect props={commonProps} valid={valid} options={field.options} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const formFields = Array(noOfLockers).fill(formRow);
|
||||||
|
const renderFormFields = (row, index) => {
|
||||||
return (
|
return (
|
||||||
<FormField key={index} label={`Locker ${index + 1}`} variant="long">
|
<FormField key={index} label={`Locker ${index + 1}`} variant="long">
|
||||||
<FormInput
|
{row.map(renderFormRow)}
|
||||||
value={locker.id}
|
|
||||||
onChange={ e => {
|
|
||||||
const newValues = [...lockerValues];
|
|
||||||
newValues[index].id = e.target.value;
|
|
||||||
newValues[index].idValid = true;
|
|
||||||
setLockerValues(newValues);
|
|
||||||
}}
|
|
||||||
valid={locker.idValid}
|
|
||||||
placeholder={"Locker Id"}
|
|
||||||
/>
|
|
||||||
<FormSelect
|
|
||||||
value={locker.size}
|
|
||||||
onChange={e => {
|
|
||||||
const newValues = [...lockerValues];
|
|
||||||
newValues[index].size = e.target.value;
|
|
||||||
newValues[index].sizeValid = true;
|
|
||||||
setLockerValues(newValues);
|
|
||||||
}}
|
|
||||||
valid={locker.sizeValid}
|
|
||||||
options={[
|
|
||||||
{label: 'Small', value: '1'},
|
|
||||||
{label: 'Medium', value: '2'},
|
|
||||||
{label: 'Large', value: '3'}
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
value={locker.keyId}
|
|
||||||
onChange={ e => {
|
|
||||||
const newValues = [...lockerValues];
|
|
||||||
newValues[index].keyId = e.target.value;
|
|
||||||
newValues[index].keyIdValid = true;
|
|
||||||
setLockerValues(newValues);
|
|
||||||
}}
|
|
||||||
valid={locker.keyIdValid}
|
|
||||||
placeholder={"Locker Key Id"}
|
|
||||||
/>
|
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
});
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -170,16 +188,11 @@ function LockersRegistration() {
|
|||||||
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
||||||
)}
|
)}
|
||||||
<FormBox title="Locker Registration">
|
<FormBox title="Locker Registration">
|
||||||
<div className="px-4 pt-7 text-2xl font-bold text-primary dark:text-primary-dark">
|
<FormHeader text={cabinetId} />
|
||||||
{cabinetId}
|
<FieldsWrapper className="">
|
||||||
</div>
|
{formFields.map(renderFormFields)}
|
||||||
<div className="flex flex-col gap-4 p-4">{lockerDetails}</div>
|
</FieldsWrapper>
|
||||||
<Button
|
<Button text="Register" onClick={handleSubmit} />
|
||||||
text="Register"
|
|
||||||
onClick={(e) => {
|
|
||||||
handleSubmit(e);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user