This commit is contained in:
2024-07-22 14:50:31 +05:30
parent aedec5f245
commit d6c0cda64c
46 changed files with 1651 additions and 925 deletions

View File

@@ -64,9 +64,6 @@ const AddBanner = ({ createApi, navigateLink, title, center }) => {
// Trigger the mutation
createApi(formData)
.then((response) => {
// Handle the response here
// // console.log("Mutation response:", response?.data?.statusCode);
// // console.log("Mutation response:", response?.data?.message);
if (response?.data?.statusCode === 200) {
setIsLoading(false);

View File

@@ -109,15 +109,8 @@ const BannerEdit = ({isLoading, data, updateBanner, navigateTo, refetch, center}
if (formData?.banner_image === data?.data?.banner_image) {
form.delete("banner_image");
}
// Log the FormData entries
// for (const [key, value] of form.entries()) {
// // console.log(`${key}: ${value}`);
// }
const mutationResult = await updateBanner({ id: id, data: form })
.then((response) => {
// Handle the response here
// // console.log("Mutation response:", response?.data?.statusCode);
// // console.log("Mutation response:", response?.data?.message);
if (response?.data?.statusCode === 200) {
setIsLoadingEdit(false);

View File

@@ -116,7 +116,6 @@ const BannerCommunity = ({
}
})
.catch((error) => {
// // console.log(error);
});
} catch (error) {
// Handle errors

View File

@@ -227,7 +227,6 @@ const CreateIO = () => {
Action: <Box display={"flex"} justifyContent={"space-between"}></Box>,
}));
console.log(extractedArray);
const destributedAmount = Number(watch().destributedAmount) || 0;
@@ -256,7 +255,6 @@ const CreateIO = () => {
// setValue("banner_image", selectedBannerImageData);
data.banner_image = selectedBannerImageData;
const updatedData = { ...data, status: "Available" };
console.log(selectedBannerImageData);
setInvestment([...investment, updatedData]);
navigate("/view-io");
reset();

View File

@@ -51,7 +51,6 @@ const CustomBreadcrumb = () => {
};
const breadcrumbs = generateBreadcrumbs(pathParts);
console.log(breadcrumbs);
return (
<Box

View File

@@ -9,6 +9,7 @@ import {
Tr,
Skeleton,
TableCaption,
Box,
} from "@chakra-ui/react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import EmptySearchList from "../EmptySearchList";
@@ -26,18 +27,29 @@ const DataTable = ({
setMouseEntered,
setMouseEnteredId,
caption,
isDraggable
}) => {
const navigate = useNavigate();
const { slideFromRight } = useContext(GlobalStateContext);
if (isLoading) {
return (
<Box>
{Array.from({ length: 10 }).map((_, index) => (
<Skeleton height="32px" my="10px" key={index} />
))}
</Box>
);
}
const handleDragEnd = (result) => {
if (!result.destination) return;
const reorderedItems = Array.from(data);
const [removed] = reorderedItems.splice(result.source.index, 1);
reorderedItems.splice(result.destination.index, 0, removed);
setData(reorderedItems)
console.log("New Order:", reorderedItems.map((item, index) => ({ index, item })));
};
return (
@@ -70,7 +82,7 @@ const DataTable = ({
</Thead>
<Tbody className="web-text-small">
{data?.map((item, index) => (
item.id ? (
item.id && isDraggable ? (
<Draggable key={item.id.toString()} draggableId={item.id.toString()} index={index}>
{(provided, snapshot) => (
<Tr

View File

@@ -129,7 +129,6 @@ const AddSponser = () => {
setSelectedOtherImageData(newSelectedImageData);
};
console.log(selectedBannerImageData);
const formFields = [
{

View File

@@ -1,4 +1,4 @@
import { Box, Button, Divider, Heading } from "@chakra-ui/react";
import { Box, Button, Divider, Heading, Spinner } from "@chakra-ui/react";
import React from "react";
import FormField from "./FormField";
import { OPACITY_ON_LOAD } from "../Layout/animations";
@@ -15,6 +15,7 @@ const FormInputMain = ({
submitTitle,
p,
w,
btnLoading
}) => {
return (
<Box mt={0} as="form" onSubmit={onSubmit}>
@@ -99,9 +100,11 @@ const FormInputMain = ({
</Button>
)}
<Button
isLoading={btnLoading}
size={"sm"}
width={w ? w : "44.5%"}
rounded={"sm"}
spinner={<Spinner size='sm' color='white' />}
type="submit"
colorScheme={"forestGreen"}
>

View File

@@ -9,14 +9,12 @@ const FormInputView = ({
onSubmit,
children,
}) => {
console.log(groupedFields);
return (
<form>
{Object?.entries(groupedFields, groupedFieldsTwo).map(
([section, fields], index) => (
<Box key={section}>
{console.log(fields)}
<Heading as="h6" size="xs" mt={index === 0 ? 3 : 4}>
{section}
</Heading>

View File

@@ -33,7 +33,6 @@ const NavBreadcrumbs = ({ nav }) => {
// Flatten nav array into breadcrumbs
const flattenedNav = flattenNav(nav);
console.log(nav);
return <CustomBreadcrumb items={flattenedNav} />;
};

View File

@@ -6,7 +6,7 @@ const ToastBox = ({ message, status }) => {
return (
<Box
color="white"
rounded={"md"}
rounded={"sm"}
className="web-text-large d-flex gap-2 align-items-center"
p={3}
bg={status === "error" ? "red.500" : status === "warn" ? "blue.500" : "green.500"}

View File

@@ -279,7 +279,7 @@ const GlobalStateProvider = ({ children }) => {
title: "Diversified Holdings",
subTitle:
"Private equity portfolio of over 60 companies in various sectors and different countries around the world",
icon: <TbClock2 fontSize={"18px"} />,
Icon: <TbClock2 fontSize={"18px"} />,
status: true,
},
{
@@ -287,7 +287,7 @@ const GlobalStateProvider = ({ children }) => {
title: "Top-Tier Manager",
subTitle:
"KKR is a world-class global PE manager with over $570bn in assets under management",
icon: <CiWallet fontSize={"18px"} />,
Icon: <CiWallet fontSize={"18px"} />,
status: true,
},
{
@@ -295,7 +295,7 @@ const GlobalStateProvider = ({ children }) => {
title: "Strong performance",
subTitle:
"Direct exposure to the KKRs best performing Buyout and Growth funds",
icon: <HiOutlineReceiptPercent fontSize={"18px"} />,
Icon: <HiOutlineReceiptPercent fontSize={"18px"} />,
status: true,
},
{
@@ -303,7 +303,7 @@ const GlobalStateProvider = ({ children }) => {
title: "Leading Track Record",
subTitle:
"Almost 50 year track record since 1977 of consistent, double-digit annual returns",
icon: <IoMdQrScanner fontSize={"18px"} />,
Icon: <IoMdQrScanner fontSize={"18px"} />,
status: true,
},
]);
@@ -1322,88 +1322,7 @@ const GlobalStateProvider = ({ children }) => {
},
]);
const [ IODetails, setIODetails ] = useState([
{
id:generateUniqueId(),
closingDate: "Fri Jul 26 2024 00:00:00 GMT+0530 (India Standard Time)",
discription: "Animi molestias cup",
discriptionArabic: "Ut aliquam corporis",
expectedReturn: 37,
goalAmount: 40,
holdingPeriod: 47,
ioName: "Harlan Head",
ioNameArabic: "Ulric Torres",
ioStatus: "Open",
maxInvestment: 80,
minInvestment: 77,
sponserName: "Ella Fitzgerald",
typeName: "Commercial"
},
{
id:generateUniqueId(),
closingDate: "Wed Sep 18 2024 00:00:00 GMT+0530 (India Standard Time)",
discription: "Voluptas necessitatibus",
discriptionArabic: "Nemo enim ipsam",
expectedReturn: 42,
goalAmount: 55,
holdingPeriod: 30,
ioName: "John Doe",
ioNameArabic: "Ali Ahmed",
ioStatus: "Closed",
maxInvestment: 95,
minInvestment: 60,
sponserName: "Louis Armstrong",
typeName: "Residential"
},
{
id:generateUniqueId(),
closingDate: "Mon Oct 21 2024 00:00:00 GMT+0530 (India Standard Time)",
discription: "Tempora incidunt",
discriptionArabic: "Eius modi tempora",
expectedReturn: 50,
goalAmount: 75,
holdingPeriod: 60,
ioName: "Jane Smith",
ioNameArabic: "Fatima Al-Hassan",
ioStatus: "Pending",
maxInvestment: 100,
minInvestment: 85,
sponserName: "Duke Ellington",
typeName: "Industrial"
},
{
id:generateUniqueId(),
closingDate: "Fri Nov 15 2024 00:00:00 GMT+0530 (India Standard Time)",
discription: "Dolor sit amet",
discriptionArabic: "Consectetur adipiscing elit",
expectedReturn: 45,
goalAmount: 60,
holdingPeriod: 90,
ioName: "Alice Johnson",
ioNameArabic: "Layla Khalid",
ioStatus: "Open",
maxInvestment: 70,
minInvestment: 50,
sponserName: "Billie Holiday",
typeName: "Commercial"
},
{
id:generateUniqueId(),
closingDate: "Tue Dec 10 2024 00:00:00 GMT+0530 (India Standard Time)",
discription: "Consectetur adipisci",
discriptionArabic: "Elit sed do eiusmod",
expectedReturn: 48,
goalAmount: 65,
holdingPeriod: 45,
ioName: "Robert Brown",
ioNameArabic: "Omar Hussain",
ioStatus: "Closed",
maxInvestment: 90,
minInvestment: 70,
sponserName: "Miles Davis",
typeName: "Residential"
}
])
const [ IODetails, setIODetails ] = useState({})
const [depositRequest, setDepositRequest] = useState([
{

View File

@@ -107,7 +107,7 @@ const DashboardLayout = ({ isOnline }) => {
// Set a timer to hide the splash screen after 3 seconds
const timer = setTimeout(() => {
setSplashVisible(false);
}, 2000); // 3000ms = 3 seconds
},300); // 3000ms = 3 seconds
// Cleanup the timer
return () => clearTimeout(timer);
@@ -643,7 +643,7 @@ const DashboardLayout = ({ isOnline }) => {
title={getTitle()}
/>
<CustomBreadcrumb />
{/* <CustomBreadcrumb /> */}
<AppContent />
</main>

View File

@@ -50,7 +50,6 @@ const Contact = () => {
console.log(errors);
// console.log(selectedBannerImageData);
const formFields = [
{
@@ -89,7 +88,6 @@ const Contact = () => {
}, {});
const onSubmit = (data) => {
console.log(data);
setSponser([
{
...data,

View File

@@ -34,7 +34,6 @@ const ConfirmModal = ({ isOpen, onClose, firstField }) => {
});
const onSubmit = (data) => {
console.log(data);
setFile(data.document[0]);
const newDocument = {

View File

@@ -34,7 +34,6 @@ const RejectModal = ({ isOpen, onClose, firstField }) => {
});
const onSubmit = (data) => {
console.log(data);
setFile(data.document[0]);
const newDocument = {

View File

@@ -7,77 +7,51 @@ import * as yup from "yup";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
import { generateUniqueId } from "../../../Contexts/GlobalStateProvider";
import { useGetInvestmentTypesQuery } from "../../../Services/investment.type.service";
import { useGetActiveSponserMasterQuery } from "../../../Services/sponser.service";
import {
useCreateIOMutation,
useGetIOByIdQuery,
useUpdateIOMutation,
} from "../../../Services/io.service";
import ToastBox from "../../../Components/ToastBox";
import { useToast } from "@chakra-ui/react";
const schema = yup.object().shape({
ioName: yup
investmentNameEnglish: yup
.string()
.required("IO name in English is required")
.min(3, "IO name in English must be at least 3 characters long")
.max(50, "IO name in English must be at most 50 characters long"),
ioNameArabic: yup
investmentNameArabic: yup
.string()
.required("IO name in Arabic is required")
.min(3, "IO name in Arabic must be at least 3 characters long")
.max(50, "IO name in Arabic must be at most 50 characters long"),
discription: yup
descriptionEnglish: yup
.string()
.required("Description in English is required")
.min(10, "Description in English must be at least 10 characters long")
.max(500, "Description in English must be at most 500 characters long"),
discriptionArabic: yup
descriptionArabic: yup
.string()
.required("Description in Arabic is required")
.min(10, "Description in Arabic must be at least 10 characters long")
.max(500, "Description in Arabic must be at most 500 characters long"),
typeName: yup
.string()
.required("Investment type in English is required")
.min(3, "Investment type in English must be at least 3 characters long")
.max(50, "Investment type in English must be at most 50 characters long"),
// typeNameArabic: yup
// .string()
// .required("Investment type in Arabic is required")
// .min(3, "Investment type in Arabic must be at least 3 characters long")
// .max(50, "Investment type in Arabic must be at most 50 characters long"),
sponserName: yup
.string()
.required("Sponsor name is required")
.min(3, "Sponsor name must be at least 3 characters long")
.max(50, "Sponsor name must be at most 50 characters long"),
// sponserNameArabic: yup
// .string()
// .required("Sponsor name in Arabic is required")
// .min(3, "Sponsor name in Arabic must be at least 3 characters long")
// .max(50, "Sponsor name in Arabic must be at most 50 characters long"),
goalAmount: yup
.number()
.required("Goal amount is required")
.positive("Goal amount must be a positive number")
.min(1, "Goal amount must be at least 1"),
minInvestment: yup
.number()
.required("Minimum investment is required")
.positive("Minimum investment must be a positive number")
.min(1, "Minimum investment must be at least 1"),
maxInvestment: yup
.number()
.required("Maximum investment is required")
.positive("Maximum investment must be a positive number")
.min(1, "Maximum investment must be at least 1")
.moreThan(
yup.ref("minInvestment"),
"Maximum investment must be greater than minimum investment"
),
closingDate: yup
.date()
.required("Closing date is required")
.min(new Date(), "Closing date cannot be in the past"),
holdingPeriod: yup
.number()
@@ -85,59 +59,77 @@ const schema = yup.object().shape({
.positive("Holding period must be a positive number")
.min(1, "Holding period must be at least 1 month"),
// minInvestmentAmount: yup
// .number()
// .required("Minimum investment is required")
// .positive("Minimum investment must be a positive number")
// .min(1, "Minimum investment must be at least 1"),
ISIN: yup.string(),
InvestmentDetails: yup.string(),
comment: yup.string(),
expectedReturn: yup
.number()
.required("Expected return is required")
.positive("Expected return must be a positive number")
.min(0.01, "Expected return must be at least 0.01"),
closingDate: yup
.date()
.required("Closing date is required")
.min(new Date(), "Closing date cannot be in the past"),
ioStatus: yup
.string(),
});
const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
const IODetails = ({ enableNextTab, index }) => {
const params = useParams();
const id = params?.id;
const navigate = useNavigate();
const toast = useToast();
const { investmentType, sponser, IODetails, setIODetails } = useContext(GlobalStateContext);
const [foundObject, setFoundObject] = useState(null);
// ======================[ States ]
const [isLoading, setIsLoading] = useState();
const investmentTypeOptions = investmentType.map(({ investmentName }) => {
return {
label: investmentName,
value: investmentName,
};
});
// ======================[ Variables Api ]
const id = params?.id;
const investmentTypeArabicOptions = investmentType.map(
({ investmentNameArabic }) => {
// ======================[ Cotext Api ]
const { investmentType, sponser, IODetails, setIODetails } =
useContext(GlobalStateContext);
// ======================[ RTK Querry Api ]
const {
data: investmentTypeData,
isLoading: investmentTypeIsLoading,
error: investmentTypeError,
} = useGetInvestmentTypesQuery();
const {
data: activeSponsers,
isLoading: activeSponsersIsLoading,
error: activeSponsersError,
} = useGetActiveSponserMasterQuery();
const {
data: IObyID,
isLoading: IObyIDisLoading,
error: IObyIDerror,
} = useGetIOByIdQuery(id, { skip: !id });
const [creatIO] = useCreateIOMutation();
const [updateIO] = useUpdateIOMutation();
// ======================[ Selector filter ]
const investmentTypeOptions = investmentTypeData?.data?.rows?.map(
({ investmentTypeName, id }) => {
return {
label: investmentNameArabic,
value: investmentNameArabic,
label: investmentTypeName,
value: id,
};
}
);
const sponserNameOption = sponser.map(({ sponserName }) => {
const sponserNameOption = activeSponsers?.data?.map(({ sponsorName, id }) => {
return {
label: sponserName,
value: sponserName,
};
});
const sponserNameArabicOption = sponser.map(({ sponserNameArabic }) => {
return {
label: sponserNameArabic,
value: sponserNameArabic,
label: sponsorName,
value: id,
};
});
// ======================[ Validator filter ]
const {
control,
reset,
@@ -147,135 +139,80 @@ const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
} = useForm({
resolver: yupResolver(schema),
});
console.log(errors);
useEffect(() => {
const found = IODetails?.find(
(item) => item?.id.toString() === id?.toString()
);
setFoundObject(found);
if (found) {
setIODetails(IObyID?.data);
if (IObyID?.data) {
reset({
ioName: found.ioName,
sponserName: found.sponserName,
ioNameArabic: found.ioNameArabic,
ioStatus: found.ioStatus,
discriptionArabic: found.discriptionArabic,
typeName: found.typeName,
discription: found.discription,
sponserName: found.sponserName,
goalAmount: found.goalAmount,
minInvestment: found.minInvestment,
maxInvestment: found.maxInvestment,
holdingPeriod: found.holdingPeriod,
expectedReturn: found.expectedReturn,
closingDate: found.closingDate,
ioStatus: found.ioStatus,
investmentNameEnglish: IObyID?.data?.investmentNameEnglish,
investmentNameArabic: IObyID?.data?.investmentNameArabic,
descriptionEnglish: IObyID?.data?.descriptionEnglish,
descriptionArabic: IObyID?.data?.descriptionArabic,
goalAmount: IObyID?.data?.goalAmount,
closingDate: IObyID?.data?.closingDate,
holdingPeriod: IObyID?.data?.holdingPeriod,
ISIN: IObyID?.data?.ISIN,
comment: IObyID?.data?.comment,
expectedReturn: IObyID?.data?.expectedReturn,
investmentType_xid: IObyID?.data?.investmentType_xid,
investmentType_xid: IObyID?.data?.investmentType_xid,
InvestmentDetails: IObyID?.data?.InvestmentDetails,
minInvestmentAmount: IObyID?.data?.minInvestmentAmount,
});
}
setIsLoading(false)
}, [id, IODetails, reset]);
}, [id, IObyID]);
// ======================[ Form Contructor Array ]
//=======================[ Creator ]
const formFields = [
{
label: "IO Name",
name: "ioName",
name: "investmentNameEnglish",
type: "text",
isRequired: true,
section: " ",
width: "49%",
},
{
label: "IO Name (Arabic)",
name: "ioNameArabic",
name: "investmentNameArabic",
type: "text",
isRequired: true,
arabic: true,
section: " ",
width: "49%",
},
{
label: "Description",
name: "discription",
name: "descriptionEnglish",
type: "textarea",
isRequired: true,
section: " ",
width: "49%",
},
{
label: "Description (Arabic)",
name: "discriptionArabic",
name: "descriptionArabic",
type: "textarea",
isRequired: true,
arabic: true,
section: " ",
width: "49%",
},
{
label: "Investment Type",
placeHolder: "Select option",
name: "typeName",
type: "select",
section: " ",
width: "32.3%",
options: investmentTypeOptions,
},
// {
// label: "Sponser Name (Arabic)",
// placeHolder: " ",
// name: "sponserNameArabic",
// type: "select",
// options: sponserNameArabicOption,
// arabic: true,
// section: " ",
// width: "49%",
// },
{
label: "Sponsorer Name",
placeHolder: "Select option",
name: "sponserName",
type: "select",
options: sponserNameOption,
section: " ",
width: "32.3%",
},
// {
// label: "Investment Type (Arabic)",
// placeHolder: " ",
// name: "typeNameArabic",
// type: "select",
// arabic: true,
// section: " ",
// width: "32.3%",
// options: investmentTypeArabicOptions,
// },
{
label: "Goal Amount",
placeHolder: "$00.00",
name: "goalAmount",
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
{
label: "Minimum Investment Amount",
placeHolder: "$00.00",
name: "minInvestment",
type: "number",
section: " ",
width: "32.3%",
},
{
label: "Maximum Investment Amount",
placeHolder: "$00.00",
name: "maxInvestment",
type: "number",
label: "Closing Date",
name: "closingDate",
type: "date",
isRequired: true,
section: " ",
width: "32.3%",
},
@@ -284,174 +221,124 @@ const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
name: "holdingPeriod",
type: "number",
placeHolder: "1Y",
isRequired: true,
section: " ",
width: "32.3%",
},
{
label: "Minimum Investment Amount",
placeHolder: "$00.00",
name: "minInvestmentAmount",
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
{
label: "ISIN",
placeHolder: "",
name: "ISIN",
type: "number",
section: " ",
width: "32.3%",
},
{
label: "Investment Details",
placeHolder: "",
name: "InvestmentDetails",
type: "text",
section: " ",
width: "32.3%",
},
{
label: "Expected Return Estimated",
placeHolder: "$00.00",
name: "expectedReturn",
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
{
label: "Investment Type",
placeHolder: "Select option",
name: "investmentType",
type: "select",
isRequired: true,
section: " ",
width: "32.3%",
options: investmentTypeOptions,
},
{
label: "Sponsorer Name",
placeHolder: "Select option",
name: "sponserName",
type: "select",
isRequired: true,
options: sponserNameOption,
section: " ",
width: "32.3%",
},
{
label: "Closing Date",
name: "closingDate",
type: "date",
label: "Comment",
placeHolder: "Enter comment here",
name: "comment",
type: "textarea",
section: " ",
width: "32.3%",
width: "100%",
options: investmentTypeOptions,
},
// {
// label: "IO status",
// placeHolder: "Select option",
// name: "ioStatus",
// type: "select",
// section: " ",
// width: "32.3%",
// options: [
// {
// label: "Open",
// value: "open",
// },
// {
// label: "Pending",
// value: "pending",
// },
// {
// label: "Closed",
// value: "closed",
// },
// ],
// },
];
//=======================[ Editor ]
const formEditFields = [
{
label: "IO Name",
value: foundObject?.ioName,
name: "ioName",
value: IObyID?.data?.investmentNameEnglish,
name: "investmentNameEnglish",
type: "text",
section: " ",
width: "49%",
isRequired: true,
},
{
label: "IO Name (Arabic)",
name: "ioNameArabic",
name: "investmentNameArabic",
type: "text",
value: foundObject?.sponserName,
value: IObyID?.data?.investmentNameArabic,
isRequired: true,
arabic: true,
section: " ",
width: "49%",
},
{
label: "Description",
name: "discription",
value: foundObject?.ioStatus,
name: "descriptionEnglish",
value: IObyID?.data?.descriptionEnglish,
type: "textarea",
isRequired: true,
section: " ",
width: "49%",
},
{
label: "Description (Arabic)",
name: "discriptionArabic",
value: foundObject?.discriptionArabic,
name: "descriptionArabic",
value: IObyID?.data?.descriptionArabic,
type: "textarea",
isRequired: true,
arabic: true,
section: " ",
width: "49%",
},
{
label: "Investment Type",
placeHolder: "Select option",
value: foundObject?.typeName,
name: "typeName",
type: "select",
section: " ",
width: "32.3%",
options: investmentTypeOptions,
},
// {
// label: "Sponser Name (Arabic)",
// placeHolder: " ",
// name: "sponserNameArabic",
// type: "select",
// options: sponserNameArabicOption,
// arabic: true,
// section: " ",
// width: "49%",
// },
{
label: "Sponsorer Name",
placeHolder: "Select option",
name: "sponserName",
type: "select",
options: sponserNameOption,
value: foundObject?.sponserName,
section: " ",
width: "32.3%",
},
// {
// label: "Investment Type (Arabic)",
// placeHolder: " ",
// name: "typeNameArabic",
// type: "select",
// arabic: true,
// section: " ",
// width: "32.3%",
// options: investmentTypeArabicOptions,
// },
{
label: "Goal Amount",
placeHolder: "$00.00",
value: foundObject?.goalAmount,
value: IObyID?.data?.goalAmount,
name: "goalAmount",
type: "number",
section: " ",
width: "32.3%",
},
{
label: "Minimum Investment Amount",
placeHolder: "$00.00",
name: "minInvestment",
value: foundObject?.minInvestment,
type: "number",
section: " ",
width: "32.3%",
},
{
label: "Maximum Investment Amount",
placeHolder: "$00.00",
name: "maxInvestment",
type: "number",
value: foundObject?.maxInvestment,
section: " ",
width: "32.3%",
},
{
label: "Holding Period",
name: "holdingPeriod",
value: foundObject?.holdingPeriod,
type: "number",
placeHolder: "1Y",
section: " ",
width: "32.3%",
},
{
label: "Expected Return Estimated",
placeHolder: "$00.00",
name: "expectedReturn",
type: "number",
value: foundObject?.expectedReturn,
isRequired: true,
section: " ",
width: "32.3%",
},
@@ -459,36 +346,96 @@ const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
label: "Closing Date",
name: "closingDate",
type: "date",
value: foundObject?.closingDate,
isRequired: true,
value: IObyID?.data?.closingDate,
section: " ",
width: "32.3%",
},
{
label: "IO status",
placeHolder: foundObject?.ioStatus,
name: "ioStatus",
type: "select",
label: "Holding Period",
name: "holdingPeriod",
value: IObyID?.data?.holdingPeriod,
type: "number",
isRequired: true,
placeHolder: "1Y",
section: " ",
width: "32.3%",
options: [
{
label: "Open",
value: "open",
},
{
label: "Pending",
value: "pending",
},
{
label: "Closed",
value: "closed",
},
],
},
{
label: "Minimum Investment Amount",
placeHolder: "$00.00",
name: "minInvestmentAmount",
value: IObyID?.data?.minInvestmentAmount,
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
{
label: "ISIN",
placeHolder: "$00.00",
name: "ISIN",
value: IObyID?.data?.ISIN,
type: "number",
section: " ",
width: "32.3%",
},
{
label: "Investment Details",
placeHolder: "",
name: "InvestmentDetails",
value: IObyID?.data?.InvestmentDetails,
type: "text",
section: " ",
width: "32.3%",
},
{
label: "Comment",
placeHolder: "Enter comment here",
name: "comment",
type: "textarea",
value: IObyID?.data?.comment,
section: " ",
width: "100%",
options: investmentTypeOptions,
},
{
label: "Expected Return Estimated",
placeHolder: "$00.00",
name: "expectedReturn",
type: "number",
isRequired: true,
value: IObyID?.data?.expectedReturn,
section: " ",
width: "32.3%",
},
{
label: "Investment Type",
placeHolder: "Select option",
value: IObyID?.data?.investmentType_xid,
name: "investmentType_xid",
type: "select",
isRequired: true,
section: " ",
width: "32.3%",
options: investmentTypeOptions,
},
{
label: "Sponsorer Name",
placeHolder: "Select option",
name: "sponsor_xid",
type: "select",
options: sponserNameOption,
value: IObyID?.data?.sponsor_xid,
section: " ",
isRequired: true,
width: "32.3%",
},
];
// ======================[ Form Contructor Filter ]
const groupedFields = formFields.reduce((groups, field) => {
const { section } = field;
if (!groups[section]) {
@@ -498,6 +445,7 @@ const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
return groups;
}, {});
// ======================[ Edit Form Contructor Filter ]
const groupedEditFields = formEditFields.reduce((groups, field) => {
const { section } = field;
if (!groups[section]) {
@@ -507,27 +455,56 @@ const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
return groups;
}, {});
const onSubmit = (data) => {
if(params?.id){
return enableNextTab(index);
const onSubmit = async (data) => {
setIsLoading(true)
console.log(data);
if (id) {
const res = await updateIO({ data, id });
if (res?.error?.status === 400 || res?.error?.status===500 ) {
setIsLoading(false)
toast({
render: () => (
<ToastBox message={res?.error?.data?.message} status={"error"} />
),
});
}
} else {
try {
const res = await creatIO(data);
if (res?.data?.statusCode === 200) {
setIsLoading(false)
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
navigate(`/create-io/${res?.data?.data}`);
enableNextTab(index);
}
} catch (error) {
setIsLoading(false)
console.log(error);
}
}
const id = generateUniqueId();
const status = "Draft"
// setValue("id", id)
console.log(data);
const updatedData = { ...data, id, ioStatus : status };
console.log(data);
// Add the updated data to the IODetails array
setIODetails([...IODetails, updatedData]);
// Navigate to the new route
navigate(`/create-io/${updatedData?.id}`);
// if (params?.id) {
// return enableNextTab(index);
// }
// const id = generateUniqueId();
// const status = "Draft";
// // setValue("id", id)
// const updatedData = { ...data, id, ioStatus: status };
// // Add the updated data to the IODetails array
// setIODetails([...IODetails, updatedData]);
// // Navigate to the new route
// navigate(`/create-io/${updatedData?.id}`);
};
if (isLoading) return <FullscreenLoaders/>;
return (
return IObyIDisLoading ? (
<FullscreenLoaders />
) : (
<FormInputMain
p={0.1}
w={250}
@@ -536,8 +513,8 @@ const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
control={control}
errors={errors}
onSubmit={handleSubmit(onSubmit)}
// onSubmit={onSubmit}
submitTitle={id ? "Update":"Submit"}
btnLoading={isLoading}
submitTitle={id ? "Update" : "Submit"}
/>
);
};

View File

@@ -37,7 +37,6 @@ const IONAVDetails = () => {
"Update On",
];
console.log(navDetails);
// Table filter
const filteredData = navDetails?.filter((item) => {
const name = item.updateBy;
@@ -107,8 +106,6 @@ const IONAVDetails = () => {
})));
console.log(extractedArray);
const handleDelete = () => {
const updatedNav = navDetails.filter(

View File

@@ -145,7 +145,7 @@ const InvestmentDocument = ({ control, errors, enableNextTab, index }) => {
),
Action: (
<Box display="flex" justifyContent="center" gap={2}>
<Tooltip
{/* <Tooltip
rounded="sm"
fontSize="xs"
label="View"
@@ -162,7 +162,7 @@ const InvestmentDocument = ({ control, errors, enableNextTab, index }) => {
>
<ViewIcon />
</Button>
</Tooltip>
</Tooltip> */}
<Tooltip
rounded="sm"
fontSize="xs"

View File

@@ -1,4 +1,14 @@
import { Box, Button, HStack, Input, Text, Tooltip, useDisclosure } from "@chakra-ui/react";
import {
Box,
Button,
HStack,
Input,
Text,
Tooltip,
useDisclosure,
Image,
useToast,
} from "@chakra-ui/react";
import React, { useContext, useEffect, useRef, useState } from "react";
import InvestmentDocuments from "../InvestmentDocuments";
import DataTable from "../../../Components/DataTable/DataTable";
@@ -6,46 +16,52 @@ import CustomAlertDialog from "../../../Components/CustomAlertDialog";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import { debounce } from "../../Master/Sponser/AddSponser";
import { formatDate } from "../../../Components/Functions/UTCConvertor";
import { AddIcon, DeleteIcon, DownloadIcon, EditIcon, ViewIcon } from "@chakra-ui/icons";
import {
AddIcon,
DeleteIcon,
DownloadIcon,
EditIcon,
ViewIcon,
} from "@chakra-ui/icons";
import KeyMeritsAdd from "../KeyMeritsAdd";
import { useParams } from "react-router-dom";
import { useDeleteKeyMeritsMutation, useGetKeyMeritsQuery } from "../../../Services/io.service";
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
import ToastBox from "../../../Components/ToastBox";
import KeyMeritsEdit from "../KeyMeritsEdit";
import SetDisplayOrder from "./SetDisplayOrder";
const KeyMerits = ({enableNextTab, index}) => {
const { keyMerits, setKeyMerits,slideFromRight} =
useContext(GlobalStateContext);
const firstField = useRef();
const [searchTerm, setSearchTerm] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [deleteAlert, setDeleteAlert] = useState(false);
const [actionId, setActionId] = useState(false);
const [mouseEntered, setMouseEntered] = useState(false);
const [mouseEnteredId, setMouseEnteredId] = useState("");
const { isOpen, onOpen, onClose } = useDisclosure();
const KeyMerits = ({ enableNextTab, index }) => {
const toast = useToast()
const params = useParams();
useEffect(() => {
// Simulate loading
const timer = setTimeout(() => {
setIsLoading(false);
}, 1500);
// Cleanup the timer on component unmount
return () => clearTimeout(timer);
}, []);
// =====================[ variables ]
const id = params?.id;
const { data, isLoading, error } = useGetKeyMeritsQuery(id);
console.log(data?.data);
const tableHeadRow = [
"Sr.no",
"Title",
"Sub title",
"Icon",
"Action",
];
const { keyMerits, setKeyMerits, slideFromRight } =
useContext(GlobalStateContext);
const firstField = useRef();
const [searchTerm, setSearchTerm] = useState("");
const [deleteAlert, setDeleteAlert] = useState(false);
const [actionId, setActionId] = useState(false);
const [mouseEntered, setMouseEntered] = useState(false);
const [isBtnLoading, setIsBtnLoading] = useState(false);
const [mouseEnteredId, setMouseEnteredId] = useState("");
const { isOpen, onOpen, onClose } = useDisclosure();
const { isOpen: isEditOpen, onOpen: onEditOpen, onClose: onEditCloseOpen } = useDisclosure();
const [ deleteKeyMerits ] = useDeleteKeyMeritsMutation()
const tableHeadRow = ["Sr.no", "Title", "Sub title", "Icon", "Action"];
const handleUpdateStatus = debounce((id) => {
setKeyMerits((prevKeyMerits) =>
prevKeyMerits.map((keyMerits) =>
keyMerits.id === id ? { ...keyMerits, status: !keyMerits.status } : keyMerits
keyMerits.id === id
? { ...keyMerits, status: !keyMerits.status }
: keyMerits
)
);
toast({
@@ -53,27 +69,32 @@ const KeyMerits = ({enableNextTab, index}) => {
});
}, 300);
const filteredData = keyMerits?.filter((item) => {
const filteredData = data?.data?.filter((item) => {
// Filter by name (case insensitive)
const name = item.title;
const name = item.meritsHeader;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
});
const handleDelete = () => {
const updatedKeyMerits = keyMerits.filter((keyMerits) => keyMerits.id !== actionId);
setTimeout(() => {
setSponser(updatedKeyMerits);
setDeleteAlert(false);
setIsLoading(false);
}, 100);
setIsLoading(true);
const handleDelete = async () => {
setIsBtnLoading(true)
try {
const res = await deleteKeyMerits(actionId)
if(res?.data?.statusCode === 200){
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
setIsBtnLoading(false)
setDeleteAlert(false)
}
} catch (error) {
}
};
const [ extractedArray, setExtractedArray ] = useState(filteredData?.map((item, index) => ({
const extractedArray = filteredData?.map((item, index) => ({
id: item.id,
"Sr.no": (
<Text
@@ -86,7 +107,7 @@ const KeyMerits = ({enableNextTab, index}) => {
{index + 1}
</Text>
),
"Title": (
Title: (
<Text
justifyContent={slideFromRight ? "right" : "left"}
as={"span"}
@@ -94,30 +115,27 @@ const KeyMerits = ({enableNextTab, index}) => {
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.title}
{item.meritsHeader}
</Text>
),
"Sub title": (
<Box w={"300px"} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item.subTitle}
{item.meritsDescription}
</Text>
</Box>
),
"Icon": (
<Text
color={'green.500'}
justifyContent={slideFromRight ? "right" : "left"}
as={"span"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.icon}
</Text>
Icon: (
<Image
src={`${import.meta.env.VITE_API_IMAGE_URL}/${item?.iconFilePath}`}
w={8}
h={8}
/>
// https://admin.tanami.betadelivery.com/public/icons/linkedin.png
),
Action: (
<Box display={"flex"} justifyContent={"space-evenly"}>
<Tooltip
<Box display={"flex"} justifyContent={"center"} gap={2}>
{/* <Tooltip
rounded={"sm"}
fontSize={"xs"}
label="View"
@@ -135,9 +153,9 @@ const KeyMerits = ({enableNextTab, index}) => {
rounded={"sm"}
size={"xs"}
>
<ViewIcon />
<ViewIcon />
</Button>
</Tooltip>
</Tooltip> */}
<Tooltip
rounded={"sm"}
fontSize={"xs"}
@@ -151,6 +169,10 @@ const KeyMerits = ({enableNextTab, index}) => {
// transition={"0.5s all"}
color="blue.400"
rounded={"sm"}
onClick={() => {
setActionId(item?.id);
onEditOpen();
}}
size={"xs"}
>
<EditIcon />
@@ -180,10 +202,11 @@ const KeyMerits = ({enableNextTab, index}) => {
</Tooltip>
</Box>
),
})));
}));
return (
return isLoading ? (
<FullscreenLoaders />
) : (
<Box>
<Box display={"flex"} justifyContent={"space-between"} mb={4}>
<Input
@@ -196,6 +219,10 @@ const KeyMerits = ({enableNextTab, index}) => {
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<Box display={'flex'} gap={2} as="span">
<SetDisplayOrder data={filteredData} />
<Button
leftIcon={<AddIcon />}
onClick={onOpen}
@@ -203,24 +230,35 @@ const KeyMerits = ({enableNextTab, index}) => {
// width={"44.5%"}
fontSize={"xs"}
rounded={"sm"}
// colorScheme="green"
color={'green'}
colorScheme="forestGreen"
>
Add key merits
</Button>
</Box>
<KeyMeritsAdd
id={id}
isOpen={isOpen}
onClose={onClose}
firstField={firstField}
/>
<KeyMeritsEdit
id={id}
actionId={actionId}
isOpen={isEditOpen}
onClose={onEditCloseOpen}
firstField={firstField}
data={data?.data}
/>
</Box>
<DataTable
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
setData={setExtractedArray}
isLoading={isLoading}
// setData={setExtractedArray}
isLoading={false}
viewActionId={actionId}
setViewActionId={setActionId}
// totalPages={10}
@@ -228,16 +266,25 @@ const KeyMerits = ({enableNextTab, index}) => {
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
<HStack justifyContent={'flex-end'}>
<Button ps={8} pe={8} colorScheme="green" size={'sm'} rounded={'sm'} onClick={()=> enableNextTab(index)}>Next</Button>
<HStack justifyContent={"flex-end"}>
<Button
ps={8}
pe={8}
colorScheme="forestGreen"
size={"sm"}
rounded={"sm"}
onClick={() => enableNextTab(index)}
>
Next
</Button>
</HStack>
<CustomAlertDialog
onClose={() => setDeleteAlert(false)}
isOpen={deleteAlert}
message={"Are you sure you want to delete sponers?"}
message={"Are you sure you want to delete key merit?"}
alertHandler={handleDelete}
isLoading={isLoading}
isLoading={isBtnLoading}
/>
</Box>
);

View File

@@ -0,0 +1,143 @@
import React, { useState } from "react";
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton,
useDisclosure,
Button,
Box,
Text,
Image,
HStack,
} from "@chakra-ui/react";
import { AddIcon, DragHandleIcon } from "@chakra-ui/icons";
import DataTable from "../../../Components/DataTable/DataTable";
const SetDisplayOrder = ({data,}) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const tableHeadRow = ["", "Title", "Icon", ];
console.log(data);
const [ extractedArray, setExtractedArray] = useState(data?.map((item, index) => ({
id:item?.id,
"": (
<Box w={"20px"} isTruncated={true}>
<DragHandleIcon />
</Box>
),
Title: (
<Box w={"300px"} isTruncated={true}>
<Text
justifyContent={"left"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item?.meritsHeader}
</Text></Box>
),
Icon: (
<HStack justify={'center'}>
<Image
src={`${import.meta.env.VITE_API_IMAGE_URL}/${item?.iconFilePath}`}
w={8}
h={8}
/></HStack>
// https://admin.tanami.betadelivery.com/public/icons/linkedin.png
),
})))
console.log(extractedArray);
return (
<>
<Button
leftIcon={<AddIcon />}
size={"sm"}
fontSize={"xs"}
rounded={"sm"}
variant={"outline"}
colorScheme="forestGreen"
onClick={onOpen}
>
Set Display Order
</Button>
<Modal isCentered size={'xl'} isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent >
<ModalHeader fontSize={"lg"}>Set Display Order</ModalHeader>
<ModalCloseButton />
<ModalBody>
<DataTable
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
setData={setExtractedArray}
isDraggable={true}
// isLoading={false}
// viewActionId={actionId}
// setViewActionId={setActionId}
// totalPages={10}
// setMouseEnteredId={setMouseEnteredId}
// setMouseEntered={setMouseEntered}
/>
</ModalBody>
<ModalFooter>
<Button
size={"sm"}
fontSize={"xs"}
rounded={"sm"}
variant={"outline"}
colorScheme="forestGreen"
mr={3}
onClick={onClose}
>
Reset order
</Button>
<Button
size={"sm"}
fontSize={"xs"}
rounded={"sm"}
colorScheme="forestGreen"
variant="solid"
>
Set order
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
};
export default SetDisplayOrder;

View File

@@ -236,7 +236,6 @@ const EditIO = ({ isOpen, onClose }) => {
];
const onSubmit = (data) => {
console.log(data);
// Handle form submission
onClose();
};

View File

@@ -22,7 +22,6 @@ import {
const { create, setCreate } = useContext(GlobalStateContext);
const [file, setFile] = useState(null);
const filteredObject = create?.find((item) => item?.id === id)
console.log(filteredObject?.Type);
const {
control,
watch,
@@ -35,7 +34,6 @@ import {
resolver: yupResolver(investmentDocSchema),
});
console.log(filteredObject);
useEffect(() => {
if (filteredObject) {
@@ -51,7 +49,6 @@ import {
const onSubmit = (data) => {
// setValue('Type',data.Type[0]?.type)
console.log(data);
const updatedCreate = create.map((item) =>
item.id === id ? { ...item, ...data } : item
);

View File

@@ -218,7 +218,6 @@ const EditViewIO = () => {
// setValue("banner_image", selectedBannerImageData);
data.banner_image = selectedBannerImageData;
const updatedData = { ...data, status: "Available" };
console.log(selectedBannerImageData);
setInvestment([...investment, updatedData]);
navigate("/view-io");
reset();

View File

@@ -43,7 +43,6 @@ import {
const onSubmit = (data) => {
console.log(data);
setSponser([
{
...data,
@@ -56,10 +55,6 @@ import {
};
const handleSave = () => {
console.log({
fileName: fileName,
file:file
});
setAlert(false)
onClose()

View File

@@ -115,7 +115,6 @@ const InputComponents = () => {
// setValue("banner_image", selectedBannerImageData);
data.banner_image = selectedBannerImageData;
const updatedData = { ...data, status: "Available" };
console.log(selectedBannerImageData);
setInvestment([...investment, updatedData]);
navigate("/view-io");
reset();

View File

@@ -19,13 +19,14 @@ import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import CustomAlertDialog from "../../Components/CustomAlertDialog";
import { v4 as uuidv4 } from 'uuid';
import { useNavigate } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import { GrDocumentPdf } from "react-icons/gr";
import { FaRegFileAlt } from "react-icons/fa";
import { TbFileTypeDocx } from "react-icons/tb";
import { AiOutlineFileGif } from "react-icons/ai";
import GlobalStateContext from "../../Contexts/GlobalStateContext";
import InvestmentDocument from "./CreateIO/InvestmentDocument";
import { useCreateInvestmentDocumentsMutation } from "../../Services/investment.documents.service";
export const bytesToMB = (bytes) => {
if (bytes === 0) return "0 MB";
@@ -54,10 +55,23 @@ export const investmentDocSchema = yup.object().shape({
fileName: yup.string().required("File name is required"),
});
const InvestmentDocuments = ({ id, isOpen, onClose, firstField, create, setCreate }) => {
const InvestmentDocuments = ({ isOpen, onClose, firstField, create, setCreate }) => {
const params = useParams()
const [file, setFile] = useState(null);
const [alert, setAlert] = useState(false);
// =====================[ variables ]
const id = params?.id
// =====================[ RTK Api calls ]
const [ createInvestmentDocument ] = useCreateInvestmentDocumentsMutation()
const navigate = useNavigate();
const {
@@ -68,27 +82,38 @@ const InvestmentDocuments = ({ id, isOpen, onClose, firstField, create, setCreat
resolver: yupResolver(investmentDocSchema),
});
// const onSubmit = (data) => {
// console.log(data);
// setFile(data.document[0]);
// // Additional code for handling form submission
// };
const onSubmit = async (data) => {
// console.log(data);
const formData = new FormData();
formData.append('documentName', data.fileName);
formData.append('document', data?.document[0]);
const onSubmit = (data) => {
console.log(data);
setFile(data.document[0]);
// Log FormData entries
for (let [key, value] of formData.entries()) {
console.log(`${key}:`, value);
}
try {
const res = await createInvestmentDocument({ data: formData, id })
console.log(res);
} catch (error) {
console.log(error);
}
const newDocument = {
...data,
document: data.document[0].name, // Store the document name
status: true,
id: uuidv4(),
createdAt: new Date().toISOString(),
Type:getFileIcon(file.type)
};
setCreate((prevCreate) => [...prevCreate, newDocument]);
onClose()
// const newDocument = {
// ...data,
// document: data.document[0].name, // Store the document name
// status: true,
// id: uuidv4(),
// createdAt: new Date().toISOString(),
// Type:getFileIcon(file.type)
// };
// setCreate((prevCreate) => [...prevCreate, newDocument]);
// onClose()
};
const handleFileChange = (event) => {

View File

@@ -1,150 +1,204 @@
import {
Box,
Button,
Drawer,
DrawerBody,
DrawerCloseButton,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerOverlay,
FormControl,
FormLabel,
Input,
InputGroup,
Stack,
} from "@chakra-ui/react";
import * as yup from "yup";
import React, { useContext, useEffect, useRef, useState } from "react";
import FormInputMain from "../../Components/FormInputMain";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import CustomAlertDialog from "../../Components/CustomAlertDialog";
export const investmentDoct = yup.object().shape({
type: yup.string().required("Sponser name is required"),
document: yup.string().required("Sponser name is required"),
fileName: yup.string().required("Mobile no is required"),
Box,
Button,
Drawer,
DrawerBody,
DrawerCloseButton,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerOverlay,
FormControl,
FormErrorMessage,
FormLabel,
Input,
Stack,
useToast,
} from "@chakra-ui/react";
import React, { useRef, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import CustomAlertDialog from "../../Components/CustomAlertDialog";
import { useCreateKeyMeritsMutation } from "../../Services/io.service";
import * as yup from "yup";
import ToastBox from "../../Components/ToastBox";
const keyMeritsSchema = yup.object().shape({
meritsHeader: yup.string().required("Title is required"),
meritsDescription: yup.string().required("Sub title is required"),
iconImage: yup.mixed().required("Icon is required"), // Adjust based on file or string
});
const KeyMeritsAdd = ({ isOpen, onClose, firstField, id }) => {
const toast = useToast()
const [alert, setAlert] = useState(false);
const [createKeyMerits] = useCreateKeyMeritsMutation();
const [isLoading, setIsLoading] = useState(false);
const {
control,
reset,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(keyMeritsSchema),
defaultValues: {
meritsHeader: "",
meritsDescription: "",
iconImage: null,
},
});
const KeyMeritsAdd = ({ id, isOpen, onClose, firstField }) => {
const [file, setFile] = useState("");
const [fileName, setFileName] = useState("");
const [alert, setAlert] = useState(false);
const {
control,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(investmentDoct),
});
const onSubmit = (data) => {
console.log(data);
setSponser([
{
...data,
status: true,
id: uuidv4(),
createdAt: new Date().toISOString(),
},
...investmentDoct,
]);
};
const handleSave = () => {
console.log({
fileName: fileName,
file:file
});
setAlert(false)
onClose()
const onSubmit = async (data) => {
setIsLoading(true);
try {
const formData = new FormData();
formData.append("meritsHeader", data.meritsHeader);
formData.append("meritsDescription", data.meritsDescription);
if (data.iconImage && data.iconImage instanceof File) {
formData.append("iconImage", data.iconImage);
}
const res = await createKeyMerits({ data: formData, id });
if (res?.data?.statusCode === 201) {
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
setAlert(false);
onClose();
setIsLoading(false);
reset()
return
}
if(res?.error?.data?.code === 400){
toast({
render: () => <ToastBox message={res?.error?.data?.message} status={'error'} />,
});
setAlert(false);
onClose();
setIsLoading(false);
reset()
return
}
} catch (error) {
if (error) {
toast({
render: () => <ToastBox message={"Something went wrong, please try again!"} status={'error'} />,
});
}
setIsLoading(false);
setAlert(false);
onClose();
reset()
}
return (
<>
<Drawer
isOpen={isOpen}
placement="right"
initialFocusRef={firstField}
onClose={onClose}
>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader fontSize={"sm"}>Key Merits</DrawerHeader>
<DrawerBody>
<FormControl mb={4}>
<FormLabel fontSize={"sm"}>Title</FormLabel>
<Input
value={fileName}
onChange={(e) => setFileName(e.target.value)}
fontSize={"sm"}
type="text"
size={"sm"}
/>
</FormControl>
<FormControl mb={4}>
<FormLabel fontSize={"sm"}>Sub Title</FormLabel>
<Input
value={fileName}
onChange={(e) => setFileName(e.target.value)}
fontSize={"sm"}
type="textarea"
size={"sm"}
/>
</FormControl>
<FormControl mb={4}>
<FormLabel fontSize={"sm"}>Icon</FormLabel>
<Input
value={file}
onChange={(e) => setFile(e.target.value)}
fontSize={"sm"}
type="file"
className="form-control"
size={"sm"}
/>
</FormControl>
</DrawerBody>
<DrawerFooter>
<Button
variant="outline"
colorScheme={"green"}
rounded={"sm"}
size={"sm"}
mr={3}
onClick={onClose}
>
Cancel
</Button>
<Button
colorScheme={"green"}
rounded={"sm"}
size={"sm"}
onClick={() => setAlert(true)}
>
Save
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
<CustomAlertDialog
isOpen={alert}
onClose={() => setAlert(false)}
alertHandler={handleSave}
message={"Are you sure you want to add this document?"}
/>
</>
);
reset()
};
export default KeyMeritsAdd;
const handleSave = () => {
handleSubmit(onSubmit)();
};
return (
<>
<Drawer
isOpen={isOpen}
placement="right"
initialFocusRef={firstField}
onClose={onClose}
>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader fontSize={"sm"}>Key Merits</DrawerHeader>
<DrawerBody>
<Stack spacing={2}>
<FormControl isInvalid={!!errors.meritsHeader} isRequired={true}>
<FormLabel fontSize={"sm"}>Title</FormLabel>
<Controller
name="meritsHeader"
control={control}
render={({ field }) => (
<Input {...field} fontSize={"sm"} type="text" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.meritsHeader?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={!!errors.meritsDescription} isRequired={true}>
<FormLabel fontSize={"sm"}>Sub Title</FormLabel>
<Controller
name="meritsDescription"
control={control}
render={({ field }) => (
<Input
{...field}
fontSize={"sm"}
type="textarea"
size={"sm"}
/>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.meritsDescription?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={!!errors.iconImage} isRequired={true}>
<FormLabel fontSize={"sm"}>Icon</FormLabel>
<Controller
name="iconImage"
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<Input
type="file"
className="form-control"
onChange={(e) => {
onChange(e.target.files[0]);
}}
onBlur={onBlur}
fontSize={"sm"}
size={"sm"}
/>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500} >
{errors.iconImage?.message}
</FormErrorMessage>
</FormControl>
</Stack>
</DrawerBody>
<DrawerFooter>
<Button
variant="outline"
colorScheme={"green"}
rounded={"sm"}
size={"sm"}
mr={3}
onClick={onClose}
>
Cancel
</Button>
<Button
colorScheme={"green"}
rounded={"sm"}
size={"sm"}
onClick={() => setAlert(true)}
>
Save
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
<CustomAlertDialog
isOpen={alert}
onClose={() => setAlert(false)}
alertHandler={handleSave}
message={"Are you sure you want to add this key merit?"}
isLoading={isLoading}
/>
</>
);
};
export default KeyMeritsAdd;

View File

@@ -0,0 +1,216 @@
import {
Box,
Button,
Drawer,
DrawerBody,
DrawerCloseButton,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerOverlay,
FormControl,
FormErrorMessage,
FormLabel,
Input,
Stack,
useToast,
} from "@chakra-ui/react";
import React, { useEffect, useRef, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import CustomAlertDialog from "../../Components/CustomAlertDialog";
import * as yup from "yup";
import ToastBox from "../../Components/ToastBox";
import { useUpdateKeyMeritsMutation } from "../../Services/io.service";
const keyMeritsSchema = yup.object().shape({
meritsHeader: yup.string().required("Title is required"),
meritsDescription: yup.string().required("Sub title is required"),
iconImage: yup.mixed().required("Icon is required"), // Adjust based on file or string
});
const KeyMeritsEdit = ({ isOpen, onClose, firstField, id, actionId, data }) => {
console.log(actionId);
const toast = useToast()
const [alert, setAlert] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [ editKeyMerits ] = useUpdateKeyMeritsMutation()
const found = data?.find((item)=> item?.id === actionId)
console.log(found);
const {
control,
reset,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(keyMeritsSchema),
});
// useEffect to reset the form when `found` changes
useEffect(() => {
if (found) {
reset({
meritsHeader: found?.meritsHeader,
meritsDescription: found?.meritsDescription,
iconImage: null,
});
}
}, [found, reset]);
const onSubmit = async (data) => {
setIsLoading(true);
try {
const formData = new FormData();
formData.append("meritsHeader", data.meritsHeader);
formData.append("meritsDescription", data.meritsDescription);
if (data.iconImage && data.iconImage instanceof File) {
formData.append("iconImage", data.iconImage);
}
const id = actionId
const res = await editKeyMerits({ data: formData, id });
if (res?.data?.statusCode === 201) {
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
setAlert(false);
onClose();
setIsLoading(false);
reset()
return
}
if(res?.error?.data?.code === 400){
toast({
render: () => <ToastBox message={res?.error?.data?.message} status={'error'} />,
});
setAlert(false);
onClose();
setIsLoading(false);
reset()
return
}
} catch (error) {
if (error) {
toast({
render: () => <ToastBox message={"Something went wrong, please try again!"} status={'error'} />,
});
}
setIsLoading(false);
setAlert(false);
onClose();
reset()
}
reset()
};
const handleSave = () => {
handleSubmit(onSubmit)();
};
return (
<>
<Drawer
isOpen={isOpen}
placement="right"
initialFocusRef={firstField}
onClose={onClose}
>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader fontSize={"sm"}>Edit Key Merits</DrawerHeader>
<DrawerBody>
<Stack spacing={2}>
<FormControl isInvalid={!!errors.meritsHeader} isRequired={true}>
<FormLabel fontSize={"sm"}>Title</FormLabel>
<Controller
name="meritsHeader"
control={control}
render={({ field }) => (
<Input {...field} fontSize={"sm"} type="text" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.meritsHeader?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={!!errors.meritsDescription} isRequired={true}>
<FormLabel fontSize={"sm"}>Sub Title</FormLabel>
<Controller
name="meritsDescription"
control={control}
render={({ field }) => (
<Input
{...field}
fontSize={"sm"}
type="textarea"
size={"sm"}
/>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.meritsDescription?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={!!errors.iconImage} isRequired={true}>
<FormLabel fontSize={"sm"}>Icon</FormLabel>
<Controller
name="iconImage"
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<Input
type="file"
className="form-control"
onChange={(e) => {
onChange(e.target.files[0]);
}}
onBlur={onBlur}
fontSize={"sm"}
size={"sm"}
/>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500} >
{errors.iconImage?.message}
</FormErrorMessage>
</FormControl>
</Stack>
</DrawerBody>
<DrawerFooter>
<Button
variant="outline"
colorScheme={"green"}
rounded={"sm"}
size={"sm"}
mr={3}
onClick={onClose}
>
Cancel
</Button>
<Button
colorScheme={"green"}
rounded={"sm"}
size={"sm"}
onClick={() => setAlert(true)}
>
Save
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
<CustomAlertDialog
isOpen={alert}
onClose={() => setAlert(false)}
alertHandler={handleSave}
message={"Are you sure you want to add this key merit?"}
isLoading={isLoading}
/>
</>
);
};
export default KeyMeritsEdit;

View File

@@ -16,10 +16,8 @@ import React, { useContext } from "react";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
const InvestmentView = ({ isOpen, onClose, secondField, id }) => {
console.log(id);
const { create, setCreate } = useContext(GlobalStateContext);
const filteredObject = create?.find((item) => item?.id === id)
console.log(filteredObject);
return (
<Drawer
isOpen={isOpen}

View File

@@ -28,7 +28,6 @@ const ExchangeRate = () => {
const [statusFilter, setStatusFilter] = useState("all");
console.log(investment);
useEffect(() => {
// Simulate loading
@@ -70,7 +69,7 @@ const ExchangeRate = () => {
);
return (
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"}>
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} >
<Tabs position="relative" variant="unstyled" mt={2}>
<TabList>
{/* <Tab fontSize={"sm"}>All</Tab> */}

View File

@@ -35,6 +35,8 @@ import Pagination from "../../../Components/Pagination";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
import ToastBox from "../../../Components/ToastBox";
import { useGetIOsQuery } from "../../../Services/io.service";
import { TABLE_PAGINATION } from "../../../Constants/Paginations";
// import { debounce } from "./AddIOCharges";
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
@@ -42,130 +44,124 @@ const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date
const ViewIOTable = () => {
const navigate = useNavigate();
const toast = useToast();
const { IODetails, setIODetails, slideFromRight } = useContext(GlobalStateContext);
const { IODetails, setIODetails, slideFromRight } =
useContext(GlobalStateContext);
const [searchTerm, setSearchTerm] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [statusFilter, setStatusFilter] = useState("all");
// const [isLoading, setIsLoading] = useState(true);
const [deleteAlert, setDeleteAlert] = useState(false);
const [actionId, setActionId] = useState(false);
const [mouseEntered, setMouseEntered] = useState(false);
const [mouseEnteredId, setMouseEnteredId] = useState("");
// ===============================[ Paginations ]
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
const [currentPage, setCurrentPage] = useState(1);
useEffect(() => {
// Simulate loading
const timer = setTimeout(() => {
setIsLoading(false);
}, 1500);
// ===============================[ RTK Api calls ]
const {
data,
isLoading,
error,
} = useGetIOsQuery({ page: currentPage, size: pageSize });
console.log(data);
// Cleanup the timer on component unmount
return () => clearTimeout(timer);
}, []);
// ====================================================[Table Setup]================================================================
// ===============================[ Table Header ]
const tableHeadRow = [
// "Sr.no",
"Deal ID",
"IO ID",
"IO Name",
"Sponsorer Name",
"IO status",
"Sponsorer",
"Investment Type",
"Goal Amount",
"Holding Period",
"IO Status",
"Action",
];
// const handleUpdateStatus = debounce((id) => {
// setInvestmentType((prevInvestmentType) =>
// prevInvestmentType.map((investmentType) =>
// investmentType.id === id
// ? { ...investmentType, status: !investmentType.status }
// : investmentType
// )
// );
// toast({
// render: () => <ToastBox message={"Status changed succesfully.!"} />,
// });
// }, 300);
console.log(IODetails);
// ====================================================[Table Filter]================================================================
const filteredData = IODetails.filter((item) => {
const filteredData = data?.data?.rows?.filter((item) => {
// Filter by name (case insensitive)
const name = item.ioName;
const name = item.investmentNameEnglish;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
// Filter by status
// const status = item.status;
// const statusLower = status ? "active" : "inactive";
const status = item?.ioStatus?.statusAdmin;
const statusMatches =
statusFilter === "all" ||
(status && status.toLowerCase() === statusFilter.toLowerCase());
// const statusMatches =
// statusFilter === "all" ||
// (statusFilter === "active" && status === true) ||
// (statusFilter === "inactive" && status === false);
return nameMatches;
return nameMatches && statusMatches;
});
const extractedArray = filteredData?.map((item, index) => ({
"Sr.no": (
<Text
justifyContent={slideFromRight ? "right" : "left"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{index + 1}
</Text>
),
"Deal ID": (
<Text
justifyContent={slideFromRight ? "right" : "left"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.id}
</Text>
"IO ID": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item.io_id ? item.io_id : "---"}
</Text>
</Box>
),
"IO Name": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item.ioName}
{item.investmentNameEnglish ? item.investmentNameEnglish : "---"}
</Text>
</Box>
),
"Sponsorer Name": (
Sponsorer: (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item.sponserName}
{item.sponsor ? item.sponsor : "---"}
</Text>
</Box>
),
"IO status": (
"Investment Type": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item.investmentType ? item.investmentType : "---"}
</Text>
</Box>
),
"Goal Amount": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item.goalAmount ? item.goalAmount : "---"}
</Text>
</Box>
),
"Holding Period": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item.holdingPeriod ? item.holdingPeriod : "---"}
</Text>
</Box>
),
"IO Status": (
<Box w={"auto"} isTruncated={true}>
<Badge
rounded={'md'}
rounded={"md"}
pt={0.5}
pb={0.5}
ps={4}
pe={4}
textTransform={'none'}
textTransform={"none"}
color={
item.ioStatus === "Open"
? "#00B69B"
item?.ioStatus?.statusAdmin === "Draft"
? "yellow.500"
: item.ioStatus === "Pending"
? "#6226EF"
: "#EF3826"
}
colorScheme={
item.ioStatus === "Open"
? "green"
: item.ioStatus === "Pending"
item?.ioStatus?.statusAdmin === "Draft"
? "yellow"
: item.ioStatus?.statusAdmin === "Pending"
? "purple"
: "red"
}
>
{item.ioStatus}
{item.ioStatus?.statusAdmin}
</Badge>
</Box>
),
@@ -194,8 +190,6 @@ const ViewIOTable = () => {
</Button>
</Tooltip>
<Tooltip
rounded={"sm"}
fontSize={"xs"}
@@ -244,16 +238,9 @@ const ViewIOTable = () => {
),
}));
const handleDelete = () => {
const upDatedIO = IODetails.filter((viewIO) => viewIO.id !== actionId);
const handleDelete = () => {};
setTimeout(() => {
setIODetails(upDatedIO);
setDeleteAlert(false);
setIsLoading(false);
}, 100);
setIsLoading(true);
};
// console.log(IOisLoading);
return (
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={38}>
@@ -279,6 +266,26 @@ const ViewIOTable = () => {
/>
<HStack display={"flex"} alignItems={"center"}>
<Select
onChange={(e) => setStatusFilter(e.target.value)}
focusBorderColor="green.500"
size={"sm"}
fontSize={"xs"}
cursor={"pointer"}
value={statusFilter} // Use the value prop here
>
<option value="all" selected disabled hidden defaultChecked>
Status
</option>
<option value="all">All</option>
<option value="Draft">Draft</option>
<option value="Cancelled">Cancelled</option>
<option value="Processing">Processing</option>
<option value="Open">Open</option>
<option value="Exited">Exited</option>
<option value="Closed">Closed</option>
</Select>
<Pagination totalItems={10} />
{/* <Link to={"/create-io"}>

View File

@@ -55,7 +55,7 @@ const ViewIOdata = () => {
];
return (
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} overflowX={"hidden"} height={"100vh"} pb={14} >
<Box paddingInline={"12px"} mt={2}>
{/* <span
onClick={() => navigate(-1)}

View File

@@ -46,9 +46,6 @@ const ViewIOdataHeader = () => {
const { isOpen, onOpen, onClose } = useDisclosure();
const btnRef = useRef();
const { IODetails } = useContext(GlobalStateContext);
const foundObject = IODetails?.find(
(item) => item?.id.toString() === id?.toString()
);
const {
isOpen: isInvestmentOpen,
@@ -125,7 +122,7 @@ const ViewIOdataHeader = () => {
position={"relative"}
>
<Box h={100} w={200} p={1.5} >
{/* <Image rounded={'md'} h={"100%"} src={foundObject?.ioName} alt={foundObject?.ioName}/> */}
{/* <Image rounded={'md'} h={"100%"} src={IODetails?.ioName} alt={IODetails?.ioName}/> */}
<Box w={'100%'} h={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'} bg={"#fff"} rounded={'md'}>
<Icon color={'gray.700'} as={GrGallery} />
</Box>
@@ -144,7 +141,7 @@ const ViewIOdataHeader = () => {
IO Name
</Text>
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
{id ? foundObject?.ioName : "---"}
{IODetails?.investmentNameEnglish ? IODetails?.investmentNameEnglish : "---"}
</Text>
</Box>
@@ -153,7 +150,7 @@ const ViewIOdataHeader = () => {
Sponsorer Name
</Text>
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
{id ? foundObject?.sponserName : "---"}
{IODetails?.sponsor ? IODetails?.sponsor : "---"}
</Text>
</Box>
@@ -169,21 +166,21 @@ const ViewIOdataHeader = () => {
pe={4}
textTransform={"none"}
color={
foundObject?.ioStatus === "Open"
IODetails?.ioStatus?.statusAdmin === "Draft"
? "#00B69B"
: foundObject?.ioStatus === "Pending"
: IODetails?.ioStatus?.statusAdmin === "Pending"
? "#6226EF"
: "#EF3826"
}
colorScheme={
foundObject?.ioStatus === "Open"
IODetails?.ioStatus?.statusAdmin === "Draft"
? "green"
: foundObject?.ioStatus === "Pending"
: IODetails?.ioStatus?.statusAdmin === "Pending"
? "purple"
: "red"
}
>
{id ? foundObject?.ioStatus : "---"}
{IODetails?.ioStatus?.statusAdmin ? IODetails?.ioStatus?.statusAdmin : "---"}
</Badge>
</Box>
<Box display={"flex"} flexDirection={"column"} gap={2}>

View File

@@ -1,5 +1,5 @@
import { Box, Button } from "@chakra-ui/react";
import React, { useContext } from "react";
import React, { useContext, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useForm } from "react-hook-form";
@@ -7,106 +7,265 @@ import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import DataTable from "../../../Components/DataTable/DataTable";
import FormInputView from "../../../Components/FormInputView";
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
import { useGetIOByIdQuery } from "../../../Services/io.service";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { formatDate } from "../../Master/Sponser/Sponsers";
const schema = yup.object().shape({
investmentNameEnglish: yup
.string()
.required("IO name in English is required")
.min(3, "IO name in English must be at least 3 characters long")
.max(50, "IO name in English must be at most 50 characters long"),
investmentNameArabic: yup
.string()
.required("IO name in Arabic is required")
.min(3, "IO name in Arabic must be at least 3 characters long")
.max(50, "IO name in Arabic must be at most 50 characters long"),
descriptionEnglish: yup
.string()
.required("Description in English is required")
.min(10, "Description in English must be at least 10 characters long")
.max(500, "Description in English must be at most 500 characters long"),
descriptionArabic: yup
.string()
.required("Description in Arabic is required")
.min(10, "Description in Arabic must be at least 10 characters long")
.max(500, "Description in Arabic must be at most 500 characters long"),
goalAmount: yup
.number()
.required("Goal amount is required")
.positive("Goal amount must be a positive number")
.min(1, "Goal amount must be at least 1"),
closingDate: yup
.date()
.required("Closing date is required")
.min(new Date(), "Closing date cannot be in the past"),
holdingPeriod: yup
.number()
.required("Holding period is required")
.positive("Holding period must be a positive number")
.min(1, "Holding period must be at least 1 month"),
// minInvestmentAmount: yup
// .number()
// .required("Minimum investment is required")
// .positive("Minimum investment must be a positive number")
// .min(1, "Minimum investment must be at least 1"),
ISIN: yup.string(),
InvestmentDetails: yup.string(),
comment: yup.string(),
expectedReturn: yup
.number()
.required("Expected return is required")
.positive("Expected return must be a positive number")
.min(0.01, "Expected return must be at least 0.01"),
});
const ViewIOdetails = () => {
const navigate = useNavigate()
const params = useParams();
const { IODetails } = useContext(GlobalStateContext);
console.log(IODetails);
const { reset } = useForm(); // assuming react-hook-form
const id = params?.id
const { IODetails, setIODetails } = useContext(GlobalStateContext);
const id = params?.id;
console.log(id);
const foundObject = IODetails?.find(
(item) => item?.id.toString() === id.toString()
);
const {
data: IObyID,
isLoading: IObyIDisLoading,
error: IObyIDerror,
} = useGetIOByIdQuery(id, { skip: !id });
const formFields = [
{
label: "IO Name",
value: foundObject?.ioName,
width: "49%",
section: "",
},
{
label: "IO Name (Arabic)",
value: foundObject?.ioNameArabic,
width: "49%",
section: "",
},
{
label: "Description",
value: foundObject?.discription,
width: "49%",
section: "",
},
{
label: "Description (Arabic)",
value: foundObject?.discriptionArabic,
width: "49%",
section: "",
},
{
label: "Investment Type",
value: foundObject?.typeName,
width: "32.3%",
section: "",
},
// {
// label: "Investment Type (Arabic)",
// value: foundObject?.typeName,
// width: "49%",
// section: "",
// },
{
label: "Sponsorer Name",
value: foundObject?.sponserName,
width: "32.3%",
section: "",
},
{
label: "Goal Amount",
value: foundObject?.goalAmount,
width: "32.3%",
section: "",
},
{
label: "Minimum Investment Amount",
value: foundObject?.minInvestment,
width: "32.3%",
section: "",
},
{
label: "Maximum Investment Amount",
value: foundObject?.maxInvestment,
width: "32.3%",
section: "",
},
{
label: "Holding Period",
value: foundObject?.holdingPeriod,
width: "32.3%",
section: "",
},
{
label: "Expected Return Estimated",
value: foundObject?.expectedReturn,
width: "32.3%",
section: "",
},
{
label: "Closing Date",
value: foundObject?.closingDate,
width: "32.3%",
section: "",
},
// {
// label: "IO Status",
// value: foundObject?.ioStatus,
// width: "32.3%",
// section: "",
// },
];
// ======================[ Validator filter ]
const {
control,
reset,
setValue,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
});
useEffect(() => {
setIODetails(IObyID?.data);
if (IObyID?.data) {
reset({
investmentNameEnglish: IObyID?.data?.investmentNameEnglish,
investmentNameArabic: IObyID?.data?.investmentNameArabic,
descriptionEnglish: IObyID?.data?.descriptionEnglish,
descriptionArabic: IObyID?.data?.descriptionArabic,
goalAmount: IObyID?.data?.goalAmount,
closingDate: IObyID?.data?.closingDate,
holdingPeriod: IObyID?.data?.holdingPeriod,
ISIN: IObyID?.data?.ISIN,
comment: IObyID?.data?.comment,
expectedReturn: IObyID?.data?.expectedReturn,
investmentType_xid: IObyID?.data?.investmentType_xid,
investmentType_xid: IObyID?.data?.investmentType_xid,
InvestmentDetails: IObyID?.data?.InvestmentDetails,
minInvestmentAmount: IObyID?.data?.minInvestmentAmount,
});
}
}, [id, IObyID]);
//=======================[ Editor ]
const formFields = [
{
label: "IO Name",
value: IObyID?.data?.investmentNameEnglish ? IObyID?.data?.investmentNameEnglish : "---",
name: "investmentNameEnglish",
type: "text",
section: " ",
width: "49%",
isRequired: true,
},
{
label: "IO Name (Arabic)",
name: "investmentNameArabic",
type: "text",
value: IObyID?.data?.investmentNameArabic ? IObyID?.data?.investmentNameArabic : "---",
isRequired: true,
arabic: true,
section: " ",
width: "49%",
},
{
label: "Description",
name: "descriptionEnglish",
value: IObyID?.data?.descriptionEnglish ? IObyID?.data?.descriptionEnglish : "---",
type: "textarea",
isRequired: true,
section: " ",
width: "49%",
},
{
label: "Description (Arabic)",
name: "descriptionArabic",
value: IObyID?.data?.descriptionArabic ? IObyID?.data?.descriptionArabic : "---",
type: "textarea",
isRequired: true,
arabic: true,
section: " ",
width: "49%",
},
{
label: "Goal Amount",
placeHolder: "$00.00",
value: IObyID?.data?.goalAmount ? IObyID?.data?.goalAmount : "---",
name: "goalAmount",
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
{
label: "Closing Date",
name: "closingDate",
type: "date",
isRequired: true,
value: IObyID?.data?.closingDate ? formatDate(IObyID?.data?.closingDate) : "---",
section: " ",
width: "32.3%",
},
{
label: "Holding Period",
name: "holdingPeriod",
value: IObyID?.data?.holdingPeriod?IObyID?.data?.holdingPeriod:"---",
type: "number",
isRequired: true,
placeHolder: "1Y",
section: " ",
width: "32.3%",
},
{
label: "Minimum Investment Amount",
placeHolder: "$00.00",
name: "minInvestmentAmount",
value: IObyID?.data?.minInvestmentAmount?IObyID?.data?.minInvestmentAmount:'---',
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
{
label: "ISIN",
placeHolder: "$00.00",
name: "ISIN",
value: IObyID?.data?.ISIN?IObyID?.data?.ISIN:"---",
type: "number",
section: " ",
width: "32.3%",
},
{
label: "Investment Details",
placeHolder: "",
name: "InvestmentDetails",
value: IObyID?.data?.InvestmentDetails?IObyID?.data?.InvestmentDetails:"---",
type: "text",
section: " ",
width: "32.3%",
},
{
label: "Expected Return Estimated",
placeHolder: "$00.00",
name: "expectedReturn",
type: "number",
isRequired: true,
value: IObyID?.data?.expectedReturn?IObyID?.data?.expectedReturn:'---',
section: " ",
width: "32.3%",
},
{
label: "Investment Type",
placeHolder: "Select option",
value: IObyID?.data?.investmentType_xid?IObyID?.data?.investmentType_xid:"---",
name: "investmentType_xid",
type: "select",
isRequired: true,
section: " ",
width: "32.3%",
},
{
label: "Sponsorer Name",
placeHolder: "Select option",
name: "sponsor_xid",
type: "select",
// options: sponserNameOption,
value: IObyID?.data?.sponsor_xid?IObyID?.data?.sponsor_xid:"---",
section: " ",
isRequired: true,
width: "32.3%",
},
{
label: "Comment",
placeHolder: "Enter comment here",
name: "comment",
type: "textarea",
value: IObyID?.data?.comment?IObyID?.data?.comment:"---",
section: " ",
width: "100%",
},
];
const groupedFields = formFields.reduce((groups, field) => {
const { section } = field;
@@ -117,11 +276,11 @@ const ViewIOdetails = () => {
return groups;
}, {});
if (!foundObject) {
if (!IObyID?.data) {
return <FullscreenLoaders/>;
}
return <Box position={'relative'}>
return <Box position={'relative'} >
<Button position={'absolute'} right={0} onClick={()=> navigate(`/create-io/${params?.id}`)} ps={4} pe={4} colorScheme="green" rounded={"sm"} size={'xs'}>Edit IO</Button> <FormInputView groupedFields={groupedFields} /> </Box>;
};

View File

@@ -96,7 +96,6 @@ const AddInvestmentType = () => {
setSelectedOtherImageData(newSelectedImageData);
};
console.log(selectedBannerImageData);
const formFields = [
{
@@ -152,7 +151,6 @@ const AddInvestmentType = () => {
]);
navigate("/investment-type");
console.log(investmentType);
};
return (

View File

@@ -27,13 +27,10 @@ const EditInvestmentType = () => {
});
useEffect(() => {
console.log(investmentType);
const id = params?.id;
console.log(id);
// Ensure id is compared correctly
const found = investmentType.find((item) => item?.id.toString() === id.toString());
console.log(found?.swiftCode);
setFoundObject(found);
if (found) {

View File

@@ -37,6 +37,7 @@ import ToastBox from "../../../Components/ToastBox";
import { debounce } from "./AddInvestmentType";
import DataTable from "../../../Components/DataTable/DataTable";
import SwitchButton from "../../../Components/SwitchButton";
import { useGetInvestmentTypesQuery } from "../../../Services/investment.type.service";
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
@@ -53,6 +54,17 @@ const InvestmentType = () => {
const [mouseEnteredId, setMouseEnteredId] = useState("");
const [isSwitchOn, setIsSwitchOn] = useState(false);
const {
data: investmentTypes,
isLoading: investmentTypesLoading,
error,
} = useGetInvestmentTypesQuery({ page: 1, size: 10 })
console.log(investmentTypes);
useEffect(() => {
// Simulate loading
const timer = setTimeout(() => {
@@ -68,7 +80,6 @@ const InvestmentType = () => {
"Sr.no",
"Investment Type",
"Description",
"Status",
"Action",
];

View File

@@ -40,6 +40,7 @@ export function debounce(func, delay) {
const AddSponser = () => {
const params = useParams();
const id = params?.id
const navigate = useNavigate();
const [bannerImageData, setBannerImageData] = useState(null);
const [selectedBannerImageData, setSelectedBannerImageData] = useState(null);
@@ -49,7 +50,9 @@ const AddSponser = () => {
const { sponser, setSponser } = useContext(GlobalStateContext);
const [createSponser] = useCreateSponserMutation();
const [updateSponser] = useUpdateSponserMutation();
const { data, error, isLoading } = useGetSponserByIdQuery(params?.id);
const { data, error, isLoading } = useGetSponserByIdQuery(id, { skip: !id });
const {
control,
@@ -62,21 +65,20 @@ const AddSponser = () => {
console.log(errors);
useEffect(() => {
if (data) {
reset({
sponsorName: data?.data?.sponsorName,
mobileNo: data?.data?.mobileNo,
sponsorNameArabic: data?.data?.sponsorNameArabic,
});
}
}, [data, reset]);
// useEffect(() => {
// if (data) {
// reset({
// sponsorName: data?.data?.sponsorName,
// mobileNo: data?.data?.mobileNo,
// sponsorNameArabic: data?.data?.sponsorNameArabic,
// });
// }
// }, [data, reset]);
if (isLoading) {
return <FullscreenLoaders />;
}
// console.log(selectedBannerImageData);
const formFields = [
{
@@ -167,7 +169,6 @@ const AddSponser = () => {
const id = params?.id
try {
await createSponser(data).then((response) => {
console.log(response);
if (response?.data?.statusCode) {
toast({
render: () => <ToastBox message={response?.data?.message} />,

View File

@@ -36,7 +36,7 @@ import {
useToggleStatusMutation,
} from "../../../Services/sponser.service";
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
export const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
const Sponser = () => {
const navigate = useNavigate();
@@ -83,6 +83,7 @@ const Sponser = () => {
// ====================================================[Table Setup]================================================================
const tableHeadRow = [
"Sponsor name",
"Sponsor name (Arabic)",
"Mobile no",
"Status",
"Created At",
@@ -155,6 +156,16 @@ const Sponser = () => {
{item.sponsorName}
</Text>
),
"Sponsor name (Arabic)":(<Text
justifyContent={slideFromRight ? "right" : "left"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.sponsorNameArabic}
</Text>),
"Mobile no": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
@@ -192,7 +203,7 @@ const Sponser = () => {
),
Action: (
<Box display={"flex"} justifyContent={"center"} gap={2}>
<Tooltip
{/* <Tooltip
rounded={"sm"}
fontSize={"xs"}
label="View"
@@ -203,7 +214,7 @@ const Sponser = () => {
<Button
// onClick={() => navigate(`/view-sponser/${item.id}`) }
onClick={() => {
navigate(`view-sponser/${item.id}`);
navigate(`/sponser/view-sponser/${item.id}`);
}}
_hover={{ color: "green.500" }}
// transition={"0.5s all"}
@@ -213,7 +224,7 @@ const Sponser = () => {
>
<ViewIcon />
</Button>
</Tooltip>
</Tooltip> */}
<Tooltip
rounded={"sm"}
@@ -320,7 +331,7 @@ const Sponser = () => {
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
isLoading={isLoading}
isLoading={isSponserLoading}
viewActionId={actionId}
setViewActionId={setActionId}
// totalPages={10}

View File

@@ -0,0 +1,25 @@
// io.service.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { api } from "./api.service";
const baseUrl = api?.defaults.baseURL;
export const keyMerits = createApi({
reducerPath: "ioService",
baseQuery: fetchBaseQuery({ baseUrl }),
tagTypes: ["getKeyMerits"],
endpoints: (builder) => ({
// =====[get]
getKeyMerits: builder.query({
query: (id) => `/io/admin/key-merits/${id}`,
providesTags: ["getKeyMerits"],
}),
}),
});
// Export hooks for usage in functional components
export const {
useGetKeyMeritsQuery,
} =
keyMerits;

View File

@@ -0,0 +1,56 @@
// io.service.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { api } from "./api.service";
const baseUrl = api?.defaults.baseURL;
export const ioService = createApi({
reducerPath: "ioService",
baseQuery: fetchBaseQuery({ baseUrl }),
tagTypes: ["getInvestmentDocuments"],
endpoints: (builder) => ({
// =====[get]
getInvestmentDocuments: builder.query({
query: ({ page, size }) => `/io/admin?page=${page}&size=${size}`,
providesTags: ["getInvestmentDocuments"],
}),
getInvestmentDocumentsById: builder.query({
query: (id) => ({ url: `/io/admin/${id}` }),
providesTags: ["getInvestmentDocuments"],
}),
// =====[create]
createInvestmentDocuments: builder.mutation({
query: ({data, id}) => ({
url: `/io/admin/document/${id}`,
method: "POST",
body: data,
}),
invalidatesTags: ["getInvestmentDocuments"],
}),
updateIO: builder.mutation({
query: ({ data, id }) => ({
url: `/io/admin/${id}`,
method: "PATCH",
body: data,
}),
invalidatesTags: ["getInvestmentDocuments"],
}),
}),
});
// Export hooks for usage in functional components
export const {
useCreateInvestmentDocumentsMutation,
} =
ioService;

View File

@@ -1,7 +1,8 @@
// investmentType.service.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { api } from "./api.service";
const baseUrl = import.meta.env.VITE_API_BASE_URL + "/api";
const baseUrl = api?.defaults.baseURL;
// Define a service using a base URL and expected endpoints
export const investmentType = createApi({
@@ -10,10 +11,10 @@ export const investmentType = createApi({
tagTypes: [],
endpoints: (builder) => ({
getInvestmentTypes: builder.query({
query: () => '/getInvestmentTypes',
query: ({ page, size }) => `/investmentType/admin?page=${page}&size=${size}`,
}),
getInvestmentTypeById: builder.query({
query: (id) => `/getInvestmentType/${id}`,
query: (id) => `/investmentType/admin/${id}`,
}),
}),
});

View File

@@ -1,22 +1,117 @@
// io.service.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { api } from "./api.service";
const baseUrl = import.meta.env.VITE_API_BASE_URL + "/api";
const baseUrl = api?.defaults.baseURL;
// Define a service using a base URL and expected endpoints
export const ioService = createApi({
reducerPath: "ioService",
baseQuery: fetchBaseQuery({ baseUrl }),
tagTypes: [],
tagTypes: ["getIO", "getKeyMerits", "getArtifacts"],
endpoints: (builder) => ({
// =====[get]
getIOs: builder.query({
query: () => '/getIOs',
query: ({ page, size }) => `/io/admin?page=${page}&size=${size}`,
providesTags: ["getIO"],
}),
getIOById: builder.query({
query: (id) => `/getIO/${id}`,
query: (id) => ({ url: `/io/admin/${id}` }),
providesTags: ["getIO"],
}),
// =====[create]
createIO: builder.mutation({
query: (data) => ({
url: `/io/admin`,
method: "POST",
body: data,
}),
invalidatesTags: ["getIO"],
}),
updateIO: builder.mutation({
query: ({ data, id }) => ({
url: `/io/admin/${id}`,
method: "PATCH",
body: data,
}),
invalidatesTags: ["getIO"],
}),
// =====[Key Merits]
getKeyMerits: builder.query({
query: (id) => `/io/admin/key-merits/${id}`,
providesTags: ["getKeyMerits"],
}),
createKeyMerits: builder.mutation({
query: ({ data, id }) => ({
url: `/io/admin/key-merits/${id}`,
method: "POST",
body: data,
// No need to manually set 'Content-Type'
}),
invalidatesTags: ["getKeyMerits"],
}),
deleteKeyMerits: builder.mutation({
query: (id) => ({
url: `/io/admin/key-merits/hard-delete/${id}`,
method: "DELETE",
}),
invalidatesTags: ["getKeyMerits"],
}),
updateKeyMerits: builder.mutation({
query: ({ data, id }) => ({ url: `/io/admin/key-merits/byId/${id}` ,
method: "PATCH",
body: data,
}),
invalidatesTags: ["getKeyMerits"],
}),
// =====[Artifacts]
getArtifacts: builder.query({
query: (id) => `/io/admin/artifact/${id}`,
providesTags: ["getArtifacts"],
}),
}),
});
// Export hooks for usage in functional components
export const { useGetIOsQuery, useGetIOByIdQuery } = ioService;
export const {
useGetIOsQuery,
useGetIOByIdQuery,
useCreateIOMutation ,
useUpdateIOMutation,
useGetKeyMeritsQuery,
useCreateKeyMeritsMutation,
useDeleteKeyMeritsMutation,
useUpdateKeyMeritsMutation,
useGetArtifactsQuery,
} =
ioService;

View File

@@ -4,7 +4,6 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { api } from "./api.service";
const baseUrl = api?.defaults.baseURL;
console.log(baseUrl);
// const baseUrl = `${import.meta.env.VITE_API_BASE_URL}/${import.meta.env.VITE_API_VERSION}`
@@ -14,11 +13,21 @@ export const sponserMaster = createApi({
baseQuery: fetchBaseQuery({ baseUrl: baseUrl }),
tagTypes: ["getSponser"],
endpoints: (builder) => ({
getSponserMaster: builder.query({
query: ({ page, size }) => `/sponsor/admin?page=${page}&size=${size}`,
providesTags: ["getSponser"],
}),
getActiveSponserMaster: builder.query({
query: () => `/sponsor/admin/active`,
providesTags: ["getSponser"],
}),
getSponserMasterActive: builder.query({
query: () => "/sponsor/admin/active",
}),
@@ -72,5 +81,6 @@ export const {
useCreateSponserMutation,
useUpdateSponserMutation,
useGetSponserByIdQuery,
useDeleteSponserMutation
useDeleteSponserMutation,
useGetActiveSponserMasterQuery
} = sponserMaster;

View File

@@ -7,6 +7,7 @@ import { ioService } from "../Services/io.service";
import { investorDetails } from "../Services/investor.details.service";
import { investorTransaction } from "../Services/investor.transaction.service";
import { api } from "../Services/api.service";
import { keyMerits } from "../Services/Key.merits.service";
export const store = configureStore({
reducer: {
@@ -29,7 +30,7 @@ export const store = configureStore({
exchangeRate.middleware,
ioService.middleware,
investorDetails.middleware,
investorTransaction.middleware
investorTransaction.middleware,
),
});