├── client
├── .gitignore
├── .dockerignore
├── public
│ ├── robots.txt
│ ├── favicon.ico
│ ├── icon72.ico
│ ├── icon96.ico
│ ├── logo256.png
│ ├── logo512.png
│ ├── manifest.json
│ └── index.html
├── src
│ ├── history.js
│ ├── constants
│ │ ├── http_error_codes.js
│ │ ├── react_routes.js
│ │ ├── cookies.js
│ │ ├── api_routes.js
│ │ ├── stateCodes.js
│ │ └── constants.js
│ ├── images
│ │ ├── badRequest400.png
│ │ ├── pageNotFound404.png
│ │ ├── emptyCheckoutCart.png
│ │ ├── internalServer500.png
│ │ └── searchMatchesNotFound404.png
│ ├── components
│ │ ├── ui
│ │ │ ├── headers.js
│ │ │ ├── error
│ │ │ │ ├── badRequest.js
│ │ │ │ ├── internalServerError.js
│ │ │ │ ├── GenericErrorMsg.js
│ │ │ │ ├── renderErrorImage.js
│ │ │ │ ├── httpError.js
│ │ │ │ ├── emptyShoppingBag.js
│ │ │ │ ├── pageNotFound.js
│ │ │ │ └── searchMatchesNotFound.js
│ │ │ ├── documentTitle.js
│ │ │ ├── BackgroundDisabledSpinner.js
│ │ │ ├── spinner.js
│ │ │ ├── breadcrumbs.js
│ │ │ ├── reduxTextField.js
│ │ │ ├── modal.js
│ │ │ ├── modalConfirmation.js
│ │ │ ├── radioButtonGroup.js
│ │ │ └── alertModal.js
│ │ ├── routes
│ │ │ ├── checkout
│ │ │ │ ├── stripeInput.js
│ │ │ │ ├── summaryCard.js
│ │ │ │ └── continueButton.js
│ │ │ ├── navbar
│ │ │ │ ├── bagButton.js
│ │ │ │ ├── sideBar.js
│ │ │ │ └── mobileMenu.js
│ │ │ ├── signin
│ │ │ │ └── GoogleAuthButton.js
│ │ │ ├── cancelPayment.js
│ │ │ ├── home
│ │ │ │ ├── homeMenuIcons.js
│ │ │ │ └── verticalSlider.js
│ │ │ ├── product
│ │ │ │ ├── filterSideNavbar
│ │ │ │ │ ├── checkboxSearchBar.js
│ │ │ │ │ ├── clearAllButton.js
│ │ │ │ │ └── priceCheckBox.js
│ │ │ │ ├── filterDropdown.js
│ │ │ │ └── filterPagination.js
│ │ │ ├── signup
│ │ │ │ └── signUp.js
│ │ │ └── priceDetails.js
│ │ └── app.js
│ ├── styles
│ │ ├── materialUI
│ │ │ ├── webFormStyles.js
│ │ │ ├── checkoutFormStyles.js
│ │ │ ├── tabStyles.js
│ │ │ └── filterNavBarStyles.js
│ │ ├── index.css
│ │ └── semanticUI
│ │ │ ├── commonStyles.css
│ │ │ └── customStyles.js
│ ├── setupTests.js
│ ├── __tests__
│ │ └── App.test.js
│ ├── logger
│ │ ├── loggerTypes.js
│ │ ├── LoggerConfig.js
│ │ └── Logger.js
│ ├── reducers
│ │ ├── events
│ │ │ └── eventReducer.js
│ │ └── index.js
│ ├── helper
│ │ ├── toggleId.js
│ │ └── updateQueryString.js
│ ├── hooks
│ │ ├── useCartTotal.js
│ │ ├── useClickAway.js
│ │ └── useAddProductsToShoppingBag.js
│ ├── api
│ │ └── service_api.js
│ ├── ErrorBoundary.js
│ └── index.js
├── Dockerfile
├── server.js
├── .env-sample
└── package.json
├── mysql-db
└── user.sql
├── server
├── payment-service
│ ├── heroku.yml
│ ├── src
│ │ ├── main
│ │ │ ├── resources
│ │ │ │ ├── application.properties
│ │ │ │ └── logback-spring.xml
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── ujjaval
│ │ │ │ └── ecommerce
│ │ │ │ └── paymentservice
│ │ │ │ ├── dto
│ │ │ │ ├── CardToken.java
│ │ │ │ └── PaymentStatus.java
│ │ │ │ ├── PaymentServiceApplication.java
│ │ │ │ ├── config
│ │ │ │ └── CORSFilter.java
│ │ │ │ └── controller
│ │ │ │ └── PaymentController.java
│ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── ujjaval
│ │ │ └── ecommerce
│ │ │ └── paymentservice
│ │ │ └── PaymentServiceApplicationTests.java
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── .gitignore
│ ├── Dockerfile-prod
│ ├── Dockerfile-dev
│ └── pom.xml
├── search-suggestion-service
│ ├── src
│ │ ├── main
│ │ │ ├── resources
│ │ │ │ ├── application-prod.properties
│ │ │ │ ├── application-dev.properties
│ │ │ │ ├── application.properties
│ │ │ │ └── logback-spring.xml
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── ujjaval
│ │ │ │ └── ecommerce
│ │ │ │ └── searchsuggestionservice
│ │ │ │ ├── service
│ │ │ │ └── SearchSuggestionService.java
│ │ │ │ ├── dto
│ │ │ │ └── SearchSuggestionKeywordInfo.java
│ │ │ │ ├── config
│ │ │ │ └── CorsConfig.java
│ │ │ │ ├── SearchSuggestionServiceApplication.java
│ │ │ │ ├── util
│ │ │ │ └── Permutation.java
│ │ │ │ └── controller
│ │ │ │ └── SearchSuggestionController.java
│ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── ujjaval
│ │ │ └── ecommerce
│ │ │ └── searchsuggestionservice
│ │ │ └── SearchSuggestionServiceApplicationTests.java
│ ├── heroku.yml
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── .gitignore
│ ├── Dockerfile-prod
│ └── Dockerfile-dev
├── common-data-service
│ ├── src
│ │ ├── main
│ │ │ ├── resources
│ │ │ │ ├── application-prod.properties
│ │ │ │ ├── fake_data
│ │ │ │ │ ├── sortby-data.txt
│ │ │ │ │ ├── price-range-data.txt
│ │ │ │ │ └── .DS_Store
│ │ │ │ ├── application-dev.properties
│ │ │ │ ├── application.properties
│ │ │ │ └── logback-spring.xml
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── ujjaval
│ │ │ │ └── ecommerce
│ │ │ │ └── commondataservice
│ │ │ │ ├── service
│ │ │ │ └── interfaces
│ │ │ │ │ ├── LoadFakeDataService.java
│ │ │ │ │ └── CommonDataService.java
│ │ │ │ ├── dao
│ │ │ │ └── sql
│ │ │ │ │ ├── info
│ │ │ │ │ ├── BankInfoRepository.java
│ │ │ │ │ ├── OrderInfoRepository.java
│ │ │ │ │ ├── AddressInfoRepository.java
│ │ │ │ │ ├── ContactInfoRepository.java
│ │ │ │ │ ├── queryhelpers
│ │ │ │ │ │ └── context
│ │ │ │ │ │ │ └── ParamsToQueryContext.java
│ │ │ │ │ └── ProductInfoRepository.java
│ │ │ │ │ ├── images
│ │ │ │ │ ├── BrandImagesRepository.java
│ │ │ │ │ ├── ApparelImagesRepository.java
│ │ │ │ │ └── CarouselImagesRepository.java
│ │ │ │ │ └── categories
│ │ │ │ │ ├── GenderCategoryRepository.java
│ │ │ │ │ ├── SortByCategoryRepository.java
│ │ │ │ │ ├── PriceRangeCategoryRepository.java
│ │ │ │ │ ├── ProductBrandCategoryRepository.java
│ │ │ │ │ └── ApparelCategoryRepository.java
│ │ │ │ ├── dto
│ │ │ │ ├── BrandsAndApparelsDTO.java
│ │ │ │ ├── FilterAttributesDTO.java
│ │ │ │ ├── ProductInfoDTO.java
│ │ │ │ ├── SearchSuggestionForTwoAttrDTO.java
│ │ │ │ ├── SearchSuggestionForThreeAttrDTO.java
│ │ │ │ ├── BrandImagesDTO.java
│ │ │ │ ├── FilterAttributesWithTotalItemsDTO.java
│ │ │ │ └── ApparelImagesDTO.java
│ │ │ │ ├── utils
│ │ │ │ └── resulttransformers
│ │ │ │ │ └── IListResultTransformer.java
│ │ │ │ ├── config
│ │ │ │ ├── AppConfig.java
│ │ │ │ ├── CorsConfig.java
│ │ │ │ ├── DevRedisConfig.java
│ │ │ │ └── ProdRedisConfig.java
│ │ │ │ ├── model
│ │ │ │ ├── HomeTabsDataResponse.java
│ │ │ │ ├── MainScreenResponse.java
│ │ │ │ ├── SearchSuggestionResponse.java
│ │ │ │ └── FilterAttributesResponse.java
│ │ │ │ ├── entity
│ │ │ │ └── sql
│ │ │ │ │ ├── categories
│ │ │ │ │ ├── SortByCategory.java
│ │ │ │ │ ├── PriceRangeCategory.java
│ │ │ │ │ ├── GenderCategory.java
│ │ │ │ │ ├── ApparelCategory.java
│ │ │ │ │ └── ProductBrandCategory.java
│ │ │ │ │ ├── images
│ │ │ │ │ ├── CarouselImages.java
│ │ │ │ │ ├── BrandImages.java
│ │ │ │ │ └── ApparelImages.java
│ │ │ │ │ └── info
│ │ │ │ │ ├── ContactInfo.java
│ │ │ │ │ ├── AddressInfo.java
│ │ │ │ │ ├── OrderInfo.java
│ │ │ │ │ └── BankInfo.java
│ │ │ │ └── CommonDataServiceApplication.java
│ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── ujjaval
│ │ │ └── ecommerce
│ │ │ └── commondataservice
│ │ │ └── CommonDataServiceApplicationTests.java
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── heroku.yml
│ ├── .gitignore
│ ├── Dockerfile-prod
│ └── Dockerfile-dev
├── authentication-service
│ ├── src
│ │ ├── main
│ │ │ ├── resources
│ │ │ │ ├── application-prod.properties
│ │ │ │ ├── application-dev.properties
│ │ │ │ ├── application.properties
│ │ │ │ └── logback-spring.xml
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── ujjaval
│ │ │ │ └── ecommerce
│ │ │ │ └── authenticationservice
│ │ │ │ ├── model
│ │ │ │ ├── AuthenticationRequest.java
│ │ │ │ ├── AccountCreationResponse.java
│ │ │ │ ├── AuthenticationResponse.java
│ │ │ │ └── AccountCreationRequest.java
│ │ │ │ ├── AuthenticationServiceApplication.java
│ │ │ │ ├── service
│ │ │ │ ├── AuthDataService.java
│ │ │ │ ├── CustomUserDetailsService.java
│ │ │ │ └── AuthDataServiceImpl.java
│ │ │ │ ├── config
│ │ │ │ ├── CorsConfigurer.java
│ │ │ │ └── SecurityConfigurer.java
│ │ │ │ ├── entity
│ │ │ │ └── UserInfo.java
│ │ │ │ ├── util
│ │ │ │ ├── Md5Util.java
│ │ │ │ └── JwtUtil.java
│ │ │ │ ├── dao
│ │ │ │ └── UserInfoRepository.java
│ │ │ │ └── filter
│ │ │ │ └── JwtRequestFilter.java
│ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── ujjaval
│ │ │ └── ecommerce
│ │ │ └── authenticationservice
│ │ │ └── AuthenticationServiceApplicationTests.java
│ ├── heroku.yml
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── .gitignore
│ ├── Dockerfile-prod
│ └── Dockerfile-dev
└── seller-account-service
│ ├── src
│ ├── main
│ │ ├── .DS_Store
│ │ ├── java
│ │ │ ├── .DS_Store
│ │ │ └── com
│ │ │ │ ├── .DS_Store
│ │ │ │ └── ujjaval
│ │ │ │ ├── .DS_Store
│ │ │ │ └── ecommerce
│ │ │ │ ├── .DS_Store
│ │ │ │ └── selleraccountservice
│ │ │ │ ├── .DS_Store
│ │ │ │ ├── entity
│ │ │ │ ├── .DS_Store
│ │ │ │ ├── nosql
│ │ │ │ │ ├── SellerReview.java
│ │ │ │ │ ├── SellerAccountNotification.java
│ │ │ │ │ ├── SellerMessage.java
│ │ │ │ │ ├── SellerMessageDetails.java
│ │ │ │ │ └── SellerBulkInfo.java
│ │ │ │ └── sql
│ │ │ │ │ └── SellerInfo.java
│ │ │ │ ├── dao
│ │ │ │ ├── sql
│ │ │ │ │ └── SellerInfoRepository.java
│ │ │ │ └── nosql
│ │ │ │ │ └── SellerBulkInfoRepository.java
│ │ │ │ ├── SellerAccountServiceApplication.java
│ │ │ │ ├── model
│ │ │ │ └── UserInfo.java
│ │ │ │ ├── service
│ │ │ │ └── SellerAccountDataService.java
│ │ │ │ └── controller
│ │ │ │ └── SellerAccountController.java
│ │ └── resources
│ │ │ └── application.properties
│ └── test
│ │ └── java
│ │ └── com
│ │ └── ujjaval
│ │ └── ecommerce
│ │ └── selleraccountservice
│ │ └── SellerAccountServiceApplicationTests.java
│ ├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
│ └── .gitignore
├── stop-all.sh
├── wait-for-mysql.sh
├── start-all.sh
├── .gitignore
└── .env-sample
/client/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .env
3 | .DS_Store
4 |
5 |
--------------------------------------------------------------------------------
/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | .env
4 |
--------------------------------------------------------------------------------
/mysql-db/user.sql:
--------------------------------------------------------------------------------
1 | GRANT ALL PRIVILEGES ON *.* TO 'mysqluser'@'%';
2 |
--------------------------------------------------------------------------------
/server/payment-service/heroku.yml:
--------------------------------------------------------------------------------
1 | build:
2 | docker:
3 | web: Dockerfile-prod
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/resources/application-prod.properties:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/search-suggestion-service/heroku.yml:
--------------------------------------------------------------------------------
1 | build:
2 | docker:
3 | web: Dockerfile-prod
--------------------------------------------------------------------------------
/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/icon72.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/public/icon72.ico
--------------------------------------------------------------------------------
/client/public/icon96.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/public/icon96.ico
--------------------------------------------------------------------------------
/client/public/logo256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/public/logo256.png
--------------------------------------------------------------------------------
/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/public/logo512.png
--------------------------------------------------------------------------------
/client/src/history.js:
--------------------------------------------------------------------------------
1 | import {createBrowserHistory} from 'history';
2 |
3 | export default createBrowserHistory();
4 |
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/resources/application-dev.properties:
--------------------------------------------------------------------------------
1 | #spring.data.redis.repositories.enabled=false
--------------------------------------------------------------------------------
/server/payment-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=payment-service
2 | server.port=${PORT}
--------------------------------------------------------------------------------
/client/src/constants/http_error_codes.js:
--------------------------------------------------------------------------------
1 | export const INTERNAL_SERVER_ERROR_CODE = 500;
2 | export const BAD_REQUEST_ERROR_CODE = 400;
--------------------------------------------------------------------------------
/server/common-data-service/src/main/resources/application-prod.properties:
--------------------------------------------------------------------------------
1 | spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
--------------------------------------------------------------------------------
/client/src/images/badRequest400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/src/images/badRequest400.png
--------------------------------------------------------------------------------
/server/authentication-service/src/main/resources/application-prod.properties:
--------------------------------------------------------------------------------
1 | spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
--------------------------------------------------------------------------------
/client/src/images/pageNotFound404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/src/images/pageNotFound404.png
--------------------------------------------------------------------------------
/client/src/images/emptyCheckoutCart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/src/images/emptyCheckoutCart.png
--------------------------------------------------------------------------------
/client/src/images/internalServer500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/src/images/internalServer500.png
--------------------------------------------------------------------------------
/server/common-data-service/src/main/resources/fake_data/sortby-data.txt:
--------------------------------------------------------------------------------
1 | 1|What's New
2 | 2|Popularity
3 | 3|Price: Low To High
4 | 4|Price: High To Low
--------------------------------------------------------------------------------
/server/authentication-service/heroku.yml:
--------------------------------------------------------------------------------
1 | setup:
2 | addons:
3 | - plan: cleardb
4 | as: DATABASE
5 | build:
6 | docker:
7 | web: Dockerfile-prod
--------------------------------------------------------------------------------
/client/src/images/searchMatchesNotFound404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/client/src/images/searchMatchesNotFound404.png
--------------------------------------------------------------------------------
/server/common-data-service/src/main/resources/fake_data/price-range-data.txt:
--------------------------------------------------------------------------------
1 | 1|Under $50
2 | 2|$50-$100
3 | 3|$100-$200
4 | 4|$200-$300
5 | 5|$300-$400
6 | 6|Above $400
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/seller-account-service/src/main/.DS_Store
--------------------------------------------------------------------------------
/server/payment-service/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/payment-service/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/seller-account-service/src/main/java/.DS_Store
--------------------------------------------------------------------------------
/stop-all.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Stop and delete the containers
4 | docker-compose down
5 |
6 | # Deleting network
7 | docker network rm spring-cloud-microservices
8 |
--------------------------------------------------------------------------------
/server/common-data-service/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/common-data-service/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/seller-account-service/src/main/java/com/.DS_Store
--------------------------------------------------------------------------------
/server/authentication-service/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/authentication-service/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/server/seller-account-service/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/seller-account-service/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/server/search-suggestion-service/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/search-suggestion-service/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/server/common-data-service/src/main/resources/fake_data/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/common-data-service/src/main/resources/fake_data/.DS_Store
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/seller-account-service/src/main/java/com/ujjaval/.DS_Store
--------------------------------------------------------------------------------
/client/src/constants/react_routes.js:
--------------------------------------------------------------------------------
1 | export const HOME_ROUTE = '/'
2 | export const PRODUCTS_ROUTE = '/products'
3 | export const CHECKOUT_ROUTE = '/checkout'
4 | export const DETAILS_ROUTE = '/products/details'
--------------------------------------------------------------------------------
/server/common-data-service/heroku.yml:
--------------------------------------------------------------------------------
1 | setup:
2 | addons:
3 | - plan: cleardb
4 | as: DATABASE
5 | - plan: heroku-redis
6 | as: DATABASE
7 | build:
8 | docker:
9 | web: Dockerfile-prod
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/.DS_Store
--------------------------------------------------------------------------------
/client/src/constants/cookies.js:
--------------------------------------------------------------------------------
1 | export const AUTH_DETAILS_COOKIE = "AUTH_DETAILS_COOKIE";
2 | export const SHOPPERS_PRODUCT_INFO_COOKIE = 'SHOPPERS_PRODUCT_INFO_COOKIE';
3 | export const CART_TOTAL_COOKIE = "CART_TOTAL_COOKIE";
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=search-suggestion-service
2 | server.port=${PORT}
3 | spring.profiles.active=${ACTIVE_PROFILE}
4 | #spring.cache.redis.time-to-live=10
--------------------------------------------------------------------------------
/client/src/components/ui/headers.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NavBarHeader = (props) => {
4 | return (
5 |
{props.title.toUpperCase()}
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/resources/application-dev.properties:
--------------------------------------------------------------------------------
1 | spring.jpa.generate-ddl=true
2 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
3 | spring.jpa.hibernate.ddl-auto=create-drop
4 | spring.data.redis.repositories.enabled=false
--------------------------------------------------------------------------------
/server/common-data-service/src/main/resources/application-dev.properties:
--------------------------------------------------------------------------------
1 | spring.jpa.generate-ddl=true
2 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
3 | #spring.jpa.hibernate.ddl-auto=create-drop
4 | spring.data.redis.repositories.enabled=false
5 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/.DS_Store
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/entity/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WHAHA-HA/spring-boot-react-ecommerce/HEAD/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/entity/.DS_Store
--------------------------------------------------------------------------------
/server/payment-service/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/server/authentication-service/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/server/common-data-service/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/service/interfaces/LoadFakeDataService.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.service.interfaces;
2 |
3 | public interface LoadFakeDataService {
4 |
5 | boolean loadTestData();
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/server/seller-account-service/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/client/src/styles/materialUI/webFormStyles.js:
--------------------------------------------------------------------------------
1 | import {makeStyles} from "@material-ui/core/styles";
2 |
3 | const useWebFormStyles = makeStyles((theme) => ({
4 | typographyRootHeader: {
5 | fontWeight: '5px'
6 | }
7 | }));
8 |
9 | export default useWebFormStyles;
10 |
--------------------------------------------------------------------------------
/server/search-suggestion-service/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/client/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/client/src/styles/materialUI/checkoutFormStyles.js:
--------------------------------------------------------------------------------
1 |
2 | export const checkoutFormStyles = theme => ({
3 | root: {
4 | '& > *': {
5 | marginLeft: theme.spacing(3),
6 | },
7 | },
8 | formControlLabel: {
9 | width: "inherit"
10 | }
11 | });
12 |
--------------------------------------------------------------------------------
/wait-for-mysql.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | cmd="$@"
6 |
7 | echo "starting"
8 |
9 | until mysql -h$DB_HOST -u$DB_USER -p$DB_PASS -e '\q'; do
10 | >&2 echo "MySQL is unavailable - sleeping"
11 | sleep 2
12 | done
13 |
14 | echo "Done"
15 |
16 | echo "MySQL is up - executing command = $cmd"
17 |
18 | exec $cmd
19 |
--------------------------------------------------------------------------------
/client/src/__tests__/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from '../components/app';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/client/src/components/ui/error/badRequest.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import badRequestImage from '../../../images/badRequest400.png'
3 | import {RenderErrorImage} from "./renderErrorImage";
4 |
5 | export const BadRequest = () => {
6 |
7 | return (
8 |
9 | );
10 | };
--------------------------------------------------------------------------------
/client/src/components/ui/documentTitle.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Helmet from 'react-helmet';
3 |
4 | const DocumentTitle = ({ title }) => {
5 | const defaultTitle = 'Shoppers';
6 | return (
7 |
8 | {title ? title : defaultTitle}
9 |
10 | );
11 | };
12 |
13 | export { DocumentTitle };
--------------------------------------------------------------------------------
/server/payment-service/src/main/java/com/ujjaval/ecommerce/paymentservice/dto/CardToken.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.paymentservice.dto;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @NoArgsConstructor
8 | @AllArgsConstructor
9 | @ToString
10 | public class CardToken {
11 | String id;
12 | Long amount;
13 | String currency;
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/server/payment-service/src/test/java/com/ujjaval/ecommerce/paymentservice/PaymentServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.paymentservice;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class PaymentServiceApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/client/src/components/ui/error/internalServerError.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import internalServerErrorImage from '../../../images/internalServer500.png'
3 | import {RenderErrorImage} from "./renderErrorImage";
4 |
5 | export const InternalServerError = () => {
6 |
7 | return (
8 |
9 | );
10 | };
--------------------------------------------------------------------------------
/server/common-data-service/src/test/java/com/ujjaval/ecommerce/commondataservice/CommonDataServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class CommonDataServiceApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/model/AuthenticationRequest.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.model;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @NoArgsConstructor
8 | @AllArgsConstructor
9 | @ToString
10 | public class AuthenticationRequest {
11 |
12 | private String username;
13 | private String password;
14 | }
15 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/info/BankInfoRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.info;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.BankInfo;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface BankInfoRepository extends JpaRepository {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/info/OrderInfoRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.info;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.OrderInfo;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface OrderInfoRepository extends JpaRepository {
7 | }
8 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/dao/sql/SellerInfoRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.dao.sql;
2 |
3 | import com.ujjaval.ecommerce.selleraccountservice.entity.sql.SellerInfo;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface SellerInfoRepository extends JpaRepository {
7 | }
8 |
--------------------------------------------------------------------------------
/client/src/constants/api_routes.js:
--------------------------------------------------------------------------------
1 | export const HOME_PAGE_DATA_API = "/home";
2 | export const TABS_DATA_API = "/tabs";
3 | export const PRODUCT_BY_ID_DATA_API = "/products?product_id=";
4 | export const PRODUCT_BY_CATEGORY_DATA_API = "/products";
5 | export const SEARCH_SUGGESTION_API = "/search-suggestion?q=";
6 | export const DEFAULT_SEARCH_SUGGESTION_API = "/default-search-suggestion";
7 | export const FILTER_ATTRIBUTES_API = "/filter";
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/info/AddressInfoRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.info;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.AddressInfo;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface AddressInfoRepository extends JpaRepository {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/info/ContactInfoRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.info;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.ContactInfo;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 |
7 | public interface ContactInfoRepository extends JpaRepository {
8 | }
9 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/test/java/com/ujjaval/ecommerce/selleraccountservice/SellerAccountServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class SellerAccountServiceApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/model/AccountCreationResponse.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.model;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @NoArgsConstructor
8 | @AllArgsConstructor
9 | @ToString
10 | public class AccountCreationResponse {
11 | private String account_creation_status;
12 | private String error_msg;
13 | }
14 |
--------------------------------------------------------------------------------
/server/authentication-service/src/test/java/com/ujjaval/ecommerce/authenticationservice/AuthenticationServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class AuthenticationServiceApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/entity/nosql/SellerReview.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.entity.nosql;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @AllArgsConstructor
8 | @ToString
9 | public class SellerReview {
10 |
11 | private double rating;
12 |
13 | private String comment;
14 |
15 | private String timestamp;
16 |
17 | }
--------------------------------------------------------------------------------
/client/src/logger/loggerTypes.js:
--------------------------------------------------------------------------------
1 | import Logger from './Logger';
2 |
3 | export const LoggerTypes = {
4 | MAIN_SCREEN_LOGGER: 1,
5 | FILTER_SCREEN_LOGGER: 2
6 | }
7 |
8 | export const LoggerRegisterInfo = [
9 | {
10 | id: LoggerTypes.MAIN_SCREEN_LOGGER,
11 | level: Logger.Levels.INFO
12 | },
13 | {
14 | id: LoggerTypes.FILTER_SCREEN_LOGGER,
15 | level: Logger.Levels.DEBUG
16 | },
17 | ]
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/model/AuthenticationResponse.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.model;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @NoArgsConstructor
8 | @AllArgsConstructor
9 | @ToString
10 | public class AuthenticationResponse {
11 |
12 | private String jwt;
13 | private String error;
14 | private String firstName;
15 | }
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/test/java/com/ujjaval/ecommerce/searchsuggestionservice/SearchSuggestionServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.searchsuggestionservice;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class SearchSuggestionServiceApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/dao/nosql/SellerBulkInfoRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.dao.nosql;
2 |
3 | import com.ujjaval.ecommerce.selleraccountservice.entity.nosql.SellerBulkInfo;
4 | import org.springframework.data.mongodb.repository.MongoRepository;
5 |
6 | public interface SellerBulkInfoRepository extends MongoRepository {
7 | }
8 |
--------------------------------------------------------------------------------
/client/src/styles/index.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | max-width: 100%;
3 | height: 100% !important;
4 | padding: 0;
5 | margin: 0;
6 | }
7 |
8 | body ::-webkit-scrollbar {
9 | width:0 !important;
10 | height: 0 !important;
11 | }
12 |
13 | #customDropdown {
14 | font-weight: bold;
15 | }
16 |
17 | input {
18 | font-size: 1.2rem !important;
19 | }
20 |
21 | .ui.button.googleButtonStyle {
22 | width: 100%;
23 | height: 40px;
24 | }
--------------------------------------------------------------------------------
/client/src/components/routes/checkout/stripeInput.js:
--------------------------------------------------------------------------------
1 | import React, { useRef, useImperativeHandle } from 'react'
2 |
3 | export const StripeInput = ({ component: Component, inputRef, ...other }) => {
4 | const elementRef = useRef();
5 | useImperativeHandle(inputRef, () => ({
6 | focus: () => elementRef.current.focus
7 | }));
8 |
9 | return (
10 | (elementRef.current = element)} {...other} />
11 | );
12 | }
--------------------------------------------------------------------------------
/client/src/components/ui/BackgroundDisabledSpinner.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Dimmer, Loader} from "semantic-ui-react";
3 | import log from 'loglevel';
4 |
5 | export default function BackgroundDisabledSpinner() {
6 | log.info(`[BackgroundDisabledSpinner] Rendering BackgroundDisabledSpinner Component...`)
7 | return (
8 |
9 | Loading
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/client/src/components/ui/error/GenericErrorMsg.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import log from 'loglevel'
3 | import {Grid} from "@material-ui/core";
4 |
5 | export const GenericErrorMsg = () => {
6 |
7 | log.info('[GenericErrorMsg] Rendering GenericErrorMsg Component')
8 | return (
9 |
10 | Oops! Something went wrong....
11 |
12 | )
13 | }
--------------------------------------------------------------------------------
/client/src/styles/semanticUI/commonStyles.css:
--------------------------------------------------------------------------------
1 |
2 | /* Quantity Dropdown Styling */
3 | .ui.menu > div {
4 | width: auto !important;
5 | min-width: auto !important;
6 | }
7 |
8 | #quantity-dropdown > .text {
9 | font-weight: bold !important;
10 | }
11 |
12 | #quantity-dropdown > .icon {
13 | margin-left: 5px !important;
14 | }
15 |
16 | #quantity-dropdown > .menu > div {
17 | padding: 5px 15px 5px 17px !important;
18 | }
19 |
20 | /*****************************/
21 |
22 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dto/BrandsAndApparelsDTO.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dto;
2 |
3 | import lombok.*;
4 |
5 | import java.io.Serializable;
6 | import java.util.List;
7 |
8 | @Getter
9 | @Setter
10 | @NoArgsConstructor
11 | @AllArgsConstructor
12 | @ToString
13 | public class BrandsAndApparelsDTO implements Serializable {
14 | List brands;
15 | List apparels;
16 | }
17 |
--------------------------------------------------------------------------------
/client/Dockerfile:
--------------------------------------------------------------------------------
1 | # Base Package
2 | FROM node:14
3 |
4 | MAINTAINER Ujjaval Desai
5 |
6 | # Create app directory
7 | WORKDIR /usr/src/app
8 |
9 | # Install app dependencies
10 | # A wildcard is used to ensure both package.json AND package-lock.json are copied
11 | # where available (npm@5+)
12 | COPY ./client/package*.json ./
13 |
14 | RUN npm install
15 |
16 | # Bundle app source
17 | COPY . .
18 |
19 | #RUN yarn install
20 |
21 | # Initiate npm start
22 | CMD [ "npm", "run-script", "start_docker_dev" ]
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/model/AccountCreationRequest.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.model;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @NoArgsConstructor
8 | @AllArgsConstructor
9 | @ToString
10 | public class AccountCreationRequest {
11 | private String username;
12 | private String password;
13 | private String lastname;
14 | private String firstname;
15 | private String email;
16 | }
17 |
--------------------------------------------------------------------------------
/server/common-data-service/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/server/seller-account-service/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/server/authentication-service/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | logs/
30 |
31 | ### VS Code ###
32 | .vscode/
33 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dto/FilterAttributesDTO.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dto;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.Setter;
7 |
8 | import java.io.Serializable;
9 |
10 | @Getter
11 | @Setter
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class FilterAttributesDTO implements Serializable {
15 | Integer id;
16 | String value;
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/entity/nosql/SellerAccountNotification.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.entity.nosql;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @NoArgsConstructor
8 | @AllArgsConstructor
9 | @ToString
10 | public class SellerAccountNotification {
11 |
12 | private int severityLevel;
13 |
14 | private boolean starred;
15 |
16 | private String notificationMsg;
17 |
18 | private String timestamp;
19 | }
20 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/SellerAccountServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class SellerAccountServiceApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(SellerAccountServiceApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/start-all.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Stop and delete the containers
4 | #docker-compose down
5 |
6 | # Stop and delete the containers
7 | docker-compose stop
8 |
9 | # Deleting network if available
10 | docker network rm spring-cloud-microservices
11 |
12 | # Creating network for services
13 | docker network create spring-cloud-microservices
14 |
15 | # Increasing default HTTP Timeout from 60 to 300
16 | export COMPOSE_HTTP_TIMEOUT=300
17 |
18 | # Start all services in background with -d flag
19 | docker-compose up --build
20 |
--------------------------------------------------------------------------------
/client/src/components/ui/error/renderErrorImage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Grid} from "@material-ui/core";
3 |
4 | export const RenderErrorImage = (props) => {
5 |
6 | return (
7 |
9 |
10 |
11 |
12 |
13 | );
14 | };
--------------------------------------------------------------------------------
/client/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const path = require('path');
3 | const port = process.env.PORT || 3000;
4 | const app = express();
5 |
6 | // the __dirname is the current directory from where the script is running
7 | app.use(express.static(__dirname));
8 | app.use(express.static(path.join(__dirname, 'build')));
9 | app.get('/ping', function (req, res) {
10 | return res.send('pong');
11 | });
12 | app.get('/*', function (req, res) {
13 | res.sendFile(path.join(__dirname, 'build', 'index.html'));
14 | });
15 | app.listen(port);
--------------------------------------------------------------------------------
/client/src/components/ui/spinner.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import CircularProgress from '@material-ui/core/CircularProgress';
3 | import {Box} from "@material-ui/core";
4 |
5 | export default function Spinner({textComponent = null}) {
6 | return (
7 |
9 |
10 |
11 | {textComponent}
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dto/ProductInfoDTO.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dto;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.ProductInfo;
4 | import lombok.*;
5 |
6 | import java.io.Serializable;
7 | import java.util.List;
8 |
9 | @Getter
10 | @Setter
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | @ToString
14 | public class ProductInfoDTO implements Serializable {
15 |
16 | private Long totalCount;
17 | private List products;
18 | }
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/entity/nosql/SellerMessage.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.entity.nosql;
2 |
3 | import lombok.*;
4 |
5 | import java.util.ArrayList;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | @Getter
10 | @Setter
11 | @ToString
12 | public class SellerMessage {
13 |
14 | private Map> msgThreadMap;
15 |
16 | public SellerMessage() {
17 |
18 | msgThreadMap = new HashMap<>();
19 | }
20 | }
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/model/UserInfo.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 |
7 | @Setter
8 | @Getter
9 | @AllArgsConstructor
10 | public class UserInfo {
11 | private int id;
12 |
13 | private String firstName;
14 |
15 | private String lastName;
16 |
17 | private String userName;
18 |
19 | private String password;
20 |
21 | private String email;
22 | }
23 |
--------------------------------------------------------------------------------
/server/payment-service/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/java/com/ujjaval/ecommerce/searchsuggestionservice/service/SearchSuggestionService.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.searchsuggestionservice.service;
2 |
3 | import com.ujjaval.ecommerce.searchsuggestionservice.dto.SearchSuggestionKeywordInfo;
4 | import java.util.List;
5 |
6 | public interface SearchSuggestionService {
7 | void loadSearchSuggestionToMap();
8 |
9 | List searchKeywordFromMap(String q);
10 |
11 | List getDefaultSearchSuggestions();
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/client/src/reducers/events/eventReducer.js:
--------------------------------------------------------------------------------
1 | import {HANDLE_TAB_HOVER_EVENT} from "../../actions/types";
2 | import log from "loglevel";
3 |
4 | export const tabHoverEventReducer = (state
5 | = {index: false, hover: false, tabColor: "black"}, action) => {
6 | switch (action.type) {
7 | case HANDLE_TAB_HOVER_EVENT:
8 | log.debug(`[TAB_HOVER_EVENT_REDUCER]: action.payload = ${JSON.stringify(action.payload)}`)
9 | return action.payload;
10 |
11 | default:
12 | return state;
13 | }
14 | };
--------------------------------------------------------------------------------
/server/search-suggestion-service/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/client/src/helper/toggleId.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | export const toggleId = (id, value, list) => {
4 | let valueExist = false
5 | let ids = []
6 |
7 | // eslint-disable-next-line array-callback-return
8 | let filteredList = list.filter(obj => {
9 | if (obj.id !== id) {
10 | ids.push(obj.id)
11 | return obj;
12 | }
13 | valueExist = true
14 | })
15 |
16 | if (valueExist) {
17 | return {list: filteredList, ids}
18 | } else {
19 | ids.push(id)
20 | list.push({id: id, value: value});
21 | return {list, ids}
22 | }
23 | }
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/AuthenticationServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
6 |
7 | @SpringBootApplication
8 | public class AuthenticationServiceApplication {
9 |
10 | public static void main(String[] args) {
11 | SpringApplication.run(AuthenticationServiceApplication.class, args);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dto/SearchSuggestionForTwoAttrDTO.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dto;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.Setter;
7 |
8 | import java.io.Serializable;
9 |
10 | @Getter
11 | @Setter
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class SearchSuggestionForTwoAttrDTO implements Serializable {
15 | Integer attr1_id;
16 | String attr1_type;
17 | Integer attr2_id;
18 | String attr2_type;
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/service/SellerAccountDataService.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.service;
2 |
3 |
4 | import com.ujjaval.ecommerce.selleraccountservice.entity.nosql.SellerBulkInfo;
5 | import com.ujjaval.ecommerce.selleraccountservice.entity.sql.SellerInfo;
6 |
7 | public interface SellerAccountDataService {
8 |
9 | public SellerInfo findSellerById(Integer sellerId);
10 |
11 | public void save();
12 |
13 | public void saveInMongo();
14 |
15 | public SellerBulkInfo findMongoAddressById();
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/entity/nosql/SellerMessageDetails.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.entity.nosql;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @NoArgsConstructor
8 | @AllArgsConstructor
9 | @ToString
10 | public class SellerMessageDetails {
11 | private int msgSeqNum;
12 |
13 | private int status;
14 |
15 | private String msgBody;
16 |
17 | private String msgSubject;
18 |
19 | private String senderName;
20 |
21 | private String timestamp;
22 |
23 | private boolean starred;
24 | }
25 |
--------------------------------------------------------------------------------
/client/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/java/com/ujjaval/ecommerce/searchsuggestionservice/dto/SearchSuggestionKeywordInfo.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.searchsuggestionservice.dto;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | @Getter
7 | @Setter
8 | public class SearchSuggestionKeywordInfo {
9 | String keyword;
10 | StringBuilder link;
11 | Integer rank;
12 |
13 | public SearchSuggestionKeywordInfo(String keyword, StringBuilder link, Integer rank) {
14 | this.keyword = keyword;
15 | this.link = new StringBuilder(link);
16 | this.rank = rank;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/images/BrandImagesRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.images;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.images.BrandImages;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 |
7 | import java.util.List;
8 |
9 | public interface BrandImagesRepository extends JpaRepository {
10 |
11 | @Query(value = "SELECT DISTINCT b FROM BrandImages b")
12 | List getAllData();
13 | }
14 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/images/ApparelImagesRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.images;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.images.ApparelImages;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 |
7 | import java.util.List;
8 |
9 | public interface ApparelImagesRepository extends JpaRepository {
10 |
11 | @Query(value = "SELECT DISTINCT c FROM ApparelImages c")
12 | List getAllData();
13 | }
14 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/images/CarouselImagesRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.images;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.images.CarouselImages;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 |
7 | import java.util.List;
8 |
9 | public interface CarouselImagesRepository extends JpaRepository {
10 |
11 | @Query(value = "SELECT DISTINCT c FROM CarouselImages c")
12 | List getAllData();
13 | }
14 |
--------------------------------------------------------------------------------
/client/src/components/routes/navbar/bagButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import log from "loglevel";
3 | import LocalMallIcon from "@material-ui/icons/LocalMall";
4 | import {Badge} from "@material-ui/core";
5 | import {useSelector} from "react-redux";
6 |
7 | export default function BagButton() {
8 | const addToCart = useSelector(state => state.addToCartReducer)
9 |
10 | log.info(`[BagButton]: Rendering BagButton Component`)
11 | return (
12 |
14 |
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/service/AuthDataService.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.service;
2 |
3 | import com.ujjaval.ecommerce.authenticationservice.entity.UserInfo;
4 |
5 | import java.security.NoSuchAlgorithmException;
6 |
7 | public interface AuthDataService {
8 |
9 | UserInfo findByUsername(String username);
10 |
11 | UserInfo findByEmail(String email);
12 |
13 | void deleteByUsernamePassword(String username, String password) throws NoSuchAlgorithmException;
14 |
15 | void createUserProfile(UserInfo userInfo) throws NoSuchAlgorithmException;
16 | }
17 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dto/SearchSuggestionForThreeAttrDTO.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dto;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.Setter;
7 |
8 | import java.io.Serializable;
9 |
10 | @Getter
11 | @Setter
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class SearchSuggestionForThreeAttrDTO implements Serializable {
15 | Integer attr1_id;
16 | String attr1_type;
17 | Integer attr2_id;
18 | String attr2_type;
19 | Integer attr3_id;
20 | String attr3_type;
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/utils/resulttransformers/IListResultTransformer.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.utils.resulttransformers;
2 |
3 | import org.hibernate.transform.ResultTransformer;
4 |
5 | import java.util.List;
6 |
7 | @FunctionalInterface
8 | public interface IListResultTransformer extends ResultTransformer {
9 |
10 | /**
11 | * Default implementation returning the tuples list as-is.
12 | *
13 | * @param tuples tuples list
14 | * @return tuples list
15 | */
16 | @Override
17 | default List transformList(List tuples) {
18 | return tuples;
19 | }
20 | }
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dto/BrandImagesDTO.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dto;
2 |
3 | import lombok.*;
4 |
5 | import java.io.Serializable;
6 |
7 | @Getter
8 | @Setter
9 | @NoArgsConstructor
10 | @ToString
11 | public class BrandImagesDTO implements Serializable {
12 |
13 | private String title;
14 |
15 | private String imageLocalPath;
16 |
17 | private String imageURL;
18 |
19 | private BrandCategoryDTO brandInfo;
20 |
21 | }
22 |
23 | @Getter
24 | @Setter
25 | @NoArgsConstructor
26 | @ToString
27 | class BrandCategoryDTO implements Serializable {
28 | private int id;
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/config/AppConfig.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.config;
2 |
3 | import org.modelmapper.ModelMapper;
4 | import org.modelmapper.convention.MatchingStrategies;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | @Configuration
9 | public class AppConfig {
10 |
11 | @Bean
12 | public ModelMapper modelMapper() {
13 | ModelMapper modelMapper = new ModelMapper();
14 | modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.LOOSE);
15 | return modelMapper;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/server/payment-service/src/main/java/com/ujjaval/ecommerce/paymentservice/PaymentServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.paymentservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
8 |
9 | @SpringBootApplication
10 | public class PaymentServiceApplication {
11 | public static void main(String[] args) {
12 | SpringApplication.run(PaymentServiceApplication.class, args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/client/src/components/ui/error/httpError.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {BAD_REQUEST_ERROR_CODE, INTERNAL_SERVER_ERROR_CODE} from "../../../constants/http_error_codes";
3 | import {InternalServerError} from "./internalServerError";
4 | import {BadRequest} from "./badRequest";
5 | import log from 'loglevel';
6 |
7 | export const HTTPError = props => {
8 | log.info(`[HTTPError] props.statusCode = ${props.statusCode}`)
9 |
10 | switch (props.statusCode) {
11 | case INTERNAL_SERVER_ERROR_CODE:
12 | return
13 | case BAD_REQUEST_ERROR_CODE:
14 | return
15 | default:
16 | return null
17 | }
18 | };
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/categories/GenderCategoryRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.categories;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.GenderCategory;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 |
7 | import java.util.List;
8 |
9 | public interface GenderCategoryRepository extends JpaRepository {
10 |
11 | @Query(value = "SELECT g FROM GenderCategory g")
12 | List getAllData();
13 |
14 | GenderCategory findByType(String gender);
15 | }
16 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/categories/SortByCategoryRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.categories;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.SortByCategory;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 |
7 | import java.util.List;
8 |
9 | public interface SortByCategoryRepository extends JpaRepository {
10 |
11 | @Query(value = "SELECT s FROM SortByCategory s")
12 | List getAllData();
13 |
14 | SortByCategory findByType(String type);
15 | }
16 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=authentication-service
2 | server.port=${PORT}
3 | spring.profiles.active=${ACTIVE_PROFILE}
4 | spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_SCHEMA}?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC
5 | spring.datasource.username=${DB_USER}
6 | spring.datasource.password=${DB_PASS}
7 |
8 | # debugging purpose
9 | spring.jpa.properties.hibernate.format_sql=true
10 | logging.level.org.hibernate.SQL=DEBUG
11 | logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
12 | logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG
13 | logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dto/FilterAttributesWithTotalItemsDTO.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dto;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 |
7 | import java.io.Serializable;
8 |
9 | @Getter
10 | @Setter
11 | @NoArgsConstructor
12 | public class FilterAttributesWithTotalItemsDTO implements Serializable {
13 |
14 | Integer id;
15 | String value;
16 | Long totalItems;
17 |
18 | public FilterAttributesWithTotalItemsDTO(Integer id, String value, Long totalItems) {
19 | this.id = id;
20 | this.value = value;
21 | this.totalItems = totalItems;
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/categories/PriceRangeCategoryRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.categories;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.PriceRangeCategory;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 |
7 | import java.util.List;
8 |
9 | public interface PriceRangeCategoryRepository extends JpaRepository {
10 |
11 | @Query(value = "SELECT p FROM PriceRangeCategory p")
12 | List getAllData();
13 |
14 | PriceRangeCategory findByType(String type);
15 | }
16 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/categories/ProductBrandCategoryRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.categories;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.ProductBrandCategory;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 |
7 | import java.util.List;
8 |
9 | public interface ProductBrandCategoryRepository extends JpaRepository {
10 |
11 | @Query(value = "SELECT p FROM ProductBrandCategory p")
12 | List getAllData();
13 |
14 | ProductBrandCategory findByType(String brandName);
15 | }
16 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/entity/nosql/SellerBulkInfo.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.entity.nosql;
2 |
3 | import lombok.*;
4 | import org.springframework.data.annotation.Id;
5 | import org.springframework.data.mongodb.core.mapping.Document;
6 |
7 | import java.util.ArrayList;
8 |
9 | @Getter
10 | @Setter
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | @ToString
14 | @Document
15 | public class SellerBulkInfo {
16 |
17 | @Id
18 | private int id;
19 |
20 | private SellerMessage sellerMessage;
21 |
22 | private ArrayList sellerReview;
23 |
24 | private ArrayList sellerAccountNotification;
25 | }
26 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/config/CorsConfigurer.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.config;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc;
6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7 |
8 | @Configuration
9 | @EnableWebMvc
10 | public class CorsConfigurer implements WebMvcConfigurer
11 | {
12 | @Override
13 | public void addCorsMappings(CorsRegistry registry) {
14 | registry.addMapping("/**")
15 | .allowedMethods("GET", "POST");
16 | }
17 | }
--------------------------------------------------------------------------------
/server/payment-service/src/main/java/com/ujjaval/ecommerce/paymentservice/dto/PaymentStatus.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.paymentservice.dto;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @NoArgsConstructor
8 | @ToString
9 | public class PaymentStatus {
10 |
11 | boolean payment_failed;
12 | Long order_id;
13 | String charge_id;
14 | String txn_id;
15 | String receipt_url;
16 |
17 | public PaymentStatus(Long order_id, boolean payment_failed, String charge_id, String txn_id, String receipt_url) {
18 | this.order_id = order_id;
19 | this.payment_failed = payment_failed;
20 | this.charge_id = charge_id;
21 | this.txn_id = txn_id;
22 | this.receipt_url = receipt_url;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=common-data-service
2 | server.port=${PORT}
3 | spring.profiles.active=${ACTIVE_PROFILE}
4 | spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_SCHEMA}?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC
5 | spring.datasource.username=${DB_USER}
6 | spring.datasource.password=${DB_PASS}
7 |
8 | spring.cache.redis.time-to-live=10
9 |
10 | # debugging purpose
11 | spring.jpa.properties.hibernate.format_sql=true
12 | #logging.level.org.hibernate.SQL=DEBUG
13 | #logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
14 | #logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG
15 | #logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | .env
4 |
5 | # Client
6 | # dependencies
7 | /client/node_modules
8 | /client/.pnp
9 | /client/.pnp.js
10 |
11 | # testing
12 | /client/coverage
13 |
14 | # production
15 | /build
16 |
17 | # misc
18 | .DS_Store
19 | client/.env
20 | client/.env.local
21 | client/.env.development.local
22 | client/.env.test.local
23 | client/.env.production.local
24 | .idea/
25 | node_modules/
26 | package-lock.json
27 |
28 | client/npm-debug.log*
29 | client/yarn-debug.log*
30 | client/yarn-error.log*
31 |
32 | # server
33 | server/common-data-service/src/main/resources/static/images/
34 | server/authentication-service/.idea/
35 | server/common-data-service/.idea/
36 | server/seller-account-service/.idea/
37 |
--------------------------------------------------------------------------------
/.env-sample:
--------------------------------------------------------------------------------
1 | MYSQL_ROOT_PASSWORD=mypass
2 | MYSQL_DATABASE=ecommerce_app_database
3 | MYSQL_USER=mysqluser
4 | MYSQL_PASSWORD=mypass
5 |
6 | DB_PORT=3306
7 | DB_SCHEMA=ecommerce_app_database
8 | DB_USER=mysqluser
9 | DB_PASS=mypass
10 |
11 | REACT_APP_STRIPE_PUBLISH_KEY=pk_test_51H805Oa3n3j3JVXUotWOsdf223PXI2ZehJ0s4QSQK0WjEJer78w87wer8h2u3bo32sTVcxyh5bDuulBildNrp
12 | REACT_APP_GOOGLE_AUTH_CLIENT_ID=23432543654-m4s23i3dsf72938gubrj32n8932ro9knqudv.apps.googleusercontent.com
13 | REACT_APP_PORT=3000
14 |
15 | REACT_CLIENT_URL=http://localhost:3000
16 | REACT_APP_ENVIRONMENT=dev
17 | ACTIVE_PROFILE=dev
18 |
19 | REDIS_PASSWORD=mypass
20 | REDIS_PORT=6379
21 |
22 | AUTHENTICATION_SERVICE_PORT=7000
23 | PAYMENT_SERVICE_PORT=9050
24 | COMMON_DATA_SERVICE_PORT=9000
25 | SEARCH_SUGGESTION_SERVICE_PORT=10000
26 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/model/HomeTabsDataResponse.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.model;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.dto.BrandsAndApparelsDTO;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.Setter;
7 | import lombok.ToString;
8 |
9 | import java.io.Serializable;
10 |
11 | @Getter
12 | @Setter
13 | @NoArgsConstructor
14 | @ToString
15 | public class HomeTabsDataResponse implements Serializable {
16 |
17 | private BrandsAndApparelsDTO men;
18 | private BrandsAndApparelsDTO women;
19 | private BrandsAndApparelsDTO boys;
20 | private BrandsAndApparelsDTO girls;
21 | private BrandsAndApparelsDTO essentials;
22 | private BrandsAndApparelsDTO homeAndLiving;
23 | }
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/config/CorsConfig.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.config;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc;
6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7 |
8 | @Configuration
9 | @EnableWebMvc
10 | public class CorsConfig implements WebMvcConfigurer
11 | {
12 | @Override
13 | public void addCorsMappings(CorsRegistry registry) {
14 | registry.addMapping("/**");
15 | //registry.addMapping("/**").allowedOrigins("https://shoppers-ecom-app.herokuapp.com")
16 | // .allowedMethods("GET", "POST");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/java/com/ujjaval/ecommerce/searchsuggestionservice/config/CorsConfig.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.searchsuggestionservice.config;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc;
6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7 |
8 | @Configuration
9 | @EnableWebMvc
10 | public class CorsConfig implements WebMvcConfigurer
11 | {
12 | @Override
13 | public void addCorsMappings(CorsRegistry registry) {
14 | registry.addMapping("/**").allowedOrigins("https://shoppers-ecom-app.herokuapp.com")
15 | .allowedMethods("GET", "POST", "OPTIONS", "DELETE");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/categories/SortByCategory.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.categories;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import javax.persistence.Entity;
9 | import javax.persistence.GeneratedValue;
10 | import javax.persistence.GenerationType;
11 | import javax.persistence.Id;
12 | import java.io.Serializable;
13 |
14 | @Getter
15 | @Setter
16 | @NoArgsConstructor
17 | @ToString
18 | @Entity
19 | public class SortByCategory implements Serializable {
20 | @Id
21 | private int id;
22 |
23 | private String type;
24 |
25 | public SortByCategory(int id, String type) {
26 | this.id = id;
27 | this.type = type;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/CommonDataServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.controller.CommonDataController;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.cache.annotation.EnableCaching;
7 | import org.springframework.context.ConfigurableApplicationContext;
8 |
9 | @SpringBootApplication
10 | @EnableCaching
11 | public class CommonDataServiceApplication {
12 |
13 | public static void main(final String[] args) {
14 | ConfigurableApplicationContext context = SpringApplication.run(CommonDataServiceApplication.class, args);
15 | context.getBean(CommonDataController.class).fillWithTestData();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/entity/sql/SellerInfo.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.entity.sql;
2 |
3 | import lombok.*;
4 |
5 | import javax.persistence.*;
6 |
7 | @Getter
8 | @Setter
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @ToString
12 | @Entity
13 | public class SellerInfo {
14 |
15 | @Id
16 | private int id;
17 |
18 | private int userId;
19 |
20 | private double balance;
21 |
22 | private float rating;
23 |
24 | private String companyName;
25 |
26 | private boolean verificationStatus;
27 |
28 | private int accountType;
29 |
30 | private String lastLoginTime;
31 |
32 | private int totalActiveOrders;
33 |
34 | private int totalCancelledOrders;
35 |
36 | private int totalDeliveredOrders;
37 |
38 | private int totalOrders;
39 | }
40 |
--------------------------------------------------------------------------------
/client/src/hooks/useCartTotal.js:
--------------------------------------------------------------------------------
1 | import {useEffect} from "react";
2 | import log from "loglevel";
3 | import {addToCartReducer} from "../reducers/screens/commonScreenReducer";
4 | import Cookies from "js-cookie";
5 | import {CART_TOTAL} from "../actions/types";
6 | import {CART_TOTAL_COOKIE} from "../constants/cookies";
7 | import {useDispatch} from "react-redux";
8 |
9 | export function useCartTotal() {
10 | const dispatch = useDispatch()
11 |
12 | useEffect(() => {
13 | log.info("[useCartTotal] Component will mount...")
14 |
15 | let cartTotal = Cookies.get(CART_TOTAL_COOKIE)
16 | if (cartTotal) {
17 | cartTotal = JSON.parse(cartTotal)
18 | dispatch({
19 | type: CART_TOTAL,
20 | payload: parseInt(cartTotal)
21 | })
22 | }
23 |
24 | // eslint-disable-next-line
25 | }, [addToCartReducer])
26 | }
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/java/com/ujjaval/ecommerce/searchsuggestionservice/SearchSuggestionServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.searchsuggestionservice;
2 |
3 | import com.ujjaval.ecommerce.searchsuggestionservice.controller.SearchSuggestionController;
4 | import org.json.JSONException;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.ConfigurableApplicationContext;
8 |
9 | import java.io.IOException;
10 |
11 | @SpringBootApplication
12 | public class SearchSuggestionServiceApplication {
13 |
14 | public static void main(String[] args) {
15 | ConfigurableApplicationContext context = SpringApplication.run(SearchSuggestionServiceApplication.class, args);
16 | context.getBean(SearchSuggestionController.class).loadSearchSuggestions();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/client/src/api/service_api.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const {
4 | REACT_APP_COMMON_DATA_SERVICE_PORT,
5 | REACT_APP_AUTHENTICATION_SERVICE_PORT,
6 | REACT_APP_SEARCH_SUGGESTION_SERVICE_PORT,
7 | REACT_APP_COMMON_DATA_SERVICE_URL,
8 | REACT_APP_AUTHENTICATION_SERVICE_URL,
9 | REACT_APP_SEARCH_SUGGESTION_SERVICE_URL
10 | } = process.env
11 |
12 | export const authServiceAPI = axios.create({
13 | baseURL: REACT_APP_AUTHENTICATION_SERVICE_URL || `http://localhost:${REACT_APP_AUTHENTICATION_SERVICE_PORT}`
14 | })
15 |
16 | export const commonServiceAPI = axios.create({
17 | baseURL: REACT_APP_COMMON_DATA_SERVICE_URL || `http://localhost:${REACT_APP_COMMON_DATA_SERVICE_PORT}`
18 | })
19 |
20 | export const searchSuggestionServiceAPI = axios.create({
21 | baseURL: REACT_APP_SEARCH_SUGGESTION_SERVICE_URL || `http://localhost:${REACT_APP_SEARCH_SUGGESTION_SERVICE_PORT}`
22 | })
--------------------------------------------------------------------------------
/client/src/components/ui/error/emptyShoppingBag.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import emptyCheckoutCartImage from '../../../images/emptyCheckoutCart.png'
3 | import {RenderErrorImage} from "./renderErrorImage";
4 | import {Button, Grid} from "@material-ui/core";
5 |
6 | export const EmptyShoppingBag = (props) => {
7 |
8 | return (
9 | <>
10 |
11 |
12 |
13 |
18 |
19 |
20 | >
21 | );
22 | };
--------------------------------------------------------------------------------
/client/.env-sample:
--------------------------------------------------------------------------------
1 | REACT_APP_STRIPE_PUBLISH_KEY=pk_test_5dsf4534jkmn4nm345QSQK0WjEJKx1PNH3mJxeUkA45345345Vcxyh5bDuulBildNrp3MWn005xEkAdJ4
2 | REACT_APP_GOOGLE_AUTH_CLIENT_ID=357808142500-sdfsndln4oh5345435.apps.googleusercontent.com
3 |
4 | # Add below ports if you are running on your machine
5 | REACT_APP_AUTHENTICATION_SERVICE_PORT=7000
6 | REACT_APP_PAYMENT_SERVICE_PORT=9050
7 | REACT_APP_COMMON_DATA_SERVICE_PORT=9000
8 | REACT_APP_SEARCH_SUGGESTION_SERVICE_PORT=10000
9 | REACT_APP_COMMON_DATA_SERVICE_IP=localhost
10 |
11 | # Add URL if you dont want to use port.
12 | # Higher priority is given to URL over PORTs.
13 | REACT_APP_AUTHENTICATION_SERVICE_URL=
14 | REACT_APP_COMMON_DATA_SERVICE_URL=
15 | REACT_APP_PAYMENT_SERVICE_URL=
16 | REACT_APP_SEARCH_SUGGESTION_SERVICE_URL=
17 |
18 | REACT_APP_ENVIRONMENT=
19 |
--------------------------------------------------------------------------------
/server/payment-service/Dockerfile-prod:
--------------------------------------------------------------------------------
1 | # Docker multi-stage build
2 |
3 | # 1. Building the App with Maven
4 | FROM maven:3-jdk-11
5 |
6 | ADD . /payment_service_staging
7 |
8 | WORKDIR /payment_service_staging
9 |
10 | # Just echo so we can see, if everything is there
11 | RUN ls -l
12 |
13 | # Run Maven build
14 | RUN mvn clean install -DskipTests
15 |
16 | # 2. Just using the build artifact and then removing the build-container
17 | FROM openjdk:11-jdk
18 |
19 | VOLUME /tmp
20 |
21 | # Add Spring Boot payment-service.jar to Container
22 | COPY --from=0 /payment_service_staging/target/payment-service.jar payment-service.jar
23 |
24 | # Fire up our Spring Boot app by default
25 | CMD ["sh", "-c", "java -Dserver.port=$PORT -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 -XX:+UseContainerSupport -Dspring.profiles.active=$ACTIVE_PROFILE -Djava.security.egd=file:/dev/./urandom -jar payment-service.jar" ]
26 |
27 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/info/queryhelpers/context/ParamsToQueryContext.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.info.queryhelpers.context;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 |
7 | import java.util.HashMap;
8 | import java.util.List;
9 |
10 | @Getter
11 | @Setter
12 | @NoArgsConstructor
13 | public class ParamsToQueryContext {
14 | String sortBy;
15 | HashMap mapParams;
16 | List conditions;
17 | String[] pageInfo;
18 |
19 | public ParamsToQueryContext(String sortBy, HashMap mapParams,
20 | List conditions, String[] pageInfo) {
21 | this.sortBy = sortBy;
22 | this.mapParams = mapParams;
23 | this.conditions = conditions;
24 | this.pageInfo = pageInfo;
25 | }
26 | }
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/categories/ApparelCategoryRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.categories;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.ApparelCategory;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 |
7 | import java.util.List;
8 |
9 | public interface ApparelCategoryRepository extends JpaRepository {
10 |
11 | @Query(value = "SELECT c FROM ApparelImages c where c.apparelCategory.type=?1 and" +
12 | " c.genderCategory.type=?2")
13 | ApparelCategory findByClothesTypeAndGender(String clothesType, String Gender);
14 |
15 | @Query(value = "SELECT c FROM ApparelCategory c")
16 | List getAllData();
17 |
18 | ApparelCategory findByType(String title);
19 | }
20 |
--------------------------------------------------------------------------------
/server/payment-service/Dockerfile-dev:
--------------------------------------------------------------------------------
1 | # Docker multi-stage build
2 |
3 | # 1. Building the App with Maven
4 | FROM maven:3-jdk-11
5 |
6 | ADD ./server/payment-service /payment_service_staging
7 |
8 | WORKDIR /payment_service_staging
9 |
10 | # Just echo so we can see, if everything is there
11 | RUN ls -l
12 |
13 | # Run Maven build
14 | RUN mvn clean install -DskipTests
15 |
16 | # 2. Just using the build artifact and then removing the build-container
17 | FROM openjdk:11-jdk
18 |
19 | VOLUME /tmp
20 |
21 | # Add Spring Boot payment-service.jar to Container
22 | COPY --from=0 /payment_service_staging/target/payment-service.jar payment-service.jar
23 |
24 | # Fire up our Spring Boot app by default
25 | CMD ["sh", "-c", "java -Dserver.port=$PORT -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 -XX:+UseContainerSupport -Dspring.profiles.active=$ACTIVE_PROFILE -Djava.security.egd=file:/dev/./urandom -jar payment-service.jar" ]
26 |
27 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/entity/UserInfo.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.entity;
2 |
3 | import lombok.*;
4 |
5 | import javax.persistence.*;
6 |
7 | @Getter
8 | @Setter
9 | @NoArgsConstructor
10 | @ToString
11 | @Entity
12 | public class UserInfo {
13 |
14 | @Id
15 | @GeneratedValue(strategy=GenerationType.IDENTITY)
16 | private int userId;
17 |
18 | private String firstName;
19 |
20 | private String lastName;
21 |
22 | private String username;
23 |
24 | private String password;
25 |
26 | private String email;
27 |
28 | public UserInfo(String firstName, String lastName, String username, String password, String email) {
29 | this.firstName = firstName;
30 | this.lastName = lastName;
31 | this.username = username;
32 | this.password = password;
33 | this.email = email;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/server/common-data-service/Dockerfile-prod:
--------------------------------------------------------------------------------
1 | # Docker multi-stage build
2 |
3 | # 1. Building the App with Maven
4 | FROM maven:3-jdk-11
5 |
6 | ADD . /common_data_service_staging
7 |
8 | WORKDIR /common_data_service_staging
9 |
10 | # Just echo so we can see, if everything is there
11 | RUN ls -l
12 |
13 | # Run Maven build
14 | RUN mvn clean install -DskipTests
15 |
16 | # 2. Just using the build artifact and then removing the build-container
17 | FROM openjdk:11-jdk
18 |
19 | VOLUME /tmp
20 |
21 | # Add Spring Boot common-data-service.jar to Container
22 | COPY --from=0 /common_data_service_staging/target/common-data-service.jar common-data-service.jar
23 |
24 | # Fire up our Spring Boot app by default
25 | CMD ["sh", "-c", "java -Dserver.port=$PORT -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 -XX:+UseContainerSupport -Dspring.profiles.active=$ACTIVE_PROFILE -Djava.security.egd=file:/dev/./urandom -jar common-data-service.jar" ]
26 |
27 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dto/ApparelImagesDTO.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dto;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import java.io.Serializable;
9 |
10 | @Getter
11 | @Setter
12 | @NoArgsConstructor
13 | @ToString
14 | public class ApparelImagesDTO implements Serializable {
15 |
16 | private String title;
17 |
18 | private String imageLocalPath;
19 |
20 | private String imageURL;
21 |
22 | private ApparelDTO apparelInfo;
23 |
24 | private GenderDTO genderInfo;
25 |
26 | }
27 |
28 | @Getter
29 | @Setter
30 | @NoArgsConstructor
31 | @ToString
32 | class ApparelDTO implements Serializable {
33 | private int id;
34 | }
35 |
36 | @Getter
37 | @Setter
38 | @NoArgsConstructor
39 | @ToString
40 | class GenderDTO implements Serializable {
41 | private int id;
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/server/authentication-service/Dockerfile-prod:
--------------------------------------------------------------------------------
1 | # Docker multi-stage build
2 |
3 | # 1. Building the App with Maven
4 | FROM maven:3-jdk-11
5 |
6 | ADD . /authentication_service_staging
7 |
8 | WORKDIR /authentication_service_staging
9 |
10 | # Just echo so we can see, if everything is there
11 | RUN ls -l
12 |
13 | # Run Maven build
14 | RUN mvn clean install -DskipTests
15 |
16 | # 2. Just using the build artifact and then removing the build-container
17 | FROM openjdk:11-jdk
18 |
19 | VOLUME /tmp
20 |
21 | # Add Spring Boot authentication-service.jar to Container
22 | COPY --from=0 /authentication_service_staging/target/authentication-service.jar authentication-service.jar
23 |
24 | # Fire up our Spring Boot app by default
25 | CMD ["sh", "-c", "java -Dserver.port=$PORT -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 -XX:+UseContainerSupport -Dspring.profiles.active=$ACTIVE_PROFILE -Djava.security.egd=file:/dev/./urandom -jar authentication-service.jar" ]
26 |
27 |
--------------------------------------------------------------------------------
/client/src/styles/materialUI/tabStyles.js:
--------------------------------------------------------------------------------
1 | import {makeStyles} from "@material-ui/core/styles";
2 |
3 | const useTabStyles = makeStyles((theme) => ({
4 | root: {
5 | flexGrow: 1,
6 | },
7 | paperRoot: {
8 | '& > *': {
9 | width: theme.spacing(45),
10 | height: theme.spacing(45),
11 | },
12 | position: "fixed",
13 | zIndex: 1201
14 | },
15 | listItemTextRoot: {
16 | '&:hover': {
17 | fontWeight: 500
18 | },
19 | color: "black",
20 | },
21 | tabRoot: {
22 | width: "auto",
23 | height: 80,
24 | flexGrow: 1,
25 | [theme.breakpoints.up('lg')]: {
26 | minWidth: 50,
27 | },
28 | },
29 | tabsWrapper: {
30 | fontWeight: "600",
31 | color: "black",
32 | [theme.breakpoints.up('md')]: {
33 | fontSize: "1rem",
34 | }
35 | },
36 | }));
37 |
38 | export default useTabStyles;
--------------------------------------------------------------------------------
/server/common-data-service/Dockerfile-dev:
--------------------------------------------------------------------------------
1 | # Docker multi-stage build
2 |
3 | # 1. Building the App with Maven
4 | FROM maven:3-jdk-11
5 |
6 | ADD ./server/common-data-service /common_data_service_staging
7 |
8 | WORKDIR /common_data_service_staging
9 |
10 | # Just echo so we can see, if everything is there
11 | RUN ls -l
12 |
13 | # Run Maven build
14 | RUN mvn clean install -DskipTests
15 |
16 | # 2. Just using the build artifact and then removing the build-container
17 | FROM openjdk:11-jdk
18 |
19 | VOLUME /tmp
20 |
21 | # Add Spring Boot common-data-service.jar to Container
22 | COPY --from=0 /common_data_service_staging/target/common-data-service.jar common-data-service.jar
23 |
24 | # Fire up our Spring Boot app by default
25 | CMD ["sh", "-c", "java -Dserver.port=$PORT -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 -XX:+UseContainerSupport -Dspring.profiles.active=$ACTIVE_PROFILE -Djava.security.egd=file:/dev/./urandom -jar common-data-service.jar" ]
26 |
27 |
--------------------------------------------------------------------------------
/client/src/ErrorBoundary.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {GenericErrorMsg} from "./components/ui/error/GenericErrorMsg";
3 |
4 | class ErrorBoundary extends Component {
5 |
6 | constructor(props) {
7 | super(props);
8 |
9 | this.state = {
10 | hasError: false
11 | }
12 | }
13 |
14 | static getDerivedStateFromError(error) {
15 | return {
16 | hasError: true
17 | }
18 | }
19 |
20 | componentDidCatch(error, errorInfo) {
21 | // You can also log the error to an error reporting service
22 | // logErrorToMyService(error, errorInfo);
23 | console.log(`error = ${error}, errorInfo = ${JSON.stringify(errorInfo)}`)
24 | }
25 |
26 | render() {
27 | if (this.state.hasError) {
28 | return (
29 |
30 | )
31 | }
32 | return this.props.children
33 | }
34 | }
35 |
36 | export default ErrorBoundary;
--------------------------------------------------------------------------------
/server/authentication-service/Dockerfile-dev:
--------------------------------------------------------------------------------
1 | # Docker multi-stage build
2 |
3 | # 1. Building the App with Maven
4 | FROM maven:3-jdk-11
5 |
6 | ADD ./server/authentication-service /authentication_service_staging
7 |
8 | WORKDIR /authentication_service_staging
9 |
10 | # Just echo so we can see, if everything is there
11 | RUN ls -l
12 |
13 | # Run Maven build
14 | RUN mvn clean install -DskipTests
15 |
16 | # 2. Just using the build artifact and then removing the build-container
17 | FROM openjdk:11-jdk
18 |
19 | VOLUME /tmp
20 |
21 | # Add Spring Boot authentication-service.jar to Container
22 | COPY --from=0 /authentication_service_staging/target/authentication-service.jar authentication-service.jar
23 |
24 | # Fire up our Spring Boot app by default
25 | CMD ["sh", "-c", "java -Dserver.port=$PORT -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 -XX:+UseContainerSupport -Dspring.profiles.active=$ACTIVE_PROFILE -Djava.security.egd=file:/dev/./urandom -jar authentication-service.jar" ]
--------------------------------------------------------------------------------
/client/src/components/ui/error/pageNotFound.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Grid, Button} from "@material-ui/core";
3 | import pageNotFoundImage from '../../../images/pageNotFound404.png'
4 | import history from "../../../history";
5 | import {RenderErrorImage} from "./renderErrorImage";
6 |
7 | export const PageNotFound = () => {
8 | const onHomeBtnClick = () => {
9 | history.push(`/`);
10 | }
11 |
12 | return (
13 | <>
14 |
15 |
16 |
17 |
22 |
23 |
24 | >
25 | )
26 | ;
27 | };
--------------------------------------------------------------------------------
/server/search-suggestion-service/Dockerfile-prod:
--------------------------------------------------------------------------------
1 | # Docker multi-stage build
2 |
3 | # 1. Building the App with Maven
4 | FROM maven:3-jdk-11
5 |
6 | ADD . /search_suggestion_service_staging
7 |
8 | WORKDIR /search_suggestion_service_staging
9 |
10 | # Just echo so we can see, if everything is there
11 | RUN ls -l
12 |
13 | # Run Maven build
14 | RUN mvn clean install -DskipTests
15 |
16 | # 2. Just using the build artifact and then removing the build-container
17 | FROM openjdk:11-jdk
18 |
19 | VOLUME /tmp
20 |
21 | # Add Spring Boot search-suggestion-service.jar to Container
22 | COPY --from=0 /search_suggestion_service_staging/target/search-suggestion-service.jar search-suggestion-service.jar
23 |
24 | # Fire up our Spring Boot app by default
25 | CMD ["sh", "-c", "java -Dserver.port=$PORT -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 -XX:+UseContainerSupport -Dspring.profiles.active=$ACTIVE_PROFILE -Djava.security.egd=file:/dev/./urandom -jar search-suggestion-service.jar" ]
26 |
27 |
--------------------------------------------------------------------------------
/client/src/components/ui/error/searchMatchesNotFound.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Box} from "@material-ui/core";
3 | import searchMatchesNotFoundImage from '../../../images/searchMatchesNotFound404.png'
4 |
5 | export const SearchMatchesNotFound = () => {
6 |
7 | return (
8 |
13 |
14 |
15 |
16 |
17 | We couldn't find any matches!
18 |
19 |
20 | Please check the spelling or try searching something else
21 |
22 |
23 | );
24 | };
--------------------------------------------------------------------------------
/client/src/helper/updateQueryString.js:
--------------------------------------------------------------------------------
1 | export const updateQueryString = (history, attributeToUpdate, id, idList) => {
2 | let route = history.location.pathname
3 | let queryStr = history.location.search
4 |
5 | if (history.location.search.search(attributeToUpdate) === -1) {
6 | return `${route}${queryStr}::${attributeToUpdate}=${id}`
7 | } else {
8 |
9 | let attributes = queryStr.split("::")
10 | let newQueryStr = []
11 | for (let i = 0; i < attributes.length; ++i) {
12 | if (attributes[i].search(attributeToUpdate) !== -1) {
13 | if (idList.length > 0) {
14 | newQueryStr.push(attributes[i].replace(
15 | new RegExp(`${attributeToUpdate}=(.*)`),
16 | `${attributeToUpdate}=${idList.toString()}`))
17 | }
18 | continue
19 | }
20 | newQueryStr.push(attributes[i])
21 | }
22 |
23 | return newQueryStr.join("::")
24 | }
25 | }
--------------------------------------------------------------------------------
/server/search-suggestion-service/Dockerfile-dev:
--------------------------------------------------------------------------------
1 | # Docker multi-stage build
2 |
3 | # 1. Building the App with Maven
4 | FROM maven:3-jdk-11
5 |
6 | ADD ./server/search-suggestion-service /search_suggestion_service_staging
7 |
8 | WORKDIR /search_suggestion_service_staging
9 |
10 | # Just echo so we can see, if everything is there
11 | RUN ls -l
12 |
13 | # Run Maven build
14 | RUN mvn clean install -DskipTests
15 |
16 | # 2. Just using the build artifact and then removing the build-container
17 | FROM openjdk:11-jdk
18 |
19 | VOLUME /tmp
20 |
21 | # Add Spring Boot search-suggestion-service.jar to Container
22 | COPY --from=0 /search_suggestion_service_staging/target/search-suggestion-service.jar search-suggestion-service.jar
23 |
24 | # Fire up our Spring Boot app by default
25 | CMD ["sh", "-c", "java -Dserver.port=$PORT -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 -XX:+UseContainerSupport -Dspring.profiles.active=$ACTIVE_PROFILE -Djava.security.egd=file:/dev/./urandom -jar search-suggestion-service.jar" ]
26 |
27 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/util/Md5Util.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.util;
2 |
3 | import javax.xml.bind.DatatypeConverter;
4 | import java.security.MessageDigest;
5 | import java.security.NoSuchAlgorithmException;
6 |
7 | public class Md5Util {
8 |
9 | public static Md5Util singletonInstance = null;
10 | private String data;
11 |
12 | private Md5Util() {
13 | }
14 |
15 | public static Md5Util getInstance() {
16 | if(singletonInstance == null) {
17 | return new Md5Util();
18 | }
19 | return singletonInstance;
20 | }
21 |
22 | public String getMd5Hash(String data) throws NoSuchAlgorithmException {
23 | MessageDigest md = MessageDigest.getInstance("MD5");
24 | md.update(data.getBytes());
25 | byte[] digest = md.digest();
26 | String hash = DatatypeConverter
27 | .printHexBinary(digest).toLowerCase();
28 | return hash;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/client/src/styles/materialUI/filterNavBarStyles.js:
--------------------------------------------------------------------------------
1 | import {makeStyles} from "@material-ui/core/styles";
2 |
3 | const drawerWidth = 240;
4 |
5 | export const useFilterNavBarStyles = makeStyles((theme) => ({
6 | root: {
7 | display: 'flex',
8 | },
9 | drawer: {
10 | [theme.breakpoints.up('sm')]: {
11 | width: drawerWidth,
12 | flexShrink: 0,
13 | },
14 | },
15 | menuButton: {
16 | marginRight: theme.spacing(2),
17 | [theme.breakpoints.up('sm')]: {
18 | display: 'none',
19 | },
20 | },
21 | // necessary for content to be below app bar
22 | toolbar: theme.mixins.toolbar,
23 | drawerPaper: {
24 | top: 80,
25 | width: drawerWidth,
26 | height: "calc(100% - 80px)",
27 | overflow: "none",
28 | overflowY: "auto",
29 | display: "block",
30 | },
31 | content: {
32 | flexGrow: 1,
33 | backgroundColor: theme.palette.background.default,
34 | paddingTop: "85px",
35 | },
36 | }));
--------------------------------------------------------------------------------
/client/src/components/routes/signin/GoogleAuthButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {connect} from "react-redux";
3 | import {Button, Icon} from "semantic-ui-react";
4 | import {signInUsingOAuth} from "../../../actions"
5 | import log from 'loglevel';
6 |
7 | class GoogleAuthButton extends React.Component {
8 | onSignInClick = () => {
9 | log.info(`[GoogleAuthButton] google button is clicked`)
10 | this.props.signInUsingOAuth(this.props.googleAuthReducer.oAuth)
11 | };
12 |
13 | render() {
14 | log.info('[GoogleAuthButton] Rendering GoogleAuthButton Component')
15 | return (
16 |
19 | )
20 | }
21 | }
22 |
23 | const mapStateToProps = (state) => {
24 | return {
25 | googleAuthReducer: state.googleAuthReducer
26 | }
27 | }
28 |
29 | export default connect(mapStateToProps, {signInUsingOAuth})(GoogleAuthButton);
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/categories/PriceRangeCategory.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.categories;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.ProductInfo;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 | import lombok.Setter;
8 | import lombok.ToString;
9 |
10 | import javax.persistence.*;
11 | import java.io.Serializable;
12 | import java.util.List;
13 |
14 | @Getter
15 | @Setter
16 | @NoArgsConstructor
17 | @ToString
18 | @Entity
19 | public class PriceRangeCategory implements Serializable {
20 | @Id
21 | private int id;
22 |
23 | private String type;
24 |
25 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "priceRangeCategory")
26 | @JsonIgnore
27 | private List productInfos;
28 |
29 | public PriceRangeCategory(int id, String type) {
30 | this.id = id;
31 | this.type = type;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/client/src/styles/semanticUI/customStyles.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 | import {Dimmer, Segment, Dropdown, Menu} from 'semantic-ui-react';
3 |
4 | export const StyledSegment = styled(Segment)({
5 | border: 'none !important',
6 | margin: '0 !important',
7 | padding: '0 !important',
8 | });
9 |
10 | export const StyledDimmer = styled(Dimmer)({
11 | padding: '0 !important',
12 | backgroundColor: 'rgba(0,0,0,0.2) !important',
13 | });
14 |
15 | export const StyledSearchBarDimmer = styled(Dimmer)({
16 | height: '100vh !important',
17 | });
18 |
19 | export const StyledLargeDropdown = styled(Dropdown)({
20 | width: "225px"
21 | });
22 |
23 | export const StyledSmallMenu = styled(Menu)({
24 | minHeight: "inherit !important",
25 | minWidth: "inherit !important",
26 | width: "inherit !important",
27 | });
28 |
29 | export const StyledSmallDropdown = styled(Dropdown)({
30 | width: "60px",
31 | height: "inherit !important",
32 | maxHeight: "17px !important",
33 | fontSize: "0.8rem",
34 | padding: "2px !important"
35 | });
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/images/CarouselImages.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.images;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import javax.persistence.Entity;
9 | import javax.persistence.GeneratedValue;
10 | import javax.persistence.GenerationType;
11 | import javax.persistence.Id;
12 | import java.io.Serializable;
13 |
14 | @Getter
15 | @Setter
16 | @NoArgsConstructor
17 | @ToString
18 | @Entity
19 | public class CarouselImages implements Serializable {
20 | @Id
21 | @GeneratedValue(strategy= GenerationType.IDENTITY)
22 | private int id;
23 |
24 | private String link;
25 |
26 | private String imageLocalPath;
27 |
28 | private String imageURL;
29 |
30 | public CarouselImages(String link, String imageLocalPath, String imageURL) {
31 | this.link = link;
32 | this.imageLocalPath = imageLocalPath;
33 | this.imageURL = imageURL;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/client/src/logger/LoggerConfig.js:
--------------------------------------------------------------------------------
1 | import Logger from './Logger';
2 | import {LoggerRegisterInfo} from './loggerTypes'
3 |
4 | class LoggerConfig {
5 |
6 | static loggerMap
7 |
8 | static enableAll() {
9 | Logger.globalLoggerLevel = Logger.Levels.ERROR
10 | }
11 |
12 | static enableAllWithSpecificLevel(level) {
13 | Logger.globalLoggerLevel = level
14 | }
15 |
16 | static disableAll() {
17 | Logger.globalLoggerLevel = Logger.Levels.DISABLE
18 | }
19 |
20 | static getLogger(id) {
21 | if (this.loggerMap.has(id)) {
22 | return this.loggerMap.get(id)
23 | }
24 | }
25 |
26 | static setLoggerMap() {
27 | if(!this.loggerMap) {
28 | this.loggerMap = new Map()
29 | }
30 | }
31 |
32 | static subscribeAllLoggers() {
33 | this.setLoggerMap()
34 | LoggerRegisterInfo.map(({id, level}) => {
35 | // console.log("Subscribing Logger id = " + id + ", Level = " + level)
36 | this.loggerMap.set(id, new Logger(level))
37 | })
38 | }
39 | }
40 |
41 | export default LoggerConfig;
--------------------------------------------------------------------------------
/client/src/hooks/useClickAway.js:
--------------------------------------------------------------------------------
1 | import{ useEffect } from "react";
2 | import log from "loglevel";
3 |
4 | /**
5 | * Hook that alerts clicks outside of the passed ref
6 | */
7 | export function useClickAway(ref, closeHandler) {
8 | useEffect(() => {
9 | /**
10 | * Alert if clicked on outside of element
11 | */
12 |
13 | function handleClickOutside(event) {
14 | try {
15 | if (event.target.getAttribute("class") &&
16 | event.target.getAttribute("class").localeCompare("MuiBackdrop-root") === 0) {
17 | closeHandler()
18 | }
19 | } catch (e) {
20 | log.error(`[useClickAway] event.target.getAttribute("class") is empty`)
21 | }
22 | }
23 |
24 | // Bind the event listener
25 | document.addEventListener("mousedown", handleClickOutside);
26 | return () => {
27 | // Unbind the event listener on clean up
28 | document.removeEventListener("mousedown", handleClickOutside);
29 | };
30 |
31 | // eslint-disable-next-line
32 | }, [ref]);
33 | }
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/info/ContactInfo.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.info;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.Setter;
7 | import lombok.ToString;
8 |
9 | import javax.persistence.*;
10 | import java.util.List;
11 |
12 | @Getter
13 | @Setter
14 | @NoArgsConstructor
15 | @ToString
16 | @Entity
17 | public class ContactInfo {
18 |
19 | @Id
20 | @GeneratedValue(strategy= GenerationType.IDENTITY)
21 | private int id;
22 |
23 | private String email;
24 |
25 | private String office;
26 |
27 | private String mobile;
28 |
29 | private String other;
30 |
31 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "contactInfo")
32 | @JsonIgnore
33 | private List banks;
34 |
35 | public ContactInfo(String email, String office, String mobile, String other) {
36 | this.email = email;
37 | this.office = office;
38 | this.mobile = mobile;
39 | this.other = other;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/model/MainScreenResponse.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.model;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.dto.BrandImagesDTO;
4 | import com.ujjaval.ecommerce.commondataservice.dto.ApparelImagesDTO;
5 | import com.ujjaval.ecommerce.commondataservice.entity.sql.images.CarouselImages;
6 | import lombok.Getter;
7 | import lombok.NoArgsConstructor;
8 | import lombok.Setter;
9 | import lombok.ToString;
10 |
11 | import java.io.Serializable;
12 | import java.util.List;
13 |
14 | @Getter
15 | @Setter
16 | @NoArgsConstructor
17 | @ToString
18 | public class MainScreenResponse implements Serializable {
19 |
20 | private List brands;
21 | private List apparels;
22 | private List carousels;
23 |
24 | public MainScreenResponse(List brands,
25 | List apparels,
26 | List carousels) {
27 | this.brands = brands;
28 | this.apparels = apparels;
29 | this.carousels = carousels;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/images/BrandImages.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.images;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.ProductBrandCategory;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.Setter;
7 | import lombok.ToString;
8 |
9 | import javax.persistence.*;
10 |
11 | @Getter
12 | @Setter
13 | @NoArgsConstructor
14 | @ToString
15 | @Entity
16 | public class BrandImages {
17 | @Id
18 | @GeneratedValue(strategy= GenerationType.IDENTITY)
19 | private int id;
20 |
21 | private String title;
22 |
23 | private String imageLocalPath;
24 |
25 | private String imageURL;
26 |
27 | @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
28 | @JoinColumn(name = "brand_id", referencedColumnName = "id")
29 | private ProductBrandCategory productBrandCategory;
30 |
31 | public BrandImages(String title, String imageLocalPath, String imageURL) {
32 | this.title = title;
33 | this.imageLocalPath = imageLocalPath;
34 | this.imageURL = imageURL;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/service/interfaces/CommonDataService.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.service.interfaces;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.dto.ProductInfoDTO;
4 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.ProductInfo;
5 | import com.ujjaval.ecommerce.commondataservice.model.FilterAttributesResponse;
6 | import com.ujjaval.ecommerce.commondataservice.model.HomeTabsDataResponse;
7 | import com.ujjaval.ecommerce.commondataservice.model.MainScreenResponse;
8 | import com.ujjaval.ecommerce.commondataservice.model.SearchSuggestionResponse;
9 |
10 | import java.util.HashMap;
11 | import java.util.List;
12 |
13 | public interface CommonDataService {
14 |
15 | MainScreenResponse getHomeScreenData(String apiName);
16 |
17 | FilterAttributesResponse getFilterAttributesByProducts(String queryParams);
18 |
19 | ProductInfoDTO getProductsByCategories(String queryParams);
20 |
21 | HashMap getProductsById(String queryParams);
22 |
23 | HomeTabsDataResponse getBrandsAndApparelsByGender(String apiName);
24 |
25 | SearchSuggestionResponse getSearchSuggestionList();
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/client/src/components/ui/breadcrumbs.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Typography from '@material-ui/core/Typography';
3 | import Breadcrumbs from '@material-ui/core/Breadcrumbs';
4 | import {Link} from "react-router-dom";
5 | import log from 'loglevel';
6 |
7 | export default function BreadcrumbsSection(props) {
8 | const renderLinks = () => {
9 | log.info(`[BreadcrumbsSection] props.linkList = ${props.linkList}`)
10 | // we dont need link for the active page breadcrumb
11 | // eslint-disable-next-line array-callback-return
12 | return props.linkList.splice(0, props.linkList.length-1).map(({name, link}) => {
13 | if(link.length > 0) {
14 | return (
15 |
16 | {name}
17 |
18 | )
19 | }
20 | })
21 | }
22 |
23 | log.info(`[BreadcrumbsSection] Rendering BreadcrumbsSection Component`)
24 |
25 | return (
26 |
27 | {renderLinks()}
28 | {props.linkList[props.linkList.length - 1].name}
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/categories/GenderCategory.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.categories;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.ProductInfo;
5 | import com.ujjaval.ecommerce.commondataservice.entity.sql.images.ApparelImages;
6 | import lombok.Getter;
7 | import lombok.NoArgsConstructor;
8 | import lombok.Setter;
9 | import lombok.ToString;
10 |
11 | import javax.persistence.*;
12 | import java.io.Serializable;
13 | import java.util.List;
14 |
15 | @Getter
16 | @Setter
17 | @NoArgsConstructor
18 | @ToString
19 | @Entity
20 | public class GenderCategory implements Serializable {
21 | @Id
22 | private int id;
23 |
24 | private String type;
25 |
26 | @OneToMany(mappedBy = "genderCategory")
27 | @JsonIgnore
28 | private List productInfos;
29 |
30 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "genderCategory")
31 | @JsonIgnore
32 | private List apparelImages;
33 |
34 | public GenderCategory(int id, String type) {
35 | this.id = id;
36 | this.type = type;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/service/CustomUserDetailsService.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.service;
2 |
3 | import com.ujjaval.ecommerce.authenticationservice.entity.UserInfo;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.security.core.userdetails.User;
6 | import org.springframework.security.core.userdetails.UserDetails;
7 | import org.springframework.security.core.userdetails.UserDetailsService;
8 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
9 | import org.springframework.stereotype.Service;
10 |
11 | import java.util.Arrays;
12 |
13 | @Service
14 | public class CustomUserDetailsService implements UserDetailsService {
15 |
16 | @Autowired
17 | private AuthDataService authDataService;
18 |
19 | @Override
20 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
21 | UserInfo userInfo = authDataService.findByUsername(username);
22 | System.out.println("Username = " + userInfo.getUsername() + ", Password = " + userInfo.getPassword());
23 | return new User(userInfo.getUsername(), userInfo.getPassword(), Arrays.asList());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/model/SearchSuggestionResponse.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.model;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.dto.SearchSuggestionForThreeAttrDTO;
4 | import com.ujjaval.ecommerce.commondataservice.dto.SearchSuggestionForTwoAttrDTO;
5 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.ApparelCategory;
6 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.GenderCategory;
7 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.ProductBrandCategory;
8 | import lombok.*;
9 |
10 | import java.io.Serializable;
11 | import java.util.List;
12 |
13 | @Getter
14 | @Setter
15 | @AllArgsConstructor
16 | @ToString
17 | public class SearchSuggestionResponse implements Serializable {
18 | List genderKeywords;
19 | List brandKeywords;
20 | List apparelKeywords;
21 | List genderApparelKeywords;
22 | List genderBrandKeywords;
23 | List apparelBrandKeywords;
24 | List threeAttrKeywords;
25 | List productKeywords;
26 | }
27 |
--------------------------------------------------------------------------------
/client/src/components/routes/cancelPayment.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import log from 'loglevel'
3 | import {Grid} from "@material-ui/core";
4 | import {Link} from "react-router-dom";
5 | import {CHECKOUT_ROUTE} from "../../constants/react_routes";
6 | import {DocumentTitle} from "../ui/documentTitle";
7 |
8 | export const CancelPayment = () => {
9 |
10 | log.info('[CancelPayment] Rendering SuccessPayment Component')
11 | return (
12 |
14 |
15 |
16 |
17 |
19 | Payment Cancelled. Sorry your payment is declined.
20 |
21 |
22 | Try again later or use different payment method.
23 |
24 |
25 |
26 | Go back to Checkout.
27 |
28 |
29 | )
30 | }
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/java/com/ujjaval/ecommerce/searchsuggestionservice/util/Permutation.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.searchsuggestionservice.util;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | import java.util.LinkedList;
7 | import java.util.List;
8 |
9 | @Getter
10 | @Setter
11 | public class Permutation {
12 | private List output;
13 |
14 | public Permutation(String[] input) {
15 | if(input.length == 0 ) {
16 | return;
17 | }
18 | output = new LinkedList<>();
19 | permute(input, 0, input.length - 1);
20 | }
21 |
22 | public void permute(String[] input, int l, int r)
23 | {
24 | if (l == r) {
25 | output.add(String.join(" ", input));
26 | }
27 | else
28 | {
29 | for (int i = l; i <= r; i++)
30 | {
31 | input = swap(input,l,i);
32 | permute(input, l+1, r);
33 | input = swap(input,l,i);
34 | }
35 | }
36 | }
37 |
38 | private String[] swap(String[] stringArr, int i, int j)
39 | {
40 | String temp = stringArr[i] ;
41 | stringArr[i] = stringArr[j];
42 | stringArr[j] = temp;
43 | return stringArr;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/categories/ApparelCategory.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.categories;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.ProductInfo;
5 | import com.ujjaval.ecommerce.commondataservice.entity.sql.images.ApparelImages;
6 | import lombok.Getter;
7 | import lombok.NoArgsConstructor;
8 | import lombok.Setter;
9 | import lombok.ToString;
10 |
11 | import javax.persistence.*;
12 | import java.io.Serializable;
13 | import java.util.List;
14 |
15 | @Getter
16 | @Setter
17 | @NoArgsConstructor
18 | @ToString
19 | @Entity
20 | public class ApparelCategory implements Serializable {
21 | @Id
22 | @GeneratedValue(strategy= GenerationType.IDENTITY)
23 | private int id;
24 |
25 | private String type;
26 |
27 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "apparelCategory")
28 | @JsonIgnore
29 | private List productInfos;
30 |
31 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "apparelCategory")
32 | @JsonIgnore
33 | private List apparelImages;
34 |
35 | public ApparelCategory(String type) {
36 | this.type = type;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/categories/ProductBrandCategory.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.categories;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.ProductInfo;
5 | import com.ujjaval.ecommerce.commondataservice.entity.sql.images.BrandImages;
6 | import lombok.Getter;
7 | import lombok.NoArgsConstructor;
8 | import lombok.Setter;
9 | import lombok.ToString;
10 |
11 | import javax.persistence.*;
12 | import java.io.Serializable;
13 | import java.util.List;
14 |
15 | @Getter
16 | @Setter
17 | @NoArgsConstructor
18 | @ToString
19 | @Entity
20 | public class ProductBrandCategory implements Serializable {
21 | @Id
22 | @GeneratedValue(strategy= GenerationType.IDENTITY)
23 | private int id;
24 |
25 | private String type;
26 |
27 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "productBrandCategory")
28 | @JsonIgnore
29 | private List productInfos;
30 |
31 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "productBrandCategory")
32 | @JsonIgnore
33 | private List brandImages;
34 |
35 | public ProductBrandCategory(String type) {
36 | this.type = type;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './components/app';
4 | import '../src/styles/index.css'
5 |
6 | import reducers from './reducers';
7 | import {Provider} from "react-redux";
8 | import {createStore, applyMiddleware, compose} from "redux";
9 | import thunk from "redux-thunk";
10 | import 'semantic-ui-css/semantic.min.css'
11 | import '../src/styles/library/swiper/swiper.css';
12 | import '../src/styles/library/swiper/swiper.min.css';
13 | import log from 'loglevel';
14 | import ErrorBoundary from "./ErrorBoundary";
15 |
16 | let composeEnhancers
17 |
18 | // enable logs & redux only in production.
19 | if (process.env.REACT_APP_ENVIRONMENT === "dev") {
20 |
21 | // by default set the level to info
22 | log.setLevel("info")
23 | composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose();
24 | } else {
25 | console.log = console.error = console.warn = function () {}
26 | log.disableAll(true)
27 | composeEnhancers = compose();
28 | }
29 |
30 |
31 | const store = createStore(
32 | reducers,
33 | composeEnhancers(applyMiddleware(thunk))
34 | );
35 |
36 | ReactDOM.render(
37 |
38 |
39 |
40 |
41 | ,
42 | document.getElementById('root')
43 | );
--------------------------------------------------------------------------------
/client/src/components/ui/reduxTextField.js:
--------------------------------------------------------------------------------
1 | import {TextField} from "@material-ui/core";
2 | import InputAdornment from "@material-ui/core/InputAdornment";
3 | import React from "react";
4 |
5 | const textFieldStyles = {
6 | width: "100%",
7 | height: "fit-content",
8 | marginTop: "20px"
9 | }
10 |
11 | export const renderReduxTextField = (
12 | {placeholder, icon, type, shrink, selectField, input, label, meta: {touched, error}, ...custom}) => {
13 |
14 | let errorExist = touched && error && error !== "";
15 | return (
16 |
32 | {icon}
33 |
34 | )
35 | } : null
36 | }
37 | {...input}
38 | {...custom}
39 | />
40 | );
41 | }
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/info/AddressInfo.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.info;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.Setter;
7 | import lombok.ToString;
8 |
9 | import javax.persistence.*;
10 | import java.util.List;
11 |
12 | @Getter
13 | @Setter
14 | @NoArgsConstructor
15 | @ToString
16 | @Entity
17 | public class AddressInfo {
18 |
19 | @Id
20 | @GeneratedValue(strategy = GenerationType.IDENTITY)
21 | private int id;
22 |
23 | private String firstLine;
24 |
25 | private String secondLine;
26 |
27 | private String zipCode;
28 |
29 | private String state;
30 |
31 | private String country;
32 |
33 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "addressInfo")
34 | @JsonIgnore
35 | private List banks;
36 |
37 | @OneToOne(mappedBy = "addressInfo")
38 | private OrderInfo order;
39 |
40 | public AddressInfo(String firstLine, String secondLine, String zipCode, String state, String country) {
41 | this.firstLine = firstLine;
42 | this.secondLine = secondLine;
43 | this.zipCode = zipCode;
44 | this.state = state;
45 | this.country = country;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/java/com/ujjaval/ecommerce/selleraccountservice/controller/SellerAccountController.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.selleraccountservice.controller;
2 |
3 | import com.ujjaval.ecommerce.selleraccountservice.entity.nosql.SellerBulkInfo;
4 | import com.ujjaval.ecommerce.selleraccountservice.entity.sql.SellerInfo;
5 | import com.ujjaval.ecommerce.selleraccountservice.service.SellerAccountDataService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.PathVariable;
9 | import org.springframework.web.bind.annotation.RestController;
10 |
11 | @RestController
12 | public class SellerAccountController {
13 |
14 | @Autowired
15 | private SellerAccountDataService sellerAccountDataService;
16 |
17 | @GetMapping("/save")
18 | public void saveAddress() {
19 | sellerAccountDataService.save();
20 | }
21 |
22 | @GetMapping("/seller/{id}")
23 | public SellerInfo getAddress(@PathVariable int id) {
24 | return sellerAccountDataService.findSellerById(id);
25 | }
26 |
27 | @GetMapping("/seller-bulk/{id}")
28 | public SellerBulkInfo getAddress() {
29 | sellerAccountDataService.saveInMongo();
30 | return sellerAccountDataService.findMongoAddressById();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/model/FilterAttributesResponse.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.model;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.dto.FilterAttributesWithTotalItemsDTO;
4 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.SortByCategory;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 | import lombok.Setter;
8 | import lombok.ToString;
9 |
10 | import java.io.Serializable;
11 | import java.util.List;
12 |
13 | @Getter
14 | @Setter
15 | @NoArgsConstructor
16 | @ToString
17 | public class FilterAttributesResponse implements Serializable {
18 |
19 | private List brands;
20 | private List genders;
21 | private List apparels;
22 | private List sortby;
23 | private List prices;
24 |
25 | public FilterAttributesResponse(List brands, List genders,
26 | List apparels, List prices) {
27 | this.brands = brands;
28 | this.genders = genders;
29 | this.apparels = apparels;
30 | this.prices = prices;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/info/OrderInfo.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.info;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import javax.persistence.*;
9 | import java.io.Serializable;
10 |
11 | @Getter
12 | @Setter
13 | @NoArgsConstructor
14 | @ToString
15 | @Entity
16 | public class OrderInfo implements Serializable {
17 |
18 | @Id
19 | @GeneratedValue(strategy= GenerationType.IDENTITY)
20 | private int id;
21 |
22 | private int customerId;
23 |
24 | private String timestamp;
25 |
26 | private String deliveryStatus;
27 |
28 | private String trackPackageLink;
29 |
30 | @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
31 | @JoinColumn(name = "address_id", referencedColumnName = "id")
32 | private AddressInfo addressInfo;
33 |
34 | @ManyToOne(fetch = FetchType.LAZY)
35 | @JoinColumn(name = "product_id")
36 | private OrderInfo orderInfo;
37 |
38 | public OrderInfo(int customerId, String timestamp, String deliveryStatus, String trackPackageLink, OrderInfo orderInfo) {
39 | this.customerId = customerId;
40 | this.timestamp = timestamp;
41 | this.deliveryStatus = deliveryStatus;
42 | this.trackPackageLink = trackPackageLink;
43 | this.orderInfo = orderInfo;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/client/src/constants/stateCodes.js:
--------------------------------------------------------------------------------
1 | export const stateCodes = {
2 | "AL": "Alabama",
3 | "AK": "Alaska",
4 | "AZ": "Arizona",
5 | "AR": "Arkansas",
6 | "CA": "California",
7 | "CO": "Colorado",
8 | "CT": "Connecticut",
9 | "DE": "Delaware",
10 | "DC": "District of Columbia",
11 | "FL": "Florida",
12 | "GA": "Georgia",
13 | "HI": "Hawaii",
14 | "ID": "Idaho",
15 | "IL": "Illinois",
16 | "IN": "Indiana",
17 | "IA": "Iowa",
18 | "KS": "Kansas",
19 | "KY": "Kentucky",
20 | "LA": "Louisiana",
21 | "ME": "Maine",
22 | "MD": "Maryland",
23 | "MA": "Massachusetts",
24 | "MI": "Michigan",
25 | "MN": "Minnesota",
26 | "MS": "Mississippi",
27 | "MO": "Missouri",
28 | "MT": "Montana",
29 | "NE": "Nebraska",
30 | "NV": "Nevada",
31 | "NH": "New Hampshire",
32 | "NJ": "New Jersey",
33 | "NM": "New Mexico",
34 | "NY": "New York",
35 | "NC": "North Carolina",
36 | "ND": "North Dakota",
37 | "OH": "Ohio",
38 | "OK": "Oklahoma",
39 | "OR": "Oregon",
40 | "PA": "Pennsylvania",
41 | "PR": "Puerto Rico",
42 | "RI": "Rhode Island",
43 | "SC": "South Carolina",
44 | "SD": "South Dakota",
45 | "TN": "Tennessee",
46 | "TX": "Texas",
47 | "UT": "Utah",
48 | "VT": "Vermont",
49 | "VA": "Virginia",
50 | "WA": "Washington",
51 | "WV": "West Virginia",
52 | "WI": "Wisconsin",
53 | "WY": "Wyoming"
54 | }
--------------------------------------------------------------------------------
/client/src/components/routes/home/homeMenuIcons.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Grid from '@material-ui/core/Grid';
3 | import {Link} from "react-router-dom";
4 | import log from 'loglevel';
5 | import {MAX_PRODUCTS_PER_PAGE} from "../../../constants/constants";
6 | import {useSelector} from "react-redux";
7 |
8 | const HomeMenuIcons = () => {
9 | const homeAPIData = useSelector(state => state.homePageDataReducer)
10 |
11 | const renderImageList = (imageList) => {
12 |
13 | // filter out images which are related to home icons.
14 | imageList = imageList.filter(image => image.imageLocalPath.search("icon") !== -1)
15 |
16 | // map the image path and link
17 | return imageList.map(info => {
18 | return (
19 |
20 |
21 |
23 |
24 |
25 | )
26 | });
27 | };
28 |
29 | log.info("[HomeMenuIcons]: Rendering HomeMenuIcons Component")
30 |
31 | return (
32 |
33 | {renderImageList(homeAPIData.data.carousels)}
34 |
35 | )
36 | };
37 | export default HomeMenuIcons;
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/info/BankInfo.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.info;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | import javax.persistence.*;
9 |
10 | @Getter
11 | @Setter
12 | @NoArgsConstructor
13 | @ToString
14 | @Entity
15 | public class BankInfo {
16 |
17 | @Id
18 | @GeneratedValue(strategy = GenerationType.IDENTITY)
19 | private int id;
20 |
21 | private int customerId;
22 |
23 | private int sellerId;
24 |
25 | private String firstName;
26 |
27 | private String lastName;
28 |
29 | private String bankName;
30 |
31 | private String routingNumber;
32 |
33 | private String accountNumber;
34 |
35 | @ManyToOne
36 | @JoinColumn(name = "address_id")
37 | private AddressInfo addressInfo;
38 |
39 | @ManyToOne
40 | @JoinColumn(name = "contact_id")
41 | private ContactInfo contactInfo;
42 |
43 | public BankInfo(int customerId, int sellerId, String firstName, String lastName, String bankName, String routingNumber, String accountNumber) {
44 | this.customerId = customerId;
45 | this.sellerId = sellerId;
46 | this.firstName = firstName;
47 | this.lastName = lastName;
48 | this.bankName = bankName;
49 | this.routingNumber = routingNumber;
50 | this.accountNumber = accountNumber;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/server/seller-account-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=seller-account-service
2 | server.port=7500
3 | spring.datasource.url=jdbc:mysql://localhost:3306/ecommerce_data?useSSL=false&serverTimezone=UTC
4 | spring.datasource.username=springstudent
5 | spring.datasource.password=springstudent
6 | #spring.datasource.url=jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:6603}/${DB_SCHEMA}?autoReconnect=true&failOverReadOnly=false&maxReconnects=2
7 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
8 | #spring.data.mongodb.uri=mongodb://0.0.0.0:27017/ecommerce_data
9 | #spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345,mongo2.example.com:23456/test
10 | spring.data.mongodb.host=0.0.0.0
11 | spring.data.mongodb.port=27017
12 | spring.data.mongodb.database=ecommerce_data
13 | spring.data.mongodb.username=springstudent
14 | spring.data.mongodb.password=springstudent
15 | #spring.datasource.initialization-mode=always
16 | #spring.jpa.hibernate.ddl-auto=create-drop
17 | spring.jpa.generate-ddl=true
18 | spring.profiles.active=dev
19 |
20 | # debugging purpose
21 | spring.jpa.properties.hibernate.format_sql=true
22 | logging.level.org.hibernate.SQL=DEBUG
23 | logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
24 | logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG
25 | logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE
26 | logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/entity/sql/images/ApparelImages.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.entity.sql.images;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.ApparelCategory;
5 | import com.ujjaval.ecommerce.commondataservice.entity.sql.categories.GenderCategory;
6 | import lombok.Getter;
7 | import lombok.NoArgsConstructor;
8 | import lombok.Setter;
9 | import lombok.ToString;
10 |
11 | import javax.persistence.*;
12 |
13 | @Getter
14 | @Setter
15 | @NoArgsConstructor
16 | @ToString
17 | @Entity
18 | public class ApparelImages {
19 | @Id
20 | @GeneratedValue(strategy= GenerationType.IDENTITY)
21 | private int id;
22 |
23 | private String title;
24 |
25 | private String imageLocalPath;
26 |
27 | private String imageURL;
28 |
29 | @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
30 | @JoinColumn(name = "apparel_id", referencedColumnName = "id")
31 | @JsonIgnore
32 | private ApparelCategory apparelCategory;
33 |
34 | @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
35 | @JoinColumn(name = "gender_id")
36 | @JsonIgnore
37 | private GenderCategory genderCategory;
38 |
39 | public ApparelImages(String title, String imageLocalPath, String imageURL) {
40 | this.title = title;
41 | this.imageLocalPath = imageLocalPath;
42 | this.imageURL = imageURL;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/client/src/components/routes/product/filterSideNavbar/checkboxSearchBar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import log from 'loglevel';
3 | import {NavBarHeader} from "../../../ui/headers";
4 | import {Grid} from "@material-ui/core";
5 | import CollapsableSearch from "../../../ui/collapsableSearch";
6 |
7 | export default function CheckboxSearchBar(props) {
8 |
9 | if (!props.checkboxList) {
10 | log.debug(`[CheckboxSearchBar] apparelList is null`)
11 | return null
12 | }
13 |
14 | const handleSearchBarChange = value => {
15 | log.info(`[CheckboxSearchBar] handleSearchClick value = ${value}`)
16 | let filterApparelList = props.checkboxList.filter(info => info.value.toUpperCase().startsWith(value.toUpperCase()))
17 | props.searchListHandler(filterApparelList)
18 | }
19 |
20 | const handleSearchBarCancel = () => {
21 | props.searchListHandler(null)
22 | }
23 |
24 | log.info(`[CheckboxSearchBar] Rendering CheckboxSearchBar Component`)
25 |
26 | return (
27 |
28 |
29 |
30 |
31 |
36 |
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/client/src/constants/constants.js:
--------------------------------------------------------------------------------
1 |
2 | export const MAX_PRODUCTS_PER_PAGE = 16;
3 |
4 | export const TAB_CONFIG = [
5 | {index: 0, label: 'MEN', color: '#ee5f73', mapKey: "men"},
6 | {index: 1, label: 'WOMEN', color: '#fb56c1', mapKey: "women"},
7 | {index: 2, label: 'KIDS', color: '#f26a10', mapKey: "boys"},
8 | {index: 3, label: 'ESSENTIALS', color: '#0db7af', mapKey: "essentials"},
9 | {index: 4, label: 'HOME & LIVING', color: '#f2c210', mapKey: "homeAndLiving"},
10 | ];
11 |
12 | export const INITIAL_PAGINATION_STATE = {
13 | pageNumber: 1,
14 | maxProducts: MAX_PRODUCTS_PER_PAGE,
15 | isLoadedFromURL: true
16 | }
17 |
18 | export const INITIAL_SORT_STATE = {
19 | id: 1,
20 | value: null,
21 | isLoadedFromURL: true
22 | }
23 |
24 | export const INITIAL_SELECTED_FILTER_ATTRIBUTE_STATE = {
25 | genders: [],
26 | apparels: [],
27 | brands: [],
28 | prices: [],
29 | oldQuery: null,
30 | newQuery: null
31 | }
32 |
33 | export const INITIAL_SHIPPING_OPTION_STATE = {
34 | price: "Free",
35 | submitted: false
36 | }
37 |
38 | export const INITIAL_SHIPPING_ADDRESS_STATE = {
39 | values: null,
40 | submitted: false
41 | }
42 |
43 | export const FILTER_ATTRIBUTES = ["genders", "apparels", "brands", "prices"]
44 | export const SORT_ATTRIBUTE = "sortby"
45 | export const PAGE_ATTRIBUTE = "page"
46 |
47 | export const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
48 | 'August', 'September', 'October', 'November', 'December'];
49 |
50 | export const HOME_PAGE_API_OBJECT_LEN = 3;
51 | export const TABS_API_OBJECT_LEN = 6;
52 |
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/java/com/ujjaval/ecommerce/searchsuggestionservice/controller/SearchSuggestionController.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.searchsuggestionservice.controller;
2 |
3 | import com.ujjaval.ecommerce.searchsuggestionservice.dto.SearchSuggestionKeywordInfo;
4 | import com.ujjaval.ecommerce.searchsuggestionservice.service.SearchSuggestionService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.core.env.Environment;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.RequestParam;
10 | import org.springframework.web.bind.annotation.RestController;
11 |
12 | import java.util.*;
13 |
14 | @RestController
15 | public class SearchSuggestionController {
16 |
17 | @Autowired
18 | SearchSuggestionService searchSuggestionService;
19 |
20 | @Autowired
21 | Environment environment;
22 |
23 | public void loadSearchSuggestions() {
24 | searchSuggestionService.loadSearchSuggestionToMap();
25 | }
26 |
27 | @GetMapping("/search-suggestion")
28 | public ResponseEntity> searchKeyword(@RequestParam String q) {
29 | return ResponseEntity.ok(searchSuggestionService.searchKeywordFromMap(q));
30 | }
31 |
32 | @GetMapping("/default-search-suggestion")
33 | public ResponseEntity> defaultSearchSuggestions() {
34 | List resultList
35 | = searchSuggestionService.getDefaultSearchSuggestions();
36 | return ResponseEntity.ok(resultList);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/client/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import {combineReducers} from "redux";
2 | import {reducer as formReducer} from "redux-form";
3 |
4 | import {
5 | homePageDataReducer, addToCartReducer,
6 | selectProductDetailReducer, shoppingBagProductReducer,
7 | filterProductsReducer, filterAttributesReducer,
8 | filterQueryReducer, tabsDataReducer,
9 | cartTotalReducer, savedSortedListReducer,
10 | shippingAddressReducer, paymentInfoReducer,
11 | shippingOptionReducer, deliveryChargesReducer,
12 | paymentResponseReducer, signInReducer, signUpReducer,
13 | googleAuthReducer, searchKeywordReducer
14 | } from "./screens/commonScreenReducer";
15 |
16 | import {tabHoverEventReducer} from "./events/eventReducer";
17 |
18 | import {
19 | selectedFilterAttributesReducer,
20 | selectSortReducer, selectPageReducer, clearFiltersReducer
21 | } from "./screens/filter/selectedFilterAttributesReducer"
22 |
23 | export default combineReducers({
24 | form: formReducer,
25 | signInReducer,
26 | signUpReducer,
27 | homePageDataReducer,
28 | addToCartReducer,
29 | tabHoverEventReducer,
30 | filterProductsReducer,
31 | filterAttributesReducer,
32 | selectSortReducer,
33 | selectPageReducer,
34 | selectProductDetailReducer,
35 | shoppingBagProductReducer,
36 | filterQueryReducer,
37 | selectedFilterAttributesReducer,
38 | tabsDataReducer,
39 | cartTotalReducer,
40 | savedSortedListReducer,
41 | shippingAddressReducer,
42 | paymentInfoReducer,
43 | shippingOptionReducer,
44 | deliveryChargesReducer,
45 | paymentResponseReducer,
46 | googleAuthReducer,
47 | searchKeywordReducer,
48 | clearFiltersReducer
49 | });
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/dao/sql/info/ProductInfoRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.dao.sql.info;
2 |
3 | import com.ujjaval.ecommerce.commondataservice.dto.SearchSuggestionForThreeAttrDTO;
4 | import com.ujjaval.ecommerce.commondataservice.dto.SearchSuggestionForTwoAttrDTO;
5 | import com.ujjaval.ecommerce.commondataservice.entity.sql.info.ProductInfo;
6 | import com.ujjaval.ecommerce.commondataservice.model.FilterAttributesResponse;
7 | import com.ujjaval.ecommerce.commondataservice.model.HomeTabsDataResponse;
8 | import org.javatuples.Pair;
9 | import org.springframework.data.jpa.repository.JpaRepository;
10 | import org.springframework.data.jpa.repository.Query;
11 |
12 | import java.util.HashMap;
13 | import java.util.List;
14 |
15 | public interface ProductInfoRepository extends JpaRepository {
16 |
17 | Pair> getProductsByCategories(HashMap conditionMap);
18 |
19 | List getProductsById(String[] productIds);
20 |
21 | FilterAttributesResponse getFilterAttributesByProducts(HashMap conditionMap);
22 |
23 | HomeTabsDataResponse getBrandsAndApparelsByGender();
24 |
25 | List getGenderApparelBrandByIdAndName();
26 |
27 | List getGenderAndApparelByIdAndName();
28 |
29 | List getGenderAndBrandByIdAndName();
30 |
31 | List getApparelAndBrandByIdAndName();
32 |
33 | @Query(value = "SELECT DISTINCT p.name FROM ProductInfo p")
34 | List getProductByName();
35 | }
36 |
--------------------------------------------------------------------------------
/client/src/components/routes/product/filterSideNavbar/clearAllButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import log from 'loglevel';
3 | import {useDispatch, useSelector} from "react-redux";
4 | import {CLEAR_ALL_FILTERS, RESET_SELECTED_CATEGORY} from "../../../../actions/types";
5 | import history from "../../../../history";
6 |
7 | function ClearAllButton() {
8 | const dispatch = useDispatch()
9 | const selectedFilterAttribute = useSelector(state => state.selectedFilterAttributesReducer)
10 |
11 | // check if any filter is selected or not
12 | if ((selectedFilterAttribute.genders.length + selectedFilterAttribute.apparels.length
13 | + selectedFilterAttribute.brands.length + selectedFilterAttribute.prices.length) === 0) {
14 | log.info(`[ClearAllButton] selected attribute are null`)
15 | return null
16 | }
17 |
18 | /**
19 | * remove all selected filters
20 | */
21 | const handleClearAllClick = () => {
22 | log.info(`[ClearAllButton] handleClearAllClick(value)`)
23 | dispatch({
24 | type: RESET_SELECTED_CATEGORY
25 | })
26 | dispatch({
27 | type: CLEAR_ALL_FILTERS,
28 | payload: true
29 | })
30 | history.push(history.location.pathname + "?q=page=0,16")
31 | }
32 |
33 | log.info(`[ClearAllButton] Rendering ClearAllButton Component`)
34 |
35 | return (
36 | <>
37 | CLEAR ALL
41 |
42 | >
43 | );
44 | }
45 |
46 | export default ClearAllButton;
--------------------------------------------------------------------------------
/client/src/components/ui/modal.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {makeStyles} from '@material-ui/core/styles';
3 | import Modal from '@material-ui/core/Modal';
4 | import {Fade} from '@material-ui/core';
5 | import Backdrop from '@material-ui/core/Backdrop';
6 |
7 | const useStyles = makeStyles((theme) => ({
8 | modal: {
9 | display: 'flex',
10 | alignItems: 'center',
11 | justifyContent: 'center',
12 | },
13 | paper: {
14 | backgroundColor: theme.palette.background.paper,
15 | boxShadow: theme.shadows[6],
16 | height: "fit-content",
17 | borderRadius: 4
18 | },
19 | }));
20 |
21 | export default function ModalSection(props) {
22 | const classes = useStyles();
23 | const [open, setOpen] = React.useState(true);
24 |
25 | const handleClose = () => {
26 | props.closeHandler();
27 | setOpen(false);
28 | };
29 |
30 | return (
31 |
32 |
45 |
46 |
47 | {props.renderWarningComponent}
48 |
49 |
50 |
51 |
52 | );
53 | }
54 |
--------------------------------------------------------------------------------
/server/payment-service/src/main/java/com/ujjaval/ecommerce/paymentservice/config/CORSFilter.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.paymentservice.config;
2 |
3 | import java.io.IOException;
4 | import javax.servlet.Filter;
5 | import javax.servlet.FilterChain;
6 | import javax.servlet.FilterConfig;
7 | import javax.servlet.ServletException;
8 | import javax.servlet.ServletRequest;
9 | import javax.servlet.ServletResponse;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 | import org.springframework.stereotype.Component;
15 |
16 | @Component
17 | public class CORSFilter implements Filter {
18 |
19 | private final Logger log = LoggerFactory.getLogger(CORSFilter.class);
20 |
21 | public CORSFilter() {
22 | log.info("CORSFilter init");
23 | }
24 |
25 | @Override
26 | public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
27 |
28 | HttpServletRequest request = (HttpServletRequest) req;
29 | HttpServletResponse response = (HttpServletResponse) res;
30 |
31 | response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
32 | response.setHeader("Access-Control-Allow-Credentials", "true");
33 | response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
34 | response.setHeader("Access-Control-Max-Age", "3600");
35 | response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
36 |
37 | chain.doFilter(req, res);
38 | }
39 |
40 | @Override
41 | public void init(FilterConfig filterConfig) {
42 | }
43 |
44 | @Override
45 | public void destroy() {
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/client/src/components/routes/product/filterDropdown.js:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from 'react';
2 | import log from 'loglevel';
3 | import {useSelector} from "react-redux";
4 | import DropdownSection from "../../ui/dropDown";
5 | import {SORT_ATTRIBUTE} from "../../../constants/constants";
6 | import history from "../../../history";
7 |
8 | export default function FilterDropdown() {
9 | const sortList = useSelector(state => state.filterAttributesReducer.data ?
10 | state.filterAttributesReducer.data[SORT_ATTRIBUTE] : null)
11 | const selectedSort = useSelector(state => state.selectSortReducer)
12 | const [sortValue, setSortValue] = useState({id:1, value: ""})
13 |
14 | useEffect(() => {
15 | if (selectedSort != null) {
16 | setSortValue(selectedSort)
17 | }
18 | }, [selectedSort])
19 |
20 | if (!sortList) {
21 | return null
22 | }
23 |
24 | const onChangeHandler = (id, value) => {
25 | log.info(`[FilterDropdown] onChangeHandler id = ${id}, value = ${value}`)
26 | setSortValue({id, value})
27 | let route = history.location.pathname
28 | let queryStr = history.location.search
29 | if (history.location.search.search("sortby") === -1) {
30 | history.push(`${route}${queryStr}::sortby=${id}`)
31 | } else {
32 | history.push(`${route}${queryStr.replace(new RegExp(`sortby=[0-9]`), `sortby=${id}`)}`)
33 | }
34 | }
35 |
36 | log.info(`[FilterDropdown] Rendering FilterDropdown Component`)
37 |
38 | return (
39 |
46 | );
47 | }
48 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/config/DevRedisConfig.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.config;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.context.annotation.Profile;
7 | import org.springframework.core.env.Environment;
8 | import org.springframework.data.redis.connection.RedisPassword;
9 | import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
10 | import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
11 | import org.springframework.data.redis.core.RedisTemplate;
12 |
13 | import java.util.Objects;
14 |
15 | @Configuration
16 | @Profile("dev")
17 | public class DevRedisConfig {
18 |
19 | @Autowired
20 | Environment environment;
21 |
22 | @Bean
23 | JedisConnectionFactory jedisConnectionFactory() {
24 | System.out.println("Loading Dev profile redis config....");
25 | RedisStandaloneConfiguration redisStandaloneConfiguration =
26 | new RedisStandaloneConfiguration(Objects.requireNonNull(environment.getProperty("REDIS_HOST")),
27 | Integer.parseInt(Objects.requireNonNull(environment.getProperty("REDIS_PORT"))));
28 |
29 | redisStandaloneConfiguration.
30 | setPassword(RedisPassword.of(Objects.requireNonNull(environment.getProperty("REDIS_PASSWORD"))));
31 | return new JedisConnectionFactory(redisStandaloneConfiguration);
32 | }
33 |
34 | @Bean
35 | public RedisTemplate redisTemplate() {
36 | RedisTemplate template = new RedisTemplate<>();
37 | template.setConnectionFactory(jedisConnectionFactory());
38 | return template;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/client/src/components/routes/home/verticalSlider.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Swiper from 'react-id-swiper';
3 | import log from 'loglevel';
4 | import {useSelector} from "react-redux";
5 | import {BadRequest} from "../../ui/error/badRequest";
6 |
7 | const VerticalSlider = () => {
8 | const homeAPIData = useSelector(state => state.homePageDataReducer)
9 |
10 | const params = {
11 | spaceBetween: 30,
12 | centeredSlides: true,
13 | autoplay: {
14 | delay: 4000,
15 | disableOnInteraction: false
16 | },
17 | pagination: {
18 | el: '.swiper-pagination',
19 | clickable: true
20 | },
21 | navigation: {
22 | nextEl: '.swiper-button-next',
23 | prevEl: '.swiper-button-prev'
24 | }
25 | }
26 |
27 | const renderImageList = (imageList) => {
28 |
29 | if(!imageList) {
30 | log.info(`[VerticalSlider]: imageList is null`)
31 | return
32 | }
33 |
34 | // filter out images which are not for carousels.
35 | imageList = imageList.filter(image => image.imageLocalPath.search("icon") === -1)
36 |
37 | log.trace("[VerticalSlider]: Rendering renderImageList imageList = " + JSON.stringify(imageList))
38 | return imageList.map(({id, imageLocalPath, imageURL}) => {
39 | log.trace(`[VerticalSlider]: Rendering renderImageList imageList filePath = ${imageLocalPath}`)
40 | return (
41 |
42 | )
43 | });
44 | };
45 |
46 | log.info("[VerticalSlider]: Rendering VerticalSlider Component")
47 | return (
48 |
49 | {renderImageList(homeAPIData.data.carousels)}
50 |
51 | )
52 | };
53 | export default VerticalSlider;
--------------------------------------------------------------------------------
/client/src/components/routes/checkout/summaryCard.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Grid, Card, CardContent} from "@material-ui/core";
3 | import DeleteIcon from '@material-ui/icons/Delete';
4 | import Button from '@material-ui/core/Button';
5 | import IconButton from '@material-ui/core/IconButton';
6 |
7 | export const SummaryCard = (props) => {
8 |
9 | const renderCardContent = () => {
10 | let id = 0
11 | return props.contentList.map((formValue) => {
12 | ++id
13 | return (
14 |
15 | {formValue}
16 |
17 | )
18 | })
19 | }
20 |
21 | return (
22 |
23 |
24 |
25 | {renderCardContent()}
26 |
27 |
28 |
29 |
30 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | )
48 | }
--------------------------------------------------------------------------------
/client/src/hooks/useAddProductsToShoppingBag.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import log from "loglevel";
3 | import {LOAD_SHOPPING_BAG_PRODUCTS} from "../actions/types";
4 | import {useDispatch, useSelector} from "react-redux";
5 | import _ from "lodash";
6 | import {PRODUCT_BY_ID_DATA_API} from "../constants/api_routes";
7 |
8 | /**
9 | * Hook that alerts clicks outside of the passed ref
10 | */
11 | export function useAddProductsToShoppingBag(getDataViaAPIFunc) {
12 | const addToCart = useSelector(state => state.addToCartReducer)
13 | const dispatch = useDispatch()
14 |
15 | const extractIdsFromObject = object => {
16 | log.info("[useAddProductsToShoppingBag] extractIdsFromObject object = " + JSON.stringify(object))
17 | let idList = []
18 | for (const [id] of Object.entries(object)) {
19 | idList.push(parseInt(id))
20 | }
21 | return idList
22 | }
23 |
24 | useEffect(() => {
25 | log.info("[useAddProductsToShoppingBag] Component will mount... addToCart = " + JSON.stringify(addToCart))
26 |
27 | let idList = []
28 |
29 | if (!_.isEmpty(addToCart.productQty)) {
30 | log.info(`[ShoppingBag] load ShoppingBag products` +
31 | ` from addToCartQuantity = ${JSON.stringify(addToCart)}`)
32 |
33 | idList = extractIdsFromObject(addToCart["productQty"])
34 |
35 | if (idList.length > 0) {
36 | getDataViaAPIFunc(LOAD_SHOPPING_BAG_PRODUCTS, PRODUCT_BY_ID_DATA_API + idList.toString(), null, false)
37 | return
38 | }
39 |
40 | }
41 |
42 | dispatch({
43 | type: LOAD_SHOPPING_BAG_PRODUCTS,
44 | payload: {isLoading: false, data: {}}
45 | })
46 |
47 | log.info(`[ShoppingBag] load ShoppingBag products idList = ${JSON.stringify(idList)}`)
48 |
49 | // eslint-disable-next-line
50 | }, [addToCart])
51 | }
--------------------------------------------------------------------------------
/client/src/components/routes/signup/signUp.js:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from "react";
2 | import SignUpForm from "./signUpForm"
3 | import {Grid} from "@material-ui/core";
4 | import log from "loglevel";
5 | import {useDispatch, useSelector} from "react-redux";
6 | import {Dimmer, Loader} from "semantic-ui-react";
7 | import {DocumentTitle} from "../../ui/documentTitle";
8 | import {RESET_SIGN_UP} from "../../../actions/types";
9 |
10 | const SignUp = () => {
11 | const [isLoading, setIsLoading] = useState(false);
12 | const {timestamp} = useSelector(state => state.signUpReducer)
13 | const dispatch = useDispatch()
14 |
15 | const setIsLoadingState = () => {
16 | setIsLoading(true);
17 | }
18 |
19 | useEffect(() => {
20 | log.info(`[SignUp]: Component did mount...`)
21 | setIsLoading(false)
22 |
23 | // eslint-disable-next-line
24 | }, [timestamp])
25 |
26 | useEffect(() => {
27 |
28 | return () => {
29 | log.info(`[SignIn] Component will unmount...`)
30 | dispatch({
31 | type: RESET_SIGN_UP
32 | })
33 | }
34 |
35 | // eslint-disable-next-line
36 | }, [])
37 |
38 | log.info(`[SignUp]: Rendering SignUp Component`)
39 |
40 | return (
41 |
42 |
43 |
44 |
45 | Sign Up
46 |
47 |
48 |
49 |
50 | {isLoading ?
51 | Loading
52 | : null}
53 |
54 | )
55 | }
56 |
57 | export default SignUp;
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/dao/UserInfoRepository.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.dao;
2 |
3 | import com.ujjaval.ecommerce.authenticationservice.entity.UserInfo;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Modifying;
6 | import org.springframework.data.jpa.repository.Query;
7 | import org.springframework.data.repository.query.Param;
8 | import org.springframework.transaction.annotation.Transactional;
9 |
10 | import java.util.Optional;
11 |
12 | public interface UserInfoRepository extends JpaRepository {
13 | @Query(value = "SELECT user_id, username, first_name, last_name, email, password " +
14 | "FROM user_info where username = :USERNAME ",
15 | nativeQuery = true)
16 | Optional findByUsername(@Param("USERNAME") String USERNAME);
17 |
18 | @Query(value = "SELECT user_id, username, first_name, last_name, email, password " +
19 | "FROM user_info where email = :EMAIL ",
20 | nativeQuery = true)
21 | Optional findByEmail(@Param("EMAIL") String EMAIL);
22 |
23 | @Query(value = "DELETE FROM user_info where username = :USERNAME and password = :PASSWORD",
24 | nativeQuery = true)
25 | void deleteByUsernamePassword(@Param("USERNAME") String USERNAME, @Param("PASSWORD") String PASSWORD);
26 |
27 | @Modifying
28 | @Transactional
29 | @Query(value = "INSERT INTO user_info (username, first_name, last_name, email, password) " +
30 | " VALUES (:USERNAME, :FIRSTNAME, :LASTNAME, :EMAIL, :PASSWORD)", nativeQuery = true)
31 | void createUserProfile(@Param("USERNAME") String USERNAME, @Param("FIRSTNAME") String FIRSTNAME,
32 | @Param("LASTNAME") String LASTNAME, @Param("EMAIL") String EMAIL,
33 | @Param("PASSWORD") String PASSWORD);
34 |
35 | }
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
18 |
19 |
20 |
29 | Welcome to Shoppers
30 |
31 |
32 |
33 |
34 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/service/AuthDataServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.service;
2 |
3 | import com.ujjaval.ecommerce.authenticationservice.dao.UserInfoRepository;
4 | import com.ujjaval.ecommerce.authenticationservice.entity.UserInfo;
5 | import com.ujjaval.ecommerce.authenticationservice.util.Md5Util;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.security.NoSuchAlgorithmException;
10 | import java.util.Optional;
11 |
12 | @Service
13 | public class AuthDataServiceImpl implements AuthDataService {
14 |
15 | @Autowired
16 | private UserInfoRepository UserInfoRepository;
17 |
18 | public UserInfo findByUsername(String username) {
19 | Optional result = UserInfoRepository.findByUsername(username);
20 |
21 | UserInfo userInfo = null;
22 |
23 | if(result.isPresent()) {
24 | userInfo = result.get();
25 | }
26 |
27 | return userInfo;
28 | }
29 |
30 | public UserInfo findByEmail(String email) {
31 | Optional result = UserInfoRepository.findByEmail(email);
32 |
33 | UserInfo userInfo = null;
34 |
35 | if(result.isPresent()) {
36 | userInfo = result.get();
37 | }
38 |
39 | return userInfo;
40 | }
41 |
42 | public void createUserProfile(UserInfo userInfo) throws NoSuchAlgorithmException {
43 | UserInfoRepository.createUserProfile(userInfo.getUsername(),
44 | userInfo.getFirstName(), userInfo.getLastName(),
45 | userInfo.getEmail(), Md5Util.getInstance().getMd5Hash(userInfo.getPassword()));
46 | }
47 |
48 | public void deleteByUsernamePassword(String username, String password) throws NoSuchAlgorithmException {
49 | UserInfoRepository.deleteByUsernamePassword(username, Md5Util.getInstance().getMd5Hash(password));
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/client/src/components/routes/navbar/sideBar.js:
--------------------------------------------------------------------------------
1 | import React, {useRef} from "react";
2 | import {makeStyles} from "@material-ui/core/styles";
3 | import AccordionSection from "./accordionSection";
4 | import Drawer from "@material-ui/core/Drawer";
5 | import log from 'loglevel';
6 | import {useClickAway} from "../../../hooks/useClickAway";
7 |
8 | export const useSideBarStyles = makeStyles((theme) => ({
9 | root: {
10 | display: 'flex',
11 | },
12 | drawer: {
13 | [theme.breakpoints.up('sm')]: {
14 | width: 280,
15 | flexShrink: 0,
16 | },
17 | },
18 | menuButton: {
19 | marginRight: theme.spacing(2),
20 | [theme.breakpoints.up('sm')]: {
21 | display: 'none',
22 | },
23 | },
24 | // necessary for content to be below app bar
25 | toolbar: theme.mixins.toolbar,
26 | drawerPaper: {
27 | position: "fixed",
28 | overflow: 'auto',
29 | backgroundColor: "#fff",
30 | [theme.breakpoints.up('xs')]: {
31 | width: 280,
32 | },
33 | [theme.breakpoints.up('sm')]: {
34 | width: 400,
35 | },
36 | },
37 | }));
38 |
39 | const SideBar = (props) => {
40 | const classes = useSideBarStyles();
41 | const wrapperRef = useRef(null);
42 |
43 | useClickAway(wrapperRef, props.closeHandler);
44 |
45 | log.info(`[SideBar] Rendering SideBar`)
46 | return (
47 |
48 |
60 |
61 | );
62 | }
63 |
64 | export default SideBar;
--------------------------------------------------------------------------------
/server/payment-service/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 | %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 | ${LOGS}/payment-service-logger.log
23 |
25 | %d %p %C{1.} [%t] %m%n
26 |
27 |
28 |
30 |
31 | ${LOGS}/archived/payment-service-logger-%d{yyyy-MM-dd}.%i.log
32 |
33 |
35 | 10MB
36 |
37 | 3
38 | 100MB
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/client/src/components/ui/modalConfirmation.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import log from 'loglevel';
3 | import {Grid, Divider} from "@material-ui/core";
4 | import Modal from "./modal";
5 |
6 | export const ModalConfirmation = (props) => {
7 |
8 | log.info("[ModalConfirmation] Rendering ModalConfirmation Component...")
9 | const renderAddressRemovalConfirmation = () => {
10 | return (
11 |
12 |
13 |
15 | {props.title}
16 |
17 |
18 | {props.question}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 | REMOVE
29 |
30 |
31 |
33 | CANCEL
34 |
35 |
36 |
37 | )
38 | }
39 |
40 | return (
41 |
44 | )
45 | }
46 |
--------------------------------------------------------------------------------
/client/src/components/routes/checkout/continueButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import log from 'loglevel';
3 | import {Button, Grid, Hidden} from "@material-ui/core";
4 |
5 | const continueButtonStyle = {
6 | backgroundColor: "#e01a2b",
7 | height: 50,
8 | fontSize: "1rem",
9 | fontWeight: "bolder",
10 | color: "White"
11 | }
12 |
13 | function ContinueButton(props) {
14 |
15 | const renderContinueDesktopBtn = () => {
16 | return (
17 |
18 |
23 |
24 | )
25 | }
26 |
27 | const renderContinueMobileBtn = () => {
28 | return (
29 |
30 |
35 |
36 | )
37 | }
38 |
39 | log.info("[Continue Button] Rendering Continue Button Component.")
40 |
41 | return (
42 | <>
43 |
44 | {renderContinueDesktopBtn()}
45 |
46 |
47 |
48 | {renderContinueMobileBtn()}
49 |
50 | >
51 | )
52 | }
53 |
54 | function continueButtonPropsAreEqual(prevProps, nextProps) {
55 | return prevProps.action === nextProps.action && !prevProps.buttonHandler;
56 | }
57 |
58 | const continueButtonMemoWrapper = React.memo(ContinueButton, continueButtonPropsAreEqual);
59 |
60 | export default continueButtonMemoWrapper;
--------------------------------------------------------------------------------
/server/common-data-service/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 | %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 | ${LOGS}/common-data-service-logger.log
23 |
25 | %d %p %C{1.} [%t] %m%n
26 |
27 |
28 |
30 |
31 | ${LOGS}/archived/common-data-service-logger-%d{yyyy-MM-dd}.%i.log
32 |
33 |
35 | 10MB
36 |
37 | 3
38 | 100MB
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 | %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 | ${LOGS}/authentication-service-logger.log
23 |
25 | %d %p %C{1.} [%t] %m%n
26 |
27 |
28 |
30 |
31 | ${LOGS}/archived/authentication-service-logger-%d{yyyy-MM-dd}.%i.log
32 |
33 |
35 | 10MB
36 |
37 | 3
38 | 100MB
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/server/search-suggestion-service/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 | %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 | ${LOGS}/search-suggestion-service-logger.log
23 |
25 | %d %p %C{1.} [%t] %m%n
26 |
27 |
28 |
30 |
31 | ${LOGS}/archived/search-suggestion-service-logger-%d{yyyy-MM-dd}.%i.log
32 |
33 |
35 | 10MB
36 |
37 | 3
38 | 100MB
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ecommerce-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@material-ui/core": "~4.12.4",
7 | "@material-ui/icons": "latest",
8 | "@material-ui/lab": "latest",
9 | "@stripe/react-stripe-js": "~1.1.2",
10 | "@stripe/stripe-js": "~1.8.0",
11 | "axios": "~0.19.2",
12 | "env-cmd": "~10.1.0",
13 | "express": "~4.17.1",
14 | "fontsource-roboto": "~2.1.3",
15 | "js-base64": "~2.5.2",
16 | "js-cookie": "~2.2.1",
17 | "lodash": "~4.17.15",
18 | "loglevel": "~1.6.8",
19 | "node-sass": "~4.14.1",
20 | "path": "~0.12.7",
21 | "prop-types": "~15.7.2",
22 | "react": "~16.13.0",
23 | "react-dom": "~16.13.0",
24 | "react-helmet": "~6.1.0",
25 | "react-id-swiper": "~4.0.0",
26 | "react-redux": "~7.2.0",
27 | "react-router-dom": "~5.2.0",
28 | "react-scripts": "~3.4.4",
29 | "react-stripe-checkout": "~2.6.3",
30 | "redux": "~4.0.5",
31 | "redux-form": "~8.3.6",
32 | "redux-thunk": "~2.3.0",
33 | "semantic-ui-css": "~2.4.1",
34 | "semantic-ui-react": "~0.88.2",
35 | "stripe": "~8.78.0",
36 | "styled-components": "~5.1.1",
37 | "swiper": "~5.4.2"
38 | },
39 | "scripts": {
40 | "start": "node server.js",
41 | "build": "react-scripts build",
42 | "start_docker_dev": "react-scripts start",
43 | "start_dev": "./node_modules/.bin/env-cmd -f .env react-scripts start",
44 | "build_dev": "./node_modules/.bin/env-cmd -f .env react-scripts build",
45 | "test": "react-scripts test",
46 | "eject": "react-scripts eject"
47 | },
48 | "eslintConfig": {
49 | "extends": "react-app"
50 | },
51 | "browserslist": {
52 | "production": [
53 | ">0.2%",
54 | "not dead",
55 | "not op_mini all"
56 | ],
57 | "development": [
58 | "last 1 chrome version",
59 | "last 1 firefox version",
60 | "last 1 safari version"
61 | ]
62 | },
63 | "devDependencies": {
64 | "@testing-library/jest-dom": "^5.11.2",
65 | "@testing-library/react": "^10.4.7"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/client/src/components/routes/navbar/mobileMenu.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import log from "loglevel";
3 | import {Grid, IconButton, Menu} from "@material-ui/core";
4 | import MenuItem from "@material-ui/core/MenuItem";
5 | import BagButton from "./bagButton";
6 |
7 | export default function MobileMenu(props) {
8 |
9 | log.info(`[MobileMenu]: Rendering MobileMenu Component`)
10 | return (
11 |
47 | );
48 | };
49 |
--------------------------------------------------------------------------------
/client/src/components/routes/priceDetails.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import log from 'loglevel';
3 | import {Divider, Grid} from "@material-ui/core";
4 | import {useSelector} from "react-redux";
5 |
6 | const paymentStyles = {
7 | header: {
8 | fontColor: "#535766",
9 | fontWeight: "bolder",
10 | fontSize: "1.2rem",
11 | padding: "20px 0",
12 | },
13 | fontColor: "#282c3f",
14 | fontWeight: 400,
15 | fontSize: "1.1rem",
16 | }
17 |
18 | function PriceDetails() {
19 | let cartTotal = useSelector(state => state.cartTotalReducer);
20 | const deliveryCharges = useSelector(state => state.deliveryChargesReducer)
21 |
22 | const renderGridData = (label, value, styles) => {
23 | return (
24 |
25 |
26 |
27 | {label}
28 |
29 |
30 |
32 | {value}
33 |
34 |
35 | )
36 | }
37 |
38 | log.info("[PriceDetails] Rendering PriceDetails Component.")
39 |
40 | return (
41 |
42 |
43 |
45 | Price Details
46 |
47 |
48 | {renderGridData("Bag Total", `$${cartTotal}`, {...paymentStyles, paddingTop: 10})}
49 | {renderGridData("Shipping", `$${deliveryCharges}`, {...paymentStyles, paddingTop: 10})}
50 |
51 |
52 |
53 |
54 |
55 | {renderGridData("Order Total", `$${cartTotal + deliveryCharges}`,
56 | {...paymentStyles.header})}
57 |
58 |
59 | )
60 | }
61 |
62 | export default PriceDetails;
--------------------------------------------------------------------------------
/client/src/components/ui/radioButtonGroup.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Radio from '@material-ui/core/Radio';
3 | import RadioGroup from '@material-ui/core/RadioGroup';
4 | import FormControlLabel from '@material-ui/core/FormControlLabel';
5 | import FormControl from '@material-ui/core/FormControl';
6 | import log from "loglevel";
7 | import {makeStyles} from "@material-ui/core/styles";
8 |
9 | const useStyles = makeStyles(() => ({
10 | label: {
11 | fontWeight: "bold",
12 | fontSize: "0.9rem"
13 | }
14 | }));
15 |
16 | export default function RadioButtonsGroup(props) {
17 | const classes = useStyles()
18 |
19 | const handleChange = (event) => {
20 | log.info(`[RadioButtonsGroup]: handleChange event.target.value = ${event.target.value}`)
21 | props.onChangeHandler(event.target.value)
22 | };
23 |
24 | const renderRadioButtonList = rbList => {
25 |
26 | if (!rbList) {
27 | log.info(`[RadioButtonsGroup]: rbList is null`)
28 | return null
29 | }
30 |
31 | log.debug(`[RadioButtonsGroup]: rbList = ${JSON.stringify(rbList)}`)
32 |
33 | return rbList.map(({id, value}) => {
34 | return }
37 | label={value}
38 | classes={{label: classes.label}}/>
39 | })
40 | }
41 |
42 | log.debug(`[RadioButtonsGroup]: props.attrList = ${props.attrList}`)
43 | log.debug(`[RadioButtonsGroup]: props.selectedValue = ${props.selectedValue}`)
44 | log.info(`[RadioButtonsGroup]: Rendering RadioButtonsGroup Component`)
45 |
46 | return (
47 |
48 |
51 | {renderRadioButtonList(props.attrList)}
52 |
53 |
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/client/src/components/app.js:
--------------------------------------------------------------------------------
1 | import React, {useState} from "react";
2 | import history from "../history";
3 | import {Router, Route, Switch} from 'react-router-dom';
4 | import log from "loglevel"
5 | import NavBar from "./routes/navbar/navBar";
6 | import {TabPanelList} from "./routes/navbar/tabPanelList";
7 | import Home from "./routes/home/home";
8 | import SignIn from "./routes/signin/signIn";
9 | import SignUp from "./routes/signup/signUp";
10 | import Product from "./routes/product/product";
11 | import ProductDetail from "./routes/detail/productDetails";
12 | import Checkout from "./routes/checkout/checkout";
13 | import ShoppingBag from "./routes/shoppingBag";
14 | import {SuccessPayment} from "./routes/successPayment";
15 | import {CancelPayment} from "./routes/cancelPayment";
16 | import {BadRequest} from "./ui/error/badRequest";
17 |
18 | const App = () => {
19 | log.info(`[App]: Rendering App Component`)
20 | const [serverError, setServerError] = useState(false);
21 |
22 | const setServerErrorHandler = () => {
23 | setServerError(true)
24 | }
25 |
26 | return (
27 |
28 |
29 |
30 | {serverError ? null:
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | }
43 |
44 | )
45 | }
46 |
47 | export default App;
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/util/JwtUtil.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.util;
2 |
3 | import io.jsonwebtoken.Claims;
4 | import io.jsonwebtoken.Jwts;
5 | import io.jsonwebtoken.SignatureAlgorithm;
6 | import org.springframework.security.core.userdetails.UserDetails;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.Date;
10 | import java.util.HashMap;
11 | import java.util.Map;
12 | import java.util.function.Function;
13 |
14 | @Service
15 | public class JwtUtil {
16 |
17 | private String SECRET_KEY = "sdf34hj@#234hls23$@423%nl";
18 |
19 | public String extractUsername(String token) {
20 | return extractClaim(token, Claims::getSubject);
21 | }
22 |
23 | public Date extractExpiration(String token) {
24 | return extractClaim(token, Claims::getExpiration);
25 | }
26 |
27 | public T extractClaim(String token, Function claimsResolver) {
28 | final Claims claims = extractAllClaims(token);
29 | return claimsResolver.apply(claims);
30 | }
31 | private Claims extractAllClaims(String token) {
32 | return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
33 | }
34 |
35 | private Boolean isTokenExpired(String token) {
36 | return extractExpiration(token).before(new Date());
37 | }
38 |
39 | public String generateToken(UserDetails userDetails) {
40 | Map claims = new HashMap<>();
41 | return createToken(claims, userDetails.getUsername());
42 | }
43 |
44 | private String createToken(Map claims, String subject) {
45 |
46 | return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
47 | .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
48 | .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
49 | }
50 |
51 | public Boolean validateToken(String token, UserDetails userDetails) {
52 | final String username = extractUsername(token);
53 | return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/client/src/logger/Logger.js:
--------------------------------------------------------------------------------
1 | class Logger {
2 | static Levels = {
3 | ERROR:1,
4 | WARN:2,
5 | INFO:3,
6 | DEBUG:4,
7 | DISABLE:99,
8 | MAX_LEVEL:100
9 | };
10 |
11 | static globalLoggerLevel = Logger.Levels.MAX_LEVEL;
12 |
13 | constructor(level = Logger.globalLoggerLevel) {
14 | this.currentLevel = level
15 | // console.log("constructor Level = " + level)
16 | }
17 |
18 | disable() {
19 | this.currentLevel = Logger.Levels.DISABLE
20 | }
21 |
22 | enable(level = Logger.Levels.ERROR) {
23 | this.currentLevel = level
24 | }
25 |
26 | send(level, message) {
27 | // eslint-disable-next-line default-case
28 | switch (level) {
29 | case Logger.Levels.DEBUG:
30 | console.log(`%c[${this.getCurrentTime()}] [DEBUG]: ${message}`, "color:orange; font-size: 15px; font-weight: bold")
31 | break
32 | case Logger.Levels.INFO:
33 | console.log(`%c[${this.getCurrentTime()}] [INFO]: ${message}`, "color:green; font-size: 15px; font-weight: bold")
34 | break
35 | case Logger.Levels.WARN:
36 | console.log(`%c[${this.getCurrentTime()}] [WARN]: ${message}`, "color:yellow; font-size: 15px; font-weight: bold")
37 | break
38 | case Logger.Levels.ERROR:
39 | console.log(`%c[${this.getCurrentTime()}] [ERROR]: ${message}`, "color:red; font-size: 15px; font-weight: bold")
40 | break
41 | }
42 | }
43 |
44 | log(level, message) {
45 | console.log("Level = " + level)
46 | if(level === Logger.Levels.DISABLE) {
47 | return;
48 | }
49 |
50 | if(Logger.globalLoggerLevel <= level || this.currentLevel <= level) {
51 | this.send(level, message)
52 | }
53 | }
54 |
55 | getCurrentTime() {
56 | let d = new Date();
57 | return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${d.getMilliseconds()}`
58 | }
59 |
60 | error(message) {
61 | this.log(Logger.Levels.ERROR, message);
62 | }
63 |
64 | warn(message) {
65 | this.log(Logger.Levels.WARN, message);
66 | }
67 |
68 | info(message) {
69 | this.log(Logger.Levels.INFO, message);
70 | }
71 |
72 | debug(message) {
73 | this.log(Logger.Levels.DEBUG, message);
74 | }
75 | }
76 |
77 | export default Logger;
--------------------------------------------------------------------------------
/client/src/components/ui/alertModal.js:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from 'react';
2 | import log from 'loglevel';
3 | import {Button, Divider, Grid} from "@material-ui/core";
4 | import Modal from "../ui/modal"
5 |
6 | function AlertModal(props) {
7 |
8 | const [alertConfirmation, setAlertConfirmation] = useState(false)
9 |
10 | useEffect(() => {
11 | log.info(`[AlertModal] Component Did mount`)
12 | if(props.enable) {
13 | log.info(`[AlertModal] enabling the alert confirmation`)
14 | setAlertConfirmation(true)
15 | }
16 |
17 | // eslint-disable-next-line
18 | }, [props.timestamp])
19 |
20 | const renderAlertConfirmation = () => {
21 | return (
22 |
23 |
24 |
26 | {props.title}
27 |
28 |
29 | {props.question}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
42 |
43 |
44 |
45 | )
46 | }
47 |
48 | const closeModalHandler = () => {
49 | setAlertConfirmation(false)
50 | }
51 |
52 | const renderModal = () => {
53 | return
56 | }
57 |
58 | log.info(`[AlertModal] Rendering AlertModal Component. alertConfirmation = ${alertConfirmation}`)
59 |
60 | return (
61 | <>
62 | {alertConfirmation ? renderModal(): null}
63 | >
64 | )
65 | }
66 |
67 | export default AlertModal;
--------------------------------------------------------------------------------
/server/payment-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.3.2.RELEASE
9 |
10 |
11 | com.ujjaval.ecommerce
12 | payment-service
13 | 0.0.1-SNAPSHOT
14 | payment-service
15 | payment-service Microservices
16 |
17 |
18 | 11
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-actuator
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-web
30 |
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-devtools
35 | runtime
36 | true
37 |
38 |
39 |
40 | com.stripe
41 | stripe-java
42 | 19.34.0
43 |
44 |
45 |
46 | org.projectlombok
47 | lombok
48 | true
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-starter-test
53 | test
54 |
55 |
56 | org.junit.vintage
57 | junit-vintage-engine
58 |
59 |
60 |
61 |
62 |
63 |
64 | payment-service
65 |
66 |
67 | org.springframework.boot
68 | spring-boot-maven-plugin
69 |
70 |
71 | repackage
72 |
73 | repackage
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/config/SecurityConfigurer.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.config;
2 |
3 | import com.ujjaval.ecommerce.authenticationservice.filter.JwtRequestFilter;
4 | import com.ujjaval.ecommerce.authenticationservice.service.CustomUserDetailsService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.security.authentication.AuthenticationManager;
8 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
12 | import org.springframework.security.config.http.SessionCreationPolicy;
13 | import org.springframework.security.crypto.password.NoOpPasswordEncoder;
14 | import org.springframework.security.crypto.password.PasswordEncoder;
15 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
16 |
17 | @EnableWebSecurity
18 | public class SecurityConfigurer extends WebSecurityConfigurerAdapter {
19 |
20 | @Autowired
21 | private CustomUserDetailsService customUserDetailsService;
22 |
23 | @Autowired
24 | private JwtRequestFilter jwtRequestFilter;
25 |
26 | protected void configure(AuthenticationManagerBuilder auth) throws Exception {
27 | auth.userDetailsService(customUserDetailsService);
28 | }
29 |
30 | @Bean
31 | public PasswordEncoder passwordEncoder() {
32 | return NoOpPasswordEncoder.getInstance();
33 | }
34 |
35 | @Override
36 | @Bean
37 | public AuthenticationManager authenticationManagerBean() throws Exception {
38 | return super.authenticationManagerBean();
39 | }
40 |
41 | @Override
42 | protected void configure(HttpSecurity httpSecurity) throws Exception {
43 | httpSecurity.csrf().disable()
44 | .authorizeRequests().antMatchers("/authenticate", "/signup", "/test").permitAll().
45 | anyRequest().authenticated().and().
46 | exceptionHandling().and().sessionManagement()
47 | .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
48 |
49 | httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/server/common-data-service/src/main/java/com/ujjaval/ecommerce/commondataservice/config/ProdRedisConfig.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.commondataservice.config;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5 | import org.springframework.cache.CacheManager;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.context.annotation.Profile;
9 | import org.springframework.core.env.Environment;
10 | import org.springframework.data.redis.cache.RedisCacheManager;
11 | import org.springframework.data.redis.connection.RedisConnectionFactory;
12 | import org.springframework.data.redis.connection.RedisPassword;
13 | import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
14 | import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
15 | import org.springframework.data.redis.core.RedisTemplate;
16 | import redis.clients.jedis.Jedis;
17 | import redis.clients.jedis.JedisPool;
18 | import redis.clients.jedis.JedisPoolConfig;
19 | import redis.clients.jedis.Protocol;
20 |
21 | import java.net.URI;
22 | import java.net.URISyntaxException;
23 | import java.net.UnknownHostException;
24 | import java.util.Objects;
25 |
26 | @Configuration
27 | @Profile("prod")
28 | public class ProdRedisConfig {
29 |
30 | @Bean
31 | public JedisConnectionFactory jedisConnectionFactory() {
32 |
33 | try {
34 | System.out.println("Loading Prod profile redis config....");
35 | String redistogoUrl = System.getenv("REDIS_URL");
36 | URI redistogoUri = new URI(redistogoUrl);
37 |
38 | JedisConnectionFactory jedisConnFactory = new JedisConnectionFactory();
39 |
40 | jedisConnFactory.setUsePool(true);
41 | jedisConnFactory.setHostName(redistogoUri.getHost());
42 | jedisConnFactory.setPort(redistogoUri.getPort());
43 | jedisConnFactory.setTimeout(Protocol.DEFAULT_TIMEOUT);
44 | jedisConnFactory.setPassword(redistogoUri.getUserInfo().split(":", 2)[1]);
45 |
46 | return jedisConnFactory;
47 |
48 | } catch (URISyntaxException e) {
49 | e.printStackTrace();
50 | return null;
51 | }
52 | }
53 |
54 | @Bean
55 | public RedisTemplate redisTemplate() {
56 | RedisTemplate template = new RedisTemplate<>();
57 | template.setConnectionFactory(jedisConnectionFactory());
58 | return template;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/client/src/components/routes/product/filterPagination.js:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from 'react';
2 | import Grid from "@material-ui/core/Grid";
3 | import log from 'loglevel';
4 | import {useSelector} from "react-redux";
5 | import Pagination from "@material-ui/lab/Pagination";
6 | import {MAX_PRODUCTS_PER_PAGE} from "../../../constants/constants";
7 | import history from "../../../history";
8 |
9 | export default function FilterPagination() {
10 | const selectedPage = useSelector(state => state.selectPageReducer)
11 | const filterProductsReducer = useSelector(state => state.filterProductsReducer)
12 | const [page, setPage] = useState(1)
13 | let totalProducts = 0
14 |
15 | useEffect(() => {
16 | if(selectedPage != null) {
17 | setPage(selectedPage.pageNumber)
18 | }
19 | }, [selectedPage])
20 |
21 | const handleChangePage = (event, page) => {
22 | log.info(`[FilterPagination] dispatching SELECT_PRODUCT_PAGE for page = ${page}`)
23 |
24 | setPage(page)
25 | let route = history.location.pathname
26 | let queryStr = history.location.search
27 | if (history.location.search.search("page") === -1) {
28 | history.push(`${route}${queryStr}::page=${page-1},${MAX_PRODUCTS_PER_PAGE}`)
29 | } else {
30 | history.push(`${route}${queryStr.replace(new RegExp(`page=[0-9]+,${MAX_PRODUCTS_PER_PAGE}`),
31 | `page=${page-1},${MAX_PRODUCTS_PER_PAGE}`)}`)
32 | }
33 | }
34 |
35 | // if we got data from the server side
36 | if (!filterProductsReducer || filterProductsReducer.hasOwnProperty("data") === false ||
37 | filterProductsReducer.data.hasOwnProperty("totalCount") === false) {
38 | log.info(`[FilterPagination] totalProducts = ${totalProducts}`)
39 | return null
40 | } else {
41 | // set the total products used to calculate how many pages require
42 | totalProducts = filterProductsReducer.data.totalCount
43 | }
44 |
45 | log.info(`[FilterPagination] Rendering FilterPagination Component selectedPage = ${JSON.stringify(selectedPage)}`)
46 |
47 | return (
48 |
52 |
56 |
57 | );
58 | }
59 |
--------------------------------------------------------------------------------
/client/src/components/routes/product/filterSideNavbar/priceCheckBox.js:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from 'react';
2 | import CheckboxList from "../../../ui/checkboxList";
3 | import log from 'loglevel';
4 | import {useSelector} from "react-redux";
5 | import {NavBarHeader} from "../../../ui/headers";
6 | import {Box} from "@material-ui/core";
7 | import history from "../../../../history";
8 | import {toggleId} from "../../../../helper/toggleId";
9 | import {updateQueryString} from "../../../../helper/updateQueryString";
10 |
11 | export default function PriceCheckBox() {
12 | const TITLE = "Price"
13 | const priceRangeList = useSelector(state => state.filterAttributesReducer.data ?
14 | state.filterAttributesReducer.data.prices : null)
15 | const selectedPriceRanges = useSelector(state => state.selectedFilterAttributesReducer.prices)
16 | const [selectedList, setSelectedList] = useState([])
17 | const resetFilter = useSelector(state => state.clearFiltersReducer)
18 |
19 | useEffect(() => {
20 | if (selectedPriceRanges.length > 0) {
21 | setSelectedList(selectedPriceRanges)
22 | } else {
23 | setSelectedList([])
24 | }
25 | }, [selectedPriceRanges])
26 |
27 | useEffect(() => {
28 | if(resetFilter) {
29 | if(selectedList.length > 0) {
30 | setSelectedList([])
31 | }
32 | }
33 |
34 | // eslint-disable-next-line
35 | }, [history.location.search])
36 |
37 | if (!priceRangeList) {
38 | log.debug(`[PriceCheckBox] priceRangeList is null`)
39 | return null
40 | }
41 |
42 | /**
43 | * select and dispatch the selected option
44 | * @param id
45 | * @param value
46 | */
47 | const handleCheckBoxChange = (id, value) => {
48 | log.info(`[PriceCheckBox] handleCheckBoxChange(id) = ${id}`)
49 | const {list, ids} = toggleId(id, value, selectedList)
50 | setSelectedList(list)
51 | history.push(updateQueryString(history, "prices", id, ids))
52 | }
53 |
54 | log.debug(`[PriceCheckBox] selectedPriceRanges...`)
55 |
56 | log.info(`[PriceCheckBox] Rendering PriceCheckBox Component`)
57 |
58 | return (
59 |
60 |
61 |
62 |
63 |
68 |
69 | );
70 | }
71 |
--------------------------------------------------------------------------------
/server/payment-service/src/main/java/com/ujjaval/ecommerce/paymentservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.paymentservice.controller;
2 |
3 | import com.stripe.Stripe;
4 | import com.stripe.exception.StripeException;
5 | import com.stripe.model.Charge;
6 | import com.stripe.param.ChargeCreateParams;
7 | import com.ujjaval.ecommerce.paymentservice.dto.CardToken;
8 | import com.ujjaval.ecommerce.paymentservice.dto.PaymentStatus;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.core.env.Environment;
11 | import org.springframework.http.ResponseEntity;
12 | import org.springframework.web.bind.annotation.*;
13 |
14 | import java.net.UnknownHostException;
15 | import java.sql.Timestamp;
16 |
17 | @CrossOrigin(origins = "*", allowedHeaders = "*")
18 | @RestController
19 | public class PaymentController {
20 |
21 | @Autowired
22 | private Environment env;
23 |
24 | @GetMapping("/test")
25 | public ResponseEntity> test() {
26 | return ResponseEntity.ok("success");
27 | }
28 |
29 | @PostMapping("/payment")
30 | public ResponseEntity chargeCustomer(@RequestBody CardToken cardToken) {
31 |
32 | Stripe.apiKey = env.getProperty("STRIPE_SECRET_KEY");
33 | Stripe.setMaxNetworkRetries(2);
34 |
35 | Charge charge;
36 | PaymentStatus paymentStatus;
37 |
38 | try {
39 | ChargeCreateParams params =
40 | ChargeCreateParams.builder()
41 | .setAmount(cardToken.getAmount())
42 | .setCurrency(cardToken.getCurrency())
43 | .setDescription("Shopper Buy")
44 | .setSource(cardToken.getId())
45 | .build();
46 |
47 | charge = Charge.create(params);
48 | System.out.println("Charge = " + charge);
49 | Timestamp timestamp = new Timestamp(System.currentTimeMillis());
50 |
51 | paymentStatus = new PaymentStatus(timestamp.getTime(), false,
52 | charge.getId(),
53 | charge.getBalanceTransaction(),
54 | charge.getReceiptUrl()
55 | );
56 |
57 | } catch (Exception e) {
58 | paymentStatus = new PaymentStatus();
59 | paymentStatus.setPayment_failed(true);
60 | System.out.println("Something went wrong with Stripe API");
61 | return ResponseEntity.badRequest().body(paymentStatus);
62 | }
63 |
64 | System.out.println("Payment is successful....");
65 | return ResponseEntity.ok(paymentStatus);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/server/authentication-service/src/main/java/com/ujjaval/ecommerce/authenticationservice/filter/JwtRequestFilter.java:
--------------------------------------------------------------------------------
1 | package com.ujjaval.ecommerce.authenticationservice.filter;
2 |
3 | import com.ujjaval.ecommerce.authenticationservice.service.CustomUserDetailsService;
4 | import com.ujjaval.ecommerce.authenticationservice.util.JwtUtil;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
7 | import org.springframework.security.core.context.SecurityContextHolder;
8 | import org.springframework.security.core.userdetails.UserDetails;
9 | import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
10 | import org.springframework.stereotype.Component;
11 | import org.springframework.web.filter.OncePerRequestFilter;
12 |
13 | import javax.servlet.FilterChain;
14 | import javax.servlet.ServletException;
15 | import javax.servlet.http.HttpServletRequest;
16 | import javax.servlet.http.HttpServletResponse;
17 | import java.io.IOException;
18 |
19 | @Component
20 | public class JwtRequestFilter extends OncePerRequestFilter {
21 |
22 | @Autowired
23 | private CustomUserDetailsService customUserDetailsService;
24 |
25 | @Autowired
26 | private JwtUtil jwtUtil;
27 |
28 | @Override
29 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
30 | throws ServletException, IOException {
31 |
32 | final String authorizationHeader = request.getHeader("Authorization");
33 |
34 | String username = null;
35 | String jwt = null;
36 |
37 | if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
38 | jwt = authorizationHeader.substring(7);
39 | username = jwtUtil.extractUsername(jwt);
40 | }
41 |
42 | if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
43 |
44 | UserDetails userDetails = this.customUserDetailsService.loadUserByUsername(username);
45 |
46 | if (jwtUtil.validateToken(jwt, userDetails)) {
47 |
48 | UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
49 | userDetails, null, userDetails.getAuthorities());
50 | usernamePasswordAuthenticationToken
51 | .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
52 | SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
53 | }
54 | }
55 | chain.doFilter(request, response);
56 | }
57 |
58 | }
--------------------------------------------------------------------------------