├── .bowerrc ├── .buildignore ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jscs.json ├── .project ├── .travis.yml ├── .yo-rc.json ├── Gruntfile.js ├── README.md ├── bower.json ├── client ├── .jshintrc ├── app │ ├── admin │ │ ├── admin.controller.js │ │ ├── admin.css │ │ ├── admin.html │ │ └── admin.js │ ├── app.css │ ├── app.js │ ├── cart │ │ ├── cart.html │ │ └── cart.js │ ├── common │ │ ├── directives │ │ │ ├── spinner │ │ │ │ └── spinner-directive.js │ │ │ ├── sw.editable.js │ │ │ ├── sw.integer.price.js │ │ │ ├── sw.loading.js │ │ │ ├── sw.money.input.js │ │ │ ├── templates │ │ │ │ └── sw.editable.html │ │ │ └── valid.number.js │ │ └── service │ │ │ └── util.js │ ├── interceptor │ │ ├── auth.interceptor.js │ │ └── error.interceptor.js │ ├── item │ │ ├── directive │ │ │ ├── item.directive.controller.js │ │ │ ├── item.directive.html │ │ │ └── item.directive.js │ │ ├── item.controller.js │ │ ├── item.html │ │ ├── item.js │ │ ├── item.service.new.js │ │ ├── item.shared.service.js │ │ ├── item.transformator.js │ │ └── search │ │ │ ├── partials │ │ │ ├── exteriors.html │ │ │ ├── horizontal.facet.html │ │ │ ├── price.html │ │ │ └── weapon.type.html │ │ │ ├── search.controller.js │ │ │ ├── search.html │ │ │ ├── search.js │ │ │ ├── search.param.resource.js │ │ │ ├── search.result.controller.js │ │ │ └── search.result.html │ ├── main │ │ ├── how_it_works.html │ │ ├── jquery.scrollTo.js │ │ ├── main.controller.js │ │ ├── main.html │ │ ├── main.js │ │ ├── privacy.html │ │ └── terms.html │ ├── payment │ │ ├── deposit.money.controller.js │ │ ├── deposit.money.html │ │ ├── payment.js │ │ └── paypal.service.js │ └── user │ │ ├── dashboard │ │ ├── dashboard.ctrl.js │ │ ├── dashboard.html │ │ ├── sell.skin.ctrl.js │ │ └── sell.skin.modal.html │ │ ├── directive │ │ └── badges │ │ │ ├── badges.directive.controller.js │ │ │ ├── badges.directive.js │ │ │ └── badges.template.html │ │ ├── inventory │ │ ├── inventory.ctrl.js │ │ └── inventory.html │ │ ├── login │ │ ├── login.controller.js │ │ ├── login.css │ │ └── login.html │ │ ├── profile │ │ ├── profile.controller.js │ │ └── profile.html │ │ ├── settings │ │ ├── settings.controller.js │ │ └── settings.html │ │ ├── signup │ │ ├── signup.controller.js │ │ └── signup.html │ │ ├── statement │ │ ├── statement.controller.js │ │ └── statement.html │ │ ├── user.js │ │ ├── user.service.js │ │ ├── util.js │ │ └── withdrawal │ │ ├── withdrawal.controller.js │ │ └── withdrawals.html ├── assets │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ └── images │ │ ├── badges │ │ ├── Beta-tester-B.png │ │ ├── bought1.png │ │ ├── bought2.png │ │ ├── bought3.png │ │ ├── bought4.png │ │ ├── bought5.png │ │ ├── premium.png │ │ ├── referal1.png │ │ ├── referal2.png │ │ ├── referal3.png │ │ ├── referal4.png │ │ ├── referal5.png │ │ ├── sale1.png │ │ ├── sale2.png │ │ ├── sale3.png │ │ ├── sale4.png │ │ ├── sale5.png │ │ ├── staff.png │ │ ├── tsr1.png │ │ ├── tsr2.png │ │ ├── tsr3.png │ │ ├── tsr4.png │ │ └── tsr5.png │ │ ├── bg.jpg │ │ ├── help_desk.png │ │ ├── hiw │ │ └── 1.jpg │ │ ├── knife.png │ │ ├── logo.jpg │ │ ├── logo.png │ │ ├── midb.jpg │ │ ├── pattern.jpg │ │ ├── paymentsf.png │ │ ├── paypal.png │ │ ├── ripple.svg │ │ ├── search.png │ │ ├── skrill.jpg │ │ ├── steam_signin.png │ │ ├── ui.totop.png │ │ └── weapon-icons │ │ ├── case.png │ │ ├── cases │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.png │ │ ├── heavy.png │ │ ├── heavy │ │ ├── M249.png │ │ ├── MAG-7.png │ │ ├── MAG7.png │ │ ├── Negev.png │ │ ├── Nova.png │ │ ├── Sawed-Off.png │ │ ├── Sawedoff.png │ │ └── XM1014.png │ │ ├── key.png │ │ ├── knife.png │ │ ├── knife │ │ ├── bayonet.png │ │ ├── bowie.png │ │ ├── butterfly.png │ │ ├── butterflyknife.png │ │ ├── falchion.png │ │ ├── falchion_knife.png │ │ ├── flip.png │ │ ├── flipknife.png │ │ ├── gutknife.png │ │ ├── huntsman.png │ │ ├── huntsmanknife.png │ │ ├── karambit.png │ │ ├── m9bayonet.png │ │ └── shadow.png │ │ ├── pistol.png │ │ ├── pistols │ │ ├── CZ75-Auto.png │ │ ├── CZ75auto.png │ │ ├── Desert Eagle.png │ │ ├── Deserteagle.png │ │ ├── Dual Berettas.png │ │ ├── Dualberettas.png │ │ ├── Five-SeveN.png │ │ ├── Fiveseven.png │ │ ├── Glock-18.png │ │ ├── Glock18.png │ │ ├── P2000.png │ │ ├── P250.png │ │ ├── Tec-9.png │ │ ├── Tec9.png │ │ ├── USP-S.png │ │ └── USP.png │ │ ├── rifle.png │ │ ├── rifle │ │ ├── AK-47.png │ │ ├── AUG.png │ │ ├── AWP.png │ │ ├── FAMAS.png │ │ ├── G3SG1.png │ │ ├── Galil AR.png │ │ ├── Galilar.png │ │ ├── M4A1-S.png │ │ ├── M4A4.png │ │ ├── SCAR-20.png │ │ ├── SG 553.png │ │ ├── SG553.png │ │ ├── SSG 08.png │ │ └── SSG08.png │ │ ├── shotgun.png │ │ ├── smg.png │ │ └── smg │ │ ├── MAC-10.png │ │ ├── MP7.png │ │ ├── MP9.png │ │ ├── P90.png │ │ ├── PP-Bizon.png │ │ └── UMP-45.png ├── components │ ├── auth │ │ ├── auth.service.js │ │ └── user.service.js │ ├── cart │ │ ├── swCart.directives.js │ │ ├── swCart.fulfilment.js │ │ ├── swCart.js │ │ └── template │ │ │ ├── addtocart.html │ │ │ ├── cart.html │ │ │ ├── checkout.html │ │ │ └── summary.html │ ├── categories-menu │ │ ├── categories-menu.directive.js │ │ ├── categories-menu.html │ │ └── categories.menu.ctrl.js │ ├── filters │ │ ├── swMoney.filter.js │ │ └── to_trusted.js │ ├── footer │ │ ├── footer.directive.js │ │ └── footer.html │ ├── modal │ │ ├── modal.css │ │ ├── modal.html │ │ └── modal.service.js │ ├── mongoose-error │ │ └── mongoose-error.directive.js │ ├── navbar │ │ ├── navbar.controller.js │ │ ├── navbar.directive.js │ │ └── navbar.html │ ├── notification │ │ └── notification.js │ ├── noty │ │ └── noty.wrapper.js │ ├── socket │ │ ├── socket.mock.js │ │ └── socket.service.js │ └── ui-router │ │ └── ui-router.mock.js ├── favicon.ico ├── favicon.png ├── index.html └── robots.txt ├── e2e ├── account │ ├── login │ │ ├── login.po.js │ │ └── login.spec.js │ ├── logout │ │ └── logout.spec.js │ └── signup │ │ ├── signup.po.js │ │ └── signup.spec.js ├── components │ └── navbar │ │ └── navbar.po.js └── main │ ├── main.po.js │ └── main.spec.js ├── karma.conf.js ├── mocha.conf.js ├── package.json ├── polldata.json └── protractor.conf.js /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "client/bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /.buildignore: -------------------------------------------------------------------------------- 1 | *.coffee 2 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # * text eol=lf 2 | # 3 | ## These files are binary and should be left untouched 4 | # 5 | 6 | # (binary is a macro for -text -diff) 7 | *.png binary 8 | *.jpg binary 9 | *.jpeg binary 10 | *.gif binary 11 | *.ico binary 12 | *.mov binary 13 | *.mp4 binary 14 | *.mp3 binary 15 | *.flv binary 16 | *.fla binary 17 | *.swf binary 18 | *.gz binary 19 | *.zip binary 20 | *.7z binary 21 | *.ttf binary 22 | *.eot binary 23 | *.woff binary 24 | *.pyc binary 25 | *.pdf binary 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | public 3 | .tmp 4 | .idea 5 | client/bower_components 6 | dist 7 | /server/config/local.env.js 8 | npm-debug.log 9 | *.log 10 | -------------------------------------------------------------------------------- /.jscs.json: -------------------------------------------------------------------------------- 1 | { 2 | "maximumLineLength": { 3 | "value": 100, 4 | "allowComments": true, 5 | "allowRegex": true 6 | }, 7 | "disallowMixedSpacesAndTabs": true, 8 | "disallowMultipleLineStrings": true, 9 | "disallowNewlineBeforeBlockStatements": true, 10 | "disallowSpaceAfterObjectKeys": true, 11 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], 12 | "disallowSpaceBeforeBinaryOperators": [","], 13 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], 14 | "disallowSpacesInAnonymousFunctionExpression": { 15 | "beforeOpeningRoundBrace": true 16 | }, 17 | "disallowSpacesInFunctionDeclaration": { 18 | "beforeOpeningRoundBrace": true 19 | }, 20 | "disallowSpacesInNamedFunctionExpression": { 21 | "beforeOpeningRoundBrace": true 22 | }, 23 | "disallowSpacesInsideArrayBrackets": true, 24 | "disallowSpacesInsideParentheses": true, 25 | "disallowTrailingComma": true, 26 | "disallowTrailingWhitespace": true, 27 | "requireCommaBeforeLineBreak": true, 28 | "requireLineFeedAtFileEnd": true, 29 | "requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"], 30 | "requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"], 31 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"], 32 | "requireSpaceBeforeBlockStatements": true, 33 | "requireSpacesInConditionalExpression": { 34 | "afterTest": true, 35 | "beforeConsequent": true, 36 | "afterConsequent": true, 37 | "beforeAlternate": true 38 | }, 39 | "requireSpacesInFunction": { 40 | "beforeOpeningCurlyBrace": true 41 | }, 42 | "validateLineBreaks": "LF", 43 | "validateParameterSeparator": ", " 44 | } 45 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | skywarrior 4 | 5 | 6 | 7 | 8 | 9 | com.aptana.ide.core.unifiedBuilder 10 | 11 | 12 | 13 | 14 | 15 | com.aptana.projects.webnature 16 | com.aptana.ruby.core.rubynature 17 | 18 | 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | - '0.11' 5 | before_script: 6 | - npm install -g bower grunt-cli 7 | - bower install 8 | services: mongodb 9 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-angular-fullstack": { 3 | "endpointDirectory": "server/api/", 4 | "insertRoutes": true, 5 | "registerRoutesFile": "server/routes.js", 6 | "routesNeedle": "// Insert routes below", 7 | "routesBase": "/api/", 8 | "pluralizeRoutes": true, 9 | "insertSockets": true, 10 | "registerSocketsFile": "server/config/socketio.js", 11 | "socketsNeedle": "// Insert sockets below", 12 | "insertModels": true, 13 | "registerModelsFile": "server/sqldb/index.js", 14 | "modelsNeedle": "// Insert models below", 15 | "filters": { 16 | "js": true, 17 | "html": true, 18 | "css": true, 19 | "uirouter": true, 20 | "bootstrap": true, 21 | "uibootstrap": true, 22 | "socketio": true, 23 | "auth": true, 24 | "models": true, 25 | "mongooseModels": true, 26 | "mongoose": true, 27 | "grunt": true, 28 | "jasmine": true, 29 | "mocha": false, 30 | "should": false, 31 | "expect": false 32 | } 33 | }, 34 | "generator-ng-component": { 35 | "routeDirectory": "client/app/", 36 | "directiveDirectory": "client/app/", 37 | "filterDirectory": "client/app/", 38 | "serviceDirectory": "client/app/", 39 | "basePath": "client", 40 | "moduleName": "", 41 | "filters": [ 42 | "uirouter", 43 | "jasmine", 44 | "uirouter" 45 | ], 46 | "extensions": [ 47 | "js", 48 | "html", 49 | "css" 50 | ], 51 | "directiveSimpleTemplates": "", 52 | "directiveComplexTemplates": "", 53 | "filterTemplates": "", 54 | "serviceTemplates": "", 55 | "factoryTemplates": "", 56 | "controllerTemplates": "", 57 | "decoratorTemplates": "", 58 | "providerTemplates": "", 59 | "routeTemplates": "" 60 | } 61 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # csgo 2 | 3 | 4 | 5 | ## Getting Started 6 | 7 | ### Prerequisites 8 | 9 | - [Git](https://git-scm.com/) 10 | - [Node.js and NPM](nodejs.org) >= v0.10.0 11 | - [Bower](bower.io) (`npm install --global bower`) 12 | - [Grunt](http://gruntjs.com/) (`npm install --global grunt-cli`) 13 | - [MongoDB](https://www.mongodb.org/) - Keep a running daemon with `mongod` 14 | 15 | ### Developing 16 | 17 | 1. Run `npm install` to install server dependencies. 18 | 19 | 2. Run `bower install` to install front-end dependencies. 20 | 21 | 3. Run `mongod` in a separate shell to keep an instance of the MongoDB Daemon running 22 | 23 | 4. Run `grunt serve` to start the development server. It should automatically open the client in your browser when ready. 24 | 25 | ## Build & development 26 | 27 | Run `grunt build` for building and `grunt serve` for preview. 28 | 29 | ## Testing 30 | 31 | Running `npm test` will run the unit tests with karma. 32 | 33 | *END* 34 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "skywarrior", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "angular": "~1.4.7", 6 | "angular-animate": "~1.4.7", 7 | "angular-bootstrap": "~1.1.0", 8 | "angular-cookies": "~1.4.7", 9 | "angular-loading-bar": "~0.8.0", 10 | "angular-resource": "~1.4.7", 11 | "angular-sanitize": "~1.4.7", 12 | "angular-ui-router": "~0.2.15", 13 | "bootstrap": "~3.1.1", 14 | "es5-shim": "~3.0.1", 15 | "font-awesome": "fontawesome#~4.4.0", 16 | "jquery.ui-to-top": "*", 17 | "json3": "~3.3.1", 18 | "lodash": "3.10.1", 19 | "ngInfiniteScroll": "1.0.0", 20 | "angular-timer": "~1.3.3", 21 | "toastr": "~2.1.2", 22 | "moment": "~2.11.2", 23 | "jQuery-One-Page-Nav": "~3.0.0", 24 | "angular-update-meta": "~1.8.0" 25 | }, 26 | "devDependencies": { 27 | "angular-mocks": "~1.4.7" 28 | }, 29 | "resolutions": { 30 | "jquery": ">= 1.9.0" 31 | }, 32 | "overrides": { 33 | "jquery.ui-to-top": { 34 | "main": [ 35 | "js/jquery.ui.totop.js", 36 | "css/ui.totop.css", 37 | "img/ui.totop.png" 38 | ] 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /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 | "globals": { 20 | "jQuery": true, 21 | "angular": true, 22 | "console": true, 23 | "$": true, 24 | "_": true, 25 | "moment": true, 26 | "describe": true, 27 | "beforeEach": true, 28 | "module": true, 29 | "inject": true, 30 | "it": true, 31 | "expect": true, 32 | "browser": true, 33 | "element": true, 34 | "by": true 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /client/app/admin/admin.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .controller('AdminCtrl', function($scope, $http, Auth, User) { 5 | 6 | // Use the User $resource to fetch all users 7 | $scope.users = User.query(); 8 | 9 | $scope.delete = function(user) { 10 | User.remove({ id: user._id }); 11 | $scope.users.splice(this.$index, 1); 12 | }; 13 | }); 14 | -------------------------------------------------------------------------------- /client/app/admin/admin.css: -------------------------------------------------------------------------------- 1 | .trash { color:rgb(209, 91, 71); } 2 | -------------------------------------------------------------------------------- /client/app/admin/admin.html: -------------------------------------------------------------------------------- 1 |
2 |

The delete user and user index api routes are restricted to users with the 'admin' role.

3 | 10 |
11 | -------------------------------------------------------------------------------- /client/app/admin/admin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .config(function($stateProvider) { 5 | $stateProvider 6 | .state('admin', { 7 | url: '/admin', 8 | templateUrl: 'app/admin/admin.html', 9 | controller: 'AdminCtrl' 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /client/app/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var myApp = angular.module('skywarriorApp', [ 4 | 'ngCookies', 5 | 'ngResource', 6 | 'ngSanitize', 7 | 'ngAnimate', 8 | 'skywarrior.notification', 9 | 'ui.router', 10 | 'ui.bootstrap', 11 | 'swCart', 12 | 'angular-loading-bar', 13 | 'infinite-scroll', 14 | 'timer', 15 | 'updateMeta' 16 | ]) 17 | .config(function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider, $compileProvider) { 18 | $urlRouterProvider 19 | .otherwise('/'); 20 | 21 | $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|mailto|steam):/); 22 | 23 | $locationProvider.html5Mode(true); 24 | $httpProvider.interceptors.push('authInterceptor'); 25 | $httpProvider.interceptors.push('errorInterceptor'); 26 | $httpProvider.useApplyAsync(true); 27 | }) 28 | 29 | .run(function ($rootScope, Auth, $cookies, notification, $window) { 30 | handleCookies($cookies, notification); 31 | redirectToMainIfNotLoggedIn($rootScope, Auth, $window); 32 | }); 33 | 34 | 35 | /** 36 | * Redirect to login if route requires auth and the user is not logged in 37 | * @param $rootScope 38 | * @param Auth 39 | * @param $state 40 | */ 41 | function redirectToMainIfNotLoggedIn($rootScope, Auth, $window) { 42 | $rootScope.$on('$stateChangeStart', function (event, next) { 43 | if (next.authenticate) { 44 | if (!Auth.isLoggedIn()) { 45 | event.preventDefault(); 46 | $window.location.href = '/auth/steam'; 47 | } 48 | } 49 | }); 50 | } 51 | 52 | function handleCookies($cookies, notification) { 53 | var message = $cookies.get('message'); 54 | if (message) { 55 | notification.warning(message); 56 | } 57 | var error = $cookies.get('error'); 58 | if (error) { 59 | notification.error(error); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /client/app/cart/cart.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /client/app/cart/cart.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 22.9.15.. 3 | */ 4 | 'use strict'; 5 | 6 | angular.module('skywarriorApp') 7 | .config(function ($stateProvider) { 8 | $stateProvider 9 | .state('cart', { 10 | url: '/checkout', 11 | templateUrl: 'app/cart/cart.html', 12 | controller: 'CartController', 13 | authenticate: true 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /client/app/common/directives/spinner/spinner-directive.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | 'use strict'; 4 | 5 | angular.module('skywarriorApp') 6 | .directive('spinner', function () { 7 | return { 8 | transclude: true, 9 | restrict: 'E', 10 | replace: true, 11 | scope: { 12 | isLoading: '=' 13 | }, 14 | template: '
' 15 | }; 16 | }); 17 | 18 | })(); 19 | -------------------------------------------------------------------------------- /client/app/common/directives/sw.editable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Vojkan on 10/26/2015. 3 | */ 4 | 'use strict'; 5 | 6 | /** 7 | */ 8 | angular.module('skywarriorApp') 9 | .directive('swEditable', function() { 10 | return { 11 | restrict: 'A', 12 | transclude: true, 13 | templateUrl: 'app/common/directives/templates/sw.editable.html', 14 | scope: { 15 | editable: '=swEditable', 16 | onSave: '&swEditableOnSave' 17 | }, 18 | link: function (scope, elem, attrs){ 19 | scope.save = function () { 20 | scope.isEditing = false; 21 | scope.onSave({$val: scope.editable}); 22 | } 23 | } 24 | }; 25 | }); 26 | -------------------------------------------------------------------------------- /client/app/common/directives/sw.integer.price.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 12.1.16.. 3 | */ 4 | (function () { 5 | angular.module('skywarriorApp') 6 | .directive('swIntegerPrice', swIntegerPrice); 7 | 8 | swIntegerPrice.$inject = []; 9 | 10 | function swIntegerPrice() { 11 | return { 12 | require: 'ngModel', 13 | restrict: 'A', 14 | link: function (scope, element, attr, ctrl) { 15 | 16 | ctrl.$formatters.push(function (val) { 17 | if (val) { 18 | if (val === 0) { 19 | return 0; 20 | } 21 | return parseInt(val / 100); 22 | } 23 | return 0; 24 | }); 25 | 26 | ctrl.$parsers.push(function (val) { 27 | if (val) { 28 | var digits = val.replace(/[^0-9]/g, ''); 29 | 30 | if (digits !== val) { 31 | ctrl.$setViewValue(digits); 32 | ctrl.$render(); 33 | } 34 | return parseInt(digits * 100, 10); 35 | } 36 | return 0; 37 | }); 38 | 39 | element.bind('keypress', function (event) { 40 | if (event.keyCode === 32) { 41 | event.preventDefault(); 42 | } 43 | }); 44 | 45 | } 46 | 47 | }; 48 | } 49 | 50 | })(); 51 | -------------------------------------------------------------------------------- /client/app/common/directives/sw.loading.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 5.1.16.. 3 | */ 4 | /*(function () { 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp'). 8 | directive('loader', loader); 9 | 10 | loader.$inject = ['$http']; 11 | 12 | function loader($http) { 13 | return { 14 | restrict: 'C', 15 | link: function (scope, element) { 16 | scope.isLoading = function () { 17 | return $http.pendingRequests.length > 0; 18 | }; 19 | scope.$watch(scope.isLoading, function (value) { 20 | if (value) { 21 | element.removeClass('ng-hide'); 22 | } else { 23 | element.addClass('ng-hide'); 24 | } 25 | }); 26 | } 27 | }; 28 | } 29 | })();*/ 30 | -------------------------------------------------------------------------------- /client/app/common/directives/sw.money.input.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 8.12.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | angular.module('skywarriorApp') 7 | .directive('swMoneyInput', swMoneyInput); 8 | 9 | swMoneyInput.$inject = ['$filter']; 10 | 11 | function swMoneyInput($filter) { 12 | return { 13 | restrict: 'A', 14 | require: 'ngModel', 15 | link: linkFn 16 | }; 17 | 18 | function linkFn(scope, element, attrs, ngModelCtrl) { 19 | ngModelCtrl.$formatters.push(function (modelValue) { 20 | if (modelValue === 0) { 21 | return Number(modelValue).toString(); 22 | } 23 | var number = modelValue / 100; 24 | return $filter('number')(number, 2); 25 | }); 26 | 27 | ngModelCtrl.$parsers.push(function (viewValue) { 28 | return viewValue * 100; 29 | }); 30 | 31 | } 32 | 33 | 34 | } 35 | 36 | })(); 37 | -------------------------------------------------------------------------------- /client/app/common/directives/templates/sw.editable.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 |
10 | 11 | Save 12 |
13 | -------------------------------------------------------------------------------- /client/app/common/directives/valid.number.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 6.10.15.. 3 | */ 4 | 5 | 6 | angular.module('skywarriorApp') 7 | .directive('validNumber', function () { 8 | return { 9 | require: '?ngModel', 10 | link: function (scope, element, attrs, ngModelCtrl) { 11 | if (!ngModelCtrl) { 12 | return; 13 | } 14 | 15 | ngModelCtrl.$parsers.push(function (val) { 16 | if (angular.isUndefined(val)) { 17 | val = ''; 18 | } 19 | var clean = val.replace(/[^0-9\.]/g, ''); 20 | var decimalCheck = clean.split('.'); 21 | if (!angular.isUndefined(decimalCheck[1])) { 22 | decimalCheck[1] = decimalCheck[1].slice(0, 2); 23 | clean = decimalCheck[0] + '.' + decimalCheck[1]; 24 | } 25 | if (val !== clean) { 26 | ngModelCtrl.$setViewValue(clean); 27 | ngModelCtrl.$render(); 28 | } 29 | return clean; 30 | }); 31 | 32 | element.bind('keypress', function (event) { 33 | if (event.keyCode === 32) { 34 | event.preventDefault(); 35 | } 36 | }); 37 | } 38 | }; 39 | }); 40 | -------------------------------------------------------------------------------- /client/app/common/service/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 4.12.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | angular.module('skywarriorApp') 7 | .factory('util', util); 8 | 9 | util.$inject = ['$q', '$http']; 10 | 11 | function util($q, $http) { 12 | return { 13 | $q: $q, 14 | $http: $http 15 | }; 16 | 17 | } 18 | 19 | })(); 20 | -------------------------------------------------------------------------------- /client/app/interceptor/auth.interceptor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 26.9.15.. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .factory('authInterceptor', function ($rootScope, $q, $cookies, $injector) { 9 | var state; 10 | var notification = $injector.get('notification'); 11 | 12 | return { 13 | // Add authorization token to headers 14 | request: function (config) { 15 | config.headers = config.headers || {}; 16 | if ($cookies.get('token')) { 17 | config.headers.Authorization = 'Bearer ' + $cookies.get('token'); 18 | } 19 | return config; 20 | }, 21 | 22 | // Intercept 401s and redirect you to main 23 | responseError: function (response) { 24 | if (response.status === 401) { 25 | (state || (state = $injector.get('$state'))).go('main'); 26 | // reset user 27 | var Auth = $injector.get('Auth'); 28 | Auth.setCurrentUser({}); 29 | // remove any stale tokens 30 | $cookies.remove('token'); 31 | return $q.reject(response); 32 | } 33 | 34 | if (response.status === 418) { 35 | notification.error('You are banned!'); 36 | } 37 | return $q.reject(response); 38 | } 39 | }; 40 | }); 41 | -------------------------------------------------------------------------------- /client/app/interceptor/error.interceptor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 26.9.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .factory('errorInterceptor', function ($q, $rootScope, notification) { 9 | return { 10 | responseError: function (response) { 11 | // FIXME create some kind of message service 12 | if (response.status >= 500) { 13 | $rootScope.$broadcast('message.error', response); 14 | notification.error(response.data.error || response.data.message || 'Something went wrong, if you encounter this problem again, please send us email with details', 'Oh this is embarrassing.'); 15 | } 16 | return $q.reject(response); 17 | } 18 | }; 19 | }); 20 | 21 | })(); 22 | -------------------------------------------------------------------------------- /client/app/item/directive/item.directive.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 22.1.16.. 3 | */ 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | angular.module('skywarriorApp') 9 | .controller('ItemDirectiveCtrl', itemDirectiveCtrl); 10 | 11 | itemDirectiveCtrl.$inject = ['ItemSharedService', 'Auth']; 12 | 13 | function itemDirectiveCtrl(ItemSharedService, Auth) { 14 | var vm = this; 15 | vm.isOwner = ItemSharedService.isOwner; 16 | vm.isLoggedIn = Auth.isLoggedIn(); 17 | 18 | ////////////////////////////////////////////////// 19 | 20 | 21 | } 22 | 23 | })(); 24 | -------------------------------------------------------------------------------- /client/app/item/directive/item.directive.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
 {{vm.item.steam_price | swMoney}}
6 | 7 | 8 |
9 |
10 |

{{vm.item.name}}

11 |
({{vm.item.type}})
12 |
({{vm.item.exterior}})
13 | 14 |
{{vm.item.user_price | swMoney}}
15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /client/app/item/directive/item.directive.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 22.1.16.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | angular.module('skywarriorApp') 7 | .directive('swItem', itemDirective); 8 | 9 | itemDirective.$inject = []; 10 | 11 | function itemDirective() { 12 | return { 13 | restrict: 'E', 14 | scope: { 15 | item : '=' 16 | }, 17 | templateUrl: 'app/item/directive/item.directive.html', 18 | controller: 'ItemDirectiveCtrl', 19 | controllerAs: 'vm', 20 | bindToController: true 21 | } 22 | } 23 | 24 | })(); 25 | -------------------------------------------------------------------------------- /client/app/item/item.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 21.9.15.. 3 | */ 4 | 'use strict'; 5 | 6 | angular.module('skywarriorApp') 7 | .controller('ItemCtrl', function ($scope, item, ItemSharedService) { 8 | $scope.item = item; 9 | $scope.isOwner = ItemSharedService.isOwner; 10 | }); 11 | -------------------------------------------------------------------------------- /client/app/item/item.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |

{{item.name}}

6 | 7 |
Home {{item.type}} 8 | {{item.name}} 9 |
10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 |
18 |
19 | 20 | 21 |
22 |
23 |
24 | 25 | 26 | 27 | 28 |
{{item.user.personaname}}
29 | 30 | 31 | 32 |
33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 |
42 |
43 |
44 |
45 |
46 | Counter-Strike: Global Offensive 49 |
50 |
Counter-Strike: Global Offensive
51 |
{{item.type}}
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 60 | Inspect in Game... 61 |
62 | 63 |
64 |
65 |

 {{item.user_price | swMoney}}

66 |
67 |  {{item.steam_price | swMoney}} - You are saving {{ (item.steam_price - item.user_price) | swMoney}}! 68 |
69 |
70 |
71 | 72 | 73 |
74 | 75 |
76 | 77 |
78 | 79 |
80 | 81 |
82 | 83 |
84 | -------------------------------------------------------------------------------- /client/app/item/item.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 21.9.15.. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .config(function ($stateProvider) { 9 | $stateProvider 10 | .state('item', { 11 | url: '/item/:id', 12 | controller: 'ItemCtrl', 13 | templateUrl: 'app/item/item.html', 14 | resolve: { 15 | item: function (ItemServiceNew, $stateParams) { 16 | return ItemServiceNew.getById($stateParams.id) 17 | .then(function (response) { 18 | return response.data; 19 | }) 20 | .catch(function (error) { 21 | }) 22 | } 23 | } 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /client/app/item/item.service.new.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 4.12.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | angular.module('skywarriorApp') 7 | .factory('ItemServiceNew', itemService); 8 | 9 | itemService.$inject = ['$http']; 10 | 11 | function itemService($http) { 12 | return { 13 | get: get, 14 | getById: getById, 15 | getItemPrice: getItemPrice, 16 | update: update, 17 | putOnSale: putOnSale, 18 | returnItems: returnItems, 19 | count: count 20 | }; 21 | 22 | function get(params) { 23 | return $http.get('/api/items', params ? {params: params} : null); 24 | } 25 | 26 | function getById(itemId) { 27 | return $http.get('/api/items/' + itemId); 28 | } 29 | 30 | function getItemPrice(itemMarketHashName) { 31 | return $http.get('/api/items/' + itemMarketHashName + '/price'); 32 | } 33 | 34 | function update(item) { 35 | return $http.put('/api/items/' + item.steam_id, item); 36 | } 37 | 38 | function putOnSale(itemId) { 39 | return $http.put('/api/items', {status: 'on sale'}, {params: {id: itemId}}); 40 | } 41 | 42 | function returnItems(itemIds) { 43 | return $http.put('/api/items', {status: 'returned'}, {params: {id: itemIds}}); 44 | } 45 | 46 | function count() { 47 | return $http.get('/api/items/count/items').then(function (response) { 48 | return response.data; 49 | }); 50 | } 51 | 52 | 53 | } 54 | 55 | 56 | })(); 57 | -------------------------------------------------------------------------------- /client/app/item/item.shared.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 23.1.16.. 3 | */ 4 | (function () { 5 | angular.module('skywarriorApp') 6 | .factory('ItemSharedService', itemSharedService); 7 | 8 | itemSharedService.$inject = ['Auth']; 9 | 10 | function itemSharedService(Auth) { 11 | return { 12 | isOwner: isOwner 13 | }; 14 | 15 | ////////////////////////////////////////////////////////// 16 | function isOwner(userId) { 17 | if (!userId) { 18 | return false; 19 | } 20 | var currentUser = Auth.getCurrentUser(); 21 | return currentUser && currentUser.steam_user_id === userId; 22 | } 23 | 24 | } 25 | 26 | })(); 27 | -------------------------------------------------------------------------------- /client/app/item/item.transformator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 28.9.15.. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .service('ItemTransformator', function () { 9 | 10 | this.transform = function (data) { 11 | if (_.isArray(data)) { 12 | _.forEach(data, function (item) { 13 | transformData(item) 14 | }) 15 | } else { 16 | transformData(data) 17 | } 18 | return data; 19 | }; 20 | 21 | /** --------------- HELPER METHODS ------------------ */ 22 | // FIXME this should be done on server side 23 | function transformData(data) { 24 | // set collection name 25 | _.assign(data, {item_set: _.result(_.find(data.tags, {'category': 'ItemSet'}), 'name')}); 26 | // set category type 27 | _.assign(data, {type: _.result(_.find(data.tags, {'category': 'Type'}), 'name')}); 28 | // quality 29 | _.assign(data, {quality: _.result(_.find(data.tags, {'category': 'Quality'}), 'name')}); 30 | // exterior 31 | _.assign(data, {exterior: _.result(_.find(data.tags, {'category': 'Exterior'}), 'name')}); 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /client/app/item/search/partials/exteriors.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Exterior

4 | 16 |
17 |
18 | -------------------------------------------------------------------------------- /client/app/item/search/partials/horizontal.facet.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 |
7 | 8 |
9 | 10 | 15 |
16 | 17 |
18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 | 26 | 33 |
34 | 35 |
36 | 37 |
38 |
39 | 42 | 43 | 44 | 45 | 46 | 47 |
48 |
49 |
50 | -------------------------------------------------------------------------------- /client/app/item/search/partials/price.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Price 5 |

6 |
7 |
8 |
9 | 10 | $ 11 | 18 |
19 |
20 | 21 | $ 22 | 29 |
30 |
31 | 34 |
35 |
36 |
37 |
38 |
39 |
40 | -------------------------------------------------------------------------------- /client/app/item/search/partials/weapon.type.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 6 |
7 |
8 |
9 |
10 |

Weapon Type

11 | 12 | 13 | 14 | Knife 15 | 16 |
17 | 21 |
22 |
23 |
24 | 25 | 26 | Pistol 27 | 28 |
29 |
30 | 31 |
32 | 36 |
37 |
38 |
39 | 40 | 41 | Rifles 42 | 43 |
44 | 48 |
49 |
50 |
51 | 52 | 53 | 54 | Heavy 55 | 56 | 57 |
58 | 62 |
63 |
64 |
65 | 66 | 67 | SMGs 68 | 69 |
70 | 74 |
75 |
76 |
77 | 78 | 79 | Cases 80 | 81 |
82 | 86 |
87 |
88 |
89 | 90 | 91 | Keys 92 | 93 | 94 | 95 | 96 | 97 |
98 |
99 |
100 | -------------------------------------------------------------------------------- /client/app/item/search/search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |
6 |
{{vm.itemsCount}} Primary Weapons
7 |
8 | 9 |
10 |
11 | 12 |
13 | 14 |
15 |
16 | 17 |
18 | 19 | 20 | 21 |
22 |
23 |
24 | 25 |
26 |
27 | 28 |
29 |

Search result

30 |
31 |
32 |
33 |
34 |
35 | 36 |
37 | -------------------------------------------------------------------------------- /client/app/item/search/search.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 5.12.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | angular.module('skywarriorApp') 7 | .config(function ($stateProvider) { 8 | $stateProvider 9 | .state('search', { 10 | url: '/search', 11 | abstract: true, 12 | templateUrl: 'app/item/search/search.html', 13 | controller: 'SearchController', 14 | controllerAs: 'vm' 15 | }) 16 | .state('search.query', { 17 | url: '/query?q', 18 | params: { 19 | sort: '-created_at', 20 | status: 'on sale' 21 | }, 22 | templateUrl: 'app/item/search/search.result.html', 23 | controller: 'SearchResultController', 24 | controllerAs: 'vm' 25 | }) 26 | .state('search.result', { 27 | parent: 'search', 28 | url: '/:trigger', 29 | params: { 30 | sort: '-created_at', 31 | status: 'on sale', // default value 32 | type: null, 33 | exterior: null, 34 | weapon: null, 35 | itemSet: null, 36 | quality: null, 37 | priceFrom: null, 38 | priceTo: null, 39 | added: null 40 | }, 41 | templateUrl: 'app/item/search/search.result.html', 42 | controller: 'SearchResultController', 43 | controllerAs: 'vm' 44 | }); 45 | }) 46 | })(); 47 | -------------------------------------------------------------------------------- /client/app/item/search/search.param.resource.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 8.12.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .factory('searchParamResource', searchParamResource); 9 | 10 | searchParamResource.$inject = []; 11 | 12 | function searchParamResource() { 13 | return { 14 | exteriors: exteriors, 15 | knives: knives, 16 | smgs: smgs, 17 | heavies: heavies, 18 | pistols: pistols, 19 | rifles: rifles, 20 | containers: containers, 21 | }; 22 | 23 | function exteriors() { 24 | return [{name: 'Field-Tested'}, {name: 'Minimal Wear'}, {name: 'Battle-Scarred'}, {name: 'Well-Worn'}, {name: 'Factory New'}, {name: 'Not Painted'}]; 25 | } 26 | 27 | function knives() { 28 | return [ 29 | {name: 'Bayonet Knife'}, 30 | {name: 'Butterfly Knife'}, 31 | {name: 'Falchion Knife'}, 32 | {name: 'Flip Knife'}, 33 | {name: 'Gut Knife'}, 34 | {name: 'Huntsman Knife'}, 35 | {name: 'Karambit Knife'}, 36 | {name: 'M9 Bayonet Knife'}, 37 | {name: 'Shadow Daggers Knife'} 38 | ]; 39 | } 40 | 41 | function pistols() { 42 | return [ 43 | {name: 'CZ75-Auto'}, 44 | {name: 'Desert Eagle'}, 45 | {name: 'Dual Berettas'}, 46 | {name: 'Five-SeveN'}, 47 | {name: 'Glock-18'}, 48 | {name: 'P250'}, 49 | {name: 'P2000'}, 50 | {name: 'Tec-9'}, 51 | {name: 'USP-S'} 52 | ]; 53 | } 54 | 55 | function rifles() { 56 | return [ 57 | {name: 'AK-47'}, 58 | {name: 'AUG'}, 59 | {name: 'AWP'}, 60 | {name: 'FAMAS'}, 61 | {name: 'G3SG1'}, 62 | {name: 'Galil AR'}, 63 | {name: 'M4A1-S'}, 64 | {name: 'M4A4'}, 65 | {name: 'SCAR-20'}, 66 | {name: 'SG 553'}, 67 | {name: 'SSG 08'} 68 | ]; 69 | } 70 | 71 | function heavies() { 72 | return [ 73 | {name: 'M249'}, 74 | {name: 'MAG-7'}, 75 | {name: 'Negev'}, 76 | {name: 'Nova'}, 77 | {name: 'Sawed-Off'}, 78 | {name: 'XM1014'} 79 | ]; 80 | } 81 | 82 | function smgs() { 83 | return [ 84 | {name: 'MAC-10'}, 85 | {name: 'MP7'}, 86 | {name: 'MP9'}, 87 | {name: 'P90'}, 88 | {name: 'PP-Bizon'}, 89 | {name: 'UMP-45'} 90 | ]; 91 | } 92 | 93 | function containers() { 94 | return [ 95 | {name: 'CS:GO Weapon Case'}, 96 | {name: 'CS:GO Weapon Case 2'}, 97 | {name: 'CS:GO Weapon Case 3'}, 98 | {name: 'Chroma Case'}, 99 | {name: 'eSports 2013 Case'}, 100 | {name: 'eSports 2013 Winter Case'}, 101 | {name: 'eSports 2014 Summer Case'}, 102 | {name: 'Falchion Case'}, 103 | {name: 'Huntsman Weapon Case'}, 104 | {name: 'Operation Bravo Case'}, 105 | {name: 'Operation Breakout Weapon Case'}, 106 | {name: 'Operation Phoenix Weapon Case'}, 107 | {name: 'Operation Vanguard Weapon Case'}, 108 | {name: 'Winter Offensive Weapon Case'} 109 | ] 110 | } 111 | 112 | } 113 | 114 | })(); 115 | -------------------------------------------------------------------------------- /client/app/item/search/search.result.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 6.12.15.. 3 | */ 4 | (function () { 5 | 6 | 'use strict'; 7 | 8 | angular.module('skywarriorApp') 9 | .controller('SearchResultController', searchResultController); 10 | 11 | searchResultController.$inject = ['$stateParams', 'ItemServiceNew']; 12 | 13 | function searchResultController($stateParams, ItemServiceNew) { 14 | var vm = this; 15 | 16 | activate(); 17 | 18 | ////////////////////////////////////////// 19 | function activate() { 20 | vm.isLoading = true; 21 | dontMixTypeParamsWithOther(); 22 | return ItemServiceNew.get($stateParams) 23 | .then(function (response) { 24 | vm.items = response.data; 25 | vm.isLoading = false; 26 | return vm.items; 27 | }) 28 | .catch(function (error) { 29 | vm.items = []; 30 | vm.isLoading = false; 31 | return vm.items; 32 | }); 33 | } 34 | 35 | function dontMixTypeParamsWithOther() { 36 | if ($stateParams.weapon || $stateParams.itemSet || $stateParams.exterior || $stateParams.quality || $stateParams.q) { 37 | resetType(); 38 | } 39 | } 40 | 41 | function resetType() { 42 | $stateParams.type = null; 43 | } 44 | } 45 | 46 | })(); 47 | -------------------------------------------------------------------------------- /client/app/item/search/search.result.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /client/app/main/jquery.scrollTo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2007-2015 Ariel Flesler - aflesler ○ gmail • com | http://flesler.blogspot.com 3 | * Licensed under MIT 4 | * @author Ariel Flesler 5 | * @version 2.1.3 6 | */ 7 | ;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1= startPosition) { 20 | $scope.isLoading = true; 21 | params = _.merge({sort: '-user_price', status: 'on sale', limit: FETCH_LIMIT_SIZE, skip: startPosition}, params); 22 | ItemServiceNew.get(params) 23 | .then(function (items) { 24 | $scope.itemsOnSale = $scope.itemsOnSale.concat(items.data); 25 | 26 | }) 27 | .catch(function (error) { 28 | }) 29 | .finally(function(){ 30 | $scope.isLoading = false; 31 | }); 32 | 33 | startPosition += FETCH_LIMIT_SIZE; 34 | } 35 | } 36 | 37 | function refreshAndLoad(params) { 38 | startPosition = 0; 39 | $scope.itemsOnSale = []; 40 | loadMore(params); 41 | } 42 | 43 | function findItemsByPrice() { 44 | $scope.itemsByLabel = 'By Price'; 45 | refreshAndLoad({sort: '-user_price'}); 46 | } 47 | 48 | function findItemsByDate() { 49 | $scope.itemsByLabel = 'By Date'; 50 | refreshAndLoad({sort: '-created_at'}); 51 | } 52 | 53 | }); 54 | -------------------------------------------------------------------------------- /client/app/main/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |

{{countObject.count}} CS:GO Skins on sale

6 |
7 | 10 | 20 |
21 |
22 | 27 |
28 |
29 |
30 | 31 |
32 |
33 |

34 |
Latest items
35 | 36 |
37 | 40 | 44 |
45 |
46 |
Sort by:
47 |
48 |

49 |
    50 |
  • 51 | 52 |
  • 53 |
  • 54 | 55 |
  • 56 |
57 |
58 |
59 |
60 | 61 |
62 | -------------------------------------------------------------------------------- /client/app/main/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .config(function ($stateProvider) { 5 | $stateProvider 6 | .state('main', { 7 | url: '/', 8 | templateUrl: 'app/main/main.html', 9 | controller: 'MainCtrl', 10 | resolve: { 11 | countObject: function (ItemServiceNew) { 12 | return ItemServiceNew.count(); 13 | } 14 | } 15 | }) 16 | .state('privacy', { 17 | url:'/privacy', 18 | templateUrl: 'app/main/privacy.html' 19 | }) 20 | .state('howItWorks', { 21 | url:'/how-it-works', 22 | templateUrl: 'app/main/how_it_works.html' 23 | }) 24 | .state('terms', { 25 | url:'/terms', 26 | templateUrl: 'app/main/terms.html' 27 | }) 28 | }); 29 | -------------------------------------------------------------------------------- /client/app/payment/deposit.money.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 17.8.15.. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .controller('DepositMoneyCtrl', function ($scope, Auth, $http, $window, notification) { 9 | 10 | var uploadValues = [{value: 10}, {value: 15}, {value: 20}, {value: 25}, {value: 30}, {value: 50}, {value: 60}, {value: 70}, {value: 80}, {value: 90}, {value: 100}, {value: 150}, {value: 200}, {value: 350}, {value: 500}]; 11 | 12 | $scope.user = Auth.getCurrentUser(); 13 | $scope.token = Auth.getToken(); 14 | $scope.uploadValues = uploadValues; 15 | $scope.selectedValue = 0; 16 | $scope.select = selectValue; 17 | $scope.makeDeposit = makeDeposit; 18 | $scope.selectedAmount = uploadValues[$scope.selectedValue].value; 19 | $scope.isRequestPending = false; 20 | 21 | /** ----------------------------------------------------------------------- **/ 22 | function makeDeposit() { 23 | if (!$scope.selectedAmount) { 24 | return; 25 | } 26 | $scope.isRequestPending = true; 27 | $http.post('/payment/paypal/deposit', {amount: $scope.selectedAmount}) 28 | .success(function (response) { 29 | $window.location.href = response.approval_url; 30 | }) 31 | .catch(function (response) { 32 | // if user wants to upload money but account is not verified 33 | notification.error(response.data.message, 'Upload failed', { 34 | tapToDismiss: false, 35 | closeButton: true, 36 | timeOut: 0, 37 | extendedTimeOut: 0 38 | }); 39 | }) 40 | .finally(function () { 41 | $scope.isRequestPending = false; 42 | }) 43 | } 44 | 45 | function selectValue(index) { 46 | $scope.selectedValue = index; 47 | $scope.selectedAmount = uploadValues[$scope.selectedValue].value; 48 | } 49 | 50 | }); 51 | 52 | -------------------------------------------------------------------------------- /client/app/payment/deposit.money.html: -------------------------------------------------------------------------------- 1 |
2 |

Deposit Cash

3 |
4 |
5 |
6 | 7 |
8 |
9 |
10 |
Please note that UNVERIFIED Paypal accounts 11 | won't be able to use deposited money until they don't verify their Paypal account.
12 |
13 |

How Much Prepaid Credit Do You Want To Deposit?

14 |

Deposits are in US$, are non-refundable and will expire one year from your last deposit.

15 | 16 | 21 | 22 | 23 | 24 |
25 |
26 |
27 |

How Do You Want To Pay?

28 | 29 |
30 |
I have read and agree to the Terms & Conditions, and I am at least 18 years old.
31 | 32 |
33 | 34 | 35 | You will be transferred to a secure PayPal page. After payment your cash will display in the top panel. 36 |
37 | 46 |
47 |
48 |
49 | 50 |
51 |
52 |

Current Credit Balance

53 |  {{user.amount.available_amount || 0 | swMoney}} 54 | View Account History 55 |
56 | 57 |
58 |
59 | 60 |
61 | 62 |
63 | -------------------------------------------------------------------------------- /client/app/payment/payment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 17.8.15.. 3 | */ 4 | 'use strict'; 5 | 6 | angular.module('skywarriorApp') 7 | .config(function($stateProvider) { 8 | $stateProvider 9 | .state('payment', { 10 | abstract: true, 11 | url: '/payment' 12 | }) 13 | .state('deposit', { 14 | url: '/upload', 15 | templateUrl: 'app/payment/deposit.money.html', 16 | controller: 'DepositMoneyCtrl' 17 | }) 18 | }); 19 | -------------------------------------------------------------------------------- /client/app/payment/paypal.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 17.8.15.. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .factory('PayPal', function ($http, $window) { 9 | 10 | return { 11 | depositMoney: depositMoney 12 | }; 13 | 14 | /** ------------------------ IMPLEMENTATION -------------------- **/ 15 | 16 | function depositMoney(upload) { 17 | $window.location.href = '/payment/paypal/deposit'; 18 | } 19 | 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/user/dashboard/dashboard.ctrl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 20.8.15.. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .controller('DashboardCtrl', function ($scope, $state, $uibModal, ItemServiceNew, Auth, userUtil, notification) { 9 | $scope.openSellSkinModal = openSellSkinModal; 10 | $scope.cancelSale = cancelSale; 11 | $scope.selection = []; 12 | $scope.toggle = toggle; 13 | $scope.isDisabled = isDisabled; 14 | $scope.user = Auth.getCurrentUser(); 15 | $scope.isTradeUrlSet = userUtil.isTradeUrlSet; 16 | $scope.isRequestPending = false; 17 | 18 | activate(); 19 | 20 | $scope.$on('open-sell-modal', function () { 21 | openSellSkinModal(); 22 | }); 23 | 24 | /** ------------------------------------------------------------- **/ 25 | 26 | function activate() { 27 | $scope.isLoading = true; 28 | $scope.isRequestPending = true; 29 | return ItemServiceNew.get({user_id: $scope.user.steam_user_id, status: 'on sale'}).then(function (response) { 30 | $scope.sellingItems = response.data; 31 | }).finally(function () { 32 | $scope.isLoading = false; 33 | $scope.isRequestPending = false; 34 | }) 35 | } 36 | 37 | function isDisabled() { 38 | return $scope.selection.length === 0; 39 | } 40 | 41 | function cancelSale() { 42 | $scope.isRequestPending = true; 43 | var selectedItems = _.at($scope.sellingItems, $scope.selection); 44 | var selectedItemIds = _.map(selectedItems, 'steam_id'); 45 | ItemServiceNew.returnItems(selectedItemIds) 46 | .then(function (response) { 47 | notification.success('Item successfully canceled!'); 48 | $state.reload('portfolio').then(function () { 49 | $scope.isRequestPending = false; 50 | }); 51 | }) 52 | .catch(function (error) { 53 | }) 54 | } 55 | 56 | function toggle(idx) { 57 | var pos = $scope.selection.indexOf(idx); 58 | if (pos == -1) { 59 | $scope.selection.push(idx); 60 | } else { 61 | $scope.selection.splice(pos, 1); 62 | } 63 | } 64 | 65 | function openSellSkinModal() { 66 | var modalInstance = $uibModal.open({ 67 | animation: true, 68 | templateUrl: 'app/user/dashboard/sell.skin.modal.html', 69 | controller: 'SellSkinCtrl', 70 | controllerAs: 'vm', 71 | bindToController: true, 72 | size: 'lg' 73 | }); 74 | modalInstance.result.then(function (selectedItem) { 75 | $scope.selected = selectedItem; 76 | }, function () { 77 | }); 78 | } 79 | 80 | }); 81 | 82 | -------------------------------------------------------------------------------- /client/app/user/dashboard/dashboard.html: -------------------------------------------------------------------------------- 1 |
2 |

User Dashboard

3 | 10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 | 18 | 22 | 23 | 45 |
46 |
47 | 48 | 49 | 50 |
51 |
52 |
53 | 54 |
55 | -------------------------------------------------------------------------------- /client/app/user/dashboard/sell.skin.ctrl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 1.9.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .controller('SellSkinCtrl', sellSkinCtrl); 9 | 10 | sellSkinCtrl.$inject = ['$scope','ItemServiceNew', 'UserService', 'notification', '$uibModalInstance']; 11 | 12 | function sellSkinCtrl($scope, ItemServiceNew, UserService, notification) { 13 | var vm = this; 14 | vm.selectedIndex = 0; 15 | vm.selectItem = selectItem; 16 | vm.placeItem = placeItem; 17 | vm.calculateAmount = calculateAmount; 18 | 19 | activate(); 20 | 21 | /**************************** IMPLEMENTATION *******************************/ 22 | 23 | function activate() { 24 | vm.isInventoryLoading = true; 25 | vm.isItemLoading = true; 26 | vm.isRequestPending = true; 27 | return getUserInventory() 28 | .then(selectFirstItemFromInventory()) 29 | .then(function (item) { 30 | ItemServiceNew.getItemPrice(item.market_hash_name).success(function (price) { 31 | _.assign(vm.selectedItem, {steam_price: price, user_price: price}); 32 | // vm.userReceivedAmount = vm.selectedItem.user_price - (vm.selectedItem.user_price * 0.1); VRATI FEE 33 | vm.userReceivedAmount = vm.selectedItem.user_price; 34 | }).finally(function () { 35 | vm.isItemLoading = false; 36 | vm.isRequestPending = false; 37 | }); 38 | }); 39 | } 40 | 41 | 42 | function getUserInventory() { 43 | return UserService.getSteamInventory().then(function (response) { 44 | vm.items = response.data; 45 | return vm.items; 46 | }).finally(function () { 47 | vm.isInventoryLoading = false; 48 | }); 49 | } 50 | 51 | function selectFirstItemFromInventory() { 52 | return function (items) { 53 | if (items && !_.isEmpty(items)) { 54 | vm.selectedItem = items[0]; 55 | return vm.selectedItem; 56 | } 57 | } 58 | } 59 | 60 | 61 | function selectItem(_item, index) { 62 | vm.isItemLoading = true; 63 | ItemServiceNew.getItemPrice(_item.market_hash_name).success(function (price) { 64 | _.assign(_item, {steam_price: price, user_price: price}); 65 | vm.selectedItem = _item; 66 | vm.selectedIndex = index; 67 | // vm.userReceivedAmount = vm.selectedItem.user_price - (vm.selectedItem.user_price * 0.1); VRATI FEE 68 | vm.userReceivedAmount = vm.selectedItem.user_price; 69 | }).finally(function () { 70 | vm.isItemLoading = false; 71 | }); 72 | } 73 | 74 | function calculateAmount() { 75 | // vm.userReceivedAmount = vm.selectedItem.user_price - (vm.selectedItem.user_price * 0.1); VRATI FEE 76 | vm.userReceivedAmount = vm.selectedItem.user_price; 77 | } 78 | 79 | function placeItem(item) { 80 | vm.isRequestPending = true; 81 | UserService.createSellOffer(item) 82 | .then(function (response) { 83 | notification.info(response.data.message, '', {tapToDismiss: false, closeButton : true, timeOut: 0, extendedTimeOut: 0}); 84 | return $scope.$close(response); 85 | }) 86 | .then(function (response) { 87 | }) 88 | .catch(function (error) { 89 | notification.error(error.data.message); 90 | }) 91 | .finally(function () { 92 | vm.isRequestPending = false; 93 | }) 94 | } 95 | } 96 | })(); 97 | -------------------------------------------------------------------------------- /client/app/user/dashboard/sell.skin.modal.html: -------------------------------------------------------------------------------- 1 | 42 | -------------------------------------------------------------------------------- /client/app/user/directive/badges/badges.directive.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 7.2.16.. 3 | */ 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | angular.module('skywarriorApp') 9 | .controller('BadgesDirectiveCtrl', badgesDirectiveCtrl); 10 | 11 | badgesDirectiveCtrl.$inject = []; 12 | 13 | function badgesDirectiveCtrl() { 14 | var vm = this; 15 | 16 | var now = moment(); 17 | var created_at = moment(vm.user.created_at); 18 | vm.daysSinceRegistration = now.diff(created_at, 'days'); 19 | 20 | ////////////////////////////////////////////////// 21 | } 22 | 23 | })(); 24 | -------------------------------------------------------------------------------- /client/app/user/directive/badges/badges.directive.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 7.2.16.. 3 | */ 4 | 5 | (function () { 6 | 'use strict'; 7 | angular.module('skywarriorApp') 8 | .directive('swBadges', itemDirective); 9 | 10 | itemDirective.$inject = []; 11 | 12 | function itemDirective() { 13 | return { 14 | restrict: 'E', 15 | scope: { 16 | user : '=' 17 | }, 18 | templateUrl: 'app/user/directive/badges/badges.template.html', 19 | controller: 'BadgesDirectiveCtrl', 20 | controllerAs: 'vm', 21 | bindToController: true 22 | } 23 | } 24 | 25 | })(); 26 | -------------------------------------------------------------------------------- /client/app/user/directive/badges/badges.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /client/app/user/inventory/inventory.ctrl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 25.10.15.. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .controller('InventoryCtrl', function ($scope, $state, items, ItemServiceNew, UserService, notification, userUtil) { 9 | $scope.items = items; 10 | $scope.putOnSale = putOnSale; 11 | $scope.requestTrade = requestTrade; 12 | $scope.isTradeUrlSet = userUtil.isTradeUrlSet; 13 | $scope.toggle = toggle; 14 | $scope.updateItem = updateItem; 15 | 16 | $scope.selectItem = selectItem; 17 | $scope.selectedItem = null; 18 | $scope.index = null; 19 | 20 | $scope.isDisabled = isDisabled; 21 | 22 | 23 | function isDisabled() { 24 | return !$scope.selectedItem; 25 | } 26 | 27 | function selectItem(selectedItem, $index) { 28 | if ($scope.index === $index) { 29 | $scope.selectedItem = null; 30 | $scope.index = null; 31 | return; 32 | } 33 | $scope.selectedItem = selectedItem; 34 | $scope.index = $index; 35 | } 36 | 37 | function updateItem(item) { 38 | ItemServiceNew.update(item).then(function (response) { 39 | $state.reload(); 40 | }) 41 | } 42 | 43 | function toggle(idx) { 44 | var pos = $scope.selection.indexOf(idx); 45 | if (pos == -1) { 46 | $scope.selection.push(idx); 47 | } else { 48 | $scope.selection.splice(pos, 1); 49 | } 50 | } 51 | 52 | 53 | function putOnSale() { 54 | $scope.isRequestPending = true; 55 | if (!$scope.selectedItem) { 56 | return; 57 | } 58 | ItemServiceNew.putOnSale($scope.selectedItem.steam_id) 59 | .then(function (response) { 60 | notification.success('Item put on sale'); 61 | $state.reload('inventory').then(function () { 62 | $scope.isRequestPending = false; 63 | }); 64 | }) 65 | .catch(function (error) { 66 | notification.error(error); 67 | $scope.isRequestPending = false; 68 | }) 69 | } 70 | 71 | function requestTrade() { 72 | $scope.isRequestPending = true; 73 | if (!$scope.selectedItem) { 74 | return; 75 | } 76 | UserService.createBuyOffer($scope.selectedItem) 77 | .then(function (response) { 78 | notification.info(response.data.message); 79 | $state.reload('inventory').then(function () { 80 | $scope.isRequestPending = false; 81 | }); 82 | }) 83 | .catch(function (error) { 84 | notification.error(error); 85 | $scope.isRequestPending = false; 86 | }); 87 | } 88 | 89 | 90 | }); 91 | -------------------------------------------------------------------------------- /client/app/user/inventory/inventory.html: -------------------------------------------------------------------------------- 1 |
2 |

User Dashboard

3 | 10 |
11 | 12 |
13 |
14 | 15 |
16 | 46 |
47 | 48 | 49 | 50 | 51 | 52 |
53 |
54 |
55 | 56 |
57 | -------------------------------------------------------------------------------- /client/app/user/login/login.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .controller('LoginCtrl', function($scope, Auth, $state) { 5 | $scope.user = {}; 6 | $scope.errors = {}; 7 | 8 | $scope.login = function(form) { 9 | $scope.submitted = true; 10 | 11 | if (form.$valid) { 12 | Auth.login({ 13 | email: $scope.user.email, 14 | password: $scope.user.password 15 | }) 16 | .then(function() { 17 | // Logged in, redirect to home 18 | $state.go('main'); 19 | }) 20 | .catch(function(err) { 21 | $scope.errors.other = err.message; 22 | }); 23 | } 24 | }; 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /client/app/user/login/login.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /client/app/user/login/login.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Login

5 |

Accounts are reset on server restart from server/config/seed.js. Default account is test@test.com / test

6 |

Admin account is admin@admin.com / admin

7 |
8 |
9 |
10 | 11 |
12 | 13 | 14 | 15 |
16 | 17 |
18 | 19 | 20 | 21 |
22 | 23 |
24 |

25 | Please enter your email and password. 26 |

27 |

28 | Please enter a valid email. 29 |

30 | 31 |

{{ errors.other }}

32 |
33 | 34 |
35 | 38 | 39 | Register 40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 | -------------------------------------------------------------------------------- /client/app/user/profile/profile.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Vojkan on 10/19/2015. 3 | */ 4 | 5 | (function () { 6 | 7 | 'use strict'; 8 | 9 | angular.module('skywarriorApp') 10 | .controller('ProfileCtrl', profileCtrl); 11 | 12 | profileCtrl.$inject = ['$stateParams', 'ItemServiceNew', 'user']; 13 | 14 | function profileCtrl($stateParams, ItemServiceNew, user) { 15 | var vm = this; 16 | vm.user = user; 17 | 18 | activate(); 19 | 20 | ////////////////////////////////////////////////////////////////////////////////////////// 21 | 22 | function activate() { 23 | ItemServiceNew.get({user_id: $stateParams.id, status: 'on sale'}) 24 | .success(function (items) { 25 | vm.items = items; 26 | }) 27 | } 28 | 29 | } 30 | 31 | 32 | })(); 33 | -------------------------------------------------------------------------------- /client/app/user/profile/profile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 6 |
7 |

{{vm.user.displayName}}

8 | Steam Profile 9 |
10 |
11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 |
24 |
25 | 26 |
27 |

{{vm.user.displayName}}'s skins

28 |
{{vm.user.displayName}} does not have any skins at the moment.
29 |
    30 |
  • 31 | 32 |
  • 33 |
34 |
35 |
36 | 37 |
38 | 39 | 45 |
46 | 47 |
48 | 49 |
50 | 51 | -------------------------------------------------------------------------------- /client/app/user/settings/settings.controller.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | 'use strict'; 4 | 5 | angular.module('skywarriorApp') 6 | .controller('SettingsCtrl', function ($rootScope, $scope, UserService, Auth, notification, $window) { 7 | $scope.updateUserInfo = updateUserInfo; 8 | $scope.isRequestPending = false; 9 | activate(); 10 | 11 | ////////////////////////////////////////////////////////////////////////////////// 12 | 13 | function activate() { 14 | $scope.isRequestPending = true; 15 | UserService.get().then(function (response) { 16 | $scope.user = response.data; 17 | $scope.user.referralLink = $window.location.origin + '/?ref='+$scope.user.referral_code; 18 | $scope.isRequestPending = false; 19 | }); 20 | } 21 | 22 | function updateUserInfo() { 23 | $scope.isRequestPending = true; 24 | UserService.update($scope.user) 25 | .success(function (updatedUser) { 26 | $scope.user = updatedUser; 27 | Auth.setCurrentUser(updatedUser); 28 | notification.success('User has been updated'); 29 | $rootScope.$broadcast('user:refreshData'); 30 | $scope.isRequestPending = false; 31 | }) 32 | .catch(function (error) { 33 | notification.error('Could not update user. Try again later'); 34 | $scope.isRequestPending = false; 35 | }) 36 | } 37 | 38 | 39 | }); 40 | })(); 41 | -------------------------------------------------------------------------------- /client/app/user/settings/settings.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |

Settings

5 | 12 |
13 | 14 |
15 |
16 | 17 |
18 |
19 |

Personal

20 |
21 | First Name 22 | 23 |
24 | 25 |
26 | Last Name 27 | 28 |
29 | 30 |
31 | Contact Email 33 | 34 |
35 | 36 |
37 | Profile introduction 39 | 40 |
41 | 42 | 43 | 44 | 45 | 46 |
47 |
48 | 49 |

Steam info

50 | 51 |
52 | Trade URL 53 | 54 | 55 | 56 | 57 | Get it 58 | 59 |
60 |
61 | Steam ID 62 | 63 |
64 |
65 | Referal Link 66 | 67 |
68 | 69 |
70 | Your Subscription 71 | 72 |
{{user.subscription.name}} (0%)
73 | No Expiration 74 |
75 | 81 | 82 |
83 |
84 | 85 |
86 |
87 |
88 | 89 |
90 | 91 | -------------------------------------------------------------------------------- /client/app/user/signup/signup.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .controller('SignupCtrl', function($scope, Auth, $state) { 5 | $scope.user = {}; 6 | $scope.errors = {}; 7 | 8 | $scope.register = function(form) { 9 | $scope.submitted = true; 10 | 11 | if (form.$valid) { 12 | Auth.createUser({ 13 | name: $scope.user.name, 14 | email: $scope.user.email, 15 | password: $scope.user.password 16 | }) 17 | .then(function() { 18 | // Account created, redirect to home 19 | $state.go('main'); 20 | }) 21 | .catch(function(err) { 22 | err = err.data; 23 | $scope.errors = {}; 24 | 25 | // Update validity of form fields that match the mongoose errors 26 | angular.forEach(err.errors, function(error, field) { 27 | form[field].$setValidity('mongoose', false); 28 | $scope.errors[field] = error.message; 29 | }); 30 | }); 31 | } 32 | }; 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /client/app/user/signup/signup.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Sign up

5 |
6 |
7 |
8 | 9 |
11 | 12 | 13 | 15 |

16 | A name is required 17 |

18 |
19 | 20 |
22 | 23 | 24 | 27 |

28 | Doesn't look like a valid email. 29 |

30 |

31 | What's your email address? 32 |

33 |

34 | {{ errors.email }} 35 |

36 |
37 | 38 |
40 | 41 | 42 | 46 |

48 | Password must be at least 3 characters. 49 |

50 |

51 | {{ errors.password }} 52 |

53 |
54 | 55 |
56 | 59 | 62 |
63 | 64 |
65 |
66 |
67 |
68 |
69 | -------------------------------------------------------------------------------- /client/app/user/statement/statement.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Vojkan on 10/19/2015. 3 | */ 4 | 'use strict'; 5 | (function () { 6 | 7 | angular.module('skywarriorApp') 8 | .controller('StatementCtrl', statementCtrl); 9 | 10 | statementCtrl.$inject = ['UserService']; 11 | 12 | function statementCtrl(UserService) { 13 | var vm = this; 14 | 15 | activate(); 16 | 17 | //////////////////////////////////////////////// 18 | function activate() { 19 | return UserService.statement().then(function(response){ 20 | return vm.data = response.data; 21 | }) 22 | } 23 | 24 | 25 | } 26 | 27 | })(); 28 | 29 | -------------------------------------------------------------------------------- /client/app/user/statement/statement.html: -------------------------------------------------------------------------------- 1 |
2 |

Statement

3 | 10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 |
18 |

Your sales and referral earnings

19 | 20 | 21 | 22 | 25 | 28 | 31 | 32 | 33 | 34 | 35 | 38 | 41 | 44 | 45 | 46 |
23 |

Net earnings

24 |
26 |

Items sold

27 |
29 |

Items bought

30 |
36 | {{vm.data.total | swMoney}} 37 | 39 | {{vm.data.itemsSold}} 40 | 42 | {{vm.data.itemsBought}} 43 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 73 | 74 | 75 | 77 | 78 | 79 |
TypeOrder IDDateItemPriceSeller
Item {{statement.type}}{{statement.trade_id}}{{statement.created_at | date}} 69 |
70 | {{statement.item_name}} 71 |
72 |
{{statement.price | swMoney}}{{statement.vendor.name}} 76 |
80 |
81 |
82 |
83 |
84 | -------------------------------------------------------------------------------- /client/app/user/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .config(function ($stateProvider) { 5 | $stateProvider 6 | .state('portfolio', { 7 | url: '/dashboard', 8 | templateUrl: 'app/user/dashboard/dashboard.html', 9 | controller: 'DashboardCtrl', 10 | authenticate: true 11 | }) 12 | .state('inventory', { 13 | url: '/inventory', 14 | templateUrl: 'app/user/inventory/inventory.html', 15 | controller: 'InventoryCtrl', 16 | resolve: { 17 | items: function (UserService) { 18 | return UserService.getLocalInventory().then(function (response) { 19 | return response.data; 20 | }) 21 | } 22 | } 23 | }) 24 | .state('profile', { 25 | url: '/profile/{id}', 26 | templateUrl: 'app/user/profile/profile.html', 27 | controller: 'ProfileCtrl', 28 | controllerAs: 'vm', 29 | resolve: { 30 | user: function (UserService, $stateParams) { 31 | return UserService.getById($stateParams.id) 32 | .then(function (response) { 33 | return response.data; 34 | }); 35 | } 36 | } 37 | }) 38 | .state('statement', { 39 | url: '/statement', 40 | templateUrl: 'app/user/statement/statement.html', 41 | controller: 'StatementCtrl', 42 | controllerAs: 'vm', 43 | authenticate: true 44 | }) 45 | .state('withdrawals', { 46 | url: '/withdrawal', 47 | templateUrl: 'app/user/withdrawal/withdrawals.html', 48 | controller: 'WithdrawalCtrl', 49 | controllerAs: 'vm', 50 | authenticate: true 51 | }) 52 | .state('settings', { 53 | url: '/settings', 54 | templateUrl: 'app/user/settings/settings.html', 55 | controller: 'SettingsCtrl', 56 | authenticate: true 57 | }) 58 | .state('logout', { 59 | url: '/logout?referrer', 60 | referrer: 'main', 61 | template: '', 62 | controller: function ($state, Auth) { 63 | var referrer = $state.params.referrer || 64 | $state.current.referrer || 65 | 'main'; 66 | Auth.logout(); 67 | $state.go(referrer); 68 | } 69 | }); 70 | }) 71 | .run(function ($rootScope) { 72 | $rootScope.$on('$stateChangeStart', function (event, next, nextParams, current) { 73 | if (next.name === 'logout' && current && current.name && !current.authenticate) { 74 | next.referrer = current.name; 75 | } 76 | }); 77 | }); 78 | -------------------------------------------------------------------------------- /client/app/user/user.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 16.12.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .factory('UserService', userService); 9 | 10 | userService.$inject = ['$http', 'ItemTransformator']; 11 | 12 | function userService($http, ItemTransformator) { 13 | 14 | return { 15 | get: get, 16 | getById: getById, 17 | getSteamInventory: getSteamInventory, 18 | getLocalInventory: getLocalInventory, 19 | createSellOffer: createSellOffer, 20 | createBuyOffer: createBuyOffer, 21 | update: update, 22 | statement: statement, 23 | getPendingWithdrawals: getPendingWithdrawals, 24 | createWithdrawal: createWithdrawal, 25 | deleteWithdrawal: deleteWithdrawal, 26 | cancelWithdrawal: cancelWithdrawal 27 | }; 28 | 29 | ////////////////////////////////////////////////////////////////////// 30 | 31 | function get() { 32 | return $http.get('/api/users/me'); 33 | } 34 | 35 | function getById(id) { 36 | return $http.get('/api/users/' + id); 37 | } 38 | 39 | function getSteamInventory() { 40 | return $http.get('/api/users/inventory/steam').then(function (response) { 41 | ItemTransformator.transform(response.data); 42 | return response; 43 | }); 44 | } 45 | 46 | function getLocalInventory() { 47 | return $http.get('/api/users/inventory/local') 48 | } 49 | 50 | function createSellOffer(item) { 51 | return $http.post('/api/users/steam/buyOffer', item); 52 | } 53 | 54 | function createBuyOffer(item) { 55 | return $http.post('/api/users/steam/sellOffer', item); 56 | } 57 | 58 | function update(user) { 59 | return $http.post('/api/users/' + user.steam_user_id, user); 60 | } 61 | 62 | function statement() { 63 | return $http.get('/api/statements/'); 64 | } 65 | 66 | function getPendingWithdrawals() { 67 | return $http.get('/api/withdrawals'); 68 | } 69 | 70 | function createWithdrawal(withdrawal) { 71 | return $http.post('/api/withdrawals/', withdrawal); 72 | } 73 | 74 | function cancelWithdrawal(withdrawalId) { 75 | return $http.post('/api/withdrawals/cancel', {id: withdrawalId}); 76 | } 77 | 78 | 79 | function deleteWithdrawal(withdrawalId) { 80 | return $http.delete('/api/withdrawals/' + withdrawalId); 81 | } 82 | 83 | } 84 | 85 | })(); 86 | -------------------------------------------------------------------------------- /client/app/user/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 1.2.16.. 3 | */ 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | angular.module('skywarriorApp') 9 | .factory('userUtil', userUtil); 10 | 11 | userUtil.$inject = ['Auth']; 12 | 13 | function userUtil(Auth) { 14 | return { 15 | isTradeUrlSet: isTradeUrlSet 16 | }; 17 | 18 | ///////////////////////////////////////////////////////////////// 19 | 20 | function isTradeUrlSet() { 21 | var user = Auth.getCurrentUser(); 22 | return !!(user.trade_url && user.trade_url != ''); 23 | } 24 | } 25 | 26 | 27 | })(); 28 | -------------------------------------------------------------------------------- /client/app/user/withdrawal/withdrawal.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Vojkan on 1/31/2016. 3 | */ 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | angular.module('skywarriorApp') 9 | .controller('WithdrawalCtrl', statementCtrl); 10 | 11 | statementCtrl.$inject = ['$rootScope', 'UserService', 'notification', 'Modal']; 12 | 13 | function statementCtrl($rootScope, UserService, notification, Modal) { 14 | var vm = this; 15 | vm.editEmail = false; 16 | vm.makeWithdrawalDisabled = false; 17 | vm.update = updateUserInfo; 18 | vm.makeWithdrawal = makeWithdrawal; 19 | vm.cancelWithdrawal = Modal.confirm.cancel(cancelWithdrawal); 20 | vm.changeEmail = changeEmail; 21 | vm.cancelEditEmail = cancelEditEmail; 22 | vm.isRequestPending = false; 23 | 24 | activate(); 25 | 26 | //////////////////////////////////////////////// 27 | function activate() { 28 | return UserService.get() 29 | .then(function (response) { 30 | return vm.user = response.data; 31 | }) 32 | .then(function (user) { 33 | initWithdrawal(user); 34 | }) 35 | .then(function () { 36 | return UserService.getPendingWithdrawals() 37 | .success(function (withdrawals) { 38 | return vm.pendingWithdrawals = withdrawals; 39 | }) 40 | .error(function (error) { 41 | vm.pendingWithdrawals = []; 42 | }) 43 | }) 44 | .catch(function (error) { 45 | }) 46 | } 47 | 48 | function makeWithdrawal() { 49 | vm.isRequestPending = true; 50 | vm.makeWithdrawalDisabled = true; 51 | UserService.createWithdrawal(vm.withdrawal) 52 | .success(function (withdrawal) { 53 | notification.success('Withdrawal has been created.'); 54 | addToPendingWithdrawals(withdrawal); 55 | initWithdrawal(); 56 | $rootScope.$broadcast('user:refreshData'); 57 | }) 58 | .error(function (error) { 59 | notification.error(error.message); 60 | }) 61 | .finally(function () { 62 | vm.makeWithdrawalDisabled = false; 63 | vm.isRequestPending = true; 64 | }) 65 | } 66 | 67 | function cancelWithdrawal(withdrawalId) { 68 | vm.isRequestPending = true; 69 | UserService.cancelWithdrawal(withdrawalId) 70 | .success(function (response) { 71 | vm.pendingWithdrawals = vm.pendingWithdrawals.filter(function (withdrawal) { 72 | return withdrawal._id !== withdrawalId; 73 | }); 74 | notification.success('Withdrawal has been canceled'); 75 | $rootScope.$broadcast('user:refreshData'); 76 | }) 77 | .error(function (error) { 78 | notification.error(error); 79 | }) 80 | .finally(function () { 81 | vm.isRequestPending = true; 82 | }) 83 | } 84 | 85 | function initWithdrawal() { 86 | vm.withdrawal = { 87 | status: 'pending', 88 | amount: 0, 89 | user_id: vm.user.steam_user_id || null, 90 | withdrawal_email: vm.user.withdrawal_email 91 | }; 92 | } 93 | 94 | function updateUserInfo() { 95 | vm.isRequestPending = true; 96 | vm.user.withdrawal_email = vm.withdrawal_email; 97 | UserService.update(vm.user) 98 | .success(function (updatedUser) { 99 | vm.user = updatedUser; 100 | vm.withdrawal.withdrawal_email = vm.user.withdrawal_email; 101 | $rootScope.$broadcast('user:refreshData', updatedUser); 102 | notification.success('User has been updated'); 103 | cancelEditEmail(); 104 | vm.isRequestPending = false; 105 | }) 106 | .catch(function (error) { 107 | notification.error('Could not update user. Try again later'); 108 | vm.isRequestPending = false; 109 | }) 110 | } 111 | 112 | function addToPendingWithdrawals(withdrawal) { 113 | if (!vm.pendingWithdrawals) { 114 | vm.pendingWithdrawals = []; 115 | } 116 | vm.pendingWithdrawals.push(withdrawal); 117 | } 118 | 119 | function changeEmail() { 120 | vm.edit = true; 121 | vm.withdrawal_email = angular.copy(vm.user.withdrawal_email); 122 | } 123 | 124 | function cancelEditEmail() { 125 | vm.edit = false; 126 | vm.withdrawal_email = null; 127 | } 128 | 129 | 130 | 131 | } 132 | 133 | })(); 134 | -------------------------------------------------------------------------------- /client/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /client/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /client/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /client/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /client/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /client/assets/images/badges/Beta-tester-B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/Beta-tester-B.png -------------------------------------------------------------------------------- /client/assets/images/badges/bought1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/bought1.png -------------------------------------------------------------------------------- /client/assets/images/badges/bought2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/bought2.png -------------------------------------------------------------------------------- /client/assets/images/badges/bought3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/bought3.png -------------------------------------------------------------------------------- /client/assets/images/badges/bought4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/bought4.png -------------------------------------------------------------------------------- /client/assets/images/badges/bought5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/bought5.png -------------------------------------------------------------------------------- /client/assets/images/badges/premium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/premium.png -------------------------------------------------------------------------------- /client/assets/images/badges/referal1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/referal1.png -------------------------------------------------------------------------------- /client/assets/images/badges/referal2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/referal2.png -------------------------------------------------------------------------------- /client/assets/images/badges/referal3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/referal3.png -------------------------------------------------------------------------------- /client/assets/images/badges/referal4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/referal4.png -------------------------------------------------------------------------------- /client/assets/images/badges/referal5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/referal5.png -------------------------------------------------------------------------------- /client/assets/images/badges/sale1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/sale1.png -------------------------------------------------------------------------------- /client/assets/images/badges/sale2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/sale2.png -------------------------------------------------------------------------------- /client/assets/images/badges/sale3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/sale3.png -------------------------------------------------------------------------------- /client/assets/images/badges/sale4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/sale4.png -------------------------------------------------------------------------------- /client/assets/images/badges/sale5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/sale5.png -------------------------------------------------------------------------------- /client/assets/images/badges/staff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/staff.png -------------------------------------------------------------------------------- /client/assets/images/badges/tsr1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/tsr1.png -------------------------------------------------------------------------------- /client/assets/images/badges/tsr2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/tsr2.png -------------------------------------------------------------------------------- /client/assets/images/badges/tsr3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/tsr3.png -------------------------------------------------------------------------------- /client/assets/images/badges/tsr4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/tsr4.png -------------------------------------------------------------------------------- /client/assets/images/badges/tsr5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/badges/tsr5.png -------------------------------------------------------------------------------- /client/assets/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/bg.jpg -------------------------------------------------------------------------------- /client/assets/images/help_desk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/help_desk.png -------------------------------------------------------------------------------- /client/assets/images/hiw/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/hiw/1.jpg -------------------------------------------------------------------------------- /client/assets/images/knife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/knife.png -------------------------------------------------------------------------------- /client/assets/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/logo.jpg -------------------------------------------------------------------------------- /client/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/logo.png -------------------------------------------------------------------------------- /client/assets/images/midb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/midb.jpg -------------------------------------------------------------------------------- /client/assets/images/pattern.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/pattern.jpg -------------------------------------------------------------------------------- /client/assets/images/paymentsf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/paymentsf.png -------------------------------------------------------------------------------- /client/assets/images/paypal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/paypal.png -------------------------------------------------------------------------------- /client/assets/images/ripple.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/assets/images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/search.png -------------------------------------------------------------------------------- /client/assets/images/skrill.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/skrill.jpg -------------------------------------------------------------------------------- /client/assets/images/steam_signin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/steam_signin.png -------------------------------------------------------------------------------- /client/assets/images/ui.totop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/ui.totop.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/case.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/case.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/1.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/10.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/11.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/12.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/13.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/14.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/2.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/3.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/4.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/5.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/6.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/7.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/8.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/cases/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/cases/9.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/heavy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/heavy.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/heavy/M249.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/heavy/M249.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/heavy/MAG-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/heavy/MAG-7.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/heavy/MAG7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/heavy/MAG7.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/heavy/Negev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/heavy/Negev.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/heavy/Nova.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/heavy/Nova.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/heavy/Sawed-Off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/heavy/Sawed-Off.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/heavy/Sawedoff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/heavy/Sawedoff.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/heavy/XM1014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/heavy/XM1014.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/key.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/bayonet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/bayonet.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/bowie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/bowie.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/butterfly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/butterfly.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/butterflyknife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/butterflyknife.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/falchion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/falchion.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/falchion_knife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/falchion_knife.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/flip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/flip.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/flipknife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/flipknife.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/gutknife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/gutknife.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/huntsman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/huntsman.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/huntsmanknife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/huntsmanknife.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/karambit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/karambit.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/m9bayonet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/m9bayonet.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/knife/shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/knife/shadow.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistol.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/CZ75-Auto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/CZ75-Auto.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/CZ75auto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/CZ75auto.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Desert Eagle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Desert Eagle.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Deserteagle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Deserteagle.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Dual Berettas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Dual Berettas.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Dualberettas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Dualberettas.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Five-SeveN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Five-SeveN.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Fiveseven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Fiveseven.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Glock-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Glock-18.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Glock18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Glock18.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/P2000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/P2000.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/P250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/P250.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Tec-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Tec-9.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/Tec9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/Tec9.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/USP-S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/USP-S.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/pistols/USP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/pistols/USP.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/AK-47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/AK-47.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/AUG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/AUG.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/AWP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/AWP.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/FAMAS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/FAMAS.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/G3SG1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/G3SG1.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/Galil AR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/Galil AR.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/Galilar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/Galilar.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/M4A1-S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/M4A1-S.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/M4A4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/M4A4.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/SCAR-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/SCAR-20.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/SG 553.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/SG 553.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/SG553.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/SG553.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/SSG 08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/SSG 08.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/rifle/SSG08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/rifle/SSG08.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/shotgun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/shotgun.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/smg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/smg.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/smg/MAC-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/smg/MAC-10.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/smg/MP7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/smg/MP7.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/smg/MP9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/smg/MP9.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/smg/P90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/smg/P90.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/smg/PP-Bizon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/smg/PP-Bizon.png -------------------------------------------------------------------------------- /client/assets/images/weapon-icons/smg/UMP-45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/assets/images/weapon-icons/smg/UMP-45.png -------------------------------------------------------------------------------- /client/components/auth/user.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .factory('User', function ($resource, ItemTransformator) { 5 | return $resource('/api/users/:id/:controller', { 6 | id: '@_id' 7 | }, 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 | update: { 22 | method: 'POST', 23 | params: { 24 | controller: 'update' 25 | } 26 | }, 27 | inventory: { 28 | method: 'GET', 29 | isArray: true, 30 | params: { 31 | id: 'me', 32 | controller: 'inventory' 33 | }, 34 | transformResponse: function (data) { 35 | data = angular.fromJson(data); 36 | ItemTransformator.transform(data); 37 | return data; 38 | } 39 | }, 40 | makeSellOffer: { 41 | method: 'POST', 42 | params: { 43 | id: 'makeBuyOffer' // from bot point of view 44 | } 45 | }, 46 | makeBuyOffer: { 47 | method: 'POST', 48 | params: { 49 | id: 'makeSellOffer' // from bot point of view 50 | } 51 | }, 52 | getSellingItems: { 53 | method: 'GET', 54 | params: { 55 | id: 'sellingItems' 56 | }, 57 | isArray: true, 58 | transformResponse: function (data) { 59 | if (_.isEmpty(data) || _.isNull(data)) { 60 | return []; 61 | } 62 | data = angular.fromJson(data); 63 | ItemTransformator.transform(data); 64 | return data; 65 | } 66 | } 67 | }); 68 | }); 69 | -------------------------------------------------------------------------------- /client/components/cart/swCart.directives.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 23.9.15.. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | 8 | angular.module('swCart.directives', ['swCart.fulfilment']) 9 | 10 | .directive('swCartAddtocart', ['swCart', function (swCart) { 11 | return { 12 | restrict: 'E', 13 | controller: 'CartController', 14 | scope: { 15 | id: '@', 16 | name: '@', 17 | quantity: '@', 18 | quantityMax: '@', 19 | price: '@', 20 | data: '=', 21 | customClass: '@' 22 | }, 23 | transclude: true, 24 | templateUrl: function (element, attrs) { 25 | if (typeof attrs.templateUrl == 'undefined') { 26 | return 'components/cart/template/addtocart.html'; 27 | } else { 28 | return attrs.templateUrl; 29 | } 30 | }, 31 | link: function (scope, element, attrs) { 32 | scope.attrs = attrs; 33 | scope.isDisabled = false; 34 | scope.inCart = function () { 35 | return swCart.getItemById(attrs.id); 36 | }; 37 | 38 | scope.addItemToCart = function (id, name, price, q, data) { 39 | scope.isDisabled = true; 40 | swCart.addItem(id, name, price, q, data).finally(function () { 41 | scope.isDisabled = false; 42 | }) 43 | }; 44 | 45 | if (scope.inCart()) { 46 | scope.q = swCart.getItemById(attrs.id).getQuantity(); 47 | } else { 48 | scope.q = parseInt(scope.quantity); 49 | } 50 | 51 | scope.qtyOpt = []; 52 | for (var i = 1; i <= scope.quantityMax; i++) { 53 | scope.qtyOpt.push(i); 54 | } 55 | 56 | 57 | } 58 | 59 | }; 60 | }]) 61 | 62 | .directive('swCart', [function () { 63 | return { 64 | restrict: 'E', 65 | controller: 'CartController', 66 | scope: {}, 67 | templateUrl: function (element, attrs) { 68 | if (typeof attrs.templateUrl == 'undefined') { 69 | return 'components/cart/template/cart.html'; 70 | } else { 71 | return attrs.templateUrl; 72 | } 73 | }, 74 | link: function (scope, element, attrs) { 75 | 76 | } 77 | }; 78 | }]) 79 | 80 | .directive('swCartSummary', [function () { 81 | return { 82 | restrict: 'E', 83 | controller: 'CartController', 84 | scope: {}, 85 | transclude: true, 86 | templateUrl: function (element, attrs) { 87 | if (typeof attrs.templateUrl == 'undefined') { 88 | return 'components/cart/template/summary.html'; 89 | } else { 90 | return attrs.templateUrl; 91 | } 92 | } 93 | }; 94 | }]) 95 | 96 | .directive('swCartCheckout', [function () { 97 | return { 98 | restrict: 'E', 99 | controller: ('CartController', ['$rootScope', '$scope', 'swCart', 'fulfilmentProvider', '$state', 'notification', function ($rootScope, $scope, swCart, fulfilmentProvider, $state, notification) { 100 | $scope.swCart = swCart; 101 | 102 | $scope.checkout = function () { 103 | fulfilmentProvider.setService($scope.service); 104 | fulfilmentProvider.setSettings($scope.settings); 105 | fulfilmentProvider.checkout() 106 | .success(function (data, status, headers, config) { 107 | if (data && data.code === 4000) { 108 | notification.warning('Click here to deposit money', data.message); 109 | return; 110 | } 111 | swCart.empty(); 112 | notification.success('You have successfully bought items'); 113 | $state.go('inventory'); 114 | }) 115 | .error(function (data, status, headers, config) { 116 | if (status === 4000) { 117 | $state.go('deposit'); 118 | } 119 | }); 120 | } 121 | }]), 122 | scope: { 123 | service: '@', 124 | settings: '=' 125 | }, 126 | transclude: true, 127 | templateUrl: function (element, attrs) { 128 | if (typeof attrs.templateUrl == 'undefined') { 129 | return 'components/cart/template/checkout.html'; 130 | } else { 131 | return attrs.templateUrl; 132 | } 133 | } 134 | }; 135 | }]); 136 | -------------------------------------------------------------------------------- /client/components/cart/swCart.fulfilment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 23.9.15.. 3 | */ 4 | angular.module('swCart.fulfilment', []) 5 | .service('fulfilmentProvider', ['$injector', function ($injector) { 6 | 7 | this._obj = { 8 | service: undefined, 9 | settings: undefined 10 | }; 11 | 12 | this.setService = function (service) { 13 | this._obj.service = service; 14 | }; 15 | 16 | this.setSettings = function (settings) { 17 | this._obj.settings = settings; 18 | }; 19 | 20 | this.checkout = function () { 21 | var provider = $injector.get('swCart.fulfilment.' + this._obj.service); 22 | return provider.checkout(this._obj.settings); 23 | } 24 | 25 | }]) 26 | 27 | 28 | .service('swCart.fulfilment.log', ['$q', '$log', 'swCart', function ($q, $log, swCart) { 29 | 30 | this.checkout = function () { 31 | 32 | var deferred = $q.defer(); 33 | 34 | $log.info(swCart.toObject()); 35 | deferred.resolve({ 36 | cart: swCart.toObject() 37 | }); 38 | 39 | return deferred.promise; 40 | 41 | } 42 | 43 | }]) 44 | 45 | .service('swCart.fulfilment.http', ['$http', 'swCart', '$rootScope', function ($http, swCart, $rootScope) { 46 | 47 | this.checkout = function (settings) { 48 | return $http.post(settings.url, {data: swCart.toObject(), options: settings.options}).success(function () { 49 | $rootScope.$broadcast('user:refreshData'); 50 | }) 51 | } 52 | }]) 53 | 54 | 55 | .service('swCart.fulfilment.paypal', ['$http', 'swCart', function ($http, swCart) { 56 | 57 | 58 | }]); 59 | -------------------------------------------------------------------------------- /client/components/cart/template/addtocart.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 | 7 | 8 | 9 | 11 |
12 |
13 | -------------------------------------------------------------------------------- /client/components/cart/template/checkout.html: -------------------------------------------------------------------------------- 1 |
2 | Checkout 3 | 4 |
5 | 6 |
7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 |
25 | 26 |
27 | -------------------------------------------------------------------------------- /client/components/cart/template/summary.html: -------------------------------------------------------------------------------- 1 | 2 | {{swCart.getTotalItems()}} 3 | 4 | -------------------------------------------------------------------------------- /client/components/categories-menu/categories-menu.directive.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 16.8.15.. 3 | */ 4 | 5 | angular.module('skywarriorApp') 6 | .directive('categoriesMenu', function () { 7 | return { 8 | templateUrl: 'components/categories-menu/categories-menu.html', 9 | restrict: 'E', 10 | controller: 'CategoriesMenuCtrl', 11 | controllerAs: 'vm' 12 | }; 13 | }); 14 | -------------------------------------------------------------------------------- /client/components/categories-menu/categories.menu.ctrl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 25.7.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .controller('CategoriesMenuCtrl', categoriesMenuCtrl); 9 | 10 | categoriesMenuCtrl.$inject = ['$state']; 11 | 12 | function categoriesMenuCtrl($state) { 13 | var vm = this; 14 | vm.searchItem = searchItem; 15 | 16 | //////////////////////////////////////////////////////////////// 17 | 18 | function searchItem() { 19 | $state.go('search.query', {q: vm.search, status: 'on sale'}).then(function () { 20 | vm.search = ''; 21 | }); 22 | } 23 | } 24 | 25 | })(); 26 | -------------------------------------------------------------------------------- /client/components/filters/swMoney.filter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 14.11.15.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | 7 | angular.module('skywarriorApp') 8 | .filter('swMoney', function ($filter) { 9 | var currency = $filter('currency'); 10 | return function (amount) { 11 | amount = amount / 100; 12 | return currency(amount, '$', 2); 13 | } 14 | }); 15 | })(); 16 | -------------------------------------------------------------------------------- /client/components/filters/to_trusted.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 7.1.16.. 3 | */ 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | angular.module('skywarriorApp') 9 | .filter('to_trusted', ['$sce', function ($sce) { 10 | return function (text) { 11 | return $sce.trustAsHtml(text); 12 | }; 13 | }]); 14 | })(); 15 | -------------------------------------------------------------------------------- /client/components/footer/footer.directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .directive('swFooter', 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 | -------------------------------------------------------------------------------- /client/components/footer/footer.html: -------------------------------------------------------------------------------- 1 |
2 | 9 | 10 | 18 | 19 | 27 | -------------------------------------------------------------------------------- /client/components/modal/modal.css: -------------------------------------------------------------------------------- 1 | .modal-primary .modal-header, 2 | .modal-info .modal-header, 3 | .modal-success .modal-header, 4 | .modal-warning .modal-header, 5 | .modal-danger .modal-header { 6 | color: #fff; 7 | border-radius: 5px 5px 0 0; 8 | } 9 | .modal-primary .modal-header { 10 | background: #428bca; 11 | } 12 | .modal-info .modal-header { 13 | background: #5bc0de; 14 | } 15 | .modal-success .modal-header { 16 | background: #5cb85c; 17 | } 18 | .modal-warning .modal-header { 19 | background: #f0ad4e; 20 | } 21 | .modal-danger .modal-header { 22 | background: #d9534f; 23 | } 24 | -------------------------------------------------------------------------------- /client/components/modal/modal.html: -------------------------------------------------------------------------------- 1 | 5 | 9 | 12 | -------------------------------------------------------------------------------- /client/components/modal/modal.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .factory('Modal', function ($rootScope, $uibModal) { 5 | /** 6 | * Opens a modal 7 | * @param {Object} scope - an object to be merged with modal's scope 8 | * @param {String} modalClass - (optional) class(es) to be applied to the modal 9 | * @return {Object} - the instance $modal.open() returns 10 | */ 11 | function openModal(scope, modalClass) { 12 | var modalScope = $rootScope.$new(); 13 | scope = scope || {}; 14 | modalClass = modalClass || 'modal-default'; 15 | 16 | angular.extend(modalScope, scope); 17 | 18 | return $uibModal.open({ 19 | templateUrl: 'components/modal/modal.html', 20 | windowClass: modalClass, 21 | scope: modalScope 22 | }); 23 | } 24 | 25 | // Public API here 26 | return { 27 | 28 | info: function (message) { 29 | var infoModal = openModal({ 30 | modal: { 31 | dismissable: true, 32 | title: 'Info', 33 | html: '

' + message + '

', 34 | buttons: [{ 35 | classes: 'btn-default', 36 | text: 'OK', 37 | click: function (e) { 38 | infoModal.close(e); 39 | } 40 | }] 41 | } 42 | }, 'modal-info'); 43 | 44 | }, 45 | 46 | error: function (message) { 47 | var errorModal = openModal({ 48 | modal: { 49 | dismissable: true, 50 | title: 'Error', 51 | html: '

' + message + '

', 52 | buttons: [{ 53 | classes: 'btn-danger', 54 | text: 'OK', 55 | click: function (e) { 56 | errorModal.close(e); 57 | } 58 | }] 59 | } 60 | }, 'modal-danger'); 61 | 62 | }, 63 | 64 | /* Confirmation modals */ 65 | confirm: { 66 | 67 | cancel: function (callback) { 68 | callback = callback || angular.noop; 69 | 70 | 71 | return function () { 72 | var args = Array.prototype.slice.call(arguments); 73 | var name = args.shift(); 74 | var cancelModal; 75 | 76 | cancelModal = openModal({ 77 | modal: { 78 | dismissable: true, 79 | title: 'Confirm cancel', 80 | html: '

Are you sure you would like to cancel ' + name + ' ?

', 81 | buttons: [{ 82 | classes: 'btn-danger', 83 | text: 'Yes', 84 | click: function (e) { 85 | cancelModal.close(e); 86 | } 87 | }, { 88 | classes: 'btn-default', 89 | text: 'No', 90 | click: function (e) { 91 | cancelModal.dismiss(e); 92 | } 93 | }] 94 | } 95 | }, 'modal-danger'); 96 | 97 | cancelModal.result.then(function (event) { 98 | callback.apply(event, args); 99 | }); 100 | } 101 | }, 102 | 103 | /** 104 | * Create a function to open a delete confirmation modal (ex. ng-click='myModalFn(name, arg1, arg2...)') 105 | * @param {Function} del - callback, ran when delete is confirmed 106 | * @return {Function} - the function to open the modal (ex. myModalFn) 107 | */ 108 | delete: function (del) { 109 | del = del || angular.noop; 110 | 111 | /** 112 | * Open a delete confirmation modal 113 | * @param {String} name - name or info to show on modal 114 | * @param {All} - any additional args are passed straight to del callback 115 | */ 116 | return function () { 117 | var args = Array.prototype.slice.call(arguments), 118 | name = args.shift(), 119 | deleteModal; 120 | 121 | deleteModal = openModal({ 122 | modal: { 123 | dismissable: true, 124 | title: 'Confirm Delete', 125 | html: '

Are you sure you want to delete ' + name + ' ?

', 126 | buttons: [{ 127 | classes: 'btn-danger', 128 | text: 'Delete', 129 | click: function (e) { 130 | deleteModal.close(e); 131 | } 132 | }, { 133 | classes: 'btn-default', 134 | text: 'Cancel', 135 | click: function (e) { 136 | deleteModal.dismiss(e); 137 | } 138 | }] 139 | } 140 | }, 'modal-danger'); 141 | 142 | deleteModal.result.then(function (event) { 143 | del.apply(event, args); 144 | }); 145 | }; 146 | } 147 | } 148 | }; 149 | }); 150 | -------------------------------------------------------------------------------- /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('skywarriorApp') 7 | .directive('mongooseError', function () { 8 | return { 9 | restrict: 'A', 10 | require: 'ngModel', 11 | link: function(scope, element, attrs, ngModel) { 12 | element.on('keydown', function() { 13 | return ngModel.$setValidity('mongoose', true); 14 | }); 15 | } 16 | }; 17 | }); 18 | -------------------------------------------------------------------------------- /client/components/navbar/navbar.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .controller('NavbarCtrl', function ($rootScope, $scope, $state, Auth, $window, $location, swCart, UserService, userUtil) { 5 | $scope.isCollapsed = true; 6 | $scope.isLoggedIn = Auth.isLoggedIn; 7 | $scope.isAdmin = Auth.isAdmin; 8 | $scope.user = Auth.getCurrentUser(); 9 | $scope.isTradeUrlSet = userUtil.isTradeUrlSet; 10 | $scope.swCart = swCart; 11 | $scope.authenticate = authenticate; 12 | $scope.sellASkinClickAction = sellASkinClickAction; 13 | 14 | //////////////////////////////////////////////////// 15 | 16 | function sellASkinClickAction() { 17 | if (Auth.isLoggedIn()) { 18 | return $state.go('portfolio').then(function () { 19 | $scope.$broadcast('open-sell-modal'); 20 | }); 21 | } 22 | authenticate(); 23 | } 24 | 25 | $rootScope.$on('swCart:expired', function () { 26 | }); 27 | 28 | $rootScope.$on('user:refreshData', function () { 29 | return UserService.get().success(function (user) { 30 | Auth.setCurrentUser(user); 31 | return $scope.user = user; 32 | }) 33 | }); 34 | 35 | function authenticate() { 36 | $window.location.href = '/auth/steam'; 37 | } 38 | 39 | }); 40 | -------------------------------------------------------------------------------- /client/components/navbar/navbar.directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('skywarriorApp') 4 | .directive('navbar', function () { 5 | return { 6 | templateUrl: 'components/navbar/navbar.html', 7 | restrict: 'E', 8 | controller: 'NavbarCtrl' 9 | }; 10 | }); 11 | -------------------------------------------------------------------------------- /client/components/navbar/navbar.html: -------------------------------------------------------------------------------- 1 | 6 | 11 | 72 | -------------------------------------------------------------------------------- /client/components/notification/notification.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 19.1.16.. 3 | */ 4 | (function () { 5 | 'use strict'; 6 | 7 | angular.module('skywarrior.notification', []) 8 | .config(configure) 9 | .factory('notification', notificationFactory); 10 | 11 | notificationFactory.$inject = []; 12 | 13 | function notificationFactory() { 14 | return { 15 | success: function (message, title, overrideOptions) { 16 | title = title || 'Success'; 17 | toastr.success(message, title, overrideOptions) 18 | }, 19 | 20 | error: function (message, title, overrideOptions) { 21 | title = title || 'Error'; 22 | toastr.error(message, title, overrideOptions) 23 | }, 24 | 25 | info: function (message, title, overrideOptions) { 26 | title = title || 'Info'; 27 | toastr.info(message, title, overrideOptions) 28 | 29 | }, 30 | 31 | warning: function (message, title, overrideOptions) { 32 | title = title || 'Warning'; 33 | toastr.warning(message, title, overrideOptions) 34 | } 35 | 36 | } 37 | } 38 | 39 | function configure() { 40 | toastr.options = { 41 | closeButton: false, 42 | debug: false, 43 | newestOnTop: false, 44 | progressBar: false, 45 | positionClass: 'toast-bottom-right', 46 | preventDuplicates: false, 47 | onclick: null, 48 | showDuration: '300', 49 | hideDuration: '1000', 50 | timeOut: '5000', 51 | extendedTimeOut: '1000', 52 | showEasing: 'swing', 53 | hideEasing: 'linear', 54 | showMethod: 'fadeIn', 55 | hideMethod: 'fadeOut' 56 | } 57 | } 58 | 59 | })(); 60 | -------------------------------------------------------------------------------- /client/components/noty/noty.wrapper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mirko on 28.9.15.. 3 | */ 4 | 'use strict'; 5 | 6 | (function (angular, $) { 7 | return angular.module('swNoty', []).provider('Noty', function () { 8 | var settings = $.noty.defaults; 9 | 10 | return { 11 | settings: settings, 12 | $get: function () { 13 | var callNoty = function (newSettings) { 14 | return noty(newSettings || {}); 15 | }; 16 | 17 | return { 18 | show: function (message, type) { 19 | callNoty({text: message || settings.text, type: type || settings.type}); 20 | }, 21 | 22 | showAlert: function (message) { 23 | callNoty({text: message || settings.text, type: "alert"}); 24 | }, 25 | 26 | showSuccess: function (message) { 27 | callNoty({text: message || settings.text, type: "success"}); 28 | }, 29 | 30 | showError: function (message) { 31 | callNoty({text: message, type: "error"}); 32 | }, 33 | 34 | closeAll: function () { 35 | return $.noty.closeAll() 36 | }, 37 | clearShowQueue: function () { 38 | return $.noty.clearQueue(); 39 | }.bind(this) 40 | } 41 | } 42 | 43 | }; 44 | }) 45 | }(angular, jQuery)); 46 | -------------------------------------------------------------------------------- /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/socket/socket.service.js: -------------------------------------------------------------------------------- 1 | /* global io */ 2 | 'use strict'; 3 | 4 | angular.module('skywarriorApp') 5 | .factory('socket', function(socketFactory) { 6 | 7 | // socket.io now auto-configures its connection when we ommit a connection url 8 | var ioSocket = io('', { 9 | // Send auth token on connection, you will need to DI the Auth service above 10 | // 'query': 'token=' + Auth.getToken() 11 | path: '/socket.io-client' 12 | }); 13 | 14 | var socket = socketFactory({ 15 | ioSocket: ioSocket 16 | }); 17 | 18 | return { 19 | socket: socket, 20 | 21 | /** 22 | * Register listeners to sync an array with updates on a model 23 | * 24 | * Takes the array we want to sync, the model name that socket updates are sent from, 25 | * and an optional callback function after new items are updated. 26 | * 27 | * @param {String} modelName 28 | * @param {Array} array 29 | * @param {Function} cb 30 | */ 31 | syncUpdates: function (modelName, array, cb) { 32 | cb = cb || angular.noop; 33 | 34 | /** 35 | * Syncs item creation/updates on 'model:save' 36 | */ 37 | socket.on(modelName + ':save', function (item) { 38 | var oldItem = _.find(array, {_id: item._id}); 39 | var index = array.indexOf(oldItem); 40 | var event = 'created'; 41 | 42 | // replace oldItem if it exists 43 | // otherwise just add item to the collection 44 | if (oldItem) { 45 | array.splice(index, 1, item); 46 | event = 'updated'; 47 | } else { 48 | array.push(item); 49 | } 50 | 51 | cb(event, item, array); 52 | }); 53 | 54 | /** 55 | * Syncs removed items on 'model:remove' 56 | */ 57 | socket.on(modelName + ':remove', function (item) { 58 | var event = 'deleted'; 59 | _.remove(array, {_id: item._id}); 60 | cb(event, item, array); 61 | }); 62 | }, 63 | 64 | /** 65 | * Removes listeners for a models updates on the socket 66 | * 67 | * @param modelName 68 | */ 69 | unsyncUpdates: function (modelName) { 70 | socket.removeAllListeners(modelName + ':save'); 71 | socket.removeAllListeners(modelName + ':remove'); 72 | } 73 | }; 74 | }); 75 | -------------------------------------------------------------------------------- /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 | var deferred = $q.defer(); 17 | var promise = deferred.promise; 18 | deferred.resolve(); 19 | return promise; 20 | }; 21 | 22 | this.go = this.transitionTo; 23 | 24 | this.expectTransitionTo = function(stateName) { 25 | this.expectedTransitions.push(stateName); 26 | }; 27 | 28 | this.ensureAllTransitionsHappened = function() { 29 | if (this.expectedTransitions.length > 0) { 30 | throw Error('Not all transitions happened!'); 31 | } 32 | }; 33 | }); 34 | -------------------------------------------------------------------------------- /client/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/favicon.ico -------------------------------------------------------------------------------- /client/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchoeup/angular-simple-app/4b7e112dd1869d00fd6c306cdc91aeeeb55d6296/client/favicon.png -------------------------------------------------------------------------------- /client/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /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 | this.form = element(by.css('.form')); 10 | this.form.email = this.form.element(by.model('user.email')); 11 | this.form.password = this.form.element(by.model('user.password')); 12 | this.form.submit = this.form.element(by.css('.btn-login')); 13 | 14 | this.login = function(data) { 15 | for (var prop in data) { 16 | var formElem = this.form[prop]; 17 | if (data.hasOwnProperty(prop) && formElem && typeof formElem.sendKeys === 'function') { 18 | formElem.sendKeys(data[prop]); 19 | } 20 | } 21 | 22 | this.form.submit.click(); 23 | }; 24 | }; 25 | 26 | module.exports = new LoginPage(); 27 | 28 | -------------------------------------------------------------------------------- /e2e/account/login/login.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('Login View', function() { 7 | var page; 8 | 9 | var loadPage = function() { 10 | browser.get(config.baseUrl + '/login'); 11 | page = require('./login.po'); 12 | }; 13 | 14 | var testUser = { 15 | name: 'Test User', 16 | email: 'test@test.com', 17 | password: 'test' 18 | }; 19 | 20 | beforeEach(function(done) { 21 | UserModel.removeAsync() 22 | .then(function() { 23 | return UserModel.createAsync(testUser); 24 | }) 25 | .then(loadPage) 26 | .finally(done); 27 | }); 28 | 29 | it('should include login form with correct inputs and submit button', function() { 30 | expect(page.form.email.getAttribute('type')).toBe('email'); 31 | expect(page.form.email.getAttribute('name')).toBe('email'); 32 | expect(page.form.password.getAttribute('type')).toBe('password'); 33 | expect(page.form.password.getAttribute('name')).toBe('password'); 34 | expect(page.form.submit.getAttribute('type')).toBe('submit'); 35 | expect(page.form.submit.getText()).toBe('Login'); 36 | }); 37 | 38 | describe('with local auth', function() { 39 | 40 | it('should login a user and redirecting to "/"', function() { 41 | page.login(testUser); 42 | 43 | var navbar = require('../../components/navbar/navbar.po'); 44 | 45 | expect(browser.getCurrentUrl()).toBe(config.baseUrl + '/'); 46 | expect(navbar.navbarAccountGreeting.getText()).toBe('Hello ' + testUser.name); 47 | }); 48 | 49 | it('should indicate login failures', function() { 50 | page.login({ 51 | email: testUser.email, 52 | password: 'badPassword' 53 | }); 54 | 55 | expect(browser.getCurrentUrl()).toBe(config.baseUrl + '/login'); 56 | 57 | var helpBlock = page.form.element(by.css('.form-group.has-error .help-block.ng-binding')); 58 | expect(helpBlock.getText()).toBe('This password is not correct.'); 59 | }); 60 | 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /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 | browser.get(config.baseUrl + '/login'); 9 | require('../login/login.po').login(user); 10 | }; 11 | 12 | var testUser = { 13 | name: 'Test User', 14 | email: 'test@test.com', 15 | password: 'test' 16 | }; 17 | 18 | beforeEach(function(done) { 19 | UserModel.removeAsync() 20 | .then(function() { 21 | return UserModel.createAsync(testUser); 22 | }) 23 | .then(function() { 24 | return login(testUser); 25 | }) 26 | .finally(done); 27 | }); 28 | 29 | describe('with local auth', function() { 30 | 31 | it('should logout a user and redirecting to "/"', function() { 32 | var navbar = require('../../components/navbar/navbar.po'); 33 | 34 | expect(browser.getCurrentUrl()).toBe(config.baseUrl + '/'); 35 | expect(navbar.navbarAccountGreeting.getText()).toBe('Hello ' + testUser.name); 36 | 37 | browser.get(config.baseUrl + '/logout'); 38 | 39 | navbar = require('../../components/navbar/navbar.po'); 40 | 41 | expect(browser.getCurrentUrl()).toBe(config.baseUrl + '/'); 42 | expect(navbar.navbarAccountGreeting.isDisplayed()).toBe(false); 43 | }); 44 | 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /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 | this.form = element(by.css('.form')); 10 | this.form.name = this.form.element(by.model('user.name')); 11 | this.form.email = this.form.element(by.model('user.email')); 12 | this.form.password = this.form.element(by.model('user.password')); 13 | this.form.submit = this.form.element(by.css('.btn-register')); 14 | 15 | this.signup = function(data) { 16 | for (var prop in data) { 17 | var formElem = this.form[prop]; 18 | if (data.hasOwnProperty(prop) && formElem && typeof formElem.sendKeys === 'function') { 19 | formElem.sendKeys(data[prop]); 20 | } 21 | } 22 | 23 | this.form.submit.click(); 24 | }; 25 | }; 26 | 27 | module.exports = new SignupPage(); 28 | 29 | -------------------------------------------------------------------------------- /e2e/account/signup/signup.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('Signup View', function() { 7 | var page; 8 | 9 | var loadPage = function() { 10 | browser.manage().deleteAllCookies(); 11 | browser.get(config.baseUrl + '/signup'); 12 | page = require('./signup.po'); 13 | }; 14 | 15 | var testUser = { 16 | name: 'Test', 17 | email: 'test@test.com', 18 | password: 'test' 19 | }; 20 | 21 | beforeEach(function() { 22 | loadPage(); 23 | }); 24 | 25 | it('should include signup form with correct inputs and submit button', function() { 26 | expect(page.form.name.getAttribute('type')).toBe('text'); 27 | expect(page.form.name.getAttribute('name')).toBe('name'); 28 | expect(page.form.email.getAttribute('type')).toBe('email'); 29 | expect(page.form.email.getAttribute('name')).toBe('email'); 30 | expect(page.form.password.getAttribute('type')).toBe('password'); 31 | expect(page.form.password.getAttribute('name')).toBe('password'); 32 | expect(page.form.submit.getAttribute('type')).toBe('submit'); 33 | expect(page.form.submit.getText()).toBe('Sign up'); 34 | }); 35 | 36 | describe('with local auth', function() { 37 | 38 | beforeAll(function(done) { 39 | UserModel.removeAsync().then(done); 40 | }); 41 | 42 | it('should signup a new user, log them in, and redirecting to "/"', function() { 43 | page.signup(testUser); 44 | 45 | var navbar = require('../../components/navbar/navbar.po'); 46 | 47 | expect(browser.getCurrentUrl()).toBe(config.baseUrl + '/'); 48 | expect(navbar.navbarAccountGreeting.getText()).toBe('Hello ' + testUser.name); 49 | }); 50 | 51 | it('should indicate signup failures', function() { 52 | page.signup(testUser); 53 | 54 | expect(browser.getCurrentUrl()).toBe(config.baseUrl + '/signup'); 55 | expect(page.form.email.getAttribute('class')).toContain('ng-invalid-mongoose'); 56 | 57 | var helpBlock = page.form.element(by.css('.form-group.has-error .help-block.ng-binding')); 58 | expect(helpBlock.getText()).toBe('The specified email address is already in use.'); 59 | }); 60 | 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | browser.get(config.baseUrl + '/'); 10 | page = require('./main.po'); 11 | }); 12 | 13 | it('should include jumbotron with correct data', function() { 14 | expect(page.h1El.getText()).toBe('\'Allo, \'Allo!'); 15 | expect(page.imgEl.getAttribute('src')).toMatch(/yeoman.png$/); 16 | expect(page.imgEl.getAttribute('alt')).toBe('I\'m Yeoman'); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // http://karma-runner.github.io/0.10/config/configuration-file.html 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | // base path, that will be used to resolve files and exclude 7 | basePath: '', 8 | 9 | // testing framework to use (jasmine/mocha/qunit/...) 10 | frameworks: ['jasmine'], 11 | 12 | // list of files / patterns to load in the browser 13 | files: [ 14 | // bower:js 15 | 'client/bower_components/jquery/dist/jquery.js', 16 | 'client/bower_components/angular/angular.js', 17 | 'client/bower_components/angular-bootstrap/ui-bootstrap-tpls.js', 18 | 'client/bower_components/angular-cookies/angular-cookies.js', 19 | 'client/bower_components/angular-resource/angular-resource.js', 20 | 'client/bower_components/angular-sanitize/angular-sanitize.js', 21 | 'client/bower_components/angular-socket-io/socket.js', 22 | 'client/bower_components/angular-ui-router/release/angular-ui-router.js', 23 | 'client/bower_components/lodash/lodash.js', 24 | 'client/bower_components/noty/js/noty/packaged/jquery.noty.packaged.js', 25 | 'client/bower_components/angular-mocks/angular-mocks.js', 26 | // endbower 27 | 'node_modules/socket.io-client/socket.io.js', 28 | 'client/app/app.js', 29 | 'client/app/app.coffee', 30 | 'client/app/**/*.js', 31 | 'client/app/**/*.coffee', 32 | 'client/components/**/*.js', 33 | 'client/components/**/*.coffee', 34 | 'client/app/**/*.jade', 35 | 'client/components/**/*.jade', 36 | 'client/app/**/*.html', 37 | 'client/components/**/*.html' 38 | ], 39 | 40 | preprocessors: { 41 | '**/*.jade': 'ng-jade2js', 42 | '**/*.html': 'html2js', 43 | '**/*.coffee': 'coffee', 44 | }, 45 | 46 | ngHtml2JsPreprocessor: { 47 | stripPrefix: 'client/' 48 | }, 49 | 50 | ngJade2JsPreprocessor: { 51 | stripPrefix: 'client/' 52 | }, 53 | 54 | 55 | 56 | // list of files / patterns to exclude 57 | exclude: [], 58 | 59 | // web server port 60 | port: 8080, 61 | 62 | // level of logging 63 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 64 | logLevel: config.LOG_INFO, 65 | 66 | // reporter types: 67 | // - dots 68 | // - progress (default) 69 | // - spec (karma-spec-reporter) 70 | // - junit 71 | // - growl 72 | // - coverage 73 | reporters: ['spec'], 74 | 75 | // enable / disable watching file and executing tests whenever any file changes 76 | autoWatch: false, 77 | 78 | 79 | // Start these browsers, currently available: 80 | // - Chrome 81 | // - ChromeCanary 82 | // - Firefox 83 | // - Opera 84 | // - Safari (only Mac) 85 | // - PhantomJS 86 | // - IE (only Windows) 87 | browsers: ['PhantomJS'], 88 | 89 | 90 | // Continuous Integration mode 91 | // if true, it capture browsers, run tests and exit 92 | singleRun: false 93 | }); 94 | }; 95 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "skywarrior", 3 | "version": "0.0.0", 4 | "main": "server/app.js", 5 | "dependencies": { 6 | "agenda": "^0.7.2", 7 | "babel-core": "^5.6.4", 8 | "bluebird": "2.9.x", 9 | "body-parser": "~1.5.0", 10 | "composable-middleware": "^0.3.0", 11 | "compression": "~1.0.1", 12 | "connect-mongo": "^0.8.1", 13 | "cookie-parser": "~1.0.1", 14 | "crypto": "0.0.3", 15 | "ejs": "~0.8.4", 16 | "errorhandler": "~1.0.0", 17 | "express": "^4.9.8", 18 | "express-jwt": "^3.0.0", 19 | "express-session": "~1.0.2", 20 | "jsonwebtoken": "^5.0.0", 21 | "lodash": "^4.0.1", 22 | "method-override": "~1.0.0", 23 | "moment": "^2.10.6", 24 | "mongoose": "^4.2.9", 25 | "morgan": "~1.0.0", 26 | "node-slack": "0.0.7", 27 | "node-uuid": "^1.4.3", 28 | "passport": "~0.2.0", 29 | "passport-local": "~0.1.6", 30 | "passport-steam": "^0.1.5", 31 | "paypal-rest-sdk": "^1.6.1", 32 | "pm2": "^1.0.0", 33 | "raven": "^0.10.0", 34 | "redis": "^2.3.0", 35 | "request": "^2.65.0", 36 | "serve-favicon": "~2.0.1", 37 | "socket.io": "^1.3.5", 38 | "socket.io-client": "^1.3.5", 39 | "socketio-jwt": "^4.2.0", 40 | "steam-totp": "1.3.0", 41 | "steam-tradeoffer-manager": "1.18.1", 42 | "steam-user": "3.3.0", 43 | "steamcommunity": "3.18.5", 44 | "steamid": "^0.3.1", 45 | "winston": "^1.0.1" 46 | }, 47 | "devDependencies": { 48 | "autoprefixer": "^6.3.1", 49 | "bower": "~1.3.12", 50 | "connect-livereload": "^0.5.3", 51 | "grunt": "~0.4.4", 52 | "grunt-angular-templates": "^0.5.4", 53 | "grunt-asset-injector": "^0.1.0", 54 | "grunt-autoprefixer": "~0.7.2", 55 | "grunt-cli": "~0.1.11", 56 | "grunt-concurrent": "~0.5.0", 57 | "grunt-contrib-clean": "~0.5.0", 58 | "grunt-contrib-concat": "~0.4.0", 59 | "grunt-contrib-copy": "~0.5.0", 60 | "grunt-contrib-cssmin": "~0.9.0", 61 | "grunt-contrib-htmlmin": "~0.2.0", 62 | "grunt-contrib-imagemin": "~0.7.1", 63 | "grunt-contrib-jshint": "~0.10.0", 64 | "grunt-contrib-sass": "^0.7.3", 65 | "grunt-contrib-uglify": "~0.4.0", 66 | "grunt-contrib-watch": "~0.6.1", 67 | "grunt-dom-munger": "^3.4.0", 68 | "grunt-env": "~0.4.1", 69 | "grunt-express-server": "~0.4.17", 70 | "grunt-filerev": "^2.3.1", 71 | "grunt-google-cdn": "~0.4.0", 72 | "grunt-injector": "^0.6.1", 73 | "grunt-karma": "~0.8.2", 74 | "grunt-mocha-test": "~0.10.2", 75 | "grunt-newer": "~0.7.0", 76 | "grunt-ng-annotate": "^0.2.3", 77 | "grunt-node-inspector": "~0.1.5", 78 | "grunt-nodemon": "~0.2.0", 79 | "grunt-npm-install": "^0.2.0", 80 | "grunt-open": "~0.2.3", 81 | "grunt-postcss": "^0.7.1", 82 | "grunt-protractor-runner": "^1.1.0", 83 | "grunt-rev": "~0.1.0", 84 | "grunt-sass": "^1.0.0", 85 | "grunt-svgmin": "~0.4.0", 86 | "grunt-usemin": "3.0.0", 87 | "grunt-wiredep": "~1.8.0", 88 | "imagemin-gifsicle": "^2.0.0", 89 | "imagemin-jpegtran": "^2.0.0", 90 | "imagemin-optipng": "^2.0.1", 91 | "imagemin-pngquant": "^2.0.0", 92 | "jit-grunt": "^0.5.0", 93 | "jshint-stylish": "~0.1.5", 94 | "karma": "~0.12.9", 95 | "karma-chrome-launcher": "~0.1.3", 96 | "karma-cli": "0.0.4", 97 | "karma-coffee-preprocessor": "~0.2.1", 98 | "karma-firefox-launcher": "~0.1.3", 99 | "karma-html2js-preprocessor": "~0.1.0", 100 | "karma-jade-preprocessor": "0.0.11", 101 | "karma-jasmine": "~0.1.5", 102 | "karma-ng-html2js-preprocessor": "~0.1.0", 103 | "karma-ng-jade2js-preprocessor": "^0.1.2", 104 | "karma-ng-scenario": "~0.1.0", 105 | "karma-phantomjs-launcher": "~0.1.4", 106 | "karma-requirejs": "~0.2.1", 107 | "karma-script-launcher": "~0.1.0", 108 | "open": "~0.0.4", 109 | "requirejs": "~2.1.11", 110 | "should": "~3.3.1", 111 | "supertest": "~0.11.0", 112 | "time-grunt": "~0.3.1" 113 | }, 114 | "engines": { 115 | "node": ">=0.10.0" 116 | }, 117 | "scripts": { 118 | "start": "pm2 start server/app.js", 119 | "stop": "pm2 stop all", 120 | "test": "grunt test", 121 | "update-webdriver": "node node_modules/grunt-protractor-runner/node_modules/protractor/bin/webdriver-manager update" 122 | }, 123 | "private": true 124 | } 125 | -------------------------------------------------------------------------------- /polldata.json: -------------------------------------------------------------------------------- 1 | {"sent":{"755991832":3,"755999509":6,"764415759":3,"764517019":6,"764580216":3,"764596477":7,"764611632":3,"764687844":6,"764725148":3,"768991779":3,"769026380":3,"769044234":3,"769075077":6,"769213153":3,"769257940":3,"769290901":6,"770385105":3,"771163071":6,"771182385":3,"771358071":6,"771364681":6,"771380673":6,"771398865":6,"771410090":3,"771441236":7,"771448211":3,"775444094":3,"775492231":3,"779571923":3,"783863992":3,"786032528":3,"786177489":3,"786206795":3,"786233605":3,"786255023":3,"786257213":8,"786258322":3,"791725069":6,"791739486":3,"791744175":3,"791777392":3,"791922599":7,"791927407":3,"791939924":3,"792023295":3,"792035517":3,"792040735":3,"792966762":3,"792999994":3,"793006290":3,"793040006":3,"793044187":3,"793051198":3,"793055998":3,"793198423":3,"793202358":3,"793217795":3,"793219893":3,"793232965":3,"793236752":3,"793239706":3,"793249525":3,"793251653":3,"793260928":3,"793263150":3,"793265733":3,"793266103":3,"793268672":3,"793275169":3,"793275365":3,"793275591":3,"793282371":3,"793295531":3,"793301025":3,"793301168":3,"793301370":3,"793304375":3,"794297665":3,"794314618":6,"794315037":6,"794389321":3,"794389927":3,"795094826":3,"795130316":3,"795151876":3,"795172856":3,"795173350":3,"795224147":3,"795247218":3,"795257444":3,"795257768":3,"795301373":3,"795333249":3,"795338219":3,"795446392":6,"795469002":6,"795523555":3,"795526505":3,"795531545":3,"795540242":3,"795545261":3,"795591230":3,"795593331":3,"795693781":3,"795712200":3,"795717384":3,"795720493":3,"799145833":3,"799161004":3,"804985783":3,"805077521":3,"805078113":3,"805079402":3,"805080137":3,"805081594":3,"805082187":3,"805082674":3,"805083856":3,"835933210":3,"837713734":7,"837718564":3,"837831021":3,"837842890":3,"837850050":3,"838075027":3,"838088926":3,"838103810":3,"838107435":3,"838157680":3,"838201571":3,"838238755":7,"838248801":7,"838259247":3,"838262895":3,"838272344":3,"838279131":7,"838287718":7,"838293292":3,"838429069":3,"838450656":3,"838464562":3,"838475350":3,"838498085":3,"838514499":3,"838528405":3,"848344320":6,"848430583":3,"848439853":6,"917716247":7,"917719258":6,"917721630":6,"917732904":6,"917734984":6,"917736959":6,"917738344":6,"917741324":6,"917750066":6,"918881367":6,"922758415":11,"923548916":7,"923551324":6,"923552423":6,"923573548":6,"923579658":6,"923582203":6,"923582614":6,"923588802":6,"923589160":11,"923592962":11,"924006664":6,"926886222":6,"939870107":6,"959671113":3,"959800248":3,"960307320":6,"960333688":3,"960408697":3,"960431321":3,"960442159":3,"960460562":3,"960466921":3,"960577581":3,"960588136":3,"960601475":3,"960644796":3,"960761374":6,"960769236":6,"960787127":6,"960797062":6,"960807055":6,"960843316":11,"960846247":3,"960854999":8,"960863848":3,"961922699":3,"961928026":3,"961986779":3,"961988949":3,"962009351":3,"962013988":3,"962050414":3,"962052341":3,"962133068":3,"962135013":3,"962143341":3,"962149788":3,"962454073":3,"962474482":3,"962479130":3,"963409952":3,"963437224":3,"963512421":3,"963530508":3,"965709370":3,"965977059":3,"966074032":3,"966678428":6,"966679911":6,"966682162":6,"971434737":3,"971755461":3,"977057102":3,"977064254":3,"977074738":3,"977075282":3,"977075580":3,"977082500":3,"977085836":3,"977088159":3,"977092405":3,"977095099":3,"977097757":3},"received":{"922758415":3,"926963444":11,"939756054":3},"offersSince":1453747559} -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration 2 | // https://github.com/angular/protractor/blob/master/referenceConf.js 3 | 4 | 'use strict'; 5 | 6 | var config = { 7 | // The timeout for each script run on the browser. This should be longer 8 | // than the maximum time your application needs to stabilize between tasks. 9 | allScriptsTimeout: 110000, 10 | 11 | // A base URL for your application under test. Calls to protractor.get() 12 | // with relative paths will be prepended with this. 13 | baseUrl: 'http://localhost:' + (process.env.PORT || '9000'), 14 | 15 | // Credientials for Saucelabs 16 | sauceUser: process.env.SAUCE_USERNAME, 17 | 18 | sauceKey: process.env.SAUCE_ACCESS_KEY, 19 | 20 | // list of files / patterns to load in the browser 21 | specs: [ 22 | 'e2e/**/*.spec.js' 23 | ], 24 | 25 | // Patterns to exclude. 26 | exclude: [], 27 | 28 | // ----- Capabilities to be passed to the webdriver instance ---- 29 | // 30 | // For a full list of available capabilities, see 31 | // https://code.google.com/p/selenium/wiki/DesiredCapabilities 32 | // and 33 | // https://code.google.com/p/selenium/source/browse/javascript/webdriver/capabilities.js 34 | capabilities: { 35 | 'browserName': 'chrome', 36 | 'name': 'Fullstack E2E', 37 | 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, 38 | 'build': process.env.TRAVIS_BUILD_NUMBER 39 | }, 40 | 41 | // ----- The test framework ----- 42 | // 43 | // Jasmine and Cucumber are fully supported as a test and assertion framework. 44 | // Mocha has limited beta support. You will need to include your own 45 | // assertion framework if working with mocha. 46 | framework: 'jasmine2', 47 | 48 | // ----- Options to be passed to minijasminenode ----- 49 | // 50 | // See the full list at https://github.com/jasmine/jasmine-npm 51 | jasmineNodeOpts: { 52 | defaultTimeoutInterval: 30000, 53 | print: function() {} // for jasmine-spec-reporter 54 | }, 55 | 56 | // Prepare environment for tests 57 | params: { 58 | serverConfig: require('./server/config/environment') 59 | }, 60 | 61 | onPrepare: function() { 62 | var SpecReporter = require('jasmine-spec-reporter'); 63 | // add jasmine spec reporter 64 | jasmine.getEnv().addReporter(new SpecReporter({displayStacktrace: true})); 65 | 66 | var serverConfig = config.params.serverConfig; 67 | 68 | // Setup mongo for tests 69 | var mongoose = require('mongoose'); 70 | mongoose.connect(serverConfig.mongo.uri, serverConfig.mongo.options); // Connect to database 71 | } 72 | }; 73 | 74 | config.params.baseUrl = config.baseUrl; 75 | exports.config = config; 76 | --------------------------------------------------------------------------------