From 40fa1013fb42ac971d02465dcb776d712412e1d1 Mon Sep 17 00:00:00 2001 From: amalv <1252707+amalv@users.noreply.github.com> Date: Wed, 27 Dec 2023 18:14:41 +0100 Subject: [PATCH] feat: add theme selector and persistence - Add a theme selector switch that allows users to toggle between light and dark modes - Persist the selected theme across page refreshes using localStorage - Adjust card and page contrast for better visibility in both light and dark modes --- package-lock.json | 184 ++++++++++-------- package.json | 5 +- src/App.tsx | 21 +- src/apolloClient.ts | 25 ++- src/components/LibraryPage/LibraryPage.tsx | 14 +- .../components/BookCard/BookCard.styles.ts | 4 +- .../components/ThemeSwitch/ThemeSwitch.tsx | 31 +++ .../components/ThemeSwitch/index.ts | 1 + .../LibraryPage/components/index.ts | 1 + src/index.css | 13 -- 10 files changed, 194 insertions(+), 105 deletions(-) create mode 100644 src/components/LibraryPage/components/ThemeSwitch/ThemeSwitch.tsx create mode 100644 src/components/LibraryPage/components/ThemeSwitch/index.ts diff --git a/package-lock.json b/package-lock.json index 9a601bc..adfd297 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,12 @@ "dependencies": { "@apollo/client": "^3.8.7", "@auth0/auth0-react": "^2.2.4", - "@emotion/react": "^11.11.1", + "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@faker-js/faker": "^8.2.0", "@fontsource/roboto": "^5.0.8", - "@mui/material": "^5.14.13", + "@mui/icons-material": "^5.15.2", + "@mui/material": "^5.15.2", "graphql": "^16.8.1", "react": "^18.2.0", "react-dom": "^18.2.0" @@ -421,9 +422,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz", + "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -568,14 +569,14 @@ "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "node_modules/@emotion/react": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", - "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "version": "11.11.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.3.tgz", + "integrity": "sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==", "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.2", + "@emotion/serialize": "^1.1.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", "@emotion/utils": "^1.2.1", "@emotion/weak-memoize": "^0.3.1", @@ -591,9 +592,9 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", - "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", "dependencies": { "@emotion/hash": "^0.9.1", "@emotion/memoize": "^0.8.1", @@ -1091,9 +1092,9 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", - "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.2.tgz", + "integrity": "sha512-Ii3MrfY/GAIN3OhXNzpCKaLxHQfJF9qvwq/kEJYdqDxeIHa01K8sldugal6TmeeXl+WMvhv9cnVzUTaFFJF09A==", "dependencies": { "@floating-ui/utils": "^0.1.3" } @@ -1108,9 +1109,9 @@ } }, "node_modules/@floating-ui/react-dom": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", - "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz", + "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==", "dependencies": { "@floating-ui/dom": "^1.5.1" }, @@ -1339,14 +1340,14 @@ } }, "node_modules/@mui/base": { - "version": "5.0.0-beta.19", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.19.tgz", - "integrity": "sha512-maNBgAscddyPNzFZQUJDF/puxM27Li+NqSBsr/lAP8TLns2VvWS2SoL3OKFOIoRnAMKGY/Ic6Aot6gCYeQnssA==", - "dependencies": { - "@babel/runtime": "^7.23.1", - "@floating-ui/react-dom": "^2.0.2", - "@mui/types": "^7.2.6", - "@mui/utils": "^5.14.13", + "version": "5.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.29.tgz", + "integrity": "sha512-OXfUssYrB6ch/xpBVHMKAjThPlI9VyGGKdvQLMXef2j39wXfcxPlUVQlwia/lmE3rxWIGvbwkZsDtNYzLMsDUg==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@floating-ui/react-dom": "^2.0.4", + "@mui/types": "^7.2.11", + "@mui/utils": "^5.15.2", "@popperjs/core": "^2.11.8", "clsx": "^2.0.0", "prop-types": "^15.8.1" @@ -1356,7 +1357,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -1370,26 +1371,51 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.14.13", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.13.tgz", - "integrity": "sha512-3ZUbzcH4yloLKlV6Y+S0Edn2wef9t+EGHSfEkwVCn8E0ULdshifEFgfEroKRegQifDIwcKS/ofccxuZ8njTAYg==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.2.tgz", + "integrity": "sha512-0vk4ckS2w1F5PmkSXSd7F/QuRlNcPqWTJ8CPl+HQRLTIhJVS/VKEI+3dQufOdKfn2wS+ecnvlvXerbugs+xZ8Q==", "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.2.tgz", + "integrity": "sha512-Vs0Z6cd6ieTavMjqPvIJJfwsKaCLdRSErk5LjKdZlBqk7r2SR6roDyhVTQuZOeCzjEFj0qZ4iVPp2DJZRwuYbw==", + "dependencies": { + "@babel/runtime": "^7.23.6" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@mui/material": { - "version": "5.14.13", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.13.tgz", - "integrity": "sha512-iPEFwhoVG789UVsXX4gqd1eJUlcLW1oceqwJYQN8Z4MpcAKfL9Lv3fda65AwG7pQ5lf+d7IbHzm4m48SWZxI2g==", - "dependencies": { - "@babel/runtime": "^7.23.1", - "@mui/base": "5.0.0-beta.19", - "@mui/core-downloads-tracker": "^5.14.13", - "@mui/system": "^5.14.13", - "@mui/types": "^7.2.6", - "@mui/utils": "^5.14.13", - "@types/react-transition-group": "^4.4.7", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.2.tgz", + "integrity": "sha512-JnoIrpNmEHG5uC1IyEdgsnDiaiuCZnUIh7f9oeAr87AvBmNiEJPbo7XrD7kBTFWwp+b97rQ12QdSs9CLhT2n/A==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@mui/base": "5.0.0-beta.29", + "@mui/core-downloads-tracker": "^5.15.2", + "@mui/system": "^5.15.2", + "@mui/types": "^7.2.11", + "@mui/utils": "^5.15.2", + "@types/react-transition-group": "^4.4.10", "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1", @@ -1401,7 +1427,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -1423,12 +1449,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.14.13", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.13.tgz", - "integrity": "sha512-5EFqk4tqiSwPguj4NW/6bUf4u1qoUWXy9lrKfNh9H6oAohM+Ijv/7qSxFjnxPGBctj469/Sc5aKAR35ILBKZLQ==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.2.tgz", + "integrity": "sha512-KlXx5TH1Mw9omSY+Q6rz5TA/P71meSYaAOeopiW8s6o433+fnOxS17rZbmd1RnDZGCo+j24TfCavQuCMBAZnQA==", "dependencies": { - "@babel/runtime": "^7.23.1", - "@mui/utils": "^5.14.13", + "@babel/runtime": "^7.23.6", + "@mui/utils": "^5.15.2", "prop-types": "^15.8.1" }, "engines": { @@ -1436,7 +1462,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -1449,11 +1475,11 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.14.13", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.13.tgz", - "integrity": "sha512-1ff/egFQl26hiwcUtCMKAkp4Sgqpm3qIewmXq+GN27fb44lDIACquehMFBuadOjceOFmbIXbayzbA46ZyqFYzA==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.2.tgz", + "integrity": "sha512-fYEN3IZzbebeHwAmQHhxwruiOIi8W74709qXg/7tgtHV4byQSmPgnnKsZkg0hFlzjEbcJIRZyZI0qEecgpR2cg==", "dependencies": { - "@babel/runtime": "^7.23.1", + "@babel/runtime": "^7.23.6", "@emotion/cache": "^11.11.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -1463,7 +1489,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.4.1", @@ -1480,15 +1506,15 @@ } }, "node_modules/@mui/system": { - "version": "5.14.13", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.13.tgz", - "integrity": "sha512-+5+Dx50lG4csbx2sGjrKLozXQJeCpJ4dIBZolyFLkZ+XphD1keQWouLUvJkPQ3MSglLLKuD37pp52YjMncZMEQ==", - "dependencies": { - "@babel/runtime": "^7.23.1", - "@mui/private-theming": "^5.14.13", - "@mui/styled-engine": "^5.14.13", - "@mui/types": "^7.2.6", - "@mui/utils": "^5.14.13", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.2.tgz", + "integrity": "sha512-I7CzLiHDtU/BTobJgSk+wPGGWG95K8lYfdFEnq//wOgSrLDAdOVvl2gleDxJWO+yAbGz4RKEOnR9KuD+xQZH4A==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@mui/private-theming": "^5.15.2", + "@mui/styled-engine": "^5.15.2", + "@mui/types": "^7.2.11", + "@mui/utils": "^5.15.2", "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -1498,7 +1524,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -1519,9 +1545,9 @@ } }, "node_modules/@mui/types": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.6.tgz", - "integrity": "sha512-7sjLQrUmBwufm/M7jw/quNiPK/oor2+pGUQP2CULRcFCArYTq78oJ3D5esTaL0UMkXKJvDqXn6Ike69yAOBQng==", + "version": "7.2.11", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.11.tgz", + "integrity": "sha512-KWe/QTEsFFlFSH+qRYf3zoFEj3z67s+qAuSnMMg+gFwbxG7P96Hm6g300inQL1Wy///gSRb8juX7Wafvp93m3w==", "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0" }, @@ -1532,12 +1558,12 @@ } }, "node_modules/@mui/utils": { - "version": "5.14.13", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.13.tgz", - "integrity": "sha512-2AFpyXWw7uDCIqRu7eU2i/EplZtks5LAMzQvIhC79sPV9IhOZU2qwOWVnPtdctRXiQJOAaXulg+A37pfhEueQw==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.2.tgz", + "integrity": "sha512-6dGM9/guFKBlFRHA7/mbM+E7wE7CYDy9Ny4JLtD3J+NTyhi8nd8YxlzgAgTaTVqY0BpdQ2zdfB/q6+p2EdGM0w==", "dependencies": { - "@babel/runtime": "^7.23.1", - "@types/prop-types": "^15.7.7", + "@babel/runtime": "^7.23.6", + "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -1546,7 +1572,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -2828,9 +2854,9 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "node_modules/@types/prop-types": { - "version": "15.7.8", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz", - "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==" + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { "version": "18.2.28", @@ -2852,9 +2878,9 @@ } }, "node_modules/@types/react-transition-group": { - "version": "4.4.7", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.7.tgz", - "integrity": "sha512-ICCyBl5mvyqYp8Qeq9B5G/fyBSRC0zx3XM3sCC6KkcMsNeAHqXBKkmat4GqdJET5jtYUpZXrxI5flve5qhi2Eg==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "dependencies": { "@types/react": "*" } diff --git a/package.json b/package.json index db54d81..00e6ca8 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,12 @@ "dependencies": { "@apollo/client": "^3.8.7", "@auth0/auth0-react": "^2.2.4", - "@emotion/react": "^11.11.1", + "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@faker-js/faker": "^8.2.0", "@fontsource/roboto": "^5.0.8", - "@mui/material": "^5.14.13", + "@mui/icons-material": "^5.15.2", + "@mui/material": "^5.15.2", "graphql": "^16.8.1", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/src/App.tsx b/src/App.tsx index 5e0d0b0..0f36954 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,15 +1,17 @@ -import { ApolloProvider } from "@apollo/client"; +import { Box } from "@mui/material"; +import { ApolloProvider, useReactiveVar } from "@apollo/client"; import { Auth0Provider } from "@auth0/auth0-react"; import { client } from "./apolloClient"; import { LibraryPage } from "./components/"; -import { createTheme, ThemeProvider, useMediaQuery } from "@mui/material"; +import { createTheme, ThemeProvider } from "@mui/material"; +import { darkModeVar } from "./apolloClient"; const App = () => { - const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)"); + const darkMode = useReactiveVar(darkModeVar) as boolean; const theme = createTheme({ palette: { - mode: prefersDarkMode ? "dark" : "light", + mode: darkMode ? "dark" : "light", primary: { light: "#a0522d", main: "#a0522d", @@ -58,7 +60,16 @@ const App = () => { > - + + + diff --git a/src/apolloClient.ts b/src/apolloClient.ts index 84f8ac7..6ba8b90 100644 --- a/src/apolloClient.ts +++ b/src/apolloClient.ts @@ -1,6 +1,15 @@ -import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client"; +import { + ApolloClient, + InMemoryCache, + createHttpLink, + makeVar, +} from "@apollo/client"; import { setContext } from "@apollo/client/link/context"; +export const darkModeVar = makeVar( + window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches +); + const API_URL = import.meta.env.VITE_API_URL_PRODUCTION || import.meta.env.VITE_API_URL_DEVELOPMENT; @@ -22,5 +31,17 @@ const authLink = setContext((_, { headers }) => { export const client = new ApolloClient({ link: authLink.concat(httpLink), - cache: new InMemoryCache(), + cache: new InMemoryCache({ + typePolicies: { + Query: { + fields: { + darkMode: { + read() { + return darkModeVar(); + }, + }, + }, + }, + }, + }), }); diff --git a/src/components/LibraryPage/LibraryPage.tsx b/src/components/LibraryPage/LibraryPage.tsx index a7bdb56..2cc7c41 100644 --- a/src/components/LibraryPage/LibraryPage.tsx +++ b/src/components/LibraryPage/LibraryPage.tsx @@ -1,7 +1,7 @@ import { useLibraryPage } from "./hooks"; import { Alert, Box, Grid, Snackbar } from "@mui/material"; import { Root } from "./LibraryPage.styles"; -import { Books, Search, UserAuthentication } from "./components"; +import { Books, Search, ThemeSwitch, UserAuthentication } from "./components"; export const LibraryPage = () => { const { search, setSearch, debouncedSearch, error, setError } = @@ -22,8 +22,16 @@ export const LibraryPage = () => { - - + + + + + diff --git a/src/components/LibraryPage/components/Books/components/BookCard/BookCard.styles.ts b/src/components/LibraryPage/components/Books/components/BookCard/BookCard.styles.ts index 783a865..42097c2 100644 --- a/src/components/LibraryPage/components/Books/components/BookCard/BookCard.styles.ts +++ b/src/components/LibraryPage/components/Books/components/BookCard/BookCard.styles.ts @@ -12,7 +12,9 @@ export const CardWrapper = styled(Card)( border-radius: 8px; overflow: hidden; transition: box-shadow 0.3s ease-in-out, transform 0.5s ease-in-out; - background: ${theme.palette.background.paper}; + background: ${ + theme.palette.mode === "dark" ? "#333" : theme.palette.background.paper + }; &:hover { box-shadow: 0 3px 6px ${theme.palette.action.hover}; diff --git a/src/components/LibraryPage/components/ThemeSwitch/ThemeSwitch.tsx b/src/components/LibraryPage/components/ThemeSwitch/ThemeSwitch.tsx new file mode 100644 index 0000000..7c453cb --- /dev/null +++ b/src/components/LibraryPage/components/ThemeSwitch/ThemeSwitch.tsx @@ -0,0 +1,31 @@ +import { useEffect } from "react"; +import { Switch, FormControlLabel } from "@mui/material"; +import { useReactiveVar } from "@apollo/client"; +import { darkModeVar } from "../../../../apolloClient"; +import Brightness4 from "@mui/icons-material/Brightness4"; +import Brightness7 from "@mui/icons-material/Brightness7"; + +export const ThemeSwitch = () => { + const darkMode = useReactiveVar(darkModeVar) as boolean; + + useEffect(() => { + const savedTheme = localStorage.getItem("theme"); + if (savedTheme) { + darkModeVar(savedTheme === "dark"); + } + }, []); + + const handleThemeChange = () => { + const newDarkMode = !darkMode; + darkModeVar(newDarkMode); + localStorage.setItem("theme", newDarkMode ? "dark" : "light"); + }; + + return ( + } + label={darkMode ? : } + sx={{ mr: 0 }} + /> + ); +}; diff --git a/src/components/LibraryPage/components/ThemeSwitch/index.ts b/src/components/LibraryPage/components/ThemeSwitch/index.ts new file mode 100644 index 0000000..255aa74 --- /dev/null +++ b/src/components/LibraryPage/components/ThemeSwitch/index.ts @@ -0,0 +1 @@ +export * from "./ThemeSwitch"; diff --git a/src/components/LibraryPage/components/index.ts b/src/components/LibraryPage/components/index.ts index 0ddee35..37dc57a 100644 --- a/src/components/LibraryPage/components/index.ts +++ b/src/components/LibraryPage/components/index.ts @@ -1,3 +1,4 @@ export * from "./Books"; export * from "./Search"; +export * from "./ThemeSwitch"; export * from "./UserAuthentication"; diff --git a/src/index.css b/src/index.css index dd801ea..66f6c27 100644 --- a/src/index.css +++ b/src/index.css @@ -54,16 +54,3 @@ button:focus, button:focus-visible { outline: 4px auto -webkit-focus-ring-color; } - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -}