diff --git a/hourglass/client/main/main.css b/hourglass/client/main/main.css index 3964e9a..d4a2627 100644 --- a/hourglass/client/main/main.css +++ b/hourglass/client/main/main.css @@ -38,6 +38,38 @@ html { user-select: none; } +::-webkit-input-placeholder { + font-size: 70%; +} + +:-moz-placeholder { + font-size: 70%; +} + +::-moz-placeholder { + font-size: 70%; +} + +:-ms-input-placeholder { + font-size: 70%; +} + +.formInvalid::-webkit-input-placeholder { + color: red; +} + +.formInvalid:-moz-placeholder { + color: red; +} + +.formInvalid::-moz-placeholder { + color: red; +} + +.formInvalid:-ms-input-placeholder { + color: red; +} + body { margin: 0; } diff --git a/hourglass/client/profile/profile.css b/hourglass/client/profile/profile.css index c6459dd..b063a7b 100644 --- a/hourglass/client/profile/profile.css +++ b/hourglass/client/profile/profile.css @@ -15,6 +15,7 @@ font-size: 150%; font-weight: 400; margin: 0; + margin-bottom: 1%; } .profHea { @@ -82,6 +83,8 @@ position: absolute; display: none; + z-index: 5; + opacity: 0; -webkit-transition: opacity 0.4s ease; @@ -94,6 +97,7 @@ font-size: 150%; margin: 0; padding: 20%; + text-align: center; cursor: pointer; @@ -144,8 +148,6 @@ } #profClassInfoHolder { - - -webkit-transition: opacity 0.4s ease; -moz-transition: opacity 0.4s ease; -ms-transition: opacity 0.4s ease; @@ -231,6 +233,17 @@ overflow-y: scroll; } +.classHolder h3 { + font-style: italic; + font-weight: 200; + margin-left: 1%; + + color: #999; + + -webkit-filter :none; + filter: none; +} + .classBox { font-size: 150%; width: 100%; @@ -273,10 +286,57 @@ width: 13%; } +#creRules { + position: absolute; +} + +#create { + margin-top: 2.5%; + padding: 5%; + padding-top: 1%; +} + +#create div { + margin: 2%; + margin-left: 11%; + margin-bottom: 5%; + display: inline-block; +} + +.creInput { + font-size: 120%; + padding: 3%; +} + +.creOp { + margin: 0 !important; +} + .-autocomplete-container { + margin: 0.5% 0 0 0 !important; display: none; } +#creSubmit { + font-weight: 200; + font-size: 140%; + margin: 0 35% 0 35%; + padding: 2%; + + background-color: rgba(0,0,0,0.25); + text-align: center; + cursor: pointer; + + -webkit-transition: background-color 0.4s ease; + -moz-transition: background-color 0.4s ease; + -ms-transition: background-color 0.4s ease; + transition: background-color 0.4s ease; +} + +#creSubmit:hover { + background-color: rgba(0,0,0,0.15); +} + #restrict { font-size: 100%; font-style: italic; diff --git a/hourglass/client/profile/profile.html b/hourglass/client/profile/profile.html index 118bb10..02fc6e2 100644 --- a/hourglass/client/profile/profile.html +++ b/hourglass/client/profile/profile.html @@ -19,7 +19,7 @@

Grade:

- {{grade}} + {{grade}}

9th

@@ -80,39 +80,51 @@ {{#each autocompleteClasses}} {{> classDisplay}} {{/each}} + {{#if notfound}} +

No results found...

+ {{/if}} {{/if}}
{{/if}} {{#if profClassTab "creClass"}} - +
+

Submit Request

+ {{/if}} diff --git a/hourglass/client/profile/profile.js b/hourglass/client/profile/profile.js index afee9f6..79d522d 100644 --- a/hourglass/client/profile/profile.js +++ b/hourglass/client/profile/profile.js @@ -82,15 +82,15 @@ Template.profile.helpers({ avatar() { var dim = window.innerWidth * 1600/1920 * .16; if(Meteor.user().profile.avatar !== undefined) { - var pic = Meteor.users().profile.avatar; + var pic = "\'"+Meteor.user().profile.avatar+"\'"; } else { - var pic = "defaultAvatars/"+(Math.floor(Math.random() * (10 - 1)) + 1).toString()+".png"; + var pic = "defaultAvatars/"+(Math.floor(Math.random() * (11 - 1)) + 1).toString()+".png"; } return "background-image:url("+pic+");background-size:"+dim.toString()+"px "+dim.toString()+"px"; }, avatarDim() { var dim = window.innerWidth * 1600/1920 * .16; - return "height:"+dim.toString()+"px;width:"+dim.toString()+"px;top:"+.43*window.innerHeight.toString()+"px"; + return "height:"+dim.toString()+"px;width:"+dim.toString()+"px;top:"+.43*window.innerHeight.toString()+"px;"; }, username() { return Meteor.user().profile.name; @@ -146,7 +146,14 @@ Template.profile.helpers({ return Session.get("autocompleteDivs"); }, myclasses() { - return Meteor.user().profile.classes; + if (Meteor.user().profile.classes === undefined || Meteor.user().profile.classes.length === 0) { + return []; + } else { + return Meteor.user().profile.classes; + } + }, + notfound() { + return Session.get("notfound"); }, confirmText() { return Session.get("confirmText"); @@ -154,26 +161,17 @@ Template.profile.helpers({ }) Template.profile.events({ - 'click #profile input' (event) { - var opened = Session.get("profradioDiv"); - if(opened !== null && opened !== event.target.getAttribute("op")) { - closeDivFade(document.getElementsByClassName("creInputSel")[opened].parentNode.childNodes[4]); - }d - }, - 'click .profInputSel' (event) { - Session.set("profradioDiv", event.target.getAttribute("op")); - openDivFade(event.target.parentNode.childNodes[4]); - }, 'click profOptions p' (event) { var p = event.target; p.parentNode.parentNode.childNodes[1].value = p.childNodes[0].nodeValue; closeDivFade(p.parentNode); Session.set("radioDiv",null); + Session.set("radioOffset",null); }, 'click .change' (event) { var ele = event.target; var sessval = Session.get("modifying"); - if(ele.id !== sessval && sessval != null) closeInput(sessval); + if(ele.id !== sessval && sessval !== null) closeInput(sessval); Session.set("modifying", ele.id); var dim = ele.getBoundingClientRect(); @@ -191,9 +189,11 @@ Template.profile.events({ input.style.width = "70%"; input.style.padding = "0.1%"; input.id = ele.id+"a"; + input.setAttribute("opc",ele.getAttribute("opc")); ele.parentNode.appendChild(input); if(ele.getAttribute("re") == "readonly") { input.readOnly = true; + input.className += " op"; input.style.cursor = "pointer"; } else { input.select(); @@ -219,10 +219,18 @@ Template.profile.events({ !event.target.parentNode.className.includes("profOptions")) { closeInput(sessval); } - if(!event.target.className.includes("radio") && + if(!event.target.className.includes("radio") && !Session.equals("radioDiv",null) && - !event.target.parentNode.className.includes("profOptions")) { - closeDivFade(document.getElementsByClassName("profOptions")[Session.get("radioDiv")]); + !event.target.parentNode.className.includes("profOptions") && + event.target.readOnly !== true) { + var opnum = (parseInt(Session.get("radioDiv"))-parseInt(Session.get("radioOffset"))).toString(); + for(var i = 0; i < document.getElementsByClassName("profOptions").length; i++) { + try { + closeDivFade(document.getElementsByClassName("profOptions")[i]); + } catch(err) {} + } + Session.set("radioDiv",null); + Session.set("radioOffset",null); } }, 'keydown' (event) { @@ -232,37 +240,54 @@ Template.profile.events({ closeInput(sessval); } catch(err) {} } + if(sessval !== null && event.keyCode !== 13) { var restrict = document.getElementById(sessval).getAttribute("restrict"); - if(restrict !== null) { - var num = parseInt(restrict)-event.target.value.length; - var restext = document.getElementById("restrict"); - if(num === 1) { - restext.childNodes[0].nodeValue = num.toString()+" character left"; - restext.style.setProperty("color","#999","important"); - } else if(num <= 0) { - var input = document.getElementById(sessval+"a"); - input.value = input.value.substring(0,parseInt(restrict)); - restext.childNodes[0].nodeValue = "0 characters left"; - restext.style.setProperty("color","#FF1A1A","important"); - } else { - restext.childNodes[0].nodeValue = num.toString()+" characters left"; - restext.style.setProperty("color","#999","important"); + if(restrict !== null) { + var num = parseInt(restrict)-event.target.value.length; + var restext = document.getElementById("restrict"); + if(num === 1) { + restext.childNodes[0].nodeValue = num.toString()+" character left"; + restext.style.setProperty("color","#999","important"); + } else if(num <= 0) { + var input = document.getElementById(sessval+"a"); + input.value = input.value.substring(0,parseInt(restrict)); + restext.childNodes[0].nodeValue = "0 characters left"; + restext.style.setProperty("color","#FF1A1A","important"); + } else { + restext.childNodes[0].nodeValue = num.toString()+" characters left"; + restext.style.setProperty("color","#999","important"); + } } } }, 'click .radio' (event) { - Session.set("radioDiv", event.target.getAttribute("op")); - openDivFade(event.target.parentNode.parentNode.childNodes[3]); + var op = event.target; + Session.set("radioDiv", op.getAttribute("op")); + Session.set("radioOffset", op.getAttribute("opc")); + try { + for(var i = 0; i < document.getElementsByClassName("profOptions").length; i++) { + var curr = document.getElementsByClassName("profOptions")[i]; + if(Session.get("radioDiv") !== i.toString()) { + closeDivFade(document.getElementsByClassName("profOptions")[i]); + } + } + } catch(err) {} + openDivFade(document.getElementsByClassName("profOptions")[op.getAttribute("op")]); }, 'click .profOptions p' (event) { var sessval = Session.get("modifying"); var p = event.target; - var input = p.parentNode.parentNode.childNodes[1].childNodes[5]; + var opnum = (parseInt(Session.get("radioDiv"))-parseInt(Session.get("radioOffset"))).toString(); + var input = document.getElementsByClassName("op")[opnum]; input.value = p.childNodes[0].nodeValue; - closeInput(sessval); + try{ + closeInput(sessval); + } catch(err) {} + closeDivFade(p.parentNode); input.focus(); - Session.set("radioDiv",null) + Session.set("radioDiv",null); + Session.set("radioOffset",null); }, 'click .addClass' () {         var functionHolder = document.getElementById("profClassInfoHolder") @@ -300,9 +325,15 @@ Template.profile.events({ } else { Session.set("notsearching",false); } - divs = []; + Session.set("autocompleteDivs",null); + var divs = []; try { var items = document.getElementsByClassName("-autocomplete-container")[0].childNodes[3].childNodes; + if(items.length === 0) { + Session.set("notfound",true); + } else { + Session.set("notfound",false); + } for(var i = 2; i < items.length; i+=3) { var item = items[i].childNodes[3]; divs.push({ @@ -317,14 +348,21 @@ Template.profile.events({ } catch(err) {} }, 'click .classBox' (event) { - if(event.target.getAttribute("classid") === null) return; + if(event.target.id === "label") return; + if(event.target.className !== "classBox") { + var attribute = event.target.parentNode.getAttribute("classid"); + } else { + var attribute = event.target.getAttribute("classid"); + } + var data = [attribute,""]; + Session.set("serverData",data); + Session.set("confirm","joinClass"); + Session.set("confirmText","Join class?"); + openDivFade(document.getElementsByClassName("overlay")[0]); setTimeout(function() { document.getElementsByClassName("overlay")[0].style.opacity = "1"; }, 200); - Session.set("serverData",[event.target.getAttribute("classid"),""]); - Session.set("confirm","joinClass"); - Session.set("confirmText","Join class?"); }, 'click .fa-check-circle-o' () { sendData(Session.get("confirm")); @@ -334,19 +372,33 @@ Template.profile.events({ }, 'click .fa-times-circle-o' () { closeDivFade(document.getElementsByClassName("overlay")[0]); - closeDivFade(document.getElementById("functionHolder")); Session.set("serverData",null); Session.set("confirm",null); }, 'click #save' () { + Session.set("serverData",getProfileData()); + Session.set("confirm","editProfile"); + Session.set("confirmText", "Save new profile settings?"); + openDivFade(document.getElementsByClassName("overlay")[0]); setTimeout(function() { document.getElementsByClassName("overlay")[0].style.opacity = "1"; }, 200); - getProfileData(); - Session.set("serverData",getProfileData()); - Session.set("confirm","editProfile"); - Session.set("confirmText", "Save new profile settings?"); + }, + 'click #creSubmit' () { + var data = getCreateFormData(); + if(data == null) return; + Session.set("serverData",data); + Session.set("confirm","createClass"); + Session.set("confirmText", "Submit request?"); + + openDivFade(document.getElementsByClassName("overlay")[0]); + setTimeout(function() { + document.getElementsByClassName("overlay")[0].style.opacity = "1"; + }, 200); + }, + 'focus .op' (event) { + event.target.click(); } }) @@ -387,7 +439,55 @@ function sendData(funcName) { } function getProfileData() { - var desc = document.getElementById("motd").childNodes[0].nodeValue; + var description = document.getElementById("motd").childNodes[0].nodeValue; var school = document.getElementById("school").childNodes[0].nodeValue; - var grade = document.getElementById("grade").childNodes[0].nodeValue; + var gradein = document.getElementById("grade").childNodes[0].nodeValue; + var grade = parseInt(gradein.substring(gradein.length-2,gradein)); + var avatar = document.getElementById("profAvatar").style.backgroundImage.replace(")","").replace("url(","").replace("\"","").replace("\"",""); + var banner = document.getElementById("profBanner").style.backgroundImage.replace(")","").replace("url(","").replace("\"","").replace("\"",""); + + return { + school: school, + grade: grade, + description: description, + avatar: avatar, + banner: banner + }; +} + +function getCreateFormData() { + var stop; + var form = document.getElementsByClassName("creInput"); + for(var i = 0; i < form.length; i++) { + if(form[i].value === "") { + form[i].focus(); + form[i].placeholder = "Missing field"; + form[i].className += " formInvalid"; + stop = true; + } else { + form[i].className = form[i].className.replace(" formInvalid",""); + } + } + if(stop) return null; + + var school = form[0].value; + var hour = form[1].value; + var teacher = form[2].value; + var name = form[3].value; + if(form[4].value == "public") { + var privacy = false; + } else { + var privacy = true; + } + var category = form[5].value; + return { + school: school, + hour: hour, + teacher: teacher, + name: name, + privacy: privacy, + category: category, + status: false, + code: "" + }; } \ No newline at end of file diff --git a/hourglass/server/main.js b/hourglass/server/main.js index 8d94251..7a812cc 100644 --- a/hourglass/server/main.js +++ b/hourglass/server/main.js @@ -91,16 +91,15 @@ Meteor.methods({ }, 'editProfile': function(change) { current = Meteor.user().profile; - current.school = change[0]; - current.grade = change[1]; - current.description = change[2]; - current.avatar = change[3]; - current.banner = change[4]; + current.school = change.school; + current.grade = change.grade; + current.description = change.description; + current.avatar = change.avatar; + current.banner = change.banner; if (schools.findOne({name:current.school}) != null && Number.isInteger(current.grade) && - current.grade >= 9 && - current.grade <= 12 && + current.grade >= 9 && current.grade <= 12 && current.description.length <= 50) { Meteor.users.update({_id: Meteor.userId()}, {$set: {profile: current}}); @@ -109,22 +108,30 @@ Meteor.methods({ return 0; } }, - 'joinClass': function(change, pass) { - found = classes.findOne({_id: change, status: true}); + 'joinClass': function(input) { + change = input[0]; + pass = input[1]; + if(Meteor.user().profile.classes === undefined) { + curr = Meteor.user().profile; + curr.classes = []; + Meteor.users.update({_id: Meteor.userId()}, {$set: {profile: curr}}) + } + prof = Meteor.user().profile; + found = classes.findOne({_id: change, status: true}); if (Meteor.user() != null && found != null && pass === found.code && - found.banned.indexOf(Meteor.userId()) === -1 && - Meteor.user().profile.classes.indexOf(change) === -1) { - + !found.banned.includes(Meteor.userId()) && + !prof.classes.includes(change)) { + current = Meteor.user().profile; current.classes.append(change); Meteor.users.update({_id: Meteor.userId()}, {$set: {profile: current}}); return 1; } else { return 0; - } + } }, 'leaveClass': function(change) { if (Meteor.user() != null) { @@ -142,4 +149,11 @@ Meteor.methods({ } } -}); \ No newline at end of file +}); + +function has(array, has) { + for(var i = 0; i < array.length; i++) { + if(array[i] === has) return true; + } + return false; +} \ No newline at end of file