From 90d22e340552b5ce13581ea158d1bd2566130a5e Mon Sep 17 00:00:00 2001 From: Reynaldo Reyes Date: Mon, 29 Feb 2016 00:49:18 -0430 Subject: [PATCH] Initial commit --- .bowerrc | 3 + .gitignore | 2 + app/css/demo-framework.css | 70 ++++ app/css/nested.css | 149 +++++++++ app/css/search-box-example.css | 59 ++++ app/css/style.css | 130 ++++++++ app/img/logo_ciencias.jpg | Bin 0 -> 23359 bytes app/img/logo_computacion.jpg | Bin 0 -> 12812 bytes app/img/logo_ucv.jpg | Bin 0 -> 35297 bytes app/index.html | 109 +++++++ app/js/app.js | 37 +++ app/js/course/course.controllers.js | 176 +++++++++++ app/js/course/course.module.js | 57 ++++ app/js/course/course.services.js | 13 + app/js/login/login.controllers.js | 175 ++++++++++ app/js/login/login.module.js | 34 ++ app/js/login/login.services.js | 56 ++++ app/js/professor/professor.controllers.js | 256 +++++++++++++++ app/js/professor/professor.module.js | 75 +++++ app/js/professor/professor.services.js | 16 + app/js/report/report.controllers.js | 105 ++++++ app/js/report/report.module.js | 81 +++++ app/js/report/report.services.js | 16 + app/js/section/section.controllers.js | 298 ++++++++++++++++++ app/js/section/section.module.js | 79 +++++ app/js/section/section.services.js | 23 ++ app/js/sidebar/sidebar.controllers.js | 97 ++++++ app/js/student/student.controllers.js | 258 +++++++++++++++ app/js/student/student.module.js | 75 +++++ app/js/student/student.services.js | 16 + app/login.html | 65 ++++ app/partials/course/create_course.html | 82 +++++ app/partials/course/list_course.html | 70 ++++ .../course/modal/create_course_modal.html | 10 + .../course/modal/delete_course_modal.html | 14 + .../course/modal/upgrade_course_modal.html | 12 + app/partials/course/update_course.html | 72 +++++ app/partials/navbar.html | 22 ++ app/partials/professor/create_professor.html | 95 ++++++ app/partials/professor/list_professor.html | 53 ++++ .../modal/create_professor_modal.html | 10 + .../professor/modal/list_professor_modal.html | 14 + .../modal/update_professor_modal.html | 12 + app/partials/professor/update_professor.html | 62 ++++ app/partials/report/report.html | 116 +++++++ app/partials/section/create_section.html | 80 +++++ app/partials/section/list_section.html | 69 ++++ .../section/modal/create_section_modal.html | 12 + .../section/modal/delete_section_modal.html | 14 + .../section/modal/update_section_modal.html | 14 + app/partials/section/update_section.html | 54 ++++ app/partials/sidebar.html | 21 ++ app/partials/students/create_students.html | 93 ++++++ app/partials/students/list_students.html | 67 ++++ .../students/modal/create_students_modal.html | 9 + .../students/modal/list_students_modal.html | 14 + .../students/modal/update_students_modal.html | 12 + app/partials/students/update_students.html | 69 ++++ app/server.js | 188 +++++++++++ bower.json | 44 +++ components/version/interpolate-filter.js | 9 + components/version/interpolate-filter_test.js | 15 + components/version/version-directive.js | 9 + components/version/version-directive_test.js | 17 + components/version/version.js | 8 + components/version/version_test.js | 11 + package.json | 22 ++ 67 files changed, 4025 insertions(+) create mode 100644 .bowerrc create mode 100644 .gitignore create mode 100644 app/css/demo-framework.css create mode 100644 app/css/nested.css create mode 100644 app/css/search-box-example.css create mode 100644 app/css/style.css create mode 100644 app/img/logo_ciencias.jpg create mode 100644 app/img/logo_computacion.jpg create mode 100644 app/img/logo_ucv.jpg create mode 100644 app/index.html create mode 100644 app/js/app.js create mode 100644 app/js/course/course.controllers.js create mode 100644 app/js/course/course.module.js create mode 100644 app/js/course/course.services.js create mode 100644 app/js/login/login.controllers.js create mode 100644 app/js/login/login.module.js create mode 100644 app/js/login/login.services.js create mode 100644 app/js/professor/professor.controllers.js create mode 100644 app/js/professor/professor.module.js create mode 100644 app/js/professor/professor.services.js create mode 100644 app/js/report/report.controllers.js create mode 100644 app/js/report/report.module.js create mode 100644 app/js/report/report.services.js create mode 100644 app/js/section/section.controllers.js create mode 100644 app/js/section/section.module.js create mode 100644 app/js/section/section.services.js create mode 100644 app/js/sidebar/sidebar.controllers.js create mode 100644 app/js/student/student.controllers.js create mode 100644 app/js/student/student.module.js create mode 100644 app/js/student/student.services.js create mode 100644 app/login.html create mode 100644 app/partials/course/create_course.html create mode 100644 app/partials/course/list_course.html create mode 100644 app/partials/course/modal/create_course_modal.html create mode 100644 app/partials/course/modal/delete_course_modal.html create mode 100644 app/partials/course/modal/upgrade_course_modal.html create mode 100644 app/partials/course/update_course.html create mode 100644 app/partials/navbar.html create mode 100644 app/partials/professor/create_professor.html create mode 100644 app/partials/professor/list_professor.html create mode 100644 app/partials/professor/modal/create_professor_modal.html create mode 100644 app/partials/professor/modal/list_professor_modal.html create mode 100644 app/partials/professor/modal/update_professor_modal.html create mode 100644 app/partials/professor/update_professor.html create mode 100644 app/partials/report/report.html create mode 100644 app/partials/section/create_section.html create mode 100644 app/partials/section/list_section.html create mode 100644 app/partials/section/modal/create_section_modal.html create mode 100644 app/partials/section/modal/delete_section_modal.html create mode 100644 app/partials/section/modal/update_section_modal.html create mode 100644 app/partials/section/update_section.html create mode 100644 app/partials/sidebar.html create mode 100644 app/partials/students/create_students.html create mode 100644 app/partials/students/list_students.html create mode 100644 app/partials/students/modal/create_students_modal.html create mode 100644 app/partials/students/modal/list_students_modal.html create mode 100644 app/partials/students/modal/update_students_modal.html create mode 100644 app/partials/students/update_students.html create mode 100644 app/server.js create mode 100644 bower.json create mode 100644 components/version/interpolate-filter.js create mode 100644 components/version/interpolate-filter_test.js create mode 100644 components/version/version-directive.js create mode 100644 components/version/version-directive_test.js create mode 100644 components/version/version.js create mode 100644 components/version/version_test.js create mode 100644 package.json diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 0000000..ba0accc --- /dev/null +++ b/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "app/bower_components" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a0b7808 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.tmp +/nbproject/private/ \ No newline at end of file diff --git a/app/css/demo-framework.css b/app/css/demo-framework.css new file mode 100644 index 0000000..c6c0db2 --- /dev/null +++ b/app/css/demo-framework.css @@ -0,0 +1,70 @@ +body { + padding-top: 70px; + padding-bottom: 30px; +} + +.box { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05); + box-shadow: 0 1px 2px rgba(0,0,0,.05); +} + +.box > h3 { + color: #333; + border-color: #ddd; + border-bottom: 1px solid transparent; + border-top-right-radius: 3px; + border-top-left-radius: 3px; + background-repeat: repeat-x; + display: block; + font-size: 16px; + padding: 10px 15px; + margin-top: 0; + margin-bottom: 0; +} + +.box-padding { + padding: 15px; +} + +.box-padding > h3 { + margin: -15px; + margin-bottom: 15px; +} + +.box-grey { + border-color: #ddd; +} + +.box-grey > h3 { + background-color: #f5f5f5; + background-image: -webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%); + background-image: linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%); +} + +.box-blue { + border-color: #bce8f1; +} + +.box-blue > h3 { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; + background-image: -webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%); + background-image: linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%); +} + +.box-yellow { + border-color: #faebcc; +} + +.box-yellow > h3 { + //color: #8a6d3b; + //background-color: #fcf8e3; + //border-color: #faebcc; + //background-image: -webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%); + //background-image: linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%); +} \ No newline at end of file diff --git a/app/css/nested.css b/app/css/nested.css new file mode 100644 index 0000000..e57c969 --- /dev/null +++ b/app/css/nested.css @@ -0,0 +1,149 @@ +/***************************** Required styles *****************************/ + +/** + * For the correct positioning of the placeholder element, the dnd-list and + * it's children must have position: relative + */ +.nestedDemo ul[dnd-list], +.nestedDemo ul[dnd-list] > li { + position: relative; +} + +/***************************** Dropzone Styling *****************************/ + +/** + * The dnd-list should always have a min-height, + * otherwise you can't drop to it once it's empty + */ +.nestedDemo .dropzone ul[dnd-list] { + min-height: 42px; + margin: 0px; + padding-left: 0px; +} + +/** + * The dnd-lists's child elements currently MUST have + * position: relative. Otherwise we can not determine + * whether the mouse pointer is in the upper or lower + * half of the element we are dragging over. In other + * browsers we can use event.offsetY for this. + */ +.nestedDemo .dropzone li { + background-color: #fff; + border: 1px solid #ddd; + display: block; + padding: 0px; +} + +/** + * Reduce opacity of elements during the drag operation. This allows the user + * to see where he is dropping his element, even if the element is huge. The + * .dndDragging class is automatically set during the drag operation. + */ +.nestedDemo .dropzone .dndDragging { + opacity: 0.7; +} + +/** + * The dndDraggingSource class will be applied to the source element of a drag + * operation. It makes sense to hide it to give the user the feeling that he's + * actually moving it. Note that the source element has also .dndDragging class. + */ +.nestedDemo .dropzone .dndDraggingSource { + display: none; +} + +/** + * An element with .dndPlaceholder class will be added as child of the dnd-list + * while the user is dragging over it. + */ +.nestedDemo .dropzone .dndPlaceholder { + background-color: #ddd; + min-height: 42px; + display: block; + position: relative; +} + +/***************************** Element Selection *****************************/ + +.nestedDemo .dropzone .selected .item { + color: #3c763d; + background-color: #dff0d8; +} + +.nestedDemo .dropzone .selected .box { + border-color: #d6e9c6; +} + +.nestedDemo .dropzone .selected .box > h3 { + color: #3c763d; + background-color: #dff0d8; + background-image: linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%); + border-color: #d6e9c6; +} + +/***************************** Element type specific styles *****************************/ + +.nestedDemo .dropzone .item { + padding: 10px 15px; +} + +.nestedDemo .dropzone .container-element { + margin: 10px; +} + +.nestedDemo .dropzone .container-element .column { + float: left; + width: 16.666%; +} + +.nestedDemo .dropzone .container-element .columnQuestions { + float: left; + width: 100%; +} +/***************************** Toolbox *****************************/ + +.nestedDemo .toolbox ul { + list-style: none; + padding-left: 0px; + cursor: move; +} + +.nestedDemo .toolbox button { + margin: 5px; + //width: 123px; + opacity: 1.0; +} + +.nestedDemo .toolbox .dndDragging { + opacity: 0.5; +} + +.nestedDemo .toolbox .dndDraggingSource { + opacity: 1.0; +} + +/***************************** Trashcan *****************************/ + +.nestedDemo .trashcan ul { + list-style: none; + padding-left: 0px; +} + +.nestedDemo .trashcan img { + width: 100%; + -webkit-filter: grayscale(100%); + -moz-filter: grayscale(100%); + filter: grayscale(100%); +} + +.nestedDemo .trashcan .dndDragover img { + width: 100%; + -webkit-filter: none; + -moz-filter: none; + filter: none; +} + +.nestedDemo .trashcan .dndPlaceholder { + display: none; +} diff --git a/app/css/search-box-example.css b/app/css/search-box-example.css new file mode 100644 index 0000000..ab7b29c --- /dev/null +++ b/app/css/search-box-example.css @@ -0,0 +1,59 @@ +html, body { + height: 100%; + margin: 0px; + padding: 0px +} + +.pac-controls { + margin-top: 16px; + border: 1px solid transparent; + border-radius: 2px 0 0 2px; + box-sizing: border-box; + -moz-box-sizing: border-box; + height: 32px !important; + outline: none; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); +} + +#pac-input { + background-color: #fff; + padding: 0 11px 0 13px; + width: 400px; + font-family: 'Open Sans', sans-serif; + font-size: 15px; + font-weight: 300; + text-overflow: ellipsis; +} + +#pac-input:focus { + border-color: #4d90fe; + margin-left: -1px; + padding-left: 14px; /* Regular padding-left + 1. */ + width: 401px; +} + +.pac-container { + font-family: 'Open Sans', sans-serif; +} + +#type-selector { + color: #fff; + background-color: #4d90fe; + padding: 5px 11px 0px 11px; +} + +#type-selector label { + font-family: 'Open Sans', sans-serif; + font-size: 13px; + font-weight: 300; +} + +.angular-google-map-container { + width: 100%; + height: 600px; +} + +/* fix for Twitter Bootstrap handling of responsive images */ +.angular-google-map img { + max-width: inherit; +} diff --git a/app/css/style.css b/app/css/style.css new file mode 100644 index 0000000..2459bc8 --- /dev/null +++ b/app/css/style.css @@ -0,0 +1,130 @@ +/* + * Estilos para el modulo de notas marginales. + */ + +/* El contenido se desplaza hacia abajo porque usamos una barra de navegación fija de 50px */ +body { + padding-top: 85px; +} + +/* + * Barra de navegación superior + * Se elimina el borde por defecto de 1px. + */ +.navbar-fixed-top { + border: 0; +} + +.navbar-fixed-top-special { + position: fixed; + z-index: 30; +} + +/* + * Sidebar + */ + +/* Hide for mobile, show later */ +.sidebar { + display: none; +} +@media (min-width: 768px) { + .sidebar { + position: fixed; + top: 85px; + bottom: 0; + left: 0; + z-index: 1000; + display: block; + padding: 20px; + overflow-x: hidden; + overflow-y: auto; /* Si el contenido es mayor al visor, se hace scroll */ + background-color: #f5f5f5; + border-right: 1px solid #ccc; + } +} + +/* Navegación del sidebar */ +.nav-sidebar { + margin-right: -21px; /* 20px padding + 1px border */ + margin-bottom: 20px; + margin-left: -20px; +} +.nav-sidebar > li > a { + padding-right: 20px; + padding-left: 20px; + color: #000; +} +.nav-sidebar > .active > a, +.nav-sidebar > .active > a:hover, +.nav-sidebar > .active > a:focus { + font-style: italic; + color: #FFF; + background-color: #808080; +} + + +/* + * Contenido principal. + */ + +.main { padding: 20px; } + +@media (min-width: 768px) { + .main { + padding-right: 40px; + padding-left: 40px; + } +} +.main .page-header { margin-top: 0; } + +/* Barra superior */ +.navbar { min-height: 85px; } +.navbar-inverse { background-color: #CCC; } +.navbar-inverse .navbar-brand { color: #808080; } +.navbar-inverse .navbar-nav > li > a { color: #808080; } + +/* Estilos para errores de validación */ +small.error { color: red; } +input.ng-dirty.ng-valid { border:1px solid Green; } +input.ng-dirty.ng-invalid { border:1px solid Red; } + + +.research tr.accordion td { background:transparent url(row_bkg.png) repeat-x scroll center left; cursor:pointer; } +.research .accordion img.arrow { background:transparent url(../img/arrows.png) no-repeat scroll 0px -16px; width:16px; height:16px; display:block;} +.research .accordion img.up { background:transparent url(../img/arrows.png) no-repeat scroll 0px -16px; width:16px; height:16px; display:block; background-position:0px 0px;} + +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +svg .state { + stroke-width: 2; + stroke: #fff; + + -webkit-transition: stroke 0.5s, stroke-width 0.5s; + -o-transition: stroke 0.5s, stroke-width 0.5s; + transition: stroke 0.5s, stroke-width 0.5s; +} +svg .state:hover , .state.active { + cursor: pointer; + stroke-width: 4; + stroke: #000; +} + +.regionlist { + -webkit-column-count: 5; /* Chrome, Safari, Opera */ + -moz-column-count: 5; /* Firefox */ + column-count: 5; +} +.regionlist > div { + display: inline-block; + width: 100%; + border-bottom: 1px solid grey; +} +.regionlist > div > div { + display: inline-block; + width: 48%; +} \ No newline at end of file diff --git a/app/img/logo_ciencias.jpg b/app/img/logo_ciencias.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ad8fc223e073cc7c05f52c38f08bb1d5be2f099d GIT binary patch literal 23359 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 literal 0 HcmV?d00001 diff --git a/app/img/logo_computacion.jpg b/app/img/logo_computacion.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a81a9fa633c36d74b984b559dd340702d36f1702 GIT binary patch literal 12812 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 literal 0 HcmV?d00001 diff --git a/app/img/logo_ucv.jpg b/app/img/logo_ucv.jpg new file mode 100644 index 0000000000000000000000000000000000000000..32d108f949f300b07c75a2b59271cda56b5d5f4b GIT binary patch literal 35297 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 literal 0 HcmV?d00001 diff --git a/app/index.html b/app/index.html new file mode 100644 index 0000000..a15263a --- /dev/null +++ b/app/index.html @@ -0,0 +1,109 @@ + + + + + + + + + + Modulo de Administración de Asistencia + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/js/app.js b/app/js/app.js new file mode 100644 index 0000000..8536ab6 --- /dev/null +++ b/app/js/app.js @@ -0,0 +1,37 @@ +(function (){ + 'user strict'; + + angular.module('app', [ + 'app.course', + 'app.login', + 'app.professor', + 'app.reports', + 'app.section', + 'app.student', + 'ngResource', + 'ui.router' + ]) + + .config(function($stateProvider, $urlRouterProvider) { + + $urlRouterProvider.otherwise('/'); + + $stateProvider + .state('login', { + url: '/login', + views: { + content: { + templateUrl: 'login.html', + controller: 'loginCtrl', + controllerAs: 'vm' + } + } + }) + }) + + .run(function ($rootScope) { + $rootScope.domainUrl = 'Localhost:3000'; + }); + + +})(); diff --git a/app/js/course/course.controllers.js b/app/js/course/course.controllers.js new file mode 100644 index 0000000..605e051 --- /dev/null +++ b/app/js/course/course.controllers.js @@ -0,0 +1,176 @@ +(function(){ + 'use strict'; + + angular + .module('app.course') + .controller('listarMateriaCtrl',listarMateriaCtrl) + .controller('crearMateriaCtrl', crearMateriaCtrl) + + listarMateriaCtrl.$inject = + ['$scope', '$rootScope', '$location', 'courses', '$modal']; + function listarMateriaCtrl($scope, $rootScope, $location, courses, $modal) { + var vm = this; + $rootScope.table = false; + + var materiaArreglo = []; + courses.query( + function(data){ + vm.materia = data; + angular.forEach(vm.materia, function (value){ + materiaArreglo.push({ + Codigo:value.Codigo, + Nombre:value.Nombre, + Creditos:value.Creditos, + Descripcion:value.Descripcion + }); + }); + $rootScope.table = true; + vm.listaMateria = materiaArreglo; + }, + function(data){ + console.log("Error al obtener los datos."); + + }); + + vm.eliminarMateriaModal = function (index) { + $rootScope.index = index; + $rootScope.botonOk = true; + $rootScope.otroBotonOk = false; + $rootScope.botonCancelar = true; + $rootScope.rsplice = false; + $rootScope.loading = false; + $rootScope.mensaje = "¿Seguro que desea eliminar la materia?"; + + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: '/partials/course/modal/delete_course_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return ""; + } + } + }); + + }; + + vm.eliminarMateria = function (index) { + $rootScope.loadingListarForm = true; + $rootScope.botonOk = false; + $rootScope.otroBotonOk = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarMateria'; + $rootScope.rsplice = true; + + courses.delete({ id: vm.materia[index]._id }, + function() { + $rootScope.loadingListarForm = false; + $rootScope.mensaje = "Materia eliminada"; + }, + function() { + $rootScope.loadingListarForm = false; + $rootScope.mensaje = "Error eliminado materia"; + }); + }; + + vm.eliminarMateriaSplice = function(index, rsplice) { + if(rsplice){ + vm.listaMateria.splice(index, 1); + $rootScope.rsplice = false; + } + }; + + vm.modificarMateria = function (index) { + $location.url('modificarMateria'); + }; + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + $rootScope.opened = true; + }; + + return vm; + }; + + crearMateriaCtrl.$inject = + ['$scope','$rootScope', '$modal', '$location', 'courses']; + function crearMateriaCtrl($scope, $rootScope, $modal, $location, courses) { + + var vm = this; + vm.submitted = false; + vm.mayorque = false; + $rootScope.mensaje = ""; + + vm.submit = function() { + + if (vm.data_input_form.$valid){ + vm.course = { + + "Codigo": vm.materia.Codigo, + "Nombre": vm.materia.Nombre, + "Creditos": vm.materia.Creditos, + "Descripcion" : vm.materia.Description, + }; + + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: + '/partials/course/modal/create_course_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return $rootScope.items; + } + } + }); + + courses.save(vm.course, + function(){ + $rootScope.botonOk = true; + $rootScope.urlLo = 'listarMateria'; + $rootScope.mensaje = + "Materia " + vm.materia.Nombre + " creada"; + }, + function(){ + $rootScope.botonOk = true; + $rootScope.urlLo = 'listarMateria'; + $rootScope.mensaje = + "Error creando la materia " + vm.materia.Nombre; + }); + }else{ + + vm.submitted = true; + } + } + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + + $rootScope.opened = true; + }; + + return vm; + }; +})(); \ No newline at end of file diff --git a/app/js/course/course.module.js b/app/js/course/course.module.js new file mode 100644 index 0000000..1d595ca --- /dev/null +++ b/app/js/course/course.module.js @@ -0,0 +1,57 @@ +(function(){ + 'use strict'; + + angular + .module("app.course", ['ui.router', 'ui.bootstrap']) + .run(addStateToScope) + .config(getRoutes); + + addStateToScope.$inject = ['$rootScope', '$state', '$stateParams']; + function addStateToScope($rootScope, $state, $stateParams){ + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + }; + + getRoutes.$inject = ['$stateProvider', '$urlRouterProvider']; + function getRoutes($stateProvider, $urlRouterProvider){ + $urlRouterProvider.otherwise('/listarMaterias'); + + $stateProvider + .state('listarMateria', { + url: '/listarMateria', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/course/list_course.html', + controller: 'listarMateriaCtrl', + controllerAs: "vm" + } + } + }) + + .state('crearMateria', { + url: '/crearMateria', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/course/create_course.html', + controller: 'crearMateriaCtrl', + controllerAs: "vm" + } + } + }) + + }; +})(); diff --git a/app/js/course/course.services.js b/app/js/course/course.services.js new file mode 100644 index 0000000..a1ab8df --- /dev/null +++ b/app/js/course/course.services.js @@ -0,0 +1,13 @@ +(function(){ + 'use strict'; + + angular + .module('app.course') + .factory('courses', courses) + .value('id',{}); + + courses.$inject = ['$resource','$rootScope']; + function courses($resource, $rootScope){ + return $resource('http://'+$rootScope.domainUrl+'/courses/:id', null); + }; +})(); diff --git a/app/js/login/login.controllers.js b/app/js/login/login.controllers.js new file mode 100644 index 0000000..14c00ff --- /dev/null +++ b/app/js/login/login.controllers.js @@ -0,0 +1,175 @@ +(function(){ + 'use strict'; + + angular + .module('app.login') + .controller('loginCtrl', loginCtrl) + .controller('ModalInstanceLoginCtrl', ModalInstanceLoginCtrl) + .constant('datepickerPopupConfig', { + datepickerPopup: 'yyyy-MM-dd', + html5Types: { + date: 'yyyy-MM-dd', + 'datetime-local': 'yyyy-MM-ddTHH:mm:ss.sss', + 'month': 'yyyy-MM' + }, + currentText: 'Hoy', + clearText: 'Limpiar', + closeText: 'Cerrar', + closeOnDateSelection: true, + appendToBody: false, + showButtonBar: true + }); + + + ModalInstanceLoginCtrl.$inject = ['$scope', '$modalInstance', 'items', '$location']; + function ModalInstanceLoginCtrl($scope, $modalInstance, items, $location){ + + $scope.items = items; + + $scope.okLogin = function (actOk, urlLo) { + //$modalInstance.close($scope.selected.item); + if(actOk){ + $location.url(urlLo); + $modalInstance.dismiss('cancel'); + } + }; + + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; + + + }; + + loginCtrl.$inject = ['$rootScope', '$location', 'Login', 'Rol','GetRol', 'hash', '$http', 'user', '$modal']; + function loginCtrl($rootScope, $location, Login, Rol, GetRol, hash, $http, user, $modal){ + var vm = this; + + + //$http.get("http://cesar:12316/api/Rol") + //.success(function(response) {$rootScope.namesw = response.Data;}); + + vm.user = user; + vm.submitted = false; + vm.mayorque = false; + $rootScope.items = ""; + $rootScope.mensaje = ""; + vm.submit = function() { + //var verificar = false; + if (vm.data_input_form.$valid){ + // se implementa todo lo necesario antes de pasar a la siguiente página. + vm.pkg = { + + "Nickname": vm.user.Nickname, + "Password": $rootScope.password + + }; + //$rootScope.mostrar = false; + $rootScope.loadingLogin = true; + $rootScope.mensaje = ""; + $rootScope.bcancel = false; + $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'myModalContentLogin.html', + controller: 'ModalInstanceLoginCtrl', + size: 'sm', + resolve: { + items: function () { + return $rootScope.items; + } + } + }); + Login.save(vm.pkg, + function(data){ + //$rootScope.mostrar = true; + $rootScope.loadingLogin = false; + //verificar = data.Data._value; + if(data.Data._value != null){ + //$rootScope.bok = true; + $rootScope.actOk = true; + $rootScope.urlLo = 'mapasReportes'; + $rootScope.bcancel = false; + + }else{ + $rootScope.bcancel = true; + $rootScope.mensaje = data.Data._error; + } + }, + function(data){ + verificar = data.Data; + if(verificar){ + alert("no existe el usuario"); + } + + }) + GetRol.get({id:vm.user.Nickname}, function(data){ + $rootScope.role = data.Data; + } + + ); + + //$location.url('/preview/'); + }else{ + + vm.submitted = true; + } + } + + vm.onSelectChange = function () { + if(vm.genero == "Masculino"){ + $rootScope.Gender = "M"; + //alert("hola " + vm.valorRol.Name); + } + if(vm.genero == "Femenino"){ + $rootScope.Gender = "F"; + } + }; + + //$rootScope.password="s3cret"; + $rootScope.getHash = function(message) { + var hashResult = hash(message); + $rootScope.password = hashResult; + return hashResult; + }; + + vm.generos = ['', 'Masculino', 'Femenino']; + vm.genero = vm.generos[0]; + + Rol.get( + function(data){ + $rootScope.rol = data.Data; + } + ); + + + vm.toggleMin = function() { + vm.maxDate = vm.maxDate ? null : new Date(); + }; + vm.toggleMin(); + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + + $rootScope.opened = true; + }; + + $rootScope.open2 = function($eventt) { + $eventt.preventDefault(); + $eventt.stopPropagation(); + + $rootScope.openedd = true; + }; + + $rootScope.dateOptions = { + formatYear: 'yy', + startingDay: 1 + }; + + return vm; + }; + + + + +})(); diff --git a/app/js/login/login.module.js b/app/js/login/login.module.js new file mode 100644 index 0000000..ec202c4 --- /dev/null +++ b/app/js/login/login.module.js @@ -0,0 +1,34 @@ +(function(){ + + 'use strict'; + + angular + .module("app.login", ['ui.router', 'ui.bootstrap']) + .run(addStateToScope) + .config(getRoutes); + + addStateToScope.$inject = ['$rootScope', '$state', '$stateParams']; + function addStateToScope($rootScope, $state, $stateParams){ + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + }; + + getRoutes.$inject = ['$stateProvider', '$urlRouterProvider']; + function getRoutes($stateProvider, $urlRouterProvider){ + $urlRouterProvider.otherwise('/'); + + $stateProvider + .state('root', { + url: '', + views: { + content: { + templateUrl: 'login.html', + controller: 'LoginCtrl', + controllerAs: 'vm' + } + } + }) + + + }; +})(); diff --git a/app/js/login/login.services.js b/app/js/login/login.services.js new file mode 100644 index 0000000..5f2ca5b --- /dev/null +++ b/app/js/login/login.services.js @@ -0,0 +1,56 @@ +(function(){ + 'use strict'; + + angular + .module('app.login') + .factory('Login', Login) + .factory('Rol', Rol) + .factory('GetRol', GetRol) + .factory('hash', hash) + .value('algoritmo','SHA-1') + .value('user',{}) + .value('id',{}) + + + Login.$inject = ['$resource','$rootScope']; + function Login($resource, $rootScope){ + return $resource('http://'+$rootScope.domainUrl+'/api/VerifyUser'); + + }; + + Rol.$inject = ['$resource','$rootScope']; + function Rol($resource, $rootScope){ + return $resource('http://'+$rootScope.domainUrl+'/api/Rol'); + }; + + GetRol.$inject = ['$resource','$rootScope']; + function GetRol($resource, $rootScope){ + return $resource('http://'+$rootScope.domainUrl+'/api/User/:id'); + }; + + hash.$inject = ['algoritmo']; + function hash(algoritmo){ + + var hashFunction; + + if (algoritmo==="MD5") { + hashFunction=CryptoJS.MD5; + } else if (algoritmo==="SHA-1") { + hashFunction=CryptoJS.SHA1; + } else if (algoritmo==="SHA-2-256") { + hashFunction=CryptoJS.SHA256; + } else if (algoritmo==="SHA-2-512") { + hashFunction=CryptoJS.SHA512; + } else { + throw Error("El tipo de algoritmo no es válido:"+algoritmo); + } + + var hash=function(message) { + var objHashResult=hashFunction(message); + var strHashResult=objHashResult.toString(CryptoJS.enc.Base64); + + return strHashResult; + } + return hash; + }; +})(); diff --git a/app/js/professor/professor.controllers.js b/app/js/professor/professor.controllers.js new file mode 100644 index 0000000..9d157ac --- /dev/null +++ b/app/js/professor/professor.controllers.js @@ -0,0 +1,256 @@ +(function(){ + 'use strict'; + + angular + .module('app.professor') + .controller('listarProfesorCtrl', listarProfesorCtrl) + .controller('crearProfesorCtrl', crearProfesorCtrl) + .controller('actualizarProfesorCtrl', actualizarProfesorCtrl) + + listarProfesorCtrl.$inject = + [ '$scope', '$rootScope', '$location', 'professors', '$modal', 'profesorSeleccionado' ]; + function listarProfesorCtrl( $scope, $rootScope, $location, professors, $modal, profesorSeleccionado ){ + + var vm = this; + vm.lista = true; + $rootScope.actOk = false; + $rootScope.loading = true; + $rootScope.table = false; + + var profesorArray = []; + professors.query( + function(data){ + vm.profesor = data; + angular.forEach(vm.profesor, function (value){ + profesorArray.push({ + Cedula:value.id, + Nombre:value.name, + Apellido:value.lastname, + Telefono:value.number, + Correo: value.email + }); + }); + $rootScope.loading = false; + $rootScope.table = true; + vm.listaProfesor = profesorArray; + + }, + function(){ + console.log("Error al obtener los datos."); + }); + + vm.eliminarProfesorModal = function (index) { + $rootScope.index = index; + $rootScope.botonOK = true; + $rootScope.botonCancelar = true; + $rootScope.acceptButton = false; + + $rootScope.rsplice = false; + $rootScope.mensaje = "¿Seguro que desea eliminar el Profesor?"; + + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'partials/professor/modal/list_professor_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return ""; + } + } + }); + }; + + vm.eliminarProfesor = function (index) { + + $rootScope.botonOK = false; + $rootScope.acceptButton = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarProfesor'; + + professors.delete({id: vm.profesor[index]._id}, + function () { + $rootScope.rsplice = true; + $rootScope.mensaje = + "Profesor " + vm.profesor[index].name + " eliminado"; + }, + function () { + $rootScope.listarProfesorsLoading = false; + $rootScope.mensaje = + "Error eliminando al Profesor " + vm.profesor[index].name; + }); + }; + + vm.removeProfesorSplice = function(index, rsplice) { + if(rsplice){ + vm.listaProfesor.splice(index, 1); + $rootScope.rsplice = false; + } + }; + + vm.modificarProfesor = function (index) { + profesorSeleccionado._id = vm.profesor[index]._id; + profesorSeleccionado.Cedula = vm.profesor[index].id; + profesorSeleccionado.Nombre = vm.profesor[index].name; + profesorSeleccionado.Apellido= vm.profesor[index].lastname; + profesorSeleccionado.Telefono = vm.profesor[index].number; + profesorSeleccionado.Correo= vm.profesor[index].email; + $location.url('actualizarProfesor'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + $rootScope.opened = true; + }; + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + return vm; + }; + + crearProfesorCtrl.$inject = + ['$scope','$rootScope', '$location', 'professors', '$modal']; + function crearProfesorCtrl($scope, $rootScope, $location, professors, $modal){ + + var vm = this; + $rootScope.mensaje = ""; + + vm.submit = function() { + + if (vm.data_input_form.$valid){ + var professor = { + "id": vm.profesor.Cedula, + "name": vm.profesor.Nombre, + "lastname": vm.profesor.Apellido, + "email": vm.profesor.Correo, + "number": vm.profesor.Telefono, + }; + + $rootScope.botonOk = false; + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'partials/professor/modal/create_professor_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return $rootScope.items; + } + } + }); + + professors.save(professor, + function(){ + $rootScope.botonOk = true; + $rootScope.urlLo = 'listarProfesor'; + $rootScope.mensaje = + "Profesor " + vm.profesor.Apellido + ", " + vm.profesor.Nombre + " agregado"; + }, + + function(){ + $rootScope.botonOk = true; + $rootScope.urlLo = 'listarProfesor'; + $rootScope.mensaje = + "Error al agregar al profesor " + vm.profesor.Apellido + ", " + vm.profesor.Nombre; + }); + }else{ + + vm.submitted = true; + } + } + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + $rootScope.opened = true; + }; + + return vm; + }; + + actualizarProfesorCtrl.$inject = + ['$scope','$rootScope', '$location', 'professors', '$modal', 'profesorSeleccionado' ]; + function actualizarProfesorCtrl ( $scope, $rootScope, $location, professors, $modal, profesorSeleccionado ){ + + var vm = this; + vm.profesor = profesorSeleccionado; + $rootScope.mensaje = ""; + $rootScope.actOk = false; + + vm.submit = function() { + + var professor = { + "_id": vm.profesor._id, + "id": vm.profesor.Cedula, + "name": vm.profesor.Nombre, + "lastname": vm.profesor.Apellido, + "email": vm.profesor.Correo, + "number": vm.profesor.Telefono, + }; + + $rootScope.botonOk = false; + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'partials/professor/modal/update_professor_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return $rootScope.items; + } + } + }); + + professors.update(professor, + function(){ + $rootScope.botonOk = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarProfesor'; + $rootScope.mensaje = + "Profesor " + vm.profesor.Apellido + ", " + vm.profesor.Nombre + " actualizado"; + }, + function(){ + $rootScope.botonOk = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarProfesor'; + $rootScope.mensaje = + "Error al modificar al profesor " + vm.profesor.Apellido + ", " + vm.profesor.Nombre; + }); + } + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + $rootScope.opened = true; + }; + + return vm; + }; + +})(); \ No newline at end of file diff --git a/app/js/professor/professor.module.js b/app/js/professor/professor.module.js new file mode 100644 index 0000000..ab1a73d --- /dev/null +++ b/app/js/professor/professor.module.js @@ -0,0 +1,75 @@ +(function(){ + 'use strict'; + + angular + .module("app.professor", ['ui.router', 'ui.bootstrap']) + .run(addStateToScope) + .config(getRoutes); + + addStateToScope.$inject = ['$rootScope', '$state', '$stateParams']; + function addStateToScope($rootScope, $state, $stateParams){ + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + }; + + getRoutes.$inject = ['$stateProvider', '$urlRouterProvider']; + function getRoutes($stateProvider, $urlRouterProvider){ + $urlRouterProvider.otherwise('/listarProfesor'); + + $stateProvider + .state('listarProfesor', { + url: '/listarProfesor', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/professor/list_professor.html', + controller: 'listarProfesorCtrl', + controllerAs: 'vm' + } + } + }) + + .state('crearProfesor', { + url: '/crearProfesor', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/professor/create_professor.html', + controller: 'crearProfesorCtrl', + controllerAs: 'vm' + } + } + }) + + .state('actualizarProfesor', { + url: '/actualizarProfesor', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/professor/update_professor.html', + controller: 'actualizarProfesorCtrl', + controllerAs: 'vm' + } + } + }) + }; +})(); diff --git a/app/js/professor/professor.services.js b/app/js/professor/professor.services.js new file mode 100644 index 0000000..8e1b8c1 --- /dev/null +++ b/app/js/professor/professor.services.js @@ -0,0 +1,16 @@ +(function(){ + 'use strict'; + + angular + .module('app.professor') + .factory('professors', professors) + .value('profesorSeleccionado',{}); + + professors.$inject = ['$resource','$rootScope']; + function professors($resource, $rootScope){ + return $resource('http://'+$rootScope.domainUrl+'/professors/:id', null, + { + 'update': {method:'PUT'} + }); + }; +})(); \ No newline at end of file diff --git a/app/js/report/report.controllers.js b/app/js/report/report.controllers.js new file mode 100644 index 0000000..bdfaf3d --- /dev/null +++ b/app/js/report/report.controllers.js @@ -0,0 +1,105 @@ +(function(){ + 'use strict'; + + angular + .module('app.reports') + .controller('poblacionNacimientoCtrl', poblacionNacimientoCtrl) + .controller('poblacionActivaCtrl', poblacionActivaCtrl) + .controller('hombresEdadCtrl', hombresEdadCtrl) + .controller('mujeresEdadCtrl', mujeresEdadCtrl) + .controller('comidasDiaCtrl', comidasDiaCtrl) + .controller('nivelEducacionCtrl', nivelEducacionCtrl) + .controller('serviciosHogaresCtrl', serviciosHogaresCtrl) + .controller('ingresosAnualesCtrl', ingresosAnualesCtrl) + + poblacionNacimientoCtrl.$inject = ['$rootScope', 'ReportJson']; + function poblacionNacimientoCtrl($rootScope, ReportJson){ + + $rootScope.labelPoblacionNacimiento = ['Extranjeros', 'Residentes']; + ReportJson.get({id:$rootScope.elementId}, function(data) { + + $rootScope.dataPoblacionNacimiento = data.Data[0].dataPoblacionNacimiento; + + }); + }; + + poblacionActivaCtrl.$inject = ['$rootScope', 'ReportJson']; + function poblacionActivaCtrl($rootScope, ReportJson){ + + $rootScope.labelsPoblacionActiva = ['Hombres', 'Mujeres']; + $rootScope.seriesPoblacionActiva = ['Economicamente Pasivos', 'Economicamente Activos']; + $rootScope.dataPoblacionActiva = []; + + ReportJson.get({id:$rootScope.elementId},function(data) { + + $rootScope.dataPoblacionActiva = data.Data[0].dataPoblacionActiva; + }); + }; + + hombresEdadCtrl.$inject = ['$rootScope', 'ReportJson']; + function hombresEdadCtrl($rootScope, ReportJson){ + $rootScope.labelsHombresEdad = ['0-6', '7-12','13-18', '19-25','26-44', '45-60','61-99', '80-84', '90+']; + $rootScope.seriesHombresEdad = ['Hombres por Generacion']; + $rootScope.dataHombresEdad = []; + + ReportJson.get({id:$rootScope.elementId},function(data) { + + $rootScope.dataHombresEdad = data.Data[0].dataHombresEdad; + }); + }; + + mujeresEdadCtrl.$inject = ['$rootScope', 'ReportJson']; + function mujeresEdadCtrl($rootScope, ReportJson){ + $rootScope.labelsMujeresEdad = ['0-6', '7-12','13-18', '19-25','26-44', '45-60','61-99', '80-84', '90+']; + $rootScope.seriesMujeresEdad = ['Mujeres por Generacion']; + $rootScope.dataMujeresEdad = []; + + ReportJson.get({id:$rootScope.elementId},function(data) { + + $rootScope.dataMujeresEdad = data.Data[0].dataMujeresEdad; + }); + }; + + comidasDiaCtrl.$inject = ['$rootScope', 'ReportJson']; + function comidasDiaCtrl($rootScope, ReportJson){ + $rootScope.labelsComidasDia = ['Desayuno', 'Almuerzo', 'Cena']; + $rootScope.dataComidasDia = []; + + ReportJson.get({id:$rootScope.elementId},function(data) { + + $rootScope.dataComidasDia = [data.Data[0].dataComidasDia]; + }); + }; + + nivelEducacionCtrl.$inject = ['$rootScope', 'ReportJson']; + function nivelEducacionCtrl($rootScope, ReportJson){ + $rootScope.labelsNivelEducacion = ['Nivel de Educacion Superior', 'Nivel de Educacion Media']; + + ReportJson.get({id:$rootScope.elementId},function(data) { + + $rootScope.dataNivelEducacion = data.Data[0].dataNivelEducacion; + }); + }; + + serviciosHogaresCtrl.$inject = ['$rootScope', 'ReportJson']; + function serviciosHogaresCtrl($rootScope, ReportJson){ + $rootScope.labelsServiciosHogares = ['Agua', 'Gas', 'Electricidad' , 'Linea Telefonica']; + $rootScope.dataServiciosHogares = []; + + ReportJson.get({id:$rootScope.elementId},function(data) { + + $rootScope.dataServiciosHogares = [data.Data[0].dataServiciosHogares]; + }); + }; + + ingresosAnualesCtrl.$inject = ['$rootScope', 'ReportJson']; + function ingresosAnualesCtrl($rootScope, ReportJson){ + $rootScope.labelsIngresosAnuales = ['Menos de 10.000', 'De 11.000 a 20.000', 'De 21.000 a 35.000' , 'De 35.000 a 50.000']; + + ReportJson.get({id:$rootScope.elementId},function(data) { + + $rootScope.dataIngresosAnuales = data.Data[0].dataIngresosAnuales; + }); + }; + +})(); diff --git a/app/js/report/report.module.js b/app/js/report/report.module.js new file mode 100644 index 0000000..6864232 --- /dev/null +++ b/app/js/report/report.module.js @@ -0,0 +1,81 @@ +(function(){ + 'use strict'; + + angular + .module("app.reports", ['ui.router', 'ui.bootstrap', 'chart.js']) + .run(addStateToScope) + .config(getRoutes); + + addStateToScope.$inject = ['$rootScope', '$state', '$stateParams']; + function addStateToScope($rootScope, $state, $stateParams){ + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + }; + + getRoutes.$inject = ['$stateProvider', '$urlRouterProvider']; + function getRoutes($stateProvider, $urlRouterProvider){ + $urlRouterProvider.otherwise('/reportes'); + + $stateProvider + + .state('poblacionNacimiento', { + url: '/reportes', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/reportes/reportes.html', + controller: 'poblacionNacimientoCtrl', + controllerAs: 'vm' + } + } + }) + .state('poblacionActiva', { + url: '/poblacionActivaCtrl', + templateUrl: 'partials/reportes/reportes.html', + controller: 'poblacionActivaCtrl', + controllerAs: 'vm' + }) + .state('hombresEdad', { + url: '/hombresEdad', + templateUrl: 'partials/reportes/reportes.html', + controller: 'hombresEdadCtrl', + controllerAs: 'vm' + }) + .state('mujeresEdad', { + url: '/mujeresEdad', + templateUrl: 'partials/reportes/reportes.html', + controller: 'mujeresEdadCtrl', + controllerAs: 'vm' + }) + .state('comidasDia', { + url: '/comidasDia', + templateUrl: 'partials/reportes/reportes.html', + controller: 'comidasDiaCtrl', + controllerAs: 'vm' + }) + .state('nivelEducacion', { + url: '/nivelEducacion', + templateUrl: 'partials/reportes/reportes.html', + controller: 'nivelEducacionCtrl', + controllerAs: 'vm' + }) + .state('serviciosHogares', { + url: '/serviciosHogares', + templateUrl: 'partials/reportes/reportes.html', + controller: 'serviciosHogaresCtrl', + controllerAs: 'vm' + }) + .state('ingresosAnuales', { + url: '/ingresosAnuales', + templateUrl: 'partials/reportes/reportes.html', + controller: 'ingresosAnualesCtrl', + controllerAs: 'vm' + }) + }; +})(); diff --git a/app/js/report/report.services.js b/app/js/report/report.services.js new file mode 100644 index 0000000..e483618 --- /dev/null +++ b/app/js/report/report.services.js @@ -0,0 +1,16 @@ +(function(){ + 'use strict'; + + angular + .module('app.reports') + .factory('ReportJson', ReportJson) + .value('id',{}) + + ReportJson.$inject = ['$resource','$rootScope']; + function ReportJson($resource, $rootScope){ + return $resource('http://'+$rootScope.domainUrl+'/api/reports/:id'); + //var json="data/data.json"; + //return $resource(json); + }; + +})(); \ No newline at end of file diff --git a/app/js/section/section.controllers.js b/app/js/section/section.controllers.js new file mode 100644 index 0000000..fd5714f --- /dev/null +++ b/app/js/section/section.controllers.js @@ -0,0 +1,298 @@ +(function(){ + 'use strict'; + + angular + .module('app.section') + .controller('listarMatriculaCtrl', listarMatriculaCtrl) + .controller('crearMatriculaCtrl', crearMatriculaCtrl) + .controller('actualizarMatriculaCtrl', actualizarMatriculaCtrl) + + listarMatriculaCtrl.$inject = [ '$scope', '$rootScope', '$location', 'sections', '$modal', 'matriculaSeleccionada']; + function listarMatriculaCtrl ( $scope, $rootScope, $location, sections, $modal, matriculaSeleccionada ){ + + var vm = this; + vm.lista = true; + $rootScope.actOk = false; + $rootScope.loading = true; + $rootScope.table = false; + + vm.submit = function() { + } + + var matriculaArray = []; + sections.query( + function(successResult){ + vm.matricula = successResult; + angular.forEach(vm.matricula, function (value){ + matriculaArray.push({ + Nombre:value.Nombre, + Codigo:value.Codigo, + Materia:value.Materia, + Semestre:value.Semestre, + Estudiantes: value.Estudiantes + }); + }); + $rootScope.loading = false; + $rootScope.table = true; + vm.listaMatricula = matriculaArray; + }, + function(data){ + console.log("Error al obtener los datos."); + + }); + + /**************************Eliminar Matricula**************************/ + /* En este proceso, primero se llama a un Modal el cual se cerciora que + el usuario se asegure de eliminar la matricula escogida, el usuario al + confirmar su decision llama automaticamente a la funcion que hara la + llamada a servicio que borrara la matricula de la base de datos. + */ + vm.eliminarMatriculaModal = function (index) { + + $rootScope.index = index; + $rootScope.botonOk = true; + $rootScope.otroBotonOk = false; + $rootScope.botonCancelar = true; + $rootScope.rsplice = false; + $rootScope.eliminarLoading = false; + $rootScope.mensaje = "¿Seguro que desea eliminar la matricula?"; + + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'partials/matricula/modal/eliminar_matricula_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return ""; + } + } + }); + }; + + vm.eliminarMatricula= function (index) { + $rootScope.botonOk = false; + $rootScope.otroBotonOk = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarMatricula'; + $rootScope.eliminarLoading = true; + var name = vm.matricula[index].Nombre; + + sections.delete({ id: vm.matricula[index]._id }, + function (successResult) { + $rootScope.eliminarLoading = false; + $rootScope.rsplice = true; + $rootScope.mensaje = "Sección " + name + " eliminada."; + }, + function (errorResult) { + $rootScope.eliminarLoading = false; + $rootScope.mensaje = "Error al eliminar la sección " + name; + console.log('Could not delete from server'); + }); + }; + + vm.eliminarMatriculaSplice = function (index, rsplice) { + if(rsplice){ + vm.listaMatricula.splice(index, 1); + $rootScope.rsplice = false; + } + }; + + /*************************Fin de Eliminar Matricula********************/ + + + vm.modificarMatricula = function (index) { + matriculaSeleccionada.Nombre = vm.matricula[index].Nombre; + matriculaSeleccionada.Codigo = vm.matricula[index].Codigo; + matriculaSeleccionada.Materia = vm.matricula[index].Materia; + matriculaSeleccionada.Semestre = vm.matricula[index].Semestre; + matriculaSeleccionada.Estudiantes= vm.matricula[index].Estudiantes; + $location.url('actualizarMatricula'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + + $rootScope.opened = true; + }; + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + return vm; + }; + + crearMatriculaCtrl.$inject = + ['$scope','$rootScope', '$location', 'sections', '$modal', 'courses']; + function crearMatriculaCtrl($scope, $rootScope, $location, sections, $modal, courses){ + + var vm = this; + vm.submitted = false; + $rootScope.mensaje = ""; + + courses.query( + function (successResult) { + vm.materias = successResult; + }, + function () { + vm.materias = null; + }); + + vm.submit = function() { + + if (vm.data_input_form.$valid){ + vm.section = { + + "section": vm.matricula.Nombre, + "code": vm.valorMateria.Codigo, + "course": vm.valorMateria.Nombre, + "semester": vm.matricula.Semestre, + "students": vm.matricula.Estudiantes, + }; + + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'partials/matricula/modal/crear_matricula_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return $rootScope.items; + } + } + }); + + sections.save(vm.section, + function(){ + $rootScope.botonOk = true; + $rootScope.urlLo = 'listarMatricula'; + $rootScope.mensaje = "Sección " + vm.matricula.Nombre + " creada"; + }, + function(){ + $rootScope.botonOk = true; + $rootScope.urlLo = 'listarMatricula'; + $rootScope.mensaje = "Error creando la seccion " + vm.matricula.Nombre; + }); + }else{ + vm.submitted = true; + } + }; + + vm.cargarEstudiantes = function () { + + }; + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + + $rootScope.opened = true; + }; + + return vm; + }; + + actualizarMatriculaCtrl.$inject = ['$scope', '$rootScope', '$location', 'sections', '$modal', 'matriculaSeleccionada']; + function actualizarMatriculaCtrl($scope, $rootScope, $location, sections, $modal, matriculaSeleccionada){ + + var vm = this; + vm.lista = true; + $rootScope.loading = true; + $rootScope.table = false; + vm.matricula = matriculaSeleccionada; + vm.listaEstudiantes = vm.matricula.Estudiantes; + + + vm.actualizarMatricula = function() { + sections.update(section, + function(){ + $rootScope.botonOk = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarMatricula'; + $rootScope.mensaje = "Sección actualizada"; + }, + function(){ + $rootScope.botonOk = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarMatricula'; + $rootScope.mensaje = "Error al actualizar la Sección "; + }); + } + + vm.retirarEstudianteModal = function (index) { + $rootScope.index = index; + + $rootScope.botonOk = true; + $rootScope.otroBotonOk = false; + $rootScope.botonCancelar = true; + + $rootScope.rsplice = false; + $rootScope.eliminarLoading = false; + $rootScope.mensaje = "¿Desea retirar este estudiante de la Sección?"; + + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'partials/matricula/modal/actualizar_matricula_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return ""; + } + } + }); + }; + + vm.retirarEstudiante = function (index) { + $rootScope.botonOk = false; + $rootScope.otroBotonOk = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'actualizarMatricula'; + }; + + vm.retirarEstudianteSplice = function(index, rsplice) { + if(rsplice){ + vm.listaEstudiantes.splice(index, 1); + $rootScope.rsplice = false; + + var section = { + 'section': vm.matricula.Nombre, + 'code': vm.matricula.Codigo, + 'course': vm.matricula.Seccion, + 'semester': vm.matricula.Semestre, + 'students': vm.listaEstudiantes + }; + } + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + $rootScope.opened = true; + }; + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + return vm; + }; + +})(); \ No newline at end of file diff --git a/app/js/section/section.module.js b/app/js/section/section.module.js new file mode 100644 index 0000000..93c6231 --- /dev/null +++ b/app/js/section/section.module.js @@ -0,0 +1,79 @@ +(function(){ + + 'use strict'; + + angular + .module("app.section", ['ui.router', 'ui.bootstrap']) + .run(addStateToScope) + .config(getRoutes); + + addStateToScope.$inject = ['$rootScope', '$state', '$stateParams']; + function addStateToScope($rootScope, $state, $stateParams){ + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + }; + + getRoutes.$inject = ['$stateProvider', '$urlRouterProvider']; + function getRoutes($stateProvider, $urlRouterProvider){ + $urlRouterProvider.otherwise('/listarMatricula'); + + $stateProvider + + .state('listarMatricula', { + url: '/listarMatricula', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/section/list_section.html', + controller: 'listarMatriculaCtrl', + controllerAs: 'vm' + } + } + }) + + .state('crearMatricula', { + url: '/crearMatricula', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/section/create_section.html', + controller: 'crearMatriculaCtrl', + controllerAs: 'vm' + } + } + }) + + .state('actualizarMatricula', { + url: '/actualizarMatricula', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/section/update_section.html', + controller: 'actualizarMatriculaCtrl', + controllerAs: 'vm' + } + } + }) + + + }; +})(); + diff --git a/app/js/section/section.services.js b/app/js/section/section.services.js new file mode 100644 index 0000000..34cd5cc --- /dev/null +++ b/app/js/section/section.services.js @@ -0,0 +1,23 @@ +(function(){ + 'use strict'; + + angular + .module('app.section') + .factory('sections', sections) + .factory('courses', courses) + .value('matriculaSeleccionada',{}); + + sections.$inject = ['$resource','$rootScope']; + function sections($resource, $rootScope){ + return $resource('http://'+$rootScope.domainUrl+'/sections/:id', null, + { + 'update': {method:'PUT'} + }); + }; + + courses.$inject = ['$resource','$rootScope']; + function courses($resource, $rootScope){ + return $resource('http://'+$rootScope.domainUrl+'/courses'); + }; + +})(); \ No newline at end of file diff --git a/app/js/sidebar/sidebar.controllers.js b/app/js/sidebar/sidebar.controllers.js new file mode 100644 index 0000000..657e7f7 --- /dev/null +++ b/app/js/sidebar/sidebar.controllers.js @@ -0,0 +1,97 @@ +(function(){ + 'use strict'; + + angular + .module('app') + .controller('sidebarCtrl', ['$scope', + function($scope) { + + var that = this; + $scope.showChilds = function(item){ + item.active = !item.active;}; + + $scope.items = [ + { + + text: 'Modulo de Administración', + subItems: [ + { + state: 'listarProfesor', + text: 'Listar Profesores' + }, + { + state: 'crearProfesor', + text: 'Agregar Profesores' + } + ] + }, + { + + text: 'Modulo de Materias', + subItems: [ + { + state: 'listarMateria', + text: 'Listar Materias' + }, + { + state: 'crearMateria', + text: 'Agregar Materia' + } + ] + }, + { + + text: 'Modulo de Estudiantes', + subItems: [ + { + state: 'listarEstudiante', + text: 'Listar Estudiantes' + }, + { + state: 'crearEstudiante', + text: 'Agregar Estudiantes' + } + ] + }, + { + + text: 'Modulo de Matriculas', + subItems: [ + { + state: 'listarMatricula', + text: 'Listar Matricula' + }, + { + state: 'crearMatricula', + text: 'Crear Matricula' + } + ] + }, + { + + text: 'Modulo de Reportes', + subItems: [ + { + state: 'reportesAlumno', + text: 'Reportes por Alumno' + }, + { + state: 'reportesClase', + text: 'Reportes por Clase' + }, + { + state: 'reportesSeccion', + text: 'Reportes por Seccion' + }, + { + state: 'reportesMateria', + text: 'Reportes por Materia' + } + ] + } + ]; + + + }]) + +})(); diff --git a/app/js/student/student.controllers.js b/app/js/student/student.controllers.js new file mode 100644 index 0000000..49d3d70 --- /dev/null +++ b/app/js/student/student.controllers.js @@ -0,0 +1,258 @@ +(function(){ + 'use strict'; + + angular + .module('app.student') + .controller('listarEstudianteCtrl', listarEstudianteCtrl) + .controller('crearEstudianteCtrl', crearEstudianteCtrl) + .controller('actualizarEstudianteCtrl', actualizarEstudianteCtrl) + + listarEstudianteCtrl.$inject = [ '$scope', '$rootScope', '$location', 'students', '$modal', 'estudianteSeleccionado' ]; + function listarEstudianteCtrl( $scope, $rootScope, $location, students, $modal, estudianteSeleccionado ){ + + var vm = this; + vm.lista = true; + $rootScope.actOk = false; + $rootScope.loading = true; + $rootScope.table = false; + + var estudiantesArray = []; + students.query( + function(data){ + vm.estudiantes = data; + angular.forEach(vm.estudiantes, function (value){ + estudiantesArray.push({ + Cedula:value.id, + Nombre:value.name, + Apellido:value.lastname, + Telefono:value.number, + Correo: value.email + }); + }); + $rootScope.loading = false; + $rootScope.table = true; + vm.listaEstudiantes = estudiantesArray; + + }, + function(){ + console.log("Error al obtener los datos."); + }); + + vm.eliminarEstudianteModal = function (index) { + $rootScope.index = index; + $rootScope.botonOK = true; + $rootScope.botonCancelar = true; + $rootScope.acceptButton = false; + + $rootScope.rsplice = false; + $rootScope.listarEstudiantesLoading = true; + $rootScope.mensaje = "¿Seguro que desea eliminar el Estudiante?"; + + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'partials/students/modal/list_students_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return ""; + } + } + }); + }; + + vm.eliminarEstudiante = function (index) { + + $rootScope.botonOK = false; + $rootScope.acceptButton = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarEstudiante'; + $rootScope.listarEstudiantesLoading = true; + + students.delete({id: vm.estudiantes[index]._id}, + function (successResult) { + $rootScope.listarEstudiantesLoading = false; + $rootScope.rsplice = true; + $rootScope.mensaje = "Usuario " + vm.estudiantes[index].name + " eliminado"; + }, + function (errorResult) { + $rootScope.listarEstudiantesLoading = false; + $rootScope.mensaje = "Error eliminando al Usuario " + vm.estudiantes[index].name; + }); + }; + + vm.removeEstudianteSplice = function(index, rsplice) { + if(rsplice){ + vm.listaEstudiantes.splice(index, 1); + $rootScope.rsplice = false; + } + }; + + vm.modificarEstudiante = function (index) { + estudianteSeleccionado._id = vm.estudiantes[index]._id; + estudianteSeleccionado.Cedula = vm.estudiantes[index].id; + estudianteSeleccionado.Nombre = vm.estudiantes[index].name; + estudianteSeleccionado.Apellido= vm.estudiantes[index].lastname; + estudianteSeleccionado.Telefono = vm.estudiantes[index].number; + estudianteSeleccionado.Correo= vm.estudiantes[index].email; + $location.url('actualizarEstudiante'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + $rootScope.opened = true; + }; + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + return vm; + }; + + crearEstudianteCtrl.$inject = ['$scope','$rootScope', '$location', 'students', '$modal']; + function crearEstudianteCtrl($scope, $rootScope, $location, students, $modal){ + + var vm = this; + $rootScope.mensaje = ""; + $rootScope.actOk = false; + + vm.submit = function() { + + if (vm.data_input_form.$valid){ + var person = { + "id": vm.estudiante.Cedula, + "name": vm.estudiante.Nombre, + "lastname": vm.estudiante.Apellido, + "email": vm.estudiante.Correo, + "number": vm.estudiante.Telefono, + }; + + $rootScope.crearEstudianteLoading = true; + $rootScope.botonOk = false; + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'partials/students/modal/create_students_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return $rootScope.items; + } + } + }); + + students.save(person, + function(){ + $rootScope.botonOk = true; + $rootScope.urlLo = 'listarEstudiante'; + $rootScope.mensaje = "Estudiante " + vm.estudiante.Apellido + ", " + vm.estudiante.Nombre + " agregado"; + $rootScope.crearEstudianteLoading = false; + }, + + function(){ + $rootScope.botonOk = true; + $rootScope.urlLo = 'listarEstudiante'; + $rootScope.mensaje = "Error al agregar al estudiante " + vm.estudiante.Apellido + ", " + vm.estudiante.Nombre; + $rootScope.crearEstudianteLoading = false; + }); + }else{ + + vm.submitted = true; + } + } + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + + $rootScope.opened = true; + }; + + return vm; + }; + + actualizarEstudianteCtrl.$inject = [ '$scope','$rootScope', '$location', 'students', '$modal', 'estudianteSeleccionado' ]; + function actualizarEstudianteCtrl ( $scope, $rootScope, $location, students, $modal, estudianteSeleccionado ){ + + var vm = this; + vm.estudiante = estudianteSeleccionado; + $rootScope.mensaje = ""; + $rootScope.actOk = false; + + vm.submit = function() { + + var student = { + "_id": vm.estudiante._id, + "id": vm.estudiante.Cedula, + "name": vm.estudiante.Nombre, + "lastname": vm.estudiante.Apellido, + "email": vm.estudiante.Correo, + "number": vm.estudiante.Telefono, + }; + + $rootScope.botonOk = false; + $rootScope.modificarEstudianteLoading = true; + + $scope.modalInstance = $modal.open({ + animation: $rootScope.animationsEnabled, + templateUrl: 'partials/students/modal/update_students_modal.html', + scope: $scope, + size: 'sm', + resolve: { + items: function () { + return $rootScope.items; + } + } + }); + + students.update(student, + function(){ + $rootScope.botonOk = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarEstudiante'; + $rootScope.mensaje = "Estudiante " + vm.estudiante.Apellido + ", " + vm.estudiante.Nombre + " actualizado"; + }, + function(){ + $rootScope.botonOk = true; + $rootScope.botonCancelar = false; + $rootScope.urlLo = 'listarEstudiante'; + $rootScope.mensaje = "Error al modificar al estudiante " + vm.estudiante.Apellido + ", " + vm.estudiante.Nombre; + }); + } + + $scope.ok = function (urlLo) { + $location.url(urlLo); + $scope.modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $scope.modalInstance.dismiss('cancel'); + }; + + $rootScope.open = function($event) { + $event.preventDefault(); + $event.stopPropagation(); + + $rootScope.opened = true; + }; + + return vm; + }; + +})(); \ No newline at end of file diff --git a/app/js/student/student.module.js b/app/js/student/student.module.js new file mode 100644 index 0000000..13f4f13 --- /dev/null +++ b/app/js/student/student.module.js @@ -0,0 +1,75 @@ +(function(){ + 'use strict'; + + angular + .module("app.student", ['ui.router', 'ui.bootstrap']) + .run(addStateToScope) + .config(getRoutes); + + addStateToScope.$inject = ['$rootScope', '$state', '$stateParams']; + function addStateToScope($rootScope, $state, $stateParams){ + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + }; + + getRoutes.$inject = ['$stateProvider', '$urlRouterProvider']; + function getRoutes($stateProvider, $urlRouterProvider){ + $urlRouterProvider.otherwise('/listarEstudiante'); + + $stateProvider + .state('listarEstudiante', { + url: '/listarEstudiante', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/students/list_students.html', + controller: 'listarEstudianteCtrl', + controllerAs: 'vm' + } + } + }) + + .state('crearEstudiante', { + url: '/crearEstudiante', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/students/create_students.html', + controller: 'crearEstudianteCtrl', + controllerAs: 'vm' + } + } + }) + + .state('actualizarEstudiante', { + url: '/actualizarEstudiante', + views: { + sidebar: { + templateUrl: 'partials/sidebar.html', + controller: 'sidebarCtrl' + }, + navbar: { + templateUrl: 'partials/navbar.html' + }, + content: { + templateUrl: 'partials/students/update_students.html', + controller: 'actualizarEstudianteCtrl', + controllerAs: 'vm' + } + } + }) + }; +})(); diff --git a/app/js/student/student.services.js b/app/js/student/student.services.js new file mode 100644 index 0000000..7e42390 --- /dev/null +++ b/app/js/student/student.services.js @@ -0,0 +1,16 @@ +(function(){ + 'use strict'; + + angular + .module('app.student') + .factory('students', students) + .value('estudianteSeleccionado',{}); + + students.$inject = ['$resource','$rootScope']; + function students($resource, $rootScope){ + return $resource('http://'+$rootScope.domainUrl+'/students/:id', null, + { + 'update': {method:'PUT'} + }); + }; +})(); \ No newline at end of file diff --git a/app/login.html b/app/login.html new file mode 100644 index 0000000..5e11b4e --- /dev/null +++ b/app/login.html @@ -0,0 +1,65 @@ +
+
+
+

Ingrese sus Datos

+
+
+
+
+ + +
+ + {{'TAG_NICK_NAME_ERROR'}} + +
+
+
+


+
+
+
+
+ + +
{{ vm.password = vm.user.Password }}
+
+ + {{'TAG_PASSWORD_ERROR'}} + +
+
{{getHash(vm.password)}}
+
+
+
+
+ +
+
+
+ +

+ + + +

+ +
+
+
+ +
+ diff --git a/app/partials/course/create_course.html b/app/partials/course/create_course.html new file mode 100644 index 0000000..e911a47 --- /dev/null +++ b/app/partials/course/create_course.html @@ -0,0 +1,82 @@ +
+
+
+

Datos de la Materia

+
+
+
+
+ + +
+ + El Código de la Materia es Obligatorio. + +
+
+
+ + +
+ + El Nombre de la Materia es Obligatorio. + +
+
+
+

+
+
+
+ + +
+ + La Cantidad de Creditos es Obligatoria. + +
+
+
+ + +
+ + Por favor, inserte una breve descripción. + +
+
+
+


+
+
+
+
+
+ +

+ + + +

+
+
+
+
+
\ No newline at end of file diff --git a/app/partials/course/list_course.html b/app/partials/course/list_course.html new file mode 100644 index 0000000..2a179e6 --- /dev/null +++ b/app/partials/course/list_course.html @@ -0,0 +1,70 @@ +
+

Lista de Materias

+


+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ + Código + + + + + + Nombre + + + + + + Creditos + + + + + + Descripción + + + Eliminar +
{{ materia.Codigo }}{{ materia.Nombre }}{{ materia.Creditos }}{{ materia.Descripcion }} + +
+
+
{{ vm.eliminarMateriaSplice(index, rsplice) }}
+
\ No newline at end of file diff --git a/app/partials/course/modal/create_course_modal.html b/app/partials/course/modal/create_course_modal.html new file mode 100644 index 0000000..3ccc3c9 --- /dev/null +++ b/app/partials/course/modal/create_course_modal.html @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/app/partials/course/modal/delete_course_modal.html b/app/partials/course/modal/delete_course_modal.html new file mode 100644 index 0000000..2737cc8 --- /dev/null +++ b/app/partials/course/modal/delete_course_modal.html @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/partials/course/modal/upgrade_course_modal.html b/app/partials/course/modal/upgrade_course_modal.html new file mode 100644 index 0000000..4c0b027 --- /dev/null +++ b/app/partials/course/modal/upgrade_course_modal.html @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/app/partials/course/update_course.html b/app/partials/course/update_course.html new file mode 100644 index 0000000..1e2011c --- /dev/null +++ b/app/partials/course/update_course.html @@ -0,0 +1,72 @@ +
+
+
+

Datos de la Materia

+
+
+
+
+ + +
+
+ + +
+ + El Nombre de la Materia es Obligatorio. + +
+
+
+


+
+
+ + +
+ + La Cantidad de Creditos es Obligatoria. + +
+
+
+ + +
+ + El Semestre es Obligatorio. + +
+
+
+


+
+
+
+
+
+ +

+ + + +

+
+
+
+
+
\ No newline at end of file diff --git a/app/partials/navbar.html b/app/partials/navbar.html new file mode 100644 index 0000000..63db001 --- /dev/null +++ b/app/partials/navbar.html @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/app/partials/professor/create_professor.html b/app/partials/professor/create_professor.html new file mode 100644 index 0000000..9cac0e3 --- /dev/null +++ b/app/partials/professor/create_professor.html @@ -0,0 +1,95 @@ +
+
+
+

Datos del Profesor

+
+
+
+
+ + +
+ + El Número de Cédula del Profesor es Obligatorio. + +
+
+
+ + +
+ + El Nombre del Profesor es Obligatorio. + +
+
+
+ + +
+ + El Apellido del Profesor es obligatorio. + +
+
+
+


+
+
+ + +
+ + El Correo del Profesor es obligatorio. + + + El Formato del Correo del Profesor es incorrecto. + +
+
+
+ + + + El Formato del Número de Teléfono es incorrecto. + +
+
+
+
+
+
+
+ +

+ + + +

+
+
+
+
+
+ diff --git a/app/partials/professor/list_professor.html b/app/partials/professor/list_professor.html new file mode 100644 index 0000000..da24bb2 --- /dev/null +++ b/app/partials/professor/list_professor.html @@ -0,0 +1,53 @@ +
+

Listado de Profesores

+
+
+ + + + + + + + + + + + + + + + + + + +
+ + Cedula + + + + + + Nombre + + + + + + Apellido + + + + + Modificar + + Borrar +
{{ profesor.Cedula }}{{ profesor.Nombre }}{{ profesor.Apellido }} + + + +
+
+
{{ vm.removeProfesorSplice(index, rsplice) }}
+
diff --git a/app/partials/professor/modal/create_professor_modal.html b/app/partials/professor/modal/create_professor_modal.html new file mode 100644 index 0000000..ae039ab --- /dev/null +++ b/app/partials/professor/modal/create_professor_modal.html @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/app/partials/professor/modal/list_professor_modal.html b/app/partials/professor/modal/list_professor_modal.html new file mode 100644 index 0000000..4036b7f --- /dev/null +++ b/app/partials/professor/modal/list_professor_modal.html @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/partials/professor/modal/update_professor_modal.html b/app/partials/professor/modal/update_professor_modal.html new file mode 100644 index 0000000..f863686 --- /dev/null +++ b/app/partials/professor/modal/update_professor_modal.html @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/app/partials/professor/update_professor.html b/app/partials/professor/update_professor.html new file mode 100644 index 0000000..4a01eb2 --- /dev/null +++ b/app/partials/professor/update_professor.html @@ -0,0 +1,62 @@ +
+
+
+
+
+
+
+

Modificar Profesor


+
+
+
+ + +
+
+ + +
+
+ + +
+
+


+
+
+
+ + + + El formato del Correo del Profesor es incorrecto. + +
+
+ + + + El formato del Teléfono debe ser: 0212-789-5551. + +
+
+
+
+
+
+
+ +

+ + + +

+
+
+
+
\ No newline at end of file diff --git a/app/partials/report/report.html b/app/partials/report/report.html new file mode 100644 index 0000000..638a1f3 --- /dev/null +++ b/app/partials/report/report.html @@ -0,0 +1,116 @@ +
+ +
+
+
+
Reporte Alumno +
+
+
+ + +
    +
  • {{'TAG_FOREIGN' }}
  • +
  • {{'TAG_RESIDENT' }}
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
Reporte por Clase +
+
+
+ + +
    +
  • {{'TAG_ECONOMIC_PASSIVE' }}
  • +
  • {{'TAG_ECONOMIC_ACTIVE' }}
  • +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
Reporte por Sección +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
Reporte por Materia +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + diff --git a/app/partials/section/create_section.html b/app/partials/section/create_section.html new file mode 100644 index 0000000..117f2ed --- /dev/null +++ b/app/partials/section/create_section.html @@ -0,0 +1,80 @@ +
+
+
+

Nueva Matricula

+
+
+
+
+ + +
+
+ + +
+
+ + +
+ + El Semestre es obligatorio. + +
+
+
+


+
+
+ + +
+ + La sección es obligatoria. + +
+
+

+ + + +
+

+
+
+
+
+
+
+
+ +

+ + + +

+
+
+
+
+
\ No newline at end of file diff --git a/app/partials/section/list_section.html b/app/partials/section/list_section.html new file mode 100644 index 0000000..88a12ae --- /dev/null +++ b/app/partials/section/list_section.html @@ -0,0 +1,69 @@ +
+

Listado de Secciones


+
+ + + + + + + + + + + + + + + + + + + + + + +
+ + Sección + + + + + + Nombre de la Materia + + + + + + Codigo de la Materia + + + + + + Semestre + + + + + Modificar + + Borrar +
{{ matricula.Nombre }}{{ matricula.Materia }}{{ matricula.Codigo }}{{ matricula.Semestre }} + + + +
+
+
{{ vm.eliminarMatriculaSplice(index, rsplice) }}
+
\ No newline at end of file diff --git a/app/partials/section/modal/create_section_modal.html b/app/partials/section/modal/create_section_modal.html new file mode 100644 index 0000000..8d22a91 --- /dev/null +++ b/app/partials/section/modal/create_section_modal.html @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/app/partials/section/modal/delete_section_modal.html b/app/partials/section/modal/delete_section_modal.html new file mode 100644 index 0000000..c6ad3d2 --- /dev/null +++ b/app/partials/section/modal/delete_section_modal.html @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/partials/section/modal/update_section_modal.html b/app/partials/section/modal/update_section_modal.html new file mode 100644 index 0000000..1fd33a3 --- /dev/null +++ b/app/partials/section/modal/update_section_modal.html @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/partials/section/update_section.html b/app/partials/section/update_section.html new file mode 100644 index 0000000..b5bfa36 --- /dev/null +++ b/app/partials/section/update_section.html @@ -0,0 +1,54 @@ +
+

Estudiantes Inscritos en {{ vm.matricula.Nombre }} - Seccion {{ vm.matricula.Seccion }} - Semestre {{ vm.matricula.Semestre }}

+
+
+ + + + + + + + + + + + + + + + + +
+ + Cedula + + + + + + Nombre + + + + + + Apellido + + + + + Retirar +
{{ estudiante.Cedula }}{{ estudiante.Nombre }}{{ estudiante.Apellido }} + +
+
+ +
{{ vm.retirarEstudianteSplice(index, rsplice) }}
+
+ Regresar +
+
\ No newline at end of file diff --git a/app/partials/sidebar.html b/app/partials/sidebar.html new file mode 100644 index 0000000..d5f3d53 --- /dev/null +++ b/app/partials/sidebar.html @@ -0,0 +1,21 @@ + + diff --git a/app/partials/students/create_students.html b/app/partials/students/create_students.html new file mode 100644 index 0000000..010574e --- /dev/null +++ b/app/partials/students/create_students.html @@ -0,0 +1,93 @@ +
+
+
+

Datos del Nuevo Alumno

+
+
+
+
+ + +
+ + El Numero de Cedula del Alumno es obligatorio. + +
+
+
+ + +
+ + El Nombre del Alumno es obligatorio. + +
+
+
+ + +
+ + El Apellido del Alumno es obligatorio. + +
+
+
+
+

+
+
+ + +
+ + El Correo del Alumno es obligatorio. + + + El formato del Correo del Alumno es incorrecto. + +
+
+
+ + + + El Formato del Numero de Telefono es incorrecto. + +
+
+
+
+
+
+
+ +

+ + + +

+
+
+
+
+
\ No newline at end of file diff --git a/app/partials/students/list_students.html b/app/partials/students/list_students.html new file mode 100644 index 0000000..765430e --- /dev/null +++ b/app/partials/students/list_students.html @@ -0,0 +1,67 @@ +
+

Listado de Estudiantes

+
+
+ + + + + + + + + + + + + + + + + + + +
+ + Cedula + + + + + + Nombre + + + + + + Apellido + + + + + Modificar + + Borrar +
{{ estudiante.Cedula }}{{ estudiante.Nombre }}{{ estudiante.Apellido }} + + + +
+
+
{{vm.removeEstudianteSplice(index, rsplice)}}
+
\ No newline at end of file diff --git a/app/partials/students/modal/create_students_modal.html b/app/partials/students/modal/create_students_modal.html new file mode 100644 index 0000000..a441654 --- /dev/null +++ b/app/partials/students/modal/create_students_modal.html @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/partials/students/modal/list_students_modal.html b/app/partials/students/modal/list_students_modal.html new file mode 100644 index 0000000..8893447 --- /dev/null +++ b/app/partials/students/modal/list_students_modal.html @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/partials/students/modal/update_students_modal.html b/app/partials/students/modal/update_students_modal.html new file mode 100644 index 0000000..716f17d --- /dev/null +++ b/app/partials/students/modal/update_students_modal.html @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/app/partials/students/update_students.html b/app/partials/students/update_students.html new file mode 100644 index 0000000..67947f8 --- /dev/null +++ b/app/partials/students/update_students.html @@ -0,0 +1,69 @@ +
+
+
+
+
+
+

Modificar Estudiante

+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+


+
+
+
+ + + + El formato del Correo del Alumno es incorrecto. + +
+
+ + + + El formato del Teléfono debe ser: 0212-789-5551. + +
+
+
+
+
+
+
+ +

+ + + +

+
+
+
+
\ No newline at end of file diff --git a/app/server.js b/app/server.js new file mode 100644 index 0000000..35ac606 --- /dev/null +++ b/app/server.js @@ -0,0 +1,188 @@ +var express = require('express'); +var app = express(); +var mongojs = require('mongojs'); +var db = mongojs('AttendanceDB', + ['Courses', 'Professors', 'Sections', 'Students']); +var bodyParser = require('body-parser'); + +app.use(express.static(__dirname)); +app.use(bodyParser.json()); + +app.get('/students', function(req, res){ + console.log('Received get all request'); + db.Students.find(function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.get('/students/:id', function(req, res){ + console.log('Received get request'); + db.Students.findOne( + {_id: new mongojs.ObjectId(req.params.id)}, function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.post('/students', function(req, res){ + console.log('Received add request'); + console.log(req.body); + db.Students.insert(req.body, function(docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.delete('/students/:id', function(req, res){ + console.log("Received delete request..."); + db.Students.remove( + {_id: new mongojs.ObjectId(req.params.id)}, function(err, docs){ + console.log(docs); + res.json(docs); + }); +}); + +app.put('/students', function(req, res){ + console.log("Received update request"); + console.log(req.body); + db.Students.findAndModify({query: + {"_id": new mongojs.ObjectId(req.body._id)}, + update: {$set: {email: req.body.email, number: req.body.number}} + }, function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.get('/courses', function(req, res){ + console.log('Received get all request'); + db.Courses.find(function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.get('/courses/:id', function(req, res){ + console.log('Received get request'); + db.Courses.findOne( + {_id: new mongojs.ObjectId(req.params.id)}, function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.post('/courses', function(req, res){ + console.log('Received add request'); + console.log(req.body); + db.Courses.insert(req.body, function(docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.delete('courses/:id', function(req, res){ + console.log("Received delete request..."); + db.Courses.remove( + {_id: new mongojs.ObjectId(req.params.id)}, function(err, docs){ + console.log(docs); + res.json(docs); + }); +}); + +app.get('/sections', function(req, res){ + console.log('Received get all request'); + db.Sections.find(function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.get('/sections/:id', function(req, res){ + console.log('Received get request'); + db.Sections.findOne( + {_id: new mongojs.ObjectId(req.params.id)}, function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.post('/sections', function(req, res){ + console.log('Received add request'); + console.log(req.body); + db.Sections.insert(req.body, function(docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.delete('/sections/:id', function(req, res){ + console.log("Received delete request..."); + db.Sections.remove( + {_id: new mongojs.ObjectId(req.params.id)}, function(err, docs){ + console.log(docs); + res.json(docs); + }); +}); + +app.put('/sections', function(req, res){ + console.log("Received update request"); + console.log(req.body); + db.Sections.findAndModify({query: + {"_id": new mongojs.ObjectId(req.body._id)}, + update: {$set: {students: req.body.students}} + }, function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.get('/professors', function(req, res){ + console.log('Received get all request'); + db.Professors.find(function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.get('/professors/:id', function(req, res){ + console.log('Received get request'); + db.Professors.findOne({_id: new mongojs.ObjectId(req.params.id)}, + function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.post('/professors', function(req, res){ + console.log('Received add request'); + console.log(req.body); + db.Professors.insert(req.body, function(docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.delete('/professors/:id', function(req, res){ + console.log("Received delete request..."); + db.Professors.remove({_id: new mongojs.ObjectId(req.params.id)}, + function(err, docs){ + console.log(docs); + res.json(docs); + }); +}); + +app.put('/professors', function(req, res){ + console.log("Received update request"); + console.log(req.body); + db.Professors.findAndModify({query: + {"_id": new mongojs.ObjectId(req.body._id)}, + update: {$set: {email: req.body.email, number: req.body.number}} + }, function(err, docs){ + console.log(docs); + res.json(docs); + }) +}); + +app.listen(3000); +console.log("server running on port 3000"); \ No newline at end of file diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..04e9706 --- /dev/null +++ b/bower.json @@ -0,0 +1,44 @@ +{ + "name": "M.A.S.A App", + "description": "M.A.S.A Project", + "version": "1.0.0", + "homepage": "https://github.com/angular/angular-seed", + "license": "MIT", + "private": true, + "dependencies": { + "angular": "~1.4.0", + "angular-resource": "~1.4.0", + "angular-ui-router": "~0.2.15", + "angular-messages": "~1.4.0", + "ngstorage": "~0.3.4", + "angular-route": "1.4.0", + "angular-loader": "1.3.x", + "angular-mocks": "~1.3.x", + "html5-boilerplate": "~4.3.0", + "angular-bootstrap": "~0.13.0", + "bootstrap": "3.x", + "ui.bootstrap": "~0.13.0", + "angular-base64": "*", + "angular-locale_es-es": "*", + "crypto-js": "*", + "angular-animate": "*", + "font-awesome": "*", + "angular-drag-and-drop-lists": "*", + "jspdf": "*", + "ng-file-upload-shim": "*", + "ng-file-upload": "*", + "base64": "*", + "lodash": "*", + "angular-simple-logger": "*", + "angular-google-maps": "*", + "angular-translate": "^2.6.1", + "angular-translate-loader-static-files": "^2.6.1", + "angular-translate-storage-local": "^2.6.1", + "ng-scrollable": "~0.2.3", + "ng-scrollbar": "~0.0.8", + "angular-chart.js": "~0.8.8" + }, + "resolutions": { + "angular": "1.4.0" + } +} diff --git a/components/version/interpolate-filter.js b/components/version/interpolate-filter.js new file mode 100644 index 0000000..3d5c19c --- /dev/null +++ b/components/version/interpolate-filter.js @@ -0,0 +1,9 @@ +'use strict'; + +angular.module('sarcFront.version.interpolate-filter', []) + +.filter('interpolate', ['version', function(version) { + return function(text) { + return String(text).replace(/\%VERSION\%/mg, version); + }; +}]); diff --git a/components/version/interpolate-filter_test.js b/components/version/interpolate-filter_test.js new file mode 100644 index 0000000..c367814 --- /dev/null +++ b/components/version/interpolate-filter_test.js @@ -0,0 +1,15 @@ +'use strict'; + +describe('sarcFront.version module', function() { + beforeEach(module('sarcFront.version')); + + describe('interpolate filter', function() { + beforeEach(module(function($provide) { + $provide.value('version', 'TEST_VER'); + })); + + it('should replace VERSION', inject(function(interpolateFilter) { + expect(interpolateFilter('before %VERSION% after')).toEqual('before TEST_VER after'); + })); + }); +}); diff --git a/components/version/version-directive.js b/components/version/version-directive.js new file mode 100644 index 0000000..34d98a2 --- /dev/null +++ b/components/version/version-directive.js @@ -0,0 +1,9 @@ +'use strict'; + +angular.module('sarcFront.version.version-directive', []) + +.directive('appVersion', ['version', function(version) { + return function(scope, elm, attrs) { + elm.text(version); + }; +}]); diff --git a/components/version/version-directive_test.js b/components/version/version-directive_test.js new file mode 100644 index 0000000..16d1450 --- /dev/null +++ b/components/version/version-directive_test.js @@ -0,0 +1,17 @@ +'use strict'; + +describe('sarcFront.version module', function() { + beforeEach(module('sarcFront.version')); + + describe('app-version directive', function() { + it('should print current version', function() { + module(function($provide) { + $provide.value('version', 'TEST_VER'); + }); + inject(function($compile, $rootScope) { + var element = $compile('')($rootScope); + expect(element.text()).toEqual('TEST_VER'); + }); + }); + }); +}); diff --git a/components/version/version.js b/components/version/version.js new file mode 100644 index 0000000..80f6039 --- /dev/null +++ b/components/version/version.js @@ -0,0 +1,8 @@ +'use strict'; + +angular.module('sarcFront.version', [ + 'sarcFront.version.interpolate-filter', + 'sarcFront.version.version-directive' +]) + +.value('version', '0.1'); diff --git a/components/version/version_test.js b/components/version/version_test.js new file mode 100644 index 0000000..15aadb5 --- /dev/null +++ b/components/version/version_test.js @@ -0,0 +1,11 @@ +'use strict'; + +describe('sarcFront.version module', function() { + beforeEach(module('sarcFront.version')); + + describe('version service', function() { + it('should return current version', inject(function(version) { + expect(version).toEqual('0.1'); + })); + }); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..28d75f4 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "masa-front", + "version": "1.0.0", + "description": "Frontend for M.A.S.A. App.", + "main": "app/index.html", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git@bitbucket.org:PosmaGroup/censys-front.git" + }, + "author": "Posma Group C.A.", + "license": "MIT", + "devDependencies": { + "karma": "^0.13.9" + }, + "dependencies": { + "express" : "latest", + "gulp":"latest" + } +}