-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added a modal for sending invitation #406
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/** | ||
* A modal component that displays a form for inviting a user. | ||
* | ||
* @component | ||
* @param {InviteUserModalProps} props - The properties for the InviteUserModal component. | ||
* @param {boolean} props.isOpen - A boolean indicating whether the modal is open. | ||
* @param {function} props.setIsOpen - A function to set the modal's open state. | ||
* @param {function} props.onSendInvite - A function to handle sending the invite. | ||
* | ||
* @returns {JSX.Element} The rendered modal component. | ||
* | ||
* @example | ||
* <InviteUserModal isOpen={isOpen} setIsOpen={setIsOpen} onSendInvite={handleSendInvite} /> | ||
*/ | ||
|
||
import { | ||
Button, | ||
MenuItem, | ||
Modal, | ||
Stack, | ||
Typography, | ||
useTheme, | ||
} from "@mui/material"; | ||
import React, { useState } from "react"; | ||
import Field from "../../Inputs/Field"; | ||
import Select from "../../Inputs/Select"; | ||
|
||
interface InviteUserModalProps { | ||
isOpen: boolean; | ||
setIsOpen: (isOpen: boolean) => void; | ||
onSendInvite: (email: string, role: string) => void; | ||
} | ||
|
||
const InviteUserModal: React.FC<InviteUserModalProps> = ({ | ||
isOpen, | ||
setIsOpen, | ||
onSendInvite, | ||
}) => { | ||
const theme = useTheme(); | ||
|
||
const [email, setEmail] = useState<string>(""); | ||
const [role, setRole] = useState<string>(""); | ||
|
||
const handleSendInvite = () => { | ||
onSendInvite(email, role); | ||
setIsOpen(false); | ||
}; | ||
|
||
return ( | ||
<Modal open={isOpen} onClose={() => setIsOpen(false)}> | ||
<Stack | ||
gap={theme.spacing(2)} | ||
color={theme.palette.text.secondary} | ||
sx={{ | ||
position: "absolute", | ||
top: "50%", | ||
left: "50%", | ||
transform: "translate(-50%, -50%)", | ||
width: 450, | ||
bgcolor: theme.palette.background.paper, | ||
border: 1, | ||
borderColor: theme.palette.border.dark, | ||
borderRadius: theme.shape.borderRadius, | ||
boxShadow: 24, | ||
p: theme.spacing(4), | ||
padding: theme.spacing(12), | ||
"&:focus": { | ||
outline: "none", | ||
}, | ||
}} | ||
> | ||
<Typography id="modal-invite-user" fontSize={16} fontWeight={600}> | ||
Invite new team member | ||
</Typography> | ||
<Typography | ||
id="invite-user-instructions" | ||
fontSize={13} | ||
textAlign={"justify"} | ||
paddingBottom={theme.spacing(8)} | ||
> | ||
When you add a new team member, they will get access to all monitors. | ||
</Typography> | ||
<Field | ||
placeholder="Email" | ||
type="email" | ||
value={email} | ||
onChange={(e) => setEmail(e.target.value)} | ||
isRequired | ||
sx={{ | ||
marginBottom: theme.spacing(4), | ||
}} | ||
/> | ||
<Select | ||
id="role-select" | ||
value={role} | ||
onChange={(e) => setRole(e.target.value as string)} | ||
items={[ | ||
{ _id: "administrator", name: "Administrator" }, | ||
{ _id: "reviewer", name: "Reviewer" }, | ||
{ _id: "editor", name: "Editor" }, | ||
]} | ||
sx={{ mt: theme.spacing(2) }} | ||
/> | ||
<Stack | ||
direction="row" | ||
gap={theme.spacing(4)} | ||
mt={theme.spacing(4)} | ||
justifyContent="flex-end" | ||
paddingBottom={theme.spacing(4)} | ||
> | ||
<Button | ||
disableRipple | ||
disableFocusRipple | ||
disableTouchRipple | ||
variant="text" | ||
color="inherit" | ||
onClick={() => setIsOpen(false)} | ||
sx={{ | ||
width: 100, | ||
textTransform: "capitalize", | ||
fontSize: 13, | ||
borderRadius: "4px", | ||
"&:hover": { | ||
boxShadow: "none", | ||
backgroundColor: "transparent", | ||
}, | ||
}} | ||
> | ||
Cancel | ||
</Button> | ||
<Button | ||
disableRipple | ||
disableFocusRipple | ||
disableTouchRipple | ||
variant="contained" | ||
color="primary" | ||
disabled={!email || !role} | ||
sx={{ | ||
width: 140, | ||
textTransform: "capitalize", | ||
fontSize: 13, | ||
boxShadow: "none", | ||
borderRadius: "4px", | ||
"&:hover": { | ||
boxShadow: "none", | ||
}, | ||
}} | ||
onClick={handleSendInvite} | ||
> | ||
Send Invite | ||
</Button> | ||
</Stack> | ||
</Stack> | ||
</Modal> | ||
); | ||
}; | ||
|
||
export default InviteUserModal; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ import Field from "../../../components/Inputs/Field"; | |
import { ReactComponent as SelectorVertical } from "../../../assets/icons/selector-vertical.svg"; | ||
import TablePaginationActions from "../../../components/TablePagination"; | ||
import { VerifyWiseContext } from "../../../../application/contexts/VerifyWise.context"; | ||
import InviteUserModal from "../../../components/Modals/InviteUser"; | ||
|
||
// Enum for roles | ||
enum Role { | ||
|
@@ -77,8 +78,9 @@ const TeamManagement: React.FC = (): JSX.Element => { | |
]); | ||
|
||
const [page, setPage] = useState(0); // Current page | ||
const { dashboardValues, setDashboardValues } = useContext(VerifyWiseContext); | ||
const { dashboardValues} = useContext(VerifyWiseContext); | ||
const [rowsPerPage, setRowsPerPage] = useState(5); // Rows per page | ||
const [inviteUserModalOpen, setInviteUserModalOpen] = useState(false); | ||
|
||
// Handle saving organization name | ||
const handleSaveOrgName = useCallback(() => { | ||
|
@@ -143,6 +145,11 @@ const TeamManagement: React.FC = (): JSX.Element => { | |
// return filteredMembers.slice(startIndex, startIndex + rowsPerPage); | ||
// }, [filteredMembers, page, rowsPerPage]); | ||
|
||
const inviteTeamMember = () => { | ||
console.log("Inviting team member"); | ||
setInviteUserModalOpen(true); | ||
}; | ||
Comment on lines
+148
to
+151
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Encapsulate inviteTeamMember logic if it grows. Right now, logging and setting the modal open is straightforward. If you need more comprehensive logic for error handling or backend calls, consider moving it to a separate function or hooking into a context or service for maintainability. |
||
|
||
return ( | ||
<Stack sx={{ pt: theme.spacing(10) }}> | ||
<Box sx={{ mb: 4 }}> | ||
|
@@ -237,7 +244,7 @@ const TeamManagement: React.FC = (): JSX.Element => { | |
</Box> | ||
|
||
<Box sx={{ mt: 10 }}> | ||
<Button variant="contained" disableRipple> | ||
<Button variant="contained" disableRipple onClick={() => inviteTeamMember()}> | ||
Invite team member | ||
</Button> | ||
</Box> | ||
|
@@ -353,6 +360,16 @@ const TeamManagement: React.FC = (): JSX.Element => { | |
</Box> | ||
</Stack> | ||
</Box> | ||
{inviteUserModalOpen && ( | ||
<InviteUserModal | ||
isOpen={inviteUserModalOpen} | ||
setIsOpen={setInviteUserModalOpen} | ||
onSendInvite={(data) => { | ||
console.log('Invite sent:', data); | ||
setInviteUserModalOpen(false); | ||
}} | ||
/> | ||
)} | ||
</Stack> | ||
); | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider using your project's custom UI components instead of MUI.
Per the feedback in the PR comments, there's a preference for aligning with the existing design system by using the project's custom components. This would ensure visual consistency across the application.