diff --git a/bookstore-frontend-react-app/src/App.css b/bookstore-frontend-react-app/src/App.css
index 2eb99bad..7096a6ea 100644
--- a/bookstore-frontend-react-app/src/App.css
+++ b/bookstore-frontend-react-app/src/App.css
@@ -1,80 +1,128 @@
@import url('https://fonts.googleapis.com/css2?family=Kaushan+Script&display=swap');
+@import url('./themes.css');
+
+#root {
+ background-color: var(--bg); /* background color variable */
+ color: var(--color-text);
+ height: 100vh;
+}
+
+#root main {
+ background-color: var(--bg)!important;
+}
body {
- margin: 0;
- padding: 0;
+ margin: 0;
+ padding: 0;
}
button {
- border-radius: 5px !important;
+ border-radius: 5px !important;
}
a {
- border-radius: 5px !important;
+ border-radius: 5px !important;
}
p {
- font-family: sans-serif !important;
+ font-family: sans-serif !important;
}
.bookstore-brand {
- font-family: 'Kaushan Script', cursive;
- font-size: 2em !important;
- font-weight: 800;
- clip-path: polygon(0 30%, 100% 11%, 100% 75%, 0 92%);
+ font-family: 'Kaushan Script', cursive;
+ font-size: 2em !important;
+ font-weight: 800;
+ clip-path: polygon(0 30%, 100% 11%, 100% 75%, 0 92%);
- background: rgb(2, 0, 36);
- background: linear-gradient(84deg, rgba(2, 0, 36, 1) 21%, rgba(0, 0, 179, 1) 63%, rgba(191, 0, 76, 1) 92%);
- padding: 5px;
+ background: rgb(2, 0, 36);
+ background: linear-gradient(84deg, rgba(2, 0, 36, 1) 21%, rgba(0, 0, 179, 1) 63%, rgba(191, 0, 76, 1) 92%);
+ padding: 5px;
}
.bookstore-brand:hover {
- color: aquamarine !important;
+ color: aquamarine !important;
}
.fp-container {
- position: fixed;
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
- background: #111c1fad;
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ background: #111c1fad;
}
.fp-container .fp-loader {
- top: 45%;
- left: 48%;
- z-index: 10000;
- position: absolute;
+ top: 45%;
+ left: 48%;
+ z-index: 10000;
+ position: absolute;
}
.pagination {
- display: flex;
- padding-left: 0;
- list-style: none;
- border-radius: 0.25rem;
+ display: flex;
+ padding-left: 0;
+ list-style: none;
+ border-radius: 0.25rem;
}
.page-item.active {
- z-index: 3;
- color: #fff;
- /* background-color: #d9230f; */
- /* border-color: #d9230f; */
+ z-index: 3;
+ color: #fff;
+ /* background-color: #d9230f; */
+ /* border-color: #d9230f; */
}
.page-item:first-child .page-link {
- margin-left: 0;
- border-top-left-radius: 0.25rem;
- border-bottom-left-radius: 0.25rem;
+ margin-left: 0;
+ border-top-left-radius: 0.25rem;
+ border-bottom-left-radius: 0.25rem;
}
.page-link {
- position: relative;
- display: block;
- padding: 0.5rem 0.75rem;
- margin-left: -1px;
- line-height: 1.25;
- color: #d9230f;
- background-color: #fff;
- border: 1px solid #eee;
+ position: relative;
+ display: block;
+ padding: 0.5rem 0.75rem;
+ margin-left: -1px;
+ line-height: 1.25;
+ color: #d9230f;
+ background-color: #fff;
+ border: 1px solid #eee;
}
+
+.row-container-fully-centered {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+}
+
+.card-body,
+.list-group-item
+{
+ background-color: var(--bg-panel)!important;
+}
+
+.table {
+ color: var(--color-text)!important;
+}
+
+.table-hover tbody tr:hover {
+ color: var(--color-text)!important;
+ background-color: var(--color-hover-row)!important;
+}
+
+.link-container a{
+ color: var(--color-link)!important;
+}
+
+.link-container a:hover,
+.nav-link:hover{
+ color: var(--color-hover)!important;
+ text-decoration-color: var(--color-hover);
+ -webkit-text-decoration-color: var(--color-hover);
+}
+
+.pagination .page-link {
+ border-radius: 5px;
+}
\ No newline at end of file
diff --git a/bookstore-frontend-react-app/src/actions/darkModeActions.js b/bookstore-frontend-react-app/src/actions/darkModeActions.js
new file mode 100644
index 00000000..c839d3d2
--- /dev/null
+++ b/bookstore-frontend-react-app/src/actions/darkModeActions.js
@@ -0,0 +1,9 @@
+import { DARK_MODE_ENABLE, DARK_MODE_DISABLE } from '../constants/darkModeConstants';
+
+export const ENABLE_DARK_MODE = () => (dispatch) => {
+ dispatch({ type: DARK_MODE_ENABLE });
+};
+
+export const DISABLE_DARK_MODE = () => (dispatch) => {
+ dispatch({ type: DARK_MODE_DISABLE });
+};
\ No newline at end of file
diff --git a/bookstore-frontend-react-app/src/components/CartItem.js b/bookstore-frontend-react-app/src/components/CartItem.js
index 8a35e6f2..3542d4e1 100644
--- a/bookstore-frontend-react-app/src/components/CartItem.js
+++ b/bookstore-frontend-react-app/src/components/CartItem.js
@@ -40,7 +40,7 @@ const CartItem = ({ item, addToCart }) => {
-
+
{item.productName}
diff --git a/bookstore-frontend-react-app/src/components/CheckoutSteps.js b/bookstore-frontend-react-app/src/components/CheckoutSteps.js
index 67c00446..a80ac78b 100644
--- a/bookstore-frontend-react-app/src/components/CheckoutSteps.js
+++ b/bookstore-frontend-react-app/src/components/CheckoutSteps.js
@@ -8,7 +8,9 @@ const CheckoutSteps = ({ step1, step2, step3, step4 }) => {
{step1 ? (
- Sign In >
+
+ Sign In >
+
) : (
Sign In
@@ -18,7 +20,9 @@ const CheckoutSteps = ({ step1, step2, step3, step4 }) => {
{step2 ? (
- Shipping >
+
+ Shipping >
+
) : (
Shipping
@@ -28,7 +32,9 @@ const CheckoutSteps = ({ step1, step2, step3, step4 }) => {
{step3 ? (
- Payment >
+
+ Payment >
+
) : (
Payment
@@ -38,7 +44,9 @@ const CheckoutSteps = ({ step1, step2, step3, step4 }) => {
{step4 ? (
- Place Order
+
+ Place Order
+
) : (
Place Order
diff --git a/bookstore-frontend-react-app/src/components/DarkModeToggle.js b/bookstore-frontend-react-app/src/components/DarkModeToggle.js
new file mode 100644
index 00000000..ac0efd5e
--- /dev/null
+++ b/bookstore-frontend-react-app/src/components/DarkModeToggle.js
@@ -0,0 +1,54 @@
+import React, { useEffect } from 'react';
+import Form from 'react-bootstrap/Form';
+import { useDispatch, useSelector } from 'react-redux';
+import { ENABLE_DARK_MODE, DISABLE_DARK_MODE } from '../actions/darkModeActions';
+
+const DarkModeToggle = () => {
+
+ const { isDark } = useSelector((state) => state.darkMode);
+ const checked = isDark;
+
+ const dispatch = useDispatch();
+
+ const changeThemeToDark = () => {
+ document.getElementById('root').setAttribute('data-theme', 'dark');
+ };
+
+ const changeThemeToLight = () => {
+ document.getElementById('root').setAttribute('data-theme', 'light');
+ };
+
+ const handleChangeToggle = (e) => {
+ if (e.target.checked) {
+ dispatch(ENABLE_DARK_MODE());
+ } else {
+ dispatch(DISABLE_DARK_MODE());
+ }
+ };
+
+ useEffect(() => {
+ if (checked) {
+ changeThemeToDark();
+ localStorage.setItem('isDark', JSON.stringify(true));
+ } else {
+ changeThemeToLight();
+ localStorage.setItem('isDark', JSON.stringify(false));
+ }
+ }
+ , [checked]
+ );
+
+ return (
+ handleChangeToggle(event)}
+ defaultChecked={checked}
+ />
+
+ );
+};
+
+export default DarkModeToggle;
diff --git a/bookstore-frontend-react-app/src/components/Header.js b/bookstore-frontend-react-app/src/components/Header.js
index 3ec8e7f7..c0c05f89 100644
--- a/bookstore-frontend-react-app/src/components/Header.js
+++ b/bookstore-frontend-react-app/src/components/Header.js
@@ -4,6 +4,7 @@ import { LinkContainer } from 'react-router-bootstrap';
import { useDispatch, useSelector } from 'react-redux';
import { isAdmin } from '../service/CommonUtils';
import { logout } from '../actions/userActions';
+import DarkModeToggle from './DarkModeToggle';
const Header = (props) => {
const userLogin = useSelector((state) => state.userLogin);
const { userInfo } = userLogin;
@@ -64,6 +65,7 @@ const Header = (props) => {
)}
+
diff --git a/bookstore-frontend-react-app/src/components/OrderItem.js b/bookstore-frontend-react-app/src/components/OrderItem.js
index 547c3adb..c66bb65b 100644
--- a/bookstore-frontend-react-app/src/components/OrderItem.js
+++ b/bookstore-frontend-react-app/src/components/OrderItem.js
@@ -34,7 +34,7 @@ const OrderItem = ({ item }) => {
-
+
{product.productName}
diff --git a/bookstore-frontend-react-app/src/components/Product.js b/bookstore-frontend-react-app/src/components/Product.js
index 82c3b561..4370afcd 100644
--- a/bookstore-frontend-react-app/src/components/Product.js
+++ b/bookstore-frontend-react-app/src/components/Product.js
@@ -8,7 +8,7 @@ const Product = (props) => {
const product = props.product;
return (
<>
-
+
{
+ switch (action.type) {
+ case DARK_MODE_ENABLE:
+ return { isDark: true };
+ case DARK_MODE_DISABLE:
+ return { isDark: false };
+ default:
+ return state;
+ }
+};
diff --git a/bookstore-frontend-react-app/src/screens/CartScreen.js b/bookstore-frontend-react-app/src/screens/CartScreen.js
index b552d2f4..65524162 100644
--- a/bookstore-frontend-react-app/src/screens/CartScreen.js
+++ b/bookstore-frontend-react-app/src/screens/CartScreen.js
@@ -70,9 +70,9 @@ const CartScreen = (props) => {
))}
)}
-
+
- Add more books
+ Add more books
diff --git a/bookstore-frontend-react-app/src/screens/OrderScreen.js b/bookstore-frontend-react-app/src/screens/OrderScreen.js
index 4fd072f2..e21a3700 100644
--- a/bookstore-frontend-react-app/src/screens/OrderScreen.js
+++ b/bookstore-frontend-react-app/src/screens/OrderScreen.js
@@ -69,7 +69,7 @@ const OrderScreen = ({ match, history }) => {
Name: {userInfo.userName}
-
+
Email: {userInfo.email}
@@ -96,7 +96,7 @@ const OrderScreen = ({ match, history }) => {
Not Paid
)}
-
+
Payment Receipt :
{order.paymentReceiptUrl}
diff --git a/bookstore-frontend-react-app/src/screens/PaymentScreen.js b/bookstore-frontend-react-app/src/screens/PaymentScreen.js
index e6a21f3d..3a642b80 100644
--- a/bookstore-frontend-react-app/src/screens/PaymentScreen.js
+++ b/bookstore-frontend-react-app/src/screens/PaymentScreen.js
@@ -89,7 +89,8 @@ const PaymentScreen = ({ history }) => {
className='p-2'
style={{
whiteSpace: 'pre-wrap',
- backgroundColor: '#eeeeee'
+ backgroundColor: '#eeeeee',
+ color: '#0e0e0e'
}}
onClick={(e) => {
console.log(a.paymentMethodId);
diff --git a/bookstore-frontend-react-app/src/screens/ProductScreen.js b/bookstore-frontend-react-app/src/screens/ProductScreen.js
index 0023efbc..e340da83 100644
--- a/bookstore-frontend-react-app/src/screens/ProductScreen.js
+++ b/bookstore-frontend-react-app/src/screens/ProductScreen.js
@@ -30,6 +30,8 @@ const ProductScreen = (props) => {
const productReviewCreate = useSelector((state) => state.productReviewCreate);
const { success: successProductReview, loading: loadingProductReview, error: errorProductReview } = productReviewCreate;
+ const isDarkMode = useSelector((state) => state.darkMode?.isDark);
+
useEffect(async () => {
// setProductimageBase64(null);
// dispatch(listProductDetailsAction(props.match.params.id));
@@ -61,7 +63,7 @@ const ProductScreen = (props) => {
return (
<>
-
+
Go Back
diff --git a/bookstore-frontend-react-app/src/screens/ShippingScreen.js b/bookstore-frontend-react-app/src/screens/ShippingScreen.js
index de21c53e..5ca14601 100644
--- a/bookstore-frontend-react-app/src/screens/ShippingScreen.js
+++ b/bookstore-frontend-react-app/src/screens/ShippingScreen.js
@@ -124,7 +124,8 @@ const ShippingScreen = ({ history }) => {
className='p-2'
style={{
whiteSpace: 'pre-wrap',
- backgroundColor: '#eeeeee'
+ backgroundColor: '#eeeeee',
+ color: '#0e0e0e'
}}
onClick={() => {
if (shippingCheckbox) {
diff --git a/bookstore-frontend-react-app/src/store.js b/bookstore-frontend-react-app/src/store.js
index 1adc5090..a6ccf0b5 100644
--- a/bookstore-frontend-react-app/src/store.js
+++ b/bookstore-frontend-react-app/src/store.js
@@ -31,6 +31,7 @@ import {
import { cartAddReducer, cartDetailReducer, cartRemoveReducer } from './reducers/cartReducers';
import { addressDeleteReducer, addressListMyReducer, addressSaveReducer } from './reducers/addressReducer';
import { paymentMethodListMyReducer, paymentMethodSaveReducer } from './reducers/paymentReducers';
+import { darkModeReducer } from './reducers/darkModeReducer';
const appReducer = combineReducers({
productList: productListReducer,
@@ -61,13 +62,15 @@ const appReducer = combineReducers({
addressListMy: addressListMyReducer,
addressDelete: addressDeleteReducer,
paymentMethodSave: paymentMethodSaveReducer,
- paymentMethodListMy: paymentMethodListMyReducer
+ paymentMethodListMy: paymentMethodListMyReducer,
+ darkMode: darkModeReducer
});
const userInfoFromStorage = localStorage.getItem('userInfo') ? JSON.parse(localStorage.getItem('userInfo')) : null;
const billingAddressId = localStorage.getItem('billingAddressId') ? localStorage.getItem('billingAddressId') : null;
const shippingAddressId = localStorage.getItem('shippingAddressId') ? localStorage.getItem('shippingAddressId') : null;
const paymentMethodId = localStorage.getItem('paymentMethodId') ? localStorage.getItem('paymentMethodId') : null;
+const isDark = localStorage.getItem('isDark') ? JSON.parse(localStorage.getItem('isDark')) : false;
const initialState = {
userLogin: { userInfo: userInfoFromStorage },
@@ -75,6 +78,9 @@ const initialState = {
billingAddressId,
shippingAddressId,
paymentMethodId
+ },
+ darkMode: {
+ isDark: isDark
}
};
diff --git a/bookstore-frontend-react-app/src/themes.css b/bookstore-frontend-react-app/src/themes.css
new file mode 100644
index 00000000..64d8b04b
--- /dev/null
+++ b/bookstore-frontend-react-app/src/themes.css
@@ -0,0 +1,21 @@
+/* default styling variables - making background color as white */
+#root{
+ --bg: #ffffff;
+ --bg-panel: #ffffff;
+ --color-heading: rgb(27, 168, 14);
+ --color-text: #333333;
+ --color-link: #d9230f;
+ --color-hover: #91170a;
+ --color-hover-row: rgba(0,0,0,.075);
+}
+
+/* dark theme styling - Here, we set data-them as "dark"*/
+#root[data-theme='dark'] {
+ --bg: #333333;
+ --bg-panel: #434343;
+ --color-heading: #0077ff;
+ --color-text: #eae9e9;
+ --color-link: #ececec;
+ --color-hover: #ffffff;
+ --color-hover-row: rgba(0,0,0,.35);
+}
\ No newline at end of file