From 0bd7c1db01017d1d2f006ed007a4124ac501c4ed Mon Sep 17 00:00:00 2001 From: Wahib Kapdi Date: Wed, 30 Oct 2024 21:20:30 -0500 Subject: [PATCH 01/13] Time Slots Fixed --- app/models/time_slot.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/time_slot.rb b/app/models/time_slot.rb index f1b1c0b..4d392bf 100644 --- a/app/models/time_slot.rb +++ b/app/models/time_slot.rb @@ -13,7 +13,7 @@ class TimeSlot < ApplicationRecord private def end_time_after_start_time - return unless end_time.present? && start_time.present? && end_time <= start_time + return unless end_time.present? && start_time.present? && Time.parse(end_time) <= Time.parse(start_time) errors.add(:end_time, 'must be after the start time') end From 8fe6339bddb90028e1b9b70d7291144cdb9db03b Mon Sep 17 00:00:00 2001 From: Navya N Date: Wed, 30 Oct 2024 22:39:40 -0500 Subject: [PATCH 02/13] instructor foreign key --- ...936_add_instructor_ref_to_room_bookings.rb | 5 + db/schema.rb | 199 ++++++++++-------- 2 files changed, 111 insertions(+), 93 deletions(-) create mode 100644 db/migrate/20241031023936_add_instructor_ref_to_room_bookings.rb diff --git a/db/migrate/20241031023936_add_instructor_ref_to_room_bookings.rb b/db/migrate/20241031023936_add_instructor_ref_to_room_bookings.rb new file mode 100644 index 0000000..2ea15fd --- /dev/null +++ b/db/migrate/20241031023936_add_instructor_ref_to_room_bookings.rb @@ -0,0 +1,5 @@ +class AddInstructorRefToRoomBookings < ActiveRecord::Migration[7.2] + def change + add_reference :room_bookings, :instructor, null: false, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 19dfe95..8774af9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -12,113 +10,128 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 20_241_029_040_851) do - create_table 'courses', force: :cascade do |t| - t.string 'course_number' - t.integer 'max_seats' - t.string 'lecture_type' - t.integer 'num_labs' - t.integer 'schedule_id', null: false - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.index ['schedule_id'], name: 'index_courses_on_schedule_id' +ActiveRecord::Schema[7.2].define(version: 2024_10_31_023936) do + create_table "courses", force: :cascade do |t| + t.string "course_number" + t.integer "max_seats" + t.string "lecture_type" + t.integer "num_labs" + t.integer "schedule_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["schedule_id"], name: "index_courses_on_schedule_id" + end + + create_table "instructor_preferences", force: :cascade do |t| + t.integer "instructor_id", null: false + t.integer "preference_level" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "course_id", null: false + t.index ["course_id"], name: "index_instructor_preferences_on_course_id" + t.index ["instructor_id"], name: "index_instructor_preferences_on_instructor_id" end - create_table 'instructor_preferences', force: :cascade do |t| - t.integer 'instructor_id', null: false - t.integer 'preference_level' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'course_id', null: false - t.index ['course_id'], name: 'index_instructor_preferences_on_course_id' - t.index ['instructor_id'], name: 'index_instructor_preferences_on_instructor_id' + create_table "instructors", force: :cascade do |t| + t.integer "id_number" + t.string "last_name" + t.string "first_name" + t.string "middle_name" + t.string "email" + t.boolean "before_9" + t.boolean "after_3" + t.text "beaware_of" + t.integer "schedule_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "max_course_load" + t.index ["schedule_id"], name: "index_instructors_on_schedule_id" end - create_table 'instructors', force: :cascade do |t| - t.integer 'id_number' - t.string 'last_name' - t.string 'first_name' - t.string 'middle_name' - t.string 'email' - t.boolean 'before_9' - t.boolean 'after_3' - t.text 'beaware_of' - t.integer 'schedule_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'max_course_load' - t.index ['schedule_id'], name: 'index_instructors_on_schedule_id' + create_table "room_blocks", force: :cascade do |t| + t.integer "room_id", null: false + t.integer "time_slot_id", null: false + t.boolean "is_blocked", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["room_id"], name: "index_room_blocks_on_room_id" + t.index ["time_slot_id"], name: "index_room_blocks_on_time_slot_id" end - create_table 'room_bookings', force: :cascade do |t| - t.integer 'room_id', null: false - t.integer 'time_slot_id', null: false - t.boolean 'is_available' - t.boolean 'is_lab' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.index ['room_id'], name: 'index_room_bookings_on_room_id' - t.index ['time_slot_id'], name: 'index_room_bookings_on_time_slot_id' + create_table "room_bookings", force: :cascade do |t| + t.integer "room_id", null: false + t.integer "time_slot_id", null: false + t.boolean "is_available" + t.boolean "is_lab" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "instructor_id", null: false + t.index ["instructor_id"], name: "index_room_bookings_on_instructor_id" + t.index ["room_id"], name: "index_room_bookings_on_room_id" + t.index ["time_slot_id"], name: "index_room_bookings_on_time_slot_id" end - create_table 'rooms', force: :cascade do |t| - t.integer 'campus' - t.boolean 'is_lecture_hall' - t.boolean 'is_learning_studio' - t.boolean 'is_lab' - t.string 'building_code' - t.string 'room_number' - t.integer 'capacity' - t.boolean 'is_active' - t.string 'comments' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'schedule_id', default: -1, null: false - t.index ['schedule_id'], name: 'index_rooms_on_schedule_id' + create_table "rooms", force: :cascade do |t| + t.integer "campus" + t.boolean "is_lecture_hall" + t.boolean "is_learning_studio" + t.boolean "is_lab" + t.string "building_code" + t.string "room_number" + t.integer "capacity" + t.boolean "is_active" + t.string "comments" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "schedule_id", default: -1, null: false + t.index ["schedule_id"], name: "index_rooms_on_schedule_id" end - create_table 'schedules', force: :cascade do |t| - t.string 'schedule_name' - t.string 'semester_name' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "schedules", force: :cascade do |t| + t.string "schedule_name" + t.string "semester_name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table 'sections', force: :cascade do |t| - t.string 'section_number' - t.integer 'seats_alloted' - t.integer 'course_id', null: false - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.index ['course_id'], name: 'index_sections_on_course_id' + create_table "sections", force: :cascade do |t| + t.string "section_number" + t.integer "seats_alloted" + t.integer "course_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["course_id"], name: "index_sections_on_course_id" end - create_table 'time_slots', force: :cascade do |t| - t.string 'day' - t.string 'start_time' - t.string 'end_time' - t.string 'slot_type' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "time_slots", force: :cascade do |t| + t.string "day" + t.string "start_time" + t.string "end_time" + t.string "slot_type" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table 'users', force: :cascade do |t| - t.string 'email' - t.string 'first_name' - t.string 'last_name' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.string 'uid' - t.string 'provider' - t.index ['email'], name: 'index_users_on_email', unique: true + create_table "users", force: :cascade do |t| + t.string "email" + t.string "first_name" + t.string "last_name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "uid" + t.string "provider" + t.index ["email"], name: "index_users_on_email", unique: true end - add_foreign_key 'courses', 'schedules' - add_foreign_key 'instructor_preferences', 'courses' - add_foreign_key 'instructor_preferences', 'instructors' - add_foreign_key 'instructors', 'schedules' - add_foreign_key 'room_bookings', 'rooms' - add_foreign_key 'room_bookings', 'time_slots' - add_foreign_key 'rooms', 'schedules' - add_foreign_key 'sections', 'courses' + add_foreign_key "courses", "schedules" + add_foreign_key "instructor_preferences", "courses" + add_foreign_key "instructor_preferences", "instructors" + add_foreign_key "instructors", "schedules" + add_foreign_key "room_blocks", "rooms" + add_foreign_key "room_blocks", "time_slots" + add_foreign_key "room_bookings", "instructors" + add_foreign_key "room_bookings", "rooms" + add_foreign_key "room_bookings", "time_slots" + add_foreign_key "rooms", "schedules" + add_foreign_key "sections", "courses" end From 70afc33b83c46388802d0396405bc0e218b66440 Mon Sep 17 00:00:00 2001 From: Navya N Date: Wed, 30 Oct 2024 23:18:32 -0500 Subject: [PATCH 03/13] post for room bookings --- app/controllers/room_bookings_controller.rb | 17 +++++++++++++++++ config/routes.rb | 2 ++ 2 files changed, 19 insertions(+) diff --git a/app/controllers/room_bookings_controller.rb b/app/controllers/room_bookings_controller.rb index 533c36f..8813f32 100644 --- a/app/controllers/room_bookings_controller.rb +++ b/app/controllers/room_bookings_controller.rb @@ -20,4 +20,21 @@ def index hash[[booking.room_id, booking.time_slot_id]] = booking end end + + + def create + room_booking = RoomBooking.new(room_booking_params) + + if room_booking.save + render json: { message: 'Room booking created successfully', room_booking: room_booking }, status: :created + else + render json: { error: 'Failed to create room booking', details: room_booking.errors.full_messages }, status: :unprocessable_entity + end + end + + private + + def room_booking_params + params.require(:room_booking).permit(:room_id, :time_slot_id, :is_available, :is_lab, :instructor_id) + end end diff --git a/config/routes.rb b/config/routes.rb index c5aa2a4..16bda4d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -45,4 +45,6 @@ # Show Time Slot View resources :time_slots, only: [:index] + + resources :room_bookings, only: [:create] end From c791a0f8fc3ac1d7ae86774c2ea67db707e3ac19 Mon Sep 17 00:00:00 2001 From: Wahib Kapdi Date: Thu, 31 Oct 2024 07:23:12 -0500 Subject: [PATCH 04/13] Added slot selection and course list addition --- app/controllers/courses_controller.rb | 11 +++ app/views/courses/_courses_list.html.erb | 15 +++ app/views/layouts/application.html.erb | 2 +- app/views/room_bookings/index.html.erb | 120 +++++++++++++++-------- config/routes.rb | 2 + 5 files changed, 107 insertions(+), 43 deletions(-) create mode 100644 app/views/courses/_courses_list.html.erb diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 70b91ea..76a7a7f 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -11,6 +11,17 @@ def index @courses = @courses.order("#{sort_column} #{direction}") end + def fetch_courses + room_id = params[:room_id] + time_slot_id = params[:time_slot_id] + + @schedule = Schedule.find(params[:schedule_id]) + @courses = @schedule.courses + @sections = Section.joins(:course) + + render json: { html: render_to_string(partial: "courses_list", locals: { sections: @sections }) } + end + private # Define the allowed sorting columns diff --git a/app/views/courses/_courses_list.html.erb b/app/views/courses/_courses_list.html.erb new file mode 100644 index 0000000..f47615f --- /dev/null +++ b/app/views/courses/_courses_list.html.erb @@ -0,0 +1,15 @@ +<% if sections.present? %> +
+ <% sections.each do |section| %> +
+
+ <%= section.course.course_number %>(<%= section.section_number %>) + Seats: <%= section.seats_alloted %> +
+
Type: <%= section.course.lecture_type %>
+
+ <% end %> +
+<% else %> +

No courses available for the selected room and time slot.

+<% end %> \ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 7a2490c..f03c124 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -14,7 +14,7 @@ - <%= stylesheet_link_tag "https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css", integrity: "sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65", crossorigin: "anonymous" %> + <%= stylesheet_link_tag "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css", integrity: "sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH", crossorigin: "anonymous" %> <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> <%= javascript_include_tag 'room_bookings' %> diff --git a/app/views/room_bookings/index.html.erb b/app/views/room_bookings/index.html.erb index 7b7b254..ebf55af 100644 --- a/app/views/room_bookings/index.html.erb +++ b/app/views/room_bookings/index.html.erb @@ -16,49 +16,85 @@ <% if !@rooms.empty? %> - -
- - - - - <% @rooms.each do |room| %> - - - <% end %> - - - - <% @time_slots.each do |time_slot| %> - - - - <% @rooms.each do |room| %> - <% booking = @bookings_matrix[[room.id, time_slot.id]] %> - - + - <% end %> - -
Times \ Rooms<%= room.building_code %> <%= room.room_number %>
<%= time_slot.start_time %> - <%= time_slot.end_time %> - <% if booking %> - <%= booking.is_available ? 'Available' : 'Booked' %> | - <%= booking.is_lab ? 'Lab' : 'Lecture' %> - <% else %> - <% end %> -
+ +
+ +
+ + + + + <% @rooms.each do |room| %> + + + <% end %> + + + + <% @time_slots.each do |time_slot| %> + + + + <% @rooms.each do |room| %> + <% booking = @bookings_matrix[[room.id, time_slot.id]] %> + + + <% end %> + + <% end %> + +
Times \ Rooms<%= room.building_code %> <%= room.room_number %>
<%= time_slot.start_time %> - <%= time_slot.end_time %> + <% if booking %> + <%= booking.is_available ? 'Available' : 'Booked' %> | + <%= booking.is_lab ? 'Lab' : 'Lecture' %> + <% else %> + <% end %> +
+
+ +
+
<% else %>

No rooms added to this schedule, click on View Data to Add Rooms!

-<% end %> \ No newline at end of file +<% end %> + \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index c5aa2a4..985d7f5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -40,6 +40,8 @@ post 'time_slots', to: 'time_slots#filter', as: 'filter_time_slots' get '/time_slots', to: 'time_slots#index' + post '/courses/fetch_courses', to: 'courses#fetch_courses' + resources :room_bookings, only: [:index] end From 8eaff119d7d4e38f0bea407bc261b895fc526805 Mon Sep 17 00:00:00 2001 From: Wahib Kapdi Date: Thu, 31 Oct 2024 09:42:55 -0500 Subject: [PATCH 05/13] Added Correct Hovering --- app/assets/stylesheets/room_bookings.css | 7 +++++ app/views/courses/_courses_list.html.erb | 35 ++++++++++++++++++++++-- app/views/room_bookings/index.html.erb | 30 ++++++++++---------- db/schema.rb | 12 -------- 4 files changed, 56 insertions(+), 28 deletions(-) diff --git a/app/assets/stylesheets/room_bookings.css b/app/assets/stylesheets/room_bookings.css index e2d9e95..af6fcdd 100644 --- a/app/assets/stylesheets/room_bookings.css +++ b/app/assets/stylesheets/room_bookings.css @@ -1,4 +1,11 @@ .is-hover { --bs-bg-opacity: 0.1; background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important; +} + +.section-item:hover { + background-color: #f0f9ff; /* Light blue shade to indicate hover */ + transition: background-color 0.3s; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Subtle shadow effect */ + cursor: pointer; } \ No newline at end of file diff --git a/app/views/courses/_courses_list.html.erb b/app/views/courses/_courses_list.html.erb index f47615f..3d0919a 100644 --- a/app/views/courses/_courses_list.html.erb +++ b/app/views/courses/_courses_list.html.erb @@ -1,7 +1,10 @@ <% if sections.present? %>
<% sections.each do |section| %> -
+
<%= section.course.course_number %>(<%= section.section_number %>) Seats: <%= section.seats_alloted %> @@ -12,4 +15,32 @@
<% else %>

No courses available for the selected room and time slot.

-<% end %> \ No newline at end of file +<% end %> + \ No newline at end of file diff --git a/app/views/room_bookings/index.html.erb b/app/views/room_bookings/index.html.erb index ebf55af..c0adcc1 100644 --- a/app/views/room_bookings/index.html.erb +++ b/app/views/room_bookings/index.html.erb @@ -19,21 +19,21 @@
- +
- + <% @rooms.each do |room| %> @@ -48,7 +48,7 @@ <% @rooms.each do |room| %> <% booking = @bookings_matrix[[room.id, time_slot.id]] %> - From 655d764ba5d044111b3d12b531d5077b01aabd62 Mon Sep 17 00:00:00 2001 From: Navya N Date: Thu, 31 Oct 2024 21:17:46 -0500 Subject: [PATCH 09/13] delete and lock courses buttons --- app/controllers/room_bookings_controller.rb | 26 +++++++ app/javascript/room_bookings.js | 2 +- app/views/room_bookings/index.html.erb | 74 ++++++++++--------- config/routes.rb | 7 +- ...01020805_add_is_locked_to_room_bookings.rb | 5 ++ db/schema.rb | 15 +++- 6 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 db/migrate/20241101020805_add_is_locked_to_room_bookings.rb diff --git a/app/controllers/room_bookings_controller.rb b/app/controllers/room_bookings_controller.rb index fbcef0e..c8a1f81 100644 --- a/app/controllers/room_bookings_controller.rb +++ b/app/controllers/room_bookings_controller.rb @@ -43,6 +43,32 @@ def create end end + def destroy + @room_booking = RoomBooking.find_by(id: params[:id]) + + if @room_booking + @room_booking.destroy + flash[:notice] = "Room booking deleted successfully." + else + flash[:alert] = "Room booking not found." + end + + redirect_to room_bookings_path # Redirect to the list of room bookings or another appropriate page + end + + def toggle_lock + @room_booking = RoomBooking.find(params[:id]) + + # Toggle the `is_locked` value + @room_booking.update(is_locked: !@room_booking.is_locked) + + # Optionally add a notice or alert to show success or failure + flash[:notice] = "Room booking lock status updated successfully." + + # Redirect to the previous page or another relevant page + redirect_back(fallback_location: room_bookings_path) + end + private def room_booking_params diff --git a/app/javascript/room_bookings.js b/app/javascript/room_bookings.js index 543cadb..2c4c01b 100644 --- a/app/javascript/room_bookings.js +++ b/app/javascript/room_bookings.js @@ -1,4 +1,4 @@ -document.addEventListener("DOMContentLoaded", function () { +document.addEventListener("turbo:load", function () { const tds = document.querySelectorAll(".grid-view-matrix td"); tds.forEach((td) => { diff --git a/app/views/room_bookings/index.html.erb b/app/views/room_bookings/index.html.erb index c106606..784899e 100644 --- a/app/views/room_bookings/index.html.erb +++ b/app/views/room_bookings/index.html.erb @@ -55,15 +55,9 @@ (<%= booking.section.section_number %>) | <%= booking.section.seats_alloted %> - <% -=begin%> - <% if booking.instructor %> - <%= link_to booking.instructor.first_name, schedule_room_bookings_path(@schedule), class: 'btn btn-primary' %> - <% else %> - <%= link_to 'Assign Instructor', schedule_room_bookings_path(@schedule), class: 'btn btn-primary' %> - <% end %> -<% -=end%> +<%= link_to "Delete", schedule_room_booking_path(@schedule,booking), method: :delete, data: { confirm: "Are you sure you want to delete this booking?",turbo_method: :delete }, class: "btn btn-danger" %> +<%= link_to (booking.is_locked ? "Locked" : "Unlocked"), toggle_lock_schedule_room_booking_path(@schedule, booking), method: :patch, class: "btn btn-warning", data: { confirm: "Are you sure you want to toggle the lock status?", turbo_method: :patch } %> + <%= form_with model: @room_booking, local: true do |form| %>
<%= form.select :instructor_id, options_from_collection_for_select(@instructors, :id, :first_name, :last_name) %> @@ -90,34 +84,44 @@

No rooms added to this schedule, click on View Data to Add Rooms!

<% end %> \ No newline at end of file + diff --git a/config/routes.rb b/config/routes.rb index 7506f15..55c5c05 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -42,7 +42,12 @@ get '/time_slots', to: 'time_slots#index' post '/courses/fetch_courses', to: 'courses#fetch_courses' - resources :room_bookings, only: [:index, :create] + resources :room_bookings, only: [:index, :create, :destroy] do + member do + patch :toggle_lock + end + end + end # Show Time Slot View diff --git a/db/migrate/20241101020805_add_is_locked_to_room_bookings.rb b/db/migrate/20241101020805_add_is_locked_to_room_bookings.rb new file mode 100644 index 0000000..0a9e316 --- /dev/null +++ b/db/migrate/20241101020805_add_is_locked_to_room_bookings.rb @@ -0,0 +1,5 @@ +class AddIsLockedToRoomBookings < ActiveRecord::Migration[7.2] + def change + add_column :room_bookings, :is_locked, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 187c9ce..b1db9c5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2024_10_31_204719) do +ActiveRecord::Schema[7.2].define(version: 2024_11_01_020805) do create_table "courses", force: :cascade do |t| t.string "course_number" t.integer "max_seats" @@ -48,6 +48,16 @@ t.index ["schedule_id"], name: "index_instructors_on_schedule_id" end + create_table "room_blocks", force: :cascade do |t| + t.integer "room_id", null: false + t.integer "time_slot_id", null: false + t.boolean "is_blocked", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["room_id"], name: "index_room_blocks_on_room_id" + t.index ["time_slot_id"], name: "index_room_blocks_on_time_slot_id" + end + create_table "room_bookings", force: :cascade do |t| t.integer "room_id", null: false t.integer "time_slot_id", null: false @@ -57,6 +67,7 @@ t.datetime "updated_at", null: false t.integer "instructor_id" t.integer "section_id" + t.boolean "is_locked" t.index ["instructor_id"], name: "index_room_bookings_on_instructor_id" t.index ["room_id"], name: "index_room_bookings_on_room_id" t.index ["section_id"], name: "index_room_bookings_on_section_id" @@ -119,6 +130,8 @@ add_foreign_key "instructor_preferences", "courses" add_foreign_key "instructor_preferences", "instructors" add_foreign_key "instructors", "schedules" + add_foreign_key "room_blocks", "rooms" + add_foreign_key "room_blocks", "time_slots" add_foreign_key "room_bookings", "instructors" add_foreign_key "room_bookings", "rooms" add_foreign_key "room_bookings", "sections" From c1d14d8c75f5c972e167e704dd23e334fec6f1d7 Mon Sep 17 00:00:00 2001 From: Wahib Kapdi Date: Fri, 1 Nov 2024 12:00:11 -0500 Subject: [PATCH 10/13] Instructor Addition Added --- app/controllers/room_bookings_controller.rb | 13 ++++++++ app/views/room_bookings/index.html.erb | 35 +++++++++++++++------ config/routes.rb | 1 + db/schema.rb | 12 ------- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/app/controllers/room_bookings_controller.rb b/app/controllers/room_bookings_controller.rb index c8a1f81..d96a2e2 100644 --- a/app/controllers/room_bookings_controller.rb +++ b/app/controllers/room_bookings_controller.rb @@ -69,6 +69,19 @@ def toggle_lock redirect_back(fallback_location: room_bookings_path) end + def update_instructor + @booking = RoomBooking.find(params[:id]) + + if @booking.update(instructor_id: params[:room_booking][:instructor_id]) + flash[:notice] = "Instructor updated successfully." + else + flash[:alert] = "Failed to update instructor." + end + + # Redirect to the previous page or another relevant page + redirect_back(fallback_location: room_bookings_path) + end + private def room_booking_params diff --git a/app/views/room_bookings/index.html.erb b/app/views/room_bookings/index.html.erb index 784899e..b84cdf8 100644 --- a/app/views/room_bookings/index.html.erb +++ b/app/views/room_bookings/index.html.erb @@ -55,18 +55,34 @@ (<%= booking.section.section_number %>) | <%= booking.section.seats_alloted %> -<%= link_to "Delete", schedule_room_booking_path(@schedule,booking), method: :delete, data: { confirm: "Are you sure you want to delete this booking?",turbo_method: :delete }, class: "btn btn-danger" %> -<%= link_to (booking.is_locked ? "Locked" : "Unlocked"), toggle_lock_schedule_room_booking_path(@schedule, booking), method: :patch, class: "btn btn-warning", data: { confirm: "Are you sure you want to toggle the lock status?", turbo_method: :patch } %> - - <%= form_with model: @room_booking, local: true do |form| %> + <%= link_to "Delete", + schedule_room_booking_path(@schedule,booking), + method: :delete, + data: { + confirm: "Are you sure you want to delete this booking?", + turbo_method: :delete + }, + class: "btn btn-danger" %> + <%= link_to (booking.is_locked ? "Locked" : "Unlocked"), + toggle_lock_schedule_room_booking_path(@schedule, booking), + method: :patch, + class: "btn btn-warning", + data: { + confirm: "Are you sure you want to toggle the lock status?", + turbo_method: :patch + } %> + <%= form_with model: booking, + url: update_instructor_schedule_room_booking_path(@schedule, booking), + method: :patch, + data: { + turbo_method: :patch + }, + remote: true do |form| %>
- <%= form.select :instructor_id, options_from_collection_for_select(@instructors, :id, :first_name, :last_name) %> -
- -
- <%= form.submit "Assign Instructor" %> + <%= form.select :instructor_id, options_from_collection_for_select(@instructors, :id, :first_name, booking.instructor_id), { prompt: "Select Instructor" }, onchange: "this.form.submit()" %>
<% end %> + <% else %> <% end %> @@ -85,6 +101,7 @@ <% end %>
Times \ Rooms24 hr<%= room.building_code %> <%= room.room_number %> + " data-room-id="<%= room.id %>" data-time-slot-id="<%= time_slot.id %>"> <% if booking %> <%= booking.is_available ? 'Available' : 'Booked' %> | <%= booking.is_lab ? 'Lab' : 'Lecture' %> @@ -87,10 +87,12 @@ .then(data => { document.getElementById("courses-list").innerHTML = data.html; document.querySelectorAll('td.table-cell').forEach(cell => { + cell.classList.remove('bg-warning-subtle'); + cell.classList.remove('bg-warning'); if (cell.dataset.roomId === roomId && cell.dataset.timeSlotId === timeSlotId) { + cell.classList.add('bg-warning'); + } else if (cell.dataset.roomId === roomId || cell.dataset.timeSlotId === timeSlotId) { cell.classList.add('bg-warning-subtle'); - } else { - cell.classList.remove('bg-warning-subtle'); } }); }); diff --git a/db/schema.rb b/db/schema.rb index 8774af9..5d5e216 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -48,16 +48,6 @@ t.index ["schedule_id"], name: "index_instructors_on_schedule_id" end - create_table "room_blocks", force: :cascade do |t| - t.integer "room_id", null: false - t.integer "time_slot_id", null: false - t.boolean "is_blocked", default: true - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["room_id"], name: "index_room_blocks_on_room_id" - t.index ["time_slot_id"], name: "index_room_blocks_on_time_slot_id" - end - create_table "room_bookings", force: :cascade do |t| t.integer "room_id", null: false t.integer "time_slot_id", null: false @@ -127,8 +117,6 @@ add_foreign_key "instructor_preferences", "courses" add_foreign_key "instructor_preferences", "instructors" add_foreign_key "instructors", "schedules" - add_foreign_key "room_blocks", "rooms" - add_foreign_key "room_blocks", "time_slots" add_foreign_key "room_bookings", "instructors" add_foreign_key "room_bookings", "rooms" add_foreign_key "room_bookings", "time_slots" From f82c4c59db2c91c41191e92396585306c0d8cf01 Mon Sep 17 00:00:00 2001 From: Wahib Kapdi Date: Thu, 31 Oct 2024 15:50:05 -0500 Subject: [PATCH 06/13] DB Structure Fixed --- app/controllers/room_bookings_controller.rb | 24 +++++++---- app/models/room_booking.rb | 1 + app/models/section.rb | 1 + app/views/courses/_courses_list.html.erb | 40 ++++++------------- config/routes.rb | 2 +- ...tructor_id_in_room_bookings_to_nullable.rb | 5 +++ ...1031204719_add_section_to_room_bookings.rb | 5 +++ db/schema.rb | 7 +++- 8 files changed, 47 insertions(+), 38 deletions(-) create mode 100644 db/migrate/20241031203245_change_instructor_id_in_room_bookings_to_nullable.rb create mode 100644 db/migrate/20241031204719_add_section_to_room_bookings.rb diff --git a/app/controllers/room_bookings_controller.rb b/app/controllers/room_bookings_controller.rb index 8813f32..26cc4d2 100644 --- a/app/controllers/room_bookings_controller.rb +++ b/app/controllers/room_bookings_controller.rb @@ -23,18 +23,28 @@ def index def create - room_booking = RoomBooking.new(room_booking_params) - - if room_booking.save - render json: { message: 'Room booking created successfully', room_booking: room_booking }, status: :created - else - render json: { error: 'Failed to create room booking', details: room_booking.errors.full_messages }, status: :unprocessable_entity + room_booking = RoomBooking.new!(room_booking_params) + puts (params[:room_id]) + puts (params[:time_slot_id]) + puts params[:section_id] + puts params[:schedule_id] + @schedule = Schedule.find(params[:schedule_id]); + + respond_to do |format| + if room_booking.save! + format.html { redirect_to schedule_room_booking_path(@schedule), notice: "Movie was successfully created." } + format.json { render :index, status: :created } + else + render json: { error: 'Failed to create room booking', details: room_booking.errors.full_messages }, status: :unprocessable_entity + flash[:alert] = "Did not work" + end end end private def room_booking_params - params.require(:room_booking).permit(:room_id, :time_slot_id, :is_available, :is_lab, :instructor_id) + puts "HERE" + params.require(:room_booking).permit(:room_id, :time_slot_id, :is_available, :is_lab, :instructor_id, :section_id) end end diff --git a/app/models/room_booking.rb b/app/models/room_booking.rb index 850e9a8..510240f 100644 --- a/app/models/room_booking.rb +++ b/app/models/room_booking.rb @@ -3,4 +3,5 @@ class RoomBooking < ApplicationRecord belongs_to :room belongs_to :time_slot + belongs_to :section end diff --git a/app/models/section.rb b/app/models/section.rb index 7e42841..36e6034 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -3,4 +3,5 @@ # Section model class Section < ApplicationRecord belongs_to :course + has_one :room_booking, optional: true end diff --git a/app/views/courses/_courses_list.html.erb b/app/views/courses/_courses_list.html.erb index 3d0919a..ecf3f8c 100644 --- a/app/views/courses/_courses_list.html.erb +++ b/app/views/courses/_courses_list.html.erb @@ -10,37 +10,21 @@ Seats: <%= section.seats_alloted %>
Type: <%= section.course.lecture_type %>
+ <%= link_to( + 'Select', + schedule_room_bookings_path( + schedule_id: @schedule.id, + room_id: params[:room_id], + time_slot_id: params[:time_slot_id], + section_id: section.id, + instructor_id: -1 + ), + data: { turbo_method: :post }, + class: 'btn btn-primary my-1 text-xs' + ) %> <% end %> <% else %>

No courses available for the selected room and time slot.

<% end %> - \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 46df8f5..7506f15 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -42,7 +42,7 @@ get '/time_slots', to: 'time_slots#index' post '/courses/fetch_courses', to: 'courses#fetch_courses' - resources :room_bookings, only: [:index] + resources :room_bookings, only: [:index, :create] end # Show Time Slot View diff --git a/db/migrate/20241031203245_change_instructor_id_in_room_bookings_to_nullable.rb b/db/migrate/20241031203245_change_instructor_id_in_room_bookings_to_nullable.rb new file mode 100644 index 0000000..66415b1 --- /dev/null +++ b/db/migrate/20241031203245_change_instructor_id_in_room_bookings_to_nullable.rb @@ -0,0 +1,5 @@ +class ChangeInstructorIdInRoomBookingsToNullable < ActiveRecord::Migration[7.2] + def change + change_column_null :room_bookings, :instructor_id, true + end +end diff --git a/db/migrate/20241031204719_add_section_to_room_bookings.rb b/db/migrate/20241031204719_add_section_to_room_bookings.rb new file mode 100644 index 0000000..18045d6 --- /dev/null +++ b/db/migrate/20241031204719_add_section_to_room_bookings.rb @@ -0,0 +1,5 @@ +class AddSectionToRoomBookings < ActiveRecord::Migration[7.2] + def change + add_reference :room_bookings, :section, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 5d5e216..187c9ce 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2024_10_31_023936) do +ActiveRecord::Schema[7.2].define(version: 2024_10_31_204719) do create_table "courses", force: :cascade do |t| t.string "course_number" t.integer "max_seats" @@ -55,9 +55,11 @@ t.boolean "is_lab" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.integer "instructor_id", null: false + t.integer "instructor_id" + t.integer "section_id" t.index ["instructor_id"], name: "index_room_bookings_on_instructor_id" t.index ["room_id"], name: "index_room_bookings_on_room_id" + t.index ["section_id"], name: "index_room_bookings_on_section_id" t.index ["time_slot_id"], name: "index_room_bookings_on_time_slot_id" end @@ -119,6 +121,7 @@ add_foreign_key "instructors", "schedules" add_foreign_key "room_bookings", "instructors" add_foreign_key "room_bookings", "rooms" + add_foreign_key "room_bookings", "sections" add_foreign_key "room_bookings", "time_slots" add_foreign_key "rooms", "schedules" add_foreign_key "sections", "courses" From 72624cb7c7c91befed8acab340a6eb8e1fb73af3 Mon Sep 17 00:00:00 2001 From: Wahib Kapdi Date: Thu, 31 Oct 2024 16:12:43 -0500 Subject: [PATCH 07/13] Course adding using schedule added --- app/controllers/room_bookings_controller.rb | 7 ++++--- app/models/section.rb | 2 +- app/views/courses/_courses_list.html.erb | 11 ++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/controllers/room_bookings_controller.rb b/app/controllers/room_bookings_controller.rb index 26cc4d2..7f17d6c 100644 --- a/app/controllers/room_bookings_controller.rb +++ b/app/controllers/room_bookings_controller.rb @@ -23,7 +23,7 @@ def index def create - room_booking = RoomBooking.new!(room_booking_params) + room_booking = RoomBooking.new(room_booking_params) puts (params[:room_id]) puts (params[:time_slot_id]) puts params[:section_id] @@ -31,8 +31,8 @@ def create @schedule = Schedule.find(params[:schedule_id]); respond_to do |format| - if room_booking.save! - format.html { redirect_to schedule_room_booking_path(@schedule), notice: "Movie was successfully created." } + if room_booking.save + format.html { redirect_to schedule_room_bookings_path(@schedule), notice: "Movie was successfully created." } format.json { render :index, status: :created } else render json: { error: 'Failed to create room booking', details: room_booking.errors.full_messages }, status: :unprocessable_entity @@ -45,6 +45,7 @@ def create def room_booking_params puts "HERE" + puts :room_booking params.require(:room_booking).permit(:room_id, :time_slot_id, :is_available, :is_lab, :instructor_id, :section_id) end end diff --git a/app/models/section.rb b/app/models/section.rb index 36e6034..f51af16 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -3,5 +3,5 @@ # Section model class Section < ApplicationRecord belongs_to :course - has_one :room_booking, optional: true + has_one :room_booking end diff --git a/app/views/courses/_courses_list.html.erb b/app/views/courses/_courses_list.html.erb index ecf3f8c..0d6a000 100644 --- a/app/views/courses/_courses_list.html.erb +++ b/app/views/courses/_courses_list.html.erb @@ -13,11 +13,12 @@ <%= link_to( 'Select', schedule_room_bookings_path( - schedule_id: @schedule.id, - room_id: params[:room_id], - time_slot_id: params[:time_slot_id], - section_id: section.id, - instructor_id: -1 + schedule_id: params[:schedule_id], + room_booking: { + room_id: params[:room_id], + time_slot_id: params[:time_slot_id], + section_id: section.id + } ), data: { turbo_method: :post }, class: 'btn btn-primary my-1 text-xs' From 175f24db440ea22c44a14bbc92588cb7ba343ea0 Mon Sep 17 00:00:00 2001 From: Wahib Kapdi Date: Thu, 31 Oct 2024 17:49:41 -0500 Subject: [PATCH 08/13] Some structure added --- app/controllers/room_bookings_controller.rb | 16 ++++++------- app/models/instructor.rb | 1 + app/models/room_booking.rb | 1 + app/views/room_bookings/index.html.erb | 25 +++++++++++++++++++-- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/app/controllers/room_bookings_controller.rb b/app/controllers/room_bookings_controller.rb index 7f17d6c..fbcef0e 100644 --- a/app/controllers/room_bookings_controller.rb +++ b/app/controllers/room_bookings_controller.rb @@ -10,10 +10,16 @@ def index @active_tab = params[:active_tab] || @tabs[0] @time_slots = TimeSlot.where(time_slots: { day: @active_tab }).to_a @time_slots.sort_by! { |ts| Time.parse(ts.start_time) } + @instructors = @schedule.instructors # Fetch room bookings only for the specified schedule - @room_bookings = RoomBooking.joins(:room, :time_slot) - .where(rooms: { schedule_id: }, time_slots: { day: @active_tab }) + @room_bookings = RoomBooking.includes( + room: {}, + section: [:course], + time_slot: {}, + instructor: {} + ).where(rooms: { schedule_id: schedule_id }, time_slots: { day: @active_tab }) + # Organize room bookings in a hash with room_id and time_slot_id as keys @bookings_matrix = @room_bookings.each_with_object({}) do |booking, hash| @@ -24,10 +30,6 @@ def index def create room_booking = RoomBooking.new(room_booking_params) - puts (params[:room_id]) - puts (params[:time_slot_id]) - puts params[:section_id] - puts params[:schedule_id] @schedule = Schedule.find(params[:schedule_id]); respond_to do |format| @@ -44,8 +46,6 @@ def create private def room_booking_params - puts "HERE" - puts :room_booking params.require(:room_booking).permit(:room_id, :time_slot_id, :is_available, :is_lab, :instructor_id, :section_id) end end diff --git a/app/models/instructor.rb b/app/models/instructor.rb index 90287cd..2d821f1 100644 --- a/app/models/instructor.rb +++ b/app/models/instructor.rb @@ -4,4 +4,5 @@ class Instructor < ApplicationRecord belongs_to :schedule has_many :instructor_preferences, dependent: :destroy + has_many :room_bookings end diff --git a/app/models/room_booking.rb b/app/models/room_booking.rb index 510240f..ccec01b 100644 --- a/app/models/room_booking.rb +++ b/app/models/room_booking.rb @@ -4,4 +4,5 @@ class RoomBooking < ApplicationRecord belongs_to :room belongs_to :time_slot belongs_to :section + belongs_to :instructor, optional: true end diff --git a/app/views/room_bookings/index.html.erb b/app/views/room_bookings/index.html.erb index c0adcc1..c106606 100644 --- a/app/views/room_bookings/index.html.erb +++ b/app/views/room_bookings/index.html.erb @@ -50,8 +50,29 @@
" data-room-id="<%= room.id %>" data-time-slot-id="<%= time_slot.id %>"> <% if booking %> - <%= booking.is_available ? 'Available' : 'Booked' %> | - <%= booking.is_lab ? 'Lab' : 'Lecture' %> + + <%= booking.section.course.course_number %> + (<%= booking.section.section_number %>) + | + <%= booking.section.seats_alloted %> + <% +=begin%> + <% if booking.instructor %> + <%= link_to booking.instructor.first_name, schedule_room_bookings_path(@schedule), class: 'btn btn-primary' %> + <% else %> + <%= link_to 'Assign Instructor', schedule_room_bookings_path(@schedule), class: 'btn btn-primary' %> + <% end %> +<% +=end%> + <%= form_with model: @room_booking, local: true do |form| %> +
+ <%= form.select :instructor_id, options_from_collection_for_select(@instructors, :id, :first_name, :last_name) %> +
+ +
+ <%= form.submit "Assign Instructor" %> +
+ <% end %> <% else %> <% end %>