diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..c13c5f6 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6621ff4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,65 @@ +# Created by https://www.gitignore.io/api/node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +#Build Directory +build/ + +# End of https://www.gitignore.io/api/node diff --git a/app/component/gallery/_create-gallery.scss b/app/component/gallery/_create-gallery.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/component/gallery/create-gallery.html b/app/component/gallery/create-gallery.html new file mode 100644 index 0000000..fe0da07 --- /dev/null +++ b/app/component/gallery/create-gallery.html @@ -0,0 +1,20 @@ + diff --git a/app/component/gallery/create-gallery.js b/app/component/gallery/create-gallery.js new file mode 100644 index 0000000..2283475 --- /dev/null +++ b/app/component/gallery/create-gallery.js @@ -0,0 +1,21 @@ +'use strict'; + +module.exports = { + template: require('./create-gallery.html'), + controller: ['$log', 'galleryService', CreateGalleryController], + controllerAs: 'createGalleryCtrl' +}; + +function CreateGalleryController($log, galleryService) { + $log.debug('CreateGalleryController'); + + this.gallery = {}; + + this.createGallery = function() { + galleryService.createGallery(this.gallery) + .then( () => { + this.gallery.name = null; + this.gallery.desc = null; + }); + }; +}; diff --git a/app/component/gallery/create-gallery/_create-gallery.scss b/app/component/gallery/create-gallery/_create-gallery.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/component/gallery/create-gallery/create-gallery.html b/app/component/gallery/create-gallery/create-gallery.html new file mode 100644 index 0000000..fe0da07 --- /dev/null +++ b/app/component/gallery/create-gallery/create-gallery.html @@ -0,0 +1,20 @@ + diff --git a/app/component/gallery/create-gallery/create-gallery.js b/app/component/gallery/create-gallery/create-gallery.js new file mode 100644 index 0000000..2283475 --- /dev/null +++ b/app/component/gallery/create-gallery/create-gallery.js @@ -0,0 +1,21 @@ +'use strict'; + +module.exports = { + template: require('./create-gallery.html'), + controller: ['$log', 'galleryService', CreateGalleryController], + controllerAs: 'createGalleryCtrl' +}; + +function CreateGalleryController($log, galleryService) { + $log.debug('CreateGalleryController'); + + this.gallery = {}; + + this.createGallery = function() { + galleryService.createGallery(this.gallery) + .then( () => { + this.gallery.name = null; + this.gallery.desc = null; + }); + }; +}; diff --git a/app/component/gallery/thumbnail-container/_thumbnail-container.scss b/app/component/gallery/thumbnail-container/_thumbnail-container.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/component/gallery/thumbnail-container/thumbnail-container.html b/app/component/gallery/thumbnail-container/thumbnail-container.html new file mode 100644 index 0000000..e69de29 diff --git a/app/component/gallery/thumbnail-container/thumbnail-container.js b/app/component/gallery/thumbnail-container/thumbnail-container.js new file mode 100644 index 0000000..e69de29 diff --git a/app/component/gallery/thumbnail/_thumbnail.scss b/app/component/gallery/thumbnail/_thumbnail.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/component/gallery/thumbnail/thumbnail.html b/app/component/gallery/thumbnail/thumbnail.html new file mode 100644 index 0000000..e69de29 diff --git a/app/component/gallery/thumbnail/thumbnail.js b/app/component/gallery/thumbnail/thumbnail.js new file mode 100644 index 0000000..e69de29 diff --git a/app/component/landing/login/_login.scss b/app/component/landing/login/_login.scss new file mode 100644 index 0000000..f42d491 --- /dev/null +++ b/app/component/landing/login/_login.scss @@ -0,0 +1,6 @@ +@import url('https://fonts.googleapis.com/css?family=Montserrat'); + +.landing { + font-size: 22px; + color: white; +}; diff --git a/app/component/landing/login/login.html b/app/component/landing/login/login.html new file mode 100644 index 0000000..ef89f48 --- /dev/null +++ b/app/component/landing/login/login.html @@ -0,0 +1,31 @@ +
+
+
+ +
+ +
+ +
+ + +
+
diff --git a/app/component/landing/login/login.js b/app/component/landing/login/login.js new file mode 100644 index 0000000..dec7c92 --- /dev/null +++ b/app/component/landing/login/login.js @@ -0,0 +1,27 @@ +'use strict'; + +require('./_login.scss'); + +module.exports = { + template: require('./login.html'), + controller: ['$log', '$location', 'authService', LoginController], + controllerAs: 'loginCtrl' +}; + +function LoginController($log, $location, authService) { + $log.debug('LoginController'); + + authService.getToken() + .then( () => { + $location.url('/home'); + }); + + this.login = function() { + $log.debug('loginCtrl.login'); + + authService.login(this.user) + .then( () => { + $location.url('/home'); + }); + }; +}; diff --git a/app/component/landing/signup/_signup.scss b/app/component/landing/signup/_signup.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/component/landing/signup/signup.html b/app/component/landing/signup/signup.html new file mode 100644 index 0000000..44bc876 --- /dev/null +++ b/app/component/landing/signup/signup.html @@ -0,0 +1,25 @@ +
+
+ + + + + + + + +
+
diff --git a/app/component/landing/signup/signup.js b/app/component/landing/signup/signup.js new file mode 100644 index 0000000..b592371 --- /dev/null +++ b/app/component/landing/signup/signup.js @@ -0,0 +1,25 @@ +'use strict'; + +module.exports = { + template: require('./signup.html'), + controller: ['$log', '$location', 'authService', SignupController], + controllerAs: 'signupCtrl' +}; + +function SignupController($log, $location, authService) { + $log.debug('SignupController'); + + authService.getToken() + .then( () => { + $location.url('/home'); + }); + + this.signup = function(user) { + $log.debug('signupCtrl.signup'); + + authService.signup(user) + .then( () => { + $location.url('/home') + }); + }; +}; diff --git a/app/component/navbar/_navbar.scss b/app/component/navbar/_navbar.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/component/navbar/navbar.html b/app/component/navbar/navbar.html new file mode 100644 index 0000000..a4e3e56 --- /dev/null +++ b/app/component/navbar/navbar.html @@ -0,0 +1,9 @@ + diff --git a/app/component/navbar/navbar.js b/app/component/navbar/navbar.js new file mode 100644 index 0000000..bbf8979 --- /dev/null +++ b/app/component/navbar/navbar.js @@ -0,0 +1,43 @@ +'use strict'; + +require('./_navbar.scss'); + +module.exports = { + template: require('./navbar.html'), + controller: ['$log', '$location', '$rootScope', 'authService', NavbarController], + controllerAs: 'navbarCtrl' +}; + +function NavbarController($log, $Location, $rootScope, authService) { + $log.debug('NavbarController'); + + this.checkPath = function() { + let path =$location.path(); + if (path === '/join') { + this.hideButtons = true; + }; + + if (path !== '/join') { + this.hideButtons = false; + authService.getToken() + .catch( () => { + $locaton.url('/join#login'); + }); + }; + }; + + this.checkPath(); + + $rootScope.$on('$locationChangeSuccess', () => { + this.checkPath(); + }); + + this.logout = function () { + $log.log('navbarCtrl.logout'); + this.hideButtons = true; + authService.logout() + .then( () => { + $location.url('/'); + }); + }; +}; diff --git a/app/config/log-config.js b/app/config/log-config.js new file mode 100644 index 0000000..c84d58c --- /dev/null +++ b/app/config/log-config.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = ['$logProvider', logConfig]; + +function logConfig($logProvider) { + $logProvider.debugEnabled(__DEBUG__); +}; diff --git a/app/config/route-config.js b/app/config/route-config.js new file mode 100644 index 0000000..20a0dba --- /dev/null +++ b/app/config/route-config.js @@ -0,0 +1,30 @@ +'use strict'; + +module.exports = ['$stateProvider', '$urlRouterProvider', routerConfig]; + +function routerConfig($stateProvider, $urlRouterProvider) { + $urlRouterProvider.when('', '/join#signup'); + $urlRouterProvider.when('/', '/join#signup'); + $urlRouterProvider.when('/signup', '/join#signup'); + $urlRouterProvider.when('/login', '/join#login'); + +let states = [ + { + name: 'home', + url: '/home', + template: require('../view/home/home.html'), + controller: 'HomeController', + controllerAs: 'homeCtrl' + }, + { + name: 'landing', + url: '/join', + template: require('../view/landing/landing.html'), + controller: 'LandingController', + controllerAs: 'landingCtrl' + } +]; +states.forEach( state => { + $stateProvider.state(state); +}); +}; diff --git a/app/config/router-config.js b/app/config/router-config.js new file mode 100644 index 0000000..20a0dba --- /dev/null +++ b/app/config/router-config.js @@ -0,0 +1,30 @@ +'use strict'; + +module.exports = ['$stateProvider', '$urlRouterProvider', routerConfig]; + +function routerConfig($stateProvider, $urlRouterProvider) { + $urlRouterProvider.when('', '/join#signup'); + $urlRouterProvider.when('/', '/join#signup'); + $urlRouterProvider.when('/signup', '/join#signup'); + $urlRouterProvider.when('/login', '/join#login'); + +let states = [ + { + name: 'home', + url: '/home', + template: require('../view/home/home.html'), + controller: 'HomeController', + controllerAs: 'homeCtrl' + }, + { + name: 'landing', + url: '/join', + template: require('../view/landing/landing.html'), + controller: 'LandingController', + controllerAs: 'landingCtrl' + } +]; +states.forEach( state => { + $stateProvider.state(state); +}); +}; diff --git a/app/entry.js b/app/entry.js new file mode 100644 index 0000000..358681e --- /dev/null +++ b/app/entry.js @@ -0,0 +1,39 @@ +'use strict'; + +require('./scss/main.scss'); + +const path = require('path'); +const angular = require('angular'); +const camelcase = require('camelcase'); +const pascalcase = require('pascalcase'); +const uiRouter = require('angular-ui-router'); +const ngTouch = require('angular-touch'); +const ngAnimate = require('angular-animate'); + +const cfgram = angular.module('cfgram', [ngTouch, ngAnimate, uiRouter]); + +let context = require.context('./config/', true, /\.js$/); +context.keys().forEach( key => { + cfgram.config(context(key)); +}); + +context = require.context('./view/', true, /\.js$/); +context.keys().forEach( key => { + let name = pascalcase(path.basename(key, '.js')); + let module = context(key); + cfgram.controller(name, module); +}); + +context = require.context('./service/', true, /\.js$/); +context.keys().forEach( key => { + let name = camelcase(path.basename(key, '.js')); + let module = context(key); + cfgram.service(name, module); +}); + +context = require.context('./component/', true, /\.js$/); +context.keys().forEach( key => { + let name = camelcase(path.basename(key, '.js')); + let module = context(key); + cfgram.component(name, module); +}); diff --git a/app/index.html b/app/index.html new file mode 100644 index 0000000..d8e713d --- /dev/null +++ b/app/index.html @@ -0,0 +1,21 @@ + + + + + + cfgram + + + + +
+
+ + + + + + + + diff --git a/app/scss/lib/_base.scss b/app/scss/lib/_base.scss new file mode 100644 index 0000000..462e816 --- /dev/null +++ b/app/scss/lib/_base.scss @@ -0,0 +1,59 @@ + + +header{ + height: 8vw; + width: 100%; + background-color: $brand1; +}; + +.input-std{ + padding: 2% 8%; + margin: 2%; + margin-right: 10%; + width: 80%; + display: flex; + flex-direction: column; + justify-content: center; +}; +.clearfix{ + clear: both; +}; +.btn-std{ + padding: 1% 5%; + border-radius: $radius; + background-color: $brand1; + color: white; + border: none; + float: right; + margin-right: 2%; + font-size: 65%; + // position: absolute; + // left: 14vw; + // top: 10vw; +}; +a,p{ + display: inline-block; + // float: right; + left: 52%; + right: 2%; + color: $brand1; +}; +a{ + text-decoration: none; + color: black; +}; + + + +body { + background-color: $brand2; + height: 65%; +}; + +footer { + background-color: $footer; + height: 10vw; + width: 100%; + position: absolute; + bottom: -30px; +}; diff --git a/app/scss/lib/_reset.scss b/app/scss/lib/_reset.scss new file mode 100644 index 0000000..d9f27b5 --- /dev/null +++ b/app/scss/lib/_reset.scss @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/app/scss/lib/_vars.scss b/app/scss/lib/_vars.scss new file mode 100644 index 0000000..8c8c853 --- /dev/null +++ b/app/scss/lib/_vars.scss @@ -0,0 +1,14 @@ +//colors + +$brand1 : #5a5d63; +$brand2 : #aaacaf; +$brand3 : white; +$footer: #727882; + +//spacing +$gtter : 30px; +$btnpad : 3%; +$radius : 3px; + +//font +@import url('https://fonts.googleapis.com/css?family=Montserrat'); diff --git a/app/scss/main.scss b/app/scss/main.scss new file mode 100644 index 0000000..d9cd6ed --- /dev/null +++ b/app/scss/main.scss @@ -0,0 +1,7 @@ +@import '/lib/reset'; +@import '/lib/vars'; +@import '/lib/base'; + +// body { +// background-color: hotpink; +// } diff --git a/app/service/auth-service.js b/app/service/auth-service.js new file mode 100644 index 0000000..0eb9f31 --- /dev/null +++ b/app/service/auth-service.js @@ -0,0 +1,89 @@ +'use strict'; + +module.exports= ['$q', '$log', '$http', '$window', authService]; + +function authService($q, $log, $http, $window) { + $log.debug('authService'); + + let service = {}; + let token = null; + + function setToken(_token) { + $log.debug('authService.setToken'); + + if (! _token) { + return $q.reject(new Error('no token')); + }; + + $window.localStorage.setItem('token', _token); + token = _token; + return $q.resolve(token); + } + + service.getToken = function() { + $log.debug('authService.getToken'); + if(token) { + return $q.resolve(token); + }; + + token = $window.localStorage.getItem('token'); + if (token) return $q.resolve(token); + return $q.reject(new Error('token not found')); + }; + + service.signup = function(user) { + $log.debug('authService.signup'); + + let url = `${__API_URL__}/api/signup`; + let config = { + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + } + }; + + return $http.post(url, user, config) + .then( res => { + $log.log('success:', res.data); + return setToken(res.data) + }) + .catch( err => { + $log.error('failure:', err.message); + return $q.reject(err); + }); + }; + + service.logout= function() { + $log.debug('authService.logout'); + + $window.localStorage.removeItem('token'); + token = null; + return $q.resolve(); + }; + + service.login = function(user) { + $log.debug('authService.login'); + + let url= `${__API_URL__}/api/login`; + let base64 = $window.btoa(`${user.username}:${user.password}`); + let config = { + headers: { + Accept: 'application/json', + Authorization: `Basic ${base64}` + } + }; + + return $http.get(url, config) + .then( res => { + $log.log('success', res.data); + return setToken(res.data); + }) + .catch(err => { + $log.error(err.message); + return $q.reject(err); + }); + }; + + return service; + +}; diff --git a/app/service/gallery-service.js b/app/service/gallery-service.js new file mode 100644 index 0000000..3d4e25a --- /dev/null +++ b/app/service/gallery-service.js @@ -0,0 +1,83 @@ +'use strict'; + +module.exports = ['$q', '$log', '$http', 'authService', galleryService]; + +function galleryService($q, $log, $http, authService) { + $log.debug('galleryService'); + + let service = {}; + service.galleries = []; + + service.createGallery = function(gallery) { + $log.debug('galleryService.createGallery'); + + + return authService.getToken() + .then( token => { + let url = `${__API_URL__}/api/gallery`; + let config = { + headers: { + Accept: 'application/json', + 'Content-Type' : 'application/json', + Authorization: `Bearer ${token}` + } + }; + + return $http.post(url, gallery, config); + }) + .then( res => { + $log.log('gallery created'); + let gallery = res.data; + service.galleries.unshift(gallery); + return gallery; + }) + .catch( err => { + $log.error(err.message); + return $q.reject(err); + }); + }; + + service.deleteGalleries = function(galleryID) { + $log.debug('galleryService.deleteGalleries'); + + return authService.getToken() + .then( token => { + let url = `${__API_URL__}/api/gallery/${galleryID}`; + let config = { + headers: { + Accept: 'application/json', + Authorization: `Bearer ${token}` + } + }; + + //TODO: Create an $http.delete request + }); + }; + + service.fetchGalleries = function() { + $log.debug('galleryService.fetchGalleries'); + + return authService.getToken() + .then( token => { + let url = `${__API_URL__}/api/gallery`; + let config = { + headers: { + Accept: 'application/json', + Authorization: `Bearer ${token}` + } + }; + + return $http.get(url, config); + }) + .then( res => { + $log.log('galleries retrieved'); + service.galleries = res.data; + return service.galleries; + }) + .catch( err => { + $log.error(err.message); + return $q.reject(err); + }); + }; + return service; +}; diff --git a/app/service/pic-service.js b/app/service/pic-service.js new file mode 100644 index 0000000..10c014d --- /dev/null +++ b/app/service/pic-service.js @@ -0,0 +1,43 @@ +'use strict'; + +module.exports = ['$q', '$log', '$http', 'Upload', 'authService', picService]; + +function picService($q, $log, $http, Upload, authService) { + $log.debug('picService'); + + let service = {}; + + service.uploadGalleryPic = function(galleryData, picData) { + $log.debug('service.uploadGalleryPic'); + + return authService.getToken() + .then( token => { + let url = `${__API_URL__}/api/gallery/${galleryData._id}/pic`; + let headers = { + Authorization: `Bearer ${token}`, + Accept: 'application/json' + }; + + return Upload.upload({ + url, + headers, + method: 'POST', + data: { + name: picData.name, + desc: picData.desc, + file: picData.file + } + }); + }) + .then ( res => { + galleryData.pics.unshift(res.data); + return res.data; + }) + .catch( err => { + $log.error(err.message); + return $q.reject(err); + }); + }; + + return +}; diff --git a/app/view/home/_home.scss b/app/view/home/_home.scss new file mode 100644 index 0000000..d8462f3 --- /dev/null +++ b/app/view/home/_home.scss @@ -0,0 +1,5 @@ +@import url('https://fonts.googleapis.com/css?family=Montserrat'); + +.home { + color: black; +}; diff --git a/app/view/home/home-controller.js b/app/view/home/home-controller.js new file mode 100644 index 0000000..7f48d88 --- /dev/null +++ b/app/view/home/home-controller.js @@ -0,0 +1,9 @@ +'use strict'; + +require('./_home.scss'); + +module.exports = ['$log', HomeController]; + +function HomeController($log) { + $log.debug('HomeController'); +}; diff --git a/app/view/home/home.html b/app/view/home/home.html new file mode 100644 index 0000000..cd25ea0 --- /dev/null +++ b/app/view/home/home.html @@ -0,0 +1,4 @@ + +
+

Bienvenue!

+
diff --git a/app/view/landing/_landing.scss b/app/view/landing/_landing.scss new file mode 100644 index 0000000..77932a8 --- /dev/null +++ b/app/view/landing/_landing.scss @@ -0,0 +1 @@ +@import url('https://fonts.googleapis.com/css?family=Montserrat'); diff --git a/app/view/landing/landing-controller.js b/app/view/landing/landing-controller.js new file mode 100644 index 0000000..cdec477 --- /dev/null +++ b/app/view/landing/landing-controller.js @@ -0,0 +1,12 @@ + +'use strict'; + +require('./_landing.scss'); + +module.exports = ['$log', '$location', '$rootScope', 'authService', LandingController]; + + +function LandingController($log, $location, authService) { + let url = $location.url(); + this.showSignup = url === '/join#signup' || url === '/join'; +}; diff --git a/app/view/landing/landing.html b/app/view/landing/landing.html new file mode 100644 index 0000000..c2c6111 --- /dev/null +++ b/app/view/landing/landing.html @@ -0,0 +1,23 @@ +
+
+
+

already a memeber?

+ + Log in here. + +
+
+ +
+
+ + +
+

Need to Sign up?

+ + Sign up here + +
+
+
diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..68c9544 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,26 @@ +const webpackConfig = require('./webpack.config.js'); +webpackConfig.entry = {}; + +module.exports = function(config) { + config.set({ + webpack: webpackConfig, + basePath: '', + frameworks: ['jasmine'], + files: [ + 'test/**/*-test.js' + ], + exclude: [ + ], + preprocessors: { + 'test/**/*-test.js': ['webpack'] + }, + reporters: ['progress'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['PhantomJS'], + singleRun: false, + concurrency: Infinity + }); +}; diff --git a/open b/open new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json new file mode 100644 index 0000000..7af90f1 --- /dev/null +++ b/package.json @@ -0,0 +1,51 @@ +{ + "name": "25-angular_auth", + "version": "1.0.0", + "description": "![cf](https://i.imgur.com/7v5ASc8.png) Lab 25 - Client Side Auth ======", + "main": "karma.conf.js", + "scripts": { + "build": "./node_modules/webpack/bin/webpack.js", + "watch": "./node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot", + "lint": "./node_modules/eslint/bin/eslint.js ./**/*.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/darms/25-angular_auth.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/darms/25-angular_auth/issues" + }, + "homepage": "https://github.com/darms/25-angular_auth#readme", + "dependencies": { + "angular": "^1.6.3", + "angular-animate": "^1.6.3", + "angular-route": "^1.6.3", + "angular-touch": "^1.6.3", + "angular-ui-router": "^0.4.2", + "babel-core": "^6.24.0", + "babel-loader": "^6.4.1", + "babel-preset-es2015": "^6.24.0", + "camelcase": "^4.0.0", + "clean-webpack-plugin": "^0.1.16", + "css-loader": "^0.27.3", + "dotenv": "^4.0.0", + "extract-text-webpack-plugin": "^2.1.0", + "file-loader": "^0.10.1", + "html-loader": "^0.4.5", + "html-webpack-plugin": "^2.28.0", + "node-sass": "^4.5.1", + "pascalcase": "^0.1.1", + "resolve-url-loader": "^2.0.2", + "sass-loader": "^6.0.3", + "style-loader": "^0.16.1", + "ui-router": "^1.0.0-alpha.3", + "url-loader": "^0.5.8", + "webpack": "^2.3.2" + }, + "devDependencies": { + "webpack-dev-server": "^2.4.2" + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..8873794 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,46 @@ +'use strict'; + +const dotenv = require('dotenv'); +const webpack = require('webpack'); +const HTMLPlugin = require('html-webpack-plugin'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); + +const production = process.env.NODE_ENV === 'production'; + +dotenv.load(); + +module.exports = { + devtool: 'eval', + entry: `${__dirname}/app/entry.js`, + output: { + filename: 'bundle.js', + path: `${__dirname}/build` + }, + plugins: [ + new HTMLPlugin({ + template: `${__dirname}/app/index.html` + }), + new ExtractTextPlugin('bundle.css'), + new webpack.DefinePlugin({ + __API_URL__: JSON.stringify(process.env.API_URL), + __DEBUG__: JSON.stringify(!production) + }) + ], + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader' + }, + { + test: /\.html$/, + loader: 'html-loader' + }, + { + test: /\.scss$/, + loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader']) + } + ] + } +}; diff --git a/wireframes/signin.png b/wireframes/signin.png new file mode 100644 index 0000000..98280c9 Binary files /dev/null and b/wireframes/signin.png differ diff --git a/wireframes/signup.png b/wireframes/signup.png new file mode 100644 index 0000000..c52936c Binary files /dev/null and b/wireframes/signup.png differ