Skip to content

Commit

Permalink
Add hook
Browse files Browse the repository at this point in the history
  • Loading branch information
emscb committed Apr 5, 2024
1 parent f42420c commit 9d5cddb
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/locale/English/translation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Translation } from "../types";

const EnglishTranslation: Translation = {
CATEGORY: {
web: "Web",
social: "Social",
unknown: "Unknown",
},
MENU: {
"재정 지원": "Financial Aid",
},
"파이콘 한국": "PyCon Korea",
준비위원회: "Organizing Team",
};
export default EnglishTranslation;
9 changes: 9 additions & 0 deletions src/locale/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { CategoryCode } from "enums/categories";

type TranslationItem = "파이콘 한국" | "준비위원회";
type MenuTranslationItem = "재정 지원";

export type Translation = { [K in TranslationItem]: string } & {
CATEGORY: { [K in CategoryCode | "unknown"]: string };
MENU: { [K in MenuTranslationItem]: string };
};
48 changes: 48 additions & 0 deletions src/utils/hooks/useTranslation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import EngTranslationKey from "locale/English/translation";

import { RootState } from "store";
import { Translation } from "locale/types";
import { useCallback } from "react";
import { useSelector } from "react-redux";
import { PickKeysByType, RecursiveKeyof } from "utils/types";

const useTranslation = () => {
const language = useSelector<RootState, RootState["core"]["language"]>(
(state) => state.core.language
);
const isTranslationKey = (
key: RecursiveKeyof<Translation>
): key is PickKeysByType<Translation, string> => key in EngTranslationKey;

const t = useCallback(
(key: RecursiveKeyof<Translation>) => {
let json;
switch (language) {
case "ENG":
json = EngTranslationKey;
break;
case "KOR":
return key;
default:
json = EngTranslationKey;
break;
}

if (isTranslationKey(key)) return json[key];
else {
const categoryIdx = key.indexOf(".");
const category = key.slice(0, categoryIdx) as keyof Omit<
Translation,
PickKeysByType<Translation, string>
>;
const subKey = key.slice(categoryIdx + 1) as keyof Translation[typeof category];
return json[category][subKey] ?? key;
}
},
[language]
);

return t;
};

export default useTranslation;
3 changes: 3 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const isLocal: () => boolean = () => {
return process.env.NODE_ENV === "development";
};
21 changes: 21 additions & 0 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export type PickKeysByType<T, TargetType> = {
[TK in keyof T]: T[TK] extends TargetType ? (TargetType extends T[TK] ? TK : never) : never;
}[keyof T];

export type ValueOf<T> = T[keyof T];

export type RecursiveKeyof<T extends Record<string, any>> = ValueOf<{
[TK in keyof T]: TK extends string
? T[TK] extends string | number | boolean | Date | undefined | null
? TK
: T[TK] extends Array<infer R>
? R extends Record<string, any>
? `${TK}.${RecursiveKeyof<R>}`
: TK
: T[TK] extends Record<string, any>
? `${TK}.${RecursiveKeyof<T[TK]>}`
: TK
: never;
}>;

export type ExtractKey<T, U extends keyof T> = Extract<keyof T, U>;

0 comments on commit 9d5cddb

Please sign in to comment.