├── .buildignore ├── client ├── app │ ├── about │ │ ├── about.scss │ │ ├── about.html │ │ ├── about.controller.js │ │ ├── about.js │ │ └── about.controller.spec.js │ ├── cart │ │ ├── cart.scss │ │ ├── cart.controller.js │ │ ├── cart.js │ │ └── cart.controller.spec.js │ ├── category │ │ ├── category.scss │ │ ├── category.js │ │ ├── category.controller.spec.js │ │ └── category.controller.js │ ├── checkout │ │ ├── checkout.scss │ │ ├── checkout.js │ │ └── checkout.controller.spec.js │ ├── contact │ │ ├── contact.scss │ │ ├── contact.html │ │ ├── contact.controller.js │ │ ├── contact.js │ │ └── contact.controller.spec.js │ ├── invoice │ │ ├── invoice.scss │ │ ├── invoice.controller.js │ │ ├── invoice.js │ │ └── invoice.controller.spec.js │ ├── orders │ │ ├── orders.scss │ │ ├── orders.js │ │ ├── orders.controller.spec.js │ │ └── orders.controller.js │ ├── product │ │ ├── product.scss │ │ ├── product.js │ │ ├── product.controller.spec.js │ │ └── product.controller.js │ ├── search │ │ ├── search.scss │ │ ├── search.controller.js │ │ ├── search.controller.spec.js │ │ └── search.js │ ├── manage-products │ │ ├── manage-products.scss │ │ ├── manage-products.controller.spec.js │ │ └── manage-products.js │ ├── manage-requests │ │ ├── manage-requests.scss │ │ ├── manage-requests.controller.spec.js │ │ └── manage-requests.js │ ├── manage-categories │ │ ├── manage-categories.scss │ │ ├── manage-categories.controller.spec.js │ │ ├── manage-categories.js │ │ ├── manage-categories-add.html │ │ └── manage-categories-edit.html │ ├── admin │ │ ├── admin.module.js │ │ ├── admin.router.js │ │ ├── admin.scss │ │ └── admin.controller.js │ ├── app.constant.js │ ├── main │ │ ├── main.js │ │ ├── main.scss │ │ └── main.controller.spec.js │ ├── account │ │ ├── login │ │ │ └── login.controller.js │ │ ├── settings │ │ │ └── settings.controller.js │ │ ├── signup │ │ │ └── signup.controller.js │ │ └── account.js │ └── app.scss ├── components │ ├── sidebar-cat │ │ ├── sidebar-cat.scss │ │ ├── sidebar-cat.directive.js │ │ ├── sidebar-cat.controller.spec.js │ │ ├── sidebar-cat.directive.spec.js │ │ ├── sidebar-cat.html │ │ └── sidebar-cat.controller.js │ ├── oauth-buttons │ │ ├── oauth-buttons.scss │ │ ├── oauth-buttons.controller.js │ │ ├── oauth-buttons.directive.js │ │ ├── oauth-buttons.html │ │ ├── oauth-buttons.controller.spec.js │ │ └── oauth-buttons.directive.spec.js │ ├── sidebar-account │ │ ├── sidebar-account.scss │ │ ├── sidebar-account.controller.js │ │ ├── sidebar-account.directive.js │ │ ├── sidebar-account.controller.spec.js │ │ ├── sidebar-account.directive.spec.js │ │ └── sidebar-account.html │ ├── util │ │ └── util.module.js │ ├── footer │ │ ├── footer.scss │ │ └── footer.directive.js │ ├── navbar │ │ ├── navbar.directive.js │ │ └── navbar.html │ ├── auth │ │ ├── auth.module.js │ │ ├── user.service.js │ │ ├── interceptor.service.js │ │ └── router.decorator.js │ ├── socket │ │ └── socket.mock.js │ ├── order │ │ ├── order.service.spec.js │ │ └── order.service.js │ ├── product │ │ ├── product.service.spec.js │ │ └── product.service.js │ ├── request │ │ ├── request.service.spec.js │ │ └── request.service.js │ ├── mongoose-error │ │ └── mongoose-error.directive.js │ ├── modal │ │ ├── modal.scss │ │ └── modal.html │ └── ui-router │ │ └── ui-router.mock.js ├── robots.txt ├── favicon.ico ├── apple-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── ms-icon-70x70.png ├── apple-icon-57x57.png ├── apple-icon-60x60.png ├── apple-icon-72x72.png ├── apple-icon-76x76.png ├── ms-icon-144x144.png ├── ms-icon-150x150.png ├── ms-icon-310x310.png ├── android-icon-36x36.png ├── android-icon-48x48.png ├── android-icon-72x72.png ├── android-icon-96x96.png ├── apple-icon-114x114.png ├── apple-icon-120x120.png ├── apple-icon-144x144.png ├── apple-icon-152x152.png ├── apple-icon-180x180.png ├── assets │ ├── img │ │ ├── favicon.ico │ │ ├── icon │ │ │ ├── bor.png │ │ │ ├── cart-bg.jpg │ │ │ ├── arrow-down.png │ │ │ ├── grid-view.png │ │ │ ├── list-view.png │ │ │ ├── slider-l-i.png │ │ │ ├── slider-r-i.png │ │ │ ├── p-details-1.jpg │ │ │ ├── p-details-2.jpg │ │ │ ├── slider-l-i-3.png │ │ │ ├── slider-l-i-h.png │ │ │ ├── slider-r-i-3.png │ │ │ ├── slider-r-i-h.png │ │ │ ├── grid-view-hover.png │ │ │ ├── list-view-hover.png │ │ │ ├── slider-l-i-h-3.png │ │ │ └── slider-r-i-h-3.png │ │ ├── mega-b-1.jpg │ │ ├── mega-b-2.jpg │ │ ├── mega-b-3.jpg │ │ ├── mega-b-4.jpg │ │ ├── mega-b-5.jpg │ │ ├── mega-b-6.jpg │ │ ├── mega-b-7.jpg │ │ ├── search.png │ │ ├── yeoman.png │ │ ├── logo │ │ │ ├── logo.png │ │ │ ├── logo-2.png │ │ │ ├── logo-3.png │ │ │ ├── logo-4.png │ │ │ ├── logo-5.png │ │ │ └── footer-logo.png │ │ ├── map-marker.png │ │ ├── not-found.png │ │ ├── about │ │ │ ├── about.jpg │ │ │ ├── ab-team1.jpg │ │ │ ├── ab-team2.jpg │ │ │ ├── ab-team3.jpg │ │ │ └── ab-team4.jpg │ │ ├── blog │ │ │ ├── blog-1.jpg │ │ │ ├── blog-2.jpg │ │ │ ├── blog-3.jpg │ │ │ ├── blog-4.jpg │ │ │ ├── blog-5.jpg │ │ │ ├── blog-6.jpg │ │ │ ├── blog-7.jpg │ │ │ ├── blog-8.jpg │ │ │ ├── news-1.jpg │ │ │ ├── news-10.jpg │ │ │ ├── news-11.jpg │ │ │ ├── news-12.jpg │ │ │ ├── news-13.jpg │ │ │ ├── news-14.jpg │ │ │ ├── news-15.jpg │ │ │ ├── news-16.jpg │ │ │ ├── news-17.jpg │ │ │ ├── news-2.jpg │ │ │ ├── news-3.jpg │ │ │ ├── news-4.jpg │ │ │ ├── news-5.jpg │ │ │ ├── news-6.jpg │ │ │ ├── news-7.jpg │ │ │ ├── news-8.jpg │ │ │ └── news-9.jpg │ │ ├── brand │ │ │ ├── brand-1.png │ │ │ ├── brand-2.png │ │ │ ├── brand-3.png │ │ │ └── brand-4.png │ │ ├── search-hover.png │ │ ├── testimonial.png │ │ ├── banner │ │ │ ├── banner-1.jpg │ │ │ ├── banner-2.jpg │ │ │ ├── banner-3.jpg │ │ │ ├── banner-4.jpg │ │ │ ├── banner-5.jpg │ │ │ ├── banner-6.jpg │ │ │ ├── banner-7.jpg │ │ │ ├── banner-8.jpg │ │ │ ├── banner-9.jpg │ │ │ ├── banner-10.jpg │ │ │ ├── banner-11.jpg │ │ │ ├── banner-12.jpg │ │ │ ├── banner-13.jpg │ │ │ ├── banner-14.jpg │ │ │ ├── banner-15.jpg │ │ │ ├── banner-16.jpg │ │ │ ├── banner-17.jpg │ │ │ ├── banner-18.jpg │ │ │ ├── banner-19.jpg │ │ │ ├── banner-20.jpg │ │ │ ├── banner-21.jpg │ │ │ ├── banner-22.jpg │ │ │ ├── banner-23.jpg │ │ │ ├── banner-24.jpg │ │ │ ├── banner-25.jpg │ │ │ ├── banner-26.jpg │ │ │ ├── banner-27.jpg │ │ │ ├── banner-28.jpg │ │ │ ├── banner-29.jpg │ │ │ ├── banner-30.jpg │ │ │ ├── banner-31.jpg │ │ │ ├── banner-32.jpg │ │ │ ├── banner-33.jpg │ │ │ ├── banner-34.jpg │ │ │ ├── banner-35.jpg │ │ │ ├── banner-36.jpg │ │ │ ├── banner-37.jpg │ │ │ ├── banner-38.jpg │ │ │ └── banner-39.jpg │ │ ├── discount-border.png │ │ ├── slider │ │ │ ├── slider-1.jpg │ │ │ ├── slider-2.jpg │ │ │ ├── slider-3.jpg │ │ │ ├── slider-l-1.png │ │ │ ├── slider-l-10.png │ │ │ ├── slider-l-2.png │ │ │ ├── slider-l-3.png │ │ │ ├── slider-l-4.png │ │ │ ├── slider-l-5.png │ │ │ ├── slider-l-6.png │ │ │ ├── slider-l-7.png │ │ │ ├── slider-l-8.png │ │ │ ├── slider-l-9.png │ │ │ ├── slider-l-logo.png │ │ │ ├── home-five │ │ │ │ ├── slider-9.jpg │ │ │ │ └── slider-10.jpg │ │ │ ├── home-four │ │ │ │ ├── slider-7.jpg │ │ │ │ ├── slider-8.jpg │ │ │ │ ├── slider-10.jpg │ │ │ │ ├── slider-l-1.png │ │ │ │ ├── slider-l-10.png │ │ │ │ ├── slider-l-11.png │ │ │ │ ├── slider-l-2.png │ │ │ │ ├── slider-l-3.png │ │ │ │ ├── slider-l-4.png │ │ │ │ ├── slider-l-5.png │ │ │ │ ├── slider-l-6.png │ │ │ │ ├── slider-l-7.png │ │ │ │ ├── slider-l-8.png │ │ │ │ └── slider-l-9.png │ │ │ ├── home-two │ │ │ │ ├── slider-3.jpg │ │ │ │ ├── slider-4.jpg │ │ │ │ ├── slider-l-1.png │ │ │ │ ├── slider-l-2.png │ │ │ │ ├── slider-l-3.png │ │ │ │ ├── slider-l-4.png │ │ │ │ └── slider-l-5.png │ │ │ └── home-three │ │ │ │ ├── slider-5.jpg │ │ │ │ ├── slider-6.jpg │ │ │ │ ├── slider-l-1.png │ │ │ │ ├── slider-l-2.png │ │ │ │ ├── slider-l-3.png │ │ │ │ ├── slider-l-4.png │ │ │ │ └── slider-l-5.png │ │ └── e-millennium_2015_-18.png │ ├── uploads │ │ ├── 19.jpg │ │ ├── 20.jpg │ │ ├── 21.jpg │ │ ├── 23.jpg │ │ ├── 24.jpg │ │ ├── 25.jpg │ │ ├── cart.jpg │ │ ├── p-1.jpg │ │ ├── p-2.jpg │ │ ├── p-3.jpg │ │ ├── p-4.jpg │ │ ├── p-5.jpg │ │ ├── cart-1.jpg │ │ ├── p-d-1.jpg │ │ ├── p-d-2.jpg │ │ ├── p-d-3.jpg │ │ ├── p-d-4.jpg │ │ ├── tab-1.jpg │ │ ├── tab-2.jpg │ │ ├── tab-3.jpg │ │ ├── tab-4.jpg │ │ ├── tab-5.jpg │ │ ├── fashion │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ ├── 7.jpg │ │ │ ├── 8.jpg │ │ │ ├── 9.jpg │ │ │ ├── 10.jpg │ │ │ ├── 11.jpg │ │ │ ├── 12.jpg │ │ │ ├── 13.jpg │ │ │ ├── 14.jpg │ │ │ └── 15.jpg │ │ ├── general │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ ├── 7.jpg │ │ │ ├── 8.jpg │ │ │ ├── 9.jpg │ │ │ ├── 10.jpg │ │ │ ├── 11.jpg │ │ │ ├── 12.jpg │ │ │ ├── 13.jpg │ │ │ ├── 14.jpg │ │ │ └── 15.jpg │ │ ├── sports │ │ │ ├── 1.jpg │ │ │ ├── 10.jpg │ │ │ ├── 11.jpg │ │ │ ├── 12.jpg │ │ │ ├── 13.jpg │ │ │ ├── 14.jpg │ │ │ ├── 15.jpg │ │ │ ├── 16.jpg │ │ │ ├── 17.jpg │ │ │ ├── 18.jpg │ │ │ ├── 19.jpg │ │ │ ├── 2.jpg │ │ │ ├── 20.jpg │ │ │ ├── 21.jpg │ │ │ ├── 22.jpg │ │ │ ├── 23.jpg │ │ │ ├── 24.jpg │ │ │ ├── 25.jpg │ │ │ ├── 26.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ ├── 7.jpg │ │ │ ├── 8.jpg │ │ │ └── 9.jpg │ │ ├── tab-p-1.jpg │ │ ├── tab-p-2.jpg │ │ ├── tab-p-3.jpg │ │ ├── tab-p-4.jpg │ │ ├── tab-p-5.jpg │ │ ├── tab-p-6.jpg │ │ ├── tab-p-7.jpg │ │ ├── tab-p-8.jpg │ │ ├── electronic │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ └── 5.jpg │ │ ├── 5H6rUxCQ8ZCE4KIBG2KW9v_Q.jpg │ │ ├── Hb4runtdiIeAXFuADsxDmbo7.jpg │ │ ├── jeWg1Duw6sOF20bdALUFMV4s.png │ │ ├── kwRihx6s0llwG9kyoPSMbGWZ.jpg │ │ ├── lbmPZHq_GqADBCpy3sJ5Bfm5.png │ │ └── nqmYs-mY_G6nLPPaGLUuKZGe.jpg │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ ├── fontawesome-webfont.woff2 │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── lib │ │ └── nivo-slider │ │ │ ├── img │ │ │ ├── arrows.png │ │ │ ├── bullets.png │ │ │ ├── loading.gif │ │ │ ├── arrows-2.png │ │ │ ├── bullets-2.png │ │ │ └── loading-2.gif │ │ │ └── home.js │ ├── js │ │ ├── plugins.js │ │ └── jquery.scrollUp.min.js │ └── css │ │ ├── owl.carousel.css │ │ └── owl.theme.css ├── android-icon-144x144.png ├── android-icon-192x192.png ├── apple-icon-precomposed.png ├── browserconfig.xml ├── .jshintrc └── manifest.json ├── .bowerrc ├── server ├── config │ └── environment │ │ ├── shared.js │ │ ├── development.js │ │ ├── test.js │ │ ├── production.js │ │ └── index.js ├── .jshintrc-spec ├── api │ ├── thing │ │ ├── thing.model.js │ │ ├── index.js │ │ ├── thing.events.js │ │ └── thing.socket.js │ ├── upload │ │ ├── upload.model.js │ │ ├── index.js │ │ ├── upload.events.js │ │ └── upload.socket.js │ ├── catalog │ │ ├── index.js │ │ ├── catalog.events.js │ │ ├── catalog.socket.js │ │ └── catalog.model.js │ ├── order │ │ ├── index.js │ │ ├── order.events.js │ │ ├── order.socket.js │ │ └── order.model.js │ ├── request │ │ ├── index.js │ │ ├── request.events.js │ │ ├── request.socket.js │ │ └── request.model.js │ ├── user │ │ ├── user.events.js │ │ ├── index.js │ │ ├── user.integration.js │ │ └── user.model.spec.js │ └── product │ │ ├── index.js │ │ ├── product.model.spec.js │ │ └── product.events.js ├── .jshintrc ├── index.js ├── components │ └── errors │ │ └── index.js ├── auth │ ├── twitter │ │ ├── index.js │ │ └── passport.js │ ├── facebook │ │ ├── index.js │ │ └── passport.js │ ├── google │ │ ├── index.js │ │ └── passport.js │ ├── local │ │ ├── index.js │ │ └── passport.js │ └── index.js ├── data │ ├── users.json │ └── reviews.json ├── routes.js └── app.js ├── .gitignore ├── .travis.yml ├── e2e ├── main │ ├── main.po.js │ └── main.spec.js ├── components │ ├── oauth-buttons │ │ └── oauth-buttons.po.js │ └── navbar │ │ └── navbar.po.js └── account │ ├── login │ └── login.po.js │ ├── signup │ └── signup.po.js │ └── logout │ └── logout.spec.js ├── mocha.conf.js ├── .editorconfig ├── bower.json ├── .gitattributes ├── README.md ├── .jscsrc └── .yo-rc.json /.buildignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/about/about.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/cart/cart.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/category/category.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/checkout/checkout.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/contact/contact.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/invoice/invoice.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/orders/orders.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/product/product.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/search/search.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/manage-products/manage-products.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/manage-requests/manage-requests.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/components/sidebar-cat/sidebar-cat.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/app/manage-categories/manage-categories.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/components/oauth-buttons/oauth-buttons.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /client/components/sidebar-account/sidebar-account.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "client/bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /client/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/favicon.ico -------------------------------------------------------------------------------- /client/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon.png -------------------------------------------------------------------------------- /client/components/util/util.module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp.util', []); 4 | -------------------------------------------------------------------------------- /client/app/about/about.html: -------------------------------------------------------------------------------- 1 | 2 |
This is the about view.
3 | -------------------------------------------------------------------------------- /client/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/favicon-16x16.png -------------------------------------------------------------------------------- /client/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/favicon-32x32.png -------------------------------------------------------------------------------- /client/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/favicon-96x96.png -------------------------------------------------------------------------------- /client/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/ms-icon-70x70.png -------------------------------------------------------------------------------- /client/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-57x57.png -------------------------------------------------------------------------------- /client/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-60x60.png -------------------------------------------------------------------------------- /client/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-72x72.png -------------------------------------------------------------------------------- /client/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-76x76.png -------------------------------------------------------------------------------- /client/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/ms-icon-144x144.png -------------------------------------------------------------------------------- /client/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/ms-icon-150x150.png -------------------------------------------------------------------------------- /client/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/ms-icon-310x310.png -------------------------------------------------------------------------------- /client/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/android-icon-36x36.png -------------------------------------------------------------------------------- /client/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/android-icon-48x48.png -------------------------------------------------------------------------------- /client/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/android-icon-72x72.png -------------------------------------------------------------------------------- /client/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/android-icon-96x96.png -------------------------------------------------------------------------------- /client/app/contact/contact.html: -------------------------------------------------------------------------------- 1 | 2 |
This is the contact view.
3 | 4 | -------------------------------------------------------------------------------- /client/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-114x114.png -------------------------------------------------------------------------------- /client/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-120x120.png -------------------------------------------------------------------------------- /client/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-144x144.png -------------------------------------------------------------------------------- /client/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-152x152.png -------------------------------------------------------------------------------- /client/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-180x180.png -------------------------------------------------------------------------------- /client/assets/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/favicon.ico -------------------------------------------------------------------------------- /client/assets/img/icon/bor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/bor.png -------------------------------------------------------------------------------- /client/assets/img/mega-b-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/mega-b-1.jpg -------------------------------------------------------------------------------- /client/assets/img/mega-b-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/mega-b-2.jpg -------------------------------------------------------------------------------- /client/assets/img/mega-b-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/mega-b-3.jpg -------------------------------------------------------------------------------- /client/assets/img/mega-b-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/mega-b-4.jpg -------------------------------------------------------------------------------- /client/assets/img/mega-b-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/mega-b-5.jpg -------------------------------------------------------------------------------- /client/assets/img/mega-b-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/mega-b-6.jpg -------------------------------------------------------------------------------- /client/assets/img/mega-b-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/mega-b-7.jpg -------------------------------------------------------------------------------- /client/assets/img/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/search.png -------------------------------------------------------------------------------- /client/assets/img/yeoman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/yeoman.png -------------------------------------------------------------------------------- /client/assets/uploads/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/19.jpg -------------------------------------------------------------------------------- /client/assets/uploads/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/20.jpg -------------------------------------------------------------------------------- /client/assets/uploads/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/21.jpg -------------------------------------------------------------------------------- /client/assets/uploads/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/23.jpg -------------------------------------------------------------------------------- /client/assets/uploads/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/24.jpg -------------------------------------------------------------------------------- /client/assets/uploads/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/25.jpg -------------------------------------------------------------------------------- /client/assets/uploads/cart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/cart.jpg -------------------------------------------------------------------------------- /client/assets/uploads/p-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/p-1.jpg -------------------------------------------------------------------------------- /client/assets/uploads/p-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/p-2.jpg -------------------------------------------------------------------------------- /client/assets/uploads/p-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/p-3.jpg -------------------------------------------------------------------------------- /client/assets/uploads/p-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/p-4.jpg -------------------------------------------------------------------------------- /client/assets/uploads/p-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/p-5.jpg -------------------------------------------------------------------------------- /client/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/android-icon-144x144.png -------------------------------------------------------------------------------- /client/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/android-icon-192x192.png -------------------------------------------------------------------------------- /client/assets/img/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/logo/logo.png -------------------------------------------------------------------------------- /client/assets/img/map-marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/map-marker.png -------------------------------------------------------------------------------- /client/assets/img/not-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/not-found.png -------------------------------------------------------------------------------- /client/assets/uploads/cart-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/cart-1.jpg -------------------------------------------------------------------------------- /client/assets/uploads/p-d-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/p-d-1.jpg -------------------------------------------------------------------------------- /client/assets/uploads/p-d-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/p-d-2.jpg -------------------------------------------------------------------------------- /client/assets/uploads/p-d-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/p-d-3.jpg -------------------------------------------------------------------------------- /client/assets/uploads/p-d-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/p-d-4.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-1.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-2.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-3.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-4.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-5.jpg -------------------------------------------------------------------------------- /client/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/apple-icon-precomposed.png -------------------------------------------------------------------------------- /client/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /client/assets/img/about/about.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/about/about.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/blog-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/blog-1.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/blog-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/blog-2.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/blog-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/blog-3.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/blog-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/blog-4.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/blog-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/blog-5.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/blog-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/blog-6.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/blog-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/blog-7.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/blog-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/blog-8.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-1.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-10.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-11.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-12.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-13.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-14.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-15.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-16.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-17.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-2.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-3.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-4.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-5.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-6.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-7.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-8.jpg -------------------------------------------------------------------------------- /client/assets/img/blog/news-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/blog/news-9.jpg -------------------------------------------------------------------------------- /client/assets/img/brand/brand-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/brand/brand-1.png -------------------------------------------------------------------------------- /client/assets/img/brand/brand-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/brand/brand-2.png -------------------------------------------------------------------------------- /client/assets/img/brand/brand-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/brand/brand-3.png -------------------------------------------------------------------------------- /client/assets/img/brand/brand-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/brand/brand-4.png -------------------------------------------------------------------------------- /client/assets/img/icon/cart-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/cart-bg.jpg -------------------------------------------------------------------------------- /client/assets/img/logo/logo-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/logo/logo-2.png -------------------------------------------------------------------------------- /client/assets/img/logo/logo-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/logo/logo-3.png -------------------------------------------------------------------------------- /client/assets/img/logo/logo-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/logo/logo-4.png -------------------------------------------------------------------------------- /client/assets/img/logo/logo-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/logo/logo-5.png -------------------------------------------------------------------------------- /client/assets/img/search-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/search-hover.png -------------------------------------------------------------------------------- /client/assets/img/testimonial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/testimonial.png -------------------------------------------------------------------------------- /client/assets/uploads/fashion/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/1.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/2.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/3.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/4.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/5.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/6.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/7.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/8.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/9.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/1.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/2.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/3.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/4.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/5.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/6.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/7.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/8.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/9.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/1.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/10.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/11.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/12.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/13.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/14.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/15.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/16.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/17.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/18.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/19.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/2.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/20.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/21.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/22.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/23.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/24.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/25.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/26.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/3.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/4.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/5.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/6.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/7.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/8.jpg -------------------------------------------------------------------------------- /client/assets/uploads/sports/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/sports/9.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-p-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-p-1.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-p-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-p-2.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-p-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-p-3.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-p-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-p-4.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-p-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-p-5.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-p-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-p-6.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-p-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-p-7.jpg -------------------------------------------------------------------------------- /client/assets/uploads/tab-p-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/tab-p-8.jpg -------------------------------------------------------------------------------- /client/assets/img/about/ab-team1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/about/ab-team1.jpg -------------------------------------------------------------------------------- /client/assets/img/about/ab-team2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/about/ab-team2.jpg -------------------------------------------------------------------------------- /client/assets/img/about/ab-team3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/about/ab-team3.jpg -------------------------------------------------------------------------------- /client/assets/img/about/ab-team4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/about/ab-team4.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-1.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-2.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-3.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-4.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-5.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-6.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-7.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-8.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-9.jpg -------------------------------------------------------------------------------- /client/assets/img/discount-border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/discount-border.png -------------------------------------------------------------------------------- /client/assets/img/icon/arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/arrow-down.png -------------------------------------------------------------------------------- /client/assets/img/icon/grid-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/grid-view.png -------------------------------------------------------------------------------- /client/assets/img/icon/list-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/list-view.png -------------------------------------------------------------------------------- /client/assets/img/icon/slider-l-i.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/slider-l-i.png -------------------------------------------------------------------------------- /client/assets/img/icon/slider-r-i.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/slider-r-i.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-1.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/slider-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-2.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/slider-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-3.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/10.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/11.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/12.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/13.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/14.jpg -------------------------------------------------------------------------------- /client/assets/uploads/fashion/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/fashion/15.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/10.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/11.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/12.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/13.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/14.jpg -------------------------------------------------------------------------------- /client/assets/uploads/general/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/general/15.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-10.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-11.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-12.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-13.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-14.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-15.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-16.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-17.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-18.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-19.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-20.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-21.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-22.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-23.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-24.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-25.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-26.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-27.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-28.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-29.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-30.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-31.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-32.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-33.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-34.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-35.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-36.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-37.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-38.jpg -------------------------------------------------------------------------------- /client/assets/img/banner/banner-39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/banner/banner-39.jpg -------------------------------------------------------------------------------- /client/assets/img/icon/p-details-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/p-details-1.jpg -------------------------------------------------------------------------------- /client/assets/img/icon/p-details-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/p-details-2.jpg -------------------------------------------------------------------------------- /client/assets/img/icon/slider-l-i-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/slider-l-i-3.png -------------------------------------------------------------------------------- /client/assets/img/icon/slider-l-i-h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/slider-l-i-h.png -------------------------------------------------------------------------------- /client/assets/img/icon/slider-r-i-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/slider-r-i-3.png -------------------------------------------------------------------------------- /client/assets/img/icon/slider-r-i-h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/slider-r-i-h.png -------------------------------------------------------------------------------- /client/assets/img/logo/footer-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/logo/footer-logo.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-1.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-10.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-2.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-3.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-4.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-5.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-6.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-7.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-8.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-9.png -------------------------------------------------------------------------------- /client/assets/uploads/electronic/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/electronic/1.jpg -------------------------------------------------------------------------------- /client/assets/uploads/electronic/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/electronic/2.jpg -------------------------------------------------------------------------------- /client/assets/uploads/electronic/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/electronic/3.jpg -------------------------------------------------------------------------------- /client/assets/uploads/electronic/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/electronic/4.jpg -------------------------------------------------------------------------------- /client/assets/uploads/electronic/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/electronic/5.jpg -------------------------------------------------------------------------------- /client/assets/img/icon/grid-view-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/grid-view-hover.png -------------------------------------------------------------------------------- /client/assets/img/icon/list-view-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/list-view-hover.png -------------------------------------------------------------------------------- /client/assets/img/icon/slider-l-i-h-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/slider-l-i-h-3.png -------------------------------------------------------------------------------- /client/assets/img/icon/slider-r-i-h-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/icon/slider-r-i-h-3.png -------------------------------------------------------------------------------- /client/assets/img/slider/slider-l-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/slider-l-logo.png -------------------------------------------------------------------------------- /client/app/admin/admin.module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp.admin', [ 4 | 'bhcmartApp.auth', 5 | 'ui.router' 6 | ]); 7 | -------------------------------------------------------------------------------- /client/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /client/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /client/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /client/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /client/assets/img/e-millennium_2015_-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/e-millennium_2015_-18.png -------------------------------------------------------------------------------- /client/assets/lib/nivo-slider/img/arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/lib/nivo-slider/img/arrows.png -------------------------------------------------------------------------------- /client/assets/lib/nivo-slider/img/bullets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/lib/nivo-slider/img/bullets.png -------------------------------------------------------------------------------- /client/assets/lib/nivo-slider/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/lib/nivo-slider/img/loading.gif -------------------------------------------------------------------------------- /client/assets/img/slider/home-five/slider-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-five/slider-9.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-7.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-8.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/home-two/slider-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-two/slider-3.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/home-two/slider-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-two/slider-4.jpg -------------------------------------------------------------------------------- /client/assets/lib/nivo-slider/img/arrows-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/lib/nivo-slider/img/arrows-2.png -------------------------------------------------------------------------------- /client/assets/lib/nivo-slider/img/bullets-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/lib/nivo-slider/img/bullets-2.png -------------------------------------------------------------------------------- /client/assets/lib/nivo-slider/img/loading-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/lib/nivo-slider/img/loading-2.gif -------------------------------------------------------------------------------- /client/assets/img/slider/home-five/slider-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-five/slider-10.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-10.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-1.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-10.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-11.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-2.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-3.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-4.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-5.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-6.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-7.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-8.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-four/slider-l-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-four/slider-l-9.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-three/slider-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-three/slider-5.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/home-three/slider-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-three/slider-6.jpg -------------------------------------------------------------------------------- /client/assets/img/slider/home-three/slider-l-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-three/slider-l-1.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-three/slider-l-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-three/slider-l-2.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-three/slider-l-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-three/slider-l-3.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-three/slider-l-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-three/slider-l-4.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-three/slider-l-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-three/slider-l-5.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-two/slider-l-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-two/slider-l-1.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-two/slider-l-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-two/slider-l-2.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-two/slider-l-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-two/slider-l-3.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-two/slider-l-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-two/slider-l-4.png -------------------------------------------------------------------------------- /client/assets/img/slider/home-two/slider-l-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/img/slider/home-two/slider-l-5.png -------------------------------------------------------------------------------- /client/assets/uploads/5H6rUxCQ8ZCE4KIBG2KW9v_Q.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/5H6rUxCQ8ZCE4KIBG2KW9v_Q.jpg -------------------------------------------------------------------------------- /client/assets/uploads/Hb4runtdiIeAXFuADsxDmbo7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/Hb4runtdiIeAXFuADsxDmbo7.jpg -------------------------------------------------------------------------------- /client/assets/uploads/jeWg1Duw6sOF20bdALUFMV4s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/jeWg1Duw6sOF20bdALUFMV4s.png -------------------------------------------------------------------------------- /client/assets/uploads/kwRihx6s0llwG9kyoPSMbGWZ.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/kwRihx6s0llwG9kyoPSMbGWZ.jpg -------------------------------------------------------------------------------- /client/assets/uploads/lbmPZHq_GqADBCpy3sJ5Bfm5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/lbmPZHq_GqADBCpy3sJ5Bfm5.png -------------------------------------------------------------------------------- /client/assets/uploads/nqmYs-mY_G6nLPPaGLUuKZGe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/uploads/nqmYs-mY_G6nLPPaGLUuKZGe.jpg -------------------------------------------------------------------------------- /client/assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /client/assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /client/assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /client/assets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chitezh/mean-ecommerce/HEAD/client/assets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /server/config/environment/shared.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports = module.exports = { 4 | // List of user roles 5 | userRoles: ['guest', 'user', 'admin'] 6 | }; 7 | -------------------------------------------------------------------------------- /client/components/footer/footer.scss: -------------------------------------------------------------------------------- 1 | footer.footer { 2 | text-align: center; 3 | padding: 30px 0; 4 | /* margin-top: 70px; 5 | border-top: 1px solid #E5E5E5;*/ 6 | } 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | public 3 | .tmp 4 | .sass-cache 5 | .idea 6 | client/bower_components 7 | dist 8 | /server/config/local.env.js 9 | npm-debug.log 10 | *..DS_Store 11 | -------------------------------------------------------------------------------- /client/app/about/about.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('AboutCtrl', function ($scope) { 5 | $scope.message = 'Hello'; 6 | }); 7 | -------------------------------------------------------------------------------- /client/app/contact/contact.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('ContactCtrl', function ($scope) { 5 | $scope.message = 'Hello'; 6 | }); 7 | -------------------------------------------------------------------------------- /client/app/app.constant.js: -------------------------------------------------------------------------------- 1 | (function(angular, undefined) { 2 | 'use strict'; 3 | 4 | angular.module('bhcmartApp.constants', []) 5 | 6 | .constant('appConfig', {userRoles:['guest','user','admin']}) 7 | 8 | ; 9 | })(angular); -------------------------------------------------------------------------------- /client/app/cart/cart.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('CartCtrl', function($scope, Modal, ngCart) { 5 | $scope.clearCart = Modal.confirm.delete(function() { 6 | ngCart.empty() 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /client/app/invoice/invoice.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('InvoiceCtrl', ['$scope', 'Order', '$stateParams', function($scope, Order, $stateParams) { 5 | $scope.invoice = Order.get({ id: $stateParams.id }); 6 | }]); 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 4.2.3 4 | matrix: 5 | fast_finish: true 6 | allow_failures: 7 | - node_js: 5.1.1 8 | before_script: 9 | - npm install -g bower grunt-cli 10 | - gem install sass 11 | - bower install 12 | services: mongodb 13 | -------------------------------------------------------------------------------- /client/components/oauth-buttons/oauth-buttons.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('OauthButtonsCtrl', function($window) { 5 | this.loginOauth = function(provider) { 6 | $window.location.href = '/auth/' + provider; 7 | }; 8 | }); 9 | -------------------------------------------------------------------------------- /client/components/navbar/navbar.directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .directive('navbar', () => ({ 5 | templateUrl: 'components/navbar/navbar.html', 6 | restrict: 'E', 7 | controller: 'NavbarController', 8 | controllerAs: 'nav' 9 | })); 10 | -------------------------------------------------------------------------------- /client/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /client/app/cart/cart.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function ($stateProvider) { 5 | $stateProvider 6 | .state('cart', { 7 | url: '/cart', 8 | templateUrl: 'app/cart/cart.html', 9 | controller: 'CartCtrl' 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /client/app/about/about.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function ($stateProvider) { 5 | $stateProvider 6 | .state('about', { 7 | url: '/about', 8 | templateUrl: 'app/about/about.html', 9 | controller: 'AboutCtrl' 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /client/components/auth/auth.module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp.auth', [ 4 | 'bhcmartApp.constants', 5 | 'bhcmartApp.util', 6 | 'ngCookies', 7 | 'ui.router' 8 | ]) 9 | .config(function($httpProvider) { 10 | $httpProvider.interceptors.push('authInterceptor'); 11 | }); 12 | -------------------------------------------------------------------------------- /server/.jshintrc-spec: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ".jshintrc", 3 | "globals": { 4 | "describe": true, 5 | "it": true, 6 | "before": true, 7 | "beforeEach": true, 8 | "after": true, 9 | "afterEach": true, 10 | "expect": true, 11 | "assert": true, 12 | "sinon": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /server/api/thing/thing.model.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('bluebird').promisifyAll(require('mongoose')); 4 | 5 | var ThingSchema = new mongoose.Schema({ 6 | name: String, 7 | info: String, 8 | active: Boolean 9 | }); 10 | 11 | export default mongoose.model('Thing', ThingSchema); 12 | -------------------------------------------------------------------------------- /client/app/search/search.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('SearchCtrl', ['$scope', '$stateParams', 'products', function($scope, $stateParams, products) { 5 | 6 | $scope.products = products; 7 | console.log($stateParams.category, $stateParams.term); 8 | }]); 9 | -------------------------------------------------------------------------------- /server/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "expr": true, 3 | "node": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "eqeqeq": true, 7 | "immed": true, 8 | "latedef": "nofunc", 9 | "newcap": true, 10 | "noarg": true, 11 | "undef": true, 12 | "smarttabs": true, 13 | "asi": true, 14 | "debug": true 15 | } 16 | -------------------------------------------------------------------------------- /client/app/contact/contact.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function ($stateProvider) { 5 | $stateProvider 6 | .state('contact', { 7 | url: '/contact', 8 | templateUrl: 'app/contact/contact.html', 9 | controller: 'ContactCtrl' 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /client/app/checkout/checkout.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function ($stateProvider) { 5 | $stateProvider 6 | .state('checkout', { 7 | url: '/checkout', 8 | templateUrl: 'app/checkout/checkout.html', 9 | controller: 'CheckoutCtrl' 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /client/app/product/product.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('product', { 7 | url: '/product/{id}', 8 | templateUrl: 'app/product/product.html', 9 | controller: 'ProductCtrl' 10 | }) 11 | }); 12 | -------------------------------------------------------------------------------- /client/components/sidebar-account/sidebar-account.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('SidebarAccountCtrl', ['$scope', 'Auth', 5 | function($scope, Auth) { 6 | $scope.isAdmin = Auth.hasRole('admin'); 7 | $scope.isLoggedIn = Auth.isLoggedIn(); 8 | } 9 | ]); 10 | -------------------------------------------------------------------------------- /client/app/category/category.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('products', { 7 | url: '/category/{slug}', 8 | templateUrl: 'app/category/category.html', 9 | controller: 'CategoryCtrl' 10 | }) 11 | }); 12 | -------------------------------------------------------------------------------- /server/api/upload/upload.model.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('bluebird').promisifyAll(require('mongoose')); 4 | import { Schema } from 'mongoose'; 5 | 6 | var UploadSchema = new mongoose.Schema({ 7 | url: String, 8 | active: Boolean 9 | }); 10 | 11 | export default mongoose.model('Upload', UploadSchema); 12 | -------------------------------------------------------------------------------- /client/app/main/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('main', { 7 | url: '/', 8 | templateUrl: 'app/main/main.html', 9 | controller: 'MainController', 10 | controllerAs: 'main' 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /client/app/orders/orders.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function ($stateProvider) { 5 | $stateProvider 6 | .state('orders', { 7 | url: '/orders', 8 | templateUrl: 'app/orders/orders.html', 9 | controller: 'OrdersCtrl', 10 | authenticate: true 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /client/components/footer/footer.directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .directive('footer', function () { 5 | return { 6 | templateUrl: 'components/footer/footer.html', 7 | restrict: 'E', 8 | link: function(scope, element) { 9 | element.addClass('footer'); 10 | } 11 | }; 12 | }); 13 | -------------------------------------------------------------------------------- /server/config/environment/development.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Development specific configuration 4 | // ================================== 5 | module.exports = { 6 | 7 | // MongoDB connection options 8 | mongo: { 9 | uri: 'mongodb://localhost/bhcmart-dev' 10 | }, 11 | 12 | // Seed database on startup 13 | seedDB: true 14 | 15 | }; 16 | -------------------------------------------------------------------------------- /client/components/navbar/navbar.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /client/components/sidebar-cat/sidebar-cat.directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .directive('sidebarCat', function() { 5 | return { 6 | templateUrl: 'components/sidebar-cat/sidebar-cat.html', 7 | restrict: 'EA', 8 | controller: 'SidebarCatCtrl', 9 | link: function(scope, element, attrs) {} 10 | }; 11 | }); 12 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Set default node environment to development 4 | var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development'; 5 | 6 | if (env === 'development' || env === 'test') { 7 | // Register the Babel require hook 8 | require('babel-core/register'); 9 | } 10 | 11 | // Export the application 12 | exports = module.exports = require('./app'); 13 | -------------------------------------------------------------------------------- /client/app/admin/admin.router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp.admin') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('admin', { 7 | url: '/admin', 8 | templateUrl: 'app/admin/admin.html', 9 | controller: 'AdminController', 10 | controllerAs: 'admin', 11 | authenticate: 'admin' 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /client/components/sidebar-account/sidebar-account.directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .directive('sidebarAccount', function () { 5 | return { 6 | templateUrl: 'components/sidebar-account/sidebar-account.html', 7 | controller: 'SidebarAccountCtrl', 8 | restrict: 'EA', 9 | link: function (scope, element, attrs) { 10 | } 11 | }; 12 | }); 13 | -------------------------------------------------------------------------------- /client/app/admin/admin.scss: -------------------------------------------------------------------------------- 1 | .trash { color:rgb(209, 91, 71); } 2 | 3 | .user-list { 4 | li { 5 | display: flex; 6 | border: none; 7 | border-bottom: 1px lightgray solid; 8 | margin-bottom: 0; 9 | &:last-child { border-bottom: none; } 10 | 11 | .user-info { 12 | flex-grow: 1; 13 | } 14 | .trash { 15 | display: flex; 16 | align-items: center; 17 | text-decoration: none; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /client/components/socket/socket.mock.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('socketMock', []) 4 | .factory('socket', function() { 5 | return { 6 | socket: { 7 | connect: function() {}, 8 | on: function() {}, 9 | emit: function() {}, 10 | receive: function() {} 11 | }, 12 | 13 | syncUpdates: function() {}, 14 | unsyncUpdates: function() {} 15 | }; 16 | }); 17 | -------------------------------------------------------------------------------- /client/components/oauth-buttons/oauth-buttons.directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .directive('oauthButtons', function() { 5 | return { 6 | templateUrl: 'components/oauth-buttons/oauth-buttons.html', 7 | restrict: 'EA', 8 | controller: 'OauthButtonsCtrl', 9 | controllerAs: 'OauthButtons', 10 | scope: { 11 | classes: '@' 12 | } 13 | }; 14 | }); 15 | -------------------------------------------------------------------------------- /client/components/order/order.service.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Service: order', function () { 4 | 5 | // load the service's module 6 | beforeEach(module('sourceApp')); 7 | 8 | // instantiate service 9 | var order; 10 | beforeEach(inject(function (_order_) { 11 | order = _order_; 12 | })); 13 | 14 | it('should do something', function () { 15 | expect(!!order).to.be.true; 16 | }); 17 | 18 | }); 19 | -------------------------------------------------------------------------------- /client/components/product/product.service.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Service: catolog', function () { 4 | 5 | // load the service's module 6 | beforeEach(module('sourceApp')); 7 | 8 | // instantiate service 9 | var catolog; 10 | beforeEach(inject(function (_catolog_) { 11 | catolog = _catolog_; 12 | })); 13 | 14 | it('should do something', function () { 15 | expect(!!catolog).to.be.true; 16 | }); 17 | 18 | }); 19 | -------------------------------------------------------------------------------- /client/components/request/request.service.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Service: request', function () { 4 | 5 | // load the service's module 6 | beforeEach(module('sourceApp')); 7 | 8 | // instantiate service 9 | var request; 10 | beforeEach(inject(function (_request_) { 11 | request = _request_; 12 | })); 13 | 14 | it('should do something', function () { 15 | expect(!!request).to.be.true; 16 | }); 17 | 18 | }); 19 | -------------------------------------------------------------------------------- /client/components/order/order.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .factory('Order', function($resource) { 5 | return $resource('/api/orders/:id/:controller', { 6 | id: '@_id' 7 | }, { 8 | 'update': { method: 'PUT' }, 9 | 'myOrders': { 10 | method: 'GET', 11 | isArray: true, 12 | params: { 13 | controller: 'myorders' 14 | } 15 | } 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /client/components/request/request.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .factory('Request', function($resource) { 5 | return $resource('/api/requests/:id/:controller', { 6 | id: '@_id' 7 | }, { 8 | 'update': { method: 'PUT' }, 9 | 'myRequests': { 10 | method: 'GET', 11 | isArray: true, 12 | params: { 13 | controller: 'myrequests' 14 | } 15 | } 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /client/components/mongoose-error/mongoose-error.directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Removes server error when user updates input 5 | */ 6 | angular.module('bhcmartApp') 7 | .directive('mongooseError', function() { 8 | return { 9 | restrict: 'A', 10 | require: 'ngModel', 11 | link: function(scope, element, attrs, ngModel) { 12 | element.on('keydown', () => ngModel.$setValidity('mongoose', true)); 13 | } 14 | }; 15 | }); 16 | -------------------------------------------------------------------------------- /server/api/thing/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'); 4 | var controller = require('./thing.controller'); 5 | 6 | var router = express.Router(); 7 | 8 | router.get('/', controller.index); 9 | router.get('/:id', controller.show); 10 | router.post('/', controller.create); 11 | router.put('/:id', controller.update); 12 | router.patch('/:id', controller.update); 13 | router.delete('/:id', controller.destroy); 14 | 15 | module.exports = router; 16 | -------------------------------------------------------------------------------- /server/config/environment/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Test specific configuration 4 | // =========================== 5 | module.exports = { 6 | // MongoDB connection options 7 | mongo: { 8 | uri: 'mongodb://localhost/bhcmart-test' 9 | }, 10 | sequelize: { 11 | uri: 'sqlite://', 12 | options: { 13 | logging: false, 14 | storage: 'test.sqlite', 15 | define: { 16 | timestamps: false 17 | } 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /e2e/main/main.po.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file uses the Page Object pattern to define the main page for tests 3 | * https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var MainPage = function() { 9 | this.heroEl = element(by.css('.hero-unit')); 10 | this.h1El = this.heroEl.element(by.css('h1')); 11 | this.imgEl = this.heroEl.element(by.css('img')); 12 | }; 13 | 14 | module.exports = new MainPage(); 15 | 16 | -------------------------------------------------------------------------------- /server/api/catalog/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'); 4 | var controller = require('./catalog.controller'); 5 | 6 | var router = express.Router(); 7 | 8 | router.get('/', controller.index); 9 | router.get('/:slug', controller.show); 10 | router.post('/', controller.create); 11 | router.put('/:id', controller.update); 12 | router.patch('/:id', controller.update); 13 | router.delete('/:id', controller.destroy); 14 | 15 | module.exports = router; 16 | -------------------------------------------------------------------------------- /mocha.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Register the Babel require hook 4 | require('babel-core/register'); 5 | 6 | var chai = require('chai'); 7 | 8 | // Load Chai assertions 9 | global.expect = chai.expect; 10 | global.assert = chai.assert; 11 | chai.should(); 12 | 13 | // Load Sinon 14 | global.sinon = require('sinon'); 15 | 16 | // Initialize Chai plugins 17 | chai.use(require('sinon-chai')); 18 | chai.use(require('chai-as-promised')); 19 | chai.use(require('chai-things')) 20 | -------------------------------------------------------------------------------- /server/components/errors/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Error responses 3 | */ 4 | 5 | 'use strict'; 6 | 7 | module.exports[404] = function pageNotFound(req, res) { 8 | var viewFilePath = '404'; 9 | var statusCode = 404; 10 | var result = { 11 | status: statusCode 12 | }; 13 | 14 | res.status(result.status); 15 | res.render(viewFilePath, {}, function(err, html) { 16 | if (err) { 17 | return res.json(result, result.status); 18 | } 19 | 20 | res.send(html); 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /client/app/invoice/invoice.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('invoice', { 7 | url: '/invoice/{id}', 8 | templateUrl: 'app/invoice/invoice.html', 9 | controller: 'InvoiceCtrl' 10 | }) 11 | .state('invoiceprint', { 12 | url: '/invoice/{id}/print', 13 | templateUrl: 'app/invoice/invoice-print.html', 14 | controller: 'InvoiceCtrl' 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /server/api/order/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'); 4 | var controller = require('./order.controller'); 5 | 6 | var router = express.Router(); 7 | 8 | router.get('/', controller.index); 9 | router.get('/:id', controller.show); 10 | router.get('/:id/myorders', controller.myOrders); 11 | router.post('/', controller.create); 12 | router.put('/:id', controller.update); 13 | router.patch('/:id', controller.update); 14 | router.delete('/:id', controller.destroy); 15 | 16 | module.exports = router; 17 | -------------------------------------------------------------------------------- /server/auth/twitter/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import express from 'express'; 4 | import passport from 'passport'; 5 | import {setTokenCookie} from '../auth.service'; 6 | 7 | var router = express.Router(); 8 | 9 | router 10 | .get('/', passport.authenticate('twitter', { 11 | failureRedirect: '/signup', 12 | session: false 13 | })) 14 | .get('/callback', passport.authenticate('twitter', { 15 | failureRedirect: '/signup', 16 | session: false 17 | }), setTokenCookie); 18 | 19 | export default router; 20 | -------------------------------------------------------------------------------- /server/api/request/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'); 4 | var controller = require('./request.controller'); 5 | 6 | var router = express.Router(); 7 | 8 | router.get('/', controller.index); 9 | router.get('/:id', controller.show); 10 | router.get('/:id/myrequests', controller.myRequests); 11 | router.post('/', controller.create); 12 | router.put('/:id', controller.update); 13 | router.patch('/:id', controller.update); 14 | router.delete('/:id', controller.destroy); 15 | 16 | module.exports = router; 17 | -------------------------------------------------------------------------------- /client/app/cart/cart.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: CartCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var CartCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | CartCtrl = $controller('CartCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/about/about.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: AboutCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var AboutCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | AboutCtrl = $controller('AboutCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/orders/orders.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: OrdersCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var OrdersCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | OrdersCtrl = $controller('OrdersCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/search/search.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: SearchCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var SearchCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | SearchCtrl = $controller('SearchCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /server/auth/facebook/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import express from 'express'; 4 | import passport from 'passport'; 5 | import {setTokenCookie} from '../auth.service'; 6 | 7 | var router = express.Router(); 8 | 9 | router 10 | .get('/', passport.authenticate('facebook', { 11 | scope: ['email', 'user_about_me'], 12 | failureRedirect: '/signup', 13 | session: false 14 | })) 15 | .get('/callback', passport.authenticate('facebook', { 16 | failureRedirect: '/signup', 17 | session: false 18 | }), setTokenCookie); 19 | 20 | export default router; 21 | -------------------------------------------------------------------------------- /client/app/contact/contact.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: ContactCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var ContactCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | ContactCtrl = $controller('ContactCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/invoice/invoice.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: InvoiceCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var InvoiceCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | InvoiceCtrl = $controller('InvoiceCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/product/product.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: ProductCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var ProductCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | ProductCtrl = $controller('ProductCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/category/category.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: CategoryCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var CategoryCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | CategoryCtrl = $controller('CategoryCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/checkout/checkout.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: CheckoutCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var CheckoutCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | CheckoutCtrl = $controller('CheckoutCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/components/oauth-buttons/oauth-buttons.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Connect with Facebook 4 | 5 | 6 | 7 | Connect with Google+ 8 | 9 | 10 | 11 | Connect with Twitter 12 | 13 | -------------------------------------------------------------------------------- /client/components/modal/modal.scss: -------------------------------------------------------------------------------- 1 | .modal-primary, 2 | .modal-info, 3 | .modal-success, 4 | .modal-warning, 5 | .modal-danger { 6 | .modal-header { 7 | color: #fff; 8 | border-radius: 5px 5px 0 0; 9 | } 10 | } 11 | .modal-primary .modal-header { 12 | background: $brand-primary; 13 | } 14 | .modal-info .modal-header { 15 | background: $brand-info; 16 | } 17 | .modal-success .modal-header { 18 | background: $brand-success; 19 | } 20 | .modal-warning .modal-header { 21 | background: $brand-warning; 22 | } 23 | .modal-danger .modal-header { 24 | background: $brand-danger; 25 | } 26 | -------------------------------------------------------------------------------- /server/auth/google/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import express from 'express'; 4 | import passport from 'passport'; 5 | import {setTokenCookie} from '../auth.service'; 6 | 7 | var router = express.Router(); 8 | 9 | router 10 | .get('/', passport.authenticate('google', { 11 | failureRedirect: '/signup', 12 | scope: [ 13 | 'profile', 14 | 'email' 15 | ], 16 | session: false 17 | })) 18 | .get('/callback', passport.authenticate('google', { 19 | failureRedirect: '/signup', 20 | session: false 21 | }), setTokenCookie); 22 | 23 | export default router; 24 | -------------------------------------------------------------------------------- /server/data/users.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "_id": "56f6acdede63e20f988a88dc", 3 | "provider": "local", 4 | "name": "Test User", 5 | "email": "test@example.com", 6 | "password": "123456", 7 | "categories": [], 8 | "role": "user" 9 | }, { 10 | "_id": "56f6acdede63e20f988a88dd", 11 | "provider": "local", 12 | "name": "Admin", 13 | "email": "admin@bhcmart.com", 14 | "password": "123456", 15 | "categories": [], 16 | "role": "admin", 17 | "address": "No 4 Achival street, Lagoon", 18 | "city": "PH", 19 | "state": "Imo", 20 | "country": "NG", 21 | "phone": "08064949432" 22 | }] 23 | -------------------------------------------------------------------------------- /client/components/auth/user.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | (function() { 4 | 5 | function UserResource($resource) { 6 | return $resource('/api/users/:id/:controller', { 7 | id: '@_id' 8 | }, { 9 | changePassword: { 10 | method: 'PUT', 11 | params: { 12 | controller: 'password' 13 | } 14 | }, 15 | get: { 16 | method: 'GET', 17 | params: { 18 | id: 'me' 19 | } 20 | } 21 | }); 22 | } 23 | 24 | angular.module('bhcmartApp.auth') 25 | .factory('User', UserResource); 26 | 27 | })(); 28 | -------------------------------------------------------------------------------- /client/components/modal/modal.html: -------------------------------------------------------------------------------- 1 | 5 | 9 | 12 | -------------------------------------------------------------------------------- /client/components/sidebar-cat/sidebar-cat.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: SidebarCatCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var SidebarCatCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | SidebarCatCtrl = $controller('SidebarCatCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/search/search.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('search', { 7 | url: '/search?category&term', 8 | templateUrl: 'app/search/search.html', 9 | controller: 'SearchCtrl', 10 | resolve: { 11 | products: ['Product', '$stateParams', function(Product, $stateParams) { 12 | return Product.search({ 13 | limit: $stateParams.term, 14 | id: $stateParams.category 15 | }); 16 | }] 17 | } 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /client/app/manage-products/manage-products.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: ManageProductsCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var ManageProductsCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | ManageProductsCtrl = $controller('ManageProductsCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/manage-requests/manage-requests.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: ManageRequestsCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var ManageRequestsCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | ManageRequestsCtrl = $controller('ManageRequestsCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/main/main.scss: -------------------------------------------------------------------------------- 1 | .thing-form { 2 | margin: 20px 0; 3 | } 4 | 5 | #banner { 6 | border-bottom: none; 7 | margin-top: -20px; 8 | } 9 | 10 | #banner h1 { 11 | font-size: 60px; 12 | line-height: 1; 13 | letter-spacing: -1px; 14 | } 15 | 16 | .hero-unit { 17 | position: relative; 18 | padding: 30px 15px; 19 | color: #F5F5F5; 20 | text-align: center; 21 | text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); 22 | background: #4393B9; 23 | } 24 | 25 | .navbar-text { 26 | margin-left: 15px; 27 | } 28 | 29 | a { 30 | color: -webkit-link; 31 | text-decoration: underline; 32 | cursor: auto !important; 33 | } 34 | -------------------------------------------------------------------------------- /e2e/main/main.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = browser.params; 4 | 5 | describe('Main View', function() { 6 | var page; 7 | 8 | beforeEach(function() { 9 | let promise = browser.get(config.baseUrl + '/'); 10 | page = require('./main.po'); 11 | return promise; 12 | }); 13 | 14 | it('should include jumbotron with correct data', function() { 15 | expect(page.h1El.getText()).to.eventually.equal('\'Allo, \'Allo!'); 16 | expect(page.imgEl.getAttribute('src')).to.eventually.match(/yeoman.png$/); 17 | expect(page.imgEl.getAttribute('alt')).to.eventually.equal('I\'m Yeoman'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /client/components/sidebar-account/sidebar-account.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: SidebarAccountCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var SidebarAccountCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | SidebarAccountCtrl = $controller('SidebarAccountCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/manage-categories/manage-categories.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: ManageCategoriesCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var ManageCategoriesCtrl, scope; 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function ($controller, $rootScope) { 12 | scope = $rootScope.$new(); 13 | ManageCategoriesCtrl = $controller('ManageCategoriesCtrl', { 14 | $scope: scope 15 | }); 16 | })); 17 | 18 | it('should ...', function () { 19 | expect(1).to.equal(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /server/api/upload/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'); 4 | var controller = require('./upload.controller'); 5 | var multiparty = require('connect-multiparty'); 6 | var uploadOptions = { 7 | autoFile: true, 8 | uploadDir: 'client/assets/uploads/' 9 | } 10 | var router = express.Router(); 11 | 12 | router.get('/', controller.index); 13 | router.get('/:id', controller.show); 14 | router.post('/', multiparty(uploadOptions), controller.create); 15 | router.put('/:id', multiparty(uploadOptions), controller.update); 16 | router.patch('/:id', controller.update); 17 | router.delete('/:id', controller.destroy); 18 | 19 | module.exports = router; 20 | -------------------------------------------------------------------------------- /client/components/oauth-buttons/oauth-buttons.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: OauthButtonsCtrl', function() { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | 8 | var OauthButtonsCtrl, $window; 9 | 10 | // Initialize the controller and a mock $window 11 | beforeEach(inject(function($controller) { 12 | $window = { 13 | location: {} 14 | }; 15 | 16 | OauthButtonsCtrl = $controller('OauthButtonsCtrl', { 17 | $window: $window 18 | }); 19 | })); 20 | 21 | it('should attach loginOauth', function() { 22 | expect(OauthButtonsCtrl.loginOauth).to.be.a('function'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /e2e/components/oauth-buttons/oauth-buttons.po.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file uses the Page Object pattern to define the main page for tests 3 | * https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var OauthButtons = function() { 9 | var oauthButtons = this.oauthButtons = element(by.css('oauth-buttons')); 10 | oauthButtons.facebook = oauthButtons.element(by.css('.btn.btn-social.btn-facebook')); 11 | oauthButtons.google = oauthButtons.element(by.css('.btn.btn-social.btn-google')); 12 | oauthButtons.twitter = oauthButtons.element(by.css('.btn.btn-social.btn-twitter')); 13 | }; 14 | 15 | module.exports = new OauthButtons(); 16 | -------------------------------------------------------------------------------- /server/auth/local/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import express from 'express'; 4 | import passport from 'passport'; 5 | import {signToken} from '../auth.service'; 6 | 7 | var router = express.Router(); 8 | 9 | router.post('/', function(req, res, next) { 10 | passport.authenticate('local', function(err, user, info) { 11 | var error = err || info; 12 | if (error) { 13 | return res.status(401).json(error); 14 | } 15 | if (!user) { 16 | return res.status(404).json({message: 'Something went wrong, please try again.'}); 17 | } 18 | 19 | var token = signToken(user._id, user.role); 20 | res.json({ token }); 21 | })(req, res, next) 22 | }); 23 | 24 | export default router; 25 | -------------------------------------------------------------------------------- /client/components/sidebar-cat/sidebar-cat.directive.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Directive: sidebarCat', function () { 4 | 5 | // load the directive's module and view 6 | beforeEach(module('bhcmartApp')); 7 | beforeEach(module('components/sidebar-cat/sidebar-cat.html')); 8 | 9 | var element, scope; 10 | 11 | beforeEach(inject(function ($rootScope) { 12 | scope = $rootScope.$new(); 13 | })); 14 | 15 | it('should make hidden element visible', inject(function ($compile) { 16 | element = angular.element(''); 17 | element = $compile(element)(scope); 18 | scope.$apply(); 19 | expect(element.text()).to.equal('this is the sidebarCat directive'); 20 | })); 21 | }); 22 | -------------------------------------------------------------------------------- /server/auth/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import express from 'express'; 4 | import passport from 'passport'; 5 | import config from '../config/environment'; 6 | import User from '../api/user/user.model'; 7 | 8 | // Passport Configuration 9 | require('./local/passport').setup(User, config); 10 | require('./facebook/passport').setup(User, config); 11 | require('./google/passport').setup(User, config); 12 | require('./twitter/passport').setup(User, config); 13 | 14 | var router = express.Router(); 15 | 16 | router.use('/local', require('./local')); 17 | router.use('/facebook', require('./facebook')); 18 | router.use('/twitter', require('./twitter')); 19 | router.use('/google', require('./google')); 20 | 21 | export default router; 22 | -------------------------------------------------------------------------------- /server/config/environment/production.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Production specific configuration 4 | // ================================= 5 | module.exports = { 6 | // Server IP 7 | ip: process.env.OPENSHIFT_NODEJS_IP || 8 | process.env.IP || 9 | undefined, 10 | 11 | // Server port 12 | port: process.env.OPENSHIFT_NODEJS_PORT || 13 | process.env.PORT || 14 | 8080, 15 | 16 | // MongoDB connection options 17 | mongo: { 18 | uri: process.env.MONGOLAB_URI || 19 | process.env.MONGOHQ_URL || 20 | process.env.OPENSHIFT_MONGODB_DB_URL + 21 | process.env.OPENSHIFT_APP_NAME || 22 | 'mongodb://localhost/bhcmart' 23 | }, 24 | seedDB: false 25 | }; 26 | -------------------------------------------------------------------------------- /client/app/manage-requests/manage-requests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('manage-requests', { 7 | url: '/manage-requests', 8 | templateUrl: 'app/manage-requests/manage-requests.html', 9 | controller: 'ManageRequestsCtrl' 10 | }) 11 | .state('submit-request', { 12 | url: '/submit-request', 13 | templateUrl: 'app/manage-requests/submit-request.html', 14 | controller: 'SubmitRequestCtrl' 15 | }).state('view-request', { 16 | url: '/request/{id}', 17 | templateUrl: 'app/manage-requests/view-request.html', 18 | controller: 'ViewRequestCtrl' 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /e2e/components/navbar/navbar.po.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file uses the Page Object pattern to define the main page for tests 3 | * https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var NavbarComponent = function() { 9 | this.navbar = element(by.css('.navbar')); 10 | this.navbarHeader = this.navbar.element(by.css('.navbar-header')); 11 | this.navbarNav = this.navbar.element(by.css('#navbar-main .nav.navbar-nav:not(.navbar-right)')); 12 | this.navbarAccount = this.navbar.element(by.css('#navbar-main .nav.navbar-nav.navbar-right')); 13 | this.navbarAccountGreeting = this.navbarAccount.element(by.binding('getCurrentUser().name')); 14 | }; 15 | 16 | module.exports = new NavbarComponent(); 17 | -------------------------------------------------------------------------------- /client/components/sidebar-account/sidebar-account.directive.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Directive: sidebarAccount', function () { 4 | 5 | // load the directive's module and view 6 | beforeEach(module('bhcmartApp')); 7 | beforeEach(module('components/sidebar-account/sidebar-account.html')); 8 | 9 | var element, scope; 10 | 11 | beforeEach(inject(function ($rootScope) { 12 | scope = $rootScope.$new(); 13 | })); 14 | 15 | it('should make hidden element visible', inject(function ($compile) { 16 | element = angular.element(''); 17 | element = $compile(element)(scope); 18 | scope.$apply(); 19 | expect(element.text()).to.equal('this is the sidebarAccount directive'); 20 | })); 21 | }); 22 | -------------------------------------------------------------------------------- /server/api/user/user.events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * User model events 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import {EventEmitter} from 'events'; 8 | import User from './user.model'; 9 | var UserEvents = new EventEmitter(); 10 | 11 | // Set max event listeners (0 == unlimited) 12 | UserEvents.setMaxListeners(0); 13 | 14 | // Model events 15 | var events = { 16 | 'save': 'save', 17 | 'remove': 'remove' 18 | }; 19 | 20 | // Register the event emitter to the model events 21 | for (var e in events) { 22 | var event = events[e]; 23 | User.schema.post(e, emitEvent(event)); 24 | } 25 | 26 | function emitEvent(event) { 27 | return function(doc) { 28 | UserEvents.emit(event + ':' + doc._id, doc); 29 | UserEvents.emit(event, doc); 30 | } 31 | } 32 | 33 | export default UserEvents; 34 | -------------------------------------------------------------------------------- /server/api/order/order.events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Order model events 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import {EventEmitter} from 'events'; 8 | var Order = require('./order.model'); 9 | var OrderEvents = new EventEmitter(); 10 | 11 | // Set max event listeners (0 == unlimited) 12 | OrderEvents.setMaxListeners(0); 13 | 14 | // Model events 15 | var events = { 16 | 'save': 'save', 17 | 'remove': 'remove' 18 | }; 19 | 20 | // Register the event emitter to the model events 21 | for (var e in events) { 22 | var event = events[e]; 23 | Order.schema.post(e, emitEvent(event)); 24 | } 25 | 26 | function emitEvent(event) { 27 | return function(doc) { 28 | OrderEvents.emit(event + ':' + doc._id, doc); 29 | OrderEvents.emit(event, doc); 30 | } 31 | } 32 | 33 | export default OrderEvents; 34 | -------------------------------------------------------------------------------- /server/api/thing/thing.events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Thing model events 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import {EventEmitter} from 'events'; 8 | var Thing = require('./thing.model'); 9 | var ThingEvents = new EventEmitter(); 10 | 11 | // Set max event listeners (0 == unlimited) 12 | ThingEvents.setMaxListeners(0); 13 | 14 | // Model events 15 | var events = { 16 | 'save': 'save', 17 | 'remove': 'remove' 18 | }; 19 | 20 | // Register the event emitter to the model events 21 | for (var e in events) { 22 | var event = events[e]; 23 | Thing.schema.post(e, emitEvent(event)); 24 | } 25 | 26 | function emitEvent(event) { 27 | return function(doc) { 28 | ThingEvents.emit(event + ':' + doc._id, doc); 29 | ThingEvents.emit(event, doc); 30 | } 31 | } 32 | 33 | export default ThingEvents; 34 | -------------------------------------------------------------------------------- /server/api/upload/upload.events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Upload model events 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import {EventEmitter} from 'events'; 8 | var Upload = require('./upload.model'); 9 | var UploadEvents = new EventEmitter(); 10 | 11 | // Set max event listeners (0 == unlimited) 12 | UploadEvents.setMaxListeners(0); 13 | 14 | // Model events 15 | var events = { 16 | 'save': 'save', 17 | 'remove': 'remove' 18 | }; 19 | 20 | // Register the event emitter to the model events 21 | for (var e in events) { 22 | var event = events[e]; 23 | Upload.schema.post(e, emitEvent(event)); 24 | } 25 | 26 | function emitEvent(event) { 27 | return function(doc) { 28 | UploadEvents.emit(event + ':' + doc._id, doc); 29 | UploadEvents.emit(event, doc); 30 | } 31 | } 32 | 33 | export default UploadEvents; 34 | -------------------------------------------------------------------------------- /server/api/user/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import {Router} from 'express'; 4 | import * as controller from './user.controller'; 5 | import * as auth from '../../auth/auth.service'; 6 | 7 | var router = new Router(); 8 | 9 | router.get('/', auth.hasRole('admin'), controller.index); 10 | router.delete('/:id', auth.hasRole('admin'), controller.destroy); 11 | router.get('/me', auth.isAuthenticated(), controller.me); 12 | router.put('/:id/password', auth.isAuthenticated(), controller.changePassword); 13 | router.get('/:id', auth.isAuthenticated(), controller.show); 14 | router.post('/', controller.create); 15 | router.post('/:id/permission', auth.hasRole('admin'), controller.authorize); 16 | router.put('/:id/permission/:cat_id', auth.hasRole('admin'), controller.deAuthorize); 17 | 18 | export default router; 19 | -------------------------------------------------------------------------------- /client/app/manage-categories/manage-categories.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('manage-categories', { 7 | url: '/manage-categories', 8 | templateUrl: 'app/manage-categories/manage-categories.html', 9 | controller: 'ManageCategoriesCtrl' 10 | }) 11 | .state('edit-category', { 12 | url: '/manage-categories/{id}', 13 | templateUrl: 'app/manage-categories/manage-categories-edit.html', 14 | controller: 'ManageCategoriesEditCtrl' 15 | }) 16 | .state('add-category', { 17 | url: '/add-category', 18 | templateUrl: 'app/manage-categories/manage-categories-add.html', 19 | controller: 'ManageCategoriesAddCtrl' 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /server/api/request/request.events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Request model events 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import {EventEmitter} from 'events'; 8 | var Request = require('./request.model'); 9 | var RequestEvents = new EventEmitter(); 10 | 11 | // Set max event listeners (0 == unlimited) 12 | RequestEvents.setMaxListeners(0); 13 | 14 | // Model events 15 | var events = { 16 | 'save': 'save', 17 | 'remove': 'remove' 18 | }; 19 | 20 | // Register the event emitter to the model events 21 | for (var e in events) { 22 | var event = events[e]; 23 | Request.schema.post(e, emitEvent(event)); 24 | } 25 | 26 | function emitEvent(event) { 27 | return function(doc) { 28 | RequestEvents.emit(event + ':' + doc._id, doc); 29 | RequestEvents.emit(event, doc); 30 | } 31 | } 32 | 33 | export default RequestEvents; 34 | -------------------------------------------------------------------------------- /server/api/catalog/catalog.events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Catalog model events 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var EventEmitter = require('events').EventEmitter; 8 | var Catalog = require('./catalog.model'); 9 | var CatalogEvents = new EventEmitter(); 10 | 11 | // Set max event listeners (0 == unlimited) 12 | CatalogEvents.setMaxListeners(0); 13 | 14 | // Model events 15 | var events = { 16 | 'save': 'save', 17 | 'remove': 'remove' 18 | }; 19 | 20 | // Register the event emitter to the model events 21 | for (var e in events) { 22 | var event = events[e]; 23 | Catalog.schema.post(e, emitEvent(event)); 24 | } 25 | 26 | function emitEvent(event) { 27 | return function(doc) { 28 | CatalogEvents.emit(event + ':' + doc._id, doc); 29 | CatalogEvents.emit(event, doc); 30 | } 31 | } 32 | 33 | module.exports = CatalogEvents; 34 | -------------------------------------------------------------------------------- /client/app/account/login/login.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class LoginController { 4 | //start-non-standard 5 | user = {}; 6 | errors = {}; 7 | submitted = false; 8 | //end-non-standard 9 | 10 | constructor(Auth, $state) { 11 | this.Auth = Auth; 12 | this.$state = $state; 13 | } 14 | 15 | login(form) { 16 | this.submitted = true; 17 | 18 | if (form.$valid) { 19 | this.Auth.login({ 20 | email: this.user.email, 21 | password: this.user.password 22 | }) 23 | .then(() => { 24 | // Logged in, redirect to home 25 | this.$state.go('main'); 26 | }) 27 | .catch(err => { 28 | this.errors.other = err.message; 29 | }); 30 | } 31 | } 32 | } 33 | 34 | angular.module('bhcmartApp') 35 | .controller('LoginController', LoginController); 36 | -------------------------------------------------------------------------------- /client/app/account/settings/settings.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class SettingsController { 4 | //start-non-standard 5 | errors = {}; 6 | submitted = false; 7 | //end-non-standard 8 | 9 | constructor(Auth) { 10 | this.Auth = Auth; 11 | } 12 | 13 | changePassword(form) { 14 | this.submitted = true; 15 | 16 | if (form.$valid) { 17 | this.Auth.changePassword(this.user.oldPassword, this.user.newPassword) 18 | .then(() => { 19 | this.message = 'Password successfully changed.'; 20 | }) 21 | .catch(() => { 22 | form.password.$setValidity('mongoose', false); 23 | this.errors.other = 'Incorrect password'; 24 | this.message = ''; 25 | }); 26 | } 27 | } 28 | } 29 | 30 | angular.module('bhcmartApp') 31 | .controller('SettingsController', SettingsController); 32 | -------------------------------------------------------------------------------- /client/app/admin/admin.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | (function() { 4 | 5 | class AdminController { 6 | constructor(User, Modal) { 7 | // Use the User $resource to fetch all users 8 | let self = this; 9 | User.query(function(users) { 10 | self.users = users; 11 | // pagination controls 12 | self.currentPage = 1; 13 | self.totalItems = self.users.length; 14 | self.itemsPerPage = 10; // items per page 15 | self.noOfPages = Math.ceil(self.totalItems / self.itemsPerPage); 16 | }); 17 | 18 | this.delete = Modal.confirm.delete(user => { 19 | user.$remove(); 20 | this.users.splice(this.users.indexOf(user), 1); 21 | }); 22 | } 23 | 24 | 25 | } 26 | 27 | angular.module('bhcmartApp.admin') 28 | .controller('AdminController', AdminController); 29 | 30 | })(); 31 | -------------------------------------------------------------------------------- /client/assets/js/plugins.js: -------------------------------------------------------------------------------- 1 | // Avoid `console` errors in browsers that lack a console. 2 | (function() { 3 | var method; 4 | var noop = function () {}; 5 | var methods = [ 6 | 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 7 | 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 8 | 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 9 | 'timeline', 'timelineEnd', 'timeStamp', 'trace', 'warn' 10 | ]; 11 | var length = methods.length; 12 | var console = (window.console = window.console || {}); 13 | 14 | while (length--) { 15 | method = methods[length]; 16 | 17 | // Only stub undefined methods. 18 | if (!console[method]) { 19 | console[method] = noop; 20 | } 21 | } 22 | }()); 23 | 24 | // Place any jQuery/helper plugins in here. 25 | -------------------------------------------------------------------------------- /client/app/category/category.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('CategoryCtrl', ['$scope', '$stateParams', 'Product', function($scope, $stateParams, Product) { 5 | console.log($stateParams) 6 | $stateParams.slug == 'all' ? Product.query(process($scope)) : Product.catalog({ id: $stateParams.slug, limit: 0 }, process($scope)); 7 | }]); 8 | 9 | let getAverageRating = p => Math.ceil(_.reduce(p.reviews, (a, b) => a + b.rating, 0) / p.reviews.length); 10 | 11 | let process = $scope => prod => { 12 | $scope.products = _.map(prod, rP => _.extend(rP, { averageRating: getAverageRating(rP) })); 13 | // pagination controls 14 | $scope.currentPage = 1; 15 | $scope.totalItems = $scope.products.length; 16 | $scope.itemsPerPage = 20; // items per page 17 | $scope.noOfPages = Math.ceil($scope.totalItems / $scope.itemsPerPage); 18 | } 19 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "source", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "angular": "~1.4.0", 6 | "json3": "~3.3.1", 7 | "es5-shim": "~3.0.1", 8 | "bootstrap-sass-official": "~3.1.1", 9 | "bootstrap": "~3.1.1", 10 | "bootstrap-social": "~4.9.1", 11 | "angular-resource": "~1.4.0", 12 | "angular-touch": "~1.4.8", 13 | "angular-animate": "~1.4.8", 14 | "angular-cookies": "~1.4.0", 15 | "angular-sanitize": "~1.4.0", 16 | "font-awesome": ">=4.1.0", 17 | "lodash": "~2.4.1", 18 | "angular-socket-io": "~0.7.0", 19 | "angular-ui-router": "~0.2.15", 20 | "angular-validation-match": "~1.5.2", 21 | "ngCart": "ngcart#^1.0.0", 22 | "angular-bootstrap": "^1.3.1", 23 | "ng-file-upload": "^12.0.4", 24 | "bootstrap-select": "^1.10.0" 25 | }, 26 | "devDependencies": { 27 | "angular-mocks": "~1.4.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /client/assets/lib/nivo-slider/home.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | "use strict"; 3 | 4 | //--------------------------------------------- 5 | //Nivo slider 6 | //--------------------------------------------- 7 | $('#nivoslider').nivoSlider({ 8 | effect: 'random', 9 | slices: 15, 10 | boxCols: 12, 11 | boxRows: 12, 12 | animSpeed: 500, 13 | pauseTime: 5000, 14 | startSlide: 0, 15 | directionNav: true, 16 | controlNavThumbs: false, 17 | pauseOnHover: false, 18 | manualAdvance: true 19 | }); 20 | 21 | $('#nivoslider-four').nivoSlider({ 22 | effect: 'fade', 23 | slices: 15, 24 | boxCols: 12, 25 | boxRows: 12, 26 | animSpeed: 500, 27 | pauseTime: 5000, 28 | startSlide: 0, 29 | directionNav: false, 30 | controlNavThumbs: false, 31 | pauseOnHover: true, 32 | manualAdvance: true 33 | }); 34 | })(jQuery); -------------------------------------------------------------------------------- /client/components/sidebar-cat/sidebar-cat.html: -------------------------------------------------------------------------------- 1 |
2 | 16 |
17 | -------------------------------------------------------------------------------- /client/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "latedef": true, 11 | "newcap": true, 12 | "noarg": true, 13 | "quotmark": "single", 14 | "undef": true, 15 | "unused": true, 16 | "strict": true, 17 | "trailing": true, 18 | "smarttabs": true, 19 | "ignoreDelimiters": [ 20 | { "start": "start-non-standard", "end": "end-non-standard" } 21 | ], 22 | "globals": { 23 | "jQuery": true, 24 | "angular": true, 25 | "console": true, 26 | "$": true, 27 | "_": true, 28 | "moment": true, 29 | "describe": true, 30 | "beforeEach": true, 31 | "module": true, 32 | "inject": true, 33 | "it": true, 34 | "expect": true, 35 | "browser": true, 36 | "element": true, 37 | "by": true 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /client/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /server/api/order/order.socket.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Broadcast updates to client when the model changes 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var OrderEvents = require('./order.events'); 8 | 9 | // Model events to emit 10 | var events = ['save', 'remove']; 11 | 12 | export function register(socket) { 13 | // Bind model events to socket events 14 | for (var i = 0, eventsLength = events.length; i < eventsLength; i++) { 15 | var event = events[i]; 16 | var listener = createListener('order:' + event, socket); 17 | 18 | OrderEvents.on(event, listener); 19 | socket.on('disconnect', removeListener(event, listener)); 20 | } 21 | } 22 | 23 | 24 | function createListener(event, socket) { 25 | return function(doc) { 26 | socket.emit(event, doc); 27 | }; 28 | } 29 | 30 | function removeListener(event, listener) { 31 | return function() { 32 | OrderEvents.removeListener(event, listener); 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /server/api/thing/thing.socket.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Broadcast updates to client when the model changes 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var ThingEvents = require('./thing.events'); 8 | 9 | // Model events to emit 10 | var events = ['save', 'remove']; 11 | 12 | export function register(socket) { 13 | // Bind model events to socket events 14 | for (var i = 0, eventsLength = events.length; i < eventsLength; i++) { 15 | var event = events[i]; 16 | var listener = createListener('thing:' + event, socket); 17 | 18 | ThingEvents.on(event, listener); 19 | socket.on('disconnect', removeListener(event, listener)); 20 | } 21 | } 22 | 23 | 24 | function createListener(event, socket) { 25 | return function(doc) { 26 | socket.emit(event, doc); 27 | }; 28 | } 29 | 30 | function removeListener(event, listener) { 31 | return function() { 32 | ThingEvents.removeListener(event, listener); 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /server/api/upload/upload.socket.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Broadcast updates to client when the model changes 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var UploadEvents = require('./upload.events'); 8 | 9 | // Model events to emit 10 | var events = ['save', 'remove']; 11 | 12 | export function register(socket) { 13 | // Bind model events to socket events 14 | for (var i = 0, eventsLength = events.length; i < eventsLength; i++) { 15 | var event = events[i]; 16 | var listener = createListener('upload:' + event, socket); 17 | 18 | UploadEvents.on(event, listener); 19 | socket.on('disconnect', removeListener(event, listener)); 20 | } 21 | } 22 | 23 | 24 | function createListener(event, socket) { 25 | return function(doc) { 26 | socket.emit(event, doc); 27 | }; 28 | } 29 | 30 | function removeListener(event, listener) { 31 | return function() { 32 | UploadEvents.removeListener(event, listener); 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /server/api/request/request.socket.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Broadcast updates to client when the model changes 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var RequestEvents = require('./request.events'); 8 | 9 | // Model events to emit 10 | var events = ['save', 'remove']; 11 | 12 | export function register(socket) { 13 | // Bind model events to socket events 14 | for (var i = 0, eventsLength = events.length; i < eventsLength; i++) { 15 | var event = events[i]; 16 | var listener = createListener('request:' + event, socket); 17 | 18 | RequestEvents.on(event, listener); 19 | socket.on('disconnect', removeListener(event, listener)); 20 | } 21 | } 22 | 23 | 24 | function createListener(event, socket) { 25 | return function(doc) { 26 | socket.emit(event, doc); 27 | }; 28 | } 29 | 30 | function removeListener(event, listener) { 31 | return function() { 32 | RequestEvents.removeListener(event, listener); 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /server/api/catalog/catalog.socket.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Broadcast updates to client when the model changes 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var CatalogEvents = require('./catalog.events'); 8 | 9 | // Model events to emit 10 | var events = ['save', 'remove']; 11 | 12 | exports.register = function(socket) { 13 | // Bind model events to socket events 14 | for (var i = 0, eventsLength = events.length; i < eventsLength; i++) { 15 | var event = events[i]; 16 | var listener = createListener('catalog:' + event, socket); 17 | 18 | CatalogEvents.on(event, listener); 19 | socket.on('disconnect', removeListener(event, listener)); 20 | } 21 | }; 22 | 23 | 24 | function createListener(event, socket) { 25 | return function(doc) { 26 | socket.emit(event, doc); 27 | }; 28 | } 29 | 30 | function removeListener(event, listener) { 31 | return function() { 32 | CatalogEvents.removeListener(event, listener); 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | # These files are text and should be normalized (Convert crlf => lf) 4 | *.php text 5 | *.css text 6 | *.js text 7 | *.htm text 8 | *.html text 9 | *.xml text 10 | *.txt text 11 | *.ini text 12 | *.inc text 13 | .htaccess text 14 | 15 | # Denote all files that are truly binary and should not be modified. 16 | # (binary is a macro for -text -diff) 17 | *.png binary 18 | *.jpg binary 19 | *.jpeg binary 20 | *.gif binary 21 | *.ico binary 22 | *.mov binary 23 | *.mp4 binary 24 | *.mp3 binary 25 | *.flv binary 26 | *.fla binary 27 | *.swf binary 28 | *.gz binary 29 | *.zip binary 30 | *.7z binary 31 | *.ttf binary 32 | 33 | # Documents 34 | *.doc diff=astextplain 35 | *.DOC diff=astextplain 36 | *.docx diff=astextplain 37 | *.DOCX diff=astextplain 38 | *.dot diff=astextplain 39 | *.DOT diff=astextplain 40 | *.pdf diff=astextplain 41 | *.PDF diff=astextplain 42 | *.rtf diff=astextplain 43 | *.RTF diff=astextplain 44 | -------------------------------------------------------------------------------- /client/components/auth/interceptor.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | (function() { 4 | 5 | function authInterceptor($rootScope, $q, $cookies, $injector, Util) { 6 | var state; 7 | return { 8 | // Add authorization token to headers 9 | request(config) { 10 | config.headers = config.headers || {}; 11 | if ($cookies.get('token') && Util.isSameOrigin(config.url)) { 12 | config.headers.Authorization = 'Bearer ' + $cookies.get('token'); 13 | } 14 | return config; 15 | }, 16 | 17 | // Intercept 401s and redirect you to login 18 | responseError(response) { 19 | if (response.status === 401) { 20 | (state || (state = $injector.get('$state'))).go('login'); 21 | // remove any stale tokens 22 | $cookies.remove('token'); 23 | } 24 | return $q.reject(response); 25 | } 26 | }; 27 | } 28 | 29 | angular.module('bhcmartApp.auth') 30 | .factory('authInterceptor', authInterceptor); 31 | 32 | })(); 33 | -------------------------------------------------------------------------------- /e2e/account/login/login.po.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file uses the Page Object pattern to define the main page for tests 3 | * https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var LoginPage = function() { 9 | var form = this.form = element(by.css('.form')); 10 | form.email = form.element(by.model('vm.user.email')); 11 | form.password = form.element(by.model('vm.user.password')); 12 | form.submit = form.element(by.css('.btn-login')); 13 | form.oauthButtons = require('../../components/oauth-buttons/oauth-buttons.po').oauthButtons; 14 | 15 | this.login = function(data) { 16 | for (var prop in data) { 17 | var formElem = form[prop]; 18 | if (data.hasOwnProperty(prop) && formElem && typeof formElem.sendKeys === 'function') { 19 | formElem.sendKeys(data[prop]); 20 | } 21 | } 22 | 23 | return form.submit.click(); 24 | }; 25 | }; 26 | 27 | module.exports = new LoginPage(); 28 | 29 | -------------------------------------------------------------------------------- /client/components/product/product.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .factory('Catalog', function($resource) { 5 | return $resource('/api/catalogs/:id', { 6 | id: '@_id' 7 | }, { 8 | 'update': { 9 | method: 'PUT' 10 | } 11 | }); 12 | }).factory('Product', function($resource) { 13 | return $resource('/api/products/:id/:controller/:limit', { 14 | id: '@_id' 15 | }, { 16 | 'update': { method: 'PUT' }, 17 | 'catalog': { 18 | method: 'GET', 19 | isArray: true, 20 | params: { 21 | controller: 'catalog' 22 | } 23 | }, 24 | 'search': { 25 | method: 'GET', 26 | isArray: true, 27 | params: { 28 | controller: 'search', 29 | } 30 | }, 31 | 'review': { 32 | method: 'POST', 33 | params: { 34 | controller: 'reviews', 35 | limit: null 36 | } 37 | } 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /server/auth/twitter/passport.js: -------------------------------------------------------------------------------- 1 | import passport from 'passport'; 2 | import {Strategy as TwitterStrategy} from 'passport-twitter'; 3 | 4 | export function setup(User, config) { 5 | passport.use(new TwitterStrategy({ 6 | consumerKey: config.twitter.clientID, 7 | consumerSecret: config.twitter.clientSecret, 8 | callbackURL: config.twitter.callbackURL 9 | }, 10 | function(token, tokenSecret, profile, done) { 11 | User.findOneAsync({ 12 | 'twitter.id_str': profile.id 13 | }) 14 | .then(user => { 15 | if (user) { 16 | return done(null, user); 17 | } 18 | 19 | user = new User({ 20 | name: profile.displayName, 21 | username: profile.username, 22 | role: 'user', 23 | provider: 'twitter', 24 | twitter: profile._json 25 | }); 26 | user.saveAsync() 27 | .then(user => done(null, user)) 28 | .catch(err => done(err)); 29 | }) 30 | .catch(err => done(err)); 31 | })); 32 | } 33 | -------------------------------------------------------------------------------- /client/app/main/main.controller.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: MainController', function() { 4 | 5 | // load the controller's module 6 | beforeEach(module('bhcmartApp')); 7 | beforeEach(module('stateMock')); 8 | beforeEach(module('socketMock')); 9 | 10 | var scope; 11 | var MainController; 12 | var state; 13 | var $httpBackend; 14 | 15 | // Initialize the controller and a mock scope 16 | beforeEach(inject(function(_$httpBackend_, $controller, $rootScope, $state) { 17 | $httpBackend = _$httpBackend_; 18 | $httpBackend.expectGET('/api/things') 19 | .respond(['HTML5 Boilerplate', 'AngularJS', 'Karma', 'Express']); 20 | 21 | scope = $rootScope.$new(); 22 | state = $state; 23 | MainController = $controller('MainController', { 24 | $scope: scope 25 | }); 26 | })); 27 | 28 | it('should attach a list of things to the controller', function() { 29 | $httpBackend.flush(); 30 | expect(MainController.awesomeThings.length).to.equal(4); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /client/components/sidebar-cat/sidebar-cat.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('SidebarCatCtrl', function($scope, Catalog, socket) { 5 | let self = $scope; 6 | 7 | Catalog.query(function(categories) { 8 | self.categories = categories; 9 | self.allCategory = _.filter(categories, function(category) { 10 | return category.ancestors.length == 0; 11 | }) 12 | let parentCategories = _.filter(categories, function(category) { 13 | return category.ancestors.length == 1 && category.slug != "upsell-products"; 14 | }) 15 | self.parentCategories = _.map(parentCategories, function(parentCategory) { 16 | parentCategory.children = _.map(parentCategory.children, function(childId) { 17 | if (childId) 18 | return _.find(categories, { 19 | "_id": childId 20 | }) 21 | }) 22 | return parentCategory 23 | }); 24 | socket.syncUpdates('catalog', self.categories); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /server/api/catalog/catalog.model.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('bluebird').promisifyAll(require('mongoose')); 4 | var Schema = mongoose.Schema; 5 | var slugs = require('mongoose-url-slugs'); 6 | 7 | var CatalogSchema = new Schema({ 8 | name: { 9 | type: String, 10 | required: true 11 | }, 12 | parent: { 13 | type: Schema.Types.ObjectId, 14 | ref: 'Catalog' 15 | }, 16 | ancestors: [{ 17 | type: Schema.Types.ObjectId, 18 | ref: 'Catalog' 19 | }], 20 | children: [{ 21 | type: Schema.Types.ObjectId, 22 | ref: 'Catalog' 23 | }] 24 | }); 25 | 26 | CatalogSchema.methods = { 27 | addChild: function(child) { 28 | var that = this; 29 | child.parent = this._id; 30 | child.ancestors = this.ancestors.concat([this._id]); 31 | return this.model('Catalog').create(child).addCallback(function(child) { 32 | that.children.push(child._id); 33 | that.save(); 34 | }); 35 | } 36 | } 37 | 38 | CatalogSchema.plugin(slugs('name')); 39 | 40 | module.exports = mongoose.model('Catalog', CatalogSchema); 41 | -------------------------------------------------------------------------------- /client/components/auth/router.decorator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | (function() { 4 | 5 | angular.module('bhcmartApp.auth') 6 | .run(function($rootScope, $state, Auth) { 7 | // Redirect to login if route requires auth and the user is not logged in, or doesn't have required role 8 | $rootScope.$on('$stateChangeStart', function(event, next) { 9 | if(!next.authenticate) { 10 | return; 11 | } 12 | 13 | if(typeof next.authenticate === 'string') { 14 | Auth.hasRole(next.authenticate, _.noop).then(has => { 15 | if(has) { 16 | return; 17 | } 18 | 19 | event.preventDefault(); 20 | return Auth.isLoggedIn(_.noop).then(is => { 21 | $state.go(is ? 'main' : 'login'); 22 | }); 23 | }); 24 | } else { 25 | Auth.isLoggedIn(_.noop).then(is => { 26 | if(is) { 27 | return; 28 | } 29 | 30 | event.preventDefault(); 31 | $state.go('main'); 32 | }); 33 | } 34 | }); 35 | }); 36 | 37 | })(); 38 | -------------------------------------------------------------------------------- /server/auth/google/passport.js: -------------------------------------------------------------------------------- 1 | import passport from 'passport'; 2 | import {OAuth2Strategy as GoogleStrategy} from 'passport-google-oauth'; 3 | 4 | export function setup(User, config) { 5 | passport.use(new GoogleStrategy({ 6 | clientID: config.google.clientID, 7 | clientSecret: config.google.clientSecret, 8 | callbackURL: config.google.callbackURL 9 | }, 10 | function(accessToken, refreshToken, profile, done) { 11 | User.findOneAsync({ 12 | 'google.id': profile.id 13 | }) 14 | .then(user => { 15 | if (user) { 16 | return done(null, user); 17 | } 18 | 19 | user = new User({ 20 | name: profile.displayName, 21 | email: profile.emails[0].value, 22 | role: 'user', 23 | username: profile.emails[0].value.split('@')[0], 24 | provider: 'google', 25 | google: profile._json 26 | }); 27 | user.saveAsync() 28 | .then(user => done(null, user)) 29 | .catch(err => done(err)); 30 | }) 31 | .catch(err => done(err)); 32 | })); 33 | } 34 | -------------------------------------------------------------------------------- /server/auth/facebook/passport.js: -------------------------------------------------------------------------------- 1 | import passport from 'passport'; 2 | import {Strategy as FacebookStrategy} from 'passport-facebook'; 3 | 4 | export function setup(User, config) { 5 | passport.use(new FacebookStrategy({ 6 | clientID: config.facebook.clientID, 7 | clientSecret: config.facebook.clientSecret, 8 | callbackURL: config.facebook.callbackURL, 9 | profileFields: [ 10 | 'displayName', 11 | 'emails' 12 | ] 13 | }, 14 | function(accessToken, refreshToken, profile, done) { 15 | User.findOneAsync({ 16 | 'facebook.id': profile.id 17 | }) 18 | .then(user => { 19 | if (user) { 20 | return done(null, user); 21 | } 22 | 23 | user = new User({ 24 | name: profile.displayName, 25 | email: profile.emails[0].value, 26 | role: 'user', 27 | provider: 'facebook', 28 | facebook: profile._json 29 | }); 30 | user.saveAsync() 31 | .then(user => done(null, user)) 32 | .catch(err => done(err)); 33 | }) 34 | .catch(err => done(err)); 35 | })); 36 | } 37 | -------------------------------------------------------------------------------- /e2e/account/signup/signup.po.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file uses the Page Object pattern to define the main page for tests 3 | * https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var SignupPage = function() { 9 | var form = this.form = element(by.css('.form')); 10 | form.name = form.element(by.model('vm.user.name')); 11 | form.email = form.element(by.model('vm.user.email')); 12 | form.password = form.element(by.model('vm.user.password')); 13 | form.confirmPassword = form.element(by.model('vm.user.confirmPassword')); 14 | form.submit = form.element(by.css('.btn-register')); 15 | form.oauthButtons = require('../../components/oauth-buttons/oauth-buttons.po').oauthButtons; 16 | 17 | this.signup = function(data) { 18 | for (var prop in data) { 19 | var formElem = form[prop]; 20 | if (data.hasOwnProperty(prop) && formElem && typeof formElem.sendKeys === 'function') { 21 | formElem.sendKeys(data[prop]); 22 | } 23 | } 24 | 25 | return form.submit.click(); 26 | }; 27 | }; 28 | 29 | module.exports = new SignupPage(); 30 | 31 | -------------------------------------------------------------------------------- /server/auth/local/passport.js: -------------------------------------------------------------------------------- 1 | import passport from 'passport'; 2 | import {Strategy as LocalStrategy} from 'passport-local'; 3 | 4 | function localAuthenticate(User, email, password, done) { 5 | User.findOneAsync({ 6 | email: email.toLowerCase() 7 | }) 8 | .then(user => { 9 | if (!user) { 10 | return done(null, false, { 11 | message: 'This email is not registered.' 12 | }); 13 | } 14 | user.authenticate(password, function(authError, authenticated) { 15 | if (authError) { 16 | return done(authError); 17 | } 18 | if (!authenticated) { 19 | return done(null, false, { message: 'This password is not correct.' }); 20 | } else { 21 | return done(null, user); 22 | } 23 | }); 24 | }) 25 | .catch(err => done(err)); 26 | } 27 | 28 | export function setup(User, config) { 29 | passport.use(new LocalStrategy({ 30 | usernameField: 'email', 31 | passwordField: 'password' // this is the virtual field on the model 32 | }, function(email, password, done) { 33 | return localAuthenticate(User, email, password, done); 34 | })); 35 | } 36 | -------------------------------------------------------------------------------- /client/components/sidebar-account/sidebar-account.html: -------------------------------------------------------------------------------- 1 |
2 | 28 |
29 | -------------------------------------------------------------------------------- /client/app/account/signup/signup.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class SignupController { 4 | //start-non-standard 5 | user = {}; 6 | errors = {}; 7 | submitted = false; 8 | //end-non-standard 9 | 10 | constructor(Auth, $state) { 11 | this.Auth = Auth; 12 | this.$state = $state; 13 | } 14 | 15 | register(form) { 16 | this.submitted = true; 17 | 18 | if (form.$valid) { 19 | this.Auth.createUser({ 20 | name: this.user.name, 21 | email: this.user.email, 22 | password: this.user.password 23 | }) 24 | .then(() => { 25 | // Account created, redirect to home 26 | this.$state.go('main'); 27 | }) 28 | .catch(err => { 29 | err = err.data; 30 | this.errors = {}; 31 | 32 | // Update validity of form fields that match the mongoose errors 33 | angular.forEach(err.errors, (error, field) => { 34 | form[field].$setValidity('mongoose', false); 35 | this.errors[field] = error.message; 36 | }); 37 | }); 38 | } 39 | } 40 | } 41 | 42 | angular.module('bhcmartApp') 43 | .controller('SignupController', SignupController); 44 | -------------------------------------------------------------------------------- /server/routes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Main application routes 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import errors from './components/errors'; 8 | import path from 'path'; 9 | 10 | export default function(app) { 11 | // Insert routes below 12 | app.use('/api/requests', require('./api/request')); 13 | app.use('/api/uploads', require('./api/upload')); 14 | app.use('/api/orders', require('./api/order')); 15 | // app.use('/api/variants', require('./api/variant')); 16 | // app.use('/api/reviews', require('./api/review')); 17 | // app.use('/api/images', require('./api/image')); 18 | app.use('/api/catalogs', require('./api/catalog')); 19 | app.use('/api/products', require('./api/product')); 20 | app.use('/api/things', require('./api/thing')); 21 | app.use('/api/users', require('./api/user')); 22 | 23 | app.use('/auth', require('./auth')); 24 | 25 | // All undefined asset or api routes should return a 404 26 | app.route('/:url(api|auth|components|app|bower_components|assets)/*') 27 | .get(errors[404]); 28 | 29 | // All other routes should redirect to the index.html 30 | app.route('/*') 31 | .get((req, res) => { 32 | res.sendFile(path.resolve(app.get('appPath') + '/index.html')); 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /client/app/manage-products/manage-products.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('manage-products', { 7 | url: '/manage-products', 8 | templateUrl: 'app/manage-products/manage-products.html', 9 | controller: 'ManageProductsCtrl' 10 | }) 11 | .state('edit-product', { 12 | url: '/manage-product/{id}', 13 | templateUrl: 'app/manage-products/manage-products-edit.html', 14 | controller: 'ManageProductsEditCtrl', 15 | resolve: { 16 | categories: ['Catalog', function(Catalog) { 17 | return Catalog.query(); 18 | }], 19 | product: ['Product', '$stateParams', function(Product, $stateParams) { 20 | return Product.get({ id: $stateParams.id }); 21 | }] 22 | } 23 | }) 24 | .state('add-product', { 25 | url: '/add-product', 26 | templateUrl: 'app/manage-products/manage-products-add.html', 27 | controller: 'ManageProductsAddCtrl', 28 | resolve: { 29 | categories: ['Catalog', function(Catalog) { 30 | return Catalog.query(); 31 | }] 32 | } 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Main application file 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import express from 'express'; 8 | import mongoose from 'mongoose'; 9 | // mongoose.Promise = require('bluebird'); 10 | import config from './config/environment'; 11 | import http from 'http'; 12 | 13 | // Connect to MongoDB 14 | mongoose.connect(config.mongo.uri, config.mongo.options); 15 | mongoose.connection.on('error', function(err) { 16 | console.error('MongoDB connection error: ' + err); 17 | process.exit(-1); 18 | }); 19 | 20 | // Populate databases with sample data 21 | if (config.seedDB) { require('./config/seed'); } 22 | 23 | // Setup server 24 | var app = express(); 25 | var server = http.createServer(app); 26 | var socketio = require('socket.io')(server, { 27 | serveClient: config.env !== 'production', 28 | path: '/socket.io-client' 29 | }); 30 | require('./config/socketio')(socketio); 31 | require('./config/express')(app); 32 | require('./routes')(app); 33 | 34 | // Start server 35 | function startServer() { 36 | server.listen(config.port, config.ip, function() { 37 | console.log('Express server listening on %d, in %s mode', config.port, app.get('env')); 38 | }); 39 | } 40 | 41 | setImmediate(startServer); 42 | 43 | // Expose app 44 | exports = module.exports = app; 45 | -------------------------------------------------------------------------------- /client/components/ui-router/ui-router.mock.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('stateMock', []); 4 | angular.module('stateMock').service('$state', function($q) { 5 | this.expectedTransitions = []; 6 | 7 | this.transitionTo = function(stateName) { 8 | if (this.expectedTransitions.length > 0) { 9 | var expectedState = this.expectedTransitions.shift(); 10 | if (expectedState !== stateName) { 11 | throw Error('Expected transition to state: ' + expectedState + ' but transitioned to ' + stateName); 12 | } 13 | } else { 14 | throw Error('No more transitions were expected! Tried to transition to ' + stateName); 15 | } 16 | console.log('Mock transition to: ' + stateName); 17 | var deferred = $q.defer(); 18 | var promise = deferred.promise; 19 | deferred.resolve(); 20 | return promise; 21 | }; 22 | 23 | this.go = this.transitionTo; 24 | 25 | this.expectTransitionTo = function(stateName) { 26 | this.expectedTransitions.push(stateName); 27 | }; 28 | 29 | this.ensureAllTransitionsHappened = function() { 30 | if (this.expectedTransitions.length > 0) { 31 | throw Error('Not all transitions happened!'); 32 | } 33 | }; 34 | }); 35 | -------------------------------------------------------------------------------- /server/api/request/request.model.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('bluebird').promisifyAll(require('mongoose')); 4 | import { Schema } from 'mongoose'; 5 | var autoIncrement = require('mongoose-auto-increment'); 6 | import config from '../../config/environment'; 7 | 8 | autoIncrement.initialize(mongoose.createConnection(config.mongo.uri)); 9 | 10 | 11 | var RequestItemSchema = new Schema({ 12 | description: String, 13 | price: Number, 14 | quantity: Number, 15 | total: Number 16 | }); 17 | 18 | var RequestSchema = new Schema({ 19 | requestNumber: String, 20 | customerId: { 21 | type: Schema.Types.ObjectId, 22 | ref: "User" 23 | }, 24 | items: [RequestItemSchema], 25 | customerName: String, 26 | customerEmail: String, 27 | customerAddress: String, 28 | customerPhone: String, 29 | customerCity: String, 30 | customerState: String, 31 | customerCountry: String, 32 | listSubTotal: Number, 33 | listCharge: Number, 34 | listTotal: Number, 35 | processed: { 36 | type: Boolean, 37 | default: false 38 | }, 39 | created: { 40 | type: Date, 41 | default: Date.now 42 | } 43 | }); 44 | 45 | RequestSchema.plugin(autoIncrement.plugin, { 46 | model: 'Request', 47 | field: 'requestNumber', 48 | startAt: 700000, 49 | incrementBy: 1 50 | }); 51 | 52 | export default mongoose.model('Request', RequestSchema); 53 | -------------------------------------------------------------------------------- /server/api/order/order.model.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('bluebird').promisifyAll(require('mongoose')); 4 | var autoIncrement = require('mongoose-auto-increment'); 5 | import config from '../../config/environment'; 6 | var Schema = mongoose.Schema 7 | 8 | autoIncrement.initialize(mongoose.createConnection(config.mongo.uri)); 9 | 10 | var OrderItemSchema = new Schema({ 11 | name: String, 12 | price: Number, 13 | quantity: Number, 14 | total: Number, 15 | productId: { 16 | type: Schema.Types.ObjectId, 17 | ref: 'Product' 18 | } 19 | }); 20 | 21 | var OrderSchema = new Schema({ 22 | orderNumber: String, 23 | shipping: Number, 24 | tax: Number, 25 | taxRate: Number, 26 | subTotal: Number, 27 | totalCost: Number, 28 | items: [OrderItemSchema], 29 | customerId: { 30 | type: Schema.Types.ObjectId, 31 | ref: 'User' 32 | }, 33 | customerName: String, 34 | customerEmail: String, 35 | customerAddress: String, 36 | customerPhone: String, 37 | customerCity: String, 38 | customerState: String, 39 | customerCountry: String, 40 | delivered: { 41 | type: Boolean, 42 | default: false 43 | }, 44 | created: { 45 | type: Date, 46 | default: Date.now 47 | } 48 | }); 49 | 50 | OrderSchema.plugin(autoIncrement.plugin, { 51 | model: 'Order', 52 | field: 'orderNumber', 53 | startAt: 400000, 54 | incrementBy: 1 55 | }); 56 | 57 | export default mongoose.model('Order', OrderSchema); 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | eCommerce site built with the MEAN stack - https://bhcmart.herokuapp.com/ 4 | 5 | ## Description 6 | 7 | This is a starter project if you intend building an eCommerce platform on MEAN(Mongo, Express, Angular, Node). [Socket](https://socket.io) was used to achieve a realtime updates in prices and quantities of products. 8 | 9 | Admin User: admin@bhcmart.com 10 | Password: 123456 11 | 12 | ### Prerequisites 13 | 14 | - [Git](https://git-scm.com/) 15 | - [Node.js and npm](nodejs.org) Node ^4.2.3, npm ^2.14.7 16 | - [Bower](bower.io) (`npm install --global bower`) 17 | - [Ruby](https://www.ruby-lang.org) and then `gem install sass` 18 | - [Grunt](http://gruntjs.com/) (`npm install --global grunt-cli`) 19 | - [MongoDB](https://www.mongodb.org/) - Keep a running daemon with `mongod` 20 | 21 | ### Developing 22 | 23 | 1. Run `npm install` to install server dependencies. 24 | 25 | 2. Run `bower install` to install front-end dependencies. 26 | 27 | 3. Run `mongod` in a separate shell to keep an instance of the MongoDB Daemon running 28 | 29 | 4. Run `grunt serve` to start the development server. It should automatically open the client in your browser when ready. 30 | 31 | ## Build & development 32 | 33 | Run `grunt build` or `grunt` for building and `grunt serve` for preview. 34 | 35 | ## Testing 36 | 37 | Running `npm test` will run the unit tests with karma. 38 | 39 | ## Production 40 | Running `grunt serve:dist` previews the application in production mode 41 | -------------------------------------------------------------------------------- /client/app/account/account.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('login', { 7 | url: '/login', 8 | templateUrl: 'app/account/login/login.html', 9 | controller: 'LoginController', 10 | controllerAs: 'vm' 11 | }) 12 | .state('logout', { 13 | url: '/logout?referrer', 14 | referrer: 'main', 15 | template: '', 16 | controller: function($state, Auth) { 17 | var referrer = $state.params.referrer || 18 | $state.current.referrer || 19 | 'main'; 20 | Auth.logout(); 21 | $state.go(referrer); 22 | } 23 | }) 24 | .state('signup', { 25 | url: '/signup', 26 | templateUrl: 'app/account/signup/signup.html', 27 | controller: 'SignupController', 28 | controllerAs: 'vm' 29 | }) 30 | .state('settings', { 31 | url: '/settings', 32 | templateUrl: 'app/account/settings/settings.html', 33 | controller: 'SettingsController', 34 | controllerAs: 'vm', 35 | authenticate: true 36 | }); 37 | }) 38 | .run(function($rootScope) { 39 | $rootScope.$on('$stateChangeStart', function(event, next, nextParams, current) { 40 | if (next.name === 'logout' && current && current.name && !current.authenticate) { 41 | next.referrer = current.name; 42 | } 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /client/app/orders/orders.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('OrdersCtrl', ['$scope', 'Order', 'Auth', 'Modal', function($scope, Order, Auth, Modal) { 5 | var user = Auth.getCurrentUser(); 6 | $scope.isAdmin = Auth.hasRole('admin'); 7 | 8 | if ($scope.isAdmin) 9 | Order.query(function(orders) { 10 | $scope.orders = orders; 11 | // pagination controls 12 | $scope.currentPage = 1; 13 | $scope.totalItems = $scope.orders.length; 14 | $scope.itemsPerPage = 10; // items per page 15 | $scope.noOfPages = Math.ceil($scope.totalItems / $scope.itemsPerPage); 16 | }); 17 | else 18 | Order.myOrders({ id: user._id }, function(orders) { 19 | $scope.orders = orders; 20 | // pagination controls 21 | $scope.currentPage = 1; 22 | $scope.totalItems = $scope.orders.length; 23 | $scope.itemsPerPage = 10; // items per page 24 | $scope.noOfPages = Math.ceil($scope.totalItems / $scope.itemsPerPage); 25 | }); 26 | 27 | $scope.deleteOrder = Modal.confirm.delete(function(o) { 28 | o.$remove(o._id, function(resp) { 29 | console.log(resp) 30 | $scope.orders.splice($scope.orders.indexOf(o), 1); 31 | }) 32 | }); 33 | 34 | $scope.deliverOrder = Modal.confirm.deliver(function(o) { 35 | o.delivered = o.delivered ? false : true; 36 | o.$update(function(resp) { 37 | console.log(resp) 38 | }) 39 | }); 40 | }]); 41 | -------------------------------------------------------------------------------- /e2e/account/logout/logout.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = browser.params; 4 | var UserModel = require(config.serverConfig.root + '/server/api/user/user.model'); 5 | 6 | describe('Logout View', function() { 7 | var login = function(user) { 8 | let promise = browser.get(config.baseUrl + '/login'); 9 | require('../login/login.po').login(user); 10 | return promise; 11 | }; 12 | 13 | var testUser = { 14 | name: 'Test User', 15 | email: 'test@example.com', 16 | password: 'test' 17 | }; 18 | 19 | beforeEach(function() { 20 | return UserModel 21 | .removeAsync() 22 | .then(function() { 23 | return UserModel.createAsync(testUser); 24 | }) 25 | .then(function() { 26 | return login(testUser); 27 | }); 28 | }); 29 | 30 | after(function() { 31 | return UserModel.removeAsync(); 32 | }) 33 | 34 | describe('with local auth', function() { 35 | 36 | it('should logout a user and redirecting to "/"', function() { 37 | var navbar = require('../../components/navbar/navbar.po'); 38 | 39 | expect(browser.getCurrentUrl()).to.eventually.equal(config.baseUrl + '/'); 40 | expect(navbar.navbarAccountGreeting.getText()).to.eventually.equal('Hello ' + testUser.name); 41 | 42 | browser.get(config.baseUrl + '/logout'); 43 | 44 | navbar = require('../../components/navbar/navbar.po'); 45 | 46 | expect(browser.getCurrentUrl()).to.eventually.equal(config.baseUrl + '/'); 47 | expect(navbar.navbarAccountGreeting.isDisplayed()).to.eventually.equal(false); 48 | }); 49 | 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /client/app/product/product.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('bhcmartApp') 4 | .controller('ProductCtrl', ['$scope', '$stateParams', '$state', 'Product', 5 | function($scope, $stateParams, $state, Product) { 6 | // Upsell Products 7 | Product.catalog({ id: 'upsell-products', limit: 6 }, function(upsellProducts) { 8 | $scope.upsellProducts = _.map(upsellProducts, upsellProduct => _.extend(upsellProduct, { averageRating: getAverageRating(upsellProduct) })); 9 | }); 10 | 11 | //Get product and fetch related products based on category 12 | $scope.product = Product.get({ id: $stateParams.id }, function(p) { 13 | $scope.product.averageRating = getAverageRating(p); 14 | Product.catalog({ id: p.categories[0].slug, limit: 6 }, function(relatedProducts) { 15 | $scope.relatedProducts = _.filter( 16 | _.map(relatedProducts, relatedProduct => 17 | _.extend(relatedProduct, { averageRating: getAverageRating(relatedProduct) })), rp => rp._id != p._id); 18 | }); 19 | }); 20 | 21 | 22 | $scope.addReview = function(review, productId) { 23 | Product.review({ id: productId }, review, function(resp) { 24 | $scope.product.reviews.push(resp); 25 | $scope.review = { rating: 5 }; 26 | $scope.message = "Review added successfully" 27 | }, function(err) { 28 | console.log(err) 29 | $scope.message = "An error occured!" 30 | }); 31 | } 32 | } 33 | ]); 34 | 35 | let getAverageRating = p => Math.ceil(_.reduce(p.reviews, (a, b) => a + b.rating, 0) / p.reviews.length); 36 | -------------------------------------------------------------------------------- /server/api/product/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'); 4 | var controller = require('./product.controller'); 5 | var multiparty = require('connect-multiparty'); 6 | var uploadOptions = { autoFile: true, 7 | uploadDir: 'client/assets/uploads/' 8 | } 9 | 10 | var router = express.Router(); 11 | 12 | // product 13 | router.post('/:id/upload', multiparty(uploadOptions), controller.upload); 14 | router.get('/', controller.index); 15 | router.get('/:slug', controller.show); 16 | router.post('/', controller.create); 17 | router.put('/:id', controller.update); 18 | router.patch('/:id', controller.update); 19 | router.delete('/:id', controller.destroy); 20 | router.get('/:slug/catalog/:limit', controller.catalog); 21 | router.get('/:slug/search/:term', controller.search); 22 | 23 | //image 24 | router.post('/:id/images', multiparty(uploadOptions), controller.uploadImage); 25 | router.get('/:id/images', controller.indexImage); 26 | router.put('/:id/images/:image_id', controller.updateImage); 27 | 28 | // Variants 29 | router.post('/:id/variants', controller.createVariant); 30 | router.get('/:id/variants', controller.indexVariant); 31 | router.put('/:id/variants/:variant_id', controller.updateVariant); 32 | router.patch('/:id/variants/:variant_id', controller.updateVariant); 33 | router.delete('/:id/variants/:variant_id', controller.destroyVariant); 34 | 35 | // Reviews 36 | router.post('/:id/reviews', controller.createReview); 37 | router.get('/:id/reviews', controller.indexReview); 38 | router.put('/:id/reviews/:review_id', controller.updateReview); 39 | router.patch('/:id/reviews/:review_id', controller.updateReview); 40 | 41 | 42 | module.exports = router; 43 | -------------------------------------------------------------------------------- /client/assets/css/owl.carousel.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Core Owl Carousel CSS File 3 | * v1.3.3 4 | */ 5 | 6 | /* clearfix */ 7 | .owl-carousel .owl-wrapper:after { 8 | content: "."; 9 | display: block; 10 | clear: both; 11 | visibility: hidden; 12 | line-height: 0; 13 | height: 0; 14 | } 15 | /* display none until init */ 16 | .owl-carousel{ 17 | display: none; 18 | position: relative; 19 | width: 100%; 20 | -ms-touch-action: pan-y; 21 | } 22 | .owl-carousel .owl-wrapper{ 23 | display: none; 24 | position: relative; 25 | -webkit-transform: translate3d(0px, 0px, 0px); 26 | } 27 | .owl-carousel .owl-wrapper-outer{ 28 | overflow: hidden; 29 | position: relative; 30 | width: 100%; 31 | } 32 | .owl-carousel .owl-wrapper-outer.autoHeight{ 33 | -webkit-transition: height 500ms ease-in-out; 34 | -moz-transition: height 500ms ease-in-out; 35 | -ms-transition: height 500ms ease-in-out; 36 | -o-transition: height 500ms ease-in-out; 37 | transition: height 500ms ease-in-out; 38 | } 39 | 40 | .owl-carousel .owl-item{ 41 | float: left; 42 | } 43 | .owl-controls .owl-page, 44 | .owl-controls .owl-buttons div{ 45 | cursor: pointer; 46 | } 47 | .owl-controls { 48 | -webkit-user-select: none; 49 | -khtml-user-select: none; 50 | -moz-user-select: none; 51 | -ms-user-select: none; 52 | user-select: none; 53 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 54 | } 55 | 56 | 57 | /* fix */ 58 | .owl-carousel .owl-wrapper, 59 | .owl-carousel .owl-item{ 60 | -webkit-backface-visibility: hidden; 61 | -moz-backface-visibility: hidden; 62 | -ms-backface-visibility: hidden; 63 | -webkit-transform: translate3d(0,0,0); 64 | -moz-transform: translate3d(0,0,0); 65 | -ms-transform: translate3d(0,0,0); 66 | } 67 | 68 | -------------------------------------------------------------------------------- /server/api/product/product.model.spec.js: -------------------------------------------------------------------------------- 1 | var Product = require('./product.model.js').product; 2 | 3 | describe('Product', function() { 4 | beforeEach(function(done){ 5 | Product.remove(done); // remove all data 6 | }); 7 | 8 | it('should not create without title', function(done) { 9 | Product.create({price: 123.45}, function(err){ 10 | err.should.not.be.empty; 11 | done(); 12 | }); 13 | }); 14 | 15 | it('should remove trailing spaces from title', function(done){ 16 | Product.create({title: ' no space ', price: 123}, 17 | productShouldHave('title', 'no space', done)); 18 | }); 19 | 20 | it('should default stock to 1', function(done){ 21 | Product.create({title: 'title', price: 123}, 22 | productShouldHave('stock', 1, done)); 23 | }); 24 | 25 | it('should not create without price', function(done) { 26 | Product.create({title: 'no price'}, function(err){ 27 | err.should.not.be.empty; 28 | done(); 29 | }); 30 | }); 31 | 32 | it('should not allow negative price', function(done) { 33 | Product.create({title: 'title', price: -123}, function(err){ 34 | err.should.not.be.empty; 35 | done(); 36 | }); 37 | }); 38 | 39 | it('should save a description', function(done){ 40 | Product.create({title: 'title', price: 123, description: 'le description'}, 41 | productShouldHave('description', 'le description', done)); 42 | }); 43 | }); 44 | 45 | function productShouldHave(name, value, done){ 46 | return function(err){ 47 | if(err) done(err); 48 | 49 | Product.findOne({}, function(err, product){ 50 | if(err) done(err); 51 | product.should.have.property(name, value); 52 | done(); 53 | }); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /server/api/user/user.integration.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import app from '../..'; 4 | import User from './user.model'; 5 | import request from 'supertest'; 6 | 7 | describe('User API:', function() { 8 | var user; 9 | 10 | // Clear users before testing 11 | before(function() { 12 | return User.removeAsync().then(function() { 13 | user = new User({ 14 | name: 'Fake User', 15 | email: 'test@example.com', 16 | password: 'password' 17 | }); 18 | 19 | return user.saveAsync(); 20 | }); 21 | }); 22 | 23 | // Clear users after testing 24 | after(function() { 25 | return User.removeAsync(); 26 | }); 27 | 28 | describe('GET /api/users/me', function() { 29 | var token; 30 | 31 | before(function(done) { 32 | request(app) 33 | .post('/auth/local') 34 | .send({ 35 | email: 'test@example.com', 36 | password: 'password' 37 | }) 38 | .expect(200) 39 | .expect('Content-Type', /json/) 40 | .end((err, res) => { 41 | token = res.body.token; 42 | done(); 43 | }); 44 | }); 45 | 46 | it('should respond with a user profile when authenticated', function(done) { 47 | request(app) 48 | .get('/api/users/me') 49 | .set('authorization', 'Bearer ' + token) 50 | .expect(200) 51 | .expect('Content-Type', /json/) 52 | .end((err, res) => { 53 | expect(res.body._id.toString()).to.equal(user._id.toString()); 54 | done(); 55 | }); 56 | }); 57 | 58 | it('should respond with a 401 when not authenticated', function(done) { 59 | request(app) 60 | .get('/api/users/me') 61 | .expect(401) 62 | .end(done); 63 | }); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /server/data/reviews.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "_id": "56f6d0b2d747e8b59b772d24", 3 | "title": "Test Review 101", 4 | "content": "uild process packs ", 5 | "by": "emeka", 6 | "rating": 4 7 | }, { 8 | "_id": "56f6d0b2d747e8b59b772d25", 9 | "title": "Test Review 91", 10 | "content": "uild process packs ", 11 | "by": "Jane", 12 | "rating": 2 13 | }, { 14 | "_id": "56f6d0b2d747e8b59b772d26", 15 | "title": "Test Review 81", 16 | "content": "uild process packs ", 17 | "by": "Andrew", 18 | "rating": 3 19 | }, { 20 | "_id": "56f6d0b2d747e8b59b772d27", 21 | "title": "Test Review 71", 22 | "content": "uild process packs ", 23 | "by": "Sameul", 24 | "rating": 2 25 | }, { 26 | "_id": "56f6d0b2d747e8b59b772d28", 27 | "title": "Test Review 61", 28 | "content": "uild process packs ", 29 | "by": "Stanley", 30 | "rating": 2 31 | }, { 32 | "_id": "56f6d0b2d747e8b59b772d29", 33 | "title": "Test Review 51", 34 | "content": "uild process packs ", 35 | "by": "My Man", 36 | "rating": 5 37 | }, { 38 | "_id": "56f6d0b2d747e8b59b772d2a", 39 | "title": "Test Review 41", 40 | "content": "uild process packs ", 41 | "by": "Abuja Guy", 42 | "rating": 4 43 | }, { 44 | "_id": "56f6d0b2d747e8b59b772d2b", 45 | "title": "Test Review 31", 46 | "content": "uild process packs ", 47 | "by": "Ramza", 48 | "rating": 4 49 | }, { 50 | "_id": "56f6d0b2d747e8b59b772d2c", 51 | "title": "Test Review 21", 52 | "content": "uild process packs ", 53 | "by": "Chitech", 54 | "rating": 4 55 | }, { 56 | "_id": "56f6d0b2d747e8b59b772d2d", 57 | "title": "Test Review 11", 58 | "content": "uild process packs ", 59 | "by": "Toystar", 60 | "rating": 3 61 | }, { 62 | "_id": "56f6d0b2d747e8b59b772d2e", 63 | "title": "Test Review 01", 64 | "content": "uild process packs ", 65 | "by": "Peerwaya", 66 | "rating": 2 67 | }] 68 | -------------------------------------------------------------------------------- /client/components/oauth-buttons/oauth-buttons.directive.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Directive: oauthButtons', function() { 4 | 5 | // load the directive's module and view 6 | beforeEach(module('bhcmartApp')); 7 | beforeEach(module('components/oauth-buttons/oauth-buttons.html')); 8 | 9 | var element, parentScope, elementScope; 10 | 11 | var compileDirective = function(template) { 12 | inject(function($compile) { 13 | element = angular.element(template); 14 | element = $compile(element)(parentScope); 15 | parentScope.$digest(); 16 | elementScope = element.isolateScope(); 17 | }); 18 | }; 19 | 20 | beforeEach(inject(function($rootScope) { 21 | parentScope = $rootScope.$new(); 22 | })); 23 | 24 | it('should contain anchor buttons', function() { 25 | compileDirective(''); 26 | expect(element.find('a.btn.btn-social').length).to.be.at.least(1); 27 | }); 28 | 29 | it('should evaluate and bind the classes attribute to scope.classes', function() { 30 | parentScope.scopedClass = 'scopedClass1'; 31 | compileDirective(''); 32 | expect(elementScope.classes).to.equal('testClass1 scopedClass1'); 33 | }); 34 | 35 | it('should bind scope.classes to class names on the anchor buttons', function() { 36 | compileDirective(''); 37 | // Add classes 38 | elementScope.classes = 'testClass1 testClass2'; 39 | elementScope.$digest(); 40 | expect(element.find('a.btn.btn-social.testClass1.testClass2').length).to.be.at.least(1); 41 | 42 | // Remove classes 43 | elementScope.classes = ''; 44 | elementScope.$digest(); 45 | expect(element.find('a.btn.btn-social.testClass1.testClass2').length).to.equal(0); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "excludeFiles": [ 3 | "client/app/app.constant.js" 4 | ], 5 | "esnext": true, 6 | "maximumLineLength": { 7 | "value": 100, 8 | "allowComments": true, 9 | "allowRegex": true 10 | }, 11 | "disallowMixedSpacesAndTabs": true, 12 | "disallowMultipleLineStrings": true, 13 | "disallowNewlineBeforeBlockStatements": true, 14 | "disallowSpaceAfterObjectKeys": true, 15 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], 16 | "disallowSpaceBeforeBinaryOperators": [","], 17 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], 18 | "disallowSpacesInAnonymousFunctionExpression": { 19 | "beforeOpeningRoundBrace": true 20 | }, 21 | "disallowSpacesInFunctionDeclaration": { 22 | "beforeOpeningRoundBrace": true 23 | }, 24 | "disallowSpacesInNamedFunctionExpression": { 25 | "beforeOpeningRoundBrace": true 26 | }, 27 | "disallowSpacesInsideArrayBrackets": true, 28 | "disallowSpacesInsideParentheses": true, 29 | "disallowTrailingComma": true, 30 | "disallowTrailingWhitespace": true, 31 | "requireCommaBeforeLineBreak": true, 32 | "requireLineFeedAtFileEnd": true, 33 | "requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"], 34 | "requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"], 35 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"], 36 | "requireSpaceBeforeBlockStatements": true, 37 | "requireSpacesInConditionalExpression": { 38 | "afterTest": true, 39 | "beforeConsequent": true, 40 | "afterConsequent": true, 41 | "beforeAlternate": true 42 | }, 43 | "requireSpacesInFunction": { 44 | "beforeOpeningCurlyBrace": true 45 | }, 46 | "validateLineBreaks": "LF", 47 | "validateParameterSeparator": ", " 48 | } 49 | -------------------------------------------------------------------------------- /client/app/manage-categories/manage-categories-add.html: -------------------------------------------------------------------------------- 1 | 2 | 14 |
15 |
16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 | 24 | 25 |

26 | Name is required 27 |

28 |
29 |
30 | 31 | 34 |
35 |

{{ message }}

36 | 37 |
38 |
39 |
40 |
41 |
42 | 43 | -------------------------------------------------------------------------------- /server/api/product/product.events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Product model events 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var EventEmitter = require('events').EventEmitter; 8 | var Product = require('./product.model').product; 9 | var Image = require('./product.model').image; 10 | var Review = require('./product.model').review; 11 | var Variant = require('./product.model').variant; 12 | 13 | var ProductEvents = new EventEmitter(); 14 | var ImageEvents = new EventEmitter(); 15 | var ReviewEvents = new EventEmitter(); 16 | var VariantEvents = new EventEmitter(); 17 | 18 | 19 | // Set max event listeners (0 == unlimited) 20 | ProductEvents.setMaxListeners(0); 21 | ImageEvents.setMaxListeners(0); 22 | ReviewEvents.setMaxListeners(0); 23 | VariantEvents.setMaxListeners(0); 24 | 25 | // Model events 26 | var events = { 27 | 'save': 'save', 28 | 'remove': 'remove' 29 | }; 30 | 31 | function emitEvent(event, ModelEvents) { 32 | return function(doc) { 33 | ModelEvents.emit(event + ':' + doc._id, doc); 34 | ModelEvents.emit(event, doc); 35 | } 36 | } 37 | 38 | // Register the event emitter to the model events 39 | for (var e in events) { 40 | var event = events[e]; 41 | Product.schema.post(e, emitEvent(event, ProductEvents)); 42 | } 43 | 44 | // Register the event emitter to the model events 45 | for (var e in events) { 46 | var event = events[e]; 47 | Image.schema.post(e, emitEvent(event, ImageEvents)); 48 | } 49 | // Register the event emitter to the model events 50 | for (var e in events) { 51 | var event = events[e]; 52 | Review.schema.post(e, emitEvent(event, ReviewEvents)); 53 | } 54 | // Register the event emitter to the model events 55 | for (var e in events) { 56 | var event = events[e]; 57 | Variant.schema.post(e, emitEvent(event, VariantEvents)); 58 | } 59 | 60 | module.exports = { 61 | product: ProductEvents, 62 | image: ImageEvents, 63 | review: ReviewEvents, 64 | variant: VariantEvents 65 | }; 66 | -------------------------------------------------------------------------------- /server/api/user/user.model.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import app from '../..'; 4 | import User from './user.model'; 5 | var user; 6 | var genUser = function() { 7 | user = new User({ 8 | provider: 'local', 9 | name: 'Fake User', 10 | email: 'test@example.com', 11 | password: 'password' 12 | }); 13 | return user; 14 | }; 15 | 16 | describe('User Model', function() { 17 | before(function() { 18 | // Clear users before testing 19 | return User.removeAsync(); 20 | }); 21 | 22 | beforeEach(function() { 23 | genUser(); 24 | }); 25 | 26 | afterEach(function() { 27 | return User.removeAsync(); 28 | }); 29 | 30 | it('should begin with no users', function() { 31 | return expect(User.findAsync({})).to 32 | .eventually.have.length(0); 33 | }); 34 | 35 | it('should fail when saving a duplicate user', function() { 36 | return expect(user.saveAsync() 37 | .then(function() { 38 | var userDup = genUser(); 39 | return userDup.saveAsync(); 40 | })).to.be.rejected; 41 | }); 42 | 43 | describe('#email', function() { 44 | it('should fail when saving without an email', function() { 45 | user.email = ''; 46 | return expect(user.saveAsync()).to.be.rejected; 47 | }); 48 | }); 49 | 50 | describe('#password', function() { 51 | beforeEach(function() { 52 | return user.saveAsync(); 53 | }); 54 | 55 | it('should authenticate user if valid', function() { 56 | expect(user.authenticate('password')).to.be.true; 57 | }); 58 | 59 | it('should not authenticate user if invalid', function() { 60 | expect(user.authenticate('blah')).to.not.be.true; 61 | }); 62 | 63 | it('should remain the same hash unless the password is updated', function() { 64 | user.name = 'Test User'; 65 | return expect(user.saveAsync() 66 | .spread(function(u) { 67 | return u.authenticate('password'); 68 | })).to.eventually.be.true; 69 | }); 70 | }); 71 | 72 | }); 73 | -------------------------------------------------------------------------------- /server/config/environment/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var _ = require('lodash'); 5 | 6 | function requiredProcessEnv(name) { 7 | if (!process.env[name]) { 8 | throw new Error('You must set the ' + name + ' environment variable'); 9 | } 10 | return process.env[name]; 11 | } 12 | 13 | // All configurations will extend these options 14 | // ============================================ 15 | var all = { 16 | env: process.env.NODE_ENV, 17 | 18 | // Root path of server 19 | root: path.normalize(__dirname + '/../../..'), 20 | 21 | // Server port 22 | port: process.env.PORT || 9000, 23 | 24 | // Server IP 25 | ip: process.env.IP || '0.0.0.0', 26 | 27 | // Should we populate the DB with sample data? 28 | seedDB: false, 29 | 30 | // Secret for session, you will want to change this and make it an environment variable 31 | secrets: { 32 | session: process.env.SESSION_SECRET || 'secret' 33 | }, 34 | 35 | // MongoDB connection options 36 | mongo: { 37 | options: { 38 | db: { 39 | safe: true 40 | } 41 | } 42 | }, 43 | 44 | facebook: { 45 | clientID: process.env.FACEBOOK_ID || 'id', 46 | clientSecret: process.env.FACEBOOK_SECRET || 'secret', 47 | callbackURL: (process.env.DOMAIN || '') + '/auth/facebook/callback' 48 | }, 49 | 50 | twitter: { 51 | clientID: process.env.TWITTER_ID || 'id', 52 | clientSecret: process.env.TWITTER_SECRET || 'secret', 53 | callbackURL: (process.env.DOMAIN || '') + '/auth/twitter/callback' 54 | }, 55 | 56 | google: { 57 | clientID: process.env.GOOGLE_ID || 'id', 58 | clientSecret: process.env.GOOGLE_SECRET || 'secret', 59 | callbackURL: (process.env.DOMAIN || '') + '/auth/google/callback' 60 | } 61 | }; 62 | 63 | // Export the config object based on the NODE_ENV 64 | // ============================================== 65 | module.exports = _.merge( 66 | all, 67 | require('./shared'), 68 | require('./' + process.env.NODE_ENV + '.js') || {}); 69 | -------------------------------------------------------------------------------- /client/app/manage-categories/manage-categories-edit.html: -------------------------------------------------------------------------------- 1 | 2 | 14 |
15 |
16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 | 24 | 25 |

26 | Name is required 27 |

28 |
29 |
30 | 31 | 34 |
35 |

{{ vm.message }}

36 | 37 |
38 |
39 |
40 |
41 |
42 | 43 | -------------------------------------------------------------------------------- /client/assets/css/owl.theme.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Owl Carousel Owl Demo Theme 3 | * v1.3.3 4 | */ 5 | 6 | .owl-theme .owl-controls{ 7 | margin-top: 10px; 8 | text-align: center; 9 | } 10 | 11 | /* Styling Next and Prev buttons */ 12 | 13 | .owl-theme .owl-controls .owl-buttons div{ 14 | color: #FFF; 15 | display: inline-block; 16 | zoom: 1; 17 | *display: inline;/*IE7 life-saver */ 18 | margin: 5px; 19 | padding: 3px 10px; 20 | font-size: 12px; 21 | -webkit-border-radius: 30px; 22 | -moz-border-radius: 30px; 23 | border-radius: 30px; 24 | background: #869791; 25 | filter: Alpha(Opacity=50);/*IE7 fix*/ 26 | opacity: 0.5; 27 | } 28 | /* Clickable class fix problem with hover on touch devices */ 29 | /* Use it for non-touch hover action */ 30 | .owl-theme .owl-controls.clickable .owl-buttons div:hover{ 31 | filter: Alpha(Opacity=100);/*IE7 fix*/ 32 | opacity: 1; 33 | text-decoration: none; 34 | } 35 | 36 | /* Styling Pagination*/ 37 | 38 | .owl-theme .owl-controls .owl-page{ 39 | display: inline-block; 40 | zoom: 1; 41 | *display: inline;/*IE7 life-saver */ 42 | } 43 | .owl-theme .owl-controls .owl-page span{ 44 | display: block; 45 | width: 12px; 46 | height: 12px; 47 | margin: 5px 7px; 48 | filter: Alpha(Opacity=50);/*IE7 fix*/ 49 | opacity: 0.5; 50 | -webkit-border-radius: 20px; 51 | -moz-border-radius: 20px; 52 | border-radius: 20px; 53 | background: #869791; 54 | } 55 | 56 | .owl-theme .owl-controls .owl-page.active span, 57 | .owl-theme .owl-controls.clickable .owl-page:hover span{ 58 | filter: Alpha(Opacity=100);/*IE7 fix*/ 59 | opacity: 1; 60 | } 61 | 62 | /* If PaginationNumbers is true */ 63 | 64 | .owl-theme .owl-controls .owl-page span.owl-numbers{ 65 | height: auto; 66 | width: auto; 67 | color: #FFF; 68 | padding: 2px 10px; 69 | font-size: 12px; 70 | -webkit-border-radius: 30px; 71 | -moz-border-radius: 30px; 72 | border-radius: 30px; 73 | } 74 | 75 | /* preloading images */ 76 | .owl-item.loading{ 77 | min-height: 150px; 78 | background: url(AjaxLoader.gif) no-repeat center center 79 | } -------------------------------------------------------------------------------- /client/assets/js/jquery.scrollUp.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * scrollup v2.4.1 3 | * Url: http://markgoodyear.com/labs/scrollup/ 4 | * Copyright (c) Mark Goodyear — @markgdyr — http://markgoodyear.com 5 | * License: MIT 6 | */ 7 | !function(l,o,e){"use strict";l.fn.scrollUp=function(o){l.data(e.body,"scrollUp")||(l.data(e.body,"scrollUp",!0),l.fn.scrollUp.init(o))},l.fn.scrollUp.init=function(r){var s,t,c,i,n,a,d,p=l.fn.scrollUp.settings=l.extend({},l.fn.scrollUp.defaults,r),f=!1;switch(d=p.scrollTrigger?l(p.scrollTrigger):l("",{id:p.scrollName,href:"#top"}),p.scrollTitle&&d.attr("title",p.scrollTitle),d.appendTo("body"),p.scrollImg||p.scrollTrigger||d.html(p.scrollText),d.css({display:"none",position:"fixed",zIndex:p.zIndex}),p.activeOverlay&&l("
",{id:p.scrollName+"-active"}).css({position:"absolute",top:p.scrollDistance+"px",width:"100%",borderTop:"1px dotted"+p.activeOverlay,zIndex:p.zIndex}).appendTo("body"),p.animation){case"fade":s="fadeIn",t="fadeOut",c=p.animationSpeed;break;case"slide":s="slideDown",t="slideUp",c=p.animationSpeed;break;default:s="show",t="hide",c=0}i="top"===p.scrollFrom?p.scrollDistance:l(e).height()-l(o).height()-p.scrollDistance,n=l(o).scroll(function(){l(o).scrollTop()>i?f||(d[s](c),f=!0):f&&(d[t](c),f=!1)}),p.scrollTarget?"number"==typeof p.scrollTarget?a=p.scrollTarget:"string"==typeof p.scrollTarget&&(a=Math.floor(l(p.scrollTarget).offset().top)):a=0,d.click(function(o){o.preventDefault(),l("html, body").animate({scrollTop:a},p.scrollSpeed,p.easingType)})},l.fn.scrollUp.defaults={scrollName:"scrollUp",scrollDistance:300,scrollFrom:"top",scrollSpeed:300,easingType:"linear",animation:"fade",animationSpeed:200,scrollTrigger:!1,scrollTarget:!1,scrollText:"Scroll to top",scrollTitle:!1,scrollImg:!1,activeOverlay:!1,zIndex:2147483647},l.fn.scrollUp.destroy=function(r){l.removeData(e.body,"scrollUp"),l("#"+l.fn.scrollUp.settings.scrollName).remove(),l("#"+l.fn.scrollUp.settings.scrollName+"-active").remove(),l.fn.jquery.split(".")[1]>=7?l(o).off("scroll",r):l(o).unbind("scroll",r)},l.scrollUp=l.fn.scrollUp}(jQuery,window,document); -------------------------------------------------------------------------------- /client/app/app.scss: -------------------------------------------------------------------------------- 1 | $icon-font-path: "../bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/"; 2 | @import '../bower_components/bootstrap-sass-official/vendor/assets/stylesheets/bootstrap'; 3 | @import '../bower_components/bootstrap-social/bootstrap-social.scss'; 4 | $fa-font-path: "../bower_components/font-awesome/fonts"; 5 | @import '../bower_components/font-awesome/scss/font-awesome'; 6 | 7 | /** 8 | * App-wide Styles 9 | */ 10 | 11 | .browserupgrade { 12 | margin: 0.2em 0; 13 | background: #ccc; 14 | color: #000; 15 | padding: 0.2em 0; 16 | } 17 | 18 | .thumb { 19 | width: 100px; 20 | height: 100px; 21 | float: none; 22 | position: relative; 23 | top: 7px; 24 | margin-bottom: 20px; 25 | } 26 | 27 | form .progress { 28 | line-height: 15px; 29 | } 30 | 31 | .remove-btn { 32 | padding-top: 20px; 33 | } 34 | 35 | .form-action.account { 36 | display: flex; 37 | } 38 | 39 | .table-col td { 40 | line-height: 25px !important; 41 | } 42 | 43 | 44 | .product-grid ul#category { 45 | margin-top: -102px !important; 46 | position: initial !important; 47 | width: 100% !important; 48 | } 49 | 50 | // Component styles are injected through grunt 51 | // injector 52 | @import 'about/about.scss'; 53 | @import 'admin/admin.scss'; 54 | @import 'cart/cart.scss'; 55 | @import 'category/category.scss'; 56 | @import 'checkout/checkout.scss'; 57 | @import 'contact/contact.scss'; 58 | @import 'invoice/invoice.scss'; 59 | @import 'main/main.scss'; 60 | @import 'manage-categories/manage-categories.scss'; 61 | @import 'manage-products/manage-products.scss'; 62 | @import 'manage-requests/manage-requests.scss'; 63 | @import 'orders/orders.scss'; 64 | @import 'product/product.scss'; 65 | @import 'search/search.scss'; 66 | @import '../components/footer/footer.scss'; 67 | @import '../components/modal/modal.scss'; 68 | @import '../components/oauth-buttons/oauth-buttons.scss'; 69 | @import '../components/sidebar-account/sidebar-account.scss'; 70 | @import '../components/sidebar-cat/sidebar-cat.scss'; 71 | // endinjector 72 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-angular-fullstack": { 3 | "generatorVersion": "3.2.0", 4 | "endpointDirectory": "server/api/", 5 | "insertRoutes": true, 6 | "registerRoutesFile": "server/routes.js", 7 | "routesNeedle": "// Insert routes below", 8 | "routesBase": "/api/", 9 | "pluralizeRoutes": true, 10 | "insertSockets": true, 11 | "registerSocketsFile": "server/config/socketio.js", 12 | "socketsNeedle": "// Insert sockets below", 13 | "insertModels": true, 14 | "registerModelsFile": "server/sqldb/index.js", 15 | "modelsNeedle": "// Insert models below", 16 | "filters": { 17 | "js": true, 18 | "babel": true, 19 | "html": true, 20 | "sass": true, 21 | "uirouter": true, 22 | "bootstrap": true, 23 | "uibootstrap": true, 24 | "socketio": true, 25 | "auth": true, 26 | "models": true, 27 | "mongooseModels": true, 28 | "mongoose": true, 29 | "oauth": true, 30 | "googleAuth": true, 31 | "facebookAuth": true, 32 | "twitterAuth": true, 33 | "grunt": true, 34 | "gulp": false, 35 | "mocha": true, 36 | "jasmine": false, 37 | "should": false, 38 | "expect": true 39 | } 40 | }, 41 | "generator-ng-component": { 42 | "routeDirectory": "client/app/", 43 | "directiveDirectory": "client/app/", 44 | "filterDirectory": "client/app/", 45 | "serviceDirectory": "client/app/", 46 | "basePath": "client", 47 | "moduleName": "", 48 | "filters": [ 49 | "uirouter", 50 | "mocha", 51 | "expect", 52 | "uirouter" 53 | ], 54 | "extensions": [ 55 | "babel", 56 | "js", 57 | "html", 58 | "scss" 59 | ], 60 | "directiveSimpleTemplates": "", 61 | "directiveComplexTemplates": "", 62 | "filterTemplates": "", 63 | "serviceTemplates": "", 64 | "factoryTemplates": "", 65 | "controllerTemplates": "", 66 | "decoratorTemplates": "", 67 | "providerTemplates": "", 68 | "routeTemplates": "" 69 | } 70 | } --------------------------------------------------------------------------------