diff --git a/package.json b/package.json
index 6f512ac..da7ce49 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
"react-to-print": "^2.14.13",
"react-toastify": "^9.1.3",
"react-window": "^1.8.7",
+ "react-intl": "^6.4.7",
"redux": "^4.2.0",
"simplebar": "^5.3.8",
"simplebar-react": "^2.4.1",
diff --git a/src/components/I18nProvider.js b/src/components/I18nProvider.js
new file mode 100644
index 0000000..3185ff5
--- /dev/null
+++ b/src/components/I18nProvider.js
@@ -0,0 +1,47 @@
+import React, {useState, useEffect, createContext} from 'react';
+import { IntlProvider } from 'react-intl';
+import enMessages from '../translations/en.json';
+import cnMessages from '../translations/zh-CN.json';
+import hkMessages from '../translations/zh-HK.json';
+
+const LocaleContext = createContext();
+
+export const I18nProvider = ({ children }) => {
+ const systemMessages = {
+ "en": enMessages,
+ "zh": hkMessages,
+ "zh-HK": hkMessages,
+ "zh-CN": cnMessages
+ };
+
+ const [locale, setLocale] = useState('en'); // Default locale, you can change this as per your requirement
+ const [messages, setMessages] = useState(systemMessages[locale]);
+
+ useEffect(() => {
+ if(localStorage.getItem('locale') === null){
+ //no locale case
+ localStorage.setItem('locale','en');
+ }
+ else{
+ setLocale(localStorage.getItem('locale'));
+ }
+ }, []);
+ useEffect(() => {
+ // Load the messages for the selected locale
+ const fetchMessages = async () => {
+ setMessages(systemMessages[locale]);
+ };
+
+ fetchMessages();
+ }, [locale]);
+
+ return (
+
+
+ {children}
+
+
+ );
+}
+
+export default LocaleContext;
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 5efaa37..b612d1b 100644
--- a/src/index.js
+++ b/src/index.js
@@ -16,6 +16,7 @@ import 'assets/third-party/apex-chart.css';
import App from './App';
import { store } from 'store';
import reportWebVitals from './reportWebVitals';
+import {I18nProvider} from "./components/I18nProvider";
// ==============================|| MAIN - REACT DOM RENDER ||============================== //
@@ -26,9 +27,11 @@ const root = createRoot(container); // createRoot(container!) if you use TypeScr
root.render(
-
+
+
-
+
+
);
diff --git a/src/layout/MainLayout/Header/HeaderContent/LocaleSelector.js b/src/layout/MainLayout/Header/HeaderContent/LocaleSelector.js
new file mode 100644
index 0000000..3d276ee
--- /dev/null
+++ b/src/layout/MainLayout/Header/HeaderContent/LocaleSelector.js
@@ -0,0 +1,142 @@
+import {useContext, useRef, useState} from 'react';
+import ListItem from '@mui/material/ListItem';
+// material-ui
+import { useTheme } from '@mui/material/styles';
+import {
+ Box,
+ ClickAwayListener,
+ IconButton,
+ List,
+ ListItemButton,
+ ListItemText,
+ Paper,
+ Popper,
+ useMediaQuery
+} from '@mui/material';
+
+import Transitions from 'components/@extended/Transitions';
+import LanguageIcon from '@mui/icons-material/Language';
+import {FormattedMessage} from "react-intl";
+import * as React from "react";
+import LocaleContext from "../../../../components/I18nProvider";
+
+// ==============================|| HEADER CONTENT - NOTIFICATION ||============================== //
+
+const LocaleSelector = () => {
+ const theme = useTheme();
+ const matchesXs = useMediaQuery(theme.breakpoints.down('md'));
+ const { setLocale } = useContext(LocaleContext);
+
+ const anchorRef = useRef(null);
+ const [open, setOpen] = useState(false);
+ const handleToggle = () => {
+ setOpen((prevOpen) => !prevOpen);
+ };
+
+
+ const handleClose = (event) => {
+ if (anchorRef.current && anchorRef.current.contains(event.target)) {
+ return;
+ }
+ setOpen(false);
+ };
+
+ const iconBackColorOpen = 'grey.300';
+ const iconBackColor = 'grey.100';
+
+ return (
+
+
+
+
+
+ {({ TransitionProps }) => (
+
+
+
+
+
+ {
+ setLocale("en")
+ localStorage.setItem('locale','en');
+ }}
+ >
+
+ />
+
+
+
+ {
+ setLocale("zh-HK")
+ localStorage.setItem('locale','zh-HK');
+ }}
+ >
+
+ />
+
+
+
+ {
+ setLocale("zh-CN")
+ localStorage.setItem('locale','zh-CN');
+ }}
+ >
+
+ />
+
+
+
+
+
+
+ )}
+
+
+ );
+};
+
+export default LocaleSelector;
diff --git a/src/layout/MainLayout/Header/HeaderContent/index.js b/src/layout/MainLayout/Header/HeaderContent/index.js
index 7d2e59a..a4cf253 100644
--- a/src/layout/MainLayout/Header/HeaderContent/index.js
+++ b/src/layout/MainLayout/Header/HeaderContent/index.js
@@ -7,6 +7,7 @@ import { Button ,Box } from '@mui/material';
// project import
// import Search from './Search';
import Profile from './Profile';
+import LocaleSelector from "./LocaleSelector";
// import Notification from './Notification';
// import MobileSection from './MobileSection';
@@ -34,7 +35,7 @@ const HeaderContent = () => {
>
*/}
-
+
{/* */}
{/* */}
diff --git a/src/layout/MainLayout/Header/index.js b/src/layout/MainLayout/Header/index.js
index 1edb078..93cb15e 100644
--- a/src/layout/MainLayout/Header/index.js
+++ b/src/layout/MainLayout/Header/index.js
@@ -50,6 +50,7 @@ import * as UrlUtils from "utils/ApiPathConst"
// import { MenuFoldOutlined,MenuOutlined } from '@ant-design/icons';
// import { AppBar } from '../../../../node_modules/@mui/material/index';
import { Link } from "react-router-dom";
+import LocaleSelector from "./HeaderContent/LocaleSelector";
const drawerWidth = 240;
@@ -383,6 +384,8 @@ function Header(props) {
+
+
{/* */}
diff --git a/src/pages/authentication/auth-forms/AuthLoginCustom.js b/src/pages/authentication/auth-forms/AuthLoginCustom.js
index 7358440..03d5a1b 100644
--- a/src/pages/authentication/auth-forms/AuthLoginCustom.js
+++ b/src/pages/authentication/auth-forms/AuthLoginCustom.js
@@ -43,6 +43,7 @@ import { useDispatch } from "react-redux";
import { handleLogin } from "auth/index";
import useJwt from "../../../auth/jwt/useJwt";
import { handleLogoutFunction } from 'auth/index';
+import {FormattedMessage} from "react-intl";
// ============================|| FIREBASE - LOGIN ||============================ //
const AuthLoginCustom = () => {
@@ -214,7 +215,11 @@ const AuthLoginCustom = () => {
- 用戶登入名稱
+
+
+
+
+