From 65fe21d97c54d0f21926a7a72b025cc33f050779 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Sun, 26 Jun 2022 19:49:12 +0200 Subject: [PATCH 01/10] Revert "commented out Localization UI" This reverts commit 9dcccf87b168197cc60f7f5317a9b4e6208a56b3. --- web/src/apps/main/components/navbar/index.tsx | 4 ++-- web/src/apps/main/redux/reducers/settings/index.ts | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/web/src/apps/main/components/navbar/index.tsx b/web/src/apps/main/components/navbar/index.tsx index e99b67ed7..e7cbe3824 100644 --- a/web/src/apps/main/components/navbar/index.tsx +++ b/web/src/apps/main/components/navbar/index.tsx @@ -18,7 +18,7 @@ import logo from "src/assets/svg/logo-wide.svg"; import { LinkV2 } from "src/components/link-v2"; import { IOSSwitch } from "./ios-switch"; -// import { LanguageSwitch } from "./lang-switch"; +import { LanguageSwitch } from "./lang-switch"; const useStyles = makeStyles((theme) => createStyles({ @@ -160,7 +160,7 @@ export const Navbar: FC = () => {
- {/* */} + { - // const persistedLanguageCode = localStorage.getItem("languageCode"); - const persistedLanguageCode = "en"; + const persistedLanguageCode = localStorage.getItem("languageCode"); const initialLanguage = allLanguages.find(({ code }) => code === persistedLanguageCode) || allLanguages[0]; document.body.setAttribute("dir", initialLanguage?.code === "ar" ? "rtl" : "ltr"); From cf65ce2d85045724fd92f79e25d21ea2a04ea7b2 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 5 Aug 2022 21:24:37 +0200 Subject: [PATCH 02/10] removed react-intl --- web/package.json | 2 - web/src/apps/main/entry/app.tsx | 111 +++++++--------------------- web/src/localization/index.tsx | 31 -------- web/src/localization/locals/fr.ts | 32 -------- yarn.lock | 118 +----------------------------- 5 files changed, 31 insertions(+), 263 deletions(-) delete mode 100644 web/src/localization/index.tsx delete mode 100644 web/src/localization/locals/fr.ts diff --git a/web/package.json b/web/package.json index 35007ebd6..58e165295 100644 --- a/web/package.json +++ b/web/package.json @@ -26,8 +26,6 @@ "markdown-to-jsx": "^7.1.0", "react": "^17.0.1", "react-dom": "^17.0.1", - "react-intl": "^5.20.6", - "react-intl-translations-manager": "^5.0.3", "react-redux": "^7.2.6", "react-router-dom": "^5.2.0", "react-spring": "^8.0.27", diff --git a/web/src/apps/main/entry/app.tsx b/web/src/apps/main/entry/app.tsx index 7a145f68e..96844fd6b 100644 --- a/web/src/apps/main/entry/app.tsx +++ b/web/src/apps/main/entry/app.tsx @@ -3,52 +3,16 @@ import "./style.scss"; import { ErrorBoundary } from "@dzcode.io/ui/dist/error-boundary"; import Container from "@material-ui/core/Container"; import { ComponentType, FC, lazy, Suspense, useEffect } from "react"; -import { defineMessages, useIntl } from "react-intl"; -import { Route, Switch, useLocation } from "react-router-dom"; +import { Route, RouteProps, Switch, useLocation } from "react-router-dom"; import { Footer } from "src/apps/main/components/footer"; import { Navbar } from "src/apps/main/components/navbar"; import { Theme } from "src/apps/main/components/theme"; import { getEnv } from "src/common/utils"; import { Loading } from "src/components/loading"; -import Localization from "src/localization"; -type RouteInterface = { +interface RouteInterface extends RouteProps { import: Promise<{ default: ComponentType }>; - exact?: boolean; -} & ({ translate?: false; path?: string } | { translate: true; path: Record }); - -const messages = defineMessages({ - learn: { - id: "learn.path", - defaultMessage: "Learn", - description: "Learn page route", - }, - projects: { - id: "projects.path", - defaultMessage: "Projects", - description: "Projects page route", - }, - articles: { - id: "articles.path", - defaultMessage: "Articles", - description: "Articles page route", - }, - faq: { - id: "faq.path", - defaultMessage: "FAQ", - description: "FAQ page route", - }, - contribute: { - id: "contribute.path", - defaultMessage: "Contribute", - description: "Contribute page route", - }, - team: { - id: "team.path", - defaultMessage: "Team", - description: "Team page route", - }, -}); +} const routes: RouteInterface[] = [ { @@ -58,59 +22,32 @@ const routes: RouteInterface[] = [ }, { import: import("src/apps/main/pages/learn"), - path: messages.learn, - translate: true, + path: "/Learn", }, { import: import("src/apps/main/pages/projects"), - path: messages.projects, - translate: true, + path: "/Projects", }, { import: import("src/apps/main/pages/articles"), - path: messages.articles, - translate: true, + path: "/Articles", }, { import: import("src/apps/main/pages/faq"), - path: messages.faq, - translate: true, + path: "/FAQ", }, { import: import("src/apps/main/pages/contribute"), - path: messages.contribute, - translate: true, + path: "/Contribute", }, { import: import("src/apps/main/pages/team"), - path: messages.team, - translate: true, + path: "/Team", }, { import: import("src/apps/main/pages/not-found"), }, ]; -const Routes: FC = () => { - const intl = useIntl(); - return ( - - {routes.map((route, index) => ( - route.import)} - /> - ))}{" "} - - ); -}; export const App: FC = () => { if (getEnv() !== "development") { @@ -128,17 +65,25 @@ export const App: FC = () => { return ( - -
- - - }> - - - -
-
-
+
+ + + }> + + {routes.map((route, index) => ( + route.import)} /> + ))} + + + +
+
); diff --git a/web/src/localization/index.tsx b/web/src/localization/index.tsx deleted file mode 100644 index 777017b0f..000000000 --- a/web/src/localization/index.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint sort-imports:off */ -import PropTypes from "prop-types"; -import { FC } from "react"; -import { IntlProvider } from "react-intl"; -import { useSelector } from "react-redux"; -import { StateInterface } from "src/apps/main/redux"; - -import ar from "./locals/ar"; -import en from "./locals/en"; - -export const Localization: FC = (props) => { - const locals: { [key: string]: Record } = { ar, en }; - - const { settings } = useSelector((state) => state); - - return ( - - {props.children} - - ); -}; - -Localization.propTypes = { - children: PropTypes.node.isRequired, -}; - -export default Localization; diff --git a/web/src/localization/locals/fr.ts b/web/src/localization/locals/fr.ts deleted file mode 100644 index 207119e34..000000000 --- a/web/src/localization/locals/fr.ts +++ /dev/null @@ -1,32 +0,0 @@ -const message: { [key: string]: string } = { - and: "and", - "articles.path": "Articles", - "contribute.path": "Contribuer", - "faq.header.title": "Questions fréquemment posées", - "faq.need.help": "Still need help? send us an email at {link}", - "faq.path": "FAQ", - "footer.contact.info": "Contact Information", - "landing.button.contribute": "Make a Contribution", - "landing.header.body": - "Whether you are a maintainer or an open-source enthusiast DzCode helps you", - "landing.header.body.contribute": "contribute", - "landing.header.body.desc": "open-source projects that solve Algerian problems.", - "landing.header.body.find": "find", - "landing.header.body.list": "list", - "landing.header.h": "Algerian Open Source Community", - "landing.mobile.desc": - "Meet the DzCode i/o Mobile App and Stay up-to-date with state of dz open-source on iOS and Android", - "landing.mobile.h": "Going Mobile", - "landing.more.articles": "Explore More Articles", - "landing.more.projects": "See More Projects", - "landing.question": "Have a question ?", - "landing.read.articles.desc": "Read awesome articles, written by Algerian Developers", - "landing.read.articles.h": "Read Community Articles", - "landing.top.projects.desc": "Find, Use and Improve solutions written by Algerians for Algerians", - "landing.top.projects.h": "Top Community Projects", - "learn.path": "Apprendre", - "projects.path": "Projets", - "team.path": "Équipe", -}; - -export default message; diff --git a/yarn.lock b/yarn.lock index f7786a9e5..751a0057e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1816,76 +1816,6 @@ resolved "https://registry.yarnpkg.com/@fontsource/roboto/-/roboto-4.5.1.tgz#63f7b783f755d8f6727eb60198627e7e1be3ac20" integrity sha512-3mhfL+eNPG/woMNqwD/OHaW5qMpeGEBsDwzmhFmjB1yUV+M+M9P0NhP/AyHvnGz3DrqkvZ7CPzNMa+UkVLeELg== -"@formatjs/ecma402-abstract@1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.10.0.tgz#f51b9167535c9463113c24644de90262aa5d31a7" - integrity sha512-WNkcUHC6xw12rWY87TUw6KXzb1LnOooYBLLqtyn1kW2j197rcwpqmUOJMBED56YcLzaJPfVw1L2ShiDhL5pVnQ== - dependencies: - "@formatjs/intl-localematcher" "0.2.21" - tslib "^2.1.0" - -"@formatjs/fast-memoize@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-1.2.0.tgz#1123bfcc5d21d761f15d8b1c32d10e1b6530355d" - integrity sha512-fObitP9Tlc31SKrPHgkPgQpGo4+4yXfQQITTCNH8AZdEqB7Mq4nPrjpUL/tNGN3lEeJcFxDbi0haX8HM7QvQ8w== - dependencies: - tslib "^2.1.0" - -"@formatjs/icu-messageformat-parser@2.0.14": - version "2.0.14" - resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.0.14.tgz#d794af24e4896f4d2b400e28c25b1ba72604c106" - integrity sha512-M79MdUMLnfLK8eMrznUwke6afH9G/eOQeYvMUJ7uElXIL+//PyyjOzb42hAYfDAGYsAcKA2TsUo33Yuy2lE4AQ== - dependencies: - "@formatjs/ecma402-abstract" "1.10.0" - "@formatjs/icu-skeleton-parser" "1.3.1" - tslib "^2.1.0" - -"@formatjs/icu-skeleton-parser@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.1.tgz#02ad3209cb518096b830582068a322fee050adcf" - integrity sha512-WdPNjhv9e7EfyrIVYk6hN6/mC9YF+PcfFViDI2kATwoi1uKHr+AkQCMoNrWyCDdUQ+Dn50mQOlrEkCBXoLrkPQ== - dependencies: - "@formatjs/ecma402-abstract" "1.10.0" - tslib "^2.1.0" - -"@formatjs/intl-displaynames@5.2.5": - version "5.2.5" - resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-5.2.5.tgz#c8cb4983a3ce3bdc18d11e22cffc7dad9ceb3050" - integrity sha512-iYlce/hG31ohJOwpv3yhOiEIwEBMqOt2kzA2BQTx1ra8ferBn4WlTxkouoDNiAKEBD1LFYZBIC25jsSJUJOEbg== - dependencies: - "@formatjs/ecma402-abstract" "1.10.0" - "@formatjs/intl-localematcher" "0.2.21" - tslib "^2.1.0" - -"@formatjs/intl-listformat@6.3.5": - version "6.3.5" - resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-6.3.5.tgz#9631b6853e3b6cdedff371e132b310d259a6410f" - integrity sha512-GtiMMx5RB/gID7ydGr+i1lRbGu728plTfT196X151cE2PYEqC05BEuHQFlE1rcUGC2+RfFqlvmipYcbOqJTQug== - dependencies: - "@formatjs/ecma402-abstract" "1.10.0" - "@formatjs/intl-localematcher" "0.2.21" - tslib "^2.1.0" - -"@formatjs/intl-localematcher@0.2.21": - version "0.2.21" - resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.2.21.tgz#39ef33d701fe8084f3d693cd3ff7cbe03cdd3a49" - integrity sha512-JTJeLiNwexN4Gy0cMxoUPvJbKhXdnSuo5jPrDafEZpnDWlJ5VDYta8zUVVozO/pwzEmFVHEUpgiEDj+39L4oMg== - dependencies: - tslib "^2.1.0" - -"@formatjs/intl@1.16.0": - version "1.16.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-1.16.0.tgz#118388adc0566532d8739039f64d288ef12b1665" - integrity sha512-LdOAHbg6FJz6mV5SQBMyB8D6/qHoatdoG2eke2Z2uVIFG4kgIG9ytJ4bVQ+5UMrn06StR3T5XxDKV7gg9nR6Ng== - dependencies: - "@formatjs/ecma402-abstract" "1.10.0" - "@formatjs/fast-memoize" "1.2.0" - "@formatjs/icu-messageformat-parser" "2.0.14" - "@formatjs/intl-displaynames" "5.2.5" - "@formatjs/intl-listformat" "6.3.5" - intl-messageformat "9.9.6" - tslib "^2.1.0" - "@gar/promisify@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210" @@ -4197,7 +4127,7 @@ resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.9.tgz#1cfb6d60ef3822c589f18e70f8b12f9a28ce8724" integrity sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ== -"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1": +"@types/hoist-non-react-statics@^3.3.0": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== @@ -4450,7 +4380,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@16 || 17", "@types/react@^17.0.0", "@types/react@^17.0.1", "@types/react@~17.0.21": +"@types/react@*", "@types/react@^17.0.0", "@types/react@^17.0.1", "@types/react@~17.0.21": version "17.0.47" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.47.tgz#4ee71aaf4c5a9e290e03aa4d0d313c5d666b3b78" integrity sha512-mk0BL8zBinf2ozNr3qPnlu1oyVTYq+4V7WA76RgxUAtf0Em/Wbid38KN6n4abEkvO4xMTBWmnP1FtQzgkEiJoA== @@ -6722,7 +6652,7 @@ chainsaw@~0.1.0: dependencies: traverse ">=0.3.0 <0.4" -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -12000,15 +11930,6 @@ interpret@^2.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -intl-messageformat@9.9.6: - version "9.9.6" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.9.6.tgz#d76e0ebbef7ae71c16b8b4328bf780180a5a1250" - integrity sha512-xgoBydnw9zGUtgCiUcxNTzrRLzAbBIgWyKvMjL2jFNCx7H0148GGQWNVOpoiON5SlcFr8lyMWdbb0m+HjydanQ== - dependencies: - "@formatjs/fast-memoize" "1.2.0" - "@formatjs/icu-messageformat-parser" "2.0.14" - tslib "^2.1.0" - invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -13433,13 +13354,6 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -18458,32 +18372,6 @@ react-error-overlay@^6.0.9: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== -react-intl-translations-manager@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/react-intl-translations-manager/-/react-intl-translations-manager-5.0.3.tgz#aee010ecf35975673e033ca5d7d3f4147894324d" - integrity sha512-EfBeugnOGFcdUbQyY9TqBMbuauQ8wm73ZqFr0UqCljhbXl7YDHQcVzclWFRkVmlUffzxitLQFhAZEVVeRNQSwA== - dependencies: - chalk "^2.3.2" - glob "^7.1.2" - json-stable-stringify "^1.0.1" - mkdirp "^0.5.1" - -react-intl@^5.20.6: - version "5.22.0" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-5.22.0.tgz#52c76bf551399257b95315a8bce307182ba786c8" - integrity sha512-+nsRkeIYRI+S2aZKxeJZ9iZFJj8I6KOMPBegZX4LWo0eLyeLrIhbrD/aceg+n/eQZMEq8AMW0n3oXrh62Q/jNg== - dependencies: - "@formatjs/ecma402-abstract" "1.10.0" - "@formatjs/icu-messageformat-parser" "2.0.14" - "@formatjs/intl" "1.16.0" - "@formatjs/intl-displaynames" "5.2.5" - "@formatjs/intl-listformat" "6.3.5" - "@types/hoist-non-react-statics" "^3.3.1" - "@types/react" "16 || 17" - hoist-non-react-statics "^3.3.2" - intl-messageformat "9.9.6" - tslib "^2.1.0" - "react-is@^16.12.0 || ^17.0.0", "react-is@^16.8.0 || ^17.0.0", react-is@^17.0.1, react-is@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" From 038437971980fa3b58dc159db2c294612842b5c6 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 5 Aug 2022 21:35:34 +0200 Subject: [PATCH 03/10] added translation component factory --- packages/ui/src/translation-factory/index.tsx | 47 +++++++++++++++++++ web/src/apps/main/components/t/dictionary.ts | 4 ++ web/src/apps/main/components/t/index.ts | 14 ++++++ 3 files changed, 65 insertions(+) create mode 100644 packages/ui/src/translation-factory/index.tsx create mode 100644 web/src/apps/main/components/t/dictionary.ts create mode 100644 web/src/apps/main/components/t/index.ts diff --git a/packages/ui/src/translation-factory/index.tsx b/packages/ui/src/translation-factory/index.tsx new file mode 100644 index 000000000..92705a49b --- /dev/null +++ b/packages/ui/src/translation-factory/index.tsx @@ -0,0 +1,47 @@ +import type { VFC } from "react"; + +type BaseDictionary = Record>; + +export const translationFactory = + ( + dictionary: T, + getLanguageCode: () => keyof T[keyof T], + fallbackText = "MISSING_TRANSLATION", + ): VFC< + Partial> & { + k?: keyof T; + r?: Record; + } + > => + // eslint-disable-next-line react/display-name + ({ k, r = {}, ...props }) => { + const languageCode = getLanguageCode(); + const key = (k as keyof T) || (Object.keys(props)[0] as keyof T); + return <>{replace(dictionary, languageCode, fallbackText, key, r)}; + }; + +export const translationFunctionFactory = + >>( + dictionary: T, + getLanguageCode: () => keyof T[keyof T], + fallbackText?: string, + ): ((k: keyof T, r?: Record) => string) => + (k, r = {}) => { + const languageCode = getLanguageCode(); + return replace(dictionary, languageCode, fallbackText, k, r); + }; + +const replace = ( + dictionary: T, + languageCode: keyof T[keyof T], + fallbackText = "MISSING_TRANSLATION", + k: keyof T, + r: Record = {}, +) => { + const key = k; + let value = dictionary[key]?.[languageCode] || fallbackText; + Object.keys(r).forEach((rKey: keyof typeof r) => { + value = value.replace(RegExp(`${rKey}`), r[rKey]); + }); + return value; +}; diff --git a/web/src/apps/main/components/t/dictionary.ts b/web/src/apps/main/components/t/dictionary.ts new file mode 100644 index 000000000..27caeafb0 --- /dev/null +++ b/web/src/apps/main/components/t/dictionary.ts @@ -0,0 +1,4 @@ +export type DictionaryKeys = keyof typeof dictionary & + (`${G}-${string}` | `${G}`); + +export const dictionary = {}; diff --git a/web/src/apps/main/components/t/index.ts b/web/src/apps/main/components/t/index.ts new file mode 100644 index 000000000..b76766e85 --- /dev/null +++ b/web/src/apps/main/components/t/index.ts @@ -0,0 +1,14 @@ +import { + translationFactory, + translationFunctionFactory, +} from "@dzcode.io/ui/dist/translation-factory"; + +import { mainStore } from "../../redux"; +import { dictionary } from "./dictionary"; + +export const T = translationFactory(dictionary, () => mainStore.getState().settings.language.code); + +export const t = translationFunctionFactory( + dictionary, + () => mainStore.getState().settings.language.code, +); From 359996d550be5c50298b46369b7af39326d9f855 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 5 Aug 2022 21:37:41 +0200 Subject: [PATCH 04/10] made @ui components locale agnostic --- .../dialog/__snapshots__/index.test.tsx.snap | 0 .../dialog/index.test.tsx | 22 ++++---- .../{ => contributor-card}/dialog/index.tsx | 50 +++++-------------- .../ui/src/contributor-card/index.test.tsx | 16 +++++- packages/ui/src/contributor-card/index.tsx | 21 ++++++-- packages/ui/src/faq-card/index.tsx | 2 +- 6 files changed, 54 insertions(+), 57 deletions(-) rename packages/ui/src/{ => contributor-card}/dialog/__snapshots__/index.test.tsx.snap (100%) rename packages/ui/src/{ => contributor-card}/dialog/index.test.tsx (71%) rename packages/ui/src/{ => contributor-card}/dialog/index.tsx (67%) diff --git a/packages/ui/src/dialog/__snapshots__/index.test.tsx.snap b/packages/ui/src/contributor-card/dialog/__snapshots__/index.test.tsx.snap similarity index 100% rename from packages/ui/src/dialog/__snapshots__/index.test.tsx.snap rename to packages/ui/src/contributor-card/dialog/__snapshots__/index.test.tsx.snap diff --git a/packages/ui/src/dialog/index.test.tsx b/packages/ui/src/contributor-card/dialog/index.test.tsx similarity index 71% rename from packages/ui/src/dialog/index.test.tsx rename to packages/ui/src/contributor-card/dialog/index.test.tsx index 908898aa2..79f52c15b 100644 --- a/packages/ui/src/dialog/index.test.tsx +++ b/packages/ui/src/contributor-card/dialog/index.test.tsx @@ -1,16 +1,16 @@ import { render, screen } from "@testing-library/react"; -import { createProjects } from "../__mocks__/create-projects"; -import { createRepositories } from "../__mocks__/create-repositories"; -import { ContributionsDialog } from "."; +import { createProjects } from "../../__mocks__/create-projects"; +import { createRepositories } from "../../__mocks__/create-repositories"; +import { ContributionsDialog, ContributionsDialogProps } from "."; it("should render a closed dialog on first mount", async () => { const onClose = jest.fn(); - const props = { + const props: ContributionsDialogProps = { onClose: onClose, open: false, - projects: createProjects(2), repositories: createRepositories(2), + repositoriesText: "Repositories", }; const { container } = render(); @@ -19,11 +19,11 @@ it("should render a closed dialog on first mount", async () => { it("should handle users with no projects", async () => { const onClose = jest.fn(); - const props = { + const props: ContributionsDialogProps = { onClose: onClose, open: true, - projects: [], repositories: createRepositories(2), + repositoriesText: "Repositories", }; render(); @@ -33,11 +33,11 @@ it("should handle users with no projects", async () => { it("should handle users with no repositories", async () => { const onClose = jest.fn(); - const props = { + const props: ContributionsDialogProps = { onClose: onClose, open: true, - projects: createProjects(2), repositories: [], + repositoriesText: "Repositories", }; render(); @@ -47,11 +47,11 @@ it("should handle users with no repositories", async () => { it("should render a dialog", async () => { const onClose = jest.fn(); - const props = { + const props: ContributionsDialogProps = { onClose: onClose, open: true, - projects: createProjects(2), repositories: createRepositories(2), + repositoriesText: "Repositories", }; render(); diff --git a/packages/ui/src/dialog/index.tsx b/packages/ui/src/contributor-card/dialog/index.tsx similarity index 67% rename from packages/ui/src/dialog/index.tsx rename to packages/ui/src/contributor-card/dialog/index.tsx index 135e7e211..54b683021 100644 --- a/packages/ui/src/dialog/index.tsx +++ b/packages/ui/src/contributor-card/dialog/index.tsx @@ -8,6 +8,7 @@ import ListItem from "@mui/material/ListItem"; import ListItemAvatar from "@mui/material/ListItemAvatar"; import ListItemText from "@mui/material/ListItemText"; import Typography from "@mui/material/Typography"; +import { FC } from "react"; interface ContributionItemProps { description: string; @@ -36,7 +37,7 @@ interface ContributionListProps { const ContributionList = ({ title, items }: ContributionListProps) => { return ( <> - + {title} @@ -48,66 +49,39 @@ const ContributionList = ({ title, items }: ContributionListProps) => { }; export interface ContributionsDialogProps { + repositoriesText: string; open: boolean; - projects?: Array<{ - slug: string; - image?: string; - title: string; - description?: string; - content?: string; - authors?: string[]; - contributors?: string[]; - views?: number; - githubURI?: string; - }>; repositories?: { provider: string; owner: string; repository: string }[]; onClose: () => void; } -export function ContributionsDialog(props: ContributionsDialogProps) { - const { onClose, open, projects, repositories } = props; - - const handleClose = () => { - onClose(); - }; - +export const ContributionsDialog: FC = ({ + onClose, + open, + repositories, + repositoriesText, +}) => { return ( - - - Contributions - - {repositories && repositories.length > 0 && ( ({ label: repository.repository, }))} /> )} - - {projects && projects.length > 0 && ( - ({ label: project.title }))} - /> - )} - ); -} +}; diff --git a/packages/ui/src/contributor-card/index.test.tsx b/packages/ui/src/contributor-card/index.test.tsx index 188e242d7..094fc16c2 100644 --- a/packages/ui/src/contributor-card/index.test.tsx +++ b/packages/ui/src/contributor-card/index.test.tsx @@ -13,7 +13,13 @@ it("should render a contributor skeleton ", async () => { it("should render a contributor card", () => { const contributor = createContributors(1)[0]; - render(); + render( + , + ); const username = screen.getByText(contributor.username); expect(username).toBeInTheDocument(); @@ -21,7 +27,13 @@ it("should render a contributor card", () => { it("should show contributions dialog after Contributions button is clicked", async () => { const contributor = createContributors(1)[0]; - render(); + render( + , + ); const button = await screen.findByRole("button", { name: "Contributions" }); userEvent.click(button); diff --git a/packages/ui/src/contributor-card/index.tsx b/packages/ui/src/contributor-card/index.tsx index 05df6b2a5..ad14dc617 100644 --- a/packages/ui/src/contributor-card/index.tsx +++ b/packages/ui/src/contributor-card/index.tsx @@ -9,7 +9,7 @@ import Skeleton from "@mui/material/Skeleton"; import Typography from "@mui/material/Typography"; import { FC, useState } from "react"; -import { ContributionsDialog } from "../dialog"; +import { ContributionsDialog } from "./dialog"; const styles = { root: { @@ -41,11 +41,17 @@ export const ContributorSkeleton = () => { ); }; -interface ContributorCardProps { +export interface ContributorCardProps { + ctaText: string; + repositoriesText: string; contributor: ContributorEntity; } -export const ContributorCard: FC = ({ contributor }) => { +export const ContributorCard: FC = ({ + contributor, + ctaText, + repositoriesText, +}) => { const [open, setOpen] = useState(false); const { avatarUrl, username, repositories } = contributor; return ( @@ -64,10 +70,15 @@ export const ContributorCard: FC = ({ contributor }) => { fullWidth variant="contained" > - Contributions + {ctaText} - setOpen(false)} /> + setOpen(false)} + /> ); }; diff --git a/packages/ui/src/faq-card/index.tsx b/packages/ui/src/faq-card/index.tsx index aae9f48c5..d322bfe3b 100644 --- a/packages/ui/src/faq-card/index.tsx +++ b/packages/ui/src/faq-card/index.tsx @@ -24,7 +24,7 @@ export const FaqCard = ({ title, questions }: FaqCardProps) => { {questions.map(({ question, answer }, index) => ( - + }> {question} From 294eb72555eef6f335766153e95fce624035fc39 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 5 Aug 2022 21:40:13 +0200 Subject: [PATCH 05/10] localized all components --- web/src/apps/main/components/card/index.tsx | 2 +- .../footer/__snapshots__/footer.spec.tsx.snap | 9 +- .../main/components/footer/footer.spec.tsx | 5 +- web/src/apps/main/components/footer/index.tsx | 51 ++-- .../apps/main/components/markdown/index.tsx | 7 +- web/src/apps/main/components/navbar/index.tsx | 27 +- web/src/apps/main/components/t/dictionary.ts | 281 +++++++++++++++++- 7 files changed, 324 insertions(+), 58 deletions(-) diff --git a/web/src/apps/main/components/card/index.tsx b/web/src/apps/main/components/card/index.tsx index 4682f1019..0917e69cc 100644 --- a/web/src/apps/main/components/card/index.tsx +++ b/web/src/apps/main/components/card/index.tsx @@ -47,7 +47,7 @@ export const Card: FC = ({ info }) => { {info ? ( <> - + {info.title} diff --git a/web/src/apps/main/components/footer/__snapshots__/footer.spec.tsx.snap b/web/src/apps/main/components/footer/__snapshots__/footer.spec.tsx.snap index e2cba5cc8..7103d6b64 100644 --- a/web/src/apps/main/components/footer/__snapshots__/footer.spec.tsx.snap +++ b/web/src/apps/main/components/footer/__snapshots__/footer.spec.tsx.snap @@ -183,13 +183,14 @@ exports[`components/footer/footer.spec.tsx should render properly 1`] = `
- Contact Information + FAQ

+213 06-76-26-11-57

@@ -206,10 +207,12 @@ exports[`components/footer/footer.spec.tsx should render properly 1`] = `

- Copyright © - 2020 + Copyright © + + 2022 @dzCode_io diff --git a/web/src/apps/main/components/footer/footer.spec.tsx b/web/src/apps/main/components/footer/footer.spec.tsx index 219c84b3a..09019fedc 100644 --- a/web/src/apps/main/components/footer/footer.spec.tsx +++ b/web/src/apps/main/components/footer/footer.spec.tsx @@ -1,5 +1,4 @@ import { render } from "@testing-library/react"; -import { IntlProvider } from "react-intl"; import { Provider } from "react-redux"; import { BrowserRouter as Router } from "react-router-dom"; import { createMainStore } from "src/apps/main/redux"; @@ -13,9 +12,7 @@ describe("components/footer/footer.spec.tsx", () => { const { container } = render( - -

- +
, ); diff --git a/web/src/apps/main/components/footer/index.tsx b/web/src/apps/main/components/footer/index.tsx index 95efcd4e1..e6123689b 100644 --- a/web/src/apps/main/components/footer/index.tsx +++ b/web/src/apps/main/components/footer/index.tsx @@ -1,11 +1,10 @@ import Container from "@material-ui/core/Container"; import Grid from "@material-ui/core/Grid"; -import makeStyles from "@material-ui/core/styles/makeStyles"; +import { makeStyles } from "@material-ui/core/styles"; import Typography from "@material-ui/core/Typography"; import { FC } from "react"; -import { FormattedMessage } from "react-intl"; -import { useIntl } from "react-intl"; import { useSelector } from "react-redux"; +import { T } from "src/apps/main/components/t"; import { StateInterface } from "src/apps/main/redux"; import { FooterComponentState } from "src/apps/main/redux/reducers/footer-component"; import { LinkV2 } from "src/components/link-v2"; @@ -34,7 +33,7 @@ const useStyles = makeStyles((theme) => ({ export const Footer: FC = () => { const classes = useStyles(); - const intl = useIntl(); + const { sections } = useSelector( (state: StateInterface) => state.footerComponent, ); @@ -48,31 +47,13 @@ export const Footer: FC = () => { sections.map((category, i) => ( - {intl.formatMessage({ - id: `footer.${category.title.toLowerCase().replace(" ", ".")}`, - defaultMessage: category.title, - })} + {category.links.map((link, i) => { return ( - + - {link.id - ? intl.formatMessage({ - id: link.id.replace("-", ".") || link.text.replace(" ", "."), - defaultMessage: link.text, - }) - : link.text} + ); @@ -82,17 +63,27 @@ export const Footer: FC = () => { - + - +213 06-76-26-11-57 + + {"+213 06-76-26-11-57"} + - contact@dzcode.io + {"contact@dzcode.io"} - Copyright © {new Date(Date.now()).getFullYear() + " "} - @dzCode_io + {new Date().getFullYear() + " "} + + {"@dzCode_io"} + diff --git a/web/src/apps/main/components/markdown/index.tsx b/web/src/apps/main/components/markdown/index.tsx index acc175929..98067e0a4 100644 --- a/web/src/apps/main/components/markdown/index.tsx +++ b/web/src/apps/main/components/markdown/index.tsx @@ -9,7 +9,7 @@ import tomorrow from "react-syntax-highlighter/dist/cjs/styles/prism/tomorrow"; import { StateInterface } from "src/apps/main/redux"; import { LinkV2 } from "src/components/link-v2"; -export const Markdown: FC = (markdownProps) => { +export const Markdown: FC = ({ children, t, ...markdownProps }) => { const theme = useTheme(); const darkMode = useSelector((state) => state.settings.darkMode); @@ -69,12 +69,13 @@ export const Markdown: FC = (markdownProps) => { }, }, }} - /> + children={t || (children as string)} // eslint-disable-line react/no-children-prop + > ); }; interface ReactMarkdown { [key: string]: unknown; - children: string; + t?: string; options?: MarkdownToJSX.Options; } diff --git a/web/src/apps/main/components/navbar/index.tsx b/web/src/apps/main/components/navbar/index.tsx index e7cbe3824..fa79fc6b2 100644 --- a/web/src/apps/main/components/navbar/index.tsx +++ b/web/src/apps/main/components/navbar/index.tsx @@ -8,10 +8,9 @@ import Toolbar from "@material-ui/core/Toolbar"; import Typography from "@material-ui/core/Typography"; import { useScrollPosition } from "@n8tb1t/use-scroll-position"; import { FC, Fragment, useState } from "react"; -import { FormattedMessage } from "react-intl"; -import { useIntl } from "react-intl"; import { useDispatch, useSelector } from "react-redux"; import { animated, useSpring } from "react-spring"; +import { T } from "src/apps/main/components/t"; import { Dispatch, StateInterface } from "src/apps/main/redux"; import { SettingsState } from "src/apps/main/redux/reducers/settings"; import logo from "src/assets/svg/logo-wide.svg"; @@ -67,7 +66,7 @@ const useStyles = makeStyles((theme) => borderBottom: `1px solid ${theme.palette.background.paper}`, }, toolbarTitle: { - marginRight: "auto", + flex: 1, }, toolbarVersion: { margin: "auto 1rem", @@ -104,7 +103,7 @@ const useStyles = makeStyles((theme) => logo: { display: "flex", alignItems: "center", - justifyContent: "center", + justifyContent: "start", height: "100%", }, logoImg: { @@ -118,13 +117,13 @@ const useStyles = makeStyles((theme) => ); export const Navbar: FC = () => { - const { settings, navbarComponent } = useSelector( - (state) => state, - ); + const { + settings, + navbarComponent: { sections }, + } = useSelector((state) => state); const dispatch = useDispatch>(); const classes = useStyles(); - const intl = useIntl(); const [visible, setVisible] = useState(true); useScrollPosition(({ prevPos, currPos }) => { const isVisible = currPos.y <= -120 ? currPos.y > prevPos.y : true; @@ -203,18 +202,14 @@ export const Navbar: FC = () => { - {navbarComponent.sections - ? navbarComponent.sections.map((section, index) => ( + {sections + ? sections.map((section, index) => ( {index > 0 && ( )} - - + + )) diff --git a/web/src/apps/main/components/t/dictionary.ts b/web/src/apps/main/components/t/dictionary.ts index 27caeafb0..ed290c2af 100644 --- a/web/src/apps/main/components/t/dictionary.ts +++ b/web/src/apps/main/components/t/dictionary.ts @@ -1,4 +1,283 @@ export type DictionaryKeys = keyof typeof dictionary & (`${G}-${string}` | `${G}`); -export const dictionary = {}; +export const dictionary = { + "navbar-section-contribute": { en: "Contribute", ar: "اساهم" }, + "navbar-section-connect": { en: "Connect", ar: "اتواصل" }, + "navbar-section-learn": { en: "Learn", ar: "اتعلم" }, + "navbar-section-projects": { en: "Projects", ar: "مشاريع" }, + "navbar-section-articles": { en: "Articles", ar: "مقالات" }, + "navbar-section-faq": { en: "FAQ", ar: "اسئلة / اجوبة" }, + + "footer-category-title-helpful-links": { + en: "Helpful Links", + ar: "روابط مفيدة", + }, + "footer-category-link-text-home": { en: "Home", ar: "الصفحة الرئيسية" }, + "footer-category-link-text-learn": { en: "Learn", ar: "اتعلم" }, + "footer-category-link-text-projects": { en: "Projects", ar: "مشاريع" }, + "footer-category-link-text-articles": { en: "Articles", ar: "مقالات" }, + "footer-category-link-text-faq": { en: "FAQ", ar: "اسئلة / اجوبة" }, + "footer-category-title-mobile": { en: "Mobile", ar: "تطبيق جوال" }, + "footer-category-link-text-android": { en: "Android", ar: "أندرويد" }, + "footer-category-link-text-ios": { en: "iOS", ar: "ايفون" }, + "footer-category-link-text-expo": { en: "Expo", ar: "اكسبو" }, + "footer-category-title-social-media": { + en: "Social Media", + ar: "وسائل التواصل الاجتماعي", + }, + "footer-category-link-text-github": { en: "Github", ar: "جيتهاب" }, + "footer-category-link-text-slack": { en: "Slack", ar: "سلاك" }, + "footer-category-link-text-facebook": { en: "Facebook", ar: "فيسبوك" }, + "footer-category-link-text-instagram": { en: "Instagram", ar: "انستغرام" }, + "footer-category-link-text-youTube": { en: "YouTube", ar: "يوتيوب" }, + "footer-category-link-text-twitter": { en: "Twitter", ar: "تويتر" }, + "footer-category-link-text-linkedIn": { en: "LinkedIn", ar: "لينكد إن" }, + "footer-contact-information": { en: "FAQ", ar: "اسئلة / اجوبة" }, + "footer-category-link-text-copyright": { + en: "Copyright ©", + ar: "حقوق النشر ©", + }, + + "faq-title": { en: "Frequently Asked Questions", ar: "اللاسئلة الاكثر طرحا" }, + "faq-need-help": { + en: "Still need help? send us an email at ", + ar: "هل ما زلت بحاجة إلى المساعدة؟ أرسل إلينا بريدًا إلكترونيًا على ", + }, + "faq-topic-1": { + en: "General", + ar: "اسئلة عامة", + }, + "faq-topic-1-question-1": { + en: "What exactly is DzCode i/o ?", + ar: "ما هو DzCode i/o بالضبط؟", + }, + "faq-topic-1-answer-1": { + en: `An open-source online community of Algerian developers, collaborating on solving Algerian technical problems.`, + ar: `مجتمع مفتوح المصدر على الإنترنت للمطورين الجزائريين ، يتعاونون في حل المشاكل التقنية الجزائرية.`, + }, + "faq-topic-1-question-2": { + en: "What are the goals of DzCode i/o ?", + ar: "ما هي أهداف DzCode i/o؟", + }, + "faq-topic-1-answer-2": { + en: ` +- Share our experiences (in form of [articles](/Articles)), there are many Algerian developers that accumulated lots of experiences, here comes dzcode.io to give them the chance to share these experiences with the right people. +- Guide new developers to build their careers (with some educational resources and [articles](/Learn)), and to understand the software market, instead of wasting their time on other resources they won't be needing. +- Fix some common Algerian software problems, in form of ready-to-use open-source [softwares](/Projects) (packages, libraries ...etc). +`, + ar: ` +- لمشاركة خبراتنا (في شكل [مقالات](/Articles)) ، هناك العديد من المطورين الجزائريين الذين جمعوا الكثير من الخبرات ، وهنا يأتي dzcode.io لمنحهم الفرصة لمشاركة هذه الخبرات مع الأشخاص المناسبين. +- توجيه المطورين الجدد لبناء حياتهم المهنية (ببعض الموارد و[المقالات التعليمية](/Learn)) ، وفهم سوق البرمجيات ، بدلاً من إضاعة وقتهم في موارد أخرى لن يحتاجوا إليها. +- إصلاح بعض مشاكل البرمجيات الجزائرية الشائعة ، على شكل [برامج](/Projects) مفتوحة المصدر جاهزة للاستخدام (حزم ، مكتبات ... إلخ). +`, + }, + "faq-topic-1-question-3": { + en: "What would I benefit from DzCode i/o?", + ar: "ما الذي سأستفيد منه من DzCode i/o؟", + }, + "faq-topic-1-answer-3": { + en: ` +- You will meet other Algerian developers, experienced and noobs, and there you can expand your professional network! +- You'll get to experience a professional environment, which is completely different than the one you used to in school, uni, or on YouTube 😄. +- Your contribution will be shown on your Github profile, and that is a big plus in your CV! +`, + ar: ` +- ستلتقي بمطورين جزائريين آخرين ، من ذوي الخبرة والمبتدئين ، وهناك يمكنك توسيع شبكتك المهنية! +- ستتمتع بتجربة بيئة احترافية مختلفة تمامًا عن تلك التي اعتدت عليها في المدرسة أو الجامعة أو على YouTube 😄. +- ستظهر مساهمتك في ملفك الشخصي على Github ، وهذه إضافة كبيرة في سيرتك الذاتية! +`, + }, + "faq-topic-2": { + en: "Participation", + ar: "المشاركة", + }, + "faq-topic-2-question-1": { + en: "How do I join DzCode i/o ?", + ar: "كيف أنضم إلى DzCode i / o؟", + }, + "faq-topic-2-answer-1": { + en: `We're most active in slack, we recommend you [join us there](https://join.slack.com/t/dzcode/shared_invite/zt-ek9kscb7-m8z_~cBjX79l~uchuABPFQ).`, + ar: `نحن أكثر نشاطًا في Slack ، نوصيك [بالانضمام إلينا هناك](https://join.slack.com/t/dzcode/shared_invite/zt-ek9kscb7-m8z_~cBjX79l~uchuABPFQ)`, + }, + "faq-topic-2-question-2": { + en: "I want to code, where should I start?", + ar: "أرغب في البرمجة ، من أين أبدأ؟", + }, + "faq-topic-2-answer-2": { + en: `Go to [/Contribute](/Contribute) page, you will see a list of projects with available tasks for you to pick from whatever you like and start programming 🔥.`, + ar: `انتقل إلى صفحة [المساهمة](/Contribute) ، سترى قائمة بالمشاريع بالمهام المتاحة لتختار منها ما تريد وتبدأ البرمجة 🔥.`, + }, + "faq-topic-2-question-3": { + en: "I like the idea, what are the different ways I can contribute to DzCode i/o ?", + ar: "تعجبني الفكرة ، ما هي الطرق المختلفة التي يمكنني من خلالها المساهمة في DzCode i/o؟", + }, + "faq-topic-2-answer-3": { + en: ` +Besides the open tasks on [/Contribute](/Contribute) page, you can also contribute to DzCode i/o by: + +- Adding your open-source projects to the dzcode.io website, you can do that [here](/Learn/About_dzcode_io/Add_Your_Project_To_dzcode_io). +- Writing about your programming experience in form of articles, to do that, simply follow [these simple steps](/Learn/About_dzcode_io/Add_Your_Article_To_dzcode_io). +`, + ar: ` +إلى جانب المهام المفتوحة في صفحة المساهمة ، يمكنك أيضًا المساهمة في DzCode i / o عن طريق: + +- إضافة مشاريعك مفتوحة المصدر إلى موقع dzcode.io ، يمكنك القيام بذلك [هنا](/Learn/About_dzcode_io/Add_Your_Project_To_dzcode_io). +- الكتابة عن التجربة البرمجة الخاصة بك في شكل مقالات ، للقيام بذلك ، ما عليك سوى اتباع [هذه الخطوات البسيطة](/Learn/About_dzcode_io/Add_Your_Article_To_dzcode_io). +`, + }, + "faq-topic-3": { + en: "Articles", + ar: "مقالات", + }, + "faq-topic-3-question-1": { + en: "How to write an article in dzcode.io", + ar: "كيفية كتابة مقال في dzcode.io", + }, + "faq-topic-3-answer-1": { + en: `Follow [these steps](/Learn/About_dzcode_io/Add_Your_Article_To_dzcode_io).`, + ar: `اتبع هذه [الخطوات](/Learn/About_dzcode_io/Add_Your_Article_To_dzcode_io).`, + }, + "faq-topic-3-question-2": { + en: "The articles should they be in English?", + ar: "هل يجب أن تكون المقالات باللغة الإنجليزية؟", + }, + "faq-topic-3-answer-2": { + en: `You can write in both English and Arabic`, + ar: `يمكنك الكتابة باللغتين الإنجليزية والعربية`, + }, + "faq-topic-3-question-3": { + en: "Can I write about anything?", + ar: "هل يمكنني الكتابة عن أي شيء؟", + }, + "faq-topic-3-answer-3": { + en: `As long as it's IT-related yes you can write about anything.`, + ar: `طالما أن الأمر يتعلق بتكنولوجيا المعلومات نعم يمكنك الكتابة عن أي شيء.`, + }, + "faq-topic-4": { + en: "Projects", + ar: "المشاريع", + }, + "faq-topic-4-question-1": { + en: "How to add my open-source project to dzcode.io", + ar: "كيفية إضافة مشروعي مفتوح المصدر إلى dzcode.io", + }, + "faq-topic-4-answer-1": { + en: `Follow [these steps](/Learn/About_dzcode_io/Add_Your_Project_To_dzcode_io).`, + ar: `اتبع هذه [الخطوات](/Learn/About_dzcode_io/Add_Your_Project_To_dzcode_io).`, + }, + "faq-topic-4-question-2": { + en: "What makes my project eligible to be added to dzcode.io", + ar: "ما الذي يجعل مشروعي مؤهلاً للإضافة إلى dzcode.io", + }, + "faq-topic-4-answer-2": { + en: `It has to solve an Algerian problem, or, be written by an Algerian Developer.`, + ar: `يجب أن تحل مشكلة جزائرية ، أو أن يكتبها مطور جزائري.`, + }, + "faq-topic-4-question-3": { + en: "Why should I add my project to dzcode.io?", + ar: "لماذا يجب علي إضافة مشروعي إلى dzcode.io؟", + }, + "faq-topic-4-answer-3": { + en: ` +- Your project will potentially get noticed by more Algerian developers. +- You will get potential contributions from other developers, which will eventually make your piece of software better. +`, + ar: ` +- من المحتمل أن يحظى مشروعك باهتمام المزيد من المطورين الجزائريين. +- ستحصل على مساهمات محتملة من مطورين آخرين ، مما سيجعل برنامجك في النهاية أفضل. +`, + }, + "landing-heading-title": { + en: `Open-Source Algerian Comunity`, + ar: `مجموعة جزائرية للبرامج مفتوحة المصدر`, + }, + "landing-heading-subtitle": { + en: `DzCode i/o helps you find, contribute and add to the list of open-source projects that solve Algerian problems.`, + ar: `يساعدك DzCode i / o في العثور على والمساهمة والإضافة إلى قائمة المشاريع مفتوحة المصدر التي تحل مشاكل الجزائر.`, + }, + "landing-cta-button": { + en: "Make a Contribution", + ar: "قدم مساهمة", + }, + "landing-help-button": { + en: "Do you have a question?", + ar: "هل لديك سؤال؟", + }, + "landing-mobile-title": { + en: "Try the mobile app from AppStore or PlayStore", + ar: "جرب تطبيق الهاتف المحمول من AppStore أو PlayStore", + }, + "landing-mobile-subtitle": { + en: "Meet the DzCode i/o mobile app and stay up-to-date with the state of Algerian open-source software on iOS and Android.", + ar: "تعرف على تطبيق DzCode i / o للجوال وابق على اطلاع دائم بأحدث البرامج مفتوحة المصدر الجزائرية على iOS و Android.", + }, + "team-error": { + en: "Oops, an error occurred while loading the articles list, please try again...", + ar: "عفوًا ، حدث خطأ أثناء تحميل قائمة المقالات ، يرجى المحاولة مرة أخرى ...", + }, + "team-try-again": { + en: "Try Again", + ar: "حاول مرة أخري", + }, + "team-title": { + en: "Get to know our team 💻", + ar: "تعرف على فريقنا 💻", + }, + "team-card-cta-button": { + en: "Contributions", + ar: "المساهمات", + }, + "team-card-repositories": { + en: "Repositories", + ar: "مستودعات", + }, + "projects-error": { + en: "Oops, an error occurred while loading the projects list, please try again...", + ar: "عفوًا ، حدث خطأ أثناء تحميل قائمة المشاريع ، يرجى المحاولة مرة أخرى ...", + }, + "projects-try-again": { + en: "Try Again", + ar: "حاول مرة أخري", + }, + "projects-title": { + en: "Open Source Projects", + ar: "مشاريع مفتوحة المصدر", + }, + "projects-card-cta-button": { + en: "Go to code", + ar: "إلى الكود", + }, + "notfound-subtitle": { + en: `Finally someone saw the 404 page Nour built 😄`, + ar: `أخيرًا شاهد شخص ما صفحة 404 التي أنشأتها نور 😄`, + }, + "notfound-back-home": { + en: "Go Back Home", + ar: "ارجع إلى الصفحة الرئيسية", + }, + "contribute-filter-projects": { + en: "Project", + ar: "المشروع", + }, + "contribute-filter-languages": { + en: "Programming Language", + ar: "لغة البرمجة", + }, + "contribute-filter-labels": { + en: "Label", + ar: "الوسم", + }, + "contribute-read-issue": { + en: "Learn more", + ar: "اقرأ المزيد", + }, + "contribute-review-changes": { + en: "Review changes", + ar: "مراجعة التغييرات", + }, + "elapsed-time-suffixes": { + en: "y|mo|d|h|min|Just now", + ar: " عام| شهر| يوم| ساعة| دقيقة| الآن", + }, +}; From c1e806d41b1834d9b2f63a50934a2a6d926c7dcc Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 5 Aug 2022 21:41:36 +0200 Subject: [PATCH 06/10] localized some pages --- .../pages/contribute/contributions/index.tsx | 24 +- .../main/pages/contribute/filters/index.tsx | 8 +- .../faq/__snapshots__/index.int.spec.tsx.snap | 218 +++++------------- .../apps/main/pages/faq/index.int.spec.tsx | 12 +- web/src/apps/main/pages/faq/index.tsx | 30 +-- web/src/apps/main/pages/not-found/index.tsx | 18 +- .../main/pages/projects/catalog/index.tsx | 6 +- web/src/apps/main/pages/projects/index.tsx | 7 +- .../apps/main/pages/team/catalog/index.tsx | 13 +- web/src/apps/main/pages/team/index.tsx | 5 +- .../main/redux/reducers/faq-page/faq-data.ts | 103 ++------- .../main/redux/reducers/faq-page/index.ts | 10 +- .../redux/reducers/footer-component/index.ts | 11 +- .../reducers/footer-component/sections.ts | 71 ++++-- .../redux/reducers/navbar-component/index.ts | 40 +--- 15 files changed, 218 insertions(+), 358 deletions(-) diff --git a/web/src/apps/main/pages/contribute/contributions/index.tsx b/web/src/apps/main/pages/contribute/contributions/index.tsx index 208a61c5f..d1c776248 100644 --- a/web/src/apps/main/pages/contribute/contributions/index.tsx +++ b/web/src/apps/main/pages/contribute/contributions/index.tsx @@ -14,9 +14,11 @@ import QuestionAnswerIcon from "@material-ui/icons/QuestionAnswer"; import Skeleton from "@material-ui/lab/Skeleton"; import { FC } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { t } from "src/apps/main/components/t"; import { Dispatch, StateInterface } from "src/apps/main/redux"; import { fetchContributions, updateFilterValue } from "src/apps/main/redux/actions/contribute-page"; import { ContributePageState } from "src/apps/main/redux/reducers/contribute-page"; +import { SettingsState } from "src/apps/main/redux/reducers/settings"; import { elapsedTime } from "src/common/utils/elapsed-time"; import { LinkV2 } from "src/components/link-v2"; @@ -36,6 +38,7 @@ const useStyles = makeStyles((theme) => ({ flex: "1", display: "flex", flexDirection: "column", + direction: "ltr", }, chip: { flex: "1", @@ -43,9 +46,6 @@ const useStyles = makeStyles((theme) => ({ marginTop: theme.spacing(1), marginRight: theme.spacing(1), }, - contribute: { - marginRight: "auto", - }, })); export const Contributions: FC = () => { @@ -53,6 +53,9 @@ export const Contributions: FC = () => { const { contributions } = useSelector( (state) => state.contributePage, ); + const { + language: { code: languageCode }, + } = useSelector((state) => state.settings); const dispatch = useDispatch>(); return ( @@ -104,17 +107,26 @@ export const Contributions: FC = () => { color: type === "issue" ? "#56d364" : "#a371f7", }} > - + - {elapsedTime(updatedAt)} + + {elapsedTime(updatedAt, t("elapsed-time-suffixes"))} + {commentsCount > 0 && ( diff --git a/web/src/apps/main/pages/contribute/filters/index.tsx b/web/src/apps/main/pages/contribute/filters/index.tsx index 1853ba188..4706af215 100644 --- a/web/src/apps/main/pages/contribute/filters/index.tsx +++ b/web/src/apps/main/pages/contribute/filters/index.tsx @@ -14,6 +14,8 @@ import SpeedDialIcon from "@material-ui/lab/SpeedDialIcon"; import { FC, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { SpeedDial } from "src/apps/main/components/speed-dial"; +import { t } from "src/apps/main/components/t"; +import type { DictionaryKeys } from "src/apps/main/components/t/dictionary"; import { Dispatch, StateInterface } from "src/apps/main/redux"; import { updateFilterValue } from "src/apps/main/redux/actions/contribute-page"; import { ContributePageState } from "src/apps/main/redux/reducers/contribute-page"; @@ -41,9 +43,11 @@ export const Filters: FC = () => { const theme = useTheme(); const md = useMediaQuery(theme.breakpoints.up("md")); const renderFilters = () => - filters.map(({ name: filterName, label: filterLabel, options }) => ( + filters.map(({ name: filterName, options }) => ( - }>{filterLabel} + }> + {t(`contribute-filter-${filterName}` as DictionaryKeys<"contribute-filter">)} + {options.map(({ label: optionLabel, name: optionName, checked }) => (
@@ -100,6 +101,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = `
- Articles + articles - ), there are many algerian developers that accumulated lots experiences, dzcode.io gives them the chance to share it with the right audience. + ), there are many Algerian developers that accumulated lots of experiences, here comes dzcode.io to give them the chance to share these experiences with the right people.
  • - Guide new developers to build their career (with detailed + Guide new developers to build their careers (with some educational resources and - documentation + articles - ), and understand the software market, instead of wasting their time on other useless resources. + ), and to understand the software market, instead of wasting their time on other resources they won't be needing.
  • - Fix some common algerian software problems, in form of ready to use open-source + Fix some common Algerian software problems, in form of ready-to-use open-source @@ -186,6 +188,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = `
  • -
    -

    - There are couple of benefits, to name few: -

    -
      -
    • - You will meet other algerian developers, experienced and juniors, where you can grow your network! -
    • -
    • - You'll get to experience a professional environment, which is completely different than the one you used to in school. -
    • -
    • - Your contribution will be shown on your Github profile, and that is a big plus in your professional career! -
    • -
    -
    -
    -
    -
    - - - -
    - -
    -
    - @@ -372,6 +278,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = ` > @@ -516,6 +412,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = `
    - Apart from checking out the + Besides the open tasks on @@ -579,7 +476,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = `

    • - Adding your open-source projects to dzcode.io website, you can do that + Adding your open-source projects to the dzcode.io website, you can do that @@ -588,11 +485,11 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = ` .
    • - Writing about your experience in form of articles, it's as easy as following the steps + Writing about your programming experience in form of articles, to do that, simply follow - here + these simple steps .
    • @@ -627,6 +524,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = ` >
      - Yes, to reach a wide range of audience we will add a feature to allow article localization and multiple language articles in the future. + You can write in both English and Arabic
      @@ -753,6 +652,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = `
      - As long as its IT related yes you can write about anything. + As long as it's IT-related yes you can write about anything.
      @@ -834,6 +734,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = ` >
      @@ -960,6 +862,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = `
      • - Your project will potentially get noticed by more algerian developers. + Your project will potentially get noticed by more Algerian developers.
      • - You will get potential contribution from other DZ developers, and eventually better shape your piece of software. + You will get potential contributions from other developers, which will eventually make your piece of software better.
      @@ -1035,6 +938,7 @@ exports[`src/pages/landing/index.tsx Render FAQ page 1`] = ` class="MuiTypography-root MuiTypography-h6 muiltr-1kgxqm0-MuiTypography-root" > Still need help? send us an email at + diff --git a/web/src/apps/main/pages/faq/index.int.spec.tsx b/web/src/apps/main/pages/faq/index.int.spec.tsx index 9efff6388..95d95dd8b 100644 --- a/web/src/apps/main/pages/faq/index.int.spec.tsx +++ b/web/src/apps/main/pages/faq/index.int.spec.tsx @@ -1,9 +1,9 @@ import { render, screen } from "@testing-library/react"; -import { IntlProvider } from "react-intl"; import { Provider } from "react-redux"; import { BrowserRouter as Router } from "react-router-dom"; import { createMainStore } from "src/apps/main/redux"; +import { t } from "../../components/t"; import { FaqPage } from "."; describe("src/pages/landing/index.tsx", () => { @@ -14,18 +14,18 @@ describe("src/pages/landing/index.tsx", () => { const { container } = render( - - - + , ); const firstQuestionTitle = await screen.findByText( - mainStore.getState().faqPage.faqData[0].title, + t(mainStore.getState().faqPage.faqData[0].title), ); - expect(firstQuestionTitle.innerHTML).toBe(mainStore.getState().faqPage.faqData[faqIndex].title); + expect(firstQuestionTitle.innerHTML).toBe( + t(mainStore.getState().faqPage.faqData[faqIndex].title), + ); expect(container).toMatchSnapshot(); }); }); diff --git a/web/src/apps/main/pages/faq/index.tsx b/web/src/apps/main/pages/faq/index.tsx index 3047607fe..fccfa02bc 100644 --- a/web/src/apps/main/pages/faq/index.tsx +++ b/web/src/apps/main/pages/faq/index.tsx @@ -3,14 +3,13 @@ import { FaqCard } from "@dzcode.io/ui/dist/faq-card"; import { Grid } from "@dzcode.io/ui/dist/grid"; import { ThemeProvider } from "@dzcode.io/ui/dist/theme/theme-provider"; import { Typography } from "@dzcode.io/ui/dist/typography"; -import { FC } from "react"; -import { FormattedMessage } from "react-intl"; +import type { FC } from "react"; import { useSelector } from "react-redux"; +import { Markdown } from "src/apps/main/components/markdown"; +import { T, t } from "src/apps/main/components/t"; import { StateInterface } from "src/apps/main/redux"; import { FaqPageState } from "src/apps/main/redux/reducers/faq-page"; -import { Markdown } from "../../components/markdown"; - const FaqCards = () => { const { faqData } = useSelector((state) => state.faqPage); @@ -19,16 +18,11 @@ const FaqCards = () => { {faqData.map(({ title, questions }, index) => ( } - questions={questions.map(({ question, answer }, index) => { + title={} + questions={questions.map(({ question, answer }) => { return { - question: ( - - ), - answer: {answer}, + question: , + answer: , }; })} /> @@ -41,7 +35,7 @@ const FaqCards = () => { const PageTitle = () => { return ( - + ); }; @@ -49,13 +43,7 @@ const PageTitle = () => { const PageFooter = () => { return ( - contact@dzcode.io, - }} - /> + contact@dzcode.io ); }; diff --git a/web/src/apps/main/pages/not-found/index.tsx b/web/src/apps/main/pages/not-found/index.tsx index e3e7a3d0d..3b7c3d1e4 100644 --- a/web/src/apps/main/pages/not-found/index.tsx +++ b/web/src/apps/main/pages/not-found/index.tsx @@ -3,10 +3,17 @@ import Button from "@material-ui/core/Button"; import makeStyles from "@material-ui/core/styles/makeStyles"; import Typography from "@material-ui/core/Typography"; import ArrowBackIcon from "@material-ui/icons/ArrowBack"; +import ArrowForwardIcon from "@material-ui/icons/ArrowForward"; import { FC } from "react"; +import { useSelector } from "react-redux"; +import { T, t } from "src/apps/main/components/t"; import svg from "src/assets/svg/404.svg"; import { LinkV2 } from "src/components/link-v2"; +import { Markdown } from "../../components/markdown"; +import { StateInterface } from "../../redux"; +import { SettingsState } from "../../redux/reducers/settings"; + const useStyles = makeStyles((theme) => ({ root: { textAlign: "center", @@ -24,18 +31,21 @@ const useStyles = makeStyles((theme) => ({ const NotFound: FC = () => { const classes = useStyles(); + const { language } = useSelector((state) => state.settings); return (
      DzCode i/o: 404 page not found - Finally someone saw the 404 page that{" "} - Nour developed 😅 + -
      diff --git a/web/src/apps/main/pages/projects/catalog/index.tsx b/web/src/apps/main/pages/projects/catalog/index.tsx index 9999409a0..530db06ee 100644 --- a/web/src/apps/main/pages/projects/catalog/index.tsx +++ b/web/src/apps/main/pages/projects/catalog/index.tsx @@ -3,8 +3,8 @@ import Grid from "@material-ui/core/Grid"; import makeStyles from "@material-ui/core/styles/makeStyles"; import Typography from "@material-ui/core/Typography"; import { FC } from "react"; -import { FormattedMessage } from "react-intl"; import { Card } from "src/apps/main/components/card"; +import { T, t } from "src/apps/main/components/t"; const useStyles = makeStyles((theme) => ({ root: { @@ -28,7 +28,7 @@ export const Catalog: FC = ({ projectsList }) => { return ( <> - + {projectsList @@ -40,7 +40,7 @@ export const Catalog: FC = ({ projectsList }) => { title: project.title || "", description: project.description || "", link: `https://www.github.com/${project.githubURI}`, - actionLabel: "Go To Code", + actionLabel: t("projects-card-cta-button"), }} /> diff --git a/web/src/apps/main/pages/projects/index.tsx b/web/src/apps/main/pages/projects/index.tsx index e717fba51..20144cde3 100644 --- a/web/src/apps/main/pages/projects/index.tsx +++ b/web/src/apps/main/pages/projects/index.tsx @@ -2,6 +2,7 @@ import { ErrorBoundary } from "@dzcode.io/ui/dist/error-boundary"; import { TryAgain } from "@dzcode.io/ui/dist/try-again"; import { FC, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { t } from "src/apps/main/components/t"; import { Dispatch, StateInterface } from "src/apps/main/redux"; import { fetchProjectsList } from "src/apps/main/redux/actions/projects-page"; import { ProjectsPageState } from "src/apps/main/redux/reducers/projects-page"; @@ -21,10 +22,10 @@ export const ProjectsPage: FC = () => { return (
      - {projectsList === "ERROR" ? ( + {projectsList == "ERROR" ? ( dispatch(fetchProjectsList())} /> ) : ( diff --git a/web/src/apps/main/pages/team/catalog/index.tsx b/web/src/apps/main/pages/team/catalog/index.tsx index 7a974a816..4b9f095e4 100644 --- a/web/src/apps/main/pages/team/catalog/index.tsx +++ b/web/src/apps/main/pages/team/catalog/index.tsx @@ -4,7 +4,7 @@ import { ContributorCard, ContributorSkeleton } from "@dzcode.io/ui/dist/contrib import { Grid } from "@dzcode.io/ui/dist/grid"; import { Typography } from "@dzcode.io/ui/dist/typography"; import { FC } from "react"; -import { FormattedMessage } from "react-intl"; +import { T, t } from "src/apps/main/components/t"; interface CatalogProps { teamList: GetTeamResponseDto["contributors"] | null; @@ -15,17 +15,18 @@ export const Catalog: FC = ({ teamList }) => { - + {teamList ? teamList.map((contributor) => ( - + )) diff --git a/web/src/apps/main/pages/team/index.tsx b/web/src/apps/main/pages/team/index.tsx index c1b431a7b..6af49de3b 100644 --- a/web/src/apps/main/pages/team/index.tsx +++ b/web/src/apps/main/pages/team/index.tsx @@ -3,6 +3,7 @@ import { ThemeProvider } from "@dzcode.io/ui/dist/theme/theme-provider"; import { TryAgain } from "@dzcode.io/ui/dist/try-again"; import { FC, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { t } from "src/apps/main/components/t"; import { Dispatch, StateInterface } from "src/apps/main/redux"; import { fetchTeamList } from "src/apps/main/redux/actions/team-page"; import { TeamPageState } from "src/apps/main/redux/reducers/team-page"; @@ -28,8 +29,8 @@ export const TeamPage: FC = () => { > {teamList === "ERROR" ? ( dispatch(fetchTeamList())} /> ) : ( diff --git a/web/src/apps/main/redux/reducers/faq-page/faq-data.ts b/web/src/apps/main/redux/reducers/faq-page/faq-data.ts index 6e0621e30..5e9e9a51c 100644 --- a/web/src/apps/main/redux/reducers/faq-page/faq-data.ts +++ b/web/src/apps/main/redux/reducers/faq-page/faq-data.ts @@ -1,105 +1,44 @@ +import { DictionaryKeys } from "src/apps/main/components/t/dictionary"; + export type FAQData = Array<{ - title: string; + title: DictionaryKeys<`faq-topic-${number}`>; questions: Array<{ - question: string; - answer: string; + question: DictionaryKeys<`faq-topic-${number}-question-${number}`>; + answer: DictionaryKeys<`faq-topic-${number}-answer-${number}`>; }>; }>; export const faqData: FAQData = [ { - title: "General", + title: "faq-topic-1", questions: [ - { - question: "What exactly is DzCode i/o ?", - answer: `An open-source online community of algerian developers, no organization or any political party is involved, only us dz developers.`, - }, - { - question: "What are the Goals of DzCode i/o ?", - answer: ` -- Share our experiences (in form of [Articles](/Articles)), there are many algerian developers that accumulated lots experiences, dzcode.io gives them the chance to share it with the right audience. -- Guide new developers to build their career (with detailed [documentation](/Learn)), and understand the software market, instead of wasting their time on other useless resources. -- Fix some common algerian software problems, in form of ready to use open-source [softwares](/Projects) (packages, libraries ...etc).`, - }, - { - question: "What benefit will i get from it ?", - answer: `There are couple of benefits, to name few: - -- You will meet other algerian developers, experienced and juniors, where you can grow your network! -- You'll get to experience a professional environment, which is completely different than the one you used to in school. -- Your contribution will be shown on your Github profile, and that is a big plus in your professional career! -`, - }, - { - question: "dzcode, dzcode.io or DzCode i/o ?", - answer: `You may get confused with the different terms, so here's the official breakdown: - -- **DzCode i/o** (with capital C) is the official name of the community. -- **dzcode.io** is the website of the DzCode i/o, this has been voted for [here](https://www.facebook.com/groups/dzdevs/permalink/3052880478141052/). -- **dzcode** is a short name, not official, but it's usually used to refer DzCode i/o. -`, - }, + { question: "faq-topic-1-question-1", answer: "faq-topic-1-answer-1" }, + { question: "faq-topic-1-question-2", answer: "faq-topic-1-answer-2" }, + { question: "faq-topic-1-question-3", answer: "faq-topic-1-answer-3" }, ], }, { - title: "Participation", + title: "faq-topic-2", questions: [ - { - question: "How to join DzCode i/o ?", - answer: `We're most active in slack, it's highly recommended to [join us there](https://join.slack.com/t/dzcode/shared_invite/zt-ek9kscb7-m8z_~cBjX79l~uchuABPFQ).`, - }, - { - question: "I want to code, where should I start ?", - answer: `Go to [/Contribute](/Contribute) page, you will see list projects with their open tasks, pick whatever you like and start coding 🔥. - -**Note** : Please make sure to inform the project maintainer to reserve the task for you, you can do that by commenting on the issue ticket.`, - }, - { - question: "I like the idea, what are the different ways i can contribute to DzCode i/o ?", - answer: `Apart from checking out the [/Contribute](/Contribute) page, you can also contribute to DzCode i/o by: - -- Adding your open-source projects to dzcode.io website, you can do that [here](/Learn/About_dzcode_io/Add_Your_Project_To_dzcode_io). -- Writing about your experience in form of articles, it's as easy as following the steps [here](/Learn/About_dzcode_io/Add_Your_Article_To_dzcode_io). -`, - }, + { question: "faq-topic-2-question-1", answer: "faq-topic-2-answer-1" }, + { question: "faq-topic-2-question-2", answer: "faq-topic-2-answer-2" }, + { question: "faq-topic-2-question-3", answer: "faq-topic-2-answer-3" }, ], }, { - title: "Articles", + title: "faq-topic-3", questions: [ - { - question: "How to write an article in dzcode.io", - answer: `See this [tutorial](/Learn/About_dzcode_io/Add_Your_Article_To_dzcode_io).`, - }, - { - question: "The Articles should they be in English ?", - answer: - "Yes, to reach a wide range of audience we will add a feature to allow article localization and multiple language articles in the future.", - }, - { - question: "Can I write about anything ?", - answer: "As long as its IT related yes you can write about anything.", - }, + { question: "faq-topic-3-question-1", answer: "faq-topic-3-answer-1" }, + { question: "faq-topic-3-question-2", answer: "faq-topic-3-answer-2" }, + { question: "faq-topic-3-question-3", answer: "faq-topic-3-answer-3" }, ], }, { - title: "Projects", + title: "faq-topic-4", questions: [ - { - question: "How to add my open-source project to dzcode.io", - answer: `See this [tutorial](/Learn/About_dzcode_io/Add_Your_Project_To_dzcode_io).`, - }, - { - question: "What makes my project eligible to be added to dzcode.io", - answer: "It has to solve an Algerian problem, or, to be written by an Algerian Developer.", - }, - { - question: "Why should i add my project to dzcode.io ?", - answer: ` -- Your project will potentially get noticed by more algerian developers. -- You will get potential contribution from other DZ developers, and eventually better shape your piece of software. -`, - }, + { question: "faq-topic-4-question-1", answer: "faq-topic-4-answer-1" }, + { question: "faq-topic-4-question-2", answer: "faq-topic-4-answer-2" }, + { question: "faq-topic-4-question-3", answer: "faq-topic-4-answer-3" }, ], }, ]; diff --git a/web/src/apps/main/redux/reducers/faq-page/index.ts b/web/src/apps/main/redux/reducers/faq-page/index.ts index cf800d08a..00ab0cead 100644 --- a/web/src/apps/main/redux/reducers/faq-page/index.ts +++ b/web/src/apps/main/redux/reducers/faq-page/index.ts @@ -1,14 +1,6 @@ import { Action } from "src/apps/main/redux"; -import { faqData } from "./faq-data"; - -export type FAQData = Array<{ - title: string; - questions: Array<{ - question: string; - answer: string; - }>; -}>; +import { FAQData, faqData } from "./faq-data"; export interface FaqPageState { faqData: FAQData; diff --git a/web/src/apps/main/redux/reducers/footer-component/index.ts b/web/src/apps/main/redux/reducers/footer-component/index.ts index 4728b9e79..8afacdd57 100644 --- a/web/src/apps/main/redux/reducers/footer-component/index.ts +++ b/web/src/apps/main/redux/reducers/footer-component/index.ts @@ -1,16 +1,9 @@ import { Action } from "src/apps/main/redux"; -import { sections } from "./sections"; +import { Section, sections } from "./sections"; export interface FooterComponentState { - sections: Array<{ - title: string; - links: Array<{ - id?: string; - href: string; - text: string; - }>; - }>; + sections: Section[]; } export const footerComponent = ( diff --git a/web/src/apps/main/redux/reducers/footer-component/sections.ts b/web/src/apps/main/redux/reducers/footer-component/sections.ts index 90db4d309..195b95a4c 100644 --- a/web/src/apps/main/redux/reducers/footer-component/sections.ts +++ b/web/src/apps/main/redux/reducers/footer-component/sections.ts @@ -1,40 +1,73 @@ +import { DictionaryKeys } from "src/apps/main/components/t/dictionary"; import { fullstackConfig } from "src/config"; -export const sections = [ +export interface Section { + title: DictionaryKeys<"footer-category-title">; + links: Array<{ + text: DictionaryKeys<"footer-category-link-text">; + href: string; + }>; +} + +export const sections: Section[] = [ { - title: "Helpful Links", + title: "footer-category-title-helpful-links", links: [ - { id: "home.path", text: "Home", href: "/" }, - { id: "learn.path", text: "Learn", href: "/Learn" }, - { id: "projects.path", text: "Projects", href: "/Projects" }, - { id: "articles.path", text: "Articles", href: "/Articles" }, - { id: "faq.path", text: "FAQ", href: "/FAQ" }, + { text: "footer-category-link-text-home", href: "/" }, + { text: "footer-category-link-text-learn", href: "/Learn" }, + { text: "footer-category-link-text-projects", href: "/Projects" }, + { text: "footer-category-link-text-articles", href: "/Articles" }, + { text: "footer-category-link-text-faq", href: "/FAQ" }, ], }, { - title: "Mobile", + title: "footer-category-title-mobile", links: [ - { text: "Android", href: fullstackConfig.mobile.android.url }, - { text: "iOS", href: fullstackConfig.mobile.ios.url }, - { text: "Expo", href: fullstackConfig.mobile.expo.url }, + { + text: "footer-category-link-text-android", + href: fullstackConfig.mobile.android.url, + }, + { + text: "footer-category-link-text-ios", + href: fullstackConfig.mobile.ios.url, + }, + { + text: "footer-category-link-text-expo", + href: fullstackConfig.mobile.expo.url, + }, ], }, { - title: "Social Media", + title: "footer-category-title-social-media", links: [ - { text: "Github", href: "https://www.github.com/dzcode-io" }, { - text: "Slack", + text: "footer-category-link-text-github", + href: "https://www.github.com/dzcode-io", + }, + { + text: "footer-category-link-text-slack", href: "https://join.slack.com/t/dzcode/shared_invite/zt-ek9kscb7-m8z_~cBjX79l~uchuABPFQ", }, - { text: "Facebook", href: "https://www.facebook.com/dzcode.io" }, - { text: "Instagram", href: "https://www.instagram.com/dzcode.io" }, { - text: "YouTube", + text: "footer-category-link-text-facebook", + href: "https://www.facebook.com/dzcode.io", + }, + { + text: "footer-category-link-text-instagram", + href: "https://www.instagram.com/dzcode.io", + }, + { + text: "footer-category-link-text-youTube", href: "https://www.youtube.com/channel/UC_tLjuQaYotzERtaAo8Y4SQ", }, - { text: "Twitter", href: "https://twitter.com/dzcode_io" }, - { text: "LinkedIn", href: "https://www.linkedin.com/groups/8924363" }, + { + text: "footer-category-link-text-twitter", + href: "https://twitter.com/dzcode_io", + }, + { + text: "footer-category-link-text-linkedIn", + href: "https://www.linkedin.com/groups/8924363", + }, ], }, ]; diff --git a/web/src/apps/main/redux/reducers/navbar-component/index.ts b/web/src/apps/main/redux/reducers/navbar-component/index.ts index b226887d1..6954ecbcd 100644 --- a/web/src/apps/main/redux/reducers/navbar-component/index.ts +++ b/web/src/apps/main/redux/reducers/navbar-component/index.ts @@ -1,40 +1,22 @@ +import { DictionaryKeys } from "src/apps/main/components/t/dictionary"; import { Action } from "src/apps/main/redux"; -export interface TranslationMessage { - id: string; - defaultMessage: string; - description?: string; -} export interface NavbarComponentState { - sections: Array<{ message: TranslationMessage; title: string; url: string }>; + sections: Array<{ + title: DictionaryKeys<"navbar">; + url: string; + }>; } export const navbarComponent = ( state: NavbarComponentState = { sections: [ - { - message: { id: "contribute.path", defaultMessage: "Contribute" }, - url: "/Contribute", - title: "Contribute", - }, - - { message: { id: "team.path", defaultMessage: "Team" }, url: "/Team", title: "Connect" }, - - { message: { id: "learn.path", defaultMessage: "Learn" }, url: "/Learn", title: "Learn" }, - - { - message: { id: "projects.path", defaultMessage: "Projects" }, - url: "/Projects", - title: "Projects", - }, - - { - message: { id: "articles.path", defaultMessage: "Articles" }, - url: "/Articles", - title: "Articles", - }, - - { message: { id: "faq.path", defaultMessage: "FAQ" }, url: "/FAQ", title: "FAQ" }, + { url: "/Contribute", title: "navbar-section-contribute" }, + { url: "/Team", title: "navbar-section-connect" }, + { url: "/Learn", title: "navbar-section-learn" }, + { url: "/Projects", title: "navbar-section-projects" }, + { url: "/Articles", title: "navbar-section-articles" }, + { url: "/FAQ", title: "navbar-section-faq" }, ], }, action: Action, From b1a5840235cf9c271bd1b91932bda2482776d29f Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 5 Aug 2022 21:46:05 +0200 Subject: [PATCH 07/10] localized and cleaned landing page --- .../header/__snapshots__/header.spec.tsx.snap | 54 +++++------- .../main/pages/landing/header/header.spec.tsx | 13 +-- .../apps/main/pages/landing/header/index.tsx | 51 +++-------- web/src/apps/main/pages/landing/index.tsx | 54 +----------- .../apps/main/pages/landing/mobile/index.tsx | 11 +-- .../main/pages/landing/top-articles/index.tsx | 86 ------------------- .../main/pages/landing/top-projects/index.tsx | 86 ------------------- .../main/redux/actions/landing-page/index.ts | 44 ---------- .../main/redux/reducers/landing-page/index.ts | 16 +--- 9 files changed, 48 insertions(+), 367 deletions(-) delete mode 100644 web/src/apps/main/pages/landing/top-articles/index.tsx delete mode 100644 web/src/apps/main/pages/landing/top-projects/index.tsx delete mode 100644 web/src/apps/main/redux/actions/landing-page/index.ts diff --git a/web/src/apps/main/pages/landing/header/__snapshots__/header.spec.tsx.snap b/web/src/apps/main/pages/landing/header/__snapshots__/header.spec.tsx.snap index 31e43f6f3..e6b8214c7 100644 --- a/web/src/apps/main/pages/landing/header/__snapshots__/header.spec.tsx.snap +++ b/web/src/apps/main/pages/landing/header/__snapshots__/header.spec.tsx.snap @@ -18,41 +18,33 @@ exports[`header component should render header component 1`] = `

      - Algerian - - Open Source + + + Open-Source + + Algerian Comunity - Community

      - Whether you are a maintainer or an open-source enthusiast DzCode helps you - - - find - - , - - - contribute - - - and - - list - - - open-source projects that solve Algerian - problems. + + DzCode i/o helps you find, + + contribute + + and add to the + + list + + of open-source projects that solve Algerian problems. +

      - Have a question ? + Do you have a question? diff --git a/web/src/apps/main/pages/landing/header/header.spec.tsx b/web/src/apps/main/pages/landing/header/header.spec.tsx index 264ef3c19..2d552f140 100644 --- a/web/src/apps/main/pages/landing/header/header.spec.tsx +++ b/web/src/apps/main/pages/landing/header/header.spec.tsx @@ -1,17 +1,20 @@ import { render } from "@testing-library/react"; -import { IntlProvider } from "react-intl"; +import { Provider } from "react-redux"; import { MemoryRouter } from "react-router-dom"; +import { createMainStore } from "src/apps/main/redux"; import { Header } from "./index"; describe("header component", () => { test("should render header component", () => { + const mainStore = createMainStore(); + const { container } = render( - - + +
      - - , + + , ); expect(container).toMatchSnapshot(); diff --git a/web/src/apps/main/pages/landing/header/index.tsx b/web/src/apps/main/pages/landing/header/index.tsx index 9bcc0d3aa..2ff679660 100644 --- a/web/src/apps/main/pages/landing/header/index.tsx +++ b/web/src/apps/main/pages/landing/header/index.tsx @@ -5,8 +5,9 @@ import Hidden from "@material-ui/core/Hidden"; import makeStyles from "@material-ui/core/styles/makeStyles"; import Typography from "@material-ui/core/Typography"; import { FC } from "react"; -import { FormattedMessage } from "react-intl"; import image from "src/apps/main/assets/svg/dzcode.svg"; +import { Markdown } from "src/apps/main/components/markdown"; +import { T, t } from "src/apps/main/components/t"; import { LinkV2 } from "src/components/link-v2"; export const Header: FC = () => { @@ -23,7 +24,6 @@ export const Header: FC = () => { }, }, title: { - // fontWeight: theme.typography.fontWeightBold, color: theme.palette.text.primary, textAlign: "center", fontSize: theme.typography.h5.fontSize, @@ -33,13 +33,8 @@ export const Header: FC = () => { }, callToAction: { width: "100%", - - [theme.breakpoints.up("sm")]: { - marginRight: "50px", - }, }, button: { - // fontWeight: theme.typography.fontWeightBold, [theme.breakpoints.down("md")]: { width: "100%", }, @@ -68,12 +63,10 @@ export const Header: FC = () => { - {msg}, - }} + @@ -83,26 +76,7 @@ export const Header: FC = () => { color="textPrimary" className={classes.description} > - {" "} - - - - ,{" "} - - {" "} - - - - {" "} - - + @@ -116,10 +90,7 @@ export const Header: FC = () => { disableTouchRipple className={classes.button} > - + @@ -133,7 +104,7 @@ export const Header: FC = () => { size="large" className={classes.button} > - + @@ -142,9 +113,7 @@ export const Header: FC = () => { - - scrum board - + scrum board diff --git a/web/src/apps/main/pages/landing/index.tsx b/web/src/apps/main/pages/landing/index.tsx index 4144ee746..d6ccd7ae0 100644 --- a/web/src/apps/main/pages/landing/index.tsx +++ b/web/src/apps/main/pages/landing/index.tsx @@ -1,65 +1,13 @@ import { ErrorBoundary } from "@dzcode.io/ui/dist/error-boundary"; -import Button from "@material-ui/core/Button"; -import createStyles from "@material-ui/core/styles/createStyles"; -import makeStyles from "@material-ui/core/styles/makeStyles"; -import ArrowForwardIcon from "@material-ui/icons/ArrowForward"; -import { FC, useEffect } from "react"; -import { FormattedMessage } from "react-intl"; -import { useDispatch } from "react-redux"; -import { Dispatch } from "src/apps/main/redux"; -import { fetchTopArticles, fetchTopProjects } from "src/apps/main/redux/actions/landing-page"; -import { LandingPageState } from "src/apps/main/redux/reducers/landing-page"; -import { LinkV2 } from "src/components/link-v2"; +import { FC } from "react"; import { Header } from "./header"; import { Mobile } from "./mobile"; -import { TopArticles } from "./top-articles"; -import { TopProjects } from "./top-projects"; - -const useStyles = makeStyles((theme) => - createStyles({ - hr: { - maxWidth: "300px", - width: "90%", - marginBottom: theme.spacing(0), - marginTop: theme.spacing(0), - }, - button: { - marginBottom: theme.spacing(4), - display: "inline-block", - }, - }), -); export const LandingPage: FC = () => { - const classes = useStyles(); - const dispatch = useDispatch>(); - - useEffect(() => { - dispatch(fetchTopProjects()); - dispatch(fetchTopArticles()); - }, []); - return (
      - -
      - - - -
      -
      - -
      - - - -
      ); diff --git a/web/src/apps/main/pages/landing/mobile/index.tsx b/web/src/apps/main/pages/landing/mobile/index.tsx index c37092a33..c18efbf0f 100644 --- a/web/src/apps/main/pages/landing/mobile/index.tsx +++ b/web/src/apps/main/pages/landing/mobile/index.tsx @@ -2,12 +2,12 @@ import Grid from "@material-ui/core/Grid"; import makeStyles from "@material-ui/core/styles/makeStyles"; import Typography from "@material-ui/core/Typography"; import { FC } from "react"; -import { FormattedMessage } from "react-intl"; import { useSelector } from "react-redux"; import androidDark from "src/apps/main/assets/png/android-dark.png"; import androidLight from "src/apps/main/assets/png/android-light.png"; import iosDark from "src/apps/main/assets/png/ios-dark.png"; import iosLight from "src/apps/main/assets/png/ios-light.png"; +import { T } from "src/apps/main/components/t"; import { StateInterface } from "src/apps/main/redux"; import { LinkV2 } from "src/components/link-v2"; import { fullstackConfig } from "src/config"; @@ -67,15 +67,10 @@ export const Mobile: FC = () => { return (
      - + - + {mobileApps.map((mobileApp, i) => ( diff --git a/web/src/apps/main/pages/landing/top-articles/index.tsx b/web/src/apps/main/pages/landing/top-articles/index.tsx deleted file mode 100644 index 64bb92b55..000000000 --- a/web/src/apps/main/pages/landing/top-articles/index.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { TryAgain } from "@dzcode.io/ui/dist/try-again"; -import Grid from "@material-ui/core/Grid"; -import makeStyles from "@material-ui/core/styles/makeStyles"; -import Typography from "@material-ui/core/Typography"; -import { FC } from "react"; -import { FormattedMessage } from "react-intl"; -import { useDispatch, useSelector } from "react-redux"; -import { Card } from "src/apps/main/components/card"; -import { Dispatch, StateInterface } from "src/apps/main/redux"; -import { fetchTopArticles } from "src/apps/main/redux/actions/landing-page"; -import { LandingPageState } from "src/apps/main/redux/reducers/landing-page"; - -const useStyles = makeStyles((theme) => ({ - root: { - marginTop: theme.spacing(4), - minHeight: "80vh", - [theme.breakpoints.up("lg")]: { - minHeight: "40vh", - }, - }, - title: { - textAlign: "center", - paddingBottom: theme.spacing(1), - }, - subTitle: { - textAlign: "center", - paddingBottom: theme.spacing(1), - }, - topArticles: { - flexGrow: 1, - paddingBottom: theme.spacing(4), - paddingTop: theme.spacing(4), - }, -})); - -export const TopArticles: FC = () => { - const classes = useStyles(); - const { topArticles } = useSelector( - (state) => state.landingPage, - ); - const dispatch = useDispatch>(); - - return ( -
      - - - - - - - - {topArticles === "ERROR" ? ( - dispatch(fetchTopArticles())} - stretch={true} - /> - ) : topArticles ? ( - topArticles.map((article) => ( - - - - )) - ) : ( - [1, 2, 3].map((id) => ( - - - - )) - )} - -
      - ); -}; diff --git a/web/src/apps/main/pages/landing/top-projects/index.tsx b/web/src/apps/main/pages/landing/top-projects/index.tsx deleted file mode 100644 index b9b182758..000000000 --- a/web/src/apps/main/pages/landing/top-projects/index.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { TryAgain } from "@dzcode.io/ui/dist/try-again"; -import Grid from "@material-ui/core/Grid"; -import makeStyles from "@material-ui/core/styles/makeStyles"; -import Typography from "@material-ui/core/Typography"; -import { FC } from "react"; -import { FormattedMessage } from "react-intl"; -import { useDispatch, useSelector } from "react-redux"; -import { Card } from "src/apps/main/components/card"; -import { Dispatch, StateInterface } from "src/apps/main/redux"; -import { fetchTopProjects } from "src/apps/main/redux/actions/landing-page"; -import { LandingPageState } from "src/apps/main/redux/reducers/landing-page"; - -const useStyles = makeStyles((theme) => ({ - root: { - marginTop: theme.spacing(4), - minHeight: "80vh", - [theme.breakpoints.up("lg")]: { - minHeight: "40vh", - }, - }, - title: { - textAlign: "center", - paddingBottom: theme.spacing(1), - }, - subTitle: { - textAlign: "center", - paddingBottom: theme.spacing(1), - }, - topProjects: { - flexGrow: 1, - paddingBottom: theme.spacing(4), - paddingTop: theme.spacing(4), - }, -})); - -export const TopProjects: FC = () => { - const classes = useStyles(); - const { topProjects } = useSelector( - (state) => state.landingPage, - ); - const dispatch = useDispatch>(); - - return ( -
      - - - - - - - - {topProjects === "ERROR" ? ( - dispatch(fetchTopProjects())} - stretch={true} - /> - ) : topProjects ? ( - topProjects.map((project, index) => ( - - - - )) - ) : ( - [1, 2, 3].map((id) => ( - - - - )) - )} - -
      - ); -}; diff --git a/web/src/apps/main/redux/actions/landing-page/index.ts b/web/src/apps/main/redux/actions/landing-page/index.ts deleted file mode 100644 index d5bba157e..000000000 --- a/web/src/apps/main/redux/actions/landing-page/index.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as Sentry from "@sentry/browser"; -import { ThunkResult } from "src/apps/main/redux"; -import { LandingPageState } from "src/apps/main/redux/reducers/landing-page"; -import { fetchV2 } from "src/common/utils/fetch"; - -export const fetchTopProjects = (): ThunkResult => async (dispatch) => { - dispatch({ - type: "UPDATE_LANDING_PAGE", - payload: { topProjects: null }, - }); - try { - const topProjects = await fetchV2("data:projects/top-projects.c.json", {}); - dispatch({ - type: "UPDATE_LANDING_PAGE", - payload: { topProjects }, - }); - } catch (error) { - dispatch({ - type: "UPDATE_LANDING_PAGE", - payload: { topProjects: "ERROR" }, - }); - Sentry.captureException(error, { tags: { type: "WEB_FETCH" } }); - } -}; - -export const fetchTopArticles = (): ThunkResult => async (dispatch) => { - dispatch({ - type: "UPDATE_LANDING_PAGE", - payload: { topArticles: null }, - }); - try { - const topArticles = await fetchV2("data:articles/top-articles.c.json", {}); - dispatch({ - type: "UPDATE_LANDING_PAGE", - payload: { topArticles }, - }); - } catch (error) { - dispatch({ - type: "UPDATE_LANDING_PAGE", - payload: { topArticles: "ERROR" }, - }); - Sentry.captureException(error, { tags: { type: "WEB_FETCH" } }); - } -}; diff --git a/web/src/apps/main/redux/reducers/landing-page/index.ts b/web/src/apps/main/redux/reducers/landing-page/index.ts index 12220af37..869f866a4 100644 --- a/web/src/apps/main/redux/reducers/landing-page/index.ts +++ b/web/src/apps/main/redux/reducers/landing-page/index.ts @@ -1,19 +1,9 @@ -import { Article, Project } from "@dzcode.io/api/dist/app/types/legacy"; -import { LOADABLE } from "@dzcode.io/utils/dist/loadable"; import { Action } from "src/apps/main/redux"; -export interface LandingPageState { - topProjects: LOADABLE[]>; - topArticles: LOADABLE; -} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface LandingPageState {} -export const landingPage = ( - state: LandingPageState = { - topProjects: null, - topArticles: null, - }, - action: Action, -) => { +export const landingPage = (state: LandingPageState = {}, action: Action) => { switch (action.type) { case "UPDATE_LANDING_PAGE": return { ...state, ...action.payload }; From b44f566735bff5686d4495093288073b7a883353 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 5 Aug 2022 21:47:04 +0200 Subject: [PATCH 08/10] localized utils --- web/src/common/utils/elapsed-time.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/web/src/common/utils/elapsed-time.ts b/web/src/common/utils/elapsed-time.ts index 3f55f3d6e..abd13a4fb 100644 --- a/web/src/common/utils/elapsed-time.ts +++ b/web/src/common/utils/elapsed-time.ts @@ -1,21 +1,24 @@ -export const elapsedTime = (time: string | number | Date) => { +export const elapsedTime = (time: string | number | Date, localizedSuffixes: string) => { const timePassed = new Date().getTime() - new Date(time).getTime(); const years = Math.floor(timePassed / 31536000000); const months = Math.floor((timePassed - years * 31536000000) / 2628000000); const days = Math.floor((timePassed - months * 2628000000) / 86400000); const hours = Math.floor((timePassed - days * 86400000) / 3600000); const minutes = Math.floor((timePassed - hours * 3600000) / 60000); + const [year, month, day, hour, minute, now] = localizedSuffixes.split("|"); return `${ years > 0 - ? `${years}y` + ? `${years}${year}` : `${ months > 0 - ? `${months}mo` + ? `${months}${month}` : `${ days > 0 - ? `${days}d` - : `${hours > 0 ? `${hours}h` : `${minutes > 0 ? `${minutes}min` : "just now"}`}` + ? `${days}${day}` + : `${ + hours > 0 ? `${hours}${hour}` : `${minutes > 0 ? `${minutes}${minute}` : now}` + }` }` }` }`; From f67b338f15c8003f1e80aab10f66e7421b643981 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 5 Aug 2022 21:53:02 +0200 Subject: [PATCH 09/10] localized and persisted dir in articles and learn pages --- web/src/apps/main/pages/articles/index.tsx | 2 +- .../apps/main/pages/articles/landing/index.tsx | 13 ++----------- web/src/apps/main/pages/learn/index.tsx | 7 ++++--- web/src/apps/main/pages/learn/landing/index.tsx | 15 +++------------ 4 files changed, 10 insertions(+), 27 deletions(-) diff --git a/web/src/apps/main/pages/articles/index.tsx b/web/src/apps/main/pages/articles/index.tsx index 85d3bcae8..f153f6b77 100644 --- a/web/src/apps/main/pages/articles/index.tsx +++ b/web/src/apps/main/pages/articles/index.tsx @@ -29,7 +29,7 @@ export const ArticlesPage: FC = () => { return ( - + {/* Sidebar */} {sidebarTree === "ERROR" ? ( diff --git a/web/src/apps/main/pages/articles/landing/index.tsx b/web/src/apps/main/pages/articles/landing/index.tsx index 2e3d614eb..d1450155a 100644 --- a/web/src/apps/main/pages/articles/landing/index.tsx +++ b/web/src/apps/main/pages/articles/landing/index.tsx @@ -5,7 +5,6 @@ import Typography from "@material-ui/core/Typography"; import useMediaQuery from "@material-ui/core/useMediaQuery"; import ListIcon from "@material-ui/icons/List"; import { FC } from "react"; -import { FormattedMessage } from "react-intl"; import articlesLanding from "src/apps/main/assets/svg/articles-landing.svg"; const useStyles = makeStyles((theme) => ({ @@ -40,18 +39,10 @@ export const Landing: FC = ({ onShowSidebar }) => {
      Dzcode i/o: Articles - + {"Welcome to the articles section of Dzcode i/o"} {md ? ( - - - + {"👈 Please select from the left sidebar"} ) : ( )}
      From de68785beffaae804a812d9982d9b8823272ecd6 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 5 Aug 2022 21:53:22 +0200 Subject: [PATCH 10/10] prefixed local version with v --- web/webpack.config.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/webpack.config.ts b/web/webpack.config.ts index 44e4c137b..0bcabb46d 100644 --- a/web/webpack.config.ts +++ b/web/webpack.config.ts @@ -24,8 +24,9 @@ const apps = glob .sync("src/apps/*/entry/app-config.ts") .map((path) => path.substring(9, path.indexOf("/", 9))); -// eslint-disable-next-line @typescript-eslint/no-var-requires -let bundleInfo: { version: string } = { version: require("./package.json").version as string }; +let bundleInfo: { version: string } = { + version: `v${require("./package.json").version as string}`, // eslint-disable-line @typescript-eslint/no-var-requires +}; try { bundleInfo = JSON.parse(readFileSync(".bundle-info.json").toString()) as typeof bundleInfo; } catch (error) {