Qortal-Hub/src/components/Group/UserListOfInvites.tsx
2024-09-14 06:33:41 +03:00

207 lines
6.3 KiB
TypeScript

import { Box, Button, ListItem, ListItemButton, ListItemText, Popover, Typography } from '@mui/material';
import React, { useContext, useEffect, useRef, useState } from 'react'
import { AutoSizer, CellMeasurer, CellMeasurerCache, List } from 'react-virtualized';
import { MyContext, getBaseApiReact } from '../../App';
import { LoadingButton } from '@mui/lab';
import { getBaseApi, getFee } from '../../background';
const cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 50,
});
const getGroupInfo = async (groupId)=> {
const response = await fetch(`${getBaseApiReact()}/groups/` + groupId);
const groupData = await response.json();
if (groupData) {
return groupData
}
}
export const getGroupNames = async (listOfGroups) => {
let groups = [];
if (listOfGroups && Array.isArray(listOfGroups)) {
for (const group of listOfGroups) {
const groupInfo = await getGroupInfo(group.groupId);
if (groupInfo) {
groups.push({ ...group, ...groupInfo });
}
}
}
return groups;
}
export const UserListOfInvites = ({myAddress, setInfoSnack, setOpenSnack}) => {
const {txList, setTxList, show} = useContext(MyContext)
const [invites, setInvites] = useState<any[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [popoverAnchor, setPopoverAnchor] = useState(null); // Track which list item the popover is anchored to
const [openPopoverIndex, setOpenPopoverIndex] = useState(null); // Track which list item has the popover open
const listRef = useRef();
const getRequests = async () => {
try {
const response = await fetch(`${getBaseApiReact()}/groups/invites/${myAddress}/?limit=0`);
const inviteData = await response.json();
const resMoreData = await getGroupNames(inviteData)
setInvites(resMoreData);
} catch (error) {
console.error(error);
}
}
useEffect(() => {
getRequests();
}, []);
const handlePopoverOpen = (event, index) => {
setPopoverAnchor(event.currentTarget);
setOpenPopoverIndex(index);
};
const handlePopoverClose = () => {
setPopoverAnchor(null);
setOpenPopoverIndex(null);
};
const handleJoinGroup = async (groupId, groupName)=> {
try {
const fee = await getFee('JOIN_GROUP')
await show({
message: "Would you like to perform an JOIN_GROUP transaction?" ,
publishFee: fee.fee + ' QORT'
})
setIsLoading(true);
await new Promise((res, rej)=> {
chrome?.runtime?.sendMessage({ action: "joinGroup", payload: {
groupId,
}}, (response) => {
if (!response?.error) {
setTxList((prev)=> [{
...response,
type: 'joined-group',
label: `Joined Group ${groupName}: awaiting confirmation`,
labelDone: `Joined Group ${groupName}: success !`,
done: false,
groupId,
}, ...prev])
res(response)
setInfoSnack({
type: "success",
message: "Successfully requested to join group. It may take a couple of minutes for the changes to propagate",
});
setOpenSnack(true);
handlePopoverClose();
return
}
setInfoSnack({
type: "error",
message: response?.error,
});
setOpenSnack(true);
rej(response.error)
});
})
} catch (error) {
} finally {
setIsLoading(false);
}
}
const rowRenderer = ({ index, key, parent, style }) => {
const invite = invites[index];
return (
<CellMeasurer
key={key}
cache={cache}
parent={parent}
columnIndex={0}
rowIndex={index}
>
{({ measure }) => (
<div style={style} onLoad={measure}>
<ListItem disablePadding>
<Popover
open={openPopoverIndex === index}
anchorEl={popoverAnchor}
onClose={handlePopoverClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "center",
}}
transformOrigin={{
vertical: "top",
horizontal: "center",
}}
style={{ marginTop: "8px" }}
>
<Box
sx={{
width: "325px",
height: "250px",
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "10px",
padding: "10px",
}}
>
<Typography>Join {invite?.groupName}</Typography>
<LoadingButton
loading={isLoading}
loadingPosition="start"
variant="contained" onClick={()=> handleJoinGroup(invite?.groupId, invite?.groupName)}>Join group</LoadingButton>
</Box>
</Popover>
<ListItemButton onClick={(event) => handlePopoverOpen(event, index)}>
<ListItemText primary={invite?.groupName} secondary={invite?.description} />
</ListItemButton>
</ListItem>
</div>
)}
</CellMeasurer>
);
};
return (
<div>
<p>Invite list</p>
<div style={{ position: 'relative', height: '500px', width: '100%', display: 'flex', flexDirection: 'column', flexShrink: 1 }}>
<AutoSizer>
{({ height, width }) => (
<List
ref={listRef}
width={width}
height={height}
rowCount={invites.length}
rowHeight={cache.rowHeight}
rowRenderer={rowRenderer}
deferredMeasurementCache={cache}
/>
)}
</AutoSizer>
</div>
</div>
);
}