Updated Login and User Management with new materialize and controls

This commit is contained in:
Brian McGonagill 2024-07-25 09:56:37 -05:00
parent 81559683eb
commit 1d7ecc3efa
13 changed files with 280 additions and 84 deletions

View file

@ -5,30 +5,22 @@
<h4>Login</h4>
<div class="card">
<div class="card-content">
<form class="login">
<div class="row">
<div class="col s12 input-field">
<form class="login row" style="gap: 1em;">
<div class="col s12 input-field outlined">
<input type="email" name="email" id="email" class="email {{#if $eq misEmail true}}red lighten-3{{/if}}" />
<label for="email">Email *</label>
</div>
</div>
<div class="row">
<div class="col s12 input-field">
<div class="col s12 input-field outlined">
<input type="password" name="password" id="password" class="password {{#if $eq misPass true}}red lighten-3{{/if}}" />
<label for="password">Password *</label>
</div>
</div>
{{#if $eq areFilled false}}
<div class="row">
<div class="col s12 red lighten-3 white-text">
<span>You must fill all fields to login.</span>
</div>
</div>
{{/if}}
<div class="row">
<div class="col s12">
<a id="logmein" class="waves-effect waves-light btn logmein green darken-1">Log In</a>
</div>
<a id="logmein" class="waves-effect waves-light right btn logmein green darken-1 white-text">Log In</a>
</div>
</form>
</div>

View file

@ -4,39 +4,27 @@
<div id="registrationForm">
<div class="container">
<h4>Register</h4>
<div class="row">
<div class="col s12">
<div class="card">
<div class="card-content">
<form class="register">
<div class="row">
<div class="col s12 input-field">
<form class="register row" style="gap: 1em;">
<div class="col s12 input-field outlined">
<input type="text" name="name" class="name {{#if $eq misName true}}red lighten-3{{/if}}" id="name" />
<label for="name">Your Full Name *</label>
</div>
</div>
<div class="row">
<div class="col s12 input-field">
<div class="col s12 input-field outlined">
<input type="email" name="email" id="email" class="email {{#if $eq misEmail true}}red lighten-3{{/if}}" />
<label for="email">Email *</label>
</div>
</div>
<div class="row">
<div class="col s12 input-field">
<div class="col s12 input-field outlined">
<input type="password" name="password" id="password" class="password {{#if $eq misPass true}}red lighten-3{{/if}}" />
<label for="password">Password *</label>
</div>
</div>
<div class="row">
<div class="col s12 input-field {{#if $eq canReg false}}orange lighten-1{{/if}}">
<div class="col s12 input-field outlined {{#if $eq canReg false}}orange lighten-1{{/if}}">
<input type="password" name="passwordConfirm" id="passwordConfirm" class="passwordConfirm" />
<label for="passwordConfirm">Confirm Password *</label>
</div>
</div>
<div class="row">
<div class="col s12">
<a id="registerMe" class="waves-effect waves-light btn registerMe {{#if $eq canReg false}}grey{{else}}green darken-1{{/if}}">Register</a>
</div>
<a id="registerMe" class="waves-effect waves-light btn right registerMe {{#if $eq canReg false}}grey{{else}}green darken-1{{/if}} white-text">Register</a>
</div>
</form>
</div>
@ -46,8 +34,6 @@
</div>
</div>
</div>
</div>
</div>
{{else}}
<h4>Registration Disabled</h4>
<p class="flow-text">The administrator of this system has disabled registration. If you believe you should be allowed to register to use this system, please contact the system administrator for assistance.</p>

View file

@ -1,8 +1,9 @@
<template name="userInfoModal">
<div id="userInfoModal" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>User Info for: {{userInfo.profile.fullname}}</h4>
<div>
<h4>Password Reset</h4>
<p class="flow-text">Password Reset</p>
</div>
<form class="row" style="gap: 1em;">
<div class="col s12 m6 l6 input-field outlined">
@ -14,11 +15,31 @@
<label for="newPassConf">Enter New Password</label>
{{#if $eq passMatch false}}<p class="red-text">Passwords do not match!</p>{{/if}}
</div>
<div class="col s12 m6 l6 input-field outlined">
<select name="userRole" id="userRole" class="userRole {{#if $eq roleEmpty true}}red lighten-2 white-text{{/if}}">
<option value="{{userRole}}" selected>{{userRole}}</option>
<option value="admin">Admin</option>
<option value="systemadmin">System Admin</option>
<option value="user">User</option>
</select>
<label for="userRole">User Role</label>
{{#if $eq roleEmpty true}}
<p class="red-text">This field is required.</p>
{{/if}}
</div>
<div class="col s12 m6 l6 input-field outlined">
<input type="text" class="usersEmail" id="usersEmail" value="{{userInfo.emails.[0].address}}"/>
<label for="usersEmail">Email</label>
{{#if $eq emailEmpty true}}
<p class="red-text">This field is required.</p>
{{/if}}
</div>
</form>
</div>
<div class="modal-footer">
<a class="modal-close btn waves-effect waves-light filled orange white-text">Cancel</a>
<a id="chPass" class="btn waves-effect waves-light filled green white-text modal-close">Change Password</a>
<a id="saveChanges" class="btn waves-effect waves-light filled green white-text">Save Changes</a>
</div>
</div>
{{> snackbar}}
</template>

View file

@ -1,39 +1,105 @@
import { M } from '../../lib/assets/materialize.js';
Template.userInfoModal.onCreated(function() {
this.subscribe("rolesAvailable");
});
Template.userInfoModal.onRendered(function() {
Session.set("passMatch", true);
Session.set("passErr", false);
Session.set("userEmailErr", false);
Session.set("userRoleErr", false);
Meteor.setTimeout(() => {
var elems = document.querySelectorAll('.modal');
var instances = M.Modal.init(elems, {});
var elemse = document.querySelectorAll('select');
var instancese = M.FormSelect.init(elemse, {});
}, 350);
});
Template.userInfoModal.helpers({
passMatch: function() {
return Session.get("passMatch");
},
emailEmpty: function() {
return Session.get("userEmailErr");
},
roleEmpty: function() {
return Session.get("userRoleErr");
},
userInfo: function() {
let usersId = Session.get("usersId");
if (usersId != "" && usersId != null) {
let usersInfo = Meteor.users.findOne({ _id: usersId });
// console.dir(usersInfo);
Session.set("usersInfo", usersInfo);
return usersInfo;
} else {
return;
}
},
userRole: function() {
let userRole = Roles.getRolesForUser( Session.get("usersId"));
Session.set("usersRole", userRole);
console.log(userRole);
return userRole;
},
rolesOptions: function() {
return Roles.find();
}
});
Template.userInfoModal.events({
"click #chPass" (event) {
"click #saveChanges" (event) {
event.preventDefault();
let usersId = Session.get("usersId");
let passwd = $("#newPass").val();
let usersEmail = $("#usersEmail").val();
let userRole = $("#userRole").val();
let userInfo = Session.get("usersInfo");
let currEmail = userInfo.emails[0].address;
let userDbRole = Session.get("usersRole");
let currRole = userDbRole[0];
let passMatch = Session.get("passMatch");
if (passwd == null || passwd == "" || passMatch == false) {
if (passMatch == false) {
Session.set("passErr", true);
return;
} else {
Meteor.call('change.userPass', usersId, passwd, function(err, result) {
if (err) {
console.log(" ERROR changing user passwrod:" + err);
} else {
console.log(" Password changed successfully!");
Session.set("passErr", false);
}
if (usersEmail == null || usersEmail == "") {
Session.set("userEmailErr", true);
return;
} else {
Session.set("userEmailErr", false);
}
if (userRole == null || userRole == "") {
Session.set("userRoleErr", true);
return;
} else {
Session.set("userRoleErr", false);
}
if (passMatch == true || passMatch == "NA") {
if (passwd != "" && passwd != null) {
// need to account for the admin changing passwords and userRole or Email
changePassword(usersId, passwd);
}
if (usersEmail != null && usersEmail != "" && usersEmail != currEmail) {
changeUserEmail(usersId, usersEmail);
}
if (userRole != null && userRole != "" && userRole != currRole) {
changeUserRole(usersId, userRole);
}
});
}
},
"click #closePass" (event) {;
@ -51,3 +117,37 @@ Template.userInfoModal.events({
}
}
});
changePassword = function(userId, passwd) {
console.log("would change password.");
Meteor.call('edit.userPass', userId, passwd, function(err, result) {
if (err) {
console.log(" ERROR changing user passwrod:" + err);
} else {
showSnackbar("Successfully Saved Changes!", "green");
console.log(" Password changed successfully!");
}
});
}
changeUserEmail = function(usersId, usersEmail) {
console.log("Would change user email");
Meteor.call('update.userEmail', usersId, usersEmail, function(err, result) {
if (err) {
console.log(" ERROR updating user email: " + err);
} else {
showSnackbar("Email updated successfully!", "green");
}
});
}
changeUserRole = function(userId, role) {
console.log("Would change user Role.");
Meteor.call('edit.userRole', userId, role, function(err, result) {
if (err) {
console.log(" ERROR updating user role: " + err);
} else {
showSnackbar("Role Successfully Updated!", "green");
}
});
}

View file

@ -30,16 +30,12 @@ Template.userMgmt.helpers({
Template.userMgmt.events({
"click .editUser" (event) {
event.preventDefault();
let userId = this._id;
// take action
Session.set("usersId", userId);
},
"click .deleteUser" (event) {
event.preventDefault();
let userId = this._id;
// take action
console.log("Delete called on : " + userId);
Session.set("deleteId", userId);
Session.set("item", "User");

View file

@ -0,0 +1,49 @@
<template name="cleanUp">
{{#if isInRole 'systemadmin, admin'}}
<h3>Clean Up System Data</h3>
<div class="row">
<div class="col s12 m6 l4">
<div class="card">
<div class="card-content">
<span class="card-title">Clean Up List Items</span>
<a class="btn waves-effect waves-light blue white-text" id="cleanLists">Clean Lists</a>
<i class="material-icons tooltipped right" data-html="true" data-position="top" data-tooltip-id="tooltip-content">info</i>
<div id="tooltip-content" style="display: none;">To clean up old lists along with related list items, ensure any lists you no longer need or use are marked as 'Complete' by tapping or clicking the checkmark icon on the list entry.</div>
</div>
</div>
</div>
<div class="col s12 m6 l4">
<div class="card">
<div class="card-content">
<span class="card-title">Clean Up Menus</span>
<a class="btn waves-effect waves-light blue white-text" id="cleanLists">Clean Menus</a>
<i class="material-icons tooltipped right" data-html="true" data-position="top" data-tooltip-id="tooltip-menus">info</i>
<div id="tooltip-menus" style="display: none;">This will clean up old Menus and items where all items are past the date, including items that have no date set.</div>
</div>
</div>
</div>
<div class="col s12 m6 l4">
<div class="card">
<div class="card-content">
<span class="card-title">Clean Up Products</span>
<a class="btn waves-effect waves-light blue white-text" id="cleanLists">Clean Products</a>
<i class="material-icons tooltipped right" data-html="true" data-position="top" data-tooltip-id="tooltip-products">info</i>
<div id="tooltip-products" style="display: none;">This will help you clean up all products. This task takes a little more user interaction in order to identify duplicate and unique items.</div>
</div>
</div>
</div>
<div class="col s12 m6 l4">
<div class="card">
<div class="card-content">
<span class="card-title">Clean Up Tasks</span>
<a class="btn waves-effect waves-light blue white-text" id="cleanLists">Clean Tasks</a>
<i class="material-icons tooltipped right" data-html="true" data-position="top" data-tooltip-id="tooltip-tasks">info</i>
<div id="tooltip-tasks" style="display: none;">This will clean up all tasks where the date has past, or the task is marked completed. For completed tasks to be cleared, today must also be past the due date on the task.</div>
</div>
</div>
</div>
</div>
{{else}}
<p class="flow-text">You appear to have reached this page without having appropriate permissions to view the contents. If you believe this is a mistake, please contact your system admin for assistance.</p>
{{/if}}
</template>

View file

@ -0,0 +1,18 @@
import { M } from '../../lib/assets/materialize.js';
Template.cleanUp.onCreated(function() {
});
Template.cleanUp.onRendered(function() {
var elems = document.querySelectorAll('.tooltipped');
var instances = M.Tooltip.init(elems, {});
});
Template.cleanUp.helpers({
});
Template.cleanUp.events({
});

View file

@ -11,6 +11,7 @@
<li id="manageStore" class="collection-item">Store</li>
<li id="taskHome" class="collection-item">Tasks</li>
<li id="systemAdmin" class="collection-item">System Admin</li>
<li id="cleanUp" class="collection-item">Clean Up System</li>
</ul>
</div>
</div>

View file

@ -1,9 +1,10 @@
<template name="systemAdmin">
<h2>System Administration</h2>
<div class="row">
<div class="col s12 m12 l6">
<div class="card">
<div class="card-content">
<h4>System Admin</h4>
<h4>Registration Settings</h4>
<div class="row">
<div class="col s12 m6 l6">
<div class="switch">

View file

@ -116,3 +116,10 @@ FlowRouter.route('/systemAdmin', {
BlazeLayout.render('MainLayout', { main: 'systemAdmin' });
}
});
FlowRouter.route('/cleanUp', {
name: 'cleanUp',
action() {
BlazeLayout.render('MainLayout', { main: 'cleanUp'});
}
});

View file

@ -3,8 +3,6 @@ import { Meteor } from 'meteor/meteor';
Meteor.startup(() => {
// code to run on server at startup
Roles.createRole("user", {unlessExists: true});
Roles.createRole("groupLeader", {unlessExists: true});
Roles.createRole("groupMember", {unlessExists: true});
Roles.createRole("admin", {unlessExists: true});
Roles.createRole("systemadmin", {unlessExists: true});
});

View file

@ -32,11 +32,30 @@ Meteor.methods({
}
},
'edit.userPass' (userId, newPassword) {
check(userId, String);
check(newPassword, String);
return Accounts.setPassword(userId, newPassword);
},
'delete.userFromSys' (userId) {
check(userId, String);
return Meteor.users.remove({ _id: userId });
},
'update.userEmail' (userId, email) {
check(userId, String);
check(email, String);
return Meteor.users.update({ _id: userId }, {
$set: {
'emails.0.address': email,
}
});
},
'edit.userRole' (userId, role) {
check(userId, String);
check(role, String);
return Roles.setUserRoles(userId, role);
}
});

View file

@ -111,3 +111,11 @@ Meteor.publish("myTasks", function() {
console.log(" ERROR pulling the task items: " + error);
}
});
Meteor.publish("rolesAvailable", function() {
try {
return Meteor.roles.find({});
} catch (error) {
console.log(" ERROR publishing roles: " + error);
}
})