-
Notifications
You must be signed in to change notification settings - Fork 21
feat(PM-1506): show already member modal #1165
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
Changes from 1 commit
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,40 @@ | ||
| /* eslint-disable react/jsx-no-bind */ | ||
| import { FC } from 'react' | ||
|
|
||
| import { BaseModal, Button } from '~/libs/ui' | ||
| import { CopilotApplication } from '~/apps/copilots/src/models/CopilotApplication' | ||
|
|
||
| import styles from './styles.module.scss' | ||
|
|
||
| interface AlreadyMemberModalProps { | ||
| onClose: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void | ||
| copilotApplication: CopilotApplication | ||
| handle?: string | ||
| onApply: () => void | ||
| projectName: string | ||
| } | ||
|
|
||
| const AlreadyMemberModal: FC<AlreadyMemberModalProps> = props => ( | ||
| <BaseModal | ||
| onClose={props.onClose as () => void} | ||
|
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. The |
||
| open | ||
| size='lg' | ||
| title='User already member of the project' | ||
| buttons={( | ||
| <> | ||
| <Button primary onClick={props.onApply} label='Confirm' /> | ||
| <Button secondary onClick={props.onClose} label='Cancel' /> | ||
| </> | ||
| )} | ||
| > | ||
| <div className={styles.applyCopilotModal}> | ||
| <div className={styles.info}> | ||
| {`The copilot ${props.handle} is part of ${props.projectName} | ||
|
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. Consider using template literals for better readability and to avoid unnecessary whitespace in the rendered string. For example: |
||
| project with ${props.copilotApplication.existingMembership?.role} role.`} | ||
| <div>Click 'Confirm' to accept and complete this opportunity.</div> | ||
| </div> | ||
| </div> | ||
| </BaseModal> | ||
| ) | ||
|
|
||
| export default AlreadyMemberModal | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,22 @@ | ||
| import { useParams } from 'react-router-dom' | ||
| import { toast } from 'react-toastify' | ||
| import { mutate } from 'swr' | ||
| import { useCallback, useMemo } from 'react' | ||
| import { useCallback, useMemo, useState } from 'react' | ||
|
|
||
| import { assignCopilotOpportunity, copilotBaseUrl } from '~/apps/copilots/src/services/copilot-opportunities' | ||
| import { CopilotApplication, CopilotApplicationStatus } from '~/apps/copilots/src/models/CopilotApplication' | ||
| import { IconSolid, Tooltip } from '~/libs/ui' | ||
|
|
||
| import AlreadyMemberModal from './AlreadyMemberModal' | ||
| import styles from './styles.module.scss' | ||
|
|
||
| const CopilotApplicationAction = ( | ||
| copilotApplication: CopilotApplication, | ||
| allCopilotApplications: CopilotApplication[], | ||
| ): JSX.Element => { | ||
| console.log(copilotApplication, 'copilotApplication') | ||
|
||
| const { opportunityId }: {opportunityId?: string} = useParams<{ opportunityId?: string }>() | ||
|
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. Remove the |
||
| const [showAlreadyMemberModal, setShowAlreadyMemberModal] = useState(false) | ||
| const isInvited = useMemo( | ||
| () => allCopilotApplications | ||
| && allCopilotApplications.findIndex(item => item.status === CopilotApplicationStatus.INVITED) > -1, | ||
|
|
@@ -28,6 +31,12 @@ const CopilotApplicationAction = ( | |
| return | ||
| } | ||
|
|
||
| if (copilotApplication.existingMembership) { | ||
|
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. Remove the commented-out |
||
| console.log('comes here') | ||
|
||
| setShowAlreadyMemberModal(true) | ||
| return | ||
| } | ||
|
|
||
| if (opportunityId) { | ||
| try { | ||
| await assignCopilotOpportunity(opportunityId, copilotApplication.id) | ||
|
|
@@ -40,6 +49,29 @@ const CopilotApplicationAction = ( | |
|
|
||
| } | ||
| }, [opportunityId, copilotApplication]) | ||
|
|
||
| const onApply = useCallback(async () => { | ||
| try { | ||
| if (!opportunityId) { | ||
| return | ||
| } | ||
|
|
||
| await assignCopilotOpportunity(opportunityId, copilotApplication.id) | ||
| toast.success('Accepted as copilot') | ||
| mutate(`${copilotBaseUrl}/copilots/opportunity/${opportunityId}/applications`) | ||
| setShowAlreadyMemberModal(false) | ||
|
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. Consider checking if |
||
| } catch (e) { | ||
| const error = e as Error | ||
| toast.error(error.message) | ||
| } | ||
| }, [opportunityId, copilotApplication]) | ||
|
|
||
| const onCloseModal = useCallback((e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => { | ||
|
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. The |
||
| e.preventDefault() | ||
| e.stopPropagation() | ||
| setShowAlreadyMemberModal(false) | ||
| }, [showAlreadyMemberModal]) | ||
|
|
||
| return ( | ||
| <div onClick={onClick} className={styles.actionWrapper}> | ||
| { | ||
|
|
@@ -67,6 +99,16 @@ const CopilotApplicationAction = ( | |
| </Tooltip> | ||
| ) | ||
| } | ||
|
|
||
| {showAlreadyMemberModal && ( | ||
| <AlreadyMemberModal | ||
| projectName={copilotApplication.projectName} | ||
| handle={copilotApplication.handle} | ||
| onClose={onCloseModal} | ||
| onApply={onApply} | ||
| copilotApplication={copilotApplication} | ||
| /> | ||
| )} | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,6 +87,7 @@ const CopilotApplications: FC<{ | |
| handle: member?.handle, | ||
| opportunityStatus: props.opportunity.status, | ||
| pastProjects: member?.pastProjects || 0, | ||
| projectName: props.opportunity.projectName, | ||
|
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. Ensure that |
||
| } | ||
| }) | ||
| .sort((a, b) => (b.fulfilment || 0) - (a.fulfilment || 0)) : []) | ||
|
|
||
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.
The
projectNameproperty is added as a required field. If this is intentional, ensure that all instances ofCopilotApplicationare updated to include this field. If it should be optional, consider adding a question mark to make itprojectName?: string.