ENCOA-18: Improve the loading of the company names on the Group and Users lists

This commit is contained in:
Tiago Ribeiro
2024-04-18 16:03:09 +01:00
parent 771262fc18
commit 36b861266f
4 changed files with 90 additions and 28 deletions

View File

@@ -14,20 +14,30 @@ import {toast} from "react-toastify";
import readXlsxFile from "read-excel-file";
import {useFilePicker} from "use-file-picker";
import {getUserCorporate} from "@/utils/groups";
import { isAgentUser, isCorporateUser } from "@/resources/user";
const columnHelper = createColumnHelper<Group>();
const EMAIL_REGEX = new RegExp(/^[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*@[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*$/);
const LinkedCorporate = ({userId}: {userId: string}) => {
const LinkedCorporate = ({userId, users, groups}: {userId: string, users: User[], groups: Group[]}) => {
const [companyName, setCompanyName] = useState("");
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setIsLoading(true);
getUserCorporate(userId)
.then((result) => setCompanyName(result?.corporateInformation?.companyInformation?.name || ""))
.finally(() => setIsLoading(false));
}, [userId]);
useEffect(() => {
const user = users.find((u) => u.id === userId)
if (!user) return setCompanyName("")
if (isCorporateUser(user)) return setCompanyName(user.corporateInformation?.companyInformation?.name || user.name)
if (isAgentUser(user)) return setCompanyName(user.agentInformation?.companyName || user.name)
const belongingGroups = groups.filter((x) => x.participants.includes(userId))
const belongingGroupsAdmins = belongingGroups.map((x) => users.find((u) => u.id === x.admin)).filter((x) => !!x && isCorporateUser(x))
if (belongingGroupsAdmins.length === 0) return setCompanyName("")
const admin = (belongingGroupsAdmins[0] as CorporateUser)
setCompanyName(admin.corporateInformation?.companyInformation.name || admin.name)
}, [userId, users, groups]);
return isLoading ? <span className="animate-pulse">Loading...</span> : <>{companyName}</>;
};
@@ -224,7 +234,7 @@ export default function GroupList({user}: {user: User}) {
}),
columnHelper.accessor("admin", {
header: "Linked Corporate",
cell: (info) => <LinkedCorporate userId={info.getValue()} />,
cell: (info) => <LinkedCorporate userId={info.getValue()} users={users} groups={groups} />,
}),
columnHelper.accessor("participants", {
header: "Participants",

View File

@@ -2,7 +2,7 @@ import Button from "@/components/Low/Button";
import {PERMISSIONS} from "@/constants/userPermissions";
import useGroups from "@/hooks/useGroups";
import useUsers from "@/hooks/useUsers";
import {Type, User, userTypes, CorporateUser} from "@/interfaces/user";
import {Type, User, userTypes, CorporateUser, Group} from "@/interfaces/user";
import {Popover, Transition} from "@headlessui/react";
import {createColumnHelper, flexRender, getCoreRowModel, useReactTable} from "@tanstack/react-table";
import axios from "axios";
@@ -44,16 +44,22 @@ const getCompanyName = async (user: User) => {
return "";
};
const CompanyNameCell = (user: User) => {
const CompanyNameCell = ({users, user, groups}: {user: User, users: User[], groups: Group[]}) => {
const [companyName, setCompanyName] = useState("");
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setIsLoading(true);
getCompanyName(user)
.then((result) => setCompanyName(result))
.finally(() => setIsLoading(false));
}, [user]);
useEffect(() => {
if (isCorporateUser(user)) return setCompanyName(user.corporateInformation?.companyInformation?.name || user.name)
if (isAgentUser(user)) return setCompanyName(user.agentInformation?.companyName || user.name)
const belongingGroups = groups.filter((x) => x.participants.includes(user.id))
const belongingGroupsAdmins = belongingGroups.map((x) => users.find((u) => u.id === x.admin)).filter((x) => !!x && isCorporateUser(x))
if (belongingGroupsAdmins.length === 0) return setCompanyName("")
const admin = (belongingGroupsAdmins[0] as CorporateUser)
setCompanyName(admin.corporateInformation?.companyInformation.name || admin.name)
}, [user, users, groups]);
return isLoading ? <span className="animate-pulse">Loading...</span> : <>{companyName}</>;
};
@@ -372,7 +378,7 @@ export default function UserList({user, filters = []}: {user: User; filters?: ((
<SorterArrow name="companyName" />
</button>
) as any,
cell: (info) => <CompanyNameCell {...info.row.original} />,
cell: (info) => <CompanyNameCell user={info.row.original} users={users} groups={groups} />,
}),
columnHelper.accessor("subscriptionExpirationDate", {
header: (

View File

@@ -0,0 +1,29 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";
import { app } from "@/firebase";
import {
getFirestore,
collection,
getDocs,
getDoc,
doc,
} from "firebase/firestore";
import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "@/lib/session";
const db = getFirestore(app);
export default withIronSessionApiRoute(handler, sessionOptions);
async function handler(req: NextApiRequest, res: NextApiResponse) {
if (!req.session.user) {
res.status(401).json({ ok: false });
return;
}
const { id } = req.query as { id: string };
const snapshot = await getDoc(doc(db, "users", id));
if (!snapshot.exists()) return res.status(404).json({ ok: false });
res.status(200).json({ ...snapshot.data(), id: snapshot.id });
}

View File

@@ -1,20 +1,37 @@
import {CorporateUser, Group, User} from "@/interfaces/user";
import { CorporateUser, Group, User } from "@/interfaces/user";
import axios from "axios";
export const isUserFromCorporate = async (userID: string) => {
const groups = (await axios.get<Group[]>(`/api/groups?participant=${userID}`)).data;
const users = (await axios.get<User[]>("/api/users/list")).data;
const groups = (await axios.get<Group[]>(`/api/groups?participant=${userID}`))
.data;
const users = (await axios.get<User[]>("/api/users/list")).data;
const adminTypes = groups.map((g) => users.find((u) => u.id === g.admin)?.type);
return adminTypes.includes("corporate");
const adminTypes = groups.map(
(g) => users.find((u) => u.id === g.admin)?.type,
);
return adminTypes.includes("corporate");
};
export const getUserCorporate = async (userID: string) => {
const users = (await axios.get<User[]>("/api/users/list")).data;
if (users.find((u) => u.id === userID)?.type === "corporate") return users.find((u) => u.id === userID) as CorporateUser;
export const getUserCorporate = async (
userID: string,
): Promise<CorporateUser | undefined> => {
const userRequest = await axios.get<User>(`/api/users/${userID}`);
if (userRequest.status === 200) {
const user = userRequest.data;
if (user.type === "corporate") return user;
}
const groups = (await axios.get<Group[]>(`/api/groups?participant=${userID}`)).data;
const groups = (await axios.get<Group[]>(`/api/groups?participant=${userID}`))
.data;
const admins = groups.map((g) => users.find((u) => u.id === g.admin)).filter((x) => x?.type === "corporate");
return admins.length > 0 ? (admins[0] as CorporateUser) : undefined;
const adminRequests = await Promise.all(
groups.map(async (g) => {
const userRequest = await axios.get<User>(`/api/users/${g.admin}`);
if (userRequest.status === 200) return userRequest.data;
return undefined;
}),
);
const admins = adminRequests.filter((x) => x?.type === "corporate");
return admins.length > 0 ? (admins[0] as CorporateUser) : undefined;
};