Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 93 additions & 51 deletions src/features/Search/Filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ import Button, { ButtonVariant } from '../../shared/Elements/Button';
import { Form } from '../../shared/Form';
import * as FormikElements from '../../shared/Form/FormikElements';
import { getOptionsFromEnum } from '../../util';
import { cut } from 'clipboard';

interface IFilterProps {
initFilters: ISearchParameter[];
onChange: (newFilters: ISearchParameter[], reviewStatus?: number[], reviewScore?: number[]) => void;
onResetForm: () => void;
loading: boolean;
reviewerModeOpen: boolean;
}

class FilterComponent extends React.Component<IFilterProps, {}> {
Expand Down Expand Up @@ -112,38 +114,42 @@ class FilterComponent extends React.Component<IFilterProps, {}> {
component={FormikElements.Select}
value={fp.values.status}
/>
<FastField
name={'reviewStatus'}
label={'Review Status'}
placeholder={'Review Statuses...'}
isMulti={true}
creatable={true}
options={[
{ label: '0', value: 0 },
{ label: '1', value: 1 },
{ label: '2', value: 2 },
]}
component={FormikElements.Select}
value={fp.values.reviewStatus}
/>
<FastField
name={'reviewScore'}
label={'Review Score'}
placeholder={'Review Scores...'}
isMulti={true}
creatable={true}
options={[
{ label: '-1', value: -1 }, // both none
{ label: '0', value: 0 },
{ label: '1', value: 1 },
{ label: '2', value: 2 },
{ label: '3', value: 3 },
{ label: '4', value: 4 },
{ label: '5', value: 5 }, // whitelist
]}
component={FormikElements.Select}
value={fp.values.reviewScore}
/>
{(this.props.reviewerModeOpen && (
<>
<FastField
name={'reviewStatus'}
label={'Review Status'}
placeholder={'Review Statuses...'}
isMulti={true}
creatable={true}
options={[
{ label: '0', value: 0 },
{ label: '1', value: 1 },
{ label: '2', value: 2 },
]}
component={FormikElements.Select}
value={fp.values.reviewStatus}
/>
<FastField
name={'reviewScore'}
label={'Review Score'}
placeholder={'Review Scores...'}
isMulti={true}
creatable={true}
options={[
{ label: '-1', value: -1 }, // both none
{ label: '0', value: 0 },
{ label: '1', value: 1 },
{ label: '2', value: 2 },
{ label: '3', value: 3 },
{ label: '4', value: 4 },
{ label: '5', value: 5 }, // whitelist
]}
component={FormikElements.Select}
value={fp.values.reviewScore}
/>
</>
))}
<FastField
name={'skills'}
label={'Skills'}
Expand All @@ -163,24 +169,48 @@ class FilterComponent extends React.Component<IFilterProps, {}> {
component={FormikElements.Select}
value={fp.values.jobInterest}
/>
<FastField
name={'reviewer1'}
label={'Reviewer 1'}
placeholder={'Reviewer 1...'}
isMulti={true}
component={FormikElements.Select}
options={getOptionsFromEnum(reviewers)}
value={fp.values.reviewer1}
/>
<FastField
name={'reviewer2'}
label={'Reviewer 2'}
placeholder={'Reviewer 2...'}
isMulti={true}
component={FormikElements.Select}
options={getOptionsFromEnum(reviewers)}
value={fp.values.reviewer2}
/>
{(this.props.reviewerModeOpen && (
<>
<FastField
name={'reviewer1'}
label={'Reviewer 1'}
placeholder={'Reviewer 1...'}
isMulti={true}
component={FormikElements.Select}
options={getOptionsFromEnum(reviewers)}
value={fp.values.reviewer1}
/>
<FastField
name={'reviewer2'}
label={'Reviewer 2'}
placeholder={'Reviewer 2...'}
isMulti={true}
component={FormikElements.Select}
options={getOptionsFromEnum(reviewers)}
value={fp.values.reviewer2}
/>
<FastField
name={'reviewStatus'}
label={'Review Status'}
placeholder={'Review Statuses...'}
isMulti={true}
creatable={true}
options={[
{ label: '0', value: 0 },
{ label: '1', value: 1 },
{ label: '2', value: 2 },
]}
component={FormikElements.Select}
value={fp.values.reviewStatus}
/>
{/* <FastField
name={'cutoffTime'}
label={'Cutoff Time'}
placeholder={'2025-11-17T23:59:59.000Z'}
component={FormikElements.Input}
/> */}
</>
))}
<Flex justifyContent={'center'}>
<Box mr={'10px'}>
<Button
Expand All @@ -203,6 +233,7 @@ class FilterComponent extends React.Component<IFilterProps, {}> {
</Button>
</Box>
</Flex>
<div style={{ height: '20px' }}></div> {/* add space under filter */}
</Form>
);
}
Expand Down Expand Up @@ -246,6 +277,16 @@ class FilterComponent extends React.Component<IFilterProps, {}> {
'reviewerName2',
values.reviewer2
);
// const cutoffObjectId = new ObjectId(Math.floor((new Date(values.cutoffTime)).getTime() / 1000).toString(16) + "0000000000000000");
// const cutoffTimeParam = values.cutoffTime
// ? [
// {
// raw: {
// _id: { $lte: cutoffObjectId}
// }
// },
// ]
// : [];
let search: ISearchParameter[] = [];
search = search.concat(
schoolSearchParam,
Expand All @@ -255,7 +296,8 @@ class FilterComponent extends React.Component<IFilterProps, {}> {
skillsParam,
jobInterestParam,
reviewer1Param,
reviewer2Param
reviewer2Param,
// cutoffTimeParam
);
// this.props.onChange(search);
// this.props.onChange(search, values.reviewStatus);
Expand Down
32 changes: 18 additions & 14 deletions src/features/Search/ResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface IResultsTableProps {
filter: string;
canEditAllStatuses?: boolean;
triggerUpdate: () => void;
reviewerModeOpen: boolean;
}

// calculate review status
Expand Down Expand Up @@ -86,22 +87,25 @@ const ResultsTable: React.FunctionComponent<IResultsTableProps> = (props) => {
Header: 'Status',
accessor: 'hacker.status',
},
{ // Number of reviewers that have reviewed this hacker
Header: 'Review Status',
id: 'reviewStatus', // required since accessor is a non-string
accessor: (row: any) => calculateReviewStatusCount(row.hacker),
Cell: (cellProps: any) => {
return cellProps.value;
...props.reviewerModeOpen ? [
{ // Number of reviewers that have reviewed this hacker
Header: 'Review Status',
id: 'reviewStatus', // required since accessor is a non-string
accessor: (row: any) => calculateReviewStatusCount(row.hacker),
Cell: (cellProps: any) => {
return cellProps.value;
},
},
},
{ // Average score of the reviews for this hacker
Header: 'Review Score',
id: 'reviewScore', // required since accessor is a non-string
accessor: (row: any) => calculateReviewScoreCount(row.hacker),
Cell: (cellProps: any) => {
return cellProps.value;
{ // Average score of the reviews for this hacker
Header: 'Review Score',
id: 'reviewScore', // required since accessor is a non-string
accessor: (row: any) => calculateReviewScoreCount(row.hacker),
Cell: (cellProps: any) => {
return cellProps.value;
},
},
},
]
: [],
{
Header: 'Job Interest',
accessor: 'hacker.application.general.jobInterest',
Expand Down
65 changes: 56 additions & 9 deletions src/features/Search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ interface ISearchState {
reviewScoreFilter: number[];
emailModalOpen: boolean;
reviewerModalOpen: boolean;
reviewerModeOpen: boolean;
emailSending: boolean;
emailStatus: string;
emailConfirming: boolean;
Expand Down Expand Up @@ -83,6 +84,7 @@ class SearchContainer extends React.Component<{}, ISearchState> {
reviewScoreFilter: [],
emailModalOpen: false,
reviewerModalOpen: false,
reviewerModeOpen: false,
emailSending: false,
emailStatus: '',
emailConfirming: false,
Expand All @@ -100,6 +102,8 @@ class SearchContainer extends React.Component<{}, ISearchState> {
this.closeEmailModal = this.closeEmailModal.bind(this);
this.openReviewerModal = this.openReviewerModal.bind(this);
this.closeReviewerModal = this.closeReviewerModal.bind(this);
this.openReviewerMode = this.openReviewerMode.bind(this);
this.closeReviewerMode = this.closeReviewerMode.bind(this);
this.startEmailConfirmation = this.startEmailConfirmation.bind(this);
this.backFromEmailConfirmation = this.backFromEmailConfirmation.bind(this);
this.confirmSendEmails = this.confirmSendEmails.bind(this);
Expand All @@ -108,6 +112,7 @@ class SearchContainer extends React.Component<{}, ISearchState> {
...this.state,
emailModalOpen: false,
reviewerModalOpen: false,
reviewerModeOpen: false,
emailSending: false,
emailStatus: '',
emailConfirming: false,
Expand Down Expand Up @@ -136,6 +141,13 @@ class SearchContainer extends React.Component<{}, ISearchState> {
this.setState({ reviewerModalOpen: false });
}

openReviewerMode() {
this.setState({ reviewerModeOpen: true });
}
closeReviewerMode() {
this.setState({ reviewerModeOpen: false });
}

async startEmailConfirmation(status: string) {
try {
// Fetch the count of emails to be sent
Expand Down Expand Up @@ -213,6 +225,42 @@ class SearchContainer extends React.Component<{}, ISearchState> {
account && account.accountType === UserType.STAFF ? true : false;
return (
<Flex flexDirection={'column'}>

<style>{`
.toggle-btn {
margin-left: 10px;
top: 7%;
background-color: ${theme.colors.black5};
border: 1px solid ${theme.colors.black20};
border-radius: 99px;
cursor: pointer;
width: 50px;
height: 28px;
transition: background-color 0.1s ease, border-color 0.2s ease;
position: relative;
box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
}
.toggle-btn .thumb {
background-color: ${theme.colors.white};
border-radius: 99px;
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
height: 20px;
width: 20px;
transform: translateX(0px);
transition: left 0.15s ease;
position: absolute;
left: 3px;
top: 50%;
transform: translateY(-50%);
}
.toggle-btn.toggled {
background-color: ${theme.colors.purple};
}
.toggle-btn.toggled .thumb {
left: calc(50px - 20px - 5px);
}
`}</style>

<Helmet>
<title> Search | {HACKATHON_NAME}</title>
</Helmet>
Expand All @@ -231,6 +279,7 @@ class SearchContainer extends React.Component<{}, ISearchState> {
onChange={this.onFilterChange}
onResetForm={this.onResetForm}
loading={loading}
reviewerModeOpen={this.state.reviewerModeOpen}
/>
</Box>
<Box width={5 / 6} mx={2}>
Expand Down Expand Up @@ -284,6 +333,12 @@ class SearchContainer extends React.Component<{}, ISearchState> {
Send Emails
</Button>
)}
<button className={`toggle-btn ${this.state.reviewerModeOpen ? "toggled" : ""}`} onClick={() => {
if (this.state.reviewerModeOpen) this.closeReviewerMode();
else this.openReviewerMode();
}}>
<div className='thumb'></div>
</button>
</Box>
</Flex>
</Box>
Expand All @@ -294,6 +349,7 @@ class SearchContainer extends React.Component<{}, ISearchState> {
filter={searchBar}
canEditAllStatuses={isStaffAccount}
triggerUpdate={this.triggerSearch}
reviewerModeOpen={this.state.reviewerModeOpen}
/>
</Flex>
</Box>
Expand Down Expand Up @@ -466,15 +522,6 @@ class SearchContainer extends React.Component<{}, ISearchState> {
</div>
)}
{/* Reviewer Modal */}

{/* {
this.state.reviewerModalOpen && (
<AssignReviewerModal
onSubmit={this.handleReviewerAssignment}
onClose={this.closeReviewerModal}
/>
)
} */}
{this.state.reviewerModalOpen && (
<div
style={{
Expand Down