405 lines
11 KiB
JavaScript
405 lines
11 KiB
JavaScript
import React, { useContext, useEffect, useState } from "react";
|
|
import {
|
|
Badge,
|
|
Box,
|
|
Button,
|
|
HStack,
|
|
Input,
|
|
Select,
|
|
Text,
|
|
Tooltip,
|
|
useToast,
|
|
} from "@chakra-ui/react";
|
|
import { useForm } from "react-hook-form";
|
|
import { yupResolver } from "@hookform/resolvers/yup";
|
|
import * as yup from "yup";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { OPACITY_ON_LOAD } from "../../Layout/animations";
|
|
import FormInputMain from "../../Components/FormInputMain";
|
|
import {
|
|
useGetContactQuery,
|
|
useSendNotificationMutation,
|
|
useUpdateContactMutation,
|
|
} from "../../Services/contact.service";
|
|
import FullscreenLoaders from "../../Components/Loaders/FullscreenLoaders";
|
|
import ToastBox from "../../Components/ToastBox";
|
|
import NormalTable from "../../Components/DataTable/NormalTable";
|
|
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
|
import { useGetInvestorsQuery } from "../../Services/investor.details.service";
|
|
import {
|
|
INVESTOR_TABLE_PAGINATION,
|
|
TABLE_PAGINATION,
|
|
} from "../../Constants/Paginations";
|
|
import { formatDate, generateSerialNumber } from "../../Constants/Constants";
|
|
import { ViewIcon } from "@chakra-ui/icons";
|
|
import { useGetUnbanInvestorQuery } from "../../Services/ban.investor.service";
|
|
|
|
export const notification = yup.object().shape({
|
|
title: yup.string().required("Notification Header is required"),
|
|
ManualDate: yup
|
|
.date()
|
|
.required("Manual Date is required")
|
|
.typeError("Invalid date format"),
|
|
ManualTime: yup
|
|
.string()
|
|
.required("Manual Time is required")
|
|
.matches(
|
|
/^([01]\d|2[0-3]):?([0-5]\d)$/,
|
|
"Invalid time format, must be in HH:mm"
|
|
),
|
|
expectedReturn: yup.string().required("Expected Return is required"),
|
|
});
|
|
|
|
export const notificationNew = yup.object().shape({
|
|
title: yup.string().required("Notification Header is required"),
|
|
message: yup.string().notRequired(),
|
|
});
|
|
|
|
const Notification = () => {
|
|
const toast = useToast();
|
|
const navigate = useNavigate();
|
|
const [form, setForm] = useState({});
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [selectedRadio, setSelectedRadio] = useState([]);
|
|
const [pageSize, setPageSize] = useState(INVESTOR_TABLE_PAGINATION?.size);
|
|
const [currentPage, setCurrentPage] = useState(
|
|
INVESTOR_TABLE_PAGINATION?.page
|
|
);
|
|
const [searchTerm, setSearchTerm] = useState("");
|
|
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
|
|
const [country, setCountry] = useState("");
|
|
const [kyc, setKyc] = useState("");
|
|
|
|
const {
|
|
control,
|
|
reset,
|
|
watch,
|
|
handleSubmit,
|
|
formState: { errors },
|
|
} = useForm({
|
|
resolver: yupResolver(notificationNew),
|
|
|
|
defaultValues: {
|
|
title: "",
|
|
message: "",
|
|
},
|
|
});
|
|
|
|
console.log(errors);
|
|
|
|
const {
|
|
data: contact,
|
|
isLoading: contactLoading,
|
|
error,
|
|
} = useGetContactQuery();
|
|
|
|
const formatDate = (date) => {
|
|
return new Date(date).toLocaleDateString("en-GB", {
|
|
day: "2-digit",
|
|
month: "2-digit",
|
|
year: "numeric",
|
|
});
|
|
};
|
|
|
|
// const {
|
|
// data: investorDetails,
|
|
// isLoading: investorDetailsLoading,
|
|
// // error,
|
|
// } = useGetInvestorsQuery({ page: currentPage, size: pageSize });
|
|
|
|
useEffect(() => {
|
|
const handler = setTimeout(() => {
|
|
setDebouncedSearchTerm(searchTerm.trim()); // Trim to remove leading/trailing spaces
|
|
}, 300);
|
|
return () => clearTimeout(handler);
|
|
}, [searchTerm]);
|
|
|
|
const {
|
|
data: investorDetails,
|
|
isLoading: investorDetailsLoading,
|
|
refetch,
|
|
} = useGetUnbanInvestorQuery(
|
|
{
|
|
page: 1, // Omit pagination for search
|
|
size: 10000, // Omit pagination for search
|
|
// page: debouncedSearchTerm ? undefined : currentPage, // Disable pagination for search
|
|
// size: debouncedSearchTerm ? undefined : 10000 || pageSize || 500, // Disable pagination for search
|
|
search: debouncedSearchTerm, // Pass search term
|
|
country_xid: country,
|
|
KYCStatus: kyc,
|
|
},
|
|
{
|
|
skip: searchTerm !== "" && debouncedSearchTerm === "", // Skip if search not debounced yet
|
|
}
|
|
);
|
|
|
|
// useEffect(() => {
|
|
// console.log("Search Term:", searchTerm);
|
|
// console.log("Debounced Search Term:", debouncedSearchTerm);
|
|
// console.log("Investor Details:", investorDetails);
|
|
// }, [searchTerm, debouncedSearchTerm, investorDetails]);
|
|
|
|
const [sendNotification] = useSendNotificationMutation();
|
|
|
|
if (contactLoading) {
|
|
return <FullscreenLoaders />;
|
|
}
|
|
|
|
const formFields = [
|
|
{
|
|
label: "Notification Header",
|
|
placeHolder: " ",
|
|
name: "title",
|
|
type: "text",
|
|
width: "100%",
|
|
maxLength: 100,
|
|
helperText: `Maximum length should be 100 characters. You have entered ${
|
|
watch()?.title?.length || 0
|
|
} characters.`,
|
|
isRequired: true,
|
|
section: "Send Custom Push Notification",
|
|
// value: contact?.phoneNumber || "",
|
|
},
|
|
{
|
|
label: "Notification Message",
|
|
placeHolder: " ",
|
|
name: "message",
|
|
width: "100%",
|
|
type: "textarea",
|
|
isRequired: true,
|
|
maxLength: 200,
|
|
helperText: `Maximum length should be 200 characters. You have entered ${
|
|
watch()?.message?.length || 0
|
|
} characters.`,
|
|
section: "Send Custom Push Notification",
|
|
// value: contact?.phoneNumber || "",
|
|
},
|
|
];
|
|
|
|
const groupedFields = formFields.reduce((groups, field) => {
|
|
const { section } = field;
|
|
if (!groups[section]) {
|
|
groups[section] = [];
|
|
}
|
|
groups[section].push(field);
|
|
return groups;
|
|
}, {});
|
|
|
|
const onSubmit = async (data) => {
|
|
const dataToPass = {
|
|
...data,
|
|
principal_xid: selectedRadio,
|
|
};
|
|
setIsLoading(true);
|
|
try {
|
|
const res = await sendNotification(dataToPass);
|
|
|
|
if (res?.error) {
|
|
toast({
|
|
render: () => (
|
|
<ToastBox status={"error"} message={res?.error?.data?.message} />
|
|
),
|
|
});
|
|
setIsLoading(false);
|
|
} else if (res?.data) {
|
|
toast({
|
|
render: () => <ToastBox message={res?.data?.message} />,
|
|
});
|
|
setIsLoading(false);
|
|
setSelectedRadio([]);
|
|
reset({
|
|
title: "", // Resetting specific fields
|
|
message: "",
|
|
}); // Clears the form fields
|
|
} else {
|
|
toast({
|
|
render: () => (
|
|
<ToastBox status={"error"} message={"Something went wrong"} />
|
|
),
|
|
});
|
|
setIsLoading(false);
|
|
}
|
|
} catch (error) {
|
|
console.log(error);
|
|
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
// ====================================================[Table Setup]================================================================
|
|
const tableHeadRow = [
|
|
"Sr N/O",
|
|
"Date",
|
|
"Client ID",
|
|
"First Name",
|
|
"Last Name",
|
|
"Country",
|
|
"Phone Number",
|
|
"E-mail ID",
|
|
"KYC Status",
|
|
];
|
|
|
|
const extractedArray = investorDetails?.data?.rows?.map((item, idx) => ({
|
|
id: item?.principal_xid,
|
|
"Sr N/O": (
|
|
<Text
|
|
justifyContent={"left"}
|
|
as={"span"}
|
|
color={"gray.600"}
|
|
className="d-flex align-items-center fw-bold web-text-small"
|
|
>
|
|
{generateSerialNumber(idx, currentPage, pageSize)}
|
|
</Text>
|
|
),
|
|
Date: (
|
|
<Box w={"auto"} isTruncated={true}>
|
|
<Text as={"span"} color={"teal.900"}>
|
|
{formatDate(item?.date)}
|
|
</Text>
|
|
</Box>
|
|
),
|
|
"Client ID": (
|
|
<Box w={"auto"} isTruncated={true}>
|
|
<Text as={"span"} color={"teal.900"}>
|
|
{item?.clientReference_id}
|
|
</Text>
|
|
</Box>
|
|
),
|
|
"First Name": (
|
|
<Box w={"auto"} isTruncated={true}>
|
|
<Text as={"span"} color={"teal.900"}>
|
|
{item?.firstName}
|
|
</Text>
|
|
</Box>
|
|
),
|
|
"Last Name": (
|
|
<Box w={"auto"} isTruncated={true}>
|
|
<Text as={"span"} color={"teal.900"}>
|
|
{item?.lastName}
|
|
</Text>
|
|
</Box>
|
|
),
|
|
Country: (
|
|
<Box w={"auto"} isTruncated={true}>
|
|
<Text as={"span"} color={"teal.900"}>
|
|
{item?.country}
|
|
</Text>
|
|
</Box>
|
|
),
|
|
"Phone Number": (
|
|
<Box w={"auto"} isTruncated={true}>
|
|
<Text as={"span"} color={"teal.900"}>
|
|
{item?.phoneNumber}
|
|
</Text>
|
|
</Box>
|
|
),
|
|
"E-mail ID": (
|
|
<Box w={"auto"} isTruncated={true}>
|
|
<Text as={"span"} color={"teal.900"}>
|
|
{item?.emailAddress}
|
|
</Text>
|
|
</Box>
|
|
),
|
|
"KYC Status": (
|
|
<Box w={"auto"} isTruncated={true}>
|
|
<Badge
|
|
fontWeight={"500"}
|
|
textTransform={"none"}
|
|
color={item?.KYCStatus === false ? "red" : "blue"}
|
|
px={2}
|
|
py={0.5}
|
|
variant={"ghost"}
|
|
>
|
|
{item?.KYCStatus === true ? "Completed" : "Not Completed"}
|
|
</Badge>
|
|
</Box>
|
|
),
|
|
}));
|
|
|
|
return (
|
|
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
|
|
<FormInputMain
|
|
groupedFields={groupedFields}
|
|
control={control}
|
|
errors={errors}
|
|
onSubmit={handleSubmit(onSubmit)}
|
|
btnLoading={isLoading}
|
|
>
|
|
<HStack
|
|
display={"flex"}
|
|
justifyContent={"space-between"}
|
|
ps={1}
|
|
pe={1}
|
|
pb={4}
|
|
pt={4}
|
|
spacing="24px"
|
|
>
|
|
<Input
|
|
mt={1}
|
|
type="search"
|
|
width={300}
|
|
placeholder="Search..."
|
|
size="sm"
|
|
rounded="sm"
|
|
focusBorderColor="green.500"
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
/>
|
|
<HStack className="col" justifyContent={"end"}>
|
|
<Select
|
|
w={250}
|
|
focusBorderColor="green.500"
|
|
size={"sm"}
|
|
fontSize={"xs"}
|
|
cursor={"pointer"}
|
|
onChange={(e) => setCountry(e.target.value)}
|
|
value={country}
|
|
>
|
|
<option value="" defaultValue={""} disabled hidden>
|
|
Country
|
|
</option>
|
|
<option value="">All</option>
|
|
<option value="1">Bahrain</option>
|
|
<option value="2">Kuwait</option>
|
|
<option value="3">Oman</option>
|
|
<option value="4">Qatar</option>
|
|
<option value="5">Saudi arabia</option>
|
|
<option value="6">United arab emirates</option>
|
|
</Select>
|
|
<Select
|
|
w={250}
|
|
focusBorderColor="green.500"
|
|
size={"sm"}
|
|
fontSize={"xs"}
|
|
cursor={"pointer"}
|
|
onChange={(e) => setKyc(e.target.value)}
|
|
value={kyc}
|
|
>
|
|
<option value="" defaultValue={""} disabled hidden>
|
|
KYC Status
|
|
</option>
|
|
<option value="">KYC Status</option>
|
|
<option value="0">Not Completed</option>
|
|
<option value="1">Completed</option>
|
|
</Select>
|
|
</HStack>
|
|
</HStack>
|
|
<Box overflow={"scroll"} h={"58vh"}>
|
|
<NormalTable
|
|
centered={true}
|
|
emptyMessage={`We don't have any Sponers `}
|
|
tableHeadRow={tableHeadRow}
|
|
data={extractedArray}
|
|
isLoading={investorDetailsLoading}
|
|
setSelectedRadio={setSelectedRadio}
|
|
selectedRadio={selectedRadio}
|
|
showRadioButton={true}
|
|
/>
|
|
</Box>
|
|
</FormInputMain>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default Notification;
|