Skip to content

Commit e3ff7c3

Browse files
authored
feat: translate app to english (#340)
* feat(sidebar, attribute-input): add PL/EN translations * fix(layout, sidebar): adjust padding and width for improved layout * feat(auth, navigation): add PL/EN translations for auth; integrate language switch in navbar * feat(homepage): add PL/EN translations for homepage * chore: sort translation chapters alphabetically * refactor: restructure superadmin panel and add PL/EN translations for dashboard * fix: resolve problems after merge * chore(format): fix prettier issues * refactor: reuse block form and improve form error translations * feat: add PL/EN translations for new email editor * feat: add PL/EN translations to event registration form * feat: add PL/EN translations for form validation messages and improve error handling in forms * chore: remove unused type import from Auth layout * feat: add PL/EN translations for attribute types * refactor: improve type safety for ATTRIBUTE_TYPES translations * feat: add PL/EN translations for email triggers and improve trigger type explanations * refactor(tags): introduce MessageTags translations and improve email tag system * refactor: localize app metadata and improve editor translations * feat: add PL/EN translations for deletions, file validation and permissions * refactor: refactor translateFormError and add action error translations * fix(auth): remove max-width from form containers and update translations * refactor: improve highlighted events translations * refactor: add PL/EN translations for participant table elements * test: fix tests after aria-label localization * refactor: update translations for event-related messages and fix key casing * refactor: improve email editor translations * fix(auth): adjust layout width * refactor: improve action error translations * chore: resolve ESLint warnings
1 parent fab0446 commit e3ff7c3

133 files changed

Lines changed: 4678 additions & 2513 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

messages/en.json

Lines changed: 734 additions & 72 deletions
Large diffs are not rendered by default.

messages/pl.json

Lines changed: 736 additions & 74 deletions
Large diffs are not rendered by default.

src/app/(homepage)/sections/events/event-list.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { compareAsc, isBefore, isSameDay } from "date-fns";
22
import { format as formatDate } from "date-fns/format";
33
import { ArrowUpRight } from "lucide-react";
4+
import { useTranslations } from "next-intl";
45
import Image from "next/image";
56
import Link from "next/link";
67

@@ -33,6 +34,8 @@ function Event({
3334
? "/assets/event-photo-placeholder.png"
3435
: `${PHOTO_URL}/${photoUrl}`;
3536

37+
const t = useTranslations("Homepage");
38+
3639
// Helper to render date range using date-fns
3740
function renderDate() {
3841
const sameDay = isSameDay(startDate, endDate);
@@ -46,9 +49,13 @@ function Event({
4649
) : (
4750
// Multi-day event: show start date on top, end date on bottom
4851
<>
49-
<span>Od {formatDate(startDate, "dd.MM.yyyy")}</span>
52+
<span>
53+
{t("from")} {formatDate(startDate, "dd.MM.yyyy")}
54+
</span>
5055
<br />
51-
<span>do {formatDate(endDate, "dd.MM.yyyy")}</span>
56+
<span>
57+
{t("to")} {formatDate(endDate, "dd.MM.yyyy")}
58+
</span>
5259
</>
5360
);
5461
}
@@ -58,19 +65,19 @@ function Event({
5865
const now = new Date();
5966
if (now < startDate) {
6067
return {
61-
status: "Nadchodzące",
68+
status: t("upcoming"),
6269
style:
6370
"rounded-full bg-[#88FC61] px-5 py-2 text-center font-extrabold whitespace-nowrap text-[#487115] dark:bg-[#88FC61]/20 dark:text-[#88FC61]",
6471
};
6572
} else if (now >= startDate && now <= endDate) {
6673
return {
67-
status: "W trakcie",
74+
status: t("ongoing"),
6875
style:
6976
"rounded-full bg-[#4473E1]/20 px-5 py-2 text-center font-extrabold whitespace-nowrap text-[#4473E1] dark:text-[#84a9ff]",
7077
};
7178
} else {
7279
return {
73-
status: "Zakończone",
80+
status: t("finished"),
7481
style:
7582
"rounded-full bg-gray-300 px-5 py-2 text-center font-extrabold whitespace-nowrap text-gray-600 dark:bg-gray-700/80 dark:text-gray-300",
7683
};
@@ -127,7 +134,7 @@ function Event({
127134
className="border-input/20 flex w-full items-center justify-center rounded-full border bg-[#d6d6d6] text-black group-hover:bg-[#4473E1] group-hover:text-white group-hover:hover:bg-[#3458ae] lg:w-min"
128135
>
129136
<Link href={`/${slug}`}>
130-
Sprawdź
137+
{t("viewDetails")}
131138
<ArrowUpRight />
132139
</Link>
133140
</Button>
@@ -148,6 +155,8 @@ function Event({
148155
}
149156

150157
export function EventList({ events }: { events: EventType[] | undefined }) {
158+
const t = useTranslations("Homepage");
159+
151160
return (
152161
<section id="events" className="flex flex-col">
153162
<div className="border-input z-10 flex w-full flex-col divide-y-[1px] border-b bg-white dark:bg-[#101011]">
@@ -181,7 +190,7 @@ export function EventList({ events }: { events: EventType[] | undefined }) {
181190
))
182191
) : (
183192
<div className="flex h-64 w-full items-center justify-center text-gray-500 dark:text-gray-400">
184-
<p className="text-xl">Brak wydarzeń w wybranym miesiącu</p>
193+
<p className="text-xl">{t("noEventsInSelectedMonth")}</p>
185194
</div>
186195
)}
187196
</div>

src/app/(homepage)/sections/events/index.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
startOfMonth,
1313
} from "date-fns";
1414
import { CircleAlert, Loader2 } from "lucide-react";
15+
import { useTranslations } from "next-intl";
1516
import { useState } from "react";
1617

1718
import { EventList } from "@/app/(homepage)/sections/events/event-list";
@@ -62,6 +63,8 @@ async function fetchEvents(
6263
}
6364

6465
export function Events() {
66+
const t = useTranslations("Homepage");
67+
6568
const [filters, setFilters] = useState<{ month: number; year: number }>({
6669
month: getMonth(new Date()),
6770
year: getYear(new Date()),
@@ -82,7 +85,7 @@ export function Events() {
8285
return (
8386
<div className="flex flex-row items-center gap-2 rounded-2xl bg-white px-6 py-4 text-black shadow-xl">
8487
<Loader2 className="animate-spin" />
85-
Pobieranie wydarzeń...
88+
{t("loadingEvents")}
8689
</div>
8790
);
8891
}
@@ -91,7 +94,7 @@ export function Events() {
9194
return (
9295
<div className="flex flex-row items-center gap-2 rounded-2xl bg-white px-6 py-4 text-black shadow-xl">
9396
<CircleAlert className="text-red-500" />
94-
<p>O nie! Nie udało się pobrać wydarzeń: {error.message}</p>
97+
<p>{t("failedToLoadEvents", { message: error.message })}</p>
9598
</div>
9699
);
97100
}

src/app/(homepage)/sections/events/timeline.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { eachMonthOfInterval, getMonth, getYear } from "date-fns";
44
import { ArrowLeftCircle, ArrowRightCircle } from "lucide-react";
55
import { motion } from "motion/react";
6+
import { useLocale } from "next-intl";
67
import { useLayoutEffect, useRef, useState } from "react";
78

89
import { Button } from "@/components/ui/button";
@@ -75,6 +76,7 @@ export function Timeline({
7576
setFilters: ({ month, year }: { month: number; year: number }) => void;
7677
}) {
7778
const ref = useRef<HTMLDivElement>(null);
79+
const locale = useLocale();
7880
const [width, setWidth] = useState(0);
7981

8082
// Get the width of the timeline
@@ -159,7 +161,7 @@ export function Timeline({
159161
{monthYears.map(({ year, month }, index) => (
160162
<TimelineStep
161163
key={`${year.toString()}-${month.toString()}`}
162-
month={new Date(year, month, 1).toLocaleString("pl", {
164+
month={new Date(year, month, 1).toLocaleString(locale, {
163165
month: "long",
164166
})}
165167
isFirst={index === 0}

src/app/(homepage)/sections/footer.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
import { ArrowRight, Heart } from "lucide-react";
2+
import { useTranslations } from "next-intl";
23
import Image from "next/image";
34
import Link from "next/link";
45
import { FaFacebook, FaGithub, FaInstagram, FaLinkedin } from "react-icons/fa";
56

7+
import { buttonVariants } from "@/components/ui/button";
68
import { cn } from "@/lib/utils";
79

8-
import { buttonVariants } from "../../../components/ui/button";
9-
1010
export function Footer() {
11+
const t = useTranslations("Homepage");
1112
return (
1213
<footer className="z-10 flex w-full flex-col items-center bg-white dark:bg-[#101011]">
1314
<div className="container flex w-full flex-col items-center justify-between gap-16 px-8 pt-16 pb-8 sm:gap-32 sm:py-16 2xl:flex-row 2xl:items-center">
1415
<div className="flex w-full flex-col text-3xl font-medium 2xl:w-auto">
15-
<p>Zostań na bieżąco z Eventownikiem Solvro</p>
16+
<p>{t("stayUpdatedWithEventownik")}</p>
1617
<Link
1718
href="/newsletter-eventownik"
1819
className="flex flex-row items-center gap-2 text-[#6583C8] hover:underline"
1920
>
20-
<span className="text-[#6583C8]">i zapisz się do newslettera.</span>
21+
<span className="text-[#6583C8]">
22+
{t("andSubscribeToNewsletter")}
23+
</span>
2124
<ArrowRight size={32} />
2225
</Link>
2326
{/*
@@ -37,37 +40,37 @@ export function Footer() {
3740
target="_blank"
3841
rel="noopener noreferrer"
3942
>
40-
Regulamin
43+
{t("termsOfService")}
4144
</a>
4245
<a href="mailto:eventownik@pwr.edu.pl?subject=Zgłoszenie%20błędu">
43-
Zgłoś błąd
46+
{t("reportBug")}
4447
</a>
4548
</div>
4649
<div className="flex w-full flex-col items-center justify-between gap-8 sm:flex-row">
4750
<a
48-
title="Koło Naukowe Solvro"
51+
title={t("knSolvro")}
4952
href="https://solvro.pwr.edu.pl/"
5053
target="_blank"
5154
rel="noopener noreferrer"
5255
>
5356
<Image
5457
src="/assets/logo/solvro_black.png"
55-
alt="Logo Koła Naukowego Solvro"
58+
alt={t("solvroLogoAlt")}
5659
className="block dark:hidden"
5760
width={200}
5861
height={200}
5962
/>
6063
<Image
6164
src="/assets/logo/solvro_white.png"
62-
alt="Logo Koła Naukowego Solvro"
65+
alt={t("solvroLogoAlt")}
6366
className="hidden dark:block"
6467
width={200}
6568
height={200}
6669
/>
6770
</a>
6871
<div className="flex flex-row gap-6">
6972
<a
70-
title="Repozytorium Eventownika na Githubie"
73+
title={t("eventownikGithubRepo")}
7174
href="https://github.com/Solvro/web-eventownik-v2"
7275
target="_blank"
7376
className={cn(
@@ -79,7 +82,7 @@ export function Footer() {
7982
<FaGithub />
8083
</a>
8184
<a
82-
title="Profil Koła Naukowego Solvro na Instagramie"
85+
title={t("solvroInstagram")}
8386
href="https://www.instagram.com/knsolvro/"
8487
target="_blank"
8588
className={cn(
@@ -91,7 +94,7 @@ export function Footer() {
9194
<FaInstagram />
9295
</a>
9396
<a
94-
title="Profil Koła Naukowego Solvro na Facebooku"
97+
title={t("solvroFacebook")}
9598
href="https://www.facebook.com/knsolvro"
9699
target="_blank"
97100
className={cn(
@@ -103,7 +106,7 @@ export function Footer() {
103106
<FaFacebook />
104107
</a>
105108
<a
106-
title="Profil Koła Naukowego Solvro na LinkedIn"
109+
title={t("solvroLinkedIn")}
107110
href="https://www.linkedin.com/company/knsolvro/"
108111
target="_blank"
109112
className={cn(
@@ -125,14 +128,14 @@ export function Footer() {
125128
<div className="container flex w-full flex-row items-center justify-center gap-8">
126129
<Image
127130
src="/logo_outline_light.png"
128-
alt="Eventownik logo"
131+
alt={t("eventownikLogo")}
129132
width="1500"
130133
height="1000"
131134
className="block dark:hidden"
132135
/>
133136
<Image
134137
src="/logo_outline_dark.png"
135-
alt="Eventownik logo"
138+
alt={t("eventownikLogo")}
136139
width="1500"
137140
height="1000"
138141
className="hidden dark:block"

0 commit comments

Comments
 (0)