This commit is contained in:
2024-10-02 18:41:38 +05:30
parent 10221c03d9
commit 2ae81ef032
9 changed files with 327 additions and 49 deletions

View File

@@ -9,27 +9,52 @@ import {
Tr,
Skeleton,
TableCaption,
Tfoot,
Checkbox,
} from "@chakra-ui/react";
import EmptySearchList from "../EmptySearchList";
import { TABLE_PAGINATION } from "../../Constants/Paginations";
const DataTable = ({
const NormalTable = ({
data,
isLoading,
tableHeadRow,
emptyMessage,
centered,
total,
showRadioButton, // Prop for showing the checkboxes
selectedRadio,
setSelectedRadio, // State for managing selected checkboxes
}) => {
console.log(data);
const columnWidth =
data && data[0]
? `${(100 / Object.keys(data[0]).length).toFixed(2)}%`
: "auto";
// Toggle checkbox selection for individual rows
const handleCheckboxChange = (value) => {
setSelectedRadio((prev) => {
if (prev.includes(value)) {
// Remove if already selected
return prev.filter((id) => id !== value);
} else {
// Add to selected
return [...prev, value];
}
});
};
// Handle "Check All" checkbox
const handleCheckAllChange = () => {
if (selectedRadio.length === data.length) {
setSelectedRadio([]); // Deselect all if already selected
} else {
const allIds = data.map((item) => item.id);
setSelectedRadio(allIds); // Select all
}
};
return (
<TableContainer overflowX={"auto"} className="h-auto mb-3 w-100 table-scroll">
<TableContainer overflowX={"auto"} className="h-auto w-100 table-scroll">
{data?.length === 0 ? (
<EmptySearchList message={emptyMessage} />
) : (
@@ -37,26 +62,42 @@ const DataTable = ({
<TableCaption p={total ? 0 : null}>
{total ? total : "Tanami v1.0.0"}
</TableCaption>
<Thead backgroundColor="forestGreen.100">
<Thead bg="forestGreen.100">
<Tr>
{showRadioButton && (
<Th
color={"purple.900"}
textAlign={"center"}
p={4}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
textTransform={"none"}
>
<Checkbox
isChecked={selectedRadio.length === data.length}
onChange={handleCheckAllChange}
colorScheme="forestGreen"
/>
</Th>
)}
{tableHeadRow.map((heading, index) => (
<Th
<Th
color={"purple.900"}
textAlign={
tableHeadRow.length - 1 === index || centered
? "center"
: "left"
}
key={index}
p={3}
width="20px" // Adjust width as needed
color={"#004118"}
whiteSpace="normal" // Allow text to wrap
wordBreak="normal" // Ensure long words break properly
overflowWrap="normal" // Break long words if necessary
p={4}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
textTransform={"none"}
>
{isLoading ? <Skeleton height="20px" /> : heading}
{/* {heading} */}
</Th>
))}
</Tr>
@@ -65,17 +106,18 @@ const DataTable = ({
{isLoading
? Array.from({ length: TABLE_PAGINATION?.size }).map(
(_, index) => (
<Tr bg={index % 2 === 0 ? "" : "forestGreen.50"} key={index}>
<Tr
bg={index % 2 === 0 ? "white" : "forestGreen.50"}
key={index}
>
{tableHeadRow.map((_, i) => (
<Td
width={"fit-content"}
key={i}
style={{
whiteSpace: "nowrap",
textOverflow: "ellipsis",
}}
className="web-text-small"
w={columnWidth}
>
<Skeleton height="20px" mb={1} mt={1} />
</Td>
@@ -84,9 +126,26 @@ const DataTable = ({
)
)
: data?.map((item, index) => (
<Tr bg={index % 2 === 0 ? "" : "forestGreen.50"} key={index}>
<Tr
cursor={"pointer"}
transition={"0.2s all"}
maxH={8}
bg={index % 2 === 0 ? "" : "forestGreen.50"}
key={index}
>
{showRadioButton && (
<Td textAlign={"center"}>
<Checkbox
bg={"#fff"}
colorScheme="forestGreen"
value={item.id}
isChecked={selectedRadio.includes(item.id)}
onChange={() => handleCheckboxChange(item.id)}
/>
</Td>
)}
{tableHeadRow.map((heading, i) => (
<Td
<Td
textAlign={
tableHeadRow?.length - 1 === i || centered
? "center"
@@ -94,6 +153,7 @@ const DataTable = ({
}
color={"gray.600"}
key={i}
fontWeight={500}
style={{
whiteSpace: "nowrap",
textOverflow: "ellipsis",
@@ -112,4 +172,4 @@ const DataTable = ({
);
};
export default DataTable;
export default NormalTable;

View File

@@ -133,9 +133,7 @@ const DashboardLayout = ({ isOnline }) => {
// dispach(loginUser(false));
setIsAuthenticate(false);
Cookies.remove("isAuthenticated");
localStorage.removeItem('refreshToken')
localStorage.removeItem('accessToken')
localStorage.removeItem('refreshTokenExp')
localStorage.clear();
navigate("/login");
};

View File

@@ -1,6 +1,10 @@
import React, { useContext, useEffect, useState } from "react";
import {
Badge,
Box,
Button,
Text,
Tooltip,
useToast,
} from "@chakra-ui/react";
import { useForm} from "react-hook-form";
@@ -15,6 +19,12 @@ import {
} 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 { TABLE_PAGINATION } from "../../Constants/Paginations";
import { generateSerialNumber } from "../../Constants/Constants";
import { ViewIcon } from "@chakra-ui/icons";
export const notification = yup.object().shape({
investmentNameEnglish: yup
@@ -47,6 +57,7 @@ const Notification = () => {
const navigate = useNavigate();
const [form, setForm] = useState({});
const [isLoading, setIsLoading] = useState(false);
const [ selectedRadio, setSelectedRadio] = useState([])
const {
control,
@@ -64,6 +75,18 @@ const Notification = () => {
isLoading: contactLoading,
error,
} = useGetContactQuery();
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page);
const {
data: investorDetails,
isLoading: investorDetailsLoading,
// error,
} = useGetInvestorsQuery({ page: currentPage, size: pageSize });
console.log(investorDetails);
const [updateContact] = useUpdateContactMutation();
useEffect(() => {
@@ -129,9 +152,20 @@ const Notification = () => {
}, {});
const onSubmit = async (data) => {
const dataToPass = {
...data,
principal_xid:selectedRadio
}
console.log(dataToPass);
setIsLoading(true);
try {
const res = await updateContact(data);
const res = await updateContact(dataToPass);
if (res?.data?.statusCode === 200) {
toast({
render: () => <ToastBox message={res?.data?.message} />,
@@ -145,6 +179,122 @@ const Notification = () => {
}
};
console.log(selectedRadio);
// ====================================================[Table Setup]================================================================
const tableHeadRow = [
"Sr No",
"Client ID",
"First Name",
"Last Name",
"Country",
"Phone Number",
"E-mail ID",
"Type",
"KYC Status",
// "Status",
];
const extractedArray = investorDetails?.data?.rows?.map((item, idx) => ({
id: item?.id,
"Sr No": (
<Text
w={'24px'}
justifyContent={"left"}
as={"span"}
color={"gray.600"}
className="d-flex align-items-center fw-bold web-text-small"
>
{/* {item.id} */}
{generateSerialNumber(idx,currentPage, pageSize )}
</Text>
),
"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?.principal?.firstName}
</Text>
</Box>
),
"Last Name": (
<Box w={"70px"} isTruncated={true}>
<Text as={"span"} color={"teal.900"}>
{item?.principal?.lastName}
</Text>
</Box>
),
Country: (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"}>
{item?.country?.countryName}
</Text>
</Box>
),
"Phone Number": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"}>
{item?.principal?.mobileNumber}
</Text>
</Box>
),
"E-mail ID": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"}>
{item?.principal?.emailAddress}
</Text>
</Box>
),
"Type": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} >
<Badge color={'blue.500'} variant={'ghost'} fontWeight={"700"} px={2} py={0.5}>
{item?.investor_type?.investorTypeName}
</Badge>
</Text>
</Box>
),
Status: (
<Box w={"auto"} isTruncated={true}>
<Badge
fontWeight={"700"}
textTransform={"none"}
colorScheme={item.ioStatus ? "red" : "green"}
px={2}
py={0.5}
>
{item.ioStatus ? "Ban" : "Unban"}
</Badge>
</Box>
),
"KYC Status": (
<Box w={"auto"} display={'flex'} alignItems={'center'} isTruncated={true}>
<Text
as={'span'}
fontWeight={"700"}
textTransform={"none"}
color={item.ioStatus ? "gray.500":item.kycStatus ? "blue.500" : "red.500"}
px={2}
py={0.5}
variant={'solid'}
>
{item.KYCStatus ? "Completed" : "Not complete"}
</Text>
</Box>
),
}));
return (
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
<FormInputMain
@@ -153,7 +303,24 @@ const Notification = () => {
errors={errors}
onSubmit={handleSubmit(onSubmit)}
btnLoading={isLoading}
>
<NormalTable
centered={true}
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
// isLoading={isLoading}
setSelectedRadio={setSelectedRadio}
selectedRadio={selectedRadio}
showRadioButton={true}
/>
</FormInputMain>
</Box>
);
};

View File

@@ -182,8 +182,8 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
? "#C6F6D5"
: IODetails?.ioStatus?.statusAdmin === "Exited"
? "#FED7D7"
: IODetails?.ioStatus?.statusAdmin === "Canclled"
? "orange.500"
: IODetails?.ioStatus?.statusAdmin === "Cancelled"
? "#E9D8FD"
: IODetails?.ioStatus?.statusAdmin === "DeActivate"
? "#E9D8FD"
: null
@@ -342,7 +342,7 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
</Box>
</Box>
<Box gap={8} me={12} w={"140px"}>
<Box gap={8} me={12} w={"180px"}>
<Box display={"flex"} justifyContent={"space-between"} gap={2} pb={1}>
<Text
as={"span"}
@@ -370,8 +370,8 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
? "green"
: IODetails?.ioStatus?.statusAdmin === "Exited"
? "red"
: IODetails?.ioStatus?.statusAdmin === "Canclled"
? "orange"
: IODetails?.ioStatus?.statusAdmin === "Cancelled"
? "purple"
: "purple"
}
>

View File

@@ -49,7 +49,6 @@ const InvestorDetails = () => {
const thirdField = useRef();
const { InvestorDetails, setInvestorDetails, slideFromRight } =
useContext(GlobalStateContext);
const [searchTerm, setSearchTerm] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [deleteAlert, setDeleteAlert] = useState(false);
const [actionId, setActionId] = useState(false);
@@ -62,13 +61,35 @@ const InvestorDetails = () => {
} = useDisclosure();
const btnRef = React.useRef();
// =========================== [Use State] =============================
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page);
const [searchTerm, setSearchTerm] = useState("");
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
// Debounce the search term to avoid making a request on every keystroke
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedSearchTerm(searchTerm);
}, 500); // Adjust delay as needed
return () => {
clearTimeout(handler);
};
}, [searchTerm]);
const {
data: investorDetails,
isLoading: investorDetailsLoading,
error,
} = useGetInvestorsQuery({ page: currentPage, size: pageSize });
} = useGetInvestorsQuery({
page: debouncedSearchTerm ? undefined : currentPage, // Omit pagination for search
size: debouncedSearchTerm ? undefined : pageSize, // Omit pagination for search
searchTerm: debouncedSearchTerm,
},
{
skip: debouncedSearchTerm === "" && searchTerm !== "", // Skip if search is empty and it's not the initial request
}
);
useEffect(() => {
@@ -143,7 +164,7 @@ const InvestorDetails = () => {
];
const extractedArray = filteredData?.map((item, idx) => ({
const extractedArray = investorDetails?.data?.rows?.map((item, idx) => ({
id: item?.id,
"Sr No": (
<Text

View File

@@ -27,14 +27,6 @@ const Sponser = () => {
const navigate = useNavigate();
const toast = useToast();
const [searchTerm, setSearchTerm] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [deleteAlert, setDeleteAlert] = useState(false);
const [actionId, setActionId] = useState(false);
@@ -46,9 +38,29 @@ const Sponser = () => {
// =========================== [Use State] =============================
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page);
const {data: sponsors,error,isLoading: isSponserLoading,} = useGetSponserMasterQuery({ page: currentPage, size: pageSize });
const [searchTerm, setSearchTerm] = useState("");
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
// console.log(sponsors?.data?.rows);
// Debounce the search term to avoid making a request on every keystroke
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedSearchTerm(searchTerm);
}, 500); // Adjust delay as needed
return () => {
clearTimeout(handler);
};
}, [searchTerm]);
const { data: sponsors, error, isLoading: isSponserLoading } = useGetSponserMasterQuery(
{
page: debouncedSearchTerm ? undefined : currentPage, // Omit pagination for search
size: debouncedSearchTerm ? undefined : pageSize, // Omit pagination for search
searchTerm: debouncedSearchTerm,
},
{
skip: debouncedSearchTerm === "" && searchTerm !== "", // Skip if search is empty and it's not the initial request
}
);
console.log(sponsors?.data?.rows);
// ==============================[Table Filter]========================
@@ -69,7 +81,7 @@ const Sponser = () => {
"Action",
];
const extractedArray = filteredData?.map((item, index) => ({
const extractedArray = sponsors?.data?.rows?.map((item, index) => ({
"Sr No": (
<Text
w={'24px'}

View File

@@ -11,11 +11,22 @@ export const investorDetails = createApi({
baseQuery: baseQuery,
tagTypes: [],
endpoints: (builder) => ({
getInvestors: builder.query({
query: ({ page, size }) =>
`/investorDetails/admin?page=${page}&size=${size}`,
providesTags: ["getInvestors"],
}),
query: ({ page, size, searchTerm }) => {
// Start with the base URL, including searchTerm
let baseURL = `/investorDetails/admin/?search_data=${searchTerm || ""}`;
// Conditionally append page and size parameters if they are defined
if (page !== undefined && size !== undefined) {
baseURL += `&page=${page}&size=${size}`;
}
return baseURL;
},
providesTags: ["getInvestors"],
}),
// =====[get investment details ]
getInvestorsDetailsById: builder.query({

View File

@@ -325,11 +325,18 @@ export const ioService = createApi({
// ======[Get All]=====
getSponserMaster: builder.query({
query: ({ page, size }) => `/sponsor/admin?page=${page}&size=${size}`,
query: ({ page, size, searchTerm }) => {
let baseURL = `/sponsor/admin/?search_data=${searchTerm || ""}`;
if (page !== undefined && size !== undefined) {
baseURL += `&page=${page}&size=${size}`; // Only add pagination if both are defined
}
return baseURL;
},
providesTags: ["getSponser"],
}),
// ========[Delete Sponser]========
deleteSponser: builder.mutation({

View File

@@ -71,6 +71,8 @@ export const baseQuery = async (args, api, extraOptions) => {
}
} catch (err) {
console.error("Failed to refresh token:", err);
localStorage.clear();
window.location.href = '/login'; // Redirect to login page
// Handle refresh failure (e.g., redirect to login)
}
}