From 85a061280c0893aeebb05c40fd01d55fa0b3354f Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Thu, 7 May 2026 18:55:02 +0300 Subject: [PATCH 01/10] restructure join-us page to support new figma card hierarchy, stacked layout and updated block composition --- .../app/[lng]/(helper)/join-us/_getPage.ts | 20 +-- .../src/entities/JoinUs/index.ts | 3 + .../entities/JoinUs/model/makeJoinUsBlocks.ts | 63 ++++++++- .../src/entities/JoinUs/ui/Block.module.scss | 128 +++++++++--------- .../JoinUsPage/ui/JoinUsPage.stories.tsx | 9 +- .../JoinUsPage/ui/JoinUsPage.tsx | 25 ++-- .../ui/SectionJoinUs.module.scss | 13 +- 7 files changed, 156 insertions(+), 105 deletions(-) diff --git a/frontend-next-migration/src/app/[lng]/(helper)/join-us/_getPage.ts b/frontend-next-migration/src/app/[lng]/(helper)/join-us/_getPage.ts index 997603549..65cae02e5 100644 --- a/frontend-next-migration/src/app/[lng]/(helper)/join-us/_getPage.ts +++ b/frontend-next-migration/src/app/[lng]/(helper)/join-us/_getPage.ts @@ -2,38 +2,38 @@ import { createPage } from '@/app/_helpers'; import { JoinUsProps } from '@/preparedPages/JoinUsPage'; import { getServerTranslation } from '@/shared/i18n'; import { - makeDiscordBlock, - makeRedditBlock, - makeDuunitoriBlock, + makeGetInTouchAndFollowBlock, + makeCommunityAndOpportunitiesBlock, + makeEducationProfessionalsBlock, makeFeedbackBlock, - makeTeachersBlock, - makeInstagramBlock, } from '@/entities/JoinUs'; import { getRouteJoinUsPage } from '@/shared/appLinks/RoutePaths'; import { defaultOpenGraph } from '@/shared/seoConstants'; export async function _getPage(lng: string) { const { t } = await getServerTranslation(lng, 'join-us'); + return createPage({ buildPage: () => ({ title: t('join-us'), - discordBlock: makeDiscordBlock(t), - connectionBlock: makeRedditBlock(t), - teachersBlock: makeTeachersBlock(t), + getInTouchAndFollowBlock: makeGetInTouchAndFollowBlock(t), + communityAndOpportunitiesBlock: makeCommunityAndOpportunitiesBlock(t), + educationProfessionalsBlock: makeEducationProfessionalsBlock(t), feedbackBlock: makeFeedbackBlock(t), - duunitoriBlock: makeDuunitoriBlock(t), - instagramBlock: makeInstagramBlock(t), }), + buildSeo: () => ({ title: t('head-title'), description: t('head-description'), keywords: t('head-keywords'), + openGraph: { ...defaultOpenGraph, title: t('og-title'), description: t('og-description'), url: `/${lng}${getRouteJoinUsPage()}`, }, + alternates: { canonical: `/${lng}${getRouteJoinUsPage()}`, }, diff --git a/frontend-next-migration/src/entities/JoinUs/index.ts b/frontend-next-migration/src/entities/JoinUs/index.ts index e324a88a6..264b9619b 100644 --- a/frontend-next-migration/src/entities/JoinUs/index.ts +++ b/frontend-next-migration/src/entities/JoinUs/index.ts @@ -1,6 +1,9 @@ export { Block } from './ui/Block'; export { + makeGetInTouchAndFollowBlock, + makeCommunityAndOpportunitiesBlock, + makeEducationProfessionalsBlock, makeDiscordBlock, makeRedditBlock, makeTeachersBlock, diff --git a/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts b/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts index ff7672542..acc9911de 100644 --- a/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts +++ b/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts @@ -16,8 +16,8 @@ import ytIcon from '@/shared/assets/images/Youtube2.svg'; * Supports multiple links per block, internationalized text labels, descriptions, and an optional image. * * @param {string} section - - * A section identifier (e.g., "discord", "teachers", "feedback") that is used to construct the correct - * translation keys dynamically. These keys are combined to fetch the localized label, description, link texts, and alt texts. + * A section identifier used to construct translation keys dynamically. + * These keys are combined to fetch the localized label, description, link texts, and alt texts. * * @param {BlockSection['links']} link - * An array of link objects. Each object represents a link associated with the block and should include: @@ -37,7 +37,7 @@ import ytIcon from '@/shared/assets/images/Youtube2.svg'; * * @callback t * @param {string} key - - * The translation key used to fetch the localized string (e.g., "block-label-discord", "block-description-feedback"). + * The translation key used to fetch the localized string. * * @returns {string} - * The translated string value associated with the provided key. @@ -64,11 +64,64 @@ export const makeBlocksWithI18n = ( }; }; +export const makeGetInTouchAndFollowBlock = makeBlocksWithI18n( + 'getInTouchAndFollow', + [ + { text: 'email', url: 'mailto:proyaleg@gmail.com', isExternal: true }, + { text: 'phone', url: 'tel:+358442407396', isExternal: true }, + { + text: 'icone', + url: AppExternalLinks.discord, + isExternal: true, + iconSrc: discordIcon.src, + }, + { + text: 'icone', + url: AppExternalLinks.facebook, + isExternal: true, + iconSrc: fbdIcon.src, + }, + { + text: 'icone', + url: AppExternalLinks.youtube, + isExternal: true, + iconSrc: ytIcon.src, + }, + { + text: 'icone', + url: AppExternalLinks.instagram, + isExternal: true, + iconSrc: igIcon.src, + }, + ], + ConnectionImage.src.toString(), +); + +export const makeCommunityAndOpportunitiesBlock = makeBlocksWithI18n( + 'communityAndOpportunities', + [ + { text: 'discord', url: AppExternalLinks.discord, isExternal: true }, + { text: 'duunitori', url: AppExternalLinks.duunitori, isExternal: true }, + ], + discordImage.src.toString(), +); + +export const makeEducationProfessionalsBlock = makeBlocksWithI18n( + 'educationProfessionals', + [ + { text: 'email', url: 'mailto:proyaleg@gmail.com', isExternal: true }, + { text: 'phone', url: 'tel:+358442407396', isExternal: true }, + { text: 'teacherPg', url: AppExternalLinks.dlpackage, isExternal: true }, + ], + teachersImage.src.toString(), +); + export const makeDiscordBlock = makeBlocksWithI18n( 'discord', [{ text: 'discord', url: AppExternalLinks.discord, isExternal: true }], discordImage.src.toString(), ); + export const makeRedditBlock = makeBlocksWithI18n( 'connection', [ @@ -77,6 +130,7 @@ export const makeRedditBlock = makeBlocksWithI18n( ], ConnectionImage.src.toString(), ); + export const makeTeachersBlock = makeBlocksWithI18n( 'teachers', [ @@ -86,6 +140,7 @@ export const makeTeachersBlock = makeBlocksWithI18n( ], teachersImage.src.toString(), ); + export const makeFeedbackBlock = makeBlocksWithI18n( 'feedback', [ @@ -94,11 +149,13 @@ export const makeFeedbackBlock = makeBlocksWithI18n( ], feedbackImage.src.toString(), ); + export const makeDuunitoriBlock = makeBlocksWithI18n( 'duunitori', [{ text: 'duunitori', url: AppExternalLinks.duunitori, isExternal: true }], duunitoriImage.src.toString(), ); + export const makeInstagramBlock = makeBlocksWithI18n( 'instagram', [ diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss index 4e62fac50..8d7c7b3d9 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss @@ -1,51 +1,50 @@ .Container { - margin: auto 0; - padding: 0 0 5px 0; - text-align: center; - height: 100%; - place-content: center; + padding: 24px; + text-align: left; + border-radius: var(--border-radius-custom); background-color: #1E3544; border: 2px solid black; box-shadow: 0.5rem 0.5rem black; - text-align: left; + display: flex; - align-items: center; + align-items: flex-start; justify-content: flex-start; - - .Content{ + .Content { flex-grow: 1; - } - + .multilineText { white-space: pre-line; - } + } - .ImageWrapper { + .ImageWrapper { width: fit-content; height: 236px; + display: flex; flex-shrink: 0; - margin: auto 10px; - padding: 10px; align-items: center; + margin: auto 10px; + padding: 10px; - img{ - width: 12em; - height: 12em; + img { + width: 9em; + height: 9em; object-fit: center; } - } + } h2 { padding: 15px 0 0 0; margin: 0; + color: var(--primary-color); font: var(--font-sw-xxl); + white-space: pre-line; } @@ -57,127 +56,134 @@ p { font: var(--font-dm-s); margin: 15px 0; + color: var(--text-color); + line-height: 1.1em; text-align: left; - max-width: 85%; + align-self: flex-start; - } a { - text-decoration: underline; font: var(--font-dm-s); - color: var(--primary-color)!important; + + color: var(--primary-color) !important; text-decoration: none; - &:hover { - color: var(--secondary-color)!important; + color: var(--secondary-color) !important; + } + + &::after { + content: ''; + display: block; + padding: 0 0 10px; } - - &::after { - content: ''; - display: block; - padding: 0 0 10px; - } } + .linkWrapper { padding: 0; margin: 0; line-height: 0.8em; } - - .linkWrapper:has(img) { - + .linkWrapper:has(img) { display: flex; align-items: center; margin: 0 10px 0 0; - a { - display:inline-flex; + + a { + display: inline-flex; flex-direction: row; - img{ + img { color: #ffa100; width: 2.7vh; + transition: transform 0.15s ease; - } - - &:hover img { - transform: scale(1.1); - } - } + &:hover img { + transform: scale(1.1); + } } + } } - - @media (max-width: breakpoint(md)) { .Container { flex-direction: column; align-items: center; justify-content: center; - text-align: center; - padding: 10px 0 0; - margin: auto; + width: 100%; + + margin: auto; + padding: 10px 0 0; + + text-align: center; + box-shadow: 0.2rem 0.2rem #121212; .linkWrapper { margin: 0; padding: 0; } + .ImageWrapper { width: 100%; height: auto; - margin: 0; - padding: 0; + display: flex; justify-content: center; align-items: center; - img{ + margin: 0; + padding: 0; + + img { width: 8em; height: 8em; object-fit: center; } } - - - p{ + p { font: var(--font-dm-xs); + margin: 10px auto; padding: 0 10px; + text-align: center; max-width: 100%; } - .linkWrapper:has(img) { + .linkWrapper:has(img) { display: flex; align-items: center; - width: 100%; - margin: 0 10px 10px ; - } + width: 100%; + margin: 0 10px 10px; + } } } + @media (min-width: breakpoint(md)) and (max-width: 900px) { .Container { .ImageWrapper { width: fit-content; height: auto; - margin: 0; - padding: 0; + display: flex; justify-content: center; align-items: center; - img{ + margin: 0; + padding: 0; + + img { width: 8em; height: 8em; object-fit: center; diff --git a/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.stories.tsx b/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.stories.tsx index 17f89e5ca..d607d9229 100644 --- a/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.stories.tsx +++ b/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.stories.tsx @@ -127,13 +127,10 @@ type Story = StoryObj; export const Default: Story = { args: { title: 'Join Us!', - discordBlock: mockDiscordBlock, - // redditBlock: mockRedditBlock, - teachersBlock: mockTeachersBlock, + getInTouchAndFollowBlock: mockConnectionBlock, + communityAndOpportunitiesBlock: mockDiscordBlock, + educationProfessionalsBlock: mockTeachersBlock, feedbackBlock: mockFeedbackBlock, - duunitoriBlock: mockDuunitoriBlock, - connectionBlock: mockConnectionBlock, - instagramBlock: mockInstagramBlock, }, parameters: { layout: 'fullscreen', diff --git a/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.tsx b/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.tsx index 299a7a258..de4f16a2f 100644 --- a/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.tsx +++ b/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.tsx @@ -5,24 +5,20 @@ import { BlockSection } from '../types'; export interface Props { title: string; - discordBlock: BlockSection; - connectionBlock: BlockSection; - instagramBlock: BlockSection; - teachersBlock: BlockSection; + getInTouchAndFollowBlock: BlockSection; + communityAndOpportunitiesBlock: BlockSection; + educationProfessionalsBlock: BlockSection; feedbackBlock: BlockSection; - duunitoriBlock: BlockSection; navHeight?: number; } export const JoinUsPage = (props: Props) => { const { title, - discordBlock, - connectionBlock, - instagramBlock, - teachersBlock, + getInTouchAndFollowBlock, + communityAndOpportunitiesBlock, + educationProfessionalsBlock, feedbackBlock, - duunitoriBlock, } = props; return ( @@ -31,13 +27,12 @@ export const JoinUsPage = (props: Props) => {

{title}

+ diff --git a/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.module.scss b/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.module.scss index 1b7a3632a..abcbae3a7 100644 --- a/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.module.scss +++ b/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.module.scss @@ -1,22 +1,15 @@ .Container { display: grid; + grid-template-columns: 1fr; + gap: 35px; + margin: 10px auto 40px; - flex-direction: row-reverse; padding-bottom: 2vh; } -@media screen and (min-width: breakpoint(sm)) { - .Container { - grid-template-columns: repeat(2, minmax(0, 1fr)); - grid-template-rows: repeat(3, minmax(0, 1fr)); - margin: 10px auto; - } -} @media screen and (max-width: breakpoint(sm)) { .Container { - grid-template-columns: 1fr; - grid-template-rows: auto; gap: 20px; margin: 0 auto; } From b1c35bd9debf57fedbd76bb5b4e26cc8eb6571a5 Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Sat, 9 May 2026 10:19:49 +0300 Subject: [PATCH 02/10] update card spacing, typography and fi locale content to match figma design --- .../src/entities/JoinUs/ui/Block.module.scss | 106 ++++++++++++------ .../src/entities/JoinUs/ui/Block.tsx | 8 +- .../JoinUsPage/ui/JoinUsPage.module.scss | 51 ++++----- .../src/shared/i18n/locales/fi/join-us.json | 26 +++-- .../ui/SectionJoinUs.module.scss | 19 ++-- 5 files changed, 125 insertions(+), 85 deletions(-) diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss index 8d7c7b3d9..653225e6c 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss @@ -1,19 +1,29 @@ .Container { + display: flex; + align-items: center; + justify-content: space-between; + + width: 100%; + min-height: 240px; + margin: auto 0; - padding: 24px; + padding: 40px 48px; + gap: 48px; + text-align: left; - border-radius: var(--border-radius-custom); + border-radius: 24px; background-color: #1E3544; - border: 2px solid black; - box-shadow: 0.5rem 0.5rem black; - display: flex; - align-items: flex-start; - justify-content: flex-start; + border: 2px solid black; + box-shadow: 8px 8px 0 black; .Content { - flex-grow: 1; + flex: 1; + + display: flex; + flex-direction: column; + justify-content: center; } .multilineText { @@ -22,28 +32,26 @@ .ImageWrapper { width: fit-content; - height: 236px; + height: auto; display: flex; flex-shrink: 0; align-items: center; - - margin: auto 10px; - padding: 10px; + justify-content: center; img { - width: 9em; - height: 9em; - object-fit: center; + width: 10em; + height: 10em; + object-fit: contain; } } h2 { - padding: 15px 0 0 0; - margin: 0; + margin: 0 0 16px; color: var(--primary-color); font: var(--font-sw-xxl); + line-height: 1.1; white-space: pre-line; } @@ -54,18 +62,23 @@ } p { + max-width: 720px; + + margin: 0 0 24px; + font: var(--font-dm-s); - margin: 15px 0; color: var(--text-color); - line-height: 1.1em; + line-height: 1.5; text-align: left; - - align-self: flex-start; } a { + display: inline-flex; + align-items: center; + gap: 8px; + font: var(--font-dm-s); color: var(--primary-color) !important; @@ -85,23 +98,35 @@ .linkWrapper { padding: 0; margin: 0; - line-height: 0.8em; + line-height: 1.4; } .linkWrapper:has(img) { display: flex; align-items: center; + margin: 0 10px 0 0; a { display: inline-flex; + align-items: center; flex-direction: row; img { - color: #ffa100; - width: 2.7vh; + width: 28px; + height: 28px; transition: transform 0.15s ease; + + filter: + brightness(0) + saturate(100%) + invert(70%) + sepia(77%) + saturate(2247%) + hue-rotate(360deg) + brightness(101%) + contrast(105%); } &:hover img { @@ -114,18 +139,23 @@ @media (max-width: breakpoint(md)) { .Container { flex-direction: column; - align-items: center; - justify-content: center; + align-items: flex-start; + justify-content: flex-start; width: 100%; margin: auto; - padding: 10px 0 0; + padding: 24px; + gap: 24px; - text-align: center; + text-align: left; box-shadow: 0.2rem 0.2rem #121212; + .Content { + width: 100%; + } + .linkWrapper { margin: 0; padding: 0; @@ -145,18 +175,22 @@ img { width: 8em; height: 8em; - object-fit: center; + object-fit: contain; } } + h2 { + margin: 0 0 12px; + } + p { - font: var(--font-dm-xs); + max-width: 100%; - margin: 10px auto; - padding: 0 10px; + margin: 0 0 20px; - text-align: center; - max-width: 100%; + font: var(--font-dm-xs); + + text-align: left; } .linkWrapper:has(img) { @@ -172,6 +206,8 @@ @media (min-width: breakpoint(md)) and (max-width: 900px) { .Container { + padding: 32px; + .ImageWrapper { width: fit-content; height: auto; @@ -186,7 +222,7 @@ img { width: 8em; height: 8em; - object-fit: center; + object-fit: contain; } } } diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx index dbbe8d212..5624a8983 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx @@ -30,9 +30,12 @@ export const Block = (props: Props) => { alt={block.imgAlt} /> +

{block.label}

+

{block.description}

+
{block.links.map((link, index) => ( diff --git a/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.module.scss b/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.module.scss index 73a426a2c..a9b2167e9 100644 --- a/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.module.scss +++ b/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.module.scss @@ -1,65 +1,54 @@ .Container { + width: 100%; + max-width: 1440px; + + margin: 0 auto; + padding: 0 48px 64px; border-radius: var(--border-radius-custom); - padding: 0 20px 20px 0; h1 { - font: var(--font-sw-5xl); - line-height: 1.5rem; - text-align: left; - color: var(--primary-color); - } + margin: 64px 0 40px; - @keyframes lineExpand { - 0% { - width: 0; - } + color: var(--primary-color); - 100% { - width: 500px; - max-width: 70vw; - } + font: var(--font-sw-5xl); + line-height: 1.1; + text-align: left; } } @media screen and (max-width: breakpoint(md)) { .Container { - padding: 10px; - margin: 0 auto; + padding: 0 16px 48px; h1 { + margin: 32px 0 24px; + font: var(--font-sw-xxl); - margin: 0 0 20px; - margin-top: 7vh; - padding: 20px 0 0 0; - text-align: center; + text-align: left; } } - } @media screen and ((min-width: breakpoint(sm)) and (max-width: breakpoint(md))) { .Container { - padding: 10px 20px; - margin: 0 auto; + padding: 0 24px 56px; h1 { - font: var(--font-sw-5xl); - margin: 40px auto; - margin-top: 10vh; + margin: 48px 0 32px; + + font: var(--font-sw-4xl); } } } @media screen and (min-width: breakpoint(md)) { .Container { - padding: 10px 20px; - margin: 0 auto; + padding: 0 48px 64px; h1 { - font: var(--font-sw-5xl); - margin: 40px auto; - margin-top: 10vh; + margin-top: 64px; } } } \ No newline at end of file diff --git a/frontend-next-migration/src/shared/i18n/locales/fi/join-us.json b/frontend-next-migration/src/shared/i18n/locales/fi/join-us.json index 70ccac9df..4fdc97970 100644 --- a/frontend-next-migration/src/shared/i18n/locales/fi/join-us.json +++ b/frontend-next-migration/src/shared/i18n/locales/fi/join-us.json @@ -1,8 +1,8 @@ { - "join-us": "Tule mukaan!", - "head-title": "Tule mukaan - ALT Zone", + "join-us": "Ota yhteyttä", + "head-title": "Ota yhteyttä - ALT Zone", "head-description": "Liity ALT Zone -projektiin! Tule testaajaksi, tutustu opetuspaketteihin, hae työharjoitteluun, liity Discord-yhteisöömme tai jaa palautteesi pelimme parantamiseksi.", - "head-keywords": "ALT Zone tule mukaan, testaaja, opetuspaketti, työharjoittelu, vapaaehtoistyö, Discord", + "head-keywords": "ALT Zone yhteystiedot, testaaja, opetuspaketti, työharjoittelu, vapaaehtoistyö, Discord", "og-title": "Liity ALT Zone -projektiin", "og-description": "Ole osa ALT Zone -matkaa — testaa peliämme, tutustu opetusvälineisiin, liity Discordiin, hae työharjoittelua tai lähetä meille palautetta.", @@ -13,13 +13,21 @@ "block-label-instagram": "Keskustele lisää \nsomessa", "block-label-discord": "Tule Testaajaksi", + "block-label-getInTouchAndFollow": "Ole yhteydessä ja seuraa", + "block-label-communityAndOpportunities": "Työyhteisö ja mahdollisuudet", + "block-label-educationProfessionals": "Opetuksen ammattilaiselle", + "block-description-discord": "Tule kertomaan ideasi liittymällä Discord- \npeliyhteisöömme", "block-description-connection": "Mikäli kiinnostuit projektistamme, ota rohkeasti yhteyttä", "block-description-teachers": "Ilmoittaudu testaamaan opetuspakettia", "block-description-duunitori": "Tarjoamme mahdollisuuksien mukaan palkatonta työkokeilua ja -harjoittelua projektimme parissa. Olet tervetullut tekemään hommia myös vapaaehtoisena. \n\nTarkastele avoimia paikkoja Duunitorista.", - "block-description-feedback": "Palautelomakkeen tavoite on kerätä palautetta \nnettisivuista ja mobiilipelistä jatkokehitystä varten. \nPalautteesi on ensisijaisen tärkeää ja käsittelemme \npalautteet yhdessä kehitystiimin kanssa. \n\nKiitos vastauksistasi jo etukäteen!", + "block-description-feedback": "Palautelomakkeen tavoite on kerätä palautetta \nnettisivuista ja mobiilipelistä jatkokehitystä varten. \nPalautteesi on ensisijaisen tärkeää ja käsittelemme \npalautteet yhdessä kehitystiimin kanssa. \n\nKiitos vastauksistasi jo etukäteen!", "block-description-instagram": "", + "block-description-getInTouchAndFollow": "Mikäli kiinnostuit projektistamme, ota rohkeasti yhteyttä. Seuraa meitä myös somessa!", + "block-description-communityAndOpportunities": "Tule kertomaan ideasi liittymällä Discord-peliyhteisöömme! Tarjoamme mahdollisuuksien mukaan palkatonta työkokeilua ja -harjoittelua projektiemme parissa. Olet tervetullut tekemään hommia myös vapaaehtoisena. Tarkastele myös avoimia paikkoja Duunitorissa.", + "block-description-educationProfessionals": "Ilmoittaudu testaamaan opetuspakettia!", + "block-link-text-discord": "discord.gg/mgjQkCR2Fg", "block-link-text-teacherPg": "Tutustu opetuspakettiin", "block-link-text-duunitori": "Avoimet paikat Duunitorissa", @@ -31,11 +39,15 @@ "block-link-text-icone": "", "block-image-alt-discord": "Discord", - "block-image-alt-connection": "Reddit", - "block-image-alt-teachers": "Teacher!", + "block-image-alt-connection": "Yhteystiedot", + "block-image-alt-teachers": "Opetus", "block-image-alt-duunitori": "Duunitori", - "block-image-alt-feedback": "Feedback", + "block-image-alt-feedback": "Palaute", "block-image-alt-instagram": "Instagram", + "block-image-alt-getInTouchAndFollow": "Ota yhteyttä", + "block-image-alt-communityAndOpportunities": "Työyhteisö ja mahdollisuudet", + "block-image-alt-educationProfessionals": "Opetuksen ammattilaiselle", + "block-website": "www.example.com" } diff --git a/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.module.scss b/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.module.scss index abcbae3a7..82f0b367e 100644 --- a/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.module.scss +++ b/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.module.scss @@ -1,16 +1,15 @@ .Container { - display: grid; - grid-template-columns: 1fr; - - gap: 35px; - - margin: 10px auto 40px; - padding-bottom: 2vh; + display: flex; + flex-direction: column; + gap: 32px; + width: 100%; + margin: 0 auto; + padding-bottom: 48px; } -@media screen and (max-width: breakpoint(sm)) { +@media screen and (max-width: breakpoint(md)) { .Container { - gap: 20px; - margin: 0 auto; + gap: 24px; + padding-bottom: 32px; } } From 7bc10a5d1dccb040781942a939100f579896537a Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Tue, 12 May 2026 19:35:19 +0300 Subject: [PATCH 03/10] improve join-us figma parity with centered card content, z-layout visuals, updated spacing and refined responsive styling --- .../entities/JoinUs/model/makeJoinUsBlocks.ts | 2 +- .../src/entities/JoinUs/ui/Block.module.scss | 61 +++++++++++-------- .../src/entities/JoinUs/ui/Block.tsx | 5 +- .../SectionJoinUs/ui/SectionJoinUs.tsx | 2 + 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts b/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts index acc9911de..8a5fc88fd 100644 --- a/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts +++ b/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts @@ -67,7 +67,6 @@ export const makeBlocksWithI18n = ( export const makeGetInTouchAndFollowBlock = makeBlocksWithI18n( 'getInTouchAndFollow', [ - { text: 'email', url: 'mailto:proyaleg@gmail.com', isExternal: true }, { text: 'phone', url: 'tel:+358442407396', isExternal: true }, { text: 'icone', @@ -93,6 +92,7 @@ export const makeGetInTouchAndFollowBlock = makeBlocksWithI18n( isExternal: true, iconSrc: igIcon.src, }, + { text: 'email', url: 'mailto:proyaleg@gmail.com', isExternal: true }, ], ConnectionImage.src.toString(), ); diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss index 653225e6c..d9c655e7d 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss @@ -1,29 +1,33 @@ .Container { + position: relative; + display: flex; align-items: center; - justify-content: space-between; + justify-content: center; width: 100%; min-height: 240px; margin: auto 0; padding: 40px 48px; - gap: 48px; text-align: left; - border-radius: 24px; + border-radius: 12px; background-color: #1E3544; border: 2px solid black; box-shadow: 8px 8px 0 black; .Content { - flex: 1; + width: 100%; display: flex; flex-direction: column; justify-content: center; + align-items: center; + + text-align: center; } .multilineText { @@ -31,11 +35,14 @@ } .ImageWrapper { - width: fit-content; - height: auto; + position: absolute; + + left: 48px; + top: 50%; + + transform: translateY(-50%); display: flex; - flex-shrink: 0; align-items: center; justify-content: center; @@ -54,6 +61,7 @@ line-height: 1.1; white-space: pre-line; + text-align: center; } h3 { @@ -71,7 +79,7 @@ color: var(--text-color); line-height: 1.5; - text-align: left; + text-align: center; } a { @@ -96,8 +104,15 @@ } .linkWrapper { + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; + gap: 24px; + padding: 0; margin: 0; + line-height: 1.4; } @@ -105,7 +120,7 @@ display: flex; align-items: center; - margin: 0 10px 0 0; + margin: 0; a { display: inline-flex; @@ -136,10 +151,15 @@ } } +.Reverse .ImageWrapper { + left: auto; + right: 48px; +} + @media (max-width: breakpoint(md)) { .Container { flex-direction: column; - align-items: flex-start; + align-items: center; justify-content: flex-start; width: 100%; @@ -148,7 +168,7 @@ padding: 24px; gap: 24px; - text-align: left; + text-align: center; box-shadow: 0.2rem 0.2rem #121212; @@ -162,6 +182,10 @@ } .ImageWrapper { + position: static; + + transform: none; + width: 100%; height: auto; @@ -190,7 +214,7 @@ font: var(--font-dm-xs); - text-align: left; + text-align: center; } .linkWrapper:has(img) { @@ -199,7 +223,7 @@ width: 100%; - margin: 0 10px 10px; + margin: 0; } } } @@ -209,20 +233,9 @@ padding: 32px; .ImageWrapper { - width: fit-content; - height: auto; - - display: flex; - justify-content: center; - align-items: center; - - margin: 0; - padding: 0; - img { width: 8em; height: 8em; - object-fit: contain; } } } diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx index 5624a8983..5c6db74eb 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx @@ -12,14 +12,15 @@ import cls from './Block.module.scss'; interface Props { block: BlockSection; + reverse?: boolean; } export const Block = (props: Props) => { - const { block } = props; + const { block, reverse = false } = props; return (
diff --git a/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.tsx b/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.tsx index b0d7272da..83dbefc45 100644 --- a/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.tsx +++ b/frontend-next-migration/src/widgets/SectionJoinUs/ui/SectionJoinUs.tsx @@ -25,6 +25,7 @@ interface Props { export const SectionJoinUs = (props: Props) => { const { blocks } = props; + return ( { ))} From 115a00664fed685f88a418157182f7442f9db19a Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Thu, 14 May 2026 11:09:14 +0300 Subject: [PATCH 04/10] Added external link icons --- .../src/entities/JoinUs/ui/Block.module.scss | 14 ++++++++++++-- .../src/entities/JoinUs/ui/Block.tsx | 10 ++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss index d9c655e7d..0e28ffee5 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss @@ -127,7 +127,7 @@ align-items: center; flex-direction: row; - img { + img:not(.ExternalIcon) { width: 28px; height: 28px; @@ -144,13 +144,23 @@ contrast(105%); } - &:hover img { + &:hover img:not(.ExternalIcon) { transform: scale(1.1); } } } } +.ExternalIcon { + width: 10px !important; + height: 10px !important; + + min-width: 10px; + + object-fit: contain; + flex-shrink: 0; +} + .Reverse .ImageWrapper { left: auto; right: 48px; diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx index 5c6db74eb..2193ab273 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx @@ -1,5 +1,6 @@ import type { BlockSection } from '../types'; import cls from './Block.module.scss'; +import externalLinkIcon from '@/shared/assets/icons/ExternalLink.svg'; /** * Block Component @@ -58,6 +59,15 @@ export const Block = (props: Props) => { )} {link.text} + + {link.isExternal && !link.iconSrc && ( + // eslint-disable-next-line @next/next/no-img-element + External link + )}
))} From 9329029b3d07c5bcc1efb73ccf7d6e48699480c9 Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Thu, 14 May 2026 15:32:09 +0300 Subject: [PATCH 05/10] Refined responsive Join Us block layouts, improved mobile typography and link styling, fixed image positioning, and corrected external link icon behavior across breakpoints --- .../src/entities/JoinUs/index.ts | 5 - .../entities/JoinUs/model/makeJoinUsBlocks.ts | 96 ++++------- .../src/entities/JoinUs/types/index.ts | 1 + .../src/entities/JoinUs/ui/Block.module.scss | 156 ++++++++++++++---- .../src/entities/JoinUs/ui/Block.tsx | 46 +++++- .../preparedPages/JoinUsPage/types/index.ts | 1 + .../src/shared/i18n/locales/fi/join-us.json | 1 + 7 files changed, 204 insertions(+), 102 deletions(-) diff --git a/frontend-next-migration/src/entities/JoinUs/index.ts b/frontend-next-migration/src/entities/JoinUs/index.ts index 264b9619b..db2e8fd4e 100644 --- a/frontend-next-migration/src/entities/JoinUs/index.ts +++ b/frontend-next-migration/src/entities/JoinUs/index.ts @@ -4,10 +4,5 @@ export { makeGetInTouchAndFollowBlock, makeCommunityAndOpportunitiesBlock, makeEducationProfessionalsBlock, - makeDiscordBlock, - makeRedditBlock, - makeTeachersBlock, - makeDuunitoriBlock, makeFeedbackBlock, - makeInstagramBlock, } from './model/makeJoinUsBlocks'; diff --git a/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts b/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts index 8a5fc88fd..bcae7ad55 100644 --- a/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts +++ b/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts @@ -3,9 +3,7 @@ import { AppExternalLinks } from '@/shared/appLinks/appExternalLinks'; import ConnectionImage from '@/shared/assets/images/heros/mirror/Mirror.png'; import teachersImage from '@/shared/assets/images/heros/sleeper/Sleeper_new.png'; import feedbackImage from '@/shared/assets/images/heros/einstein/einstein.png'; -import duunitoriImage from '@/shared/assets/images/heros/purple-girls/purpel-girls-main.png'; import discordImage from '@/shared/assets/images/heros/conman/conman.png'; -import instagramImage from '@/shared/assets/images/heros/fate-priest/Believer.png'; import igIcon from '@/shared/assets/images/Insta2.svg'; import fbdIcon from '@/shared/assets/images/Facebook2.svg'; import discordIcon from '@/shared/assets/images/Discord2.svg'; @@ -57,6 +55,7 @@ export const makeBlocksWithI18n = ( text: t(`block-link-text-${linkItem.text}`), isExternal: linkItem.isExternal ?? false, iconSrc: linkItem.iconSrc, + showExternalIcon: linkItem.showExternalIcon, })), img: img || '', imgAlt: t(`block-image-alt-${section}`), @@ -100,8 +99,24 @@ export const makeGetInTouchAndFollowBlock = makeBlocksWithI18n( export const makeCommunityAndOpportunitiesBlock = makeBlocksWithI18n( 'communityAndOpportunities', [ - { text: 'discord', url: AppExternalLinks.discord, isExternal: true }, - { text: 'duunitori', url: AppExternalLinks.duunitori, isExternal: true }, + { + text: 'discord', + url: AppExternalLinks.discord, + isExternal: true, + showExternalIcon: true, + }, + { + text: 'news', + url: '/fi/news', + isExternal: true, + showExternalIcon: true, + }, + { + text: 'duunitori', + url: AppExternalLinks.duunitori, + isExternal: true, + showExternalIcon: true, + }, ], discordImage.src.toString(), ); @@ -109,34 +124,14 @@ export const makeCommunityAndOpportunitiesBlock = makeBlocksWithI18n( export const makeEducationProfessionalsBlock = makeBlocksWithI18n( 'educationProfessionals', [ - { text: 'email', url: 'mailto:proyaleg@gmail.com', isExternal: true }, - { text: 'phone', url: 'tel:+358442407396', isExternal: true }, - { text: 'teacherPg', url: AppExternalLinks.dlpackage, isExternal: true }, - ], - teachersImage.src.toString(), -); - -export const makeDiscordBlock = makeBlocksWithI18n( - 'discord', - [{ text: 'discord', url: AppExternalLinks.discord, isExternal: true }], - discordImage.src.toString(), -); - -export const makeRedditBlock = makeBlocksWithI18n( - 'connection', - [ - { text: 'email', url: 'mailto:proyaleg@gmail.com', isExternal: true }, { text: 'phone', url: 'tel:+358442407396', isExternal: true }, - ], - ConnectionImage.src.toString(), -); - -export const makeTeachersBlock = makeBlocksWithI18n( - 'teachers', - [ + { + text: 'teacherPg', + url: AppExternalLinks.dlpackage, + isExternal: true, + showExternalIcon: true, + }, { text: 'email', url: 'mailto:proyaleg@gmail.com', isExternal: true }, - { text: 'phone', url: 'tel:+358442407396', isExternal: true }, - { text: 'teacherPg', url: AppExternalLinks.dlpackage, isExternal: true }, ], teachersImage.src.toString(), ); @@ -144,45 +139,18 @@ export const makeTeachersBlock = makeBlocksWithI18n( export const makeFeedbackBlock = makeBlocksWithI18n( 'feedback', [ - { text: 'feedbackWep', url: AppExternalLinks.googleWebFeedback, isExternal: true }, - { text: 'feedbackGame', url: AppExternalLinks.googleFeedback, isExternal: true }, - ], - feedbackImage.src.toString(), -); - -export const makeDuunitoriBlock = makeBlocksWithI18n( - 'duunitori', - [{ text: 'duunitori', url: AppExternalLinks.duunitori, isExternal: true }], - duunitoriImage.src.toString(), -); - -export const makeInstagramBlock = makeBlocksWithI18n( - 'instagram', - [ - { - text: 'icone', - url: AppExternalLinks.discord, - isExternal: true, - iconSrc: discordIcon.src, - }, - { - text: 'icone', - url: AppExternalLinks.facebook, - isExternal: true, - iconSrc: fbdIcon.src, - }, { - text: 'icone', - url: AppExternalLinks.youtube, + text: 'feedbackWep', + url: AppExternalLinks.googleWebFeedback, isExternal: true, - iconSrc: ytIcon.src, + showExternalIcon: true, }, { - text: 'icone', - url: AppExternalLinks.instagram, + text: 'feedbackGame', + url: AppExternalLinks.googleFeedback, isExternal: true, - iconSrc: igIcon.src, + showExternalIcon: true, }, ], - instagramImage.src.toString(), + feedbackImage.src.toString(), ); diff --git a/frontend-next-migration/src/entities/JoinUs/types/index.ts b/frontend-next-migration/src/entities/JoinUs/types/index.ts index 01123d85a..5323432d1 100644 --- a/frontend-next-migration/src/entities/JoinUs/types/index.ts +++ b/frontend-next-migration/src/entities/JoinUs/types/index.ts @@ -16,6 +16,7 @@ export interface BlockSection { text: string; url: string; isExternal?: boolean; + showExternalIcon?: boolean; iconSrc?: string; }[]; img: string; diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss index 0e28ffee5..83f80ee71 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss @@ -84,23 +84,22 @@ a { display: inline-flex; + flex-direction: row; align-items: center; - gap: 8px; + justify-content: center; + + gap: 4px; font: var(--font-dm-s); color: var(--primary-color) !important; text-decoration: none; + white-space: nowrap; + &:hover { color: var(--secondary-color) !important; } - - &::after { - content: ''; - display: block; - padding: 0 0 10px; - } } .linkWrapper { @@ -108,7 +107,9 @@ justify-content: center; align-items: center; flex-wrap: wrap; - gap: 24px; + + column-gap: 24px; + row-gap: 12px; padding: 0; margin: 0; @@ -116,11 +117,30 @@ line-height: 1.4; } - .linkWrapper:has(img) { + /* text link spacing */ + .linkWrapper:not(:has(.icon)) { + margin: 0 24px; + } + + /* social icon spacing */ + .linkWrapper:has(.icon) { + margin: 0 -12px; + } + + .socialLinks { display: flex; align-items: center; + justify-content: center; + flex-wrap: nowrap; + gap: 4px; + } - margin: 0; + .linkWrapper:has(.icon) { + display: flex; + align-items: center; + + margin-top: 0; + margin-bottom: 0; a { display: inline-flex; @@ -152,13 +172,16 @@ } .ExternalIcon { - width: 10px !important; - height: 10px !important; + width: 0.8em; + height: 0.8em; + + display: inline-block; - min-width: 10px; + margin-left: 0.2em; + + vertical-align: middle; object-fit: contain; - flex-shrink: 0; } .Reverse .ImageWrapper { @@ -174,9 +197,11 @@ width: 100%; + min-height: 520px; + margin: auto; - padding: 24px; - gap: 24px; + padding: 56px 24px; + gap: 40px; text-align: center; @@ -184,11 +209,38 @@ .Content { width: 100%; + + gap: 40px; + } + + .Content > .linkWrapper { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + row-gap: 20px; } .linkWrapper { margin: 0; padding: 0; + + width: auto; + } + + .socialLinks { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + + gap: 4px; + + img { + width: 32px !important; + height: 32px !important; + } } .ImageWrapper { @@ -214,45 +266,91 @@ } h2 { - margin: 0 0 12px; + margin: 0 0 36px; } p { - max-width: 100%; + max-width: 270px; - margin: 0 0 20px; + margin: 8px 0 56px; - font: var(--font-dm-xs); + font-size: 1.9rem; + font-weight: 400; + line-height: 1.65; text-align: center; } - .linkWrapper:has(img) { + a { + display: inline-flex; + flex-direction: column; + align-items: center; + justify-content: center; + + font-size: 1.9rem; + font-weight: 400; + line-height: 1.65; + + gap: 2px; + + text-align: center; + + white-space: nowrap; + } + + .ExternalIcon { + display: block; + + width: 0.8em; + height: 0.8em; + + margin-top: 2px; + margin-left: 0; + } + + .linkWrapper:has(.icon) { display: flex; align-items: center; - width: 100%; + width: auto; margin: 0; } } } -@media (min-width: breakpoint(md)) and (max-width: 900px) { +@media (min-width: breakpoint(md)) and (max-width: 1200px) { .Container { - padding: 32px; + padding: 32px 32px 32px 140px; .ImageWrapper { + top: 24px; + left: 24px; + right: auto; + + transform: none; + img { - width: 8em; - height: 8em; + width: 6em; + height: 6em; } } } -} - - + .Reverse.Container { + padding: 32px 140px 32px 32px; + .ImageWrapper { + top: 24px; + right: 24px; + left: auto; + transform: none; + img { + width: 6em; + height: 6em; + } + } + } +} \ No newline at end of file diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx index 2193ab273..ea8c82ad9 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx @@ -19,6 +19,9 @@ interface Props { export const Block = (props: Props) => { const { block, reverse = false } = props; + const socialLinks = block.links.filter((link) => link.iconSrc); + const normalLinks = block.links.filter((link) => !link.iconSrc); + return (
{

{block.description}

- {block.links.map((link, index) => ( + {normalLinks.slice(0, 1).map((link, index) => (
{ target={link.isExternal ? '_blank' : undefined} rel={link.isExternal ? 'noopener noreferrer' : undefined} > - {link.iconSrc && ( + {link.text} + + {link.showExternalIcon && ( // eslint-disable-next-line @next/next/no-img-element + External link + )} + +
+ ))} + + {socialLinks.length > 0 && ( +
+ {socialLinks.map((link, index) => ( + + {/* eslint-disable-next-line @next/next/no-img-element */} {`${link.text} - )} + + ))} +
+ )} + {normalLinks.slice(1).map((link, index) => ( +
+ {link.text} - {link.isExternal && !link.iconSrc && ( + {link.showExternalIcon && ( // eslint-disable-next-line @next/next/no-img-element Date: Sun, 17 May 2026 17:59:54 +0300 Subject: [PATCH 06/10] Fix JoinUs block rendering when links are undefined in tests --- frontend-next-migration/src/entities/JoinUs/ui/Block.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx index ea8c82ad9..30510eda7 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx @@ -19,8 +19,10 @@ interface Props { export const Block = (props: Props) => { const { block, reverse = false } = props; - const socialLinks = block.links.filter((link) => link.iconSrc); - const normalLinks = block.links.filter((link) => !link.iconSrc); + const links = block.links ?? []; + + const socialLinks = links.filter((link) => link.iconSrc); + const normalLinks = links.filter((link) => !link.iconSrc); return (
Date: Sun, 17 May 2026 18:11:24 +0300 Subject: [PATCH 07/10] Another fix to prevent block crashing if data is undefined --- frontend-next-migration/src/entities/JoinUs/ui/Block.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx index 30510eda7..a01a75535 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx @@ -19,7 +19,7 @@ interface Props { export const Block = (props: Props) => { const { block, reverse = false } = props; - const links = block.links ?? []; + const links = block?.links ?? []; const socialLinks = links.filter((link) => link.iconSrc); const normalLinks = links.filter((link) => !link.iconSrc); From bdfa8a4773ede386fc60b03c8e6838433605e56a Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Sun, 17 May 2026 18:20:50 +0300 Subject: [PATCH 08/10] And another fix to block --- frontend-next-migration/src/entities/JoinUs/ui/Block.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx index a01a75535..9719c24ec 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.tsx @@ -19,7 +19,11 @@ interface Props { export const Block = (props: Props) => { const { block, reverse = false } = props; - const links = block?.links ?? []; + if (!block) { + return null; + } + + const links = block.links ?? []; const socialLinks = links.filter((link) => link.iconSrc); const normalLinks = links.filter((link) => !link.iconSrc); From 9f210a4b816bc073d074b4bfca80b850d31ffed3 Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Sun, 17 May 2026 18:34:15 +0300 Subject: [PATCH 09/10] FIX: Updated JoinUsPage tests to match renamed block props --- .../JoinUsPage/ui/JoinUsPage.test.tsx | 29 ++----------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.test.tsx b/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.test.tsx index 15c079f8b..4732a9bc5 100644 --- a/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.test.tsx +++ b/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.test.tsx @@ -34,31 +34,15 @@ const feedbackBlock: BlockSection = { img: '', }; -const duunitoriBlock: BlockSection = { - label: 'Duunitori', - description: 'Open positions at Duunitori.', - links: [{ text: 'Duunitori link', url: 'https://example.com', isExternal: true }], - img: '', -}; - -const instagramBlock: BlockSection = { - label: 'Instagram', - description: 'Follow us on Instagram!', - links: [{ text: 'Instagram link', url: 'https://example.com', isExternal: true }], - img: '', -}; - describe('JoinUsPage', () => { const setup = () => render( , ); @@ -73,31 +57,24 @@ describe('JoinUsPage', () => { // Labels expect(screen.getByText('Discord')).toBeInTheDocument(); expect(screen.getByText('Reddit')).toBeInTheDocument(); - expect(screen.getByText('Instagram')).toBeInTheDocument(); expect(screen.getByText('Teachers!')).toBeInTheDocument(); expect(screen.getByText('Feedback')).toBeInTheDocument(); - expect(screen.getByText('Duunitori')).toBeInTheDocument(); // Descriptions expect(screen.getByText('Join our Discord server to connect!')).toBeInTheDocument(); expect(screen.getByText('Reddit community page.')).toBeInTheDocument(); - expect(screen.getByText('Follow us on Instagram!')).toBeInTheDocument(); expect(screen.getByText('Information for teachers.')).toBeInTheDocument(); expect(screen.getByText('Send us your feedback.')).toBeInTheDocument(); - expect(screen.getByText('Open positions at Duunitori.')).toBeInTheDocument(); // Link texts expect(screen.getByText('Discord link')).toBeInTheDocument(); expect(screen.getByText('Reddit link')).toBeInTheDocument(); - expect(screen.getByText('Instagram link')).toBeInTheDocument(); expect(screen.getByText('Teachers link')).toBeInTheDocument(); expect(screen.getByText('Feedback link')).toBeInTheDocument(); - expect(screen.getByText('Duunitori link')).toBeInTheDocument(); // imgs expect(screen.queryByAltText('Discord Icon')).not.toBeInTheDocument(); expect(screen.queryByAltText('Reddit Icon')).not.toBeInTheDocument(); - expect(screen.queryByAltText('Instagram Icon')).not.toBeInTheDocument(); expect(screen.queryByAltText('Teachers Icon')).not.toBeInTheDocument(); expect(screen.queryByAltText('Feedback Icon')).not.toBeInTheDocument(); }); From 9e362a3836a9b7316c71741a4c02d8449a6d794e Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Sat, 23 May 2026 12:48:11 +0300 Subject: [PATCH 10/10] Some fixes to link behavior and block naming --- .../src/app/[lng]/(helper)/join-us/_getPage.ts | 16 ++++++++-------- .../src/entities/JoinUs/index.ts | 8 ++++---- .../entities/JoinUs/model/makeJoinUsBlocks.ts | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/frontend-next-migration/src/app/[lng]/(helper)/join-us/_getPage.ts b/frontend-next-migration/src/app/[lng]/(helper)/join-us/_getPage.ts index 65cae02e5..381f5c685 100644 --- a/frontend-next-migration/src/app/[lng]/(helper)/join-us/_getPage.ts +++ b/frontend-next-migration/src/app/[lng]/(helper)/join-us/_getPage.ts @@ -2,10 +2,10 @@ import { createPage } from '@/app/_helpers'; import { JoinUsProps } from '@/preparedPages/JoinUsPage'; import { getServerTranslation } from '@/shared/i18n'; import { - makeGetInTouchAndFollowBlock, - makeCommunityAndOpportunitiesBlock, - makeEducationProfessionalsBlock, - makeFeedbackBlock, + makeGetInTouchAndFollow, + makeCommunityAndOpportunities, + makeEducationProfessionals, + makeFeedback, } from '@/entities/JoinUs'; import { getRouteJoinUsPage } from '@/shared/appLinks/RoutePaths'; import { defaultOpenGraph } from '@/shared/seoConstants'; @@ -16,10 +16,10 @@ export async function _getPage(lng: string) { return createPage({ buildPage: () => ({ title: t('join-us'), - getInTouchAndFollowBlock: makeGetInTouchAndFollowBlock(t), - communityAndOpportunitiesBlock: makeCommunityAndOpportunitiesBlock(t), - educationProfessionalsBlock: makeEducationProfessionalsBlock(t), - feedbackBlock: makeFeedbackBlock(t), + getInTouchAndFollowBlock: makeGetInTouchAndFollow(t), + communityAndOpportunitiesBlock: makeCommunityAndOpportunities(t), + educationProfessionalsBlock: makeEducationProfessionals(t), + feedbackBlock: makeFeedback(t), }), buildSeo: () => ({ diff --git a/frontend-next-migration/src/entities/JoinUs/index.ts b/frontend-next-migration/src/entities/JoinUs/index.ts index db2e8fd4e..3fbceff3b 100644 --- a/frontend-next-migration/src/entities/JoinUs/index.ts +++ b/frontend-next-migration/src/entities/JoinUs/index.ts @@ -1,8 +1,8 @@ export { Block } from './ui/Block'; export { - makeGetInTouchAndFollowBlock, - makeCommunityAndOpportunitiesBlock, - makeEducationProfessionalsBlock, - makeFeedbackBlock, + makeGetInTouchAndFollow, + makeCommunityAndOpportunities, + makeEducationProfessionals, + makeFeedback, } from './model/makeJoinUsBlocks'; diff --git a/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts b/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts index bcae7ad55..696e5d7b7 100644 --- a/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts +++ b/frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts @@ -63,7 +63,7 @@ export const makeBlocksWithI18n = ( }; }; -export const makeGetInTouchAndFollowBlock = makeBlocksWithI18n( +export const makeGetInTouchAndFollow = makeBlocksWithI18n( 'getInTouchAndFollow', [ { text: 'phone', url: 'tel:+358442407396', isExternal: true }, @@ -96,7 +96,7 @@ export const makeGetInTouchAndFollowBlock = makeBlocksWithI18n( ConnectionImage.src.toString(), ); -export const makeCommunityAndOpportunitiesBlock = makeBlocksWithI18n( +export const makeCommunityAndOpportunities = makeBlocksWithI18n( 'communityAndOpportunities', [ { @@ -108,8 +108,8 @@ export const makeCommunityAndOpportunitiesBlock = makeBlocksWithI18n( { text: 'news', url: '/fi/news', - isExternal: true, - showExternalIcon: true, + isExternal: false, + showExternalIcon: false, }, { text: 'duunitori', @@ -121,7 +121,7 @@ export const makeCommunityAndOpportunitiesBlock = makeBlocksWithI18n( discordImage.src.toString(), ); -export const makeEducationProfessionalsBlock = makeBlocksWithI18n( +export const makeEducationProfessionals = makeBlocksWithI18n( 'educationProfessionals', [ { text: 'phone', url: 'tel:+358442407396', isExternal: true }, @@ -136,7 +136,7 @@ export const makeEducationProfessionalsBlock = makeBlocksWithI18n( teachersImage.src.toString(), ); -export const makeFeedbackBlock = makeBlocksWithI18n( +export const makeFeedback = makeBlocksWithI18n( 'feedback', [ {