diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index eff79ab..8c4e45d 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,9 +4,19 @@
-
+
+
+
+
+
+
+
+
+
+
+
@@ -338,7 +348,7 @@
-
+
@@ -412,9 +422,9 @@
-
+
@@ -531,22 +541,6 @@
-
-
- 1743691399769
-
-
-
- 1743691399769
-
-
-
- 1743691471368
-
-
-
- 1743691471368
-
1743705749057
@@ -923,7 +917,23 @@
1752586932190
-
+
+
+ 1752591387066
+
+
+
+ 1752591387066
+
+
+
+ 1752596436284
+
+
+
+ 1752596436284
+
+
@@ -970,8 +980,6 @@
-
-
@@ -995,7 +1003,9 @@
-
+
+
+
false
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index e1832e1..71fadf9 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -220,7 +220,7 @@
"seeExamples": "See Examples"
},
"toolLayout": {
- "allToolsTitle": "All {{type}} Tools"
+ "allToolsTitle": "All {{type}}"
},
"toolMultiFileResult": {
"copied": "File copied",
diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json
index be49c2d..ce5493f 100644
--- a/public/locales/fr/translation.json
+++ b/public/locales/fr/translation.json
@@ -58,7 +58,7 @@
"description": "Outils pour travailler avec des images PNG : convertissez des PNG en JPG, créez des PNG transparents, modifiez les couleurs PNG, recadrez, faites pivoter, redimensionnez des PNG et bien plus encore.",
"title": "Outils PNG"
},
- "seeAll": "Tout voir {{title}}",
+ "seeAll": "Voir les {{title}}",
"string": {
"description": "Outils pour travailler avec du texte : convertissez du texte en images, recherchez et remplacez du texte, divisez du texte en fragments, joignez des lignes de texte, répétez du texte et bien plus encore.",
"title": "Outils de texte"
@@ -220,7 +220,7 @@
"seeExamples": "Voir des exemples"
},
"toolLayout": {
- "allToolsTitle": "Tous {{type}} Outils"
+ "allToolsTitle": "Tous les {{type}}"
},
"toolMultiFileResult": {
"copied": "Fichier copié",
diff --git a/public/locales/hi/translation.json b/public/locales/hi/translation.json
index 3fdf9ba..ae00805 100644
--- a/public/locales/hi/translation.json
+++ b/public/locales/hi/translation.json
@@ -220,7 +220,7 @@
"seeExamples": "उदाहरण देखें"
},
"toolLayout": {
- "allToolsTitle": "सभी {{type}} टूल्स"
+ "allToolsTitle": "सभी {{type}}"
},
"toolMultiFileResult": {
"copied": "फ़ाइल कॉपी की गई",
diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx
index 4cae00e..18c99d5 100644
--- a/src/components/Hero.tsx
+++ b/src/components/Hero.tsx
@@ -151,7 +151,7 @@ export default function Hero() {
renderGroup={(params) => {
return (
- {getToolCategoryTitle(params.group)}
+ {getToolCategoryTitle(params.group, t)}
{params.children}
);
diff --git a/src/components/ToolHeader.tsx b/src/components/ToolHeader.tsx
index 01275c4..a39c0db 100644
--- a/src/components/ToolHeader.tsx
+++ b/src/components/ToolHeader.tsx
@@ -11,6 +11,7 @@ import { isBookmarked, toggleBookmarked } from '@utils/bookmark';
import IconButton from '@mui/material/IconButton';
import { useTranslation } from 'react-i18next';
import useMediaQuery from '@mui/material/useMediaQuery';
+import { validNamespaces } from '../i18n';
const StyledButton = styled(Button)(({ theme }) => ({
backgroundColor: 'white',
@@ -94,6 +95,7 @@ export default function ToolHeader({
path
}: ToolHeaderProps) {
const theme = useTheme();
+ const { t } = useTranslation();
const [bookmarked, setBookmarked] = useState(isBookmarked(path));
return (
@@ -101,7 +103,7 @@ export default function ToolHeader({
items={[
{ title: 'All tools', link: '/' },
{
- title: getToolsByCategory().find(
+ title: getToolsByCategory(t).find(
(category) => category.type === type
)!.rawTitle,
link: '/categories/' + type
diff --git a/src/components/ToolLayout.tsx b/src/components/ToolLayout.tsx
index 7f127c8..131cf61 100644
--- a/src/components/ToolLayout.tsx
+++ b/src/components/ToolLayout.tsx
@@ -43,7 +43,7 @@ export default function ToolLayout({
const toolDescription: string = t(i18n.description);
const otherCategoryTools =
- getToolsByCategory()
+ getToolsByCategory(t)
.find((category) => category.type === type)
?.tools.filter((tool) => t(tool.name) !== toolTitle)
.map((tool) => ({
@@ -75,10 +75,10 @@ export default function ToolLayout({
{children}
category.type === type)!
- .rawTitle
+ getToolsByCategory(t).find((category) => category.type === type)!
+ .title
)
})}
toolCards={otherCategoryTools}
diff --git a/src/i18n/index.ts b/src/i18n/index.ts
index 63ff50a..d0d392b 100644
--- a/src/i18n/index.ts
+++ b/src/i18n/index.ts
@@ -2,7 +2,7 @@ import i18n, { ParseKeys } from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
-export const validNamespaces: string[] = [
+export const validNamespaces: (string | 'translation')[] = [
'string',
'number',
'video',
diff --git a/src/pages/home/Categories.tsx b/src/pages/home/Categories.tsx
index 250600e..81bf1b6 100644
--- a/src/pages/home/Categories.tsx
+++ b/src/pages/home/Categories.tsx
@@ -9,6 +9,7 @@ import { categoriesColors } from 'config/uiConfig';
import { Icon } from '@iconify/react';
import { useTranslation } from 'react-i18next';
import { getI18nNamespaceFromToolCategory } from '@utils/string';
+import { validNamespaces } from '../../i18n';
type ArrayElement =
ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
@@ -32,10 +33,10 @@ const SingleCategory = function ({
`categories.${category.type}.description`,
category.description
);
- const seeAllText = t('categories.seeAll', 'See all {{title}}', {
+ const seeAllText = t('translation:categories.seeAll', 'See all {{title}}', {
title: categoryTitle
});
- const tryText = t('categories.try', 'Try {{title}}', {
+ const tryText = t('translation:categories.try', 'Try {{title}}', {
//@ts-ignore
title: t(category.example.title)
});
@@ -111,9 +112,10 @@ const SingleCategory = function ({
);
};
export default function Categories() {
+ const { t } = useTranslation();
return (
- {getToolsByCategory().map((category, index) => (
+ {getToolsByCategory(t).map((category, index) => (
))}
diff --git a/src/pages/tools-by-category/index.tsx b/src/pages/tools-by-category/index.tsx
index 44324fb..794c5e6 100644
--- a/src/pages/tools-by-category/index.tsx
+++ b/src/pages/tools-by-category/index.tsx
@@ -23,7 +23,7 @@ import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import SearchIcon from '@mui/icons-material/Search';
import { Helmet } from 'react-helmet';
import { useTranslation } from 'react-i18next';
-import { I18nNamespaces } from '../../i18n';
+import { I18nNamespaces, validNamespaces } from '../../i18n';
const StyledLink = styled(Link)(({ theme }) => ({
'&:hover': {
@@ -36,16 +36,12 @@ export default function ToolsByCategory() {
const mainContentRef = React.useRef(null);
const { categoryName } = useParams();
const [searchTerm, setSearchTerm] = React.useState('');
- const rawTitle = getToolCategoryTitle(categoryName as string);
+ const { t } = useTranslation(validNamespaces);
+ const rawTitle = getToolCategoryTitle(categoryName as string, t);
// First get tools by category without filtering
const toolsByCategory =
- getToolsByCategory().find(({ type }) => type === categoryName)?.tools ?? [];
-
- const namespace =
- toolsByCategory.length > 0
- ? getI18nNamespaceFromToolCategory(toolsByCategory[0].type)
- : 'translation';
- const { t } = useTranslation(namespace);
+ getToolsByCategory(t).find(({ type }) => type === categoryName)?.tools ??
+ [];
const categoryTools = filterTools(toolsByCategory, searchTerm, t);
@@ -77,10 +73,9 @@ export default function ToolsByCategory() {
navigate('/')}>
- {`All ${rawTitle} Tools`}
+
+ {t('translation:toolLayout.allToolsTitle', { type: rawTitle })}
+
+): {
title: string;
rawTitle: string;
description: string;
@@ -179,9 +179,13 @@ export const getToolsByCategory = (): {
(config) => config.type === type
);
return {
- rawTitle: categoryConfig?.title ?? capitalizeFirstLetter(type),
- title: `${categoryConfig?.title ?? capitalizeFirstLetter(type)} Tools`,
- description: categoryConfig?.value ?? '',
+ rawTitle: categoryConfig?.title
+ ? t(categoryConfig.title)
+ : capitalizeFirstLetter(type),
+ title: categoryConfig?.title
+ ? t(categoryConfig.title)
+ : `${capitalizeFirstLetter(type)} Tools`,
+ description: categoryConfig?.value ? t(categoryConfig.value) : '',
type,
icon: categoryConfig!.icon,
tools: tools ?? [],
diff --git a/src/utils/string.ts b/src/utils/string.ts
index f145cdd..4207348 100644
--- a/src/utils/string.ts
+++ b/src/utils/string.ts
@@ -2,6 +2,7 @@ import { UpdateField } from '@components/options/ToolOptions';
import { getToolsByCategory } from '@tools/index';
import { ToolCategory } from '@tools/defineTool';
import { I18nNamespaces, validNamespaces } from '../i18n';
+import { TFunction } from 'i18next';
// Here starting the shared values for string manipulation.
@@ -109,8 +110,11 @@ export function itemCounter(
return dict;
}
-export const getToolCategoryTitle = (categoryName: string): string =>
- getToolsByCategory().find((category) => category.type === categoryName)!
+export const getToolCategoryTitle = (
+ categoryName: string,
+ t: TFunction
+): string =>
+ getToolsByCategory(t).find((category) => category.type === categoryName)!
.rawTitle;
// Type guard to check if a value is a valid I18nNamespaces