Added created classes tab, and all functionality

This commit is contained in:
Kenneth Jao 2016-08-16 20:46:38 -04:00
parent 1ab2d57b79
commit 0683c73f4c
7 changed files with 343 additions and 106 deletions

View File

@ -243,7 +243,7 @@ input, textarea {
filter: drop-shadow(2px 2px 5px #666);
}
.fa-plus, .fa-minus, .fa-tasks, .fa-graduation-cap {
.fa-plus, .fa-minus, .fa-tasks, .fa-graduation-cap, .fa-exchange {
font-size: 130%;
padding: 5%;
-webkit-filter: drop-shadow(2px 2px 5px #666);

View File

@ -52,7 +52,7 @@ Template.registerHelper('divColor', (div) => {
});
Template.registerHelper('overlayDim', (part) => {
var dim = [window.innerWidth * 0.2, window.innerHeight * 0.2];
var dim = [window.innerWidth * 0.2, window.innerHeight * 0.25];
var width = "width:" + dim[0].toString() + "px;";
var height = "height:" + dim[1].toString() + "px;";
var margin = "margin-left:" + (-dim[0] / 2).toString() + "px;";

View File

@ -200,7 +200,7 @@
display: inline;
}
#profClassSearch, .userAddInput {
#profClassSearch {
font-size: 125%;
width: 30%;
margin-top: 3%;
@ -210,6 +210,10 @@
animation: expand .7s ease 1;
}
#profClassSearch .-autocomplete-container {
display: none;
}
@-webkit-keyframes expand {
0% { width: 0%; }
100% { width: 30%; }
@ -324,10 +328,10 @@
margin-right: 5% !important;
margin-bottom: 0 !important;
position: relative;
overflow: hidden !important;
}
#formContainer div {
.formDiv {
margin: 3% 6% 5% 6%;
width: 35%;
display: inline-block;
@ -345,7 +349,6 @@
.-autocomplete-container {
margin: 0 0 0 0 !important;
position: absolute;
display: none;
}
#creSubmit {
@ -416,18 +419,173 @@
#createdClasses {
width: 25%;
margin-right: -80%;
padding: 3%;
margin-right: -40%;
padding: 2.5%;
border-top: 5px solid #2E4F74;
border-top: 5px solid #27646D;
box-shadow: -1px 2px 5px 1px #444;
position: absolute;
top: 30%;
top: 20%;
right: 0;
-webkit-transition: margin 0.4s ease;
-moz-transition: margin 0.4s ease;
-ms-transition: margin 0.4s ease;
transition: margin 0.4s ease;
}
#code {
font-size: 120%;
width: 30%;
}
#codetext {
width: 15% !important;
}
#copy, #deleteClass {
margin-left: 1%;
padding: 2%;
background-color: rgba(0,0,0,0.2);
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
}
#copy:hover, #deleteClass:hover {
background-color: rgba(0,0,0,0.1);
}
.userAddInput {
font-size: 100%;
width: 50%;
padding: 2%;
}
#createdClasses h3 {
font-weight: 400;
font-size: 200%;
}
#createdClasses h4 {
width: 25%;
padding-right: 0;
}
#createdClasses .fa-plus {
cursor: pointer;
-webkit-transition: color 0.4s ease;
-moz-transition: color 0.4s ease;
-ms-transition: color 0.4s ease;
transition: color 0.4s ease;
}
#createdClasses .fa-plus:hover {
color: #519C39;
}
.userHolder {
width: 100%;
max-height: 10%;
margin-left: 5%;
padding: 2%;
padding-right: 20%;
overflow-y: scroll;
overflow-x: hidden;
}
.userBox {
font-size: 100%;
width: 80%;
margin-bottom: 3%;
padding: 4%;
box-shadow: 2px 2px 5px 3px #666;
display: table;
}
.email {
margin-right: 5%;
}
.realname {
margin-right: 5%;
}
.userBox .fa-times {
font-size: 150%;
-webkit-transition: color 0.4s ease;
-moz-transition: color 0.4s ease;
-ms-transition: color 0.4s ease;
transition: color 0.4s ease;
}
.userBox .fa-times:hover {
color: #CC4444;
}
#deleteClass {
font-size: 150%;
width: 29%;
margin: 5% 30% 0 30%;
}
#changeAdmin span {
font-size: 90%;
padding: 3%;
background-color: rgba(0,0,0,0.2);
display: inline-block;
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
}
#changeAdmin span:hover {
background-color: rgba(0,0,0,0.1);
}
#changeAdmin input {
font-size: 100%;
width: 50%;
margin-left: 3%;
margin-right: 5%;
padding: 2%;
-webkit-animation: expand2 .7s ease 1;
animation: expand2 .7s ease 1;
}
@-webkit-keyframes expand2 {
0% { width: 0%; }
100% { width: 50%; }
}
@keyframes expand2 {
0% { width: 0%; }
100% { width: 50%; }
}
.fa-exchange {
padding: 0 !important;
-webkit-transition: color 0.4s ease;
-moz-transition: color 0.4s ease;
-ms-transition: color 0.4s ease;
transition: color 0.4s ease
}
.fa-exchange:hover {
color: #CC4444;
}

View File

@ -91,23 +91,23 @@
<div id="creRules"><p>Insert description and rules of create a class --Will style later--</p></div>
<form id="create">
<div id="formContainer">
<div>
<div class="formDiv">
<p class="profTitle">School:</p>
{{> inputAutocomplete settings=schoolcomplete class="form-control creInput" type="text" name="school" placeholder="Example: International Academy" }}
</div>
<div>
<div class="formDiv">
<p class="profTitle">Hour:</p>
<input class="creInput" type="text" name="hour">
</div>
<div>
<div class="formDiv">
<p class="profTitle">Teacher:</p>
{{> inputAutocomplete settings=teachercomplete class="form-control creInput" type="text" name="teacher" placeholder="Example: Woods" }}
</div>
<div>
<div class="formDiv">
<p class="profTitle">Class Name:</p>
<input class="creInput" type="text" name="classname">
</div>
<div>
<div class="formDiv">
<p class="profTitle">Privacy:</p>
<input class="creInput radio op" type="text" name="privacy" opc="1" op="1" readonly>
<div class="profOptions creOp" style="background-color:{{divColor 'header'}}">
@ -115,7 +115,7 @@
<p class="profOptionText">Private</p>
</div>
</div>
<div>
<div class="formDiv">
<p class="profTitle">Category:</p>
<input class="creInput radio op" type="text" name="category" opc="1" op="2" readonly>
<div class="profOptions creOp" style="background-color:{{divColor 'header'}}">
@ -142,27 +142,40 @@
</div>
</div>
<div id="createdClasses" style="background-color:{{divColor 'cards'}}">
<div id="createdClasses" style="background-color:{{divColor 'cards'}}" classid="{{selectedClass '_id'}}">
<h3>{{selectedClass 'name'}}</h3>
<h4>Code: {{selectedClass 'code'}}</h4>
<h4 id="codetext">Code:</h4>
<input id="code" value="{{selectedClass 'code'}}" type="text" readonly>
{{#if code}}
<h4 id="copy">Copy Code</h4>
{{/if}}
<div id="moderatorCont">
<div class="userAdder">
<h4>Moderators: </h4>
<h4>Moderators:</h4>
<input class="userAddInput" type="text" placeholder="1234@abc.xyz">
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
{{#each selectedClass 'moderators'}}
{{> userDisplay}}
{{/each}}
<div class="userHolder" style="max-height:{{userHolder}}">
{{#each selectedClass 'moderators'}}
{{> userDisplay}}
{{/each}}
</div>
</div>
<div id="blockEditCont">
<div id="bannedCont">
<div class="userAdder">
<h4>View only: </h4>
<h4>Banned:</h4>
<input class="userAddInput" type="text" placeholder="1234@abc.xyz">
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
{{#each selectedClass 'blockEdit'}}
{{> userDisplay}}
{{/each}}
</div>
<div class="userHolder" style="max-height:{{userHolder}}">
{{#each selectedClass 'banned'}}
{{> userDisplay}}
{{/each}}
</div>
</div>
<div id="changeAdmin">
<span>Change Owner</span>
</div>
<div id="deleteClass">Delete Class</div>
</div>
</template>
@ -180,6 +193,7 @@
<div class="userBox" userid="{{_id}}">
<span class="email">{{email}}</span>
<span class="realname">{{name}}</span>
<i class="fa fa-times" aria-hidden="true"></i>
</div>
</template>

View File

@ -17,7 +17,8 @@ Session.set("serverData", null);
Session.set("autocompleteDivs", null);
Session.set("confirmText", null);
Session.set("selectedClass",null);
Session.set("adding",null);
Session.set("selectClassId",null);
Session.set("code",null);
var themeColors = {
"light": {
@ -144,9 +145,9 @@ Template.profile.helpers({
privacy: {$eq: false},
_id: {$nin: Meteor.user().profile.classes}
},
{sort: {subscribers: -1 }},
{limit: 20}
).fetch();
{sort: {subscribers: -1 }},
{limit: 20}
).fetch();
},
profClassHeight() {
return 0.6 * window.innerHeight.toString() + "px";
@ -181,7 +182,36 @@ Template.profile.helpers({
return Session.get("confirmText");
},
selectedClass(val) {
return Session.get("selectedClass")[val];
var usertype = ["moderators","banned"];
var attribute = Session.get("selectClassId");
var array = classes.findOne({_id:attribute});
if(array.code === "") {
array.code = "None";
Session.set("code", false);
} else {
Session.set("code", true);
}
for(var i = 0; i < usertype.length; i++) {
var users = array[usertype[i]];
array[usertype[i]] = [];
for(var j = 0; j < users.length; j++) {
var detailusers = {};
var user = Meteor.users.findOne({_id:users[j]});
detailusers._id = user._id;
detailusers.email = user.services.google.email;
detailusers.name = user.profile.name;
array[usertype[i]].push(detailusers);
}
}
return array[val];
},
code() {
return Session.get("code");
},
userHolder() {
return 0.15 * window.innerHeight.toString() + "px";
}
});
@ -257,21 +287,19 @@ Template.profile.events({
Session.set("radioDiv", null);
Session.set("radioOffset", null);
}
if(event.target.className !== "userAddInput" &&
Session.get("adding")) {
var inputs = document.getElementsByClassName("userAddInput");
for(var i = 0; i < inputs.length; i++) {
try {
inputs[i].parentNode.removeChild(inputs[i]);
} catch(err) {}
}
Session.set("adding",false);
}
if(!document.getElementById("createdClasses").contains(event.target) &&
Session.get("selectedClass") !== null) {
document.getElementById("createdClasses").style.marginRight = "-40%";
setTimeout(function() { Session.set("selectedClass", null); }, 300);
}
if(!document.getElementById("createdClasses").contains(event.target) &&
Session.get("code") !== null &&
!event.target.className.includes("fa-times-circle-o")) {
document.getElementById("createdClasses").style.marginRight = "-40%";
setTimeout(function() { Session.set("selectedClass", null); }, 300);
}
if(Session.get("changeAdmin") &&
!document.getElementById("changeAdmin").contains(event.target)) {
Session.set("changeAdmin",false);
var div = document.getElementById("changeAdmin");
div.removeChild(div.childNodes[3]);
div.removeChild(div.childNodes[3]);
}
},
'keydown' (event) {
var sessval = Session.get("modifying");
@ -338,20 +366,20 @@ Template.profile.events({
}, 300);    
},
    'click .manageClass' () {        
var functionHolder = document.getElementById("profClassInfoHolder");
closeDivFade(functionHolder);        
setTimeout(function() {            
Session.set("profClassTab", "manClass");            
openDivFade(functionHolder);        
}, 300);    
var functionHolder = document.getElementById("profClassInfoHolder");
closeDivFade(functionHolder);        
setTimeout(function() {            
Session.set("profClassTab", "manClass");            
openDivFade(functionHolder);        
}, 300);    
},
    'click .createClass' () {        
var functionHolder = document.getElementById("profClassInfoHolder");        
closeDivFade(functionHolder);        
setTimeout(function() {            
Session.set("profClassTab", "creClass");            
openDivFade(functionHolder);        
}, 300);    
var functionHolder = document.getElementById("profClassInfoHolder");        
closeDivFade(functionHolder);        
setTimeout(function() {            
Session.set("profClassTab", "creClass");            
openDivFade(functionHolder);        
}, 300);    
},
'click .fa-search' () {
Session.set("searching", true);
@ -409,8 +437,8 @@ Template.profile.events({
sendData(Session.get("confirm"));
closeDivFade(document.getElementsByClassName("overlay")[0]);
if(Session.get("confirm") === "createClass") {
var form = document.getElementById("create");
for(var i = 0; i < form.length; i++) form[i].value = "";
var form = document.getElementById("create");
for(var i = 0; i < form.length; i++) form[i].value = "";
}
Session.set("serverData", null);
Session.set("confirm", null);
@ -420,16 +448,6 @@ Template.profile.events({
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);
},
'click #creSubmit' () {
var data = getCreateFormData();
if (data === null) return;
@ -438,44 +456,82 @@ Template.profile.events({
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();
},
'click .owned' (event) {
if (event.target.id === "label") return;
if (event.target.id === "label") return;
if (!event.target.className.includes("owned")) {
var attribute = event.target.parentNode.getAttribute("classid");
} else {
var attribute = event.target.getAttribute("classid");
}
var usertype = ["moderators","banned","blockEdit"];
var array = classes.findOne({_id:attribute});
if(array.code === "") array.code = "None";
for(var i = 0; i < usertype.length; i++) {
var users = array[usertype[i]];
for(var j = 0; j < users.length; j++) {
var detailusers = {};
var user = Meteor.users.findOne({_id:users[j]});
detailusers._id = user._id;
detailusers.email = user.name + "hi";
detailusers.name = user.name;
array[usertype[i]] = detailusers;
}
}
document.getElementById("createdClasses").style.marginRight = "0";
Session.set("selectedClass",array);
Session.set("selectClassId",attribute);
document.getElementById("createdClasses").style.marginRight = "0";
},
'click .userAdder .fa-plus' (event) {
if(Session.get("adding")) return;
var input = document.createElement("input");
input.className = "userAddInput";
event.target.parentNode.appendChild(input);
Session.set("adding", true);
var input = event.target.parentNode.childNodes[3];
input.placeholder = "1234@abc.xyz";
input.className.replace(" formInvalid","");
var value = input.value;
input.value = "";
if(checkUser(value)) {
input.className += " formInvalid";
input.placeholder = "Not a valid user";
return;
}
var user = Meteor.users.findOne({"services.google.email":input.value});
Session.set("serverData", [
user._id,
document.getElementById("createdClasses").getAttribute("classid"),
event.target.parentNode.childNodes[1].childNodes[0].nodeValue.replace(":","").toLowerCase()
]);
sendData("trackUserInClass");
},
'click .userBox .fa-times' (event) {
var box = event.target.parentNode;
Session.set("serverData", [
box.getAttribute("userid"),
document.getElementById("createdClasses").getAttribute("classid"),
box.parentNode.parentNode.childNodes[1].childNodes[1].childNodes[0].nodeValue.replace(":","").toLowerCase()
])
sendData("untrackUserInClass");
},
'click #copy' () {
if(document.getElementById("code").value === "None") return;
document.getElementById("code").select();
document.execCommand("copy");
},
'click #deleteClass' () {
Session.set("serverData",document.getElementById("createdClasses").getAttribute("classid"));
Session.set("confirm", "deleteClass");
Session.set("confirmText", "Delete this class?");
openDivFade(document.getElementsByClassName("overlay")[0]);
},
'click #changeAdmin span' (event) {
if(Session.get("changeAdmin")) return;
Session.set("changeAdmin",true);
var input = document.createElement("input");
input.placeholder = "1234@abc.xyz";
var i = document.createElement("i");
i.className = "fa fa-exchange";
i.setAttribute("aria-hidden","true");
event.target.parentNode.appendChild(input);
event.target.parentNode.appendChild(i);
},
'click .fa-exchange' (event) {
var input = event.target.parentNode.childNodes[3];
input.placeholder = "1234@abc.xyz";
input.className.replace(" formInvalid","");
var value = input.value;
input.value = "";
if(checkUser(value)) {
input.className += " formInvalid";
input.placeholder = "Not a valid user";
return;
}
}
});
@ -542,7 +598,7 @@ function getCreateFormData() {
var stop;
var form = document.getElementsByClassName("creInput");
for (var i = 0; i < form.length; i++) {
if(i === 1 || i === 2) continue;
if(i === 1 || i === 2) continue;
if (form[i].value === "") {
form[i].focus();
form[i].placeholder = "Missing field";
@ -575,3 +631,12 @@ function getCreateFormData() {
code: ""
};
}
function checkUser(email) {
var user = Meteor.users.findOne({"services.google.email":email});
if(user === undefined) {
return true;
} else {
return false;
}
}

View File

@ -20,7 +20,7 @@ classes.schema = new SimpleSchema({
privacy: {type: Boolean},
category: {type: String},
moderators: {type: [String], optional: true},
blockEdit: {type: [String], optional: true},
banned: {type: [String], optional: true},
subscribers: {type: [String], optional: true}
});

View File

@ -16,7 +16,7 @@ superadmins = [
];
worktype = ["test", "quiz", "project", "normal"];
var possiblelist = ["moderators","blockEdit"];
var possiblelist = ["moderators","banned"];
for (var i = 0; i < superadmins.length; i++) {
var superadmin = superadmins[i];
@ -57,7 +57,7 @@ Meteor.publish('classes', function() {
privacy: 1,
category: 1,
moderators: 1,
blockEdit: 1,
banned: 1,
subscribers: 1
}
});
@ -148,7 +148,7 @@ Meteor.methods({
input.category = "other";
}
input.moderators = [];
input.blockEdit = [];
input.banned = [];
classes.insert(input);
Meteor.call('joinClass', classes.findOne(input)._id, input.code, function(error, result) {});
return 1;
@ -162,7 +162,7 @@ Meteor.methods({
if (Roles.userIsInRole(Meteor.userId(), ['superadmin', 'admin'])) {
classes.update({_id: input[1]}, {$set: {admin: input[0]}});
} else if (found && foundclass && foundclass.admin == Meteor.userId() &&
foundclass.blockEdit.indexOf(input[0]) != -1) {
foundclass.banned.indexOf(input[0]) != -1) {
classes.update({_id: input[1]}, {$set: {admin: input[0]}});
} else {
throw "Unauthorized";
@ -229,7 +229,7 @@ Meteor.methods({
if (Meteor.user() !== null &&
found !== null &&
Meteor.user().profile.classes.indexOf(input.class) !== -1 &&
found.blockEdit.indexOf(Meteor.userId()) === -1 &&
found.banned.indexOf(Meteor.userId()) === -1 &&
input.dueDate instanceof Date && input.dueDate.getTime() >= ref &&
worktype.indexOf(input.type) != -1 &&
input.name.length <= 50 && input.description.length <= 150) {
@ -305,7 +305,7 @@ Meteor.methods({
var user = Meteor.userId();
if (typeof comment === "string" && comment.length <= 200 &&
currentclass.subscribers.indexOf(Meteor.userId()) != -1 &&
currentclass.blockEdit.indexOf(Meteor.userId()) === -1) {
currentclass.banned.indexOf(Meteor.userId()) === -1) {
var comments = workobject.comments.concat(comment);
work.update({
_id: input[1]