From 3b0632a1513bd6edcb745a2689b3dea73ed97870 Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Fri, 25 Oct 2013 20:36:06 -0500 Subject: [PATCH] Finished initial version of the client-side UI. Also moved to an automated build using make. --- .gitignore | 3 + Makefile | 14 + index.html | 177 ------------ .../www/css/nursery-schedule.scss | 39 ++- src/www/css/schedule-maker.scss | 108 ++++++++ src/www/index.html | 197 ++++++++++++++ src/www/js/schedule-maker.js | 254 ++++++++++++++++++ src/www/schedule-maker.html | 182 +++++++++++++ 8 files changed, 787 insertions(+), 187 deletions(-) create mode 100644 .gitignore create mode 100644 Makefile delete mode 100644 index.html rename nursery-schedule.scss => src/www/css/nursery-schedule.scss (57%) create mode 100644 src/www/css/schedule-maker.scss create mode 100644 src/www/index.html create mode 100644 src/www/js/schedule-maker.js create mode 100644 src/www/schedule-maker.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..196b097 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.sw? +.sass-cache +build/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..88f0ff7 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +build : + mkdir -p build/css + cp src/www/*.* build + cp -r src/www/js build +# cp -r resources/* build/. + sass src/www/css/nursery-schedule.scss build/css/nursery-schedule.css + sass src/www/css/schedule-maker.scss build/css/schedule-maker.css + +clean : + -rm -r build + +local-deploy: build + cp -r build ~/temp/server + ssh jdb-server 'rm -r ~/public_html/nursery-schedule; mv temp/build ~/public_html/nursery-schedule' diff --git a/index.html b/index.html deleted file mode 100644 index 346e7ae..0000000 --- a/index.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - -
-
-

First Sunday, Oct. 6th

-
-
    -
  • Toddlers
  • -
  • Sara Bernard
  • -
  • Priscilla Reid
  • -
  • Becca Torres
  • -
-
    -
  • Infants
  • -
  • Latonya Kirton
  • -
  • Susan Vacca
  • -
  • Brandie Kristoff
  • -
-
-
-
    -
  • Evening Service
  • -
  • Susan Miller
  • -
  • TBD
  • -
-
-
- -
-

Second Sunday, Oct. 13th

-
-
    -
  • Toddlers
  • -
  • Sara Bernard
  • -
  • Priscilla Reid
  • -
  • Rebecca Dombroski
  • -
-
    -
  • Infants
  • -
  • Latonya Kirton
  • -
  • Susan Vacca
  • -
  • Mila Hill
  • -
-
-
-
    -
  • Evening Service
  • -
  • Zoe Torres
  • -
  • Hannah Torres
  • -
-
-
- -
-

Third Sunday, Oct. 20th

-
-
    -
  • Toddlers
  • -
  • Sara Bernard
  • -
  • Priscilla Reid
  • -
  • Della Borrego
  • -
-
    -
  • Infants
  • -
  • Latonya Kirton
  • -
  • Susan Vacca
  • -
  • Deborah McDonald
  • -
-
-
-
    -
  • Evening Service
  • -
  • TBD
  • -
  • Alayna Robert
  • -
-
-
- -
-

Fourth Sunday, Oct. 27th

-
-
    -
  • Toddlers
  • -
  • Sara Bernard
  • -
  • Priscilla Reid
  • -
  • TBD
  • -
-
    -
  • Infants
  • -
  • Latonya Kirton
  • -
  • Susan Vacca
  • -
  • Crystal Johnson
  • -
-
-
-
    -
  • Evening Service
  • -
  • Deidra Dawson
  • -
  • Shekinah Dawson
  • -
-
-
- -
-

Fifth Sunday

-
-
    -
  • Toddlers
  • -
  • Sara Bernard
  • -
  • Priscilla Reid
  • -
  • Julie Froese
  • -
-
    -
  • Infants
  • -
  • Latonya Kirton
  • -
  • Susan Vacca
  • -
  • TBD
  • -
-
-
-
    -
  • Evening Service
  • -
  • TBD
  • -
  • TBD
  • -
-
-
-
- -
-
-

First Wednesday, Oct. 2nd

-
    -
  • Courtney or Bryan Bootka
  • -
  • Gabby Galvez
  • -
-
- -
-

Second Wednesday, Oct. 9th

-
    -
  • Reeta or Lionel Aguilar
  • -
  • Stephanie Langley
  • -
-
- -
-

Third Wednesday, Oct. 16th

-
    -
  • Christina Grooms
  • -
  • Lanell Hanson
  • -
-
- -
-

Fourth Wednesday, Oct. 23rd

-
    -
  • Cassie Hernandez
  • -
  • Regena Dumas
  • -
-
- -
-

Fifth Wednesday, Oct. 30th

-
    -
  • Regina Noble
  • -
  • TBD
  • -
-
- -
- - diff --git a/nursery-schedule.scss b/src/www/css/nursery-schedule.scss similarity index 57% rename from nursery-schedule.scss rename to src/www/css/nursery-schedule.scss index d6c5093..f5674bf 100644 --- a/nursery-schedule.scss +++ b/src/www/css/nursery-schedule.scss @@ -3,6 +3,10 @@ * @author Jonathan Bernard */ +// Fonts +@import url(http://fonts.googleapis.com/css?family=Abel|Lato|Josefin+Sans:400,600|Titillium+Web:400,300,600|Open+Sans|Raleway:400,600,500|Nunito:300,400|Oxygen:400,700); + + /// Global Rules * { -moz-box-sizing: border-box; @@ -11,18 +15,34 @@ margin: 0; padding: 0; } +/* HTML5 elements */ +article,aside,details,figcaption,figure, +footer,header,hgroup,menu,nav,section { + display:block; } + html { font-size: 90%; } +body { + font-family: "Abel"; + line-height: 1.1em; } + +h5 { + font-size: small; + font-weight: normal; + text-decoration: underline; } + +body.alt { + font-family: "Nunito"; + font-weight: 300; + + h3 { font-weight: 400; } + h5 { font-weight: 300; } } + /*html { background-color: $bgColor; color: $fgColor; font-size: 150%; }*/ -/* HTML5 elements */ -article,aside,details,figcaption,figure, -footer,header,hgroup,menu,nav,section { - display:block; } - .sundays, .wednesdays { } .first, .second, .third, .fourth, .fifth { @@ -31,16 +51,15 @@ footer,header,hgroup,menu,nav,section { vertical-align: top; width: 20em; } -.date { - float: right; - margin-right: 5rem; } +.date { } ul { list-style: none; } -.am ul { +.toddlers, .infants { display: inline-block; + vertical-align: top; width: 9rem; } -div.am, div.pm { +div.am, div.pm, .wednesdays ul { margin-top: 0.5rem; } diff --git a/src/www/css/schedule-maker.scss b/src/www/css/schedule-maker.scss new file mode 100644 index 0000000..186f854 --- /dev/null +++ b/src/www/css/schedule-maker.scss @@ -0,0 +1,108 @@ +/** + * Nursery Schedule Maker + * @author Jonathan Bernard + */ + +/// Global Rules +* { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + margin: 0; + padding: 0; } + +/* HTML5 elements */ +article,aside,details,figcaption,figure, +footer,header,hgroup,menu,nav,section { + display:block; } + +body { + line-height: normal; + margin: 2rem; } + +.header { position: relative; } + +.load-dialog { + background: rgba(0, 0, 0, 0.5); + bottom: 0; + display: none; + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 10; + + div { + text-align: center; + margin-top: 4rem; + + span { + background: whitesmoke; + border-radius: 3px; + padding: 1em; + + #fileLoad { width: 30rem; } } } } + +.tools { + + position: absolute; + top: 0; + right: 0; + + input[type="date"] { + border: solid thin gray; + border-radius: 3px; } + + ul { + list-style: none; + + li { + padding-right: 0.5rem; + display: inline-block; } } + + .publish { text-decoration: line-through; } } + +.sundays { border-right: solid thin lightgray; } +.wednesdays { padding-left: 2rem; } + +.sundays, .wednesdays { + display: inline-block; + line-height: 1.1rem; + margin-top: 2rem; + vertical-align: top; + width: 49%; + + .teacher-needed { + color: #A00; + font-style: italic; } + + li { + position: relative; + + input.name { + display: none; + width: 8rem; } + + .clone, .remove { + cursor: pointer; + display: none; + padding: 0 0.5em; + position: absolute; } + + &:hover { + .clone, .remove { display: inline-block; } } + + &.editing { + input.name { display: inline-block; } + span.name { display: none; } } + + &.editing:hover { + .clone, .remove { display: none; } } } } + +.sundays { + .remove { left: 7.5rem; } + .clone { left: 6.5rem; } } + +.wednesdays { + .remove { left: 11.5rem; } + .clone { left: 10.5rem; } } diff --git a/src/www/index.html b/src/www/index.html new file mode 100644 index 0000000..b6392e4 --- /dev/null +++ b/src/www/index.html @@ -0,0 +1,197 @@ + + + + + + +
+
+

First Sunday, Oct. 6th

+
+
+
Toddlers
+
    +
  • Sara Bernard
  • +
  • Priscilla Reid
  • +
  • Becca Torres
  • +
+
+
+
Infants
+
    +
  • Latonya Kirton
  • +
  • Susan Vacca
  • +
  • Brandie Kristoff
  • +
+
+
+
+
Evening Service
+
    +
  • Susan Miller
  • +
  • TBD
  • +
+
+
+ +
+

Second Sunday, Oct. 13th

+
+
+
Toddlers
+
    +
  • Sara Bernard
  • +
  • Priscilla Reid
  • +
  • Rebecca Dombroski
  • +
+
+
+
Infants
+
    +
  • Latonya Kirton
  • +
  • Susan Vacca
  • +
  • Mila Hill
  • +
+
+
+
+
Evening Service
+
    +
  • Zoe Torres
  • +
  • Hannah Torres
  • +
+
+
+ +
+

Third Sunday, Oct. 20th

+
+
+
Toddlers
+
    +
  • Sara Bernard
  • +
  • Priscilla Reid
  • +
  • Della Borrego
  • +
+
+
+
Infants
+
    +
  • Latonya Kirton
  • +
  • Susan Vacca
  • +
  • Deborah McDonald
  • +
+
+
+
+
Evening Service
+
    +
  • TBD
  • +
  • Alayna Robert
  • +
+
+
+ +
+

Fourth Sunday, Oct. 27th

+
+
+
Toddlers
+
    +
  • Sara Bernard
  • +
  • Priscilla Reid
  • +
  • TBD
  • +
+
+
+
Infants
+
    +
  • Latonya Kirton
  • +
  • Susan Vacca
  • +
  • Crystal Johnson
  • +
+
+
+
+
Evening Service
+
    +
  • Deidra Dawson
  • +
  • Shekinah Dawson
  • +
+
+
+ +
+

Fifth Sunday

+
+
+
Toddlers
+
    +
  • Sara Bernard
  • +
  • Priscilla Reid
  • +
  • Julie Froese
  • +
+
+
+
Infants
+
    +
  • Latonya Kirton
  • +
  • Susan Vacca
  • +
  • TBD
  • +
+
+
+
+
Evening Service
+
    +
  • TBD
  • +
  • TBD
  • +
+
+
+
+ +
+
+

First Wednesday, Oct. 2nd

+
    +
  • Courtney or Bryan Bootka
  • +
  • Gabby Galvez
  • +
+
+ +
+

Second Wednesday, Oct. 9th

+
    +
  • Reeta or Lionel Aguilar
  • +
  • Stephanie Langley
  • +
+
+ +
+

Third Wednesday, Oct. 16th

+
    +
  • Christina Grooms
  • +
  • Lanell Hanson
  • +
+
+ +
+

Fourth Wednesday, Oct. 23rd

+
    +
  • Cassie Hernandez
  • +
  • Regena Dumas
  • +
+
+ +
+

Fifth Wednesday, Oct. 30th

+
    +
  • Regina Noble
  • +
  • TBD
  • +
+
+ +
+ + diff --git a/src/www/js/schedule-maker.js b/src/www/js/schedule-maker.js new file mode 100644 index 0000000..fd70015 --- /dev/null +++ b/src/www/js/schedule-maker.js @@ -0,0 +1,254 @@ +(function() { + var root = this; + + var SM = root.ScheduleMaker = {}; + + SM.minSunAmTeachers = 3; + SM.minSunPmTeachers = 2; + SM.minWedTeachers = 2; + + SM.views = []; + + SM.ServiceView = function(element) { + + // #### Set properties + this.el = element; + this.$el = $(element); + var thisView = this; + + this.$el.attr('viewId', SM.views.length) + SM.views.push(thisView); + + // #### Set methods + this.findTeacherMinimum = function($ulEl) { + if ($ulEl.parents('.am').length > 0) { + return SM.minSunAmTeachers; } + else if ($ulEl.parents('.pm').length > 0) { + return SM.minSunPmTeachers; } + else return SM.minWedTeachers; }; + + this.volunteersAdded = function(event) { + // event.target should refer to the ul receiving the item. + var $ulEl = $(event.target); + + if ($ulEl.find('li.teacher-needed').length > 0) { + $ulEl.find('li.teacher-needed').first().remove(); + $ulEl.sortable("refresh"); } }; + + this.updatePlaceholders = function(event) { + // event.target should refer to the ul receiving the item. + var $ulEl = $(event.target); + + while ($ulEl.find('li').length < + this.findTeacherMinimum($ulEl)) { + var $li = $(document.createElement('li')); + $li.addClass('teacher-needed'); + $li.text('teacher needed'); + $li.on('dblclick', this.editPlaceholder); + $ulEl.append($li[0]); + $ulEl.sortable("refresh"); } }; + + this.deleteName = function (event) { + // event.target is the ul > li > span element containing the 'X' + var ulEl = $(event.target).closest('ul')[0]; + $(event.target).closest('li').remove(); + this.updatePlaceholders({target: ulEl})}; + + this.copyName = function (event) { + // event.target is the ul > li > span element containing the 'C' + var $liEl = $(event.target).closest('li'); + var $ulEl = $liEl.closest('ul'); + $ulEl.append($liEl.clone(true)); + this.volunteersAdded({target: $ulEl[0]}); }; + + this.editName = function(event) { + // event.target is the li > span.name element that was clicked. + var $spanEl = $(event.target); + var $liEl = $spanEl.parent(); + $liEl.find('input.name').val($spanEl.text()); + $liEl.addClass('editing'); + $liEl.find('input.name').focus(); }; + + this.saveName = function(event) { + // event.target is the li > input.name element that was blurred. + var $inputEl = $(event.target); + var $liEl = $inputEl.parent(); + $liEl.find('span.name').text($inputEl.val()); + $liEl.removeClass('editing'); }; + + this.editPlaceholder = function(event) { + var liEl = this.newName(event); + this.editName({target: $(liEl).find('span.name')[0]}); }; + + this.newName = function(event) { + var $ulEl = $(event.target).closest('ul'); + var $liEl = $(document.createElement('li')); + $liEl.append('' + + 'CX'); + $liEl.find('span.name').on('dblclick', this.editName); + $liEl.find('input.name').on('blur', this.saveName); + $liEl.find('.remove').on('click', this.deleteName); + $liEl.find('.clone').on('click', this.copyName); + + $ulEl.append($liEl[0]); + + this.volunteersAdded({target: $ulEl[0]}); + $ulEl.sortable("refresh"); + return $liEl[0]; }; + + var funs = ['newName', 'saveName', 'editName', 'deleteName', + 'copyName', 'editPlaceholder', 'volunteersAdded', + 'updatePlaceholders']; + funs.forEach(function(funName) { + thisView[funName] = thisView[funName].bind(thisView); }); + + // #### Initialize the existing view objects. + var $volunteerLists = this.$el.find('ul'); + $volunteerLists.sortable({ + connectWith: 'ul', + cancel: 'li.teacher-needed' }); + + // updatePlaceholders adds place-holders if there are not enough + // teachers. We call this once during initialization to pad out the + // lists to the minimums + $volunteerLists.each(function(idx) { + thisView.updatePlaceholders({target: this}); }); + + // #### Event handlers + + // Handlers to refresh the missing teacher spots when someone is + // drag-and-dropped. + $volunteerLists.on("sortreceive", this.volunteersAdded); + $volunteerLists.on("sortremove", this.updatePlaceholders); + + // Handler to remove names when the 'X' is clicked. + this.$el.find('.remove').on('click', this.deleteName); + + // Handler to edit names when they are double-clicked. + this.$el.find('span.name').on('dblclick', this.editName); + + // Handler to save the editing changes back to the li + this.$el.find('input.name').on('blur', this.saveName); + }; + + SM.saveSchedule = function() { + + // Create the JSON object to serialize to the file. + var data = {}; + + // Save the date. + data.date = $('input[type=date]').val(); + + // Gather the sunday data + data.sundays = {}; + $('.sundays > div').each(function() { + var divEl = this; + var $divEl = $(this); + + data.sundays[divEl.className] = {}; + + // Save each of the service data. + $divEl.find('ul').each(function() { + var ulEl = this; + var $ulEl = $(this); + + var roomName = 'pm'; + if ($ulEl.parents('.toddlers').length > 0) roomName = 'toddlers'; + else if ($ulEl.parents('.infants').length > 0) roomName = 'infants'; + + data.sundays[divEl.className][roomName] = + $ulEl.find('span.name').map(function() { + return $(this).text(); }).get(); + }); + }); + + // Gather Wednesday data + data.wednesdays = {}; + $('.wednesdays > div').each(function() { + var divEl = this; + var $divEl = $(this); + + // Save the service data. + data.wednesdays[divEl.className] = $divEl.find('span.name').map( + function() { return $(this).text(); }).get(); }); + + var jsonData = JSON.stringify(data); + var jsonBlob = new Blob([jsonData], {type: 'text/plain'}); + + // Save the file to disk by presenting it as a download to the user. + var linkEl = document.createElement('a'); + var $linkEl = $(linkEl); + linkEl.download = "nursery-schedule-" + $('input[type=date]').val(); + linkEl.innerHTML = "Download Schedule Data" + + if (window.webkitURL != null) { + linkEl.href = window.webkitURL.createObjectURL(jsonBlob); } + else { + linkEl.href = window.URL.createObjectURL(jsonBlob); + $(linkEl).on("click", function (e) { $(e.target).remove(); }); + $(linkEl).css('display', 'none'); + $('body').append(linkEl); } + linkEl.click(); }; + + SM.hideLoadDialog = function(e) { + if (e.target == $('#fileLoad')[0]) return; + $('.load-dialog').fadeOut(); }; + + SM.showLoadDialog = function() { $('.load-dialog').fadeIn(); }; + + SM.loadSchedule = function() { + // Remove exsting data. + $('.sundays ul li, .wednesdays ul li').remove() + + var fileName = $('#fileLoad')[0].files[0]; + var fileReader = new FileReader(); + + fileReader.onload = function(e) { + var fileText = e.target.result; + var data = JSON.parse(fileText); + + // Restore the date. + $('input[type=date]').val(data.date); + + // Restore Sunday services + for(var day in data.sundays) { + for(var roomName in data.sundays[day]) { + var $divEl = $('.sundays .' + day); + var $ulEl = $divEl.find('.' + roomName + ' ul'); + var view = SM.views[parseInt($divEl.attr('viewId'))]; + data.sundays[day][roomName].forEach(function(personName) { + var liEl = view.newName({target: $ulEl[0]}); + $(liEl).find('span.name').text(personName); }); + view.updatePlaceholders({target: $ulEl[0]}); } } + + // Restore Wednesday services + for(var day in data.wednesdays) { + var $divEl = $('.wednesdays .' + day); + var $ulEl = $divEl.find('ul'); + var view = SM.views[parseInt($divEl.attr('viewId'))]; + data.wednesdays[day].forEach(function(personName) { + var liEl = view.newName({target: $ulEl[0]}); + $(liEl).find('span.name').text(personName); }); + view.updatePlaceholders({target: $ulEl[0]}); } } + + fileReader.readAsText(fileName, "UTF-8"); + }; + + SM.publicShedule = function() { + // TODO + }; + + SM.init = function() { + // Create our ServiceViews + $('.sundays > div, .wednesdays > div').each(function(idx, elem) { + var view = new SM.ServiceView(elem); }); + + // Wire up our toolbar + $('.save').on('click', SM.saveSchedule); + $('.load').on('click', SM.showLoadDialog); + $('.publish').on('click', SM.publishSchedule); + $('.load-dialog').on('click', SM.hideLoadDialog); + $('.load-dialog a').on('click', SM.loadSchedule); + }; + +}).call(this); diff --git a/src/www/schedule-maker.html b/src/www/schedule-maker.html new file mode 100644 index 0000000..e8f3d7b --- /dev/null +++ b/src/www/schedule-maker.html @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + +
+

Nursery Schedule Maker

+
+
+ +
+
+

First Sunday

+
+
+
Toddlers
+
    +
+
+
+
Infants
+
    +
+
+
+
+
Evening Service
+
    +
+
+
+ +
+

Second Sunday

+
+
+
Toddlers
+
    +
+
+
+
Infants
+
    +
+
+
+
+
Evening Service
+
    +
+
+
+ +
+

Third Sunday

+
+
+
Toddlers
+
    +
+
+
+
Infants
+
    +
+
+
+
+
Evening Service
+
    +
+
+
+ +
+

Fourth Sunday

+
+
+
Toddlers
+
    +
+
+
+
Infants
+
    +
+
+
+
+
Evening Service
+
    +
+
+
+ +
+

Fifth Sunday

+
+
+
Toddlers
+
    +
+
+
+
Infants
+
    +
+
+
+
+
Evening Service
+
    +
+
+
+ +
+ +
+
+

First Wednesday

+
    +
+
+ +
+

Second Wednesday

+
    +
+
+ +
+

Third Wednesday

+
    +
+
+ +
+

Fourth Wednesday

+
    +
+
+ +
+

Fifth Wednesday

+
    +
+
+ +
+ +
+
+ Load It! +
+
+ + +