Skip to content

Commit

Permalink
Working on User Admin view
Browse files Browse the repository at this point in the history
  • Loading branch information
DerekTBrown committed Aug 21, 2017
1 parent 4ac8d53 commit 450e7fa
Show file tree
Hide file tree
Showing 18 changed files with 415 additions and 33 deletions.
4 changes: 2 additions & 2 deletions both/models/course.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

/* COURSE DESCRIPTION */
interface CourseDescription {
content: string;
syllabus: string;
content: string; // Markdown Not Supported
syllabus: string; // Markdown Supported
}

/* PERMISSIONS */
Expand Down
1 change: 1 addition & 0 deletions both/models/session.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface Session {
_id? : string,

user_id : string,
course_id : string,
lab_id: string,

// Status
Expand Down
3 changes: 3 additions & 0 deletions both/schemas/session.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export const SessionSchema : SimpleSchema = new SimpleSchema({
user_id: {
type: String
},
course_id: {
type: String
},
lab_id: {
type: String
},
Expand Down
22 changes: 3 additions & 19 deletions client/imports/account/dashboard.component.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
<div class="tuxlab-dashboard" style="min-height:2000px">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pellentesque nunc vel sollicitudin commodo. Vestibulum nulla est, cursus eu diam auctor, malesuada feugiat sapien. Phasellus in nisi vel odio tempor tincidunt. In massa arcu, viverra in lobortis in, laoreet dapibus neque. Nulla gravida, purus congue posuere elementum, mauris justo bibendum ex, dapibus tempor tortor ligula at nisl. Nulla cursus orci sit amet ante posuere, vel viverra tortor elementum. Nunc blandit magna eu turpis sodales, ac elementum odio lobortis. Pellentesque eu mauris varius, sagittis mauris et, placerat est. Donec porta ex fringilla condimentum lobortis. Integer eu magna molestie, posuere quam ut, luctus nisi. Integer ut lorem ut mi posuere tempor. Etiam ac purus vitae mi hendrerit interdum vel eu mi. Duis venenatis, massa non pulvinar maximus, est urna interdum lectus, in placerat libero ligula eget massa. Nam vestibulum congue leo et bibendum. Sed sit amet lacus mollis, lobortis lorem vestibulum, iaculis risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<div class="tuxlab-dashboard">

<h2> Welcome to TuxLab! </h2>

Integer sit amet orci et velit tincidunt feugiat. Vestibulum tincidunt tortor mi, a convallis arcu posuere id. Maecenas fermentum ligula sit amet volutpat consequat. In non ex massa. Duis facilisis turpis euismod leo dignissim sollicitudin et eget tellus. Nunc ut tortor malesuada, sagittis leo eu, vulputate lacus. Aenean auctor mi arcu, quis molestie tortor molestie ut. Nulla id metus molestie, interdum magna non, egestas odio. Nunc pulvinar ac mi id ultricies. Aliquam erat volutpat. Curabitur sit amet nisl a felis auctor accumsan. Pellentesque dictum lacinia velit, laoreet consectetur tellus egestas sed.

Morbi sollicitudin, quam vel ultricies placerat, dolor ligula tempor eros, et consectetur diam est vel justo. Sed scelerisque felis libero, eget faucibus mi gravida nec. Quisque non vulputate risus. Mauris condimentum nibh augue, eu bibendum est aliquam eu. Praesent a velit eu risus semper blandit vel in augue. Aenean massa dolor, fermentum eu sem ac, sollicitudin placerat erat. Donec in leo dapibus, ullamcorper urna vel, facilisis magna. Sed bibendum dui odio, ut ultricies nunc rhoncus sit amet. Nullam venenatis elit enim, non eleifend nisl pulvinar sed. Ut molestie eu justo quis ultricies. Morbi fringilla mi quis tempor cursus. Vivamus eleifend congue mi, vel posuere libero viverra ac.

Nulla vitae condimentum quam, aliquet ullamcorper lorem. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut eget congue eros, ac mollis diam. Aenean tincidunt sit amet felis non molestie. Nunc rutrum arcu vitae mattis pretium. In vitae dui elementum, condimentum arcu vitae, congue lectus. Integer gravida, dolor id luctus accumsan, purus ligula tincidunt ipsum, eget scelerisque lorem purus ut sapien. Donec a feugiat quam.

Pellentesque nec laoreet lacus. Duis in sapien eu ex faucibus dignissim. Aliquam fermentum at tortor quis hendrerit. Integer blandit quis tellus eu interdum. Morbi placerat euismod porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque vehicula libero sit amet enim egestas, pretium sollicitudin est euismod. In vitae imperdiet nisi. Sed auctor finibus lacinia. Suspendisse ultricies ultricies neque nec egestas.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pellentesque nunc vel sollicitudin commodo. Vestibulum nulla est, cursus eu diam auctor, malesuada feugiat sapien. Phasellus in nisi vel odio tempor tincidunt. In massa arcu, viverra in lobortis in, laoreet dapibus neque. Nulla gravida, purus congue posuere elementum, mauris justo bibendum ex, dapibus tempor tortor ligula at nisl. Nulla cursus orci sit amet ante posuere, vel viverra tortor elementum. Nunc blandit magna eu turpis sodales, ac elementum odio lobortis. Pellentesque eu mauris varius, sagittis mauris et, placerat est. Donec porta ex fringilla condimentum lobortis. Integer eu magna molestie, posuere quam ut, luctus nisi. Integer ut lorem ut mi posuere tempor. Etiam ac purus vitae mi hendrerit interdum vel eu mi. Duis venenatis, massa non pulvinar maximus, est urna interdum lectus, in placerat libero ligula eget massa. Nam vestibulum congue leo et bibendum. Sed sit amet lacus mollis, lobortis lorem vestibulum, iaculis risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Integer sit amet orci et velit tincidunt feugiat. Vestibulum tincidunt tortor mi, a convallis arcu posuere id. Maecenas fermentum ligula sit amet volutpat consequat. In non ex massa. Duis facilisis turpis euismod leo dignissim sollicitudin et eget tellus. Nunc ut tortor malesuada, sagittis leo eu, vulputate lacus. Aenean auctor mi arcu, quis molestie tortor molestie ut. Nulla id metus molestie, interdum magna non, egestas odio. Nunc pulvinar ac mi id ultricies. Aliquam erat volutpat. Curabitur sit amet nisl a felis auctor accumsan. Pellentesque dictum lacinia velit, laoreet consectetur tellus egestas sed.

Morbi sollicitudin, quam vel ultricies placerat, dolor ligula tempor eros, et consectetur diam est vel justo. Sed scelerisque felis libero, eget faucibus mi gravida nec. Quisque non vulputate risus. Mauris condimentum nibh augue, eu bibendum est aliquam eu. Praesent a velit eu risus semper blandit vel in augue. Aenean massa dolor, fermentum eu sem ac, sollicitudin placerat erat. Donec in leo dapibus, ullamcorper urna vel, facilisis magna. Sed bibendum dui odio, ut ultricies nunc rhoncus sit amet. Nullam venenatis elit enim, non eleifend nisl pulvinar sed. Ut molestie eu justo quis ultricies. Morbi fringilla mi quis tempor cursus. Vivamus eleifend congue mi, vel posuere libero viverra ac.

Nulla vitae condimentum quam, aliquet ullamcorper lorem. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut eget congue eros, ac mollis diam. Aenean tincidunt sit amet felis non molestie. Nunc rutrum arcu vitae mattis pretium. In vitae dui elementum, condimentum arcu vitae, congue lectus. Integer gravida, dolor id luctus accumsan, purus ligula tincidunt ipsum, eget scelerisque lorem purus ut sapien. Donec a feugiat quam.

Pellentesque nec laoreet lacus. Duis in sapien eu ex faucibus dignissim. Aliquam fermentum at tortor quis hendrerit. Integer blandit quis tellus eu interdum. Morbi placerat euismod porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque vehicula libero sit amet enim egestas, pretium sollicitudin est euismod. In vitae imperdiet nisi. Sed auctor finibus lacinia. Suspendisse ultricies ultricies neque nec egestas.
</div>
15 changes: 15 additions & 0 deletions client/imports/admin/user_list.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div class="user_list">
<h1> Users </h1>

<!-- Search Items -->


<!-- List of Users -->
<ul fxLayout="column">
<li *ngFor="let user of (users | async);">
<tuxlab-user-item [user]="user"></tuxlab-user-item>
</li>
</ul>

<!-- Pagination -->
</div>
59 changes: 59 additions & 0 deletions client/imports/admin/user_list.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
div.user_list{
width: 100%;
max-width: 960px;
min-height: 900px;

margin: 30px auto;
padding: 45px;

background-color: #fff;
box-shadow:
0 -1px 1px rgba(0,0,0,0.15),
0 -10px 0 -5px #eee,
0 -10px 1px -4px rgba(0,0,0,0.15),
0 -20px 0 -10px #eee,
0 -20px 1px -9px rgba(0,0,0,0.15);
}

ul {
list-style: none !important;
padding: 20px 10px !important;
background-color: #fff !important;
}

h1{
font-weight: 300 !important;
margin: 0px !important;
}

h3{
font-size: 16px;
font-weight: 400 !important;
margin: 0px !important;
}

h4{
font-size: 16px;
font-weight: 300 !important;
margin: 0px !important;
}

h5{
font-size: 14px;
font-weight: 700 !important;
margin: 0px !important;
}

.tuxlab_user_item{
padding:5px 0px;
border-bottom: 1px solid #ccc;
}

div.expand_title{
height: 40px;
}

div.expand_container{
margin-left: 40px;
padding-bottom: 10px;
}
205 changes: 205 additions & 0 deletions client/imports/admin/user_list.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// Meteor Imports
import * as _ from "lodash";
import { Meteor } from 'meteor/meteor';
import { MeteorComponent } from 'angular2-meteor';
import { ObservableCursor } from "meteor-rxjs";
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/distinct';

// Angular Imports
import { Router, ActivatedRoute } from "@angular/router";
import { Component, Input, ChangeDetectionStrategy, NgZone } from '@angular/core';

// Define Course List Component
import template from "./user_list.component.html";
import style from "./user_list.component.scss";

// Import Course Data
import { Course } from '../../../both/models/course.model';
import { Courses } from '../../../both/collections/course.collection';

import { CourseRecord } from '../../../both/models/course_record.model';
import { CourseRecords } from '../../../both/collections/course_record.collection';

import { Session } from '../../../both/models/session.model';
import { Sessions } from '../../../both/collections/session.collection';

import { User } from '../../../both/models/user.model';
import { Users } from '../../../both/collections/user.collection';

/** USER -> COURSE -> SESSION **/
@Component({
selector: 'tuxlab-user-session-item',
template : `
A Session
`,
styles: [ style ],
changeDetection: ChangeDetectionStrategy.OnPush
})

export class UserSessionItem extends MeteorComponent {
@Input('session') session : Session;

}

/** USER -> COURSE LIST **/
@Component({
selector: 'tuxlab-user-courserecord-item',
template : `
<div fxLayout="column">
<div class="expand_title" fxLayout="row" fxLayoutAlign="start center">
<button md-icon-button (click)="expand = !expand" [ngSwitch]="expand">
<md-icon *ngSwitchCase="true">expand_less</md-icon>
<md-icon *ngSwitchCase="false">expand_more</md-icon>
</button>
<h5>{{ course?.course_name }}</h5>
</div>
<div class="expand_container" *ngIf="expand" fxLayout="column" class="course_records">
<h5> Sessions: </h5>
<ul fxLayout="column" class="sessions">
<li *ngFor="let session of (sessions | async);">
<tuxlab-user-session-item [session]="session"></tuxlab-user-session-item>
</li>
</ul>
</div>
</div>
`,
styles: [ `` ],
changeDetection: ChangeDetectionStrategy.OnPush
})

export class UserCourseRecordItem extends MeteorComponent {
@Input('user') user : User;
@Input('courserecord') course_record : CourseRecord;

private course : Course;
private sessions : ObservableCursor<Session>;

private expand : boolean = false;

constructor( private router : Router,
private route : ActivatedRoute,
private zone : NgZone ) {
super();
}

ngOnInit(){
this.zone.run(() => {

// Subscribe to Course
new Promise((resolve, reject) => {
Meteor.subscribe('courses.id', this.course_record.course_id, () => {
resolve();
})
})

// Get Course
.then(() => {
this.course = Courses.findOne({ _id : this.course_record.course_id });
})

// Subscribe to Sessions
.then(() => {
return new Promise((resolve, reject) => {
Meteor.subscribe('Sessions.userCourse', this.user._id, this.course_record.course_id, () => {
resolve();
});
})
})

// Get Sessions
.then(() => {
this.sessions = Sessions.observable.find({
user_id: this.user._id,
course_id : this.course._id
});
})
})
}
}

/** USER ITEM **/
@Component({
selector: 'tuxlab-user-item',
template : `
<div class="tuxlab_user_item" fxLayout="column">
<div class="expand_title" fxLayout="row" fxLayoutAlign="start center">
<button md-icon-button (click)="expand = !expand" [ngSwitch]="expand">
<md-icon *ngSwitchCase="true">expand_less</md-icon>
<md-icon *ngSwitchCase="false">expand_more</md-icon>
</button>
<div>
<h3>{{ user?.profile?.name }}</h3>
<h4>{{ user?.profile?.email }}</h4>
</div>
</div>
<div class="expand_container course_records" *ngIf="expand" fxLayout="column">
<br>
<ng-container [ngSwitch]="(course_records | async)?.length > 0">
<ng-container *ngSwitchCase="false">
<h5> No Courses Found </h5>
</ng-container>
<ng-container *ngSwitchCase="true">
<h5> Courses: </h5>
<ul fxLayout="column" class="course_records">
<li *ngFor="let record of (course_records | async);">
<tuxlab-user-courserecord-item [courserecord]="record" [user]="user"></tuxlab-user-courserecord-item>
</li>
</ul>
</ng-container>
</ng-container>
</div>
</div>
`,
styles: [ style ],
changeDetection: ChangeDetectionStrategy.OnPush
})

export class UserItem extends MeteorComponent {
@Input('user') user : User;
private course_records : ObservableCursor<CourseRecord>;

private expand : boolean = false;

constructor( private zone : NgZone ) {
super();
}

ngOnInit(){
Meteor.subscribe('course_records.user', this.user._id);
this.course_records = CourseRecords.observable.find({
user_id : this.user._id
});
}
}

/** USER LIST **/
@Component({
selector: 'tuxlab-user-list',
template,
styles: [ style ],
changeDetection: ChangeDetectionStrategy.OnPush
})

export class UserList extends MeteorComponent {
private users : ObservableCursor<User>;

constructor( private router : Router,
private route : ActivatedRoute,
private zone : NgZone ) {
super();
}

ngOnInit(){
Meteor.subscribe('user.all');
this.users = Users.observable.find({});
}
}
4 changes: 4 additions & 0 deletions client/imports/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ html, body, main {
font-family: 'Roboto', sans-serif;
}

h1, h2, h3, h4, h5{
font-family: 'Roboto', sans-serif !important;
}

// Override
// https://github.com/angular/material2/issues/2112
.mat-card-header-text {
Expand Down
20 changes: 18 additions & 2 deletions client/imports/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import Dashboard from './account/dashboard.component';
import Login from './account/login.component';
import { Users } from '../../both/collections/user.collection';

// Admin
import { UserList, UserItem, UserCourseRecordItem, UserSessionItem } from './admin/user_list.component';

// Course
import CourseList from './course/course_list.component';
import CourseView from './course/course_view.component';
Expand Down Expand Up @@ -52,6 +55,9 @@ export const AppRoutes : Routes = [
{ path: 'legal', component: Legal },
{ path: 'error/:error_code', component: ErrorPage },

// Admin
{ path: 'admin/users', component: UserList },

// Courses
{ path: 'explore', component: CourseList },
{ path: 'courses', component: CourseList, canActivate: [AuthGuard] },
Expand All @@ -71,14 +77,24 @@ export const AppRoutes : Routes = [
ErrorPage,
Legal,
Login,
SelectUser,

// Course
CourseList,
CourseView,
CourseViewLabItem,

// Lab
LabView,
LabTerminal,
ConnectionDetailsDialog,
MessageDialog,
CourseViewLabItem,
SelectUser

// Admin
UserList,
UserItem,
UserCourseRecordItem,
UserSessionItem
],
imports: [
RouterModule.forRoot(
Expand Down
Loading

0 comments on commit 450e7fa

Please sign in to comment.