diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb
index 4ba4bcc..47f7e49 100644
--- a/app/controllers/categories_controller.rb
+++ b/app/controllers/categories_controller.rb
@@ -3,11 +3,17 @@ class CategoriesController < ApplicationController
# GET /categories or /categories.json
def index
- @categories = Category.all
+ @categories = Category.includes(:products).all
+
+ @categories.each do |category|
+ category.products = category.products || []
+ end
end
# GET /categories/1 or /categories/1.json
def show
+ # `set_category` before_action will load @category; expose associated products as @products
+ @products = @category.products
end
# GET /categories/new
@@ -60,7 +66,7 @@ class CategoriesController < ApplicationController
private
# Use callbacks to share common setup or constraints between actions.
def set_category
- @category = Category.find(params.expect(:id))
+ @category = Category.find(params[:id])
end
# Only allow a list of trusted parameters through.
diff --git a/app/controllers/products_controller.rb b/app/controllers/products_controller.rb
index 5e5d0bd..879990b 100644
--- a/app/controllers/products_controller.rb
+++ b/app/controllers/products_controller.rb
@@ -8,6 +8,8 @@ class ProductsController < ApplicationController
# GET /products/1 or /products/1.json
def show
+ @category = Category.find_by(id: params[:id])
+ @product = Product.find_by(id: params[:id])
end
# GET /products/new
@@ -65,6 +67,6 @@ class ProductsController < ApplicationController
# Only allow a list of trusted parameters through.
def product_params
- params.expect(product: [ :name, :description, :price, images: [] ])
+ params.require(:product).permit(:name, :category_id, :description, :price, images: [])
end
end
diff --git a/app/models/category.rb b/app/models/category.rb
index d58b9f4..851f439 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -1,4 +1,6 @@
class Category < ApplicationRecord
has_rich_text :description
has_one_attached :image
+ # Use lowercase association name so ActiveRecord sets up `category.products`
+ has_many :products, dependent: :destroy
end
diff --git a/app/models/product.rb b/app/models/product.rb
index 4ce2d44..2dfb4d0 100644
--- a/app/models/product.rb
+++ b/app/models/product.rb
@@ -1,4 +1,6 @@
class Product < ApplicationRecord
has_rich_text :description
has_many_attached :images
+
+ belongs_to :category
end
diff --git a/app/views/categories/_category.html.erb b/app/views/categories/_category.html.erb
index 17b84da..63bb4dc 100644
--- a/app/views/categories/_category.html.erb
+++ b/app/views/categories/_category.html.erb
@@ -1,8 +1,5 @@
-
- Name:
- <%= category.name %>
-
+
<%= category.name %>
Description:
@@ -14,4 +11,14 @@
<%= link_to category.image.filename, category.image if category.image.attached? %>
-
+ <% if products.present? %>
+ Products in this Category
+
+ <% products.each do |product| %>
+ - <%= product.name %> - $<%= product.price %>
+ <% end %>
+
+ <% else %>
+ No products available in this category.
+ <% end %>
+
\ No newline at end of file
diff --git a/app/views/categories/index.html.erb b/app/views/categories/index.html.erb
index 4f7b00d..6b4515e 100644
--- a/app/views/categories/index.html.erb
+++ b/app/views/categories/index.html.erb
@@ -6,7 +6,7 @@
<% @categories.each do |category| %>
- <%= render category %>
+ <%= render partial: "category", locals: {category: category, products: category.products} %>
<%= link_to "Show this category", category %>
diff --git a/app/views/categories/show.html.erb b/app/views/categories/show.html.erb
index dd28ade..b2e2b1a 100644
--- a/app/views/categories/show.html.erb
+++ b/app/views/categories/show.html.erb
@@ -1,6 +1,6 @@
<%= notice %>
-<%= render @category %>
+<%= render partial: "category", locals: { category: @category, products: @products } %>
<%= link_to "Edit this category", edit_category_path(@category) %> |
diff --git a/app/views/institutions/index.html.erb b/app/views/institutions/index.html.erb
index 762b520..ccb6792 100644
--- a/app/views/institutions/index.html.erb
+++ b/app/views/institutions/index.html.erb
@@ -53,8 +53,8 @@ html, body {
margin: 0;
padding: 0;
font-family: "Poppins", sans-serif;
- background: linear-gradient(135deg, #0f1724, #1e293b);
- color: #e6eef6;
+ background: #181a1b !important;
+ color: #0f1724;
}
.page-wrapper {
@@ -65,7 +65,7 @@ html, body {
}
.container {
- max-width: 1900px;
+ max-width: 100%;
margin: 0 auto;
padding-top: 20px;
flex: 1;
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 72c72f2..6ef9747 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -150,10 +150,50 @@ background: linear-gradient(-45deg, #1e88e5, #43a047, #6a1b9a, #d81b60);
.navbar {
position: fixed;
top: 0;
- width: 100%;
+ width: 88%;
+ margin-left: 12%;
}
-
+
+ /* Sidebar styles */
+ .sidebar {
+ position: fixed;
+ top: 0; /* align under navbar */
+ left: 0;
+ bottom: 0;
+ width: 240px;
+ padding: 18px;
+ background: rgba(28,30,33,0.95);
+ color: #e6eef0;
+ border-right: 1px solid rgba(255,255,255,0.03);
+ z-index: 1040;
+ transition: transform .28s ease, width .2s ease;
+ overflow-y: auto;
+ }
+ .sidebar .side-logo { width:44px; height:44px; border-radius:8px; object-fit:cover; }
+ .sidebar .sidebar-brand { display:flex; align-items:center; gap:12px; margin-bottom:12px; }
+ .sidebar .brand-text { font-weight:700; color:#bfe6c8; font-size:1rem }
+ .sidebar .sidebar-toggle { margin-left:auto; background:transparent; border:none; color: #cfe9d8; font-size:1.1rem; cursor:pointer; }
+ .sidebar-nav ul { list-style:none; padding:0; margin:6px 0; }
+ .sidebar-nav li { margin:8px 0; }
+ .sidebar-nav a { color: #e6eef0; text-decoration:none; display:flex; gap:10px; align-items:center; padding:8px 10px; border-radius:8px; }
+ .sidebar-nav a:hover { background: rgba(30,136,229,0.12); color: #fff; }
+
+ /* Main content shift */
+ .main-container { margin-left: 0; transition: margin-left .28s ease; }
+
+ @media (min-width: 992px) {
+ .main-container { margin-left: 260px; }
+ }
+
+ /* Collapsed state */
+ .sidebar.collapsed { transform: translateX(-100%); }
+ @media (max-width: 991px) {
+ .sidebar { transform: translateX(-100%); }
+ .sidebar.open { transform: translateX(0); }
+ .main-container { margin-left: 0; }
+ }
+
<%# Includes all stylesheet files in app/assets/stylesheets %>
@@ -178,27 +218,6 @@ background: linear-gradient(-45deg, #1e88e5, #43a047, #6a1b9a, #d81b60);
- -
- <%= link_to "🏠 Home", root_path, class: "nav-link active" %>
-
- -
- <%= link_to "🎓 Programs", programs_path, class: "nav-link" %>
-
- -
- <%= link_to "🕌 Ziyara", ziyaras_path, class: "nav-link" %>
-
- -
- <%= link_to "📚 All Students", students_path, class: "nav-link" %>
-
- -
- <%= link_to "💰 Income", incomes_path, class: "nav-link" %>
-
- -
- <%= link_to "📊 Expenses", expenses_path, class: "nav-link" %>
-
- -
- <%= link_to "🏫 Records", exclusive_traditional_records_path, class: "nav-link" %>
-
-
<%= link_to "📞 Contact", contact_path, class: "nav-link" %>
@@ -281,9 +300,29 @@ background: linear-gradient(-45deg, #1e88e5, #43a047, #6a1b9a, #d81b60);
<% content_for :title, "Institutions & Programs" %>
+
+
- <% if flash.any? %>
+ <% if flash.any? %>
<% flash.each do |name, message| %>
<% if name.to_s == 'notice' || name.to_s == 'alert' %>
@@ -293,13 +332,31 @@ background: linear-gradient(-45deg, #1e88e5, #43a047, #6a1b9a, #d81b60);
<% end %>
<% end %>
-