Skip to content
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

feat: Show bonus xp end date #3025

Merged
3 changes: 2 additions & 1 deletion src/commons/XMLParser/XMLParserHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ const makeAssessmentOverview = (result: any, maxXpVal: number): AssessmentOvervi
isGradingPublished: false,
xp: 0,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
};
};

Expand Down
3 changes: 2 additions & 1 deletion src/commons/application/actions/__tests__/SessionActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,8 @@ test('updateAssessmentOverviews generates correct action object', () => {
xp: 0,
isGradingPublished: false,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
}
];
const action = SessionActions.updateAssessmentOverviews(overviews);
Expand Down
6 changes: 4 additions & 2 deletions src/commons/application/reducers/__tests__/SessionReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@ const assessmentOverviewsTest1: AssessmentOverview[] = [
xp: 0,
isGradingPublished: false,
maxTeamSize: 5,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
}
];

Expand All @@ -358,7 +359,8 @@ const assessmentOverviewsTest2: AssessmentOverview[] = [
xp: 1,
isGradingPublished: false,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
}
];

Expand Down
12 changes: 10 additions & 2 deletions src/commons/assessment/Assessment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { useDispatch } from 'react-redux';
import { Navigate, useLoaderData, useParams } from 'react-router';
import { NavLink } from 'react-router-dom';
import { numberRegExp } from 'src/features/academy/AcademyTypes';
import classes from 'src/styles/Academy.module.scss';

import defaultCoverImage from '../../assets/default_cover_image.jpg';
import SessionActions from '../application/actions/SessionActions';
Expand All @@ -38,7 +39,7 @@ import Markdown from '../Markdown';
import NotificationBadge from '../notificationBadge/NotificationBadge';
import { filterNotificationsByAssessment } from '../notificationBadge/NotificationBadgeHelper';
import Constants from '../utils/Constants';
import { beforeNow, getPrettyDate } from '../utils/DateHelper';
import { beforeNow, getPrettyDate, getPrettyDateAfterHours } from '../utils/DateHelper';
import { useResponsive, useSession } from '../utils/Hooks';
import { assessmentTypeLink, convertParamToInt } from '../utils/ParamParseHelper';
import AssessmentNotFound from './AssessmentNotFound';
Expand Down Expand Up @@ -179,12 +180,19 @@ const Assessment: React.FC = () => {
</div>
<div className={classNames('listing-text', !isMobileBreakpoint && 'col-xs-9')}>
{makeOverviewCardTitle(overview, index, renderGradingTooltip)}
<div className="listing-xp">
<div className={classes['listing-xp']}>
<H6>
{overview.isGradingPublished
? `XP: ${overview.xp} / ${overview.maxXp}`
: `Max XP: ${overview.maxXp}`}
</H6>
{overview.earlySubmissionXp > 0 && (
<Tooltip
content={`Max XP ends on ${getPrettyDateAfterHours(overview.openAt, overview.hoursBeforeEarlyXpDecay)}`}
>
<Icon icon={IconNames.InfoSign} />
</Tooltip>
)}
</div>
<div className="listing-description">
<Markdown content={overview.shortSummary} />
Expand Down
4 changes: 3 additions & 1 deletion src/commons/assessment/AssessmentTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export type AssessmentOverview = {
title: string;
xp: number;
maxTeamSize: number; // For team assessment
hoursBeforeEarlyXpDecay: number;
};

/*
Expand Down Expand Up @@ -259,7 +260,8 @@ export const overviewTemplate = (): AssessmentOverview => {
isGradingPublished: false,
xp: 0,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
};
};

Expand Down
30 changes: 20 additions & 10 deletions src/commons/mocks/AssessmentMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ const mockUnopenedAssessmentsOverviews: AssessmentOverview[] = [
xp: 0,
isGradingPublished: false,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
}
];

Expand Down Expand Up @@ -162,7 +163,8 @@ const mockOpenedAssessmentsOverviews: AssessmentOverview[] = [
xp: 1,
isGradingPublished: false,
maxTeamSize: 4,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
},
{
type: 'Missions',
Expand All @@ -182,7 +184,8 @@ const mockOpenedAssessmentsOverviews: AssessmentOverview[] = [
xp: 2,
isGradingPublished: false,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
},
{
type: 'Quests',
Expand All @@ -202,7 +205,8 @@ const mockOpenedAssessmentsOverviews: AssessmentOverview[] = [
xp: 3,
isGradingPublished: false,
maxTeamSize: 2,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
},
{
type: 'Paths',
Expand All @@ -222,7 +226,8 @@ const mockOpenedAssessmentsOverviews: AssessmentOverview[] = [
xp: 0,
isGradingPublished: false,
maxTeamSize: 2,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
},
{
type: 'Others',
Expand All @@ -243,7 +248,8 @@ const mockOpenedAssessmentsOverviews: AssessmentOverview[] = [
private: true,
maxTeamSize: 1,
isGradingPublished: false,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
}
];

Expand All @@ -266,7 +272,8 @@ const mockClosedAssessmentOverviews: AssessmentOverview[] = [
xp: 800,
isGradingPublished: false,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
},
{
type: 'Quests',
Expand All @@ -286,7 +293,8 @@ const mockClosedAssessmentOverviews: AssessmentOverview[] = [
xp: 500,
isGradingPublished: false,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
},
{
type: 'Quests',
Expand All @@ -306,7 +314,8 @@ const mockClosedAssessmentOverviews: AssessmentOverview[] = [
xp: 150,
isGradingPublished: false,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
},
{
type: 'Paths',
Expand All @@ -326,7 +335,8 @@ const mockClosedAssessmentOverviews: AssessmentOverview[] = [
xp: 100,
isGradingPublished: false,
maxTeamSize: 1,
hasVotingFeatures: false
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0
}
];

Expand Down
7 changes: 7 additions & 0 deletions src/commons/utils/DateHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,10 @@ export const getStandardDate = (dateString: string): string => {
const prettyDate = date.format('MMMM Do YYYY');
return prettyDate;
};

export const getPrettyDateAfterHours = (dateString: string, hours: number): string => {
const date = moment(dateString).add(hours, 'hours');
const absolutePrettyDate = date.format('Do MMMM, HH:mm');
const relativePrettyDate = date.fromNow();
return `${absolutePrettyDate} (${relativePrettyDate})`;
};
5 changes: 5 additions & 0 deletions src/styles/Academy.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@
align-items: center;
justify-content: center;
}

.listing-xp {
display: flex;
gap: 0.5rem;
}
Loading