Skip to content

Idrees/enhancement/437 update join us page #453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export async function _getPage(lng: string) {
buildPage: () => ({
title: t('join-us'),
discordBlock: makeDiscordBlock(t),
redditBlock: makeRedditBlock(t),
connectionBlock: makeRedditBlock(t),
teachersBlock: makeTeachersBlock(t),
feedbackBlock: makeFeedbackBlock(t),
duunitoriBlock: makeDuunitoriBlock(t),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react';

export default function JoinUsLayout({ children }: { children: React.ReactNode }) {
return <div style={{ marginTop: -120 }}>{children}</div>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,68 @@ import { makeBlocksWithI18n } from './makeJoinUsBlocks';
import { AppExternalLinks } from '@/shared/appLinks/appExternalLinks';

describe('makeJoinUsBlocks', () => {
/**
* Mock translation function used for testing
*/
const mockTranslation = (key: string): string => {
const translations: Record<string, string> = {
'block-label-discord': 'Discord',
'block-description-discord': 'Join our Discord community.',
'block-link-text-discord': 'Go to Discord',
'block-image-alt-discord': 'Discord Icon',

'block-label-reddit': 'Reddit',
'block-description-reddit': 'Follow us on Reddit.',
'block-link-text-reddit': 'Go to Reddit',
'block-image-alt-reddit': 'Reddit Icon',
};

return translations[key] || key;
};

it('should generate a Discord block with correct translations', () => {
const makeDiscordBlock = makeBlocksWithI18n('discord', AppExternalLinks.discord);
const makeDiscordBlock = makeBlocksWithI18n('discord', [
{ text: 'discord', url: AppExternalLinks.discord, isExternal: true },
]);

const block = makeDiscordBlock(mockTranslation);

expect(block).toEqual({
label: 'Discord',
description: 'Join our Discord community.',
link: AppExternalLinks.discord,
linkText: 'Go to Discord',
links: [
{
text: 'Go to Discord',
url: AppExternalLinks.discord,
isExternal: true,
iconSrc: undefined,
},
],
img: '',
imgAlt: 'Discord Icon',
});
});

it('should generate a Reddit block with correct translations', () => {
const makeRedditBlock = makeBlocksWithI18n('reddit', AppExternalLinks.reddit);
const makeRedditBlock = makeBlocksWithI18n('reddit', [
{ text: 'reddit', url: AppExternalLinks.reddit, isExternal: true },
]);

const block = makeRedditBlock(mockTranslation);

expect(block).toEqual({
label: 'Reddit',
description: 'Follow us on Reddit.',
link: AppExternalLinks.reddit,
linkText: 'Go to Reddit',
links: [
{
text: 'Go to Reddit',
url: AppExternalLinks.reddit,
isExternal: true,
iconSrc: undefined,
},
],
img: '',
imgAlt: 'Reddit Icon',
});
});
});
132 changes: 114 additions & 18 deletions frontend-next-migration/src/entities/JoinUs/model/makeJoinUsBlocks.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,133 @@
import { BlockSection } from '../types';
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';
import ytIcon from '@/shared/assets/images/Youtube2.svg';
import { block } from 'sharp';
import { fas } from '@fortawesome/free-solid-svg-icons';

/**
* Creates a function to generate a `BlockSection` object, using
* internationalized labels, descriptions, and link text.
* Creates a function that generates a `BlockSection` object, used for building blocks on the "Join Us" page.
* 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.
*
* @param {BlockSection['links']} link -
* An array of link objects. Each object represents a link associated with the block and should include:
* - `url` (string): The link's destination URL.
* - `text` (string): A key used to find the translated link text via the `t` function.
* - `isExternal` (boolean, optional): Indicates if the link should open in a new tab (default is `false` if not specified).
* - `iconSrc` (string, optional): An optional source URL for an icon image associated with the link.
*
* @param {string} section - The section identifier used to retrieve the appropriate i18n strings.
* @param {string} link - The URL associated with this block, to be used in the generated `BlockSection`.
* @returns {function} - A function that takes a translation function `t` and returns a `BlockSection`
* populated with i18n strings.
* @param {string} [img] -
* (Optional) A direct source path for the block's main image (such as a hero image or thumbnail).
* If not provided, the block will still work but without an associated image.
*
* @returns {(t: (key: string) => string) => BlockSection}
* Returns a function that accepts a translation function `t`.
* When executed, this function returns a `BlockSection` object fully populated with localized texts
* and the provided links and images.
*
* @callback t
* @param {string} key - The i18n key to retrieve the translated string.
* @returns {BlockSection} - An object adhering to the `BlockSection` interface, containing label,
* description, link, and linkText fields.
* @param {string} key -
* The translation key used to fetch the localized string (e.g., "block-label-discord", "block-description-feedback").
*
* @returns {string} -
* The translated string value associated with the provided key.
*/

export const makeBlocksWithI18n = (
section: string,
link: string,
link: BlockSection['links'],
img?: string,
): ((t: (key: string) => string) => BlockSection) => {
return (t: (key: string) => string): BlockSection => {
return {
label: t(`block-label-${section}`),
description: t(`block-description-${section}`),
link: link,
linkText: t(`block-link-text-${section}`),
links: link.map((l) => ({
url: l.url,
text: t(`block-link-text-${l.text}`),
isExternal: l.isExternal ?? false,
iconSrc: l.iconSrc,
})),
img: img || '',
imgAlt: t(`block-image-alt-${section}`),
};
};
};

export const makeDiscordBlock = makeBlocksWithI18n('discord', AppExternalLinks.discord);
export const makeRedditBlock = makeBlocksWithI18n('reddit', AppExternalLinks.reddit);
export const makeTeachersBlock = makeBlocksWithI18n('teachers', 'https://example.com/');
export const makeFeedbackBlock = makeBlocksWithI18n('feedback', AppExternalLinks.googleFeedback);
export const makeDuunitoriBlock = makeBlocksWithI18n('duunitori', AppExternalLinks.duunitori);
export const makeInstagramBlock = makeBlocksWithI18n('instagram', AppExternalLinks.instagram);
export const makeDiscordBlock = makeBlocksWithI18n(
'discord',
[{ text: 'discord', url: AppExternalLinks.discord, isExternal: true }],
discordImage.src.toString(),
);
export const makeRedditBlock = makeBlocksWithI18n(
'connection',
[
{ text: 'email', url: '', isExternal: true },
{ text: 'phone', url: '', isExternal: false },
],
ConnectionImage.src.toString(),
);
export const makeTeachersBlock = makeBlocksWithI18n(
'teachers',
[
{ text: 'email', url: '', isExternal: true },
{ text: 'phone', url: '', isExternal: true },
{ text: 'teacherPg', url: AppExternalLinks.dlpackage, isExternal: true },
],
teachersImage.src.toString(),
);
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,
isExternal: true,
iconSrc: ytIcon.src,
},
{
text: 'icone',
url: AppExternalLinks.instagram,
isExternal: true,
iconSrc: igIcon.src,
},
],
instagramImage.src.toString(),
);
10 changes: 8 additions & 2 deletions frontend-next-migration/src/entities/JoinUs/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
export interface BlockSection {
label: string;
description: string;
link: string;
linkText: string;
links: {
text: string;
url: string;
isExternal?: boolean;
iconSrc?: string;
}[];
img: string;
imgAlt?: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { AppLink } from '@/shared/ui/AppLink/AppLink';
import { BlockSection } from '../types';
import cls from './Block.module.scss';
import Image from 'next/image';

interface Props {
block: BlockSection;
}

/*
export const Block = (props: Props) => {
const { block } = props;
return (
<div
className={cls.Container}
data-testid="block"
>
<img src={block.img} alt={block.imgAlt} />
<h2>{block.label}</h2>
<p>{block.description}</p>
<AppLink
className={cls.link}
isExternal={true}
to={block.link}
>
{block.linkText}
</AppLink>
</div>
);
};
*/

export const Block = (props: Props) => {
const { block } = props;

return (
<div
className={cls.Container}
data-testid="block"
>
<div className={cls.ImageWrapper}>
<img
className={cls.Image}
src={block.img}
alt={block.imgAlt}
/>
</div>
<div className="text-container">
<h2>{block.label}</h2>
<p>{block.description}</p>
{block.links.map((link, index) => (
<a
key={index}
href={link.url}
target="_blank"
rel="noopener noreferrer"
>
Testilinkki
</a>
))}
</div>
</div>
);
};
Loading