From 2554b41a9ab7dfb661535810776ed9031fd134ac Mon Sep 17 00:00:00 2001 From: Pyry Koivisto Date: Fri, 6 Sep 2024 16:51:10 +0300 Subject: [PATCH] VKT(Frontend): Rework enrollment preview structure on mobile to better match designs [deploy] --- .../vkt/public/i18n/fi-FI/public.json | 7 +- .../vkt/public/i18n/sv-SE/public.json | 7 +- .../steps/ExamEventDetails.tsx | 246 +++++++++++++----- 3 files changed, 198 insertions(+), 62 deletions(-) diff --git a/frontend/packages/vkt/public/i18n/fi-FI/public.json b/frontend/packages/vkt/public/i18n/fi-FI/public.json index f86d58f20..e2e59e47e 100644 --- a/frontend/packages/vkt/public/i18n/fi-FI/public.json +++ b/frontend/packages/vkt/public/i18n/fi-FI/public.json @@ -217,7 +217,12 @@ }, "examEventDetails": { "previousEnrollmentLabel": "Aikaisempiin erinomaisen taidon tutkintoihin osallistuminen", - "selectedSkillsLabel": "Valitut tutkinnot", + "desktop": { + "selectedSkillsLabel": "Valitut tutkinnot" + }, + "phone": { + "selectedSkillLabel": "Valittu tutkinto" + }, "selectedPartialExamsLabel": "Valitut osakokeet", "title": "Tutkinnon tiedot" }, diff --git a/frontend/packages/vkt/public/i18n/sv-SE/public.json b/frontend/packages/vkt/public/i18n/sv-SE/public.json index 2afb6edc6..f730dbcb2 100644 --- a/frontend/packages/vkt/public/i18n/sv-SE/public.json +++ b/frontend/packages/vkt/public/i18n/sv-SE/public.json @@ -218,7 +218,12 @@ }, "examEventDetails": { "previousEnrollmentLabel": "Deltagande i tidigare språkexamina för statsförvaltingen som gäller utmärkta språkkunskaper", - "selectedSkillsLabel": "Valda examina", + "desktop": { + "selectedSkillsLabel": "Valda examina" + }, + "phone": { + "selectedSkillLabel": "Valt examen" + }, "selectedPartialExamsLabel": "Valda delprov", "title": "Uppgifter om examen" }, diff --git a/frontend/packages/vkt/src/components/publicEnrollment/steps/ExamEventDetails.tsx b/frontend/packages/vkt/src/components/publicEnrollment/steps/ExamEventDetails.tsx index 93df7c095..401c9ca4b 100644 --- a/frontend/packages/vkt/src/components/publicEnrollment/steps/ExamEventDetails.tsx +++ b/frontend/packages/vkt/src/components/publicEnrollment/steps/ExamEventDetails.tsx @@ -1,85 +1,87 @@ +import { Divider } from '@mui/material'; import { H2, Text } from 'shared/components'; +import { useWindowProperties } from 'shared/hooks'; import { useCommonTranslation, usePublicTranslation } from 'configs/i18n'; import { useAppSelector } from 'configs/redux'; import { ClerkEnrollment } from 'interfaces/clerkEnrollment'; import { PartialExamsAndSkills } from 'interfaces/common/enrollment'; +import { PublicFreeEnrollmentDetails } from 'interfaces/publicEducation'; import { PublicEnrollment } from 'interfaces/publicEnrollment'; import { publicEnrollmentSelector } from 'redux/selectors/publicEnrollment'; import { EnrollmentUtils } from 'utils/enrollment'; import { ENROLLMENT_SKILL_PRICE } from 'utils/publicEnrollment'; -export const ExamEventDetails = ({ + +const getFreeEnrollmentsLeft = ( + skill: string, + freeEnrollmentDetails?: PublicFreeEnrollmentDetails, +) => { + if (!freeEnrollmentDetails) { + return ''; + } + + switch (skill) { + case 'textualSkill': + return freeEnrollmentDetails.freeTextualSkillLeft; + case 'oralSkill': + return freeEnrollmentDetails.freeOralSkillLeft; + default: + return ''; + } +}; + +const getEnrollmentSkillPrice = ( + skill: string, + enrollment: PublicEnrollment | ClerkEnrollment, + freeEnrollmentDetails?: PublicFreeEnrollmentDetails, +) => { + if (!freeEnrollmentDetails || !EnrollmentUtils.hasFreeBasis(enrollment)) { + return ENROLLMENT_SKILL_PRICE; + } + + switch (skill) { + case 'textualSkill': + return freeEnrollmentDetails.freeTextualSkillLeft > 0 + ? 0 + : ENROLLMENT_SKILL_PRICE; + case 'oralSkill': + return freeEnrollmentDetails.freeOralSkillLeft > 0 + ? 0 + : ENROLLMENT_SKILL_PRICE; + default: + return ENROLLMENT_SKILL_PRICE; + } +}; + +const DesktopSkillsList = ({ enrollment, - clerkView = false, + clerkView, }: { enrollment: PublicEnrollment | ClerkEnrollment; - clerkView?: boolean; + clerkView: boolean; }) => { + const translateCommon = useCommonTranslation(); const { t } = usePublicTranslation({ keyPrefix: 'vkt.component.publicEnrollment.steps.preview', }); - const translateCommon = useCommonTranslation(); const publicEnrollment = useAppSelector(publicEnrollmentSelector); const freeEnrollmentDetails = (enrollment as ClerkEnrollment).freeEnrollmentDetails || publicEnrollment.freeEnrollmentDetails; - - const skills = ['textualSkill', 'oralSkill'].filter( - (skill) => !!enrollment[skill as keyof PartialExamsAndSkills], - ); - - const partialExams = [ - 'writingPartialExam', - 'readingComprehensionPartialExam', - 'speakingPartialExam', - 'speechComprehensionPartialExam', - ].filter((exam) => !!enrollment[exam as keyof PartialExamsAndSkills]); - - const getFreeEnrollmentsLeft = (skill: string) => { - if (!freeEnrollmentDetails) { - return ''; - } - - switch (skill) { - case 'textualSkill': - return freeEnrollmentDetails.freeTextualSkillLeft; - case 'oralSkill': - return freeEnrollmentDetails.freeOralSkillLeft; - default: - return ''; - } - }; - - const getEnrollmentSkillPrice = (skill: string) => { - if (!freeEnrollmentDetails || !EnrollmentUtils.hasFreeBasis(enrollment)) { - return ENROLLMENT_SKILL_PRICE; - } - - switch (skill) { - case 'textualSkill': - return freeEnrollmentDetails.freeTextualSkillLeft > 0 - ? 0 - : ENROLLMENT_SKILL_PRICE; - case 'oralSkill': - return freeEnrollmentDetails.freeOralSkillLeft > 0 - ? 0 - : ENROLLMENT_SKILL_PRICE; - default: - return ENROLLMENT_SKILL_PRICE; - } - }; - const hasFreeEnrollments = freeEnrollmentDetails && EnrollmentUtils.hasFreeBasis(enrollment) && (freeEnrollmentDetails.freeTextualSkillLeft > 0 || freeEnrollmentDetails.freeOralSkillLeft > 0); + const skills = ['textualSkill', 'oralSkill'].filter( + (skill) => !!enrollment[skill as keyof PartialExamsAndSkills], + ); - const displaySkillsList = () => ( + return (
- {t('examEventDetails.selectedPartialExamsLabel')} + {t('examEventDetails.desktop.selectedSkillsLabel')} {hasFreeEnrollments && !clerkView && ( @@ -96,36 +98,160 @@ export const ExamEventDetails = ({ {translateCommon(`enrollment.partialExamsAndSkills.${skill}`)} {(enrollment.isFree || EnrollmentUtils.hasFreeBasis(enrollment)) && - !clerkView && {getFreeEnrollmentsLeft(skill)} / 3} - {!clerkView && {getEnrollmentSkillPrice(skill)}€} + !clerkView && ( + + {getFreeEnrollmentsLeft(skill, freeEnrollmentDetails)} / 3 + + )} + {!clerkView && ( + + {getEnrollmentSkillPrice( + skill, + enrollment, + freeEnrollmentDetails, + )} + € + + )}
))}
); +}; + +const DesktopExamsList = ({ + enrollment, +}: { + enrollment: ClerkEnrollment | PublicEnrollment; +}) => { + const { t } = usePublicTranslation({ + keyPrefix: 'vkt.component.publicEnrollment.steps.preview.examEventDetails', + }); + const translateCommon = useCommonTranslation(); - const displayExamsList = () => ( + const partialExams = [ + 'writingPartialExam', + 'readingComprehensionPartialExam', + 'speakingPartialExam', + 'speechComprehensionPartialExam', + ].filter((exam) => !!enrollment[exam as keyof PartialExamsAndSkills]); + + return (
- {t('examEventDetails.selectedSkillsLabel')} + {t('selectedPartialExamsLabel')} {':'}
); +}; + +const PhoneSkillsAndExamsList = ({ + enrollment, +}: { + enrollment: ClerkEnrollment | PublicEnrollment; +}) => { + const translateCommon = useCommonTranslation(); + const { t } = usePublicTranslation({ + keyPrefix: 'vkt.component.publicEnrollment.steps.preview', + }); + const publicEnrollment = useAppSelector(publicEnrollmentSelector); + const freeEnrollmentDetails = + (enrollment as ClerkEnrollment).freeEnrollmentDetails || + publicEnrollment.freeEnrollmentDetails; + 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')} + + + {getFreeEnrollmentsLeft(skill, freeEnrollmentDetails)}/3 + + + {t('educationDetails.price')} + + + {getEnrollmentSkillPrice( + skill, + enrollment, + freeEnrollmentDetails, + )} +  € + +
+ +
+ ))} +
+ + {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')}

- {displaySkillsList()} - {displayExamsList()} + {isPhone && } + {!isPhone && ( + <> + + + + )} {!clerkView && (