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} - + {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 }) => { {item.productName} - + {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