From 85a061280c0893aeebb05c40fd01d55fa0b3354f Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Thu, 7 May 2026 18:55:02 +0300 Subject: [PATCH 01/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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', [ { From 58001a6898e91a3a9ec21910ddde3aa66026b866 Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Wed, 3 Jun 2026 20:20:48 +0300 Subject: [PATCH 11/12] Fixed: Header going under navbar on smaller screens, font size on smaller screens, content alignment on tablets and images overlapping text on tablets --- .../src/entities/JoinUs/ui/Block.module.scss | 21 ++++++++++--------- .../JoinUsPage/ui/JoinUsPage.module.scss | 4 ++-- 2 files changed, 13 insertions(+), 12 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 83f80ee71..516b7ff12 100644 --- a/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss +++ b/frontend-next-migration/src/entities/JoinUs/ui/Block.module.scss @@ -274,7 +274,7 @@ margin: 8px 0 56px; - font-size: 1.9rem; + font-size: 1.6rem; font-weight: 400; line-height: 1.65; @@ -287,7 +287,7 @@ align-items: center; justify-content: center; - font-size: 1.9rem; + font-size: 1.6rem; font-weight: 400; line-height: 1.65; @@ -320,36 +320,37 @@ } @media (min-width: breakpoint(md)) and (max-width: 1200px) { + .Container { - padding: 32px 32px 32px 140px; + padding: 80px 64px 32px; .ImageWrapper { - top: 24px; + top: 12px; left: 24px; right: auto; transform: none; img { - width: 6em; - height: 6em; + width: 5em; + height: 5em; } } } .Reverse.Container { - padding: 32px 140px 32px 32px; + padding: 80px 64px 32px; .ImageWrapper { - top: 24px; + top: 12px; right: 24px; left: auto; transform: none; img { - width: 6em; - height: 6em; + width: 5em; + height: 5em; } } } 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 a9b2167e9..1cda279ec 100644 --- a/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.module.scss +++ b/frontend-next-migration/src/preparedPages/JoinUsPage/ui/JoinUsPage.module.scss @@ -20,7 +20,7 @@ @media screen and (max-width: breakpoint(md)) { .Container { - padding: 0 16px 48px; + padding: 96px 16px 48px; h1 { margin: 32px 0 24px; @@ -33,7 +33,7 @@ @media screen and ((min-width: breakpoint(sm)) and (max-width: breakpoint(md))) { .Container { - padding: 0 24px 56px; + padding: 96px 24px 56px; h1 { margin: 48px 0 32px; From febc21272e22a0d4ae3e7cbbffc5b4d7ca258c2b Mon Sep 17 00:00:00 2001 From: EemeliJ Date: Tue, 9 Jun 2026 17:14:33 +0300 Subject: [PATCH 12/12] Added english translations --- .../src/shared/i18n/locales/en/join-us.json | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/frontend-next-migration/src/shared/i18n/locales/en/join-us.json b/frontend-next-migration/src/shared/i18n/locales/en/join-us.json index f8830d5b1..fc55a33e7 100644 --- a/frontend-next-migration/src/shared/i18n/locales/en/join-us.json +++ b/frontend-next-migration/src/shared/i18n/locales/en/join-us.json @@ -1,32 +1,38 @@ { - "join-us": "Join us!", - "head-title": "Join us - ALT Zone", - "head-description": "Join the ALT Zone project! Become a tester, explore teaching packages, apply for internships, join our Discord community, or share your feedback to improve our game.", - "head-keywords": "ALT Zone join us, tester, teaching package, internship, volunteer, Discord", + "join-us": "Get in touch", + + "head-title": "Get in touch - ALT Zone", + "head-description": "Join the ALT Zone project! Become a tester, explore our educational materials, apply for an internship, join our Discord community, or share feedback to help improve our game.", + "head-keywords": "ALT Zone contact, tester, educational materials, internship, volunteer work, Discord", + "og-title": "Join the ALT Zone Project", - "og-description": "Be part of the ALT Zone journey — test our game, explore teaching tools, join our Discord, apply for internships, or send us your feedback.", + "og-description": "Be a part of the ALT Zone journey — test our game, explore educational materials, join our Discord community, apply for an internship, or send us feedback.", - "block-label-discord": "Become a Tester", - "block-label-connection": "Contact Us", - "block-label-teachers": "Are You a Teacher?", - "block-label-duunitori": "Work With Us", + "block-label-getInTouchAndFollow": "Get in touch and follow us", + "block-label-communityAndOpportunities": "Community and opportunities", + "block-label-educationProfessionals": "For education professionals", "block-label-feedback": "Give feedback", - "block-label-instagram": "Chat More on \nSocial Media", - "block-description-discord": "Share your ideas by joining our Discord community", - "block-description-connection": "If you're interested in our project, feel free to get in touch", - "block-description-teachers": "Sign up to test the teaching package", - "block-description-duunitori": "We offer unpaid internship and volunteer opportunities within our project. You're also welcome to join as a volunteer. Check open positions on Duunitori.", - "block-description-feedback": "Our feedback form helps us improve our website and mobile game. Your input is valuable and will be reviewed by our development team. Thank you in advance!", - "block-description-instagram": "", + "block-description-getInTouchAndFollow": "If you're interested in our project, don't hesitate to get in touch. You can also follow us on social media!", + "block-description-communityAndOpportunities": "Share your ideas by joining our Discord gaming community! We occasionally offer unpaid work experience and internship opportunities within our projects. You're also welcome to contribute as a volunteer. Check out our open positions on Duunitori.", + "block-description-educationProfessionals": "Sign up to test our educational materials!", + "block-description-feedback": "The purpose of our feedback forms is to collect feedback on both the website and the mobile game to support future development. Your feedback is extremely valuable to us and will be reviewed together with our development team.\n\nThank you in advance for your responses!", "block-link-text-discord": "discord.gg/mgjQkCR2Fg", - "block-link-text-teacherPg": "Explore the teaching package", + "block-link-text-teacherPg": "Explore educational materials", + "block-link-text-news": "Learn more about us in the news", "block-link-text-duunitori": "Open positions on Duunitori", - "block-link-text-feedbackWep": "Website feedback", - "block-link-text-feedbackGame": "Game feedback", + "block-link-text-feedbackWep": "Website feedback form", + "block-link-text-feedbackGame": "Game feedback form", "block-link-text-instagram": "@gamingpsyche", "block-link-text-email": "proyaleg@gmail.com", "block-link-text-phone": "+358442407396", - "block-link-text-icone": "" + "block-link-text-icone": "", + + "block-image-alt-getInTouchAndFollow": "Get in touch", + "block-image-alt-communityAndOpportunities": "Community and opportunities", + "block-image-alt-educationProfessionals": "For education professionals", + "block-image-alt-feedback": "Feedback", + + "block-website": "www.example.com" }