Browse Source

I forgot to commit

Maarten van den Berg 8 years ago
parent
commit
5248c6210f
51 changed files with 925 additions and 19 deletions
  1. 3 0
      app/assets/javascripts/dashboard.coffee
  2. 8 0
      app/assets/stylesheets/application.scss
  3. 3 0
      app/assets/stylesheets/dashboard.scss
  4. 1 1
      app/assets/stylesheets/void.scss
  5. 11 1
      app/controllers/authentication_controller.rb
  6. 8 0
      app/controllers/dashboard_controller.rb
  7. 82 0
      app/controllers/groups_controller.rb
  8. 86 0
      app/controllers/members_controller.rb
  9. 90 0
      app/controllers/people_controller.rb
  10. 66 8
      app/helpers/authentication_helper.rb
  11. 2 0
      app/helpers/dashboard_helper.rb
  12. 19 0
      app/helpers/groups_helper.rb
  13. 2 0
      app/helpers/members_helper.rb
  14. 2 0
      app/helpers/people_helper.rb
  15. 3 0
      app/models/activity.rb
  16. 8 0
      app/models/group.rb
  17. 13 2
      app/models/person.rb
  18. 53 0
      app/views/dashboard/home.html.haml
  19. 17 0
      app/views/groups/_form.html.erb
  20. 2 0
      app/views/groups/_group.json.jbuilder
  21. 6 0
      app/views/groups/edit.html.erb
  22. 28 0
      app/views/groups/index.html.erb
  23. 1 0
      app/views/groups/index.json.jbuilder
  24. 5 0
      app/views/groups/new.html.erb
  25. 26 0
      app/views/groups/show.html.erb
  26. 1 0
      app/views/groups/show.json.jbuilder
  27. 10 0
      app/views/groups/user_groups.html.haml
  28. 5 1
      app/views/layouts/application.html.erb
  29. 19 0
      app/views/members/_form.html.erb
  30. 2 0
      app/views/members/_member.json.jbuilder
  31. 6 0
      app/views/members/edit.html.erb
  32. 25 0
      app/views/members/index.html.erb
  33. 1 0
      app/views/members/index.json.jbuilder
  34. 5 0
      app/views/members/new.html.erb
  35. 5 0
      app/views/members/show.html.erb
  36. 1 0
      app/views/members/show.json.jbuilder
  37. 37 0
      app/views/people/_form.html.erb
  38. 2 0
      app/views/people/_person.json.jbuilder
  39. 6 0
      app/views/people/edit.html.erb
  40. 26 0
      app/views/people/index.html.erb
  41. 1 0
      app/views/people/index.json.jbuilder
  42. 5 0
      app/views/people/new.html.erb
  43. 7 0
      app/views/people/show.html.erb
  44. 1 0
      app/views/people/show.json.jbuilder
  45. 5 4
      app/views/shared/_alerts.html.haml
  46. 43 0
      app/views/shared/_menu.html.haml
  47. 14 2
      config/routes.rb
  48. 9 0
      test/controllers/dashboard_controller_test.rb
  49. 48 0
      test/controllers/groups_controller_test.rb
  50. 48 0
      test/controllers/members_controller_test.rb
  51. 48 0
      test/controllers/people_controller_test.rb

+ 3 - 0
app/assets/javascripts/dashboard.coffee

@@ -0,0 +1,3 @@
1
+# Place all the behaviors and hooks related to the matching controller here.
2
+# All this logic will automatically be available in application.js.
3
+# You can use CoffeeScript in this file: http://coffeescript.org/

+ 8 - 0
app/assets/stylesheets/application.scss

@@ -16,6 +16,9 @@
16 16
 @import "bootstrap-sprockets";
17 17
 @import "bootstrap";
18 18
 
19
+@import "font-awesome-sprockets";
20
+@import "font-awesome";
21
+
19 22
 /* Horizontally distribute ul items.
20 23
  *
21 24
  * Adapted from the following StackOverflow answer:
@@ -47,3 +50,8 @@ ul.hdis li {
47 50
     top: 1.25em;
48 51
 }
49 52
 /* End of CC-BY-SA code. */
53
+
54
+/* Don't overlap with the menu. */
55
+body {
56
+  padding-top: 70px;
57
+}

+ 3 - 0
app/assets/stylesheets/dashboard.scss

@@ -0,0 +1,3 @@
1
+// Place all the styles related to the Dashboard controller here.
2
+// They will automatically be included in application.css.
3
+// You can use Sass (SCSS) here: http://sass-lang.com/

+ 1 - 1
app/assets/stylesheets/void.scss

@@ -1,4 +1,4 @@
1
-body {
1
+body.void {
2 2
 	padding-top: 		40px;
3 3
 	padding-bottom: 	40px;
4 4
 	background-color: 	#eee;

+ 11 - 1
app/controllers/authentication_controller.rb

@@ -6,6 +6,7 @@ class AuthenticationController < ApplicationController
6 6
   def login
7 7
     if params[:session][:email].blank? || params[:session][:password].blank?
8 8
       flash[:warning] = "You forgot to add value"
9
+      redirect_to action: 'login_form'
9 10
     else
10 11
       u = User.find_by(email: params[:session][:email])
11 12
 
@@ -13,12 +14,21 @@ class AuthenticationController < ApplicationController
13 14
         log_in(u, params[:session][:remember_me].to_i)
14 15
 
15 16
         flash[:success] = "Hello, #{u.person.full_name}!"
17
+        redirect_to dashboard_home_path
16 18
       else
17 19
         flash[:danger] = "Invalid username/password combination!"
20
+        redirect_to action: 'login_form'
18 21
       end
19 22
     end
23
+  end
24
+
25
+  def logout_form
26
+    render layout: 'void'
27
+  end
20 28
 
21
-    redirect_to action: 'login_form'
29
+  def logout
30
+    log_out
31
+    redirect_to login_path
22 32
   end
23 33
 
24 34
   def create_password_form

+ 8 - 0
app/controllers/dashboard_controller.rb

@@ -0,0 +1,8 @@
1
+class DashboardController < ApplicationController
2
+  before_action :require_login!
3
+
4
+  def home
5
+    @user_organized = current_person.activities.where(is_organizer: true)
6
+    @need_response = current_person.activities.includes(:participants)
7
+  end
8
+end

+ 82 - 0
app/controllers/groups_controller.rb

@@ -0,0 +1,82 @@
1
+class GroupsController < ApplicationController
2
+  include GroupsHelper
3
+  before_action :require_admin!, only: [:index]
4
+  before_action :require_membership!, only: [:show]
5
+  before_action :require_leader!, only: [:edit, :update, :destroy]
6
+  before_action :set_group, only: [:show, :edit, :update, :destroy]
7
+
8
+  # GET /groups
9
+  # GET /groups.json
10
+  def index
11
+    @groups = Group.all
12
+  end
13
+
14
+  def user_groups
15
+    @groups = current_person.groups
16
+  end
17
+
18
+  # GET /groups/1
19
+  # GET /groups/1.json
20
+  def show
21
+  end
22
+
23
+  # GET /groups/new
24
+  def new
25
+    @group = Group.new
26
+  end
27
+
28
+  # GET /groups/1/edit
29
+  def edit
30
+  end
31
+
32
+  # POST /groups
33
+  # POST /groups.json
34
+  def create
35
+    @group = Group.new(group_params)
36
+
37
+    respond_to do |format|
38
+      if @group.save
39
+        format.html { redirect_to @group, notice: 'Group was successfully created.' }
40
+        format.json { render :show, status: :created, location: @group }
41
+      else
42
+        format.html { render :new }
43
+        format.json { render json: @group.errors, status: :unprocessable_entity }
44
+      end
45
+    end
46
+  end
47
+
48
+  # PATCH/PUT /groups/1
49
+  # PATCH/PUT /groups/1.json
50
+  def update
51
+    respond_to do |format|
52
+      if @group.update(group_params)
53
+        format.html { redirect_to @group, notice: 'Group was successfully updated.' }
54
+        format.json { render :show, status: :ok, location: @group }
55
+      else
56
+        format.html { render :edit }
57
+        format.json { render json: @group.errors, status: :unprocessable_entity }
58
+      end
59
+    end
60
+  end
61
+
62
+  # DELETE /groups/1
63
+  # DELETE /groups/1.json
64
+  def destroy
65
+    @group.destroy
66
+    respond_to do |format|
67
+      format.html { redirect_to groups_url, notice: 'Group was successfully destroyed.' }
68
+      format.json { head :no_content }
69
+    end
70
+  end
71
+
72
+  private
73
+    # Use callbacks to share common setup or constraints between actions.
74
+    def set_group
75
+      @group = Group.find(params[:id])
76
+    end
77
+
78
+    # Never trust parameters from the scary internet, only allow the white list through.
79
+    def group_params
80
+      params.fetch(:group, {})
81
+    end
82
+end

+ 86 - 0
app/controllers/members_controller.rb

@@ -0,0 +1,86 @@
1
+class MembersController < ApplicationController
2
+  include GroupsHelper
3
+  before_action :set_group
4
+  before_action :set_member, only: [:show, :edit, :update, :destroy]
5
+  before_action :require_leader!
6
+
7
+  # GET /members
8
+  # GET /members.json
9
+  def index
10
+    @members = Member.all
11
+  end
12
+
13
+  # GET /members/1
14
+  # GET /members/1.json
15
+  def show
16
+  end
17
+
18
+  # GET /members/new
19
+  def new
20
+    @member = Member.new
21
+    @possible_members = Person.where.not(id: @group.person_ids)
22
+  end
23
+
24
+  # GET /members/1/edit
25
+  def edit
26
+    @possible_members = Person.where.not(id: @group.person_ids)
27
+  end
28
+
29
+  # POST /members
30
+  # POST /members.json
31
+  def create
32
+    @member = Member.new(member_params)
33
+    @member.group = @group
34
+
35
+    respond_to do |format|
36
+      if @member.save
37
+        format.html { redirect_to group_member_url(@group, @member), notice: 'Member was successfully created.' }
38
+        format.json { render :show, status: :created, location: @member }
39
+      else
40
+        @possible_members = Person.where.not(id: @group.person_ids)
41
+        format.html { render :new }
42
+        format.json { render json: @member.errors, status: :unprocessable_entity }
43
+      end
44
+    end
45
+  end
46
+
47
+  # PATCH/PUT /members/1
48
+  # PATCH/PUT /members/1.json
49
+  def update
50
+    respond_to do |format|
51
+      if @member.update(member_params)
52
+        format.html { redirect_to group_member_url(@group, @member), notice: 'Member was successfully updated.' }
53
+        format.json { render :show, status: :ok, location: @member }
54
+      else
55
+        @possible_members = Person.where.not(id: @group.person_ids)
56
+        format.html { render :edit }
57
+        format.json { render json: @member.errors, status: :unprocessable_entity }
58
+      end
59
+    end
60
+  end
61
+
62
+  # DELETE /members/1
63
+  # DELETE /members/1.json
64
+  def destroy
65
+    @member.destroy
66
+    respond_to do |format|
67
+      format.html { redirect_to group_members_url(@group), notice: 'Member was successfully destroyed.' }
68
+      format.json { head :no_content }
69
+    end
70
+  end
71
+
72
+  private
73
+    # Use callbacks to share common setup or constraints between actions.
74
+    def set_member
75
+      @member = Member.find(params[:id])
76
+    end
77
+
78
+    def set_group
79
+      @group = Group.find(params[:group_id])
80
+    end
81
+
82
+    # Never trust parameters from the scary internet, only allow the white list through.
83
+    def member_params
84
+      params.require(:member).permit(:person_id, :is_leader)
85
+    end
86
+end

+ 90 - 0
app/controllers/people_controller.rb

@@ -0,0 +1,90 @@
1
+class PeopleController < ApplicationController
2
+  before_action :set_person, only: [:show, :edit, :update, :destroy]
3
+  before_action :require_login!
4
+  before_action :require_admin!, except: [:show]
5
+
6
+  # GET /people
7
+  # GET /people.json
8
+  def index
9
+    @people = Person.all
10
+  end
11
+
12
+  # GET /people/1
13
+  # GET /people/1.json
14
+  def show
15
+    if @person != current_person
16
+      require_admin!
17
+    end
18
+  end
19
+
20
+  # GET /people/new
21
+  def new
22
+    @person = Person.new
23
+  end
24
+
25
+  # GET /people/1/edit
26
+  def edit
27
+  end
28
+
29
+  # POST /people
30
+  # POST /people.json
31
+  def create
32
+    @person = Person.new(person_params)
33
+
34
+    respond_to do |format|
35
+      if @person.save
36
+        format.html do
37
+          flash[:success] = "Person was successfully created."
38
+          redirect_to @person
39
+        end
40
+        format.json { render :show, status: :created, location: @person }
41
+      else
42
+        format.html { render :new }
43
+        format.json { render json: @person.errors, status: :unprocessable_entity }
44
+      end
45
+    end
46
+  end
47
+
48
+  # PATCH/PUT /people/1
49
+  # PATCH/PUT /people/1.json
50
+  def update
51
+    respond_to do |format|
52
+      if @person.update(person_params)
53
+        format.html do
54
+          flash[:success] = "Person was successfully updated."
55
+          redirect_to @person
56
+        end
57
+
58
+        format.json { render :show, status: :ok, location: @person }
59
+      else
60
+        format.html { render :edit }
61
+        format.json { render json: @person.errors, status: :unprocessable_entity }
62
+      end
63
+    end
64
+  end
65
+
66
+  # DELETE /people/1
67
+  # DELETE /people/1.json
68
+  def destroy
69
+    @person.destroy
70
+    respond_to do |format|
71
+      format.html do
72
+        flash[:success] = 'Person was successfully destroyed.'
73
+        redirect_to people_url
74
+      end
75
+
76
+      format.json { head :no_content }
77
+    end
78
+  end
79
+
80
+  private
81
+    # Use callbacks to share common setup or constraints between actions.
82
+    def set_person
83
+      @person = Person.find(params[:id])
84
+    end
85
+
86
+    # Never trust parameters from the scary internet, only allow the white list through.
87
+    def person_params
88
+      params.require(:person).permit(:first_name, :infix, :last_name, :email, :birth_date, :is_admin)
89
+    end
90
+end

+ 66 - 8
app/helpers/authentication_helper.rb

@@ -1,4 +1,5 @@
1 1
 module AuthenticationHelper
2
+  # Create a new Session and set the relevant cookies.
2 3
   def log_in(user, remember, new=true)
3 4
     reset_session
4 5
 
@@ -9,8 +10,14 @@ module AuthenticationHelper
9 10
     if new
10 11
       if remember == 1
11 12
         token = Session.new_token
12
-        cookies.signed.permanent[:remember_token] = token
13
-        cookies.signed.permanent[:user_id] = user.id
13
+        cookies.signed.permanent[:remember_token] = {
14
+          value: token,
15
+          httponly: true
16
+        }
17
+        cookies.signed.permanent[:user_id] = {
18
+          value: user.id,
19
+          httponly: true
20
+        }
14 21
       else
15 22
         token = nil
16 23
       end
@@ -21,11 +28,30 @@ module AuthenticationHelper
21 28
         remember_digest: token ? Session.digest(token) : nil
22 29
       )
23 30
       if remember
24
-        cookies.signed.permanent[:session_id] = s.id
31
+        cookies.signed.permanent[:session_id] = {
32
+          value: s.id,
33
+          httponly: true
34
+        }
25 35
       end
26 36
     end
27 37
   end
28 38
 
39
+  # Determine whether the user is logged in, and if so, disable the Session, then flush session cookies.
40
+  def log_out
41
+    if is_logged_in?
42
+      get_user_session
43
+
44
+      @user_session.update!(active: false)
45
+    end
46
+
47
+    cookies.delete(:user_id)
48
+    cookies.delete(:remember_token)
49
+    cookies.delete(:session_id)
50
+    reset_session
51
+  end
52
+
53
+  # Determine whether the current request is from a user with a non-expired session.
54
+  # Makes @user_session available as a side effect if the user is not.
29 55
   def is_logged_in?
30 56
     # Case 1: User has an active session inside the cookie.
31 57
     # We verify that the session hasn't expired yet.
@@ -39,16 +65,16 @@ module AuthenticationHelper
39 65
       if cookies.signed.permanent[:remember_token] && cookies.signed.permanent[:user_id] &&
40 66
           cookies.signed.permanent[:session_id]
41 67
 
42
-        s = Session.find_by(
43
-          id: cookies.signed.permanent[:session_id]
44
-        )
45
-        if s.nil? || s.remember_digest.nil?
68
+        get_user_session
69
+
70
+        if @user_session.nil? || @user_session.remember_digest.nil?
46 71
           return false
47 72
         end
48 73
 
49 74
         session_password = BCrypt::Password.new s.remember_digest
50 75
 
51
-        if s.expires > DateTime.now && session_password == cookies.signed.permanent[:remember_token]
76
+        if @user_session.expires > DateTime.now &&
77
+            session_password == cookies.signed.permanent[:remember_token]
52 78
           log_in s.user, false, false
53 79
           return true
54 80
         end
@@ -57,8 +83,40 @@ module AuthenticationHelper
57 83
       end
58 84
 
59 85
     return false
86
+    end
87
+  end
88
+
89
+  # Get the Session object representing the current user's session.
90
+  def get_user_session
91
+    if @user_session
92
+      @user_session
93
+    else
94
+      @user_session ||= Session.find_by(
95
+        id: cookies.signed.permanent[:session_id]
96
+      )
97
+    end
98
+  end
99
+
100
+  def current_user
101
+    get_user_session
102
+    @user_session.user
103
+  end
104
+
105
+  def current_person
106
+    current_user.person
107
+  end
60 108
 
109
+  def require_login!
110
+    if !is_logged_in?
111
+      flash[:warning] = "You need to be logged in to do that."
112
+      redirect_to controller: 'authentication', action: 'login_form'
61 113
     end
62 114
   end
63 115
 
116
+  def require_admin!
117
+    if !current_person.is_admin?
118
+      flash[:danger] = "You need to be an administrator to do that."
119
+      redirect_to '/dashboard'
120
+    end
121
+  end
64 122
 end

+ 2 - 0
app/helpers/dashboard_helper.rb

@@ -0,0 +1,2 @@
1
+module DashboardHelper
2
+end

+ 19 - 0
app/helpers/groups_helper.rb

@@ -0,0 +1,19 @@
1
+module GroupsHelper
2
+  def require_membership!
3
+    require_login!
4
+    if !(Member.exists?(group: @group, person: current_person) || current_person.is_admin?)
5
+      flash[:danger] = "You need to be a member of that group to do that."
6
+      redirect_to dashboard_url
7
+    end
8
+  end
9
+
10
+  def require_leader!
11
+    require_login!
12
+
13
+    if !(Member.exists?(group: @group, is_leader: true, person: current_person) ||
14
+         current_person.is_admin?)
15
+      flash[:danger] = "You need to be a group leader to do that."
16
+      redirect_to dashboard_url
17
+    end
18
+  end
19
+end

+ 2 - 0
app/helpers/members_helper.rb

@@ -0,0 +1,2 @@
1
+module MembersHelper
2
+end

+ 2 - 0
app/helpers/people_helper.rb

@@ -0,0 +1,2 @@
1
+module PeopleHelper
2
+end

+ 3 - 0
app/models/activity.rb

@@ -1,3 +1,6 @@
1 1
 class Activity < ApplicationRecord
2 2
   belongs_to :group
3
+
4
+  has_many :participants
5
+  has_many :people, through: :participants
3 6
 end

+ 8 - 0
app/models/group.rb

@@ -1,2 +1,10 @@
1 1
 class Group < ApplicationRecord
2
+  has_many :members
3
+  has_many :people, through: :members
4
+
5
+  has_many :activities
6
+
7
+  def leaders
8
+    self.members.where(is_leader: true)
9
+  end
2 10
 end

+ 13 - 2
app/models/person.rb

@@ -1,10 +1,13 @@
1 1
 class Person < ApplicationRecord
2 2
   has_one :user
3
+  has_many :members
4
+  has_many :participants
5
+  has_many :groups, through: :members
6
+  has_many :activities, through: :participants
3 7
 
4 8
   validates :email, presence: true, uniqueness: true
5 9
   validates :first_name, presence: true
6 10
   validates :last_name, presence: true
7
-  validates :is_admin, presence: true
8 11
 
9 12
   validate :birth_date_cannot_be_in_future
10 13
 
@@ -19,9 +22,17 @@ class Person < ApplicationRecord
19 22
     end
20 23
   end
21 24
 
25
+  def reversed_name
26
+    if self.infix
27
+      [self.last_name, self.infix, self.first_name].join(', ')
28
+    else
29
+      [self.last_name, self.first_name].join(', ')
30
+    end
31
+  end
32
+
22 33
   private
23 34
   def birth_date_cannot_be_in_future
24
-    if self.birth_date > Date.today
35
+    if self.birth_date && self.birth_date > Date.today
25 36
       errors.add(:birth_date, "can't be in the future.")
26 37
     end
27 38
   end

+ 53 - 0
app/views/dashboard/home.html.haml

@@ -0,0 +1,53 @@
1
+.container
2
+  .row
3
+    - if @need_response.any?
4
+      .col-md.12
5
+        .panel.panel-default
6
+          .panel-heading
7
+            Need response
8
+
9
+          .panel-body
10
+            %table.table.table-bordered
11
+              %thead
12
+                %tr
13
+                  %th
14
+                    Name
15
+                  %th
16
+                    Group
17
+                  %th
18
+                    When
19
+                  %th
20
+                    Where
21
+                  %th
22
+                    Actions
23
+
24
+              %tbody
25
+                - @need_response.each do |e|
26
+                  %tr
27
+                    %td
28
+                      - if e.secret_name && e.participants.first.is_organizer
29
+                        = e.secret_name
30
+                      = e.public_name
31
+                    %td
32
+                      = e.group.name
33
+                    %td
34
+                      = e.start
35
+                    %td
36
+                      = e.location
37
+                    %td
38
+    .col-md-6
39
+      .panel.panel-default
40
+        .panel-heading
41
+          Groups
42
+
43
+        .panel-body
44
+          %table.table.table-bordered
45
+            %tbody
46
+              - current_person.groups.each do |group|
47
+                %tr
48
+                  %td
49
+                    = link_to group do
50
+                      = group.name
51
+
52
+    .col-md-6
53
+      TODO

+ 17 - 0
app/views/groups/_form.html.erb

@@ -0,0 +1,17 @@
1
+<%= form_for(group) do |f| %>
2
+  <% if group.errors.any? %>
3
+    <div id="error_explanation">
4
+      <h2><%= pluralize(group.errors.count, "error") %> prohibited this group from being saved:</h2>
5
+
6
+      <ul>
7
+      <% group.errors.full_messages.each do |message| %>
8
+        <li><%= message %></li>
9
+      <% end %>
10
+      </ul>
11
+    </div>
12
+  <% end %>
13
+
14
+  <div class="actions">
15
+    <%= f.submit %>
16
+  </div>
17
+<% end %>

+ 2 - 0
app/views/groups/_group.json.jbuilder

@@ -0,0 +1,2 @@
1
+json.extract! group, :id, :created_at, :updated_at
2
+json.url group_url(group, format: :json)

+ 6 - 0
app/views/groups/edit.html.erb

@@ -0,0 +1,6 @@
1
+<h1>Editing Group</h1>
2
+
3
+<%= render 'form', group: @group %>
4
+
5
+<%= link_to 'Show', @group %> |
6
+<%= link_to 'Back', groups_path %>

+ 28 - 0
app/views/groups/index.html.erb

@@ -0,0 +1,28 @@
1
+<p id="notice"><%= notice %></p>
2
+
3
+<h1>Groups</h1>
4
+
5
+<table class="table">
6
+  <thead>
7
+    <tr>
8
+      <th>Name</th>
9
+      <th>Members</th>
10
+      <th>Events</th>
11
+      <th colspan="2">Actions</th>
12
+    </tr>
13
+  </thead>
14
+
15
+  <tbody>
16
+    <% @groups.each do |group| %>
17
+      <tr>
18
+        <td><%= link_to group.name, group %></td>
19
+        <td><%= link_to 'Edit', edit_group_path(group) %></td>
20
+        <td><%= link_to 'Destroy', group, method: :delete, data: { confirm: 'Are you sure?' } %></td>
21
+      </tr>
22
+    <% end %>
23
+  </tbody>
24
+</table>
25
+
26
+<br>
27
+
28
+<%= link_to 'New Group', new_group_path %>

+ 1 - 0
app/views/groups/index.json.jbuilder

@@ -0,0 +1 @@
1
+json.array! @groups, partial: 'groups/group', as: :group

+ 5 - 0
app/views/groups/new.html.erb

@@ -0,0 +1,5 @@
1
+<h1>New Group</h1>
2
+
3
+<%= render 'form', group: @group %>
4
+
5
+<%= link_to 'Back', groups_path %>

+ 26 - 0
app/views/groups/show.html.erb

@@ -0,0 +1,26 @@
1
+<h2><%= @group.name %></h2>
2
+
3
+<h3>Members</h3>
4
+<ul>
5
+  <% @group.members.each do |m| %>
6
+    <li>
7
+      <% if m.is_leader %>
8
+        <i class="fa fa-angle-up"></i>
9
+      <% end %>
10
+      <%= m.person.full_name %>
11
+    </li>
12
+  <% end %>
13
+</ul>
14
+<%= link_to 'Manage members', group_members_path(@group) %>
15
+
16
+<h3>Events</h3>
17
+<ul>
18
+  <% @group.activities.each do |e| %>
19
+    <li>
20
+      <%= e.public_name %>
21
+    </li>
22
+  <% end %>
23
+</ul>
24
+
25
+<%= link_to 'Edit', edit_group_path(@group) %> |
26
+<%= link_to 'Back', groups_path %>

+ 1 - 0
app/views/groups/show.json.jbuilder

@@ -0,0 +1 @@
1
+json.partial! "groups/group", group: @group

+ 10 - 0
app/views/groups/user_groups.html.haml

@@ -0,0 +1,10 @@
1
+.container
2
+  %h1
3
+    My groups
4
+
5
+  %table.table.table-striped
6
+    %tbody
7
+      - @groups.each do |g|
8
+        %tr
9
+          %td
10
+            = link_to g.name, g

+ 5 - 1
app/views/layouts/application.html.erb

@@ -9,6 +9,10 @@
9 9
   </head>
10 10
 
11 11
   <body>
12
-    <%= yield %>
12
+    <%= render 'shared/menu' %>
13
+    <%= render 'shared/alerts' %>
14
+    <div class="container">
15
+      <%= yield %>
16
+    </div>
13 17
   </body>
14 18
 </html>

+ 19 - 0
app/views/members/_form.html.erb

@@ -0,0 +1,19 @@
1
+<%= form_for([@group, member]) do |f| %>
2
+  <% if member.errors.any? %>
3
+    <div id="error_explanation">
4
+      <h2><%= pluralize(member.errors.count, "error") %> prohibited this member from being saved:</h2>
5
+
6
+      <ul>
7
+      <% member.errors.full_messages.each do |message| %>
8
+        <li><%= message %></li>
9
+      <% end %>
10
+      </ul>
11
+    </div>
12
+  <% end %>
13
+
14
+  <div class="actions">
15
+    <%= f.collection_select(:person_id, @possible_members, :id, :full_name, prompt: true) %>
16
+    <%= f.check_box :is_leader %> Beheerder
17
+    <%= f.submit %>
18
+  </div>
19
+<% end %>

+ 2 - 0
app/views/members/_member.json.jbuilder

@@ -0,0 +1,2 @@
1
+json.extract! member, :id, :created_at, :updated_at
2
+json.url member_url(member, format: :json)

+ 6 - 0
app/views/members/edit.html.erb

@@ -0,0 +1,6 @@
1
+<h1>Editing Member</h1>
2
+
3
+<%= render 'form', member: @member %>
4
+
5
+<%= link_to 'Show', group_member_path(@group, @member) %> |
6
+<%= link_to 'Back', group_members_path(@group) %>

+ 25 - 0
app/views/members/index.html.erb

@@ -0,0 +1,25 @@
1
+<p id="notice"><%= notice %></p>
2
+
3
+<h1>Members</h1>
4
+
5
+<table>
6
+  <thead>
7
+    <tr>
8
+      <th colspan="3"></th>
9
+    </tr>
10
+  </thead>
11
+
12
+  <tbody>
13
+    <% @members.each do |member| %>
14
+      <tr>
15
+        <td><%= link_to member.person.full_name, group_member_path(@group, member) %></td>
16
+        <td><%= link_to 'Edit', edit_group_member_path(@group, member) %></td>
17
+        <td><%= link_to 'Destroy', group_member_path(@group, member), method: :delete, data: { confirm: 'Are you sure?' } %></td>
18
+      </tr>
19
+    <% end %>
20
+  </tbody>
21
+</table>
22
+
23
+<br>
24
+
25
+<%= link_to 'New Member', new_group_member_path(@group) %>

+ 1 - 0
app/views/members/index.json.jbuilder

@@ -0,0 +1 @@
1
+json.array! @members, partial: 'members/member', as: :member

+ 5 - 0
app/views/members/new.html.erb

@@ -0,0 +1,5 @@
1
+<h1>Add member to <%= @group.name %></h1>
2
+
3
+<%= render 'form', member: @member %>
4
+
5
+<%= link_to 'Back', group_members_path(@group) %>

+ 5 - 0
app/views/members/show.html.erb

@@ -0,0 +1,5 @@
1
+<p id="notice"><%= notice %></p>
2
+
3
+<%= @member.person.full_name %> is lid van <%= @group.name %>.
4
+<%= link_to 'Edit', edit_group_member_path(@group, @member) %> |
5
+<%= link_to 'Back', group_members_path(@group) %>

+ 1 - 0
app/views/members/show.json.jbuilder

@@ -0,0 +1 @@
1
+json.partial! "members/member", member: @member

+ 37 - 0
app/views/people/_form.html.erb

@@ -0,0 +1,37 @@
1
+<%= form_for(person) do |f| %>
2
+  <% if person.errors.any? %>
3
+    <div id="error_explanation">
4
+      <h2><%= pluralize(person.errors.count, "error") %> prohibited this person from being saved:</h2>
5
+
6
+      <ul>
7
+      <% person.errors.full_messages.each do |message| %>
8
+        <li><%= message %></li>
9
+      <% end %>
10
+      </ul>
11
+    </div>
12
+  <% end %>
13
+
14
+  <div class="actions">
15
+    <div class="form-group">
16
+      <%= f.label :first_name %>
17
+      <%= f.text_field :first_name, class: 'form-control' %>
18
+      <%= f.label :infix %>
19
+      <%= f.text_field :infix, class: 'form-control' %>
20
+      <%= f.label :last_name %>
21
+      <%= f.text_field :last_name, class: 'form-control' %>
22
+    </div>
23
+    <div class="form-group">
24
+      <%= f.label :email %>
25
+      <%= f.email_field :email, class: 'form-control' %>
26
+    </div>
27
+    <div class="form-group">
28
+      <%= f.label :birth_date %>
29
+      <%= f.date_field :birth_date, type: 'date', class: 'form-control' %>
30
+    </div>
31
+    <div class="form-group">
32
+      <%= f.check_box :is_admin %>
33
+      <%= f.label :is_admin %>
34
+    </div>
35
+    <%= f.submit %>
36
+  </div>
37
+<% end %>

+ 2 - 0
app/views/people/_person.json.jbuilder

@@ -0,0 +1,2 @@
1
+json.extract! person, :id, :created_at, :updated_at
2
+json.url person_url(person, format: :json)

+ 6 - 0
app/views/people/edit.html.erb

@@ -0,0 +1,6 @@
1
+<h1>Editing Person</h1>
2
+
3
+<%= render 'form', person: @person %>
4
+
5
+<%= link_to 'Show', @person %> |
6
+<%= link_to 'Back', people_path %>

+ 26 - 0
app/views/people/index.html.erb

@@ -0,0 +1,26 @@
1
+<p id="notice"><%= notice %></p>
2
+
3
+<h1>People</h1>
4
+
5
+<table class="table">
6
+  <thead>
7
+    <tr>
8
+      <th colspan="4"></th>
9
+    </tr>
10
+  </thead>
11
+
12
+  <tbody>
13
+    <% @people.each do |person| %>
14
+      <tr>
15
+        <td><%= person.full_name %></td>
16
+        <td><%= link_to 'Show', person %></td>
17
+        <td><%= link_to 'Edit', edit_person_path(person) %></td>
18
+        <td><%= link_to 'Destroy', person, method: :delete, data: { confirm: 'Are you sure?' } %></td>
19
+      </tr>
20
+    <% end %>
21
+  </tbody>
22
+</table>
23
+
24
+<br>
25
+
26
+<%= link_to 'New Person', new_person_path %>

+ 1 - 0
app/views/people/index.json.jbuilder

@@ -0,0 +1 @@
1
+json.array! @people, partial: 'people/person', as: :person

+ 5 - 0
app/views/people/new.html.erb

@@ -0,0 +1,5 @@
1
+<h1>New Person</h1>
2
+
3
+<%= render 'form', person: @person %>
4
+
5
+<%= link_to 'Back', people_path %>

+ 7 - 0
app/views/people/show.html.erb

@@ -0,0 +1,7 @@
1
+<h2><%= @person.reversed_name %></h2>
2
+<ul>
3
+  <li><%= @person.birth_date %></li>
4
+  <li><%= @person.email %></li>
5
+</ul>
6
+<%= link_to 'Edit', edit_person_path(@person) %> |
7
+<%= link_to 'Back', people_path %>

+ 1 - 0
app/views/people/show.json.jbuilder

@@ -0,0 +1 @@
1
+json.partial! "people/person", person: @person

+ 5 - 4
app/views/shared/_alerts.html.haml

@@ -1,4 +1,5 @@
1
-.alerts
2
-  - flash.each do |name, msg|
3
-    %div{class: "alert alert-#{name}"}
4
-      = msg
1
+.container
2
+  .alerts
3
+    - flash.each do |name, msg|
4
+      %div{class: "alert alert-#{name}"}
5
+        = msg

+ 43 - 0
app/views/shared/_menu.html.haml

@@ -0,0 +1,43 @@
1
+%nav.navbar.navbar-default.navbar-fixed-top
2
+  .container
3
+    .navbar-header
4
+      %button.navbar-toggle.collapsed{type: 'button', data: {toggle: 'collapse', target: '#navbar'}, 'aria-expanded': false, 'aria-controls': 'navbar'}
5
+        .sr-only
6
+          inklappen enzo
7
+        .icon-bar
8
+        .icon-bar
9
+        .icon-bar
10
+      = link_to root_path, class: 'navbar-brand' do
11
+        Damena
12
+
13
+    .navbar-collapse.collapse#navbar
14
+      %ul.nav.navbar-nav
15
+        %li
16
+          = link_to root_path do
17
+            %i.fa.fa-home{'aria-hidden': true}
18
+            Home
19
+
20
+        %li
21
+          = link_to user_groups_path do
22
+            %i.fa.fa-users{'aria-hidden': true}
23
+            Groups
24
+
25
+        - if current_person.is_admin?
26
+          %li
27
+            = link_to people_path do
28
+              %i.fa.fa-user{'aria-hidden': true}
29
+              People
30
+
31
+          %li
32
+            = link_to groups_path do
33
+              %i.fa.fa-users{'aria-hidden': true}
34
+              All groups
35
+
36
+      %ul.nav.navbar-nav.navbar-right
37
+        %li
38
+          = link_to current_person do
39
+            = current_person.full_name
40
+        %li
41
+          = link_to logout_path, confirm: "Really log out?", method: :delete do
42
+            %i.fa.fa-sign-out{'aria-hidden': true}
43
+            Log out

+ 14 - 2
config/routes.rb

@@ -1,5 +1,9 @@
1 1
 Rails.application.routes.draw do
2
-  get  'login', to: 'authentication#login_form'
2
+  get 'dashboard/home'
3
+
4
+  root to: 'dashboard#home'
5
+
6
+  get  'login', to: 'authentication#login_form', as: :login
3 7
   post 'login', to: 'authentication#login'
4 8
 
5 9
   get  'register', to: 'authentication#create_password_form'
@@ -8,7 +12,15 @@ Rails.application.routes.draw do
8 12
   get  'forgot', to: 'authentication#forgotten_password_form'
9 13
   post 'forgot', to: 'authentication#forgotten_password'
10 14
 
11
-  get 'logintest', to: 'authentication#login_status'
15
+  get 'logout', to: 'authentication#logout_confirm'
16
+  delete 'logout', to: 'authentication#logout'
17
+
18
+  resources :people
19
+
20
+  resources :groups do
21
+    resources :members
22
+  end
23
+  get 'my_groups', to: 'groups#user_groups', as: :user_groups
12 24
 
13 25
   # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
14 26
 end

+ 9 - 0
test/controllers/dashboard_controller_test.rb

@@ -0,0 +1,9 @@
1
+require 'test_helper'
2
+
3
+class DashboardControllerTest < ActionDispatch::IntegrationTest
4
+  test "should get home" do
5
+    get dashboard_home_url
6
+    assert_response :success
7
+  end
8
+
9
+end

+ 48 - 0
test/controllers/groups_controller_test.rb

@@ -0,0 +1,48 @@
1
+require 'test_helper'
2
+
3
+class GroupsControllerTest < ActionDispatch::IntegrationTest
4
+  setup do
5
+    @group = groups(:one)
6
+  end
7
+
8
+  test "should get index" do
9
+    get groups_url
10
+    assert_response :success
11
+  end
12
+
13
+  test "should get new" do
14
+    get new_group_url
15
+    assert_response :success
16
+  end
17
+
18
+  test "should create group" do
19
+    assert_difference('Group.count') do
20
+      post groups_url, params: { group: {  } }
21
+    end
22
+
23
+    assert_redirected_to group_url(Group.last)
24
+  end
25
+
26
+  test "should show group" do
27
+    get group_url(@group)
28
+    assert_response :success
29
+  end
30
+
31
+  test "should get edit" do
32
+    get edit_group_url(@group)
33
+    assert_response :success
34
+  end
35
+
36
+  test "should update group" do
37
+    patch group_url(@group), params: { group: {  } }
38
+    assert_redirected_to group_url(@group)
39
+  end
40
+
41
+  test "should destroy group" do
42
+    assert_difference('Group.count', -1) do
43
+      delete group_url(@group)
44
+    end
45
+
46
+    assert_redirected_to groups_url
47
+  end
48
+end

+ 48 - 0
test/controllers/members_controller_test.rb

@@ -0,0 +1,48 @@
1
+require 'test_helper'
2
+
3
+class MembersControllerTest < ActionDispatch::IntegrationTest
4
+  setup do
5
+    @member = members(:one)
6
+  end
7
+
8
+  test "should get index" do
9
+    get members_url
10
+    assert_response :success
11
+  end
12
+
13
+  test "should get new" do
14
+    get new_member_url
15
+    assert_response :success
16
+  end
17
+
18
+  test "should create member" do
19
+    assert_difference('Member.count') do
20
+      post members_url, params: { member: {  } }
21
+    end
22
+
23
+    assert_redirected_to member_url(Member.last)
24
+  end
25
+
26
+  test "should show member" do
27
+    get member_url(@member)
28
+    assert_response :success
29
+  end
30
+
31
+  test "should get edit" do
32
+    get edit_member_url(@member)
33
+    assert_response :success
34
+  end
35
+
36
+  test "should update member" do
37
+    patch member_url(@member), params: { member: {  } }
38
+    assert_redirected_to member_url(@member)
39
+  end
40
+
41
+  test "should destroy member" do
42
+    assert_difference('Member.count', -1) do
43
+      delete member_url(@member)
44
+    end
45
+
46
+    assert_redirected_to members_url
47
+  end
48
+end

+ 48 - 0
test/controllers/people_controller_test.rb

@@ -0,0 +1,48 @@
1
+require 'test_helper'
2
+
3
+class PeopleControllerTest < ActionDispatch::IntegrationTest
4
+  setup do
5
+    @person = people(:one)
6
+  end
7
+
8
+  test "should get index" do
9
+    get people_url
10
+    assert_response :success
11
+  end
12
+
13
+  test "should get new" do
14
+    get new_person_url
15
+    assert_response :success
16
+  end
17
+
18
+  test "should create person" do
19
+    assert_difference('Person.count') do
20
+      post people_url, params: { person: {  } }
21
+    end
22
+
23
+    assert_redirected_to person_url(Person.last)
24
+  end
25
+
26
+  test "should show person" do
27
+    get person_url(@person)
28
+    assert_response :success
29
+  end
30
+
31
+  test "should get edit" do
32
+    get edit_person_url(@person)
33
+    assert_response :success
34
+  end
35
+
36
+  test "should update person" do
37
+    patch person_url(@person), params: { person: {  } }
38
+    assert_redirected_to person_url(@person)
39
+  end
40
+
41
+  test "should destroy person" do
42
+    assert_difference('Person.count', -1) do
43
+      delete person_url(@person)
44
+    end
45
+
46
+    assert_redirected_to people_url
47
+  end
48
+end