Skip to content

Commit e9ea087

Browse files
update
1 parent 6b212ba commit e9ea087

File tree

8 files changed

+104
-52
lines changed

8 files changed

+104
-52
lines changed

data/cardsData.js

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
/**
88
* @typedef {Object} CardsData
9-
* @property {string} project - "project" devient la clé unique de l'objet qui contient toutes les infos et traductions relatives à la carte et qui seront poussées à i18n lors de l'initialisation.
9+
* @property {string} project - REQUIS - "project" devient la clé unique de l'objet qui contient toutes les infos et traductions relatives à la carte et qui seront poussées à i18n lors de l'initialisation.
1010
* @property {string} imageCover - Nom du fichier image avec extension.
1111
* @property {string} title - Nom du projet affiché sur la carte.
1212
* @property {string} author - Auteur du projet affiché sur la carte.
@@ -26,7 +26,7 @@ export const cardsData = [
2626
imageCover: "marv.jpg",
2727
title: "Marv",
2828
author: "Paul",
29-
github: "Low-Fuel",
29+
github: "",
3030
demo: "https://marv-bot.fr",
3131
translations: [
3232
{
@@ -36,9 +36,39 @@ export const cardsData = [
3636
},
3737
{
3838
lang: "fr",
39-
translations:
39+
description:
4040
"Un bot Discord en NodeJS qui utilise chatGPT et un système de synthèse et de reconnaissance vocale permettant d’intéragir avec le bot grâce à la voix.",
4141
},
42+
{
43+
lang: "es",
44+
description:
45+
"Un bot de Discord en NodeJS que usa ChatGPT y un sistema de síntesis y reconocimiento de voz, lo que permite interactuar con el bot a través de comandos de voz.",
46+
},
47+
],
48+
},
49+
{
50+
project: "matrix",
51+
imageCover: "matrix.jpg",
52+
title: "Matrix",
53+
author: "Paul",
54+
github: "Matrix",
55+
demo: "",
56+
translations: [
57+
{
58+
lang: "en",
59+
description:
60+
"Real-time capture from your WebCam to ASCII Art rendering in a Qt6 window and to a virtual webcam, all in Python.",
61+
},
62+
{
63+
lang: "fr",
64+
description:
65+
"Capture de votre WebCam en temps réel vers un rendu ASCII Art dans une fenêtre Qt6 et vers une webcam virtuelle, le tout en Python.",
66+
},
67+
{
68+
lang: "es",
69+
description:
70+
"Captura en tiempo real desde tu WebCam a una representación en ASCII Art en una ventana Qt6 y a una webcam virtual, todo en Python.",
71+
},
4272
],
4373
},
4474
];

src/App.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { useEffect } from "react";
2-
import { ORGNAME } from "../config/globals";
3-
import { fetchReposData } from "../utils/helpers";
2+
// import { ORGNAME } from "../config/globals";
3+
// import { fetchReposData } from "../utils/helpers";
44
import CardsWrapper from "./components/CardsWrapper";
55
import Header from "./components/Header";
66
import Info from "./components/Info";
77
import LangageSwitcher from "./components/LangSwitcher";
88

99
function App() {
1010
useEffect(() => {
11-
fetchReposData(ORGNAME);
11+
// fetchReposData(ORGNAME);
1212
}, []);
1313

1414
return (

src/components/Card.jsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import { FaGithub } from "react-icons/fa";
33
import { MdOutlineRemoveRedEye } from "react-icons/md";
44
import { BASE_IMG_PATH, DEFAULT_IMG_COVER } from "../../config/globals";
55

6-
function Card({ imgName = DEFAULT_IMG_COVER, title = "No name" }) {
6+
function Card({
7+
imgName = DEFAULT_IMG_COVER,
8+
title = "No name",
9+
translationKey,
10+
demoUrl,
11+
author,
12+
}) {
713
const { t } = useTranslation();
814

915
const buttonStyle =
@@ -21,11 +27,11 @@ function Card({ imgName = DEFAULT_IMG_COVER, title = "No name" }) {
2127
</div>
2228

2329
<div className="h-full max-h-[180px] overflow-hidden overflow-y-auto text-ellipsis py-4 text-sm text-neutral-200">
24-
{t(`marv.description`)}
30+
{t(`app.card:${translationKey}.description`)}
2531
</div>
2632

2733
<div className="py-4 text-center italic text-neutral-300">
28-
{t("devby")} <span className="font-bold">Paul</span>
34+
{t("devby")} <span className="font-bold">{author}</span>
2935
</div>
3036

3137
<div className="flex justify-center gap-x-4 py-2">
@@ -34,7 +40,7 @@ function Card({ imgName = DEFAULT_IMG_COVER, title = "No name" }) {
3440
Github
3541
</a>
3642

37-
<a className={`${buttonStyle}`}>
43+
<a className={`${buttonStyle}`} href={demoUrl}>
3844
<MdOutlineRemoveRedEye size={"24"} className="mr-2" /> Demo
3945
</a>
4046
</div>

src/components/CardsWrapper.jsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
import Card from "./Card";
2+
import { cardsData } from "../../data/cardsData";
23

34
function CardsWrapper() {
45
return (
56
<div className="flex items-center justify-center">
67
<div className="flex max-w-[1280px] flex-wrap justify-center gap-8 p-8">
7-
<Card imgName="matrix.jpg" />
8-
<Card imgName="marv.jpg" />
9-
<Card />
10-
<Card />
11-
<Card />
12-
<Card />
13-
<Card />
14-
<Card />
8+
{cardsData.map((card, i) => {
9+
console.log(card);
10+
return (
11+
<Card
12+
title={card.title}
13+
imgName={card.imageCover}
14+
key={i}
15+
translationKey={card.project}
16+
demoUrl={card.demo}
17+
author={card.author}
18+
/>
19+
);
20+
})}
1521
</div>
1622
</div>
1723
);

src/components/Header.jsx

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,6 @@
11
import { FaGithub } from "react-icons/fa";
22
import { BsDiscord } from "react-icons/bs";
33
import { useTranslation } from "react-i18next";
4-
import i18n from "../i18n";
5-
6-
const add = () => {
7-
i18n.addResourceBundle(
8-
"es",
9-
"translation",
10-
{
11-
marv: {
12-
title: "Marv",
13-
description:
14-
"Un bot de Discord en NodeJS que usa ChatGPT y un sistema de síntesis y reconocimiento de voz, lo que permite interactuar con el bot a través de comandos de voz.",
15-
},
16-
info: "Nuestros proyectos",
17-
baseline: "Desarrollo de software y scripts",
18-
discord: "Únete a nuestro Discord",
19-
20-
devby: "Desarrollado por",
21-
},
22-
false,
23-
true,
24-
);
25-
};
26-
add();
274

285
function Header() {
296
const { t } = useTranslation();

src/components/LangSwitcher.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { useState } from "react";
2-
import { changeLanguage } from "../../utils/helpers";
2+
import { changeLanguage, normalizeLang } from "../../utils/helpers";
33
import i18next from "i18next";
44

55
function LangageSwitcher() {
66
const currentLanguage = i18next.language;
7-
const [activeLang, setActiveLang] = useState(currentLanguage);
7+
8+
const [activeLang, setActiveLang] = useState(normalizeLang(currentLanguage));
89

910
const btnStyleBase =
1011
"py-2 px-6 pointer mr-2 rounded-full my-2 text-xs hover:bg-accentDarker transition-colors";

src/i18n.js

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import i18n from "i18next";
22
import { initReactI18next } from "react-i18next";
33
import LanguageDetector from "i18next-browser-languagedetector";
4+
import { cardsData } from "../data/cardsData";
45

56
i18n
67
.use(LanguageDetector)
@@ -9,10 +10,6 @@ i18n
910
resources: {
1011
en: {
1112
translation: {
12-
marv: {
13-
description:
14-
"A Discord bot in NodeJS that uses ChatGPT and a speech synthesis and recognition system, allowing interaction with the bot through voice commands.",
15-
},
1613
info: "Our projects",
1714
baseline: "Software & Script Development",
1815
discord: "Join our Discord",
@@ -21,17 +18,21 @@ i18n
2118
},
2219
fr: {
2320
translation: {
24-
marv: {
25-
description:
26-
"Un bot Discord en NodeJS qui utilise chatGPT et un système de synthèse et de reconnaissance vocale permettant d’intéragir avec le bot grâce à la voix.",
27-
},
28-
2921
info: "Nos projets",
3022
baseline: "Développement de softs & scripts",
3123
discord: "Rejoignez notre Discord",
3224
devby: "Developpé par",
3325
},
3426
},
27+
28+
es: {
29+
translation: {
30+
info: "Nuestros proyectos",
31+
baseline: "Desarrollo de software y scripts",
32+
discord: "Únete a nuestro Discord",
33+
devby: "Desarrollado por",
34+
},
35+
},
3536
},
3637
fallbackLng: "en",
3738
debug: true,
@@ -40,4 +41,28 @@ i18n
4041
},
4142
});
4243

44+
function fillTranslations(cardsData) {
45+
console.log("loading translations...");
46+
cardsData.forEach((card) => {
47+
card.translations.forEach((translation) => {
48+
const { lang, description } = translation;
49+
i18n.addResourceBundle(
50+
lang,
51+
"app.card",
52+
{
53+
[card.project]: {
54+
description,
55+
},
56+
},
57+
true,
58+
true,
59+
);
60+
});
61+
});
62+
}
63+
64+
fillTranslations(cardsData);
65+
66+
console.log(i18n.getResourceBundle("en", "app.card"));
67+
4368
export default i18n;

utils/helpers.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,10 @@ export const getDicordInviteInfo = async (inviteCode) => {
6464
return null;
6565
}
6666
};
67+
68+
export const normalizeLang = (lang) => {
69+
if (typeof lang === "string" && lang.includes("-")) {
70+
return lang.split("-")[0];
71+
}
72+
return lang;
73+
};

0 commit comments

Comments
 (0)