Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: i18n - it, lt, pt-BR, fr #129

Open
wants to merge 5 commits into
base: release/v0.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Release v0.2.1

- added example of scheduler data filtering in readme.md
- added support for lt, fr, it locales

# Release v0.2

Expand Down
2 changes: 1 addition & 1 deletion development.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ To set up the project locally for development and testing, please follow these s
```
- **constants** - all constants that are globally used and should not change during usage of app, e.g.: height and width of cell, width of single tile.
- **context** - folder that consists CalendarProvider and LocaleProvider
- **locales** - folder that consists files with translations (currently en / pl / de / lt)
- **locales** - folder that consists files with translations (currently en / pl / de / lt / fr / it )
- **types** - folder that consists all global types and type guards
- **utils** - folder that consists all utility functions used within app (e.g. drawing all the grid, data parsers etc.)

Expand Down
24 changes: 11 additions & 13 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,19 +186,17 @@ const mockedSchedulerData: SchedulerData = [

##### Scheduler Config Object

---

| Property Name | Type | Default | Description |
| ------------------------------------ | ------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| zoom | `0` or `1 | 0 | `0` - display grid divided into weeks `1` - display grid divided into days |
| filterButtonState | `number` | 0 | `< 0` - hides filter button, `0` - state for when filters were not set, `> 0` - state for when some filters were set (allows to also handle `onClearFilterData` event) |
| maxRecordsPerPage | `number` | 50 | number of items from `SchedulerData` visible per page |
| lang | `en`, `lt` or `pl` | en | scheduler's language |
| includeTakenHoursOnWeekendsInDayView | `boolean` | `false` | show weekends as taken when given resource is longer than a week |
| showTooltip | `boolean` | `true` | show tooltip when hovering over tiles |
| translations | `LocaleType[]` | `undefined` | option to add specific langs translations |
| showThemeToggle | `boolean` | `false` | show toggle button to switch between light/dark mode |
| defaultTheme | `light` or `dark` | `light` | scheduler's default theme |
| Property Name | Type | Default | Description |
| ------------------------------------ | --------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| zoom | `0` or `1` | 0 | `0` - display grid divided into weeks `1` - display grid divided into days |
| filterButtonState | `number` | 0 | `< 0` - hides filter button, `0` - state for when filters were not set, `> 0` - state for when some filters were set (allows to also handle `onClearFilterData` event) |
| maxRecordsPerPage | `number` | 50 | number of items from `SchedulerData` visible per page |
| lang | `en`, `lt`, `de`, `fr`, `it`, `pt-BR` or `pl` | en | scheduler's language |
| includeTakenHoursOnWeekendsInDayView | `boolean` | `false` | show weekends as taken when given resource is longer than a week |
| showTooltip | `boolean` | `true` | show tooltip when hovering over tiles |
| translations | `LocaleType[]` | `undefined` | option to add specific langs translations |
| showTooltip | `boolean` | `true` | show tooltip when hovering over tiles |
| translations | `LocaleType[]` | `undefined` | option to add specific langs translations |

#### Translation object example

Expand Down
76 changes: 25 additions & 51 deletions src/context/LocaleProvider/LocaleProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,39 @@
import { useCallback, useContext, useEffect, useState } from "react";
import { useContext, useEffect, useState } from "react";
import dayjs from "dayjs";
import { localeContext } from "./localeContext";
import { locales } from "./locales";
import { LocaleProviderProps, LocaleType } from "./types";
import { LocaleProviderProps } from "./types";

const LocaleProvider = ({ children, lang, translations }: LocaleProviderProps) => {
const [localLang, setLocalLang] = useState<string>("en");
const localesData = locales.getLocales();

const findLocale = useCallback(() => {
const locale = localesData.find((l) => {
return l.id === localLang;
});

if (typeof locale?.dayjsTranslations === "object") {
dayjs.locale(locale.dayjsTranslations);
}

return locale || localesData[0];
}, [localLang]);

const [currentLocale, setCurrentLocale] = useState<LocaleType>(findLocale());

const saveCurrentLocale = (locale: LocaleType) => {
localStorage.setItem("locale", locale.translateCode);
setCurrentLocale(locale);
};
const [currentLocale, setCurrentLocale] = useState(
locales.getLocales().filter((locale) => locale.id === "en")[0]
);

useEffect(() => {
translations?.forEach((translation) => {
const localeData = localesData.find((el) => el.id === translation.id);
if (!localeData) {
locales.addLocales(translation);
}
const overwrittenLocalesData = locales.locales.map((locale) => {
let localeTemp = locale;
translations?.forEach((translation) => {
if (locale.id === translation.id) {
localeTemp = translation;
}
});
return localeTemp;
});
}, [translations]);

useEffect(() => {
const localeId = localStorage.getItem("locale");
const language = lang ?? localeId ?? "en";
localStorage.setItem("locale", language);
setLocalLang(language);
setCurrentLocale(findLocale());
}, [findLocale, lang]);

const { Provider } = localeContext;
const location = overwrittenLocalesData?.find((locale) => locale.id === lang);
if (location) {
setCurrentLocale(location);
dayjs.locale(location.dayjsTranslations);
}
}, [translations, lang]);

return (
<Provider value={{ currentLocale, localesData, setCurrentLocale: saveCurrentLocale }}>
<localeContext.Provider
value={{
currentLocale
}}>
{children}
</Provider>
</localeContext.Provider>
);
};

Expand All @@ -58,15 +42,5 @@ const useLanguage = () => {
return context.currentLocale.lang;
};

const useLocales = () => {
const context = useContext(localeContext);
return context.localesData;
};

const useSetLocale = () => {
const context = useContext(localeContext);
return context.setCurrentLocale;
};

export default LocaleProvider;
export { useLanguage, useLocales, useSetLocale };
export { useLanguage };
2 changes: 1 addition & 1 deletion src/context/LocaleProvider/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default, useLanguage, useLocales, useSetLocale } from "./LocaleProvider";
export { default, useLanguage } from "./LocaleProvider";
4 changes: 1 addition & 3 deletions src/context/LocaleProvider/localeContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,5 @@ import { locales } from "./locales";
import { LocaleContextType } from "./types";

export const localeContext = createContext<LocaleContextType>({
localesData: locales.getLocales(),
currentLocale: locales.getLocales()[0],
setCurrentLocale: () => {}
currentLocale: locales.getLocales().filter((locale) => locale.id === "en")[0]
});
39 changes: 30 additions & 9 deletions src/context/LocaleProvider/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,36 @@ import enDayjsTranslations from "dayjs/locale/en";
import plDayjsTranslations from "dayjs/locale/pl";
import deDayjsTranslations from "dayjs/locale/de";
import ltDayjsTranslations from "dayjs/locale/lt";
import { en, pl, de, lt } from "@/locales";
import frDayjsTranslations from "dayjs/locale/fr";
import itDayjsTranslations from "dayjs/locale/it";
import ptBRDayjsTranslations from "dayjs/locale/pt-br";
import { en, pl, de, lt, fr, it, ptBR } from "@/locales";
import { LocaleType } from "./types";

export const localesData: LocaleType[] = [
{
id: "de",
lang: de,
translateCode: "de-DE",
dayjsTranslations: deDayjsTranslations
},
{
id: "en",
lang: en,
translateCode: "en-GB",
dayjsTranslations: enDayjsTranslations
},
{
id: "pl",
lang: pl,
translateCode: "pl-PL",
dayjsTranslations: plDayjsTranslations
id: "fr",
lang: fr,
translateCode: "fr-FR",
dayjsTranslations: frDayjsTranslations
},
{
id: "it",
lang: it,
translateCode: "it-IT",
dayjsTranslations: itDayjsTranslations
},
{
id: "lt",
Expand All @@ -25,10 +40,16 @@ export const localesData: LocaleType[] = [
dayjsTranslations: ltDayjsTranslations
},
{
id: "de",
lang: de,
translateCode: "de-DE",
dayjsTranslations: deDayjsTranslations
id: "pl",
lang: pl,
translateCode: "pl-PL",
dayjsTranslations: plDayjsTranslations
},
{
id: "pt-BR",
lang: ptBR,
translateCode: "pt-BR",
dayjsTranslations: ptBRDayjsTranslations
}
];

Expand Down
2 changes: 0 additions & 2 deletions src/context/LocaleProvider/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { LangCodes } from "@/types/global";

export type LocaleContextType = {
currentLocale: LocaleType;
localesData: LocaleType[];
setCurrentLocale: (locale: LocaleType) => void;
};

export type LocaleProviderProps = {
Expand Down
17 changes: 17 additions & 0 deletions src/locales/fr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const fr = {
feelingEmpty: "Le planning est vide...",
free: "Libre",
loadNext: "Suivant",
loadPrevious: "Précédent",
over: "over",
taken: "Pris",
topbar: {
filters: "Filtres",
next: "suiv.",
prev: "préc.",
today: "Aujourd'hui",
view: "Voir"
},
search: "rechercher",
week: "semaine"
};
3 changes: 3 additions & 0 deletions src/locales/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ export { pl } from "./pl";
export { en } from "./en";
export { de } from "./de";
export { lt } from "./lt";
export { fr } from "./fr";
export { it } from "./it";
export { ptBR } from "./ptBR";
17 changes: 17 additions & 0 deletions src/locales/it.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const it = {
feelingEmpty: "Mi sento così vuoto...",
free: "Libero",
loadNext: "Prossimo",
loadPrevious: "Precedente",
over: "sopra",
taken: "Occupato",
topbar: {
filters: "Filtri",
next: "prossimo",
prev: "precedente",
today: "Oggi",
view: "Vista"
},
search: "cerca",
week: "settimana"
};
17 changes: 17 additions & 0 deletions src/locales/ptBR.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const ptBR = {
feelingEmpty: "Sem dados...",
free: "livre",
loadNext: "Próximo",
loadPrevious: "Anterior",
over: "finalizado",
taken: "ocupado",
topbar: {
filters: "filtros",
next: "próximo",
prev: "anterior",
today: "hoje",
view: "visualização"
},
search: "Procurar",
week: "Semana"
};
4 changes: 2 additions & 2 deletions src/types/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type ZoomLevelTuple = typeof allZoomLevel;

export type ZoomLevel = ZoomLevelTuple[number];

export type LangCodes = "en" | "pl" | "de" | "lt";
export type LangCodes = "en" | "pl" | "de" | "lt" | "fr" | "it" | "pt-BR";

export type Config = {
zoom: ZoomLevel;
Expand All @@ -21,7 +21,7 @@ export type Config = {
*/
filterButtonState?: number;
/**
* Language code: "en" | "pl" | "de"
* Language code: "en" | "pl" | "de" | "lt" | "fr" | "it" | "pt-BR"
*/
lang?: LangCodes | string;
isFiltersButtonVisible?: boolean;
Expand Down