diff --git a/client/main.html b/client/main.html
index 32dd10b..c441456 100644
--- a/client/main.html
+++ b/client/main.html
@@ -5,6 +5,9 @@
+
+
+
(
+
diff --git a/imports/client/views/etc/index.js b/imports/client/views/etc/index.js
index 6579f02..f8fb0eb 100644
--- a/imports/client/views/etc/index.js
+++ b/imports/client/views/etc/index.js
@@ -13,14 +13,17 @@ import { Users } from '/imports/collections/users/index
const meteorTick = (props, onData) => {
const handles = [
- Meteor.subscribe('users.current')
+ Meteor.subscribe('users.current'),
+ Meteor.subscribe('orgs.current')
];
if(_.every(handles, (handle) => (handle.ready()) )) {
const user = Users.current();
+ const org = Orgs.current();
onData(null, {
data: {
user: user,
+ org: org
},
});
}
diff --git a/imports/client/views/etc/signup.js b/imports/client/views/etc/signup.js
index a47fa6e..f78461d 100644
--- a/imports/client/views/etc/signup.js
+++ b/imports/client/views/etc/signup.js
@@ -22,6 +22,7 @@ export class InviteSignupView extends Component {
};
render() {
+ const {user, org} = this.props.data;
return (
diff --git a/imports/client/views/org/admin/students/StudentDataView.js b/imports/client/views/org/admin/students/StudentDataView.js
new file mode 100644
index 0000000..03a3f53
--- /dev/null
+++ b/imports/client/views/org/admin/students/StudentDataView.js
@@ -0,0 +1,88 @@
+import _ from 'lodash';
+import { Meteor } from 'meteor/meteor';
+
+import React, { Component } from 'react';
+import { Link,browserHistory } from 'react-router';
+import { FormGroup,Panel,Table,
+ ButtonToolbar,Modal,
+ FormControl,Glyphicon,Button } from 'react-bootstrap';
+ import { AddStudentForm } from './addStudentForm';
+
+export class StudentDataView extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ show: false
+ };
+ this.showModal = this.showModal.bind(this);
+ this.hideModal = this.hideModal.bind(this);
+ this.onUpdate = this.onUpdate.bind(this);
+ };
+
+ showModal() {
+ this.setState({show: true});
+ }
+
+ hideModal() {
+ this.setState({show: false});
+ }
+ onUpdate(key, value) {
+ this.setState({[key]: value});
+ };
+
+ render() {
+ return (
+
+
+
+
+
+ # |
+ First Name |
+ Last Name |
+
+
+
+ {
+ this.props.data.students.map(function(student, i)
+ {
+ return(
+
+ {i+1} |
+ {student.firstName} |
+ {student.lastName} |
+
+ )
+ })
+ }
+
+
+
+
+
+
+
+ New Student
+
+
+
+
+
+
+
+
+
+
+
+ );
+ };
+
+};
diff --git a/imports/client/views/org/admin/students/addStudentForm.js b/imports/client/views/org/admin/students/addStudentForm.js
new file mode 100644
index 0000000..fa3c589
--- /dev/null
+++ b/imports/client/views/org/admin/students/addStudentForm.js
@@ -0,0 +1,90 @@
+import _ from 'lodash';
+import { Meteor } from 'meteor/meteor';
+
+import React, { Component } from 'react';
+import { Link,browserHistory } from 'react-router';
+import { FormGroup,InputGroup,
+ DropdownButton,MenuItem,ControlLabel,
+ SplitButton,
+ FormControl,Glyphicon,Button } from 'react-bootstrap';
+import {DatePicker} from 'react-bootstrap-date-picker'
+import {addStudentManually} from '/imports/collections/students/methods';
+
+export class AddStudentForm extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ firstName: "",
+ lastName: "",
+ middleName: "",
+ dob: "",
+ };
+ this.onUpdate = this.onUpdate.bind(this);
+ this.aFunction = this.aFunction.bind(this);
+ };
+
+ onUpdate(key, value) {
+ this.setState({[key]: value});
+ };
+ aFunction(e){
+ console.log(e);
+ console.log(e);
+ }
+ addStudent(e){
+ e.preventDefault();
+ e.persist();
+ const firstName = this.state.firstName;
+ const middleName = this.state.middleName;
+ const lastName = this.state.lastName;
+ if(firstName==""){
+ Bert.alert('Enter Fist Name', 'danger');
+ } else if(middleName==""){
+ Bert.alert('Enter Middle name!', 'danger');
+ } else{
+ addStudentManually.call({
+ firstName: firstName,
+ middleName: middleName,
+ lastName: lastName
+ }, function (error, result) {
+ console.log(error);
+ console.log(result);
+ });
+ }
+ }
+ render() {
+ return (
+
+ );
+ };
+
+};
diff --git a/imports/client/views/org/admin/students/index.js b/imports/client/views/org/admin/students/index.js
new file mode 100644
index 0000000..20d1f09
--- /dev/null
+++ b/imports/client/views/org/admin/students/index.js
@@ -0,0 +1,54 @@
+// import { StudentDataController } from '/imports/client/views/org/admin/students/index'
+import _ from 'lodash';
+import {
+ composeWithTracker,
+ compose,
+ composeAll
+ } from 'react-komposer';
+import { Loading } from '/imports/client/components/Loading';
+
+import { Orgs } from '/imports/collections/orgs/index';
+import { Users } from '/imports/collections/users/index';
+import { StudentDataView } from './StudentDataView';
+import { Students } from '/imports/collections/students/methods'
+
+
+const meteorTick = (props, onData) => {
+
+ const handles = [
+ Meteor.subscribe('users.current'),
+ Meteor.subscribe('orgs.current'),
+ Meteor.subscribe('users.forMyOrg')
+ ];
+
+ if(_.every(handles, (handle) => (handle.ready()) )) {
+ const user = Users.current();
+ const org = Orgs.current();
+ const students = Users.find({"role":"STUDENT"}).fetch();
+ console.log(students);
+ onData(null, {
+ data: {
+ user: user,
+ org: org,
+ students:students
+ },
+ });
+ }
+
+ return () => {
+ _.each(handles, (handle) => handle.stop() );
+ };
+};
+
+
+const reduxTick = (props, onData) => {
+ onData(null, {
+ data: {}
+ });
+};
+
+
+export const StudentDataController = composeAll(
+ composeWithTracker(meteorTick, Loading),
+ compose(reduxTick, Loading),
+)(StudentDataView);
diff --git a/imports/client/views/org/app/module/navigation/AuthenticatedNavigation.js b/imports/client/views/org/app/module/navigation/AuthenticatedNavigation.js
index bfe5a7e..9a2f16e 100644
--- a/imports/client/views/org/app/module/navigation/AuthenticatedNavigation.js
+++ b/imports/client/views/org/app/module/navigation/AuthenticatedNavigation.js
@@ -1,10 +1,11 @@
-import React, { Component } from 'react';
-import { browserHistory } from 'react-router';
-import { LinkContainer } from 'react-router-bootstrap';
+import React, { Component } from 'react';
+import { browserHistory } from 'react-router';
+import { LinkContainer } from 'react-router-bootstrap';
+import { logout } from '/imports/client/app/utils/loginMethods';
import { Navbar,Modal, Nav, NavItem,
Glyphicon,
- NavDropdown, MenuItem } from 'react-bootstrap';
-import { Meteor } from 'meteor/meteor';
+ NavDropdown, MenuItem } from 'react-bootstrap';
+import { Meteor } from 'meteor/meteor';
const handleLogout = () => Meteor.logout(() => browserHistory.push('/login'));
@@ -16,27 +17,32 @@ export class AuthenticatedNavigation extends Component {
};
};
render(){
- const {user} = this.props.data;
+ const {user, org} = this.props.data;
return(
-
+
-
- YOUNGDESK
+ {org.name}
+
-
+
+
);
}
}
diff --git a/imports/client/views/org/app/module/navigation/index.js b/imports/client/views/org/app/module/navigation/index.js
index 0965b10..fbfa4d7 100644
--- a/imports/client/views/org/app/module/navigation/index.js
+++ b/imports/client/views/org/app/module/navigation/index.js
@@ -15,14 +15,17 @@ import { AppNavigation } from './AppNavigation';
const meteorTick = (props, onData) => {
const handles = [
- Meteor.subscribe('users.current')
+ Meteor.subscribe('users.current'),
+ Meteor.subscribe('orgs.current')
];
if(_.every(handles, (handle) => (handle.ready()) )) {
const user = Users.current();
+ const org = Orgs.current();
onData(null, {
data: {
user: user,
+ org: org
},
});
}
diff --git a/imports/collections/students/index.js b/imports/collections/students/index.js
index 545a927..c4a8a15 100644
--- a/imports/collections/students/index.js
+++ b/imports/collections/students/index.js
@@ -1,5 +1,4 @@
-// import { Users } from '/imports/collections/users/index';
-// import { Users } from '/imports/collections/users/index';
+// import {Students } from '/imports/collections/students/methods'
import _ from 'lodash';
import { Meteor } from 'meteor/meteor';
@@ -7,108 +6,62 @@ import { Mongo } from 'meteor/mongo';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
import { Orgs } from '/imports/collections/orgs/index';
+import { Users } from '/imports/collections/users/index';
-class User {
-
+class Student {
constructor(doc) {
_.assign(this, doc);
};
- isEmailVerified() {
- return !! _.find(this.emails, x => x.verified);
- };
-
- isPhoneVerified() {
- return !! _.find(this.phones, x => x.verified);
- };
-
- isIdentityVerified() {
- return !! _.find(this.identities, x => x.verified);
- };
-
- getRole() {
- const org = Orgs.findOne({_id: this.orgId});
- if(!org) return null;
- const connection = _.find(org.users, {userId: this._id});
- if(!connection) return null;
- return connection.role;
- };
-
- getFullName() {
- return `${this.firstName} ${this.lastName}`;
- };
- getFirstName() {
- return `${this.firstName}`;
- };
- getLastName() {
- return `${this.lastName}`;
- };
- getEmail() {
- return `${this.emails[0].address}`;
- };
- getOrganization(){
- return `${this.orgId}`;
- };
-
- getNameByUserId(userId){
- var user = Users.findOne({"_id":userId});
- return user.firstName + " " + user.lastName;
- }
- getAvatarUrl() {
- let random = parseInt(this._id.substr(0, 4), 36);
- random = '' + (random % 32);
- while(random.length < 3) random = '0' + random;
- return `/files/random/random${ random }.png`;
+ getUserIds() {
+ return _.filter(_.map(this.users, 'userId'));
};
};
-
-export { User };
-
-
-const transform = function(doc) {
- return new User(doc);
+export { Student };
+
+class StudentsCollection extends Mongo.Collection {
+ insert(item, callback) {
+ _.assign(item, {
+ createdAt: new Date().getTime(),
+ });
+ return super.insert(item, callback);
+ };
};
-export const Users = {
-
- current: function() {
- return Meteor.users.findOne({_id: Meteor.userId()}, _.extend({transform: transform}));
+export const Students = new StudentsCollection('Students', {
+ transform: (item) => {
+ return new Student(item);
},
+});
- find: function(selector, options) {
- return Meteor.users.find(selector || {}, _.extend({transform: transform}, options));
+_.assign(Students, {
+ allStudents: () => {
+ const user = Users.current();
+ if(!user) return null;
+ return Orgs.find({'users.userId': user._id});
},
-
- findOne: function(selector, options) {
- return Meteor.users.findOne(selector || {}, _.extend({transform: transform}, options));
+ current: () => {
+ const user = Users.current();
+ if(!user) return null;
+ return Orgs.findOne({_id: user.orgId});
+ },
+ currentOrgUsers: () => {
+ const OrgsArr = Orgs.current();
+ if(!OrgsArr) return null;
+ return OrgsArr.users;
},
- insert: _.bind(Meteor.users.insert, Meteor.users),
- update: _.bind(Meteor.users.update, Meteor.users),
- remove: _.bind(Meteor.users.remove, Meteor.users),
- allow: _.bind(Meteor.users.allow, Meteor.users),
- deny: _.bind(Meteor.users.deny, Meteor.users),
- attachSchema: _.bind(Meteor.users.attachSchema, Meteor.users),
-
-};
-
+});
-Users.deny({
+Students.deny({
insert() { return true; },
update() { return true; },
remove() { return true; },
});
-Users.roles = {
- 'STUDENT': 'STUDENT',
- 'TEACHER': 'TEACHER',
- 'ADMIN': 'ADMIN',
- 'PARENT': 'PARENT'
-};
-
-Users.schema = new SimpleSchema({
- roles: { type: String },
+Students.schema = new SimpleSchema({
+ userId: { type: String },
orgId: { type: String },
admissionId: { type: String, optional: true },
enrollmentDate: { type: String, optional: true },
@@ -137,19 +90,14 @@ Users.schema = new SimpleSchema({
state: { type: String, optional: true },
zip: { type: String, optional: true },
}),
+ optional: true
},
parent: {
type: [new SimpleSchema({
id: { type: String, },
relatinship: { type: Boolean, },
})],
- minCount: 1,
- },
- emails: {
- type: [new SimpleSchema({
- address: { type: String, },
- verified: { type: Boolean, },
- })],
+ optional: true
},
prevInstitute: {
type: [new SimpleSchema({
@@ -161,16 +109,6 @@ Users.schema = new SimpleSchema({
optional: true
},
- phones: {
- type: [new SimpleSchema({
- country: { type: String, },
- prefix: { type: String, },
- number: { type: String, },
- verified: { type: Boolean, },
- })],
- optional: true
- },
-
services: {
type: Object,
optional: true,
@@ -183,9 +121,9 @@ Users.schema = new SimpleSchema({
});
-Users.attachSchema(Users.schema);
+Students.attachSchema(Students.schema);
-Users.privateFields = {
+Students.privateFields = {
orgId: 1,
address: 1,
@@ -198,7 +136,7 @@ Users.privateFields = {
createdAt: 1,
};
-Users.publicFields = {
+Students.publicFields = {
firstName: 1,
lastName: 1,
emails: 1,
diff --git a/imports/collections/students/methods.js b/imports/collections/students/methods.js
new file mode 100644
index 0000000..7ba181a
--- /dev/null
+++ b/imports/collections/students/methods.js
@@ -0,0 +1,57 @@
+// import { } from '/imports/collections/students/methods';
+import _ from 'lodash';
+import { Meteor } from 'meteor/meteor';
+import { ValidatedMethod } from 'meteor/mdg:validated-method';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';
+import { Bert } from 'meteor/themeteorchef:bert';
+import { Users } from '/imports/collections/users/index';
+import { Students } from '/imports/collections/students/index';
+import { Orgs } from '/imports/collections/orgs/index';
+export const studentMethods = new ValidatedMethod({
+ name: 'student.method',
+
+ validate: new SimpleSchema({
+ itemId: { type: String },
+ }).validator(),
+
+ run({itemId}) {
+ return {};
+ },
+
+});
+
+export const addStudentManually = new ValidatedMethod({
+ name: 'student.addManually',
+
+ validate: new SimpleSchema({
+ firstName: { type: String },
+ middleName: { type: String },
+ lastName: { type: String },
+ }).validator(),
+
+ run({firstName,middleName,lastName}) {
+ console.log(firstName);
+ console.log(middleName);
+ console.log(lastName);
+ const user = Users.findOne({_id: this.userId});
+ orgId = user.orgId;
+ newUserId = Users.insert({
+ username: firstName,
+ firstName: firstName,
+ middleName: middleName,
+ lastName: lastName,
+ orgId: orgId,
+ role: 'STUDENT'
+ });
+ log(newUserId);
+ if(newUserId){
+ Students.insert({
+ userId: newUserId,
+ orgId: orgId,
+ });
+ }
+ return {newUserId};
+ },
+
+});
diff --git a/imports/collections/users/index.js b/imports/collections/users/index.js
index aadd8c9..1afdfe0 100644
--- a/imports/collections/users/index.js
+++ b/imports/collections/users/index.js
@@ -108,8 +108,9 @@ Users.roles = {
Users.schema = new SimpleSchema({
- role: { type: String },
+ role: { type: String },
orgId: { type: String },
+ username: { type: String, optional: true },
prefix: { type: String, optional: true },
firstName: { type: String, optional: true },
middlename: { type: String, optional: true },
@@ -121,6 +122,7 @@ Users.schema = new SimpleSchema({
address: { type: String, },
verified: { type: Boolean, },
})],
+ optional: true
},
phones: {
type: [new SimpleSchema({
diff --git a/imports/collections/users/publications.js b/imports/collections/users/publications.js
index 42beeda..e0ecf59 100644
--- a/imports/collections/users/publications.js
+++ b/imports/collections/users/publications.js
@@ -12,3 +12,13 @@ Meteor.publish('users.current', function() {
fields: Users.privateFields,
});
});
+Meteor.publish('users.forMyOrg', function() {
+ const user = Users.findOne({_id: this.userId});
+ if(!user) return [];
+ const org = Orgs.findOne({_id: user.orgId});
+ if(!org) return [];
+
+ return Users.find({
+ orgId: user.orgId,role:"STUDENT"
+ });
+});
diff --git a/imports/server/collections.js b/imports/server/collections.js
index 84e5e33..e14c417 100644
--- a/imports/server/collections.js
+++ b/imports/server/collections.js
@@ -2,3 +2,5 @@ import '/imports/collections/orgs/publications'
import '/imports/collections/orgs/methods';
import '/imports/collections/users/publications';
+
+import '/imports/collections/students/methods';
diff --git a/imports/server/fixtures.js b/imports/server/fixtures.js
index 57713fe..904502b 100644
--- a/imports/server/fixtures.js
+++ b/imports/server/fixtures.js
@@ -1,6 +1,7 @@
-import { Meteor } from 'meteor/meteor';
-import { Roles } from 'meteor/alanning:roles';
-import { Accounts } from 'meteor/accounts-base';
+import { Meteor } from 'meteor/meteor';
+import { Roles } from 'meteor/alanning:roles';
+import { Accounts } from 'meteor/accounts-base';
+import { Orgs } from '/imports/collections/orgs/index';
if (!Meteor.isProduction) {
const users = [{
@@ -18,6 +19,12 @@ if (!Meteor.isProduction) {
if (!userExists) {
const userId = Accounts.createUser({ email, password, profile });
Roles.addUsersToRoles(userId, roles);
+ const org = [{
+ name: 'yd',
+ slug: 'yd',
+ "users.userId": userId
+ }];
+ Orgs.inser
}
});
}
diff --git a/package.json b/package.json
index a05f111..1e5db5b 100644
--- a/package.json
+++ b/package.json
@@ -71,7 +71,8 @@
"react-addons-css-transition-group": "^15.4.2",
"react-addons-pure-render-mixin": "^15.3.2",
"react-addons-transition-group": "^15.4.2",
- "react-bootstrap": "^0.30.5",
+ "react-bootstrap": "^0.30.8",
+ "react-bootstrap-date-picker": "^4.0.0",
"react-dom": "^15.4.2",
"react-fontawesome": "^1.5.0",
"react-komposer": "^1.13.1",
diff --git a/private/fixtures/Orgs-Orgs.csv b/private/fixtures/Orgs-Orgs.csv
new file mode 100644
index 0000000..ab80eee
--- /dev/null
+++ b/private/fixtures/Orgs-Orgs.csv
@@ -0,0 +1,4 @@
+key,name,userKeys
+ADMIN,Admin org,ADMIN
+BRISBANE,Brisbane Kangaroos,"ADAM,BOB,CHARLIE"
+PERTH,Perth Sharks,"ADAM,DAVE"
\ No newline at end of file
diff --git a/private/fixtures/Users-Users.csv b/private/fixtures/Users-Users.csv
new file mode 100644
index 0000000..c4b7f06
--- /dev/null
+++ b/private/fixtures/Users-Users.csv
@@ -0,0 +1,3 @@
+key,first,last,orgKey,email,isMeta
+ADMIN,Admin,Adminovich,ADMIN,admin@acme.dev,TRUE
+ADMIN,Deepak,Jha,YD,deepak@youngdesk.com,TRUE