From 61b62712d4f16956f7b9095e8ae9b2ba19b06286 Mon Sep 17 00:00:00 2001 From: Ying Tong Date: Thu, 2 Apr 2026 09:04:37 +0800 Subject: [PATCH 1/7] feat: Add base styling for custom 404 and 500 error pages --- app/controllers/errors_controller.rb | 5 +++ .../errors/internal_server_error.html.erb | 45 +++++++++++++++++++ app/views/errors/not_found.html.erb | 45 +++++++++++++++++++ config/application.rb | 3 ++ config/environments/development.rb | 2 +- config/routes.rb | 2 + 6 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 app/controllers/errors_controller.rb create mode 100644 app/views/errors/internal_server_error.html.erb create mode 100644 app/views/errors/not_found.html.erb diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb new file mode 100644 index 00000000..5e50a5f4 --- /dev/null +++ b/app/controllers/errors_controller.rb @@ -0,0 +1,5 @@ +class ErrorsController < ApplicationController + def not_found; end + + def internal_server_error; end +end diff --git a/app/views/errors/internal_server_error.html.erb b/app/views/errors/internal_server_error.html.erb new file mode 100644 index 00000000..99af097b --- /dev/null +++ b/app/views/errors/internal_server_error.html.erb @@ -0,0 +1,45 @@ +<% content_for :hide_breadcrumbs, true %> +<% content_for :hide_toggler, true %> +
+
+ <%# The Error Code %> +

500

+ + <%# The Main Heading %> +

+ Internal Server Error +

+ + <%# The Subtext %> +

+ Sorry, we couldn't find the page you're looking for. It might have been + moved or deleted. +

+ + <%# Action Buttons %> +
+ + <%= link_to "Go back home", + root_path, + class: + "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + + <%# Secondary Link: Optional, route to a help desk or contact page %> + + Contact support + + + +
+
+
diff --git a/app/views/errors/not_found.html.erb b/app/views/errors/not_found.html.erb new file mode 100644 index 00000000..94633d69 --- /dev/null +++ b/app/views/errors/not_found.html.erb @@ -0,0 +1,45 @@ +<% content_for :hide_breadcrumbs, true %> +<% content_for :hide_toggler, true %> +
+
+ <%# The Error Code %> +

404

+ + <%# The Main Heading %> +

+ Page not found +

+ + <%# The Subtext %> +

+ Sorry, we couldn't find the page you're looking for. It might have been + moved or deleted. +

+ + <%# Action Buttons %> +
+ + <%= link_to "Go back home", + root_path, + class: + "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + + <%# Secondary Link: Optional, route to a help desk or contact page %> + + Contact support + + + +
+
+
diff --git a/config/application.rb b/config/application.rb index d115942b..902e1265 100644 --- a/config/application.rb +++ b/config/application.rb @@ -28,5 +28,8 @@ class Application < Rails::Application # view constants thresholds config.participants_threshold = 500 config.supervisors_threshold = 100 + + # redirect error routes to use custom design + config.exceptions_app = routes end end diff --git a/config/environments/development.rb b/config/environments/development.rb index e7ba5d32..972b356f 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -10,7 +10,7 @@ config.eager_load = false # Show full error reports. - config.consider_all_requests_local = true + config.consider_all_requests_local = false # Enable server timing. config.server_timing = true diff --git a/config/routes.rb b/config/routes.rb index afead3bd..d3c9a0a2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -83,6 +83,8 @@ # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Can be used by load balancers and uptime monitors to verify that the app is live. get 'up' => 'rails/health#show', as: :rails_health_check + match '/404', to: 'errors#not_found', via: :all + match '/500', to: 'errors#internal_server_error', via: :all # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest From c76324476323dbe0934cd5cc9c7f02e1eb3420c6 Mon Sep 17 00:00:00 2001 From: Ying Tong Date: Fri, 3 Apr 2026 21:48:32 +0800 Subject: [PATCH 2/7] styling: 404 and 500 --- .../errors/internal_server_error.html.erb | 25 +++-------------- app/views/errors/not_found.html.erb | 28 +++++-------------- 2 files changed, 11 insertions(+), 42 deletions(-) diff --git a/app/views/errors/internal_server_error.html.erb b/app/views/errors/internal_server_error.html.erb index 99af097b..2ce5db9c 100644 --- a/app/views/errors/internal_server_error.html.erb +++ b/app/views/errors/internal_server_error.html.erb @@ -1,45 +1,28 @@ <% content_for :hide_breadcrumbs, true %> <% content_for :hide_toggler, true %> +<% provide :no_footer, true %>
- <%# The Error Code %> -

500

+

500

- <%# The Main Heading %>

Internal Server Error

- <%# The Subtext %>

Sorry, we couldn't find the page you're looking for. It might have been moved or deleted.

- <%# Action Buttons %>
- <%= link_to "Go back home", + <%= link_to "Return to Dashboard", root_path, class: "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> - <%# Secondary Link: Optional, route to a help desk or contact page %> - - Contact support - - -
diff --git a/app/views/errors/not_found.html.erb b/app/views/errors/not_found.html.erb index 94633d69..5aee9055 100644 --- a/app/views/errors/not_found.html.erb +++ b/app/views/errors/not_found.html.erb @@ -1,45 +1,31 @@ <% content_for :hide_breadcrumbs, true %> <% content_for :hide_toggler, true %> +<% provide :no_footer, true %>
- <%# The Error Code %> -

404

+

404

- <%# The Main Heading %>

Page not found

- <%# The Subtext %>

- Sorry, we couldn't find the page you're looking for. It might have been - moved or deleted. + Sorry, we couldn't find the page you're looking for. It probably doesn't + exist, or might have been moved or deleted.

- <%# Action Buttons %>
- <%= link_to "Go back home", + <%= link_to "Return to Dashboard", root_path, class: "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> - <%# Secondary Link: Optional, route to a help desk or contact page %> - - Contact support - - -
From 52461d915be81ebab47c96ef84947b56246ca570 Mon Sep 17 00:00:00 2001 From: Ying Tong Date: Fri, 3 Apr 2026 23:32:02 +0800 Subject: [PATCH 3/7] feat: Add custom error page styles --- app/views/errors/forbidden.html.erb | 30 ++++++++++++++++++ app/views/errors/service_unavailable.html.erb | 30 ++++++++++++++++++ app/views/errors/unauthorized.html.erb | 31 +++++++++++++++++++ .../errors/unprocessable_entity.html.erb | 31 +++++++++++++++++++ config/routes.rb | 4 +++ 5 files changed, 126 insertions(+) create mode 100644 app/views/errors/forbidden.html.erb create mode 100644 app/views/errors/service_unavailable.html.erb create mode 100644 app/views/errors/unauthorized.html.erb create mode 100644 app/views/errors/unprocessable_entity.html.erb diff --git a/app/views/errors/forbidden.html.erb b/app/views/errors/forbidden.html.erb new file mode 100644 index 00000000..572c648c --- /dev/null +++ b/app/views/errors/forbidden.html.erb @@ -0,0 +1,30 @@ +<% content_for :hide_breadcrumbs, true %> +<% content_for :hide_toggler, true %> +<% provide :no_footer, true %> +
+
+

403

+ +

+ Forbidden +

+ +

+ Sorry, you are not authorized to view this page. +

+ +
+ + <%= link_to "Return to Dashboard", + root_path, + class: + "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + +
+
+
diff --git a/app/views/errors/service_unavailable.html.erb b/app/views/errors/service_unavailable.html.erb new file mode 100644 index 00000000..227ed686 --- /dev/null +++ b/app/views/errors/service_unavailable.html.erb @@ -0,0 +1,30 @@ +<% content_for :hide_breadcrumbs, true %> +<% content_for :hide_toggler, true %> +<% provide :no_footer, true %> +
+
+

503

+ +

+ Service Unavailable +

+ +

+ Sorry, this page is undergoing maintenance. Please try again later. +

+ +
+ + <%= link_to "Return to Dashboard", + root_path, + class: + "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + +
+
+
diff --git a/app/views/errors/unauthorized.html.erb b/app/views/errors/unauthorized.html.erb new file mode 100644 index 00000000..6e86b193 --- /dev/null +++ b/app/views/errors/unauthorized.html.erb @@ -0,0 +1,31 @@ +<% content_for :hide_breadcrumbs, true %> +<% content_for :hide_toggler, true %> +<% provide :no_footer, true %> +
+
+

401

+ +

+ Unauthorized +

+ +

+ You need to be authenticated to access this page. Please login to + continue. +

+ +
+ + <%= link_to "Go to Login", + login_path, + class: + "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + +
+
+
diff --git a/app/views/errors/unprocessable_entity.html.erb b/app/views/errors/unprocessable_entity.html.erb new file mode 100644 index 00000000..888a5465 --- /dev/null +++ b/app/views/errors/unprocessable_entity.html.erb @@ -0,0 +1,31 @@ +<% content_for :hide_breadcrumbs, true %> +<% content_for :hide_toggler, true %> +<% provide :no_footer, true %> +
+
+

422

+ +

+ Unprocessable Entity +

+ +

+ Sorry, an error occurred. If you had submitted a form right before this + error occurred, try resubmitting it again. +

+ +
+ + <%= link_to "Return to Dashboard", + root_path, + class: + "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + +
+
+
diff --git a/config/routes.rb b/config/routes.rb index d3c9a0a2..7139baa1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -85,6 +85,10 @@ get 'up' => 'rails/health#show', as: :rails_health_check match '/404', to: 'errors#not_found', via: :all match '/500', to: 'errors#internal_server_error', via: :all + match '/401', to: 'errors#unauthorized', via: :all + match '/403', to: 'errors#forbidden', via: :all + match '/503', to: 'errors#service_unavailable', via: :all + match '/422', to: 'errors#unprocessable_entity', via: :all # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest From 3e11e9aee3e0a229cf2af246057e1d2887fc4eea Mon Sep 17 00:00:00 2001 From: Ying Tong Date: Fri, 3 Apr 2026 23:37:37 +0800 Subject: [PATCH 4/7] style: fix ui glitch --- app/views/courses/add_lecturers.html.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/courses/add_lecturers.html.erb b/app/views/courses/add_lecturers.html.erb index e6f564d6..2ce2ff8b 100644 --- a/app/views/courses/add_lecturers.html.erb +++ b/app/views/courses/add_lecturers.html.erb @@ -9,7 +9,8 @@
From 7e599773385ea76fab1e541199288db6e1888b08 Mon Sep 17 00:00:00 2001 From: Ying Tong Date: Fri, 3 Apr 2026 23:42:05 +0800 Subject: [PATCH 5/7] fix: Add missing methods in error controller --- app/controllers/errors_controller.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb index 5e50a5f4..1726066f 100644 --- a/app/controllers/errors_controller.rb +++ b/app/controllers/errors_controller.rb @@ -2,4 +2,12 @@ class ErrorsController < ApplicationController def not_found; end def internal_server_error; end + + def unprocessable_entity; end + + def unauthorized; end + + def forbidden; end + + def service_unavailable; end end From 8322be946ede55821603ea20fbd7d33064055f53 Mon Sep 17 00:00:00 2001 From: Ying Tong Date: Fri, 3 Apr 2026 23:52:08 +0800 Subject: [PATCH 6/7] feat: Restyle --- app/views/errors/forbidden.html.erb | 21 ++++++++++------ .../errors/internal_server_error.html.erb | 25 +++++++++++++------ app/views/errors/not_found.html.erb | 21 ++++++++++------ app/views/errors/service_unavailable.html.erb | 21 ++++++++++------ app/views/errors/unauthorized.html.erb | 23 +++++++++++------ .../errors/unprocessable_entity.html.erb | 25 ++++++++++++------- 6 files changed, 90 insertions(+), 46 deletions(-) diff --git a/app/views/errors/forbidden.html.erb b/app/views/errors/forbidden.html.erb index 572c648c..492f2b3b 100644 --- a/app/views/errors/forbidden.html.erb +++ b/app/views/errors/forbidden.html.erb @@ -1,20 +1,27 @@ <% content_for :hide_breadcrumbs, true %> <% content_for :hide_toggler, true %> -<% provide :no_footer, true %> +
-

403

-

+

+ 403 +

+ +

Forbidden

-

+

Sorry, you are not authorized to view this page.

@@ -23,7 +30,7 @@ <%= link_to "Return to Dashboard", root_path, class: - "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + "cursor-pointer bg-slate-600 hover:bg-slate-700 text-white font-bold py-3.5 px-8 rounded-xl shadow-lg shadow-slate-500/20 hover:shadow-slate-500/30 transition-all transform active:scale-95 text-sm sm:text-base inline-flex justify-center items-center" %>
diff --git a/app/views/errors/internal_server_error.html.erb b/app/views/errors/internal_server_error.html.erb index 2ce5db9c..79db9f03 100644 --- a/app/views/errors/internal_server_error.html.erb +++ b/app/views/errors/internal_server_error.html.erb @@ -1,19 +1,28 @@ <% content_for :hide_breadcrumbs, true %> <% content_for :hide_toggler, true %> -<% provide :no_footer, true %> +
-

500

-

+

+ 500 +

+ +

Internal Server Error

-

- Sorry, we couldn't find the page you're looking for. It might have been - moved or deleted. +

+ Sorry, an unexpected error occurred. Please try again later.

@@ -21,7 +30,7 @@ <%= link_to "Return to Dashboard", root_path, class: - "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + "cursor-pointer bg-slate-600 hover:bg-slate-700 text-white font-bold py-3.5 px-8 rounded-xl shadow-lg shadow-slate-500/20 hover:shadow-slate-500/30 transition-all transform active:scale-95 text-sm sm:text-base inline-flex justify-center items-center" %>
diff --git a/app/views/errors/not_found.html.erb b/app/views/errors/not_found.html.erb index 5aee9055..d34f59fd 100644 --- a/app/views/errors/not_found.html.erb +++ b/app/views/errors/not_found.html.erb @@ -1,20 +1,27 @@ <% content_for :hide_breadcrumbs, true %> <% content_for :hide_toggler, true %> -<% provide :no_footer, true %> +
-

404

-

+

+ 404 +

+ +

Page not found

-

+

Sorry, we couldn't find the page you're looking for. It probably doesn't exist, or might have been moved or deleted.

@@ -24,7 +31,7 @@ <%= link_to "Return to Dashboard", root_path, class: - "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + "cursor-pointer bg-slate-600 hover:bg-slate-700 text-white font-bold py-3.5 px-8 rounded-xl shadow-lg shadow-slate-500/20 hover:shadow-slate-500/30 transition-all transform active:scale-95 text-sm sm:text-base inline-flex justify-center items-center" %>
diff --git a/app/views/errors/service_unavailable.html.erb b/app/views/errors/service_unavailable.html.erb index 227ed686..ea2f7888 100644 --- a/app/views/errors/service_unavailable.html.erb +++ b/app/views/errors/service_unavailable.html.erb @@ -1,20 +1,27 @@ <% content_for :hide_breadcrumbs, true %> <% content_for :hide_toggler, true %> -<% provide :no_footer, true %> +
-

503

-

+

+ 503 +

+ +

Service Unavailable

-

+

Sorry, this page is undergoing maintenance. Please try again later.

@@ -23,7 +30,7 @@ <%= link_to "Return to Dashboard", root_path, class: - "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + "cursor-pointer bg-slate-600 hover:bg-slate-700 text-white font-bold py-3.5 px-8 rounded-xl shadow-lg shadow-slate-500/20 hover:shadow-slate-500/30 transition-all transform active:scale-95 text-sm sm:text-base inline-flex justify-center items-center" %>
diff --git a/app/views/errors/unauthorized.html.erb b/app/views/errors/unauthorized.html.erb index 6e86b193..52ae8242 100644 --- a/app/views/errors/unauthorized.html.erb +++ b/app/views/errors/unauthorized.html.erb @@ -1,21 +1,28 @@ <% content_for :hide_breadcrumbs, true %> <% content_for :hide_toggler, true %> -<% provide :no_footer, true %> +
-

401

-

+

+ 401 +

+ +

Unauthorized

-

- You need to be authenticated to access this page. Please login to +

+ Sorry, you must be authenticated to view this page. Please login to continue.

@@ -24,7 +31,7 @@ <%= link_to "Go to Login", login_path, class: - "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + "cursor-pointer bg-slate-600 hover:bg-slate-700 text-white font-bold py-3.5 px-8 rounded-xl shadow-lg shadow-slate-500/20 hover:shadow-slate-500/30 transition-all transform active:scale-95 text-sm sm:text-base inline-flex justify-center items-center" %>
diff --git a/app/views/errors/unprocessable_entity.html.erb b/app/views/errors/unprocessable_entity.html.erb index 888a5465..eace7604 100644 --- a/app/views/errors/unprocessable_entity.html.erb +++ b/app/views/errors/unprocessable_entity.html.erb @@ -1,22 +1,29 @@ <% content_for :hide_breadcrumbs, true %> <% content_for :hide_toggler, true %> -<% provide :no_footer, true %> +
-

422

-

+

+ 422 +

+ +

Unprocessable Entity

-

- Sorry, an error occurred. If you had submitted a form right before this - error occurred, try resubmitting it again. +

+ Sorry, an error occurred. If you had just submitted a form before this + error occurred. please try resubmitting again.

@@ -24,7 +31,7 @@ <%= link_to "Return to Dashboard", root_path, class: - "rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200" %> + "cursor-pointer bg-slate-600 hover:bg-slate-700 text-white font-bold py-3.5 px-8 rounded-xl shadow-lg shadow-slate-500/20 hover:shadow-slate-500/30 transition-all transform active:scale-95 text-sm sm:text-base inline-flex justify-center items-center" %>
From 88abfa19fe059c8ab68ba49b6a755fdcdfcb685c Mon Sep 17 00:00:00 2001 From: Ying Tong Date: Fri, 3 Apr 2026 23:56:14 +0800 Subject: [PATCH 7/7] Revert to debug view on dev --- config/environments/development.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index 972b356f..e7ba5d32 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -10,7 +10,7 @@ config.eager_load = false # Show full error reports. - config.consider_all_requests_local = false + config.consider_all_requests_local = true # Enable server timing. config.server_timing = true