integrated fetch organization list api and display with search filter
This commit is contained in:
parent
9a3488c92b
commit
0d9ef7f248
149
src/components/Organization/OrganizationsList.jsx
Normal file
149
src/components/Organization/OrganizationsList.jsx
Normal file
@ -0,0 +1,149 @@
|
||||
import React from "react";
|
||||
import { useOrganizationsList } from "../../hooks/useOrganization";
|
||||
import { ITEMS_PER_PAGE } from "../../utils/constants";
|
||||
import Avatar from "../common/Avatar";
|
||||
import { useDebounce } from "../../utils/appUtils";
|
||||
|
||||
const OrganizationsList = ({searchText}) => {
|
||||
const searchString = useDebounce(searchText,500)
|
||||
const {
|
||||
data = [],
|
||||
isLoading,
|
||||
isFetching,
|
||||
isError,
|
||||
error,
|
||||
} = useOrganizationsList(ITEMS_PER_PAGE, 1, true,null,searchString);
|
||||
|
||||
const organizationsColumns = [
|
||||
{
|
||||
key: "name",
|
||||
label: "Organization Name",
|
||||
getValue: (org) => (
|
||||
<div className="d-flex gap-2 py-1 ">
|
||||
<i class="bx bx-buildings"></i>
|
||||
<span
|
||||
className="text-truncate d-inline-block "
|
||||
style={{ maxWidth: "150px" }}
|
||||
>
|
||||
{org?.name || "N/A"}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
align: "text-start",
|
||||
},
|
||||
{
|
||||
key: "contactPerson",
|
||||
label: "Contact Person",
|
||||
getValue: (org) => (
|
||||
(
|
||||
<div className="d-flex align-items-center ps-1">
|
||||
<Avatar
|
||||
size="xs"
|
||||
classAvatar="m-0"
|
||||
firstName={(org?.name || "").trim().split(" ")[0] || ""}
|
||||
lastName={(org?.name || "").trim().split(" ")[1] || ""}
|
||||
/>
|
||||
<span
|
||||
className="text-truncate d-inline-block "
|
||||
style={{ maxWidth: "150px" }}
|
||||
>
|
||||
{org?.name || "N/A"}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
),
|
||||
align: "text-start",
|
||||
},
|
||||
{
|
||||
key: "contactNumber",
|
||||
label: "Phone Number",
|
||||
getValue: (org) => org.contactNumber || "N/A",
|
||||
align: "text-start",
|
||||
},
|
||||
{
|
||||
key: "email",
|
||||
label: "Email",
|
||||
getValue: (org) => (
|
||||
<span
|
||||
className="text-truncate d-inline-block"
|
||||
style={{ maxWidth: "200px" }}
|
||||
>
|
||||
{org?.email || "N/A"}
|
||||
</span>
|
||||
),
|
||||
align: "text-start",
|
||||
},
|
||||
{
|
||||
key: "sprid",
|
||||
label: "SPRID Id",
|
||||
getValue: (org) => org.sprid || "N/A",
|
||||
align: "text-center",
|
||||
},
|
||||
];
|
||||
|
||||
if (isFetching && !isFetching) return <div>Loading...</div>;
|
||||
if (isError) return <div>{error?.message || "Something went wrong"}</div>;
|
||||
|
||||
return (
|
||||
<div className="card px-0 px-sm-4">
|
||||
<div className="card-datatable table-responsive" id="horizontal-example">
|
||||
<div className="dataTables_wrapper no-footer px-2">
|
||||
<table className="table border-top dataTable text-nowrap">
|
||||
<thead>
|
||||
<tr className="table_header_border">
|
||||
{organizationsColumns.map((col) => (
|
||||
<th
|
||||
key={col.key}
|
||||
className="sorting d-table-cell"
|
||||
aria-sort="descending"
|
||||
>
|
||||
<div className={`${col.align}`}>{col.label}</div>
|
||||
</th>
|
||||
))}
|
||||
<th className="sticky-action-column bg-white text-center">
|
||||
Action
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.length > 0 ? (
|
||||
data.map((org) => (
|
||||
<tr key={org.id}>
|
||||
{organizationsColumns.map((col) => (
|
||||
<td
|
||||
key={col.key}
|
||||
className={`d-table-cell ${col.align ?? ""}`}
|
||||
>
|
||||
{col.customRender
|
||||
? col.customRender(org)
|
||||
: col.getValue(org)}
|
||||
</td>
|
||||
))}
|
||||
<td className="sticky-action-column ">
|
||||
<div className="d-flex justify-content-center gap-2 ">
|
||||
<i className="bx bx-show text-primary cursor-pointer"></i>
|
||||
<i className="bx bx-edit text-secondary cursor-pointer"></i>
|
||||
<i className="bx bx-trash text-danger cursor-pointer"></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
) : (
|
||||
<tr>
|
||||
<td
|
||||
colSpan={organizationsColumns.length + 1}
|
||||
className="text-center"
|
||||
>
|
||||
<p className="fw-semibold">Not Found</p>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrganizationsList;
|
@ -4,7 +4,7 @@ import {
|
||||
openOrgModal,
|
||||
closeOrgModal,
|
||||
} from "../slices/localVariablesSlice";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import OrganizationRepository from "../repositories/OrganizationRespository";
|
||||
import showToast from "../services/toastService";
|
||||
|
||||
@ -22,11 +22,24 @@ export const useOrganizationModal = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export const useOrganizationsList = (pageSize, pageNumber, active, sprid, searchString="") => {
|
||||
return useQuery({
|
||||
queryKey: ["organizationList", pageSize, pageNumber, active, sprid, searchString],
|
||||
queryFn: async() => {
|
||||
const resp = await OrganizationRepository.getOrganizationList(pageSize, pageNumber, active, sprid, searchString);
|
||||
return resp.data;
|
||||
},
|
||||
keepPreviousData: true,
|
||||
});
|
||||
};
|
||||
|
||||
export const useCreateOrganization = (onSuccessCallback) => {
|
||||
const useClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: async (OrgPayload) =>
|
||||
await OrganizationRepository.createOrganization(OrgPayload),
|
||||
onSuccess: (_, variables) => {
|
||||
useClient.invalidateQueries({queryKey:["organizationList"]})
|
||||
showToast("Organization created successfully", "success");
|
||||
if (onSuccessCallback) onSuccessCallback();
|
||||
},
|
||||
|
@ -1,9 +1,12 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||
import { useOrganizationModal } from "../../hooks/useOrganization";
|
||||
import OrganizationsList from "../../components/Organization/OrganizationsList";
|
||||
|
||||
const OrganizationPage = () => {
|
||||
const orgModal = useOrganizationModal()
|
||||
const [searchText,setSearchText] = useState("")
|
||||
|
||||
return (
|
||||
<div className="container-fluid">
|
||||
<Breadcrumb
|
||||
@ -12,10 +15,12 @@ const OrganizationPage = () => {
|
||||
<div className="card my-3 px-sm-2 px-0">
|
||||
<div className="card-body py-2 px-3">
|
||||
<div className="row align-items-center">
|
||||
<div className="col-6 ">
|
||||
<div className="col-6 d-flex ">
|
||||
<div className="d-flex align-items-center">
|
||||
<input
|
||||
type="search"
|
||||
value={searchText}
|
||||
onChange={(e)=>setSearchText(e.target.value)}
|
||||
className="form-control form-control-sm w-auto"
|
||||
placeholder="Search Organization"
|
||||
aria-describedby="search-label"
|
||||
@ -36,6 +41,8 @@ const OrganizationPage = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<OrganizationsList searchText={searchText}/>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,9 +1,14 @@
|
||||
import { api } from "../utils/axiosClient";
|
||||
|
||||
|
||||
const OrganizationRepository = {
|
||||
createOrganization:(data)=>api.post('/api/Organization/create',data)
|
||||
}
|
||||
const OrganizationRepository = {
|
||||
createOrganization: (data) => api.post("/api/Organization/create", data),
|
||||
getOrganizationList: (pageSize, pageNumber, active, sprid, searchString) => {
|
||||
return api.get(
|
||||
`/api/Organization/list?pageSize=${pageSize}&pageNumber=${pageNumber}&active=${active}&${
|
||||
sprid ? `sprid=${sprid}&` : ""
|
||||
}searchString=${searchString}`
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default OrganizationRepository;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user