Skip to content

Commit

Permalink
Add support for dark mode
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandruIstrate committed Feb 3, 2024
1 parent b129ccc commit f266a65
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 33 deletions.
75 changes: 75 additions & 0 deletions salary-calc/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions salary-calc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"react-bootstrap": "^2.8.0",
"react-dom": "^18.2.0",
"react-i18next": "^14.0.1",
"react-responsive": "^9.0.2",
"react-router-dom": "^6.21.3",
"react-scripts": "5.0.1",
"react-select": "^5.8.0",
Expand Down
6 changes: 6 additions & 0 deletions salary-calc/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
"page": {
"title": "Salary Converter"
},
"themes": {
"title": "Theme",
"light": "Light",
"dark": "Dark",
"auto": "Automatic"
},
"banner": "Development Build",
"nav": {
"title": "Salary Converter"
Expand Down
47 changes: 39 additions & 8 deletions salary-calc/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ import ToastContainer from "react-bootstrap/ToastContainer";

import Select from "react-select";

import { useLocation, useNavigate } from "react-router-dom";
import { useMediaQuery } from "react-responsive";
import { countries } from "countries-list";
import { registerLocale, getName as getLocalCountryName } from "i18n-iso-countries";
import { isEqual } from "lodash";
import { useLocation, useNavigate } from "react-router-dom";
import { useTranslation, withTranslation, Trans } from "react-i18next";
import { polyfillCountryFlagEmojis } from "country-flag-emoji-polyfill";

Expand All @@ -33,6 +34,7 @@ import { WorldBankAPI } from "src/api/WorldBankAPI";
import { LocalStorage } from "src/utils/LocalStorage";

import { supportedLngs } from "src/i18n";
import { getThemes } from "src/themes";

import "./App.css";

Expand Down Expand Up @@ -140,6 +142,9 @@ function HistoryContent({ t, historyItems, onClick }) {
}

function App() {
// Translation
const { t, i18n } = useTranslation();

// App State
const [salary, setSalary] = useState(LocalStorage.salary ?? 0);
const [sourceCountry, setSourceCountry] = useState(
Expand All @@ -152,16 +157,13 @@ function App() {

const [showToast, setShowToast] = useState(false);

const [activeTheme, setActiveTheme] = useState(getThemes(t)[LocalStorage.theme ?? "auto"]);

// Navigation
const location = useLocation();
const navigate = useNavigate();

// Translation
const { t, i18n } = useTranslation();

// Translated components
const NavbarContentWrapped = withTranslation()(NavbarContent);
const FooterContentWrapped = withTranslation()(FooterContent);
const CountrySelectWrapped = withTranslation()(CountrySelect);
const HistoryContentWrapped = withTranslation()(HistoryContent);

Expand Down Expand Up @@ -311,6 +313,32 @@ function App() {
document.title = t("page.title");
}, [i18n, i18n.resolvedLanguage, t])

// Set a media query for when the user changes the system theme
const systemPrefersDark = useMediaQuery({
query: "(prefers-color-scheme: dark)"
});

// Set the page theme when it's changed
useEffect(() => {
// Store the result here
var theme = "light";

// Handle the special case when we don't have a theme set or it's set to auto
if (!activeTheme || activeTheme.id === "auto") {
// Set the theme based on user preference
theme = systemPrefersDark ? "dark" : 'light';
} else {
// Get the Bootstrap name of the theme and store it
theme = activeTheme.bsName;
}

// Set the theme on the document
document.documentElement.setAttribute("data-bs-theme", theme);

// Also persist the theme selection between sessions
LocalStorage.theme = theme;
}, [activeTheme, systemPrefersDark])

// UI Rendering Functions

const renderCalculatorArea = () => {
Expand Down Expand Up @@ -679,7 +707,10 @@ function App() {

{/* App Header */}
<header>
<NavbarContentWrapped />
<NavbarContent
activeTheme={activeTheme}
setActiveTheme={setActiveTheme}
/>
</header>

{/* Main Content */}
Expand Down Expand Up @@ -723,7 +754,7 @@ function App() {
{/* Footer */}
<footer className="footer font-small blue bg-light pt-4">
{/* Footer Content */}
<FooterContentWrapped />
<FooterContent />

{/* Copyright */}
<div className="footer-copyright text-center py-3">
Expand Down
4 changes: 3 additions & 1 deletion salary-calc/src/components/FooterContent.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Container from "react-bootstrap/Container";

import { withTranslation } from "react-i18next";

import NewTabLink from "src/components/NewTabLink";

function FooterContent({ t }) {
Expand Down Expand Up @@ -65,4 +67,4 @@ function FooterContent({ t }) {
)
}

export default FooterContent;
export default withTranslation()(FooterContent);
Loading

0 comments on commit f266a65

Please sign in to comment.