diff --git a/client/main.html b/client/main.html index 193f9e8..96756e6 100644 --- a/client/main.html +++ b/client/main.html @@ -5,6 +5,6 @@ -
- + + diff --git a/imports/api/assets.js b/imports/api/assets.js index 73871a0..5e1a4fa 100644 --- a/imports/api/assets.js +++ b/imports/api/assets.js @@ -9,7 +9,7 @@ import {AssetAssignmentHistory} from "/imports/api/asset-assignment-history"; // console.log("Setting Up Assets...") export const Assets = new Mongo.Collection('assets'); -export const conditions = ['New','Like New','Good','Okay','Damaged'] +export const conditions = ['New','Like New','Good','Okay','Damaged', 'Missing', 'Decommissioned'] /* const AssetsSchema = new SimpleSchema({ @@ -90,7 +90,7 @@ Meteor.methods({ check(condition, String); if(conditionDetails) check(conditionDetails, String); - if(condition !== 'New' && condition !== 'Like New' && condition !== 'Good' && condition !== 'Okay' && condition !== 'Damaged') { + if(!conditions.includes(condition)) { //Should never happen. console.error("Invalid condition option in assets.add(..)"); throw new Meteor.Error("Invalid condition option."); @@ -123,7 +123,7 @@ Meteor.methods({ check(condition, String); if(conditionDetails) check(conditionDetails, String); - if(condition !== 'New' && condition !== 'Like New' && condition !== 'Good' && condition !== 'Okay' && condition !== 'Damaged') { + if(!conditions.includes(condition)) { //Should never happen. console.error("Invalid condition option in assets.update(..)"); throw new Meteor.Error("Invalid condition option."); @@ -176,7 +176,7 @@ Meteor.methods({ if(!date) date = new Date(); - if(condition !== 'New' && condition !== 'Like New' && condition !== 'Good' && condition !== 'Okay' && condition !== 'Damaged') { + if(!conditions.includes(condition)) { //Should never happen. console.error("Invalid condition option in assets.unassign(..)"); throw new Meteor.Error("Invalid condition option."); @@ -225,7 +225,7 @@ Meteor.methods({ if(!date) date = new Date(); - if(condition !== 'New' && condition !== 'Like New' && condition !== 'Good' && condition !== 'Okay' && condition !== 'Damaged') { + if(!conditions.includes(condition)) { //Should never happen. console.error("Invalid condition option in assets.unassign(..)"); throw new Meteor.Error("Invalid condition option."); diff --git a/imports/api/workshops.js b/imports/api/workshops.js new file mode 100644 index 0000000..74c57c0 --- /dev/null +++ b/imports/api/workshops.js @@ -0,0 +1,97 @@ +import {Mongo} from "meteor/mongo"; +import {Meteor} from "meteor/meteor"; +import { check, Match } from 'meteor/check'; +import { Roles } from 'meteor/alanning:roles'; + +// +// An asset type is a specific type of equipment. Example: Lenovo 100e Chromebook. +// +export const Workshops = new Mongo.Collection('workshops'); + +if(Meteor.isServer) { + // Drop any old indexes we no longer will use. Create indexes we need. + //try {Workshops._dropIndex("External ID")} catch(e) {} + //Workshops.createIndex({name: "text"}, {name: "name", unique: false}); + //Workshops.createIndex({id: 1}, {name: "External ID", unique: true}); + + //Debug: Show all indexes. + // Workshops.rawCollection().indexes((err, indexes) => { + // console.log(indexes); + // }); + + // This code only runs on the server + Meteor.publish('workshops', function() { + return Workshops.find({}); + }); +} +Meteor.methods({ + 'workshops.add'(name, description, signupLimit) { + let signupSheet = []; + + check(name, String); + check(description, String); + // Match a positive integer or undefined/null. + check(signupLimit, Match.Where((x) => { + check(x, Match.Maybe(Match.Integer)); + return x ? x > 0 : true + })) + + if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { + Workshops.insert({name, description, signupLimit, signupSheet}); + } + }, + 'workshops.update'(_id, name, description, signupLimit) { + check(_id, String); + check(name, String); + check(description, String); + // Match a positive integer or undefined/null. + check(signupLimit, Match.Where((x) => { + check(x, Match.Maybe(Match.Integer)); + return x ? x > 0 : true + })) + + if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { + Workshops.update({_id}, {$set: {name, description, signupLimit}}); + } + }, + 'workshops.signup'(_id) { + check(_id, String); + + if(Meteor.userId()) { + let workshop = Workshops.findOne(_id); + + if(workshop) { + if(!workshop.signupLimit || workshop.signedUp.length < workshop.signupLimit) { + Workshops.update({_id}, {$push: {signupSheet: {_id: Meteor.userId()}}}); + } + } + } + }, + 'workshops.unsignup'(_id) { + check(_id, String); + + if(Meteor.userId()) { + let workshop = Workshops.findOne(_id); + + if(workshop) { + Workshops.update({_id}, {$pull: {signupSheet: {_id: Meteor.userId()}}}); + } + } + }, + 'workshops.complete'(_id) { + check(_id, String); + + if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { + Workshops.update({_id}, {$set: {isComplete: true}}) + } + }, + 'workshops.remove'(_id) { + check(_id, String); + + if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { + Workshops.remove({_id}) + } + }, +}); + +// console.log("Asset types setup.") diff --git a/imports/ui/App.jsx b/imports/ui/App.jsx index cb7bd32..9acd569 100644 --- a/imports/ui/App.jsx +++ b/imports/ui/App.jsx @@ -12,6 +12,9 @@ import History from './pages/History' import Search from './pages/Search' import Users from './pages/Users' import Admin from './pages/Admin' +import Home from './pages/Home' +import {StudentPage} from './pages/Student/StudentPage' +import {Workshops} from './pages/Student/Workshops' const appTheme = createTheme({ components: { @@ -65,7 +68,7 @@ const appTheme = createTheme({ } }) -export const App = () => { +export const App = (props) => { const {user, canManageLaptops, isAdmin} = useTracker(() => { const user = Meteor.user(); const canManageLaptops = user && Roles.userIsInRole(user._id, 'laptop-management', 'global'); @@ -84,43 +87,44 @@ export const App = () => {