Compare commits
2 Commits
f06a7381e7
...
ad515c5be9
Author | SHA1 | Date | |
---|---|---|---|
ad515c5be9 | |||
c1647ab498 |
frontend/src
25
frontend/src/hooks/i18n.ts
Normal file
25
frontend/src/hooks/i18n.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { useProfile } from "./profile.ts";
|
||||
import { messages } from "../lib/messages.ts";
|
||||
|
||||
type MessageType = typeof messages;
|
||||
|
||||
type MessageKeys = keyof MessageType;
|
||||
|
||||
type MessageParams<T extends MessageKeys> = MessageType[T]["en"] extends (
|
||||
...args: any // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
) => any // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
? Parameters<MessageType[T]["en"]>
|
||||
: [];
|
||||
|
||||
export function useI18n() {
|
||||
const profile = useProfile();
|
||||
const lang = profile.language;
|
||||
return function <T extends MessageKeys>(
|
||||
key: T,
|
||||
...args: MessageParams<T>
|
||||
): string {
|
||||
const message = messages[key][lang] ?? messages[key]["en"];
|
||||
// @ts-expect-error see https://stackoverflow.com/a/75086839
|
||||
return typeof message === "function" ? message(...args) : message;
|
||||
};
|
||||
}
|
23
frontend/src/lib/messages.ts
Normal file
23
frontend/src/lib/messages.ts
Normal file
@ -0,0 +1,23 @@
|
||||
type AllLanguages<T> = { en: T; sv: T };
|
||||
|
||||
export const messages = {
|
||||
"Home screen": {
|
||||
en: "Home",
|
||||
sv: "Aktuellt",
|
||||
},
|
||||
"Here you can see the latest and greatest": {
|
||||
en: "Here you can see the latest and greatest",
|
||||
sv: "Här ser du allt som är aktuellt",
|
||||
},
|
||||
Profile: {
|
||||
en: "Profile",
|
||||
sv: "Profil",
|
||||
},
|
||||
"Log out": {
|
||||
en: "Log out",
|
||||
sv: "Logga ut",
|
||||
},
|
||||
} as const satisfies Record<
|
||||
string,
|
||||
AllLanguages<string> | AllLanguages<(...args: any) => string> // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
>;
|
@ -1,8 +1,11 @@
|
||||
import { useI18n } from "../hooks/i18n.ts";
|
||||
|
||||
export default function Home() {
|
||||
const i18n = useI18n();
|
||||
return (
|
||||
<>
|
||||
<h1>Home screen</h1>
|
||||
<p>Here you can see the latest and greatest</p>
|
||||
<h1>{i18n("Home screen")}</h1>
|
||||
<p>{i18n("Here you can see the latest and greatest")}</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,21 +1,23 @@
|
||||
import { NavLink } from "react-router";
|
||||
import "./menu.css";
|
||||
import { useState } from "react";
|
||||
import { useI18n } from "../hooks/i18n.ts";
|
||||
|
||||
export default function Menu() {
|
||||
const [subMenuVisible, setSubMenuVisible] = useState(false);
|
||||
const i18n = useI18n();
|
||||
return (
|
||||
<menu className={"main"}>
|
||||
<li>
|
||||
<NavLink to={"/"}>Home</NavLink>
|
||||
<NavLink to={"/"}>{i18n("Home screen")}</NavLink>
|
||||
</li>
|
||||
<li>
|
||||
<button onClick={() => setSubMenuVisible((current) => !current)}>
|
||||
<span>| | |</span>
|
||||
</button>
|
||||
<menu className={"sub " + (subMenuVisible ? "visible" : "")}>
|
||||
<li>Profile</li>
|
||||
<li>Log out</li>
|
||||
<li>{i18n("Profile")}</li>
|
||||
<li>{i18n("Log out")}</li>
|
||||
</menu>
|
||||
</li>
|
||||
</menu>
|
||||
|
Loading…
x
Reference in New Issue
Block a user