diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..b5441525 Binary files /dev/null and b/.DS_Store differ diff --git a/lab-yana/.babelrc b/lab-yana/.babelrc new file mode 100644 index 00000000..9d8d5165 --- /dev/null +++ b/lab-yana/.babelrc @@ -0,0 +1 @@ +{ "presets": ["es2015"] } diff --git a/lab-yana/.env b/lab-yana/.env new file mode 100644 index 00000000..2f02e4b0 --- /dev/null +++ b/lab-yana/.env @@ -0,0 +1 @@ +API_URL='http://localhost:3003' diff --git a/lab-yana/.eslintrc b/lab-yana/.eslintrc new file mode 100644 index 00000000..8dc68078 --- /dev/null +++ b/lab-yana/.eslintrc @@ -0,0 +1,21 @@ +{ + "rules": { + "no-console": "off", + "indent": [ "error", 2 ], + "quotes": [ "error", "single" ], + "semi": ["error", "always"], + "linebreak-style": [ "error", "unix" ] + }, + "env": { + "es6": true, + "node": true, + "mocha": true, + "jasmine": true + }, + "ecmaFeatures": { + "modules": true, + "experimentalObjectRestSpread": true, + "impliedStrict": true + }, + "extends": "eslint:recommended" +} diff --git a/lab-yana/.gitignore b/lab-yana/.gitignore new file mode 100644 index 00000000..20155648 --- /dev/null +++ b/lab-yana/.gitignore @@ -0,0 +1,120 @@ +# Created by https://www.gitignore.io/api/node,vim,osx,macos,linux + +*node_modules + +### Node ### +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# ignore angular build directory +build + +# 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 + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# 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 + + + +### Vim ### +# swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags + + +### 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 + + +### macOS ### +# Icon must end with two \r +# Thumbnails +# Files that might appear in the root of a volume +# Directories potentially created on remote AFP share + + +### Linux ### + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# End of https://www.gitignore.io/api/node,vim,osx,macos,linux diff --git a/lab-yana/app/component/gallery/create-gallery/_create-gallery.scss b/lab-yana/app/component/gallery/create-gallery/_create-gallery.scss new file mode 100644 index 00000000..3ae04e6e --- /dev/null +++ b/lab-yana/app/component/gallery/create-gallery/_create-gallery.scss @@ -0,0 +1,13 @@ +@import '../../../scss/lib/theme/_vars.scss'; + +.create-gallery { + img { + width: 25px; + } + button { + left: 254px; + padding-left: 30px; + padding-right: 30px; + border-radius: 7px; + } +} diff --git a/lab-yana/app/component/gallery/create-gallery/create-gallery.html b/lab-yana/app/component/gallery/create-gallery/create-gallery.html new file mode 100644 index 00000000..e7cae6d9 --- /dev/null +++ b/lab-yana/app/component/gallery/create-gallery/create-gallery.html @@ -0,0 +1,13 @@ + diff --git a/lab-yana/app/component/gallery/create-gallery/create-gallery.js b/lab-yana/app/component/gallery/create-gallery/create-gallery.js new file mode 100644 index 00000000..d0625f29 --- /dev/null +++ b/lab-yana/app/component/gallery/create-gallery/create-gallery.js @@ -0,0 +1,25 @@ +'use strict'; + +require('./_create-gallery.scss'); + +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() { + $log.debug('CreateGalleryController.createGallery'); + + galleryService.createGallery(this.gallery) + .then( () => { + this.gallery.name = null; + this.gallery.desc = null; + }); + }; +} diff --git a/lab-yana/app/component/gallery/edit-gallery/_edit-gallery.scss b/lab-yana/app/component/gallery/edit-gallery/_edit-gallery.scss new file mode 100644 index 00000000..f568c65e --- /dev/null +++ b/lab-yana/app/component/gallery/edit-gallery/_edit-gallery.scss @@ -0,0 +1,57 @@ +@import '../../../scss/lib/theme/_vars.scss'; + +.edit { + margin-top: -15px; + width: 100%; + background-color: $mainBackground; + input { + display: inline-block; + width: 67%; + margin-top: -5px; + color: #696969; + float: left; + font-size: 14px; + border-radius: 8px; + background-color: #B0B0B0; + padding-top: 3px; + padding-bottom: 3px; + margin-left: 5px; + border: 1px solid #606060; + } + + div { + width: 100%; + border-radius: 7px; + background-color: $footerBackground; + padding-bottom: 2px; + padding-top: 1px; + padding-right: 10px; + } + + button { + left: 152px; + font-size: 12px; + border-radius: 7px; + padding-right: 30px; + padding-left: 30px; + padding-top: 5px; + padding-bottom: 5px; + } + fieldset { + text-align: left; + } + fieldset:first-of-type { + input { + margin-top: 9px; + width: 78%; + } + .item-label { + margin-top: 14px; + } + } + .item-label { + font-weight: bold; + display: inline-block; + float: left; + } +} diff --git a/lab-yana/app/component/gallery/edit-gallery/edit-gallery.html b/lab-yana/app/component/gallery/edit-gallery/edit-gallery.html new file mode 100644 index 00000000..7440c2cd --- /dev/null +++ b/lab-yana/app/component/gallery/edit-gallery/edit-gallery.html @@ -0,0 +1,19 @@ +
+ +
+
+ name: + +
+
+ description: + +
+
+ + +
diff --git a/lab-yana/app/component/gallery/edit-gallery/edit-gallery.js b/lab-yana/app/component/gallery/edit-gallery/edit-gallery.js new file mode 100644 index 00000000..835ee4ce --- /dev/null +++ b/lab-yana/app/component/gallery/edit-gallery/edit-gallery.js @@ -0,0 +1,22 @@ +'use strict'; + +require('./_edit-gallery.scss'); + +module.exports = { + template: require('./edit-gallery.html'), + controller: ['$log', 'galleryService', EditGalleryController], + controllerAs: 'editGalleryCtrl', + bindings: { + gallery: '<' + } +}; + +function EditGalleryController($log, galleryService) { + $log.debug('EditGalleryController'); + + this.updateGallery = function() { + $log.debug('EditGalleryController.updateGallery'); + + galleryService.updateGallery(this.gallery._id, this.gallery); + }; +} diff --git a/lab-yana/app/component/gallery/gallery-item/_gallery-item.scss b/lab-yana/app/component/gallery/gallery-item/_gallery-item.scss new file mode 100644 index 00000000..e888f3f1 --- /dev/null +++ b/lab-yana/app/component/gallery/gallery-item/_gallery-item.scss @@ -0,0 +1,55 @@ +@import '../../../scss/lib/theme/_vars.scss'; + +.gallery-item { + display: block; + clear: both; + width: 98%; + background-color: $mainBackground; + + .current-item { + display: block; + text-align: left; + color: $highlightBackground; + background-color: $footerBackground; + border-radius: 7px; + padding-bottom: 62px; + span { + font-weight: bold; + display: inline-block; + float: left; + clear: left; + } + p { + display: inline-block; + font-weight: normal; + color: #696969; + float: left; + clear: right; + margin-left: 14px; + } + } + +} +.button-container { + display: block; + background-color: $mainBackground; + margin-top: 15px; + clear: right; + margin-bottom: 70px; + + button:first-of-type { + background-color: $highlightBackground; + color: $mainBackground; + margin-left: 10px; + } + button { + float: right; + font-size: 12px; + border-radius: 7px; + padding-right: 32px; + padding-left: 32px; + padding-top: 6px; + padding-bottom: 6px; + border: none; + } +} diff --git a/lab-yana/app/component/gallery/gallery-item/gallery-item.html b/lab-yana/app/component/gallery/gallery-item/gallery-item.html new file mode 100644 index 00000000..855b9b3b --- /dev/null +++ b/lab-yana/app/component/gallery/gallery-item/gallery-item.html @@ -0,0 +1,20 @@ + diff --git a/lab-yana/app/component/gallery/gallery-item/gallery-item.js b/lab-yana/app/component/gallery/gallery-item/gallery-item.js new file mode 100644 index 00000000..6f174bf2 --- /dev/null +++ b/lab-yana/app/component/gallery/gallery-item/gallery-item.js @@ -0,0 +1,23 @@ +'use strict'; + +require('./_gallery-item.scss'); + +module.exports = { + template: require('./gallery-item.html'), + controller: ['$log', 'galleryService', GalleryItemController], + controllerAs: 'galleryItemCtrl', + bindings: { + gallery: '<' + } +}; + +function GalleryItemController($log, galleryService) { + $log.debug('GalleryItemController'); + + this.showEdit = false; + this.deleteGallery = function() { + $log.debug('GalleryController.deleteGallery'); + + galleryService.deleteGallery(this.gallery._id); + }; +} diff --git a/lab-yana/app/component/gallery/thumbnail-container/_thumbnail-container.scss b/lab-yana/app/component/gallery/thumbnail-container/_thumbnail-container.scss new file mode 100644 index 00000000..5a485c76 --- /dev/null +++ b/lab-yana/app/component/gallery/thumbnail-container/_thumbnail-container.scss @@ -0,0 +1,5 @@ +.thumbnail-container { + display: block; + margin-top: -20vw; + padding-bottom: 7vw; +} diff --git a/lab-yana/app/component/gallery/thumbnail-container/thumbnail-container.html b/lab-yana/app/component/gallery/thumbnail-container/thumbnail-container.html new file mode 100644 index 00000000..be8732c3 --- /dev/null +++ b/lab-yana/app/component/gallery/thumbnail-container/thumbnail-container.html @@ -0,0 +1,7 @@ +
+
{{thumbnailContainerCtrl.gallery.name}}
+ +
+ +
+
diff --git a/lab-yana/app/component/gallery/thumbnail-container/thumbnail-container.js b/lab-yana/app/component/gallery/thumbnail-container/thumbnail-container.js new file mode 100644 index 00000000..18bf16d4 --- /dev/null +++ b/lab-yana/app/component/gallery/thumbnail-container/thumbnail-container.js @@ -0,0 +1,11 @@ +'use strict'; + +require('./_thumbnail-container.scss'); + +module.exports = { + template: require('./thumbnail-container.html'), + controllerAs: 'thumbnailContainerCtrl', + bindings: { + gallery: '<' + } +}; diff --git a/lab-yana/app/component/gallery/thumbnail/_thumbnail.scss b/lab-yana/app/component/gallery/thumbnail/_thumbnail.scss new file mode 100644 index 00000000..2ed3c14e --- /dev/null +++ b/lab-yana/app/component/gallery/thumbnail/_thumbnail.scss @@ -0,0 +1,17 @@ +.thumbnail { + img { + margin-top: 2vw; + width: 30vw; + height: 20vw; + margin-left: 6vw; + } + button { + font-size: 12px; + border-radius: 7px; + padding-right: 30px; + padding-left: 30px; + padding-top: 5px; + padding-bottom: 5px; + left: 32vw; + } +} diff --git a/lab-yana/app/component/gallery/thumbnail/thumbnail.html b/lab-yana/app/component/gallery/thumbnail/thumbnail.html new file mode 100644 index 00000000..11a08aa3 --- /dev/null +++ b/lab-yana/app/component/gallery/thumbnail/thumbnail.html @@ -0,0 +1,4 @@ +
+ {{thumbnailCtrl.pic.desc}} + +
diff --git a/lab-yana/app/component/gallery/thumbnail/thumbnail.js b/lab-yana/app/component/gallery/thumbnail/thumbnail.js new file mode 100644 index 00000000..c8cb4ea7 --- /dev/null +++ b/lab-yana/app/component/gallery/thumbnail/thumbnail.js @@ -0,0 +1,23 @@ +'use strict'; + +require('./_thumbnail.scss'); + +module.exports = { + template: require('./thumbnail.html'), + controller: ['$log', 'picService', ThumbnailController], + controllerAs: 'thumbnailCtrl', + bindings: { + pic: '<', + gallery: '<' + } +}; + +function ThumbnailController($log, picService) { + $log.debug('ThumbnailController'); + + this.deletePic = function() { + $log.debug('ThumbnailController.deletePic'); + + picService.deleteGalleryPic(this.gallery, this.pic); + }; +} diff --git a/lab-yana/app/component/gallery/upload-pic/_upload-pic.scss b/lab-yana/app/component/gallery/upload-pic/_upload-pic.scss new file mode 100644 index 00000000..a8c20179 --- /dev/null +++ b/lab-yana/app/component/gallery/upload-pic/_upload-pic.scss @@ -0,0 +1,35 @@ +.upload-pic { + display: block; + div { + article { + margin-top: 0; + text-align: center; + display: inline-block; + } + button { + display: inline-block; + } + float: right; + } + article { + text-decoration: underline; + margin-bottom: 1.3vw; + } + input { + width: 100%; + border-radius: 0.5vw; + padding: 0.7vw; + background-color: #B0B0B0; + color: white; + margin-bottom: 0; + } + button { + font-size: 12px; + border-radius: 7px; + padding-right: 30px; + padding-left: 30px; + padding-top: 5px; + padding-bottom: 5px; + left: 1.5vw; + } +} diff --git a/lab-yana/app/component/gallery/upload-pic/upload-pic.html b/lab-yana/app/component/gallery/upload-pic/upload-pic.html new file mode 100644 index 00000000..bc37bcf4 --- /dev/null +++ b/lab-yana/app/component/gallery/upload-pic/upload-pic.html @@ -0,0 +1,17 @@ +
+
+
upload a new pic:
+
+ + +
+
+
+ select an image to upload +
+ +
+
+
diff --git a/lab-yana/app/component/gallery/upload-pic/upload-pic.js b/lab-yana/app/component/gallery/upload-pic/upload-pic.js new file mode 100644 index 00000000..2e28186a --- /dev/null +++ b/lab-yana/app/component/gallery/upload-pic/upload-pic.js @@ -0,0 +1,29 @@ +'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() { + $log.debug('UploadPicController.uploadPic'); + + picService.uploadGalleryPic(this.gallery, this.pic) + .then( () => { + this.pic.name = null; + this.pic.desc = null; + this.pic.file = null; + }); + }; +} diff --git a/lab-yana/app/component/landing/login/_login.scss b/lab-yana/app/component/landing/login/_login.scss new file mode 100644 index 00000000..499c8c8a --- /dev/null +++ b/lab-yana/app/component/landing/login/_login.scss @@ -0,0 +1,41 @@ +@import '../../../scss/lib/theme/_vars.scss'; + +.login { + article { + color: $highlightBackground; + font-size: 14px; + padding-top: 30px; + } + form { + margin-right: 3%; + } +} + +.btn-std { + font-size: 14px; + border: 1px solid $highlightBackground; + border-radius: 2px; + padding-right: 45px; + padding-left: 45px; + padding-top: 10px; + padding-bottom: 10px; + margin-top: 14px; + margin-bottom: 10px; + color: $mainBackground; + background-color: $highlightBackground; + display: inline-block; + position: relative; + left: 265px; +} + +.input-std { + border-radius: 2px; + width: 100%; + padding-top: 10px; + padding-bottom: 10px; + padding-left: 10px; + margin-top: 10px; + margin-bottom: 10px; + color: $footerBackground; + border: 0.5px solid $footerBackground; +} diff --git a/lab-yana/app/component/landing/login/login.html b/lab-yana/app/component/landing/login/login.html new file mode 100644 index 00000000..ebbe200d --- /dev/null +++ b/lab-yana/app/component/landing/login/login.html @@ -0,0 +1,27 @@ +
+
sign in.
+
+
+ +
+
+ +
+ +
+
diff --git a/lab-yana/app/component/landing/login/login.js b/lab-yana/app/component/landing/login/login.js new file mode 100644 index 00000000..a46719fb --- /dev/null +++ b/lab-yana/app/component/landing/login/login.js @@ -0,0 +1,23 @@ +'use strict'; + +require('./_login.scss'); + +module.exports = { + template: require('./login.html'), + controller: ['$log', '$location', 'authService', LoginController], + controllerAs: 'loginCtrl' +}; + +function LoginController($log, $location, authService) { + $log.debug('LoginController'); + + authService.getToken() + .then( () => $location.url('/home')); + + this.login = function() { + $log.debug('LoginController.login'); + + authService.login(this.user) + .then( () => $location.url('/home')); + }; +} diff --git a/lab-yana/app/component/landing/signup/_signup.scss b/lab-yana/app/component/landing/signup/_signup.scss new file mode 100644 index 00000000..7df7525b --- /dev/null +++ b/lab-yana/app/component/landing/signup/_signup.scss @@ -0,0 +1,41 @@ +@import '../../../scss/lib/theme/_vars.scss'; + +// .signup { +// article { +// color: $highlightBackground; +// font-size: 14px; +// padding-top: 30px; +// } +// form { +// margin-right: 3%; +// } +// } +// +// .btn-std { +// font-size: 14px; +// border: 1px solid $highlightBackground; +// border-radius: 2px; +// padding-right: 45px; +// padding-left: 45px; +// padding-top: 10px; +// padding-bottom: 10px; +// margin-top: 14px; +// margin-bottom: 10px; +// color: $mainBackground; +// background-color: $highlightBackground; +// display: inline-block; +// position: relative; +// left: 265px; +// } +// +// .input-std { +// border-radius: 2px; +// width: 100%; +// padding-top: 10px; +// padding-bottom: 10px; +// padding-left: 10px; +// margin-top: 10px; +// margin-bottom: 10px; +// color: $footerBackground; +// border: 0.5px solid $footerBackground; +// } diff --git a/lab-yana/app/component/landing/signup/signup.html b/lab-yana/app/component/landing/signup/signup.html new file mode 100644 index 00000000..c73ad07c --- /dev/null +++ b/lab-yana/app/component/landing/signup/signup.html @@ -0,0 +1,22 @@ +
+
sign up.
+
+ + + + +
+
diff --git a/lab-yana/app/component/landing/signup/signup.js b/lab-yana/app/component/landing/signup/signup.js new file mode 100644 index 00000000..27853b91 --- /dev/null +++ b/lab-yana/app/component/landing/signup/signup.js @@ -0,0 +1,23 @@ +'use strict'; + +require('./_signup.scss'); + +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('SignupController.signup'); + + authService.signup(user) + .then( () => $location.url('/home')); + }; +} diff --git a/lab-yana/app/component/navbar/_navbar.scss b/lab-yana/app/component/navbar/_navbar.scss new file mode 100644 index 00000000..66f1d82a --- /dev/null +++ b/lab-yana/app/component/navbar/_navbar.scss @@ -0,0 +1,32 @@ +@import '../../scss/lib/theme/_vars.scss'; + +.smallButt { + display: inline-block; + background-color: $mainBackground; + border: 0.5px solid $mainBackground; + border-radius: 6px; + font-size: 11px; + color: $highlightBackground; + padding-left: 8px; + padding-right: 8px; + padding-top: 1.5px; + padding-bottom: 3px; + margin-top: 20px; + margin-right: 20px; +} + +.navbar { + width: 100%; + ul, div, nav { + display: inline-block; + } + nav { + float: right; + } + div { + float: right; + } + img { + width: 25px; + } +} diff --git a/lab-yana/app/component/navbar/navbar.html b/lab-yana/app/component/navbar/navbar.html new file mode 100644 index 00000000..2217f5d4 --- /dev/null +++ b/lab-yana/app/component/navbar/navbar.html @@ -0,0 +1,11 @@ + diff --git a/lab-yana/app/component/navbar/navbar.js b/lab-yana/app/component/navbar/navbar.js new file mode 100644 index 00000000..37d7d595 --- /dev/null +++ b/lab-yana/app/component/navbar/navbar.js @@ -0,0 +1,33 @@ +'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() { + $log.debug('NavbarController.checkPath'); + let path = $location.path(); + if (path === '/join') this.hideBtn = true; + if (path !== '/join') this.hideBtn = false; + + authService.getToken() + .catch( () => $location.url('/join#login')); //if there is no token, that means user is not signed in, take them to log in screen + }; + + this.checkPath(); + $rootScope.$on('$locationChangeSuccess', () => this.checkPath()) //any time the location changes, check the path to determine whether or not to display the logout button + + this.logout = function () { + $log.debug('NavbarController.logout'); + this.hideBtn = true; + authService.logout() + .then( () => $location.url('/')); //after running the logout method from the auth Service, which removes token from local storage, take user to landing view + }; +} diff --git a/lab-yana/app/config/log-config.js b/lab-yana/app/config/log-config.js new file mode 100644 index 00000000..01068985 --- /dev/null +++ b/lab-yana/app/config/log-config.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = ['$logProvider', logConfig]; + +function logConfig($logProvider) { + $logProvider.debugEnabled(__DEBUG__); +} diff --git a/lab-yana/app/config/router-config.js b/lab-yana/app/config/router-config.js new file mode 100644 index 00000000..f7e5188d --- /dev/null +++ b/lab-yana/app/config/router-config.js @@ -0,0 +1,28 @@ +'use strict'; + +module.exports = ['$stateProvider', '$urlRouterProvider', routerConfig]; + +function routerConfig($stateProvider, $urlRouterProvider) { + $urlRouterProvider.when('', '/join#signup'); + $urlRouterProvider.when('/', '/join#signup'); + $urlRouterProvider.when('/signup', '/join#signup'); + $urlRouterProvider.when('/login', '/join#login'); + + let states = [ + { + name: 'home', + url: '/home', + template: require('../view/home/home.html'), + controller: 'HomeController', + controllerAs: 'homeCtrl' + }, + { + name: 'landing', + url: '/join', + template: require('../view/landing/landing.html'), + controller: 'LandingController', + controllerAs: 'landingCtrl' + } + ]; + states.forEach(state => $stateProvider.state(state)); +} diff --git a/lab-yana/app/directive/_social-icons.scss b/lab-yana/app/directive/_social-icons.scss new file mode 100644 index 00000000..3ac3127b --- /dev/null +++ b/lab-yana/app/directive/_social-icons.scss @@ -0,0 +1,51 @@ +.iconz { + padding-left: 5%; + li { + display: inline-block; + transform: scale(0.3); + width: 7vw; + height: 7vw; + } +} + +.instagram { + background: url('../../assets/social-icons.png') no-repeat -312px -7px; + width: 80px; + height: 81px; +} + +.youtube { + background: url('../../assets/social-icons.png') no-repeat -216px -8px; + width: 64px; + height: 80px; +} + +.twitter { + background: url('../../assets/social-icons.png') no-repeat -112px -16px; + width: 80px; + height: 64px; +} + +.in { + background: url('../../assets/social-icons.png') no-repeat -415px -12px; + width: 71px; + height: 71px; +} + +.t { + background: url('../../assets/social-icons.png') no-repeat -527px -13px; + width: 45px; + height: 70px; +} + +.google-plus { + background: url('../../assets/social-icons.png') no-repeat -620px -15px; + width: 67px; + height: 68px; +} + +.fb { + background: url('../../assets/social-icons.png') no-repeat -37px -13px; + width: 34px; + height: 69px; +} diff --git a/lab-yana/app/directive/social-icons.html b/lab-yana/app/directive/social-icons.html new file mode 100644 index 00000000..a2b85992 --- /dev/null +++ b/lab-yana/app/directive/social-icons.html @@ -0,0 +1,5 @@ + diff --git a/lab-yana/app/directive/social-icons.js b/lab-yana/app/directive/social-icons.js new file mode 100644 index 00000000..cc9f4733 --- /dev/null +++ b/lab-yana/app/directive/social-icons.js @@ -0,0 +1,21 @@ +'use strict'; + +require('./_social-icons.scss'); + +module.exports = function() { + return { + restrict: 'EAC', + template: require('./social-icons.html'), + controller: ['$log', SocialIconsController], + bindToController: true, + controllerAs: 'socialIconsCtrl', + scope: { + cssClass: '@' + } + }; +}; + +function SocialIconsController($log) { + $log.debug('SocialIconsController'); + this.icons = ['fb', 'twitter', 'youtube', 'instagram', 'in', 't', 'google-plus']; +} diff --git a/lab-yana/app/entry.js b/lab-yana/app/entry.js new file mode 100644 index 00000000..bfc878ae --- /dev/null +++ b/lab-yana/app/entry.js @@ -0,0 +1,52 @@ +'use strict'; + +require('./scss/main.scss'); + +const path = require('path'); +const angular = require('angular'); +const pascalcase = require('pascalcase'); +const camelcase = require('camelcase'); +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, ngFileUpload]); + +let context = require.context('./config/', true, /\.js$/); +context.keys().forEach(key => cfgram.config(context(key))); + +context = require.context('./view/', true, /\.js$/), +context.keys().forEach(key => { + let name = pascalcase(path.basename(key, '.js')); + let module = context(key); + cfgram.controller(name, module); +}); + +context = require.context('./service/', true, /\.js$/), +context.keys().forEach(key => { + let name = camelcase(path.basename(key, '.js')); + let module = context(key); + cfgram.service(name, module); +}); + +context = require.context('./component/', true, /\.js$/), +context.keys().forEach(key => { + let name = camelcase(path.basename(key, '.js')); + let module = context(key); + cfgram.component(name, module); +}); + +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/lab-yana/app/filter/date-filter.js b/lab-yana/app/filter/date-filter.js new file mode 100644 index 00000000..e69de29b diff --git a/lab-yana/app/filter/gallery-filter.js b/lab-yana/app/filter/gallery-filter.js new file mode 100644 index 00000000..17b1d35a --- /dev/null +++ b/lab-yana/app/filter/gallery-filter.js @@ -0,0 +1,16 @@ +'use strict'; + +module.exports = function() { + return function(galleries, searchTerm) { + let fuzzyRegex = makeFuzzyRegex(searchTerm); + return galleries.filter(gallery => { + return fuzzyRegex.test(gallery.name.toUpperCase()) || fuzzyRegex.test(gallery.desc.toUpperCase()); + }); + }; +}; + +function makeFuzzyRegex(input) { + if (!input) return /.*/; + let fuzzyString = '.*' + input.toUpperCase().split('').join('.*') + '.*'; + return new RegExp(fuzzyString); +} diff --git a/lab-yana/app/index.html b/lab-yana/app/index.html new file mode 100644 index 00000000..e41df85e --- /dev/null +++ b/lab-yana/app/index.html @@ -0,0 +1,21 @@ + + + + + + cfgram + + +
+ +
+ +
+ +
+ + + + diff --git a/lab-yana/app/scss/lib/base/_base.scss b/lab-yana/app/scss/lib/base/_base.scss new file mode 100644 index 00000000..b7169638 --- /dev/null +++ b/lab-yana/app/scss/lib/base/_base.scss @@ -0,0 +1,12 @@ +@import '../theme/_vars.scss'; + +body { + margin: auto; +} + +li { + margin-left: 5px; + display: inline-block; + text-align: center; + vertical-align: middle; +} diff --git a/lab-yana/app/scss/lib/base/_reset.scss b/lab-yana/app/scss/lib/base/_reset.scss new file mode 100644 index 00000000..ed11813c --- /dev/null +++ b/lab-yana/app/scss/lib/base/_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/lab-yana/app/scss/lib/bootstrap/_custom-bootstrap-vars.scss b/lab-yana/app/scss/lib/bootstrap/_custom-bootstrap-vars.scss new file mode 100644 index 00000000..e69de29b diff --git a/lab-yana/app/scss/lib/bootstrap/_custom-bootstrap.scss b/lab-yana/app/scss/lib/bootstrap/_custom-bootstrap.scss new file mode 100644 index 00000000..e69de29b diff --git a/lab-yana/app/scss/lib/layout/_layout.scss b/lab-yana/app/scss/lib/layout/_layout.scss new file mode 100644 index 00000000..06023889 --- /dev/null +++ b/lab-yana/app/scss/lib/layout/_layout.scss @@ -0,0 +1,121 @@ +@import '../theme/_vars.scss'; + +body { + margin-top: 45px; + width: 435px; + height: 810px; + font-family: $fontStyle; +} + +header { + width: 100%; + color: $white; + background-color: $highlightBackground; + font-size: 18px; + ul { + padding: 15px; + } +} + +main { + background-color: $mainBackground; + width: 433px; + border-left: 1px solid $footerBackground; + border-right: 1px solid $footerBackground; + article { + color: $highlightBackground; + font-size: 14px; + padding-top: 30px; + } + form { + margin-right: 3%; + } + + .btn-std { + font-size: 14px; + border: 1px solid $highlightBackground; + border-radius: 2px; + padding-right: 45px; + padding-left: 45px; + padding-top: 10px; + padding-bottom: 10px; + margin-top: 14px; + margin-bottom: 10px; + color: $mainBackground; + background-color: $highlightBackground; + display: inline-block; + position: relative; + left: 265px; + } + + .input-std { + border-radius: 2px; + width: 100%; + padding-top: 10px; + padding-bottom: 10px; + padding-left: 10px; + margin-top: 10px; + margin-bottom: 10px; + color: $footerBackground; + border: 0.5px solid $footerBackground; + } +} + +footer { + width: 100%; + background-color: $footerBackground; + padding-top: 25px; + padding-bottom: 25px; +} + +.iconz { + li { + display: inline-block; + width: 5.8vw; + height: 5.4vw; + transform: scale(0.3); + margin: -1vw -1.8vw; + } +} + +.instagram { + background: url('../../assets/social-icons.png') no-repeat -312px -7px; + width: 80px; + height: 81px; +} + +.youtube { + background: url('../../assets/social-icons.png') no-repeat -216px -8px; + width: 64px; + height: 80px; +} + +.twitter { + background: url('../../assets/social-icons.png') no-repeat -112px -16px; + width: 80px; + height: 64px; +} + +.in { + background: url('../../assets/social-icons.png') no-repeat -415px -12px; + width: 71px; + height: 71px; +} + +.t { + background: url('../../assets/social-icons.png') no-repeat -527px -13px; + width: 45px; + height: 70px; +} + +.google-plus { + background: url('../../assets/social-icons.png') no-repeat -620px -15px; + width: 67px; + height: 68px; +} + +.fb { + background: url('../../assets/social-icons.png') no-repeat -37px -13px; + width: 34px; + height: 69px; +} diff --git a/lab-yana/app/scss/lib/theme/_vars.scss b/lab-yana/app/scss/lib/theme/_vars.scss new file mode 100644 index 00000000..5c142cfc --- /dev/null +++ b/lab-yana/app/scss/lib/theme/_vars.scss @@ -0,0 +1,5 @@ +$mainBackground: #d8d8d8; +$highlightBackground: #4a4a4a; +$footerBackground: #9b9b9b; +$white: #fff; +$fontStyle: Verdana; diff --git a/lab-yana/app/scss/main.scss b/lab-yana/app/scss/main.scss new file mode 100644 index 00000000..0d698e36 --- /dev/null +++ b/lab-yana/app/scss/main.scss @@ -0,0 +1,3 @@ +@import './lib/base/_reset.scss'; +@import './lib/base/_base.scss'; +@import './lib/layout/_layout.scss'; diff --git a/lab-yana/app/service/auth-service.js b/lab-yana/app/service/auth-service.js new file mode 100644 index 00000000..91214fbc --- /dev/null +++ b/lab-yana/app/service/auth-service.js @@ -0,0 +1,81 @@ +'use strict'; + +module.exports = ['$q', '$log', '$http', '$window', authService]; + +function authService($q, $log, $http, $window) { + $log.debug('authService'); + + let service = {}; + let token = null; + + function setToken(_token) { + $log.debug('authService.setToken'); + if (!_token) return $q.reject(new Error('no token')); + + $window.localStorage.setItem('token', _token); + token = _token; + return $q.resolve(token); + } + + service.getToken = function() { + $log.debug('authService.getToken'); + + if (token) return $q.resolve(token); //if there is already a token, don't bother with the rest of the function + token = $window.localStorage.getItem('token'); //find the token variable in local storage + if (token) return $q.resolve(token); //return the token found + return $q.reject(new Error('token not found')); //in case there is no token var in local storage + }; + + service.signup = function(user) { + $log.debug('authService.signup'); + + let url = `${__API_URL__}/api/signup`; + let config = { + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + } + }; + + return $http.post(url, user, config) + .then(response => { + $log.log('success: ', response.data); + return setToken(response.data); + }) + .catch(err => { + $log.error('failure: ', err.message); + return $q.reject(new Error('signup failed')); + }); + }; + + service.login = function(user) { + $log.debug('authService.login'); + + let url = `${__API_URL__}/api/login`; + let base64 = $window.btoa(`${user.username}:${user.password}`); + let config = { + headers: { + Accept: 'application/json', + Authorization: `Basic ${base64}` + } + }; + return $http.get(url, config) + .then(response => { + $log.log('success:', response.data); + return setToken(response.data); + }) + .catch(err => { + $log.error('failure', err.message); + return $q.reject(new Error('login failed')); + }); + }; + + service.logout = function() { + $log.debug('authService.logout'); + + $window.localStorage.removeItem('token'); + token = null; + return $q.resolve(); + }; + return service; +} diff --git a/lab-yana/app/service/gallery-service.js b/lab-yana/app/service/gallery-service.js new file mode 100644 index 00000000..eee57d77 --- /dev/null +++ b/lab-yana/app/service/gallery-service.js @@ -0,0 +1,122 @@ +'use strict'; + +module.exports = ['$q', '$log', '$http', 'authService', galleryService]; + +function galleryService($q, $log, $http, authService) { + $log.debug('galleryService'); + + let service = {}; + service.galleries = []; + + service.createGallery = function(gallery) { + $log.debug('galleryService.createGallery'); + + return authService.getToken() + .then(token => { + let url = `${__API_URL__}/api/gallery`; + let config = { + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }; + return $http.post(url, gallery, config); + }) + .then(response => { + $log.log('gallery created'); + let gallery = response.data; + service.galleries.unshift(gallery); + return gallery; + }) + .catch(err => { + $log.error(err.message); + return $q.reject(err); + }); + } + + service.fetchGalleries = function() { + $log.debug('galleryService.fetchGalleries'); + + return authService.getToken() + .then(token => { + let url = `${__API_URL__}/api/gallery`; + let config = { + headers: { + Authorization: `Bearer ${token}`, + Accept: 'application/json' + } + }; + return $http.get(url, config); + }) + .then(response => { + $log.log('galleries fetched'); + service.galleries = response.data; + return service.galleries; + }) + .catch(err => { + $log.error(err.message); + return $q.reject(err); + }); + }; + + service.deleteGallery = function(galleryID) { + $log.debug('galleryService.deleteGalleries'); + + authService.getToken() + .then(token => { + let url = `${__API_URL__}/api/gallery/${galleryID}`; + let config = { + headers: { + Authorization: `Bearer ${token}`, + Accept: 'application/json' + } + }; + return $http.delete(url, config); + }) + .then( () => { + $log.log('gallery removed'); + service.galleries.some((gallery, index) => { + if (gallery._id === galleryID) { + service.galleries.splice(index, 1); + return true; + } + }); + }) + .catch(err => { + $log.error(err.message); + return $q.reject(err); + }); + }; + + service.updateGallery = function(galleryID, galleryData) { + $log.debug('galleryService.updateGallery'); + + authService.getToken() + .then(token => { + let url = `${__API_URL__}/api/gallery/${galleryID}`; + let config = { + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + Accept: 'application/json' + } + }; + return $http.put(url, galleryData, config); + }) + .then(response => { + $log.log('gallery updated'); + service.galleries.some((gallery, index) => { + if (gallery._id === galleryID) { + service.galleries[index] = response.data; + return true; + } + }); + }) + .catch(err => { + $log.error(err.message); + return $q.reject(err); + }); + } + return service; +} diff --git a/lab-yana/app/service/pic-service.js b/lab-yana/app/service/pic-service.js new file mode 100644 index 00000000..b5c71091 --- /dev/null +++ b/lab-yana/app/service/pic-service.js @@ -0,0 +1,67 @@ +'use strict'; + +module.exports = ['$q', '$log', '$http', 'Upload', 'authService', picService]; + +function picService($q, $log, $http, Upload, authService) { + $log.debug('picService'); + + let service = {}; + + service.uploadGalleryPic = function(galleryData, picData) { + $log.debug('picService.uploadGalleryPic'); + + return authService.getToken() + .then(token => { + let url = `${__API_URL__}/api/gallery/${galleryData._id}/pic`; + let headers = { + Authorization: `Bearer ${token}`, + Accept: 'application/json' + }; + return Upload.upload({ + url, + headers, + method: 'POST', + data: { + name: picData.name, + desc: picData.desc, + file: picData.file + } + }); + }) + .then(response => { + $log.debug('galleryData', galleryData); + galleryData.pics.unshift(response.data); + $log.debug('galleryData.pics', galleryData.pics); + return response.data; + }) + .catch(err => { + $log.error(err.message); + return $q.reject(err); + }); + }; + + service.deleteGalleryPic = function(galleryData, picData) { + $log.debug('picService.deleteGalleryPic'); + + return authService.getToken() + .then(token => { + let url = `${__API_URL__}/api/gallery/${galleryData._id}/pic/${picData._id}`; + let config = { + headers: { Authorization: `Bearer ${token}` } + }; + return $http.delete(url, config); + }) + .then( () => { + $log.log('photo deleted'); + galleryData.pics.splice(galleryData.pics.indexOf(picData), 1); + return; + }) + .catch(err => { + $log.error(err.message); + return $q.reject(err); + }); + }; + + + return service; +} diff --git a/lab-yana/app/view/home/_home.scss b/lab-yana/app/view/home/_home.scss new file mode 100644 index 00000000..1ef4d5c6 --- /dev/null +++ b/lab-yana/app/view/home/_home.scss @@ -0,0 +1,45 @@ +@import '../../scss/lib/theme/_vars.scss'; + +.update-gallery { + width: 95%; + button { + left: 210px; + padding-left: 30px; + padding-right: 30px; + border-radius: 7px; + } +} + +.container { + width: 94%; + margin: auto; + ul { + padding-bottom: 200px; + article { + margin-top: 30px; + margin-bottom: 20px; + margin-left: 5px; + } + } + li { + display: block; + width: 98%; + background-color: $footerBackground; + color: $highlightBackground; + border-radius: 7px; + font-size: 14px; + font-weight: normal; + padding-top: 15px; + margin-bottom: 20px; + span { + display: block; + text-align: left; + padding-left: 15px; + padding-bottom: 15px; + p { + display: inline; + font-weight: bold; + } + } + } +} diff --git a/lab-yana/app/view/home/home-controller.js b/lab-yana/app/view/home/home-controller.js new file mode 100644 index 00000000..d6a32363 --- /dev/null +++ b/lab-yana/app/view/home/home-controller.js @@ -0,0 +1,28 @@ +'use strict'; + +require('./_home.scss'); + +module.exports = ['$log', '$rootScope', 'galleryService', HomeController]; + +function HomeController($log, $rootScope, galleryService) { + $log.debug('HomeController'); + + this.galleries = []; + + this.fetchGalleries = function() { + $log.debug('HomeController.fetchGalleries'); + + galleryService.fetchGalleries() + .then(galleries => this.galleries = galleries); + }; + + this.galleryDeleteDone = function(gallery) { + $log.debug('HomeController.galleryDeleteDone', gallery); + + if (this.currentGallery._id === gallery._id) this.currentGallery = null; + }; + + this.fetchGalleries(); + $rootScope.$on('$locationChangeSuccess', () => this.fetchGalleries()); + +} diff --git a/lab-yana/app/view/home/home.html b/lab-yana/app/view/home/home.html new file mode 100644 index 00000000..fb25678c --- /dev/null +++ b/lab-yana/app/view/home/home.html @@ -0,0 +1,16 @@ +
+
+ + + + +
+
diff --git a/lab-yana/app/view/landing/_landing.scss b/lab-yana/app/view/landing/_landing.scss new file mode 100644 index 00000000..051d7b0f --- /dev/null +++ b/lab-yana/app/view/landing/_landing.scss @@ -0,0 +1,26 @@ +@import '../../scss/lib/theme/_vars.scss'; + +.landing { + font-size: 13px; + padding-bottom: 396px; + p { + display: inline-block; + color: #888888; + text-align: right; + position: relative; + left: 180px; + } + a { + font-weight: bolder; + display: inline-block; + color: $highlightBackground; + text-decoration: none; + text-align: right; + float: right; + } +} + +.join-container { + width: 94%; + margin: auto; +} diff --git a/lab-yana/app/view/landing/landing-controller.js b/lab-yana/app/view/landing/landing-controller.js new file mode 100644 index 00000000..bade1abf --- /dev/null +++ b/lab-yana/app/view/landing/landing-controller.js @@ -0,0 +1,12 @@ +'use strict'; + +require('./_landing.scss'); + +module.exports = ['$log', '$location', '$rootScope', 'authService', LandingController]; + +function LandingController($log, $location, authService) { + $log.debug('LandingController'); + + let url = $location.url(); + this.showSignup = url === '/join#signup' || url === '/join'; +} diff --git a/lab-yana/app/view/landing/landing.html b/lab-yana/app/view/landing/landing.html new file mode 100644 index 00000000..9de6b52b --- /dev/null +++ b/lab-yana/app/view/landing/landing.html @@ -0,0 +1,16 @@ +
+
+
+ +

already a member?

+ sign in here. +
+
+
+
+ +

want to sign up?

+ sign up here. +
+
+
diff --git a/lab-yana/assets/clean-social-icons.jpg b/lab-yana/assets/clean-social-icons.jpg new file mode 100644 index 00000000..dfef78a2 Binary files /dev/null and b/lab-yana/assets/clean-social-icons.jpg differ diff --git a/lab-yana/assets/logo.png b/lab-yana/assets/logo.png new file mode 100644 index 00000000..38a23b2d Binary files /dev/null and b/lab-yana/assets/logo.png differ diff --git a/lab-yana/assets/social-icons.jpg b/lab-yana/assets/social-icons.jpg new file mode 100644 index 00000000..bf40778d Binary files /dev/null and b/lab-yana/assets/social-icons.jpg differ diff --git a/lab-yana/assets/social-icons.png b/lab-yana/assets/social-icons.png new file mode 100644 index 00000000..52cffe36 Binary files /dev/null and b/lab-yana/assets/social-icons.png differ diff --git a/lab-yana/karma.conf.js b/lab-yana/karma.conf.js new file mode 100644 index 00000000..765179e5 --- /dev/null +++ b/lab-yana/karma.conf.js @@ -0,0 +1,79 @@ +// Karma configuration +// Generated on Wed Mar 22 2017 12:51:00 GMT-0700 (PDT) + +const webpack = require('./webpack.config.js'); +delete webpack.entry; + +module.exports = function(config) { + config.set({ + + // to wire to webpack + webpack, + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '', + + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['jasmine'], + + + // list of files / patterns to load in the browser + files: [ + 'app/entry.js', + 'test/**/*-test.js', + 'node_modules/angular-mocks/angular-mocks.js' + ], + + + // list of files to exclude + exclude: [ + ], + + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + 'test/**/*-test.js': ['webpack'], + 'app/entry.js': ['webpack'] + }, + + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['mocha'], + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['Chrome'], + + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: false, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: Infinity + }); +}; diff --git a/lab-yana/package.json b/lab-yana/package.json new file mode 100644 index 00000000..d898227c --- /dev/null +++ b/lab-yana/package.json @@ -0,0 +1,57 @@ +{ + "name": "lab-yana", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "./node_modules/webpack/bin/webpack.js", + "build-watch": "./node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot", + "lint": "./node_modules/eslint/bin/eslint.js **/*.js", + "test": "./node_modules/karma/bin/karma start --single-run", + "test-watch": "./node_modules/karma/bin/karma start" + }, + "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-bootstrap": "^2.5.0", + "angular-ui-router": "^0.4.2", + "babel-core": "^6.24.0", + "babel-loader": "^6.4.1", + "babel-preset-es2015": "^6.24.0", + "bootstrap-sass": "^3.3.7", + "camelcase": "^3.0.0", + "clean-webpack-plugin": "^0.1.16", + "css-loader": "^0.27.3", + "dotenv": "^4.0.0", + "eslint": "^3.18.0", + "extract-text-webpack-plugin": "^2.1.0", + "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", + "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": { + "angular-mocks": "^1.6.4", + "camelcase": "^3.0.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/lab-yana/test/auth-service-test.js b/lab-yana/test/auth-service-test.js new file mode 100644 index 00000000..24350431 --- /dev/null +++ b/lab-yana/test/auth-service-test.js @@ -0,0 +1,22 @@ +'use strict'; + +describe('Auth Service', function() { + beforeEach(() => { + angular.mock.module('cfgram'); + angular.mock.inject(($rootScope, authService, $window) => { + this.$rootScope = $rootScope; + this.authService = authService; + this.$window = $window; + }); + }); + describe('authService.getToken', () => { + it('should return a token', () => { + this.authService.token = null; + this.$window.localStorage.setItem('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/lab-yana/test/edit-gallery-component-test.js b/lab-yana/test/edit-gallery-component-test.js new file mode 100644 index 00000000..4aee2e89 --- /dev/null +++ b/lab-yana/test/edit-gallery-component-test.js @@ -0,0 +1,48 @@ +'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 bindings = { + gallery: { + name: 'test gallery name', + desc: 'test gallery description' + } + }; + let editGalleryCtrl = this.$componentController('editGallery', null, bindings); + expect(editGalleryCtrl.gallery.name).toEqual(bindings.gallery.name); + expect(editGalleryCtrl.gallery.desc).toEqual(bindings.gallery.desc); + this.$rootScope.$apply(); + }); + describe('editGalleryCtrl.updateGallery()', () => { + it('should make a valid PUT request', () => { + let url = 'http://localhost:3003/api/gallery/4242'; + let headers = { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: 'Bearer test token' + }; + let tempGallery = { + _id: '4242', + name: 'updated name', + desc: 'updated desc' + }; + this.$httpBackend.expectPUT(url, tempGallery, headers).respond(200); + + let bindings = { gallery: tempGallery }; + let editGalleryCtrl = this.$componentController('editGallery', null, bindings); + editGalleryCtrl.updateGallery(); + expect(editGalleryCtrl.gallery.name).toEqual('updated name'); + expect(editGalleryCtrl.gallery.desc).toEqual('updated desc'); + this.$rootScope.$apply(); + }); + }) +}); diff --git a/lab-yana/test/gallery-item-component-test.js b/lab-yana/test/gallery-item-component-test.js new file mode 100644 index 00000000..6ef7f433 --- /dev/null +++ b/lab-yana/test/gallery-item-component-test.js @@ -0,0 +1,82 @@ +'use strict'; + +describe('Gallery Item 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; + }); + }); + describe('galleryItemCtrl.deleteDone()', () => { + it('should call deleteDone', () => { + let bindings = { + gallery: { + _id: '4242', + name: 'test gallery name', + desc: 'test gallery description', + pics: [], + }, + deleteDone: function(data) { + expect(data.galleryData._id).toEqual('4242'); + } + }; + let galleryItemCtrl = this.$componentController('galleryItem', null, bindings); + galleryItemCtrl.deleteDone({ galleryData: galleryItemCtrl.gallery }); + + this.$rootScope.$apply(); + }); + }); + it('should call deleteDone with gallery after deleteGallery', () => { + let url = 'http://localhost:3003/api/gallery/4242'; + let headers = { + Accept: 'application/json', + Authorization: 'Bearer test token' + }; + let tempGallery = { + _id: '4242', + name: 'test name', + desc: 'test desc' + }; + let bindings = { + gallery: tempGallery, + deleteDone: function(data) { + expect(data.galleryData._id).toEqual('4242'); + } + }; + this.$httpBackend.expectDELETE(url, headers).respond(204); + let galleryItemCtrl = this.$componentController('galleryItem', null, bindings); + // spyOn(galleryItemCtrl, 'deleteDone'); + galleryItemCtrl.deleteGallery('4242'); + // expect(galleryItemCtrl.deleteDone).toHaveBeenCalledWith('4242'); + this.$httpBackend.flush(); + this.$rootScope.$apply(); + }); + describe('galleryItemCtrl.deleteGallery()', () => { + it('should make a valid DELETE request', () => { + let url = 'http://localhost:3003/api/gallery/4242'; + let headers = { + Accept: 'application/json', + Authorization: 'Bearer test token' + }; + let tempGallery = { + _id: '4242', + name: 'test name', + desc: 'test desc' + }; + let bindings = { + gallery: tempGallery, + deleteDone: function(data) { + expect(data.galleryData._id).toEqual('4242'); + } + }; + this.$httpBackend.expectDELETE(url, headers).respond(204); + let galleryItemCtrl = this.$componentController('galleryItem', null, bindings); + galleryItemCtrl.deleteGallery(tempGallery._id) + this.$httpBackend.flush(); + this.$rootScope.$apply(); + }); +}); +}); diff --git a/lab-yana/test/gallery-service-test.js b/lab-yana/test/gallery-service-test.js new file mode 100644 index 00000000..193967cb --- /dev/null +++ b/lab-yana/test/gallery-service-test.js @@ -0,0 +1,46 @@ +'use strict'; + +describe('Gallery Service', function() { + beforeEach(() => { + angular.mock.module('cfgram'); + angular.mock.inject(($rootScope, authService, galleryService, $window, $httpBackend) => { + this.$rootScope = $rootScope; + this.authService = authService; + this.galleryService = galleryService; + this.$httpBackend = $httpBackend; + this.$window = $window; + }); + }); + describe('galleryService.createGallery', () => { + it('should create a new gallery', () => { + let galleryData = { + name: 'example gallery name', + desc: 'example gallery description' + }; + let headers = { + 'Content-Type': 'application/json', + Accept: 'application/json', + Authorization: 'Bearer test token' + }; + this.$httpBackend.expectPOST('http://localhost:3003/api/gallery', galleryData, headers) + .respond(200, { + _id: '42', + username: 'exampleuser', + name: galleryData.name, + desc: galleryData.desc, + pics: [] + }); + this.galleryService.createGallery(galleryData); + this.$httpBackend.flush(); + this.$rootScope.$apply(); + }); + }); + describe('galleryService.deleteGallery', () => { + it('should delete a gallery', () => { + this.$httpBackend.expectDELETE('http://localhost:3003/api/gallery/42') + .respond(204); + this.galleryService.deleteGallery('42'); + this.$rootScope.$apply(); + }); + }); +}); diff --git a/lab-yana/webpack.config.js b/lab-yana/webpack.config.js new file mode 100644 index 00000000..ca2ca556 --- /dev/null +++ b/lab-yana/webpack.config.js @@ -0,0 +1,47 @@ +'use strict'; + +require('dotenv').load(); + +const webpack = require('webpack'); +const HTMLPlugin = require('html-webpack-plugin'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); +const production = process.env.NODE_ENV === 'production'; + +module.exports = { + devtool: 'eval', + entry: `${__dirname}/app/entry.js`, + output: { + filename: 'bundle.js', + path: `${__dirname}/build` + }, + plugins: [ + new HTMLPlugin({ template: `${__dirname}/app/index.html` }), + new ExtractTextPlugin('bundle.css'), + new webpack.DefinePlugin({ + __API_URL__: JSON.stringify(process.env.API_URL), + __DEBUG__: JSON.stringify(!production) + }) + ], + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader' + }, + { + test: /\.html$/, + loader: 'html-loader' + }, + { + test: /\.png$/, + loader: 'file-loader', + options: { name: '[path][name].[hash][ext]' } + }, + { + test: /\.scss$/, + loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader']) + } + ] + } +}; diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 00000000..f55bb22e --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,24 @@ +0 info it worked if it ends with ok +1 verbose cli [ '/Users/radenska/.nvm/versions/node/v6.9.5/bin/node', +1 verbose cli '/Users/radenska/.nvm/versions/node/v6.9.5/bin/npm', +1 verbose cli 'run', +1 verbose cli 'lint' ] +2 info using npm@3.10.10 +3 info using node@v6.9.5 +4 verbose config Skipping project config: /Users/radenska/.npmrc. (matches userconfig) +5 verbose stack Error: ENOENT: no such file or directory, open '/Users/radenska/package.json' +5 verbose stack at Error (native) +6 verbose cwd /Users/radenska/codefellows/401/labs/25-angular_auth +7 error Darwin 16.4.0 +8 error argv "/Users/radenska/.nvm/versions/node/v6.9.5/bin/node" "/Users/radenska/.nvm/versions/node/v6.9.5/bin/npm" "run" "lint" +9 error node v6.9.5 +10 error npm v3.10.10 +11 error path /Users/radenska/package.json +12 error code ENOENT +13 error errno -2 +14 error syscall open +15 error enoent ENOENT: no such file or directory, open '/Users/radenska/package.json' +16 error enoent ENOENT: no such file or directory, open '/Users/radenska/package.json' +16 error enoent This is most likely not a problem with npm itself +16 error enoent and is related to npm not being able to find a file. +17 verbose exit [ -2, true ]