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;
- }
-}