Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All fields for student dashboard #11

Merged
merged 13 commits into from Feb 14, 2017
Merged
4 changes: 2 additions & 2 deletions app/assets/javascripts/app.js
@@ -1,4 +1,4 @@
var planner = angular.module('planner', ['ui.router', 'restangular', 'Devise']);
var planner = angular.module('planner', ['ui.router', 'restangular', 'Devise', 'ngFlash']);

planner.config(function(AuthProvider) {
AuthProvider.loginPath('/advisors/sign_in.json');
Expand All @@ -18,7 +18,7 @@ planner.run(['$rootScope', function($rootScope){
}]);

planner.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {

$urlRouterProvider.otherwise('/');

$stateProvider
Expand Down
1 change: 1 addition & 0 deletions app/assets/javascripts/application.js
Expand Up @@ -18,4 +18,5 @@
//= require restangular
//= require bootstrap-sprockets
//= require angular-devise
//= require angular-flash
//= require_tree .
31 changes: 26 additions & 5 deletions app/assets/javascripts/controllers/StudentsIndexCtrl.js
@@ -1,13 +1,21 @@
planner.controller('StudentsIndexCtrl', ['$scope', 'Restangular', 'advisors', 'students',
function($scope, Restangular, advisors, students) {
planner.controller('StudentsIndexCtrl', ['$scope', 'Restangular', 'advisors', 'students', 'Auth', 'Flash',
function($scope, Restangular, advisors, students, Auth, Flash) {

$scope.advisors = advisors;
$scope.students = students;
$scope.property = "last_name";
$scope.reverse = false;

students.forEach(function(current) { current.pinned = false; });
students[0].pinned = true;
$scope.students = students;
Auth.currentUser().then(function(advisor) {
$scope.currentAdvisor = advisor;
$scope.students.forEach(function(student) {
updatePinned(student);
});
});

var updatePinned = function(student) {
student.pinned = student.advisor.id === $scope.currentAdvisor.id;
};

$scope.alternate = function(property) {
if ($scope.property == property) {
Expand All @@ -30,5 +38,18 @@ planner.controller('StudentsIndexCtrl', ['$scope', 'Restangular', 'advisors', 's
return classString;
};

$scope.updateAdvisor = function(student) {
student.save().then(function(response) {
student.advisor_id = response.advisor_id;
student.advisor = response.advisor;
updatePinned(student);
var message = response.advisor.first_name + ' ' + response.advisor.last_name + " is now the advisor for " + student.first_name + ' ' + student.last_name;
Flash.create('success', message);
}, function(response) {
console.warn(response);
Flash.create('danger', response.statusText);
});
};

}
]);
11 changes: 8 additions & 3 deletions app/assets/stylesheets/angular_app.scss
@@ -1,3 +1,8 @@
// Place all the styles related to the angular_app controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.flash-container {
text-align: right;
position: absolute;
right: 2em;
.alert {
display: inline-block;
}
}
2 changes: 1 addition & 1 deletion app/controllers/advisors/sessions_controller.rb
Expand Up @@ -9,7 +9,7 @@ class Advisors::SessionsController < Devise::SessionsController
# POST /resource/sign_in
def create
self.resource = warden.authenticate!(auth_options)
flash[:notice] = "Welcome #{ self.resource.name }!"
# flash[:notice] = "Welcome #{ self.resource.name }!"
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
Expand Down
15 changes: 14 additions & 1 deletion app/controllers/students_controller.rb
Expand Up @@ -2,7 +2,6 @@ class StudentsController < ApplicationController

def index
@students = Student.all
render json: @students, status: 200
end

def show
Expand All @@ -13,4 +12,18 @@ def show
# renders the jbuilder
end

def update
@student = Student.find_by_id(params[:id])
if @student.update_attributes(student_params)
render json: @student.as_json(include: :advisor)
else
render json: @student.errors, status: :unprocessable_entity
end
end

private
def student_params
params.require(:student).permit(:id, :advisor_id)
end

end
7 changes: 7 additions & 0 deletions app/helpers/students_helper.rb
@@ -1,2 +1,9 @@
module StudentsHelper
def friendly_date(meeting)
if meeting.term == "ANY"
meeting.year.to_s
else
meeting.term.titleize + ' ' + meeting.year.to_s
end
end
end
2 changes: 1 addition & 1 deletion app/models/course.rb
Expand Up @@ -75,7 +75,7 @@ def create_meetings(num = 5)
num.times do |num|
current_year = Date.today.year
self.meetings.create({
term: self.term,
term: self.term.name,
session: self.sessions.sample,
year: Date.new(current_year).advance(years: num).year
})
Expand Down
1 change: 1 addition & 0 deletions app/models/meeting.rb
Expand Up @@ -10,4 +10,5 @@ class Meeting < ApplicationRecord
has_many :teachers, through: :meetings_teachers

belongs_to :course

end
16 changes: 10 additions & 6 deletions app/models/plan.rb
Expand Up @@ -13,18 +13,22 @@ class Plan < ApplicationRecord

has_many :intended_courses_plans
has_many :intended_courses, through: :intended_courses_plans

has_many :enrollments
has_many :scheduled_classes, through: :enrollments,
class_name: 'Meeting'

belongs_to :degree

def courses
{
'intended_courses': self.intended_courses,
'completed_courses': self.completed_courses,
'scheduled_classes': self.scheduled_classes
}
self.completed_courses + self.intended_courses
end

# TODO More edge case coverage
def thesis_starts
unless self.scheduled_classes.empty? || Course.thesis_writing.meetings.empty?
self.scheduled_classes.merge(Course.thesis_writing.meetings).first
end
end

end
11 changes: 11 additions & 0 deletions app/views/students/index.json.jbuilder
@@ -0,0 +1,11 @@
json.array! @students do |student|
json.extract! student, *student.attributes.keys
json.advisor student.advisor
if student.plan.concentration
json.concentration student.plan.concentration.name
json.thesis_starts friendly_date(student.plan.thesis_starts)
json.graduation_date student.plan.graduation_term.titleize + ' ' + student.plan.graduation_year.to_s
end
json.currently_registered student.plan.latest_registered
json.registration_date student.plan.registration_date
end
3 changes: 2 additions & 1 deletion app/views/students/show.json.jbuilder
@@ -1,4 +1,5 @@
json.extract! @student, *@student.attributes.keys
json.advisor @student.advisor
json.plan do
json.extract! @plan, *@plan.attributes.keys
json.term = @term
Expand All @@ -8,4 +9,4 @@ json.plan do
json.description @degree.description
json.concentrations @degree.concentrations
end
end
end
10 changes: 9 additions & 1 deletion db/seeds.rb
Expand Up @@ -204,6 +204,14 @@
plan.foreign_courses << ForeignCourse.all.sample
end

puts 'creating on-track student'
on_track = Student.last.plan
on_track.concentration = Concentration.last
on_track.completed_courses << Course.thesis_writing
on_track.scheduled_classes << Course.thesis_writing.meetings.first
on_track.save
p on_track


# degree
# terms
Expand All @@ -217,4 +225,4 @@
# categories
# foreign courses
# meetings
# plans
# plans
5 changes: 4 additions & 1 deletion public/templates/dashboard-header.html
@@ -1,8 +1,11 @@
<div class="container">

<div class="flash-container">
<flash-message></flash-message>
</div>
<h2>Dashboard</h2>

<a ui-sref="dashboard.students">Students</a>
<a ui-sref="dashboard.meetings">Classes</a>
<a ui-sref="dashboard.meetings">Classes</a>

</div>
18 changes: 12 additions & 6 deletions public/templates/students.html
Expand Up @@ -7,21 +7,27 @@ <h2>Students</h2>
<th class="sortable" ng-class="sortableClasses('last_name')" ng-click="alternate('last_name')">Last name</th>
<th class="sortable" ng-class="sortableClasses('concentration')" ng-click="alternate('concentration')">Concentration</th>
<th class="sortable" ng-class="sortableClasses('thesis_starts')" ng-click="alternate('thesis_starts')">Thesis starts</th>
<th class="sortable" ng-class="sortableClasses('comp_date')" ng-click="alternate('comp_date')">Comp date</th>
<th class="sortable" ng-class="sortableClasses('graduation')" ng-click="alternate('graduation')">Graduation</th>
<th class="sortable" ng-class="sortableClasses('graduation_date')" ng-click="alternate('graduation_date')">Graduation</th>
<th class="sortable" ng-class="sortableClasses('currently_registered')" ng-click="alternate('currently_registered')">Now registered?</th>
<th class="sortable" ng-class="sortableClasses('registration_date')" ng-click="alternate('registration_date')">Registration date</th>
</thead>
<tbody>
<tr ng-repeat="student in students | orderBy: ['-pinned', property]">
<td>
<select ng-model="student.advisor" ng-options="advisor.id as advisor.first_name for advisor in advisors"></select>
<select
ng-model="student.advisor_id"
ng-options="advisor.id as (advisor.first_name + ' ' + advisor.last_name) for advisor in advisors"
ng-change="updateAdvisor(student)">
</select>
<span class="glyphicon glyphicon-star" ng-show="student.pinned"></span>
</td>
<td><a ui-sref="ips.choose({ student_id: student.id })">{{ student.first_name }}</a></td>
<td>{{ student.last_name }}</td>
<td>{{ student.concentration }}</td>
<td>{{ student.thesisStarts }}</td>
<td>{{ student.compDate }}</td>
<td>{{ student.graduationDate }}</td>
<td>{{ student.thesis_starts }}</td>
<td>{{ student.graduation_date }}</td>
<td>{{ student.currently_registered ? "Yes" : "" }}</td>
<td>{{ student.registration_date }}</td>
</tr>
</tbody>
</table>