From c85ce240c29d44e8441315d1c23f9774fe42783a Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Tue, 28 Mar 2017 15:25:49 -0700 Subject: [PATCH 01/23] added entry.js --- .babelrc | 3 ++ .eslintignore | 0 .eslintrc | 22 +++++++++ .gitignore | 120 ++++++++++++++++++++++++++++++++++++++++++++++ app/entry.js | 37 ++++++++++++++ app/index.html | 11 +++++ package.json | 44 +++++++++++++++++ webpack.config.js | 43 +++++++++++++++++ 8 files changed, 280 insertions(+) create mode 100644 .babelrc create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 app/entry.js create mode 100644 app/index.html create mode 100644 package.json create mode 100644 webpack.config.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..c13c5f62 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..e69de29b diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..7f50cb6a --- /dev/null +++ b/.eslintrc @@ -0,0 +1,22 @@ +{ + "rules": { + "no-console": "off", + "indent": [ "error", 2 ], + "quotes": [ "error", "single" ], + "semi": ["error", "always"], + "linebreak-style": [ "error", "unix" ], + "no-unused-vars": [2, {"vars": "local", "args": "after-used"}] + }, + "env": { + "es6": true, + "node": true, + "mocha": true, + "jasmine": true + }, + "ecmaFeatures": { + "modules": true, + "experimentalObjectRestSpread": true, + "impliedStrict": true + }, + "extends": "eslint:recommended" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..916de44e --- /dev/null +++ b/.gitignore @@ -0,0 +1,120 @@ + +# Created by https://www.gitignore.io/api/node,osx,windows + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +#Test-Data +/data + +#Node +/node_modules + +# 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 + + +### OSX ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.gitignore.io/api/node,osx,windows diff --git a/app/entry.js b/app/entry.js new file mode 100644 index 00000000..db661b63 --- /dev/null +++ b/app/entry.js @@ -0,0 +1,37 @@ +'use strict'; + +const angular = require('angular'); +const camelcase = require('camelcase'); +const pascalcase = require('pascalcase'); +const path = require('path'); +const uiRouter = require('angular-ui-router'); +const ngTouch = require('angular-touch'); +const ngAnimate = require('angular-animate'); + +const cfgram = angular.module('cfgram', [uiRouter, ngAnimate, ngTouch]); + +let context = require.context('./config/', true, /\.js$/); +context.keys().forEach( key => { + cfgram.config(context(key)); +}); + +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); +}); + +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('./view/', true, /\.js$/); +context.keys().forEach( key => { + let name = pascalcase(path.basename(key, '.js')); + let module = context(key); + cfgram.controller(name, module); +}); diff --git a/app/index.html b/app/index.html new file mode 100644 index 00000000..f37c9e69 --- /dev/null +++ b/app/index.html @@ -0,0 +1,11 @@ + + + + + + CF-Gram + + + + + diff --git a/package.json b/package.json new file mode 100644 index 00000000..02a87b37 --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "frontend-auth", + "version": "1.0.0", + "description": "", + "main": "index.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 ./*" + }, + "keywords": [], + "author": "", + "license": "ISC", + "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": { + "eslint": "^3.18.0", + "webpack-dev-server": "^2.4.2" + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 00000000..788f65bd --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,43 @@ + +'use strict'; + +require('dotenv').load(); + +const webpack = require('webpack'); +const HTMLPlugin = require('html-webpack-plugin'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); + +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__: process.env.API_URL + }) + ], + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader' + }, + { + test: /\.html$/, + loader: 'html-loader' + }, + { + test: /\.scss$/, + loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader']) + } + ] + } +}; From 0d774ba0fc440e8a2bfffcac34b21ad876e07572 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Tue, 28 Mar 2017 15:47:23 -0700 Subject: [PATCH 02/23] added auth-service.js --- app/service/auth-service.js | 90 +++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 app/service/auth-service.js diff --git a/app/service/auth-service.js b/app/service/auth-service.js new file mode 100644 index 00000000..f8645621 --- /dev/null +++ b/app/service/auth-service.js @@ -0,0 +1,90 @@ +'use strict'; + +module.exports = ['$log', '$q', '$http', '$window', authService]; + +//hard-coded becuase my .env was being a bitch +process.env.API_URL = 'https://cfgram-staging-nikko.herokuapp.com'; + +function authService($log, $q, $http, $window) { + $log.debug('auth service'); + + let service = {}; + let token = null; + + function setToken(_token) { + $log.debug('authService.setToken'); + + if(!token) return $q.reject(new Error('no token')); + + $window.localStorage.token = _token; + token = _token; + return $q.resolve(token); + } + + service.getToken = function() { + $log.debug('authService.getToken'); + + if (token) return $q.resolve(token); + + token = $window.localStorage.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 = `${process.env.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('error:', err.message); + return $q.reject(err); + }); + }; + + service.logout = function() { + $log.debug('authService.logout'); + + delete $window.localStorage.token; + token = null; + return $q.resolve(); + }; + + service.login = function(user) { + $log.debug('authService.login'); + + let url = `${process.env.API_URL}/api/login`; + let base64 = $window.btoa(`${user.username}:${user.password}`); + let config = { + headers: { + 'Authorization': `Basic ${base64}`, + 'Accept': 'application/json' + } + }; + + return $http.get(url, user, config) + .then( res => { + $log.log('success', res.data); + return setToken(res.data); + }) + .catch( err => { + $log.log('error', err.message); + return $q.reject(err); + }); + }; + + return service; +} From b968587fd5653594dd05e9a573f1a01726f99861 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Tue, 28 Mar 2017 19:37:00 -0700 Subject: [PATCH 03/23] added final scaffold and route config --- app/component/login/_login.scss | 0 app/component/login/login.html | 0 app/component/login/login.js | 0 app/component/signup/_signup.scss | 0 app/component/signup/signup.html | 0 app/component/signup/signup.js | 0 app/config/route-config.js | 31 ++++++++++++++++++++++++++ app/view/home/_home.scss | 0 app/view/home/home-controller.js | 10 +++++++++ app/view/home/home.html | 3 +++ app/view/landing/_landing.scss | 0 app/view/landing/landing-controller.js | 12 ++++++++++ app/view/landing/landing.html | 0 13 files changed, 56 insertions(+) create mode 100644 app/component/login/_login.scss create mode 100644 app/component/login/login.html create mode 100644 app/component/login/login.js create mode 100644 app/component/signup/_signup.scss create mode 100644 app/component/signup/signup.html create mode 100644 app/component/signup/signup.js create mode 100644 app/config/route-config.js create mode 100644 app/view/home/_home.scss create mode 100644 app/view/home/home-controller.js create mode 100644 app/view/home/home.html create mode 100644 app/view/landing/_landing.scss create mode 100644 app/view/landing/landing-controller.js create mode 100644 app/view/landing/landing.html diff --git a/app/component/login/_login.scss b/app/component/login/_login.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/component/login/login.html b/app/component/login/login.html new file mode 100644 index 00000000..e69de29b diff --git a/app/component/login/login.js b/app/component/login/login.js new file mode 100644 index 00000000..e69de29b diff --git a/app/component/signup/_signup.scss b/app/component/signup/_signup.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/component/signup/signup.html b/app/component/signup/signup.html new file mode 100644 index 00000000..e69de29b diff --git a/app/component/signup/signup.js b/app/component/signup/signup.js new file mode 100644 index 00000000..e69de29b diff --git a/app/config/route-config.js b/app/config/route-config.js new file mode 100644 index 00000000..ea475162 --- /dev/null +++ b/app/config/route-config.js @@ -0,0 +1,31 @@ +'use strict'; + +module.exports = ['$stateProvider', '$urlRouterProvider', routeConfig]; + +function routeConfig($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/view/home/_home.scss b/app/view/home/_home.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/view/home/home-controller.js b/app/view/home/home-controller.js new file mode 100644 index 00000000..5bf6258e --- /dev/null +++ b/app/view/home/home-controller.js @@ -0,0 +1,10 @@ +'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 00000000..088d1736 --- /dev/null +++ b/app/view/home/home.html @@ -0,0 +1,3 @@ +
+

yo we at the home page

+
diff --git a/app/view/landing/_landing.scss b/app/view/landing/_landing.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/view/landing/landing-controller.js b/app/view/landing/landing-controller.js new file mode 100644 index 00000000..30352e8f --- /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, $rootScope, authService) { + $log.debug('LandingController'); + + let url = $location.url(); + this.showSignup = url === '/join#signup' || '/join'; +} diff --git a/app/view/landing/landing.html b/app/view/landing/landing.html new file mode 100644 index 00000000..e69de29b From 6fb6b70d1309546d1ba8e19e53815324ae3a50f2 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Tue, 28 Mar 2017 22:03:10 -0700 Subject: [PATCH 04/23] got the app to work yeehaw --- app/component/login/login.html | 34 ++++++++++++++++++++++++++++++++ app/component/login/login.js | 34 ++++++++++++++++++++++++++++++++ app/component/signup/signup.html | 25 +++++++++++++++++++++++ app/component/signup/signup.js | 25 +++++++++++++++++++++++ app/entry.js | 4 +++- app/scss/main.scss | 0 app/service/auth-service.js | 3 ++- app/view/landing/landing.html | 31 +++++++++++++++++++++++++++++ 8 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 app/scss/main.scss diff --git a/app/component/login/login.html b/app/component/login/login.html index e69de29b..0c2af902 100644 --- a/app/component/login/login.html +++ b/app/component/login/login.html @@ -0,0 +1,34 @@ + diff --git a/app/component/login/login.js b/app/component/login/login.js index e69de29b..3fbff4a3 100644 --- a/app/component/login/login.js +++ b/app/component/login/login.js @@ -0,0 +1,34 @@ +'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'); + }) + .catch( err => { + $log.error('failed to get token', err.message); + }); + + this.login = function() { + $log.debug('loginCtrl.login'); + + authService.login(this.user) + .then( () => { + $location.url('/home'); + }) + .catch( err => { + $log.error('failed to login', err.message); + }); + }; + +} diff --git a/app/component/signup/signup.html b/app/component/signup/signup.html index e69de29b..17ebe888 100644 --- a/app/component/signup/signup.html +++ b/app/component/signup/signup.html @@ -0,0 +1,25 @@ + diff --git a/app/component/signup/signup.js b/app/component/signup/signup.js index e69de29b..2f58215c 100644 --- a/app/component/signup/signup.js +++ b/app/component/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/entry.js b/app/entry.js index db661b63..44d308d0 100644 --- a/app/entry.js +++ b/app/entry.js @@ -1,5 +1,7 @@ 'use strict'; +require('./scss/main.scss'); + const angular = require('angular'); const camelcase = require('camelcase'); const pascalcase = require('pascalcase'); @@ -8,7 +10,7 @@ const uiRouter = require('angular-ui-router'); const ngTouch = require('angular-touch'); const ngAnimate = require('angular-animate'); -const cfgram = angular.module('cfgram', [uiRouter, ngAnimate, ngTouch]); +const cfgram = angular.module('cfgram', [ngTouch, ngAnimate, uiRouter]); let context = require.context('./config/', true, /\.js$/); context.keys().forEach( key => { diff --git a/app/scss/main.scss b/app/scss/main.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/service/auth-service.js b/app/service/auth-service.js index f8645621..798c64cb 100644 --- a/app/service/auth-service.js +++ b/app/service/auth-service.js @@ -14,7 +14,7 @@ function authService($log, $q, $http, $window) { function setToken(_token) { $log.debug('authService.setToken'); - if(!token) return $q.reject(new Error('no token')); + if(!_token) return $q.reject(new Error('no token')); $window.localStorage.token = _token; token = _token; @@ -43,6 +43,7 @@ function authService($log, $q, $http, $window) { 'Accept': 'application/json' } }; + console.log('heres my user', user); return $http.post(url, user, config) .then( res => { diff --git a/app/view/landing/landing.html b/app/view/landing/landing.html index e69de29b..a85688cb 100644 --- a/app/view/landing/landing.html +++ b/app/view/landing/landing.html @@ -0,0 +1,31 @@ +
+ +
+ +
+ +

already a member?

+ + sign in here. + +
+ +
+ +
+ +
+ +

want to sign up?

+ + sign up here + +
+ +
+ +
From aeca33ce494fb2d30d4da615efe4c1bb82b138fc Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Tue, 28 Mar 2017 22:20:06 -0700 Subject: [PATCH 05/23] got my signup route to work, signin still needs some work --- app/component/login/login.js | 6 ------ app/service/auth-service.js | 6 +++--- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/component/login/login.js b/app/component/login/login.js index 3fbff4a3..edfa4903 100644 --- a/app/component/login/login.js +++ b/app/component/login/login.js @@ -14,9 +14,6 @@ function LoginController($log, $location, authService) { authService.getToken() .then( () => { $location.url('/home'); - }) - .catch( err => { - $log.error('failed to get token', err.message); }); this.login = function() { @@ -25,9 +22,6 @@ function LoginController($log, $location, authService) { authService.login(this.user) .then( () => { $location.url('/home'); - }) - .catch( err => { - $log.error('failed to login', err.message); }); }; diff --git a/app/service/auth-service.js b/app/service/auth-service.js index 798c64cb..b107f2bc 100644 --- a/app/service/auth-service.js +++ b/app/service/auth-service.js @@ -43,7 +43,6 @@ function authService($log, $q, $http, $window) { 'Accept': 'application/json' } }; - console.log('heres my user', user); return $http.post(url, user, config) .then( res => { @@ -71,10 +70,11 @@ function authService($log, $q, $http, $window) { let base64 = $window.btoa(`${user.username}:${user.password}`); let config = { headers: { - 'Authorization': `Basic ${base64}`, - 'Accept': 'application/json' + 'Accept': 'application/json', + 'Authorization': `Basic ${base64}` } }; + $log.log('heres my url, user, and config', url, user, config); return $http.get(url, user, config) .then( res => { From bd6abb74c2eb3a862acf7937adf93c71721fdf4b Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 29 Mar 2017 10:07:30 -0700 Subject: [PATCH 06/23] had to change my .get to and use my config param differently, it helped my login method with my own backend --- app/service/auth-service.js | 8 ++++---- app/service/gallery-service.js | 0 2 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 app/service/gallery-service.js diff --git a/app/service/auth-service.js b/app/service/auth-service.js index b107f2bc..06ed0446 100644 --- a/app/service/auth-service.js +++ b/app/service/auth-service.js @@ -66,17 +66,17 @@ function authService($log, $q, $http, $window) { service.login = function(user) { $log.debug('authService.login'); - let url = `${process.env.API_URL}/api/login`; let base64 = $window.btoa(`${user.username}:${user.password}`); let config = { + method: 'GET', headers: { 'Accept': 'application/json', 'Authorization': `Basic ${base64}` - } + }, + url: `${process.env.API_URL}/api/login`, }; - $log.log('heres my url, user, and config', url, user, config); - return $http.get(url, user, config) + return $http(config) .then( res => { $log.log('success', res.data); return setToken(res.data); diff --git a/app/service/gallery-service.js b/app/service/gallery-service.js new file mode 100644 index 00000000..e69de29b From 087c87d99b65dad83eac7b1993b9c7147a28ba74 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 29 Mar 2017 15:10:17 -0700 Subject: [PATCH 07/23] got my gallery-service methods to work properly with my own backend --- .../create-gallery/_create-gallery.scss} | 0 .../create-gallery/create-gallery.html | 21 ++++ .../gallery/create-gallery/create-gallery.js | 23 +++++ .../login/_login.scss} | 0 app/component/{ => landing}/login/login.html | 0 app/component/{ => landing}/login/login.js | 0 app/component/landing/signup/_signup.scss | 0 .../{ => landing}/signup/signup.html | 0 app/component/{ => landing}/signup/signup.js | 0 app/component/navbar/_navbar.scss | 0 app/component/navbar/navbar.html | 10 ++ app/component/navbar/navbar.js | 45 +++++++++ app/config/log-config.js | 7 ++ app/index.html | 3 + app/service/auth-service.js | 14 +-- app/service/gallery-service.js | 94 ++++++++++++++++++ app/view/home/home-controller.js | 18 +++- app/view/home/home.html | 10 ++ {wireframes/assets => assets}/cf-logo.png | Bin webpack.config.js | 15 ++- 20 files changed, 246 insertions(+), 14 deletions(-) rename app/component/{login/_login.scss => gallery/create-gallery/_create-gallery.scss} (100%) create mode 100644 app/component/gallery/create-gallery/create-gallery.html create mode 100644 app/component/gallery/create-gallery/create-gallery.js rename app/component/{signup/_signup.scss => landing/login/_login.scss} (100%) rename app/component/{ => landing}/login/login.html (100%) rename app/component/{ => landing}/login/login.js (100%) create mode 100644 app/component/landing/signup/_signup.scss rename app/component/{ => landing}/signup/signup.html (100%) rename app/component/{ => landing}/signup/signup.js (100%) create mode 100644 app/component/navbar/_navbar.scss create mode 100644 app/component/navbar/navbar.html create mode 100644 app/component/navbar/navbar.js create mode 100644 app/config/log-config.js rename {wireframes/assets => assets}/cf-logo.png (100%) diff --git a/app/component/login/_login.scss b/app/component/gallery/create-gallery/_create-gallery.scss similarity index 100% rename from app/component/login/_login.scss rename to app/component/gallery/create-gallery/_create-gallery.scss 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 00000000..2d9f7f2c --- /dev/null +++ b/app/component/gallery/create-gallery/create-gallery.html @@ -0,0 +1,21 @@ + 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 00000000..0044d219 --- /dev/null +++ b/app/component/gallery/create-gallery/create-gallery.js @@ -0,0 +1,23 @@ +'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.description = null; + }); + }; + + +} diff --git a/app/component/signup/_signup.scss b/app/component/landing/login/_login.scss similarity index 100% rename from app/component/signup/_signup.scss rename to app/component/landing/login/_login.scss diff --git a/app/component/login/login.html b/app/component/landing/login/login.html similarity index 100% rename from app/component/login/login.html rename to app/component/landing/login/login.html diff --git a/app/component/login/login.js b/app/component/landing/login/login.js similarity index 100% rename from app/component/login/login.js rename to app/component/landing/login/login.js diff --git a/app/component/landing/signup/_signup.scss b/app/component/landing/signup/_signup.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/component/signup/signup.html b/app/component/landing/signup/signup.html similarity index 100% rename from app/component/signup/signup.html rename to app/component/landing/signup/signup.html diff --git a/app/component/signup/signup.js b/app/component/landing/signup/signup.js similarity index 100% rename from app/component/signup/signup.js rename to app/component/landing/signup/signup.js diff --git a/app/component/navbar/_navbar.scss b/app/component/navbar/_navbar.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/component/navbar/navbar.html b/app/component/navbar/navbar.html new file mode 100644 index 00000000..d03d2b07 --- /dev/null +++ b/app/component/navbar/navbar.html @@ -0,0 +1,10 @@ + diff --git a/app/component/navbar/navbar.js b/app/component/navbar/navbar.js new file mode 100644 index 00000000..a21d9ca0 --- /dev/null +++ b/app/component/navbar/navbar.js @@ -0,0 +1,45 @@ +'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( () => { + $location.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 00000000..8696e637 --- /dev/null +++ b/app/config/log-config.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = ['$logProvider', logConfig]; + +function logConfig($logProvider) { + $logProvider.debugEnabled(process.env.__DEBUG__); +} diff --git a/app/index.html b/app/index.html index f37c9e69..72e073b9 100644 --- a/app/index.html +++ b/app/index.html @@ -5,6 +5,9 @@ CF-Gram +
+ +
diff --git a/app/service/auth-service.js b/app/service/auth-service.js index 06ed0446..200372ff 100644 --- a/app/service/auth-service.js +++ b/app/service/auth-service.js @@ -2,9 +2,6 @@ module.exports = ['$log', '$q', '$http', '$window', authService]; -//hard-coded becuase my .env was being a bitch -process.env.API_URL = 'https://cfgram-staging-nikko.herokuapp.com'; - function authService($log, $q, $http, $window) { $log.debug('auth service'); @@ -35,16 +32,19 @@ function authService($log, $q, $http, $window) { service.signup = function(user) { $log.debug('authService.signup'); + $log.log('process.env.__API_URL__', process.env.__API_URL__); - let url = `${process.env.API_URL}/api/signup`; let config = { + method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' - } + }, + url: `${process.env.__API_URL__}/api/signup`, + data: user }; - return $http.post(url, user, config) + return $http(config) .then( res => { $log.log('success', res.data); return setToken(res.data); @@ -73,7 +73,7 @@ function authService($log, $q, $http, $window) { 'Accept': 'application/json', 'Authorization': `Basic ${base64}` }, - url: `${process.env.API_URL}/api/login`, + url: `${process.env.__API_URL__}/api/login`, }; return $http(config) diff --git a/app/service/gallery-service.js b/app/service/gallery-service.js index e69de29b..9146cbb3 100644 --- a/app/service/gallery-service.js +++ b/app/service/gallery-service.js @@ -0,0 +1,94 @@ +'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 config = { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + url: `${process.env.__API_URL__}/api/gallery`, + data: gallery + }; + + + return $http(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 config = { + method: 'DELETE', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + url: `${process.env.__API_URL__}/api/gallery/${galleryID}` + }; + + return $http(galleryID, config); + }) + .catch( err => { + $log.error(err.message); + return $q.reject(err); + }); + + }; + + service.fetchGalleries = function() { + $log.debug('galleryService.fetchGalleries'); + + return authService.getToken() + .then( token => { + let config = { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'Authorization': `Bearer ${token}` + }, + url: `${process.env.__API_URL__}/api/gallery` + }; + + return $http(config); + }) + .then( res => { + $log.log('got galleries'); + service.galleries = res.data; + return service.galleries; + }) + .catch( err => { + $log.error(err.message); + return $q.reject(err); + }); + }; + + return service; +} diff --git a/app/view/home/home-controller.js b/app/view/home/home-controller.js index 5bf6258e..4640d170 100644 --- a/app/view/home/home-controller.js +++ b/app/view/home/home-controller.js @@ -2,9 +2,23 @@ require('./_home.scss'); -module.exports = ['$log', HomeController]; +module.exports = ['$log', '$rootScope', 'galleryService', HomeController]; -function HomeController($log) { +function HomeController($log, $rootScope, galleryService) { $log.debug('HomeController'); + this.galleries = []; + + this.fetchGalleries = function() { + galleryService.fetchGalleries() + .then( galleries => { + this.galleries = galleries; + }); + }; + + this.fetchGalleries(); + + $rootScope.$on('$locationChangeSuccess', () => { + this.fetchGalleries(); + }); } diff --git a/app/view/home/home.html b/app/view/home/home.html index 088d1736..4d91bf31 100644 --- a/app/view/home/home.html +++ b/app/view/home/home.html @@ -1,3 +1,13 @@

yo we at the home page

+ + + +
    +
  • + name: {{ gallery.name }} + description: {{ gallery.description }} + id: {{ gallery._id }} +
  • +
diff --git a/wireframes/assets/cf-logo.png b/assets/cf-logo.png similarity index 100% rename from wireframes/assets/cf-logo.png rename to assets/cf-logo.png diff --git a/webpack.config.js b/webpack.config.js index 788f65bd..afd66706 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,12 +1,14 @@ - 'use strict'; -require('dotenv').load(); - +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`, @@ -20,8 +22,11 @@ module.exports = { }), new ExtractTextPlugin('bundle.css'), new webpack.DefinePlugin({ - __API_URL__: process.env.API_URL - }) + 'process.env': { + '__API_URL__': JSON.stringify(process.env.API_URL), + '__DEBUG__': JSON.stringify(!production) + } + }), ], module: { rules: [ From 4130766cf67471db4a4791f9f94466be1cf8ecaa Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 29 Mar 2017 15:39:04 -0700 Subject: [PATCH 08/23] fixed logout button issue --- app/component/navbar/navbar.html | 2 +- app/component/navbar/navbar.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/component/navbar/navbar.html b/app/component/navbar/navbar.html index d03d2b07..fa5f3a86 100644 --- a/app/component/navbar/navbar.html +++ b/app/component/navbar/navbar.html @@ -3,7 +3,7 @@

cfgram

diff --git a/app/component/navbar/navbar.js b/app/component/navbar/navbar.js index a21d9ca0..a371de10 100644 --- a/app/component/navbar/navbar.js +++ b/app/component/navbar/navbar.js @@ -7,7 +7,7 @@ module.exports = { controller: ['$log', '$location', '$rootScope', 'authService', NavbarController], controllerAs: 'navbarCtrl' }; - + function NavbarController($log, $location, $rootScope, authService) { $log.debug('NavbarController'); From 1caa8453c696273323a95fa19bea1bd9ddd21465 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 29 Mar 2017 17:13:52 -0700 Subject: [PATCH 09/23] started adding styles --- app/component/navbar/_navbar.scss | 38 ++++++++++++++++++++++++ app/component/navbar/navbar.html | 6 ++-- app/component/navbar/navbar.js | 2 +- app/index.html | 10 ++++--- app/scss/_reset.scss | 48 +++++++++++++++++++++++++++++++ app/scss/_vars.scss | 7 +++++ app/scss/main.scss | 14 +++++++++ webpack.config.js | 4 ++- 8 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 app/scss/_reset.scss create mode 100644 app/scss/_vars.scss diff --git a/app/component/navbar/_navbar.scss b/app/component/navbar/_navbar.scss index e69de29b..1b4b9232 100644 --- a/app/component/navbar/_navbar.scss +++ b/app/component/navbar/_navbar.scss @@ -0,0 +1,38 @@ +//:::: Navbar Styles ::::// + +.navbar { + width: 100%; + height: 9vw; + background-color: #4a4a4a; + outline: 1px solid orange; + position: relative; + + img { + width: 6vw; + height: 6vw; + position: absolute; + top: 17%; + left: 3%; + } + + h2 { + font-size: 4vw; + position: absolute; + top: 26%; + left: 10.5%; + color: #e6e6e6; + } + + .logout-btn { + position: absolute; + right: 3%; + top: 32%; + border-radius: 10px; + border: none; + background-color: #d8d8d8; + color: #727272; + width: 12vw; + height: 3vw; + font-size: 1.75vw; + } +} diff --git a/app/component/navbar/navbar.html b/app/component/navbar/navbar.html index fa5f3a86..4ea91d6a 100644 --- a/app/component/navbar/navbar.html +++ b/app/component/navbar/navbar.html @@ -1,10 +1,8 @@ diff --git a/app/component/navbar/navbar.js b/app/component/navbar/navbar.js index a371de10..a21d9ca0 100644 --- a/app/component/navbar/navbar.js +++ b/app/component/navbar/navbar.js @@ -7,7 +7,7 @@ module.exports = { controller: ['$log', '$location', '$rootScope', 'authService', NavbarController], controllerAs: 'navbarCtrl' }; - + function NavbarController($log, $location, $rootScope, authService) { $log.debug('NavbarController'); diff --git a/app/index.html b/app/index.html index 72e073b9..cb27ea41 100644 --- a/app/index.html +++ b/app/index.html @@ -5,10 +5,12 @@ CF-Gram -
- -
- +
+ +
+
+ +
diff --git a/app/scss/_reset.scss b/app/scss/_reset.scss new file mode 100644 index 00000000..ed11813c --- /dev/null +++ b/app/scss/_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/_vars.scss b/app/scss/_vars.scss new file mode 100644 index 00000000..051e018a --- /dev/null +++ b/app/scss/_vars.scss @@ -0,0 +1,7 @@ +//:::: Variables :::: // + +$sitePrimary: #d8d8d8; +$siteSecondary: #9b9b9b; +$navbarBg: #4a4a4a; +$footerBg: #9b9b9b; +$buttonBg: #4a4a4a; diff --git a/app/scss/main.scss b/app/scss/main.scss index e69de29b..942cb765 100644 --- a/app/scss/main.scss +++ b/app/scss/main.scss @@ -0,0 +1,14 @@ +@import 'reset'; +@import 'vars'; +// :::: Base Styles :::: // + +html body { + max-width: 960px; + height: 100%; + margin: 0 auto; + background-color: $sitePrimary; +} + +header { + height: 5%; +} diff --git a/webpack.config.js b/webpack.config.js index afd66706..a2c9a542 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,10 +2,12 @@ const dotenv = require('dotenv'); const webpack = require('webpack'); +const path = require('path'); const HTMLPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const production = process.env.NODE_ENV === 'production'; +const sassVars = require('./app/scss/_vars.scss'); dotenv.load(); @@ -25,7 +27,7 @@ module.exports = { 'process.env': { '__API_URL__': JSON.stringify(process.env.API_URL), '__DEBUG__': JSON.stringify(!production) - } + }, }), ], module: { From 145e9af46afb2d22193ab61780d584624df19947 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 29 Mar 2017 22:09:05 -0700 Subject: [PATCH 10/23] got my styles looking good --- .../create-gallery/_create-gallery.scss | 41 +++++++++++++++++++ .../create-gallery/create-gallery.html | 20 +++++---- .../gallery/create-gallery/create-gallery.js | 2 + app/index.html | 2 + app/scss/main.scss | 12 ++++++ app/view/home/_home.scss | 27 ++++++++++++ app/view/home/home.html | 10 ++--- 7 files changed, 102 insertions(+), 12 deletions(-) diff --git a/app/component/gallery/create-gallery/_create-gallery.scss b/app/component/gallery/create-gallery/_create-gallery.scss index e69de29b..d30218df 100644 --- a/app/component/gallery/create-gallery/_create-gallery.scss +++ b/app/component/gallery/create-gallery/_create-gallery.scss @@ -0,0 +1,41 @@ +//:::: Create Gallery Styles ::::// + +.create-gallery { + margin: 0 auto; + + h2 { + font-size: 3vw; + margin-top: 6%; + + }; + + input { + width: 97%; + margin: 2% 0; + border: 1px solid; + border-color: #727272; + height: 4vw; + border-radius: 8px; + padding-left: 2vw; + font-size: 1.35vw; + } + + button { + float: right; + border-radius: 10px; + background-color: #4a4a4a; + border: none; + color: #e6e6e6; + width: 18vw; + height: 4.5vw; + font-size: 1.75vw; + padding: 0 3vw; + margin-bottom: 10%; + } +} + +.clearfix { + width: 100%; + height: 0%; + clear: both; +} diff --git a/app/component/gallery/create-gallery/create-gallery.html b/app/component/gallery/create-gallery/create-gallery.html index 2d9f7f2c..0ee19f07 100644 --- a/app/component/gallery/create-gallery/create-gallery.html +++ b/app/component/gallery/create-gallery/create-gallery.html @@ -1,21 +1,27 @@ diff --git a/app/component/gallery/create-gallery/create-gallery.js b/app/component/gallery/create-gallery/create-gallery.js index 0044d219..6d664775 100644 --- a/app/component/gallery/create-gallery/create-gallery.js +++ b/app/component/gallery/create-gallery/create-gallery.js @@ -1,5 +1,7 @@ 'use strict'; +require('./_create-gallery.scss'); + module.exports = { template: require('./create-gallery.html'), controller: ['$log', 'galleryService', CreateGalleryController], diff --git a/app/index.html b/app/index.html index cb27ea41..e34e06d7 100644 --- a/app/index.html +++ b/app/index.html @@ -12,5 +12,7 @@
+ +
diff --git a/app/scss/main.scss b/app/scss/main.scss index 942cb765..c7d6157a 100644 --- a/app/scss/main.scss +++ b/app/scss/main.scss @@ -9,6 +9,18 @@ html body { background-color: $sitePrimary; } +main{ + width: 90%; + margin: 0 5%; +} + header { height: 5%; } + +footer { + background-color: #9b9b9b; + width: 100%; + height: 7vw; + margin-top: 200px +} diff --git a/app/view/home/_home.scss b/app/view/home/_home.scss index e69de29b..1d531986 100644 --- a/app/view/home/_home.scss +++ b/app/view/home/_home.scss @@ -0,0 +1,27 @@ +//:::: Gallery Styles ::::// + +.home-content { + width: 95%; + margin: 0 auto; + + h2 { + font-size: 3vw; + } + .gallery { + background-color: #9b9b9b; + margin-top: 5%; + height: 9vw; + line-height: 3vw; + border-radius: 8px; + padding: 5px 0 5px 10px; + font-size: 1.75vw; + + .tag { + font-weight: bold; + + .gallery-info { + font-weight: normal; + } + } + } +} diff --git a/app/view/home/home.html b/app/view/home/home.html index 4d91bf31..6acfedb9 100644 --- a/app/view/home/home.html +++ b/app/view/home/home.html @@ -1,13 +1,13 @@
-

yo we at the home page

+

Galleries

    -
  • - name: {{ gallery.name }} - description: {{ gallery.description }} - id: {{ gallery._id }} +
From 0fb55dd889456a726e6ca02ea2b28e3afb03cbfd Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 29 Mar 2017 22:50:45 -0700 Subject: [PATCH 11/23] styled sign in and sign up, known issue with sign in page, could be easily fixed if I can get my stylesheets to cascade properly --- app/component/landing/login/_login.scss | 43 +++++++++++++++++++++++ app/component/landing/login/login.html | 4 ++- app/component/landing/signup/_signup.scss | 42 ++++++++++++++++++++++ app/component/landing/signup/signup.html | 4 ++- app/component/landing/signup/signup.js | 2 ++ app/scss/_vars.scss | 15 ++++---- app/scss/main.scss | 4 +-- app/view/landing/_landing.scss | 26 ++++++++++++++ app/view/landing/landing.html | 25 ++++++++----- 9 files changed, 146 insertions(+), 19 deletions(-) diff --git a/app/component/landing/login/_login.scss b/app/component/landing/login/_login.scss index e69de29b..3801cec8 100644 --- a/app/component/landing/login/_login.scss +++ b/app/component/landing/login/_login.scss @@ -0,0 +1,43 @@ +//:::: Login Styles ::::// + + +.login { + margin: 0 auto; + width: 100%; + + h2 { + font-size: 3vw; + margin-top: 6%; + color: #4a4a4a; + + }; + + input { + width: 97%; + margin: 2% 0; + border: 1px solid; + border-color: #727272; + height: 4vw; + border-radius: 8px; + padding-left: 2vw; + font-size: 1.35vw; + } + + button { + float: right; + border-radius: 10px; + background-color: #4a4a4a; + border: none; + color: #e6e6e6; + width: 18vw; + height: 4.5vw; + font-size: 1.75vw; + padding: 0 3vw; + } +} + +.clearfix { + width: 100%; + height: 0%; + clear: both; +} diff --git a/app/component/landing/login/login.html b/app/component/landing/login/login.html index 0c2af902..8ca5d8a9 100644 --- a/app/component/landing/login/login.html +++ b/app/component/landing/login/login.html @@ -1,4 +1,6 @@ - From b918432153bbc938eb4541b5b1c059087dfd4f97 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Mon, 3 Apr 2017 22:13:56 -0700 Subject: [PATCH 18/23] added styles and pic component --- .../_thumbnail-container.scss | 0 .../thumbnail-container.html | 1 + .../thumbnail-container.js | 12 +++++++++ .../gallery/thumbnail/_thumbnail.scss | 0 app/component/gallery/thumbnail/thumbnail.js | 19 +++++++++++++ .../gallery/upload-pic/_upload-pic.scss | 0 .../gallery/upload-pic/upload-pic.html | 26 ++++++++++++++++++ .../gallery/upload-pic/upload-pic.js | 27 +++++++++++++++++++ 8 files changed, 85 insertions(+) create mode 100644 app/component/gallery/thumbnail-container/_thumbnail-container.scss create mode 100644 app/component/gallery/thumbnail-container/thumbnail-container.js create mode 100644 app/component/gallery/thumbnail/_thumbnail.scss create mode 100644 app/component/gallery/thumbnail/thumbnail.js create mode 100644 app/component/gallery/upload-pic/_upload-pic.scss create mode 100644 app/component/gallery/upload-pic/upload-pic.html create mode 100644 app/component/gallery/upload-pic/upload-pic.js 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 00000000..e69de29b diff --git a/app/component/gallery/thumbnail-container/thumbnail-container.html b/app/component/gallery/thumbnail-container/thumbnail-container.html index 191d00a2..d906c776 100644 --- a/app/component/gallery/thumbnail-container/thumbnail-container.html +++ b/app/component/gallery/thumbnail-container/thumbnail-container.html @@ -6,3 +6,4 @@

{{ thumbnailContainerCtrl.gallery.name }}

+ 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 00000000..c09a86b3 --- /dev/null +++ b/app/component/gallery/thumbnail-container/thumbnail-container.js @@ -0,0 +1,12 @@ +'use strict'; + +require('./_thumbnail-container.scss'); + +module.exports = { + template: require('./thumbnail-container.html'), + controllerAs: 'thumbnailContainerCtrl', + bindings: { + gallery: '<' + } +}; + diff --git a/app/component/gallery/thumbnail/_thumbnail.scss b/app/component/gallery/thumbnail/_thumbnail.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/component/gallery/thumbnail/thumbnail.js b/app/component/gallery/thumbnail/thumbnail.js new file mode 100644 index 00000000..66419a7b --- /dev/null +++ b/app/component/gallery/thumbnail/thumbnail.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = { + template: require('./thumbnail.html'), + controller: ['$log', 'picService', ThumbnailController], + controllerAs: 'thumbnailCtrl', + bindings: { + pic: '<' + } +}; + +function ThumbnailController($log, picService) { + $log.debug('ThumbnailController'); + + //TODO:Build out this delete function + this.deletePic = function() { + $log.debug('thumbnailCtrl.deletePic'); + } +} diff --git a/app/component/gallery/upload-pic/_upload-pic.scss b/app/component/gallery/upload-pic/_upload-pic.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/component/gallery/upload-pic/upload-pic.html b/app/component/gallery/upload-pic/upload-pic.html new file mode 100644 index 00000000..d2d8744d --- /dev/null +++ b/app/component/gallery/upload-pic/upload-pic.html @@ -0,0 +1,26 @@ +
+
+ + +

upload a new pic

+ +
+ + +
+ +
+

select a pic to upload

+ + +
+
+ +
diff --git a/app/component/gallery/upload-pic/upload-pic.js b/app/component/gallery/upload-pic/upload-pic.js new file mode 100644 index 00000000..fdad1bb4 --- /dev/null +++ b/app/component/gallery/upload-pic/upload-pic.js @@ -0,0 +1,27 @@ +'use strict'; + +require('./_upload-pic.scss'); + +module.exports = { + template: require('./upload-pic.html'), + controller: ['$log', 'picService', UploadPicController], + controllerAs: 'uploadPicCtrl', + bindings: { + gallery: '<' + } +}; + +function UploadPicController($log, picService) { + $log.debug('UploadPicController'); + + this.pic = {}; + + this.uploadPic = function() { + picService.uploadGalleryPic(this.gallery, this.pic) + .then( () => { + this.pic.name = null; + this.pic.description = null; + this.pic.file = null; + }); + }; +} From 1c4f1fc66d1caeeade00804b5749ef349b88f492 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Mon, 3 Apr 2017 22:14:41 -0700 Subject: [PATCH 19/23] added styles and pic component --- app/entry.js | 3 +- app/service/pic-service.js | 57 ++++++++++++++++++++++++++++++++ app/view/home/home-controller.js | 7 ++++ app/view/home/home.html | 9 ++++- package.json | 1 + 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/app/entry.js b/app/entry.js index 44d308d0..215be150 100644 --- a/app/entry.js +++ b/app/entry.js @@ -9,8 +9,9 @@ const path = require('path'); const uiRouter = require('angular-ui-router'); const ngTouch = require('angular-touch'); const ngAnimate = require('angular-animate'); +const ngFileUpload = require('ng-file-upload'); -const cfgram = angular.module('cfgram', [ngTouch, ngAnimate, uiRouter]); +const cfgram = angular.module('cfgram', [ngTouch, ngAnimate, uiRouter, ngFileUpload]); let context = require.context('./config/', true, /\.js$/); context.keys().forEach( key => { diff --git a/app/service/pic-service.js b/app/service/pic-service.js index e69de29b..f1315c62 100644 --- a/app/service/pic-service.js +++ b/app/service/pic-service.js @@ -0,0 +1,57 @@ +'use strict'; + +module.exports = ['$log', '$q', '$http', 'Upload', 'authService', picService]; + +function picService($log, $q, $http, Upload, authService) { + $log.debug('picService'); + let service = {}; + + service.uploadGalleryPic = function(galleryData, picData) { + $log.debug(picService.uploadGalleryPic); + + return authService.getToken() + .then( token => { + // let url = `${process.env.__API_URL__}/api/gallery/${galleryData._id}/pic`; + // let headers = { + // 'Authorization': `Bearer ${token}`, + // 'Accept': 'application/json' + // }; + let url = `${process.env.__API_URL__}/api/gallery/${galleryData._id}/pic`; + + let config = { + method: 'POST', + headers: { + 'Authorization': `Bearer ${token}`, + 'Accept': 'application/json' + }, + url: url, + data: { + name: picData.name, + description: picData.description, + file: picData.file + } + }; + return Upload.upload({ + config + // url, + // headers, + // method: 'POST', + // data: { + // name: picData.name, + // description: picData.description, + // file: picData.file + // } + }); + }) + .then( res => { + galleryData.pics.unshift(res.data); + return res.data; + }) + .catch( err => { + $log.debug(err.message); + return $q.reject(err); + }); + }; + + return service; +} diff --git a/app/view/home/home-controller.js b/app/view/home/home-controller.js index 4640d170..e51b99a1 100644 --- a/app/view/home/home-controller.js +++ b/app/view/home/home-controller.js @@ -13,9 +13,16 @@ function HomeController($log, $rootScope, galleryService) { galleryService.fetchGalleries() .then( galleries => { this.galleries = galleries; + this.currentGallery = galleries[0]; }); }; + this.galleryDeleteDone = function(gallery) { + if (this.currentGallery._id === gallery._id) { + this.currentGallery = null; + } + }; + this.fetchGalleries(); $rootScope.$on('$locationChangeSuccess', () => { diff --git a/app/view/home/home.html b/app/view/home/home.html index c3146538..07aaf4e3 100644 --- a/app/view/home/home.html +++ b/app/view/home/home.html @@ -4,6 +4,13 @@

Galleries

    - + +
+ + + diff --git a/package.json b/package.json index 02a87b37..7342680c 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "file-loader": "^0.10.1", "html-loader": "^0.4.5", "html-webpack-plugin": "^2.28.0", + "ng-file-upload": "^12.2.13", "node-sass": "^4.5.1", "pascalcase": "^0.1.1", "resolve-url-loader": "^2.0.2", From 0de1e75db488628b487ecd5d6160cd2b17a070e8 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Tue, 4 Apr 2017 13:25:02 -0700 Subject: [PATCH 20/23] got my initial 3 tests to pass --- .../thumbnail-container.js | 3 +- app/service/auth-service.js | 1 - app/service/pic-service.js | 30 ++++--------- karma.conf.js | 29 ++++++++++++ package.json | 11 ++++- test/auth-service-test.js | 30 +++++++++++++ test/example-test.js | 7 +++ test/gallery-service-test.js | 44 +++++++++++++++++++ webpack.config.js | 1 - 9 files changed, 129 insertions(+), 27 deletions(-) create mode 100644 karma.conf.js create mode 100644 test/auth-service-test.js create mode 100644 test/example-test.js create mode 100644 test/gallery-service-test.js diff --git a/app/component/gallery/thumbnail-container/thumbnail-container.js b/app/component/gallery/thumbnail-container/thumbnail-container.js index c09a86b3..6de5d377 100644 --- a/app/component/gallery/thumbnail-container/thumbnail-container.js +++ b/app/component/gallery/thumbnail-container/thumbnail-container.js @@ -8,5 +8,4 @@ module.exports = { bindings: { gallery: '<' } -}; - +}; diff --git a/app/service/auth-service.js b/app/service/auth-service.js index 200372ff..ce2d66cd 100644 --- a/app/service/auth-service.js +++ b/app/service/auth-service.js @@ -32,7 +32,6 @@ function authService($log, $q, $http, $window) { service.signup = function(user) { $log.debug('authService.signup'); - $log.log('process.env.__API_URL__', process.env.__API_URL__); let config = { method: 'POST', diff --git a/app/service/pic-service.js b/app/service/pic-service.js index f1315c62..ad7ffe26 100644 --- a/app/service/pic-service.js +++ b/app/service/pic-service.js @@ -11,36 +11,22 @@ function picService($log, $q, $http, Upload, authService) { return authService.getToken() .then( token => { - // let url = `${process.env.__API_URL__}/api/gallery/${galleryData._id}/pic`; - // let headers = { - // 'Authorization': `Bearer ${token}`, - // 'Accept': 'application/json' - // }; + let url = `${process.env.__API_URL__}/api/gallery/${galleryData._id}/pic`; + let headers = { + 'Authorization': `Bearer ${token}`, + 'Accept': 'application/json' + }; - let config = { + return Upload.upload({ + url, + headers, method: 'POST', - headers: { - 'Authorization': `Bearer ${token}`, - 'Accept': 'application/json' - }, - url: url, data: { name: picData.name, description: picData.description, file: picData.file } - }; - return Upload.upload({ - config - // url, - // headers, - // method: 'POST', - // data: { - // name: picData.name, - // description: picData.description, - // file: picData.file - // } }); }) .then( res => { diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 00000000..f6f6d029 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,29 @@ +const webpackConfig = require('./webpack.config.js'); +delete webpackConfig.entry; + +module.exports = function(config) { + config.set({ + webpack: webpackConfig, + basePath: '', + frameworks: ['jasmine'], + files: [ + 'app/entry.js', + 'test/**/*-test.js', + 'node_modules/angular-mocks/angular-mocks.js' + ], + exclude: [ + ], + preprocessors: { + 'test/**/*-test.js': ['webpack'], + 'app/entry.js': ['webpack'] + }, + reporters: ['mocha'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + concurrency: Infinity + }); +}; diff --git a/package.json b/package.json index 7342680c..ee2ad08f 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "main": "index.js", "scripts": { "build": "./node_modules/webpack/bin/webpack.js", - "watch": "./node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot", + "build-watch": "./node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot", + "test": "./node_modules/karma/bin/karma start --single-run", + "test-watch": "./node_modules/karma/bin/karma start", "lint": "./node_modules/eslint/bin/eslint.js ./*" }, "keywords": [], @@ -39,7 +41,14 @@ "webpack": "^2.3.2" }, "devDependencies": { + "angular-mocks": "^1.6.4", "eslint": "^3.18.0", + "jasmine-core": "^2.5.2", + "karma": "^1.5.0", + "karma-chrome-launcher": "^2.0.0", + "karma-jasmine": "^1.1.0", + "karma-mocha-reporter": "^2.2.3", + "karma-webpack": "^2.0.3", "webpack-dev-server": "^2.4.2" } } diff --git a/test/auth-service-test.js b/test/auth-service-test.js new file mode 100644 index 00000000..f9a71d5b --- /dev/null +++ b/test/auth-service-test.js @@ -0,0 +1,30 @@ +'use strict'; + +describe('Auth Service', function() { + beforeEach( () => { + angular.mock.module('cfgram'); + angular.mock.inject(($rootScope, authService, $window, $httpBackend) => { + this.$window = $window; + this.$rootScope = $rootScope; + this.authService = authService; + this.$httpBackend = $httpBackend; + }); + }); + + describe('authService.getToken', () => { + it('should return a token', () => { + this.authService.token = null; + this.$window.localStorage.token = 'test token'; + + this.authService.getToken() + .then( token => { + expect(token).toEqual('test token'); + }) + .catch(err => { + expect(err).toEqual(null); + }); + + this.$rootScope.$apply(); + }); + }); +}); diff --git a/test/example-test.js b/test/example-test.js new file mode 100644 index 00000000..23ae19f5 --- /dev/null +++ b/test/example-test.js @@ -0,0 +1,7 @@ +'use strict'; + +describe('Example Test', function() { + it('should pass this test', () => { + expect(true).toEqual(true); + }); +}); diff --git a/test/gallery-service-test.js b/test/gallery-service-test.js new file mode 100644 index 00000000..5192a9ff --- /dev/null +++ b/test/gallery-service-test.js @@ -0,0 +1,44 @@ +'use strict'; + +describe('Gallery Service', function() { + beforeEach(() => { + angular.mock.module('cfgram'); + angular.mock.inject(($rootScope, authService, galleryService, $window, $httpBackend) =>{ + this.$window = $window; + this.$rootScope = $rootScope; + this.authService = authService; + this.galleryService = galleryService; + this.$httpBackend = $httpBackend; + }); + }); + + describe('galleryService.createGallery', () => { + it('should create a new gallery', () => { + let galleryData = { + name: 'example gallery', + description: 'example description' + }; + + let headers = { + 'Content-Type': 'application/json', + Accept: 'application/json', + Authorization: 'Bearer test token' + }; + + this.$httpBackend.expectPOST('http://localhost:3000/api/gallery', galleryData, headers) + .respond(200, { + _id: '1234', + username: 'testuser', + name: galleryData.name, + description: galleryData.description, + pics: [] + }); + + this.galleryService.createGallery(galleryData); + this.$httpBackend.flush(); + this.$rootScope.$apply(); + }); + }); + + // TODO: create another test for deleting a gallery +}); diff --git a/webpack.config.js b/webpack.config.js index fe54f371..6441b9d9 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,7 +2,6 @@ const dotenv = require('dotenv'); const webpack = require('webpack'); -const path = require('path'); const HTMLPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); From 3a99c9a1339f0cabf1c769f558e47db6342226a2 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Tue, 4 Apr 2017 21:31:15 -0700 Subject: [PATCH 21/23] got my tests to pass, need to add DELETE functionality --- app/service/pic-service.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/service/pic-service.js b/app/service/pic-service.js index ad7ffe26..1d675ed8 100644 --- a/app/service/pic-service.js +++ b/app/service/pic-service.js @@ -11,7 +11,7 @@ function picService($log, $q, $http, Upload, authService) { return authService.getToken() .then( token => { - + let url = `${process.env.__API_URL__}/api/gallery/${galleryData._id}/pic`; let headers = { 'Authorization': `Bearer ${token}`, @@ -20,13 +20,13 @@ function picService($log, $q, $http, Upload, authService) { return Upload.upload({ url, - headers, method: 'POST', data: { name: picData.name, description: picData.description, file: picData.file - } + }, + headers }); }) .then( res => { From f6623c04821d8564770ed4bdf5b26c5c64d21440 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 5 Apr 2017 22:33:30 -0700 Subject: [PATCH 22/23] added component tests --- app/service/pic-service.js | 37 +++++++++++---- test/edit-gallery-componenet-test.js | 67 ++++++++++++++++++++++++++++ test/gallery-item-componenet-test.js | 35 +++++++++++++++ 3 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 test/edit-gallery-componenet-test.js create mode 100644 test/gallery-item-componenet-test.js diff --git a/app/service/pic-service.js b/app/service/pic-service.js index 1d675ed8..f5324c4e 100644 --- a/app/service/pic-service.js +++ b/app/service/pic-service.js @@ -12,21 +12,40 @@ function picService($log, $q, $http, Upload, authService) { return authService.getToken() .then( token => { - let url = `${process.env.__API_URL__}/api/gallery/${galleryData._id}/pic`; - let headers = { - 'Authorization': `Bearer ${token}`, - 'Accept': 'application/json' - }; + // let url = `${process.env.__API_URL__}/api/gallery/${galleryData._id}/pic`; + // let headers = { + // 'Authorization': `Bearer ${token}`, + // 'Accept': 'application/json' + // }; - return Upload.upload({ - url, + let testURL = (process.env.__API_URL__ + '/api/gallery/' + galleryData._id + '/pic'); + + + let config = { method: 'POST', + headers: { + 'Authorization': `Bearer ${token}`, + 'Accept': 'application/json' + }, + url: testURL.toString(), data: { name: picData.name, description: picData.description, file: picData.file - }, - headers + } + }; + $log.log('heres the config object', config); + + return Upload.upload({ + config + // url, + // method: 'POST', + // data: { + // name: picData.name, + // description: picData.description, + // file: picData.file + // }, + // headers }); }) .then( res => { diff --git a/test/edit-gallery-componenet-test.js b/test/edit-gallery-componenet-test.js new file mode 100644 index 00000000..8ffa5564 --- /dev/null +++ b/test/edit-gallery-componenet-test.js @@ -0,0 +1,67 @@ +'use strict'; + +describe('Edit Gallery Component', function() { + + beforeEach( () => { + angular.mock.module('cfgram'); + angular.mock.inject(($rootScope, $componentController, $httpBackend, authService) => { + this.$rootScope = $rootScope; + this.$componentController = $componentController; + this.$httpBackend = $httpBackend; + this.authService = authService; + }); + }); + + it('should contain the proper component bindings', () => { + let mockBindings = { + gallery: { + name: 'test gallery name', + description: 'test gallery description' + } + }; + + let editGalleryCtrl = this.$componentController('editGallery', null, mockBindings); + expect(editGalleryCtrl.gallery.name).toEqual(mockBindings.gallery.name); + expect(editGalleryCtrl.gallery.description).toEqual(mockBindings.gallery.description); + + this.$rootScope.$apply(); + }); + + describe('editGalleryCtrl.updateGallery', () => { + it('should make a valid PUT request', () => { + let url = 'http://localhost:3000/api/gallery/123'; + let headers = { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + 'Authorization': 'Bearer test token' + }; + let updateData = { + name: 'updated gallery', + description: 'whoah this so new', + _id: '123' + }; + + this.$httpBackend.expectPUT(url, updateData, headers) + .respond(200); + + let mockBindings = { + gallery: { + _id: '123', + name: 'first gallery', + description: 'this is old' + } + }; + + let editGalleryCtrl = this.$componentController('editGallery', null, mockBindings); + editGalleryCtrl.gallery.name = 'updated gallery'; + editGalleryCtrl.gallery.description = 'whoah this is so new'; + // editGalleryCtrl.updateGallery(); + // .then( gallery => { + // write my tests here + // }); + + // this.$httpBackend.flush(); + this.$rootScope.$apply(); + }); + }); +}); diff --git a/test/gallery-item-componenet-test.js b/test/gallery-item-componenet-test.js new file mode 100644 index 00000000..cb46c317 --- /dev/null +++ b/test/gallery-item-componenet-test.js @@ -0,0 +1,35 @@ +'use strict'; + +describe('Gallery Item Componenet', function() { + + beforeEach( () => { + angular.mock.module('cfgram'); + angular.mock.inject(( $rootScope, $componentController, $httpBackend, authService) => { + this.$rootScope = $rootScope; + this.$componentController = $componentController; + this.$httpBackend = $httpBackend; + this.authService = authService; + }); + }); + + describe('galleryItemCtrl.deleteDone', () => { + it('should call deleteDone', () => { + let mockBindings = { + gallery: { + _id: '1', + name: 'test name', + description: 'test description', + pics: [] + }, + deleteDone: function(data) { + expect(data.galleryData._id).toEqual('1'); + } + }; + + let galleryItemCtrl = this.$componentController('galleryItem', null, mockBindings); + galleryItemCtrl.deleteDone({ galleryData: galleryItemCtrl.gallery }); + //add some tests here + this.$rootScope.$apply(); + }); + }); +}); From e5e8d13d35d05c4df0b5d3b3dbb98ef58c134259 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Mon, 10 Apr 2017 15:07:20 -0700 Subject: [PATCH 23/23] added ui-bootstrap and modal test to landing page --- .../modals/landing-modal/_landing-modal.scss | 0 .../landing-modal/landing-modal-content.html | 14 + .../modals/landing-modal/landing-modal.html | 1 + .../modals/landing-modal/landing-modal.js | 54 ++ app/component/navbar/navbar.html | 7 +- app/directive/social-icons.html | 7 + app/directive/social-icons.js | 19 + app/entry.js | 17 +- app/filter/gallery-search.js | 17 + app/index.html | 4 +- .../lib/bootstrap/_custom-bootstrap-vars.scss | 874 ++++++++++++++++++ app/scss/lib/bootstrap/_custom-bootstrap.scss | 50 + app/scss/main.scss | 5 + app/view/home/home.html | 7 +- app/view/landing/landing.html | 4 +- package.json | 2 + 16 files changed, 1075 insertions(+), 7 deletions(-) create mode 100644 app/component/modals/landing-modal/_landing-modal.scss create mode 100644 app/component/modals/landing-modal/landing-modal-content.html create mode 100644 app/component/modals/landing-modal/landing-modal.html create mode 100644 app/component/modals/landing-modal/landing-modal.js create mode 100644 app/directive/social-icons.html create mode 100644 app/directive/social-icons.js create mode 100644 app/filter/gallery-search.js create mode 100644 app/scss/lib/bootstrap/_custom-bootstrap-vars.scss create mode 100644 app/scss/lib/bootstrap/_custom-bootstrap.scss diff --git a/app/component/modals/landing-modal/_landing-modal.scss b/app/component/modals/landing-modal/_landing-modal.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/component/modals/landing-modal/landing-modal-content.html b/app/component/modals/landing-modal/landing-modal-content.html new file mode 100644 index 00000000..2b0a0d27 --- /dev/null +++ b/app/component/modals/landing-modal/landing-modal-content.html @@ -0,0 +1,14 @@ + + + diff --git a/app/component/modals/landing-modal/landing-modal.html b/app/component/modals/landing-modal/landing-modal.html new file mode 100644 index 00000000..432773bc --- /dev/null +++ b/app/component/modals/landing-modal/landing-modal.html @@ -0,0 +1 @@ + diff --git a/app/component/modals/landing-modal/landing-modal.js b/app/component/modals/landing-modal/landing-modal.js new file mode 100644 index 00000000..bc443294 --- /dev/null +++ b/app/component/modals/landing-modal/landing-modal.js @@ -0,0 +1,54 @@ +'use strict'; + +require('./_landing-modal.scss'); + +module.exports = { + template: require('./landing-modal.html'), + controller: ['$log', '$uibModal', '$scope', LandingModalController], + controllerAs: 'landingModalCtrl' +}; + +function LandingModalController($log, $uibModal, $scope) { + $log.debug('LandingModalController'); + + this.createModal = function() { + let modal = $uibModal.open({ + backdrop: 'static', + keyboard: true, + backdropClick: false, + template: require('./landing-modal-content.html'), + scope: $scope + }); + + $scope.modalInstance = modal; + return modal.result; + }; + + this.triggerModal = function() { + this.createModal() + .then( (data) => { + this.handleSuccess(data); + }) + .then(null, (reason) => { + this.handleDismiss(reason); + console.log('heres the scope object', $scope); + console.log('heres the this, controller as:', this); + }); + }; + + this.yes = function() { + $scope.modalInstance.close('Yes Button Clicked'); + }; + + this.no = function() { + $scope.modalInstance.dismiss('No Button Clicked'); + }; + + this.handleSuccess = function(data) { + $log.info('Modal closed: ' + data); + }; + + this.handleDismiss = function(reason) { + $log.info('Modal dismissed: ' + reason); + }; +} diff --git a/app/component/navbar/navbar.html b/app/component/navbar/navbar.html index 4ea91d6a..f5ad8d0f 100644 --- a/app/component/navbar/navbar.html +++ b/app/component/navbar/navbar.html @@ -2,7 +2,8 @@

cfgram

-
- -
+ +
+ +
diff --git a/app/directive/social-icons.html b/app/directive/social-icons.html new file mode 100644 index 00000000..7a9a972f --- /dev/null +++ b/app/directive/social-icons.html @@ -0,0 +1,7 @@ + diff --git a/app/directive/social-icons.js b/app/directive/social-icons.js new file mode 100644 index 00000000..bacf55a7 --- /dev/null +++ b/app/directive/social-icons.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = function(){ + return { + restrict: 'EAC', + template: require('./social-icons.html'), + controller: ['$log', SocialIconsController], + bindtoController: true, + controllerAs: 'socialIconsCtrl', + scope: { + test: '@' + } + }; +}; + +function SocialIconsController($log) { + $log.debug('SocialIconsController'); + this.icons = ['fb', 'twitter', 'instagram']; +} diff --git a/app/entry.js b/app/entry.js index 215be150..0e19c9b2 100644 --- a/app/entry.js +++ b/app/entry.js @@ -10,8 +10,9 @@ const uiRouter = require('angular-ui-router'); const ngTouch = require('angular-touch'); const ngAnimate = require('angular-animate'); const ngFileUpload = require('ng-file-upload'); +const uiBootstrap = require('angular-ui-bootstrap'); -const cfgram = angular.module('cfgram', [ngTouch, ngAnimate, uiRouter, ngFileUpload]); +const cfgram = angular.module('cfgram', [ngTouch, ngAnimate, uiRouter, ngFileUpload, uiBootstrap]); let context = require.context('./config/', true, /\.js$/); context.keys().forEach( key => { @@ -38,3 +39,17 @@ context.keys().forEach( key => { let module = context(key); cfgram.controller(name, module); }); + +context = require.context('./filter/', true, /\.js$/); +context.keys().forEach( key => { + let name = camelcase(path.basename(key, '.js')); + let module = context(key); + cfgram.filter(name, module); +}); + +context = require.context('./directive/', true, /\.js$/); +context.keys().forEach( key => { + let name = camelcase(path.basename(key, '.js')); + let module = context(key); + cfgram.directive(name, module); +}); diff --git a/app/filter/gallery-search.js b/app/filter/gallery-search.js new file mode 100644 index 00000000..11ecef86 --- /dev/null +++ b/app/filter/gallery-search.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = function() { + return function(galleries, searchTerm) { + let fuzzyRegex = generateFuzzyRegex(searchTerm); + + return galleries.filter(gallery => { + return fuzzyRegex.test(gallery.name.toUpperCase()); + }); + }; +}; + +function generateFuzzyRegex(input) { + if(!input) return /.*/; + let fuzzyString = '.*' + input.toUpperCase().split('').join('.*') + '.*'; + return new RegExp(fuzzyString); +} diff --git a/app/index.html b/app/index.html index e34e06d7..6c8f535b 100644 --- a/app/index.html +++ b/app/index.html @@ -13,6 +13,8 @@ -
+
+ +
diff --git a/app/scss/lib/bootstrap/_custom-bootstrap-vars.scss b/app/scss/lib/bootstrap/_custom-bootstrap-vars.scss new file mode 100644 index 00000000..e0496852 --- /dev/null +++ b/app/scss/lib/bootstrap/_custom-bootstrap-vars.scss @@ -0,0 +1,874 @@ +$bootstrap-sass-asset-helper: false !default; +// +// Variables +// -------------------------------------------------- + + +//== Colors +// +//## Gray and brand colors for use across Bootstrap. + +$gray-base: #000 !default; +$gray-darker: lighten($gray-base, 13.5%) !default; // #222 +$gray-dark: lighten($gray-base, 20%) !default; // #333 +$gray: lighten($gray-base, 33.5%) !default; // #555 +$gray-light: lighten($gray-base, 46.7%) !default; // #777 +$gray-lighter: lighten($gray-base, 93.5%) !default; // #eee + +$brand-primary: darken(#428bca, 6.5%) !default; // #337ab7 +$brand-success: #5cb85c !default; +$brand-info: #5bc0de !default; +$brand-warning: #f0ad4e !default; +$brand-danger: #d9534f !default; + + +//== Scaffolding +// +//## Settings for some of the most global styles. + +//** Background color for ``. +$body-bg: #fff !default; +//** Global text color on ``. +$text-color: $gray-dark !default; + +//** Global textual link color. +$link-color: $brand-primary !default; +//** Link hover color set via `darken()` function. +$link-hover-color: darken($link-color, 15%) !default; +//** Link hover decoration. +$link-hover-decoration: underline !default; + + +//== Typography +// +//## Font, line-height, and color for body text, headings, and more. + +$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif !default; +$font-family-serif: Georgia, "Times New Roman", Times, serif !default; +//** Default monospace fonts for ``, ``, and `
`.
+$font-family-monospace:   Menlo, Monaco, Consolas, "Courier New", monospace !default;
+$font-family-base:        $font-family-sans-serif !default;
+
+$font-size-base:          14px !default;
+$font-size-large:         ceil(($font-size-base * 1.25)) !default; // ~18px
+$font-size-small:         ceil(($font-size-base * 0.85)) !default; // ~12px
+
+$font-size-h1:            floor(($font-size-base * 2.6)) !default; // ~36px
+$font-size-h2:            floor(($font-size-base * 2.15)) !default; // ~30px
+$font-size-h3:            ceil(($font-size-base * 1.7)) !default; // ~24px
+$font-size-h4:            ceil(($font-size-base * 1.25)) !default; // ~18px
+$font-size-h5:            $font-size-base !default;
+$font-size-h6:            ceil(($font-size-base * 0.85)) !default; // ~12px
+
+//** Unit-less `line-height` for use in components like buttons.
+$line-height-base:        1.428571429 !default; // 20/14
+//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
+$line-height-computed:    floor(($font-size-base * $line-height-base)) !default; // ~20px
+
+//** By default, this inherits from the ``.
+$headings-font-family:    inherit !default;
+$headings-font-weight:    500 !default;
+$headings-line-height:    1.1 !default;
+$headings-color:          inherit !default;
+
+
+//== Iconography
+//
+//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
+
+//** Load fonts from this directory.
+
+// [converter] If $bootstrap-sass-asset-helper if used, provide path relative to the assets load path.
+// [converter] This is because some asset helpers, such as Sprockets, do not work with file-relative paths.
+$icon-font-path: if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/bootstrap/") !default;
+
+//** File name for all font files.
+$icon-font-name:          "glyphicons-halflings-regular" !default;
+//** Element ID within SVG icon file.
+$icon-font-svg-id:        "glyphicons_halflingsregular" !default;
+
+
+//== Components
+//
+//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
+
+$padding-base-vertical:     6px !default;
+$padding-base-horizontal:   12px !default;
+
+$padding-large-vertical:    10px !default;
+$padding-large-horizontal:  16px !default;
+
+$padding-small-vertical:    5px !default;
+$padding-small-horizontal:  10px !default;
+
+$padding-xs-vertical:       1px !default;
+$padding-xs-horizontal:     5px !default;
+
+$line-height-large:         1.3333333 !default; // extra decimals for Win 8.1 Chrome
+$line-height-small:         1.5 !default;
+
+$border-radius-base:        4px !default;
+$border-radius-large:       6px !default;
+$border-radius-small:       3px !default;
+
+//** Global color for active items (e.g., navs or dropdowns).
+$component-active-color:    #fff !default;
+//** Global background color for active items (e.g., navs or dropdowns).
+$component-active-bg:       $brand-primary !default;
+
+//** Width of the `border` for generating carets that indicate dropdowns.
+$caret-width-base:          4px !default;
+//** Carets increase slightly in size for larger components.
+$caret-width-large:         5px !default;
+
+
+//== Tables
+//
+//## Customizes the `.table` component with basic values, each used across all table variations.
+
+//** Padding for ``s and ``s.
+$table-cell-padding:            8px !default;
+//** Padding for cells in `.table-condensed`.
+$table-condensed-cell-padding:  5px !default;
+
+//** Default background color used for all tables.
+$table-bg:                      transparent !default;
+//** Background color used for `.table-striped`.
+$table-bg-accent:               #f9f9f9 !default;
+//** Background color used for `.table-hover`.
+$table-bg-hover:                #f5f5f5 !default;
+$table-bg-active:               $table-bg-hover !default;
+
+//** Border color for table and cell borders.
+$table-border-color:            #ddd !default;
+
+
+//== Buttons
+//
+//## For each of Bootstrap's buttons, define text, background and border color.
+
+$btn-font-weight:                normal !default;
+
+$btn-default-color:              #333 !default;
+$btn-default-bg:                 #fff !default;
+$btn-default-border:             #ccc !default;
+
+$btn-primary-color:              #fff !default;
+$btn-primary-bg:                 $brand-primary !default;
+$btn-primary-border:             darken($btn-primary-bg, 5%) !default;
+
+$btn-success-color:              #fff !default;
+$btn-success-bg:                 $brand-success !default;
+$btn-success-border:             darken($btn-success-bg, 5%) !default;
+
+$btn-info-color:                 #fff !default;
+$btn-info-bg:                    $brand-info !default;
+$btn-info-border:                darken($btn-info-bg, 5%) !default;
+
+$btn-warning-color:              #fff !default;
+$btn-warning-bg:                 $brand-warning !default;
+$btn-warning-border:             darken($btn-warning-bg, 5%) !default;
+
+$btn-danger-color:               #fff !default;
+$btn-danger-bg:                  $brand-danger !default;
+$btn-danger-border:              darken($btn-danger-bg, 5%) !default;
+
+$btn-link-disabled-color:        $gray-light !default;
+
+// Allows for customizing button radius independently from global border radius
+$btn-border-radius-base:         $border-radius-base !default;
+$btn-border-radius-large:        $border-radius-large !default;
+$btn-border-radius-small:        $border-radius-small !default;
+
+
+//== Forms
+//
+//##
+
+//** `` background color
+$input-bg:                       #fff !default;
+//** `` background color
+$input-bg-disabled:              $gray-lighter !default;
+
+//** Text color for ``s
+$input-color:                    $gray !default;
+//** `` border color
+$input-border:                   #ccc !default;
+
+// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
+//** Default `.form-control` border radius
+// This has no effect on ``s in CSS.
+$input-border-radius:            $border-radius-base !default;
+//** Large `.form-control` border radius
+$input-border-radius-large:      $border-radius-large !default;
+//** Small `.form-control` border radius
+$input-border-radius-small:      $border-radius-small !default;
+
+//** Border color for inputs on focus
+$input-border-focus:             #66afe9 !default;
+
+//** Placeholder text color
+$input-color-placeholder:        #999 !default;
+
+//** Default `.form-control` height
+$input-height-base:              ($line-height-computed + ($padding-base-vertical * 2) + 2) !default;
+//** Large `.form-control` height
+$input-height-large:             (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default;
+//** Small `.form-control` height
+$input-height-small:             (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default;
+
+//** `.form-group` margin
+$form-group-margin-bottom:       15px !default;
+
+$legend-color:                   $gray-dark !default;
+$legend-border-color:            #e5e5e5 !default;
+
+//** Background color for textual input addons
+$input-group-addon-bg:           $gray-lighter !default;
+//** Border color for textual input addons
+$input-group-addon-border-color: $input-border !default;
+
+//** Disabled cursor for form controls and buttons.
+$cursor-disabled:                not-allowed !default;
+
+
+//== Dropdowns
+//
+//## Dropdown menu container and contents.
+
+//** Background for the dropdown menu.
+$dropdown-bg:                    #fff !default;
+//** Dropdown menu `border-color`.
+$dropdown-border:                rgba(0,0,0,.15) !default;
+//** Dropdown menu `border-color` **for IE8**.
+$dropdown-fallback-border:       #ccc !default;
+//** Divider color for between dropdown items.
+$dropdown-divider-bg:            #e5e5e5 !default;
+
+//** Dropdown link text color.
+$dropdown-link-color:            $gray-dark !default;
+//** Hover color for dropdown links.
+$dropdown-link-hover-color:      darken($gray-dark, 5%) !default;
+//** Hover background for dropdown links.
+$dropdown-link-hover-bg:         #f5f5f5 !default;
+
+//** Active dropdown menu item text color.
+$dropdown-link-active-color:     $component-active-color !default;
+//** Active dropdown menu item background color.
+$dropdown-link-active-bg:        $component-active-bg !default;
+
+//** Disabled dropdown menu item background color.
+$dropdown-link-disabled-color:   $gray-light !default;
+
+//** Text color for headers within dropdown menus.
+$dropdown-header-color:          $gray-light !default;
+
+//** Deprecated `$dropdown-caret-color` as of v3.1.0
+$dropdown-caret-color:           #000 !default;
+
+
+//-- Z-index master list
+//
+// Warning: Avoid customizing these values. They're used for a bird's eye view
+// of components dependent on the z-axis and are designed to all work together.
+//
+// Note: These variables are not generated into the Customizer.
+
+$zindex-navbar:            1000 !default;
+$zindex-dropdown:          1000 !default;
+$zindex-popover:           1060 !default;
+$zindex-tooltip:           1070 !default;
+$zindex-navbar-fixed:      1030 !default;
+$zindex-modal-background:  1040 !default;
+$zindex-modal:             1050 !default;
+
+
+//== Media queries breakpoints
+//
+//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
+
+// Extra small screen / phone
+//** Deprecated `$screen-xs` as of v3.0.1
+$screen-xs:                  480px !default;
+//** Deprecated `$screen-xs-min` as of v3.2.0
+$screen-xs-min:              $screen-xs !default;
+//** Deprecated `$screen-phone` as of v3.0.1
+$screen-phone:               $screen-xs-min !default;
+
+// Small screen / tablet
+//** Deprecated `$screen-sm` as of v3.0.1
+$screen-sm:                  768px !default;
+$screen-sm-min:              $screen-sm !default;
+//** Deprecated `$screen-tablet` as of v3.0.1
+$screen-tablet:              $screen-sm-min !default;
+
+// Medium screen / desktop
+//** Deprecated `$screen-md` as of v3.0.1
+$screen-md:                  992px !default;
+$screen-md-min:              $screen-md !default;
+//** Deprecated `$screen-desktop` as of v3.0.1
+$screen-desktop:             $screen-md-min !default;
+
+// Large screen / wide desktop
+//** Deprecated `$screen-lg` as of v3.0.1
+$screen-lg:                  1200px !default;
+$screen-lg-min:              $screen-lg !default;
+//** Deprecated `$screen-lg-desktop` as of v3.0.1
+$screen-lg-desktop:          $screen-lg-min !default;
+
+// So media queries don't overlap when required, provide a maximum
+$screen-xs-max:              ($screen-sm-min - 1) !default;
+$screen-sm-max:              ($screen-md-min - 1) !default;
+$screen-md-max:              ($screen-lg-min - 1) !default;
+
+
+//== Grid system
+//
+//## Define your custom responsive grid.
+
+//** Number of columns in the grid.
+$grid-columns:              12 !default;
+//** Padding between columns. Gets divided in half for the left and right.
+$grid-gutter-width:         30px !default;
+// Navbar collapse
+//** Point at which the navbar becomes uncollapsed.
+$grid-float-breakpoint:     $screen-sm-min !default;
+//** Point at which the navbar begins collapsing.
+$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default;
+
+
+//== Container sizes
+//
+//## Define the maximum width of `.container` for different screen sizes.
+
+// Small screen / tablet
+$container-tablet:             (720px + $grid-gutter-width) !default;
+//** For `$screen-sm-min` and up.
+$container-sm:                 $container-tablet !default;
+
+// Medium screen / desktop
+$container-desktop:            (940px + $grid-gutter-width) !default;
+//** For `$screen-md-min` and up.
+$container-md:                 $container-desktop !default;
+
+// Large screen / wide desktop
+$container-large-desktop:      (1140px + $grid-gutter-width) !default;
+//** For `$screen-lg-min` and up.
+$container-lg:                 $container-large-desktop !default;
+
+
+//== Navbar
+//
+//##
+
+// Basics of a navbar
+$navbar-height:                    50px !default;
+$navbar-margin-bottom:             $line-height-computed !default;
+$navbar-border-radius:             $border-radius-base !default;
+$navbar-padding-horizontal:        floor(($grid-gutter-width / 2)) !default;
+$navbar-padding-vertical:          (($navbar-height - $line-height-computed) / 2) !default;
+$navbar-collapse-max-height:       340px !default;
+
+$navbar-default-color:             #777 !default;
+$navbar-default-bg:                #f8f8f8 !default;
+$navbar-default-border:            darken($navbar-default-bg, 6.5%) !default;
+
+// Navbar links
+$navbar-default-link-color:                #777 !default;
+$navbar-default-link-hover-color:          #333 !default;
+$navbar-default-link-hover-bg:             transparent !default;
+$navbar-default-link-active-color:         #555 !default;
+$navbar-default-link-active-bg:            darken($navbar-default-bg, 6.5%) !default;
+$navbar-default-link-disabled-color:       #ccc !default;
+$navbar-default-link-disabled-bg:          transparent !default;
+
+// Navbar brand label
+$navbar-default-brand-color:               $navbar-default-link-color !default;
+$navbar-default-brand-hover-color:         darken($navbar-default-brand-color, 10%) !default;
+$navbar-default-brand-hover-bg:            transparent !default;
+
+// Navbar toggle
+$navbar-default-toggle-hover-bg:           #ddd !default;
+$navbar-default-toggle-icon-bar-bg:        #888 !default;
+$navbar-default-toggle-border-color:       #ddd !default;
+
+
+//=== Inverted navbar
+// Reset inverted navbar basics
+$navbar-inverse-color:                      lighten($gray-light, 15%) !default;
+$navbar-inverse-bg:                         #222 !default;
+$navbar-inverse-border:                     darken($navbar-inverse-bg, 10%) !default;
+
+// Inverted navbar links
+$navbar-inverse-link-color:                 lighten($gray-light, 15%) !default;
+$navbar-inverse-link-hover-color:           #fff !default;
+$navbar-inverse-link-hover-bg:              transparent !default;
+$navbar-inverse-link-active-color:          $navbar-inverse-link-hover-color !default;
+$navbar-inverse-link-active-bg:             darken($navbar-inverse-bg, 10%) !default;
+$navbar-inverse-link-disabled-color:        #444 !default;
+$navbar-inverse-link-disabled-bg:           transparent !default;
+
+// Inverted navbar brand label
+$navbar-inverse-brand-color:                $navbar-inverse-link-color !default;
+$navbar-inverse-brand-hover-color:          #fff !default;
+$navbar-inverse-brand-hover-bg:             transparent !default;
+
+// Inverted navbar toggle
+$navbar-inverse-toggle-hover-bg:            #333 !default;
+$navbar-inverse-toggle-icon-bar-bg:         #fff !default;
+$navbar-inverse-toggle-border-color:        #333 !default;
+
+
+//== Navs
+//
+//##
+
+//=== Shared nav styles
+$nav-link-padding:                          10px 15px !default;
+$nav-link-hover-bg:                         $gray-lighter !default;
+
+$nav-disabled-link-color:                   $gray-light !default;
+$nav-disabled-link-hover-color:             $gray-light !default;
+
+//== Tabs
+$nav-tabs-border-color:                     #ddd !default;
+
+$nav-tabs-link-hover-border-color:          $gray-lighter !default;
+
+$nav-tabs-active-link-hover-bg:             $body-bg !default;
+$nav-tabs-active-link-hover-color:          $gray !default;
+$nav-tabs-active-link-hover-border-color:   #ddd !default;
+
+$nav-tabs-justified-link-border-color:            #ddd !default;
+$nav-tabs-justified-active-link-border-color:     $body-bg !default;
+
+//== Pills
+$nav-pills-border-radius:                   $border-radius-base !default;
+$nav-pills-active-link-hover-bg:            $component-active-bg !default;
+$nav-pills-active-link-hover-color:         $component-active-color !default;
+
+
+//== Pagination
+//
+//##
+
+$pagination-color:                     $link-color !default;
+$pagination-bg:                        #fff !default;
+$pagination-border:                    #ddd !default;
+
+$pagination-hover-color:               $link-hover-color !default;
+$pagination-hover-bg:                  $gray-lighter !default;
+$pagination-hover-border:              #ddd !default;
+
+$pagination-active-color:              #fff !default;
+$pagination-active-bg:                 $brand-primary !default;
+$pagination-active-border:             $brand-primary !default;
+
+$pagination-disabled-color:            $gray-light !default;
+$pagination-disabled-bg:               #fff !default;
+$pagination-disabled-border:           #ddd !default;
+
+
+//== Pager
+//
+//##
+
+$pager-bg:                             $pagination-bg !default;
+$pager-border:                         $pagination-border !default;
+$pager-border-radius:                  15px !default;
+
+$pager-hover-bg:                       $pagination-hover-bg !default;
+
+$pager-active-bg:                      $pagination-active-bg !default;
+$pager-active-color:                   $pagination-active-color !default;
+
+$pager-disabled-color:                 $pagination-disabled-color !default;
+
+
+//== Jumbotron
+//
+//##
+
+$jumbotron-padding:              30px !default;
+$jumbotron-color:                inherit !default;
+$jumbotron-bg:                   $gray-lighter !default;
+$jumbotron-heading-color:        inherit !default;
+$jumbotron-font-size:            ceil(($font-size-base * 1.5)) !default;
+$jumbotron-heading-font-size:    ceil(($font-size-base * 4.5)) !default;
+
+
+//== Form states and alerts
+//
+//## Define colors for form feedback states and, by default, alerts.
+
+$state-success-text:             #3c763d !default;
+$state-success-bg:               #dff0d8 !default;
+$state-success-border:           darken(adjust-hue($state-success-bg, -10), 5%) !default;
+
+$state-info-text:                #31708f !default;
+$state-info-bg:                  #d9edf7 !default;
+$state-info-border:              darken(adjust-hue($state-info-bg, -10), 7%) !default;
+
+$state-warning-text:             #8a6d3b !default;
+$state-warning-bg:               #fcf8e3 !default;
+$state-warning-border:           darken(adjust-hue($state-warning-bg, -10), 5%) !default;
+
+$state-danger-text:              #a94442 !default;
+$state-danger-bg:                #f2dede !default;
+$state-danger-border:            darken(adjust-hue($state-danger-bg, -10), 5%) !default;
+
+
+//== Tooltips
+//
+//##
+
+//** Tooltip max width
+$tooltip-max-width:           200px !default;
+//** Tooltip text color
+$tooltip-color:               #fff !default;
+//** Tooltip background color
+$tooltip-bg:                  #000 !default;
+$tooltip-opacity:             .9 !default;
+
+//** Tooltip arrow width
+$tooltip-arrow-width:         5px !default;
+//** Tooltip arrow color
+$tooltip-arrow-color:         $tooltip-bg !default;
+
+
+//== Popovers
+//
+//##
+
+//** Popover body background color
+$popover-bg:                          #fff !default;
+//** Popover maximum width
+$popover-max-width:                   276px !default;
+//** Popover border color
+$popover-border-color:                rgba(0,0,0,.2) !default;
+//** Popover fallback border color
+$popover-fallback-border-color:       #ccc !default;
+
+//** Popover title background color
+$popover-title-bg:                    darken($popover-bg, 3%) !default;
+
+//** Popover arrow width
+$popover-arrow-width:                 10px !default;
+//** Popover arrow color
+$popover-arrow-color:                 $popover-bg !default;
+
+//** Popover outer arrow width
+$popover-arrow-outer-width:           ($popover-arrow-width + 1) !default;
+//** Popover outer arrow color
+$popover-arrow-outer-color:           fade_in($popover-border-color, 0.05) !default;
+//** Popover outer arrow fallback color
+$popover-arrow-outer-fallback-color:  darken($popover-fallback-border-color, 20%) !default;
+
+
+//== Labels
+//
+//##
+
+//** Default label background color
+$label-default-bg:            $gray-light !default;
+//** Primary label background color
+$label-primary-bg:            $brand-primary !default;
+//** Success label background color
+$label-success-bg:            $brand-success !default;
+//** Info label background color
+$label-info-bg:               $brand-info !default;
+//** Warning label background color
+$label-warning-bg:            $brand-warning !default;
+//** Danger label background color
+$label-danger-bg:             $brand-danger !default;
+
+//** Default label text color
+$label-color:                 #fff !default;
+//** Default text color of a linked label
+$label-link-hover-color:      #fff !default;
+
+
+//== Modals
+//
+//##
+
+//** Padding applied to the modal body
+$modal-inner-padding:         15px !default;
+
+//** Padding applied to the modal title
+$modal-title-padding:         15px !default;
+//** Modal title line-height
+$modal-title-line-height:     $line-height-base !default;
+
+//** Background color of modal content area
+$modal-content-bg:                             #fff !default;
+//** Modal content border color
+$modal-content-border-color:                   rgba(0,0,0,.2) !default;
+//** Modal content border color **for IE8**
+$modal-content-fallback-border-color:          #999 !default;
+
+//** Modal backdrop background color
+$modal-backdrop-bg:           #000 !default;
+//** Modal backdrop opacity
+$modal-backdrop-opacity:      .5 !default;
+//** Modal header border color
+$modal-header-border-color:   #e5e5e5 !default;
+//** Modal footer border color
+$modal-footer-border-color:   $modal-header-border-color !default;
+
+$modal-lg:                    900px !default;
+$modal-md:                    600px !default;
+$modal-sm:                    300px !default;
+
+
+//== Alerts
+//
+//## Define alert colors, border radius, and padding.
+
+$alert-padding:               15px !default;
+$alert-border-radius:         $border-radius-base !default;
+$alert-link-font-weight:      bold !default;
+
+$alert-success-bg:            $state-success-bg !default;
+$alert-success-text:          $state-success-text !default;
+$alert-success-border:        $state-success-border !default;
+
+$alert-info-bg:               $state-info-bg !default;
+$alert-info-text:             $state-info-text !default;
+$alert-info-border:           $state-info-border !default;
+
+$alert-warning-bg:            $state-warning-bg !default;
+$alert-warning-text:          $state-warning-text !default;
+$alert-warning-border:        $state-warning-border !default;
+
+$alert-danger-bg:             $state-danger-bg !default;
+$alert-danger-text:           $state-danger-text !default;
+$alert-danger-border:         $state-danger-border !default;
+
+
+//== Progress bars
+//
+//##
+
+//** Background color of the whole progress component
+$progress-bg:                 #f5f5f5 !default;
+//** Progress bar text color
+$progress-bar-color:          #fff !default;
+//** Variable for setting rounded corners on progress bar.
+$progress-border-radius:      $border-radius-base !default;
+
+//** Default progress bar color
+$progress-bar-bg:             $brand-primary !default;
+//** Success progress bar color
+$progress-bar-success-bg:     $brand-success !default;
+//** Warning progress bar color
+$progress-bar-warning-bg:     $brand-warning !default;
+//** Danger progress bar color
+$progress-bar-danger-bg:      $brand-danger !default;
+//** Info progress bar color
+$progress-bar-info-bg:        $brand-info !default;
+
+
+//== List group
+//
+//##
+
+//** Background color on `.list-group-item`
+$list-group-bg:                 #fff !default;
+//** `.list-group-item` border color
+$list-group-border:             #ddd !default;
+//** List group border radius
+$list-group-border-radius:      $border-radius-base !default;
+
+//** Background color of single list items on hover
+$list-group-hover-bg:           #f5f5f5 !default;
+//** Text color of active list items
+$list-group-active-color:       $component-active-color !default;
+//** Background color of active list items
+$list-group-active-bg:          $component-active-bg !default;
+//** Border color of active list elements
+$list-group-active-border:      $list-group-active-bg !default;
+//** Text color for content within active list items
+$list-group-active-text-color:  lighten($list-group-active-bg, 40%) !default;
+
+//** Text color of disabled list items
+$list-group-disabled-color:      $gray-light !default;
+//** Background color of disabled list items
+$list-group-disabled-bg:         $gray-lighter !default;
+//** Text color for content within disabled list items
+$list-group-disabled-text-color: $list-group-disabled-color !default;
+
+$list-group-link-color:         #555 !default;
+$list-group-link-hover-color:   $list-group-link-color !default;
+$list-group-link-heading-color: #333 !default;
+
+
+//== Panels
+//
+//##
+
+$panel-bg:                    #fff !default;
+$panel-body-padding:          15px !default;
+$panel-heading-padding:       10px 15px !default;
+$panel-footer-padding:        $panel-heading-padding !default;
+$panel-border-radius:         $border-radius-base !default;
+
+//** Border color for elements within panels
+$panel-inner-border:          #ddd !default;
+$panel-footer-bg:             #f5f5f5 !default;
+
+$panel-default-text:          $gray-dark !default;
+$panel-default-border:        #ddd !default;
+$panel-default-heading-bg:    #f5f5f5 !default;
+
+$panel-primary-text:          #fff !default;
+$panel-primary-border:        $brand-primary !default;
+$panel-primary-heading-bg:    $brand-primary !default;
+
+$panel-success-text:          $state-success-text !default;
+$panel-success-border:        $state-success-border !default;
+$panel-success-heading-bg:    $state-success-bg !default;
+
+$panel-info-text:             $state-info-text !default;
+$panel-info-border:           $state-info-border !default;
+$panel-info-heading-bg:       $state-info-bg !default;
+
+$panel-warning-text:          $state-warning-text !default;
+$panel-warning-border:        $state-warning-border !default;
+$panel-warning-heading-bg:    $state-warning-bg !default;
+
+$panel-danger-text:           $state-danger-text !default;
+$panel-danger-border:         $state-danger-border !default;
+$panel-danger-heading-bg:     $state-danger-bg !default;
+
+
+//== Thumbnails
+//
+//##
+
+//** Padding around the thumbnail image
+$thumbnail-padding:           4px !default;
+//** Thumbnail background color
+$thumbnail-bg:                $body-bg !default;
+//** Thumbnail border color
+$thumbnail-border:            #ddd !default;
+//** Thumbnail border radius
+$thumbnail-border-radius:     $border-radius-base !default;
+
+//** Custom text color for thumbnail captions
+$thumbnail-caption-color:     $text-color !default;
+//** Padding around the thumbnail caption
+$thumbnail-caption-padding:   9px !default;
+
+
+//== Wells
+//
+//##
+
+$well-bg:                     #f5f5f5 !default;
+$well-border:                 darken($well-bg, 7%) !default;
+
+
+//== Badges
+//
+//##
+
+$badge-color:                 #fff !default;
+//** Linked badge text color on hover
+$badge-link-hover-color:      #fff !default;
+$badge-bg:                    $gray-light !default;
+
+//** Badge text color in active nav link
+$badge-active-color:          $link-color !default;
+//** Badge background color in active nav link
+$badge-active-bg:             #fff !default;
+
+$badge-font-weight:           bold !default;
+$badge-line-height:           1 !default;
+$badge-border-radius:         10px !default;
+
+
+//== Breadcrumbs
+//
+//##
+
+$breadcrumb-padding-vertical:   8px !default;
+$breadcrumb-padding-horizontal: 15px !default;
+//** Breadcrumb background color
+$breadcrumb-bg:                 #f5f5f5 !default;
+//** Breadcrumb text color
+$breadcrumb-color:              #ccc !default;
+//** Text color of current page in the breadcrumb
+$breadcrumb-active-color:       $gray-light !default;
+//** Textual separator for between breadcrumb elements
+$breadcrumb-separator:          "/" !default;
+
+
+//== Carousel
+//
+//##
+
+$carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6) !default;
+
+$carousel-control-color:                      #fff !default;
+$carousel-control-width:                      15% !default;
+$carousel-control-opacity:                    .5 !default;
+$carousel-control-font-size:                  20px !default;
+
+$carousel-indicator-active-bg:                #fff !default;
+$carousel-indicator-border-color:             #fff !default;
+
+$carousel-caption-color:                      #fff !default;
+
+
+//== Close
+//
+//##
+
+$close-font-weight:           bold !default;
+$close-color:                 #000 !default;
+$close-text-shadow:           0 1px 0 #fff !default;
+
+
+//== Code
+//
+//##
+
+$code-color:                  #c7254e !default;
+$code-bg:                     #f9f2f4 !default;
+
+$kbd-color:                   #fff !default;
+$kbd-bg:                      #333 !default;
+
+$pre-bg:                      #f5f5f5 !default;
+$pre-color:                   $gray-dark !default;
+$pre-border-color:            #ccc !default;
+$pre-scrollable-max-height:   340px !default;
+
+
+//== Type
+//
+//##
+
+//** Horizontal offset for forms and lists.
+$component-offset-horizontal: 180px !default;
+//** Text muted color
+$text-muted:                  $gray-light !default;
+//** Abbreviations and acronyms border color
+$abbr-border-color:           $gray-light !default;
+//** Headings small color
+$headings-small-color:        $gray-light !default;
+//** Blockquote small color
+$blockquote-small-color:      $gray-light !default;
+//** Blockquote font size
+$blockquote-font-size:        ($font-size-base * 1.25) !default;
+//** Blockquote border color
+$blockquote-border-color:     $gray-lighter !default;
+//** Page header border color
+$page-header-border-color:    $gray-lighter !default;
+//** Width of horizontal description list titles
+$dl-horizontal-offset:        $component-offset-horizontal !default;
+//** Point at which .dl-horizontal becomes horizontal
+$dl-horizontal-breakpoint:    $grid-float-breakpoint !default;
+//** Horizontal line color.
+$hr-border:                   $gray-lighter !default;
diff --git a/app/scss/lib/bootstrap/_custom-bootstrap.scss b/app/scss/lib/bootstrap/_custom-bootstrap.scss
new file mode 100644
index 00000000..b32e1cdb
--- /dev/null
+++ b/app/scss/lib/bootstrap/_custom-bootstrap.scss
@@ -0,0 +1,50 @@
+@import "custom-bootstrap-vars";
+
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/mixins";
+
+// Reset and dependencies
+// @import "~bootstrap-sass/assets/stylesheets/bootstrap/normalize";
+// @import "~bootstrap-sass/assets/stylesheets/bootstrap/print";
+// @import "~bootstrap-sass/assets/stylesheets/bootstrap/glyphicons";
+
+// Core CSS
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/scaffolding";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/type";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/code";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/grid";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/tables";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/forms";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/buttons";
+
+// Components
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/component-animations";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/dropdowns";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/button-groups";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/input-groups";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/navs";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/navbar";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/breadcrumbs";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/pagination";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/pager";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/labels";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/badges";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/jumbotron";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/thumbnails";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/alerts";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/progress-bars";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/media";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/list-group";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/panels";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/responsive-embed";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/wells";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/close";
+
+// Components w/ JavaScript
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/modals";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/tooltip";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/popovers";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/carousel";
+
+// Utility classes
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/utilities";
+@import "~bootstrap-sass/assets/stylesheets/bootstrap/responsive-utilities";
diff --git a/app/scss/main.scss b/app/scss/main.scss
index bfcb26ba..43c413a6 100644
--- a/app/scss/main.scss
+++ b/app/scss/main.scss
@@ -1,4 +1,9 @@
 @import 'reset';
+
+// :::: Bootstrap Components :::: //
+@import "lib/bootstrap/custom-bootstrap";
+
+
 // @import 'vars';
 // :::: Base Styles :::: //
 
diff --git a/app/view/home/home.html b/app/view/home/home.html
index 07aaf4e3..13d93938 100644
--- a/app/view/home/home.html
+++ b/app/view/home/home.html
@@ -2,9 +2,14 @@
 
   
 
+  
+
   

Galleries