Skip to content

Commit

Permalink
feat(interview-feedback): update feedback result usage
Browse files Browse the repository at this point in the history
  • Loading branch information
artsiom aliakseyenka committed Aug 20, 2023
1 parent 0b568a7 commit 9a7635e
Show file tree
Hide file tree
Showing 19 changed files with 468 additions and 251 deletions.
82 changes: 82 additions & 0 deletions client/src/components/Profile/LegacyScreeningFeedback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import * as React from 'react';
import { Tag, Typography, Table } from 'antd';
import { Rating } from 'components/Rating';
import { LegacyFeedback } from 'common/models/profile';
import { ENGLISH_LEVELS } from 'data/english';
import { CODING_LEVELS, SKILLS_LEVELS } from 'data/interviews/technical-screening';

const { Text } = Typography;

enum SKILL_NAME {
htmlCss = 'HTML/CSS',
dataStructures = 'Data structures',
common = 'Common of CS / Programming',
}

/**
* this feedback template will live here until we will migrate all feedbacks to new template
*/
export function LegacyScreeningFeedback({ feedback }: { feedback: LegacyFeedback }) {
const { comment, skills, programmingTask, english } = feedback;

const skillSet = [
...(Object.keys(skills) as any[]).map((key: keyof typeof skills) => ({
rating: skills[key],
name: SKILL_NAME[key],
key,
isNotCodeWritingLevel: true,
})),
{
rating: programmingTask.codeWritingLevel,
name: 'Code writing level',
key: 'codeWritingLevel',
isNotCodeWritingLevel: false,
},
];
const englishLevel = typeof english === 'number' ? ENGLISH_LEVELS[english] : english;

return (
<>
{comment && (
<p style={{ marginBottom: 20 }}>
<Text strong>Comment: </Text>
{comment}
</p>
)}
<p style={{ marginBottom: 5 }}>
Programming task(s): <br /> <Text code>{programmingTask.task}</Text>
</p>
<p style={{ marginBottom: 5 }}>
Has the student solved the task(s)?{' '}
{programmingTask.resolved === 1 ? (
<Tag color="green">Yes</Tag>
) : programmingTask.resolved === 2 ? (
<Tag color="orange">Yes (with tips)</Tag>
) : (
<Tag color="red">No</Tag>
)}
</p>
<p style={{ marginBottom: 5 }}>Comments about coding level: {programmingTask.comment}</p>
<p style={{ marginBottom: 5 }}>Estimated English level: {englishLevel?.toString().toUpperCase()}</p>
<Table
dataSource={skillSet}
size="small"
rowKey="key"
pagination={false}
columns={[
{
dataIndex: 'name',
ellipsis: true,
width: '30%',
},
{
dataIndex: 'rating',
render: (rating, record) => (
<Rating rating={rating} tooltips={record.isNotCodeWritingLevel ? SKILLS_LEVELS : CODING_LEVELS} />
),
},
]}
/>
</>
);
}
8 changes: 5 additions & 3 deletions client/src/components/Profile/PreScreeningIviewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import PreScreeningIviewModal from './PreScreeningIviewModal';
const { Text } = Typography;

import { QuestionCircleOutlined, FullscreenOutlined } from '@ant-design/icons';
import { getRating } from 'domain/interview';

type Props = {
data: StageInterviewDetailedFeedback[];
Expand Down Expand Up @@ -36,11 +37,12 @@ class PreScreeningIviewsCard extends React.PureComponent<Props, State> {
render() {
const interviews = this.props.data;
const { isPreScreeningIviewModalVisible, courseIndex } = this.state;
const interviewResult = interviews[courseIndex];

return (
<>
<PreScreeningIviewModal
feedback={interviews[courseIndex]}
interviewResult={interviewResult}
isVisible={isPreScreeningIviewModalVisible}
onHide={this.hidePreScreeningIviewModal}
/>
Expand All @@ -51,13 +53,13 @@ class PreScreeningIviewsCard extends React.PureComponent<Props, State> {
<List
itemLayout="horizontal"
dataSource={interviews}
renderItem={({ courseName, interviewer, rating, date, isGoodCandidate }, idx) => (
renderItem={({ courseName, interviewer, score, maxScore, date, isGoodCandidate, version }, idx) => (
<List.Item style={{ display: 'flex', justifyContent: 'space-between' }}>
<div style={{ flexGrow: 2 }}>
<p style={{ marginBottom: 0 }}>
<Text strong>{courseName}</Text>
</p>
<Rating rating={rating} />
<Rating rating={getRating(score, maxScore, version)} />
<p style={{ fontSize: 12, marginBottom: 5 }}>Date: {formatDate(date)}</p>
{isGoodCandidate != null ? (
<p style={{ fontSize: 12, marginBottom: 5 }}>
Expand Down
87 changes: 11 additions & 76 deletions client/src/components/Profile/PreScreeningIviewModal.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,22 @@
import * as React from 'react';
import { Modal, Tag, Typography, Table } from 'antd';
import { Modal, Tag } from 'antd';
import { formatDate } from 'services/formatter';
import { Rating } from 'components/Rating';
import { StageInterviewDetailedFeedback } from 'common/models/profile';
import { CODING_LEVELS, SKILLS_LEVELS, SKILL_NAME } from 'services/reference-data/stageInterview';
import { ENGLISH_LEVELS } from 'data/english';

const { Text } = Typography;
import { LegacyFeedback, StageInterviewDetailedFeedback } from 'common/models/profile';
import { LegacyScreeningFeedback } from './LegacyScreeningFeedback';
import { PrescreeningFeedback } from './PrescreeningFeedback';
import { getRating } from 'domain/interview';

type Props = {
feedback: StageInterviewDetailedFeedback;
interviewResult: StageInterviewDetailedFeedback;
isVisible: boolean;
onHide: () => void;
};

class PreScreeningIviewModal extends React.PureComponent<Props> {
render() {
const { feedback, isVisible, onHide } = this.props;
const {
courseName,
courseFullName,
date,
rating,
interviewer,
isGoodCandidate,
comment,
skills,
programmingTask,
english,
} = feedback;
const skillSet = [
...(Object.keys(skills) as any[]).map((key: keyof typeof skills) => ({
rating: skills[key],
name: SKILL_NAME[key],
key: `stageInterview-${courseName}-${date}-skills-${key}`,
isNotCodeWritingLevel: true,
})),
{
rating: programmingTask.codeWritingLevel,
name: 'Code writing level',
key: `stageInterview-${courseName}-${date}-skills-codeWritingLevel`,
isNotCodeWritingLevel: false,
},
];
const englishLevel = typeof english === 'number' ? ENGLISH_LEVELS[english] : english;
const { interviewResult, isVisible, onHide } = this.props;
const { courseFullName, date, score, interviewer, isGoodCandidate, feedback, version, maxScore } = interviewResult;
return (
<Modal
title={`${courseFullName} Pre-Screening Interview Feedback`}
Expand All @@ -52,7 +25,7 @@ class PreScreeningIviewModal extends React.PureComponent<Props> {
footer={null}
width={'80%'}
>
<Rating rating={rating} />
<Rating rating={getRating(score, maxScore, version)} />
<p style={{ marginBottom: 5 }}>Date: {formatDate(date)}</p>
{isGoodCandidate != null ? (
<p style={{ marginBottom: 5 }}>
Expand All @@ -62,46 +35,8 @@ class PreScreeningIviewModal extends React.PureComponent<Props> {
<p style={{ marginBottom: 20 }}>
Interviewer: <a href={`/profile?githubId=${interviewer.githubId}`}>{interviewer.name}</a>
</p>
{comment && (
<p style={{ marginBottom: 20 }}>
<Text strong>Comment: </Text>
{comment}
</p>
)}
<p style={{ marginBottom: 5 }}>
Programming task(s): <br /> <Text code>{programmingTask.task}</Text>
</p>
<p style={{ marginBottom: 5 }}>
Has the student solved the task(s)?{' '}
{programmingTask.resolved === 1 ? (
<Tag color="green">Yes</Tag>
) : programmingTask.resolved === 2 ? (
<Tag color="orange">Yes (with tips)</Tag>
) : (
<Tag color="red">No</Tag>
)}
</p>
<p style={{ marginBottom: 5 }}>Comments about coding level: {programmingTask.comment}</p>
<p style={{ marginBottom: 5 }}>Estimated English level: {englishLevel?.toString().toUpperCase()}</p>
<Table
dataSource={skillSet}
size="small"
rowKey="key"
pagination={false}
columns={[
{
dataIndex: 'name',
ellipsis: true,
width: '30%',
},
{
dataIndex: 'rating',
render: (rating, record) => (
<Rating rating={rating} tooltips={record.isNotCodeWritingLevel ? SKILLS_LEVELS : CODING_LEVELS} />
),
},
]}
/>
{version === 0 && <LegacyScreeningFeedback feedback={feedback as LegacyFeedback} />}
{version === 1 && <PrescreeningFeedback feedback={feedback} />}
</Modal>
);
}
Expand Down
127 changes: 127 additions & 0 deletions client/src/components/Profile/PrescreeningFeedback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import * as React from 'react';
import { Typography, Table, Row, Space } from 'antd';
import { Rating } from 'components/Rating';
import { StageInterviewDetailedFeedback } from 'common/models/profile';
import {
CODING_LEVELS,
FeedbackStepId,
InterviewFeedbackStepData,
InterviewFeedbackValues,
InterviewQuestion,
SKILLS_LEVELS,
} from 'data/interviews/technical-screening';

const { Text, Title } = Typography;

export function PrescreeningFeedback({ feedback }: { feedback: StageInterviewDetailedFeedback['feedback'] }) {
const { steps } = feedback as { steps: Record<FeedbackStepId, InterviewFeedbackStepData> };

const { theory, practice, english, decision, intro } = steps;
const isRejected = intro.values?.interviewResult === 'missed';

if (isRejected) {
return (
<Space direction="vertical">
{intro.values?.comment && (
<Space>
<Text strong>Comment: </Text>
<Text>{intro.values?.comment as string} </Text>
</Space>
)}
</Space>
);
}

return (
<>
<Space direction="vertical">
{decision.values?.redFlags && (
<Space>
<Text strong>Red flags: </Text>
<Text>{decision.values?.redFlags as string} </Text>
</Space>
)}
{decision.values?.comment && (
<Space>
<Text strong>Comment: </Text>
<Text>{decision.values?.comment as string} </Text>
</Space>
)}
{english.values && (
<>
<Space>
<Text strong>Certified level of English: </Text>
<Text>{english.values?.englishCertificate as string} </Text>
</Space>
<Space>
<Text strong>English level by interviewers opinion:</Text>
<Text>{english.values?.selfAssessment as string} </Text>
</Space>
</>
)}
{english.values?.comment && (
<Space>
<Text strong>Where did the student learn English: </Text>
<Text>{english.values?.comment as string} </Text>
</Space>
)}
<SkillSection skills={theory.values} title="Theory" tooltips={SKILLS_LEVELS} />
<SkillSection skills={practice.values} title="Practice" tooltips={CODING_LEVELS} />
</Space>
</>
);
}

function SkillSection({
skills,
title,
tooltips,
}: {
skills: InterviewFeedbackValues | undefined;
title: string;
tooltips: string[];
}) {
if (!skills) return null;

return (
<Space direction="vertical" style={{ marginBottom: 20 }}>
<Title level={4}>{title}</Title>
<SkillTable skills={skills.questions as InterviewQuestion[]} tooltips={tooltips} />
{skills.comment && (
<Row>
<Text strong>Comment: </Text>&nbsp;{skills.comment as string}
</Row>
)}
</Space>
);
}

function SkillTable({ skills, tooltips }: { skills: InterviewQuestion[]; tooltips: string[] }) {
return (
<Table
dataSource={skills}
size="small"
rowKey="key"
pagination={false}
columns={[
{
width: '60%',
render: (_, record) => (
<>
{record.topic && (
<Row>
<Text type="secondary">{record.topic}</Text>
</Row>
)}
<Text>{record.title}</Text>
</>
),
},
{
dataIndex: 'value',
render: rating => <Rating rating={rating} tooltips={tooltips} />,
},
]}
/>
);
}
Loading

0 comments on commit 9a7635e

Please sign in to comment.