Update Tasks
This commit is contained in:
@@ -25,6 +25,8 @@ All this task must be done in 1 day
|
|||||||
|
|
||||||
- in src/pages/AdminListReceipts.jsx - there is a table listing receipts
|
- in src/pages/AdminListReceipts.jsx - there is a table listing receipts
|
||||||
|
|
||||||
|
- fix the list table, the localReceiptData need data from src/utils/data.jsx, for some reason it is not getting that data
|
||||||
|
|
||||||
- fix the bind issue in src/components/MkdListTable/MkdListTableBindOperations.jsx - all //TO DO
|
- fix the bind issue in src/components/MkdListTable/MkdListTableBindOperations.jsx - all //TO DO
|
||||||
the `MkdListTableV2` component has actions props which is an object of key:value pair of action definitions
|
the `MkdListTableV2` component has actions props which is an object of key:value pair of action definitions
|
||||||
For example the edit action,
|
For example the edit action,
|
||||||
@@ -44,6 +46,7 @@ All this task must be done in 1 day
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
- complete the open and close action feature, update the status to open and close to see the above binding work, also not that close action is meant to show open if status is open, and open is only meant to show is status is closed - `lines -> 326,330,444,464`
|
||||||
|
|
||||||
> the edit action binds via the bind property to a column "receipt_status", if the value of receipt_status is 1 then the edit should be hidden, i.e not shown
|
> the edit action binds via the bind property to a column "receipt_status", if the value of receipt_status is 1 then the edit should be hidden, i.e not shown
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,232 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import MkdSDK from "Utils/MkdSDK";
|
||||||
|
import {
|
||||||
|
GlobalContext,
|
||||||
|
RequestItems,
|
||||||
|
createRequest,
|
||||||
|
customRequest,
|
||||||
|
deleteRequest,
|
||||||
|
updateRequest,
|
||||||
|
} from "Context/Global";
|
||||||
|
import { AuthContext } from "Context/Auth";
|
||||||
|
import { MkdInput } from "Components/MkdInput";
|
||||||
|
import { InteractiveButton } from "Components/InteractiveButton";
|
||||||
|
import { AddButton } from "Components/AddButton";
|
||||||
|
|
||||||
|
export const ActionConfirmation = ({
|
||||||
|
data = { id: null },
|
||||||
|
options = { endpoint: null, method: "GET" },
|
||||||
|
onSuccess,
|
||||||
|
onClose,
|
||||||
|
multiple = false,
|
||||||
|
action = "",
|
||||||
|
mode = "create",
|
||||||
|
table = "",
|
||||||
|
inputConfirmation = true,
|
||||||
|
}) => {
|
||||||
|
let sdk = new MkdSDK();
|
||||||
|
|
||||||
|
const schema = yup
|
||||||
|
.object({
|
||||||
|
confirm: yup
|
||||||
|
.string()
|
||||||
|
.required()
|
||||||
|
.oneOf([action], `Confirmation must be "${action}"`),
|
||||||
|
})
|
||||||
|
.required();
|
||||||
|
|
||||||
|
const {
|
||||||
|
state: { createModel, updateModel, deleteModel },
|
||||||
|
dispatch: globalDispatch,
|
||||||
|
} = React.useContext(GlobalContext);
|
||||||
|
const { state: authState, dispatch } = React.useContext(AuthContext);
|
||||||
|
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
setValue,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
|
if (!multiple) {
|
||||||
|
switch (mode) {
|
||||||
|
case "create":
|
||||||
|
return createData(data);
|
||||||
|
case "update":
|
||||||
|
return editData(data);
|
||||||
|
case "delete":
|
||||||
|
return deleteData(data);
|
||||||
|
case "custom":
|
||||||
|
return customData(data);
|
||||||
|
case "manual":
|
||||||
|
return manualData(data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
makeRequests();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const makeRequests = async () => {
|
||||||
|
const result = await createRequest(globalDispatch, dispatch, table, data);
|
||||||
|
if (!result.error && onSuccess) {
|
||||||
|
onSuccess();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const editData = async (data) => {
|
||||||
|
console.log("data >>", data);
|
||||||
|
const result = await updateRequest(
|
||||||
|
globalDispatch,
|
||||||
|
dispatch,
|
||||||
|
table,
|
||||||
|
data?.id,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!result?.error && onSuccess) {
|
||||||
|
onSuccess();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createData = async (data) => {
|
||||||
|
if (action === "move") return moveRequest(data);
|
||||||
|
const result = await createRequest(globalDispatch, dispatch, table, data);
|
||||||
|
|
||||||
|
if (!result?.error && onSuccess) {
|
||||||
|
onSuccess();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteData = async (data) => {
|
||||||
|
const result = await deleteRequest(
|
||||||
|
globalDispatch,
|
||||||
|
dispatch,
|
||||||
|
table,
|
||||||
|
data.id
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!result?.error && onSuccess) {
|
||||||
|
onSuccess();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const customData = async (data) => {
|
||||||
|
const result = await customRequest(
|
||||||
|
globalDispatch,
|
||||||
|
dispatch,
|
||||||
|
{
|
||||||
|
endpoint: options?.endpoint,
|
||||||
|
method: options?.method,
|
||||||
|
payload: data,
|
||||||
|
},
|
||||||
|
RequestItems.createModel
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
result &&
|
||||||
|
result?.hasOwnProperty("error") &&
|
||||||
|
!result?.error &&
|
||||||
|
onSuccess
|
||||||
|
) {
|
||||||
|
onSuccess(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const manualData = (data) => {
|
||||||
|
if (onSuccess) {
|
||||||
|
onSuccess(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const moveRequest = async (data) => {
|
||||||
|
const result = await customRequest(
|
||||||
|
globalDispatch,
|
||||||
|
dispatch,
|
||||||
|
{
|
||||||
|
endpoint: "/v3/api/custom/qualitysign/inventory/move",
|
||||||
|
method: "POST",
|
||||||
|
payload: data,
|
||||||
|
},
|
||||||
|
RequestItems.createModel
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!result?.error && onSuccess) {
|
||||||
|
onSuccess(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!inputConfirmation) {
|
||||||
|
setValue("confirm", action);
|
||||||
|
}
|
||||||
|
}, [inputConfirmation]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
// <div className={`px-5 ${multiple ? "flex justify-center" : ""}`}>
|
||||||
|
<div className="mx-auto flex h-fit flex-col items-center justify-start rounded !font-inter leading-snug tracking-wide">
|
||||||
|
<form
|
||||||
|
className={`flex h-fit w-full flex-col text-start`}
|
||||||
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
|
>
|
||||||
|
<div className="space-y-5">
|
||||||
|
<div className="my-2">
|
||||||
|
<div>
|
||||||
|
Are you sure you want to {action}{" "}
|
||||||
|
{data?.id && data?.id?.length && data?.id?.length > 1
|
||||||
|
? "these"
|
||||||
|
: "this"}{" "}
|
||||||
|
{table}?
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={`!mb-10 ${inputConfirmation ? "" : "hidden"}`}>
|
||||||
|
<MkdInput
|
||||||
|
type={"text"}
|
||||||
|
page={"items"}
|
||||||
|
name={`confirm`}
|
||||||
|
errors={errors}
|
||||||
|
register={register}
|
||||||
|
label={
|
||||||
|
<div className="font-bold text-black">
|
||||||
|
Type '{action}' below
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
className={"grow"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-5 flex w-full grow gap-5">
|
||||||
|
<AddButton
|
||||||
|
type="button"
|
||||||
|
onClick={() => onClose()}
|
||||||
|
className="grow self-end !border-soft-200 !bg-transparent font-bold !text-[#4F46E5]"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</AddButton>
|
||||||
|
<InteractiveButton
|
||||||
|
type="submit"
|
||||||
|
loading={
|
||||||
|
createModel?.loading ||
|
||||||
|
updateModel?.loading ||
|
||||||
|
deleteModel?.loading
|
||||||
|
}
|
||||||
|
disabled={
|
||||||
|
createModel?.loading ||
|
||||||
|
updateModel?.loading ||
|
||||||
|
deleteModel?.loading
|
||||||
|
}
|
||||||
|
className="focus:shadow-outline bg-primaryBlue !w-1/2 self-end rounded px-4 py-2 font-bold capitalize text-white focus:outline-none"
|
||||||
|
>
|
||||||
|
{action}
|
||||||
|
</InteractiveButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ActionConfirmation;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default as ActionConfirmation } from "./ActionConfirmation";
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { Modal } from "Components/Modal";
|
||||||
|
import { ActionConfirmation } from "Components/ActionConfirmation";
|
||||||
|
|
||||||
|
export const ActionConfirmationModal = ({
|
||||||
|
data = { id: null },
|
||||||
|
options = { endpoint: null, method: "GET" },
|
||||||
|
onSuccess,
|
||||||
|
onClose,
|
||||||
|
multiple = false,
|
||||||
|
action = "",
|
||||||
|
mode = "create",
|
||||||
|
table = "",
|
||||||
|
title = "",
|
||||||
|
isOpen = false,
|
||||||
|
inputConfirmation = true,
|
||||||
|
modalClasses = {
|
||||||
|
modalDialog:
|
||||||
|
"max-h-[90%] min-h-[12rem] overflow-y-auto !w-full md:!w-[29.0625rem]",
|
||||||
|
modal: "h-full",
|
||||||
|
},
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isOpen={isOpen}
|
||||||
|
modalCloseClick={onClose}
|
||||||
|
title={title}
|
||||||
|
modalHeader
|
||||||
|
classes={modalClasses}
|
||||||
|
>
|
||||||
|
{isOpen && (
|
||||||
|
<ActionConfirmation
|
||||||
|
data={data}
|
||||||
|
mode={mode}
|
||||||
|
table={table}
|
||||||
|
action={action}
|
||||||
|
onClose={onClose}
|
||||||
|
options={options}
|
||||||
|
multiple={multiple}
|
||||||
|
onSuccess={onSuccess}
|
||||||
|
inputConfirmation={inputConfirmation}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ActionConfirmationModal;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default as ActionConfirmationModal } from "./ActionConfirmationModal";
|
||||||
@@ -37,7 +37,7 @@ const AddButton = ({
|
|||||||
onClick={onClickHandle}
|
onClick={onClickHandle}
|
||||||
className={`${animate && "animate-wiggle"} ${
|
className={`${animate && "animate-wiggle"} ${
|
||||||
classes.button
|
classes.button
|
||||||
} relative flex h-[3rem] cursor-pointer items-center justify-center gap-2 overflow-hidden rounded-[.625rem] border border-primary bg-primary px-[.625rem] py-2 font-inter text-sm font-medium leading-loose tracking-wide text-white ${className}`}
|
} relative flex h-[3rem] cursor-pointer items-center justify-center gap-2 overflow-hidden rounded-[.625rem] border border-[#4F46E5] bg-[#4F46E5] px-[.625rem] py-2 font-inter text-sm font-medium leading-loose tracking-wide text-white ${className}`}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<MoonLoader
|
<MoonLoader
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
/* background-color: #7B1113; */
|
/* background-color:#4F46E5; */
|
||||||
}
|
}
|
||||||
.button:after {
|
.button:after {
|
||||||
content: "";
|
content: "";
|
||||||
background-color: #7b1113;
|
background-color: #4f46e5;
|
||||||
/* background: #4f46e5; */
|
/* background: #4f46e5; */
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import React, { memo, useId } from "react";
|
||||||
|
import MoonLoader from "react-spinners/MoonLoader";
|
||||||
|
import classes from "./InteractiveButton.module.css";
|
||||||
|
|
||||||
|
const InteractiveButton = ({
|
||||||
|
loading = false,
|
||||||
|
disabled,
|
||||||
|
children,
|
||||||
|
type = "button",
|
||||||
|
className,
|
||||||
|
loaderclasses,
|
||||||
|
onClick,
|
||||||
|
color = "#ffffff",
|
||||||
|
}) => {
|
||||||
|
const override = {
|
||||||
|
borderColor: "#ffffff",
|
||||||
|
};
|
||||||
|
const id = useId();
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type={type}
|
||||||
|
disabled={disabled}
|
||||||
|
className={`${classes.button} relative flex h-[3rem] cursor-pointer items-center justify-center gap-5 overflow-hidden rounded-[.625rem] border border-[#4F46E5] bg-[#4F46E5] px-[.625rem] py-[.5625rem] text-sm font-medium leading-none text-white ${className}`}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<MoonLoader
|
||||||
|
color={color}
|
||||||
|
loading={loading}
|
||||||
|
cssOverride={override}
|
||||||
|
size={14}
|
||||||
|
className={loaderclasses}
|
||||||
|
// aria-label="Loading Spinner"
|
||||||
|
data-testid={id}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{children ? <span>{children}</span> : null}
|
||||||
|
</>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(InteractiveButton);
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
.button {
|
||||||
|
position: relative;
|
||||||
|
border: none;
|
||||||
|
color: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
-webkit-transition-duration: 0.4s; /* Safari */
|
||||||
|
transition-duration: 0.4s;
|
||||||
|
text-decoration: none;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
/* background-color: #4F46E5; */
|
||||||
|
}
|
||||||
|
.button:after {
|
||||||
|
content: "";
|
||||||
|
background-color: #4f46e5;
|
||||||
|
/* background: #4f46e5; */
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
padding-top: 300%;
|
||||||
|
padding-left: 350%;
|
||||||
|
margin-left: -20px !important;
|
||||||
|
margin-top: -120%;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:active:after {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
opacity: 1;
|
||||||
|
transition: 0s;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default as InteractiveButton } from "./InteractiveButton";
|
||||||
@@ -36,7 +36,7 @@ const MkdListTableRowDropdown = ({
|
|||||||
actions[key]?.action([row[actionId]]);
|
actions[key]?.action([row[actionId]]);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className={`!h-[2rem] !w-[2.0713rem] !border-soft-200 !bg-white`}
|
className={`!h-[2rem] !w-[2.0713rem] !border-gray-200 !bg-white`}
|
||||||
>
|
>
|
||||||
{actions[key]?.icon
|
{actions[key]?.icon
|
||||||
? actions[key]?.icon
|
? actions[key]?.icon
|
||||||
@@ -63,7 +63,7 @@ const MkdListTableRowDropdown = ({
|
|||||||
// actions[key]?.action([row[actionId]]);
|
// actions[key]?.action([row[actionId]]);
|
||||||
// }
|
// }
|
||||||
}}
|
}}
|
||||||
className={`!h-[2rem] !w-[2.0713rem] !border-soft-200 !bg-white`}
|
className={`!h-[2rem] !w-[2.0713rem] !border-gray-200 !bg-white`}
|
||||||
>
|
>
|
||||||
{actions[key]?.icon
|
{actions[key]?.icon
|
||||||
? actions[key]?.icon
|
? actions[key]?.icon
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
import React, { memo, useEffect, useRef } from "react";
|
||||||
|
import { MdClose } from "react-icons/md";
|
||||||
|
|
||||||
|
const Modal = ({
|
||||||
|
children,
|
||||||
|
title,
|
||||||
|
modalCloseClick,
|
||||||
|
modalHeader,
|
||||||
|
classes = { modal: "h-full", modalDialog: "h-[90%]", modalContent: "" },
|
||||||
|
page = "",
|
||||||
|
isOpen,
|
||||||
|
}) => {
|
||||||
|
const modalRef = useRef(null);
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// if (isOpen) {
|
||||||
|
// document.body.style.overflow = "hidden";
|
||||||
|
// } else {
|
||||||
|
// document.body.style.overflow = "auto";
|
||||||
|
// }
|
||||||
|
// }, [isOpen]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const scrollableElements = document.querySelectorAll(
|
||||||
|
"body, .scrollable-container" // Add other selectors if needed
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isOpen) {
|
||||||
|
scrollableElements.forEach((element) => {
|
||||||
|
element.style.overflow = "hidden";
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
scrollableElements.forEach((element) => {
|
||||||
|
element.style.overflow = "auto";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
scrollableElements.forEach((element) => {
|
||||||
|
element.style.overflow = "auto";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={modalRef}
|
||||||
|
style={{
|
||||||
|
zIndex: 999999999999,
|
||||||
|
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
||||||
|
}}
|
||||||
|
className={`fixed bottom-0 left-0 right-0 top-0 flex w-full scale-0 items-center justify-center bg-[#00000099] p-5 backdrop-blur-sm transition-all ${
|
||||||
|
isOpen ? "scale-100" : "scale-0"
|
||||||
|
} ${classes?.modal}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
page === "ManagePermissionAddRole" ? "w-fit" : "w-[80%]"
|
||||||
|
} relative overflow-auto rounded-lg bg-white pb-5 shadow ${
|
||||||
|
classes?.modalDialog
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{modalHeader && (
|
||||||
|
<div
|
||||||
|
className={`sticky inset-x-0 top-0 !z-50 m-auto flex w-full justify-between border-b bg-white px-5 py-4`}
|
||||||
|
>
|
||||||
|
<div className="text-center font-inter text-[1.125rem] font-bold capitalize leading-[1.5rem] tracking-[-1.5%]">
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="modal-close cursor-pointer"
|
||||||
|
onClick={modalCloseClick}
|
||||||
|
>
|
||||||
|
<MdClose className="text-xl" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className={`-z-10 mt-4 px-5 ${classes?.modalContent}`}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ModalMemo = memo(Modal);
|
||||||
|
export { ModalMemo as Modal };
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
// import { Close, danger, warning } from 'Assets/svgs'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
|
||||||
|
const ModalAlert = ( { closeModalFunction, message, title, messageClasses, titleClasses, buttonText = "OK" } ) => {
|
||||||
|
return (
|
||||||
|
<aside
|
||||||
|
className='fixed top-0 right-0 bottom-0 left-0 flex justify-center items-center '
|
||||||
|
style={ {
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
zIndex: '1000',
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
<section className='bg-white min-w-[25rem] w-[25rem] rounded-[.5rem] py-6 px-6 flex flex-col gap-6'>
|
||||||
|
<div className='flex justify-between '>
|
||||||
|
<div>
|
||||||
|
{/* <img src={danger} width={30} height={30} alt='danger' /> */ }
|
||||||
|
</div>
|
||||||
|
<button onClick={ closeModalFunction }>
|
||||||
|
{/* <img src={Close} width={30} height={30} alt='close' /> */ }
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
title ?
|
||||||
|
<div className={ ` ${ titleClasses }` }>
|
||||||
|
{ title }
|
||||||
|
{/* <div className='py-3 text-[1rem] leading-[1.75rem] text-[#333333] '>{message}</div> */ }
|
||||||
|
</div> : null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
message ?
|
||||||
|
<div className={ `text-[1.5rem] leading-[1.5rem] text-[#667085] font-normal ${ messageClasses }` }>
|
||||||
|
{ message }
|
||||||
|
{/* <div className='py-3 text-[1rem] leading-[1.75rem] text-[#333333] '>{message}</div> */ }
|
||||||
|
</div> : null
|
||||||
|
}
|
||||||
|
|
||||||
|
<div className='w-full flex justify-center items-center font-medium text-[base] leading-[1.5rem]'>
|
||||||
|
<button
|
||||||
|
className='border border-[#DC5A5D] bg-[#DC5A5D] rounded-[.5rem] w-[10.375rem] h-[2.75rem] flex items-center justify-center text-white'
|
||||||
|
style={ {
|
||||||
|
width: '10.375rem',
|
||||||
|
height: '2.75rem',
|
||||||
|
} }
|
||||||
|
onClick={ closeModalFunction }
|
||||||
|
>
|
||||||
|
{ buttonText }
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</aside>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModalAlert
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { CloseIcon, DangerIcon } from "Assets/svgs";
|
||||||
|
import { InteractiveButton } from "Components/InteractiveButton";
|
||||||
|
import { MdClose } from "react-icons/md";
|
||||||
|
|
||||||
|
// type Props = {
|
||||||
|
// closeModalFunction: () => void
|
||||||
|
// actionHandler: any
|
||||||
|
// message?: string
|
||||||
|
// title?: string
|
||||||
|
// rejectText?: string
|
||||||
|
// acceptText?: string
|
||||||
|
// titleClasses?: string
|
||||||
|
// messageClasses?: string
|
||||||
|
// }
|
||||||
|
|
||||||
|
const ModalPrompt = ({
|
||||||
|
open,
|
||||||
|
closeModalFunction,
|
||||||
|
actionHandler,
|
||||||
|
message,
|
||||||
|
title,
|
||||||
|
messageClasses,
|
||||||
|
titleClasses,
|
||||||
|
acceptText = "",
|
||||||
|
rejectText = "Cancel",
|
||||||
|
loading = false,
|
||||||
|
allowAccept = true,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<aside
|
||||||
|
className={`fixed inset-0 m-auto flex items-center justify-center backdrop-blur-sm transition-all ${
|
||||||
|
open ? "scale-100" : "scale-0"
|
||||||
|
}`}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
||||||
|
zIndex: "91000",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<section className="flex w-[25rem] min-w-[25rem] flex-col gap-6 rounded-md bg-white px-6 py-6">
|
||||||
|
<div className="flex justify-between ">
|
||||||
|
<div>
|
||||||
|
{title ? (
|
||||||
|
<div className={` ${titleClasses}`}>
|
||||||
|
{title}
|
||||||
|
{/* <div className='py-3 text-[1rem] leading-[1.75rem] text-[#333333] '>{message}</div> */}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{/* <DangerIcon className={`h-5 w-5`} /> */}
|
||||||
|
{/* <img src={danger} width={30} height={30} alt='danger' /> */}
|
||||||
|
</div>
|
||||||
|
<button disabled={loading} onClick={closeModalFunction}>
|
||||||
|
<MdClose className="text-xl" />
|
||||||
|
{/* <img src={Close} width={30} height={30} alt='close' /> */}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/* {title ? (
|
||||||
|
<div className={` ${titleClasses}`}>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
) : null} */}
|
||||||
|
{/* <div className='py-3 text-[1rem] leading-[1.75rem] text-[#333333] '>{message}</div> */}
|
||||||
|
{message ? (
|
||||||
|
<div className={`text-[#667085] ${messageClasses}`}>
|
||||||
|
{message}
|
||||||
|
{/* <div className='py-3 text-[1rem] leading-[1.75rem] text-[#333333] '>{message}</div> */}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<div className="flex w-full justify-between gap-2 font-medium uppercase leading-[1.5rem] text-[base]">
|
||||||
|
<InteractiveButton
|
||||||
|
disabled={loading}
|
||||||
|
loading={loading}
|
||||||
|
className={`${
|
||||||
|
allowAccept ? "flex !w-1/2" : "hidden w-0"
|
||||||
|
} h-[2.75rem] !rounded-[.625rem] bg-primary uppercase !text-white`}
|
||||||
|
onClick={actionHandler}
|
||||||
|
>
|
||||||
|
{acceptText && acceptText.toLowerCase() !== "yes"
|
||||||
|
? `Yes ${acceptText}`
|
||||||
|
: "Yes"}
|
||||||
|
</InteractiveButton>
|
||||||
|
<button
|
||||||
|
disabled={loading}
|
||||||
|
className={`flex h-[2.75rem] items-center justify-center rounded-[.625rem] border border-[#d8dae5] text-[#667085] ${
|
||||||
|
allowAccept ? " w-1/2" : "grow"
|
||||||
|
}`}
|
||||||
|
onClick={closeModalFunction}
|
||||||
|
>
|
||||||
|
{rejectText}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</aside>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalPrompt;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export { Modal } from "./Modal";
|
||||||
|
export { default as ModalPrompt } from "./ModalPrompt";
|
||||||
|
export { default as ModalAlert } from "./ModalAlert";
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import MkdSDK from "Utils/MkdSDK";
|
import MkdSDK from "Utils/MkdSDK";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { AuthContext, tokenExpireError } from "Context/Auth";
|
import { AuthContext, tokenExpireError } from "Context/Auth";
|
||||||
@@ -8,10 +8,16 @@ import {
|
|||||||
setGLobalProperty,
|
setGLobalProperty,
|
||||||
} from "Context/Global";
|
} from "Context/Global";
|
||||||
import { MkdListTableV2 } from "Components/MkdListTable";
|
import { MkdListTableV2 } from "Components/MkdListTable";
|
||||||
import { EditIcon2, TrashIcon } from "Assets/svgs";
|
import {
|
||||||
|
CircleCheckMarkIcon,
|
||||||
|
EditIcon2,
|
||||||
|
RotateIcon,
|
||||||
|
TrashIcon,
|
||||||
|
} from "Assets/svgs";
|
||||||
import { AiFillEye } from "react-icons/ai";
|
import { AiFillEye } from "react-icons/ai";
|
||||||
import { operations } from "Components/MkdListTable/MkdListTableBindOperations";
|
import { operations } from "Components/MkdListTable/MkdListTableBindOperations";
|
||||||
import { receiptData } from "Utils/data";
|
import { receiptData } from "Utils/data";
|
||||||
|
import { ActionConfirmationModal } from "Components/ActionConfirmationModal";
|
||||||
|
|
||||||
let sdk = new MkdSDK();
|
let sdk = new MkdSDK();
|
||||||
|
|
||||||
@@ -309,12 +315,29 @@ const AdminListReceipts = () => {
|
|||||||
dispatch: globalDispatch,
|
dispatch: globalDispatch,
|
||||||
state: { confirmRequest },
|
state: { confirmRequest },
|
||||||
} = React.useContext(GlobalContext);
|
} = React.useContext(GlobalContext);
|
||||||
|
const [selectedItems, setSelectedItems] = React.useState([]);
|
||||||
|
const [localReceiptData, setLocalReceiptData] = React.useState([]);
|
||||||
|
const [showOpenModal, setShowOpenModal] = React.useState(false);
|
||||||
|
const [showCloseModal, setShowCloseModal] = React.useState(false);
|
||||||
|
|
||||||
|
const onToggleModal = (modal, toggle, ids = []) => {
|
||||||
|
switch (modal) {
|
||||||
|
case "close":
|
||||||
|
// TO DO
|
||||||
|
setSelectedItems(ids);
|
||||||
|
break;
|
||||||
|
case "open":
|
||||||
|
// TO DO
|
||||||
|
setSelectedItems(ids);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overflow-x-auto rounded bg-white p-5 shadow">
|
<div className="overflow-x-auto rounded bg-white p-5 shadow">
|
||||||
<MkdListTableV2
|
<MkdListTableV2
|
||||||
defaultColumns={columns}
|
defaultColumns={columns}
|
||||||
externalData={receiptData}
|
externalData={localReceiptData}
|
||||||
useExternalData={true}
|
useExternalData={true}
|
||||||
tableRole={"admin"}
|
tableRole={"admin"}
|
||||||
table={"receipts"}
|
table={"receipts"}
|
||||||
@@ -355,6 +378,39 @@ const AdminListReceipts = () => {
|
|||||||
ifValue: 1,
|
ifValue: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
close: {
|
||||||
|
show: true,
|
||||||
|
action: (ids) => onToggleModal("close", true, ids),
|
||||||
|
multiple: true,
|
||||||
|
locations: ["buttons"],
|
||||||
|
children: "Close",
|
||||||
|
icon: <CircleCheckMarkIcon className="h-[.955rem] w-[.955rem]" />,
|
||||||
|
bind: {
|
||||||
|
column: "receipt_status",
|
||||||
|
action: "hide",
|
||||||
|
operator: "eq",
|
||||||
|
ifValue: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
open: {
|
||||||
|
show: true,
|
||||||
|
action: (ids) => onToggleModal("open", true, ids),
|
||||||
|
multiple: true,
|
||||||
|
locations: ["buttons"],
|
||||||
|
children: "Open",
|
||||||
|
icon: (
|
||||||
|
<RotateIcon
|
||||||
|
className="h-[.955rem] w-[.955rem]"
|
||||||
|
stroke={"#717179"}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
bind: {
|
||||||
|
column: "receipt_status",
|
||||||
|
action: "hide",
|
||||||
|
operator: "eq",
|
||||||
|
ifValue: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
add: {
|
add: {
|
||||||
show: false,
|
show: false,
|
||||||
// action: () => navigate("/admin/add-receipts"),
|
// action: () => navigate("/admin/add-receipts"),
|
||||||
@@ -373,6 +429,47 @@ const AdminListReceipts = () => {
|
|||||||
// allowEditing
|
// allowEditing
|
||||||
refreshRef={refreshRef}
|
refreshRef={refreshRef}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<ActionConfirmationModal
|
||||||
|
isOpen={showCloseModal}
|
||||||
|
title="Close Receipt"
|
||||||
|
modalClasses={{
|
||||||
|
modalDialog:
|
||||||
|
"max-h-[90%] min-h-[12rem] overflow-y-auto !w-full md:!w-[29.0625rem]",
|
||||||
|
modal: "h-full",
|
||||||
|
}}
|
||||||
|
data={{ id: selectedItems[0] }}
|
||||||
|
onClose={() => onToggleModal("close", false, [])}
|
||||||
|
onSuccess={(data) => {
|
||||||
|
// TO DO - Update the receipt_status to closed here
|
||||||
|
onToggleModal("close", false, []);
|
||||||
|
}}
|
||||||
|
action="close"
|
||||||
|
mode="manual"
|
||||||
|
multiple={false}
|
||||||
|
table="receipts"
|
||||||
|
inputConfirmation={false}
|
||||||
|
/>
|
||||||
|
<ActionConfirmationModal
|
||||||
|
isOpen={showOpenModal}
|
||||||
|
title="Open Receipt"
|
||||||
|
modalClasses={{
|
||||||
|
modalDialog:
|
||||||
|
"max-h-[90%] min-h-[12rem] overflow-y-auto !w-full md:!w-[29.0625rem]",
|
||||||
|
modal: "h-full",
|
||||||
|
}}
|
||||||
|
data={{ id: selectedItems[0] }}
|
||||||
|
onClose={() => onToggleModal("open", false, [])}
|
||||||
|
onSuccess={(data) => {
|
||||||
|
// TO DO - Update the receipt_status to open here
|
||||||
|
onToggleModal("open", false, []);
|
||||||
|
}}
|
||||||
|
action="open"
|
||||||
|
mode="manual"
|
||||||
|
multiple={false}
|
||||||
|
table="receipts"
|
||||||
|
inputConfirmation={false}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user