From bc01c84473ee42ba0d93910bb80291bad864dd49 Mon Sep 17 00:00:00 2001 From: Alex White Date: Fri, 22 Apr 2016 13:09:55 -0500 Subject: [PATCH 001/233] Adding comment to .gitignore in order to push a change to develop branch and trigger a docker hub image build --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4749fef..0b8a22b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /bower_components +#IntelliJ/WebStorm /.idea *.iml From 7c009be53503e2459dfbc78c8a510976b15bf0ad Mon Sep 17 00:00:00 2001 From: Alex White Date: Fri, 22 Apr 2016 15:49:25 -0500 Subject: [PATCH 002/233] Updating grunt-contrib-compass and update Dockerfile to install ruby/compass --- Dockerfile | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c0d4fc8..a607b69 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,10 @@ RUN mkdir /stlcourts-client COPY . /stlcourts-client WORKDIR /stlcourts-client +#Install Ruby & Compass +RUN apt-get install -y ruby-full +RUN gem install compass + RUN npm set progress=false && npm install RUN bower --allow-root install diff --git a/package.json b/package.json index 7b3ff27..7730512 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "grunt-autoprefixer": "^3.0.4", "grunt-concurrent": "^1.0.0", "grunt-contrib-clean": "^1.0.0", - "grunt-contrib-compass": "^1.0.0", + "grunt-contrib-compass": "^1.1.1", "grunt-contrib-concat": "^0.5.0", "grunt-contrib-connect": "^0.9.0", "grunt-contrib-copy": "^0.7.0", From 54c28b7626c8c3c68e7e55170ba8fea58eb1a916 Mon Sep 17 00:00:00 2001 From: s0042625 Date: Wed, 27 Apr 2016 10:54:46 -0500 Subject: [PATCH 003/233] Update logo to real yourSTLCourts logo --- app/images/communisee.png | Bin 27320 -> 0 bytes app/images/ystlc-logo.png | Bin 0 -> 62438 bytes app/views/header.html | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 app/images/communisee.png create mode 100644 app/images/ystlc-logo.png diff --git a/app/images/communisee.png b/app/images/communisee.png deleted file mode 100644 index 1894f255ae2fbfc4afdf19c185eaf9117564c466..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27320 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 bh;YJ;L!flzSDdh41Hj1vls{HW8VCI!=Z8dH diff --git a/app/images/ystlc-logo.png b/app/images/ystlc-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3f1495eb2c82a7c26240c57428576e5e46861a14 GIT binary patch literal 62438 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

Dgvbc1MSrjhn1wtN7vdoR1ePq!L-7A-`tCrg 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

{JQiBHI?A^mIi~RKt@&MnBvjjlM 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 - +

From 3990122c1a51b68618a7456745f0b4e85b1e681d Mon Sep 17 00:00:00 2001 From: matt598 Date: Sun, 19 Jun 2016 22:18:14 -0500 Subject: [PATCH 018/233] added comments/notes --- app/views/citationInfo.html | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/citationInfo.html b/app/views/citationInfo.html index 7de62d3..a8f4d83 100644 --- a/app/views/citationInfo.html +++ b/app/views/citationInfo.html @@ -47,6 +47,7 @@

I Want To...

+ From e054813cc65e563940916181c6d9806d2cab23b5 Mon Sep 17 00:00:00 2001 From: matt598 Date: Sun, 19 Jun 2016 22:25:06 -0500 Subject: [PATCH 019/233] adding info page to header and re-directing payment options --- app/scripts/app.js | 4 ++++ app/views/PaymentOptions.html | 1 + app/views/header.html | 1 + app/views/help.html | 1 + app/views/info.html | 6 ++++++ 5 files changed, 13 insertions(+) create mode 100644 app/views/info.html diff --git a/app/scripts/app.js b/app/scripts/app.js index 058ca28..a554ec6 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -25,6 +25,10 @@ angular.module('ghAngularApp').config(function($stateProvider, $urlRouterProvide url: '/help', templateUrl: 'views/help.html' }) + .state('info', { + url: '/info', + templateUrl: 'views/info.html' + }) .state('citationInfo', { url: '/ticketInfo', templateUrl: 'views/citationInfo.html', diff --git a/app/views/PaymentOptions.html b/app/views/PaymentOptions.html index 36cb3d6..f4fd8f9 100644 --- a/app/views/PaymentOptions.html +++ b/app/views/PaymentOptions.html @@ -1,3 +1,4 @@ +
From df5984d9749a20aa8f5a83bbfd2ffe7ab7ec4274 Mon Sep 17 00:00:00 2001 From: Alex White Date: Thu, 23 Jun 2016 01:02:25 -0500 Subject: [PATCH 027/233] Rename ghAngular angular module to yourStlCourts --- Gruntfile.js | 2 +- README.md | 2 +- app/index.html | 2 +- app/scripts/app.js | 6 +++--- app/scripts/controllers/citationInfo.ctrl.js | 2 +- app/scripts/controllers/dobPicker.ctrl.js | 2 +- app/scripts/controllers/header.ctrl.js | 2 +- app/scripts/controllers/home.ctrl.js | 2 +- app/scripts/controllers/locationPickerMap.ctrl.js | 2 +- app/scripts/controllers/opportunityCreate.ctrl.js | 2 +- app/scripts/controllers/opportunityDetails.ctrl.js | 2 +- app/scripts/controllers/opportunityNeedCreate.ctrl.js | 2 +- app/scripts/controllers/paymentOptions.ctrl.js | 2 +- app/scripts/controllers/sponsorLogin.ctrl.js | 2 +- app/scripts/controllers/sponsorManagement.ctrl.js | 2 +- app/scripts/directives/formField.dir.js | 2 +- app/scripts/directives/layout.dir.js | 2 +- app/scripts/directives/ngTranscludeReplace.dir.js | 2 +- app/scripts/services/Auth.svc.js | 2 +- app/scripts/services/Citations.svc.js | 2 +- app/scripts/services/Courts.svc.js | 2 +- app/scripts/services/DateFormatter.svc.js | 2 +- app/scripts/services/ErrorMessageResolver.svc.js | 2 +- app/scripts/services/Opportunities.svc.js | 2 +- app/scripts/services/Sponsor.svc.js | 2 +- app/scripts/services/States.svc.js | 2 +- app/scripts/services/ValidationElementModifier.svc.js | 2 +- bower.json | 5 ++++- test/spec/controllers/main.js | 2 +- 29 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 3b7144c..b795d37 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -345,7 +345,7 @@ module.exports = function (grunt) { ngtemplates: { dist: { options: { - module: 'ghAngularApp', + module: 'yourStlCourts', htmlmin: '<%= htmlmin.dist.options %>', usemin: 'scripts/scripts.js' }, diff --git a/README.md b/README.md index e590360..cac6d91 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This project contains the source code for the Angular application at yourstlcour ## Build & development -* Download & Install NodeJS w/ npm +* Download & Install NodeJS (v4.x) w/ npm * Download & Install Ruby * Install grunt-cli `npm install -g grunt-cli` * Install bower `npm install -g bower` diff --git a/app/index.html b/app/index.html index 0e6f588..c429e7f 100644 --- a/app/index.html +++ b/app/index.html @@ -19,7 +19,7 @@ - +
diff --git a/app/scripts/app.js b/app/scripts/app.js index a554ec6..73872d6 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -1,9 +1,9 @@ 'use strict'; -angular.module('ghAngularApp', ['ngResource', 'ngSanitize', 'ngTouch', 'envConfig', 'ui.router', 'esri.map', 'toaster', +angular.module('yourStlCourts', ['ngResource', 'ngSanitize', 'ngTouch', 'envConfig', 'ui.router', 'esri.map', 'toaster', 'ui.bootstrap', 'ui.select', 'jcs-autoValidate']); -angular.module('ghAngularApp').config(function($stateProvider, $urlRouterProvider, ENV, $httpProvider, uiSelectConfig) { +angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvider, ENV, $httpProvider, uiSelectConfig) { $urlRouterProvider.otherwise('/'); $stateProvider @@ -94,7 +94,7 @@ angular.module('ghAngularApp').config(function($stateProvider, $urlRouterProvide uiSelectConfig.searchEnabled = true; }); -angular.module('ghAngularApp').run(function (validator, validationElementModifier, errorMessageResolver) { +angular.module('yourStlCourts').run(function (validator, validationElementModifier, errorMessageResolver) { validator.registerDomModifier(validationElementModifier.key, validationElementModifier); validator.setDefaultElementModifier(validationElementModifier.key); validator.setValidElementStyling(false); diff --git a/app/scripts/controllers/citationInfo.ctrl.js b/app/scripts/controllers/citationInfo.ctrl.js index 7e05708..091ae27 100644 --- a/app/scripts/controllers/citationInfo.ctrl.js +++ b/app/scripts/controllers/citationInfo.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('citationInfoCtrl', function ($state, $window, citations, Courts) { +angular.module('yourStlCourts').controller('citationInfoCtrl', function ($state, $window, citations, Courts) { var ctrl = this; ctrl.selectCitation = function(citation){ diff --git a/app/scripts/controllers/dobPicker.ctrl.js b/app/scripts/controllers/dobPicker.ctrl.js index 25febf7..fb1d7b4 100644 --- a/app/scripts/controllers/dobPicker.ctrl.js +++ b/app/scripts/controllers/dobPicker.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('dobPickerCtrl', function ($uibModalInstance, DateFormatter, toaster) { +angular.module('yourStlCourts').controller('dobPickerCtrl', function ($uibModalInstance, DateFormatter, toaster) { var today = new Date(); var ctrl = this; diff --git a/app/scripts/controllers/header.ctrl.js b/app/scripts/controllers/header.ctrl.js index 0c7ca6a..2e0bf8d 100644 --- a/app/scripts/controllers/header.ctrl.js +++ b/app/scripts/controllers/header.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('HeaderCtrl', function (Auth) { +angular.module('yourStlCourts').controller('HeaderCtrl', function (Auth) { var ctrl = this; ctrl.isAuthenticated = function(){ diff --git a/app/scripts/controllers/home.ctrl.js b/app/scripts/controllers/home.ctrl.js index c81c432..e9a5054 100644 --- a/app/scripts/controllers/home.ctrl.js +++ b/app/scripts/controllers/home.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('HomeCtrl', function (Citations, toaster, States, municipalities, $uibModal, $state) { +angular.module('yourStlCourts').controller('HomeCtrl', function (Citations, toaster, States, municipalities, $uibModal, $state) { var ctrl = this; ctrl.states = States; ctrl.municipalities = municipalities; diff --git a/app/scripts/controllers/locationPickerMap.ctrl.js b/app/scripts/controllers/locationPickerMap.ctrl.js index f79fd76..f92a446 100644 --- a/app/scripts/controllers/locationPickerMap.ctrl.js +++ b/app/scripts/controllers/locationPickerMap.ctrl.js @@ -1,7 +1,7 @@ 'use strict'; /* global esri */ -angular.module('ghAngularApp').controller('locationPickerMapCtrl', function ($scope, esriRegistry, $uibModalInstance, municipalities) { +angular.module('yourStlCourts').controller('locationPickerMapCtrl', function ($scope, esriRegistry, $uibModalInstance, municipalities) { var ctrl = this; ctrl.selectedMunicipalities = []; diff --git a/app/scripts/controllers/opportunityCreate.ctrl.js b/app/scripts/controllers/opportunityCreate.ctrl.js index 2cb2120..7a543dd 100644 --- a/app/scripts/controllers/opportunityCreate.ctrl.js +++ b/app/scripts/controllers/opportunityCreate.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('OpportunityCreateCtrl', function ($uibModalInstance, toaster, Opportunities, Auth, courts) { +angular.module('yourStlCourts').controller('OpportunityCreateCtrl', function ($uibModalInstance, toaster, Opportunities, Auth, courts) { var ctrl = this; ctrl.municipalities = courts; ctrl.opportunity = { diff --git a/app/scripts/controllers/opportunityDetails.ctrl.js b/app/scripts/controllers/opportunityDetails.ctrl.js index 257ef57..98bf995 100644 --- a/app/scripts/controllers/opportunityDetails.ctrl.js +++ b/app/scripts/controllers/opportunityDetails.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('OpportunityDetailsCtrl', function (opportunity, needs, $uibModalInstance, DateFormatter) { +angular.module('yourStlCourts').controller('OpportunityDetailsCtrl', function (opportunity, needs, $uibModalInstance, DateFormatter) { var ctrl = this; ctrl.opportunity = opportunity; ctrl.needs = needs; diff --git a/app/scripts/controllers/opportunityNeedCreate.ctrl.js b/app/scripts/controllers/opportunityNeedCreate.ctrl.js index 39649e2..9ff4388 100644 --- a/app/scripts/controllers/opportunityNeedCreate.ctrl.js +++ b/app/scripts/controllers/opportunityNeedCreate.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('OpportunityNeedCreateCtrl', function ($uibModalInstance, toaster, Opportunities, courts, opportunity) { +angular.module('yourStlCourts').controller('OpportunityNeedCreateCtrl', function ($uibModalInstance, toaster, Opportunities, courts, opportunity) { var ctrl = this; ctrl.municipalities = courts; ctrl.opportunity = opportunity; diff --git a/app/scripts/controllers/paymentOptions.ctrl.js b/app/scripts/controllers/paymentOptions.ctrl.js index 4e0d1f9..557b1d9 100644 --- a/app/scripts/controllers/paymentOptions.ctrl.js +++ b/app/scripts/controllers/paymentOptions.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('PaymentOptionsCtrl', function (citation, Opportunities, $state, $uibModal) { +angular.module('yourStlCourts').controller('PaymentOptionsCtrl', function (citation, Opportunities, $state, $uibModal) { var ctrl = this; ctrl.citation = citation; diff --git a/app/scripts/controllers/sponsorLogin.ctrl.js b/app/scripts/controllers/sponsorLogin.ctrl.js index 89b93f7..7b7b12d 100644 --- a/app/scripts/controllers/sponsorLogin.ctrl.js +++ b/app/scripts/controllers/sponsorLogin.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('SponsorLoginCtrl', function ($state, toaster, Sponsor, Auth) { +angular.module('yourStlCourts').controller('SponsorLoginCtrl', function ($state, toaster, Sponsor, Auth) { var ctrl = this; if(Auth.isAuthenticated()){ $state.go('sponsorMgmt'); diff --git a/app/scripts/controllers/sponsorManagement.ctrl.js b/app/scripts/controllers/sponsorManagement.ctrl.js index c9fb1d8..913ab91 100644 --- a/app/scripts/controllers/sponsorManagement.ctrl.js +++ b/app/scripts/controllers/sponsorManagement.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').controller('SponsorMgmtCtrl', function ($state, Sponsor, Auth, opportunities, courts, +angular.module('yourStlCourts').controller('SponsorMgmtCtrl', function ($state, Sponsor, Auth, opportunities, courts, Opportunities, toaster, $uibModal) { var ctrl = this; diff --git a/app/scripts/directives/formField.dir.js b/app/scripts/directives/formField.dir.js index a080d0d..c0bdb50 100644 --- a/app/scripts/directives/formField.dir.js +++ b/app/scripts/directives/formField.dir.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').directive('formField', function () { +angular.module('yourStlCourts').directive('formField', function () { return { restrict: 'E', require: '^form', diff --git a/app/scripts/directives/layout.dir.js b/app/scripts/directives/layout.dir.js index 8ff0970..5ff2d4f 100644 --- a/app/scripts/directives/layout.dir.js +++ b/app/scripts/directives/layout.dir.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').directive('layout', function () { +angular.module('yourStlCourts').directive('layout', function () { return { restrict: 'A', diff --git a/app/scripts/directives/ngTranscludeReplace.dir.js b/app/scripts/directives/ngTranscludeReplace.dir.js index e254900..5e9d751 100644 --- a/app/scripts/directives/ngTranscludeReplace.dir.js +++ b/app/scripts/directives/ngTranscludeReplace.dir.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').directive('ngTranscludeReplace', [function () { +angular.module('yourStlCourts').directive('ngTranscludeReplace', [function () { return { terminal: true, restrict: 'EA', diff --git a/app/scripts/services/Auth.svc.js b/app/scripts/services/Auth.svc.js index cf3aecd..dbd9992 100644 --- a/app/scripts/services/Auth.svc.js +++ b/app/scripts/services/Auth.svc.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').factory('Auth', function ($state) { +angular.module('yourStlCourts').factory('Auth', function ($state) { function authenticate(sponsor) { localStorage.setItem('sponsor', JSON.stringify(sponsor)); diff --git a/app/scripts/services/Citations.svc.js b/app/scripts/services/Citations.svc.js index 205350d..aeddf6a 100644 --- a/app/scripts/services/Citations.svc.js +++ b/app/scripts/services/Citations.svc.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').factory('Citations', function ($resource) { +angular.module('yourStlCourts').factory('Citations', function ($resource) { var CitationResource = $resource('citations/:id'); function find(parameters) { diff --git a/app/scripts/services/Courts.svc.js b/app/scripts/services/Courts.svc.js index 82c9742..945fdca 100644 --- a/app/scripts/services/Courts.svc.js +++ b/app/scripts/services/Courts.svc.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').factory('Courts', function ($resource, $q) { +angular.module('yourStlCourts').factory('Courts', function ($resource, $q) { var CourtResource = $resource('courts/:id'); var courts; diff --git a/app/scripts/services/DateFormatter.svc.js b/app/scripts/services/DateFormatter.svc.js index 18c9ccf..0284dc0 100644 --- a/app/scripts/services/DateFormatter.svc.js +++ b/app/scripts/services/DateFormatter.svc.js @@ -1,7 +1,7 @@ 'use strict'; /* jshint ignore:start */ -angular.module('ghAngularApp').factory('DateFormatter', function () { +angular.module('yourStlCourts').factory('DateFormatter', function () { var dateFormat = { masks : { "default": "mm/dd/yyyy", diff --git a/app/scripts/services/ErrorMessageResolver.svc.js b/app/scripts/services/ErrorMessageResolver.svc.js index 0ced28a..71e34d2 100644 --- a/app/scripts/services/ErrorMessageResolver.svc.js +++ b/app/scripts/services/ErrorMessageResolver.svc.js @@ -1,5 +1,5 @@ 'use strict'; -angular.module('ghAngularApp').factory('errorMessageResolver', function ($q) { +angular.module('yourStlCourts').factory('errorMessageResolver', function ($q) { /** * Replaces string placeholders with corresponding template string */ diff --git a/app/scripts/services/Opportunities.svc.js b/app/scripts/services/Opportunities.svc.js index d78f283..ea488ca 100644 --- a/app/scripts/services/Opportunities.svc.js +++ b/app/scripts/services/Opportunities.svc.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').factory('Opportunities', function ($resource) { +angular.module('yourStlCourts').factory('Opportunities', function ($resource) { var OpportunitiesResource = $resource('opportunities/:id'); function findBySponsorId(sponsorId) { diff --git a/app/scripts/services/Sponsor.svc.js b/app/scripts/services/Sponsor.svc.js index 453db03..1261611 100644 --- a/app/scripts/services/Sponsor.svc.js +++ b/app/scripts/services/Sponsor.svc.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').factory('Sponsor', function ($http) { +angular.module('yourStlCourts').factory('Sponsor', function ($http) { function Login(credentials) { return $http.post('sponsors/login', credentials); } diff --git a/app/scripts/services/States.svc.js b/app/scripts/services/States.svc.js index 672c2b3..315360d 100644 --- a/app/scripts/services/States.svc.js +++ b/app/scripts/services/States.svc.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('ghAngularApp').factory('States', function () { +angular.module('yourStlCourts').factory('States', function () { return [ 'AL', 'AK', diff --git a/app/scripts/services/ValidationElementModifier.svc.js b/app/scripts/services/ValidationElementModifier.svc.js index 2ca187e..cffe958 100644 --- a/app/scripts/services/ValidationElementModifier.svc.js +++ b/app/scripts/services/ValidationElementModifier.svc.js @@ -1,5 +1,5 @@ 'use strict'; -angular.module('ghAngularApp').factory('validationElementModifier', function () { +angular.module('yourStlCourts').factory('validationElementModifier', function () { var reset = function (el) { angular.forEach(el.find('span.help-block'), function (helpBlock) { helpBlock = angular.element(helpBlock); diff --git a/bower.json b/bower.json index d50114a..348d84c 100644 --- a/bower.json +++ b/bower.json @@ -19,7 +19,7 @@ "angular-mocks": "~1.5.0" }, "appPath": "app", - "moduleName": "ghAngularApp", + "moduleName": "yourStlCourts", "overrides": { "bootstrap": { "main": [ @@ -28,5 +28,8 @@ "dist/js/bootstrap.js" ] } + }, + "resolutions": { + "angular": "~1.5.6" } } diff --git a/test/spec/controllers/main.js b/test/spec/controllers/main.js index cd20d47..a1fdf34 100644 --- a/test/spec/controllers/main.js +++ b/test/spec/controllers/main.js @@ -3,7 +3,7 @@ describe('Controller: MainCtrl', function () { // load the controller's module - beforeEach(module('ghAngularApp')); + beforeEach(module('yourStlCourts')); var MainCtrl, scope; From fb8e5f07e9d217192917bc4717766e468bcf8282 Mon Sep 17 00:00:00 2001 From: Alex White Date: Thu, 23 Jun 2016 01:21:27 -0500 Subject: [PATCH 028/233] Add first meaningful jasmine tests as POC --- README.md | 5 +++ test/spec/controllers/header.ctrl.spec.js | 40 +++++++++++++++++++++++ test/spec/controllers/main.js | 23 ------------- 3 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 test/spec/controllers/header.ctrl.spec.js delete mode 100644 test/spec/controllers/main.js diff --git a/README.md b/README.md index cac6d91..952b807 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,11 @@ This project contains the source code for the Angular application at yourstlcour * Install app dependencies `npm install && bower install` * Install compass `gem install compass` +### Configs +* local = use local API +* uionly = use test API +* production = use API at /api/ (presumably proxied) + ### Build Run `grunt build:(local|uionly|production)` for building and `grunt serve:(local|uionly|production)` for preview. diff --git a/test/spec/controllers/header.ctrl.spec.js b/test/spec/controllers/header.ctrl.spec.js new file mode 100644 index 0000000..6afd21b --- /dev/null +++ b/test/spec/controllers/header.ctrl.spec.js @@ -0,0 +1,40 @@ +'use strict'; + +describe('HeaderCtrl', function () { + + var HeaderCtrl; + + beforeEach(function() { + module('yourStlCourts'); + + inject(function($controller, Auth) { + HeaderCtrl = $controller('HeaderCtrl', { + Auth: Auth + }); + }); + }); + + it('indicates is authenticated', inject(function (Auth) { + spyOn(Auth, 'isAuthenticated').and.returnValue(true); + + var isAuthenticated = HeaderCtrl.isAuthenticated(); + + expect(isAuthenticated).toBe(true); + })); + + it('indicates is not authenticated', inject(function (Auth) { + spyOn(Auth, 'isAuthenticated').and.returnValue(false); + + var isAuthenticated = HeaderCtrl.isAuthenticated(); + + expect(isAuthenticated).toBe(false); + })); + + it('logs out', inject(function(Auth) { + spyOn(Auth, 'logout'); + + HeaderCtrl.logout(); + + expect(Auth.logout).toHaveBeenCalled(); + })); +}); diff --git a/test/spec/controllers/main.js b/test/spec/controllers/main.js deleted file mode 100644 index a1fdf34..0000000 --- a/test/spec/controllers/main.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -describe('Controller: MainCtrl', function () { - - // load the controller's module - beforeEach(module('yourStlCourts')); - - var MainCtrl, - scope; - - // Initialize the controller and a mock scope - beforeEach(inject(function ($controller, $rootScope) { - scope = $rootScope.$new(); - MainCtrl = $controller('MainCtrl', { - $scope: scope - // place here mocked dependencies - }); - })); - - it('should attach a list of awesomeThings to the scope', function () { - expect(MainCtrl.awesomeThings.length).toBe(3); - }); -}); From 7ce9fe7928fc39a2046d547542a2800ca30b09fd Mon Sep 17 00:00:00 2001 From: Alex White Date: Thu, 23 Jun 2016 01:23:45 -0500 Subject: [PATCH 029/233] Run tests in Dockerfile --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a607b69..83791ba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,10 @@ RUN bower --allow-root install # Rebuild node-sass due to some node versioning possible conflicts RUN npm rebuild node-sass -#TODO: Run jasmine tests +RUN npm install -g karma-cli + +#Run jasmine tests +RUN grunt test:local # Building RUN grunt build:production From 1f43b101acb7732bb503742ba2f5808d37cc0ecd Mon Sep 17 00:00:00 2001 From: matt598 Date: Mon, 27 Jun 2016 14:50:47 -0500 Subject: [PATCH 030/233] Fixing Links --- app/views/info.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/info.html b/app/views/info.html index 5733456..7af026c 100644 --- a/app/views/info.html +++ b/app/views/info.html @@ -6,16 +6,16 @@

Info

- Court Rights + Court Rights - Dress Code + Dress Code - Court Fees & Fines + Court Fees & Fines - Contact Information + Contact Information
From 29b6b9015d1d855dabc95f271b9a3d648dc668e2 Mon Sep 17 00:00:00 2001 From: matt598 Date: Mon, 27 Jun 2016 14:52:15 -0500 Subject: [PATCH 031/233] Fixing Links --- app/views/info.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/info.html b/app/views/info.html index 7af026c..ad27cd6 100644 --- a/app/views/info.html +++ b/app/views/info.html @@ -6,16 +6,16 @@

Info

- Court Rights + Court Rights - Dress Code + Dress Code - Court Fees & Fines + Court Fees & Fines - Contact Information + Contact Information
From 1863eba913b4f0a946ae1ea5bfbbfd9aa801e666 Mon Sep 17 00:00:00 2001 From: matt598 Date: Mon, 27 Jun 2016 15:22:25 -0500 Subject: [PATCH 032/233] Tweaking navbar and navbar-brand by moving height 85px; from navbar to navbar-brand --- app/styles/main.scss | 2 +- app/views/info.html | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/styles/main.scss b/app/styles/main.scss index 5ac6f3f..6fefdb0 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -48,7 +48,6 @@ html, body { .navbar { background-color: $lightGrey !important; - height: 85px; } footer { @@ -177,6 +176,7 @@ label { .navbar-brand { padding: 5px !important; + height: 85px; } .navbar-default .navbar-nav > li > a { diff --git a/app/views/info.html b/app/views/info.html index ad27cd6..b9338e0 100644 --- a/app/views/info.html +++ b/app/views/info.html @@ -6,21 +6,22 @@

Info

- Court Rights + Court Rights - Dress Code + Dress Code - Court Fees & Fines + Court Fees & Fines - Contact Information + Contact Information
+
-

Court Rights

+

Court Rights

You must first enter a plea. You may plead not guilty, guilty, or guilty with an explanation. If you plead NOT GUILTY, your case will be set for trial. You must appear on the date and at the time the trial is scheduled or a warrant will be issued for your arrest. At your trial, you should be prepared to present any evidence you believe will help you in your defense. The rules of evidence apply at your trial, which may prevent some evidence you may want to present from being admitted before the Judge.

Your Rights with a Not Guilty Plea are as follows:

    @@ -39,12 +40,14 @@

    If you plead guilty, you give up all the rights listed above

    Punishment and Fines

    After a plea of guilty or a finding of guilty, the court has the authority to assess court fines and/or a jail sentence. The amount assessed by the court is affected by the facts and the circumstances of the case. Mitigating circumstances may lower the fine, but aggravating circumstances may increase the fine. You have a right to know the minimum and maximum punishment for your offense at the start of your trial.

+
-

Dress Code

+

Dress Code

You must dress appropriately if you enter the courthouses. No halter tops, t-shirts, shorts, baggy pants, or other inappropriate clothing will be tolerated. You also must turn off all pagers and cell-phones.

+
-

Court Fees

+

Court Fees

All cases incur a fee of $22.50-$27.50 in addition to the fine associated with the violation. This fee goes toward Basic Court Costs, Crime Victim's Compensation Surcharge, Law Enforcement Training Fund, Peace Officer's Standard Training Fund, Biometric Verification System Surcharge, and the Domestic Violence Shelter Fund. No other fees are assessed.

@@ -199,6 +202,7 @@

Court Fees

*waived if child restraint is purchased before court date

+

Contact Information

From 3e24527d4e44bfec66e9e199fecc8bc386385cab Mon Sep 17 00:00:00 2001 From: matt598 Date: Mon, 27 Jun 2016 15:31:29 -0500 Subject: [PATCH 033/233] Removing DOB column. --- app/views/citationInfo.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/views/citationInfo.html b/app/views/citationInfo.html index 2e0d1c8..14b9218 100644 --- a/app/views/citationInfo.html +++ b/app/views/citationInfo.html @@ -6,7 +6,6 @@

Ticket Results

- @@ -15,7 +14,6 @@

Ticket Results

- - + - + - + - + diff --git a/test/spec/controllers/citationInfo.ctrl.spec.js b/test/spec/controllers/citationInfo.ctrl.spec.js index 3f58965..3ac53a1 100644 --- a/test/spec/controllers/citationInfo.ctrl.spec.js +++ b/test/spec/controllers/citationInfo.ctrl.spec.js @@ -2,6 +2,7 @@ describe('CitationInfoCtrl', function () { var CitationInfoCtrl; + var $anchorScroll = jasmine.createSpy("anchorScroll"); var faqData = { "dataLabel": [ @@ -114,7 +115,8 @@ describe('CitationInfoCtrl', function () { Courts: Courts, Session: session, courts: courts, - moment: moment + moment: moment, + $anchorScroll:$anchorScroll }); }); }); @@ -123,12 +125,23 @@ describe('CitationInfoCtrl', function () { expect(CitationInfoCtrl.faqData).toEqual(faqData); })); - it('correctly sets selected citation', inject(function (Courts, $q, $rootScope,Session) { + it('calls $anchorScroll', inject(function(Courts, $q, $rootScope){ var deferred = $q.defer(); deferred.resolve(court); spyOn(Courts, 'findById').and.returnValue(deferred.promise); - CitationInfoCtrl.selectCitation(citation); + CitationInfoCtrl.selectCitation(citation,'someId'); + $rootScope.$apply(); + + expect($anchorScroll).toHaveBeenCalledWith("someId"); + })); + + it('correctly sets selected citation', inject(function (Courts, $q, $rootScope) { + var deferred = $q.defer(); + deferred.resolve(court); + spyOn(Courts, 'findById').and.returnValue(deferred.promise); + + CitationInfoCtrl.selectCitation(citation,'someId'); $rootScope.$apply(); expect(CitationInfoCtrl.selectedCitation).toEqual(citation); @@ -142,7 +155,7 @@ describe('CitationInfoCtrl', function () { deferred.resolve(court); spyOn(Courts, 'findById').and.returnValue(deferred.promise); - CitationInfoCtrl.selectCitation(citation); + CitationInfoCtrl.selectCitation(citation,'someId'); $rootScope.$apply(); expect(CitationInfoCtrl.paymentUrl).toEqual(municipality.paymentUrl); @@ -157,17 +170,17 @@ describe('CitationInfoCtrl', function () { $rootScope.$apply(); expect (CitationInfoCtrl.showPaymentButton()).toBe(false); - CitationInfoCtrl.selectCitation(citationWithViolations); + CitationInfoCtrl.selectCitation(citationWithViolations,'someId'); CitationInfoCtrl.paymentUrl = "someUrl"; $rootScope.$apply(); expect (CitationInfoCtrl.showPaymentButton()).toBe(false); - CitationInfoCtrl.selectCitation(citationPayableOnline); + CitationInfoCtrl.selectCitation(citationPayableOnline,'someId'); CitationInfoCtrl.paymentUrl = "someUrl"; $rootScope.$apply(); expect (CitationInfoCtrl.showPaymentButton()).toBe(true); - CitationInfoCtrl.selectCitation(citationPayableOnline); + CitationInfoCtrl.selectCitation(citationPayableOnline,'someId'); CitationInfoCtrl.paymentUrl = ""; $rootScope.$apply(); expect (CitationInfoCtrl.showPaymentButton()).toBe(false); From 320d479893fc63969f6504f736f9d70ec5eeff97 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Tue, 25 Apr 2017 10:29:16 -0500 Subject: [PATCH 196/233] fixed datepicker so that it auto advances (#100) --- app/scripts/directives/stlCourtsDatepicker.dir.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/directives/stlCourtsDatepicker.dir.js b/app/scripts/directives/stlCourtsDatepicker.dir.js index 9d1545d..621a125 100644 --- a/app/scripts/directives/stlCourtsDatepicker.dir.js +++ b/app/scripts/directives/stlCourtsDatepicker.dir.js @@ -54,7 +54,7 @@ angular.module('yourStlCourts').directive('stlCourtsDatepicker', function($timeo var maxLength = $(event.target).attr("maxlength"); var numberOfExistingDigits = $(event.target).val().length; updateDateString(); - if (numberOfExistingDigits === maxLength){ + if (numberOfExistingDigits === Number(maxLength)){ //tab to the next field if ($(event.target).next("span") !== $()){ clearInputElement($(event.target).next().next()); From 13c4812261c504c4c738fae30fb33add2722c03c Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Tue, 25 Apr 2017 10:32:11 -0500 Subject: [PATCH 197/233] added "Find Court Info" to mobile menu (#103) --- app/views/header.html | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/header.html b/app/views/header.html index 0ee5af7..ec9d3d8 100644 --- a/app/views/header.html +++ b/app/views/header.html @@ -16,6 +16,7 @@

- YourSTLCourts is the St. Louis region’s only free, web and mobile tool that puts your rights and your case records right at your fingertips. Use your phone or computer to access your court date and location, payment and community service options, and legal rights. Then, sign up to receive reminders of your court date via text message, by texting “help” to {{ctrl.textPhoneNumber}}. Standard SMS rates apply. + YourSTLCourts is the St. Louis region’s only free, web and mobile tool that puts your rights and your case records right at your fingertips. Use your phone or computer to access your court date and location, payment and community service options, and legal rights. Then, sign up to receive reminders of your court date via text message, by texting “Ticket” to {{ctrl.textPhoneNumber}}. Standard SMS rates apply.

For years, many court users have faced difficult navigation, unclear processes, sometimes unfair practices and a lack of effective communication. With a focus on using technology to increase accessibility, YourSTLCourts is incrementally improving how citizens interact with the municipal court system. Our partners have been diligently coding, advocating and building relationships in order to increase government transparency and decrease traffic-related incarcerations through a pre-trial, technology-based-solution known as YourSTLCourts. diff --git a/app/views/header.html b/app/views/header.html index ec9d3d8..da76bee 100644 --- a/app/views/header.html +++ b/app/views/header.html @@ -19,6 +19,7 @@

  • Your Legal Rights
  • Community Service
  • +
  • Help
  • diff --git a/app/views/smsInstructions.html b/app/views/smsInstructions.html new file mode 100644 index 0000000..8427692 --- /dev/null +++ b/app/views/smsInstructions.html @@ -0,0 +1,8 @@ +
    +

    Text Message Help

    +
    +
    +

    + YourSTLCourts is the St. Louis region’s only free, web and mobile tool that puts your rights and your case records right at your fingertips. Use your phone or computer to access your court date and location, payment and community service options, and legal rights. Then, sign up to receive reminders of your court date via text message, by texting “Ticket” to {{ctrl.textPhoneNumber}}. Standard SMS rates apply. +

    +
    diff --git a/test/spec/controllers/smsInstructions.ctrl.spec.js b/test/spec/controllers/smsInstructions.ctrl.spec.js new file mode 100644 index 0000000..a86f68c --- /dev/null +++ b/test/spec/controllers/smsInstructions.ctrl.spec.js @@ -0,0 +1,21 @@ +'use strict'; + +describe('SMSInstructionsCtrl', function() { + var SMSInstructionsCtrl; + + beforeEach(function() { + module('yourStlCourts'); + + inject(function($controller){ + SMSInstructionsCtrl = $controller('SMSInstructionsCtrl',{ + smsPhoneNumber:"someNumber" + }); + + }); + }); + + it('sets textPhoneNumber on intitialization',inject(function(){ + expect(SMSInstructionsCtrl.textPhoneNumber).toEqual("someNumber"); + })); + +}); From 2e4aa3cf07d1bf80a06839b53540306b01421bfd Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 30 Apr 2017 19:33:21 -0500 Subject: [PATCH 202/233] Created new Going to Court Page and modified Your Legal Rights Page (#106) --- app/scripts/app.js | 4 + app/views/goingToCourt.html | 169 ++++++++++++++++++++++++++++++++++++ app/views/header.html | 1 + app/views/info.html | 133 ---------------------------- 4 files changed, 174 insertions(+), 133 deletions(-) create mode 100644 app/views/goingToCourt.html diff --git a/app/scripts/app.js b/app/scripts/app.js index 5ffd6d7..e930dbb 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -60,6 +60,10 @@ angular.module('yourStlCourts').config(function ($stateProvider, $urlRouterProvi url: '/info', templateUrl: 'views/info.html' }) + .state('goingToCourt', { + url: '/goingToCourt', + templateUrl: 'views/goingToCourt.html' + }) .state('legal', { url: '/legal', templateUrl: 'views/legal.html' diff --git a/app/views/goingToCourt.html b/app/views/goingToCourt.html new file mode 100644 index 0000000..e4e28ae --- /dev/null +++ b/app/views/goingToCourt.html @@ -0,0 +1,169 @@ +
    +

    Going To Court

    +
    +
    + +

    + The following are guidelines for going to court. These are not court-specific, and rules for attendance are likely vary from court to court, however they are intended to be general best practices for going to court. +

    +
    + +

    Dress Code

    +

    + Appropriate clothing should be work when going to court. While many courts will not require a strict dress code, it is better to avoid any potential dress code violations when possible. +

    +

    + Clothing which should be avoided, when possible, includes halter tops, t-shirts, shorts, baggy pants, or other clothes which could be deemed professionally inappropriate clothing. +

    +
    + +
    + +

    Do's & Don'ts

    +

    Addressing The Court

    +

    + When addressing the court or anyone working in the court system, please be respectful, clear and concise in your speech and avoid the use of anything that could make you more difficult to understand. This could include chewing gum, chewing tobacco or visual mouth enhancements that could be removed (such as a grill / fronts / golds). +

    +

    Electronic Devices

    +

    + Cell phones, tablets, pagers, hand-held gaming devices and other electronic devices brought into court with you should be turned to silent or powered off completely while you are inside the courtroom. +

    +

    Smoking and Nicotine Consumption

    +

    + Smoking and the use of electronic nicotine vaporizers should not be consumed in the court building or within a short distance of the doors. While many courts will have areas marked off, it is best to err on the side of caution and be away from the doors or back to your car if you wish to smoke or vape. +

    +
    +
    + +

    Court Fees & Fines

    +

    + In addition to the fine associated with your violation, cases may incur additional court fees. These fees pay for basic court costs as well as other programs and surcharges, such as: Crime Victim Compensation, Law Enforcement Training, Peace Officer Training, Biometric Verification System, Domestic Violence Shelter and others. +

    +

    Offenses which may carry a separate and compounding fine

    +

    + The offenses below are examples of citations which may carry a separate and compounding fine. Ultimately, a judge will determine the cost of each fine on an individual basis even though some courts may have standard fines and fees for various offenses. If you have: +

    +
      +
      +
    • +
    Ticket # NameDOB Court Date Court Location Violations
    {{citation.citation_number}} {{citation.first_name}} {{citation.last_name}}{{citation.date_of_birth}} {{citation.court_date}} {{citation.court_location}} From 30289fd536fb36446e9af03dc38a4e9040c7076b Mon Sep 17 00:00:00 2001 From: matt598 Date: Mon, 27 Jun 2016 15:37:37 -0500 Subject: [PATCH 034/233] Adding in Q&A style --- app/styles/main.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/styles/main.scss b/app/styles/main.scss index 6fefdb0..f7a67fb 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -212,6 +212,16 @@ table { } } +.Question{ + font-size: 1.5em; + color: $blue; +} + +.Answer{ + font-size: 1.2em; + color: $lightGray; +} + @media print { .no-print, .no-print * { From 2c6805bf440ae46136b7639151f51bd4cfcc86a2 Mon Sep 17 00:00:00 2001 From: matt598 Date: Mon, 27 Jun 2016 17:18:03 -0500 Subject: [PATCH 035/233] changing color to grey --- app/styles/main.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/styles/main.scss b/app/styles/main.scss index f7a67fb..499c4fa 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -219,7 +219,7 @@ table { .Answer{ font-size: 1.2em; - color: $lightGray; + color: $grey; } @media print { From ed3d02d35ef33076709d845378459641fdc38850 Mon Sep 17 00:00:00 2001 From: matt598 Date: Mon, 27 Jun 2016 17:29:46 -0500 Subject: [PATCH 036/233] Changed title from url to Your STL Courts --- app/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/index.html b/app/index.html index c429e7f..4c35157 100644 --- a/app/index.html +++ b/app/index.html @@ -2,7 +2,7 @@ - + Your STL Courts From 2d89cacae5f78f0b4d0d0321786c2ec663e3ea7c Mon Sep 17 00:00:00 2001 From: Alex White Date: Tue, 28 Jun 2016 00:23:09 -0500 Subject: [PATCH 037/233] Updated README to reflect how to run karma tests with watcher; added new dobPicker.ctrl spec tests --- README.md | 4 +- app/scripts/controllers/dobPicker.ctrl.js | 7 +-- test/spec/controllers/dobPicker.ctrl.spec.js | 64 ++++++++++++++++++++ 3 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 test/spec/controllers/dobPicker.ctrl.spec.js diff --git a/README.md b/README.md index 952b807..b5736a6 100644 --- a/README.md +++ b/README.md @@ -27,4 +27,6 @@ Run `grunt build:(local|uionly|production)` for building and `grunt serve:(local ## Testing * Install karma `npm install -g karma-cli` -Running `grunt test:local` will run the unit tests with karma. +* Running `karma start test\karma.conf.js` will run the unit tests and re-run on file changes. +... Alternatively, `cd test` and `karma start` +* Running `grunt test:local` will run the unit tests a single time with karma. diff --git a/app/scripts/controllers/dobPicker.ctrl.js b/app/scripts/controllers/dobPicker.ctrl.js index fb1d7b4..1ea005d 100644 --- a/app/scripts/controllers/dobPicker.ctrl.js +++ b/app/scripts/controllers/dobPicker.ctrl.js @@ -21,12 +21,9 @@ angular.module('yourStlCourts').controller('dobPickerCtrl', function ($uibModalI }; ctrl.save = function(form) { - if (form.$valid) - { + if (form.$valid) { $uibModalInstance.close(DateFormatter.format(ctrl.dob, 'mm/dd/yyyy')); - } - else - { + } else { toaster.pop('error', 'Invalid date of birth.'); } }; diff --git a/test/spec/controllers/dobPicker.ctrl.spec.js b/test/spec/controllers/dobPicker.ctrl.spec.js new file mode 100644 index 0000000..be5378c --- /dev/null +++ b/test/spec/controllers/dobPicker.ctrl.spec.js @@ -0,0 +1,64 @@ +'use strict'; + +describe('DobPickerCtrl', function () { + + var DobPickerCtrl; + var modalInstance; + + beforeEach(function() { + module('yourStlCourts'); + + inject(function($controller, DateFormatter, toaster) { + modalInstance = { + dismiss: jasmine.createSpy('dismiss spy'), + close: jasmine.createSpy('close spy') + }; + DobPickerCtrl = $controller('dobPickerCtrl', { + $uibModalInstance: modalInstance, + DateFormatter: DateFormatter, + toaster: toaster + }); + }); + }); + + it('sets variables on init', function() { + var today = new Date(); + + expect(DobPickerCtrl.dob).toBeNull(); + expect(DobPickerCtrl.status.opened).toBe(false); + expect(DobPickerCtrl.datepickerOptions.minDate).toEqual(new Date(1900, 0, 1)); + expect(DobPickerCtrl.datepickerOptions.maxDate).toEqual(new Date(today.getFullYear()-18,today.getMonth(),today.getDate())); + expect(DobPickerCtrl.datepickerFormat).toEqual('MM/dd/yyyy'); + expect(DobPickerCtrl.acceptedDatepickerFormats).toEqual(['dd-MMMM-yyyy', 'MM-dd-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate']); + }); + + it('sets to open status', function() { + DobPickerCtrl.open(); + + expect(DobPickerCtrl.status.opened).toBe(true); + }); + + it('closes modal with dob on save', inject(function(DateFormatter) { + var form = { $valid: true }; + DobPickerCtrl.dob = new Date(1999, 5, 18); + + DobPickerCtrl.save(form); + + expect(modalInstance.close).toHaveBeenCalledWith('06/18/1999'); + })); + + it('shows error when saving invalid date', inject(function(toaster) { + var form = { $valid: false }; + spyOn(toaster, 'pop'); + + DobPickerCtrl.save(form); + + expect(toaster.pop).toHaveBeenCalledWith('error', 'Invalid date of birth.'); + })); + + it('cancels', function() { + DobPickerCtrl.cancel(); + + expect(modalInstance.dismiss).toHaveBeenCalled(); + }); +}); From bbbd231a44a3ddf1f815237f9b76e5f6e14bd131 Mon Sep 17 00:00:00 2001 From: matt598 Date: Tue, 28 Jun 2016 14:35:00 -0500 Subject: [PATCH 038/233] Adding phone number to help page --- app/views/help.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/views/help.html b/app/views/help.html index 88fde5a..a4fa040 100644 --- a/app/views/help.html +++ b/app/views/help.html @@ -96,4 +96,7 @@

    Payment Help


    +
    +

    You can also text Your STL Courts at: (314) XXX-XXXX

    +
    From 72ab4d8bb39d5c28bbeb59f2901ae793ba67a01d Mon Sep 17 00:00:00 2001 From: matt598 Date: Wed, 29 Jun 2016 16:15:14 -0500 Subject: [PATCH 039/233] Adding Tickets to header bar --- app/scripts/app.js | 12 ++- app/scripts/controllers/citationInfo.ctrl.js | 2 +- .../{home.ctrl.js => ticketSearch.ctrl.js} | 2 +- app/scripts/directives/layout.dir.js | 2 +- app/views/header.html | 1 + app/views/home.html | 88 ------------------- app/views/ticketSearch.html | 88 +++++++++++++++++++ 7 files changed, 103 insertions(+), 92 deletions(-) rename app/scripts/controllers/{home.ctrl.js => ticketSearch.ctrl.js} (96%) create mode 100644 app/views/ticketSearch.html diff --git a/app/scripts/app.js b/app/scripts/app.js index 73872d6..fc6a0a6 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -17,6 +17,16 @@ angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvid } } }) + .state('ticketSearch', { + url: '/ticket/search', + templateUrl: 'views/ticketSearch.html', + controller: 'ticketSearchCtrl as ctrl', + resolve: { + municipalities: function(Courts){ + return Courts.findAll(); + } + } + }) .state('about', { url: '/about', templateUrl: 'views/about.html' @@ -30,7 +40,7 @@ angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvid templateUrl: 'views/info.html' }) .state('citationInfo', { - url: '/ticketInfo', + url: '/ticket/info', templateUrl: 'views/citationInfo.html', controller: 'citationInfoCtrl as ctrl', params: { diff --git a/app/scripts/controllers/citationInfo.ctrl.js b/app/scripts/controllers/citationInfo.ctrl.js index 091ae27..8524705 100644 --- a/app/scripts/controllers/citationInfo.ctrl.js +++ b/app/scripts/controllers/citationInfo.ctrl.js @@ -12,7 +12,7 @@ angular.module('yourStlCourts').controller('citationInfoCtrl', function ($state, }; if(!citations) { - $state.go('home'); + $state.go('ticketSearch'); } else { ctrl.citations = citations; ctrl.selectedCitation = null; diff --git a/app/scripts/controllers/home.ctrl.js b/app/scripts/controllers/ticketSearch.ctrl.js similarity index 96% rename from app/scripts/controllers/home.ctrl.js rename to app/scripts/controllers/ticketSearch.ctrl.js index e9a5054..d29dc5c 100644 --- a/app/scripts/controllers/home.ctrl.js +++ b/app/scripts/controllers/ticketSearch.ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('yourStlCourts').controller('HomeCtrl', function (Citations, toaster, States, municipalities, $uibModal, $state) { +angular.module('yourStlCourts').controller('ticketSearchCtrl', function (Citations, toaster, States, municipalities, $uibModal, $state) { var ctrl = this; ctrl.states = States; ctrl.municipalities = municipalities; diff --git a/app/scripts/directives/layout.dir.js b/app/scripts/directives/layout.dir.js index 5ff2d4f..0d0a82d 100644 --- a/app/scripts/directives/layout.dir.js +++ b/app/scripts/directives/layout.dir.js @@ -6,7 +6,7 @@ angular.module('yourStlCourts').directive('layout', function () { link: function ($scope, element) { $scope.$on('$stateChangeStart', function(event, toState){ - if (toState.name === 'home' || toState.name === 'about' || toState.name === 'help' || toState.name === 'info') { + if (toState.name === 'home' || toState.name === 'ticketSearch' || toState.name === 'about' || toState.name === 'help' || toState.name === 'info') { element.addClass('background'); } else { element.removeClass('background'); diff --git a/app/views/header.html b/app/views/header.html index 2075f20..5844fe3 100644 --- a/app/views/header.html +++ b/app/views/header.html @@ -14,6 +14,7 @@
    +

    Everything you need in one place.

    +

    Use the search box below to find relevant court information.

    + +
    From d758fbe5083d57b5c3bbefdf850ab0177b0fa900 Mon Sep 17 00:00:00 2001 From: matt598 Date: Wed, 6 Jul 2016 13:58:55 -0500 Subject: [PATCH 047/233] Search Bar Looks Better --- app/views/home.html | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/views/home.html b/app/views/home.html index aa78f5b..4437b70 100644 --- a/app/views/home.html +++ b/app/views/home.html @@ -5,8 +5,17 @@

    Home

    Everything you need in one place.

    Use the search box below to find relevant court information.

    - - - + +

    + + + + +

    +
    From d0df9affc2738d5abd69e0f63e8d74a3a9a4cf81 Mon Sep 17 00:00:00 2001 From: matt598 Date: Wed, 6 Jul 2016 14:42:33 -0500 Subject: [PATCH 048/233] Fixing Uniform fines --- app/views/info.html | 72 ++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/app/views/info.html b/app/views/info.html index 0c61444..49cf409 100644 --- a/app/views/info.html +++ b/app/views/info.html @@ -48,7 +48,7 @@

    Dress Code

    Court Fees

    -

    All cases incur a fee of $22.50-$27.50 in addition to the fine associated with the violation. This fee goes toward Basic Court Costs, Crime Victim's Compensation Surcharge, Law Enforcement Training Fund, Peace Officer's Standard Training Fund, Biometric Verification System Surcharge, and the Domestic Violence Shelter Fund. No other fees are assessed.

    +

    All cases also incur a fee of $22.50-$27.50 in addition to the fine associated with the violation. This fee goes toward Basic Court Costs, Crime Victim's Compensation Surcharge, Law Enforcement Training Fund, Peace Officer's Standard Training Fund, Biometric Verification System Surcharge, and the Domestic Violence Shelter Fund. No other fees are assessed.

    @@ -60,79 +60,79 @@

    Court Fees

    - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -140,67 +140,67 @@

    Court Fees

    - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
    Corner Cutting to Avoid Signal$70.50$50.50
    Driving On Closed Road$70.50$50.50
    Driving Over Curb$70.50$50.50
    Driving Wrong Side of Road$70.50$50.50
    Driving Wrong Way (One Way Street)$70.50$50.50
    Blocking Driveway or Alley$75.00$50.50
    Expired License Plates (Tags)$75.00$50.50
    Failure to Secure a Load$75.00$50.50
    Fake Temporary Tags$75.00$50.50
    Fictitious License Tabs$75.00$50.50
    Improper Exhaust or Muffler$75.00$50.50
    Improper Registration (Failure to Register)$75.00$50.50
    License Plate not Illuminated$75.00$50.50
    No Brake Lights$75.00$50.50
    No Headlight$75.00$50.50
    No Inspection Sticker$75.00$50.50
    No License Plates$75.00$50.50
    No Motorcycle Helmet$75.00$50.50
    No Taillights$75.00$50.50
    Child Restraint Seat Violation*
    Failure to Keep to the Right$95.00$70.50
    Failure to Obey Electric Signal$95.00$70.50
    Failure to Obey Stop Sign$95.00$70.50
    Failure to Sound Horn$95.00$70.50
    Failure to Yield$95.00$70.50
    Failure to Yield to Emergency Vehicles$95.00$70.50
    Following too Closely$95.00$70.50
    Impeding/Obstructing Traffic Movement$95.00$70.50
    Improper Backing$95.00$70.50
    Improper Lane Usage$95.00$70.50
    Improper Passing$95.00$70.50
    Improper/Prohibited Turn$95.00$70.50
    No Through Traffic$95.00$70.50
    Prohibited U-Turn$95.00$70.50
    Traffic Turn Signal Violation$95.00$70.50
    -

    *waived if child restraint is purchased before court date

    +

    *typically waived if child restraint is purchased before court date

    From 77104b8cb7766a2dca5078b124c16d15923a3c4c Mon Sep 17 00:00:00 2001 From: Will Stampley Date: Thu, 7 Jul 2016 08:27:06 -0500 Subject: [PATCH 049/233] Making the package name and version match in NPM and bower. --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7730512..362c396 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { - "name": "ghangular", + "name": "yourSTLCourts-client", + "version": "0.9.0", "private": true, "devDependencies": { "grunt": "^0.4.5", From 9f32f0d2dc35c14b9e9f3dd04d991fa40f7aa6cb Mon Sep 17 00:00:00 2001 From: matt598 Date: Thu, 7 Jul 2016 10:41:01 -0500 Subject: [PATCH 050/233] Adding breakdown of a ticket --- app/views/about.html | 2 +- app/views/help.html | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/about.html b/app/views/about.html index 8ddb5b2..1406a85 100644 --- a/app/views/about.html +++ b/app/views/about.html @@ -1,6 +1,6 @@
    -

    About

    +

    About Your STL Courts

    YourSTLCourts.com is your one-stop shop for the municipal courts of St. Louis County. YourSTLCourts is a common space that connects you to diff --git a/app/views/help.html b/app/views/help.html index a4fa040..c362652 100644 --- a/app/views/help.html +++ b/app/views/help.html @@ -97,6 +97,8 @@

    Payment Help


    -

    You can also text Your STL Courts at: (314) XXX-XXXX

    +

    Reasources

    + Breakdown of a ticket +

    You can also get your info by texting: (314) XXX-XXXX

    From 10c1ae381a95a4133b84e081a453a76f4ee08534 Mon Sep 17 00:00:00 2001 From: matt598 Date: Thu, 7 Jul 2016 10:41:36 -0500 Subject: [PATCH 051/233] Removing Home header from home page --- app/views/home.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/views/home.html b/app/views/home.html index 4437b70..0df1fec 100644 --- a/app/views/home.html +++ b/app/views/home.html @@ -1,7 +1,4 @@
    -
    -

    Home

    -

    Everything you need in one place.

    Use the search box below to find relevant court information.

    From cfbed232c203a542a7818e3afe3319e551604890 Mon Sep 17 00:00:00 2001 From: matt598 Date: Thu, 7 Jul 2016 10:45:18 -0500 Subject: [PATCH 052/233] Making Ticket Breakdown open in new tab --- app/views/help.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/help.html b/app/views/help.html index c362652..62e5205 100644 --- a/app/views/help.html +++ b/app/views/help.html @@ -98,7 +98,7 @@

    Payment Help

    Reasources

    - Breakdown of a ticket + Breakdown of a ticket

    You can also get your info by texting: (314) XXX-XXXX

    From 89046a426459c75e8b389fede583ee4637f91e7a Mon Sep 17 00:00:00 2001 From: Alex White Date: Thu, 7 Jul 2016 12:08:18 -0500 Subject: [PATCH 053/233] Adjusted karma test settings and coverage reporting --- .gitignore | 1 + Gruntfile.js | 2 +- app/index.html | 2 +- app/scripts/app.js | 24 ++++----- .../jcs-auto-validate.min.js | 0 test/karma.conf.js => karma.conf.js | 52 +++++++++++-------- package.json | 5 +- 7 files changed, 50 insertions(+), 36 deletions(-) rename app/{scripts => vendor}/jcs-auto-validate.min.js (100%) rename test/karma.conf.js => karma.conf.js (70%) diff --git a/.gitignore b/.gitignore index f971158..8cfb941 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /bower_components /dist +/coverage #IntelliJ/WebStorm /.idea diff --git a/Gruntfile.js b/Gruntfile.js index b795d37..8e924a3 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -428,7 +428,7 @@ module.exports = function (grunt) { // Test settings karma: { unit: { - configFile: 'test/karma.conf.js', + configFile: 'karma.conf.js', singleRun: true } }, diff --git a/app/index.html b/app/index.html index ce095d6..924e26d 100644 --- a/app/index.html +++ b/app/index.html @@ -56,8 +56,8 @@ + - diff --git a/app/scripts/app.js b/app/scripts/app.js index 85ec854..17ceec3 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -12,16 +12,6 @@ angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvid templateUrl: 'views/home.html', controller: 'homeCtrl as ctrl' }) - .state('ticketSearch', { - url: '/ticket/search', - templateUrl: 'views/ticketSearch.html', - controller: 'ticketSearchCtrl as ctrl', - resolve: { - municipalities: function(Courts){ - return Courts.findAll(); - } - } - }) .state('about', { url: '/about', templateUrl: 'views/about.html' @@ -30,12 +20,22 @@ angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvid url: '/help', templateUrl: 'views/help.html' }) - .state('info', { + .state('info', { url: '/info', templateUrl: 'views/info.html' }) + .state('ticketSearch', { + url: '/tickets/search', + templateUrl: 'views/ticketSearch.html', + controller: 'ticketSearchCtrl as ctrl', + resolve: { + municipalities: function(Courts){ + return Courts.findAll(); + } + } + }) .state('citationInfo', { - url: '/ticket/info', + url: '/tickets/info', templateUrl: 'views/citationInfo.html', controller: 'citationInfoCtrl as ctrl', params: { diff --git a/app/scripts/jcs-auto-validate.min.js b/app/vendor/jcs-auto-validate.min.js similarity index 100% rename from app/scripts/jcs-auto-validate.min.js rename to app/vendor/jcs-auto-validate.min.js diff --git a/test/karma.conf.js b/karma.conf.js similarity index 70% rename from test/karma.conf.js rename to karma.conf.js index 72c0476..9315a9f 100644 --- a/test/karma.conf.js +++ b/karma.conf.js @@ -1,7 +1,5 @@ // Karma configuration // http://karma-runner.github.io/0.12/config/configuration-file.html -// Generated on 2015-09-10 using -// generator-karma 1.0.0 module.exports = function(config) { 'use strict'; @@ -11,7 +9,7 @@ module.exports = function(config) { autoWatch: true, // base path, that will be used to resolve files and exclude - basePath: '../', + basePath: './', // testing framework to use (jasmine/mocha/qunit/...) // as well as any additional frameworks (requirejs/chai/sinon/...) @@ -36,11 +34,37 @@ module.exports = function(config) { 'bower_components/angular-ui-select/dist/select.js', 'bower_components/angular-mocks/angular-mocks.js', // endbower - "app/scripts/**/*.js", - "test/mock/**/*.js", - "test/spec/**/*.js" + 'app/vendor/jcs-auto-validate.min.js', + 'app/scripts/**/*.js', + 'test/spec/**/*.js' ], + preprocessors: { + 'app/scripts/**/*.js': ['coverage'] + }, + + reporters: [ + 'spec', + 'coverage' + ], + + specReporter: { + maxLogLines: 10, // limit number of lines logged per test + suppressErrorSummary: true, // do not print error summary + suppressFailed: false, // do not print information about failed tests + suppressPassed: false, // do not print information about passed tests + suppressSkipped: true, // do not print information about skipped tests + showSpecTiming: false // print the time elapsed for each spec + }, + + coverageReporter: { + dir: 'coverage/', + reporters: [ + {type: 'text-summary'}, + {type: 'html'} + ] + }, + // list of files / patterns to exclude exclude: [ ], @@ -48,24 +72,10 @@ module.exports = function(config) { // web server port port: 8080, - // Start these browsers, currently available: - // - Chrome - // - ChromeCanary - // - Firefox - // - Opera - // - Safari (only Mac) - // - PhantomJS - // - IE (only Windows) browsers: [ "PhantomJS" ], - // Which plugins to enable - plugins: [ - "karma-phantomjs-launcher", - "karma-jasmine" - ], - // Continuous Integration mode // if true, it capture browsers, run tests and exit singleRun: false, @@ -74,7 +84,7 @@ module.exports = function(config) { // level of logging // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG - logLevel: config.LOG_INFO, + logLevel: config.LOG_INFO // Uncomment the following lines if you are using grunt's server to run the tests // proxies: { diff --git a/package.json b/package.json index 362c396..6b48066 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,10 @@ "grunt-wiredep": "^2.0.0", "jit-grunt": "^0.9.1", "jshint-stylish": "^1.0.0", + "karma-coverage": "^0.5.3", "karma-jasmine": "*", "karma-phantomjs-launcher": "*", + "karma-spec-reporter": "0.0.26", "load-grunt-tasks": "^3.2.0", "time-grunt": "^1.0.0" }, @@ -38,7 +40,8 @@ "node": ">=0.10.0" }, "scripts": { - "test": "grunt test" + "test": "grunt test:local", + "test-watch": "karma start --auto-watch --no-single-run" }, "dependencies": { "express": "^4.13.3", From c6af3ed63b7d5e4d12e5d1a950cba331a1996962 Mon Sep 17 00:00:00 2001 From: matt598 Date: Thu, 7 Jul 2016 12:26:28 -0500 Subject: [PATCH 054/233] Adding Legal & Privacy Pages --- app/index.html | 2 +- app/scripts/app.js | 8 ++++++++ app/views/footer.html | 23 +++++++++++++++++++++++ app/views/legal.html | 8 ++++++++ app/views/privacy.html | 8 ++++++++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 app/views/footer.html create mode 100644 app/views/legal.html create mode 100644 app/views/privacy.html diff --git a/app/index.html b/app/index.html index ce095d6..351e6d7 100644 --- a/app/index.html +++ b/app/index.html @@ -32,7 +32,7 @@
    - © CivTech St. Louis +
    diff --git a/app/scripts/app.js b/app/scripts/app.js index 85ec854..20e3360 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -34,6 +34,14 @@ angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvid url: '/info', templateUrl: 'views/info.html' }) + .state('legal', { + url: '/legal', + templateUrl: 'views/legal.html' + }) + .state('privacy', { + url: '/privacy', + templateUrl: 'views/privacy.html' + }) .state('citationInfo', { url: '/ticket/info', templateUrl: 'views/citationInfo.html', diff --git a/app/views/footer.html b/app/views/footer.html new file mode 100644 index 0000000..0d79f1b --- /dev/null +++ b/app/views/footer.html @@ -0,0 +1,23 @@ +
    + +
    diff --git a/app/views/legal.html b/app/views/legal.html new file mode 100644 index 0000000..bca1ecd --- /dev/null +++ b/app/views/legal.html @@ -0,0 +1,8 @@ +
    +
    +

    Legal Info

    +
    +
    + Filler Text +
    +
    diff --git a/app/views/privacy.html b/app/views/privacy.html new file mode 100644 index 0000000..1ec9074 --- /dev/null +++ b/app/views/privacy.html @@ -0,0 +1,8 @@ +
    +
    +

    Privacy Policy

    +
    +
    + Filler Text +
    +
    From de6bf3c7a66ad60e64ffa989c9b549f9ca6a88be Mon Sep 17 00:00:00 2001 From: matt598 Date: Thu, 7 Jul 2016 12:45:29 -0500 Subject: [PATCH 055/233] Formatting Footer --- app/index.html | 1 + app/scripts/controllers/footer.ctrl.js | 9 +++++++++ app/views/footer.html | 6 +++--- 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 app/scripts/controllers/footer.ctrl.js diff --git a/app/index.html b/app/index.html index 351e6d7..caba2c3 100644 --- a/app/index.html +++ b/app/index.html @@ -62,6 +62,7 @@ + diff --git a/app/scripts/controllers/footer.ctrl.js b/app/scripts/controllers/footer.ctrl.js new file mode 100644 index 0000000..dd92155 --- /dev/null +++ b/app/scripts/controllers/footer.ctrl.js @@ -0,0 +1,9 @@ +'use strict'; + +angular.module('yourStlCourts').controller('FooterCtrl', function (Auth) { + var ctrl = this; + + ctrl.collapseOptions = function(){ + return false; + }; +}); diff --git a/app/views/footer.html b/app/views/footer.html index 0d79f1b..03b733b 100644 --- a/app/views/footer.html +++ b/app/views/footer.html @@ -1,17 +1,17 @@ -
    +
    {{citation.citation_number}} {{citation.first_name}} {{citation.last_name}}{{citation.court_date}}{{ctrl.formatDate(citation.court_date)}} {{citation.court_location}} @@ -61,7 +61,7 @@

    Ticket Info

    Case Number
    {{ctrl.selectedCitation.citation_number}}
    Ticket Date
    -
    {{ctrl.selectedCitation.citation_date}}
    +
    {{ctrl.formatDate(ctrl.selectedCitation.citation_date)}}
    Total Fine
    @@ -86,7 +86,7 @@

    Ticket Info

    Court Information

    Court Date
    -
    {{ctrl.selectedCitation.court_date}}
    +
    {{ctrl.formatDate(ctrl.selectedCitation.court_date)}}
    Court Name
    {{ctrl.selectedCitation.court.municipality}}
    Court Phone Number
    From 133314380e9ff08cb19d349fe7f499bc6f86a5e1 Mon Sep 17 00:00:00 2001 From: Alex White Date: Tue, 12 Jul 2016 01:36:02 -0500 Subject: [PATCH 070/233] Fix sticky footer in FireFox --- app/styles/main.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/styles/main.scss b/app/styles/main.scss index e9e4e1b..80c767f 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -15,10 +15,10 @@ html, body { #wrapper { min-height: 100%; width: 100%; - height: auto; + height: 100%; position: relative; - margin-bottom: -60px !important; - padding-bottom: 60px !important; + margin: 0 auto -60px !important; + padding: 0 0 60px !important; display: table; } From 430a5087062ffac0ce2513fd44bfcf36c4fd3508 Mon Sep 17 00:00:00 2001 From: matt598 Date: Tue, 12 Jul 2016 11:21:11 -0500 Subject: [PATCH 071/233] Changing order of Help and About --- app/views/footer.html | 2 +- app/views/header.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/footer.html b/app/views/footer.html index 9c1b5b2..11e68d9 100644 --- a/app/views/footer.html +++ b/app/views/footer.html @@ -9,8 +9,8 @@ - +
  • Legal Info
  • Privacy Policy
  • diff --git a/app/views/header.html b/app/views/header.html index 7138d93..7e81c9c 100644 --- a/app/views/header.html +++ b/app/views/header.html @@ -18,8 +18,8 @@
  • Info
  • -
  • About
  • Help
  • +
  • About
  • Logged in as: {{ctrl.getAuthenticatedSponsor().name}}   From e401f7ded1df7853342e8787ce1405664092b8c8 Mon Sep 17 00:00:00 2001 From: matt598 Date: Tue, 12 Jul 2016 11:43:33 -0500 Subject: [PATCH 072/233] Fixing formatting on date --- app/scripts/controllers/citationInfo.ctrl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/controllers/citationInfo.ctrl.js b/app/scripts/controllers/citationInfo.ctrl.js index e83883a..a6e0168 100644 --- a/app/scripts/controllers/citationInfo.ctrl.js +++ b/app/scripts/controllers/citationInfo.ctrl.js @@ -88,7 +88,7 @@ angular.module('yourStlCourts').controller('citationInfoCtrl', function ($state, ctrl.formatDate = function(dateToFormat){ //var moment = require('moment'); - //return moment(dateToFormat).format('YYYY/MM/DD'); + //return moment(dateToFormat).format('MM/DD/YYYY'); return dateToFormat; }; }); From 11ab38026be395c610e507bac6319e515dc8b902 Mon Sep 17 00:00:00 2001 From: matt598 Date: Tue, 12 Jul 2016 12:21:39 -0500 Subject: [PATCH 073/233] Changing Tickets to Ticket Finder in header & footer --- app/views/footer.html | 2 +- app/views/header.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/footer.html b/app/views/footer.html index 11e68d9..08afe4e 100644 --- a/app/views/footer.html +++ b/app/views/footer.html @@ -7,7 +7,7 @@
      - + diff --git a/app/views/header.html b/app/views/header.html index 7e81c9c..f3af1a3 100644 --- a/app/views/header.html +++ b/app/views/header.html @@ -14,7 +14,7 @@ From f8a75b08a00e0a5e723d51a84382d43bae172a1f Mon Sep 17 00:00:00 2001 From: matt598 Date: Mon, 25 Jul 2016 11:40:28 -0500 Subject: [PATCH 084/233] updating header --- app/views/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/header.html b/app/views/header.html index f3af1a3..3ac530d 100644 --- a/app/views/header.html +++ b/app/views/header.html @@ -15,7 +15,7 @@

    We respect your right to privacy. This policy summarizes what personally identifiable information we may collect and how we might use this information. We reserve the right to modify this privacy policy at any time. We will promptly reflect any such modifications in these Web pages.

    +

    We will only collect personally identifiable information (such as name, title, company name, address, telephone number or e-mail address) that you voluntarily provide through our website or email correspondence. We will collect general information (such as the type of browser you use, the files you request, and the domain name and country from which you request information) to improve our website and better meet your needs.

    +

    Before we collect any personally identifiable information, we will provide an explanation for the possible use of your data. The information you supply will be used by us to respond to your inquiries or supply you with requested information. It may be necessary, if required by law or if pertinent to judicial or governmental investigations, to release your personally identifiable information. If you have submitted personal information to us electronically and would like it removed or modified, please contact us. We will use reasonable efforts to comply with your request.

    From 63e7f9f7258e192a175925d7f79d103b00da90f4 Mon Sep 17 00:00:00 2001 From: matt598 Date: Mon, 8 Aug 2016 19:21:07 -0500 Subject: [PATCH 086/233] updating header --- app/views/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/header.html b/app/views/header.html index 3ac530d..8ceaea6 100644 --- a/app/views/header.html +++ b/app/views/header.html @@ -15,7 +15,7 @@ - - +
    +

    Court Rights

    You must first enter a plea. You may plead not guilty, guilty, or guilty with an explanation. If you plead NOT GUILTY, your case will be set for trial. You must appear on the date and at the time the trial is scheduled or a warrant will be issued for your arrest. At your trial, you should be prepared to present any evidence you believe will help you in your defense. The rules of evidence apply at your trial, which may prevent some evidence you may want to present from being admitted before the Judge.

    Your Rights with a Not Guilty Plea are as follows:

    -
      +
      • You have a right to be informed as to the nature of the charge against you and the minimum and maximum punishment for the charge;
      • You have the right to be represented by an attorney and an attorney may be appointed for you if you are indigent (unable to afford an attorney) AND it appears that there would possibly be a jail sentence upon conviction;
      • You have a right to a have a trial, including a trial by jury;
      • @@ -23,175 +22,181 @@

        Your Rights with a Not Guilty Plea are as follows:

      • You have the right to subpoena persons to testify on your behalf at your trial (a subpoena is an order from the court to a witness that they must appear at the trial). The court administrator can provide the subpoena forms, but you must serve them yourself upon the witness;
      • You have the right to testify at your trial but neither the City nor anyone else can force you to testify;
      • If you had a trial and were found guilty you have a right to appeal that decision to another court.
      • -
    +

    If you plead guilty, you give up all the rights listed above

    -

    By pleading Guilty, you admit that you committed the act charged, that the law prohibits the act, and that you have no defense for your act. This also relieves the City of its burden of proving a case against you. You may plead guilty for most offenses by mail or by paying your fine during court business hours.

    -

    If you were involved in a traffic accident at the time of the alleged offense, your plea of guilty could be used later in a civil suit for damages as an admission by you that you were at fault or were the party responsible for the accident. You are urged not to plead guilty if you do not feel that you are guilty.

    -

    In the case of a guilty plea or a finding of guilty, a fine most likely will be assessed. A plea of Guilty with an Explanation may or may not have an effect on the amount assessed. If you are unable to make a payment on the date of your court hearing, you must speak with the court clerk to make arrangements to pay or to be found indigent, which will result in community service being assessed. If you are given a new date for payment, if no payment is made and you do not appear on your court date, a warrant will be issued for your arrest and you may have your driver’s license suspended. If you are unable to pay your fine, you must still show up at your court date. You WILL NOT be arrested for failure to pay if you show up for court.

    +
      +
    • By pleading Guilty, you admit that you committed the act charged, that the law prohibits the act, and that you have no defense for your act. This also relieves the City of its burden of proving a case against you. You may plead guilty for most offenses by mail or by paying your fine during court business hours.
    • +
    • If you were involved in a traffic accident at the time of the alleged offense, your plea of guilty could be used later in a civil suit for damages as an admission by you that you were at fault or were the party responsible for the accident. You are urged not to plead guilty if you do not feel that you are guilty.
    • +
    • In the case of a guilty plea or a finding of guilty, a fine most likely will be assessed. A plea of Guilty with an Explanation may or may not have an effect on the amount assessed. If you are unable to make a payment on the date of your court hearing, you must speak with the court clerk to make arrangements to pay or to be found indigent, which will result in community service being assessed. If you are given a new date for payment, if no payment is made and you do not appear on your court date, a warrant will be issued for your arrest and you may have your driver’s license suspended. If you are unable to pay your fine, you must still show up at your court date. You WILL NOT be arrested for failure to pay if you show up for court.
    • +

    Punishment and Fines

    -

    After a plea of guilty or a finding of guilty, the court has the authority to assess court fines and/or a jail sentence. The amount assessed by the court is affected by the facts and the circumstances of the case. Mitigating circumstances may lower the fine, but aggravating circumstances may increase the fine. You have a right to know the minimum and maximum punishment for your offense at the start of your trial.

    +
      +
    • After a plea of guilty or a finding of guilty, the court has the authority to assess court fines and/or a jail sentence. The amount assessed by the court is affected by the facts and the circumstances of the case. Mitigating circumstances may lower the fine, but aggravating circumstances may increase the fine. You have a right to know the minimum and maximum punishment for your offense at the start of your trial.
    • +
    -
    +

    Dress Code

    -

    You must dress appropriately if you enter the courthouses. No halter tops, t-shirts, shorts, baggy pants, or other inappropriate clothing will be tolerated. You also must turn off all pagers and cell-phones.

    +
      +
    • You must dress appropriately if you enter the courthouses. No halter tops, t-shirts, shorts, baggy pants, or other inappropriate clothing will be tolerated. You also must turn off all pagers and cell-phones.
    • +
    - -
    +
    +

    Court Fees

    -

    All cases also incur a fee of $22.50-$27.50 in addition to the fine associated with the violation. This fee goes toward Basic Court Costs, Crime Victim's Compensation Surcharge, Law Enforcement Training Fund, Peace Officer's Standard Training Fund, Biometric Verification System Surcharge, and the Domestic Violence Shelter Fund. No other fees are assessed.

    - - - - - - -
    OffenseFine
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Corner Cutting to Avoid Signal$50.50
    Driving On Closed Road$50.50
    Driving Over Curb$50.50
    Driving Wrong Side of Road$50.50
    Driving Wrong Way (One Way Street)$50.50
    Blocking Driveway or Alley$50.50
    Expired License Plates (Tags)$50.50
    Failure to Secure a Load$50.50
    Fake Temporary Tags$50.50
    Fictitious License Tabs$50.50
    Improper Exhaust or Muffler$50.50
    Improper Registration (Failure to Register)$50.50
    License Plate not Illuminated$50.50
    No Brake Lights$50.50
    No Headlight$50.50
    No Inspection Sticker$50.50
    No License Plates$50.50
    No Motorcycle Helmet$50.50
    No Taillights$50.50
    Child Restraint Seat Violation*$49.00
    Failure to Keep to the Right$70.50
    Failure to Obey Electric Signal$70.50
    Failure to Obey Stop Sign$70.50
    Failure to Sound Horn$70.50
    Failure to Yield$70.50
    Failure to Yield to Emergency Vehicles$70.50
    Following too Closely$70.50
    Impeding/Obstructing Traffic Movement$70.50
    Improper Backing$70.50
    Improper Lane Usage$70.50
    Improper Passing$70.50
    Improper/Prohibited Turn$70.50
    No Through Traffic$70.50
    Prohibited U-Turn$70.50
    Traffic Turn Signal Violation$70.50
    -
    -

    *typically waived if child restraint is purchased before court date

    +
      +
    • All cases also incur a fee of $22.50-$27.50 in addition to the fine associated with the violation. This fee goes toward Basic Court Costs, Crime Victim's Compensation Surcharge, Law Enforcement Training Fund, Peace Officer's Standard Training Fund, Biometric Verification System Surcharge, and the Domestic Violence Shelter Fund. No other fees are assessed.
    • +
      +
    • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      OffenseFine
      Corner Cutting to Avoid Signal$50.50
      Driving On Closed Road$50.50
      Driving Over Curb$50.50
      Driving Wrong Side of Road$50.50
      Driving Wrong Way (One Way Street)$50.50
      Blocking Driveway or Alley$50.50
      Expired License Plates (Tags)$50.50
      Failure to Secure a Load$50.50
      Fake Temporary Tags$50.50
      Fictitious License Tabs$50.50
      Improper Exhaust or Muffler$50.50
      Improper Registration (Failure to Register)$50.50
      License Plate not Illuminated$50.50
      No Brake Lights$50.50
      No Headlight$50.50
      No Inspection Sticker$50.50
      No License Plates$50.50
      No Motorcycle Helmet$50.50
      No Taillights$50.50
      Child Restraint Seat Violation*$49.00
      Failure to Keep to the Right$70.50
      Failure to Obey Electric Signal$70.50
      Failure to Obey Stop Sign$70.50
      Failure to Sound Horn$70.50
      Failure to Yield$70.50
      Failure to Yield to Emergency Vehicles$70.50
      Following too Closely$70.50
      Impeding/Obstructing Traffic Movement$70.50
      Improper Backing$70.50
      Improper Lane Usage$70.50
      Improper Passing$70.50
      Improper/Prohibited Turn$70.50
      No Through Traffic$70.50
      Prohibited U-Turn$70.50
      Traffic Turn Signal Violation$70.50
      +

      *typically waived if child restraint is purchased before court date

      +
    • +
    From 5194fcbd16defd1479f7d9f7da0071aff5ce6c88 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Fri, 28 Oct 2016 06:58:51 -0500 Subject: [PATCH 108/233] added landing error page and an error service to handle errors (#16) * added landing error page and an error service to handle errors * Cleaned up long if line and made it an array to search. * Single Line Array * Fixed formatting and added unit tests for the error controller and Errors service * Errors Unit Test --- app/index.html | 2 ++ app/scripts/app.js | 26 ++++++++++++++++----- app/scripts/controllers/error.ctrl.js | 7 ++++++ app/scripts/directives/layout.dir.js | 3 ++- app/scripts/services/Errors.svc.js | 28 +++++++++++++++++++++++ app/styles/main.scss | 2 +- app/views/error.html | 7 ++++++ test/spec/controllers/error.ctrl.spec.js | 29 ++++++++++++++++++++++++ test/spec/service/Errors.svc.spec.js | 25 ++++++++++++++++++++ 9 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 app/scripts/controllers/error.ctrl.js create mode 100644 app/scripts/services/Errors.svc.js create mode 100644 app/views/error.html create mode 100644 test/spec/controllers/error.ctrl.spec.js create mode 100644 test/spec/service/Errors.svc.spec.js diff --git a/app/index.html b/app/index.html index e7900c2..2f05283 100644 --- a/app/index.html +++ b/app/index.html @@ -78,6 +78,7 @@ + @@ -91,6 +92,7 @@ + diff --git a/app/scripts/app.js b/app/scripts/app.js index 184f325..c5e8120 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -49,6 +49,19 @@ angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvid } } }) + .state('error',{ + url:'/error', + templateUrl: 'views/error.html', + controller:'ErrorCtrl as ctrl', + params: { + error: { value : undefined } + }, + resolve: { + error: function($stateParams) { + return $stateParams.error; + } + } + }) .state('courtSearchInfo', { url: '/courts/{courtId}', templateUrl: 'views/courtSearchInfo.html', @@ -57,12 +70,13 @@ angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvid court: {value: undefined} }, resolve: { - court: function ($stateParams,Courts) { - if ($stateParams.courtId != ""){ - return Courts.findById($stateParams.courtId) - }else{ - return null; - }; + court: function ($stateParams, Courts, Errors) { + if (!$stateParams.courtId) { + throw Errors.makeError(Errors.ERROR_CODE.BAD_REQUEST, "No Court was found with the url you provided."); + } else { + return Courts.findById($stateParams.courtId).catch(function () { + throw Errors.makeError(Errors.ERROR_CODE.NOT_FOUND, "No Court was found with the url you provided."); }) + } } } }) diff --git a/app/scripts/controllers/error.ctrl.js b/app/scripts/controllers/error.ctrl.js new file mode 100644 index 0000000..f294591 --- /dev/null +++ b/app/scripts/controllers/error.ctrl.js @@ -0,0 +1,7 @@ +'use strict'; + +angular.module('yourStlCourts').controller('ErrorCtrl', function (error) { + var ctrl = this; + ctrl.errorCode = error ? error.code : ""; + ctrl.errorMessage = error ? error.message : ""; +}); diff --git a/app/scripts/directives/layout.dir.js b/app/scripts/directives/layout.dir.js index 0d0a82d..188e95d 100644 --- a/app/scripts/directives/layout.dir.js +++ b/app/scripts/directives/layout.dir.js @@ -6,7 +6,8 @@ angular.module('yourStlCourts').directive('layout', function () { link: function ($scope, element) { $scope.$on('$stateChangeStart', function(event, toState){ - if (toState.name === 'home' || toState.name === 'ticketSearch' || toState.name === 'about' || toState.name === 'help' || toState.name === 'info') { + var statesToUseBackground = ['home','ticketSearch','about','help','info','error']; + if (statesToUseBackground.indexOf(toState.name) != -1){ element.addClass('background'); } else { element.removeClass('background'); diff --git a/app/scripts/services/Errors.svc.js b/app/scripts/services/Errors.svc.js new file mode 100644 index 0000000..0585bcd --- /dev/null +++ b/app/scripts/services/Errors.svc.js @@ -0,0 +1,28 @@ +'use strict'; + +angular.module('yourStlCourts').factory('Errors', function ($rootScope, $state) { + var ERROR_CODE = { + BAD_REQUEST: 400, + NOT_FOUND: 404 + } + + var svc = { + makeError: makeError, + ERROR_CODE: ERROR_CODE + }; + + $rootScope.$on('$stateChangeError',function(event, toState,toParams,fromState,fromParams,error){ + event.preventDefault(); + $state.go('error', {error: error}); + }); + + function makeError (errorCode, errorMessage) { + return { + code: errorCode, + message: errorMessage + }; + } + + return svc; +}); + diff --git a/app/styles/main.scss b/app/styles/main.scss index 86113b1..d11b5ca 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -277,7 +277,7 @@ table { color: $grey; } -#homePage .well{ +#homePage .well, #errorPage .well{ margin-top: 20px; } diff --git a/app/views/error.html b/app/views/error.html new file mode 100644 index 0000000..5b2e7a7 --- /dev/null +++ b/app/views/error.html @@ -0,0 +1,7 @@ +
    +
    +

    Oops! We encountered an error.

    +

    {{ctrl.errorMessage}}

    +

    Click Here to return to the main page.

    +
    +
    diff --git a/test/spec/controllers/error.ctrl.spec.js b/test/spec/controllers/error.ctrl.spec.js new file mode 100644 index 0000000..3c894d0 --- /dev/null +++ b/test/spec/controllers/error.ctrl.spec.js @@ -0,0 +1,29 @@ +'use strict'; + +describe('ErrorCtrl', function() { + var ErrorCtrl; + + beforeEach(function() { + module('yourStlCourts'); + }); + + it('sets error to value on initialization',inject(function(){ + inject(function($controller) { + ErrorCtrl = $controller('ErrorCtrl', { + error: {code: 404, message: "There was an error"} + }); + }); + expect(ErrorCtrl.errorCode).toEqual(404); + expect(ErrorCtrl.errorMessage).toEqual("There was an error"); + })); + + it('sets error to "" on initialization',inject(function(){ + inject(function($controller) { + ErrorCtrl = $controller('ErrorCtrl', { + error: null + }); + }); + expect(ErrorCtrl.errorCode).toEqual(""); + expect(ErrorCtrl.errorMessage).toEqual(""); + })); +}); diff --git a/test/spec/service/Errors.svc.spec.js b/test/spec/service/Errors.svc.spec.js new file mode 100644 index 0000000..b157002 --- /dev/null +++ b/test/spec/service/Errors.svc.spec.js @@ -0,0 +1,25 @@ +'use strict'; + +describe('Errors', function() { + var Errors; + + beforeEach(function() { + module('yourStlCourts'); + inject(function (_Errors_) { + Errors = _Errors_; + }); + }); + + it('returns the correct error object',function(){ + var error = Errors.makeError(404,"Got an error."); + expect(error.code).toEqual(404); + expect(error.message).toEqual("Got an error."); + }); + + it('goes to error page when $stateChangeError is triggered',inject(function($rootScope,$state){ + spyOn($state,'go'); + var error = {code:404,message:"Got an error."}; + $rootScope.$broadcast("$stateChangeError","","","","",error); + expect($state.go).toHaveBeenCalledWith('error',{error:error}); + })); +}); From d4531193392526942e2a77ea938321790693af3a Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Thu, 10 Nov 2016 07:56:40 -0600 Subject: [PATCH 109/233] Limited ui-select choices to 3 at a time (#22) --- app/views/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/home.html b/app/views/home.html index 9e0c78f..93d60f0 100644 --- a/app/views/home.html +++ b/app/views/home.html @@ -11,7 +11,7 @@

    Everything you need in one place.

    {{$select.selected.municipality}} - +
    From 378bbfde548217eab9fdcc745cd913a172f309ae Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Thu, 10 Nov 2016 07:57:45 -0600 Subject: [PATCH 110/233] Fixed pages not scrolling to top when loaded (#21) --- app/scripts/app.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/scripts/app.js b/app/scripts/app.js index c5e8120..17509ac 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -150,10 +150,13 @@ angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvid uiSelectConfig.searchEnabled = true; }); -angular.module('yourStlCourts').run(function (validator, validationElementModifier, errorMessageResolver) { +angular.module('yourStlCourts').run(function ($rootScope,validator, validationElementModifier, errorMessageResolver) { validator.registerDomModifier(validationElementModifier.key, validationElementModifier); validator.setDefaultElementModifier(validationElementModifier.key); validator.setValidElementStyling(false); validator.setErrorMessageResolver(errorMessageResolver.resolve); + $rootScope.$on('$stateChangeSuccess', function() { + document.body.scrollTop = document.documentElement.scrollTop = 0; + }); } ); From 861e939ba42bf4e08866c258fde4e6c238e6a15c Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Thu, 10 Nov 2016 07:59:55 -0600 Subject: [PATCH 111/233] Removed Headers that were underlined and italics on some headers (#19) --- app/styles/main.scss | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/styles/main.scss b/app/styles/main.scss index d11b5ca..65300bf 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -294,13 +294,6 @@ table { padding-right:10px; } -#infoPage h2, #helpPage h2{ - text-decoration: underline; -} - -#infoPage h3, .helpPage-Question{ - font-style: italic; -} .helpPage-Question:hover{ cursor:pointer; } From 9c3d0d440c91c8b8ccaf3b0308480d41781634ca Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Thu, 10 Nov 2016 13:20:03 -0600 Subject: [PATCH 112/233] Combined Home Page and Ticket Search Pages and wrote Unit Tests (#18) * Combined Home Page and Ticket Search Pages and wrote Unit Tests * Added complete unit testing --- app/index.html | 1 - app/scripts/app.js | 10 - app/scripts/controllers/home.ctrl.js | 128 ++++++++++- app/scripts/controllers/ticketSearch.ctrl.js | 134 ----------- app/styles/main.scss | 40 +++- app/views/footer.html | 1 - app/views/header.html | 1 - app/views/home.html | 145 +++++++----- app/views/ticketSearch.html | 88 ------- test/spec/controllers/home.ctrl.spec.js | 228 ++++++++++++++++++- 10 files changed, 478 insertions(+), 298 deletions(-) delete mode 100644 app/scripts/controllers/ticketSearch.ctrl.js delete mode 100644 app/views/ticketSearch.html diff --git a/app/index.html b/app/index.html index 2f05283..6a624d4 100644 --- a/app/index.html +++ b/app/index.html @@ -70,7 +70,6 @@ - diff --git a/app/scripts/app.js b/app/scripts/app.js index 17509ac..657c569 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -39,16 +39,6 @@ angular.module('yourStlCourts').config(function($stateProvider, $urlRouterProvid url: '/privacy', templateUrl: 'views/privacy.html' }) - .state('ticketSearch', { - url: '/tickets/search', - templateUrl: 'views/ticketSearch.html', - controller: 'ticketSearchCtrl as ctrl', - resolve: { - municipalities: function(Courts){ - return Courts.findAll(); - } - } - }) .state('error',{ url:'/error', templateUrl: 'views/error.html', diff --git a/app/scripts/controllers/home.ctrl.js b/app/scripts/controllers/home.ctrl.js index b3f6947..aac5220 100644 --- a/app/scripts/controllers/home.ctrl.js +++ b/app/scripts/controllers/home.ctrl.js @@ -1,8 +1,8 @@ 'use strict'; -angular.module('yourStlCourts').controller('HomeCtrl', function ($state,municipalities) { +angular.module('yourStlCourts').controller('HomeCtrl', function (Citations,toaster,States,municipalities,$uibModal,$state) { var ctrl = this; - + ctrl.states = States; ctrl.municipalities = municipalities; ctrl.selectedCourt = null; @@ -10,4 +10,128 @@ angular.module('yourStlCourts').controller('HomeCtrl', function ($state,municipa $state.go('courtSearchInfo',{'courtId':ctrl.selectedCourt.id}); }; + ctrl.citationCriteria = {}; + + ctrl.hasEverSelected = false; + + ctrl.OptionToSelect = { + TICKET_NUMBER : 'TICKET_NUMBER', + DRIVER_INFO : 'DRIVER_INFO', + LOCATION : 'LOCATION', + COURT_SEARCH : 'COURT_SEARCH' + } + var optionSelectedMap = { + TICKET_NUMBER : false, + DRIVER_INFO : false, + LOCATION : false, + COURT_SEARCH : false + }; + + ctrl.setOptionsSelectedMap = function(optionToSelect){ + initializeCitationCriteria(); + ctrl.hasEverSelected = true; + for(var item in optionSelectedMap){ + if (item == optionToSelect){ + optionSelectedMap[item] = true; + }else{ + optionSelectedMap[item] = false; + } + } + } + + ctrl.isUnselected = function(option){ + return !optionSelectedMap[option] && ctrl.hasEverSelected; + }; + + ctrl.isSelected = function(option ){ + return optionSelectedMap[option]; + }; + + function initializeCitationCriteria() { + ctrl.citationCriteria = { + citationNumber: null, + licenseNumber: null, + licenseState: 'MO', + firstName: null, + lastName: null, + municipalityNames: null, + dob: null + }; + } + + + ctrl.getDOB = function(citationCriteriaFrm){ + if(citationCriteriaFrm.$valid) { + var modalInstance = $uibModal.open({ + templateUrl: 'views/dobPicker.html', + controller: 'dobPickerCtrl as ctrl', + size: 'sm' + }); + + modalInstance.result.then(function (dob) { + ctrl.citationCriteria.dob = dob; + ctrl.findTicket(); + }); + } else { + toaster.pop('error', 'Please provide the required information'); + } + }; + + ctrl.findTicket = function() { + var params = { + dob: ctrl.citationCriteria.dob + }; + + if(optionSelectedMap[ctrl.OptionToSelect.TICKET_NUMBER]) { + params.citationNumber = ctrl.citationCriteria.citationNumber; + } else if(optionSelectedMap[ctrl.OptionToSelect.DRIVER_INFO]) { + params.licenseNumber = ctrl.citationCriteria.licenseNumber; + params.licenseState = ctrl.citationCriteria.licenseState; + } else if(optionSelectedMap[ctrl.OptionToSelect.LOCATION]) { + var names = []; + ctrl.citationCriteria.municipalityNames.forEach(function(municip){ + names.push(municip.municipality); + }); + params.municipalityNames = names; + params.lastName = ctrl.citationCriteria.lastName; + } + + Citations.find(params).then(function(result){ + if(result.citations.length > 0) { + $state.go('citationInfo', {citations: result.citations}); + } else { + var homeLink = 'clicking here' + var noTicketsFoundMsg = 'We could not find any results for the information you provided. It\'s possible that the municipality that issued your citation does not participate in YourSTLCourts. You may obtain information for any municipality via '+homeLink+'. Mention you\'d like them to participate in YourSTLCourts.'; + toaster.pop({ + type: 'error', + body: noTicketsFoundMsg, + bodyOutputType: 'trustedHtml', + timeout:0 + }); + } + }, function(){ + toaster.pop('error', 'Oh no! We couldn\'t get your ticket information!'); + }); + }; + + ctrl.openMap = function(){ + ctrl.citationCriteria.municipalityNames = null; + + var modalInstance = $uibModal.open({ + templateUrl: 'views/locationPickerMap.html', + controller: 'LocationPickerMapCtrl as ctrl', + size: 'md', + resolve: { + municipalities: function() { + return ctrl.municipalities; + } + } + }); + + modalInstance.result.then(function (selectedMunicipalities) { + ctrl.citationCriteria.municipalityNames = selectedMunicipalities; + }); + }; + + initializeCitationCriteria(); }); diff --git a/app/scripts/controllers/ticketSearch.ctrl.js b/app/scripts/controllers/ticketSearch.ctrl.js deleted file mode 100644 index c641d10..0000000 --- a/app/scripts/controllers/ticketSearch.ctrl.js +++ /dev/null @@ -1,134 +0,0 @@ -'use strict'; - -angular.module('yourStlCourts').controller('ticketSearchCtrl', function (Citations, toaster, States, municipalities, $uibModal, $state) { - var ctrl = this; - ctrl.states = States; - ctrl.municipalities = municipalities; - - ctrl.citationCriteria = {}; - - ctrl.hasEverSelected = false; - var optionSelectedMap = { - TICKET_NUMBER : false, - DRIVER_INFO : false, - LOCATION : false - }; - - ctrl.isUnselected = function(option){ - return !optionSelectedMap[option] && ctrl.hasEverSelected; - }; - - ctrl.isSelected = function(option ){ - return optionSelectedMap[option]; - }; - - function initializeCitationCriteria() { - ctrl.citationCriteria = { - citationNumber: null, - licenseNumber: null, - licenseState: 'MO', - firstName: null, - lastName: null, - municipalityNames: null, - dob: null - }; - } - - ctrl.getTicketWithNumber = function(){ - initializeCitationCriteria(); - ctrl.hasEverSelected = true; - optionSelectedMap.TICKET_NUMBER = true; - optionSelectedMap.DRIVER_INFO = false; - optionSelectedMap.LOCATION = false; - }; - - ctrl.getTicketWithDriverInfo = function(){ - initializeCitationCriteria(); - ctrl.hasEverSelected = true; - optionSelectedMap.TICKET_NUMBER = false; - optionSelectedMap.DRIVER_INFO = true; - optionSelectedMap.LOCATION = false; - }; - - ctrl.getTicketWithLocation = function(){ - initializeCitationCriteria(); - ctrl.hasEverSelected = true; - optionSelectedMap.TICKET_NUMBER = false; - optionSelectedMap.DRIVER_INFO = false; - optionSelectedMap.LOCATION = true; - }; - - ctrl.getDOB = function(citationCriteriaFrm){ - if(citationCriteriaFrm.$valid) { - var modalInstance = $uibModal.open({ - templateUrl: 'views/dobPicker.html', - controller: 'dobPickerCtrl as ctrl', - size: 'sm' - }); - - modalInstance.result.then(function (dob) { - ctrl.citationCriteria.dob = dob; - ctrl.findTicket(); - }); - } else { - toaster.pop('error', 'Please provide the required information'); - } - }; - - ctrl.findTicket = function() { - var params = { - dob: ctrl.citationCriteria.dob - }; - - if(optionSelectedMap['TICKET_NUMBER']) { - params.citationNumber = ctrl.citationCriteria.citationNumber; - } else if(optionSelectedMap['DRIVER_INFO']) { - params.licenseNumber = ctrl.citationCriteria.licenseNumber; - params.licenseState = ctrl.citationCriteria.licenseState; - } else if(optionSelectedMap['LOCATION']) { - var names = []; - ctrl.citationCriteria.municipalityNames.forEach(function(municip){ - names.push(municip.municipality); - }); - params.municipalityNames = names; - params.lastName = ctrl.citationCriteria.lastName; - } - - Citations.find(params).then(function(result){ - if(result.citations.length > 0) { - $state.go('citationInfo', {citations: result.citations}); - } else { - var homeLink = 'clicking here' - var noTicketsFoundMsg = 'We could not find any results for the information you provided. It\'s possible that the municipality that issued your citation does not participate in YourSTLCourts. You may obtain information for any municipality via '+homeLink+'. Mention you\'d like them to participate in YourSTLCourts.'; - toaster.pop({ - type: 'error', - body: noTicketsFoundMsg, - bodyOutputType: 'trustedHtml' - }); - } - }, function(){ - toaster.pop('error', 'Oh no! We couldn\'t get your ticket information!'); - }); - }; - - ctrl.openMap = function(){ - ctrl.citationCriteria.municipalityNames = null; - - var modalInstance = $uibModal.open({ - templateUrl: 'views/locationPickerMap.html', - controller: 'LocationPickerMapCtrl as ctrl', - size: 'md', - resolve: { - municipalities: function() { - return ctrl.municipalities; - } - } - }); - - modalInstance.result.then(function (selectedMunicipalities) { - ctrl.citationCriteria.municipalityNames = selectedMunicipalities; - }); - }; - - initializeCitationCriteria(); -}); diff --git a/app/styles/main.scss b/app/styles/main.scss index 65300bf..cb16019 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -74,7 +74,15 @@ h3 { color: $blue; } -p, ul, ol { +p, ul, ol, +.court-search-bar .ui-select-placeholder, +.court-search-bar .ui-select-search, +.court-search-bar ul, +.homepageTileSelected .ui-select-placeholder, +.homepageTileSelected .ui-select-search, +.homepageTileSelected .ui-select-toggle, +.homepageTileSelected ul, +.homepageTileSelected input{ font-size: 1.1rem; } @@ -117,8 +125,17 @@ $homepageTileHeight : 250px; } } -.homePageTileRow { - margin-bottom: $footerHeight; +.homepageHeader-selected{ + text-align: center; +} + +.homepageTileIcon-selected{ + display: block; + width:100%; +} + +.homePageBottomMargin{ + margin-bottom: $footerHeight + 30px; } .homepageTile-bottomButton{ @@ -135,6 +152,17 @@ $homepageTileHeight : 250px; } +.court-search-bar{ + padding: 0 1em 2em 1em; +} + +.find-court-heading h3{ + display: inline-block; +} + +.find-court-heading{ + margin: 1em 0; +} .homepageTile { min-height: $homepageTileHeight; @@ -154,13 +182,13 @@ $homepageTileHeight : 250px; font-size: 1.2em; } -.homepageTile:hover { +.homepageTile:hover, .court-search-bar:hover { border-color: $blue; cursor: pointer; } -.homepageTile.unselected { - opacity: 0.5; +.homepageTile.unselected, .court-search-bar.unselected { + opacity: 0.7; } .homepageTileSelected { diff --git a/app/views/footer.html b/app/views/footer.html index 2c0ca9e..77c66a9 100644 --- a/app/views/footer.html +++ b/app/views/footer.html @@ -6,7 +6,6 @@
    Ticket #{{citation.citation_number}}
    Name{{citation.first_name}} {{citation.last_name}}Court Date{{ctrl.formatDate(citation.court_date)}}Court Date{{ctrl.formatDate(citation.court_dateTime)}} Court Location{{citation.court_location}} Violations @@ -103,7 +103,9 @@

    Violations

    Court Information

    Court Date
    -
    {{ctrl.formatDate(ctrl.selectedCitation.court_date)}}
    +
    {{ctrl.formatDate(ctrl.selectedCitation.court_dateTime)}}
    +
    Court Time
    +
    {{ctrl.formatTime(ctrl.selectedCitation.court_dateTime)}}
    Court Name
    {{ctrl.selectedCitation.court.name}} Court
    Court Phone Number
    diff --git a/app/views/dobPicker.html b/app/views/dobPicker.html index 0b8ecef..cfb1156 100644 --- a/app/views/dobPicker.html +++ b/app/views/dobPicker.html @@ -6,7 +6,7 @@
    Ticket #{{citation.citation_number}}
    Name{{citation.first_name}} {{citation.last_name}} Court Date{{ctrl.formatDate(citation.court_dateTime)}}Court Location{{citation.court_location}}Court Location{{ctrl.citationCourtLocations[citation.court_id]}} Violations diff --git a/test/spec/controllers/citationInfo.ctrl.spec.js b/test/spec/controllers/citationInfo.ctrl.spec.js index b0959d1..993d6e8 100644 --- a/test/spec/controllers/citationInfo.ctrl.spec.js +++ b/test/spec/controllers/citationInfo.ctrl.spec.js @@ -59,12 +59,25 @@ describe('CitationInfoCtrl', function () { var court = { id: 6, + name: "courtName6", address: "123 Anystreet", city: "anyCity", state: "MO", zip: "12345" }; + var court2 = { + id: 5, + name: "courtName5" + }; + + var court3 = { + id: 11, + name: "courtName11" + }; + + var courts = [court,court2,court3]; + var session = { getLastSelectedCitation:function(){return null}, setSelectedCitation:function(value){} @@ -75,7 +88,7 @@ describe('CitationInfoCtrl', function () { beforeEach(function () { module('yourStlCourts'); - inject(function ($rootScope, $httpBackend, $controller, $state, $window, Courts) { + inject(function ($rootScope, $httpBackend, $controller, $state, $window, Courts, moment) { $httpBackend.whenGET(/municipalities/).respond(200, ''); $httpBackend.whenGET(/courts/).respond(200, ''); $httpBackend.whenGET(/info/).respond(200, ''); @@ -87,7 +100,9 @@ describe('CitationInfoCtrl', function () { $window: $window, citations: citations, Courts: Courts, - Session: session + Session: session, + courts: courts, + moment: moment }); }); }); @@ -147,7 +162,8 @@ describe('CitationInfoCtrl', function () { $state: $state, $window: $window, citations: null, - Courts: Courts + Courts: Courts, + courts: courts }); expect($state.go).toHaveBeenCalledWith('home'); @@ -170,7 +186,8 @@ describe('CitationInfoCtrl', function () { $state: $state, $window: $window, citations: [citation], - Courts: Courts + Courts: Courts, + courts: courts }); $rootScope.$apply(); @@ -218,4 +235,9 @@ describe('CitationInfoCtrl', function () { isoDate = null; expect(CitationInfoCtrl.formatDate(isoDate)).toEqual(""); })); + + it('correctly sets citationCourtLocations', function(){ + expect(CitationInfoCtrl.citationCourtLocations[5]).toEqual("courtName5"); + expect(CitationInfoCtrl.citationCourtLocations[11]).toEqual("courtName11"); + }); }); From fdfda5475b761a6ae67ab7198271e54e6813b5af Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Fri, 21 Apr 2017 13:27:05 -0500 Subject: [PATCH 189/233] Removed court fees and added note to fine. (#97) * Removed court fees and added note to fine. * Updated Wording --- app/styles/subPages.scss | 3 ++- app/views/citationInfo.html | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/styles/subPages.scss b/app/styles/subPages.scss index 04cee6b..a925eed 100644 --- a/app/styles/subPages.scss +++ b/app/styles/subPages.scss @@ -361,7 +361,8 @@ faq-group.no-margin .panel-group{ vertical-align: top; } -#payment-warning{ +#payment-warning, +#fine-warning{ display:block; font-style: italic; font-size: .9em; diff --git a/app/views/citationInfo.html b/app/views/citationInfo.html index c8d6306..96a367a 100644 --- a/app/views/citationInfo.html +++ b/app/views/citationInfo.html @@ -62,10 +62,14 @@

    Ticket Info

    ${{ctrl.getFineTotal(ctrl.selectedCitation)}} + + Note: this is the amount of your fine only. Your total will also include court fees. + Fine Info Unavailable + From 57bd45cc11b9324a943669974b8d9f9d36017a19 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Fri, 21 Apr 2017 13:33:09 -0500 Subject: [PATCH 190/233] Updated text (#94) --- app/views/about.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/about.html b/app/views/about.html index a4aa48f..a2cd90a 100644 --- a/app/views/about.html +++ b/app/views/about.html @@ -9,7 +9,7 @@

    About YourSTLCourts

    For years, many court users have faced difficult navigation, unclear processes, sometimes unfair practices and a lack of effective communication. With a focus on using technology to increase accessibility, YourSTLCourts is incrementally improving how citizens interact with the municipal court system. Our partners have been diligently coding, advocating and building relationships in order to increase government transparency and decrease traffic-related incarcerations through a pre-trial, technology-based-solution known as YourSTLCourts.

    - YourSTLCourts was born of the John D. and Catherine T. MacArthur Foundation Civic Tech and Data Collaborative grant, awarded and prototyped in GlobalHack's first civic hackathon in 2015, and funded in part by the John D. and Catherine T. MacArthur Foundation's Safety and Justice Challenge Grant in 2016. The grant is managed by Rise Community Development in partnership with St. Louis County and CivTech St. Louis. + YourSTLCourts was started by the John D. and Catherine T. MacArthur Foundation Civic Tech and Data Collaborative grant, awarded and prototyped in GlobalHack's first civic hackathon in 2015, and funded in part by the John D. and Catherine T. MacArthur Foundation's Safety and Justice Challenge Grant in 2016. The grant is managed by Rise Community Development in partnership with St. Louis County and CivTech St. Louis.

    It is only possible to find open municipal case information in YourSTLCourts by those courts that have elected to provide such data. Not all courts may participate. From 55db86e4bfa47b10659eea271605cf852cdc8cf7 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Fri, 21 Apr 2017 14:54:11 -0500 Subject: [PATCH 191/233] =?UTF-8?q?payment=20button=20and=20associated=20n?= =?UTF-8?q?ote=20now=20both=20hide=20when=20payment=20is=20not=20=E2=80=A6?= =?UTF-8?q?=20(#96)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * payment button and associated note now both hide when payment is not available * made a showPaymentButton method in the controller and added unit test. --- app/scripts/controllers/citationInfo.ctrl.js | 8 ++++ app/views/citationInfo.html | 4 +- .../controllers/citationInfo.ctrl.spec.js | 39 ++++++++++++++++++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/app/scripts/controllers/citationInfo.ctrl.js b/app/scripts/controllers/citationInfo.ctrl.js index c6a8eb0..10f5dec 100644 --- a/app/scripts/controllers/citationInfo.ctrl.js +++ b/app/scripts/controllers/citationInfo.ctrl.js @@ -116,6 +116,14 @@ angular.module('yourStlCourts').controller('CitationInfoCtrl', function (faqData return canPayOnline; }; + ctrl.showPaymentButton = function(){ + if (ctrl.selectedCitation) { + return (ctrl.paymentUrl != '' && ctrl.canPayOnline(ctrl.selectedCitation)); + }else{ + return false; + } + }; + ctrl.hasViolations = function(citation) { return citation.violations.length > 0; }; diff --git a/app/views/citationInfo.html b/app/views/citationInfo.html index 96a367a..7306f40 100644 --- a/app/views/citationInfo.html +++ b/app/views/citationInfo.html @@ -129,8 +129,8 @@

    Court Information

    I Want To...

    -

    - +

    + Note: paying your ticket is considered an admission of guilt. If you do not wish to plead guilty, you must appear in court to meet with the judge. diff --git a/test/spec/controllers/citationInfo.ctrl.spec.js b/test/spec/controllers/citationInfo.ctrl.spec.js index 993d6e8..3f58965 100644 --- a/test/spec/controllers/citationInfo.ctrl.spec.js +++ b/test/spec/controllers/citationInfo.ctrl.spec.js @@ -32,6 +32,11 @@ describe('CitationInfoCtrl', function () { court_cost: 2.0 }; + var violationPayableOnline = { + id:20, + can_pay_online:true + }; + var citation = { id: 2, court_id: 5, @@ -53,6 +58,13 @@ describe('CitationInfoCtrl', function () { municipality_id:5 }; + var citationPayableOnline = { + id: 13, + court_id:11, + violations: [violationPayableOnline], + municipality_id:5 + }; + var citations = [ citation, citationWithViolations ]; @@ -125,7 +137,7 @@ describe('CitationInfoCtrl', function () { expect(CitationInfoCtrl.selectedCitation.courtDirectionLink).toEqual(expectedAddress); })); - it('correctly sets selected paymentUrl', inject(function (Courts, $q, $rootScope,Session) { + it('correctly sets selected paymentUrl', inject(function (Courts, $q, $rootScope) { var deferred = $q.defer(); deferred.resolve(court); spyOn(Courts, 'findById').and.returnValue(deferred.promise); @@ -136,6 +148,31 @@ describe('CitationInfoCtrl', function () { expect(CitationInfoCtrl.paymentUrl).toEqual(municipality.paymentUrl); })); + it('correctly shows or hides payment button', inject(function(Courts, $q, $rootScope){ + var deferred = $q.defer(); + deferred.resolve(court); + spyOn(Courts, 'findById').and.returnValue(deferred.promise); + + CitationInfoCtrl.selectCitation(null); + $rootScope.$apply(); + expect (CitationInfoCtrl.showPaymentButton()).toBe(false); + + CitationInfoCtrl.selectCitation(citationWithViolations); + CitationInfoCtrl.paymentUrl = "someUrl"; + $rootScope.$apply(); + expect (CitationInfoCtrl.showPaymentButton()).toBe(false); + + CitationInfoCtrl.selectCitation(citationPayableOnline); + CitationInfoCtrl.paymentUrl = "someUrl"; + $rootScope.$apply(); + expect (CitationInfoCtrl.showPaymentButton()).toBe(true); + + CitationInfoCtrl.selectCitation(citationPayableOnline); + CitationInfoCtrl.paymentUrl = ""; + $rootScope.$apply(); + expect (CitationInfoCtrl.showPaymentButton()).toBe(false); + })); + it('correctly sets selected citation when citation is null', inject(function () { CitationInfoCtrl.selectCitation(null); From c71c916e35a7fc3cc76e760ffdc08251847668cf Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 24 Apr 2017 15:35:31 -0500 Subject: [PATCH 192/233] Fixed drop down from separating (#104) --- app/styles/main.scss | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/app/styles/main.scss b/app/styles/main.scss index 4c84fb9..43e028b 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -309,9 +309,9 @@ label { background-size:100%; background-repeat: no-repeat; padding:0px; + padding-top:50px; text-align: center; font-family: 'Source Sans Pro', sans-serif; - overflow: hidden; /* anything other than visible needed so that the h1 margin-top doesn't collapse into this element's margin-top */ width:100%; } @@ -320,7 +320,6 @@ label { color:$white; padding:0 15px; margin:0px !important; - margin-top:50px !important; } #searchBoxInstructions{ @@ -352,10 +351,10 @@ label { #mainSearchBox{ height: 285px; background-image: url('../images/main-image-1366x285.jpg'); + padding-top:50px; } #mainSearchBox h1{ font-size:3em; - margin-top:50px !important; } #searchBoxInstructions,.main-page-banner{ @@ -376,11 +375,11 @@ label { #mainSearchBox{ height: 214px; background-image: url('../images/main-image-1024x214.jpg'); + padding-top:30px; } #mainSearchBox h1{ font-size:2.5em; - margin-top:30px !important; } #searchBoxInstructions,.main-page-banner{ @@ -396,11 +395,11 @@ label { #mainSearchBox{ height: 161px; background-image: url('../images/main-image-768x161.jpg'); + padding-top:10px; } #mainSearchBox h1{ font-size:2em; - margin-top:10px !important; } #searchBoxInstructions, .main-page-banner{ @@ -421,11 +420,11 @@ label { #mainSearchBox{ height: 94px; background-image: url('../images/main-image-450x94.jpg'); + padding-top:5px; } #mainSearchBox h1{ font-size:1.1em; - margin-top:5px !important; } #searchBoxInstructions, .main-page-banner{ @@ -441,11 +440,11 @@ label { #mainSearchBox{ height: 67px; background-image: url('../images/main-image-320x67.jpg'); + padding-top:5px; } #mainSearchBox h1{ font-size:1em; - margin-top:5px !important; } #searchBoxInstructions,.main-page-banner{ @@ -563,9 +562,6 @@ table { } } -#municipalitiesFinder .ui-select-choices { - position:fixed; - top:auto; - left:auto; - width:inherit; +#municipalitiesFinder .ui-select-search{ + width:100% !important; } From 92de684dc92d8916100cfe8c7808e3681bd61da0 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 24 Apr 2017 15:36:01 -0500 Subject: [PATCH 193/233] increased size of text message sign up message for mobile phones (#102) --- app/styles/pageMessage.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/styles/pageMessage.scss b/app/styles/pageMessage.scss index 91f0f36..a7ac526 100644 --- a/app/styles/pageMessage.scss +++ b/app/styles/pageMessage.scss @@ -40,7 +40,7 @@ z-index: 9; margin:0 auto 10px auto; background-color: $scheme_limeGreen; - width:80%; + width:90%; } @media only screen and (max-width: 767px) { @@ -61,8 +61,8 @@ } } -@media only screen and (max-width: 380px) { +@media only screen and (max-width: 367px) { .page-message-message{ - font-size: .8em; + font-size: .9em; } } From 9e9c35dc687a8180da4d8244580a387fb0fd6947 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 24 Apr 2017 15:36:35 -0500 Subject: [PATCH 194/233] Updated YourLegalRights copy (#99) * Updated YourLegalRights copy * updated page formatting --- app/views/info.html | 331 ++++++++++++++++++++++---------------------- 1 file changed, 167 insertions(+), 164 deletions(-) diff --git a/app/views/info.html b/app/views/info.html index c0e5134..29d5736 100644 --- a/app/views/info.html +++ b/app/views/info.html @@ -2,170 +2,173 @@

    Your Ticket. Your Rights. Right at Your Fingertips.

    - -
    - -

    Your Legal Rights

    -

    You must first enter a plea. You may plead not guilty, guilty, or guilty with an explanation. If you plead NOT GUILTY, your case will be set for trial. You must appear on the date and at the time the trial is scheduled or a warrant will be issued for your arrest. At your trial, you should be prepared to present any evidence you believe will help you in your defense. The rules of evidence apply at your trial, which may prevent some evidence you may want to present from being admitted before the Judge.

    -

    Your Rights with a Not Guilty Plea are as follows:

    -
    -
      -
    • You have a right to be informed as to the nature of the charge against you and the minimum and maximum punishment for the charge;
    • -
    • You have the right to be represented by an attorney and an attorney may be appointed for you if you are indigent (unable to afford an attorney) AND it appears that there would possibly be a jail sentence upon conviction;
    • -
    • You have a right to a have a trial, including a trial by jury;
    • -
    • At trial you have the right to question any witness who may testify against you;
    • -
    • You have the right to subpoena persons to testify on your behalf at your trial (a subpoena is an order from the court to a witness that they must appear at the trial). The court administrator can provide the subpoena forms, but you must serve them yourself upon the witness;
    • -
    • You have the right to testify at your trial but neither the City nor anyone else can force you to testify;
    • -
    • If you had a trial and were found guilty you have a right to appeal that decision to another court.
    • -
    -
    -

    If you plead guilty, you give up all the rights listed above

    -
    -
      -
    • By pleading Guilty, you admit that you committed the act charged, that the law prohibits the act, and that you have no defense for your act. This also relieves the City of its burden of proving a case against you. You may plead guilty for most offenses by mail or by paying your fine during court business hours.
    • -
    • If you were involved in a traffic accident at the time of the alleged offense, your plea of guilty could be used later in a civil suit for damages as an admission by you that you were at fault or were the party responsible for the accident. You are urged not to plead guilty if you do not feel that you are guilty.
    • -
    • In the case of a guilty plea or a finding of guilty, a fine most likely will be assessed. A plea of Guilty with an Explanation may or may not have an effect on the amount assessed. If you are unable to make a payment on the date of your court hearing, you must speak with the court clerk to make arrangements to pay or to be found indigent, which will result in community service being assessed. If you are given a new date for payment, if no payment is made and you do not appear on your court date, a warrant will be issued for your arrest and you may have your driver’s license suspended. If you are unable to pay your fine, you must still show up at your court date. You WILL NOT be arrested for failure to pay if you show up for court.
    • -
    -
    -

    Punishment and Fines

    -

    - After a plea of guilty or a finding of guilty, the court has the authority to assess court fines and/or a jail sentence. The amount assessed by the court is affected by the facts and the circumstances of the case. Mitigating circumstances may lower the fine, but aggravating circumstances may increase the fine. You have a right to know the minimum and maximum punishment for your offense at the start of your trial. -

    + +
    + +

    Your Legal Rights

    +

    + You have been charged with an ordinance violation(s). At your first court appearance (called an arraignment), you will be advised of the charge(s) against you. You have the right to retain counsel. You have the right to request the appointment of counsel if you are indigent and unable to employ counsel and there is a possibility of a jail sentence. You have the right to remain silent. Any statement made by you may be used against you. +

    +

    You May Plead Not Guilty

    +

    + Your case will then be scheduled for a trial at a later date. You have the right to a Jury Trial. At the trial, you are presumed innocent. The County Counselor/Prosecutor must prove your guilt beyond a reasonable doubt. At the trial you have the right to confront and cross-examine the witnesses against you. You have the right to present evidence in defense of the charges, call witnesses and testify, but you are not required to do so. +

    +

    + If you are found guilty after the trial, you have the right to file an appeal. The appeal requires a cost deposit $70 (per case) plus the amount charged by the State to transcribe the tape of the trial. The appeal must be filed within ten (10) days of the court's finding of guilt. Your case will be transcribed and transferred to the Missouri Court of Appeals for further adjudication. +

    + +

    You May Plead Guilty

    +

    + If you plead guilty, there will not be a trial of any kind and you will thereby waive you right to a trial. In most cases, a fine plus court costs will be assessed. You will be given a Fine/Cost/Fee Bill with the payment due date and payment instructions. If you are unable to pay the fine you can request that your case be placed on a future docket, to allow you time to pay the penalty imposed. Payment plans can be arranged. +

    +

    + You will not be incarcerated for failure to pay your fines and/or court costs. However, if you fail to appear in court to show cause why you cannot pay, you may ultimately be arrested. If you are indigent and cannot pay the fines and/or the court costs a form will be provided to you so that the Judge can determine your ability to pay. +

    + +

    Miscellaneous

    +

    + Neither the judge nor the court clerks can give you legal advice. If you wish to consult with or hire an attorney, please tell the judge and he/she will continue your case. +

    +

    + The courtroom is open to the public and can accommodate anyone with a disability. Everyone entering the courtroom is subject to security screening. No weapons of any kind are allowed. +

    + +
    + +
    + +

    Dress Code

    +

    + You must dress appropriately if you enter the courthouses. No halter tops, t-shirts, shorts, baggy pants, or other inappropriate clothing will be tolerated. You also must turn off all pagers and cell-phones. +

    -
    - -

    Dress Code

    -

    - You must dress appropriately if you enter the courthouses. No halter tops, t-shirts, shorts, baggy pants, or other inappropriate clothing will be tolerated. You also must turn off all pagers and cell-phones. -

    -
    -
    - -

    Court Fees & Fines

    -

    - In addition to the fine associated with your violation, all cases incur a court fee of approximately $20-$30. These fees pay for basic court costs as well as other programs and surcharges, such as: Crime Victim Compensation, Law Enforcement Training, Peace Officer Training, Biometric Verification System, and Domestic Violence Shelter. No other fees are assessed. Each of the offenses below, carries with it a separate and compounding fine, which could cost as much as $72 or as little as $49 each (approximates). Ultimately, a judge can determine the cost of each fine on an individual basis. -

    -
      -
      -
    • - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Offense
      Corner Cutting to Avoid Signal
      Driving On Closed Road
      Driving Over Curb
      Driving Wrong Side of Road
      Driving Wrong Way (One Way Street)
      Blocking Driveway or Alley
      Expired License Plates (Tags)
      Failure to Secure a Load
      Fake Temporary Tags
      Fictitious License Tabs
      Improper Exhaust or Muffler
      Improper Registration (Failure to Register)
      License Plate not Illuminated
      No Brake Lights
      No Headlight
      No Inspection Sticker
      No License Plates
      No Motorcycle Helmet
      No Taillights
      Child Restraint Seat Violation*
      Failure to Keep to the Right
      Failure to Obey Electric Signal
      Failure to Obey Stop Sign
      Failure to Sound Horn
      Failure to Yield
      Failure to Yield to Emergency Vehicles
      Following too Closely
      Impeding/Obstructing Traffic Movement
      Improper Backing
      Improper Lane Usage
      Improper Passing
      Improper/Prohibited Turn
      No Through Traffic
      Prohibited U-Turn
      Traffic Turn Signal Violation
      -

      *typically waived if child restraint is purchased before court date

      -
    • -
    -
    +
    + +

    Court Fees & Fines

    +

    + In addition to the fine associated with your violation, all cases incur a court fee of approximately $20-$30. These fees pay for basic court costs as well as other programs and surcharges, such as: Crime Victim Compensation, Law Enforcement Training, Peace Officer Training, Biometric Verification System, and Domestic Violence Shelter. No other fees are assessed. Each of the offenses below, carries with it a separate and compounding fine, which could cost as much as $72 or as little as $49 each (approximates). Ultimately, a judge can determine the cost of each fine on an individual basis. +

    +
      +
      +
    • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Offense
      Corner Cutting to Avoid Signal
      Driving On Closed Road
      Driving Over Curb
      Driving Wrong Side of Road
      Driving Wrong Way (One Way Street)
      Blocking Driveway or Alley
      Expired License Plates (Tags)
      Failure to Secure a Load
      Fake Temporary Tags
      Fictitious License Tabs
      Improper Exhaust or Muffler
      Improper Registration (Failure to Register)
      License Plate not Illuminated
      No Brake Lights
      No Headlight
      No Inspection Sticker
      No License Plates
      No Motorcycle Helmet
      No Taillights
      Child Restraint Seat Violation*
      Failure to Keep to the Right
      Failure to Obey Electric Signal
      Failure to Obey Stop Sign
      Failure to Sound Horn
      Failure to Yield
      Failure to Yield to Emergency Vehicles
      Following too Closely
      Impeding/Obstructing Traffic Movement
      Improper Backing
      Improper Lane Usage
      Improper Passing
      Improper/Prohibited Turn
      No Through Traffic
      Prohibited U-Turn
      Traffic Turn Signal Violation
      +

      *typically waived if child restraint is purchased before court date

      +
    • +
    +
    From 55e86bde6c1e3e2a5c81b81a080d99e4086ccc9a Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 24 Apr 2017 15:37:44 -0500 Subject: [PATCH 195/233] view button causes scroll to citation information (#95) * view button causes scroll to citation information unit tests created * added anchorScroll to selectCitation --- app/scripts/controllers/citationInfo.ctrl.js | 7 +++-- app/views/citationInfo.html | 2 +- .../controllers/citationInfo.ctrl.spec.js | 27 ++++++++++++++----- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/app/scripts/controllers/citationInfo.ctrl.js b/app/scripts/controllers/citationInfo.ctrl.js index 10f5dec..735ce08 100644 --- a/app/scripts/controllers/citationInfo.ctrl.js +++ b/app/scripts/controllers/citationInfo.ctrl.js @@ -1,13 +1,13 @@ 'use strict'; -angular.module('yourStlCourts').controller('CitationInfoCtrl', function (faqData,$state, $window, citations,municipalities,courts,Courts,Session,moment) { +angular.module('yourStlCourts').controller('CitationInfoCtrl', function (faqData,$state, $window, citations,municipalities,courts,Courts,Session,moment,$anchorScroll) { var ctrl = this; ctrl.faqData = faqData; ctrl.selectedCitation = null; ctrl.paymentUrl = ""; ctrl.citationCourtLocations = {}; - ctrl.selectCitation = function(citation){ + ctrl.selectCitation = function(citation,idToScrollTo){ ctrl.selectedCitation = citation; Session.setSelectedCitation(ctrl.selectedCitation); if (ctrl.selectedCitation) { @@ -21,6 +21,9 @@ angular.module('yourStlCourts').controller('CitationInfoCtrl', function (faqData break; } } + if (citations.length > 1) { + $anchorScroll(idToScrollTo); + } } }; diff --git a/app/views/citationInfo.html b/app/views/citationInfo.html index 7306f40..43d2781 100644 --- a/app/views/citationInfo.html +++ b/app/views/citationInfo.html @@ -15,7 +15,7 @@

    Ticket Results

    Violations
    Ticket #{{citation.citation_number}}
    Name{{citation.first_name}} {{citation.last_name}}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Offense
    Corner Cutting to Avoid Signal
    Driving On Closed Road
    Driving Over Curb
    Driving Wrong Side of Road
    Driving Wrong Way (One Way Street)
    Blocking Driveway or Alley
    Expired License Plates (Tags)
    Failure to Secure a Load
    Fake Temporary Tags
    Fictitious License Tabs
    Improper Exhaust or Muffler
    Improper Registration (Failure to Register)
    License Plate not Illuminated
    No Brake Lights
    No Headlight
    No Inspection Sticker
    No License Plates
    No Motorcycle Helmet
    No Taillights
    Child Restraint Seat Violation*
    Failure to Keep to the Right
    Failure to Obey Electric Signal
    Failure to Obey Stop Sign
    Failure to Sound Horn
    Failure to Yield
    Failure to Yield to Emergency Vehicles
    Following too Closely
    Impeding/Obstructing Traffic Movement
    Improper Backing
    Improper Lane Usage
    Improper Passing
    Improper/Prohibited Turn
    No Through Traffic
    Prohibited U-Turn
    Traffic Turn Signal Violation
    +

    *typically waived if child restraint is purchased before court date

    + + +
    +
    +
    diff --git a/app/views/header.html b/app/views/header.html index da76bee..6f45c79 100644 --- a/app/views/header.html +++ b/app/views/header.html @@ -18,6 +18,7 @@
  • Find Your Ticket
  • Your Legal Rights
  • +
  • Going To Court
  • Community Service
  • Help
  • diff --git a/app/views/info.html b/app/views/info.html index 29d5736..d19ad69 100644 --- a/app/views/info.html +++ b/app/views/info.html @@ -4,8 +4,6 @@

    Your Ticket. Your Rights. Right at Your Fingertips.

    @@ -37,138 +35,7 @@

    Miscellaneous

    The courtroom is open to the public and can accommodate anyone with a disability. Everyone entering the courtroom is subject to security screening. No weapons of any kind are allowed.

    -
    -
    - -

    Dress Code

    -

    - You must dress appropriately if you enter the courthouses. No halter tops, t-shirts, shorts, baggy pants, or other inappropriate clothing will be tolerated. You also must turn off all pagers and cell-phones. -

    -
    -
    - -

    Court Fees & Fines

    -

    - In addition to the fine associated with your violation, all cases incur a court fee of approximately $20-$30. These fees pay for basic court costs as well as other programs and surcharges, such as: Crime Victim Compensation, Law Enforcement Training, Peace Officer Training, Biometric Verification System, and Domestic Violence Shelter. No other fees are assessed. Each of the offenses below, carries with it a separate and compounding fine, which could cost as much as $72 or as little as $49 each (approximates). Ultimately, a judge can determine the cost of each fine on an individual basis. -

    -
      -
      -
    • - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Offense
      Corner Cutting to Avoid Signal
      Driving On Closed Road
      Driving Over Curb
      Driving Wrong Side of Road
      Driving Wrong Way (One Way Street)
      Blocking Driveway or Alley
      Expired License Plates (Tags)
      Failure to Secure a Load
      Fake Temporary Tags
      Fictitious License Tabs
      Improper Exhaust or Muffler
      Improper Registration (Failure to Register)
      License Plate not Illuminated
      No Brake Lights
      No Headlight
      No Inspection Sticker
      No License Plates
      No Motorcycle Helmet
      No Taillights
      Child Restraint Seat Violation*
      Failure to Keep to the Right
      Failure to Obey Electric Signal
      Failure to Obey Stop Sign
      Failure to Sound Horn
      Failure to Yield
      Failure to Yield to Emergency Vehicles
      Following too Closely
      Impeding/Obstructing Traffic Movement
      Improper Backing
      Improper Lane Usage
      Improper Passing
      Improper/Prohibited Turn
      No Through Traffic
      Prohibited U-Turn
      Traffic Turn Signal Violation
      -

      *typically waived if child restraint is purchased before court date

      -
    • -
    -
    From e9a4b53eabb67da61f1501e8aaf48b844738a772 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 30 Apr 2017 19:34:40 -0500 Subject: [PATCH 203/233] Updated wording. (#110) * Updated wording. * Updated wording with clarification --- app/views/communityService.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/views/communityService.html b/app/views/communityService.html index c3c273f..cb86fab 100644 --- a/app/views/communityService.html +++ b/app/views/communityService.html @@ -5,6 +5,11 @@

    Community Service Options

    Maybe you have a ticket but can’t afford the fines and fees. Spending time doing community service can be an alternative to paying for some traffic violations, as long as the judge agrees.

    +

    + If, when you see the judge, he/she agrees to a community service option in lieu of fines, it will be your responsibility to contact the Community Service agency, arrange for the community service time and date with them, and then bring back proof of your service to the judge. +

    + + From 9b7a1841fce57d79911f3319bb600b6628563f86 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 30 Apr 2017 19:35:16 -0500 Subject: [PATCH 204/233] updated q&a by removing a question and answer (#111) --- app/data/questionAnswers.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/data/questionAnswers.json b/app/data/questionAnswers.json index 22ecfc2..09725ce 100644 --- a/app/data/questionAnswers.json +++ b/app/data/questionAnswers.json @@ -48,10 +48,6 @@ "fill-in":""} ], "legal-faq": [ - {"q":"How do I get help with my case?", - "a":"Everyone has the right to legal representation in court. There are lawyers who are willing to provide assistance to you on your case at no charge. Though, this does not obligate them to represent you unless you enter into a formal agreement. Contact 282-7272 for more information.", - "keywords":[], - "fill-in":""}, {"q":"I do not believe the charge against me is fair, but what can I do?", "a":"If you believe you are not guilty, do not plead guilty. Doing so is an admission of guilt that can result in relinquishing your rights of legal representation and presenting witnesses. Additional repercussions could include: fines, points on your license and/or additional liability. If you want to plead “not guilty,” you have the right to legal representation, and a lawyer will be provided to you if you cannot afford one. Visit the Your Rights page for additional information.", "keywords":[], From ce7fc1b30c38326a96f21cf3ac20d2eab93528fe Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 30 Apr 2017 21:17:24 -0500 Subject: [PATCH 205/233] Updated about page text (#112) --- app/views/about.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/about.html b/app/views/about.html index 56a1f39..b99e299 100644 --- a/app/views/about.html +++ b/app/views/about.html @@ -3,10 +3,10 @@

    About YourSTLCourts

    - YourSTLCourts is the St. Louis region’s only free, web and mobile tool that puts your rights and your case records right at your fingertips. Use your phone or computer to access your court date and location, payment and community service options, and legal rights. Then, sign up to receive reminders of your court date via text message, by texting “Ticket” to {{ctrl.textPhoneNumber}}. Standard SMS rates apply. + YourSTLCourts is the St. Louis region’s only free, web and mobile tool that puts your rights and your case records right at your fingertips. Use your phone or computer to access your court date and location, payment and community service options, and legal rights. Then, sign up to receive reminders of your court date via text message, by texting “ticket” to {{ctrl.textPhoneNumber}}. Standard SMS rates apply.

    - For years, many court users have faced difficult navigation, unclear processes, sometimes unfair practices and a lack of effective communication. With a focus on using technology to increase accessibility, YourSTLCourts is incrementally improving how citizens interact with the municipal court system. Our partners have been diligently coding, advocating and building relationships in order to increase government transparency and decrease traffic-related incarcerations through a pre-trial, technology-based-solution known as YourSTLCourts. + With a focus on using technology to increase accessibility, YourSTLCourts is incrementally improving how citizens interact with the municipal court system. Our partners have been diligently coding, advocating and building relationships in order to decrease traffic-related incarcerations through a pre-trial, technology-based-solution known as YourSTLCourts.

    YourSTLCourts was started by the John D. and Catherine T. MacArthur Foundation Civic Tech and Data Collaborative grant, awarded and prototyped in GlobalHack's first civic hackathon in 2015, and funded in part by the John D. and Catherine T. MacArthur Foundation's Safety and Justice Challenge Grant in 2016. The grant is managed by Rise Community Development in partnership with St. Louis County and CivTech St. Louis. From d47e6527bfe2c2c54ab886a889bdc7b46acbce9e Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 30 Apr 2017 21:17:44 -0500 Subject: [PATCH 206/233] Added find a court menu item (#113) --- app/views/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/header.html b/app/views/header.html index 6f45c79..aac35f3 100644 --- a/app/views/header.html +++ b/app/views/header.html @@ -16,7 +16,7 @@

    The following are guidelines for going to court. These are not court-specific, and rules for attendance are likely vary from court to court, however they are intended to be general best practices for going to court.

    - +

    Dress Code

    Appropriate clothing should be work when going to court. While many courts will not require a strict dress code, it is better to avoid any potential dress code violations when possible. @@ -23,7 +23,7 @@

    Dress Code

    - +

    Do's & Don'ts

    Addressing The Court

    @@ -39,7 +39,7 @@

    Smoking and Nicotine Consumption

    - +

    Court Fees & Fines

    In addition to the fine associated with your violation, cases may incur additional court fees. These fees pay for basic court costs as well as other programs and surcharges, such as: Crime Victim Compensation, Law Enforcement Training, Peace Officer Training, Biometric Verification System, Domestic Violence Shelter and others. diff --git a/app/views/info.html b/app/views/info.html index d19ad69..793f55d 100644 --- a/app/views/info.html +++ b/app/views/info.html @@ -3,39 +3,41 @@

    Your Ticket. Your Rights. Right at Your Fingertips.

    -
    - -

    Your Legal Rights

    -

    - You have been charged with an ordinance violation(s). At your first court appearance (called an arraignment), you will be advised of the charge(s) against you. You have the right to retain counsel. You have the right to request the appointment of counsel if you are indigent and unable to employ counsel and there is a possibility of a jail sentence. You have the right to remain silent. Any statement made by you may be used against you. -

    -

    You May Plead Not Guilty

    -

    - Your case will then be scheduled for a trial at a later date. You have the right to a Jury Trial. At the trial, you are presumed innocent. The County Counselor/Prosecutor must prove your guilt beyond a reasonable doubt. At the trial you have the right to confront and cross-examine the witnesses against you. You have the right to present evidence in defense of the charges, call witnesses and testify, but you are not required to do so. -

    -

    - If you are found guilty after the trial, you have the right to file an appeal. The appeal requires a cost deposit $70 (per case) plus the amount charged by the State to transcribe the tape of the trial. The appeal must be filed within ten (10) days of the court's finding of guilt. Your case will be transcribed and transferred to the Missouri Court of Appeals for further adjudication. -

    -

    You May Plead Guilty

    -

    - If you plead guilty, there will not be a trial of any kind and you will thereby waive you right to a trial. In most cases, a fine plus court costs will be assessed. You will be given a Fine/Cost/Fee Bill with the payment due date and payment instructions. If you are unable to pay the fine you can request that your case be placed on a future docket, to allow you time to pay the penalty imposed. Payment plans can be arranged. -

    -

    - You will not be incarcerated for failure to pay your fines and/or court costs. However, if you fail to appear in court to show cause why you cannot pay, you may ultimately be arrested. If you are indigent and cannot pay the fines and/or the court costs a form will be provided to you so that the Judge can determine your ability to pay. -

    +

    Your Legal Rights

    +

    + You have been charged with an ordinance violation(s). At your first court appearance (called an arraignment), you will be advised of the charge(s) against you. You have the right to retain counsel. You have the right to request the appointment of counsel if you are indigent and unable to employ counsel and there is a possibility of a jail sentence. You have the right to remain silent. Any statement made by you may be used against you. +

    + +

    You May Plead Not Guilty

    +

    + Your case will then be scheduled for a trial at a later date. You have the right to a Jury Trial. At the trial, you are presumed innocent. The County Counselor/Prosecutor must prove your guilt beyond a reasonable doubt. At the trial you have the right to confront and cross-examine the witnesses against you. You have the right to present evidence in defense of the charges, call witnesses and testify, but you are not required to do so. +

    +

    + If you are found guilty after the trial, you have the right to file an appeal. The appeal requires a cost deposit $70 (per case) plus the amount charged by the State to transcribe the tape of the trial. The appeal must be filed within ten (10) days of the court's finding of guilt. Your case will be transcribed and transferred to the Missouri Court of Appeals for further adjudication. +

    -

    Miscellaneous

    -

    - Neither the judge nor the court clerks can give you legal advice. If you wish to consult with or hire an attorney, please tell the judge and he/she will continue your case. -

    -

    - The courtroom is open to the public and can accommodate anyone with a disability. Everyone entering the courtroom is subject to security screening. No weapons of any kind are allowed. -

    -
    + +

    You May Plead Guilty

    +

    + If you plead guilty, there will not be a trial of any kind and you will thereby waive you right to a trial. In most cases, a fine plus court costs will be assessed. You will be given a Fine/Cost/Fee Bill with the payment due date and payment instructions. If you are unable to pay the fine you can request that your case be placed on a future docket, to allow you time to pay the penalty imposed. Payment plans can be arranged. +

    +

    + You will not be incarcerated for failure to pay your fines and/or court costs. However, if you fail to appear in court to show cause why you cannot pay, you may ultimately be arrested. If you are indigent and cannot pay the fines and/or the court costs a form will be provided to you so that the Judge can determine your ability to pay. +

    + +

    Miscellaneous

    +

    + Neither the judge nor the court clerks can give you legal advice. If you wish to consult with or hire an attorney, please tell the judge and he/she will continue your case. +

    +

    + The courtroom is open to the public and can accommodate anyone with a disability. Everyone entering the courtroom is subject to security screening. No weapons of any kind are allowed. +

    -
    + diff --git a/test/spec/controllers/goingToCourt.ctrl.spec.js b/test/spec/controllers/goingToCourt.ctrl.spec.js new file mode 100644 index 0000000..f4df9fb --- /dev/null +++ b/test/spec/controllers/goingToCourt.ctrl.spec.js @@ -0,0 +1,25 @@ +'use strict'; + +describe('GoingToCourtCtrl', function () { + var GoingToCourtCtrl; + var anchorScrollSpy = jasmine.createSpy('anchorScroll'); + + beforeEach(function () { + module('yourStlCourts'); + + inject(function ($httpBackend, $controller) { + $httpBackend.whenGET(/municipalities/).respond(200, ''); + $httpBackend.whenGET(/courts/).respond(200, ''); + $httpBackend.whenGET(/info/).respond(200, ''); + + GoingToCourtCtrl = $controller('GoingToCourtCtrl', { + $anchorScroll:anchorScrollSpy + }); + }); + }); + + it('correctly initializes', inject(function () { + GoingToCourtCtrl.scrollTo("hi"); + expect(anchorScrollSpy).toHaveBeenCalledWith("hi"); + })); +}); diff --git a/test/spec/controllers/info.ctrl.spec.js b/test/spec/controllers/info.ctrl.spec.js new file mode 100644 index 0000000..9cc2cfd --- /dev/null +++ b/test/spec/controllers/info.ctrl.spec.js @@ -0,0 +1,25 @@ +'use strict'; + +describe('InfoCtrl', function () { + var InfoCtrl; + var anchorScrollSpy = jasmine.createSpy('anchorScroll'); + + beforeEach(function () { + module('yourStlCourts'); + + inject(function ($httpBackend, $controller) { + $httpBackend.whenGET(/municipalities/).respond(200, ''); + $httpBackend.whenGET(/courts/).respond(200, ''); + $httpBackend.whenGET(/info/).respond(200, ''); + + InfoCtrl = $controller('InfoCtrl', { + $anchorScroll:anchorScrollSpy + }); + }); + }); + + it('correctly initializes', inject(function () { + InfoCtrl.scrollTo("hi"); + expect(anchorScrollSpy).toHaveBeenCalledWith("hi"); + })); +}); From a03fbf5b7cbc6968191f050fbb0b53113295194f Mon Sep 17 00:00:00 2001 From: Alex White Date: Sun, 30 Apr 2017 23:58:27 -0500 Subject: [PATCH 209/233] Add SSL Config (#115) --- deploy/nginx.conf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/deploy/nginx.conf b/deploy/nginx.conf index b86ba08..9b3aa43 100644 --- a/deploy/nginx.conf +++ b/deploy/nginx.conf @@ -49,15 +49,15 @@ http { server { listen 80; - #listen 443 ssl; + listen 443 ssl; # force https-redirects - #if ($scheme = http) { - # return 301 https://$server_name$request_uri; - #} + if ($scheme = http) { + return 301 https://$server_name$request_uri; + } - #ssl on; - #ssl_certificate /etc/ssl/your_domain_name.pem; (or bundle.crt) - #ssl_certificate_key /etc/ssl/your_domain_name.key; + ssl on; + ssl_certificate /var/local/nginx/ssl/certs/__yourstlcourts_com.crt + ssl_certificate_key /var/local/nginx/ssl/keys/server.key; server_name yourstlcourts.com; root /usr/share/nginx/html; From 10c967aec00f28e325d87cf9531dfc6aab52472f Mon Sep 17 00:00:00 2001 From: Alex White Date: Mon, 1 May 2017 00:43:07 -0500 Subject: [PATCH 210/233] Forgot comma! --- deploy/nginx.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/nginx.conf b/deploy/nginx.conf index 9b3aa43..b4ce63e 100644 --- a/deploy/nginx.conf +++ b/deploy/nginx.conf @@ -56,7 +56,7 @@ http { } ssl on; - ssl_certificate /var/local/nginx/ssl/certs/__yourstlcourts_com.crt + ssl_certificate /var/local/nginx/ssl/certs/__yourstlcourts_com.crt; ssl_certificate_key /var/local/nginx/ssl/keys/server.key; server_name yourstlcourts.com; From 2e76b920fa02cf58625470107a177c5438225946 Mon Sep 17 00:00:00 2001 From: Alex White Date: Mon, 1 May 2017 06:13:31 -0500 Subject: [PATCH 211/233] Revert ssl! --- deploy/nginx.conf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/deploy/nginx.conf b/deploy/nginx.conf index b4ce63e..da724dd 100644 --- a/deploy/nginx.conf +++ b/deploy/nginx.conf @@ -49,15 +49,15 @@ http { server { listen 80; - listen 443 ssl; + #listen 443 ssl; # force https-redirects - if ($scheme = http) { - return 301 https://$server_name$request_uri; - } + #if ($scheme = http) { + # return 301 https://$server_name$request_uri; + #} - ssl on; - ssl_certificate /var/local/nginx/ssl/certs/__yourstlcourts_com.crt; - ssl_certificate_key /var/local/nginx/ssl/keys/server.key; + #ssl on; + #ssl_certificate /var/local/nginx/ssl/certs/__yourstlcourts_com.crt; + #ssl_certificate_key /var/local/nginx/ssl/keys/server.key; server_name yourstlcourts.com; root /usr/share/nginx/html; From ee717f6a8008571b1712442cbbfddb495785340b Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 1 May 2017 06:15:01 -0500 Subject: [PATCH 212/233] Changed Name of St. Louis County (#114) --- app/scripts/controllers/locationPickerMap.ctrl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/controllers/locationPickerMap.ctrl.js b/app/scripts/controllers/locationPickerMap.ctrl.js index 4ca1035..5ce491e 100644 --- a/app/scripts/controllers/locationPickerMap.ctrl.js +++ b/app/scripts/controllers/locationPickerMap.ctrl.js @@ -97,7 +97,7 @@ angular.module('yourStlCourts').controller('LocationPickerMapCtrl', function ($s function getMunicipalityFromMapName(muniMapName){ function getName(nameString){ if (nameString.toLowerCase() == "unincorporated"){ - nameString += " St. Louis County"; + nameString = "St. Louis County - Unincorporated"; } return nameString.replace("&", "and"); From b1d0efcff28fe7ab9a5550f04e3ff756e7ec9c09 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 1 May 2017 23:14:00 -0500 Subject: [PATCH 213/233] Cleared selectedCitation on load of new citations (#117) --- app/scripts/services/Session.svc.js | 5 +++++ test/spec/service/Session.svc.spec.js | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/app/scripts/services/Session.svc.js b/app/scripts/services/Session.svc.js index d4767a9..ab5ac6f 100644 --- a/app/scripts/services/Session.svc.js +++ b/app/scripts/services/Session.svc.js @@ -9,6 +9,7 @@ angular.module('yourStlCourts').factory('Session', function () { function setLatestCitations(citations){ latestCitations = citations; + clearLastSelectedCitation(); } function getLastSelectedCitation(){ @@ -19,6 +20,10 @@ angular.module('yourStlCourts').factory('Session', function () { lastSelectedCitation = citation; } + function clearLastSelectedCitation(){ + lastSelectedCitation = null; + } + var svc = { getLatestCitations: getLatestCitations, setLatestCitations: setLatestCitations, diff --git a/test/spec/service/Session.svc.spec.js b/test/spec/service/Session.svc.spec.js index cb89dcb..15efed9 100644 --- a/test/spec/service/Session.svc.spec.js +++ b/test/spec/service/Session.svc.spec.js @@ -31,4 +31,11 @@ describe('Session', function() { expect(returnedCitation).toEqual(citations[1]); }); + it('correctly clears last selected citation', function(){ + Session.setSelectedCitation(citations[1]); + Session.setLatestCitations(citations); + var returnedCitation = Session.getLastSelectedCitation(); + expect(returnedCitation).toBe(null); + }); + }); From b805f2ef2abcf30734a5656194c33b02f3ff3a7f Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Wed, 3 May 2017 11:16:46 -0500 Subject: [PATCH 214/233] Adjusted header menu for more options, cleaned up footer. (#119) --- app/styles/header.scss | 6 +++--- app/styles/main.scss | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/styles/header.scss b/app/styles/header.scss index a7df867..df8a4c9 100644 --- a/app/styles/header.scss +++ b/app/styles/header.scss @@ -66,7 +66,7 @@ } @media screen and (min-width:901px){ .navbar-nav{ - font-size: .9em; + font-size: .8em; } .navbar-nav{ @@ -88,7 +88,7 @@ @media screen and (min-width:1025px){ .navbar-nav{ - font-size: 1.1em; + font-size: 1em; } } @@ -113,7 +113,7 @@ .navbar-nav{ float:none !important; display:inline-block; - font-size: .9em; + font-size: .7em; } .navbar{ margin-bottom:5px !important; diff --git a/app/styles/main.scss b/app/styles/main.scss index 89fa111..36028a1 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -52,6 +52,19 @@ footer { line-height: $footer-height; } +@media screen and (max-width:767px){ + footer { + text-align: center; + background-color: #333; + position: absolute; + left: 0; + bottom: 0; + height: auto; + width: 100%; + overflow:hidden; + } +} + p.address1{ padding-top:0px; padding-bottom:0px; From 555f56650508f799aedc402a5eab5420dc7715e9 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Wed, 3 May 2017 12:05:56 -0500 Subject: [PATCH 215/233] Formatting changes for comma list of supported municipalities (#118) * Formatting changes for comma list of supported municipalities * Reformated HTML to remove inline div --- app/views/citationsNotFound.html | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/views/citationsNotFound.html b/app/views/citationsNotFound.html index a74bf48..3db9045 100644 --- a/app/views/citationsNotFound.html +++ b/app/views/citationsNotFound.html @@ -21,18 +21,19 @@

    The court is not participating on this site

    This site is for St. Louis County tickets. Both the unincorporated areas and the municipalities that are part of the county.

    -
    -

    +

    + Currently the following municipalities are supported by this site: -

    -

    + +
    + , {{municipality.name}} -

    -
    + +

    If you believe you have a ticket from a non-supported municipality, you may look the associated court up on our site by clicking here.
    When you contact your court, please tell them that you'd like them to participate in YourStlCourts.

    -
    +

    From 64bef32a06021734149b98edd8948bbc7265713a Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Thu, 4 May 2017 14:49:01 -0500 Subject: [PATCH 216/233] change url to "tickets" from "citations" (#120) --- app/scripts/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/app.js b/app/scripts/app.js index 4cdc110..326bc35 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -146,7 +146,7 @@ angular.module('yourStlCourts').config(function ($stateProvider, $urlRouterProvi } }) .state('noCitationsFound',{ - url: '/citations/error/notFound', + url: '/tickets/error/notFound', templateUrl: 'views/citationsNotFound.html', controller: 'NoCitationsFoundCtrl as ctrl', resolve: { From a6de032acb42a6ab55f4e374a9bdcbcd420de3f7 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Thu, 4 May 2017 14:49:25 -0500 Subject: [PATCH 217/233] vertically centered loading indicator (#121) --- app/styles/loading.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/styles/loading.scss b/app/styles/loading.scss index 7d62c32..a2abe8b 100644 --- a/app/styles/loading.scss +++ b/app/styles/loading.scss @@ -21,7 +21,7 @@ .loadingContent { width: 100px; height: 100px; - position: absolute; + position: fixed; left: 50%; top: 50%; margin: -50px 0 0 -50px; From 39d8ad8290d31b890199a4c39eff09672ebca5a7 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 15 May 2017 11:05:14 -0500 Subject: [PATCH 218/233] Display drivers license state on citationInfo page (#124) --- app/views/citationInfo.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/citationInfo.html b/app/views/citationInfo.html index 9f29989..1658432 100644 --- a/app/views/citationInfo.html +++ b/app/views/citationInfo.html @@ -47,7 +47,7 @@

    {{ctrl.selectedCitation.defendant_address}}

    {{ctrl.selectedCitation.defendant_city}}, {{ctrl.selectedCitation.defendant_state}}

    -

    Driver's License #: {{ctrl.selectedCitation.drivers_license_number}}

    +

    Driver's License #: {{ctrl.selectedCitation.drivers_license_number}} - {{ctrl.selectedCitation.drivers_license_state}}


    From 4c6cb07a446b0526917f8e1a4ef8f19ed2906bcc Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 15 May 2017 11:05:53 -0500 Subject: [PATCH 219/233] Removed court fee code and note (#125) --- app/views/citationInfo.html | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/app/views/citationInfo.html b/app/views/citationInfo.html index 1658432..d113be1 100644 --- a/app/views/citationInfo.html +++ b/app/views/citationInfo.html @@ -65,24 +65,10 @@

    Ticket Info

    Fine Info Unavailable - - Note: this is the amount of your fine only. Your total will also include court fees. - Note: you must appear in court and speak with the judge to pay this citation. -
    From 3bb3c2f05dfb93e8eae259310cbee71ddc36d1e3 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 15 May 2017 11:07:19 -0500 Subject: [PATCH 220/233] Renamed County to: St. Louis County Municipal Courts - Unincorporated (#127) * Renamed County to: St. Louis County Municipal Courts - Unincorporated * Updated to St. Louis County Municipal --- app/scripts/controllers/locationPickerMap.ctrl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/controllers/locationPickerMap.ctrl.js b/app/scripts/controllers/locationPickerMap.ctrl.js index 5ce491e..d2932a9 100644 --- a/app/scripts/controllers/locationPickerMap.ctrl.js +++ b/app/scripts/controllers/locationPickerMap.ctrl.js @@ -97,7 +97,7 @@ angular.module('yourStlCourts').controller('LocationPickerMapCtrl', function ($s function getMunicipalityFromMapName(muniMapName){ function getName(nameString){ if (nameString.toLowerCase() == "unincorporated"){ - nameString = "St. Louis County - Unincorporated"; + nameString = "St. Louis County Municipal"; } return nameString.replace("&", "and"); From fee1c14d38bd353c700dd59d98892a038a14d5c3 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 15 May 2017 11:07:57 -0500 Subject: [PATCH 221/233] Renamed ticketFinder close button so map city selector close didn't overlap with city. (#128) --- app/styles/main.scss | 4 ++-- app/views/ticketFinderBox.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/styles/main.scss b/app/styles/main.scss index 36028a1..820cb17 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -232,14 +232,14 @@ $homepageTileHeight : 75px; color:inherit; } -.close{ +.homepageTileClose.close{ position:absolute; top:5px; right:5px; color:$white !important; opacity: 1.0; } -.close:hover{ +.homepageTileClose.close:hover{ color:$white !important; } diff --git a/app/views/ticketFinderBox.html b/app/views/ticketFinderBox.html index 4baad30..8f3fb38 100644 --- a/app/views/ticketFinderBox.html +++ b/app/views/ticketFinderBox.html @@ -9,7 +9,7 @@

    {{ctrl.text}}

    - +
    From d01293cb5406e0fccd3507592cbf8269a8427d7c Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 22 May 2017 23:17:51 -0500 Subject: [PATCH 222/233] Auto focus on certain fields (#123) * Implemented focusing for ticket finder boxes and dob month field * Added auto focusing to ticket finder boxes, date picker and after typing in last part of date on dob datepicker, the find Ticket button will auto focus as well as when the datepicker picker is used to fill in the date * Updated unit test --- .bowerrc | 3 ++- app/index.html | 3 ++- app/scripts/controllers/ticketFinder.ctrl.js | 1 + app/scripts/directives/stlCourtsDatepicker.dir.js | 15 +++++++++++++-- app/scripts/directives/stlCourtsFocus.dir.js | 14 ++++++++++++++ app/views/citations.html | 4 ++-- app/views/dobPicker.html | 4 ++-- app/views/stlCourtsDatepicker.html | 2 +- app/views/ticketFinderContentDriver.html | 2 +- app/views/ticketFinderContentLocation.html | 2 +- app/views/ticketFinderContentTicket.html | 2 +- bower.json | 4 ++-- karma.conf.js | 2 +- test/spec/controllers/ticketFinder.ctrl.spec.js | 1 + 14 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 app/scripts/directives/stlCourtsFocus.dir.js diff --git a/.bowerrc b/.bowerrc index 69fad35..0e769bd 100644 --- a/.bowerrc +++ b/.bowerrc @@ -1,3 +1,4 @@ { - "directory": "bower_components" + "directory": "bower_components", + "strict-ssl": false } diff --git a/app/index.html b/app/index.html index fcbcc08..552e447 100644 --- a/app/index.html +++ b/app/index.html @@ -91,7 +91,6 @@ - @@ -99,6 +98,7 @@ + @@ -155,6 +155,7 @@ + diff --git a/app/scripts/controllers/ticketFinder.ctrl.js b/app/scripts/controllers/ticketFinder.ctrl.js index 9d0601d..a43e116 100644 --- a/app/scripts/controllers/ticketFinder.ctrl.js +++ b/app/scripts/controllers/ticketFinder.ctrl.js @@ -44,6 +44,7 @@ angular.module('yourStlCourts').controller('TicketFinderCtrl', function (TicketF ctrl.getDOB = function(){ if(ctrl.ticketForm.$valid) { var modalInstance = $uibModal.open({ + animation:false, //allows focus cursor to stay in input box on edge & IE browsers templateUrl: 'views/dobPicker.html', controller: 'dobPickerCtrl as ctrl', size: 'sm' diff --git a/app/scripts/directives/stlCourtsDatepicker.dir.js b/app/scripts/directives/stlCourtsDatepicker.dir.js index 621a125..fa17efb 100644 --- a/app/scripts/directives/stlCourtsDatepicker.dir.js +++ b/app/scripts/directives/stlCourtsDatepicker.dir.js @@ -12,11 +12,13 @@ angular.module('yourStlCourts').directive('stlCourtsDatepicker', function($timeo dateObject:'=?', //returns javascript Date dateField:'=?', //returns date String formatted to "MM/dd/yyyy" dateValid:'=?', - dateOver18:'=?' + dateOver18:'=?', + okButtonId:'@' }, templateUrl: 'views/stlCourtsDatepicker.html', controller: 'StlCourtsDatepicker as ctrl', link: function($scope,element,attrs){ + var scope = $scope; var keys = { backspace:8, delete:46, @@ -56,9 +58,14 @@ angular.module('yourStlCourts').directive('stlCourtsDatepicker', function($timeo updateDateString(); if (numberOfExistingDigits === Number(maxLength)){ //tab to the next field - if ($(event.target).next("span") !== $()){ + if ($(event.target).next("span").length !== 0){ clearInputElement($(event.target).next().next()); $(event.target).next().next().focus(); + }else{ + if (scope.okButtonId) { + //last date field is filled in go to OK button + $("#" + scope.okButtonId).focus(); + } } } }else{ @@ -152,6 +159,10 @@ angular.module('yourStlCourts').directive('stlCourtsDatepicker', function($timeo uibDatePickerDateJustChangedDateString = true; $scope.ctrl.dateString = formatDateObjToDateFormat(); loadDateStringToElement(); + if (scope.okButtonId) { + //user just selected a date from the datePicker and it filled in the whole date + $("#" + scope.okButtonId).focus(); + } }else{ initialDTSet = false; } diff --git a/app/scripts/directives/stlCourtsFocus.dir.js b/app/scripts/directives/stlCourtsFocus.dir.js new file mode 100644 index 0000000..69d7e46 --- /dev/null +++ b/app/scripts/directives/stlCourtsFocus.dir.js @@ -0,0 +1,14 @@ +'use strict'; + +angular.module('yourStlCourts').directive('stlCourtsFocus', function ($timeout) { + return { + restrict: 'A', + + link: function ($scope, element, attr) { + var scope = $scope; + $timeout(function(){ + $(element).get(0).focus(); + }); + } + }; +}); diff --git a/app/views/citations.html b/app/views/citations.html index 04324ab..f8ace6b 100644 --- a/app/views/citations.html +++ b/app/views/citations.html @@ -7,9 +7,9 @@

    As a security precaution, please enter your date of birt
    - +
    - +
    diff --git a/app/views/dobPicker.html b/app/views/dobPicker.html index cfb1156..7d68f0f 100644 --- a/app/views/dobPicker.html +++ b/app/views/dobPicker.html @@ -6,11 +6,11 @@ diff --git a/app/views/stlCourtsDatepicker.html b/app/views/stlCourtsDatepicker.html index 046af1f..9d4a42d 100644 --- a/app/views/stlCourtsDatepicker.html +++ b/app/views/stlCourtsDatepicker.html @@ -1,6 +1,6 @@
    - + / / diff --git a/app/views/ticketFinderContentDriver.html b/app/views/ticketFinderContentDriver.html index e36524d..c654c47 100644 --- a/app/views/ticketFinderContentDriver.html +++ b/app/views/ticketFinderContentDriver.html @@ -1,5 +1,5 @@ - + diff --git a/app/views/ticketFinderContentLocation.html b/app/views/ticketFinderContentLocation.html index dcc0df4..7bfb5fc 100644 --- a/app/views/ticketFinderContentLocation.html +++ b/app/views/ticketFinderContentLocation.html @@ -1,5 +1,5 @@ - + diff --git a/app/views/ticketFinderContentTicket.html b/app/views/ticketFinderContentTicket.html index 7d00a46..a3f80e8 100644 --- a/app/views/ticketFinderContentTicket.html +++ b/app/views/ticketFinderContentTicket.html @@ -1,3 +1,3 @@ - + diff --git a/bower.json b/bower.json index 2961230..5d3d09c 100644 --- a/bower.json +++ b/bower.json @@ -10,7 +10,6 @@ "angular-touch": "1.3.0", "angular-ui-router": "0.2.15", "angularjs-toaster": "0.4.15", - "angular-bootstrap": "1.3.2", "angular-ui-select": "0.19.4", "jquery": "2.2.4", "moment": "2.14.1", @@ -18,7 +17,8 @@ "angular-simple-logger": "0.1.7", "angular-moment": "1.0.1", "lodash": "4.17.4", - "Autolinker.js": "1.4.2" + "Autolinker.js": "1.4.2", + "angular-bootstrap": "2.5.0" }, "devDependencies": { "angular-mocks": "1.5.0" diff --git a/karma.conf.js b/karma.conf.js index 16d14e4..9ebf897 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -40,7 +40,6 @@ module.exports = function(config) { 'bower_components/angular-touch/angular-touch.js', 'bower_components/angular-ui-router/release/angular-ui-router.js', 'bower_components/angularjs-toaster/toaster.js', - 'bower_components/angular-bootstrap/ui-bootstrap-tpls.js', 'bower_components/angular-ui-select/dist/select.js', 'bower_components/moment/moment.js', 'bower_components/leaflet/dist/leaflet-src.js', @@ -48,6 +47,7 @@ module.exports = function(config) { 'bower_components/angular-moment/angular-moment.js', 'bower_components/lodash/lodash.js', 'bower_components/Autolinker.js/dist/Autolinker.js', + 'bower_components/angular-bootstrap/ui-bootstrap-tpls.js', 'bower_components/angular-mocks/angular-mocks.js', // endbower 'app/vendor/ui-leaflet.js', diff --git a/test/spec/controllers/ticketFinder.ctrl.spec.js b/test/spec/controllers/ticketFinder.ctrl.spec.js index cd0dd1a..9cd3904 100644 --- a/test/spec/controllers/ticketFinder.ctrl.spec.js +++ b/test/spec/controllers/ticketFinder.ctrl.spec.js @@ -105,6 +105,7 @@ describe('TicketFinderCtrl', function() { $rootScope.$apply(); var expectedModalOptions = { + animation:false, templateUrl: 'views/dobPicker.html', controller: 'dobPickerCtrl as ctrl', size: 'sm' From 96eb17598c545f0858c33b76520cfb404a982424 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 4 Jun 2017 06:30:05 -0500 Subject: [PATCH 223/233] removed space before comma (#132) --- app/views/citationsNotFound.html | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/views/citationsNotFound.html b/app/views/citationsNotFound.html index 3db9045..9f6da29 100644 --- a/app/views/citationsNotFound.html +++ b/app/views/citationsNotFound.html @@ -26,14 +26,11 @@

    The court is not participating on this site

    Currently the following municipalities are supported by this site:
    - - , - {{municipality.name}} - + , {{municipality.name}}

    If you believe you have a ticket from a non-supported municipality, you may look the associated court up on our site by clicking here.
    When you contact your court, please tell them that you'd like them to participate in YourStlCourts.

    -

    +
    From 515a1ad0a5954452ec118b132bd1df51e183f12c Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 4 Jun 2017 06:30:26 -0500 Subject: [PATCH 224/233] fixed typo (#131) --- app/data/questionAnswers.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/data/questionAnswers.json b/app/data/questionAnswers.json index 0ae46aa..70ac652 100644 --- a/app/data/questionAnswers.json +++ b/app/data/questionAnswers.json @@ -1,7 +1,7 @@ { "ticket-faq":[ {"q":"I know I got a ticket but I can't find it in YourSTLCourts.", - "a":"Currently the municipalities listed below have opted to participate in YourSTLCourts. If you can't locate your ticket information, it may be that the court where you received your ticket is not participating in YourSTLCourts. We encourage you to call City Hall and/or court to ask that they participate in YourSTLCours. You can find contact information for any court in St. Louis County by clicking here.", + "a":"Currently the municipalities listed below have opted to participate in YourSTLCourts. If you can't locate your ticket information, it may be that the court where you received your ticket is not participating in YourSTLCourts. We encourage you to call City Hall and/or court to ask that they participate in YourSTLCourts. You can find contact information for any court in St. Louis County by clicking here.", "keywords":[], "fill-in":"supportedMunicipalities"}, {"q":"I know I need to appear in court soon. I lost my ticket but remember where I was pulled over. How can I find my court date and location?", From 3114174727d4805ca0cc0648e3080ff24de81d9b Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 4 Jun 2017 06:31:16 -0500 Subject: [PATCH 225/233] Updated language on page (#130) --- app/views/goingToCourt.html | 142 +----------------------------------- 1 file changed, 4 insertions(+), 138 deletions(-) diff --git a/app/views/goingToCourt.html b/app/views/goingToCourt.html index d4ec445..c70b081 100644 --- a/app/views/goingToCourt.html +++ b/app/views/goingToCourt.html @@ -15,155 +15,21 @@

    Going To Court

    Dress Code

    - Appropriate clothing should be work when going to court. While many courts will not require a strict dress code, it is better to avoid any potential dress code violations when possible. -

    -

    - Clothing which should be avoided, when possible, includes halter tops, t-shirts, shorts, baggy pants, or other clothes which could be deemed professionally inappropriate clothing. + Appropriate clothing should be worn when going to court, though some courts do not require a strict dress code.

    Do's & Don'ts

    -

    Addressing The Court

    -

    - When addressing the court or anyone working in the court system, please be respectful, clear and concise in your speech and avoid the use of anything that could make you more difficult to understand. This could include chewing gum, chewing tobacco or visual mouth enhancements that could be removed (such as a grill / fronts / golds). -

    Electronic Devices

    - Cell phones, tablets, pagers, hand-held gaming devices and other electronic devices brought into court with you should be turned to silent or powered off completely while you are inside the courtroom. -

    -

    Smoking and Nicotine Consumption

    -

    - Smoking and the use of electronic nicotine vaporizers should not be consumed in the court building or within a short distance of the doors. While many courts will have areas marked off, it is best to err on the side of caution and be away from the doors or back to your car if you wish to smoke or vape. -

    -
    -
    - -

    Court Fees & Fines

    -

    - In addition to the fine associated with your violation, cases may incur additional court fees. These fees pay for basic court costs as well as other programs and surcharges, such as: Crime Victim Compensation, Law Enforcement Training, Peace Officer Training, Biometric Verification System, Domestic Violence Shelter and others. + Cell phones, tablets, pagers, hand-held gaming devices and other electronic devices brought into court with you should be turned to silent while you are inside the courtroom.

    -

    Offenses which may carry a separate and compounding fine

    +

    Smoking and Vaporizers

    - The offenses below are examples of citations which may carry a separate and compounding fine. Ultimately, a judge will determine the cost of each fine on an individual basis even though some courts may have standard fines and fees for various offenses. If you have: + Smoking and the use of electronic nicotine vaporizers is prohibited inside court.

    -
      -
      -
    • - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Offense
      Corner Cutting to Avoid Signal
      Driving On Closed Road
      Driving Over Curb
      Driving Wrong Side of Road
      Driving Wrong Way (One Way Street)
      Blocking Driveway or Alley
      Expired License Plates (Tags)
      Failure to Secure a Load
      Fake Temporary Tags
      Fictitious License Tabs
      Improper Exhaust or Muffler
      Improper Registration (Failure to Register)
      License Plate not Illuminated
      No Brake Lights
      No Headlight
      No Inspection Sticker
      No License Plates
      No Motorcycle Helmet
      No Taillights
      Child Restraint Seat Violation*
      Failure to Keep to the Right
      Failure to Obey Electric Signal
      Failure to Obey Stop Sign
      Failure to Sound Horn
      Failure to Yield
      Failure to Yield to Emergency Vehicles
      Following too Closely
      Impeding/Obstructing Traffic Movement
      Improper Backing
      Improper Lane Usage
      Improper Passing
      Improper/Prohibited Turn
      No Through Traffic
      Prohibited U-Turn
      Traffic Turn Signal Violation
      -

      *typically waived if child restraint is purchased before court date

      -
    • -

    From 0128f1ce67ef0ea7363d649f1bc2e698d06766df Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 4 Jun 2017 22:36:58 -0500 Subject: [PATCH 226/233] url address updated (#133) * url address updated * Changed SMS citation link * Changed SMS ticket link URL --- app/scripts/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/app.js b/app/scripts/app.js index 326bc35..27d2652 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -136,7 +136,7 @@ angular.module('yourStlCourts').config(function ($stateProvider, $urlRouterProvi } }) .state('citations', { - url: '/citations/{citationId}', + url: '/tickets/{citationId}/info', templateUrl: 'views/citations.html', controller: 'CitationsCtrl as ctrl', resolve: { From ebfe048ac274fe11422e0ef23c06f95bb1c0585b Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Sun, 4 Jun 2017 23:55:04 -0500 Subject: [PATCH 227/233] =?UTF-8?q?Renamed=20courts=20to=20divisions=20whe?= =?UTF-8?q?n=20more=20than=20one=20court=20is=20assigned=20to=20a=E2=80=A6?= =?UTF-8?q?=20(#126)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Renamed courts to divisions when more than one court is assigned to a municipality * Added database control to determine if court or division * Removed court_type field * Removed redundant "Court" tags on name --- app/views/citationInfo.html | 2 +- app/views/courtSearchInfo.html | 2 +- app/views/home.html | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/citationInfo.html b/app/views/citationInfo.html index d113be1..9aa90bf 100644 --- a/app/views/citationInfo.html +++ b/app/views/citationInfo.html @@ -103,7 +103,7 @@

    Court Information

    Court Time
    {{ctrl.formatTime(ctrl.selectedCitation.court_dateTime)}}
    Court Name
    -
    {{ctrl.selectedCitation.court.name}} Court
    +
    {{ctrl.selectedCitation.court.name}}
    Court Phone Number
    {{ctrl.selectedCitation.court.phone}} x{{ctrl.selectedCitation.court.extension}}
    Court Location
    diff --git a/app/views/courtSearchInfo.html b/app/views/courtSearchInfo.html index 9b55150..fe5cb2e 100644 --- a/app/views/courtSearchInfo.html +++ b/app/views/courtSearchInfo.html @@ -1,5 +1,5 @@
    -

    {{ctrl.courtName}} Court Information

    +

    {{ctrl.courtName}} Information

    diff --git a/app/views/home.html b/app/views/home.html index de2afef..8ebc41d 100644 --- a/app/views/home.html +++ b/app/views/home.html @@ -6,11 +6,11 @@

    Your Ticket. Your Rights. Right at your Fingertips.

    -  Court +   - ( Court) + ()
    From 3b2c807dc232bfb5c443dd3a56ddf112330ce76a Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Mon, 5 Jun 2017 12:40:03 -0500 Subject: [PATCH 228/233] Handle more than one person per citation (#129) * Added warning note that multiple people may be listed for citation results. Added unit tests. * Updated unit tests * Unit tests updated, warning text updated, citations grouped by name. * Changed array initialization technique and for loop structure. * kept header of person name for 1 person shown in ticket results * unchanged header for person name. * Added header for ticket results for one person * Simplified number of objects and arrays by removing redundant array --- app/scripts/controllers/citationInfo.ctrl.js | 28 +++++++++ app/views/citationInfo.html | 62 ++++++++++--------- .../controllers/citationInfo.ctrl.spec.js | 60 ++++++++++++++++++ 3 files changed, 122 insertions(+), 28 deletions(-) diff --git a/app/scripts/controllers/citationInfo.ctrl.js b/app/scripts/controllers/citationInfo.ctrl.js index 735ce08..55b1566 100644 --- a/app/scripts/controllers/citationInfo.ctrl.js +++ b/app/scripts/controllers/citationInfo.ctrl.js @@ -2,11 +2,38 @@ angular.module('yourStlCourts').controller('CitationInfoCtrl', function (faqData,$state, $window, citations,municipalities,courts,Courts,Session,moment,$anchorScroll) { var ctrl = this; + var PLACEHOLDER_DL_NUM = "NO_DL_NUM"; + ctrl.faqData = faqData; ctrl.selectedCitation = null; ctrl.paymentUrl = ""; ctrl.citationCourtLocations = {}; + ctrl.groupCitationsByDL = function(){ + var dlNum = ""; + var dlState = ""; + var groupedCitations = {}; + + citations.forEach(function(citation){ + dlNum = citation.drivers_license_number; + dlState = citation.drivers_license_state; + if (dlNum === ""){ + //in the event the defendant does not have a DL Num assign one so the object has a key + dlNum = PLACEHOLDER_DL_NUM; + } + if (!groupedCitations[dlNum+dlState]){ + groupedCitations[dlNum+dlState] = []; + } + groupedCitations[dlNum+dlState].push(citation); + }); + + return groupedCitations; + }; + + ctrl.issueMultiplePeopleWarning = function(){ + return (ctrl.groupedCitations.length > 1); + }; + ctrl.selectCitation = function(citation,idToScrollTo){ ctrl.selectedCitation = citation; Session.setSelectedCitation(ctrl.selectedCitation); @@ -44,6 +71,7 @@ angular.module('yourStlCourts').controller('CitationInfoCtrl', function (faqData $state.go('home'); } else { ctrl.citations = citations; + ctrl.groupedCitations = ctrl.groupCitationsByDL(); for(var citationCount = 0; citationCount < citations.length; citationCount++){ var courtId = citations[citationCount].court_id; var foundCourt = _.find(courts, {id: courtId}); diff --git a/app/views/citationInfo.html b/app/views/citationInfo.html index 9aa90bf..0d6497a 100644 --- a/app/views/citationInfo.html +++ b/app/views/citationInfo.html @@ -3,36 +3,42 @@

    Ticket Results

    +
    Ticket results may be shown for multiple people.
    - - - - - - - - - - - - - - - - - - - -
    Ticket #NameCourt DateCourt LocationViolations
    Ticket #{{citation.citation_number}}
    Name{{citation.first_name}} {{citation.last_name}}Court Date{{ctrl.formatDate(citation.court_dateTime)}}Court Location{{ctrl.citationCourtLocations[citation.court_id]}} - Violations - - {{violation.violation_description}}, - - - Violation data unavailable. Please contact your court. - -
    +
    +

    + {{citationGrouping[0].first_name + " " + citationGrouping[0].last_name}} +

    + + + + + + + + + + + + + + + + + + + +
    Ticket #NameCourt DateCourt LocationViolations
    Ticket #{{citation.citation_number}}
    Name{{citation.first_name}} {{citation.last_name}}Court Date{{ctrl.formatDate(citation.court_dateTime)}}Court Location{{ctrl.citationCourtLocations[citation.court_id]}} + Violations + + {{violation.violation_description}}, + + + Violation data unavailable. Please contact your court. + +
    +
    diff --git a/test/spec/controllers/citationInfo.ctrl.spec.js b/test/spec/controllers/citationInfo.ctrl.spec.js index 3ac53a1..d6a71c0 100644 --- a/test/spec/controllers/citationInfo.ctrl.spec.js +++ b/test/spec/controllers/citationInfo.ctrl.spec.js @@ -66,6 +66,36 @@ describe('CitationInfoCtrl', function () { municipality_id:5 }; + var citationDuplicate1 = { + id:20, + court_id:11, + violations: [violationPayableOnline], + municipality_id:5, + drivers_license_number: "1234", + drivers_license_state: "MO" + }; + + var citationDuplicate2 = { + id:21, + court_id:11, + violations: [violationPayableOnline], + municipality_id:5, + drivers_license_number: "1235", + drivers_license_state: "MO" + }; + + var citationDuplicate3 = { + id:21, + court_id:11, + violations: [violationPayableOnline], + municipality_id:5, + drivers_license_number: "1234", + drivers_license_state: "MO" + }; + + var citationsDuplicate = [citationDuplicate1,citationDuplicate2]; + var citationsNonDuplicate = [citationDuplicate1,citationDuplicate3]; + var citations = [ citation, citationWithViolations ]; @@ -290,4 +320,34 @@ describe('CitationInfoCtrl', function () { expect(CitationInfoCtrl.citationCourtLocations[5]).toEqual("courtName5"); expect(CitationInfoCtrl.citationCourtLocations[11]).toEqual("courtName11"); }); + + it('catches citations with different people', inject(function ($controller, $state, $window, Courts) { + var CitationInfoCtrl = $controller('CitationInfoCtrl', { + faqData: faqData, + municipalities: municipalities, + $state: $state, + $window: $window, + citations: citationsDuplicate, + Courts: Courts, + courts: courts + }); + + expect(CitationInfoCtrl.groupedCitations.length).toBe(2); + expect(CitationInfoCtrl.issueMultiplePeopleWarning()).toBe(true); + })); + + it('catches citations with different people and does not return false positive', inject(function ($controller, $state, $window, Courts) { + var CitationInfoCtrl = $controller('CitationInfoCtrl', { + faqData: faqData, + municipalities: municipalities, + $state: $state, + $window: $window, + citations: citationsNonDuplicate, + Courts: Courts, + courts: courts + }); + + expect(CitationInfoCtrl.groupedCitations.length).toBe(1); + expect(CitationInfoCtrl.issueMultiplePeopleWarning()).toBe(false); + })); }); From 47d37f672832acdfa6153dba9bb56c8501927c17 Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Thu, 8 Jun 2017 21:31:38 -0500 Subject: [PATCH 229/233] Edited going to court section on fees and fines (#134) --- app/views/goingToCourt.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/views/goingToCourt.html b/app/views/goingToCourt.html index c70b081..9ac70d7 100644 --- a/app/views/goingToCourt.html +++ b/app/views/goingToCourt.html @@ -31,5 +31,12 @@

    Smoking and Vaporizers

    Smoking and the use of electronic nicotine vaporizers is prohibited inside court.

    +
    + +

    Court Fees & Fines

    +

    + In addition to the fine associated with your violation, cases may incur additional court fees. These vary by court based on the municipality's legal ordinances. +

    +
    From 6fd7a736a105dc8bcd47abcf637d610c44a9d3bd Mon Sep 17 00:00:00 2001 From: ctwoolsey Date: Thu, 8 Jun 2017 21:46:45 -0500 Subject: [PATCH 230/233] =?UTF-8?q?Fixed=20code=20bug=20and=20junit=20test?= =?UTF-8?q?=20to=20get=20number=20of=20citations=20in=20object=20in?= =?UTF-8?q?=E2=80=A6=20(#135)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixed code bug and junit test to get number of citations in object instead of array * used loadash ._size to get number of groupedCitations * Updated groupedCitation count code again. --- app/scripts/controllers/citationInfo.ctrl.js | 4 +++- test/spec/controllers/citationInfo.ctrl.spec.js | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/scripts/controllers/citationInfo.ctrl.js b/app/scripts/controllers/citationInfo.ctrl.js index 55b1566..68d03ba 100644 --- a/app/scripts/controllers/citationInfo.ctrl.js +++ b/app/scripts/controllers/citationInfo.ctrl.js @@ -8,6 +8,7 @@ angular.module('yourStlCourts').controller('CitationInfoCtrl', function (faqData ctrl.selectedCitation = null; ctrl.paymentUrl = ""; ctrl.citationCourtLocations = {}; + ctrl.groupedCitations = {}; ctrl.groupCitationsByDL = function(){ var dlNum = ""; @@ -31,7 +32,8 @@ angular.module('yourStlCourts').controller('CitationInfoCtrl', function (faqData }; ctrl.issueMultiplePeopleWarning = function(){ - return (ctrl.groupedCitations.length > 1); + + return (_.size(ctrl.groupedCitations) > 1); }; ctrl.selectCitation = function(citation,idToScrollTo){ diff --git a/test/spec/controllers/citationInfo.ctrl.spec.js b/test/spec/controllers/citationInfo.ctrl.spec.js index d6a71c0..a629099 100644 --- a/test/spec/controllers/citationInfo.ctrl.spec.js +++ b/test/spec/controllers/citationInfo.ctrl.spec.js @@ -332,7 +332,7 @@ describe('CitationInfoCtrl', function () { courts: courts }); - expect(CitationInfoCtrl.groupedCitations.length).toBe(2); + expect(_.size(CitationInfoCtrl.groupedCitations)).toBe(2); expect(CitationInfoCtrl.issueMultiplePeopleWarning()).toBe(true); })); @@ -347,7 +347,7 @@ describe('CitationInfoCtrl', function () { courts: courts }); - expect(CitationInfoCtrl.groupedCitations.length).toBe(1); + expect(_.size(CitationInfoCtrl.groupedCitations)).toBe(1); expect(CitationInfoCtrl.issueMultiplePeopleWarning()).toBe(false); })); }); From 7841bb9a21dc6ae0de1aa1e74c415663fad40fdf Mon Sep 17 00:00:00 2001 From: Alex White Date: Thu, 8 Jun 2017 22:26:34 -0500 Subject: [PATCH 231/233] Add support for prerender to support search engine crawling (#136) --- deploy/nginx.conf | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/deploy/nginx.conf b/deploy/nginx.conf index da724dd..8e93647 100644 --- a/deploy/nginx.conf +++ b/deploy/nginx.conf @@ -69,14 +69,42 @@ http { } location / { - # Make sure to pass any headers through the proxy here and not inside the if statements ! - proxy_set_header Host $host; - proxy_set_header Accept-Encoding ""; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - try_files $uri /index.html; - } + # Make sure to pass any headers through the proxy here and not inside the if statements ! + proxy_set_header Host $host; + proxy_set_header Accept-Encoding ""; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Defining a variable that will be used to process normal or crawler requests separately + set $prerender 0; + + if ($http_user_agent ~* "googlebot|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") { + set $prerender 1; + } + + if ($args ~ "_escaped_fragment_") { + set $prerender 1; + } + + if ($http_user_agent ~ "Prerender") { + set $prerender 0; + } + + # Allow normal processing without prerender or rewrite + if ($uri ~ "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff)") { + set $prerender 2; + } + + if ($prerender = 1) { + # when a crawler asks for a page proxy the request to the prerender host + rewrite .* /$scheme://$host$request_uri? break; + proxy_pass http://prerender-server; + } + + if ($prerender = 0) { + rewrite .* /index.html break; + } + } } } From 812a4e145fd37d333ee657c8e20b19a2c07978a5 Mon Sep 17 00:00:00 2001 From: Alex White Date: Thu, 8 Jun 2017 23:05:02 -0500 Subject: [PATCH 232/233] Prerender (#137) * Add support for prerender to support search engine crawling * Add upstream prerender server in nginx --- deploy/nginx.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deploy/nginx.conf b/deploy/nginx.conf index 8e93647..a1ff0c2 100644 --- a/deploy/nginx.conf +++ b/deploy/nginx.conf @@ -43,6 +43,10 @@ http { gzip on; # tells the server to use on-the-fly gzip compression. + upstream prerender-server { + server prerender:3000 max_fails=2 fail_timeout=15s; + } + upstream API { server stlcourts-api:8080; } From 241a353378fd145db017fa96a51158214ae4ff72 Mon Sep 17 00:00:00 2001 From: Alex White Date: Mon, 12 Jun 2017 22:57:06 -0500 Subject: [PATCH 233/233] Make prerender use prerender.io --- app/index.html | 2 ++ deploy/nginx.conf | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/index.html b/app/index.html index 552e447..6ab4be8 100644 --- a/app/index.html +++ b/app/index.html @@ -5,6 +5,8 @@ Your STL Courts + + diff --git a/deploy/nginx.conf b/deploy/nginx.conf index a1ff0c2..5f00d5a 100644 --- a/deploy/nginx.conf +++ b/deploy/nginx.conf @@ -44,7 +44,7 @@ http { # tells the server to use on-the-fly gzip compression. upstream prerender-server { - server prerender:3000 max_fails=2 fail_timeout=15s; + server service.prerender.io max_fails=2 fail_timeout=15s; } upstream API { @@ -79,6 +79,7 @@ http { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Prerender-Token Uc0oODEz55JlZcywLMX3; # Defining a variable that will be used to process normal or crawler requests separately set $prerender 0;