From a137dff49fec4c5242410c793ba0488efa39e8ee Mon Sep 17 00:00:00 2001 From: Kenneth Jao Date: Sun, 15 Jan 2017 23:59:10 -0500 Subject: [PATCH 1/2] signup page --- hourglass/client/main/main.js | 7 +-- hourglass/client/profile/profile.css | 56 +++++++++++++++++ hourglass/client/profile/profile.html | 37 +++++++++--- hourglass/client/profile/profile.js | 86 ++++++++++++++++++++++++++- hourglass/lib/constants.js | 7 ++- hourglass/lib/router.js | 1 - 6 files changed, 177 insertions(+), 17 deletions(-) diff --git a/hourglass/client/main/main.js b/hourglass/client/main/main.js index b5bd0d7..226592d 100644 --- a/hourglass/client/main/main.js +++ b/hourglass/client/main/main.js @@ -8,9 +8,6 @@ import './main.html'; var load = true; var calWorkOpen = null; var calWorkDate = null; -modifyingInput = null; -var clickDisabled = false; -var optionOpen = false; var defaultWork = { name: "Name | Click here to edit...", @@ -77,7 +74,7 @@ Template.registerHelper('screen', (multiplier, fraction) => { }); Template.registerHelper('divColor', (div) => { // Reactive color changing based on preferences. Colors stored in themeColors. - return Session.get("user").preferences.theme[div]; + return (Object.keys(Session.get("user")).length === 0) ? themeColors["lux"][div] : Session.get("user").preferences.theme[div]; }); Template.registerHelper('overlayDim', (part) => { // Gets size of the overlay container. @@ -750,7 +747,7 @@ Template.main.events({ // Other Functions -function toggleOptionMenu(toggle, menu) { +toggleOptionMenu = function(toggle, menu) { if(toggle) { $(".selectedOption").removeClass("selectedOption"); $("#" + menu).next() diff --git a/hourglass/client/profile/profile.css b/hourglass/client/profile/profile.css index e69de29..ab7f9e4 100644 --- a/hourglass/client/profile/profile.css +++ b/hourglass/client/profile/profile.css @@ -0,0 +1,56 @@ +#profPageWrapper { + width: 100%; + height: 100%; + + background-color: #DBDBDB; + + position: absolute; + top: 0; + left: 0; +} + +#basicInfo { + margin-top: 10%; +} + +#newUserWrapper { + width: 25%; + padding: 3%; + margin: auto; + + background-color: rgba(255,255,255,0.3); +} + +#newUserWrapper .formDiv { + width: 100%; + margin: 0; + padding: 0; +} + +.opTitle { + font-weight: 200; + margin: 0; +} + +#newUserWrapper .optionHolder { + width: 100% !important; +} + +#basicNext { + padding: 2%; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + cursor: pointer; + text-align: center; + + -webkit-transition: background-color 0.5s ease; + -moz-transition: background-color 0.5s ease; + -ms-transition: background-color 0.5s ease; + transition: background-color 0.5s ease; +} + +#basicNext:hover { + background-color: rgba(0,0,0,0.1); +} + diff --git a/hourglass/client/profile/profile.html b/hourglass/client/profile/profile.html index 3e8c4d3..3e8dd71 100644 --- a/hourglass/client/profile/profile.html +++ b/hourglass/client/profile/profile.html @@ -1,12 +1,33 @@ diff --git a/hourglass/client/profile/profile.js b/hourglass/client/profile/profile.js index e1b73d0..7c90fcc 100644 --- a/hourglass/client/profile/profile.js +++ b/hourglass/client/profile/profile.js @@ -15,7 +15,89 @@ Template.profile.helpers({ }); Template.profile.events({ - 'click #schoolnext' () { + 'click' (event) { // Closes respective divs when clicking outside of them. Order matters. + console.log("asdf"); + var e = event.target.className; + + if(modifyingInput !== null && event.target !== document.getElementById(modifyingInput)) { + console.log("hia"); + if (!(e.includes("optionHolder") || e.includes("optionText"))) { + console.log("hi"); + toggleOptionMenu(false, modifyingInput); + modifyingInput = null; + } + } + }, + 'click #schoolnext' () { // Animation to display class section - } + }, + // HANDLING INPUT CHANGING + 'focus .clickModify' (event) { + $(".optionHolder") + .fadeOut(100); + + if(modifyingInput !== null) { + if(!$("#"+modifyingInput)[0].className.includes("dropdown")) closeInput(modifyingInput); + } + modifyingInput = event.target.id; + if(!$("#"+modifyingInput)[0].className.includes("dropdown")) { + event.target.select(); + event.target.style.cursor = "text"; + } + }, + 'keydown .dropdown' (event) { + var first = $("#"+modifyingInput).next().children("p:first-child"); + var last = $("#"+modifyingInput).next().children("p:last-child"); + var next = $(".selectedOption").next(); + var prev = $(".selectedOption").prev(); + var lastSel = $(".selectedOption"); + + if (event.keyCode === 38) { + event.preventDefault(); + if (lastSel === undefined) { + last.addClass("selectedOption"); + } else { + if (prev.length === 0) { + last.addClass("selectedOption"); + lastSel.removeClass("selectedOption"); + } else { + prev.addClass("selectedOption"); + lastSel.removeClass("selectedOption"); + } + } + } else if (event.keyCode === 40) { + event.preventDefault(); + if (lastSel === undefined) { + first.addClass("selectedOption"); + last.removeClass("selectedOption"); + } else { + if (next.length === 0) { + first.addClass("selectedOption"); + lastSel.removeClass("selectedOption"); + } else { + next.addClass("selectedOption"); + lastSel.removeClass("selectedOption"); + } + } + } else if (event.keyCode === 13) { + lastSel[0].click(); + $("#"+modifyingInput)[0].focus(); + } + }, + 'click .dropdown, focus .dropdown' (event) { + if(clickDisabled) return; + clickDisabled = true; + if(event.target.id === optionOpen[0] && optionOpen[1]) { + toggleOptionMenu(false, event.target.id); + } else { + toggleOptionMenu(true, event.target.id); + } + setTimeout(function(){clickDisabled = false;},130); // Prevents spamming and handles extra click events. + }, + 'click .optionText' (event) { // Click each preferences setting. + var option = event.target.childNodes[0].nodeValue; + document.getElementById(modifyingInput).value = option; + toggleOptionMenu(false, modifyingInput); + $(".selectedOption").removeClass("selectedOption"); + }, }); diff --git a/hourglass/lib/constants.js b/hourglass/lib/constants.js index 03bc54a..3649b06 100644 --- a/hourglass/lib/constants.js +++ b/hourglass/lib/constants.js @@ -122,4 +122,9 @@ options = { } serverData = null; -confirm = null; \ No newline at end of file +confirm = null; + +//Input Handling +modifyingInput = null; +clickDisabled = false; +optionOpen = false; \ No newline at end of file diff --git a/hourglass/lib/router.js b/hourglass/lib/router.js index 50de376..5456e8f 100644 --- a/hourglass/lib/router.js +++ b/hourglass/lib/router.js @@ -54,7 +54,6 @@ Router.route('/profile', { } }, action: function() { - Session.set("user", Meteor.user().profile); this.render("profile"); } }); From c80dc3e32512d7b27ccce7b402c7aec7ebbdc61d Mon Sep 17 00:00:00 2001 From: Kenneth Jao Date: Tue, 17 Jan 2017 00:18:26 -0500 Subject: [PATCH 2/2] profile page --- hourglass/client/main/main.css | 4 + hourglass/client/main/main.js | 25 +++- hourglass/client/menus/menus.js | 20 +--- hourglass/client/profile/profile.css | 90 +++++++++++++- hourglass/client/profile/profile.html | 47 +++++++- hourglass/client/profile/profile.js | 165 +++++++++++++++++++++++++- 6 files changed, 320 insertions(+), 31 deletions(-) diff --git a/hourglass/client/main/main.css b/hourglass/client/main/main.css index 0dab4af..e883c3f 100644 --- a/hourglass/client/main/main.css +++ b/hourglass/client/main/main.css @@ -76,6 +76,10 @@ body { pointer-events: all; } +input { + font-family: Raleway !important; +} + .noScroll { width: 100%; height: 100%; diff --git a/hourglass/client/main/main.js b/hourglass/client/main/main.js index 9a042a5..fe3a541 100644 --- a/hourglass/client/main/main.js +++ b/hourglass/client/main/main.js @@ -56,11 +56,6 @@ Template.main.rendered = function() { document.getElementsByTagName("body")[0].style.color = Session.get("user").preferences.theme.textColor; }; -Template.profile.rendered = function() { - Accounts._loginButtonsSession.set('dropdownVisible', true); - document.getElementsByTagName("body")[0].style.color = Session.get("user").preferences.theme.textColor; -}; - // Global Helpers Template.registerHelper('adminPage', () => { @@ -968,6 +963,26 @@ function formReadable(input, val) { // Makes work information readable by users. } } +checkComplete = function(required, inputs) { + var values = {}; + var no = []; + for (var i = 0; i < inputs.length; i++) { + var val = inputs[i].value; + var where = inputs[i].getAttribute("form"); + if (val === "" && _.contains(required, where)) { + no.push(where); + } + values[where] = val; + } + if (no.length > 0) { // Check missing fields. + return [false,no.reduce(function(a, b) { + return (b === no[no.length - 1]) ? a + ((no.length === 2) ? " and " : ", and ") + b : a + ", " + b; + }), values]; + } else { + return [true,"", values]; + } +} + startDragula = function() { dragula([document.querySelector('#classesMode'), document.querySelector('#nonexistant')], { moves: function(el, container, handle) { diff --git a/hourglass/client/menus/menus.js b/hourglass/client/menus/menus.js index 9cf6eb8..f8c8e91 100644 --- a/hourglass/client/menus/menus.js +++ b/hourglass/client/menus/menus.js @@ -503,23 +503,11 @@ Template.createClass.helpers({ Template.createClass.events({ 'click #creSubmit' () { var inputs = document.getElementsByClassName("creInput"); - var values = {}; var required = ["school", "name", "privacy", "category"]; - var no = []; - for (var i = 0; i < inputs.length; i++) { - var val = inputs[i].value; - var where = inputs[i].getAttribute("form"); - if (val === "" && _.contains(required, where)) { - no.push(where); - } - values[where] = val; - } - console.log(values); - console.log(no); - if (no.length > 0) { // Check missing fields. - sAlert.error("Missing " + no.reduce(function(a, b) { - return (b === no[no.length - 1]) ? a + ", and " + b : a + ", " + b; - }), { + var alert = checkComplete(required, inputs); + var values = alert[2]; + if (!alert[0]) { // Check missing fields. + sAlert.error("Missing " + alert[1], { effect: 'stackslide', position: 'top', timeout: 3000 diff --git a/hourglass/client/profile/profile.css b/hourglass/client/profile/profile.css index 83e581d..381bf12 100644 --- a/hourglass/client/profile/profile.css +++ b/hourglass/client/profile/profile.css @@ -3,14 +3,45 @@ height: 100%; background-color: #282933; + color: #FCF0F0 !important; position: absolute; top: 0; left: 0; + + user-select: none; +} + +#profPageWrapper input { + color: #FCF0F0 !important; +} + +#profPageWrapper .optionText { + background-color: #282933 !important; +} + +#profPageWrapper #classSearch { + background-color: rgba(0,0,0,0.1); + border: 0; + + -webkit-transition: background-color 0.5s ease; + -moz-transition: background-color 0.5s ease; + -ms-transition: background-color 0.5s ease; + transition: background-color 0.5s ease; +} + +#profPageWrapper #classSearch:hover { + background-color: rgba(0,0,0,0.2); +} + +#profPageWrapper .classBox:not(:first-child) { + border: 1px solid #FCF0F0 !important; } #basicInfo { - margin-top: 10%; + width: 100%; + position: absolute; + top: 20%; } #newUserWrapper { @@ -39,9 +70,11 @@ #basicNext { padding: 2%; + border: 1px solid #FCF0F0; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; + cursor: pointer; text-align: center; @@ -54,3 +87,58 @@ #basicNext:hover { background-color: rgba(0,0,0,0.1); } + +#backArrow { + margin: auto; + z-index: 10; + cursor: pointer; + opacity: 0; + + position: relative; + top: 5%; + + -webkit-transition: background-color 0.5s ease; + -moz-transition: background-color 0.5s ease; + -ms-transition: background-color 0.5s ease; + transition: background-color 0.5s ease; +} + +#backArrow i { + line-height: 5vh; +} + +#backArrow:hover { + background-color: rgba(255,255,255,0.05); +} + +#forwardArrow { + margin: auto; + z-index: 10; + cursor: pointer; + opacity: 0; + + position: relative; + top: 85%; + + -webkit-transition: background-color 0.5s ease; + -moz-transition: background-color 0.5s ease; + -ms-transition: background-color 0.5s ease; + transition: background-color 0.5s ease; +} + +#forwardArrow:hover { + background-color: rgba(255,255,255,0.05); +} + +#enrollInfo { + width: 100%; + position: absolute; + top: 150%; +} + +#enrollUserWrapper { + width: 60%; + margin: auto; + padding: 1%; + background-color: rgba(255,255,255,0.2); +} diff --git a/hourglass/client/profile/profile.html b/hourglass/client/profile/profile.html index 3e8dd71..dc4f350 100644 --- a/hourglass/client/profile/profile.html +++ b/hourglass/client/profile/profile.html @@ -1,11 +1,14 @@ diff --git a/hourglass/client/profile/profile.js b/hourglass/client/profile/profile.js index 54145d8..a6c8317 100644 --- a/hourglass/client/profile/profile.js +++ b/hourglass/client/profile/profile.js @@ -3,6 +3,13 @@ import { Template } from 'meteor/templating'; + +Session.set("sections", [0,0]) // [Completed, Viewing] +Session.set("profile", {}); +Session.set("notsearching", true); // If user isn't searching +Session.set("noclass", null); // If user doesn't have classes. +Session.set("notfound", null); // If no results for autocomplete. + Template.profile.helpers({ schoolgradenext() { if(_.contains([null, undefined, ""], Meteor.user().profile.school || @@ -11,6 +18,88 @@ Template.profile.helpers({ } else { return "disabled"; } + }, + showArrow(type) { + var order = [ + {"back":false, "forward":true}, + {"back":true, "forward":true}, + {"back":true, "forward":false} + ]; + var section = Session.get("sections"); + if(type === "forward") { + return (section[1]+1 <= section[0] && order[section[1]][type]) ? "block":"none"; + } else { + return (order[section[1]][type]) ? "block":"none"; + } + }, + classes() { + var array = classes.find({ + status: { + $eq: true + }, + privacy: { + $eq: false + }, + school: { + $eq: Session.get("profile").school + } + }, { + sort: { + subscribers: -1 + } + }, { + limit: 20 + }).fetch(); + + for (var i = 0; i < array.length; i++) { + array[i].join = true; + array[i].subscribers = array[i].subscribers.length; + array[i].teachershort = array[i].teacher.split(" ").slice(1).reduce(function(a, b) { + return a + " " + b; + }); + } + if (array.length === 0) { + Session.set("noclass", true); + } else { + Session.set("noclass", false); + } + return array; + }, + classSettings() { + return { + position: "bottom", + limit: 10, + rules: [{ + token: '', + collection: classes, + template: Template.classDisplay, + filter: { + privacy: false, + status: true + }, + selector: (match) => { + regex = new RegExp(match, 'i'); + return { + $or: [{ + 'name': regex + }, { + 'teacher': regex + }, { + 'hour': regex + }] + }; + } + }] + }; + }, + notsearching() { // Tells whether user is using the searchbox + return Session.get("notsearching"); + }, + autocompleteClasses() { // Returns current auto-completes for classes + return Session.get("autocompleteDivs"); + }, + notfound() { // Returns if autocomplete has no results. + return Session.get("notfound"); } }); @@ -19,16 +108,37 @@ Template.profile.events({ var e = event.target.className; if(modifyingInput !== null && event.target !== document.getElementById(modifyingInput)) { - console.log("hia"); if (!(e.includes("optionHolder") || e.includes("optionText"))) { - console.log("hi"); toggleOptionMenu(false, modifyingInput); modifyingInput = null; } } }, - 'click #schoolnext' () { - // Animation to display class section + 'click #basicNext' () { + var inputs = document.getElementsByClassName("basicInfoField"); + var required = ["school", "grade"]; + var alert = checkComplete(required, inputs); + var values = alert[2]; + if(!alert[0]) { + sAlert.error("Missing " + alert[1], { + effect: 'stackslide', + position: 'top', + timeout: 3000 + }); + return; + } + var profile = Session.get("profile"); + profile.school = values["school"]; + profile.grade = values["grade"]; + Session.set("profile", profile); + Session.set("sections", [(Session.get("sections")[0] < 1) ? 1 : Session.get("sections")[0], Session.get("sections")[1]]) + slideToField(1); + }, + 'click #backArrow' () { + slideToField(Session.get("sections")[1]-1); + }, + 'click #forwardArrow' () { + slideToField(Session.get("sections")[1]+1); }, // HANDLING INPUT CHANGING 'focus .clickModify' (event) { @@ -99,4 +209,51 @@ Template.profile.events({ toggleOptionMenu(false, modifyingInput); $(".selectedOption").removeClass("selectedOption"); }, + 'input #classSearch' (event) { // Auto-complete updater + if (event.target.value.length === 0) { + Session.set("notsearching", true); + } else { + Session.set("notsearching", false); + } + Session.set("autocompleteDivs", null); + var divs = []; + try { + var items = document.getElementsByClassName("-autocomplete-container")[0].childNodes[3].childNodes; + if (items.length === 0) { // If no results. + Session.set("notfound", true); + } else { + Session.set("notfound", false); + } + for (var i = 2; i < items.length; i += 3) { // Iterate through autocomplete div. + var item = items[i].childNodes[3]; + if (Meteor.user().profile.classes.indexOf(item.getAttribute("classid")) !== -1) continue; + divs.push({ + name: item.childNodes[1].childNodes[0].nodeValue, + teacher: item.childNodes[3].childNodes[0].nodeValue, + hour: item.childNodes[5].childNodes[0].nodeValue, + subscribers: Math.floor(item.childNodes[7].childNodes[0].nodeValue.replace(",", "").length / 17), + _id: item.getAttribute("classid") + }); + } + Session.set("autocompleteDivs", divs.sort(function(a, b) { + return b.subscribers - a.subscribers; + })); + } catch (err) {} + }, }); + +function slideToField(field) { + var order = ["basicInfo", "enrollInfo"]; + $(".moveArrow").animate({"opacity":0}) + var viewing = Session.get("sections")[1] + var move = (viewing-field < 0) ? "-50%" : "150%"; + $("#"+order[viewing]).animate({top: move}); + $("#"+order[field]).animate({ + top:"20%" + },{ + complete: function() { + Session.set("sections", [Session.get("sections")[0],field]); + $(".moveArrow").animate({"opacity":1}); + } + }); +}