Add locker service methods for status change and key swap; create LockerMaintenance and LockerStatus components with form validation and translations
This commit is contained in:
parent
8cee8e0383
commit
9d72dc6868
@ -66,5 +66,17 @@
|
|||||||
"customerType": "Customer Type",
|
"customerType": "Customer Type",
|
||||||
"collateralFDAccount": "Collateral FD Account",
|
"collateralFDAccount": "Collateral FD Account",
|
||||||
"rentPayAccount": "Rent Pay Account",
|
"rentPayAccount": "Rent Pay Account",
|
||||||
"submit": "Submit"
|
"submit": "Submit",
|
||||||
|
"lockerId": "Locker ID",
|
||||||
|
"status": "Status",
|
||||||
|
"lockerStatus": "Locker Status",
|
||||||
|
"open": "Open",
|
||||||
|
"close": "Close",
|
||||||
|
"reasonForChange": "Reason for Change",
|
||||||
|
"oldKeyId": "Old Key ID",
|
||||||
|
"newKeyId": "New Key ID",
|
||||||
|
"confirmNewKeyId": "Confirm New Key ID",
|
||||||
|
"highlightedFieldsInvalid": "Highlighted fields are invalid",
|
||||||
|
"changeStatus": "Change Status",
|
||||||
|
"keySwap": "Key Swap"
|
||||||
}
|
}
|
@ -26,11 +26,10 @@ function Header() {
|
|||||||
submenu: [
|
submenu: [
|
||||||
{ name: "accountCreation", path: "operation/account" },
|
{ name: "accountCreation", path: "operation/account" },
|
||||||
{ name: "cabinetMaintenance", path: "operation/cabinet" },
|
{ name: "cabinetMaintenance", path: "operation/cabinet" },
|
||||||
{ name: "lockerMaintenance", path: "locker-maintenance" },
|
{ name: "lockerMaintenance", path: "operation/locker" },
|
||||||
{ name: "rentPenaltyCollection", path: "rent-collection" },
|
{ name: "chargeManagement", path: "operation/charge-management" },
|
||||||
{ name: "chargeManagement", path: "charge-management" },
|
{ name: "checkInOutManagement", path: "operation/check-in-out" },
|
||||||
{ name: "checkInOutManagement", path: "check-in-out" },
|
{ name: "accountSurrender", path: "operation/account-surrender" }
|
||||||
{ name: "accountSurrender", path: "account-surrender" }
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ name: "worklist", submenu: [{ name: "myIntimation", path: "my-intimation" }] },
|
{ name: "worklist", submenu: [{ name: "myIntimation", path: "my-intimation" }] },
|
||||||
|
15
src/main.jsx
15
src/main.jsx
@ -9,6 +9,9 @@ import CabinetMaintenace from "./pages/CabinetMaintenance.jsx";
|
|||||||
import CabinetCreation from "./pages/CabinetCreation.jsx";
|
import CabinetCreation from "./pages/CabinetCreation.jsx";
|
||||||
import LockersRegistration from "./pages/LockersRegistration.jsx";
|
import LockersRegistration from "./pages/LockersRegistration.jsx";
|
||||||
import AccountCreation from "./pages/AccountCreation.jsx";
|
import AccountCreation from "./pages/AccountCreation.jsx";
|
||||||
|
import LockerMaintenance from "./pages/LockerMaintenance.jsx";
|
||||||
|
import LockerStatus from "./pages/LockerStatus.jsx";
|
||||||
|
import KeySwap from "./pages/KeySwap.jsx";
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
@ -34,6 +37,18 @@ const router = createBrowserRouter([
|
|||||||
{
|
{
|
||||||
path: "operation/account",
|
path: "operation/account",
|
||||||
element: <AccountCreation />,
|
element: <AccountCreation />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "operation/locker",
|
||||||
|
element: <LockerMaintenance />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "operation/locker/status",
|
||||||
|
element: <LockerStatus />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "operation/locker/key-swap",
|
||||||
|
element: <KeySwap />,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
219
src/pages/KeySwap.jsx
Normal file
219
src/pages/KeySwap.jsx
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { motion, AnimatePresence } from "motion/react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useToast } from "../hooks/useToast";
|
||||||
|
import { useLoading } from "../hooks/useLoading";
|
||||||
|
import FormField from "../components/FormField";
|
||||||
|
import FormInput from "../components/FormInput";
|
||||||
|
import FormSelect from "../components/FormSelect";
|
||||||
|
import Button from "../components/Button";
|
||||||
|
import { lockerService } from "../services/locker.service";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import FormBox from "../components/FormBox";
|
||||||
|
import { Copy } from "lucide-react";
|
||||||
|
|
||||||
|
function KeySwap() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const showToast = useToast();
|
||||||
|
const { isLoading, setIsLoading } = useLoading();
|
||||||
|
const [notification, setNotification] = useState({
|
||||||
|
visible: false,
|
||||||
|
message: "",
|
||||||
|
type: "",
|
||||||
|
});
|
||||||
|
const [keySwapDetails, setKeySwapDetails] = useState({
|
||||||
|
cabinetId: "",
|
||||||
|
lockerId: "",
|
||||||
|
reason: "",
|
||||||
|
oldKey: "",
|
||||||
|
newKey: "",
|
||||||
|
newKeyConfirm: "",
|
||||||
|
cabinetIdValid: true,
|
||||||
|
lockerIdValid: true,
|
||||||
|
reasonValid: true,
|
||||||
|
oldKeyValid: true,
|
||||||
|
newKeyValid: true,
|
||||||
|
newKeyConfirmValid: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const formFields = [
|
||||||
|
{
|
||||||
|
name: "cabinetId",
|
||||||
|
label: t("cabinetId"),
|
||||||
|
type: "input",
|
||||||
|
maxLength: 6,
|
||||||
|
readOnly: isLoading,
|
||||||
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lockerId",
|
||||||
|
label: t("lockerId"),
|
||||||
|
type: "input",
|
||||||
|
maxLength: 6,
|
||||||
|
readOnly: isLoading,
|
||||||
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "reason",
|
||||||
|
label: t("reasonForChange"),
|
||||||
|
type: "input",
|
||||||
|
maxLength: 50,
|
||||||
|
readOnly: isLoading,
|
||||||
|
validate: (value) => value !== "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "oldKey",
|
||||||
|
label: t("oldKeyId"),
|
||||||
|
type: "input",
|
||||||
|
maxLength: 6,
|
||||||
|
readOnly: isLoading,
|
||||||
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "newKey",
|
||||||
|
label: t("newKeyId"),
|
||||||
|
type: "input",
|
||||||
|
maxLength: 6,
|
||||||
|
readOnly: isLoading,
|
||||||
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "newKeyConfirm",
|
||||||
|
label: t("confirmNewKeyId"),
|
||||||
|
type: "input",
|
||||||
|
maxLength: 6,
|
||||||
|
readOnly: isLoading,
|
||||||
|
validate: (value) => value !== "" && value === keySwapDetails.newKey,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleKeySwap = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
let valid = true;
|
||||||
|
|
||||||
|
for (const field of formFields) {
|
||||||
|
if (!field.validate(keySwapDetails[field.name])) {
|
||||||
|
valid = false;
|
||||||
|
setKeySwapDetails((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[`${field.name}Valid`]: false,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
showToast(t("highlightedFieldsInvalid"), "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
const response = await lockerService.keySwap(
|
||||||
|
keySwapDetails.cabinetId,
|
||||||
|
keySwapDetails.lockerId,
|
||||||
|
keySwapDetails.reason,
|
||||||
|
keySwapDetails.oldKey,
|
||||||
|
keySwapDetails.newKey
|
||||||
|
);
|
||||||
|
if (response.status === 200) {
|
||||||
|
setNotification({
|
||||||
|
visible: true,
|
||||||
|
message: response.data.message,
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setNotification({
|
||||||
|
visible: true,
|
||||||
|
message: response.data.message,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setNotification({
|
||||||
|
visible: true,
|
||||||
|
message: error.message,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderField = (field) => {
|
||||||
|
const commonProps = {
|
||||||
|
value: keySwapDetails[field.name],
|
||||||
|
onChange: (e) => {
|
||||||
|
const newLockerDetails = { ...keySwapDetails };
|
||||||
|
newLockerDetails[field.name] = e.target.value.toUpperCase();
|
||||||
|
newLockerDetails[`${field.name}Valid`] = true;
|
||||||
|
setKeySwapDetails(newLockerDetails);
|
||||||
|
},
|
||||||
|
maxLength: field.maxLength,
|
||||||
|
className: clsx(!keySwapDetails[`${field.name}Valid`] && "border-error"),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
|
{field.type === "input" ? (
|
||||||
|
<FormInput
|
||||||
|
{...commonProps}
|
||||||
|
type={field.subType}
|
||||||
|
readOnly={field.readOnly}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FormSelect {...commonProps} options={field.options} />
|
||||||
|
)}
|
||||||
|
</FormField>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<AnimatePresence>
|
||||||
|
{notification.visible && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
className={clsx(
|
||||||
|
"p-4 mb-8 font-body text-center text-xl rounded-2xl flex items-center justify-center gap-2",
|
||||||
|
notification.type === "error"
|
||||||
|
? "bg-error-surface text-error"
|
||||||
|
: "bg-success-surface text-success"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{notification.message.split(":").map((msg, index) => {
|
||||||
|
return index === 1 ? (
|
||||||
|
<span key={index} className="border-b border-dashed">
|
||||||
|
{msg}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span key={index}>{msg}</span>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
<Copy
|
||||||
|
cursor={"pointer"}
|
||||||
|
size={15}
|
||||||
|
onClick={navigator.clipboard.writeText(
|
||||||
|
notification.message.split(":")[1].trim()
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
<div className="relative">
|
||||||
|
{notification.type === "success" && (
|
||||||
|
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
||||||
|
)}
|
||||||
|
<FormBox title={t("lockerStatus")}>
|
||||||
|
<div className="p-2 pt-7 flex flex-col gap-4">
|
||||||
|
{formFields.map(renderField)}
|
||||||
|
</div>
|
||||||
|
<Button text={t("submit")} onClick={handleKeySwap} />
|
||||||
|
</FormBox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default KeySwap;
|
70
src/pages/LockerMaintenance.jsx
Normal file
70
src/pages/LockerMaintenance.jsx
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import FormBox from "../components/FormBox";
|
||||||
|
import Button from "../components/Button";
|
||||||
|
import { motion, AnimatePresence } from "motion/react";
|
||||||
|
import clsx from "clsx";
|
||||||
|
|
||||||
|
function LockerMaintenance() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [operation, setOperation] = useState({ value: "", valid: true });
|
||||||
|
|
||||||
|
const handleNext = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (operation.value === "") {
|
||||||
|
setOperation({ value: operation.value, valid: false });
|
||||||
|
}
|
||||||
|
navigate(operation.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormBox title={t("cabinetMaintenance")}>
|
||||||
|
<div className="p-2 pt-7">
|
||||||
|
<div className="flex">
|
||||||
|
<label className="mr-4 text-lg text-black dark:text-primary-dark w-[10%]">
|
||||||
|
{t("operation")}
|
||||||
|
</label>
|
||||||
|
<div className="w-full">
|
||||||
|
<select
|
||||||
|
className={clsx(
|
||||||
|
"w-1/5 h-10 px-2 rounded-full dark:bg-grey dark:text-primary-dark border-2 focus:outline-grey border-grey",
|
||||||
|
!operation.valid && "border-error"
|
||||||
|
)}
|
||||||
|
onChange={(e) =>
|
||||||
|
setOperation({ value: e.target.value, valid: true })
|
||||||
|
}
|
||||||
|
defaultValue={operation.value}
|
||||||
|
value={operation.value}
|
||||||
|
>
|
||||||
|
<option value="" disabled>
|
||||||
|
{t("select")}
|
||||||
|
</option>
|
||||||
|
<option value="status">{t("changeStatus")}</option>
|
||||||
|
<option value="key-swap">{t("keySwap")}</option>
|
||||||
|
</select>
|
||||||
|
<AnimatePresence initial={false}>
|
||||||
|
{!operation.valid && (
|
||||||
|
<motion.div
|
||||||
|
className="w-1/5 text-sm text-error ml-3 pt-1"
|
||||||
|
initial={{ opacity: 0, scale: 0 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
exit={{ opacity: 0, scale: 0 }}
|
||||||
|
key="cabinetIdError"
|
||||||
|
>
|
||||||
|
Invalid Operation
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button text={t("next")} onClick={(e) => handleNext(e)} />
|
||||||
|
</FormBox>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LockerMaintenance;
|
164
src/pages/LockerStatus.jsx
Normal file
164
src/pages/LockerStatus.jsx
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
import FormBox from "../components/FormBox";
|
||||||
|
import FormField from "../components/FormField";
|
||||||
|
import FormInput from "../components/FormInput";
|
||||||
|
import FormSelect from "../components/FormSelect";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useToast } from "../hooks/useToast";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import Button from "../components/Button";
|
||||||
|
import { lockerService } from "../services/locker.service";
|
||||||
|
import { useLoading } from "../hooks/useLoading";
|
||||||
|
import { AnimatePresence, motion } from "motion/react";
|
||||||
|
|
||||||
|
function LockerStatus() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const showToast = useToast();
|
||||||
|
const [lockerDetails, setLockerDetails] = useState({
|
||||||
|
cabinetId: "",
|
||||||
|
lockerId: "",
|
||||||
|
status: "",
|
||||||
|
cabinetIdValid: true,
|
||||||
|
lockerIdValid: true,
|
||||||
|
statusValid: true,
|
||||||
|
});
|
||||||
|
const { isLoading, setIsLoading } = useLoading();
|
||||||
|
const [notification, setNotification] = useState({
|
||||||
|
visible: false,
|
||||||
|
message: "",
|
||||||
|
type: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const formFields = [
|
||||||
|
{
|
||||||
|
name: "cabinetId",
|
||||||
|
label: t("cabinetId"),
|
||||||
|
type: "input",
|
||||||
|
maxLength: 6,
|
||||||
|
readOnly: isLoading,
|
||||||
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lockerId",
|
||||||
|
label: t("lockerId"),
|
||||||
|
type: "input",
|
||||||
|
maxLength: 6,
|
||||||
|
readOnly: isLoading,
|
||||||
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "status",
|
||||||
|
label: t("status"),
|
||||||
|
type: "select",
|
||||||
|
readOnly: isLoading,
|
||||||
|
options: [
|
||||||
|
{ value: "open", label: t("open") },
|
||||||
|
{ value: "close", label: t("close") },
|
||||||
|
],
|
||||||
|
validate: (value) => value !== "",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
let isValid = true;
|
||||||
|
const newValidationState = { ...lockerDetails };
|
||||||
|
|
||||||
|
// Validate account details fields
|
||||||
|
formFields.forEach((field) => {
|
||||||
|
if (field.validate) {
|
||||||
|
const fieldIsValid = field.validate(lockerDetails[field.name]);
|
||||||
|
newValidationState[`${field.name}Valid`] = fieldIsValid;
|
||||||
|
if (!fieldIsValid) isValid = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setLockerDetails(newValidationState);
|
||||||
|
|
||||||
|
if (!isValid) {
|
||||||
|
showToast("Highlighted fields are invalid", "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await lockerService.changeLockerStatus(
|
||||||
|
lockerDetails.cabinetId,
|
||||||
|
lockerDetails.lockerId,
|
||||||
|
lockerDetails.status
|
||||||
|
);
|
||||||
|
setNotification({
|
||||||
|
visible: true,
|
||||||
|
message: response.data.message,
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
showToast(error.response.data.message, "error");
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderField = (field) => {
|
||||||
|
const commonProps = {
|
||||||
|
value: lockerDetails[field.name],
|
||||||
|
onChange: (e) => {
|
||||||
|
const newLockerDetails = { ...lockerDetails };
|
||||||
|
newLockerDetails[field.name] = e.target.value.toUpperCase();
|
||||||
|
newLockerDetails[`${field.name}Valid`] = true;
|
||||||
|
setLockerDetails(newLockerDetails);
|
||||||
|
},
|
||||||
|
maxLength: field.maxLength,
|
||||||
|
className: clsx(!lockerDetails[`${field.name}Valid`] && "border-error"),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
|
{field.type === "input" ? (
|
||||||
|
<FormInput
|
||||||
|
{...commonProps}
|
||||||
|
type={field.subType}
|
||||||
|
readOnly={field.readOnly}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FormSelect {...commonProps} options={field.options} />
|
||||||
|
)}
|
||||||
|
</FormField>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<AnimatePresence>
|
||||||
|
{notification.visible && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
className={clsx(
|
||||||
|
"p-4 mb-8 font-body text-center text-xl rounded-2xl flex items-center justify-center gap-2",
|
||||||
|
notification.type === "error"
|
||||||
|
? "bg-error-surface text-error"
|
||||||
|
: "bg-success-surface text-success"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{notification.message}
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
<div className="relative">
|
||||||
|
{notification.type === "success" && (
|
||||||
|
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
||||||
|
)}
|
||||||
|
<FormBox title={t("lockerStatus")}>
|
||||||
|
<div className="p-2 pt-7 flex flex-col gap-4">
|
||||||
|
{formFields.map(renderField)}
|
||||||
|
</div>
|
||||||
|
<Button text={t("submit")} onClick={handleSubmit} />
|
||||||
|
</FormBox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LockerStatus;
|
@ -4,7 +4,7 @@ import clsx from "clsx";
|
|||||||
import FormBox from "../components/FormBox";
|
import FormBox from "../components/FormBox";
|
||||||
import Button from "../components/Button";
|
import Button from "../components/Button";
|
||||||
import { useToast } from "../hooks/useToast";
|
import { useToast } from "../hooks/useToast";
|
||||||
import { lockersService } from "../services/locker.service";
|
import { lockerService } from "../services/locker.service";
|
||||||
import { Copy } from "lucide-react";
|
import { Copy } from "lucide-react";
|
||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from "motion/react";
|
||||||
import { motion } from "motion/react";
|
import { motion } from "motion/react";
|
||||||
@ -103,7 +103,7 @@ function LockersRegistration() {
|
|||||||
try {
|
try {
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await lockersService.registerLockers(
|
const response = await lockerService.registerLockers(
|
||||||
cabinetId,
|
cabinetId,
|
||||||
lockerValues
|
lockerValues
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import api from './api';
|
import api from './api';
|
||||||
|
|
||||||
export const lockersService = {
|
export const lockerService = {
|
||||||
registerLockers: async (cabinetId, lockers) => {
|
registerLockers: async (cabinetId, lockers) => {
|
||||||
return api.post('/cabinet', {
|
return api.post('/cabinet', {
|
||||||
cabinetId,
|
cabinetId,
|
||||||
@ -11,4 +11,12 @@ export const lockersService = {
|
|||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
changeLockerStatus: async (cabinetId, lockerId, status) => {
|
||||||
|
return api.patch(`/locker/status`, { cabinetId, lockerId, status });
|
||||||
|
},
|
||||||
|
|
||||||
|
keySwap: async (cabinetId, lockerId, reason, oldKey, newKey) => {
|
||||||
|
return api.patch(`/locker/key`, { cabinetId, lockerId, reason, oldKey, newKey });
|
||||||
|
}
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user