mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-09 19:29:45 -06:00
refactor i18n
This commit is contained in:
16
client/src/Components/I18nLoader/index.jsx
Normal file
16
client/src/Components/I18nLoader/index.jsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import i18n from "../../Utils/i18n";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useEffect } from "react";
|
||||
const I18nLoader = () => {
|
||||
const language = useSelector((state) => state.ui.language);
|
||||
|
||||
useEffect(() => {
|
||||
if (language && i18n.language !== language) {
|
||||
i18n.changeLanguage(language);
|
||||
}
|
||||
}, [language]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default I18nLoader;
|
||||
@@ -164,7 +164,8 @@ Select.propTypes = {
|
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
items: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
_id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
_id: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool])
|
||||
.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
})
|
||||
).isRequired,
|
||||
|
||||
@@ -3,15 +3,17 @@ import { Box, MenuItem, Select, Stack } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import "flag-icons/css/flag-icons.min.css";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { setLanguage } from "../Features/UI/uiSlice";
|
||||
|
||||
const LanguageSelector = () => {
|
||||
const { i18n } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const { language } = useSelector((state) => state.ui);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const handleChange = (event) => {
|
||||
const newLang = event.target.value;
|
||||
i18n.changeLanguage(newLang);
|
||||
dispatch(setLanguage(newLang));
|
||||
};
|
||||
|
||||
const languages = Object.keys(i18n.options.resources || {});
|
||||
@@ -32,7 +34,6 @@ const LanguageSelector = () => {
|
||||
}
|
||||
if (parsedLang.includes("-")) {
|
||||
parsedLang = parsedLang.split("-")[1].toLowerCase();
|
||||
console.log("parsedLang", parsedLang);
|
||||
}
|
||||
|
||||
const flag = parsedLang ? `fi fi-${parsedLang}` : null;
|
||||
|
||||
@@ -5,7 +5,6 @@ const initialState = {
|
||||
isLoading: false,
|
||||
apiBaseUrl: "",
|
||||
logLevel: "debug",
|
||||
language: "gb",
|
||||
pagespeedApiKey: "",
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ const initialState = {
|
||||
greeting: { index: 0, lastUpdate: null },
|
||||
timezone: "America/Toronto",
|
||||
distributedUptimeEnabled: false,
|
||||
language: "gb",
|
||||
language: "en",
|
||||
starPromptOpen: true,
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ const uiSlice = createSlice({
|
||||
setTimezone(state, action) {
|
||||
state.timezone = action.payload.timezone;
|
||||
},
|
||||
setLanguage(state, action) {
|
||||
setLanguage: (state, action) => {
|
||||
state.language = action.payload;
|
||||
},
|
||||
setStarPromptOpen: (state, action) => {
|
||||
|
||||
@@ -22,7 +22,7 @@ const SettingsURL = ({ HEADING_SX, handleChange, showURL }) => {
|
||||
<Select
|
||||
name="showURL"
|
||||
label={t("settingsURLSelectTitle")}
|
||||
value={showURL}
|
||||
value={showURL || ""}
|
||||
onChange={handleChange}
|
||||
items={[
|
||||
{ _id: true, name: t("settingsURLEnabled") },
|
||||
|
||||
@@ -93,7 +93,6 @@ const Settings = () => {
|
||||
|
||||
if (name === "language") {
|
||||
dispatch(setLanguage(value));
|
||||
i18n.changeLanguage(value);
|
||||
}
|
||||
|
||||
if (name === "deleteStats") {
|
||||
|
||||
@@ -17,14 +17,17 @@ const StatusBoxes = ({ shouldRender, monitorsSummary }) => {
|
||||
>
|
||||
<StatusBox
|
||||
title={t("monitorStatus.up")}
|
||||
status="up"
|
||||
value={monitorsSummary?.upMonitors ?? 0}
|
||||
/>
|
||||
<StatusBox
|
||||
title={t("monitorStatus.down")}
|
||||
status="down"
|
||||
value={monitorsSummary?.downMonitors ?? 0}
|
||||
/>
|
||||
<StatusBox
|
||||
title={t("monitorStatus.paused")}
|
||||
status="paused"
|
||||
value={monitorsSummary?.pausedMonitors ?? 0}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
@@ -5,9 +5,8 @@ import Arrow from "../../../../../assets/icons/top-right-arrow.svg?react";
|
||||
import Background from "../../../../../assets/Images/background-grid.svg?react";
|
||||
import ClockSnooze from "../../../../../assets/icons/clock-snooze.svg?react";
|
||||
|
||||
const StatusBox = ({ title, value }) => {
|
||||
const StatusBox = ({ title, value, status }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
let sharedStyles = {
|
||||
position: "absolute",
|
||||
right: 8,
|
||||
@@ -17,21 +16,21 @@ const StatusBox = ({ title, value }) => {
|
||||
|
||||
let color;
|
||||
let icon;
|
||||
if (title === "up") {
|
||||
if (status === "up") {
|
||||
color = theme.palette.success.lowContrast;
|
||||
icon = (
|
||||
<Box sx={{ ...sharedStyles, top: 8 }}>
|
||||
<Arrow />
|
||||
</Box>
|
||||
);
|
||||
} else if (title === "down") {
|
||||
} else if (status === "down") {
|
||||
color = theme.palette.error.lowContrast;
|
||||
icon = (
|
||||
<Box sx={{ ...sharedStyles, transform: "rotate(180deg)", top: 5 }}>
|
||||
<Arrow />
|
||||
</Box>
|
||||
);
|
||||
} else if (title === "paused") {
|
||||
} else if (status === "paused") {
|
||||
color = theme.palette.warning.lowContrast;
|
||||
icon = (
|
||||
<Box sx={{ ...sharedStyles, top: 12, right: 12 }}>
|
||||
@@ -100,8 +99,9 @@ const StatusBox = ({ title, value }) => {
|
||||
};
|
||||
|
||||
StatusBox.propTypes = {
|
||||
title: PropTypes.oneOf(["up", "down", "paused"]).isRequired,
|
||||
title: PropTypes.string,
|
||||
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
|
||||
status: PropTypes.string,
|
||||
};
|
||||
|
||||
export default StatusBox;
|
||||
|
||||
@@ -4,7 +4,6 @@ const BASE_URL = import.meta.env.VITE_APP_API_BASE_URL;
|
||||
const FALLBACK_BASE_URL = "http://localhost:5000/api/v1";
|
||||
import { clearAuthState } from "../Features/Auth/authSlice";
|
||||
import { clearUptimeMonitorState } from "../Features/UptimeMonitors/uptimeMonitorsSlice";
|
||||
|
||||
class NetworkService {
|
||||
constructor(store, dispatch, navigate) {
|
||||
this.store = store;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import i18n from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import { setLanguage } from "../Features/UI/uiSlice";
|
||||
import store from "../store";
|
||||
|
||||
const primaryLanguage = "en";
|
||||
|
||||
// Load all translation files eagerly
|
||||
const translations = import.meta.glob("../locales/*.json", { eager: true });
|
||||
|
||||
const resources = {};
|
||||
@@ -15,12 +14,9 @@ Object.keys(translations).forEach((path) => {
|
||||
};
|
||||
});
|
||||
|
||||
const savedLanguage = store.getState()?.ui?.language;
|
||||
const initialLanguage = savedLanguage;
|
||||
|
||||
i18n.use(initReactI18next).init({
|
||||
resources,
|
||||
lng: initialLanguage,
|
||||
lng: primaryLanguage,
|
||||
fallbackLng: primaryLanguage,
|
||||
debug: import.meta.env.MODE === "development",
|
||||
ns: ["translation"],
|
||||
@@ -30,8 +26,4 @@ i18n.use(initReactI18next).init({
|
||||
},
|
||||
});
|
||||
|
||||
i18n.on("languageChanged", (lng) => {
|
||||
store.dispatch(setLanguage(lng));
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App.jsx";
|
||||
import "./index.css";
|
||||
import "./Utils/i18n";
|
||||
import { BrowserRouter as Router } from "react-router-dom";
|
||||
import { Provider } from "react-redux";
|
||||
import { persistor, store } from "./store";
|
||||
@@ -9,6 +8,7 @@ import { PersistGate } from "redux-persist/integration/react";
|
||||
import NetworkServiceProvider from "./Utils/NetworkServiceProvider.jsx";
|
||||
import { networkService } from "./Utils/NetworkService";
|
||||
export { networkService };
|
||||
import I18nLoader from "./Components/I18nLoader";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<Provider store={store}>
|
||||
@@ -16,6 +16,7 @@ ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
loading={null}
|
||||
persistor={persistor}
|
||||
>
|
||||
<I18nLoader />
|
||||
<Router>
|
||||
<NetworkServiceProvider>
|
||||
<App />
|
||||
|
||||
Reference in New Issue
Block a user