diff --git a/CHANGELOG.md b/CHANGELOG.md index e44472ea..e3ac2bd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/development.md b/development.md index 15cb9c61..88b1a05f 100644 --- a/development.md +++ b/development.md @@ -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.) diff --git a/readme.md b/readme.md index 72d406e8..68c49327 100644 --- a/readme.md +++ b/readme.md @@ -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 diff --git a/src/context/LocaleProvider/LocaleProvider.tsx b/src/context/LocaleProvider/LocaleProvider.tsx index 3afa8bc5..0075b1dd 100644 --- a/src/context/LocaleProvider/LocaleProvider.tsx +++ b/src/context/LocaleProvider/LocaleProvider.tsx @@ -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("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(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 ( - + {children} - + ); }; @@ -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 }; diff --git a/src/context/LocaleProvider/index.ts b/src/context/LocaleProvider/index.ts index 33a052a1..a94fcf3e 100644 --- a/src/context/LocaleProvider/index.ts +++ b/src/context/LocaleProvider/index.ts @@ -1 +1 @@ -export { default, useLanguage, useLocales, useSetLocale } from "./LocaleProvider"; +export { default, useLanguage } from "./LocaleProvider"; diff --git a/src/context/LocaleProvider/localeContext.tsx b/src/context/LocaleProvider/localeContext.tsx index b74720f4..9627eb7d 100644 --- a/src/context/LocaleProvider/localeContext.tsx +++ b/src/context/LocaleProvider/localeContext.tsx @@ -3,7 +3,5 @@ import { locales } from "./locales"; import { LocaleContextType } from "./types"; export const localeContext = createContext({ - localesData: locales.getLocales(), - currentLocale: locales.getLocales()[0], - setCurrentLocale: () => {} + currentLocale: locales.getLocales().filter((locale) => locale.id === "en")[0] }); diff --git a/src/context/LocaleProvider/locales.ts b/src/context/LocaleProvider/locales.ts index b0b15182..d9331792 100644 --- a/src/context/LocaleProvider/locales.ts +++ b/src/context/LocaleProvider/locales.ts @@ -2,10 +2,19 @@ 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, @@ -13,10 +22,16 @@ export const localesData: LocaleType[] = [ 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", @@ -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 } ]; diff --git a/src/context/LocaleProvider/types.ts b/src/context/LocaleProvider/types.ts index 7f78d59c..ede53218 100644 --- a/src/context/LocaleProvider/types.ts +++ b/src/context/LocaleProvider/types.ts @@ -3,8 +3,6 @@ import { LangCodes } from "@/types/global"; export type LocaleContextType = { currentLocale: LocaleType; - localesData: LocaleType[]; - setCurrentLocale: (locale: LocaleType) => void; }; export type LocaleProviderProps = { diff --git a/src/locales/fr.ts b/src/locales/fr.ts new file mode 100644 index 00000000..340f57e0 --- /dev/null +++ b/src/locales/fr.ts @@ -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" +}; diff --git a/src/locales/index.ts b/src/locales/index.ts index 914554ee..d1d62c23 100644 --- a/src/locales/index.ts +++ b/src/locales/index.ts @@ -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"; diff --git a/src/locales/it.ts b/src/locales/it.ts new file mode 100644 index 00000000..27632e40 --- /dev/null +++ b/src/locales/it.ts @@ -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" +}; diff --git a/src/locales/ptBR.ts b/src/locales/ptBR.ts new file mode 100644 index 00000000..be892b45 --- /dev/null +++ b/src/locales/ptBR.ts @@ -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" +}; diff --git a/src/types/global.ts b/src/types/global.ts index fd94bf5f..634f2ae7 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -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; @@ -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;