From 527543d79f486ddd13667e41df4f08c4b4fd2ca5 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 6 Feb 2026 20:32:10 +0000 Subject: [PATCH] base page, auth header, language and theme switches --- .../v2/design-elements/BasePage.tsx | 46 ++++++++ .../Components/v2/inputs/LanguageSelector.tsx | 100 ++++++++++++++++++ .../src/Components/v2/inputs/SwitchTheme.tsx | 48 +++++++++ client/src/Components/v2/inputs/index.tsx | 2 + client/src/Pages/About/index.jsx | 18 ---- client/src/Pages/Auth/Login/index.tsx | 14 +++ .../Pages/Auth/Login/{index.jsx => old.jsx} | 0 .../Auth/components/HeaderAuthControls.tsx | 53 ++++++++++ client/src/Routes/index.jsx | 10 +- client/src/locales/en.json | 20 ++++ 10 files changed, 291 insertions(+), 20 deletions(-) create mode 100644 client/src/Components/v2/inputs/LanguageSelector.tsx create mode 100644 client/src/Components/v2/inputs/SwitchTheme.tsx delete mode 100644 client/src/Pages/About/index.jsx create mode 100644 client/src/Pages/Auth/Login/index.tsx rename client/src/Pages/Auth/Login/{index.jsx => old.jsx} (100%) create mode 100644 client/src/Pages/Auth/components/HeaderAuthControls.tsx diff --git a/client/src/Components/v2/design-elements/BasePage.tsx b/client/src/Components/v2/design-elements/BasePage.tsx index 22330f46d..b0f5ee26f 100644 --- a/client/src/Components/v2/design-elements/BasePage.tsx +++ b/client/src/Components/v2/design-elements/BasePage.tsx @@ -1,4 +1,6 @@ +import Logo from "@/assets/icons/checkmate-icon.svg?react"; import Stack from "@mui/material/Stack"; +import Box from "@mui/material/Box"; import Alert from "@mui/material/Alert"; import Link from "@mui/material/Link"; import { @@ -9,6 +11,7 @@ import { } from "@/Components/v2/design-elements/Fallback"; import { Breadcrumb } from "@/Components/v2/design-elements/Breadcrumb"; import CircularProgress from "@mui/material/CircularProgress"; +import { HeaderAuthControls } from "@/Pages/Auth/components/HeaderAuthControls"; import type { StackProps } from "@mui/material/Stack"; import { useTheme } from "@mui/material/styles"; @@ -201,3 +204,46 @@ export const MonitorBasePageWithStates = ({ ); }; + +interface BaseAuthPageProps extends React.PropsWithChildren { + title: string; + subtitle: string; +} + +export const BaseAuthPage = ({ title, subtitle, children }: BaseAuthPageProps) => { + const theme = useTheme(); + return ( + + + + + + + + {title} + + {subtitle} + + {children} + + ); +}; diff --git a/client/src/Components/v2/inputs/LanguageSelector.tsx b/client/src/Components/v2/inputs/LanguageSelector.tsx new file mode 100644 index 000000000..2a1274ef2 --- /dev/null +++ b/client/src/Components/v2/inputs/LanguageSelector.tsx @@ -0,0 +1,100 @@ +import Stack from "@mui/material/Stack"; +import Box from "@mui/material/Box"; +import MenuItem from "@mui/material/MenuItem"; +import { Select } from "@/Components/v2/inputs"; +import "flag-icons/css/flag-icons.min.css"; + +import { useTranslation } from "react-i18next"; +import { useTheme } from "@mui/material"; +import { useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import { setLanguage } from "@/Features/UI/uiSlice"; +import type { RootState } from "@/Types/state"; + +const langMap: Record = { + cs: "cz", + ja: "jp", + uk: "ua", + vi: "vn", +}; + +export const LanguageSelector = () => { + const { i18n } = useTranslation(); + const theme = useTheme(); + const { language = "en" } = useSelector((state: RootState) => state.ui); + const dispatch = useDispatch(); + const handleChange = (event: any) => { + const newLang = event.target.value; + dispatch(setLanguage(newLang)); + }; + + const languages = Object.keys(i18n.options.resources || {}); + + return ( + + ); +}; + +export default LanguageSelector; diff --git a/client/src/Components/v2/inputs/SwitchTheme.tsx b/client/src/Components/v2/inputs/SwitchTheme.tsx new file mode 100644 index 000000000..e609f50fb --- /dev/null +++ b/client/src/Components/v2/inputs/SwitchTheme.tsx @@ -0,0 +1,48 @@ +import IconButton from "@mui/material/IconButton"; + +import { Moon, Sun } from "lucide-react"; + +import { setMode } from "@/Features/UI/uiSlice.js"; +import { useTheme } from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import type { RootState } from "@/Types/state"; + +export const SwitchTheme = () => { + const mode = useSelector((state: RootState) => state.ui.mode); + const dispatch = useDispatch(); + const theme = useTheme(); + + const handleChange = () => { + dispatch(setMode(mode === "light" ? "dark" : "light")); + }; + return ( + + {mode === "light" ? ( + + ) : ( + + )} + + ); +}; diff --git a/client/src/Components/v2/inputs/index.tsx b/client/src/Components/v2/inputs/index.tsx index 25d9febe3..78f1a51cf 100644 --- a/client/src/Components/v2/inputs/index.tsx +++ b/client/src/Components/v2/inputs/index.tsx @@ -16,3 +16,5 @@ export * from "./ImageUpload"; export * from "./ColorPicker"; export { DatePickerComponent as DatePicker } from "./DatePicker"; export { TimePickerComponent as TimePicker } from "./TimePicker"; +export * from "./LanguageSelector"; +export * from "./SwitchTheme"; diff --git a/client/src/Pages/About/index.jsx b/client/src/Pages/About/index.jsx deleted file mode 100644 index ff7bb6c6b..000000000 --- a/client/src/Pages/About/index.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; -import AppBar from "@/Components/v1/Common/AppBar.jsx"; -import Footer from "@/Components/v1/Common/Footer.jsx"; -import { useTranslation } from "react-i18next"; - -const AboutUs = () => { - const { t } = useTranslation(); - - return ( -
- -

{t("aboutus")}

-
-
- ); -}; - -export default AboutUs; diff --git a/client/src/Pages/Auth/Login/index.tsx b/client/src/Pages/Auth/Login/index.tsx new file mode 100644 index 000000000..5756f18cb --- /dev/null +++ b/client/src/Pages/Auth/Login/index.tsx @@ -0,0 +1,14 @@ +import { BaseAuthPage } from "@/Components/v2/design-elements"; + +import { useTranslation } from "react-i18next"; +const LoginPage = () => { + const { t } = useTranslation(); + return ( + + ); +}; + +export default LoginPage; diff --git a/client/src/Pages/Auth/Login/index.jsx b/client/src/Pages/Auth/Login/old.jsx similarity index 100% rename from client/src/Pages/Auth/Login/index.jsx rename to client/src/Pages/Auth/Login/old.jsx diff --git a/client/src/Pages/Auth/components/HeaderAuthControls.tsx b/client/src/Pages/Auth/components/HeaderAuthControls.tsx new file mode 100644 index 000000000..a62048372 --- /dev/null +++ b/client/src/Pages/Auth/components/HeaderAuthControls.tsx @@ -0,0 +1,53 @@ +import Stack, { type StackProps } from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import Logo from "@/assets/icons/checkmate-icon.svg?react"; +import { LanguageSelector, SwitchTheme } from "@/Components/v2/inputs"; + +import { useTheme } from "@mui/material/styles"; +import { useTranslation } from "react-i18next"; + +interface HeaderAuthControlsProps extends StackProps { + hideLogo?: boolean; +} + +export const HeaderAuthControls = ({ + hideLogo = false, + ...stackProps +}: HeaderAuthControlsProps) => { + // Hooks + const theme = useTheme(); + const { t } = useTranslation(); + + return ( + + + {!hideLogo && ( + <> + + {t("common.appName")} + + )} + + + + + + + ); +}; diff --git a/client/src/Routes/index.jsx b/client/src/Routes/index.jsx index 22b5b446a..b281b359e 100644 --- a/client/src/Routes/index.jsx +++ b/client/src/Routes/index.jsx @@ -7,7 +7,7 @@ import { Navigate, Route, Routes as LibRoutes } from "react-router"; import HomeLayout from "@/Components/v1/Layouts/HomeLayout"; import NotFound from "../Pages/NotFound/index.jsx"; // Auth -import AuthLogin from "../Pages/Auth/Login/index.jsx"; +import AuthLogin from "../Pages/Auth/Login"; import AuthRegister from "../Pages/Auth/Register/index.jsx"; import AuthForgotPassword from "../Pages/Auth/ForgotPassword.jsx"; import AuthCheckEmail from "../Pages/Auth/CheckEmail.jsx"; @@ -360,7 +360,13 @@ const Routes = () => { } + element={ + <> + + + + + } />