├── .dockerignore ├── .env.example ├── .gitignore ├── README.md ├── docker-compose.prod.yaml ├── docker-compose.yaml ├── docker ├── Dockerfile └── Dockerfile.prod ├── nginx └── nginx.conf ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html └── manifest.json └── src ├── App.css ├── App.js ├── App.test.js ├── Layouts ├── MainLayout.jsx └── SecondaryLayout.jsx ├── Utility ├── currency.js └── formValidation.js ├── assets ├── icons │ ├── cart.svg │ ├── check-circle.png │ ├── facebook-f.svg │ ├── instagram.svg │ ├── linkedin.svg │ ├── money.png │ ├── truck.png │ └── twitter.svg └── images │ ├── baby_dress.jpg │ ├── fila_black.jpg │ ├── flare_dress.png │ ├── shirt.jpg │ └── shop_images │ ├── analog-quartz-watch.jpg │ ├── belt.jpg │ ├── bodycon-dress.jpg │ ├── boy_boxers.jpg │ ├── boys-t-shirt.jpg │ ├── cotton-dress.jpg │ ├── crew-neck-tshirt.jpg │ ├── floral-dress.jpg │ ├── gemch_shoes.jpg │ ├── gladiator-flat-flip.jpg │ ├── gsoft-khaki.jpg │ ├── leather-shoes.jpg │ ├── princes-dress.jpg │ ├── quartz-wrist-watch.jpg │ ├── singedani-handbag.jpg │ ├── slim-fit-suit.jpg │ ├── sneakers.jpg │ ├── vest.jpg │ └── vintage-flare-dress.jpg ├── components ├── AddToWishlist │ └── AddToWishlist.jsx ├── Cart │ ├── CartProductTotals.jsx │ └── CartProducts.jsx ├── Checkout │ ├── CheckoutCartProduct.jsx │ ├── CheckoutCartTotals.jsx │ ├── Forms │ │ ├── CustomerInputs.jsx │ │ ├── DeliveryOptions.jsx │ │ └── Payments │ │ │ ├── CreditCardInputs.jsx │ │ │ └── PaymentOptions.jsx │ ├── PromoCodeForm.jsx │ └── PromoCodeValue.jsx ├── CurrencyConverter.jsx ├── EmptyCategoryPageContent.jsx ├── Footer │ ├── Footer.css │ ├── Index.jsx │ └── components │ │ ├── FooterLinks.jsx │ │ ├── GitLink.jsx │ │ └── NewsLetter.jsx ├── LeftColumn.jsx ├── Loader │ ├── Index.css │ └── Index.jsx ├── Menus │ ├── MainMenu.jsx │ ├── MenuComponent.jsx │ └── SideMenu.jsx ├── OrderSuccess.jsx ├── ProductCard │ ├── Index.jsx │ ├── ProductCard.css │ └── ProductFeatures.jsx ├── ProductFilter │ ├── Index.jsx │ └── index.css ├── ProductsDisplay │ └── Index.jsx ├── PromoCodes.jsx ├── Ratings │ └── Ratings.jsx └── UI │ ├── Alert │ └── Alert.jsx │ ├── Backdrop │ └── Backdrop.jsx │ ├── BreadCrumbs │ └── BreadCrumbs.jsx │ ├── Icons │ └── Icons.jsx │ ├── Input │ └── InputField.js │ ├── Menu │ └── Menu.jsx │ ├── MenuItem │ └── MenuItem.jsx │ ├── Modal │ └── Modal.jsx │ └── Wrappers │ ├── MainPageWrapper.jsx │ ├── PageContentWrapper.jsx │ └── SideMenuWrapper.jsx ├── index.css ├── index.js ├── static ├── constants.js └── data.js ├── store ├── actions │ ├── actionTypes.js │ └── index.js ├── reducers │ └── index.js ├── selectors.js └── store.js └── views ├── All.jsx ├── Cart.jsx ├── Checkout.jsx ├── Home ├── Home.css ├── Home.jsx └── components │ ├── Banner.jsx │ ├── Deal.jsx │ ├── HomeSale.jsx │ ├── ItemBanners.jsx │ └── SelloutCards.jsx ├── ProductCategories.jsx ├── ProductDetails ├── ProductDetails.css └── ProductDetails.jsx ├── Sale.jsx └── index.js /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | build 4 | .dockerignore 5 | docker 6 | **/.git 7 | **/.DS_Store 8 | **/node_modules -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | REACT_APP_STRIPE_KEY=somekey 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | .env 4 | 5 | # dependencies 6 | /node_modules 7 | /.pnp 8 | .pnp.js 9 | 10 | # testing 11 | /coverage 12 | 13 | # production 14 | /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | #ide 28 | .idea 29 | 30 | #build 31 | /build 32 | 33 | 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## React-Redux Ecommerce web application 2 | 3 | this is a sample ecommerce web app made using react, redux and react router. 4 | 5 | Live demo can be found at [https://blissful-ramanujan-3c108d.netlify.app/](https://blissful-ramanujan-3c108d.netlify.app/). 6 | 7 | ## Build Setup 8 | 9 | 1. Run `npm install` in root directory, to install all required dependencies. 10 | 2. Rename `.env.example` file to `.env` 11 | 3. Add your **Stripe Api Key** to the `.env` file 12 | 4. Use `npm start` to start the application on your local machine 13 | 5. Use `4242 4242 4242 4242` credit card number when checking out! 14 | -------------------------------------------------------------------------------- /docker-compose.prod.yaml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | react-duka-prod: 5 | container_name: react-duka-prod 6 | build: 7 | context: . 8 | dockerfile: docker/Dockerfile.prod 9 | ports: 10 | - "8877:80" 11 | stdin_open: true 12 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | react-duka: 5 | container_name: react-duka 6 | build: 7 | context: . 8 | dockerfile: docker/Dockerfile 9 | volumes: 10 | - ".:/var/www/" 11 | - "/var/www/node_nodules" 12 | ports: 13 | - 3001:3000 14 | environment: 15 | - CHOKIDAR_USEPOLLING=true 16 | stdin_open: true 17 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # Set the base image to node:14.9-stretch 2 | FROM node:14.9-stretch 3 | 4 | # Specify where our app will live in the container 5 | WORKDIR /var/www/ 6 | 7 | # add `/var/www/node_modules/.bin` to $PATH 8 | ENV PATH /var/www/node_modules/.bin:$PATH 9 | 10 | # install app dependencies 11 | COPY package.json ./ 12 | COPY package-lock.json ./ 13 | RUN npm install 14 | RUN npm install react-scripts@3.4.3 15 | 16 | # add app 17 | COPY . ./ 18 | 19 | # start app 20 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /docker/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # Set the base image to node:14.9-stretch 2 | FROM node:14.9-stretch as builder 3 | 4 | # Specify where our app will live in the container 5 | WORKDIR /var/www/ 6 | 7 | # add `/var/www/node_modules/.bin` to $PATH 8 | ENV PATH /var/www/node_modules/.bin:$PATH 9 | 10 | # install app dependencies 11 | COPY package.json ./ 12 | COPY package-lock.json ./ 13 | RUN npm install 14 | RUN npm install react-scripts@3.4.3 15 | 16 | # add app 17 | COPY . ./ 18 | 19 | # start app 20 | RUN npm run build 21 | 22 | 23 | FROM nginx:1.19.2-perl 24 | COPY --from=builder /var/www/build /usr/share/nginx/html 25 | COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf 26 | EXPOSE 80 27 | CMD ["nginx","-g","deamon off;"] -------------------------------------------------------------------------------- /nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | 3 | listen 80; 4 | 5 | location / { 6 | root /usr/share/nginx/html; 7 | index index.html index.htm; 8 | try_files $uri $uri/ /index.html; 9 | } 10 | 11 | error_page 500 502 503 504 /50x.html; 12 | 13 | location = /50x.html { 14 | root /usr/share/nginx/html; 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-shop", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "bootstrap": "^4.3.1", 7 | "prop-types": "^15.6.2", 8 | "react": "16.7.0", 9 | "react-dom": "16.7.0", 10 | "react-icons": "^3.9.0", 11 | "react-redux": "6.0.0", 12 | "react-router": "4.3.1", 13 | "react-router-dom": "4.3.1", 14 | "react-scripts": "^3.4.3", 15 | "react-stripe-elements": "^2.0.2", 16 | "redux": "4.0.1", 17 | "redux-thunk": "2.3.0" 18 | }, 19 | "scripts": { 20 | "start": "react-scripts start", 21 | "build": "react-scripts build", 22 | "test": "react-scripts test", 23 | "eject": "react-scripts eject", 24 | "docker-run-dev" : "docker-compose up -d --build", 25 | "docker-run-prod" : "docker-compose -f docker-compose.prod.yaml up -d --build", 26 | "docker-stop" : "docker-compose stop" 27 | }, 28 | "eslintConfig": { 29 | "extends": "react-app" 30 | }, 31 | "browserslist": [ 32 | ">0.2%", 33 | "not dead", 34 | "not ie <= 11", 35 | "not op_mini all" 36 | ], 37 | "devDependencies": { 38 | "redux-devtools-extension": "^2.13.8" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collinsNick/React-redux-shopping-web-app/d3defcc6fcca8665b9b0ef5fa4a120bf3d92a018/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | React-shop 16 | 17 | 18 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | /* ------------- general --------------*/ 2 | .container-fluid { 3 | padding-right: 0; 4 | padding-left: 0; 5 | } 6 | 7 | .shop-container { 8 | width: 75%; 9 | } 10 | 11 | .shop-bg-white { 12 | background-color: #fff; 13 | } 14 | 15 | .text-success { 16 | color: #f17e0a !important; 17 | } 18 | 19 | input.shop-input-error { 20 | color: #b93338; 21 | background-color: #f2dede; 22 | border: 1px solid #eed3d7; 23 | } 24 | 25 | [type="text"]:focus.shop-input-error, 26 | [type="email"]:focus.shop-input-error { 27 | color: #b93338; 28 | background-color: #f2dede; 29 | border: 1px solid #eed3d7; 30 | } 31 | 32 | input.success { 33 | color: #398843; 34 | background-color: #dff0d8; 35 | border: 1px solid #d6e9c6; 36 | } 37 | 38 | .page-results { 39 | font-size: 16px; 40 | font-weight: 400; 41 | margin-bottom: 10px; 42 | } 43 | 44 | /* ------------- breadCrumbs --------------*/ 45 | 46 | .breadcrumb { 47 | padding: 0.5rem 0rem; 48 | margin-bottom: 0.5rem; 49 | background-color: transparent; 50 | } 51 | 52 | .breadcrumb-item + .breadcrumb-item::before { 53 | display: inline-block; 54 | padding-right: 0.5rem; 55 | color: #6c757d; 56 | content: "/"; 57 | } 58 | 59 | .breadcrumb-item > a { 60 | text-transform: capitalize !important; 61 | text-decoration: none; 62 | color: #000; 63 | } 64 | 65 | .breadcrumb-item > a:hover { 66 | text-decoration: none; 67 | color: #000; 68 | } 69 | 70 | .breadcrumb-item.active { 71 | text-transform: capitalize !important; 72 | } 73 | 74 | /* ------------- shop menu --------------*/ 75 | 76 | .navbar { 77 | padding: 0.8rem 1rem; 78 | } 79 | 80 | .navbar-brand > a { 81 | color: #e40046; 82 | text-decoration: none; 83 | font-weight: bold; 84 | } 85 | 86 | .badge-light { 87 | color: #fff; 88 | background-color: #e40046; 89 | } 90 | 91 | .nav-link.active .badge-light { 92 | color: #e40046; 93 | background-color: #fff; 94 | } 95 | 96 | .navbar-light .navbar-nav .nav-link { 97 | color: #6e6e6e; 98 | } 99 | 100 | .navbar-light .navbar-nav .nav-link:hover { 101 | color: #e40046; 102 | } 103 | 104 | .navbar-light .navbar-nav .nav-link.active, 105 | .navbar-light .navbar-nav .nav-link.show, 106 | .navbar-light .navbar-nav .show > .nav-link { 107 | background-color: #e40046; 108 | color: #fff; 109 | } 110 | 111 | .bg-light { 112 | background-color: #fff !important; 113 | } 114 | 115 | /* ------------- shop left column --------------*/ 116 | .shop-left-column { 117 | background: #fff; 118 | box-shadow: 2px 2px 2px -2px gray; 119 | } 120 | 121 | .shop-left-column h5 { 122 | color: #f17e0a; 123 | font-weight: 600; 124 | } 125 | 126 | .shop-left-column p { 127 | font-size: 0.92rem; 128 | text-align: justify; 129 | } 130 | 131 | .shop-text-red { 132 | color: #e40046; 133 | } 134 | 135 | /* ------------- modal --------------*/ 136 | .shop-modal { 137 | position: fixed; 138 | top: 0; 139 | left: 0; 140 | z-index: 1050; 141 | display: block; 142 | width: 100%; 143 | overflow: hidden; 144 | outline: 0; 145 | } 146 | 147 | /* ------------- shop cart --------------*/ 148 | .shop-div { 149 | background-color: #fff; 150 | } 151 | 152 | .shop-cart-b-container { 153 | text-align: right !important; 154 | } 155 | 156 | .shop-empty-cart a, 157 | .shop-empty-cart a .hover { 158 | color: #f17e0a; 159 | text-decoration: none; 160 | } 161 | 162 | .shop-cart-image { 163 | width: 100px; 164 | height: 100px; 165 | } 166 | 167 | .shop-btn-warning, 168 | .shop-btn-warning:focus, 169 | .shop-btn-warning.focus, 170 | .shop-btn-warning:hover, 171 | .shop-btn-warning:active, 172 | .shop-btn-warning:active:focus, 173 | .shop-btn-warning.active { 174 | background-color: transparent; 175 | border-color: #e40046; 176 | color: #e40046; 177 | } 178 | 179 | .shop-btn-outline, 180 | .shop-btn-outline:focus, 181 | .shop-btn-outline.focus, 182 | .shop-btn-outline:hover, 183 | .shop-btn-outline:active, 184 | .shop-btn-outline:active:focus, 185 | .shop-btn-outline.active { 186 | background-color: transparent; 187 | border-color: #6c757d; 188 | color: #6c757d; 189 | margin-right: 1rem; 190 | } 191 | 192 | .shop-cart-total { 193 | font-weight: 500; 194 | } 195 | 196 | .shop-cart-amounts { 197 | font-size: 0.95rem; 198 | } 199 | 200 | .shop-cart-item-price, 201 | .shop-cart-item-total { 202 | font-size: 0.95rem; 203 | } 204 | 205 | .shop-cart-item-total span { 206 | font-weight: 600; 207 | } 208 | 209 | .shop-cart-category { 210 | color: #777; 211 | font-size: 0.95rem; 212 | } 213 | 214 | .wishlist-container > .product-wishlist { 215 | position: absolute; 216 | right: 1.5rem; 217 | top: -0.3rem; 218 | } 219 | 220 | .shop-cart-name { 221 | font-size: 1rem; 222 | font-weight: 500; 223 | } 224 | 225 | .shop-cart-product-details .badge-warning { 226 | color: #fff; 227 | background-color: #e40046; 228 | } 229 | 230 | .shop-cart-product-details .badge-success { 231 | color: #fff; 232 | background-color: #f17e0a; 233 | } 234 | 235 | /* ------------- shop footer --------------*/ 236 | .shop-footer { 237 | background: #1e1e1e; 238 | color: #fff; 239 | } 240 | 241 | .shop-footer a { 242 | color: #fff; 243 | font-weight: bold; 244 | } 245 | 246 | /* ------------- modal --------------*/ 247 | .modal .shop-display { 248 | display: block !important; 249 | } 250 | 251 | /* ------------- side bar --------------*/ 252 | 253 | .side-menu-wrapper { 254 | width: 200px; 255 | min-height: 100vh; 256 | background: #fff; 257 | color: #fff; 258 | position: fixed; 259 | margin-left: -200px; 260 | box-shadow: 2px 2px 2px -2px gray; 261 | transition: all 0.3s; 262 | z-index: 2050; 263 | } 264 | 265 | .page-wrapper { 266 | width: 100%; 267 | transition: all 0.3s; 268 | position: absolute; 269 | top: 0; 270 | right: 0; 271 | } 272 | 273 | .side-menu-wrapper.show { 274 | margin-left: 0px; 275 | } 276 | 277 | .nav { 278 | list-style-type: none; 279 | } 280 | 281 | .nav .nav-item .nav-link { 282 | padding: 15px 20px; 283 | font-size: 1em; 284 | display: block; 285 | color: #6e6e6e; 286 | } 287 | 288 | .nav .nav-item .nav-link:hover { 289 | color: #e40046; 290 | } 291 | 292 | .nav .nav-item .nav-link.active { 293 | background-color: #e40046; 294 | color: #ffffff; 295 | } 296 | 297 | /* ------------- backdrop --------------*/ 298 | .shop-backdrop { 299 | position: fixed; 300 | top: 0; 301 | left: 0; 302 | z-index: 1040; 303 | width: 100vw; 304 | height: 100vh; 305 | background-color: rgba(0, 0, 0, 0.5); 306 | } 307 | 308 | /* ------------- checkout page --------------*/ 309 | .badge-secondary { 310 | color: #fff; 311 | background-color: #f17e0a; 312 | } 313 | 314 | .shop-checkout-image { 315 | width: 60px; 316 | margin-top: 5px; 317 | } 318 | 319 | .list-group-item { 320 | padding: 0.75rem 0.75rem; 321 | } 322 | 323 | .checkout-product-info h6 { 324 | font-size: 0.95rem; 325 | color: #000; 326 | } 327 | 328 | .checkout-product-info p { 329 | margin-top: 0.2rem; 330 | margin-bottom: 0; 331 | font-size: 0.9rem; 332 | color: #f17e0a; 333 | font-weight: 600; 334 | } 335 | 336 | .checkout-product-info small { 337 | color: #000; 338 | font-weight: 600; 339 | } 340 | 341 | .shop-checkout-prices { 342 | color: #000; 343 | font-size: 0.9rem; 344 | } 345 | 346 | .shop-checkout-prices span { 347 | font-weight: 600; 348 | } 349 | 350 | .shop-checkout-total { 351 | color: #000; 352 | font-weight: 600; 353 | font-size: 1.2rem; 354 | } 355 | 356 | .shop-checkout-total .shop-total { 357 | color: #f17e0a; 358 | } 359 | 360 | .shop-form ul { 361 | list-style-type: none; 362 | font-size: 1rem; 363 | padding-left: 2rem; 364 | } 365 | 366 | input[type="radio"] { 367 | margin-right: 1rem; 368 | } 369 | 370 | .shop-card-field { 371 | border: 1px solid #ced4da; 372 | border-radius: 3px; 373 | } 374 | 375 | .shop-input-errors { 376 | width: 100%; 377 | margin-top: 0.25rem; 378 | font-size: 80%; 379 | color: #dc3545; 380 | } 381 | 382 | .shop-delivery-options { 383 | background-color: #fff; 384 | border-radius: 5px; 385 | box-shadow: 2px 2px 2px -2px gray; 386 | font-size: 0.95rem; 387 | } 388 | 389 | /* ------------- side bar --------------*/ 390 | @media (max-width: 767.98px) { 391 | /* ------------- general --------------*/ 392 | .shop-container { 393 | width: 100%; 394 | } 395 | 396 | .shop-hide { 397 | display: none; 398 | } 399 | 400 | /* ------------- footer --------------*/ 401 | .shop-footer { 402 | font-size: 0.9rem; 403 | } 404 | 405 | /* ------------- product card --------------*/ 406 | .shop-card .shop-card-discount, 407 | .shop-card .shop-card-sale { 408 | font-size: 10px; 409 | font-weight: 600; 410 | } 411 | 412 | .shop-card .shop-card-image img { 413 | width: 50%; 414 | } 415 | 416 | .shop-card .shop-card-title { 417 | font-size: 14px; 418 | } 419 | 420 | /* ------------- cart page --------------*/ 421 | .shop-cart-image-div { 422 | display: none; 423 | } 424 | 425 | .shop-empty-cart { 426 | font-size: 1rem !important; 427 | } 428 | 429 | .shop-cart-item-price { 430 | margin-top: 0.5rem; 431 | } 432 | 433 | .shop-cart-b-container { 434 | text-align: left !important; 435 | margin-top: 0.5rem; 436 | } 437 | 438 | .btn-outline-secondary { 439 | margin-right: 0.5rem; 440 | margin-bottom: 0.9rem; 441 | } 442 | 443 | .checkout { 444 | margin-right: 0.5rem; 445 | } 446 | 447 | .shop-cart-total { 448 | font-size: 1.2rem; 449 | } 450 | 451 | .shop-btn-outline { 452 | margin-bottom: 0.5rem; 453 | } 454 | } 455 | 456 | @media (max-width: 991.98px) { 457 | .shop-cart-name { 458 | font-size: 0.9rem; 459 | font-weight: 500; 460 | margin-top: 0.5rem; 461 | } 462 | 463 | .shop-cart-category { 464 | font-size: 0.9rem; 465 | } 466 | 467 | .shop-cart-item-price, 468 | .shop-cart-item-total { 469 | font-size: 0.9rem; 470 | } 471 | 472 | /* ------------- left column --------------*/ 473 | .shop-left-column h5 { 474 | font-size: 1rem; 475 | } 476 | 477 | .shop-left-column p { 478 | font-size: 0.8rem; 479 | } 480 | 481 | .shop-btn-outline { 482 | margin-bottom: 0.5rem; 483 | } 484 | 485 | .shop-div h5 { 486 | font-size: 1rem; 487 | } 488 | } 489 | 490 | @media (min-width: 767.99px) { 491 | .side-menu-wrapper { 492 | margin-left: -200px; 493 | } 494 | 495 | .side-menu-wrapper.show { 496 | margin-left: -200px; 497 | } 498 | } 499 | 500 | @media (min-width: 767.99px) and (max-width: 991.98px) { 501 | .shop-container { 502 | width: 100%; 503 | } 504 | 505 | /* ------------- product card --------------*/ 506 | .shop-card .shop-card-discount, 507 | .shop-card .shop-card-sale { 508 | font-size: 10px; 509 | font-weight: 600; 510 | } 511 | 512 | .shop-card .shop-card-title { 513 | font-size: 14px; 514 | } 515 | } 516 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Route, Switch, withRouter, Redirect } from "react-router-dom"; 3 | import { connect } from "react-redux"; 4 | import { closeMaxProductModal, toogleSideBar } from "./store/actions"; 5 | import MainLayout from "./Layouts/MainLayout"; 6 | import * as Maincontainers from "./views"; 7 | import "./App.css"; 8 | 9 | class App extends Component { 10 | render() { 11 | return ( 12 |
13 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | ( 34 | 38 | )} 39 | /> 40 | {/*always redirect to index*/} 41 | 42 | 43 | 44 |
45 | ); 46 | } 47 | } 48 | 49 | const mapStateToProps = (state) => { 50 | return { 51 | storeCartItemsCount: state.cartTotal, 52 | showModalProp: state.productMaxShowModal, 53 | modalMessageProp: state.modalMessage, 54 | showSideNavigationProp: state.showSideNavigation, 55 | }; 56 | }; 57 | 58 | const mapDispatchToProps = (dispatch) => { 59 | return { 60 | closeModalProp: () => dispatch(closeMaxProductModal()), 61 | toggleSideBarProp: () => dispatch(toogleSideBar()), 62 | }; 63 | }; 64 | 65 | export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App)); 66 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /src/Layouts/MainLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import MainWrapper from "../components/UI/Wrappers/MainPageWrapper"; 3 | import SideMenuWrapper from "../components/UI/Wrappers/SideMenuWrapper"; 4 | import ContentWrapper from "../components/UI/Wrappers/PageContentWrapper"; 5 | import MainMenu from "../components/Menus/MainMenu"; 6 | import SideMenu from "../components/Menus/SideMenu"; 7 | import Footer from "../components/Footer/Index"; 8 | import Modal from "../components/UI/Modal/Modal"; 9 | import PropTypes from "prop-types"; 10 | 11 | const MainLayout = (props) => { 12 | return ( 13 | 14 | 15 | 19 | 23 | 24 | 25 |
26 | 30 |
31 |
32 | {props.children} 33 | {props.showModal ? ( 34 | 38 | {props.modalMessage} 39 | 40 | ) : null} 41 |
42 |