-
Notifications
You must be signed in to change notification settings - Fork 18
PROD: Copilot portal CRs & Bugs V3 #1181
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 all commits
858ae52
fb804da
1f9e9c7
774bfd7
ba5b0d4
985f376
9aab68a
cfccb97
b50cfaa
9689622
c2eaa92
8b8754c
9e4b437
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,35 @@ | ||
/* eslint-disable react/jsx-no-bind */ | ||
import { FC } from 'react' | ||
|
||
import { BaseModal, Button } from '~/libs/ui' | ||
|
||
import styles from './styles.module.scss' | ||
|
||
interface ConfirmModalProps { | ||
onClose: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void | ||
onApply: () => void | ||
} | ||
|
||
const ConfirmModal: FC<ConfirmModalProps> = props => ( | ||
<BaseModal | ||
onClose={props.onClose as () => void} | ||
open | ||
size='lg' | ||
title='Confirm to accept as copilot' | ||
buttons={( | ||
<> | ||
<Button primary onClick={props.onApply} label='Confirm' /> | ||
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. SuggestionConsider adding |
||
<Button secondary onClick={props.onClose} label='Cancel' /> | ||
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. SuggestionConsider adding |
||
</> | ||
)} | ||
> | ||
<div className={styles.applyCopilotModal}> | ||
<div className={styles.info}> | ||
Click 'Confirm' to accept by updating project role to 'Copilot' | ||
and complete this opportunity | ||
</div> | ||
</div> | ||
</BaseModal> | ||
) | ||
|
||
export default ConfirmModal |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,13 @@ | ||
import { useParams } from 'react-router-dom' | ||
import { toast } from 'react-toastify' | ||
import { mutate } from 'swr' | ||
import { useCallback, useMemo, useState } from 'react' | ||
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 import statement for |
||
|
||
import { assignCopilotOpportunity, copilotBaseUrl } from '~/apps/copilots/src/services/copilot-opportunities' | ||
import { assignCopilotOpportunity } 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 ConfirmModal from './ConfirmModal' | ||
import styles from './styles.module.scss' | ||
|
||
const CopilotApplicationAction = ( | ||
|
@@ -16,6 +16,7 @@ const CopilotApplicationAction = ( | |
): JSX.Element => { | ||
const { opportunityId }: {opportunityId?: string} = useParams<{ opportunityId?: string }>() | ||
const [showAlreadyMemberModal, setShowAlreadyMemberModal] = useState(false) | ||
const [showConfirmModal, setShowConfirmModal] = useState(false) | ||
const isInvited = useMemo( | ||
() => allCopilotApplications | ||
&& allCopilotApplications.findIndex(item => item.status === CopilotApplicationStatus.INVITED) > -1, | ||
|
@@ -32,19 +33,8 @@ const CopilotApplicationAction = ( | |
|
||
if (copilotApplication.existingMembership) { | ||
setShowAlreadyMemberModal(true) | ||
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 |
||
return | ||
} | ||
|
||
if (opportunityId) { | ||
try { | ||
await assignCopilotOpportunity(opportunityId, copilotApplication.id) | ||
toast.success('Invited a copilot') | ||
mutate(`${copilotBaseUrl}/copilots/opportunity/${opportunityId}/applications`) | ||
} catch (e) { | ||
const error = e as Error | ||
toast.error(error.message) | ||
} | ||
|
||
} else { | ||
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 |
||
setShowConfirmModal(true) | ||
} | ||
}, [opportunityId, copilotApplication]) | ||
|
||
|
@@ -56,8 +46,9 @@ const CopilotApplicationAction = ( | |
|
||
await assignCopilotOpportunity(opportunityId, copilotApplication.id) | ||
toast.success('Accepted as copilot') | ||
mutate(`${copilotBaseUrl}/copilots/opportunity/${opportunityId}/applications`) | ||
copilotApplication.onApplied() | ||
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 |
||
setShowAlreadyMemberModal(false) | ||
setShowConfirmModal(false) | ||
} catch (e) { | ||
const error = e as Error | ||
toast.error(error.message) | ||
|
@@ -68,6 +59,7 @@ const CopilotApplicationAction = ( | |
e.preventDefault() | ||
e.stopPropagation() | ||
setShowAlreadyMemberModal(false) | ||
setShowConfirmModal(false) | ||
}, [showAlreadyMemberModal]) | ||
|
||
return ( | ||
|
@@ -84,7 +76,7 @@ const CopilotApplicationAction = ( | |
!isInvited | ||
&& copilotApplication.status === CopilotApplicationStatus.PENDING | ||
&& copilotApplication.opportunityStatus === 'active' && ( | ||
<Tooltip content='Send Invitation'> | ||
<Tooltip content='Accept'> | ||
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 tooltip content has been changed from 'Send Invitation' to 'Accept'. Ensure that this change aligns with the intended functionality and user experience. If the action is still related to sending an invitation, consider revisiting the tooltip text for clarity. |
||
<IconSolid.UserAddIcon /> | ||
</Tooltip> | ||
) | ||
|
@@ -107,6 +99,13 @@ const CopilotApplicationAction = ( | |
copilotApplication={copilotApplication} | ||
/> | ||
)} | ||
|
||
{showConfirmModal && ( | ||
<ConfirmModal | ||
onClose={onCloseModal} | ||
onApply={onApply} | ||
/> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,6 +77,7 @@ const CopilotApplications: FC<{ | |
copilotApplications?: CopilotApplication[] | ||
members?: FormattedMembers[] | ||
opportunity: CopilotOpportunity | ||
onApplied: () => void | ||
}> = props => { | ||
const getData = (): CopilotApplication[] => (props.copilotApplications ? props.copilotApplications.map(item => { | ||
const member = props.members && props.members.find(each => each.userId === item.userId) | ||
|
@@ -85,6 +86,7 @@ const CopilotApplications: FC<{ | |
activeProjects: member?.activeProjects || 0, | ||
fulfilment: member?.copilotFulfillment || 0, | ||
handle: member?.handle, | ||
onApplied: props.onApplied, | ||
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 |
||
opportunityStatus: props.opportunity.status, | ||
pastProjects: member?.pastProjects || 0, | ||
projectName: props.opportunity.projectName, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,9 +14,12 @@ const OpportunityDetails: FC<{ | |
{props.opportunity?.skills.map(item => (<span className={styles.skillPill}>{item.name}</span>))} | ||
</div> | ||
<h2 className={styles.subHeading}> Description </h2> | ||
<p> | ||
{props.opportunity?.overview} | ||
</p> | ||
{props.opportunity?.overview && ( | ||
<div dangerouslySetInnerHTML={{ | ||
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. Using |
||
__html: props.opportunity.overview.replace(/\n/g, '<br />'), | ||
}} | ||
/> | ||
)} | ||
</div> | ||
<div> | ||
<h2 className={styles.subHeading}> Complexity </h2> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,6 +45,7 @@ const CopilotRequestForm: FC<{}> = () => { | |
const [formErrors, setFormErrors] = useState<any>({}) | ||
const [paymentType, setPaymentType] = useState<string>('') | ||
const [projectFromQuery, setProjectFromQuery] = useState<Project>() | ||
const activeProjectStatuses = ['active', 'approved', 'draft', 'new'] | ||
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 defining |
||
|
||
const { data: copilotRequestData }: CopilotRequestResponse = useCopilotRequest(routeParams.requestId) | ||
|
||
|
@@ -114,7 +115,13 @@ const CopilotRequestForm: FC<{}> = () => { | |
label: string; | ||
value: string; | ||
}>> { | ||
const response = await getProjects(inputValue) | ||
const response = await getProjects(inputValue, { | ||
filter: { | ||
status: { | ||
$in: [activeProjectStatuses], | ||
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 variable |
||
}, | ||
}, | ||
}) | ||
return response.map(project => ({ label: project.name, value: project.id })) | ||
} | ||
|
||
|
@@ -494,6 +501,7 @@ const CopilotRequestForm: FC<{}> = () => { | |
.setFullYear(new Date() | ||
.getFullYear() + 2))} | ||
minYear={new Date()} | ||
className={styles.datepicker} | ||
/> | ||
<p className={styles.formRow}>How many weeks will you need the copilot for?</p> | ||
<InputText | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,4 +97,8 @@ $gradient: linear-gradient( | |
margin-right: $sp-1; | ||
} | ||
} | ||
|
||
.datepicker input{ | ||
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 adding a space before the opening curly brace for consistency with the rest of the file's formatting. |
||
color: black; | ||
} | ||
} | ||
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. It's a good practice to ensure that files end with a newline character to avoid potential issues with some tools and version control systems. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -200,7 +200,10 @@ const CopilotRequestsPage: FC = () => { | |
className: styles.opportunityTitle, | ||
label: 'Title', | ||
propertyName: 'opportunityTitle', | ||
type: 'text', | ||
renderer: (copilotRequest: CopilotRequest) => ( | ||
<div className={styles.title}>{copilotRequest.opportunityTitle}</div> | ||
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 adding a fallback or default value for |
||
), | ||
type: 'element', | ||
}, | ||
{ | ||
label: 'Type', | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,8 +63,8 @@ export const getProject = (projectId: string): Promise<Project> => { | |
return xhrGetAsync<Project>(url) | ||
} | ||
|
||
export const getProjects = (search?: string, filter?: any): Promise<Project[]> => { | ||
const params = { name: `"${search}"`, ...filter } | ||
export const getProjects = (search?: string, config?: {filter: any}): Promise<Project[]> => { | ||
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 type for |
||
const params = { name: search, ...config?.filter } | ||
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 |
||
const url = buildUrl(baseUrl, params) | ||
return xhrGetAsync<Project[]>(url) | ||
} |
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.
Suggestion
The
onClose
prop is being cast to() => void
, which might suppress type errors. Consider ensuring that theonClose
function matches the expected type without casting.