diff --git a/backend/vkt/src/main/java/fi/oph/vkt/util/EnrollmentUtil.java b/backend/vkt/src/main/java/fi/oph/vkt/util/EnrollmentUtil.java index 4b1e507b6..a30711812 100644 --- a/backend/vkt/src/main/java/fi/oph/vkt/util/EnrollmentUtil.java +++ b/backend/vkt/src/main/java/fi/oph/vkt/util/EnrollmentUtil.java @@ -11,6 +11,7 @@ public class EnrollmentUtil { private static final int SKILL_FEE = 25700; + private static final int SKILL_APPOINTMENT_FEE = 12900; public static final Integer FREE_ENROLLMENT_LIMIT = 3; public static int getTotalFee(final EnrollmentAppointment enrollmentAppointment) { @@ -30,7 +31,7 @@ public static int getTotalFee(final Enrollment enrollment, final FreeEnrollmentD } public static int getTextualSkillFee(final EnrollmentAppointment enrollmentAppointment) { - return enrollmentAppointment.isTextualSkill() ? SKILL_FEE : 0; + return enrollmentAppointment.isTextualSkill() ? SKILL_APPOINTMENT_FEE : 0; } public static int getTextualSkillFee(final Enrollment enrollment, final FreeEnrollmentDetails freeEnrollmentDetails) { @@ -44,7 +45,7 @@ public static int getTextualSkillFee(final Enrollment enrollment, final FreeEnro } public static int getOralSkillFee(final EnrollmentAppointment enrollmentAppointment) { - return enrollmentAppointment.isOralSkill() ? SKILL_FEE : 0; + return enrollmentAppointment.isOralSkill() ? SKILL_APPOINTMENT_FEE : 0; } public static int getOralSkillFee(final Enrollment enrollment, final FreeEnrollmentDetails freeEnrollmentDetails) { @@ -74,7 +75,7 @@ public static int getUnderstandingSkillFee(final EnrollmentAppointment enrollmen return 0; } - return SKILL_FEE; + return SKILL_APPOINTMENT_FEE; } public static int getUnderstandingSkillFee(final Enrollment enrollment) { diff --git a/frontend/packages/vkt/src/components/publicEnrollmentAppointment/steps/ExamEventDetails.tsx b/frontend/packages/vkt/src/components/publicEnrollmentAppointment/steps/ExamEventDetails.tsx new file mode 100644 index 000000000..599336e88 --- /dev/null +++ b/frontend/packages/vkt/src/components/publicEnrollmentAppointment/steps/ExamEventDetails.tsx @@ -0,0 +1,190 @@ +import { Divider } from '@mui/material'; +import { H2, Text } from 'shared/components'; +import { useWindowProperties } from 'shared/hooks'; + +import { useCommonTranslation, usePublicTranslation } from 'configs/i18n'; +import { ClerkEnrollment } from 'interfaces/clerkEnrollment'; +import { PartialExamsAndSkills } from 'interfaces/common/enrollment'; +import { PublicEnrollment } from 'interfaces/publicEnrollment'; +import { ENROLLMENT_APPOINTMENT_SKILL_PRICE } from 'utils/publicEnrollment'; + +const DesktopSkillsList = ({ + enrollment, + clerkView, +}: { + enrollment: PublicEnrollment | ClerkEnrollment; + clerkView: boolean; +}) => { + const translateCommon = useCommonTranslation(); + const { t } = usePublicTranslation({ + keyPrefix: 'vkt.component.publicEnrollment.steps.preview', + }); + const skills = ['textualSkill', 'oralSkill'].filter( + (skill) => !!enrollment[skill as keyof PartialExamsAndSkills], + ); + + return ( +
+
+ + {t('examEventDetails.desktop.selectedSkillsLabel')} + + {!clerkView && ( + {t('educationDetails.price')} + )} +
+ {skills.map((skill, i) => ( +
+ + {translateCommon(`enrollment.partialExamsAndSkills.${skill}`)} + + {!clerkView && ( + + {ENROLLMENT_APPOINTMENT_SKILL_PRICE} + € + + )} +
+ ))} +
+ ); +}; + +const DesktopExamsList = ({ + enrollment, +}: { + enrollment: ClerkEnrollment | PublicEnrollment; +}) => { + const { t } = usePublicTranslation({ + keyPrefix: 'vkt.component.publicEnrollment.steps.preview.examEventDetails', + }); + const translateCommon = useCommonTranslation(); + + const partialExams = [ + 'writingPartialExam', + 'readingComprehensionPartialExam', + 'speakingPartialExam', + 'speechComprehensionPartialExam', + ].filter((exam) => !!enrollment[exam as keyof PartialExamsAndSkills]); + + return ( +
+ + {t('selectedPartialExamsLabel')} + {':'} + + +
+ ); +}; + +const PhoneSkillsAndExamsList = ({ + enrollment, +}: { + enrollment: ClerkEnrollment | PublicEnrollment; +}) => { + const translateCommon = useCommonTranslation(); + const { t } = usePublicTranslation({ + keyPrefix: 'vkt.component.publicEnrollment.steps.preview', + }); + const skills = ['textualSkill', 'oralSkill'].filter( + (skill) => !!enrollment[skill as keyof PartialExamsAndSkills], + ); + const partialExams = [ + 'writingPartialExam', + 'readingComprehensionPartialExam', + 'speakingPartialExam', + 'speechComprehensionPartialExam', + ].filter((exam) => !!enrollment[exam as keyof PartialExamsAndSkills]); + + return ( + <> + {skills.map((skill) => ( +
+
+ + + {t('examEventDetails.phone.selectedSkillLabel')}:{' '} + {translateCommon(`enrollment.partialExamsAndSkills.${skill}`)} + + + + {t('educationDetails.freeEnrollmentsLeft')} + + + {t('educationDetails.price')} + + + {ENROLLMENT_APPOINTMENT_SKILL_PRICE} +  € + +
+ +
+ ))} +
+ + {t('examEventDetails.selectedPartialExamsLabel')}: + + +
+ + ); +}; + +export const ExamEventDetails = ({ + enrollment, + clerkView = false, +}: { + enrollment: PublicEnrollment | ClerkEnrollment; + clerkView?: boolean; +}) => { + const { t } = usePublicTranslation({ + keyPrefix: 'vkt.component.publicEnrollment.steps.preview', + }); + const translateCommon = useCommonTranslation(); + const { isPhone } = useWindowProperties(); + + return ( +
+

{t('examEventDetails.title')}

+ {isPhone && } + {!isPhone && ( + <> + + + + )} + {!clerkView && ( +
+ + {t('examEventDetails.previousEnrollmentLabel')} + {':'} + + + {enrollment.previousEnrollment + ? `${translateCommon('yes')}: ${enrollment.previousEnrollment}` + : translateCommon('no')} + +
+ )} +
+ ); +}; diff --git a/frontend/packages/vkt/src/components/publicEnrollmentAppointment/steps/Preview.tsx b/frontend/packages/vkt/src/components/publicEnrollmentAppointment/steps/Preview.tsx index c0f8f5aaa..8047d2977 100644 --- a/frontend/packages/vkt/src/components/publicEnrollmentAppointment/steps/Preview.tsx +++ b/frontend/packages/vkt/src/components/publicEnrollmentAppointment/steps/Preview.tsx @@ -9,7 +9,7 @@ import { Trans } from 'react-i18next'; import { H2, WebLink } from 'shared/components'; import { APIResponseStatus, Color } from 'shared/enums'; -import { ExamEventDetails } from 'components/publicEnrollment/steps/ExamEventDetails'; +import { ExamEventDetails } from 'components/publicEnrollmentAppointment/steps/ExamEventDetails'; import { PersonDetails } from 'components/publicEnrollmentAppointment/steps/PersonDetails'; import { useCommonTranslation, usePublicTranslation } from 'configs/i18n'; import { useAppDispatch, useAppSelector } from 'configs/redux'; diff --git a/frontend/packages/vkt/src/utils/publicEnrollment.ts b/frontend/packages/vkt/src/utils/publicEnrollment.ts index f4ed9fcd6..34d1793ae 100644 --- a/frontend/packages/vkt/src/utils/publicEnrollment.ts +++ b/frontend/packages/vkt/src/utils/publicEnrollment.ts @@ -8,6 +8,7 @@ import { PublicEnrollment } from 'interfaces/publicEnrollment'; import { EnrollmentUtils } from 'utils/enrollment'; export const ENROLLMENT_SKILL_PRICE = 257; +export const ENROLLMENT_APPOINTMENT_SKILL_PRICE = 129; export class PublicEnrollmentUtils { static getEnrollmentSteps(includePaymentStep: boolean) {