Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
347be3f
Images exported and testing card layout
NikolasKataja Oct 15, 2025
e3b01ec
Testing new card design on clan page
NikolasKataja Oct 21, 2025
76fe8a6
Use ModularCard in ClanAllSubPage
NikolasKataja Oct 22, 2025
ed35ac9
Fixing desktop clan card, mobile started
NikolasKataja Oct 24, 2025
172e90c
Mobilecard added and adjustments to modular card.
NikolasKataja Oct 27, 2025
372318d
Mobilecard improved
NikolasKataja Oct 28, 2025
8dbf50c
Responsive update to clancards
NikolasKataja Oct 29, 2025
465af96
tweaks to scrolling behavior
NikolasKataja Oct 29, 2025
c80d8de
prev/next page buttons and logic removed, new searchbar implementatio…
NikolasKataja Nov 1, 2025
f7cfa99
use LayoutWithSidebars, move PageTitle to ClanAllSubPage
NikolasKataja Nov 3, 2025
4632345
responsivenes updates and new searchbar
NikolasKataja Nov 3, 2025
7320344
testing better content fitment and responsivenes for desktop clancard
NikolasKataja Nov 4, 2025
b2e0cf9
Mobile clancard updated
NikolasKataja Nov 5, 2025
f4cee6b
Mobilecard layout updated
NikolasKataja Nov 6, 2025
5039bae
change page title to Clans/Klaanit
NikolasKataja Nov 6, 2025
d5ab41f
remove global styles and improve responsiveness
NikolasKataja Nov 8, 2025
6243313
mobilecarditemwrap, fix mistake
NikolasKataja Nov 8, 2025
ff38695
small tweaks to modularcard
NikolasKataja Nov 10, 2025
2eb1228
fix modularcard sm breakpoint and mobilecard improvements
NikolasKataja Nov 11, 2025
73c5af7
cleanup ClanAllSubPage
NikolasKataja Nov 11, 2025
d583aca
simular search logic as other pages and more cleanup
NikolasKataja Nov 11, 2025
02d84a6
cleanup
NikolasKataja Nov 12, 2025
02c9e80
SearchBarTablet fix
NikolasKataja Nov 12, 2025
7828c45
change modularcardtheme name to CLANCARD
NikolasKataja Nov 12, 2025
8ff691c
fix mobilecard gap and padding + eslint fix
NikolasKataja Nov 19, 2025
46b7d30
Removed image placeholder from news without one, and added a static t…
eleino Nov 20, 2025
525b7a9
Removed an empty div with no class definition in the style file
eleino Nov 21, 2025
7bf668f
testing clanLabel implementation
NikolasKataja Nov 23, 2025
4d87c5d
ellipsis for lable text
NikolasKataja Nov 24, 2025
adcd13f
Changed news text to align to left, decreased the width of the text a…
eleino Nov 25, 2025
951980f
Reduce clan label padding/gap and enable flex-wrap
NikolasKataja Nov 25, 2025
e5a3df9
move clan label icon map to entities
NikolasKataja Nov 26, 2025
a975f3f
small font fix
NikolasKataja Nov 26, 2025
d56ef95
Fix lint issues and console errors and warnings
juhaj77 Nov 26, 2025
25e912a
image width:auto;
juhaj77 Nov 28, 2025
b7a73f3
image width:auto;
juhaj77 Nov 28, 2025
9d34d55
Increased news text width slightly on smaller screens
eleino Nov 29, 2025
4712cbd
Merge branch 'dev' into juhaj77/chore/600-fix-all-lint-errors-and-war…
juhaj77 Dec 1, 2025
75210af
fixed lint errors
juhaj77 Dec 1, 2025
c30648a
fixed image priority prop
juhaj77 Dec 1, 2025
58c50a7
Fix mobile ClanCard hover overflow and lock layout heights
NikolasKataja Dec 2, 2025
37c2d24
removed image legacy prop warning
juhaj77 Dec 3, 2025
98f96b5
Merge branch 'dev' into nikolas/enhancement/564-update-clan-page
Rutjake Dec 5, 2025
537127a
Merge pull request #597 from Alt-Org/nikolas/enhancement/564-update-c…
Rutjake Dec 5, 2025
87905b1
fix(seo): Restore Open Graph and metadata logic lost in merge
Rutjake Dec 5, 2025
96b4f44
Removed join_message from IJoin
salimsara Dec 5, 2025
8c8b583
Merge pull request #601 from Alt-Org/eleino/enhancement/596-update-ne…
Skoivumaki Dec 8, 2025
7403dcf
hook up PictureGallery page to Directus + fix subDescription typo
NikolasKataja Dec 8, 2025
ce45b49
load photo_object_translations and display title/description/subDescr…
NikolasKataja Dec 10, 2025
04e6b90
Updated IClan fields, and created IClanRole type
salimsara Dec 10, 2025
17d6be7
Small fix
salimsara Dec 11, 2025
e70f01b
Added Google Analytics via @next/third-parties
eleino Dec 11, 2025
30d7073
removed subDescription use author instead
NikolasKataja Dec 11, 2025
6411baf
fix mobile text alignment
NikolasKataja Dec 12, 2025
c269526
Modified news element image to stop it shrinking indefinitely
eleino Dec 15, 2025
e1f314c
Updated Google drive links on PRG page
eleino Dec 15, 2025
d55e56f
mock getPhotoObjectTexts in gallery hook tests
NikolasKataja Dec 15, 2025
639ae8c
fix: hero page after merge
patinen Oct 29, 2025
1a22b7c
fix: break circular dependency;
patinen Oct 29, 2025
4392862
refactor: update hero page data fetching logic to prioritize Directus…
patinen Dec 16, 2025
9b0ecd6
refactor: extract groupHeroesByGroup function to improve code organiz…
patinen Dec 16, 2025
5143494
feat(heroes): migrate hero data fetching to Directus with static fall…
patinen Dec 16, 2025
773368b
Follow-up commit to include changes that were prepared locally but mi…
patinen Dec 16, 2025
48444d2
fix(hero) from last push: fetch hero rarityClass from heroes;
patinen Dec 16, 2025
4dd4418
Add linkify to news body and fix ESLint warning
NikolasKataja Dec 17, 2025
1e35229
fix(heroes): i18n hero rarity labels + restore per-stat rarityClass f…
patinen Dec 17, 2025
2beee8f
Fixes to IClan interface
salimsara Dec 18, 2025
7f1cce3
start fixing mobile layout
NikolasKataja Dec 19, 2025
104d932
Small fixes
salimsara Dec 21, 2025
2e84c80
normalize locale codes for Directus API
patinen Dec 22, 2025
7826e27
improve sectiongallery layout
NikolasKataja Dec 22, 2025
0883f9b
fix mobile image fit
NikolasKataja Dec 22, 2025
666f1cb
fix image blur and mobile layout
NikolasKataja Dec 27, 2025
b2aa224
share button mobile placement fix
NikolasKataja Dec 27, 2025
b82fc2a
Merge pull request #609 from Alt-Org/eleino/feature/606-implement-goo…
Rutjake Jan 5, 2026
5899266
Merge pull request #610 from Alt-Org/nikolas/feature/603-implement-di…
Rutjake Jan 5, 2026
5087eed
Merge branch 'dev' into juhaj77/chore/600-fix-all-lint-errors-and-war…
Rutjake Jan 5, 2026
094c64e
linkify fix: link color and text-decoration
patinen Jan 8, 2026
edd92d2
Merge pull request #612 from Alt-Org/607-implement-clickable-links-an…
Rutjake Jan 8, 2026
0287ae5
Restored missing imports when crashing in ci build
Rutjake Jan 8, 2026
1d4f7bf
Author's name changed to the correct form
Rutjake Jan 8, 2026
a0b1621
Merge pull request #602 from Alt-Org/juhaj77/chore/600-fix-all-lint-e…
Rutjake Jan 8, 2026
6bef797
added the MarkoOne font and updated it to be used as title font
eleino Jan 15, 2026
217fa83
Updated remaining references to Sedgwick Ave to use Marko One instead
eleino Jan 15, 2026
d288878
Remove @kaisahakola from CODEOWNERS
Rutjake Jan 21, 2026
bfac664
Add registry info section with i18n support and SCSS styling
Rutjake Jan 26, 2026
21ada37
Merge pull request #578 from Alt-Org/juho/enhancement/548-move-hardco…
Skoivumaki Jan 28, 2026
0000be3
fix: removed `join_message` which is no longer in types
Skoivumaki Jan 28, 2026
f55a5bc
Merge pull request #614 from Alt-Org/eleino/chore/611-update-font-sty…
Skoivumaki Jan 28, 2026
c9f34ec
fix: build error
Skoivumaki Jan 28, 2026
2e571bc
fix: type error
Skoivumaki Jan 28, 2026
2a261a3
Merge pull request #613 from Alt-Org/salimsara/chore/604-update-iclan…
Rutjake Jan 29, 2026
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
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @leolabdev @Skoivumaki @kaisahakola @Rutjake @patinen
* @leolabdev @Skoivumaki @Rutjake @patinen
30 changes: 24 additions & 6 deletions frontend-next-migration/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend-next-migration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@fortawesome/react-fontawesome": "^0.2.0",
"@hookform/resolvers": "^3.3.2",
"@next/bundle-analyzer": "^14.0.1",
"@next/third-parties": "^16.0.8",
"@reduxjs/toolkit": "^1.9.7",
"accept-language": "^3.0.18",
"html-react-parser": "^5.1.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,43 @@ import { getServerTranslation } from '@/shared/i18n';
import { ClanRoomSubPageProps } from '@/preparedPages/ClanPages';
import { envHelper } from '@/shared/const/envHelper';
import { notFound } from 'next/navigation';
import { getRouteOneClanPage } from '@/shared/appLinks/RoutePaths';
import type { IClan } from '@/entities/Clan';
import { baseUrl, defaultOpenGraph } from '@/shared/seoConstants';

const toAbsolute = (src?: string | null) =>
!src ? null : /^https?:\/\//i.test(src) ? src : `${baseUrl}${src}`;

// Use fallback only, no clan-specific logo image exists
function getOgImageUrl(_: Partial<IClan>) {
const fallback = defaultOpenGraph.images?.[0]?.url ?? null;
return toAbsolute(fallback);
}

export async function _getPage(lng: string, id: string) {
const { t } = await getServerTranslation(lng, 'clan');
const response = await fetch(`${envHelper.apiLink}/clan/${id}`);
if (!response.ok) {
return notFound();
notFound();
}
const clanData = await response.json();

const payload = await response.json();
const clan = payload?.data?.Clan ?? {};

const name = (clan.name as string | undefined)?.trim() || id;
const desc = (clan.phrase as string | undefined)?.trim() || t('head-description');

// Routes & SEO
const relPath = getRouteOneClanPage(encodeURIComponent(id));
const path = `/${lng}${relPath}`;
const title = `${t('head-title')} — ${name}`;
const keywords = `${t('head-keywords')}${clan.tag ? `, ${clan.tag}` : ''}`;

const ogUrl = getOgImageUrl(clan);
const ogImages = ogUrl
? [{ url: ogUrl, alt: `${name} — ${t('head-title')}` }]
: (defaultOpenGraph.images ?? []);

return createPage<ClanRoomSubPageProps>({
buildPage: () => ({
translations: {
Expand Down Expand Up @@ -40,9 +69,18 @@ export async function _getPage(lng: string, id: string) {
},
}),
buildSeo: () => ({
title: `${t('head-title')}: ${clanData.data.Clan.name}`,
description: `${clanData.data.Clan.phrase}`,
keywords: `${t('head-keywords')}, ${clanData.data.Clan.tag}`,
title,
description: desc,
keywords,
openGraph: {
...defaultOpenGraph,
type: 'website',
title,
description: desc,
url: path,
images: ogImages,
},
alternates: { canonical: path },
}),
});
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,65 @@
import { createPage } from '@/app/_helpers';
import { getServerTranslation } from '@/shared/i18n';
import { notFound } from 'next/navigation';
import { SingleFurnitureCollectionPageProps } from '@/preparedPages/FurnitureCollectionsPages';
import { baseUrl, defaultOpenGraph } from '@/shared/seoConstants';
import { FurnitureManager } from '@/entities/Furniture';
import React from 'react';

type Props = React.ComponentProps<typeof SingleFurnitureCollectionPageProps>;

function getOgImageUrl(set: ReturnType<FurnitureManager['getFurnitureSet']>) {
const img = set?.coverWebp ?? set?.cover;
if (!img) return null;
const src = typeof img === 'string' ? img : img.src;
return /^https?:\/\//i.test(src) ? src : `${baseUrl}${src}`;
}

export async function _getPage(lng: string, group: string) {
const { t } = await getServerTranslation(lng, 'furniture');
const manager = new FurnitureManager();
const set = manager.getFurnitureSet(group);
if (!set) notFound();

// Title-casing fallback (e.g. "neuro" -> "Neuro")
const toTitleCase = (text: string) =>
text
.trim()
.replace(/[-_]+/g, ' ')
.replace(/\b[a-z]/gi, (ch) => ch.toLocaleUpperCase());

const setName = t(`sets.${group}.name`, toTitleCase(group));
const setDesc = t(`sets.${group}.description`, t('head-description'));

// Routes & SEO
const relPath = `/collections/furniture/set/${encodeURIComponent(group)}`;
const path = `/${lng}${relPath}`;
const title = `${setName} - ${t('head-title')}`;
const keywords = `${t('head-keywords')}, ${setName}`;
const ogImageUrl = getOgImageUrl(set);
const ogImage = ogImageUrl
? ({ url: ogImageUrl, alt: `${setName} - ${t('furniture-collections-title')}` } as const)
: null;

const ogImages = ogImage ? [ogImage] : (defaultOpenGraph.images ?? []);

return createPage<Props>({
buildPage: () => ({
collectionId: group,
}),
buildSeo: () => ({
title: t('head-title'),
description: t('head-description'),
keywords: t('head-keywords'),
title,
description: setDesc,
keywords,
openGraph: {
...defaultOpenGraph,
type: 'website',
title,
description: setDesc,
url: path,
images: ogImages,
},
alternates: { canonical: path },
}),
});
}
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
export { PageLoader as default } from '@/widgets/PageLoader';
export default function Loading() {
return (
<div
role="status"
aria-busy="true"
aria-live="polite"
style={{ padding: '1rem' }}
>
Loading…
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import { createPage } from '@/app/_helpers';
import { getServerTranslation } from '@/shared/i18n';
import { notFound } from 'next/navigation';
import { HeroGroup } from '@/entities/Hero';
import { HeroGroup, GroupInfo } from '@/entities/Hero';
import {
initializeHeroGroups,
initializeHeroGroupsFromDirectus,
} from '@/entities/Hero/model/initializeHeroGroups';
import { StaticImageData } from 'next/image';
import { SingleDefensePageProps } from '@/preparedPages/DefenseGalleryPages';
import { getRouteDefenseGalleryGroupPage } from '@/shared/appLinks/RoutePaths';
import defenceGalleryImage from '@/shared/assets/images/descriptionCard/defense_gallery.png';
import { baseUrl, defaultOpenGraph } from '@/shared/seoConstants';

function getOgImageUrl(info?: GroupInfo) {
const candidate =
(info?.srcImg as string | StaticImageData | undefined) ??
(info?.heroes?.[0]?.srcImg as string | StaticImageData | undefined) ??
(defaultOpenGraph.images?.[0]?.url as string | undefined);

const src = typeof candidate === 'string' ? candidate : candidate?.src;
if (!src) return null;
return /^https?:\/\//i.test(src) ? src : `${baseUrl}${src}`;
}

export async function _getPage(lng: string, heroGroup: string) {
const { t } = await getServerTranslation(lng, 'heroes');
Expand All @@ -13,27 +29,49 @@ export async function _getPage(lng: string, heroGroup: string) {
notFound();
}

const group = heroGroup as HeroGroup;
// Try to fetch from Directus first, fallback to static data
let groups: Record<HeroGroup, GroupInfo>;
try {
groups = await initializeHeroGroupsFromDirectus(lng as 'en' | 'fi' | 'ru');
// If Directus returns empty, fallback to static
if (Object.keys(groups).length === 0) {
groups = initializeHeroGroups(t);
}
} catch {
groups = initializeHeroGroups(t);
}
const info = groups[group];

const groupName = info?.name ?? group;
const groupDesc = info?.description ?? t('defense-gallery-description');

// Routes & SEO
const relPath = getRouteDefenseGalleryGroupPage(encodeURIComponent(group));
const path = `/${lng}${relPath}`;
const title = `${t('og-title')} - ${groupName}`;
const keywords = `${t('head-keywords')}, ${groupName}`;

const ogImageUrl = getOgImageUrl(info);
const ogImages = ogImageUrl
? [{ url: ogImageUrl, alt: `${groupName} - ${t('defense-gallery')}` }]
: (defaultOpenGraph.images ?? []);

return createPage<SingleDefensePageProps>({
buildPage: () => ({
heroGroup: heroGroup as HeroGroup,
}),
buildPage: () => ({ heroGroup: group }),
buildSeo: () => ({
title: heroGroup,
description: heroGroup,
keywords: `${t('head-keywords')}, ${heroGroup}`,
title,
description: groupDesc,
keywords,
openGraph: {
images: [
{
url: defenceGalleryImage.src,
},
],
title: `${t('og-title')} - ${heroGroup}`,
description: t('og-description'),
url: `/${lng}${getRouteDefenseGalleryGroupPage(heroGroup as HeroGroup)}`,
},
alternates: {
canonical: `/${lng}${getRouteDefenseGalleryGroupPage(heroGroup as HeroGroup)}`,
...defaultOpenGraph,
type: 'website',
title,
description: groupDesc,
url: path,
images: ogImages,
},
alternates: { canonical: path },
}),
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export default function NotFound() {
}}
>
<h1>{t('not-found-title')}</h1>
<Link href={getRouteAllHeroesPage()}>
<Link
href={getRouteAllHeroesPage()}
prefetch={false}
>
<b>{t('not-found-check-heroes')}</b>
</Link>
</div>
Expand Down
Loading