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