Skip to content

Commit 43ac502

Browse files
committed
Translations
1 parent 844e95e commit 43ac502

20 files changed

Lines changed: 389 additions & 73 deletions

apps/web/src/components/ActivityFeed.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export default function ActivityFeed() {
6868
}
6969

7070
return (
71-
<Titled title={(s) => `Feed ${sep} ${s}`}>
71+
<Titled title={(s) => `${t("nav.feed")} ${sep} ${s}`}>
7272
<div className="m-2">
7373
<Card title={t("nav.feed")}>
7474
<p className="text-500 mb-4">

apps/web/src/components/ErrorBoundary.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from "react";
22
import {store} from "../redux/store";
33
import {error} from "../redux/error/actions";
4+
import {i18n} from "@zxplay/i18n";
45

56
export default class ErrorBoundary extends React.Component {
67

@@ -16,7 +17,7 @@ export default class ErrorBoundary extends React.Component {
1617

1718
render() {
1819
if (this.state.hasError) {
19-
store.dispatch(error('There was a problem in rendering this content.'));
20+
store.dispatch(error(i18n.t('errors.renderProblem')));
2021
return <></>
2122
}
2223

apps/web/src/components/HomePage.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ export default function HomePage() {
5959
<TabPanel header={t("home.tabEmulator")}>
6060
<Emulator zoom={zoom} width={width}/>
6161
</TabPanel>
62-
<TabPanel header="Sinclair BASIC">
62+
<TabPanel header={t("home.tabSinclairBasic")}>
6363
<DemoSinclairBasicEditor/>
6464
</TabPanel>
65-
<TabPanel header="Z80 Assembly">
65+
<TabPanel header={t("home.tabZ80Assembly")}>
6666
<DemoAssemblyEditor/>
6767
</TabPanel>
6868
</TabView>
@@ -78,10 +78,10 @@ export default function HomePage() {
7878
<TabView
7979
activeIndex={selectedTabIndex}
8080
onTabChange={(e) => dispatch(setSelectedTabIndex(e.index))}>
81-
<TabPanel header="Sinclair BASIC">
81+
<TabPanel header={t("home.tabSinclairBasic")}>
8282
<DemoSinclairBasicEditor/>
8383
</TabPanel>
84-
<TabPanel header="Z80 Assembly">
84+
<TabPanel header={t("home.tabZ80Assembly")}>
8585
<DemoAssemblyEditor/>
8686
</TabPanel>
8787
</TabView>

apps/web/src/components/PrivacyPolicyPage.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import {Titled} from "react-titled";
55
import {Card} from "primereact/card";
66
import {requestPrivacyPolicy} from "../redux/app/actions";
77
import {sep} from "../constants";
8+
import {useTranslation} from "@zxplay/i18n";
89

910
export default function PrivacyPolicyPage() {
11+
const {t} = useTranslation();
1012
const dispatch = useDispatch();
1113

1214
const text = useSelector(state => state?.app.privacyPolicy);
@@ -18,7 +20,7 @@ export default function PrivacyPolicyPage() {
1820
}, []);
1921

2022
return (
21-
<Titled title={(s) => `Privacy Policy ${sep} ${s}`}>
23+
<Titled title={(s) => `${t("nav.privacyPolicy")} ${sep} ${s}`}>
2224
<Card className="m-2">
2325
<ReactMarkdown>
2426
{text}

apps/web/src/components/ProjectList.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export default function ProjectList() {
109109
return (
110110
<React.Fragment>
111111
<span className="user-select-none paginator-label">
112-
Items per page:{" "}
112+
{t("projectList.itemsPerPage")}{" "}
113113
</span>
114114
<Dropdown
115115
value={options.value}

apps/web/src/components/ProjectPage.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export default function ProjectPage({ projectId }) {
5959
const className = isMobile ? "" : "mx-2 my-1";
6060

6161
return (
62-
<Titled title={(s) => `${title} ${sep} Project ${sep} ${s}`}>
62+
<Titled title={(s) => `${title} ${sep} ${t("nav.project")} ${sep} ${s}`}>
6363
<Toast ref={toast} />
6464
<div className={className}>
6565
<div className="grid full-width-grid">

apps/web/src/components/PublicProfiles.jsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,22 @@ const GET_PUBLIC_PROFILES = gql`
5555

5656
const SORT_OPTIONS = [
5757
{
58-
label: "Recent activity",
58+
labelKey: "profiles.sortRecent",
5959
value: "recent",
6060
orderBy: [{ projects_aggregate: { max: { updated_at: "desc_nulls_last" } } }],
6161
},
6262
{
63-
label: "Most public projects",
63+
labelKey: "profiles.sortProjects",
6464
value: "projects",
6565
orderBy: [{ projects_aggregate: { count: "desc" } }],
6666
},
6767
{
68-
label: "Most followers",
68+
labelKey: "profiles.sortFollowers",
6969
value: "followers",
7070
orderBy: [{ followers_aggregate: { count: "desc" } }],
7171
},
7272
{
73-
label: "Newest",
73+
labelKey: "profiles.sortNewest",
7474
value: "newest",
7575
orderBy: [{ created_at: "desc" }],
7676
},
@@ -180,7 +180,7 @@ export default function PublicProfiles() {
180180
<Card title={t("profiles.title")}>
181181
<div className="flex flex-wrap align-items-center justify-content-between gap-3 mb-4">
182182
<p className="text-500 m-0">
183-
Browse public profiles on ZX Play
183+
{t("profiles.intro")}
184184
{totalCount > 0 && (
185185
<span className="ml-2">
186186
(showing {page * pageSize + 1} -{" "}
@@ -199,12 +199,15 @@ export default function PublicProfiles() {
199199
}}
200200
/>
201201
<label htmlFor="hideEmpty" className="text-500 text-sm">
202-
Only with public projects
202+
{t("profiles.onlyWithProjects")}
203203
</label>
204204
</div>
205205
<Dropdown
206206
value={sort}
207-
options={SORT_OPTIONS}
207+
options={SORT_OPTIONS.map((o) => ({
208+
...o,
209+
label: t(o.labelKey),
210+
}))}
208211
style={{ width: "16rem" }}
209212
onChange={(e) => {
210213
setSort(e.value);

apps/web/src/components/PublicProjectPage.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import gql from "graphql-tag";
88
import { gqlFetch } from "../graphql_fetch";
99
import { loadProject } from "../redux/project/actions";
1010
import ProjectPage from "./ProjectPage";
11+
import { useTranslation } from "@zxplay/i18n";
1112

1213
// Simple query to get project by slug
1314
// Hasura's RLS will handle filtering to only show projects the current user can access
@@ -25,6 +26,7 @@ const GET_PROJECT_BY_SLUG = gql`
2526
`;
2627

2728
export default function PublicProjectPage() {
29+
const { t } = useTranslation();
2830
const { userSlug, projectSlug } = useParams();
2931
const navigate = useNavigate();
3032
const dispatch = useDispatch();
@@ -57,9 +59,9 @@ export default function PublicProjectPage() {
5759

5860
if (!project) {
5961
if (!currentUserId) {
60-
setError("Please log in to view this project");
62+
setError(t("publicProject.loginRequired"));
6163
} else {
62-
setError("Project not found");
64+
setError(t("publicProject.notFound"));
6365
}
6466
return;
6567
}
@@ -70,7 +72,7 @@ export default function PublicProjectPage() {
7072

7173
} catch (err) {
7274
console.error("Failed to fetch project:", err);
73-
setError("Failed to load project");
75+
setError(t("publicProject.loadFailed"));
7476
} finally {
7577
setLoading(false);
7678
}

apps/web/src/components/TermsOfUsePage.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import {Titled} from "react-titled";
55
import {Card} from "primereact/card";
66
import {requestTermsOfUse} from "../redux/app/actions";
77
import {sep} from "../constants";
8+
import {useTranslation} from "@zxplay/i18n";
89

910
export default function InfoLegacyTerms() {
11+
const {t} = useTranslation();
1012
const dispatch = useDispatch();
1113

1214
const text = useSelector(state => state?.app.termsOfUse);
@@ -18,7 +20,7 @@ export default function InfoLegacyTerms() {
1820
}, []);
1921

2022
return (
21-
<Titled title={(s) => `Terms of Use ${sep} ${s}`}>
23+
<Titled title={(s) => `${t("nav.termsOfUse")} ${sep} ${s}`}>
2224
<Card className="m-2">
2325
<ReactMarkdown>
2426
{text}

apps/web/src/components/UserProfileSettings.jsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,17 @@ export default function UserProfileSettings() {
137137

138138
const validateSlug = async (slug) => {
139139
if (!slug) {
140-
setSlugError("URL slug is required");
140+
setSlugError(t("settings.slugRequired"));
141141
return false;
142142
}
143143

144144
if (!isValidSlug(slug)) {
145-
setSlugError("Slug must be 3+ characters, lowercase letters, numbers, and hyphens only");
145+
setSlugError(t("settings.slugInvalid"));
146146
return false;
147147
}
148148

149149
if (isReservedSlug(slug)) {
150-
setSlugError("This URL is reserved and cannot be used");
150+
setSlugError(t("settings.slugReserved"));
151151
return false;
152152
}
153153

@@ -159,12 +159,12 @@ export default function UserProfileSettings() {
159159
});
160160

161161
if (response?.data?.user?.length > 0) {
162-
setSlugError("This URL is already taken");
162+
setSlugError(t("settings.slugTaken"));
163163
return false;
164164
}
165165
} catch (error) {
166166
console.error("Failed to check slug availability:", error);
167-
setSlugError("Failed to verify URL availability");
167+
setSlugError(t("settings.slugCheckFailed"));
168168
return false;
169169
}
170170

@@ -201,7 +201,7 @@ export default function UserProfileSettings() {
201201

202202
if (response?.data?.update_user_by_pk) {
203203
setOriginalProfile(profile);
204-
setSaveMessage({ severity: "success", text: "Profile updated successfully!" });
204+
setSaveMessage({ severity: "success", text: t("settings.saveSuccess") });
205205

206206
// Refresh user info in Redux store to update navigation
207207
// Add small delay to ensure database update is complete
@@ -214,7 +214,7 @@ export default function UserProfileSettings() {
214214
}
215215
} catch (error) {
216216
console.error("Failed to save profile:", error);
217-
setSaveMessage({ severity: "error", text: "Failed to save profile changes" });
217+
setSaveMessage({ severity: "error", text: t("settings.saveFailed") });
218218
} finally {
219219
setSaving(false);
220220
}

0 commit comments

Comments
 (0)