teacher and banned

This commit is contained in:
Yaman Qalieh 2016-11-18 20:51:04 -05:00
commit ca94e92267
11 changed files with 631 additions and 158 deletions

View File

@ -304,7 +304,7 @@ body {
.mode h4 {
width: 65%;
padding-left: 9%;
padding-left: 5%;
line-height: 6vh;
display: table-cell;
vertical-align: middle;
@ -363,6 +363,7 @@ body {
font-size: 1.7vh;
padding: 5%;
display: table-cell;
pointer-events: none;
}
.sideClassName {
@ -684,9 +685,9 @@ textarea.clickModify {
}
.optionText {
font-size: 120%;
font-size: 120% !important;
min-width: 10%;
padding: 4% 7% 4% 7%;
padding: 4% 7% 4% 7% !important;
margin: 0;
box-shadow: inset 0 0 0 99999px rgba(0,0,0,0.05);
@ -798,23 +799,16 @@ textarea.clickModify {
background-color: rgba(0,0,0,0.15);
}
.overlay {
.overlay, #confirmOverlay {
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
background-color: rgba(0,0,0,0.7);
display: none;
position: absolute;
top: 0;
left: 0;
z-index: 51;
opacity: 0;
-webkit-transition: opacity 0.4s ease;
-moz-transition: opacity 0.4s ease;
-ms-transition: opacity 0.4s ease;
transition: opacity 0.4s ease;
}
.overlayCont {
@ -824,11 +818,12 @@ textarea.clickModify {
margin: auto;
margin-top: 25vh;
padding: 1%;
box-shadow: 2px 2px 5px 3px #666;
-moz-border-radius: 30px;
-webkit-border-radius: 30px;
border-radius: 30px;
box-shadow: 2px 2px 5px 1px #666;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
text-align: center;
}
@ -1230,13 +1225,6 @@ textarea.clickModify {
top: 0.5vh;
right: 1.5vw;
z-index: 20;
opacity: 0;
-webkit-transition: opacity 0.4s ease;
-moz-transition: opacity 0.4s ease;
-ms-transition: opacity 0.4s ease;
transition: opacity 0.4s ease;
}
#userDropdownAvatar {

View File

@ -60,6 +60,10 @@
{{#if currSettingMode 'addClass'}}
{{> joinClass}}
{{/if}}
{{#if currSettingMode 'createClass'}}
{{> createClass}}
{{/if}}
</div>
</div>
@ -134,6 +138,16 @@
</div>
</div>
<div id="confirmOverlay">
<div class="overlayCont" style="background-color:{{divColor 'mainColor'}}">
<p>{{confirmText}}</p>
<div id="faCont">
<i class="fa fa-check-circle-o" aria-hidden="true"></i>
<i class="fa fa-times-circle-o" aria-hidden="true"></i>
</div>
</div>
</div>
<div id="userDropdown" style="background-color:{{divColor 'userDropdownColor'}}">
<div id="userTab" style="border-bottom: 3vh solid {{divColor 'userDropdownColor'}}"></div>
<div id="userDropdownAvatar" style="background-color:{{divColor 'userDropdownColor'}}">
@ -245,7 +259,7 @@
</template>
<template name="option">
<p class="optionText" style="background-color:{{divColor 'mainColor'}}">{{alias}}</p>
<p class="optionText" style="background-color:{{divColor 'mainColor'}};" onmouseover="$(this).css('box-shadow','inset 0 0 0 99999px rgba(0,0,0,0.2)');" onmouseleave="$(this).css('box-shadow','');">{{alias}}</p>
</template>
<template name="workDisplay">

View File

@ -32,6 +32,7 @@ Session.set("typeFilterHover", null); // Stores current hovered type filter.
Session.set("classDispHover", null); // Stores current hovered class filter.
Session.set("refetchEvents", null); // Stores whether to get calendar events again.
Session.set("restrictText", {}); // Stores text for comment character restriction.
Session.set("confirmText", ""); // Stores text for confirmations.
// On render actions
@ -41,7 +42,7 @@ Template.login.rendered = function() {
Template.main.created = function() {
Session.set("mode", Session.get("user").preferences.mode);
Session.set("classInfo", Session.get("user").classes[0]);
Session.set("classInfo", null);
}
Template.main.rendered = function() {
@ -63,17 +64,6 @@ Template.profile.rendered = function() {
document.getElementsByTagName("body")[0].style.color = Session.get("user").preferences.theme.textColor;
};
Template.selectOptionMenu.rendered = function() {
$(".optionText").hover(
function() {
$(this).addClass("selectedOption");
},
function() {
$(this).removeClass("selectedOption");
}
);
}
// Global Helpers
Template.registerHelper('adminPage', () => {
@ -124,12 +114,14 @@ Template.registerHelper('myClasses', () => { // Gets all classes and respective
_id: courses[i]
});
found.subscribers = found.subscribers.length;
found.teachershort = found.teacher.split(" ").slice(1).reduce(function(a,b) { return a+ " " + b;});
found.mine = true;
if (found.admin === Meteor.userId()) { // If user owns this class.
found.box = " owned";
found.mine = false;
}
}
found.selected = ((classDisp.indexOf(courses[i]) !== -1)) ? Session.get("user").preferences.theme.modeHighlight : "rgba(0,0,0,0)"; // Filter selected.
array.push(found);
@ -265,6 +257,10 @@ Template.registerHelper('work', (value) => {// Returns the specified work value.
}
});
Template.registerHelper('confirmText', () => {
return Session.get("confirmText");
})
// Main template helpers and events
Template.main.helpers({
@ -368,7 +364,7 @@ Template.main.helpers({
eventClick: function(event, jsEvent, view) { // On-click for work.
Session.set("newWork", false);
Session.set("currentWork", work.findOne({_id: event.id}));
openDivFade(document.getElementsByClassName("overlay")[0]);
$(".overlay").fadeIn(250);
},
eventMouseover: function(event, jsEvent, view) {
this.style.boxShadow = "inset 0 0 0 99999px rgba(255,255,255,0.2)";
@ -468,13 +464,13 @@ Template.main.events({
}
if (e === "overlay") { // Overlay closing.
closeDivFade(document.getElementsByClassName("overlay")[0]);
$(".overlay").fadeOut(250);
if (!Session.get("newWork")) {
document.getElementById("workComment").value = "";
}
}
if (!document.getElementById("userDropdown").contains(event.target)) closeDivFade(document.getElementById("userDropdown"));
if (!document.getElementById("userDropdown").contains(event.target)) $("#userDropdown").fadeOut(250);
},
// MAIN MENU BUTTONS
'click .fa-bars' (event) { // Click menu button.
@ -495,13 +491,28 @@ Template.main.events({
}
Session.set("newWork", true);
Session.set("currentWork",{class: attr, dueDate: (new Date((new Date()).valueOf() + 1000*3600*24))});
openDivFade(document.getElementsByClassName("overlay")[0]);
$(".overlay").fadeIn(250);
},
'click .fa-check-circle-o' () { // Confirmation Button
sendData(confirm);
$("#confirmOverlay").fadeOut(250);
if(confirm === "changeAdmin") {
$("#changeAdminWrapper").fadeOut(250);
} else if(confirm === "deleteClass") {
Session.set("classInfo", null);
}
serverData = null;
confirm = null;
},
'click .fa-times-circle-o' () { // Deny Button
$("#confirmOverlay").fadeOut(250);
serverData = null;
confirm = null;
},
'click #dropdown' (event) {
if (document.getElementById("userDropdown").style.display === "block") return;
setTimeout(function() {
openDivFade(document.getElementById("userDropdown"));
}, 100);
$("#userDropdown").fadeIn(250);
},
'click .workCard' (event) { // Display work information on work card click.
var workid = event.target.getAttribute("workid");
@ -523,7 +534,7 @@ Template.main.events({
var inputs = $('#editWork .clickModify').css("cursor", "default");
}
}
openDivFade(document.getElementsByClassName("overlay")[0]);
$(".overlay").fadeIn(250);
},
'click #requestSubmit' () {
var area = document.getElementById("requestArea");
@ -662,6 +673,8 @@ Template.main.events({
if(Session.get("newWork")) return;
if(checkMissing()) return;
sendData("editWork");
} else if(modifyingInput.slice(0,3) === "cre") {
document.getElementById(modifyingInput).value = option;
} else {
var newSetting = Session.get("user");
newSetting.preferences[modifyingInput] = (function() {
@ -714,12 +727,12 @@ Template.main.events({
if(checkMissing()) return;
sendData("createWork");
Session.set("newWork",false);
closeDivFade(document.getElementsByClassName("overlay")[0]);
$(".overlay").fadeOut(250);
},
'click #workDelete' () {
serverData = Session.get("currentWork")._id;
sendData("deleteWork");
closeDivFade(document.getElementsByClassName("overlay")[0]);
$(".overlay").fadeOut(250);
},
'click #markDone' () { // Click done button.
serverData = [Session.get("currentWork")._id, "done"];
@ -756,21 +769,6 @@ function toggleOptionMenu(toggle, menu) {
}
}
function openDivFade(div) {
div.style.display = "block";
div.style.opacity = "0";
setTimeout(function() {
div.style.opacity = "1";
}, 100);
}
function closeDivFade(div) {
div.style.opacity = "0";
setTimeout(function() {
div.style.display = "none";
}, 100);
}
sendData = function(funcName) { // Call Meteor function, and do actions after function is completed depending on function.
if(funcName === "editWork" || funcName === "createWork") {
for(var key in serverData) {
@ -780,6 +778,7 @@ sendData = function(funcName) { // Call Meteor function, and do actions after fu
Meteor.call(funcName, serverData, function(error, result) {
serverData = null;
currWork = Session.get("currentWork");
if(currWork !== null && currWork._id !== undefined) {
Session.set("currentWork", work.findOne({
_id: currWork._id
@ -798,6 +797,13 @@ sendData = function(funcName) { // Call Meteor function, and do actions after fu
position: 'bottom-right',
timeout: 2500
});
if(funcName === "createClass") {
var inputs = document.getElementsByClassName("creInput");
for(var i = 0; i < inputs.length; i++) {
inputs[i].value = "";
}
toggleToMode("manageClass");
}
}
document.getElementsByTagName("body")[0].style.color = Session.get("user").preferences.theme.textColor;
});
@ -981,4 +987,4 @@ startDragula = function() {
}
Meteor.call("reorderClasses", final);
});
}
};

View File

@ -155,6 +155,23 @@
background-color: rgba(0,0,0,0.3);
}
.classBox .fa {
text-align: center;
-webkit-transition: color 0.4s ease;
-moz-transition: color 0.4s ease;
-ms-transition: color 0.4s ease;
transition: color 0.4s ease;
}
.classBox .fa-times:hover {
color: #FF1A1A;
}
.classBox .fa-plus:hover {
color: #85E085;
}
.owned {
box-shadow: inset 0 0 0 99999px rgba(255,255,255,0.3);
-webkit-transition: background-color 0.4s ease;
@ -175,16 +192,23 @@
pointer-events: none;
}
.classBox .fa-times {
display: table-cell;
width: 5%;
.classBox .fa {
font-size: 2.5vh !important;
padding: 0 !important;
display: table-cell !important;
width: 5% !important;
}
.name {
width: 40%;
}
.teacher {
width: 25%;
}
.hour.classText, .subscribers.classText {
width: 15%;
text-align: center;
}
@ -298,7 +322,7 @@
display: inline-block;
}
#infoClassCont div .fa-files-o{
#infoClassCont div .fa-files-o, #infoClassCont div .fa-pencil-square-o {
font-size: 2vh;
position: absolute;
@ -335,6 +359,59 @@
position: absolute;
}
#changeAdminWrapper {
margin-top: 1%;
display: none;
}
#changeAdminWrapper span {
font-size: 2vh;
display: inline-block !important;
}
#changeAdmin {
width: 40%;
margin: 0 1% 0 1%;
font-size: 2vh;
padding: 1%;
outline: none;
}
#adminSubmit {
padding: 2%;
background-color: rgba(0,0,0,0.1);
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;
}
#adminSubmit:hover {
background-color: rgba(0,0,0,0.2);
}
#deleteClass {
cursor: pointer;
float: right;
}
#deleteClass:hover {
color: #FF1A1A;
}
#deleteClass .fa {
margin-top: 0;
-webkit-transition: color 0.4s ease;
-moz-transition: color 0.4s ease;
-ms-transition: color 0.4s ease;
transition: color 0.4s ease;
}
.userAdder {
width: 100%;
margin-bottom: 3%;
@ -400,3 +477,130 @@
.userDisp .fa:hover {
color: #FF1A1A;
}
#joinTop {
margin: 2% 0 0 5%;
}
#joinTop .-autocomplete-container {
display: none;
}
#joinTop .fa {
font-size: 2.5vh;
}
#classSearch, #privateCode {
font-size: 2vh;
padding: 1%;
outline: none;
}
#private {
font-size: 2.4vh;
padding: 1.5%;
margin: 0 2% 0 2%;
background-color: rgba(0,0,0,0.1);
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;
}
#private:hover {
background-color: rgba(0,0,0,0.2);
}
#privateCode {
width: 25%;
display: none;
-webkit-animation: expand .7s ease 1;
animation: expand .7s ease 1;
}
@-webkit-keyframes expand {
0% { width: 0%; }
100% { width: 25%; }
}
@keyframes expand {
0% { width: 0%; }
100% { width: 25%; }
}
#createWrapper {
padding: 3%;
}
#creRules p {
padding: 0;
}
.formDiv {
margin-left: 25%;
padding: 1% 2% 1% 2%;
width: 30%;
background-color: rgba(255,255,255,0.1);
position: relative;
display: table;
}
.formDiv:first-child {
padding-top: 2%;
}
.formDiv:last-child {
padding-bottom: 2%;
}
.formDiv input {
font-size: 2vh;
width: calc(98% - 8px) !important;
padding: 1%;
margin: 1%;
}
.formDiv .optionHolder {
width: 89%;
}
.formDiv .-autocomplete-container {
margin: 1% 0 0 0.5%;
}
.profTitle {
padding-left: 0 !important;
}
#formContainer {
margin: 2%;
}
#creSubmit {
font-weight: 200;
width: 30%;
padding: 2%;
margin-top: 2%;
margin-left: 25%;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
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.1);
}

View File

@ -141,7 +141,9 @@
</template>
<template name="sidebarCreatePlate">
<h3 class="sectionTitle downOffset">Classes</h3>
<div class="sectionTitle downOffset">
<h3>Requests</h3>
</div>
<p class="sidebarDesc">Pick a class to create work for.</p>
{{#each myClasses}}
{{> sidebarClasses}}
@ -187,11 +189,15 @@
<span style="border-bottom: 3px solid {{classInfoMode 'users'}}">Users</span>
</div>
<div id="infoClassCont">
{{#if classSelected}}
{{#if classInfoMode 'general' 'a'}}
{{> classInfoGeneral}}
{{else}}
{{> classInfoUsers}}
{{/if}}
{{else}}
<p>Click on a class to see its info.</p>
{{/if}}
</div>
</div>
</div>
@ -207,13 +213,14 @@
<p>Join Classes</p>
</div>
<div class="circleIcon">
<i class="fa fa-tasks" aria-hidden="true"></i>
<i class="fa fa-graduation-cap" aria-hidden="true"></i>
</div>
</div>
<div id="joinTop">
<i class="fa fa-search" aria-hidden="true"></i>
{{> inputAutocomplete id="classSearch" settings=classSettings placeholder="Search..."}}
<!-- <h4 id="private">Join Private Class</h4> -->
<h4 id="private">Join Private Class</h4>
<input id="privateCode" placeholder="Enter code here...">
</div>
<div id="settingClassWrapper">
<div id="label" class="classBox">
@ -254,11 +261,69 @@
<span style="border-bottom: 3px solid {{classInfoMode 'users'}}">Users</span>
</div>
<div id="infoClassCont">
{{#if classSelected}}
{{#if classInfoMode 'general' 'a'}}
{{> classInfoGeneral}}
{{else}}
{{> classInfoUsers}}
{{/if}}
{{else}}
<p>Click on a class to see its info!</p>
{{/if}}
</div>
</div>
</div>
</div>
</template>
<template name="createClass">
<div id="backgroundOverlay" style="background-color:{{divColor 'secondaryColor'}}">
<div id="colLeft">
<div class="settingHeader">
<div>
<h2>Create Classes</h2>
</div>
<div class="circleIcon">
<i class="fa fa-book" aria-hidden="true"></i>
</div>
</div>
<div id="createWrapper">
<div id="creRules">
<p>Submit a request for a class to be approved by an administrator.<br>
You can have up to 8 unapproved classes at once.</p>
</div>
<div id="formContainer">
<div class="formDiv">
{{> inputAutocomplete settings=schoolComplete class="form-control creInput" type="text" form="school" placeholder="**School | Ex: International Academy" }}
</div>
<div class="formDiv">
<input class="creInput" type="text" form="hour" placeholder="Hour">
</div>
<div class="formDiv">
{{> inputAutocomplete settings=teacherComplete class="form-control creInput" type="text" form="teacher" placeholder="Teacher | Ex: Marc DeZwaan" }}
</div>
<div class="formDiv">
<input class="creInput" type="text" form="name" placeholder="**Class Name">
</div>
<div class="formDiv">
<p class="profTitle">**Privacy:</p>
<input id="creprivacy" style="color:{{divColor 'textColor'}}" class="creInput clickModify dropdown" type="text" form="privacy" placeholder="Click here to edit..." readonly>
<div class="optionHolder">
{{#each selectOptions 'privacy'}}
{{> option}}
{{/each}}
</div>
</div>
<div class="formDiv">
<p class="profTitle">**Category:</p>
<input id="crecategory" style="color:{{divColor 'textColor'}}" class="creInput clickModify dropdown" type="text" form="category" placeholder="Click here to edit..." readonly>
<div class="optionHolder">
{{#each selectOptions 'category'}}
{{> option}}
{{/each}}
</div>
</div>
<h3 id="creSubmit" style="border:1px solid {{divColor 'textColor'}}">Submit Request</h3>
</div>
</div>
</div>
@ -268,14 +333,18 @@
<template name="classDisplay">
<div class="classBox{{box}}" classid="{{_id}}" style="border:1px solid {{divColor 'textColor'}}">
<span class="name classText">{{name}}</span>
<span class="teacher classText">{{teacher}}</span>
<span class="teacher classText">{{teachershort}}</span>
<span class="hour classText">{{hour}}</span>
<span class="subscribers classText">{{subscribers}}</span>
{{#if mine}}
<i class="fa fa-times" aria-hidden="true"></i>
{{else}}
{{#if join}}
<i class="fa fa-plus" aria-hidden="true"></i>
{{else}}
<i class="fa fa-times" aria-hidden="true" style="visibility:hidden"></i>
{{/if}}
{{/if}}
</div>
</template>
@ -286,11 +355,25 @@
<i class="fa fa-lock" aria-hidden="true"></i>
</div>
<span>Private</span>
{{#unless classInfo 'personal'}}
{{#if classInfo 'mine'}}
<div id="deleteClass" class="circleIcon">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
{{/if}}
{{/unless}}
{{else}}
<div class="circleIcon">
<i class="fa fa-unlock-alt" aria-hidden="true"></i>
</div>
<span>Public</span>
{{#unless classInfo 'personal'}}
{{#if classInfo 'mine'}}
<div id="deleteClass" class="circleIcon">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
{{/if}}
{{/unless}}
{{/if}}
</div>
<div class="infoCard" style="border:1px solid {{divColor 'textColor'}}">
@ -312,8 +395,19 @@
<div class="infoCard" style="border:1px solid {{divColor 'textColor'}}">
<h4 style="border-bottom:1px solid {{divColor 'textColor'}}">Owner</h4>
{{> classInfoUserDisp classInfo 'admin'}}
{{#unless classInfo 'personal'}}
{{#if classInfo 'mine'}}
<i class="fa fa-pencil-square-o" aria-hidden="true" onmouseover="$(this).css('color','{{divColor 'iconHighlight'}}')" onmouseleave="$(this).css('color','{{divColor 'textColor'}}')"></i>
{{/if}}
{{/unless}}
</div>
{{> classInfoCode classInfo 'code'}}
<div id="changeAdminWrapper">
<span>Change Admin: </span>
<input id="changeAdmin">
<div id="adminSubmit">Change</div>
</div>
</template>
<template name="classInfoUsers">
@ -391,3 +485,10 @@
{{/if}}
</template>
<template name="schoolList">
{{name}}
</template>
<template name="teacherList">
{{name}}
</template>

View File

@ -1,13 +1,17 @@
/* jshint esversion: 6 */
Session.set("settingMode", "manageClass");
Session.set("classInfoMode", "general");
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.
var filterOpen = [false, true, true, true, true];
var sidebarMode = [null,null];
Template.sidebarMenuPlate.rendered = function(){$(".menuWrapper").slideDown(300);}
Template.sidebarOptionPlate.rendered = function(){$(".menuWrapper").slideDown(300);}
Template.sidebarRequestPlate.rendered = function(){$(".menuWrapper").slideDown(300);}
Template.sidebarCreatePlate.rendered = function(){$(".menuWrapper").slideDown(300);}
Template.sidebarMenuPlate.rendered = function(){$(".menuWrapper").slideDown(300);};
Template.sidebarOptionPlate.rendered = function(){$(".menuWrapper").slideDown(300);};
Template.sidebarRequestPlate.rendered = function(){$(".menuWrapper").slideDown(300);};
Template.sidebarCreatePlate.rendered = function(){$(".menuWrapper").slideDown(300);};
Template.sidebarMenuPlate.helpers({
modeStatus(status) { // Color status of display modes.
@ -27,13 +31,13 @@ Template.sidebarMenuPlate.helpers({
},
filterOn() {
return Session.get("classDisp").length !== 0 || Session.get("typeFilter").length !== 0;
},
}
});
Template.sidebarMenuPlate.events({
'click .classes' () { // Click classes mode button.
if (Session.equals("mode", "classes")) return;
toggleToMode("classes")
toggleToMode("classes");
setTimeout(startDragula, 500);
toggleToSidebar(false);
},
@ -69,16 +73,7 @@ Template.sidebarMenuPlate.events({
},
// CLASS FILTERS
'click .sideClass' (event) { // Click class list in sidebar.
var div = event.target;
while (div.getAttribute("classid") === null) div = div.parentNode;
var classid = div.getAttribute("classid");
if (Session.equals("sidebarMode","create")) { // If creating work from calendar.
var newSetting = Session.get("currentWork");
newSetting.class = classid;
Session.set("currentWork", newSetting);
openDivFade(document.getElementsByClassName("overlay")[0]);
} else { // Normal clicking turns on filter.
var classid = event.target.getAttribute("classid");
var array = Session.get("classDisp");
if (array.indexOf(classid) !== -1) {
array.splice(array.indexOf(classid), 1);
@ -86,7 +81,6 @@ Template.sidebarMenuPlate.events({
array.push(classid);
}
Session.set("classDisp", array);
}
},
'click .sideFilter' (event) {
var div = event.target;
@ -180,6 +174,16 @@ Template.sidebarOptionPlate.events({
}
});
Template.sidebarCreatePlate.events({
'click .sideClass' (event) { // Click class list in sidebar.
var classid = event.target.getAttribute("classid");
var newSetting = Session.get("currentWork");
newSetting.class = classid;
Session.set("currentWork", newSetting);
$(".overlay").fadeIn(250);
}
});
Template.registerHelper("classInfo", (info) => {
var thisClass = classes.findOne({_id:Session.get("classInfo")});
var isYou = Session.equals("classInfo", Meteor.userId());
@ -197,7 +201,8 @@ Template.registerHelper("classInfo", (info) => {
case "admin":
return Meteor.users.findOne({_id: (isYou) ? Meteor.userId() : thisClass.admin});
case "code":
return (isYou || !thisClass.code) ? {exists: false} : {exists: true, code: thisClass.code};
if(isYou) return {exists: false};
return (isYou || Meteor.userId() !== this.admin) ? {exists: false} : {exists: true, code: Meteor.call('getCode', thisClass._id)};
case "mine":
return (isYou) ? true : Meteor.userId() === thisClass.admin;
case "moderators":
@ -233,7 +238,11 @@ Template.registerHelper("classInfo", (info) => {
Template.registerHelper("classInfoMode", (mode, check) => {
if(typeof check === "string") return Session.equals("classInfoMode",mode);
return (Session.equals("classInfoMode", mode)) ? Session.get("user").preferences.theme.modeHighlight + ";background-color:rgba(0,0,0,0.1);" : "rgba(0,0,0,0)";
})
});
Template.registerHelper("classSelected", () => {
return !Session.equals("classInfo", null);
});
Template.manageClass.events({
'click .classBox' (event) {
@ -248,6 +257,44 @@ Template.manageClass.events({
'click #classInfoModeWrapper span:last-child' () {
if(Session.equals("classInfoMode","users")) return;
toggleToClassInfoMode("users");
},
'click .infoCard .fa-pencil-square-o' () {
$("#changeAdminWrapper").fadeIn(250);
},
'click #adminSubmit' () {
var input = document.getElementById("changeAdmin");
var value = input.value;
var classid = Session.get("classInfo");
var user = Meteor.users.findOne({
"services.google.email": value
});
if(!user) {
sAlert.error("Invalid email!", {
effect: 'stackslide',
position: 'top',
timeout: 3000
});
return;
}
serverData = [
user._id,
classid
];
Session.set("confirmText", "Change ownership?");
confirm = "changeAdmin";
$("#confirmOverlay").fadeIn(250);
},
'click #deleteClass' () {
serverData = Session.get("classInfo");
confirm = "deleteClass";
Session.set("confirmText", "Delete this class?");
$("#confirmOverlay").fadeIn(250);
},
'click .classBox .fa-times' (event) {
serverData = event.target.parentNode.getAttribute("classid");
confirm = "leaveClass";
Session.set("confirmText", "Leave this class?");
$("#confirmOverlay").fadeIn(250);
}
});
@ -264,7 +311,9 @@ Template.joinClass.helpers({
).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);
@ -308,7 +357,7 @@ Template.joinClass.helpers({
},
notfound() { // Returns if autocomplete has no results.
return Session.get("notfound");
},
}
});
Template.joinClass.events({
@ -352,9 +401,110 @@ Template.joinClass.events({
});
}
Session.set("autocompleteDivs", divs.sort(function(a, b) {
return b.subscribers - a.subscribers
return b.subscribers - a.subscribers;
}));
} catch (err) {}
},
'click .classBox .fa-plus' (event) {
serverData = [event.target.parentNode.getAttribute("classid"), ""];
confirm = "joinClass";
Session.set("confirmText", "Join this class?");
$("#confirmOverlay").fadeIn(250);
},
'click #private' () {
$("#privateCode").css('display','inline-block');
var input = document.getElementById("privateCode");
input.focus();
if(input.value === "") return;
Meteor.call("joinPrivateClass", input.value, function(error, result) {
if(result) {
sAlert.success("Joined!", {
effect: 'genie',
position: 'bottom-right',
timeout: 1500
});
} else {
sAlert.error("Invalid code!", {
effect: 'stackslide',
position: 'top',
timeout: 1500
});
}
});
}
});
Template.createClass.helpers({
schoolComplete() { // Returns autocomplete array for schools.
return {
position: "bottom",
limit: 6,
rules: [{
token: '',
collection: schools,
field: 'name',
matchAll: true,
template: Template.schoolList
}]
};
},
teacherComplete() { // Returns autocomplete array for teachers.
return {
position: "bottom",
limit: 1,
rules: [{
token: '',
collection: teachers,
field: 'name',
template: Template.teacherList
}]
};
}
});
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;}), {
effect: 'stackslide',
position: 'top',
timeout: 3000
});
return;
}
values.privacy = (values.privacy === "Public") ? false : true;
values.status = false;
values.category.toLowerCase();
values.code = "";
serverData = values;
if(!teachers.findOne({name: values.teacher})) {
Meteor.call("createTeacher", values.teacher, values.school, function(error,result) {
if (error !== undefined) {
sAlert.error(error.message, {
effect: 'stackslide',
position: 'top'
});
} else {
sendData("createClass");
}
});
} else {
sendData("createClass");
}
}
});
@ -385,7 +535,7 @@ Template.classInfoUsers.events({
input.value = "";
},
'click .userDisp .fa' (event) {
var outerInput = event.target.parentNode.parentNode.parentNode.parentNode.childNodes[1]
var outerInput = event.target.parentNode.parentNode.parentNode.parentNode.childNodes[1];
var type = outerInput.childNodes[6].getAttribute("user");
var userid = event.target.parentNode.parentNode.getAttribute("userid");
if(!Meteor.users.findOne({_id: userid})) {
@ -421,10 +571,11 @@ Template.classInfoCode.events({
toggleToMode = function(mode) {
$("#mainBody").fadeOut(250, function() {
(Session.equals("sidebarMode", "option")) ? Session.set("settingMode", mode) : Session.set("mode",mode);
(Session.equals("sidebarMode", "option")) ? Session.set("settingMode", mode) : Session.set("mode", mode);
Session.set("classInfo", null);
$("#mainBody").fadeIn(250);
});
}
};
toggleToSidebar = function(sidebar) {
try {
@ -442,19 +593,20 @@ toggleToSidebar = function(sidebar) {
Session.set("sidebarMode", sidebar);
});
}
}
};
toggleToClassInfo = function(classId) {
$("#changeAdminWrapper").fadeOut(250);
$("#infoClassCont").fadeOut(250, function() {
Session.set("classInfo", classId);
Session.set("classInfoMode", "general");
$(this).fadeIn(250);
});
}
};
toggleToClassInfoMode = function(mode) {
$("#infoClassCont").fadeOut(250, function() {
Session.set("classInfoMode", mode);
$(this).fadeIn(250);
});
}
};

View File

@ -1,14 +1,21 @@
schools = new Mongo.Collection("Schools");
teachers = new Mongo.Collection("Teachers");
classes = new Mongo.Collection("Classes");
work = new Mongo.Collection("Work");
requests = new Mongo.Collection("Requests");
admins = Meteor.users;
teachers = new Mongo.Collection("Teachers");
schools.schema = new SimpleSchema({
name: {type: String}
});
teachers.schema = new SimpleSchema({
name: {type: String},
school: {type: String},
creator: {type: String, optional: true}
});
classes.schema = new SimpleSchema({
school: {type: String},
//icon: {type: String},
@ -63,6 +70,7 @@ teachers.schema = new SimpleSchema({
});
schools.attachSchema(schools.schema);
teachers.attachSchema(teachers.schema);
classes.attachSchema(classes.schema);
work.attachSchema(work.schema);
requests.attachSchema(requests.schema);

View File

@ -10,6 +10,16 @@ AdminConfig = {
color: 'red',
label: 'Schools'
},
teachers: {
icon: 'book',
tableColumns: [
{ label: 'ID', name: '_id' },
{ label: 'Name', name: 'name' },
{ label: 'School', name: 'school'}
],
color: 'orange',
label: 'Teachers'
},
classes: {
icon: 'graduation-cap',
tableColumns: [

View File

@ -1,9 +1,9 @@
themeColors = {
"lux": {
"background": "White.jpg",
"mainColor": "#EEE",
"secondaryColor": "#FEFEFE",
"sidebarColor": "#799cb8",
"mainColor": "#DBDBDB",
"secondaryColor": "#E8E8E8",
"sidebarColor": "#799CB8",
"userDropdownColor": "#E6E6E6",
"iconHighlight": "#FFF",
"modeHighlight": "#D34949",
@ -28,8 +28,8 @@ themeColors = {
"sidebarColor": "#327C5A",
"userDropdownColor": "#CC3333",
"iconHighlight": "#327C5A",
"modeHighlight": "#C9fE62",
"classCardColor":"#302c36",
"modeHighlight": "#C9FE62",
"classCardColor":"#302C36",
"textColor": "#FCF0F0"
},
"aequor": {
@ -50,7 +50,7 @@ themeColors = {
"sidebarColor": "#6D9957",
"userDropdownColor": "#89BB52",
"iconHighlight": "#91EE61",
"modeHighlight": "#B9f643",
"modeHighlight": "#B9F643",
"classCardColor":"#C18311",
"textColor": "#FCF0F0"
},
@ -122,3 +122,4 @@ options = {
}
serverData = null;
confirm = null;

View File

@ -6,6 +6,7 @@ Router.route('/', {
return [
Meteor.subscribe('classes', this.params._id),
Meteor.subscribe('schools', this.params._id),
Meteor.subscribe('teachers', this.params._id),
Meteor.subscribe('work', this.params._id),
Meteor.subscribe('requests', this.params._id),
Meteor.subscribe('users', this.params._id)
@ -45,6 +46,7 @@ Router.route('/profile', {
return [
Meteor.subscribe('classes', this.params._id),
Meteor.subscribe('schools', this.params._id),
Meteor.subscribe('teachers', this.params._id),
Meteor.subscribe('work', this.params._id),
Meteor.subscribe('requests', this.params._id),
Meteor.subscribe('users', this.params._id)
@ -57,30 +59,6 @@ Router.route('/profile', {
}
});
Router.route('/user/:email', {
data: function() {
return Meteor.users.findOne({'services.google.email': this.params.email});
},
waitOn: function() {
return [
Meteor.subscribe('users', this.params._id)
];
},
action: function() {
if(Meteor.users.findOne({'services.google.email': this.params.email}) !== undefined) {
if(Meteor.user() && this.params.email === Meteor.user().services.google.email) {
Session.set("user", Meteor.user().profile);
this.redirect('/profile');
} else {
Session.set("user", Meteor.user().profile);
this.render('user');
}
} else {
this.render("NotFound");
}
}
});
Router.configure({
notFoundTemplate: "NotFound"
});

View File

@ -25,6 +25,10 @@ Meteor.publish('schools', function() {
return schools.find();
});
Meteor.publish('teachers', function() {
return teachers.find({}, {fields: {name: 1, school: 1}});
});
// Returns the code for classes (for debug)
Meteor.publish('classes', function() {
@ -125,15 +129,15 @@ Meteor.publish('users', function() {
}
});
// Allows only superadmins to edit collections from client
Security.permit(['insert', 'update', 'remove']).collections([schools, classes, work]).ifHasRole('superadmin');
Accounts.validateLoginAttempt(function(info) {
var user = info.user;
// Accounts.validateLoginAttempt(function(info) {
// var user = info.user;
// if(user.banned) throw new Meteor.Error(403, 'You are banned');
if(user.isBanned) throw new Meteor.Error(403, 'You are banned');
});
// });
var errors = [
@ -156,7 +160,8 @@ var errors = [
["trivial", "This request is too long."],
["trivial", "Not a valid work type"],
["unauthorized", "This class has not been approved yet"],
["matching", "This teacher already exists"],
["matching", "This teacher already exists!"],
["trivial", "Please put the full name!"], // 20
["unauthorized", "Sorry, you are not authorized to complete this action."], // n - 2
["other", "Error could not be processed"] // n - 1
@ -192,7 +197,7 @@ function securityCheck(checklist, input) {
break;
// Duplicate classes
case 4:
if (classes.findOne({school: input.school, status: true, privacy: false, teacher: input.teacher, hour: input.hour}) || (input.teacher === "" && input.hour === "")) error = 3;
if (classes.findOne({school: input.school, teacher: input.teacher, status: true, privacy: false, hour: input.hour}) || (input.teacher === "" && input.hour === "")) error = 3;
break;
// Class admin
case 5:
@ -275,12 +280,16 @@ function securityCheck(checklist, input) {
break;
// New Teacher doesn't already exist
case 26:
if (teachers.find({name: input.teacherName, school: input.school}).fetch().length > 0) error = 19;
if (teachers.find({name: input.teachername, school: input.school}).fetch().length > 0) error = 19;
break;
// Not banning admin
case 27:
if (Roles.userIsInRole(input.userId, ['superadmin', 'admin'])) error = errors.length - 2;
break;
// Incorrect teacher format
case 28:
if (input.teachername.split(" ").length < 2) error = 20;
break;
}
results.push(error);
}
@ -332,7 +341,6 @@ Meteor.methods({
throw new Meteor.Error(errors[security]);
}
},
// Class Functions
'createClass': function(input) {
classes.schema.validate(input);
@ -350,7 +358,6 @@ Meteor.methods({
input.subscribers = [];
input.moderators = [];
input.banned = [];
classes.insert(input, function(err, result) {
Meteor.call('joinClass', [result, input.code]);
});
@ -726,9 +733,11 @@ Meteor.methods({
var current = Meteor.user().profile;
var index = current.classes.indexOf(change);
if (index >= 0) {
console.log("hi");
if (classes.findOne({
_id: change
}).admin != Meteor.userId()) {
console.log("f");
current.classes.splice(index, 1);
Meteor.users.update({
_id: Meteor.userId()
@ -799,11 +808,13 @@ Meteor.methods({
}
},
'createTeacher': function(teacherName, schoolName) {
var security = securityCheck([26, 3, true], {teachername: teacherName, school: schoolName});
teachers.schema.validate({name: teacherName, school: schoolName});
var security = securityCheck([26, 28, 3, true], {teachername: teacherName, school: schoolName});
if (!security) {
teachers.insert({
name: teacherName,
school: schoolName
school: schoolName,
creator: Meteor.userId()
});
} else {
throw new Meteor.Error(errors[security]);